time Signature functionality wip
This commit is contained in:
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 222 B |
@@ -129,6 +129,7 @@ class Chart {
|
||||
1 => "Camera Movement",
|
||||
2 => "BPM Change",
|
||||
3 => "Alt Animation Toggle",
|
||||
4 => "Time Signature Change",
|
||||
];
|
||||
|
||||
if (data.events == null) data.events = [];
|
||||
|
||||
@@ -10,7 +10,7 @@ import funkin.backend.assets.Paths;
|
||||
using StringTools;
|
||||
|
||||
class EventsData {
|
||||
public static var defaultEventsList:Array<String> = ["HScript Call", "Camera Movement", "Add Camera Zoom", "Camera Modulo Change", "Camera Flash", "BPM Change", "Scroll Speed Change", "Alt Animation Toggle", "Play Animation"];
|
||||
public static var defaultEventsList:Array<String> = ["HScript Call", "Camera Movement", "Add Camera Zoom", "Camera Modulo Change", "Camera Flash", "BPM Change", "Scroll Speed Change", "Alt Animation Toggle", "Play Animation", "Time Signature Change"];
|
||||
public static var defaultEventsParams:Map<String, Array<EventParamInfo>> = [
|
||||
"HScript Call" => [
|
||||
{name: "Function Name", type: TString, defValue: "myFunc"},
|
||||
@@ -49,6 +49,7 @@ class EventsData {
|
||||
],
|
||||
"Alt Animation Toggle" => [{name: "Enable On Sing Poses", type: TBool, defValue: true}, {name: "Enable On Idle", type: TBool, defValue: true}, {name: "Strumline", type: TStrumLine, defValue: 0}],
|
||||
"Play Animation" => [{name: "Character", type: TStrumLine, defValue: 0}, {name: "Animation", type: TString, defValue: "animation"}, {name: "Is forced?", type: TBool, defValue: true}],
|
||||
"Time Signature Change" => [{name: "Target Beat Count", type: TFloat(1), defValue: 4}, {name: "Target Step Count", type: TFloat(1), defValue: 4}],
|
||||
];
|
||||
|
||||
public static var eventsList:Array<String> = defaultEventsList.copy();
|
||||
|
||||
@@ -109,6 +109,16 @@ class FNFLegacyParser {
|
||||
});
|
||||
}
|
||||
|
||||
if (section.sectionBeats != beatsPerMeasure) {
|
||||
beatsPerMeasure = section.sectionBeats != null ? section.sectionBeats : data.beatsPerMeasure.getDefault(4);
|
||||
|
||||
result.events.push({
|
||||
time: curTime,
|
||||
name: "Time Signature Change",
|
||||
params: [section.sectionBeats, 4]
|
||||
});
|
||||
}
|
||||
|
||||
curTime += curCrochet * beatsPerMeasure;
|
||||
}
|
||||
}
|
||||
@@ -179,7 +189,8 @@ class FNFLegacyParser {
|
||||
mustHitSection: notes[section-1] != null ? notes[section-1].mustHitSection : false,
|
||||
bpm: notes[section-1] != null ? notes[section-1].bpm : chart.meta.bpm,
|
||||
changeBPM: false,
|
||||
altAnim: notes[section-1] != null ? notes[section-1].altAnim : false
|
||||
altAnim: notes[section-1] != null ? notes[section-1].altAnim : false,
|
||||
sectionBeats: notes[section-1] != null ? notes[section-1].sectionBeats : chart.meta.beatsPerMeasure.getDefault(4)
|
||||
};
|
||||
|
||||
var sectionEndTime:Float = Conductor.getTimeForStep(Conductor.getMeasureLength() * (section+1));
|
||||
@@ -193,6 +204,8 @@ class FNFLegacyParser {
|
||||
case "BPM Change":
|
||||
baseSection.changeBPM = true;
|
||||
baseSection.bpm = event.params[0];
|
||||
case "Time Signature Change":
|
||||
baseSection.sectionBeats = event.params[0];
|
||||
}
|
||||
}
|
||||
notes[section] = baseSection;
|
||||
|
||||
@@ -10,6 +10,8 @@ typedef BPMChangeEvent =
|
||||
var stepTime:Float;
|
||||
var songTime:Float;
|
||||
var bpm:Float;
|
||||
var beatsPerMeasure:Float;
|
||||
var stepsPerBeat:Float;
|
||||
}
|
||||
|
||||
class Conductor
|
||||
@@ -21,6 +23,8 @@ class Conductor
|
||||
public static var onBeatHit:FlxTypedSignal<Int->Void> = new FlxTypedSignal();
|
||||
public static var onStepHit:FlxTypedSignal<Int->Void> = new FlxTypedSignal();
|
||||
public static var onBPMChange:FlxTypedSignal<Float->Void> = new FlxTypedSignal();
|
||||
public static var onBeatsPerMeasureChange:FlxTypedSignal<Float->Void> = new FlxTypedSignal();
|
||||
public static var onStepsPerBeatChange:FlxTypedSignal<Float->Void> = new FlxTypedSignal();
|
||||
|
||||
/**
|
||||
* Current BPM
|
||||
@@ -108,36 +112,42 @@ class Conductor
|
||||
songPosition = lastSongPos = curBeatFloat = curStepFloat = curBeat = curStep = 0;
|
||||
bpmChangeMap = [];
|
||||
changeBPM(0);
|
||||
changeTimeSignature(4, 4);
|
||||
}
|
||||
|
||||
public static function setupSong(SONG:ChartData) {
|
||||
reset();
|
||||
mapBPMChanges(SONG);
|
||||
changeBPM(SONG.meta.bpm, cast SONG.meta.beatsPerMeasure.getDefault(4), cast SONG.meta.stepsPerBeat.getDefault(4));
|
||||
changeBPM(SONG.meta.bpm);
|
||||
changeTimeSignature(cast SONG.meta.beatsPerMeasure.getDefault(4), cast SONG.meta.stepsPerBeat.getDefault(4));
|
||||
}
|
||||
/**
|
||||
* Maps BPM changes from a song.
|
||||
* @param song Song to map BPM changes from.
|
||||
*/
|
||||
public static function mapBPMChanges(song:ChartData)
|
||||
{
|
||||
public static function mapBPMChanges(song:ChartData) {
|
||||
bpmChangeMap = [
|
||||
{
|
||||
stepTime: 0,
|
||||
songTime: 0,
|
||||
bpm: song.meta.bpm
|
||||
bpm: song.meta.bpm,
|
||||
beatsPerMeasure: song.meta.beatsPerMeasure.getDefault(4),
|
||||
stepsPerBeat: song.meta.stepsPerBeat.getDefault(4)
|
||||
}
|
||||
];
|
||||
|
||||
if (song.events == null) return;
|
||||
|
||||
var curBPM:Float = song.meta.bpm;
|
||||
var curBeatsPerMeasure:Float = song.meta.beatsPerMeasure.getDefault(4);
|
||||
var curStepsPerBeat:Float = song.meta.stepsPerBeat.getDefault(4);
|
||||
var songTime:Float = 0;
|
||||
var stepTime:Float = 0;
|
||||
|
||||
for(e in song.events) if (e.name == "BPM Change" && e.params != null && e.params[0] is Float) {
|
||||
for(e in song.events) {
|
||||
if (e.name == "BPM Change" && e.params != null && e.params[0] is Float) {
|
||||
if (e.params[0] == curBPM) continue;
|
||||
var steps = (e.time - songTime) / ((60 / curBPM) * 1000 / 4);
|
||||
var steps = (e.time - songTime) / ((60 / curBPM) * 1000 / stepsPerBeat);
|
||||
stepTime += steps;
|
||||
songTime = e.time;
|
||||
curBPM = e.params[0];
|
||||
@@ -145,9 +155,34 @@ class Conductor
|
||||
bpmChangeMap.push({
|
||||
stepTime: stepTime,
|
||||
songTime: songTime,
|
||||
bpm: curBPM
|
||||
bpm: curBPM,
|
||||
beatsPerMeasure: curBeatsPerMeasure, // keep old beatsPerMeasure and stepsPerMeasure so shit doesnt break
|
||||
stepsPerBeat: curStepsPerBeat
|
||||
});
|
||||
}
|
||||
|
||||
if (e.name == "Time Signature Change" && e.params != null) {
|
||||
var newBeatsPerMeasure = e.params[0];
|
||||
var newStepsPerBeat = e.params[1];
|
||||
|
||||
if (newBeatsPerMeasure == curBeatsPerMeasure && newStepsPerBeat == curStepsPerBeat) continue;
|
||||
|
||||
var steps = (e.time - songTime) / ((60 / curBPM) * 1000 / stepsPerBeat);
|
||||
stepTime += steps;
|
||||
songTime = e.time;
|
||||
|
||||
curBeatsPerMeasure = newBeatsPerMeasure;
|
||||
curStepsPerBeat = newStepsPerBeat;
|
||||
|
||||
bpmChangeMap.push({
|
||||
stepTime: stepTime,
|
||||
songTime: songTime,
|
||||
bpm: curBPM, // keep old bpm so shit doesnt break
|
||||
beatsPerMeasure: curBeatsPerMeasure,
|
||||
stepsPerBeat: curStepsPerBeat
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static var elapsed:Float;
|
||||
@@ -186,19 +221,29 @@ class Conductor
|
||||
__updateSongPos(FlxG.elapsed);
|
||||
|
||||
if (bpm > 0) {
|
||||
// updates curbeat and stuff
|
||||
// Check for BPM change
|
||||
__lastChange = {
|
||||
stepTime: 0,
|
||||
songTime: 0,
|
||||
bpm: 0
|
||||
bpm: 0,
|
||||
beatsPerMeasure: beatsPerMeasure,
|
||||
stepsPerBeat: stepsPerBeat
|
||||
};
|
||||
for (change in Conductor.bpmChangeMap)
|
||||
{
|
||||
|
||||
for (change in Conductor.bpmChangeMap) {
|
||||
if (Conductor.songPosition >= change.songTime)
|
||||
__lastChange = change;
|
||||
}
|
||||
|
||||
if (__lastChange.bpm > 0 && bpm != __lastChange.bpm) changeBPM(__lastChange.bpm);
|
||||
// Change BPM if necessary
|
||||
if (__lastChange.bpm > 0 && bpm != __lastChange.bpm) {
|
||||
changeBPM(__lastChange.bpm);
|
||||
}
|
||||
|
||||
// Check for time signature change
|
||||
if (__lastChange.beatsPerMeasure != beatsPerMeasure || __lastChange.stepsPerBeat != stepsPerBeat) {
|
||||
changeTimeSignature(__lastChange.beatsPerMeasure, __lastChange.stepsPerBeat);
|
||||
}
|
||||
|
||||
curStepFloat = __lastChange.stepTime + ((Conductor.songPosition - __lastChange.songTime) / Conductor.stepCrochet);
|
||||
curBeatFloat = curStepFloat / stepsPerBeat;
|
||||
@@ -271,34 +316,50 @@ class Conductor
|
||||
onBPMChange.dispatch(bpm);
|
||||
}
|
||||
|
||||
public static function changeTimeSignature(newBeatsPerMeasure:Float, newStepsPerBeat:Float) {
|
||||
beatsPerMeasure = newBeatsPerMeasure;
|
||||
stepsPerBeat = newStepsPerBeat;
|
||||
|
||||
crochet = ((60 / bpm) * 1000);
|
||||
stepCrochet = crochet / stepsPerBeat;
|
||||
|
||||
onBeatsPerMeasureChange.dispatch(beatsPerMeasure);
|
||||
onStepsPerBeatChange.dispatch(stepsPerBeat);
|
||||
}
|
||||
|
||||
public static function getTimeForStep(step:Float) {
|
||||
var bpmChange:BPMChangeEvent = {
|
||||
stepTime: 0,
|
||||
songTime: 0,
|
||||
bpm: bpm
|
||||
bpm: bpm,
|
||||
beatsPerMeasure: beatsPerMeasure,
|
||||
stepsPerBeat: stepsPerBeat
|
||||
};
|
||||
|
||||
for(change in bpmChangeMap)
|
||||
if (change.stepTime < step && change.stepTime >= bpmChange.stepTime)
|
||||
bpmChange = change;
|
||||
|
||||
return bpmChange.songTime + ((step - bpmChange.stepTime) * ((60 / bpmChange.bpm) * (1000/stepsPerBeat)));
|
||||
return bpmChange.songTime + ((step - bpmChange.stepTime) * ((60 / bpmChange.bpm) * (1000 / bpmChange.stepsPerBeat)));
|
||||
}
|
||||
|
||||
public static function getStepForTime(time:Float) {
|
||||
var bpmChange:BPMChangeEvent = {
|
||||
stepTime: 0,
|
||||
songTime: 0,
|
||||
bpm: bpm
|
||||
bpm: bpm,
|
||||
beatsPerMeasure: beatsPerMeasure,
|
||||
stepsPerBeat: stepsPerBeat
|
||||
};
|
||||
|
||||
for(change in bpmChangeMap)
|
||||
if (change.songTime < time && change.songTime >= bpmChange.songTime)
|
||||
bpmChange = change;
|
||||
|
||||
return bpmChange.stepTime + ((time - bpmChange.songTime) / ((60 / bpmChange.bpm) * (1000/stepsPerBeat)));
|
||||
return bpmChange.stepTime + ((time - bpmChange.songTime) / ((60 / bpmChange.bpm) * (1000 / bpmChange.stepsPerBeat)));
|
||||
}
|
||||
|
||||
|
||||
public static inline function getMeasureLength()
|
||||
return stepsPerBeat * beatsPerMeasure;
|
||||
|
||||
|
||||
@@ -109,7 +109,7 @@ class CharterEvent extends UISliceSprite implements ICharterSelectable {
|
||||
|
||||
draggable = true;
|
||||
for (event in events)
|
||||
if (event.name == "BPM Change") {
|
||||
if (event.name == "BPM Change" || event.name == "Time Signature Change") {
|
||||
draggable = false;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1388,6 +1388,7 @@ class PlayState extends MusicBeatState
|
||||
if (strumLines.members[event.params[0]] != null && strumLines.members[event.params[0]].characters != null)
|
||||
for (char in strumLines.members[event.params[0]].characters)
|
||||
if (char != null) char.playAnim(event.params[1], event.params[2], null);
|
||||
case "Time Signature Change": // automatically handled by conductor
|
||||
case "Unknown": // nothing
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user