mirror of
https://github.com/ninjamuffin99/Funkin.git
synced 2025-05-21 22:53:13 +00:00
Chart wizard plus shader fixes
This commit is contained in:
parent
fbf92acf23
commit
19b2f3799a
4
hmm.json
4
hmm.json
|
@ -11,14 +11,14 @@
|
||||||
"name": "flixel",
|
"name": "flixel",
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"dir": null,
|
"dir": null,
|
||||||
"ref": "6728df7",
|
"ref": "8ff2aa9",
|
||||||
"url": "https://github.com/MasterEric/flixel"
|
"url": "https://github.com/MasterEric/flixel"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "flixel-addons",
|
"name": "flixel-addons",
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"dir": null,
|
"dir": null,
|
||||||
"ref": "a3877f0",
|
"ref": "157eaf3",
|
||||||
"url": "https://github.com/MasterEric/flixel-addons"
|
"url": "https://github.com/MasterEric/flixel-addons"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -129,6 +129,7 @@ class Conductor
|
||||||
*/
|
*/
|
||||||
public static function forceBPM(bpm:Float)
|
public static function forceBPM(bpm:Float)
|
||||||
{
|
{
|
||||||
|
trace('[CONDUCTOR] Forcing BPM to ' + bpm);
|
||||||
Conductor.bpmOverride = bpm;
|
Conductor.bpmOverride = bpm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,10 +214,8 @@ class Conductor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function mapTimeChanges(currentChart:SongDifficulty)
|
public static function mapTimeChanges(songTimeChanges:Array<SongTimeChange>)
|
||||||
{
|
{
|
||||||
var songTimeChanges:Array<SongTimeChange> = currentChart.timeChanges;
|
|
||||||
|
|
||||||
timeChanges = [];
|
timeChanges = [];
|
||||||
|
|
||||||
for (currentTimeChange in songTimeChanges)
|
for (currentTimeChange in songTimeChanges)
|
||||||
|
|
|
@ -7,30 +7,38 @@ import flixel.system.FlxSound;
|
||||||
// when needed
|
// when needed
|
||||||
class VoicesGroup extends FlxTypedGroup<FlxSound>
|
class VoicesGroup extends FlxTypedGroup<FlxSound>
|
||||||
{
|
{
|
||||||
public var time(default, set):Float = 0;
|
public var time(get, set):Float;
|
||||||
|
|
||||||
public var volume(default, set):Float = 1;
|
public var volume(get, set):Float;
|
||||||
|
|
||||||
public var pitch(default, set):Float = 1;
|
public var pitch(get, set):Float;
|
||||||
|
|
||||||
// make it a group that you add to?
|
// make it a group that you add to?
|
||||||
public function new(song:String, ?files:Array<String> = null)
|
public function new()
|
||||||
{
|
{
|
||||||
super();
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Remove this.
|
||||||
|
public static function build(song:String, ?files:Array<String> = null):VoicesGroup
|
||||||
|
{
|
||||||
|
var result = new VoicesGroup();
|
||||||
|
|
||||||
if (files == null)
|
if (files == null)
|
||||||
{
|
{
|
||||||
// Add an empty voice.
|
// Add an empty voice.
|
||||||
add(new FlxSound());
|
result.add(new FlxSound());
|
||||||
return;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (sndFile in files)
|
for (sndFile in files)
|
||||||
{
|
{
|
||||||
var snd:FlxSound = new FlxSound().loadEmbedded(Paths.voices(song, '$sndFile'));
|
var snd:FlxSound = new FlxSound().loadEmbedded(Paths.voices(song, '$sndFile'));
|
||||||
FlxG.sound.list.add(snd); // adds it to sound group for proper volumes
|
FlxG.sound.list.add(snd); // adds it to sound group for proper volumes
|
||||||
add(snd); // adds it to main group for other shit
|
result.add(snd); // adds it to main group for other shit
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -83,6 +91,14 @@ class VoicesGroup extends FlxTypedGroup<FlxSound>
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function get_time():Float
|
||||||
|
{
|
||||||
|
if (getFirstAlive() != null)
|
||||||
|
return getFirstAlive().time;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
function set_time(time:Float):Float
|
function set_time(time:Float):Float
|
||||||
{
|
{
|
||||||
forEachAlive(function(snd)
|
forEachAlive(function(snd)
|
||||||
|
@ -94,6 +110,14 @@ class VoicesGroup extends FlxTypedGroup<FlxSound>
|
||||||
return time;
|
return time;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function get_volume():Float
|
||||||
|
{
|
||||||
|
if (getFirstAlive() != null)
|
||||||
|
return getFirstAlive().volume;
|
||||||
|
else
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
// in PlayState, adjust the code so that it only mutes the player1 vocal tracks?
|
// in PlayState, adjust the code so that it only mutes the player1 vocal tracks?
|
||||||
function set_volume(volume:Float):Float
|
function set_volume(volume:Float):Float
|
||||||
{
|
{
|
||||||
|
@ -105,9 +129,20 @@ class VoicesGroup extends FlxTypedGroup<FlxSound>
|
||||||
return volume;
|
return volume;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function get_pitch():Float
|
||||||
|
{
|
||||||
|
#if FLX_PITCH
|
||||||
|
if (getFirstAlive() != null)
|
||||||
|
return getFirstAlive().pitch;
|
||||||
|
else
|
||||||
|
#end
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
function set_pitch(val:Float):Float
|
function set_pitch(val:Float):Float
|
||||||
{
|
{
|
||||||
#if HAS_PITCH
|
#if FLX_PITCH
|
||||||
|
trace('Setting audio pitch to ' + val);
|
||||||
forEachAlive(function(snd)
|
forEachAlive(function(snd)
|
||||||
{
|
{
|
||||||
snd.pitch = val;
|
snd.pitch = val;
|
||||||
|
|
|
@ -445,7 +445,7 @@ class ChartingState extends MusicBeatState
|
||||||
add(playheadTest);
|
add(playheadTest);
|
||||||
|
|
||||||
// WONT WORK FOR TUTORIAL OR TEST SONG!!! REDO LATER
|
// WONT WORK FOR TUTORIAL OR TEST SONG!!! REDO LATER
|
||||||
vocals = new VoicesGroup(daSong, _song.voiceList);
|
vocals = VoicesGroup.build(daSong, _song.voiceList);
|
||||||
// vocals = new FlxSound().loadEmbedded(Paths.voices(daSong));
|
// vocals = new FlxSound().loadEmbedded(Paths.voices(daSong));
|
||||||
// FlxG.sound.list.add(vocals);
|
// FlxG.sound.list.add(vocals);
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@ class Cursor
|
||||||
static final CURSOR_GRABBING_PARAMS:CursorParams = {
|
static final CURSOR_GRABBING_PARAMS:CursorParams = {
|
||||||
graphic: "assets/images/cursor/cursor-grabbing.png",
|
graphic: "assets/images/cursor/cursor-grabbing.png",
|
||||||
scale: 1.0,
|
scale: 1.0,
|
||||||
offsetX: 8,
|
offsetX: 32,
|
||||||
offsetY: 0,
|
offsetY: 0,
|
||||||
};
|
};
|
||||||
static var assetCursorGrabbing:BitmapData = null;
|
static var assetCursorGrabbing:BitmapData = null;
|
||||||
|
|
|
@ -354,7 +354,7 @@ class PlayState extends MusicBeatState
|
||||||
|
|
||||||
if (currentSong_NEW != null)
|
if (currentSong_NEW != null)
|
||||||
{
|
{
|
||||||
Conductor.mapTimeChanges(currentChart);
|
Conductor.mapTimeChanges(currentChart.timeChanges);
|
||||||
// Conductor.bpm = currentChart.getStartingBPM();
|
// Conductor.bpm = currentChart.getStartingBPM();
|
||||||
|
|
||||||
// TODO: Support for dialog.
|
// TODO: Support for dialog.
|
||||||
|
@ -1029,9 +1029,9 @@ class PlayState extends MusicBeatState
|
||||||
currentSong.song = currentSong.song;
|
currentSong.song = currentSong.song;
|
||||||
|
|
||||||
if (currentSong.needsVoices)
|
if (currentSong.needsVoices)
|
||||||
vocals = new VoicesGroup(currentSong.song, currentSong.voiceList);
|
vocals = VoicesGroup.build(currentSong.song, currentSong.voiceList);
|
||||||
else
|
else
|
||||||
vocals = new VoicesGroup(currentSong.song, null);
|
vocals = VoicesGroup.build(currentSong.song, null);
|
||||||
|
|
||||||
vocals.members[0].onComplete = function()
|
vocals.members[0].onComplete = function()
|
||||||
{
|
{
|
||||||
|
|
|
@ -45,6 +45,11 @@ class Song // implements IPlayStateScriptedClass
|
||||||
populateFromMetadata();
|
populateFromMetadata();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getRawMetadata():Array<SongMetadata>
|
||||||
|
{
|
||||||
|
return _metadata;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Populate the song data from the provided metadata,
|
* Populate the song data from the provided metadata,
|
||||||
* including data from individual difficulties. Does not load chart data.
|
* including data from individual difficulties. Does not load chart data.
|
||||||
|
@ -246,7 +251,7 @@ class SongDifficulty
|
||||||
|
|
||||||
public function buildVocals(charId:String = "bf"):VoicesGroup
|
public function buildVocals(charId:String = "bf"):VoicesGroup
|
||||||
{
|
{
|
||||||
var result:VoicesGroup = new VoicesGroup(this.song.songId, this.buildVoiceList());
|
var result:VoicesGroup = VoicesGroup.build(this.song.songId, this.buildVoiceList());
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,12 +96,12 @@ class SongDataParser
|
||||||
if (songCache.exists(songId))
|
if (songCache.exists(songId))
|
||||||
{
|
{
|
||||||
var song:Song = songCache.get(songId);
|
var song:Song = songCache.get(songId);
|
||||||
trace('[STAGEDATA] Successfully fetch song: ${songId}');
|
trace('[SONGDATA] Successfully fetch song: ${songId}');
|
||||||
return song;
|
return song;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
trace('[STAGEDATA] Failed to fetch song, not found in cache: ${songId}');
|
trace('[SONGDATA] Failed to fetch song, not found in cache: ${songId}');
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -110,6 +110,25 @@ class ChartEditorDialogHandler
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Get the list of songs and insert them as links into the "Create From Song" section.
|
// TODO: Get the list of songs and insert them as links into the "Create From Song" section.
|
||||||
|
var linkTemplateDadBattle:Link = dialog.findComponent('splashTemplateDadBattle', Link);
|
||||||
|
linkTemplateDadBattle.onClick = (_event) ->
|
||||||
|
{
|
||||||
|
dialog.hideDialog(DialogButton.CANCEL);
|
||||||
|
|
||||||
|
// Load song from template
|
||||||
|
state.loadSongAsTemplate('dadbattle');
|
||||||
|
}
|
||||||
|
var linkTemplateBopeebo:Link = dialog.findComponent('splashTemplateBopeebo', Link);
|
||||||
|
linkTemplateBopeebo.onClick = (_event) ->
|
||||||
|
{
|
||||||
|
dialog.hideDialog(DialogButton.CANCEL);
|
||||||
|
|
||||||
|
// Load song from template
|
||||||
|
state.loadSongAsTemplate('bopeebo');
|
||||||
|
}
|
||||||
|
|
||||||
|
var splashTemplateContainer:VBox = dialog.findComponent('splashTemplateContainer', VBox);
|
||||||
|
|
||||||
return dialog;
|
return dialog;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -237,7 +256,7 @@ class ChartEditorDialogHandler
|
||||||
var dialogBPM:NumberStepper = dialog.findComponent('dialogBPM', NumberStepper);
|
var dialogBPM:NumberStepper = dialog.findComponent('dialogBPM', NumberStepper);
|
||||||
dialogBPM.onChange = (event:UIEvent) ->
|
dialogBPM.onChange = (event:UIEvent) ->
|
||||||
{
|
{
|
||||||
if (event.value == null)
|
if (event.value == null || event.value <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var timeChanges = state.currentSongMetadata.timeChanges;
|
var timeChanges = state.currentSongMetadata.timeChanges;
|
||||||
|
@ -249,6 +268,9 @@ class ChartEditorDialogHandler
|
||||||
{
|
{
|
||||||
timeChanges[0].bpm = event.value;
|
timeChanges[0].bpm = event.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Conductor.forceBPM(event.value);
|
||||||
|
|
||||||
state.currentSongMetadata.timeChanges = timeChanges;
|
state.currentSongMetadata.timeChanges = timeChanges;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -388,9 +410,9 @@ class ChartEditorDialogHandler
|
||||||
{
|
{
|
||||||
if (selectedFile != null)
|
if (selectedFile != null)
|
||||||
{
|
{
|
||||||
trace('Selected file: ' + selectedFile);
|
trace('Selected file: ' + selectedFile.name + "~" + selectedFile.fullPath);
|
||||||
vocalsEntryLabel.text = 'Vocals for $charName (click to browse)\n$selectedFile';
|
vocalsEntryLabel.text = 'Vocals for $charName (click to browse)\n${selectedFile.name}';
|
||||||
// state.loadVocalsFromBytes(selectedFile.bytes);
|
state.loadVocalsFromBytes(selectedFile.bytes);
|
||||||
removeDropHandler(onDropFile);
|
removeDropHandler(onDropFile);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package funkin.ui.debug.charting;
|
package funkin.ui.debug.charting;
|
||||||
|
|
||||||
|
import funkin.play.song.SongData.SongDataParser;
|
||||||
|
import funkin.play.song.Song;
|
||||||
import lime.media.AudioBuffer;
|
import lime.media.AudioBuffer;
|
||||||
import funkin.input.Cursor;
|
import funkin.input.Cursor;
|
||||||
import flixel.FlxSprite;
|
import flixel.FlxSprite;
|
||||||
|
@ -433,7 +435,7 @@ class ChartEditorState extends HaxeUIState
|
||||||
* The audio track for the vocals.
|
* The audio track for the vocals.
|
||||||
* TODO: Replace with a VocalSoundGroup.
|
* TODO: Replace with a VocalSoundGroup.
|
||||||
*/
|
*/
|
||||||
var audioVocalTrack:FlxSound;
|
var audioVocalTrackGroup:VoicesGroup;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CHART DATA
|
* CHART DATA
|
||||||
|
@ -758,7 +760,9 @@ class ChartEditorState extends HaxeUIState
|
||||||
// TODO: We should be loading the music later when the user requests it.
|
// TODO: We should be loading the music later when the user requests it.
|
||||||
// loadDefaultMusic();
|
// loadDefaultMusic();
|
||||||
|
|
||||||
ChartEditorDialogHandler.openWelcomeDialog(this, false);
|
// TODO: Change to false.
|
||||||
|
var canCloseInitialDialog = true;
|
||||||
|
ChartEditorDialogHandler.openWelcomeDialog(this, canCloseInitialDialog);
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildDefaultSongData()
|
function buildDefaultSongData()
|
||||||
|
@ -771,6 +775,8 @@ class ChartEditorState extends HaxeUIState
|
||||||
|
|
||||||
// Initialize the song chart data.
|
// Initialize the song chart data.
|
||||||
songChartData = new Map<String, SongChartData>();
|
songChartData = new Map<String, SongChartData>();
|
||||||
|
|
||||||
|
audioVocalTrackGroup = new VoicesGroup();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -933,7 +939,7 @@ class ChartEditorState extends HaxeUIState
|
||||||
playbarHeadDragging = true;
|
playbarHeadDragging = true;
|
||||||
|
|
||||||
// If we were dragging the playhead while the song was playing, resume playing.
|
// If we were dragging the playhead while the song was playing, resume playing.
|
||||||
if (audioVocalTrack.playing)
|
if (audioInstTrack != null && audioInstTrack.playing)
|
||||||
{
|
{
|
||||||
playbarHeadDraggingWasPlaying = true;
|
playbarHeadDraggingWasPlaying = true;
|
||||||
stopAudioPlayback();
|
stopAudioPlayback();
|
||||||
|
@ -1057,16 +1063,35 @@ class ChartEditorState extends HaxeUIState
|
||||||
});
|
});
|
||||||
setUISelected('menubarItemMetronomeEnabled', shouldPlayMetronome);
|
setUISelected('menubarItemMetronomeEnabled', shouldPlayMetronome);
|
||||||
|
|
||||||
|
var instVolumeLabel:Label = findComponent('menubarLabelVolumeInstrumental', Label);
|
||||||
addUIChangeListener('menubarItemVolumeInstrumental', (event:UIEvent) ->
|
addUIChangeListener('menubarItemVolumeInstrumental', (event:UIEvent) ->
|
||||||
{
|
{
|
||||||
var volume:Float = event.value / 100.0;
|
var volume:Float = event.value / 100.0;
|
||||||
audioInstTrack.volume = volume;
|
if (audioInstTrack != null)
|
||||||
|
audioInstTrack.volume = volume;
|
||||||
|
instVolumeLabel.text = 'Instrumental - ${event.value}%';
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var vocalsVolumeLabel:Label = findComponent('menubarLabelVolumeVocals', Label);
|
||||||
addUIChangeListener('menubarItemVolumeVocals', (event:UIEvent) ->
|
addUIChangeListener('menubarItemVolumeVocals', (event:UIEvent) ->
|
||||||
{
|
{
|
||||||
var volume:Float = event.value / 100.0;
|
var volume:Float = event.value / 100.0;
|
||||||
audioVocalTrack.volume = volume;
|
if (audioVocalTrackGroup != null)
|
||||||
|
audioVocalTrackGroup.volume = volume;
|
||||||
|
vocalsVolumeLabel.text = 'Vocals - ${event.value}%';
|
||||||
|
});
|
||||||
|
|
||||||
|
var playbackSpeedLabel:Label = findComponent('menubarLabelPlaybackSpeed', Label);
|
||||||
|
addUIChangeListener('menubarItemPlaybackSpeed', (event:UIEvent) ->
|
||||||
|
{
|
||||||
|
var pitch = event.value * 2.0 / 100.0;
|
||||||
|
#if FLX_PITCH
|
||||||
|
if (audioInstTrack != null)
|
||||||
|
audioInstTrack.pitch = pitch;
|
||||||
|
if (audioVocalTrackGroup != null)
|
||||||
|
audioVocalTrackGroup.pitch = pitch;
|
||||||
|
#end
|
||||||
|
playbackSpeedLabel.text = 'Playback Speed - ${pitch}x';
|
||||||
});
|
});
|
||||||
|
|
||||||
addUIChangeListener('menubarItemToggleToolboxTools', (event:UIEvent) ->
|
addUIChangeListener('menubarItemToggleToolboxTools', (event:UIEvent) ->
|
||||||
|
@ -2242,8 +2267,8 @@ class ChartEditorState extends HaxeUIState
|
||||||
var oldStepTime = Conductor.currentStepTime;
|
var oldStepTime = Conductor.currentStepTime;
|
||||||
Conductor.update(audioInstTrack.time);
|
Conductor.update(audioInstTrack.time);
|
||||||
// Resync vocals.
|
// Resync vocals.
|
||||||
if (Math.abs(audioInstTrack.time - audioVocalTrack.time) > 100)
|
if (Math.abs(audioInstTrack.time - audioVocalTrackGroup.time) > 100)
|
||||||
audioVocalTrack.time = audioInstTrack.time;
|
audioVocalTrackGroup.time = audioInstTrack.time;
|
||||||
var diffStepTime = Conductor.currentStepTime - oldStepTime;
|
var diffStepTime = Conductor.currentStepTime - oldStepTime;
|
||||||
|
|
||||||
// Move the playhead.
|
// Move the playhead.
|
||||||
|
@ -2257,8 +2282,8 @@ class ChartEditorState extends HaxeUIState
|
||||||
|
|
||||||
Conductor.update(audioInstTrack.time);
|
Conductor.update(audioInstTrack.time);
|
||||||
// Resync vocals.
|
// Resync vocals.
|
||||||
if (audioVocalTrack != null && Math.abs(audioInstTrack.time - audioVocalTrack.time) > 100)
|
if (audioVocalTrackGroup != null && Math.abs(audioInstTrack.time - audioVocalTrackGroup.time) > 100)
|
||||||
audioVocalTrack.time = audioInstTrack.time;
|
audioVocalTrackGroup.time = audioInstTrack.time;
|
||||||
|
|
||||||
// We need time in fractional steps here to allow the song to actually play.
|
// We need time in fractional steps here to allow the song to actually play.
|
||||||
// Also account for a potentially offset playhead.
|
// Also account for a potentially offset playhead.
|
||||||
|
@ -2281,16 +2306,20 @@ class ChartEditorState extends HaxeUIState
|
||||||
{
|
{
|
||||||
if (audioInstTrack != null)
|
if (audioInstTrack != null)
|
||||||
audioInstTrack.play();
|
audioInstTrack.play();
|
||||||
if (audioVocalTrack != null)
|
if (audioVocalTrackGroup != null)
|
||||||
audioVocalTrack.play();
|
audioVocalTrackGroup.play();
|
||||||
|
if (audioVocalTrackGroup != null)
|
||||||
|
audioVocalTrackGroup.play();
|
||||||
}
|
}
|
||||||
|
|
||||||
function stopAudioPlayback()
|
function stopAudioPlayback()
|
||||||
{
|
{
|
||||||
if (audioInstTrack != null)
|
if (audioInstTrack != null)
|
||||||
audioInstTrack.pause();
|
audioInstTrack.pause();
|
||||||
if (audioVocalTrack != null)
|
if (audioVocalTrackGroup != null)
|
||||||
audioVocalTrack.pause();
|
audioVocalTrackGroup.pause();
|
||||||
|
if (audioVocalTrackGroup != null)
|
||||||
|
audioVocalTrackGroup.pause();
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleAudioPlayback()
|
function toggleAudioPlayback()
|
||||||
|
@ -2418,8 +2447,12 @@ class ChartEditorState extends HaxeUIState
|
||||||
*/
|
*/
|
||||||
public function loadInstrumentalFromPath(path:String):Void
|
public function loadInstrumentalFromPath(path:String):Void
|
||||||
{
|
{
|
||||||
|
#if sys
|
||||||
var fileBytes:haxe.io.Bytes = sys.io.File.getBytes(path);
|
var fileBytes:haxe.io.Bytes = sys.io.File.getBytes(path);
|
||||||
loadInstrumentalFromBytes(fileBytes);
|
loadInstrumentalFromBytes(fileBytes);
|
||||||
|
#else
|
||||||
|
trace("[WARN] This platform can't load audio from a file path, you'll need to fetch the bytes some other way.");
|
||||||
|
#end
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2440,6 +2473,14 @@ class ChartEditorState extends HaxeUIState
|
||||||
postLoadInstrumental();
|
postLoadInstrumental();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function loadInstrumentalFromAsset(path:String):Void
|
||||||
|
{
|
||||||
|
var vocalTrack = FlxG.sound.load(path, 1.0, false);
|
||||||
|
audioInstTrack = vocalTrack;
|
||||||
|
|
||||||
|
postLoadInstrumental();
|
||||||
|
}
|
||||||
|
|
||||||
function postLoadInstrumental()
|
function postLoadInstrumental()
|
||||||
{
|
{
|
||||||
// Prevent the time from skipping back to 0 when the song ends.
|
// Prevent the time from skipping back to 0 when the song ends.
|
||||||
|
@ -2447,14 +2488,10 @@ class ChartEditorState extends HaxeUIState
|
||||||
{
|
{
|
||||||
if (audioInstTrack != null)
|
if (audioInstTrack != null)
|
||||||
audioInstTrack.pause();
|
audioInstTrack.pause();
|
||||||
if (audioVocalTrack != null)
|
if (audioVocalTrackGroup != null)
|
||||||
audioVocalTrack.pause();
|
audioVocalTrackGroup.pause();
|
||||||
};
|
};
|
||||||
|
|
||||||
var DAD_BATTLE_BPM = 180;
|
|
||||||
var BOPEEBO_BPM = 100;
|
|
||||||
Conductor.forceBPM(DAD_BATTLE_BPM);
|
|
||||||
|
|
||||||
songLength = Std.int(Conductor.getTimeInSteps(audioInstTrack.length) * GRID_SIZE);
|
songLength = Std.int(Conductor.getTimeInSteps(audioInstTrack.length) * GRID_SIZE);
|
||||||
|
|
||||||
gridTiledSprite.height = songLength;
|
gridTiledSprite.height = songLength;
|
||||||
|
@ -2470,20 +2507,79 @@ class ChartEditorState extends HaxeUIState
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load a music track for playback.
|
* Loads a vocal track from an absolute file path.
|
||||||
*/
|
*/
|
||||||
function loadDefaultMusic()
|
public function loadVocalsFromPath(path:String):Void
|
||||||
{
|
{
|
||||||
// TODO: How to load music by selecting with a file dialog?
|
#if sys
|
||||||
audioInstTrack = FlxG.sound.play(Paths.inst('dadbattle'), 1.0, false);
|
var fileBytes:haxe.io.Bytes = sys.io.File.getBytes(path);
|
||||||
audioInstTrack.autoDestroy = false;
|
loadVocalsFromBytes(fileBytes);
|
||||||
audioInstTrack.pause();
|
#else
|
||||||
|
trace("[WARN] This platform can't load audio from a file path, you'll need to fetch the bytes some other way.");
|
||||||
|
#end
|
||||||
|
}
|
||||||
|
|
||||||
audioVocalTrack = FlxG.sound.play(Paths.voices('dadbattle'), 1.0, false);
|
public function loadVocalsFromAsset(path:String):Void
|
||||||
audioVocalTrack.autoDestroy = false;
|
{
|
||||||
audioVocalTrack.pause();
|
var vocalTrack = FlxG.sound.load(path, 1.0, false);
|
||||||
|
audioVocalTrackGroup.add(vocalTrack);
|
||||||
|
}
|
||||||
|
|
||||||
postLoadInstrumental();
|
/**
|
||||||
|
* Loads a vocal track from audio byte data.
|
||||||
|
*/
|
||||||
|
public function loadVocalsFromBytes(bytes:haxe.io.Bytes):Void
|
||||||
|
{
|
||||||
|
var openflSound = new openfl.media.Sound();
|
||||||
|
openflSound.loadCompressedDataFromByteArray(openfl.utils.ByteArray.fromBytes(bytes), bytes.length);
|
||||||
|
var vocalTrack = FlxG.sound.load(openflSound, 1.0, false);
|
||||||
|
audioVocalTrackGroup.add(vocalTrack);
|
||||||
|
|
||||||
|
// Tell the user the load was successful.
|
||||||
|
// TODO: Un-bork this.
|
||||||
|
// showNotification('Loaded instrumental track successfully.');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch's a song's existing chart and audio and loads it, replacing the current song.
|
||||||
|
*/
|
||||||
|
public function loadSongAsTemplate(songId:String)
|
||||||
|
{
|
||||||
|
var song:Song = SongDataParser.fetchSong(songId);
|
||||||
|
|
||||||
|
if (song == null)
|
||||||
|
{
|
||||||
|
// showNotification('Failed to load song template.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load the song metadata.
|
||||||
|
var rawSongMetadata:Array<SongMetadata> = song.getRawMetadata();
|
||||||
|
|
||||||
|
this.songMetadata = new Map<String, SongMetadata>();
|
||||||
|
|
||||||
|
for (metadata in rawSongMetadata)
|
||||||
|
{
|
||||||
|
var variation = (metadata.variation == null || metadata.variation == '') ? 'default' : metadata.variation;
|
||||||
|
this.songMetadata.set(variation, metadata);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.songChartData = new Map<String, SongChartData>();
|
||||||
|
|
||||||
|
for (metadata in rawSongMetadata)
|
||||||
|
{
|
||||||
|
var variation = (metadata.variation == null || metadata.variation == '') ? 'default' : metadata.variation;
|
||||||
|
this.songChartData.set(variation, SongDataParser.parseSongChartData(songId, metadata.variation));
|
||||||
|
}
|
||||||
|
|
||||||
|
Conductor.mapTimeChanges(currentSongMetadata.timeChanges);
|
||||||
|
|
||||||
|
loadInstrumentalFromAsset(Paths.inst(songId));
|
||||||
|
loadVocalsFromAsset(Paths.voices(songId));
|
||||||
|
|
||||||
|
// Apply BPM
|
||||||
|
|
||||||
|
// showNotification('Loaded song ${songId}.');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2498,8 +2594,8 @@ class ChartEditorState extends HaxeUIState
|
||||||
// Update the songPosition in the audio tracks.
|
// Update the songPosition in the audio tracks.
|
||||||
if (audioInstTrack != null)
|
if (audioInstTrack != null)
|
||||||
audioInstTrack.time = scrollPositionInMs + playheadPositionInMs;
|
audioInstTrack.time = scrollPositionInMs + playheadPositionInMs;
|
||||||
if (audioVocalTrack != null)
|
if (audioVocalTrackGroup != null)
|
||||||
audioVocalTrack.time = scrollPositionInMs + playheadPositionInMs;
|
audioVocalTrackGroup.time = scrollPositionInMs + playheadPositionInMs;
|
||||||
|
|
||||||
// We need to update the note sprites because we changed the scroll position.
|
// We need to update the note sprites because we changed the scroll position.
|
||||||
noteDisplayDirty = true;
|
noteDisplayDirty = true;
|
||||||
|
|
Loading…
Reference in a new issue