Merge branch 'rewrite/master' into feature/chart-editor-context-menus

This commit is contained in:
Cameron Taylor
2024-01-05 20:11:38 -05:00
32 changed files with 840 additions and 627 deletions
@@ -21,6 +21,7 @@ import flixel.system.FlxAssets.FlxSoundAsset;
import flixel.tweens.FlxEase;
import flixel.tweens.FlxTween;
import flixel.tweens.misc.VarTween;
import haxe.ui.Toolkit;
import flixel.util.FlxColor;
import flixel.util.FlxSort;
import flixel.util.FlxTimer;
@@ -274,13 +275,13 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
function get_songLengthInSteps():Float
{
return Conductor.getTimeInSteps(songLengthInMs);
return Conductor.instance.getTimeInSteps(songLengthInMs);
}
function set_songLengthInSteps(value:Float):Float
{
// Getting a reasonable result from setting songLengthInSteps requires that Conductor.mapBPMChanges be called first.
songLengthInMs = Conductor.getStepTimeInMs(value);
// Getting a reasonable result from setting songLengthInSteps requires that Conductor.instance.mapBPMChanges be called first.
songLengthInMs = Conductor.instance.getStepTimeInMs(value);
return value;
}
@@ -394,12 +395,12 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
function get_scrollPositionInMs():Float
{
return Conductor.getStepTimeInMs(scrollPositionInSteps);
return Conductor.instance.getStepTimeInMs(scrollPositionInSteps);
}
function set_scrollPositionInMs(value:Float):Float
{
scrollPositionInSteps = Conductor.getTimeInSteps(value);
scrollPositionInSteps = Conductor.instance.getTimeInSteps(value);
return value;
}
@@ -453,13 +454,13 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
function get_playheadPositionInMs():Float
{
if (audioVisGroup != null && audioVisGroup.playerVis != null)
audioVisGroup.playerVis.realtimeStartOffset = -Conductor.getStepTimeInMs(playheadPositionInSteps);
return Conductor.getStepTimeInMs(playheadPositionInSteps);
audioVisGroup.playerVis.realtimeStartOffset = -Conductor.instance.getStepTimeInMs(playheadPositionInSteps);
return Conductor.instance.getStepTimeInMs(playheadPositionInSteps);
}
function set_playheadPositionInMs(value:Float):Float
{
playheadPositionInSteps = Conductor.getTimeInSteps(value);
playheadPositionInSteps = Conductor.instance.getTimeInSteps(value);
if (audioVisGroup != null && audioVisGroup.playerVis != null) audioVisGroup.playerVis.realtimeStartOffset = -value;
return value;
@@ -874,6 +875,70 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
return Save.get().chartEditorHasBackup = value;
}
/**
* A list of previous working file paths.
* Also known as the "recent files" list.
* The first element is [null] if the current working file has not been saved anywhere yet.
*/
public var previousWorkingFilePaths(default, set):Array<Null<String>> = [null];
function set_previousWorkingFilePaths(value:Array<Null<String>>):Array<Null<String>>
{
// Called only when the WHOLE LIST is overridden.
previousWorkingFilePaths = value;
applyWindowTitle();
populateOpenRecentMenu();
applyCanQuickSave();
return value;
}
/**
* The current file path which the chart editor is working with.
* If `null`, the current chart has not been saved yet.
*/
public var currentWorkingFilePath(get, set):Null<String>;
function get_currentWorkingFilePath():Null<String>
{
return previousWorkingFilePaths[0];
}
function set_currentWorkingFilePath(value:Null<String>):Null<String>
{
if (value == previousWorkingFilePaths[0]) return value;
if (previousWorkingFilePaths.contains(null))
{
// Filter all instances of `null` from the array.
previousWorkingFilePaths = previousWorkingFilePaths.filter(function(x:Null<String>):Bool {
return x != null;
});
}
if (previousWorkingFilePaths.contains(value))
{
// Move the path to the front of the list.
previousWorkingFilePaths.remove(value);
previousWorkingFilePaths.unshift(value);
}
else
{
// Add the path to the front of the list.
previousWorkingFilePaths.unshift(value);
}
while (previousWorkingFilePaths.length > Constants.MAX_PREVIOUS_WORKING_FILES)
{
// Remove the last path in the list.
previousWorkingFilePaths.pop();
}
populateOpenRecentMenu();
applyWindowTitle();
return value;
}
/**
* Whether the difficulty tree view in the toolbox has been modified and needs to be updated.
* This happens when we add/remove difficulties.
@@ -903,6 +968,12 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
*/
var commandHistoryDirty:Bool = true;
/**
* If true, we are currently in the process of quitting the chart editor.
* Skip any update functions as most of them will call a crash.
*/
var criticalFailure:Bool = false;
// Input
/**
@@ -1733,70 +1804,6 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
*/
var params:Null<ChartEditorParams>;
/**
* A list of previous working file paths.
* Also known as the "recent files" list.
* The first element is [null] if the current working file has not been saved anywhere yet.
*/
public var previousWorkingFilePaths(default, set):Array<Null<String>> = [null];
function set_previousWorkingFilePaths(value:Array<Null<String>>):Array<Null<String>>
{
// Called only when the WHOLE LIST is overridden.
previousWorkingFilePaths = value;
applyWindowTitle();
populateOpenRecentMenu();
applyCanQuickSave();
return value;
}
/**
* The current file path which the chart editor is working with.
* If `null`, the current chart has not been saved yet.
*/
public var currentWorkingFilePath(get, set):Null<String>;
function get_currentWorkingFilePath():Null<String>
{
return previousWorkingFilePaths[0];
}
function set_currentWorkingFilePath(value:Null<String>):Null<String>
{
if (value == previousWorkingFilePaths[0]) return value;
if (previousWorkingFilePaths.contains(null))
{
// Filter all instances of `null` from the array.
previousWorkingFilePaths = previousWorkingFilePaths.filter(function(x:Null<String>):Bool {
return x != null;
});
}
if (previousWorkingFilePaths.contains(value))
{
// Move the path to the front of the list.
previousWorkingFilePaths.remove(value);
previousWorkingFilePaths.unshift(value);
}
else
{
// Add the path to the front of the list.
previousWorkingFilePaths.unshift(value);
}
while (previousWorkingFilePaths.length > Constants.MAX_PREVIOUS_WORKING_FILES)
{
// Remove the last path in the list.
previousWorkingFilePaths.pop();
}
populateOpenRecentMenu();
applyWindowTitle();
return value;
}
public function new(?params:ChartEditorParams)
{
super();
@@ -2419,13 +2426,13 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
}
else
{
Conductor.currentTimeChange.bpm += 1;
Conductor.instance.currentTimeChange.bpm += 1;
this.refreshToolbox(CHART_EDITOR_TOOLBOX_METADATA_LAYOUT);
}
}
playbarBPM.onRightClick = _ -> {
Conductor.currentTimeChange.bpm -= 1;
Conductor.instance.currentTimeChange.bpm -= 1;
this.refreshToolbox(CHART_EDITOR_TOOLBOX_METADATA_LAYOUT);
}
@@ -2474,9 +2481,9 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
menubarItemPaste.onClick = _ -> {
var targetMs:Float = scrollPositionInMs + playheadPositionInMs;
var targetStep:Float = Conductor.getTimeInSteps(targetMs);
var targetStep:Float = Conductor.instance.getTimeInSteps(targetMs);
var targetSnappedStep:Float = Math.floor(targetStep / noteSnapRatio) * noteSnapRatio;
var targetSnappedMs:Float = Conductor.getStepTimeInMs(targetSnappedStep);
var targetSnappedMs:Float = Conductor.instance.getStepTimeInMs(targetSnappedStep);
performCommand(new PasteItemsCommand(targetSnappedMs));
};
@@ -2706,10 +2713,12 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
saveDataDirty = false;
}
var displayAutosavePopup:Bool = false;
/**
* UPDATE FUNCTIONS
*/
function autoSave():Void
function autoSave(?beforePlaytest:Bool = false):Void
{
var needsAutoSave:Bool = saveDataDirty;
@@ -2727,13 +2736,21 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
if (needsAutoSave)
{
this.exportAllSongData(true, null);
var absoluteBackupsPath:String = Path.join([Sys.getCwd(), ChartEditorImportExportHandler.BACKUPS_PATH]);
this.infoWithActions('Auto-Save', 'Chart auto-saved to ${absoluteBackupsPath}.', [
{
text: "Take Me There",
callback: openBackupsFolder,
}
]);
if (beforePlaytest)
{
displayAutosavePopup = true;
}
else
{
displayAutosavePopup = false;
var absoluteBackupsPath:String = Path.join([Sys.getCwd(), ChartEditorImportExportHandler.BACKUPS_PATH]);
this.infoWithActions('Auto-Save', 'Chart auto-saved to ${absoluteBackupsPath}.', [
{
text: "Take Me There",
callback: openBackupsFolder,
}
]);
}
}
#end
}
@@ -2801,7 +2818,7 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
public override function update(elapsed:Float):Void
{
// Override F4 behavior to include the autosave.
if (FlxG.keys.justPressed.F4)
if (FlxG.keys.justPressed.F4 && !criticalFailure)
{
quitChartEditor();
return;
@@ -2810,6 +2827,8 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
// dispatchEvent gets called here.
super.update(elapsed);
if (criticalFailure) return;
// These ones happen even if the modal dialog is open.
handleMusicPlayback(elapsed);
handleNoteDisplay();
@@ -2849,7 +2868,7 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
if (metronomeVolume > 0.0 && this.subState == null && (audioInstTrack != null && audioInstTrack.isPlaying))
{
playMetronomeTick(Conductor.currentBeat % 4 == 0);
playMetronomeTick(Conductor.instance.currentBeat % 4 == 0);
}
// Show the mouse cursor.
@@ -2869,8 +2888,8 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
if (audioInstTrack != null && audioInstTrack.isPlaying)
{
if (healthIconDad != null) healthIconDad.onStepHit(Conductor.currentStep);
if (healthIconBF != null) healthIconBF.onStepHit(Conductor.currentStep);
if (healthIconDad != null) healthIconDad.onStepHit(Conductor.instance.currentStep);
if (healthIconBF != null) healthIconBF.onStepHit(Conductor.instance.currentStep);
}
// Updating these every step keeps it more accurate.
@@ -2898,12 +2917,12 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
audioInstTrack.update(elapsed);
// If the song starts 50ms in, make sure we start the song there.
if (Conductor.instrumentalOffset < 0)
if (Conductor.instance.instrumentalOffset < 0)
{
if (audioInstTrack.time < -Conductor.instrumentalOffset)
if (audioInstTrack.time < -Conductor.instance.instrumentalOffset)
{
trace('Resetting instrumental time to ${- Conductor.instrumentalOffset}ms');
audioInstTrack.time = -Conductor.instrumentalOffset;
trace('Resetting instrumental time to ${- Conductor.instance.instrumentalOffset}ms');
audioInstTrack.time = -Conductor.instance.instrumentalOffset;
}
}
}
@@ -2914,16 +2933,16 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
{
// If middle mouse panning during song playback, we move ONLY the playhead, without scrolling. Neat!
var oldStepTime:Float = Conductor.currentStepTime;
var oldSongPosition:Float = Conductor.songPosition + Conductor.instrumentalOffset;
Conductor.update(audioInstTrack.time);
handleHitsounds(oldSongPosition, Conductor.songPosition + Conductor.instrumentalOffset);
var oldStepTime:Float = Conductor.instance.currentStepTime;
var oldSongPosition:Float = Conductor.instance.songPosition + Conductor.instance.instrumentalOffset;
Conductor.instance.update(audioInstTrack.time);
handleHitsounds(oldSongPosition, Conductor.instance.songPosition + Conductor.instance.instrumentalOffset);
// Resync vocals.
if (audioVocalTrackGroup != null && Math.abs(audioInstTrack.time - audioVocalTrackGroup.time) > 100)
{
audioVocalTrackGroup.time = audioInstTrack.time;
}
var diffStepTime:Float = Conductor.currentStepTime - oldStepTime;
var diffStepTime:Float = Conductor.instance.currentStepTime - oldStepTime;
// Move the playhead.
playheadPositionInPixels += diffStepTime * GRID_SIZE;
@@ -2933,9 +2952,9 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
else
{
// Else, move the entire view.
var oldSongPosition:Float = Conductor.songPosition + Conductor.instrumentalOffset;
Conductor.update(audioInstTrack.time);
handleHitsounds(oldSongPosition, Conductor.songPosition + Conductor.instrumentalOffset);
var oldSongPosition:Float = Conductor.instance.songPosition + Conductor.instance.instrumentalOffset;
Conductor.instance.update(audioInstTrack.time);
handleHitsounds(oldSongPosition, Conductor.instance.songPosition + Conductor.instance.instrumentalOffset);
// Resync vocals.
if (audioVocalTrackGroup != null && Math.abs(audioInstTrack.time - audioVocalTrackGroup.time) > 100)
{
@@ -2944,7 +2963,7 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
// We need time in fractional steps here to allow the song to actually play.
// Also account for a potentially offset playhead.
scrollPositionInPixels = (Conductor.currentStepTime + Conductor.instrumentalOffsetSteps) * GRID_SIZE - playheadPositionInPixels;
scrollPositionInPixels = (Conductor.instance.currentStepTime + Conductor.instance.instrumentalOffsetSteps) * GRID_SIZE - playheadPositionInPixels;
// DO NOT move song to scroll position here specifically.
@@ -3075,8 +3094,8 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
// Let's try testing only notes within a certain range of the view area.
// TODO: I don't think this messes up really long sustains, does it?
var viewAreaTopMs:Float = scrollPositionInMs - (Conductor.measureLengthMs * 2); // Is 2 measures enough?
var viewAreaBottomMs:Float = scrollPositionInMs + (Conductor.measureLengthMs * 2); // Is 2 measures enough?
var viewAreaTopMs:Float = scrollPositionInMs - (Conductor.instance.measureLengthMs * 2); // Is 2 measures enough?
var viewAreaBottomMs:Float = scrollPositionInMs + (Conductor.instance.measureLengthMs * 2); // Is 2 measures enough?
// Add notes that are now visible.
for (noteData in currentSongChartNoteData)
@@ -3363,14 +3382,14 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
// PAGE UP = Jump up to nearest measure
if (pageUpKeyHandler.activated)
{
var measureHeight:Float = GRID_SIZE * 4 * Conductor.beatsPerMeasure;
var measureHeight:Float = GRID_SIZE * 4 * Conductor.instance.beatsPerMeasure;
var playheadPos:Float = scrollPositionInPixels + playheadPositionInPixels;
var targetScrollPosition:Float = Math.floor(playheadPos / measureHeight) * measureHeight;
// If we would move less than one grid, instead move to the top of the previous measure.
var targetScrollAmount = Math.abs(targetScrollPosition - playheadPos);
if (targetScrollAmount < GRID_SIZE)
{
targetScrollPosition -= GRID_SIZE * Constants.STEPS_PER_BEAT * Conductor.beatsPerMeasure;
targetScrollPosition -= GRID_SIZE * Constants.STEPS_PER_BEAT * Conductor.instance.beatsPerMeasure;
}
scrollAmount = targetScrollPosition - playheadPos;
@@ -3379,21 +3398,21 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
if (playbarButtonPressed == 'playbarBack')
{
playbarButtonPressed = '';
scrollAmount = -GRID_SIZE * 4 * Conductor.beatsPerMeasure;
scrollAmount = -GRID_SIZE * 4 * Conductor.instance.beatsPerMeasure;
shouldPause = true;
}
// PAGE DOWN = Jump down to nearest measure
if (pageDownKeyHandler.activated)
{
var measureHeight:Float = GRID_SIZE * 4 * Conductor.beatsPerMeasure;
var measureHeight:Float = GRID_SIZE * 4 * Conductor.instance.beatsPerMeasure;
var playheadPos:Float = scrollPositionInPixels + playheadPositionInPixels;
var targetScrollPosition:Float = Math.ceil(playheadPos / measureHeight) * measureHeight;
// If we would move less than one grid, instead move to the top of the next measure.
var targetScrollAmount = Math.abs(targetScrollPosition - playheadPos);
if (targetScrollAmount < GRID_SIZE)
{
targetScrollPosition += GRID_SIZE * Constants.STEPS_PER_BEAT * Conductor.beatsPerMeasure;
targetScrollPosition += GRID_SIZE * Constants.STEPS_PER_BEAT * Conductor.instance.beatsPerMeasure;
}
scrollAmount = targetScrollPosition - playheadPos;
@@ -3402,7 +3421,7 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
if (playbarButtonPressed == 'playbarForward')
{
playbarButtonPressed = '';
scrollAmount = GRID_SIZE * 4 * Conductor.beatsPerMeasure;
scrollAmount = GRID_SIZE * 4 * Conductor.instance.beatsPerMeasure;
shouldPause = true;
}
@@ -3607,10 +3626,10 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
// The song position of the cursor, in steps.
var cursorFractionalStep:Float = cursorY / GRID_SIZE;
var cursorMs:Float = Conductor.getStepTimeInMs(cursorFractionalStep);
var cursorMs:Float = Conductor.instance.getStepTimeInMs(cursorFractionalStep);
// Round the cursor step to the nearest snap quant.
var cursorSnappedStep:Float = Math.floor(cursorFractionalStep / noteSnapRatio) * noteSnapRatio;
var cursorSnappedMs:Float = Conductor.getStepTimeInMs(cursorSnappedStep);
var cursorSnappedMs:Float = Conductor.instance.getStepTimeInMs(cursorSnappedStep);
// The direction value for the column at the cursor.
var cursorGridPos:Int = Math.floor(cursorX / GRID_SIZE);
@@ -3632,7 +3651,7 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
// We released the mouse. Select the notes in the box.
var cursorFractionalStepStart:Float = cursorYStart / GRID_SIZE;
var cursorStepStart:Int = Math.floor(cursorFractionalStepStart);
var cursorMsStart:Float = Conductor.getStepTimeInMs(cursorStepStart);
var cursorMsStart:Float = Conductor.instance.getStepTimeInMs(cursorStepStart);
var cursorColumnBase:Int = Math.floor(cursorX / GRID_SIZE);
var cursorColumnBaseStart:Int = Math.floor(cursorXStart / GRID_SIZE);
@@ -3868,11 +3887,11 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
var dragDistanceMs:Float = 0;
if (dragTargetNote != null && dragTargetNote.noteData != null)
{
dragDistanceMs = Conductor.getStepTimeInMs(dragTargetNote.noteData.getStepTime() + dragDistanceSteps) - dragTargetNote.noteData.time;
dragDistanceMs = Conductor.instance.getStepTimeInMs(dragTargetNote.noteData.getStepTime() + dragDistanceSteps) - dragTargetNote.noteData.time;
}
else if (dragTargetEvent != null && dragTargetEvent.eventData != null)
{
dragDistanceMs = Conductor.getStepTimeInMs(dragTargetEvent.eventData.getStepTime() + dragDistanceSteps) - dragTargetEvent.eventData.time;
dragDistanceMs = Conductor.instance.getStepTimeInMs(dragTargetEvent.eventData.getStepTime() + dragDistanceSteps) - dragTargetEvent.eventData.time;
}
var dragDistanceColumns:Int = dragTargetCurrentColumn;
@@ -3932,7 +3951,7 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
{
stepTime = dragTargetEvent.eventData.getStepTime();
}
var dragDistanceSteps:Float = Conductor.getTimeInSteps(cursorSnappedMs).clamp(0, songLengthInSteps - (1 * noteSnapRatio)) - stepTime;
var dragDistanceSteps:Float = Conductor.instance.getTimeInSteps(cursorSnappedMs).clamp(0, songLengthInSteps - (1 * noteSnapRatio)) - stepTime;
var data:Int = 0;
var noteGridPos:Int = 0;
if (dragTargetNote != null && dragTargetNote.noteData != null)
@@ -3964,8 +3983,8 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
// Handle extending the note as you drag.
var stepTime:Float = inline currentPlaceNoteData.getStepTime();
var dragLengthSteps:Float = Conductor.getTimeInSteps(cursorSnappedMs) - stepTime;
var dragLengthMs:Float = dragLengthSteps * Conductor.stepLengthMs;
var dragLengthSteps:Float = Conductor.instance.getTimeInSteps(cursorSnappedMs) - stepTime;
var dragLengthMs:Float = dragLengthSteps * Conductor.instance.stepLengthMs;
var dragLengthPixels:Float = dragLengthSteps * GRID_SIZE;
if (gridGhostNote != null && gridGhostNote.noteData != null && gridGhostHoldNote != null)
@@ -4465,7 +4484,7 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
if (playbarHeadLayout.playbarHead.value != songPosPercent) playbarHeadLayout.playbarHead.value = songPosPercent;
}
var songPos:Float = Conductor.songPosition + Conductor.instrumentalOffset;
var songPos:Float = Conductor.instance.songPosition + Conductor.instance.instrumentalOffset;
var songPosSeconds:String = Std.string(Math.floor((Math.abs(songPos) / 1000) % 60)).lpad('0', 2);
var songPosMinutes:String = Std.string(Math.floor((Math.abs(songPos) / 1000) / 60)).lpad('0', 2);
if (songPos < 0) songPosMinutes = '-' + songPosMinutes;
@@ -4521,11 +4540,11 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
var playheadPos:Float = scrollPositionInPixels + playheadPositionInPixels;
var playheadPosFractionalStep:Float = playheadPos / GRID_SIZE / noteSnapRatio;
var playheadPosStep:Int = Std.int(Math.floor(playheadPosFractionalStep));
var playheadPosSnappedMs:Float = playheadPosStep * Conductor.stepLengthMs * noteSnapRatio;
var playheadPosSnappedMs:Float = playheadPosStep * Conductor.instance.stepLengthMs * noteSnapRatio;
// Look for notes within 1 step of the playhead.
var notesAtPos:Array<SongNoteData> = SongDataUtils.getNotesInTimeRange(currentSongChartNoteData, playheadPosSnappedMs,
playheadPosSnappedMs + Conductor.stepLengthMs * noteSnapRatio);
playheadPosSnappedMs + Conductor.instance.stepLengthMs * noteSnapRatio);
notesAtPos = SongDataUtils.getNotesWithData(notesAtPos, [column]);
if (notesAtPos.length == 0)
@@ -4632,6 +4651,8 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
FlxG.switchState(new MainMenuState());
resetWindowTitle();
criticalFailure = true;
}
/**
@@ -4722,9 +4743,9 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
else
{
var targetMs:Float = scrollPositionInMs + playheadPositionInMs;
var targetStep:Float = Conductor.getTimeInSteps(targetMs);
var targetStep:Float = Conductor.instance.getTimeInSteps(targetMs);
var targetSnappedStep:Float = Math.floor(targetStep / noteSnapRatio) * noteSnapRatio;
var targetSnappedMs:Float = Conductor.getStepTimeInMs(targetSnappedStep);
var targetSnappedMs:Float = Conductor.instance.getStepTimeInMs(targetSnappedStep);
targetSnappedMs;
}
performCommand(new PasteItemsCommand(targetMs));
@@ -4862,7 +4883,7 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
*/
function testSongInPlayState(minimal:Bool = false):Void
{
autoSave();
autoSave(true);
stopWelcomeMusic();
@@ -5066,7 +5087,7 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
// Remove any notes past the end of the song.
var songCutoffPointSteps:Float = songLengthInSteps - 0.1;
var songCutoffPointMs:Float = Conductor.getStepTimeInMs(songCutoffPointSteps);
var songCutoffPointMs:Float = Conductor.instance.getStepTimeInMs(songCutoffPointSteps);
currentSongChartNoteData = SongDataUtils.clampSongNoteData(currentSongChartNoteData, 0.0, songCutoffPointMs);
currentSongChartEventData = SongDataUtils.clampSongEventData(currentSongChartEventData, 0.0, songCutoffPointMs);
@@ -5168,7 +5189,7 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
var prevDifficulty = availableDifficulties[availableDifficulties.length - 1];
selectedDifficulty = prevDifficulty;
Conductor.mapTimeChanges(this.currentSongMetadata.timeChanges);
Conductor.instance.mapTimeChanges(this.currentSongMetadata.timeChanges);
refreshDifficultyTreeSelection();
this.refreshToolbox(CHART_EDITOR_TOOLBOX_METADATA_LAYOUT);
@@ -5230,9 +5251,9 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
// Update the songPosition in the audio tracks.
if (audioInstTrack != null)
{
audioInstTrack.time = scrollPositionInMs + playheadPositionInMs - Conductor.instrumentalOffset;
audioInstTrack.time = scrollPositionInMs + playheadPositionInMs - Conductor.instance.instrumentalOffset;
// Update the songPosition in the Conductor.
Conductor.update(audioInstTrack.time);
Conductor.instance.update(audioInstTrack.time);
if (audioVocalTrackGroup != null) audioVocalTrackGroup.time = audioInstTrack.time;
}
@@ -5292,6 +5313,20 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
this.persistentUpdate = true;
this.persistentDraw = true;
if (displayAutosavePopup)
{
displayAutosavePopup = false;
Toolkit.callLater(() -> {
var absoluteBackupsPath:String = Path.join([Sys.getCwd(), ChartEditorImportExportHandler.BACKUPS_PATH]);
this.infoWithActions('Auto-Save', 'Chart auto-saved to ${absoluteBackupsPath}.', [
{
text: "Take Me There",
callback: openBackupsFolder,
}
]);
});
}
moveSongToScrollPosition();
fadeInWelcomeMusic(7, 10);
@@ -5551,7 +5586,7 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
trace('ERROR: Instrumental track is null!');
}
this.songLengthInMs = (audioInstTrack?.length ?? 1000.0) + Conductor.instrumentalOffset;
this.songLengthInMs = (audioInstTrack?.length ?? 1000.0) + Conductor.instance.instrumentalOffset;
// Many things get reset when song length changes.
healthIconsDirty = true;
@@ -34,7 +34,12 @@ class ChangeStartingBPMCommand implements ChartEditorCommand
state.currentSongMetadata.timeChanges = timeChanges;
Conductor.mapTimeChanges(state.currentSongMetadata.timeChanges);
state.noteDisplayDirty = true;
state.notePreviewDirty = true;
state.notePreviewViewportBoundsDirty = true;
state.scrollPositionInPixels = 0;
Conductor.instance.mapTimeChanges(state.currentSongMetadata.timeChanges);
}
public function undo(state:ChartEditorState):Void
@@ -51,7 +56,12 @@ class ChangeStartingBPMCommand implements ChartEditorCommand
state.currentSongMetadata.timeChanges = timeChanges;
Conductor.mapTimeChanges(state.currentSongMetadata.timeChanges);
state.noteDisplayDirty = true;
state.notePreviewDirty = true;
state.notePreviewViewportBoundsDirty = true;
state.scrollPositionInPixels = 0;
Conductor.instance.mapTimeChanges(state.currentSongMetadata.timeChanges);
}
public function toString():String
@@ -33,7 +33,7 @@ class MoveEventsCommand implements ChartEditorCommand
{
// Clone the notes to prevent editing from affecting the history.
var resultEvent = event.clone();
resultEvent.time = (resultEvent.time + offset).clamp(0, Conductor.getStepTimeInMs(state.songLengthInSteps - (1 * state.noteSnapRatio)));
resultEvent.time = (resultEvent.time + offset).clamp(0, Conductor.instance.getStepTimeInMs(state.songLengthInSteps - (1 * state.noteSnapRatio)));
movedEvents.push(resultEvent);
}
@@ -21,8 +21,8 @@ class MoveItemsCommand implements ChartEditorCommand
public function new(notes:Array<SongNoteData>, events:Array<SongEventData>, offset:Float, columns:Int)
{
// Clone the notes to prevent editing from affecting the history.
this.notes = [for (note in notes) note.clone()];
this.events = [for (event in events) event.clone()];
this.notes = notes.clone();
this.events = events.clone();
this.offset = offset;
this.columns = columns;
this.movedNotes = [];
@@ -41,7 +41,7 @@ class MoveItemsCommand implements ChartEditorCommand
{
// Clone the notes to prevent editing from affecting the history.
var resultNote = note.clone();
resultNote.time = (resultNote.time + offset).clamp(0, Conductor.getStepTimeInMs(state.songLengthInSteps - (1 * state.noteSnapRatio)));
resultNote.time = (resultNote.time + offset).clamp(0, Conductor.instance.getStepTimeInMs(state.songLengthInSteps - (1 * state.noteSnapRatio)));
resultNote.data = ChartEditorState.gridColumnToNoteData((ChartEditorState.noteDataToGridColumn(resultNote.data) + columns).clamp(0,
ChartEditorState.STRUMLINE_SIZE * 2 - 1));
@@ -52,7 +52,7 @@ class MoveItemsCommand implements ChartEditorCommand
{
// Clone the notes to prevent editing from affecting the history.
var resultEvent = event.clone();
resultEvent.time = (resultEvent.time + offset).clamp(0, Conductor.getStepTimeInMs(state.songLengthInSteps - (1 * state.noteSnapRatio)));
resultEvent.time = (resultEvent.time + offset).clamp(0, Conductor.instance.getStepTimeInMs(state.songLengthInSteps - (1 * state.noteSnapRatio)));
movedEvents.push(resultEvent);
}
@@ -34,7 +34,7 @@ class MoveNotesCommand implements ChartEditorCommand
{
// Clone the notes to prevent editing from affecting the history.
var resultNote = note.clone();
resultNote.time = (resultNote.time + offset).clamp(0, Conductor.getStepTimeInMs(state.songLengthInSteps - (1 * state.noteSnapRatio)));
resultNote.time = (resultNote.time + offset).clamp(0, Conductor.instance.getStepTimeInMs(state.songLengthInSteps - (1 * state.noteSnapRatio)));
resultNote.data = ChartEditorState.gridColumnToNoteData((ChartEditorState.noteDataToGridColumn(resultNote.data) + columns).clamp(0,
ChartEditorState.STRUMLINE_SIZE * 2 - 1));
@@ -32,9 +32,9 @@ class PasteItemsCommand implements ChartEditorCommand
return;
}
var stepEndOfSong:Float = Conductor.getTimeInSteps(state.songLengthInMs);
var stepEndOfSong:Float = Conductor.instance.getTimeInSteps(state.songLengthInMs);
var stepCutoff:Float = stepEndOfSong - 1.0;
var msCutoff:Float = Conductor.getStepTimeInMs(stepCutoff);
var msCutoff:Float = Conductor.instance.getStepTimeInMs(stepCutoff);
addedNotes = SongDataUtils.offsetSongNoteData(currentClipboard.notes, Std.int(targetTimestamp));
addedNotes = SongDataUtils.clampSongNoteData(addedNotes, 0.0, msCutoff);
@@ -185,7 +185,7 @@ class ChartEditorAudioHandler
state.audioVocalTrackGroup.addPlayerVoice(vocalTrack);
state.audioVisGroup.addPlayerVis(vocalTrack);
state.audioVisGroup.playerVis.x = 885;
state.audioVisGroup.playerVis.realtimeVisLenght = Conductor.getStepTimeInMs(16) * 0.00195;
state.audioVisGroup.playerVis.realtimeVisLenght = Conductor.instance.getStepTimeInMs(16) * 0.00195;
state.audioVisGroup.playerVis.daHeight = (ChartEditorState.GRID_SIZE) * 16;
state.audioVisGroup.playerVis.detail = 1;
@@ -196,7 +196,7 @@ class ChartEditorAudioHandler
state.audioVisGroup.addOpponentVis(vocalTrack);
state.audioVisGroup.opponentVis.x = 435;
state.audioVisGroup.opponentVis.realtimeVisLenght = Conductor.getStepTimeInMs(16) * 0.00195;
state.audioVisGroup.opponentVis.realtimeVisLenght = Conductor.instance.getStepTimeInMs(16) * 0.00195;
state.audioVisGroup.opponentVis.daHeight = (ChartEditorState.GRID_SIZE) * 16;
state.audioVisGroup.opponentVis.detail = 1;
@@ -684,8 +684,8 @@ class ChartEditorDialogHandler
state.songMetadata.set(targetVariation, newSongMetadata);
Conductor.instrumentalOffset = state.currentInstrumentalOffset; // Loads from the metadata.
Conductor.mapTimeChanges(state.currentSongMetadata.timeChanges);
Conductor.instance.instrumentalOffset = state.currentInstrumentalOffset; // Loads from the metadata.
Conductor.instance.mapTimeChanges(state.currentSongMetadata.timeChanges);
state.selectedVariation = Constants.DEFAULT_VARIATION;
state.selectedDifficulty = state.availableDifficulties[0];
@@ -43,7 +43,8 @@ class ChartEditorImportExportHandler
var variation = (metadata.variation == null || metadata.variation == '') ? Constants.DEFAULT_VARIATION : metadata.variation;
// Clone to prevent modifying the original.
var metadataClone:SongMetadata = metadata.clone(variation);
var metadataClone:SongMetadata = metadata.clone();
metadataClone.variation = variation;
if (metadataClone != null) songMetadata.set(variation, metadataClone);
var chartData:Null<SongChartData> = SongRegistry.instance.parseEntryChartData(songId, metadata.variation);
@@ -114,9 +115,9 @@ class ChartEditorImportExportHandler
state.songMetadata = newSongMetadata;
state.songChartData = newSongChartData;
Conductor.forceBPM(null); // Disable the forced BPM.
Conductor.instrumentalOffset = state.currentInstrumentalOffset; // Loads from the metadata.
Conductor.mapTimeChanges(state.currentSongMetadata.timeChanges);
Conductor.instance.forceBPM(null); // Disable the forced BPM.
Conductor.instance.instrumentalOffset = state.currentInstrumentalOffset; // Loads from the metadata.
Conductor.instance.mapTimeChanges(state.currentSongMetadata.timeChanges);
state.notePreviewDirty = true;
state.notePreviewViewportBoundsDirty = true;
@@ -415,16 +416,34 @@ class ChartEditorImportExportHandler
]);
// We have to force write because the program will die before the save dialog is closed.
trace('Force exporting to $targetPath...');
FileUtil.saveFilesAsZIPToPath(zipEntries, targetPath, targetMode);
if (onSaveCb != null) onSaveCb(targetPath);
try
{
FileUtil.saveFilesAsZIPToPath(zipEntries, targetPath, targetMode);
// On success.
if (onSaveCb != null) onSaveCb(targetPath);
}
catch (e)
{
// On failure.
if (onCancelCb != null) onCancelCb();
}
}
else
{
// Force write since we know what file the user wants to overwrite.
trace('Force exporting to $targetPath...');
FileUtil.saveFilesAsZIPToPath(zipEntries, targetPath, targetMode);
state.saveDataDirty = false;
if (onSaveCb != null) onSaveCb(targetPath);
try
{
// On success.
FileUtil.saveFilesAsZIPToPath(zipEntries, targetPath, targetMode);
state.saveDataDirty = false;
if (onSaveCb != null) onSaveCb(targetPath);
}
catch (e)
{
// On failure.
if (onCancelCb != null) onCancelCb();
}
}
}
else
@@ -125,7 +125,7 @@ class ChartEditorThemeHandler
// 2 * (Strumline Size) + 1 grid squares wide, by (4 * quarter notes per measure) grid squares tall.
// This gets reused to fill the screen.
var gridWidth:Int = Std.int(ChartEditorState.GRID_SIZE * TOTAL_COLUMN_COUNT);
var gridHeight:Int = Std.int(ChartEditorState.GRID_SIZE * Conductor.stepsPerMeasure);
var gridHeight:Int = Std.int(ChartEditorState.GRID_SIZE * Conductor.instance.stepsPerMeasure);
state.gridBitmap = FlxGridOverlay.createGrid(ChartEditorState.GRID_SIZE, ChartEditorState.GRID_SIZE, gridWidth, gridHeight, true, gridColor1, gridColor2);
// Selection borders
@@ -142,7 +142,7 @@ class ChartEditorThemeHandler
selectionBorderColor);
// Selection borders horizontally along the middle.
for (i in 1...(Conductor.stepsPerMeasure))
for (i in 1...(Conductor.instance.stepsPerMeasure))
{
state.gridBitmap.fillRect(new Rectangle(0, (ChartEditorState.GRID_SIZE * i) - (ChartEditorState.GRID_SELECTION_BORDER_WIDTH / 2),
state.gridBitmap.width, ChartEditorState.GRID_SELECTION_BORDER_WIDTH),
@@ -197,9 +197,9 @@ class ChartEditorThemeHandler
};
// Selection borders horizontally in the middle.
for (i in 1...(Conductor.stepsPerMeasure))
for (i in 1...(Conductor.instance.stepsPerMeasure))
{
if ((i % Conductor.beatsPerMeasure) == 0)
if ((i % Conductor.instance.beatsPerMeasure) == 0)
{
state.gridBitmap.fillRect(new Rectangle(0, (ChartEditorState.GRID_SIZE * i) - (GRID_BEAT_DIVIDER_WIDTH / 2), state.gridBitmap.width,
GRID_BEAT_DIVIDER_WIDTH),
@@ -120,9 +120,9 @@ class ChartEditorMetadataToolbox extends ChartEditorBaseToolbox
if (event.value == null) return;
chartEditorState.currentInstrumentalOffset = event.value;
Conductor.instrumentalOffset = event.value;
Conductor.instance.instrumentalOffset = event.value;
// Update song length.
chartEditorState.songLengthInMs = (chartEditorState.audioInstTrack?.length ?? 1000.0) + Conductor.instrumentalOffset;
chartEditorState.songLengthInMs = (chartEditorState.audioInstTrack?.length ?? 1000.0) + Conductor.instance.instrumentalOffset;
};
inputOffsetVocal.onChange = function(event:UIEvent) {
+29 -29
View File
@@ -75,7 +75,7 @@ class LatencyState extends MusicBeatSubState
// funnyStatsGraph.hi
Conductor.forceBPM(60);
Conductor.instance.forceBPM(60);
noteGrp = new FlxTypedGroup<NoteSprite>();
add(noteGrp);
@@ -91,14 +91,14 @@ class LatencyState extends MusicBeatSubState
// // musSpec.visType = FREQUENCIES;
// add(musSpec);
for (beat in 0...Math.floor(FlxG.sound.music.length / Conductor.beatLengthMs))
for (beat in 0...Math.floor(FlxG.sound.music.length / Conductor.instance.beatLengthMs))
{
var beatTick:FlxSprite = new FlxSprite(songPosToX(beat * Conductor.beatLengthMs), FlxG.height - 15);
var beatTick:FlxSprite = new FlxSprite(songPosToX(beat * Conductor.instance.beatLengthMs), FlxG.height - 15);
beatTick.makeGraphic(2, 15);
beatTick.alpha = 0.3;
add(beatTick);
var offsetTxt:FlxText = new FlxText(songPosToX(beat * Conductor.beatLengthMs), FlxG.height - 26, 0, "swag");
var offsetTxt:FlxText = new FlxText(songPosToX(beat * Conductor.instance.beatLengthMs), FlxG.height - 26, 0, "swag");
offsetTxt.alpha = 0.5;
diffGrp.add(offsetTxt);
@@ -130,7 +130,7 @@ class LatencyState extends MusicBeatSubState
for (i in 0...32)
{
var note:NoteSprite = new NoteSprite(NoteStyleRegistry.instance.fetchDefault(), Conductor.beatLengthMs * i);
var note:NoteSprite = new NoteSprite(NoteStyleRegistry.instance.fetchDefault(), Conductor.instance.beatLengthMs * i);
noteGrp.add(note);
}
@@ -146,9 +146,9 @@ class LatencyState extends MusicBeatSubState
override function stepHit():Bool
{
if (Conductor.currentStep % 4 == 2)
if (Conductor.instance.currentStep % 4 == 2)
{
blocks.members[((Conductor.currentBeat % 8) + 1) % 8].alpha = 0.5;
blocks.members[((Conductor.instance.currentBeat % 8) + 1) % 8].alpha = 0.5;
}
return super.stepHit();
@@ -156,11 +156,11 @@ class LatencyState extends MusicBeatSubState
override function beatHit():Bool
{
if (Conductor.currentBeat % 8 == 0) blocks.forEach(blok -> {
if (Conductor.instance.currentBeat % 8 == 0) blocks.forEach(blok -> {
blok.alpha = 0;
});
blocks.members[Conductor.currentBeat % 8].alpha = 1;
blocks.members[Conductor.instance.currentBeat % 8].alpha = 1;
// block.visible = !block.visible;
return super.beatHit();
@@ -192,17 +192,17 @@ class LatencyState extends MusicBeatSubState
if (FlxG.keys.pressed.D) FlxG.sound.music.time += 1000 * FlxG.elapsed;
Conductor.update(swagSong.getTimeWithDiff() - Conductor.inputOffset);
// Conductor.songPosition += (Timer.stamp() * 1000) - FlxG.sound.music.prevTimestamp;
Conductor.instance.update(swagSong.getTimeWithDiff() - Conductor.instance.inputOffset);
// Conductor.instance.songPosition += (Timer.stamp() * 1000) - FlxG.sound.music.prevTimestamp;
songPosVis.x = songPosToX(Conductor.songPosition);
songVisFollowAudio.x = songPosToX(Conductor.songPosition - Conductor.instrumentalOffset);
songVisFollowVideo.x = songPosToX(Conductor.songPosition - Conductor.inputOffset);
songPosVis.x = songPosToX(Conductor.instance.songPosition);
songVisFollowAudio.x = songPosToX(Conductor.instance.songPosition - Conductor.instance.instrumentalOffset);
songVisFollowVideo.x = songPosToX(Conductor.instance.songPosition - Conductor.instance.inputOffset);
offsetText.text = "INST Offset: " + Conductor.instrumentalOffset + "ms";
offsetText.text += "\nINPUT Offset: " + Conductor.inputOffset + "ms";
offsetText.text += "\ncurrentStep: " + Conductor.currentStep;
offsetText.text += "\ncurrentBeat: " + Conductor.currentBeat;
offsetText.text = "INST Offset: " + Conductor.instance.instrumentalOffset + "ms";
offsetText.text += "\nINPUT Offset: " + Conductor.instance.inputOffset + "ms";
offsetText.text += "\ncurrentStep: " + Conductor.instance.currentStep;
offsetText.text += "\ncurrentBeat: " + Conductor.instance.currentBeat;
var avgOffsetInput:Float = 0;
@@ -221,24 +221,24 @@ class LatencyState extends MusicBeatSubState
{
if (FlxG.keys.justPressed.RIGHT)
{
Conductor.instrumentalOffset += 1.0 * multiply;
Conductor.instance.instrumentalOffset += 1.0 * multiply;
}
if (FlxG.keys.justPressed.LEFT)
{
Conductor.instrumentalOffset -= 1.0 * multiply;
Conductor.instance.instrumentalOffset -= 1.0 * multiply;
}
}
else
{
if (FlxG.keys.justPressed.RIGHT)
{
Conductor.inputOffset += 1.0 * multiply;
Conductor.instance.inputOffset += 1.0 * multiply;
}
if (FlxG.keys.justPressed.LEFT)
{
Conductor.inputOffset -= 1.0 * multiply;
Conductor.instance.inputOffset -= 1.0 * multiply;
}
}
@@ -250,7 +250,7 @@ class LatencyState extends MusicBeatSubState
}*/
noteGrp.forEach(function(daNote:NoteSprite) {
daNote.y = (strumLine.y - ((Conductor.songPosition - Conductor.instrumentalOffset) - daNote.noteData.time) * 0.45);
daNote.y = (strumLine.y - ((Conductor.instance.songPosition - Conductor.instance.instrumentalOffset) - daNote.noteData.time) * 0.45);
daNote.x = strumLine.x + 30;
if (daNote.y < strumLine.y) daNote.alpha = 0.5;
@@ -258,7 +258,7 @@ class LatencyState extends MusicBeatSubState
if (daNote.y < 0 - daNote.height)
{
daNote.alpha = 1;
// daNote.data.strumTime += Conductor.beatLengthMs * 8;
// daNote.data.strumTime += Conductor.instance.beatLengthMs * 8;
}
});
@@ -267,14 +267,14 @@ class LatencyState extends MusicBeatSubState
function generateBeatStuff()
{
Conductor.update(swagSong.getTimeWithDiff());
Conductor.instance.update(swagSong.getTimeWithDiff());
var closestBeat:Int = Math.round(Conductor.songPosition / Conductor.beatLengthMs) % diffGrp.members.length;
var getDiff:Float = Conductor.songPosition - (closestBeat * Conductor.beatLengthMs);
getDiff -= Conductor.inputOffset;
var closestBeat:Int = Math.round(Conductor.instance.songPosition / Conductor.instance.beatLengthMs) % diffGrp.members.length;
var getDiff:Float = Conductor.instance.songPosition - (closestBeat * Conductor.instance.beatLengthMs);
getDiff -= Conductor.instance.inputOffset;
// lil fix for end of song
if (closestBeat == 0 && getDiff >= Conductor.beatLengthMs * 2) getDiff -= FlxG.sound.music.length;
if (closestBeat == 0 && getDiff >= Conductor.instance.beatLengthMs * 2) getDiff -= FlxG.sound.music.length;
trace("\tDISTANCE TO CLOSEST BEAT: " + getDiff + "ms");
trace("\tCLOSEST BEAT: " + closestBeat);