new chart editor, sm file support, bpm changes, and scroll speed changes.
This commit is contained in:
@ -1,7 +1,9 @@
|
||||
#if sys
|
||||
package smTools;
|
||||
|
||||
import sys.io.File;
|
||||
import haxe.Exception;
|
||||
import lime.app.Application;
|
||||
import haxe.Json;
|
||||
|
||||
class SMFile
|
||||
{
|
||||
@ -12,6 +14,10 @@ class SMFile
|
||||
|
||||
private var _fileData:Array<String>;
|
||||
|
||||
public var isDouble:Bool = false;
|
||||
|
||||
public var isValid:Bool = true;
|
||||
|
||||
public var _readTime:Float = 0;
|
||||
|
||||
public var header:SMHeader;
|
||||
@ -19,43 +25,230 @@ class SMFile
|
||||
|
||||
public function new(data:Array<String>)
|
||||
{
|
||||
_fileData = data;
|
||||
|
||||
// Gather header data
|
||||
var headerData = "";
|
||||
var inc = 0;
|
||||
while(!StringTools.contains(data[inc + 1],"//"))
|
||||
try
|
||||
{
|
||||
headerData += data[inc] + "\n";
|
||||
inc++;
|
||||
// trace(data[inc]);
|
||||
}
|
||||
_fileData = data;
|
||||
|
||||
header = new SMHeader(headerData.split('\n'));
|
||||
|
||||
// check if this is a valid file, it should be a dance double file.
|
||||
inc += 3; // skip three lines down
|
||||
if (!StringTools.contains(data[inc],"dance-double:"))
|
||||
return;
|
||||
trace('this is dance double');
|
||||
|
||||
inc += 4; // skip 5 down to where da notes @
|
||||
trace(data[inc]);
|
||||
|
||||
measures = [];
|
||||
|
||||
while(data[inc + 1] != ";")
|
||||
{
|
||||
var measure = "";
|
||||
while(data[inc + 1] != ",")
|
||||
// Gather header data
|
||||
var headerData = "";
|
||||
var inc = 0;
|
||||
while(!StringTools.contains(data[inc + 1],"//"))
|
||||
{
|
||||
headerData += data[inc];
|
||||
inc++;
|
||||
var line = data[inc];
|
||||
measure += line + "\n";
|
||||
// trace(data[inc]);
|
||||
}
|
||||
measures.push(new SMMeasure(measure.split('\n')));
|
||||
|
||||
header = new SMHeader(headerData.split(';'));
|
||||
|
||||
if (!StringTools.contains(header.MUSIC,"ogg"))
|
||||
{
|
||||
Application.current.window.alert("The music MUST be an OGG File.","SM File loading (" + header.TITLE + ")");
|
||||
isValid = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// check if this is a valid file, it should be a dance double file.
|
||||
inc += 3; // skip three lines down
|
||||
if (!StringTools.contains(data[inc],"dance-double:") && !StringTools.contains(data[inc],"dance-single"))
|
||||
{
|
||||
Application.current.window.alert("The file you are loading is neither a Dance Double chart or a Dance Single chart","SM File loading (" + header.TITLE + ")");
|
||||
isValid = false;
|
||||
return;
|
||||
}
|
||||
if (StringTools.contains(data[inc],"dance-double:"))
|
||||
isDouble = true;
|
||||
if (isDouble)
|
||||
trace('this is dance double');
|
||||
|
||||
inc += 5; // skip 5 down to where da notes @
|
||||
|
||||
measures = [];
|
||||
|
||||
var measure = "";
|
||||
|
||||
trace(data[inc - 1]);
|
||||
|
||||
for (ii in inc...data.length)
|
||||
{
|
||||
var i = data[ii];
|
||||
if (StringTools.contains(i,",") || StringTools.contains(i,";"))
|
||||
{
|
||||
measures.push(new SMMeasure(measure.split('\n')));
|
||||
//trace(measures.length);
|
||||
measure = "";
|
||||
continue;
|
||||
}
|
||||
measure += i + "\n";
|
||||
}
|
||||
trace(measures.length + " Measures");
|
||||
}
|
||||
trace(measures.length + " Measures");
|
||||
catch(e:Exception)
|
||||
{
|
||||
Application.current.window.alert("Failure to load file.\n" + e,"SM File loading");
|
||||
}
|
||||
}
|
||||
|
||||
public function convertToFNF(saveTo:String):String
|
||||
{
|
||||
|
||||
// array's for helds
|
||||
var heldNotes:Array<Array<Dynamic>>;
|
||||
|
||||
|
||||
if (isDouble) // held storage lanes
|
||||
heldNotes = [[],[],[],[],[],[],[],[]];
|
||||
else
|
||||
heldNotes = [[],[],[],[]];
|
||||
|
||||
|
||||
// variables
|
||||
|
||||
var measureIndex = 0;
|
||||
var currentBeat:Float = 0;
|
||||
var output = "";
|
||||
|
||||
// init a fnf song
|
||||
|
||||
var song = {
|
||||
song: header.TITLE,
|
||||
notes: [],
|
||||
eventObjects: [],
|
||||
bpm: header.getBPM(0),
|
||||
needsVoices: true,
|
||||
player1: 'bf',
|
||||
player2: 'gf',
|
||||
gfVersion: 'gf',
|
||||
noteStyle: 'normal',
|
||||
stage: 'stage',
|
||||
speed: 1.0,
|
||||
validScore: false
|
||||
};
|
||||
|
||||
// lets check if the sm loading was valid
|
||||
|
||||
if (!isValid)
|
||||
{
|
||||
var json = {
|
||||
"song": song
|
||||
};
|
||||
|
||||
var data:String = Json.stringify(json,null," ");
|
||||
File.saveContent(saveTo,data);
|
||||
return data;
|
||||
}
|
||||
|
||||
// aight time to convert da measures
|
||||
|
||||
trace("Converting measures");
|
||||
|
||||
for(measure in measures)
|
||||
{
|
||||
// private access since _measure is private
|
||||
@:privateAccess
|
||||
var lengthInRows = 192 / (measure._measure.length - 1);
|
||||
|
||||
var rowIndex = 0;
|
||||
|
||||
// section declaration
|
||||
|
||||
var section = {
|
||||
sectionNotes: [],
|
||||
lengthInSteps: 16,
|
||||
typeOfSection: 0,
|
||||
mustHitSection: false,
|
||||
bpm: header.getBPM(0),
|
||||
changeBPM: false,
|
||||
altAnim: false
|
||||
};
|
||||
|
||||
// if it's not a double always set this to true
|
||||
|
||||
if (!isDouble)
|
||||
section.mustHitSection = true;
|
||||
|
||||
@:privateAccess
|
||||
for(i in 0...measure._measure.length - 1)
|
||||
{
|
||||
var noteRow = (measureIndex * 192) + (lengthInRows * rowIndex);
|
||||
|
||||
var notes:Array<String> = [];
|
||||
|
||||
for(note in measure._measure[i].split(''))
|
||||
{
|
||||
//output += note;
|
||||
notes.push(note);
|
||||
}
|
||||
|
||||
currentBeat = noteRow / 48;
|
||||
|
||||
var seg = TimingStruct.getTimingAtBeat(currentBeat);
|
||||
|
||||
var timeInSec:Float = (seg.startTime + ((currentBeat - seg.startBeat) / (seg.bpm/60)));
|
||||
|
||||
var rowTime = timeInSec * 1000;
|
||||
|
||||
//output += " - Row " + noteRow + " - Time: " + rowTime + " (" + timeInSec + ") - Beat: " + currentBeat + " - Current BPM: " + header.getBPM(currentBeat) + "\n";
|
||||
|
||||
var index = 0;
|
||||
var takeover = false;
|
||||
|
||||
for(i in notes)
|
||||
{
|
||||
// if its a mine lets skip (maybe add mines in the future??)
|
||||
if (i == "M")
|
||||
continue;
|
||||
|
||||
// get the lane and note type
|
||||
var lane = index;
|
||||
var numba = Std.parseInt(i);
|
||||
|
||||
// switch through the type and add the note
|
||||
|
||||
switch(numba)
|
||||
{
|
||||
case 1: // normal
|
||||
section.sectionNotes.push([rowTime,lane ,0]);
|
||||
case 2: // held head
|
||||
heldNotes[lane] = [rowTime,lane,0];
|
||||
case 3: // held tail
|
||||
var data = heldNotes[lane];
|
||||
var timeDiff = rowTime - data[0];
|
||||
section.sectionNotes.push([data[0],lane,timeDiff]);
|
||||
heldNotes[index] = [];
|
||||
}
|
||||
index++;
|
||||
}
|
||||
|
||||
|
||||
rowIndex++;
|
||||
}
|
||||
|
||||
// push the section
|
||||
|
||||
song.notes.push(section);
|
||||
|
||||
//output += ",\n";
|
||||
|
||||
measureIndex++;
|
||||
}
|
||||
|
||||
//File.saveContent("fuac" + header.TITLE,output);
|
||||
|
||||
if (header.changeEvents.length != 0)
|
||||
{
|
||||
song.eventObjects = header.changeEvents;
|
||||
}
|
||||
|
||||
// save da song
|
||||
|
||||
var json = {
|
||||
"song": song
|
||||
};
|
||||
|
||||
var data:String = Json.stringify(json,null," ");
|
||||
File.saveContent(saveTo,data);
|
||||
return data;
|
||||
}
|
||||
}
|
||||
#end
|
@ -15,13 +15,83 @@ class SMHeader
|
||||
public var BACKGROUND = "";
|
||||
public var CDTITLE = "";
|
||||
public var OFFSET = "";
|
||||
public var BPMS = "";
|
||||
public var BPMS = ""; // time=bpm
|
||||
|
||||
public var changeEvents:Array<Song.Event>;
|
||||
|
||||
public function new(headerData:Array<String>)
|
||||
{
|
||||
_header = headerData;
|
||||
|
||||
for (i in headerData)
|
||||
{
|
||||
readHeaderLine(i);
|
||||
}
|
||||
|
||||
trace(BPMS);
|
||||
|
||||
MUSIC = StringTools.replace(MUSIC," ", "_");
|
||||
|
||||
changeEvents = [];
|
||||
|
||||
getBPM(0,true);
|
||||
}
|
||||
|
||||
public function getBeatFromBPMIndex(index):Float
|
||||
{
|
||||
var bpmSplit = BPMS.split(',');
|
||||
var beat = 0;
|
||||
for(ii in 0...bpmSplit.length)
|
||||
{
|
||||
if (ii == index)
|
||||
return Std.parseFloat(StringTools.replace(bpmSplit[ii].split('=')[0],",",""));
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
public function getBPM(beat:Float, printAllBpms:Bool = false)
|
||||
{
|
||||
var bpmSplit = BPMS.split(',');
|
||||
if (printAllBpms)
|
||||
{
|
||||
TimingStruct.clearTimings();
|
||||
var currentIndex = 0;
|
||||
for(i in bpmSplit)
|
||||
{
|
||||
var bpm:Float = Std.parseFloat(i.split('=')[1]);
|
||||
var beat:Float = Std.parseFloat(StringTools.replace(i.split('=')[0],",",""));
|
||||
|
||||
var endBeat:Float = Math.POSITIVE_INFINITY;
|
||||
|
||||
TimingStruct.addTiming(beat,bpm,endBeat, -Std.parseFloat(OFFSET));
|
||||
|
||||
if (changeEvents.length != 0)
|
||||
{
|
||||
var data = TimingStruct.AllTimings[currentIndex - 1];
|
||||
data.endBeat = beat;
|
||||
data.length = (data.endBeat - data.startBeat) / (data.bpm / 60);
|
||||
TimingStruct.AllTimings[currentIndex].startTime = data.startTime + data.length;
|
||||
}
|
||||
|
||||
changeEvents.push(new Song.Event(HelperFunctions.truncateFloat(beat,0) + "SM",beat,bpm,"BPM Change"));
|
||||
|
||||
if (bpmSplit.length == 1)
|
||||
break;
|
||||
currentIndex++;
|
||||
}
|
||||
|
||||
trace(changeEvents.length + " - BPM CHANGES");
|
||||
return 0.0;
|
||||
}
|
||||
var returningBPM = Std.parseFloat(bpmSplit[0].split('=')[1]);
|
||||
for(i in bpmSplit)
|
||||
{
|
||||
var bpm:Float = Std.parseFloat(i.split('=')[1]);
|
||||
var beatt:Float = Std.parseFloat(StringTools.replace(i.split('=')[0],",",""));
|
||||
if (beatt <= beat)
|
||||
returningBPM = bpm;
|
||||
}
|
||||
return returningBPM;
|
||||
}
|
||||
|
||||
function readHeaderLine(line:String)
|
||||
|
@ -11,6 +11,19 @@ class SMMeasure
|
||||
{
|
||||
_measure = measureData;
|
||||
notes = [];
|
||||
|
||||
// 0 = no note
|
||||
// 1 = normal note
|
||||
// 2 = head of sustain
|
||||
// 3 = tail of sustain
|
||||
|
||||
for(i in measureData)
|
||||
{
|
||||
for (ii in 0...i.length)
|
||||
{
|
||||
notes.push(new SMNote(i.split('')[ii],ii));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#end
|
@ -3,8 +3,13 @@ package smTools;
|
||||
|
||||
class SMNote
|
||||
{
|
||||
public var time:Float;
|
||||
public var data:Int;
|
||||
public var length:Float;
|
||||
public var data:String;
|
||||
public var lane:Int;
|
||||
|
||||
public function new(_data:String,_lane:Int)
|
||||
{
|
||||
data = _data;
|
||||
lane = _lane;
|
||||
}
|
||||
}
|
||||
#end
|
Reference in New Issue
Block a user