new chart editor, sm file support, bpm changes, and scroll speed changes.
This commit is contained in:
parent
c69e83d8e0
commit
aa2119d034
@ -57,6 +57,7 @@
|
|||||||
<library name="week4" preload="true" />
|
<library name="week4" preload="true" />
|
||||||
<library name="week5" preload="true" />
|
<library name="week5" preload="true" />
|
||||||
<library name="week6" preload="true" />
|
<library name="week6" preload="true" />
|
||||||
|
<library name="sm" preload="true" />
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section if="NO_PRELOAD_ALL">
|
<section if="NO_PRELOAD_ALL">
|
||||||
@ -69,6 +70,7 @@
|
|||||||
<library name="week4" preload="false" />
|
<library name="week4" preload="false" />
|
||||||
<library name="week5" preload="false" />
|
<library name="week5" preload="false" />
|
||||||
<library name="week6" preload="false" />
|
<library name="week6" preload="false" />
|
||||||
|
<library name="sm" preload="false" />
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<assets path="assets/songs" library="songs" exclude="*.ogg" if="web"/>
|
<assets path="assets/songs" library="songs" exclude="*.ogg" if="web"/>
|
||||||
@ -89,6 +91,8 @@
|
|||||||
<assets path="assets/week5" library="week5" exclude="*.mp3" unless="web"/>
|
<assets path="assets/week5" library="week5" exclude="*.mp3" unless="web"/>
|
||||||
<assets path="assets/week6" library="week6" exclude="*.ogg" if="web"/>
|
<assets path="assets/week6" library="week6" exclude="*.ogg" if="web"/>
|
||||||
<assets path="assets/week6" library="week6" exclude="*.mp3" unless="web"/>
|
<assets path="assets/week6" library="week6" exclude="*.mp3" unless="web"/>
|
||||||
|
<assets path="assets/sm" library="sm" exclude="*.ogg" if="web"/>
|
||||||
|
<assets path="assets/sm" library="sm" exclude="*.mp3" unless="web"/>
|
||||||
|
|
||||||
<assets path='example_mods' rename='mods' embed='false'/>
|
<assets path='example_mods' rename='mods' embed='false'/>
|
||||||
<assets path='art/readme.txt' rename='do NOT readme.txt' />
|
<assets path='art/readme.txt' rename='do NOT readme.txt' />
|
||||||
|
@ -76,3 +76,4 @@ This game was made with love to Newgrounds and its community. Extra love to Tom
|
|||||||
- [Rozebud](https://github.com/ThatRozebudDude) - Ideas (that I stole)
|
- [Rozebud](https://github.com/ThatRozebudDude) - Ideas (that I stole)
|
||||||
- [Puyo](https://github.com/daniel11420) - Setting up appveyor and a lot of other help
|
- [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
|
- [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)
|
BIN
assets/preload/images/stepmania-icon.png
Normal file
BIN
assets/preload/images/stepmania-icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.0 KiB |
1
assets/sm/HOW TO ADD SM FILES.txt
Normal file
1
assets/sm/HOW TO ADD SM FILES.txt
Normal file
@ -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.
|
File diff suppressed because it is too large
Load Diff
@ -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 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 timeScale:Float = Conductor.safeZoneOffset / 166;
|
||||||
|
|
||||||
public static var lengthInSteps:Float = 0;
|
|
||||||
|
|
||||||
public static var bpmChangeMap:Array<BPMChangeEvent> = [];
|
public static var bpmChangeMap:Array<BPMChangeEvent> = [];
|
||||||
|
|
||||||
public function new()
|
public function new()
|
||||||
@ -70,15 +68,27 @@ class Conductor
|
|||||||
trace("new BPM map BUDDY " + bpmChangeMap);
|
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;
|
bpm = newBpm;
|
||||||
|
|
||||||
crochet = ((60 / bpm) * 1000);
|
crochet = ((60 / bpm) * 1000);
|
||||||
stepCrochet = crochet / 4;
|
stepCrochet = crochet / 4;
|
||||||
|
|
||||||
lengthInSteps = (FlxG.sound.music.length / stepCrochet);
|
|
||||||
|
|
||||||
trace("\nLength in in steps: " + lengthInSteps);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,5 +1,12 @@
|
|||||||
package;
|
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 Song.SwagSong;
|
||||||
import flixel.input.gamepad.FlxGamepad;
|
import flixel.input.gamepad.FlxGamepad;
|
||||||
import flash.text.TextField;
|
import flash.text.TextField;
|
||||||
@ -63,6 +70,9 @@ class FreeplayState extends MusicBeatState
|
|||||||
|
|
||||||
//var diffList = "";
|
//var diffList = "";
|
||||||
|
|
||||||
|
songData = [];
|
||||||
|
songs = [];
|
||||||
|
|
||||||
for (i in 0...initSonglist.length)
|
for (i in 0...initSonglist.length)
|
||||||
{
|
{
|
||||||
var data:Array<String> = initSonglist[i].split(':');
|
var data:Array<String> = 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);
|
//trace("\n" + diffList);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -315,6 +354,18 @@ class FreeplayState extends MusicBeatState
|
|||||||
PlayState.storyDifficulty = curDifficulty;
|
PlayState.storyDifficulty = curDifficulty;
|
||||||
PlayState.storyWeek = songs[curSelected].week;
|
PlayState.storyWeek = songs[curSelected].week;
|
||||||
trace('CUR WEEK' + PlayState.storyWeek);
|
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());
|
LoadingState.loadAndSwitchState(new PlayState());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -328,6 +379,7 @@ class FreeplayState extends MusicBeatState
|
|||||||
if (curDifficulty > 2)
|
if (curDifficulty > 2)
|
||||||
curDifficulty = 0;
|
curDifficulty = 0;
|
||||||
|
|
||||||
|
|
||||||
// adjusting the highscore song name to be compatible (changeDiff)
|
// adjusting the highscore song name to be compatible (changeDiff)
|
||||||
var songHighscore = StringTools.replace(songs[curSelected].songName, " ", "-");
|
var songHighscore = StringTools.replace(songs[curSelected].songName, " ", "-");
|
||||||
switch (songHighscore) {
|
switch (songHighscore) {
|
||||||
@ -353,6 +405,7 @@ class FreeplayState extends MusicBeatState
|
|||||||
FlxG.sound.play(Paths.sound('scrollMenu'), 0.4);
|
FlxG.sound.play(Paths.sound('scrollMenu'), 0.4);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
curSelected += change;
|
curSelected += change;
|
||||||
|
|
||||||
if (curSelected < 0)
|
if (curSelected < 0)
|
||||||
@ -379,6 +432,16 @@ class FreeplayState extends MusicBeatState
|
|||||||
diffCalcText.text = 'RATING: ${DiffCalc.CalculateDiff(songData.get(songs[curSelected].songName)[curDifficulty])}';
|
diffCalcText.text = 'RATING: ${DiffCalc.CalculateDiff(songData.get(songs[curSelected].songName)[curDifficulty])}';
|
||||||
|
|
||||||
#if PRELOAD_ALL
|
#if PRELOAD_ALL
|
||||||
|
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);
|
FlxG.sound.playMusic(Paths.inst(songs[curSelected].songName), 0);
|
||||||
#end
|
#end
|
||||||
|
|
||||||
@ -428,12 +491,27 @@ class SongMetadata
|
|||||||
{
|
{
|
||||||
public var songName:String = "";
|
public var songName:String = "";
|
||||||
public var week:Int = 0;
|
public var week:Int = 0;
|
||||||
|
#if sys
|
||||||
|
public var sm:SMFile;
|
||||||
|
public var path:String;
|
||||||
|
#end
|
||||||
public var songCharacter:String = "";
|
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)
|
public function new(song:String, week:Int, songCharacter:String)
|
||||||
{
|
{
|
||||||
this.songName = song;
|
this.songName = song;
|
||||||
this.week = week;
|
this.week = week;
|
||||||
this.songCharacter = songCharacter;
|
this.songCharacter = songCharacter;
|
||||||
}
|
}
|
||||||
|
#end
|
||||||
}
|
}
|
||||||
|
@ -13,9 +13,15 @@ class HealthIcon extends FlxSprite
|
|||||||
{
|
{
|
||||||
super();
|
super();
|
||||||
|
|
||||||
loadGraphic(Paths.image('iconGrid'), true, 150, 150);
|
|
||||||
|
|
||||||
antialiasing = true;
|
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', [0, 1], 0, false, isPlayer);
|
||||||
animation.add('bf-car', [0, 1], 0, false, isPlayer);
|
animation.add('bf-car', [0, 1], 0, false, isPlayer);
|
||||||
animation.add('bf-christmas', [0, 1], 0, false, isPlayer);
|
animation.add('bf-christmas', [0, 1], 0, false, isPlayer);
|
||||||
|
@ -12,4 +12,5 @@ class HelperFunctions
|
|||||||
public static function GCD(a, b) {
|
public static function GCD(a, b) {
|
||||||
return b == 0 ? FlxMath.absInt(a) : GCD(b, a % b);
|
return b == 0 ? FlxMath.absInt(a) : GCD(b, a % b);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -38,9 +38,9 @@ class MainMenuState extends MusicBeatState
|
|||||||
var newGaming2:FlxText;
|
var newGaming2:FlxText;
|
||||||
public static var firstStart:Bool = true;
|
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";
|
public static var gameVer:String = "0.2.7.1";
|
||||||
|
|
||||||
var magenta:FlxSprite;
|
var magenta:FlxSprite;
|
||||||
|
@ -3,15 +3,11 @@ package;
|
|||||||
#if windows
|
#if windows
|
||||||
import Discord.DiscordClient;
|
import Discord.DiscordClient;
|
||||||
#end
|
#end
|
||||||
import flixel.tweens.FlxTween;
|
|
||||||
import flixel.util.FlxColor;
|
import flixel.util.FlxColor;
|
||||||
import openfl.Lib;
|
import openfl.Lib;
|
||||||
import Conductor.BPMChangeEvent;
|
import Conductor.BPMChangeEvent;
|
||||||
import flixel.FlxG;
|
import flixel.FlxG;
|
||||||
import flixel.addons.transition.FlxTransitionableState;
|
|
||||||
import flixel.addons.ui.FlxUIState;
|
import flixel.addons.ui.FlxUIState;
|
||||||
import flixel.math.FlxRect;
|
|
||||||
import flixel.util.FlxTimer;
|
|
||||||
|
|
||||||
class MusicBeatState extends FlxUIState
|
class MusicBeatState extends FlxUIState
|
||||||
{
|
{
|
||||||
@ -20,6 +16,7 @@ class MusicBeatState extends FlxUIState
|
|||||||
|
|
||||||
private var curStep:Int = 0;
|
private var curStep:Int = 0;
|
||||||
private var curBeat:Int = 0;
|
private var curBeat:Int = 0;
|
||||||
|
private var curDecimalBeat:Float = 0;
|
||||||
private var controls(get, never):Controls;
|
private var controls(get, never):Controls;
|
||||||
|
|
||||||
inline function get_controls():Controls
|
inline function get_controls():Controls
|
||||||
@ -27,6 +24,7 @@ class MusicBeatState extends FlxUIState
|
|||||||
|
|
||||||
override function create()
|
override function create()
|
||||||
{
|
{
|
||||||
|
TimingStruct.clearTimings();
|
||||||
(cast (Lib.current.getChildAt(0), Main)).setFPSCap(FlxG.save.data.fpsCap);
|
(cast (Lib.current.getChildAt(0), Main)).setFPSCap(FlxG.save.data.fpsCap);
|
||||||
|
|
||||||
if (transIn != null)
|
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 (FlxG.save.data.fpsRain && skippedFrames >= 6)
|
||||||
{
|
{
|
||||||
if (currentColor >= array.length)
|
if (currentColor >= array.length)
|
||||||
|
@ -33,6 +33,8 @@ class Note extends FlxSprite
|
|||||||
public var originColor:Int = 0; // The sustain note's original note's color
|
public var originColor:Int = 0; // The sustain note's original note's color
|
||||||
public var noteSection:Int = 0;
|
public var noteSection:Int = 0;
|
||||||
|
|
||||||
|
public var noteCharterObject:FlxSprite;
|
||||||
|
|
||||||
public var noteScore:Float = 1;
|
public var noteScore:Float = 1;
|
||||||
|
|
||||||
public var noteYOff:Int = 0;
|
public var noteYOff:Int = 0;
|
||||||
|
30
source/OFLWaveform.hx
Normal file
30
source/OFLWaveform.hx
Normal file
@ -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();
|
||||||
|
}
|
||||||
|
}
|
@ -52,6 +52,13 @@ class OutdatedSubState extends MusicBeatState
|
|||||||
+ "\n\nPress Space to view the full changelog and update\nor ESCAPE to ignore this",
|
+ "\n\nPress Space to view the full changelog and update\nor ESCAPE to ignore this",
|
||||||
32);
|
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.setFormat("VCR OSD Mono", 32, FlxColor.fromRGB(200, 200, 200), CENTER);
|
||||||
txt.borderColor = FlxColor.BLACK;
|
txt.borderColor = FlxColor.BLACK;
|
||||||
txt.borderSize = 3;
|
txt.borderSize = 3;
|
||||||
@ -84,10 +91,15 @@ class OutdatedSubState extends MusicBeatState
|
|||||||
|
|
||||||
override function update(elapsed:Float)
|
override function update(elapsed:Float)
|
||||||
{
|
{
|
||||||
if (controls.ACCEPT)
|
if (controls.ACCEPT && MainMenuState.nightly == "")
|
||||||
{
|
{
|
||||||
fancyOpenURL("https://kadedev.github.io/Kade-Engine/changelogs/changelog-" + needVer);
|
fancyOpenURL("https://kadedev.github.io/Kade-Engine/changelogs/changelog-" + needVer);
|
||||||
}
|
}
|
||||||
|
else if (controls.ACCEPT)
|
||||||
|
{
|
||||||
|
leftState = true;
|
||||||
|
FlxG.switchState(new MainMenuState());
|
||||||
|
}
|
||||||
if (controls.BACK)
|
if (controls.BACK)
|
||||||
{
|
{
|
||||||
leftState = true;
|
leftState = true;
|
||||||
|
@ -133,6 +133,11 @@ class PauseSubState extends MusicBeatSubstate
|
|||||||
}
|
}
|
||||||
var songPath = 'assets/data/' + songLowercase + '/';
|
var songPath = 'assets/data/' + songLowercase + '/';
|
||||||
|
|
||||||
|
#if sys
|
||||||
|
if (PlayState.isSM && !PlayState.isStoryMode)
|
||||||
|
songPath = PlayState.pathToSm;
|
||||||
|
#end
|
||||||
|
|
||||||
if (controls.UP_P || upPcontroller)
|
if (controls.UP_P || upPcontroller)
|
||||||
{
|
{
|
||||||
changeSelection(-1);
|
changeSelection(-1);
|
||||||
|
@ -1,5 +1,11 @@
|
|||||||
package;
|
package;
|
||||||
|
|
||||||
|
import Song.Event;
|
||||||
|
import openfl.media.Sound;
|
||||||
|
#if sys
|
||||||
|
import sys.io.File;
|
||||||
|
import smTools.SMFile;
|
||||||
|
#end
|
||||||
import openfl.ui.KeyLocation;
|
import openfl.ui.KeyLocation;
|
||||||
import openfl.events.Event;
|
import openfl.events.Event;
|
||||||
import haxe.EnumTools;
|
import haxe.EnumTools;
|
||||||
@ -112,6 +118,12 @@ class PlayState extends MusicBeatState
|
|||||||
|
|
||||||
private var vocals:FlxSound;
|
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 var originalX:Float;
|
||||||
|
|
||||||
public static var dad:Character;
|
public static var dad:Character;
|
||||||
@ -169,6 +181,8 @@ class PlayState extends MusicBeatState
|
|||||||
|
|
||||||
public static var offsetTesting:Bool = false;
|
public static var offsetTesting:Bool = false;
|
||||||
|
|
||||||
|
public var isSMFile:Bool = false;
|
||||||
|
|
||||||
var notesHitArray:Array<Date> = [];
|
var notesHitArray:Array<Date> = [];
|
||||||
var currentFrames:Int = 0;
|
var currentFrames:Int = 0;
|
||||||
|
|
||||||
@ -257,6 +271,8 @@ class PlayState extends MusicBeatState
|
|||||||
|
|
||||||
override public function create()
|
override public function create()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
FlxG.mouse.visible = false;
|
||||||
instance = this;
|
instance = this;
|
||||||
|
|
||||||
if (FlxG.save.data.fpsCap > 290)
|
if (FlxG.save.data.fpsCap > 290)
|
||||||
@ -372,6 +388,47 @@ class PlayState extends MusicBeatState
|
|||||||
Conductor.mapBPMChanges(SONG);
|
Conductor.mapBPMChanges(SONG);
|
||||||
Conductor.changeBPM(SONG.bpm);
|
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<Song.Event> = [];
|
||||||
|
|
||||||
|
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: '
|
trace('INFORMATION ABOUT WHAT U PLAYIN WIT:\nFRAMES: ' + PlayStateChangeables.safeFrames + '\nZONE: ' + Conductor.safeZoneOffset + '\nTS: '
|
||||||
+ Conductor.timeScale + '\nBotPlay : ' + PlayStateChangeables.botPlay);
|
+ Conductor.timeScale + '\nBotPlay : ' + PlayStateChangeables.botPlay);
|
||||||
|
|
||||||
@ -1604,7 +1661,20 @@ class PlayState extends MusicBeatState
|
|||||||
|
|
||||||
if (!paused)
|
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);
|
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;
|
FlxG.sound.music.onComplete = endSong;
|
||||||
@ -1689,10 +1759,17 @@ class PlayState extends MusicBeatState
|
|||||||
|
|
||||||
curSong = songData.song;
|
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)
|
if (SONG.needsVoices)
|
||||||
vocals = new FlxSound().loadEmbedded(Paths.voices(PlayState.SONG.song));
|
vocals = new FlxSound().loadEmbedded(Paths.voices(PlayState.SONG.song));
|
||||||
else
|
else
|
||||||
vocals = new FlxSound();
|
vocals = new FlxSound();
|
||||||
|
#end
|
||||||
|
|
||||||
trace('loaded vocals');
|
trace('loaded vocals');
|
||||||
|
|
||||||
@ -1722,6 +1799,11 @@ class PlayState extends MusicBeatState
|
|||||||
|
|
||||||
var songPath = 'assets/data/' + songLowercase + '/';
|
var songPath = 'assets/data/' + songLowercase + '/';
|
||||||
|
|
||||||
|
#if sys
|
||||||
|
if (isSM && !isStoryMode)
|
||||||
|
songPath = pathToSm;
|
||||||
|
#end
|
||||||
|
|
||||||
for (file in sys.FileSystem.readDirectory(songPath))
|
for (file in sys.FileSystem.readDirectory(songPath))
|
||||||
{
|
{
|
||||||
var path = haxe.io.Path.join([songPath, file]);
|
var path = haxe.io.Path.join([songPath, file]);
|
||||||
@ -2071,12 +2153,77 @@ class PlayState extends MusicBeatState
|
|||||||
public var stopUpdate = false;
|
public var stopUpdate = false;
|
||||||
public var removedVideo = false;
|
public var removedVideo = false;
|
||||||
|
|
||||||
|
public var currentBPM = 0;
|
||||||
|
|
||||||
|
public var updateFrame = 0;
|
||||||
|
|
||||||
override public function update(elapsed:Float)
|
override public function update(elapsed:Float)
|
||||||
{
|
{
|
||||||
#if !debug
|
#if !debug
|
||||||
perfectMode = false;
|
perfectMode = false;
|
||||||
#end
|
#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)
|
if (PlayStateChangeables.botPlay && FlxG.keys.justPressed.ONE)
|
||||||
camHUD.visible = !camHUD.visible;
|
camHUD.visible = !camHUD.visible;
|
||||||
|
|
||||||
@ -2528,6 +2675,9 @@ class PlayState extends MusicBeatState
|
|||||||
camHUD.zoom = FlxMath.lerp(1, camHUD.zoom, 0.95);
|
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("beatShit", curBeat);
|
||||||
FlxG.watch.addQuick("stepShit", curStep);
|
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)] != null)
|
||||||
{
|
{
|
||||||
if (SONG.notes[Math.floor(curStep / 16)].changeBPM)
|
|
||||||
{
|
|
||||||
Conductor.changeBPM(SONG.notes[Math.floor(curStep / 16)].bpm);
|
|
||||||
FlxG.log.add('CHANGED BPM!');
|
|
||||||
}
|
|
||||||
// else
|
// else
|
||||||
// Conductor.changeBPM(SONG.bpm);
|
// Conductor.changeBPM(SONG.bpm);
|
||||||
|
|
||||||
|
@ -2,6 +2,8 @@ package;
|
|||||||
|
|
||||||
typedef SwagSection =
|
typedef SwagSection =
|
||||||
{
|
{
|
||||||
|
var startTime:Float;
|
||||||
|
var endTime:Float;
|
||||||
var sectionNotes:Array<Array<Dynamic>>;
|
var sectionNotes:Array<Array<Dynamic>>;
|
||||||
var lengthInSteps:Int;
|
var lengthInSteps:Int;
|
||||||
var typeOfSection:Int;
|
var typeOfSection:Int;
|
||||||
@ -13,6 +15,8 @@ typedef SwagSection =
|
|||||||
|
|
||||||
class Section
|
class Section
|
||||||
{
|
{
|
||||||
|
public var startTime:Float = 0;
|
||||||
|
public var endTime:Float = 0;
|
||||||
public var sectionNotes:Array<Array<Dynamic>> = [];
|
public var sectionNotes:Array<Array<Dynamic>> = [];
|
||||||
|
|
||||||
public var lengthInSteps:Int = 16;
|
public var lengthInSteps:Int = 16;
|
||||||
|
32
source/SectionRender.hx
Normal file
32
source/SectionRender.hx
Normal file
@ -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)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
@ -7,10 +7,28 @@ import lime.utils.Assets;
|
|||||||
|
|
||||||
using StringTools;
|
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 =
|
typedef SwagSong =
|
||||||
{
|
{
|
||||||
|
var chartVersion:String;
|
||||||
var song:String;
|
var song:String;
|
||||||
var notes:Array<SwagSection>;
|
var notes:Array<SwagSection>;
|
||||||
|
var eventObjects:Array<Event>;
|
||||||
var bpm:Float;
|
var bpm:Float;
|
||||||
var needsVoices:Bool;
|
var needsVoices:Bool;
|
||||||
var speed:Float;
|
var speed:Float;
|
||||||
@ -25,10 +43,12 @@ typedef SwagSong =
|
|||||||
|
|
||||||
class Song
|
class Song
|
||||||
{
|
{
|
||||||
|
public var chartVersion:String;
|
||||||
public var song:String;
|
public var song:String;
|
||||||
public var notes:Array<SwagSection>;
|
public var notes:Array<SwagSection>;
|
||||||
public var bpm:Float;
|
public var bpm:Float;
|
||||||
public var needsVoices:Bool = true;
|
public var needsVoices:Bool = true;
|
||||||
|
public var eventObjects:Array<Event>;
|
||||||
public var speed:Float = 1;
|
public var speed:Float = 1;
|
||||||
|
|
||||||
public var player1:String = 'bf';
|
public var player1:String = 'bf';
|
||||||
@ -44,10 +64,19 @@ class Song
|
|||||||
this.bpm = bpm;
|
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
|
public static function loadFromJson(jsonInput:String, ?folder:String):SwagSong
|
||||||
{
|
{
|
||||||
trace(jsonInput);
|
|
||||||
|
|
||||||
// pre lowercasing the folder name
|
// pre lowercasing the folder name
|
||||||
var folderLowercase = StringTools.replace(folder, " ", "-").toLowerCase();
|
var folderLowercase = StringTools.replace(folder, " ", "-").toLowerCase();
|
||||||
switch (folderLowercase) {
|
switch (folderLowercase) {
|
||||||
|
55
source/TimingStruct.hx
Normal file
55
source/TimingStruct.hx
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
import flixel.FlxG;
|
||||||
|
|
||||||
|
class TimingStruct
|
||||||
|
{
|
||||||
|
public static var AllTimings:Array<TimingStruct> = [];
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
@ -84,9 +84,6 @@ class TitleState extends MusicBeatState
|
|||||||
trace('NEWGROUNDS LOL');
|
trace('NEWGROUNDS LOL');
|
||||||
#end
|
#end
|
||||||
|
|
||||||
// var file:SMFile = SMFile.loadFile("file.sm");
|
|
||||||
// this was testing things
|
|
||||||
|
|
||||||
#if FREEPLAY
|
#if FREEPLAY
|
||||||
FlxG.switchState(new FreeplayState());
|
FlxG.switchState(new FreeplayState());
|
||||||
#elseif CHARTING
|
#elseif CHARTING
|
||||||
@ -287,7 +284,7 @@ class TitleState extends MusicBeatState
|
|||||||
{
|
{
|
||||||
returnedData[0] = data.substring(0, data.indexOf(';'));
|
returnedData[0] = data.substring(0, data.indexOf(';'));
|
||||||
returnedData[1] = data.substring(data.indexOf('-'), data.length);
|
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);
|
trace('outdated lmao! ' + returnedData[0] + ' != ' + MainMenuState.kadeEngineVer);
|
||||||
OutdatedSubState.needVer = returnedData[0];
|
OutdatedSubState.needVer = returnedData[0];
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
#if sys
|
#if sys
|
||||||
package smTools;
|
package smTools;
|
||||||
|
|
||||||
import sys.io.File;
|
import sys.io.File;
|
||||||
|
import haxe.Exception;
|
||||||
|
import lime.app.Application;
|
||||||
|
import haxe.Json;
|
||||||
|
|
||||||
class SMFile
|
class SMFile
|
||||||
{
|
{
|
||||||
@ -12,12 +14,18 @@ class SMFile
|
|||||||
|
|
||||||
private var _fileData:Array<String>;
|
private var _fileData:Array<String>;
|
||||||
|
|
||||||
|
public var isDouble:Bool = false;
|
||||||
|
|
||||||
|
public var isValid:Bool = true;
|
||||||
|
|
||||||
public var _readTime:Float = 0;
|
public var _readTime:Float = 0;
|
||||||
|
|
||||||
public var header:SMHeader;
|
public var header:SMHeader;
|
||||||
public var measures:Array<SMMeasure>;
|
public var measures:Array<SMMeasure>;
|
||||||
|
|
||||||
public function new(data:Array<String>)
|
public function new(data:Array<String>)
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
_fileData = data;
|
_fileData = data;
|
||||||
|
|
||||||
@ -26,36 +34,221 @@ class SMFile
|
|||||||
var inc = 0;
|
var inc = 0;
|
||||||
while(!StringTools.contains(data[inc + 1],"//"))
|
while(!StringTools.contains(data[inc + 1],"//"))
|
||||||
{
|
{
|
||||||
headerData += data[inc] + "\n";
|
headerData += data[inc];
|
||||||
inc++;
|
inc++;
|
||||||
// trace(data[inc]);
|
// trace(data[inc]);
|
||||||
}
|
}
|
||||||
|
|
||||||
header = new SMHeader(headerData.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.
|
// check if this is a valid file, it should be a dance double file.
|
||||||
inc += 3; // skip three lines down
|
inc += 3; // skip three lines down
|
||||||
if (!StringTools.contains(data[inc],"dance-double:"))
|
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;
|
return;
|
||||||
|
}
|
||||||
|
if (StringTools.contains(data[inc],"dance-double:"))
|
||||||
|
isDouble = true;
|
||||||
|
if (isDouble)
|
||||||
trace('this is dance double');
|
trace('this is dance double');
|
||||||
|
|
||||||
inc += 4; // skip 5 down to where da notes @
|
inc += 5; // skip 5 down to where da notes @
|
||||||
trace(data[inc]);
|
|
||||||
|
|
||||||
measures = [];
|
measures = [];
|
||||||
|
|
||||||
while(data[inc + 1] != ";")
|
|
||||||
{
|
|
||||||
var measure = "";
|
var measure = "";
|
||||||
while(data[inc + 1] != ",")
|
|
||||||
|
trace(data[inc - 1]);
|
||||||
|
|
||||||
|
for (ii in inc...data.length)
|
||||||
|
{
|
||||||
|
var i = data[ii];
|
||||||
|
if (StringTools.contains(i,",") || StringTools.contains(i,";"))
|
||||||
{
|
{
|
||||||
inc++;
|
|
||||||
var line = data[inc];
|
|
||||||
measure += line + "\n";
|
|
||||||
}
|
|
||||||
measures.push(new SMMeasure(measure.split('\n')));
|
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
|
#end
|
@ -15,15 +15,85 @@ class SMHeader
|
|||||||
public var BACKGROUND = "";
|
public var BACKGROUND = "";
|
||||||
public var CDTITLE = "";
|
public var CDTITLE = "";
|
||||||
public var OFFSET = "";
|
public var OFFSET = "";
|
||||||
public var BPMS = "";
|
public var BPMS = ""; // time=bpm
|
||||||
|
|
||||||
|
public var changeEvents:Array<Song.Event>;
|
||||||
|
|
||||||
public function new(headerData:Array<String>)
|
public function new(headerData:Array<String>)
|
||||||
{
|
{
|
||||||
_header = headerData;
|
_header = headerData;
|
||||||
|
|
||||||
for (i in headerData)
|
for (i in headerData)
|
||||||
|
{
|
||||||
readHeaderLine(i);
|
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)
|
function readHeaderLine(line:String)
|
||||||
{
|
{
|
||||||
var propName = line.split('#')[1].split(':')[0];
|
var propName = line.split('#')[1].split(':')[0];
|
||||||
|
@ -11,6 +11,19 @@ class SMMeasure
|
|||||||
{
|
{
|
||||||
_measure = measureData;
|
_measure = measureData;
|
||||||
notes = [];
|
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
|
#end
|
@ -3,8 +3,13 @@ package smTools;
|
|||||||
|
|
||||||
class SMNote
|
class SMNote
|
||||||
{
|
{
|
||||||
public var time:Float;
|
public var data:String;
|
||||||
public var data:Int;
|
public var lane:Int;
|
||||||
public var length:Float;
|
|
||||||
|
public function new(_data:String,_lane:Int)
|
||||||
|
{
|
||||||
|
data = _data;
|
||||||
|
lane = _lane;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#end
|
#end
|
Loading…
x
Reference in New Issue
Block a user