diff --git a/Project.xml b/Project.xml
index eeffad6..320a787 100644
--- a/Project.xml
+++ b/Project.xml
@@ -57,6 +57,7 @@
+
@@ -89,7 +91,9 @@
-
+
+
+
diff --git a/README.md b/README.md
index a1645e9..0711867 100644
--- a/README.md
+++ b/README.md
@@ -75,4 +75,5 @@ This game was made with love to Newgrounds and its community. Extra love to Tom
- [GWebDev](https://github.com/GrowtopiaFli) - Video Code
- [Rozebud](https://github.com/ThatRozebudDude) - Ideas (that I stole)
- [Puyo](https://github.com/daniel11420) - Setting up appveyor and a lot of other help
-- [Smokey](https://twitter.com/Smokey_5_) - telling me that I should do the tricky asset loading
\ No newline at end of file
+- [Smokey](https://twitter.com/Smokey_5_) - telling me that I should do the tricky asset loading
+- [Poco](https://github.com/poco0317) - math degree (aka most of the fucking math in this project)
\ No newline at end of file
diff --git a/assets/preload/images/stepmania-icon.png b/assets/preload/images/stepmania-icon.png
new file mode 100644
index 0000000..023353b
Binary files /dev/null and b/assets/preload/images/stepmania-icon.png differ
diff --git a/assets/sm/HOW TO ADD SM FILES.txt b/assets/sm/HOW TO ADD SM FILES.txt
new file mode 100644
index 0000000..5eb12c3
--- /dev/null
+++ b/assets/sm/HOW TO ADD SM FILES.txt
@@ -0,0 +1 @@
+Put both the .sm and .ogg in the same folder and put the folder in this folder. Launch the game and go into freeplay, it'll load into the song list.
\ No newline at end of file
diff --git a/source/ChartingState.hx b/source/ChartingState.hx
index 14a7e5d..db20a29 100644
--- a/source/ChartingState.hx
+++ b/source/ChartingState.hx
@@ -1,5 +1,12 @@
package;
+import openfl.system.System;
+import lime.app.Application;
+#if sys
+import sys.io.File;
+#end
+import flixel.addons.ui.FlxUIButton;
+import flixel.addons.ui.StrNameLabel;
import flixel.FlxCamera;
import flixel.FlxObject;
import flixel.addons.ui.FlxUIText;
@@ -42,15 +49,25 @@ using StringTools;
class ChartingState extends MusicBeatState
{
+ public static var instance:ChartingState;
+
var _file:FileReference;
public var playClaps:Bool = false;
- public var snap:Int = 1;
+ public var snap:Int = 16;
+
+ public var deezNuts:Map = new Map(); // snap conversion map
var UI_box:FlxUITabMenu;
var UI_options:FlxUITabMenu;
+ public static var lengthInSteps:Float = 0;
+ public static var lengthInBeats:Float = 0;
+
+ public var beatsShown:Float = 1; // for the zoom factor
+ public var zoomFactor:Float = 1;
+
/**
* Array of notes showing when each section STARTS in STEPS
* Usually rounded up??
@@ -75,11 +92,14 @@ class ChartingState extends MusicBeatState
var dummyArrow:FlxSprite;
+
var curRenderedNotes:FlxTypedGroup;
var curRenderedSustains:FlxTypedGroup;
var gridBG:FlxSprite;
+ public var sectionRenderes:FlxTypedGroup;
+
public static var _song:SwagSong;
var typingShit:FlxInputText;
@@ -95,27 +115,55 @@ class ChartingState extends MusicBeatState
var player2:Character = new Character(0,0, "dad");
var player1:Boyfriend = new Boyfriend(0,0, "bf");
- var leftIcon:HealthIcon;
- var rightIcon:HealthIcon;
+ public static var leftIcon:HealthIcon;
+
+ var height = 0;
+
+ public static var rightIcon:HealthIcon;
private var lastNote:Note;
+
+ public var lines:FlxTypedGroup;
+
var claps:Array = [];
public var snapText:FlxText;
var camFollow:FlxObject;
+ public static var latestChartVersion = "2";
+
override function create()
{
curSection = lastSection;
+ trace(1 > Math.POSITIVE_INFINITY);
+
+ FlxG.mouse.visible = true;
+
+ instance = this;
+
+ deezNuts.set(4,1);
+ deezNuts.set(8,2);
+ deezNuts.set(16,4);
+ deezNuts.set(32,8);
+ deezNuts.set(64,16);
+
+ sectionRenderes = new FlxTypedGroup();
+ lines = new FlxTypedGroup();
+ texts = new FlxTypedGroup();
+
+ TimingStruct.clearTimings();
+
if (PlayState.SONG != null)
_song = PlayState.SONG;
else
{
_song = {
+ chartVersion: latestChartVersion,
song: 'Test',
notes: [],
+ eventObjects: [],
bpm: 150,
needsVoices: true,
player1: 'bf',
@@ -130,18 +178,19 @@ class ChartingState extends MusicBeatState
addGrid(1);
- var blackBorder:FlxSprite = new FlxSprite(60,10).makeGraphic(120,100,FlxColor.BLACK);
- blackBorder.scrollFactor.set();
+ if (_song.chartVersion == null)
+ _song.chartVersion = "2";
+
- blackBorder.alpha = 0.3;
+ //var blackBorder:FlxSprite = new FlxSprite(60,10).makeGraphic(120,100,FlxColor.BLACK);
+ //blackBorder.scrollFactor.set();
- /*
- snapText = new FlxText(60,10,0,"Snap: 1/" + snap + " (Press SHIFT to unsnap the cursor)\nAdd Notes: 1-8 (or click)\nDiff: 0", 14);
+ //blackBorder.alpha = 0.3;
+
+
+ snapText = new FlxText(60,10,0,"", 14);
snapText.scrollFactor.set();
- */
-
- gridBlackLine = new FlxSprite(gridBG.x + gridBG.width / 2).makeGraphic(2, Std.int(gridBG.height), FlxColor.BLACK);
- add(gridBlackLine);
+
curRenderedNotes = new FlxTypedGroup();
curRenderedSustains = new FlxTypedGroup();
@@ -155,16 +204,117 @@ class ChartingState extends MusicBeatState
// sections = _song.notes;
- updateGrid();
-
loadSong(_song.song);
Conductor.changeBPM(_song.bpm);
Conductor.mapBPMChanges(_song);
leftIcon = new HealthIcon(_song.player1);
rightIcon = new HealthIcon(_song.player2);
- leftIcon.scrollFactor.set(1, 1);
- rightIcon.scrollFactor.set(1, 1);
+
+ var index = 0;
+
+
+
+ trace("goin");
+
+ var currentIndex = 0;
+ for (i in _song.eventObjects)
+ {
+ var name = Reflect.field(i,"name");
+ var type = Reflect.field(i,"type");
+ var pos = Reflect.field(i,"position");
+ var value = Reflect.field(i,"value");
+
+ if (type == "BPM Change")
+ {
+ var beat:Float = pos;
+
+ var endBeat:Float = Math.POSITIVE_INFINITY;
+
+ TimingStruct.addTiming(beat,value,endBeat, 0); // offset in this case = start time since we don't have a offset
+
+ if (currentIndex != 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;
+ }
+
+ currentIndex++;
+ }
+ }
+
+ var lastSeg = TimingStruct.AllTimings[TimingStruct.AllTimings.length - 1];
+
+ for (i in 0...TimingStruct.AllTimings.length)
+ {
+ var seg = TimingStruct.AllTimings[i];
+ if (i == TimingStruct.AllTimings.length - 1)
+ lastSeg = seg;
+ }
+
+ recalculateAllSectionTimes();
+
+ trace("Song length in MS: " + FlxG.sound.music.length);
+
+ for(i in 0...9000000) // REALLY HIGH BEATS just cuz like ig this is the upper limit, I mean ur chart is probably going to run like ass anyways
+ {
+ var seg = TimingStruct.getTimingAtBeat(i);
+
+
+ var start:Float = (i - seg.startBeat) / (seg.bpm / 60);
+
+ var time = (seg.startTime + start) * 1000;
+
+ if (time > FlxG.sound.music.length)
+ break;
+
+ lengthInBeats = i;
+ }
+
+ lengthInSteps = lengthInBeats * 4;
+
+ trace('LENGTH IN STEPS ' + lengthInSteps + ' | LENGTH IN BEATS ' + lengthInBeats + ' | SECTIONS: ' + Math.floor(((lengthInSteps + 16)) / 16));
+
+ var sections = Math.floor(((lengthInSteps + 16)) / 16);
+
+ var targetY = getYfromStrum(FlxG.sound.music.length);
+
+ trace("TARGET " + targetY);
+
+ for (awfgaw in 0...Math.round(targetY / 640) + 1920) // grids/steps
+ {
+ var renderer = new SectionRender(0,640 * awfgaw,GRID_SIZE);
+ if (_song.notes[awfgaw] == null)
+ _song.notes.push(newSection(16,true,false));
+ renderer.section = _song.notes[awfgaw];
+
+ sectionRenderes.add(renderer);
+
+ var down = getYfromStrum(renderer.section.startTime) * zoomFactor;
+
+ var sectionicon = _song.notes[awfgaw].mustHitSection ? new HealthIcon(_song.player1).clone() : new HealthIcon(_song.player2).clone();
+ sectionicon.x = -95;
+ sectionicon.y = down - 75;
+ sectionicon.setGraphicSize(0, 45);
+
+ renderer.icon = sectionicon;
+ renderer.lastUpdated = _song.notes[awfgaw].mustHitSection;
+
+ add(sectionicon);
+ height = Math.floor(renderer.y);
+ }
+
+
+
+ trace(height);
+
+ gridBlackLine = new FlxSprite(gridBG.width / 2).makeGraphic(2, height, FlxColor.BLACK);
+
+ //leftIcon.scrollFactor.set();
+ //rightIcon.scrollFactor.set();
+
leftIcon.setGraphicSize(0, 45);
rightIcon.setGraphicSize(0, 45);
@@ -175,16 +325,16 @@ class ChartingState extends MusicBeatState
leftIcon.setPosition(0, -100);
rightIcon.setPosition(gridBG.width / 2, -100);
+ leftIcon.scrollFactor.set();
+ rightIcon.scrollFactor.set();
+
bpmTxt = new FlxText(1000, 50, 0, "", 16);
bpmTxt.scrollFactor.set();
add(bpmTxt);
- strumLine = new FlxSprite(0, 50).makeGraphic(Std.int(GRID_SIZE * 8), 4);
- add(strumLine);
+ strumLine = new FlxSprite(0, 0).makeGraphic(Std.int(GRID_SIZE * 8), 4);
dummyArrow = new FlxSprite().makeGraphic(GRID_SIZE, GRID_SIZE);
- add(dummyArrow);
-
var tabs = [
{name: "Song", label: 'Song Data'},
{name: "Section", label: 'Section Data'},
@@ -200,7 +350,7 @@ class ChartingState extends MusicBeatState
UI_box.y = 20;
add(UI_box);
- var opt_tabs = [{name: "Options", label:'Editor Options'}];
+ var opt_tabs = [{name: "Options", label:'Song Options'}, {name: "Events", label:'Song Events'}];
UI_options = new FlxUITabMenu(null, opt_tabs, true);
@@ -211,23 +361,128 @@ class ChartingState extends MusicBeatState
UI_options.y = FlxG.height - 300;
add(UI_options);
+
addSongUI();
addSectionUI();
addNoteUI();
addOptionsUI();
+ addEventsUI();
+ regenerateLines();
+
+
+ updateGrid();
+
+ trace("bruh");
+
+
+ add(sectionRenderes);
+ add(dummyArrow);
+ add(strumLine);
+ add(lines);
+ add(texts);
+ add(gridBlackLine);
add(curRenderedNotes);
add(curRenderedSustains);
- add(blackBorder);
- //add(snapText);
+ trace("bruh");
+ //add(blackBorder);
+ add(snapText);
+ trace("bruh");
+ trace("create");
+
+ TimingStruct.clearTimings();
+
+ var currentIndex = 0;
+ for (i in _song.eventObjects)
+ {
+ if (i.type == "BPM Change")
+ {
+ var beat:Float = i.position;
+
+ var endBeat:Float = Math.POSITIVE_INFINITY;
+
+ TimingStruct.addTiming(beat,i.value,endBeat, 0); // offset in this case = start time since we don't have a offset
+
+ if (currentIndex != 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;
+ }
+
+ currentIndex++;
+ }
+ }
super.create();
}
+ public var texts:FlxTypedGroup;
+
+ function regenerateLines()
+ {
+ while(lines.members.length > 0)
+ {
+ lines.members[0].destroy();
+ lines.members.remove(lines.members[0]);
+ }
+
+ while(texts.members.length > 0)
+ {
+ texts.members[0].destroy();
+ texts.members.remove(texts.members[0]);
+ }
+ trace("removed lines and texts");
+
+ if (_song.eventObjects != null)
+ for(i in _song.eventObjects)
+ {
+ var seg = TimingStruct.getTimingAtBeat(i.position);
+
+ var posi:Float = 0;
+
+ if (seg != null)
+ {
+ var start:Float = (i.position - seg.startBeat) / (seg.bpm / 60);
+
+ posi = seg.startTime + start;
+ }
+
+ var pos = getYfromStrum(posi * 1000) * zoomFactor;
+
+ if (pos < 0)
+ pos = 0;
+
+ var type = i.type;
+
+ var text = new FlxText(-190, pos,0,i.name + "\n" + type + "\n" + i.value,12);
+ var line = new FlxSprite(0, pos).makeGraphic(Std.int(GRID_SIZE * 8), 4, FlxColor.BLUE);
+
+ line.alpha = 0.2;
+
+ lines.add(line);
+ texts.add(text);
+
+ add(line);
+ add(text);
+ }
+
+ for (i in sectionRenderes)
+ {
+ var pos = getYfromStrum(i.section.startTime) * zoomFactor;
+ i.icon.y = pos - 75;
+
+ var line = new FlxSprite(0, pos).makeGraphic(Std.int(GRID_SIZE * 8), 4, FlxColor.BLACK);
+ line.alpha = 0.4;
+ lines.add(line);
+ }
+ }
+
function addGrid(?divisions:Float = 1)
{
// This here is because non-integer numbers aren't supported as grid sizes, making the grid slowly 'drift' as it goes on
@@ -236,19 +491,430 @@ class ChartingState extends MusicBeatState
h = GRID_SIZE;
remove(gridBG);
- gridBG = FlxGridOverlay.create(GRID_SIZE, Std.int(h), GRID_SIZE * 8, GRID_SIZE * 16);
- add(gridBG);
+ gridBG = FlxGridOverlay.create(GRID_SIZE, Std.int(h), GRID_SIZE * 8,GRID_SIZE * 16);
+ trace(gridBG.height);
+ //gridBG.scrollFactor.set();
+ //gridBG.x += 358;
+ //gridBG.y += 390;
+ trace("height of " + (Math.floor(lengthInSteps)));
+
+
+ /*for(i in 0...Math.floor(lengthInSteps))
+ {
+ trace("Creating sprite " + i);
+ var grid = FlxGridOverlay.create(GRID_SIZE, Std.int(h), GRID_SIZE * 8, GRID_SIZE * 16);
+ add(grid);
+ if (i > lengthInSteps)
+ break;
+ }*/
+
+ var totalHeight = 0;
+
+ //add(gridBG);
+
+
+ remove(gridBlackLine);
+ gridBlackLine = new FlxSprite(0 + gridBG.width / 2).makeGraphic(2, Std.int(Math.floor(lengthInSteps)), FlxColor.BLACK);
+ add(gridBlackLine);
}
var stepperDiv:FlxUINumericStepper;
var check_snap:FlxUICheckBox;
+ var listOfEvents:FlxUIDropDownMenu;
+ var currentSelectedEventName:String = "";
+ var savedType:String = "";
+ var savedValue:String = "";
+ var currentEventPosition:Float = 0;
+
+ function containsName(name:String, events:Array):Song.Event
+ {
+ for (i in events)
+ {
+ var thisName = Reflect.field(i,"name");
+
+ if (thisName == name)
+ return i;
+ }
+ return null;
+ }
+
+ public var chartEvents:Array = [];
+
+ public var Typeables:Array = [];
+
+ function addEventsUI()
+ {
+ if (_song.eventObjects == null)
+ {
+ _song.eventObjects = [new Song.Event("Init BPM",0,_song.bpm,"BPM Change")];
+ }
+
+ var firstEvent = "";
+
+ if (Lambda.count(_song.eventObjects) != 0)
+ {
+ firstEvent = _song.eventObjects[0].name;
+ }
+
+ var listLabel = new FlxText(10, 5, 'List of Events');
+ var nameLabel = new FlxText(150, 5, 'Event Name');
+ var eventName = new FlxUIInputText(150,20,80,"");
+ var typeLabel = new FlxText(10, 45, 'Type of Event');
+ var eventType = new FlxUIDropDownMenu(10,60,FlxUIDropDownMenu.makeStrIdLabelArray(["BPM Change", "Scroll Speed Change"], true));
+ var valueLabel = new FlxText(150, 45, 'Event Value');
+ var eventValue = new FlxUIInputText(150,60,80,"");
+ var eventSave = new FlxButton(10,155,"Save Event", function() {
+ var pog:Song.Event = new Song.Event(currentSelectedEventName,currentEventPosition,HelperFunctions.truncateFloat(Std.parseFloat(savedValue), 3),savedType);
+
+ trace("trying to save " + currentSelectedEventName);
+
+ var obj = containsName(pog.name,_song.eventObjects);
+
+
+ if (pog.name == "")
+ return;
+
+ trace("yeah we can save it");
+
+ if (obj != null)
+ _song.eventObjects.remove(obj);
+ _song.eventObjects.push(pog);
+
+ trace(_song.eventObjects.length);
+
+ TimingStruct.clearTimings();
+
+ var currentIndex = 0;
+ for (i in _song.eventObjects)
+ {
+ var name = Reflect.field(i,"name");
+ var type = Reflect.field(i,"type");
+ var pos = Reflect.field(i,"position");
+ var value = Reflect.field(i,"value");
+
+ trace(i.type);
+ if (type == "BPM Change")
+ {
+ var beat:Float = pos;
+
+ var endBeat:Float = Math.POSITIVE_INFINITY;
+
+ TimingStruct.addTiming(beat,value,endBeat, 0); // offset in this case = start time since we don't have a offset
+
+ if (currentIndex != 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;
+ }
+
+ currentIndex++;
+ }
+ }
+
+ if (pog.type == "BPM Change")
+ recalculateAllSectionTimes();
+
+ regenerateLines();
+
+ var listofnames = [];
+
+ for (key => value in _song.eventObjects) {
+ listofnames.push(value.name);
+ }
+
+ listOfEvents.setData(FlxUIDropDownMenu.makeStrIdLabelArray(listofnames, true));
+
+ listOfEvents.selectedLabel = pog.name;
+
+ trace('end');
+ });
+ var posLabel = new FlxText(150, 85, 'Event Position');
+ var eventPos = new FlxUIInputText(150,100,80,"");
+ var eventAdd = new FlxButton(95,155,"Add Event", function() {
+
+ var pog:Song.Event = new Song.Event("New Event " + HelperFunctions.truncateFloat(curDecimalBeat, 3),HelperFunctions.truncateFloat(curDecimalBeat, 3),_song.bpm + "","BPM Change");
+
+ trace("adding " + pog.name);
+
+ var obj = containsName(pog.name,_song.eventObjects);
+
+ if (obj != null)
+ return;
+
+ trace("yeah we can add it");
+
+ _song.eventObjects.push(pog);
+
+ eventName.text = pog.name;
+ eventType.selectedLabel = pog.type;
+ eventValue.text = pog.value;
+ eventPos.text = pog.position + "";
+ currentSelectedEventName = pog.name;
+ currentEventPosition = pog.position;
+
+ savedType = pog.type;
+ savedValue = pog.value;
+
+ var listofnames = [];
+
+ for (key => value in _song.eventObjects) {
+ listofnames.push(value.name);
+ }
+
+ listOfEvents.setData(FlxUIDropDownMenu.makeStrIdLabelArray(listofnames, true));
+
+ listOfEvents.selectedLabel = pog.name;
+
+ TimingStruct.clearTimings();
+
+ var currentIndex = 0;
+ for (i in _song.eventObjects)
+ {
+ var name = Reflect.field(i,"name");
+ var type = Reflect.field(i,"type");
+ var pos = Reflect.field(i,"position");
+ var value = Reflect.field(i,"value");
+
+ trace(i.type);
+ if (type == "BPM Change")
+ {
+ var beat:Float = pos;
+
+ var endBeat:Float = Math.POSITIVE_INFINITY;
+
+ TimingStruct.addTiming(beat,value,endBeat, 0); // offset in this case = start time since we don't have a offset
+
+ if (currentIndex != 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;
+ }
+
+ currentIndex++;
+ }
+ }
+ trace("BPM CHANGES:");
+
+ for (i in TimingStruct.AllTimings)
+ trace(i.bpm + " - START: " + i.startBeat + " - END: " + i.endBeat + " - START-TIME: " + i.startTime);
+
+ recalculateAllSectionTimes();
+
+ regenerateLines();
+
+
+ });
+ var eventRemove = new FlxButton(180,155,"Remove Event", function() {
+
+ trace("lets see if we can remove " + listOfEvents.selectedLabel);
+
+ var obj = containsName(listOfEvents.selectedLabel,_song.eventObjects);
+
+ trace(obj);
+
+ if (obj == null)
+ return;
+
+ trace("yeah we can remove it it");
+
+ _song.eventObjects.remove(obj);
+
+ var firstEvent = _song.eventObjects[0];
+
+ if (firstEvent == null)
+ {
+ _song.eventObjects.push(new Song.Event("Init BPM",0,_song.bpm,"BPM Change"));
+ firstEvent = _song.eventObjects[0];
+ }
+
+ eventName.text = firstEvent.name;
+ eventType.selectedLabel = firstEvent.type;
+ eventValue.text = firstEvent.value;
+ eventPos.text = firstEvent.position + "";
+ currentSelectedEventName = firstEvent.name;
+ currentEventPosition = firstEvent.position;
+
+ savedType = firstEvent.type;
+ savedValue = firstEvent.value;
+
+ var listofnames = [];
+
+ for (key => value in _song.eventObjects) {
+ listofnames.push(value.name);
+ }
+
+ listOfEvents.setData(FlxUIDropDownMenu.makeStrIdLabelArray(listofnames, true));
+
+ listOfEvents.selectedLabel = firstEvent.name;
+
+ TimingStruct.clearTimings();
+
+ var currentIndex = 0;
+ for (i in _song.eventObjects)
+ {
+ var name = Reflect.field(i,"name");
+ var type = Reflect.field(i,"type");
+ var pos = Reflect.field(i,"position");
+ var value = Reflect.field(i,"value");
+
+ trace(i.type);
+ if (type == "BPM Change")
+ {
+ var beat:Float = pos;
+
+ var endBeat:Float = Math.POSITIVE_INFINITY;
+
+ TimingStruct.addTiming(beat,value,endBeat, 0); // offset in this case = start time since we don't have a offset
+
+ if (currentIndex != 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;
+ }
+
+ currentIndex++;
+ }
+ }
+
+ recalculateAllSectionTimes();
+
+ regenerateLines();
+
+
+ });
+ var updatePos = new FlxButton(150,120,"Update Pos", function() {
+ var obj = containsName(currentSelectedEventName,_song.eventObjects);
+ if (obj == null)
+ return;
+ currentEventPosition = curDecimalBeat;
+ obj.position = currentEventPosition;
+ eventPos.text = currentEventPosition + "";
+ });
+
+
+
+ var listofnames = [];
+
+ var firstEventObject = null;
+
+ for (event in _song.eventObjects) {
+ var name = Reflect.field(event,"name");
+ var type = Reflect.field(event,"type");
+ var pos = Reflect.field(event,"position");
+ var value = Reflect.field(event,"value");
+
+ trace(value);
+
+ var eventt = new Song.Event(name,pos,value,type);
+
+ chartEvents.push(eventt);
+ listofnames.push(name);
+ }
+
+ _song.eventObjects = chartEvents;
+
+ if (listofnames.length == 0)
+ listofnames.push("");
+
+ if (_song.eventObjects.length != 0)
+ firstEventObject = _song.eventObjects[0];
+ trace("bruh");
+
+
+ if (firstEvent != "")
+ {
+ trace(firstEventObject);
+ eventName.text = firstEventObject.name;
+ trace("bruh");
+ eventType.selectedLabel = firstEventObject.type;
+ trace("bruh");
+ eventValue.text = firstEventObject.value;
+ trace("bruh");
+ currentSelectedEventName = firstEventObject.name;
+ trace("bruh");
+ currentEventPosition = firstEventObject.position;
+ trace("bruh");
+ eventPos.text = currentEventPosition + "";
+ trace("bruh");
+ }
+
+ listOfEvents = new FlxUIDropDownMenu(10,20, FlxUIDropDownMenu.makeStrIdLabelArray(listofnames, true), function(name:String)
+ {
+ var event = containsName(listOfEvents.selectedLabel,_song.eventObjects);
+
+ if (event == null)
+ return;
+
+ trace('selecting ' + name + ' found: ' + event);
+
+ eventName.text = event.name;
+ eventValue.text = event.value;
+ eventPos.text = event.position + "";
+ eventType.selectedLabel = event.type;
+ currentSelectedEventName = event.name;
+ currentEventPosition = event.position;
+ });
+
+ eventValue.callback = function(string:String, string2:String)
+ {
+ trace(string + " - value");
+ savedValue = string;
+ };
+
+ eventType.callback = function(type:String)
+ {
+ savedType = eventType.selectedLabel;
+ };
+
+ eventName.callback = function(string:String, string2:String)
+ {
+ var obj = containsName(currentSelectedEventName,_song.eventObjects);
+ if (obj == null)
+ {
+ currentSelectedEventName = string;
+ return;
+ }
+ obj = containsName(string,_song.eventObjects);
+ if (obj != null)
+ return;
+ obj = containsName(currentSelectedEventName,_song.eventObjects);
+ obj.name = string;
+ currentSelectedEventName = string;
+ };
+ trace("bruh");
+
+ Typeables.push(eventPos);
+ Typeables.push(eventValue);
+ Typeables.push(eventName);
+
+ var tab_events = new FlxUI(null, UI_options);
+ tab_events.name = "Events";
+ tab_events.add(posLabel);
+ tab_events.add(valueLabel);
+ tab_events.add(nameLabel);
+ tab_events.add(listLabel);
+ tab_events.add(typeLabel);
+ tab_events.add(eventName);
+ tab_events.add(eventType);
+ tab_events.add(listOfEvents);
+ tab_events.add(eventValue);
+ tab_events.add(eventSave);
+ tab_events.add(eventAdd);
+ tab_events.add(eventRemove);
+ tab_events.add(eventPos);
+ tab_events.add(updatePos);
+ UI_options.addGroup(tab_events);
+ }
+
function addOptionsUI()
{
- stepperDiv = new FlxUINumericStepper(10, 26, 1, subDivisions, 1, 4);
- stepperDiv.value = 0;
- stepperDiv.name = 'divisions';
-
- var stepperDivLabel = new FlxText(8, 10, 'Grid sub-divisions');
+
var hitsounds = new FlxUICheckBox(10, 60, null, null, "Play hitsounds", 100);
hitsounds.checked = false;
@@ -280,12 +946,8 @@ class ChartingState extends MusicBeatState
var tab_options = new FlxUI(null, UI_options);
tab_options.name = "Options";
- tab_options.add(stepperDiv);
- tab_options.add(stepperDivLabel);
- tab_options.add(check_snap);
tab_options.add(hitsounds);
tab_options.add(check_mute_inst);
-
UI_options.addGroup(tab_options);
}
@@ -345,7 +1007,14 @@ class ChartingState extends MusicBeatState
var stepperSpeedLabel = new FlxText(74,80,'Scroll Speed');
var stepperVocalVol:FlxUINumericStepper = new FlxUINumericStepper(10, 95, 0.1, 1, 0.1, 10, 1);
+ #if sys
+ if (!PlayState.isSM)
+ stepperVocalVol.value = vocals.volume;
+ else
+ stepperVocalVol.value = 1;
+ #else
stepperVocalVol.value = vocals.volume;
+ #end
stepperVocalVol.name = 'song_vocalvol';
var stepperVocalVolLabel = new FlxText(74, 95, 'Vocal Volume');
@@ -417,6 +1086,7 @@ class ChartingState extends MusicBeatState
var noteStyleLabel = new FlxText(10,280,64,'Note Skin');
+
var tab_group_song = new FlxUI(null, UI_box);
tab_group_song.name = "Song";
tab_group_song.add(UI_songTitle);
@@ -477,15 +1147,6 @@ class ChartingState extends MusicBeatState
var tab_group_section = new FlxUI(null, UI_box);
tab_group_section.name = 'Section';
- stepperLength = new FlxUINumericStepper(10, 10, 4, 0, 0, 999, 0);
- stepperLength.value = _song.notes[curSection].lengthInSteps;
- stepperLength.name = "section_length";
-
- var stepperLengthLabel = new FlxText(74,10,'Section Length (in steps)');
-
- stepperSectionBPM = new FlxUINumericStepper(10, 80, 1, Conductor.bpm, 0, 999, 0);
- stepperSectionBPM.value = Conductor.bpm;
- stepperSectionBPM.name = 'section_bpm';
var stepperCopy:FlxUINumericStepper = new FlxUINumericStepper(110, 132, 1, 1, -999, 999, 0);
var stepperCopyLabel = new FlxText(174,132,'sections back');
@@ -499,33 +1160,69 @@ class ChartingState extends MusicBeatState
var swapSection:FlxButton = new FlxButton(10, 170, "Swap Section", function()
{
- for (i in 0..._song.notes[curSection].sectionNotes.length)
+
+ var sect = lastUpdatedSection;
+
+ if (sect != null)
+ return;
+
+ for (i in 0...sect.sectionNotes.length)
{
- var note = _song.notes[curSection].sectionNotes[i];
+ var note = sect.sectionNotes[i];
note[1] = (note[1] + 4) % 8;
- _song.notes[curSection].sectionNotes[i] = note;
+ sect.sectionNotes[i] = note;
updateGrid();
}
});
- check_mustHitSection = new FlxUICheckBox(10, 30, null, null, "Camera Points to P1?", 100);
- check_mustHitSection.name = 'check_mustHit';
+ check_mustHitSection = new FlxUICheckBox(10, 30, null, null, "Camera Points to P1?", 100,null,function() {
+ var sect = lastUpdatedSection;
+
+ trace(sect);
+
+ if (sect != null)
+ return;
+
+ sect.mustHitSection = check_mustHitSection.checked;
+
+ for (i in sectionRenderes)
+ {
+ if (i.section.startTime == sect.startTime)
+ {
+ var cachedY = i.icon.y;
+ remove(i.icon);
+ var sectionicon = check_mustHitSection.checked ? new HealthIcon(_song.player1).clone() : new HealthIcon(_song.player2).clone();
+ sectionicon.x = -95;
+ sectionicon.y = cachedY;
+ sectionicon.setGraphicSize(0, 45);
+
+ i.icon = sectionicon;
+ i.lastUpdated = sect.mustHitSection;
+
+ add(sectionicon);
+ }
+ }
+ });
check_mustHitSection.checked = true;
// _song.needsVoices = check_mustHit.checked;
check_altAnim = new FlxUICheckBox(10, 340, null, null, "Alternate Animation", 100);
check_altAnim.name = 'check_altAnim';
- check_changeBPM = new FlxUICheckBox(10, 60, null, null, 'Change BPM', 100);
- check_changeBPM.name = 'check_changeBPM';
+ var refresh = new FlxButton(10, 60, 'Refresh Section', function() {
+ var section = getSectionByTime(Conductor.songPosition);
- tab_group_section.add(stepperLength);
- tab_group_section.add(stepperLengthLabel);
- tab_group_section.add(stepperSectionBPM);
+ if (section == null)
+ return;
+
+ check_mustHitSection.checked = section.mustHitSection;
+ check_altAnim.checked = section.altAnim;
+ });
+
+ tab_group_section.add(refresh);
tab_group_section.add(stepperCopy);
tab_group_section.add(stepperCopyLabel);
tab_group_section.add(check_mustHitSection);
tab_group_section.add(check_altAnim);
- tab_group_section.add(check_changeBPM);
tab_group_section.add(copyButton);
tab_group_section.add(clearSectionButton);
tab_group_section.add(swapSection);
@@ -545,7 +1242,7 @@ class ChartingState extends MusicBeatState
writingNotesText = new FlxUIText(20,100, 0, "");
writingNotesText.setFormat("Arial",20,FlxColor.WHITE,FlxTextAlign.LEFT,FlxTextBorderStyle.OUTLINE,FlxColor.BLACK);
- stepperSusLength = new FlxUINumericStepper(10, 10, Conductor.stepCrochet / 2, 0, 0, Conductor.stepCrochet * _song.notes[curSection].lengthInSteps * 4);
+ stepperSusLength = new FlxUINumericStepper(10, 10, Conductor.stepCrochet / 2, 0, 0, Conductor.stepCrochet * 16 * 4);
stepperSusLength.value = 0;
stepperSusLength.name = 'note_susLength';
@@ -559,8 +1256,8 @@ class ChartingState extends MusicBeatState
UI_box.addGroup(tab_group_note);
- /*player2 = new Character(0,gridBG.y, _song.player2);
- player1 = new Boyfriend(player2.width * 0.2,gridBG.y + player2.height, _song.player1);
+ /*player2 = new Character(0,0, _song.player2);
+ player1 = new Boyfriend(player2.width * 0.2,0 + player2.height, _song.player1);
player1.y = player1.y - player1.height;
@@ -571,6 +1268,8 @@ class ChartingState extends MusicBeatState
UI_box.add(player2);*/
}
+
+
function loadSong(daSong:String):Void
{
@@ -579,23 +1278,45 @@ class ChartingState extends MusicBeatState
FlxG.sound.music.stop();
// vocals.stop();
}
-
+ #if sys
+ if (PlayState.isSM)
+ {
+ trace("Loading " + PlayState.pathToSm + "/" + PlayState.sm.header.MUSIC);
+ var bytes = File.getBytes(PlayState.pathToSm + "/" + PlayState.sm.header.MUSIC);
+ var sound = new Sound();
+ sound.loadCompressedDataFromByteArray(bytes.getData(), bytes.length);
+ FlxG.sound.playMusic(sound);
+ }
+ else
+ FlxG.sound.playMusic(Paths.inst(daSong), 0.6);
+ #else
FlxG.sound.playMusic(Paths.inst(daSong), 0.6);
+ #end
// WONT WORK FOR TUTORIAL OR TEST SONG!!! REDO LATER
+ #if sys
+ if (PlayState.isSM)
+ vocals = null;
+ else
+ vocals = new FlxSound().loadEmbedded(Paths.voices(daSong));
+ #else
vocals = new FlxSound().loadEmbedded(Paths.voices(daSong));
+ #end
FlxG.sound.list.add(vocals);
FlxG.sound.music.pause();
- vocals.pause();
+ if (!PlayState.isSM)
+ vocals.pause();
FlxG.sound.music.onComplete = function()
{
- vocals.pause();
- vocals.time = 0;
+ if (!PlayState.isSM)
+ {
+ vocals.pause();
+ vocals.time = 0;
+ }
FlxG.sound.music.pause();
FlxG.sound.music.time = 0;
- changeSection();
};
}
@@ -626,13 +1347,8 @@ class ChartingState extends MusicBeatState
var label = check.getLabel().text;
switch (label)
{
- case 'Camera Points to P1?':
- _song.notes[curSection].mustHitSection = check.checked;
- case 'Change BPM':
- _song.notes[curSection].changeBPM = check.checked;
- FlxG.log.add('changed bpm shit');
case "Alternate Animation":
- _song.notes[curSection].altAnim = check.checked;
+ getSectionByTime(Conductor.songPosition).altAnim = check.checked;
}
}
else if (id == FlxUINumericStepper.CHANGE_EVENT && (sender is FlxUINumericStepper))
@@ -646,7 +1362,7 @@ class ChartingState extends MusicBeatState
case 'section_length':
if (nums.value <= 4)
nums.value = 4;
- _song.notes[curSection].lengthInSteps = Std.int(nums.value);
+ getSectionByTime(Conductor.songPosition).lengthInSteps = Std.int(nums.value);
updateGrid();
case 'song_speed':
@@ -673,12 +1389,13 @@ class ChartingState extends MusicBeatState
case 'section_bpm':
if (nums.value <= 0.1)
nums.value = 0.1;
- _song.notes[curSection].bpm = Std.int(nums.value);
+ getSectionByTime(Conductor.songPosition).bpm = Std.int(nums.value);
updateGrid();
case 'song_vocalvol':
if (nums.value <= 0.1)
nums.value = 0.1;
+ if (!PlayState.isSM)
vocals.volume = nums.value;
case 'song_instvol':
@@ -700,27 +1417,27 @@ class ChartingState extends MusicBeatState
/* this function got owned LOL
function lengthBpmBullshit():Float
{
- if (_song.notes[curSection].changeBPM)
- return _song.notes[curSection].lengthInSteps * (_song.notes[curSection].bpm / _song.bpm);
+ if (getSectionByTime(Conductor.songPosition).changeBPM)
+ return getSectionByTime(Conductor.songPosition).lengthInSteps * (getSectionByTime(Conductor.songPosition).bpm / _song.bpm);
else
- return _song.notes[curSection].lengthInSteps;
+ return getSectionByTime(Conductor.songPosition).lengthInSteps;
}*/
+
+
function stepStartTime(step):Float
{
- return _song.bpm / (step / 4) / 60;
+ return Conductor.bpm / (step / 4) / 60;
}
- function sectionStartTime():Float
+ function sectionStartTime(?customIndex:Int = -1):Float
{
- var daBPM:Float = _song.bpm;
+ if (customIndex == -1)
+ customIndex = curSection;
+ var daBPM:Float = Conductor.bpm;
var daPos:Float = 0;
- for (i in 0...curSection)
+ for (i in 0...customIndex)
{
- if (_song.notes[i].changeBPM)
- {
- daBPM = _song.notes[i].bpm;
- }
daPos += 4 * (1000 * 60 / daBPM);
}
return daPos;
@@ -731,22 +1448,167 @@ class ChartingState extends MusicBeatState
public var diff:Float = 0;
+ public var changeIndex = 0;
+
+ public var currentBPM:Float = 0;
+ public var lastBPM:Float = 0;
+
+ public var updateFrame = 0;
+ public var lastUpdatedSection:SwagSection = null;
+
+ public function resizeEverything()
+ {
+ curRenderedNotes.forEach(function(note) {
+ var seg = TimingStruct.getTimingAtTimestamp(note.strumTime);
+ note.y = getYfromStrum(note.strumTime) * zoomFactor;
+ var stepCrochet = (((60 / seg.bpm) * 1000) / 4);
+ if (note.sustainLength >= 2)
+ {
+ note.noteCharterObject.y = note.y + GRID_SIZE;
+ note.noteCharterObject.makeGraphic(8,Math.floor((getYfromStrum(note.strumTime + note.sustainLength) * zoomFactor) - note.y),FlxColor.WHITE);
+ }
+ });
+
+ regenerateLines();
+ }
+
+
+
override function update(elapsed:Float)
{
updateHeads();
- //snapText.text = "Snap: 1/" + snap + " (" + (doSnapShit ? "Shift to disable" : "Snap Disabled, Shift to renable. It's a bit buggy") + ")\nAdd Notes: 1-8 (or click)";
+ var doInput = true;
- curStep = recalculateSteps();
+ for (i in Typeables)
+ {
+ if (i.hasFocus)
+ doInput = false;
+ }
- /*if (FlxG.keys.pressed.CONTROL && FlxG.keys.justPressed.RIGHT)
+ if (doInput)
+ {
+ if (FlxG.mouse.wheel != 0)
+ {
+ FlxG.sound.music.pause();
+
+ if (!PlayState.isSM)
+ vocals.pause();
+ claps.splice(0, claps.length);
+
+
+ if (FlxG.keys.pressed.CONTROL)
+ {
+ var amount = FlxG.mouse.wheel;
+
+ if(amount > 0)
+ amount = 0;
+
+ var increase:Float = 0;
+
+ if (amount < 0)
+ increase = -0.04;
+ else
+ increase = 0.04;
+
+
+ zoomFactor += increase;
+
+ if (zoomFactor > 2)
+ zoomFactor = 2;
+
+ if (zoomFactor < 0.1)
+ zoomFactor = 0.1;
+
+ resizeEverything();
+ }
+ else
+ {
+ var amount = FlxG.mouse.wheel;
+
+ if(amount > 0 && strumLine.y < 0)
+ amount = 0;
+
+ if (doSnapShit)
+ {
+ var increase:Float = 0;
+ var beats:Float = 0;
+
+ if (amount < 0)
+ {
+ increase = 1 / deezNuts.get(snap);
+ beats = (Math.floor((curDecimalBeat * deezNuts.get(snap)) + 0.001) / deezNuts.get(snap)) + increase;
+ }
+ else
+ {
+ increase = -1 / deezNuts.get(snap);
+ beats = ((Math.ceil(curDecimalBeat * deezNuts.get(snap)) - 0.001) / deezNuts.get(snap)) + increase;
+ }
+
+ trace("SNAP - " + snap + " INCREASE - " + increase + " - GO TO BEAT " + beats);
+
+ var data = TimingStruct.getTimingAtBeat(beats);
+
+ var bpm = data != null ? data.bpm : _song.bpm;
+
+ if (data != null)
+ {
+
+ FlxG.sound.music.time = (data.startTime + ((beats - data.startBeat) / (bpm/60)) ) * 1000;
+ }
+ }
+ if (!PlayState.isSM)
+ vocals.time = FlxG.sound.music.time;
+ }
+ }
+ }
+
+ if (updateFrame == 4)
+ {
+ TimingStruct.clearTimings();
+
+ var currentIndex = 0;
+ for (i in _song.eventObjects)
+ {
+ if (i.type == "BPM Change")
+ {
+ var beat:Float = i.position;
+
+ var endBeat:Float = Math.POSITIVE_INFINITY;
+
+ TimingStruct.addTiming(beat,i.value,endBeat, 0); // offset in this case = start time since we don't have a offset
+
+ if (currentIndex != 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;
+ }
+
+ currentIndex++;
+ }
+ }
+
+ recalculateAllSectionTimes();
+
+ regenerateLines();
+ updateFrame++;
+ }
+ else if (updateFrame != 5)
+ updateFrame++;
+
+ snapText.text = "Snap: 1/" + snap + " (" + (doSnapShit ? "Shift to disable, Left or Right to increase/decrease" : "Snap Disabled, Shift to renable.") + ")\nAdd Notes: 1-8 (or click)\nZoom: " + zoomFactor;
+
+
+ if (FlxG.keys.justPressed.RIGHT)
snap = snap * 2;
- if (FlxG.keys.pressed.CONTROL && FlxG.keys.justPressed.LEFT)
+ if (FlxG.keys.justPressed.LEFT)
snap = Math.round(snap / 2);
- if (snap >= 192)
- snap = 192;
- if (snap <= 1)
- snap = 1;*/
+ if (snap >= 64)
+ snap = 64;
+ if (snap <= 4)
+ snap = 4;
/*
if (FlxG.keys.justPressed.SHIFT)
doSnapShit = !doSnapShit;
@@ -758,11 +1620,66 @@ class ChartingState extends MusicBeatState
doSnapShit = !defaultSnap;
}
+
check_snap.checked = doSnapShit;
Conductor.songPosition = FlxG.sound.music.time;
_song.song = typingShit.text;
+
+ var timingSeg = TimingStruct.getTimingAtTimestamp(Conductor.songPosition);
+
+ var start = Conductor.songPosition;
+
+ if (timingSeg != null)
+ {
+ var timingSegBpm = timingSeg.bpm;
+ currentBPM = timingSegBpm;
+
+ if (currentBPM != Conductor.bpm)
+ {
+ trace("BPM CHANGE to " + currentBPM);
+ Conductor.changeBPM(currentBPM, false);
+ }
+
+ var pog:Float = (curDecimalBeat - timingSeg.startBeat) / (Conductor.bpm / 60);
+
+ start = (timingSeg.startTime + pog) * 1000;
+ }
+
+
+ var weird = getSectionByTime(start, true);
+
+ FlxG.watch.addQuick("Section",weird);
+
+ if (weird != null)
+ {
+ if (lastUpdatedSection != getSectionByTime(start,true))
+ {
+ lastUpdatedSection = weird;
+ check_mustHitSection.checked = weird.mustHitSection;
+ check_altAnim.checked = weird.altAnim;
+ }
+ }
+
+
+ strumLine.y = getYfromStrum(start) * zoomFactor;
+ camFollow.y = strumLine.y;
+
+
+ bpmTxt.text = Std.string(FlxMath.roundDecimal(Conductor.songPosition / 1000, 2))
+ + " / "
+ + Std.string(FlxMath.roundDecimal(FlxG.sound.music.length / 1000, 2))
+ + "\nCur Section: "
+ + curSection
+ + "\nCurBPM: "
+ + currentBPM
+ + "\nCurBeat: "
+ + HelperFunctions.truncateFloat(curDecimalBeat,3)
+ + "\nZoom: "
+ + zoomFactor;
+
+
var left = FlxG.keys.justPressed.ONE;
var down = FlxG.keys.justPressed.TWO;
var up = FlxG.keys.justPressed.THREE;
@@ -774,6 +1691,8 @@ class ChartingState extends MusicBeatState
var pressArray = [left, down, up, right, leftO, downO, upO, rightO];
var delete = false;
+ if (doInput)
+ {
curRenderedNotes.forEach(function(note:Note)
{
if (strumLine.overlaps(note) && pressArray[Math.floor(Math.abs(note.noteData))])
@@ -791,10 +1710,7 @@ class ChartingState extends MusicBeatState
addNote(new Note(Conductor.songPosition,p));
}
}
-
- strumLine.y = getYfromStrum((Conductor.songPosition - sectionStartTime()) % (Conductor.stepCrochet * _song.notes[curSection].lengthInSteps));
- camFollow.y = strumLine.y;
-
+ }
if (playClaps)
{
@@ -802,21 +1718,21 @@ class ChartingState extends MusicBeatState
{
if (FlxG.sound.music.playing)
{
- FlxG.overlap(strumLine, note, function(_, _)
+ if (strumLine.overlaps(note))
{
if(!claps.contains(note))
{
claps.push(note);
FlxG.sound.play(Paths.sound('SNAP'));
}
- });
+ }
}
});
}
/*curRenderedNotes.forEach(function(note:Note) {
if (strumLine.overlaps(note) && strumLine.y == note.y) // yandere dev type shit
{
- if (_song.notes[curSection].mustHitSection)
+ if (getSectionByTime(Conductor.songPosition).mustHitSection)
{
trace('must hit ' + Math.abs(note.noteData));
if (note.noteData < 4)
@@ -883,23 +1799,10 @@ class ChartingState extends MusicBeatState
}
});*/
- if (curBeat % 4 == 0 && curStep >= 16 * (curSection + 1))
- {
- trace(curStep);
- trace((_song.notes[curSection].lengthInSteps) * (curSection + 1));
- trace('DUMBSHIT');
- if (_song.notes[curSection + 1] == null)
- {
- addSection();
- }
-
- changeSection(curSection + 1, false);
- }
-
- FlxG.watch.addQuick('daBeat', curBeat);
- FlxG.watch.addQuick('daStep', curStep);
+ FlxG.watch.addQuick('daBeat', curDecimalBeat);
+
if (FlxG.mouse.justPressed)
{
if (FlxG.mouse.overlaps(curRenderedNotes))
@@ -921,10 +1824,10 @@ class ChartingState extends MusicBeatState
}
else
{
- if (FlxG.mouse.x > gridBG.x
- && FlxG.mouse.x < gridBG.x + gridBG.width
- && FlxG.mouse.y > gridBG.y
- && FlxG.mouse.y < gridBG.y + (GRID_SIZE * _song.notes[curSection].lengthInSteps))
+ if (FlxG.mouse.x > 0
+ && FlxG.mouse.x < 0 + gridBG.width
+ && FlxG.mouse.y > 0
+ && FlxG.mouse.y < 0 + height)
{
FlxG.log.add('added note');
addNote();
@@ -932,44 +1835,42 @@ class ChartingState extends MusicBeatState
}
}
- if (FlxG.mouse.x > gridBG.x
- && FlxG.mouse.x < gridBG.x + gridBG.width
- && FlxG.mouse.y > gridBG.y
- && FlxG.mouse.y < gridBG.y + (GRID_SIZE * _song.notes[curSection].lengthInSteps))
+ if (FlxG.mouse.x > 0
+ && FlxG.mouse.x < gridBG.width
+ && FlxG.mouse.y > 0
+ && FlxG.mouse.y < height)
{
dummyArrow.visible = true;
dummyArrow.x = Math.floor(FlxG.mouse.x / GRID_SIZE) * GRID_SIZE;
- var div_by:Float = GRID_SIZE / subDivisions;
-
- if (doSnapShit)
- dummyArrow.y = Math.floor(FlxG.mouse.y / div_by) * div_by;
- else
- dummyArrow.y = FlxG.mouse.y;
+ dummyArrow.y = (Math.floor(FlxG.mouse.y / deezNuts.get(snap)) * deezNuts.get(snap));
}
else
{
dummyArrow.visible = false;
}
+ if (doInput)
+ {
if (FlxG.keys.justPressed.ENTER)
{
lastSection = curSection;
PlayState.SONG = _song;
FlxG.sound.music.stop();
+ if (!PlayState.isSM)
vocals.stop();
LoadingState.loadAndSwitchState(new PlayState());
}
if (FlxG.keys.justPressed.E)
{
- changeNoteSustain(Conductor.stepCrochet);
+ changeNoteSustain(((60 / (timingSeg != null ? timingSeg.bpm : _song.bpm)) * 1000) / 4);
}
if (FlxG.keys.justPressed.Q)
{
- changeNoteSustain(-Conductor.stepCrochet);
+ changeNoteSustain(-(((60 / (timingSeg != null ? timingSeg.bpm : _song.bpm)) * 1000) / 4));
}
if (FlxG.keys.justPressed.TAB)
@@ -1006,23 +1907,18 @@ class ChartingState extends MusicBeatState
var shiftThing:Int = 1;
if (FlxG.keys.pressed.SHIFT)
shiftThing = 4;
- if (!FlxG.keys.pressed.CONTROL)
- {
- if (FlxG.keys.justPressed.RIGHT || FlxG.keys.justPressed.D)
- changeSection(curSection + shiftThing);
- if (FlxG.keys.justPressed.LEFT || FlxG.keys.justPressed.A)
- changeSection(curSection - shiftThing);
- }
if (FlxG.keys.justPressed.SPACE)
{
if (FlxG.sound.music.playing)
{
FlxG.sound.music.pause();
+ if (!PlayState.isSM)
vocals.pause();
claps.splice(0, claps.length);
}
else
{
+ if (!PlayState.isSM)
vocals.play();
FlxG.sound.music.play();
}
@@ -1037,48 +1933,15 @@ class ChartingState extends MusicBeatState
}
- if (FlxG.sound.music.time < 0 || curStep < 0)
+ if (FlxG.sound.music.time < 0 || curDecimalBeat < 0)
FlxG.sound.music.time = 0;
- if (FlxG.mouse.wheel != 0)
- {
- FlxG.sound.music.pause();
- vocals.pause();
- claps.splice(0, claps.length);
-
- var amount = FlxG.mouse.wheel;
-
- if(amount > 0 && strumLine.y < gridBG.y)
- amount = 0;
-
- if (doSnapShit)
- {
- var increase:Int = 0;
-
- if (amount < 0)
- increase = 1;
- else
- increase = -1;
-
- trace(increase + " - " + curStep + " - " + (curStep + increase));
-
- // *Maybe a pre-snap goes here but I don't really know, I don't chart with number keys
- FlxG.sound.music.time += (increase * Conductor.stepCrochet) / subDivisions;
-
- var msStep = FlxG.sound.music.time / Conductor.stepCrochet;
-
- curStep = Std.int(msStep);
- }
- else
- FlxG.sound.music.time -= (amount * Conductor.stepCrochet * 0.4);
- vocals.time = FlxG.sound.music.time;
- }
-
if (!FlxG.keys.pressed.SHIFT)
{
if (FlxG.keys.pressed.W || FlxG.keys.pressed.S)
{
FlxG.sound.music.pause();
+ if (!PlayState.isSM)
vocals.pause();
claps.splice(0, claps.length);
@@ -1091,6 +1954,7 @@ class ChartingState extends MusicBeatState
else
FlxG.sound.music.time += daTime;
+ if (!PlayState.isSM)
vocals.time = FlxG.sound.music.time;
}
}
@@ -1099,6 +1963,7 @@ class ChartingState extends MusicBeatState
if (FlxG.keys.justPressed.W || FlxG.keys.justPressed.S)
{
FlxG.sound.music.pause();
+ if (!PlayState.isSM)
vocals.pause();
var daTime:Float = Conductor.stepCrochet * 2;
@@ -1110,25 +1975,18 @@ class ChartingState extends MusicBeatState
else
FlxG.sound.music.time += daTime;
+ if (!PlayState.isSM)
vocals.time = FlxG.sound.music.time;
}
}
}
-
+ }
_song.bpm = tempBpm;
/* if (FlxG.keys.justPressed.UP)
Conductor.changeBPM(Conductor.bpm + 1);
if (FlxG.keys.justPressed.DOWN)
Conductor.changeBPM(Conductor.bpm - 1); */
-
- bpmTxt.text = bpmTxt.text = Std.string(FlxMath.roundDecimal(Conductor.songPosition / 1000, 2))
- + " / "
- + Std.string(FlxMath.roundDecimal(FlxG.sound.music.length / 1000, 2))
- + "\nSection: "
- + curSection
- + "\nCurStep: "
- + curStep;
super.update(elapsed);
}
@@ -1147,58 +2005,21 @@ class ChartingState extends MusicBeatState
updateGrid();
}
- override function beatHit()
- {
- trace('beat');
-
- super.beatHit();
- if (!player2.animation.curAnim.name.startsWith("sing"))
- {
- player2.playAnim('idle');
- }
- player1.dance();
- }
-
- function recalculateSteps():Int
- {
- var lastChange:BPMChangeEvent = {
- stepTime: 0,
- songTime: 0,
- bpm: 0
- }
- for (i in 0...Conductor.bpmChangeMap.length)
- {
- if (FlxG.sound.music.time > Conductor.bpmChangeMap[i].songTime)
- lastChange = Conductor.bpmChangeMap[i];
- }
-
- curStep = lastChange.stepTime + Math.floor((FlxG.sound.music.time - lastChange.songTime) / Conductor.stepCrochet);
- updateBeat();
-
- return curStep;
- }
-
function resetSection(songBeginning:Bool = false):Void
{
- updateGrid();
-
FlxG.sound.music.pause();
+ if (!PlayState.isSM)
vocals.pause();
// Basically old shit from changeSection???
- FlxG.sound.music.time = sectionStartTime();
-
- if (songBeginning)
- {
- FlxG.sound.music.time = 0;
- curSection = 0;
- }
+ FlxG.sound.music.time = 0;
+ if (!PlayState.isSM)
vocals.time = FlxG.sound.music.time;
- updateCurStep();
updateGrid();
- updateSectionUI();
+ if (!songBeginning)
+ updateSectionUI();
}
function changeSection(sec:Int = 0, ?updateMusic:Bool = true):Void
@@ -1215,6 +2036,7 @@ class ChartingState extends MusicBeatState
if (updateMusic)
{
FlxG.sound.music.pause();
+ if (!PlayState.isSM)
vocals.pause();
/*var daNum:Int = 0;
@@ -1226,6 +2048,7 @@ class ChartingState extends MusicBeatState
}*/
FlxG.sound.music.time = sectionStartTime();
+ if (!PlayState.isSM)
vocals.time = FlxG.sound.music.time;
updateCurStep();
}
@@ -1240,13 +2063,17 @@ class ChartingState extends MusicBeatState
function copySection(?sectionNum:Int = 1)
{
var daSec = FlxMath.maxInt(curSection, sectionNum);
+ var sect = lastUpdatedSection;
+
+ if (sect != null)
+ return;
for (note in _song.notes[daSec - sectionNum].sectionNotes)
{
var strum = note[0] + Conductor.stepCrochet * (_song.notes[daSec].lengthInSteps * sectionNum);
var copiedNote:Array = [strum, note[1], note[2]];
- _song.notes[daSec].sectionNotes.push(copiedNote);
+ sect.sectionNotes.push(copiedNote);
}
updateGrid();
@@ -1254,13 +2081,19 @@ class ChartingState extends MusicBeatState
function updateSectionUI():Void
{
- var sec = _song.notes[curSection];
+ var sec = getSectionByTime(Conductor.songPosition);
- stepperLength.value = sec.lengthInSteps;
- check_mustHitSection.checked = sec.mustHitSection;
- check_altAnim.checked = sec.altAnim;
- check_changeBPM.checked = sec.changeBPM;
- stepperSectionBPM.value = sec.bpm;
+ if (sec == null)
+ {
+ check_mustHitSection.checked = true;
+ check_altAnim.checked = false;
+ }
+ else
+ {
+ check_mustHitSection.checked = sec.mustHitSection;
+ check_altAnim.checked = sec.altAnim;
+ check_changeBPM.checked = sec.changeBPM;
+ }
}
function updateHeads():Void
@@ -1285,12 +2118,6 @@ class ChartingState extends MusicBeatState
function updateGrid():Void
{
- addGrid(subDivisions);
-
- remove(gridBlackLine);
- gridBlackLine = new FlxSprite(gridBG.x + gridBG.width / 2).makeGraphic(2, Std.int(gridBG.height), FlxColor.BLACK);
- add(gridBlackLine);
-
while (curRenderedNotes.members.length > 0)
{
curRenderedNotes.remove(curRenderedNotes.members[0], true);
@@ -1301,23 +2128,6 @@ class ChartingState extends MusicBeatState
curRenderedSustains.remove(curRenderedSustains.members[0], true);
}
- var sectionInfo:Array = _song.notes[curSection].sectionNotes;
-
- if (_song.notes[curSection].changeBPM && _song.notes[curSection].bpm > 0)
- {
- Conductor.changeBPM(_song.notes[curSection].bpm);
- FlxG.log.add('CHANGED BPM!');
- }
- else
- {
- // get last bpm
- var daBPM:Float = _song.bpm;
- for (i in 0...curSection)
- if (_song.notes[i].changeBPM)
- daBPM = _song.notes[i].bpm;
- Conductor.changeBPM(daBPM);
- }
-
/* // PORT BULLSHIT, INCASE THERE'S NO SUSTAIN DATA FOR A NOTE
for (sec in 0..._song.notes.length)
{
@@ -1332,39 +2142,69 @@ class ChartingState extends MusicBeatState
}
*/
- for (i in sectionInfo)
+ var currentSection = 0;
+
+ for (section in _song.notes)
{
- var daNoteInfo = i[1];
- var daStrumTime = i[0];
- var daSus = i[2];
-
- var note:Note = new Note(daStrumTime, daNoteInfo % 4,null,false,true);
- note.rawNoteData = daNoteInfo;
- note.sustainLength = daSus;
- note.setGraphicSize(GRID_SIZE, GRID_SIZE);
- note.updateHitbox();
- note.x = Math.floor(daNoteInfo * GRID_SIZE);
- note.y = Math.floor(getYfromStrum((daStrumTime - sectionStartTime()) % (Conductor.stepCrochet * _song.notes[curSection].lengthInSteps)));
-
- if (curSelectedNote != null)
- if (curSelectedNote[0] == note.strumTime)
- lastNote = note;
-
- curRenderedNotes.add(note);
-
- if (daSus > 0)
+ for (i in section.sectionNotes)
{
- var sustainVis:FlxSprite = new FlxSprite(note.x + (GRID_SIZE / 2),
- note.y + GRID_SIZE).makeGraphic(8, Math.floor(FlxMath.remapToRange(daSus, 0, Conductor.stepCrochet * _song.notes[curSection].lengthInSteps, 0, gridBG.height)));
- curRenderedSustains.add(sustainVis);
+ var seg = TimingStruct.getTimingAtTimestamp(i[0]);
+ var daNoteInfo = i[1];
+ var daStrumTime = i[0];
+ var daSus = i[2];
+
+ var note:Note = new Note(daStrumTime, daNoteInfo % 4,null,false,true);
+ note.rawNoteData = daNoteInfo;
+ note.sustainLength = daSus;
+ note.setGraphicSize(Math.floor(GRID_SIZE), Math.floor(GRID_SIZE));
+ note.updateHitbox();
+ note.x = Math.floor(daNoteInfo * GRID_SIZE);
+
+ note.y = Math.floor(getYfromStrum(daStrumTime) * zoomFactor);
+
+ if (curSelectedNote != null)
+ if (curSelectedNote[0] == note.strumTime)
+ lastNote = note;
+
+ curRenderedNotes.add(note);
+
+ var stepCrochet = (((60 / seg.bpm) * 1000) / 4);
+
+ if (daSus > 0)
+ {
+ var sustainVis:FlxSprite = new FlxSprite(note.x + (GRID_SIZE / 2),
+ note.y + GRID_SIZE).makeGraphic(8, Math.floor((getYfromStrum(daStrumTime + daSus) - note.y) * zoomFactor));
+
+ note.noteCharterObject = sustainVis;
+
+ curRenderedSustains.add(sustainVis);
+ }
}
+ currentSection++;
}
}
private function addSection(lengthInSteps:Int = 16):Void
{
+ var daPos:Float = 0;
+ var start:Float = 0;
+
+ var bpm = _song.bpm;
+ for (i in 0...curSection)
+ {
+ for(ii in TimingStruct.AllTimings)
+ {
+ var data = TimingStruct.getTimingAtTimestamp(start);
+ if ((data != null ? data.bpm : _song.bpm) != bpm && bpm != ii.bpm)
+ bpm = ii.bpm;
+ }
+ start += (4 * (60 / bpm)) * 1000;
+ }
+
var sec:SwagSection = {
+ startTime: daPos,
+ endTime: Math.POSITIVE_INFINITY,
lengthInSteps: lengthInSteps,
bpm: _song.bpm,
changeBPM: false,
@@ -1381,11 +2221,11 @@ class ChartingState extends MusicBeatState
{
var swagNum:Int = 0;
- for (i in _song.notes[curSection].sectionNotes)
+ for (i in getSectionByTime(note.strumTime).sectionNotes)
{
if (i[0] == note.strumTime && i[1] == note.rawNoteData)
{
- curSelectedNote = _song.notes[curSection].sectionNotes[swagNum];
+ curSelectedNote = getSectionByTime(note.strumTime).sectionNotes[swagNum];
}
swagNum += 1;
@@ -1399,20 +2239,40 @@ class ChartingState extends MusicBeatState
function deleteNote(note:Note):Void
{
lastNote = note;
- for (i in _song.notes[curSection].sectionNotes)
+
+ var section = getSectionByTime(note.strumTime);
+
+ trace(section);
+
+ var found = false;
+
+ for (i in section.sectionNotes)
{
if (i[0] == note.strumTime && i[1] == note.rawNoteData)
{
- _song.notes[curSection].sectionNotes.remove(i);
+ section.sectionNotes.remove(i);
+ found = true;
+ }
+ }
+
+ if (!found) // backup check
+ {
+ for(i in _song.notes)
+ {
+ for (n in i.sectionNotes)
+ if (n[0] == note.strumTime && n[1] == note.rawNoteData)
+ i.sectionNotes.remove(n);
}
}
+ trace("DELETED!");
+
updateGrid();
}
function clearSection():Void
{
- _song.notes[curSection].sectionNotes = [];
+ getSectionByTime(Conductor.songPosition).sectionNotes = [];
updateGrid();
}
@@ -1429,7 +2289,26 @@ class ChartingState extends MusicBeatState
private function newSection(lengthInSteps:Int = 16,mustHitSection:Bool = false,altAnim:Bool = true):SwagSection
{
+
+ var daPos:Float = 0;
+
+ var currentSeg = TimingStruct.AllTimings[TimingStruct.AllTimings.length - 1];
+
+ var currentBeat = 4;
+
+ for(i in _song.notes)
+ currentBeat += 4;
+
+ if (currentSeg == null)
+ return null;
+
+ var start:Float = (currentBeat - currentSeg.startBeat) / (currentSeg.bpm / 60);
+
+ daPos = (currentSeg.startTime + start) * 1000;
+
var sec:SwagSection = {
+ startTime: daPos,
+ endTime: Math.POSITIVE_INFINITY,
lengthInSteps: lengthInSteps,
bpm: _song.bpm,
changeBPM: false,
@@ -1439,15 +2318,67 @@ class ChartingState extends MusicBeatState
altAnim: altAnim
};
+
return sec;
}
+ function recalculateAllSectionTimes()
+ {
+
+ /*if (TimingStruct.AllTimings.length > 0)
+ {
+ trace("Song length in MS: " + FlxG.sound.music.length);
+
+ for(i in 0...9000000) // REALLY HIGH BEATS just cuz like ig this is the upper limit, I mean ur chart is probably going to run like ass anyways
+ {
+ var seg = TimingStruct.getTimingAtBeat(i);
+
+ var time = (i / (seg.bpm / 60)) * 1000;
+
+ if (time > FlxG.sound.music.length)
+ break;
+
+ lengthInBeats = i;
+ }
+
+ lengthInSteps = lengthInBeats * 4;
+
+ trace('LENGTH IN STEPS ' + lengthInSteps + ' | LENGTH IN BEATS ' + lengthInBeats);
+ }*/
+
+ trace("RECALCULATING SECTION TIMES");
+ for (i in 0..._song.notes.length) // loops through sections
+ {
+ var section = _song.notes[i];
+
+ var currentBeat = 4 * i;
+
+ var currentSeg = TimingStruct.getTimingAtBeat(currentBeat);
+
+ if (currentSeg == null)
+ return;
+
+ var start:Float = (currentBeat - currentSeg.startBeat) / (currentSeg.bpm / 60);
+
+ section.startTime = (currentSeg.startTime + start) * 1000;
+
+ if (i != 0)
+ _song.notes[i - 1].endTime = section.startTime;
+ section.endTime = Math.POSITIVE_INFINITY;
+
+ }
+ once = true;
+ }
+
+ var once = false;
+
+
function shiftNotes(measure:Int=0,step:Int=0,ms:Int = 0):Void
{
var newSong = [];
- var millisecadd = (((measure*4)+step/4)*(60000/_song.bpm))+ms;
- var totaladdsection = Std.int((millisecadd/(60000/_song.bpm)/4));
+ var millisecadd = (((measure*4)+step/4)*(60000/currentBPM))+ms;
+ var totaladdsection = Std.int((millisecadd/(60000/currentBPM)/4));
trace(millisecadd,totaladdsection);
if(millisecadd > 0)
{
@@ -1475,7 +2406,7 @@ class ChartingState extends MusicBeatState
{
newtiming = 0;
}
- var futureSection = Math.floor(newtiming/4/(60000/_song.bpm));
+ var futureSection = Math.floor(newtiming/4/(60000/currentBPM));
_song.notes[daSection].sectionNotes[daNote][0] = newtiming;
newSong[futureSection].sectionNotes.push(_song.notes[daSection].sectionNotes[daNote]);
@@ -1485,22 +2416,68 @@ class ChartingState extends MusicBeatState
}
//trace("DONE BITCH");
_song.notes = newSong;
+ recalculateAllSectionTimes();
updateGrid();
updateSectionUI();
updateNoteUI();
}
+
+ public function getSectionByTime(ms:Float, ?changeCurSectionIndex:Bool = false):SwagSection
+ {
+ var index = 0;
+
+
+
+ for (i in _song.notes)
+ {
+ if (ms >= i.startTime && ms < i.endTime)
+ {
+ if (changeCurSectionIndex)
+ curSection = index;
+ return i;
+ }
+ index++;
+ }
+
+
+ return null;
+ }
+
+ public function getNoteByTime(ms:Float)
+ {
+ for(i in _song.notes)
+ {
+ for(n in i.sectionNotes)
+ if (n[0] == ms)
+ return i;
+ }
+ return null;
+ }
+
+
private function addNote(?n:Note):Void
{
- var noteStrum = getStrumTime(dummyArrow.y) + sectionStartTime();
+ var strum = getStrumTime(dummyArrow.y) / zoomFactor;
+
+ trace(strum + " from " + dummyArrow.y);
+
+ trace("adding note with " + strum + " from dummyArrow");
+
+ var section = getSectionByTime(strum);
+
+ if (section == null)
+ return;
+
+ var noteStrum = strum;
var noteData = Math.floor(FlxG.mouse.x / GRID_SIZE);
var noteSus = 0;
if (n != null)
- _song.notes[curSection].sectionNotes.push([n.strumTime, n.noteData, n.sustainLength]);
+ section.sectionNotes.push([n.strumTime, n.noteData, n.sustainLength]);
else
- _song.notes[curSection].sectionNotes.push([noteStrum, noteData, noteSus]);
+ section.sectionNotes.push([noteStrum, noteData, noteSus]);
- var thingy = _song.notes[curSection].sectionNotes[_song.notes[curSection].sectionNotes.length - 1];
+ var thingy = section.sectionNotes[section.sectionNotes.length - 1];
curSelectedNote = thingy;
@@ -1512,12 +2489,12 @@ class ChartingState extends MusicBeatState
function getStrumTime(yPos:Float):Float
{
- return FlxMath.remapToRange(yPos, gridBG.y, gridBG.y + gridBG.height, 0, 16 * Conductor.stepCrochet);
+ return FlxMath.remapToRange(yPos, 0, lengthInSteps, 0, lengthInSteps);
}
function getYfromStrum(strumTime:Float):Float
{
- return FlxMath.remapToRange(strumTime, 0, 16 * Conductor.stepCrochet, gridBG.y, gridBG.y + gridBG.height);
+ return FlxMath.remapToRange(strumTime, 0, lengthInSteps, 0, lengthInSteps);
}
/*
@@ -1611,7 +2588,7 @@ class ChartingState extends MusicBeatState
/**
* Called when the save file dialog is cancelled.
- */
+ */
function onSaveCancel(_):Void
{
_file.removeEventListener(Event.COMPLETE, onSaveComplete);
diff --git a/source/Conductor.hx b/source/Conductor.hx
index 4560078..f5c40c1 100644
--- a/source/Conductor.hx
+++ b/source/Conductor.hx
@@ -28,8 +28,6 @@ class Conductor
public static var safeZoneOffset:Float = Math.floor((safeFrames / 60) * 1000); // is calculated in create(), is safeFrames in milliseconds
public static var timeScale:Float = Conductor.safeZoneOffset / 166;
- public static var lengthInSteps:Float = 0;
-
public static var bpmChangeMap:Array = [];
public function new()
@@ -70,15 +68,27 @@ class Conductor
trace("new BPM map BUDDY " + bpmChangeMap);
}
- public static function changeBPM(newBpm:Float)
+ public static function recalculateTimingStruct(SONG:Song)
+ {
+ for(i in SONG.eventObjects)
+ {
+ /*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;
+ }*/
+ }
+ }
+
+ public static function changeBPM(newBpm:Float, ?recalcLength = true)
{
bpm = newBpm;
crochet = ((60 / bpm) * 1000);
stepCrochet = crochet / 4;
-
- lengthInSteps = (FlxG.sound.music.length / stepCrochet);
-
- trace("\nLength in in steps: " + lengthInSteps);
}
}
\ No newline at end of file
diff --git a/source/FreeplayState.hx b/source/FreeplayState.hx
index 123e240..12ce62a 100644
--- a/source/FreeplayState.hx
+++ b/source/FreeplayState.hx
@@ -1,5 +1,12 @@
package;
-
+import openfl.utils.Future;
+import openfl.media.Sound;
+import flixel.system.FlxSound;
+#if sys
+import smTools.SMFile;
+import sys.FileSystem;
+import sys.io.File;
+#end
import Song.SwagSong;
import flixel.input.gamepad.FlxGamepad;
import flash.text.TextField;
@@ -63,6 +70,9 @@ class FreeplayState extends MusicBeatState
//var diffList = "";
+ songData = [];
+ songs = [];
+
for (i in 0...initSonglist.length)
{
var data:Array = initSonglist[i].split(':');
@@ -83,6 +93,35 @@ class FreeplayState extends MusicBeatState
}
+ trace("tryin to load sm files");
+
+ #if sys
+ for(i in FileSystem.readDirectory("assets/sm/"))
+ {
+ trace(i);
+ if (FileSystem.isDirectory("assets/sm/" + i))
+ {
+ trace("Reading SM file dir " + i);
+ for (file in FileSystem.readDirectory("assets/sm/" + i))
+ {
+ if (file.contains(" "))
+ FileSystem.rename("assets/sm/" + i + "/" + file,"assets/sm/" + i + "/" + file.replace(" ","_"));
+ if (file.endsWith(".sm"))
+ {
+ trace("reading " + file);
+ var file:SMFile = SMFile.loadFile("assets/sm/" + i + "/" + file.replace(" ","_"));
+ trace("Converting " + file.header.TITLE);
+ var data = file.convertToFNF("assets/sm/" + i + "/converted.json");
+ var meta = new SongMetadata(file.header.TITLE, 0, "sm",file,"assets/sm/" + i);
+ songs.push(meta);
+ var song = Song.loadFromJsonRAW(data);
+ songData.set(file.header.TITLE, [song,song,song]);
+ }
+ }
+ }
+ }
+ #end
+
//trace("\n" + diffList);
/*
@@ -315,6 +354,18 @@ class FreeplayState extends MusicBeatState
PlayState.storyDifficulty = curDifficulty;
PlayState.storyWeek = songs[curSelected].week;
trace('CUR WEEK' + PlayState.storyWeek);
+ #if sys
+ if (songs[curSelected].songCharacter == "sm")
+ {
+ PlayState.isSM = true;
+ PlayState.sm = songs[curSelected].sm;
+ PlayState.pathToSm = songs[curSelected].path;
+ }
+ else
+ PlayState.isSM = false;
+ #else
+ PlayState.isSM = false;
+ #end
LoadingState.loadAndSwitchState(new PlayState());
}
}
@@ -328,6 +379,7 @@ class FreeplayState extends MusicBeatState
if (curDifficulty > 2)
curDifficulty = 0;
+
// adjusting the highscore song name to be compatible (changeDiff)
var songHighscore = StringTools.replace(songs[curSelected].songName, " ", "-");
switch (songHighscore) {
@@ -353,6 +405,7 @@ class FreeplayState extends MusicBeatState
FlxG.sound.play(Paths.sound('scrollMenu'), 0.4);
+
curSelected += change;
if (curSelected < 0)
@@ -379,7 +432,17 @@ class FreeplayState extends MusicBeatState
diffCalcText.text = 'RATING: ${DiffCalc.CalculateDiff(songData.get(songs[curSelected].songName)[curDifficulty])}';
#if PRELOAD_ALL
- FlxG.sound.playMusic(Paths.inst(songs[curSelected].songName), 0);
+ if (songs[curSelected].songCharacter == "sm")
+ {
+ var data = songs[curSelected];
+ trace("Loading " + data.path + "/" + data.sm.header.MUSIC);
+ var bytes = File.getBytes(data.path + "/" + data.sm.header.MUSIC);
+ var sound = new Sound();
+ sound.loadCompressedDataFromByteArray(bytes.getData(), bytes.length);
+ FlxG.sound.playMusic(sound);
+ }
+ else
+ FlxG.sound.playMusic(Paths.inst(songs[curSelected].songName), 0);
#end
var hmm;
@@ -428,12 +491,27 @@ class SongMetadata
{
public var songName:String = "";
public var week:Int = 0;
+ #if sys
+ public var sm:SMFile;
+ public var path:String;
+ #end
public var songCharacter:String = "";
+ #if sys
+ public function new(song:String, week:Int, songCharacter:String, ?sm:SMFile = null, ?path:String = "")
+ {
+ this.songName = song;
+ this.week = week;
+ this.songCharacter = songCharacter;
+ this.sm = sm;
+ this.path = path;
+ }
+ #else
public function new(song:String, week:Int, songCharacter:String)
{
this.songName = song;
this.week = week;
this.songCharacter = songCharacter;
}
+ #end
}
diff --git a/source/HealthIcon.hx b/source/HealthIcon.hx
index 74f46a1..5a9b044 100644
--- a/source/HealthIcon.hx
+++ b/source/HealthIcon.hx
@@ -12,10 +12,16 @@ class HealthIcon extends FlxSprite
public function new(char:String = 'bf', isPlayer:Bool = false)
{
super();
-
- loadGraphic(Paths.image('iconGrid'), true, 150, 150);
antialiasing = true;
+
+ if (char == 'sm')
+ {
+ loadGraphic(Paths.image("stepmania-icon"));
+ return;
+ }
+
+ loadGraphic(Paths.image('iconGrid'), true, 150, 150);
animation.add('bf', [0, 1], 0, false, isPlayer);
animation.add('bf-car', [0, 1], 0, false, isPlayer);
animation.add('bf-christmas', [0, 1], 0, false, isPlayer);
diff --git a/source/HelperFunctions.hx b/source/HelperFunctions.hx
index b17dc6a..4b704c1 100644
--- a/source/HelperFunctions.hx
+++ b/source/HelperFunctions.hx
@@ -12,4 +12,5 @@ class HelperFunctions
public static function GCD(a, b) {
return b == 0 ? FlxMath.absInt(a) : GCD(b, a % b);
}
+
}
\ No newline at end of file
diff --git a/source/MainMenuState.hx b/source/MainMenuState.hx
index ab5f444..452ce07 100644
--- a/source/MainMenuState.hx
+++ b/source/MainMenuState.hx
@@ -38,9 +38,9 @@ class MainMenuState extends MusicBeatState
var newGaming2:FlxText;
public static var firstStart:Bool = true;
- public static var nightly:String = "";
+ public static var nightly:String = "-Pre-Release";
- public static var kadeEngineVer:String = "1.5.4" + nightly;
+ public static var kadeEngineVer:String = "1.6" + nightly;
public static var gameVer:String = "0.2.7.1";
var magenta:FlxSprite;
diff --git a/source/MusicBeatState.hx b/source/MusicBeatState.hx
index 9deb2bf..7a3bde8 100644
--- a/source/MusicBeatState.hx
+++ b/source/MusicBeatState.hx
@@ -3,15 +3,11 @@ package;
#if windows
import Discord.DiscordClient;
#end
-import flixel.tweens.FlxTween;
import flixel.util.FlxColor;
import openfl.Lib;
import Conductor.BPMChangeEvent;
import flixel.FlxG;
-import flixel.addons.transition.FlxTransitionableState;
import flixel.addons.ui.FlxUIState;
-import flixel.math.FlxRect;
-import flixel.util.FlxTimer;
class MusicBeatState extends FlxUIState
{
@@ -20,6 +16,7 @@ class MusicBeatState extends FlxUIState
private var curStep:Int = 0;
private var curBeat:Int = 0;
+ private var curDecimalBeat:Float = 0;
private var controls(get, never):Controls;
inline function get_controls():Controls
@@ -27,6 +24,7 @@ class MusicBeatState extends FlxUIState
override function create()
{
+ TimingStruct.clearTimings();
(cast (Lib.current.getChildAt(0), Main)).setFPSCap(FlxG.save.data.fpsCap);
if (transIn != null)
@@ -73,6 +71,29 @@ class MusicBeatState extends FlxUIState
}
}
+ if (Conductor.songPosition < 0)
+ curDecimalBeat = 0;
+ else
+ {
+ if (TimingStruct.AllTimings.length > 1)
+ {
+ var data = TimingStruct.getTimingAtTimestamp(Conductor.songPosition);
+
+ FlxG.watch.addQuick("Current Conductor Timing Seg", data.bpm);
+
+ Conductor.crochet = ((60 / data.bpm) * 1000);
+
+ var percent = (Conductor.songPosition - (data.startTime * 1000)) / (data.length * 1000);
+
+ curDecimalBeat = data.startBeat + (((Conductor.songPosition/1000) - data.startTime) * (data.bpm / 60));
+ }
+ else
+ {
+ curDecimalBeat = (Conductor.songPosition / 1000) * (Conductor.bpm/60);
+ Conductor.crochet = ((60 / Conductor.bpm) * 1000);
+ }
+ }
+
if (FlxG.save.data.fpsRain && skippedFrames >= 6)
{
if (currentColor >= array.length)
diff --git a/source/Note.hx b/source/Note.hx
index 472dbd2..82d6a6d 100644
--- a/source/Note.hx
+++ b/source/Note.hx
@@ -33,6 +33,8 @@ class Note extends FlxSprite
public var originColor:Int = 0; // The sustain note's original note's color
public var noteSection:Int = 0;
+ public var noteCharterObject:FlxSprite;
+
public var noteScore:Float = 1;
public var noteYOff:Int = 0;
diff --git a/source/OFLWaveform.hx b/source/OFLWaveform.hx
new file mode 100644
index 0000000..46d1512
--- /dev/null
+++ b/source/OFLWaveform.hx
@@ -0,0 +1,30 @@
+import lime.media.AudioSource;
+import lime.media.AudioBuffer;
+import openfl.media.Sound;
+import openfl.display.Graphics;
+import openfl.display.Sprite;
+
+class OFLWaveform extends Sprite
+{
+ public var musicLength = 0;
+ public var _x = 0;
+ public var _y = 0;
+
+ public var _sound:String;
+
+ function new(x,y,musicLength, data:String)
+ {
+ super();
+
+ _x = x;
+ _y = y;
+ _sound = data;
+ this.musicLength = musicLength;
+ }
+
+ public function drawWaveform()
+ {
+ var gfx:Graphics = graphics;
+ gfx.clear();
+ }
+}
\ No newline at end of file
diff --git a/source/OutdatedSubState.hx b/source/OutdatedSubState.hx
index f7015c4..3c7487e 100644
--- a/source/OutdatedSubState.hx
+++ b/source/OutdatedSubState.hx
@@ -51,6 +51,13 @@ class OutdatedSubState extends MusicBeatState
+ "\n& more changes and bugfixes in the full changelog"
+ "\n\nPress Space to view the full changelog and update\nor ESCAPE to ignore this",
32);
+
+ if (MainMenuState.nightly != "")
+ txt.text =
+ "You are on\n"
+ + MainMenuState.kadeEngineVer + "-" + MainMenuState.nightly
+ + "\nWhich is a PRE-RELEASE BUILD!"
+ + "\n\nReport all bugs to the author of the pre-release.\nSpace/Escape ignores this.";
txt.setFormat("VCR OSD Mono", 32, FlxColor.fromRGB(200, 200, 200), CENTER);
txt.borderColor = FlxColor.BLACK;
@@ -84,10 +91,15 @@ class OutdatedSubState extends MusicBeatState
override function update(elapsed:Float)
{
- if (controls.ACCEPT)
+ if (controls.ACCEPT && MainMenuState.nightly == "")
{
fancyOpenURL("https://kadedev.github.io/Kade-Engine/changelogs/changelog-" + needVer);
}
+ else if (controls.ACCEPT)
+ {
+ leftState = true;
+ FlxG.switchState(new MainMenuState());
+ }
if (controls.BACK)
{
leftState = true;
diff --git a/source/PauseSubState.hx b/source/PauseSubState.hx
index 0d78ca9..3b406a6 100644
--- a/source/PauseSubState.hx
+++ b/source/PauseSubState.hx
@@ -133,6 +133,11 @@ class PauseSubState extends MusicBeatSubstate
}
var songPath = 'assets/data/' + songLowercase + '/';
+ #if sys
+ if (PlayState.isSM && !PlayState.isStoryMode)
+ songPath = PlayState.pathToSm;
+ #end
+
if (controls.UP_P || upPcontroller)
{
changeSelection(-1);
diff --git a/source/PlayState.hx b/source/PlayState.hx
index 969568b..6bf6c36 100644
--- a/source/PlayState.hx
+++ b/source/PlayState.hx
@@ -1,5 +1,11 @@
package;
+import Song.Event;
+import openfl.media.Sound;
+#if sys
+import sys.io.File;
+import smTools.SMFile;
+#end
import openfl.ui.KeyLocation;
import openfl.events.Event;
import haxe.EnumTools;
@@ -112,6 +118,12 @@ class PlayState extends MusicBeatState
private var vocals:FlxSound;
+ public static var isSM:Bool = false;
+ #if sys
+ public static var sm:SMFile;
+ public static var pathToSm:String;
+ #end
+
public var originalX:Float;
public static var dad:Character;
@@ -169,6 +181,8 @@ class PlayState extends MusicBeatState
public static var offsetTesting:Bool = false;
+ public var isSMFile:Bool = false;
+
var notesHitArray:Array = [];
var currentFrames:Int = 0;
@@ -257,6 +271,8 @@ class PlayState extends MusicBeatState
override public function create()
{
+
+ FlxG.mouse.visible = false;
instance = this;
if (FlxG.save.data.fpsCap > 290)
@@ -372,6 +388,47 @@ class PlayState extends MusicBeatState
Conductor.mapBPMChanges(SONG);
Conductor.changeBPM(SONG.bpm);
+ if (SONG.eventObjects == null)
+ {
+ SONG.eventObjects = [new Song.Event("Init BPM",0,SONG.bpm,"BPM Change")];
+ }
+
+
+ TimingStruct.clearTimings();
+
+ var convertedStuff:Array = [];
+
+ var currentIndex = 0;
+ for (i in SONG.eventObjects)
+ {
+ var name = Reflect.field(i,"name");
+ var type = Reflect.field(i,"type");
+ var pos = Reflect.field(i,"position");
+ var value = Reflect.field(i,"value");
+
+ if (type == "BPM Change")
+ {
+ var beat:Float = pos;
+
+ var endBeat:Float = Math.POSITIVE_INFINITY;
+
+ TimingStruct.addTiming(beat,value,endBeat, 0); // offset in this case = start time since we don't have a offset
+
+ if (currentIndex != 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;
+ }
+
+ currentIndex++;
+ }
+ convertedStuff.push(new Song.Event(name,pos,value,type));
+ }
+
+ SONG.eventObjects = convertedStuff;
+
trace('INFORMATION ABOUT WHAT U PLAYIN WIT:\nFRAMES: ' + PlayStateChangeables.safeFrames + '\nZONE: ' + Conductor.safeZoneOffset + '\nTS: '
+ Conductor.timeScale + '\nBotPlay : ' + PlayStateChangeables.botPlay);
@@ -1604,7 +1661,20 @@ class PlayState extends MusicBeatState
if (!paused)
{
+ #if sys
+ if (!isStoryMode && isSM)
+ {
+ trace("Loading " + pathToSm + "/" + sm.header.MUSIC);
+ var bytes = File.getBytes(pathToSm + "/" + sm.header.MUSIC);
+ var sound = new Sound();
+ sound.loadCompressedDataFromByteArray(bytes.getData(), bytes.length);
+ FlxG.sound.playMusic(sound);
+ }
+ else
+ FlxG.sound.playMusic(Paths.inst(PlayState.SONG.song), 1, false);
+ #else
FlxG.sound.playMusic(Paths.inst(PlayState.SONG.song), 1, false);
+ #end
}
FlxG.sound.music.onComplete = endSong;
@@ -1689,10 +1759,17 @@ class PlayState extends MusicBeatState
curSong = songData.song;
+ #if sys
+ if (SONG.needsVoices && !isSM)
+ vocals = new FlxSound().loadEmbedded(Paths.voices(PlayState.SONG.song));
+ else
+ vocals = new FlxSound();
+ #else
if (SONG.needsVoices)
vocals = new FlxSound().loadEmbedded(Paths.voices(PlayState.SONG.song));
else
vocals = new FlxSound();
+ #end
trace('loaded vocals');
@@ -1721,6 +1798,11 @@ class PlayState extends MusicBeatState
}
var songPath = 'assets/data/' + songLowercase + '/';
+
+ #if sys
+ if (isSM && !isStoryMode)
+ songPath = pathToSm;
+ #end
for (file in sys.FileSystem.readDirectory(songPath))
{
@@ -2071,12 +2153,77 @@ class PlayState extends MusicBeatState
public var stopUpdate = false;
public var removedVideo = false;
+ public var currentBPM = 0;
+
+ public var updateFrame = 0;
+
override public function update(elapsed:Float)
{
#if !debug
perfectMode = false;
#end
+ if (updateFrame == 4)
+ {
+ TimingStruct.clearTimings();
+
+ var currentIndex = 0;
+ for (i in SONG.eventObjects)
+ {
+ if (i.type == "BPM Change")
+ {
+ var beat:Float = i.position;
+
+ var endBeat:Float = Math.POSITIVE_INFINITY;
+
+ TimingStruct.addTiming(beat,i.value,endBeat, 0); // offset in this case = start time since we don't have a offset
+
+ if (currentIndex != 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;
+ }
+
+ currentIndex++;
+ }
+ }
+ updateFrame++;
+ }
+ else if (updateFrame != 5)
+ updateFrame++;
+
+
+ var timingSeg = TimingStruct.getTimingAtTimestamp(Conductor.songPosition);
+
+ if (timingSeg != null)
+ {
+
+ var timingSegBpm = timingSeg.bpm;
+
+ if (timingSegBpm != Conductor.bpm)
+ {
+ trace("BPM CHANGE to " + timingSegBpm);
+ Conductor.changeBPM(timingSegBpm, false);
+ }
+
+ }
+
+ var newScroll = PlayStateChangeables.scrollSpeed;
+
+ for(i in SONG.eventObjects)
+ {
+ switch(i.type)
+ {
+ case "Scroll Speed Change":
+ if (i.position < curDecimalBeat)
+ newScroll = i.value;
+ }
+ }
+
+ PlayStateChangeables.scrollSpeed = newScroll;
+
if (PlayStateChangeables.botPlay && FlxG.keys.justPressed.ONE)
camHUD.visible = !camHUD.visible;
@@ -2528,6 +2675,9 @@ class PlayState extends MusicBeatState
camHUD.zoom = FlxMath.lerp(1, camHUD.zoom, 0.95);
}
+ FlxG.watch.addQuick("curBPM", Conductor.bpm);
+ FlxG.watch.addQuick("Closest Note", (unspawnNotes.length != 0 ? unspawnNotes[0].strumTime - Conductor.songPosition : "No note"));
+
FlxG.watch.addQuick("beatShit", curBeat);
FlxG.watch.addQuick("stepShit", curStep);
@@ -4164,11 +4314,6 @@ class PlayState extends MusicBeatState
if (SONG.notes[Math.floor(curStep / 16)] != null)
{
- if (SONG.notes[Math.floor(curStep / 16)].changeBPM)
- {
- Conductor.changeBPM(SONG.notes[Math.floor(curStep / 16)].bpm);
- FlxG.log.add('CHANGED BPM!');
- }
// else
// Conductor.changeBPM(SONG.bpm);
diff --git a/source/Section.hx b/source/Section.hx
index c1af6ac..fcb574a 100644
--- a/source/Section.hx
+++ b/source/Section.hx
@@ -2,6 +2,8 @@ package;
typedef SwagSection =
{
+ var startTime:Float;
+ var endTime:Float;
var sectionNotes:Array>;
var lengthInSteps:Int;
var typeOfSection:Int;
@@ -13,6 +15,8 @@ typedef SwagSection =
class Section
{
+ public var startTime:Float = 0;
+ public var endTime:Float = 0;
public var sectionNotes:Array> = [];
public var lengthInSteps:Int = 16;
diff --git a/source/SectionRender.hx b/source/SectionRender.hx
new file mode 100644
index 0000000..3410ccb
--- /dev/null
+++ b/source/SectionRender.hx
@@ -0,0 +1,32 @@
+import flixel.FlxG;
+import flixel.util.FlxColor;
+import flixel.group.FlxGroup.FlxTypedGroup;
+import Section.SwagSection;
+import flixel.addons.display.FlxGridOverlay;
+import flixel.FlxSprite;
+
+class SectionRender extends FlxSprite
+{
+ public var section:SwagSection;
+ public var icon:FlxSprite;
+ public var lastUpdated:Bool;
+
+ public function new(x:Float,y:Float,GRID_SIZE:Int, ?Height:Int = 16)
+ {
+ super(x,y);
+
+ makeGraphic(GRID_SIZE * 8, GRID_SIZE * Height,FlxColor.BLACK);
+
+ var h = GRID_SIZE;
+ if (Math.floor(h) != h)
+ h = GRID_SIZE;
+
+ FlxGridOverlay.overlay(this,GRID_SIZE, Std.int(h), GRID_SIZE * 8,GRID_SIZE * Height);
+ }
+
+
+
+ override function update(elapsed)
+ {
+ }
+}
\ No newline at end of file
diff --git a/source/Song.hx b/source/Song.hx
index 5329079..abbec7f 100644
--- a/source/Song.hx
+++ b/source/Song.hx
@@ -7,10 +7,28 @@ import lime.utils.Assets;
using StringTools;
+class Event
+{
+ public var name:String;
+ public var position:Float;
+ public var value:Dynamic;
+ public var type:String;
+
+ public function new(name:String,pos:Float,value:Dynamic,type:String)
+ {
+ this.name = name;
+ this.position = pos;
+ this.value = value;
+ this.type = type;
+ }
+}
+
typedef SwagSong =
{
+ var chartVersion:String;
var song:String;
var notes:Array;
+ var eventObjects:Array;
var bpm:Float;
var needsVoices:Bool;
var speed:Float;
@@ -25,10 +43,12 @@ typedef SwagSong =
class Song
{
+ public var chartVersion:String;
public var song:String;
public var notes:Array;
public var bpm:Float;
public var needsVoices:Bool = true;
+ public var eventObjects:Array;
public var speed:Float = 1;
public var player1:String = 'bf';
@@ -44,10 +64,19 @@ class Song
this.bpm = bpm;
}
+ public static function loadFromJsonRAW(rawJson:String)
+ {
+ while (!rawJson.endsWith("}"))
+ {
+ rawJson = rawJson.substr(0, rawJson.length - 1);
+ // LOL GOING THROUGH THE BULLSHIT TO CLEAN IDK WHATS STRANGE
+ }
+
+ return parseJSONshit(rawJson);
+ }
+
public static function loadFromJson(jsonInput:String, ?folder:String):SwagSong
{
- trace(jsonInput);
-
// pre lowercasing the folder name
var folderLowercase = StringTools.replace(folder, " ", "-").toLowerCase();
switch (folderLowercase) {
diff --git a/source/TimingStruct.hx b/source/TimingStruct.hx
new file mode 100644
index 0000000..82128a3
--- /dev/null
+++ b/source/TimingStruct.hx
@@ -0,0 +1,55 @@
+import flixel.FlxG;
+
+class TimingStruct
+{
+ public static var AllTimings:Array = [];
+
+ public var bpm:Float = 0;
+
+ public var startBeat:Float = 0;
+ public var endBeat:Float = Math.POSITIVE_INFINITY;
+ public var startTime:Float = 0;
+
+ public var length:Float = Math.POSITIVE_INFINITY; // in beats
+
+ public static function clearTimings()
+ {
+ AllTimings = [];
+ }
+
+ public static function addTiming(startBeat,bpm,endBeat:Float, offset:Float)
+ {
+ var pog = new TimingStruct(startBeat,bpm,endBeat, offset);
+ AllTimings.push(pog);
+ }
+
+ public function new(startBeat,bpm,endBeat:Float, offset:Float)
+ {
+ this.bpm = bpm;
+ this.startBeat = startBeat;
+ if (endBeat != -1)
+ this.endBeat = endBeat;
+ startTime = offset;
+ }
+
+ public static function getTimingAtTimestamp(msTime:Float):TimingStruct
+ {
+ for(i in AllTimings)
+ {
+ if (msTime >= i.startTime * 1000 && msTime < (i.startTime + i.length) * 1000)
+ return i;
+ }
+ trace('Apparently ' + msTime + ' is out of any segs');
+ return null;
+ }
+
+ public static function getTimingAtBeat(beat):TimingStruct
+ {
+ for(i in AllTimings)
+ {
+ if (i.startBeat <= beat && i.endBeat >= beat)
+ return i;
+ }
+ return null;
+ }
+}
\ No newline at end of file
diff --git a/source/TitleState.hx b/source/TitleState.hx
index 13c4660..27372b0 100644
--- a/source/TitleState.hx
+++ b/source/TitleState.hx
@@ -84,9 +84,6 @@ class TitleState extends MusicBeatState
trace('NEWGROUNDS LOL');
#end
- // var file:SMFile = SMFile.loadFile("file.sm");
- // this was testing things
-
#if FREEPLAY
FlxG.switchState(new FreeplayState());
#elseif CHARTING
@@ -287,7 +284,7 @@ class TitleState extends MusicBeatState
{
returnedData[0] = data.substring(0, data.indexOf(';'));
returnedData[1] = data.substring(data.indexOf('-'), data.length);
- if (!MainMenuState.kadeEngineVer.contains(returnedData[0].trim()) && !OutdatedSubState.leftState && MainMenuState.nightly == "")
+ if (!MainMenuState.kadeEngineVer.contains(returnedData[0].trim()) && !OutdatedSubState.leftState)
{
trace('outdated lmao! ' + returnedData[0] + ' != ' + MainMenuState.kadeEngineVer);
OutdatedSubState.needVer = returnedData[0];
diff --git a/source/smTools/SMFile.hx b/source/smTools/SMFile.hx
index f4cde5b..fcb6555 100644
--- a/source/smTools/SMFile.hx
+++ b/source/smTools/SMFile.hx
@@ -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;
+ 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)
{
- _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>;
+
+
+ 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 = [];
+
+ 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
\ No newline at end of file
diff --git a/source/smTools/SMHeader.hx b/source/smTools/SMHeader.hx
index cfe7770..656b15a 100644
--- a/source/smTools/SMHeader.hx
+++ b/source/smTools/SMHeader.hx
@@ -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;
public function new(headerData:Array)
{
_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)
diff --git a/source/smTools/SMMeasure.hx b/source/smTools/SMMeasure.hx
index bd21dd9..4519cbd 100644
--- a/source/smTools/SMMeasure.hx
+++ b/source/smTools/SMMeasure.hx
@@ -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
\ No newline at end of file
diff --git a/source/smTools/SMNote.hx b/source/smTools/SMNote.hx
index 6f2a5bd..0a97f63 100644
--- a/source/smTools/SMNote.hx
+++ b/source/smTools/SMNote.hx
@@ -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
\ No newline at end of file