1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
|
import 'dart:ffi';
import 'dart:io';
enum Difficulty { Beginner, Easy, Medium, Hard, Challenge, Edit }
// These are the standard note values:
//
// 0 – No note
// 1 – Normal note
// 2 – Hold head
// 3 – Hold/Roll tail
// 4 – Roll head
// M – Mine (or other negative note)
//
// Later versions of StepMania accept other note values which may not work in older versions:
//
// K – Automatic keysound
// L – Lift note
// F – Fake note
RegExp noteTypes = RegExp(r'^([012345MKLF]+)\s*([,;])?');
class Chart {
String? chartType;
// Description/author
String? author;
// Difficulty (one of Beginner, Easy, Medium, Hard, Challenge, Edit)
Difficulty? difficulty;
// Numerical meter
int? numericalMeter;
// Groove radar values, generated by the program
String? radarValues;
List<List<String>>? measures;
}
class Simfile {
String path;
String? lines;
// tags of simfile
Map<String, String> tags = {};
Chart? chartSimplest;
Map<double, double> bpms = {};
double offset = 0;
Simfile(this.path);
void load() {
lines = File(path).readAsStringSync();
RegExp commentsRegExp = RegExp(r'//.*$');
lines = lines?.replaceAll(commentsRegExp, '');
RegExp fieldDataRegExp = RegExp(r'#([^;]+):([^;]*);');
for (final fieldData in fieldDataRegExp.allMatches(lines!)) {
List<String> keys =
fieldData[1]!.split(':').map((key) => key.trim()).toList();
String value = fieldData[2]!;
if (keys[0] == "BPMS") {
for (final pairRaw in value.split(',')) {
List<String> pair = pairRaw.split('=');
if (pair.length != 2) {
continue;
}
double time = double.parse(pair[0]);
double bpm = double.parse(pair[1]);
bpms[time] = bpm;
}
}
if (keys[0] == "OFFSET") {
offset = double.parse(value);
}
if (keys[0] != "NOTES") {
tags[keys[0]] = value;
continue;
}
Chart chart = Chart();
chart.chartType = keys[1];
chart.author = keys[2];
chart.difficulty = Difficulty.values.byName(keys[3]);
chart.numericalMeter = int.parse(keys[4]);
chart.radarValues = keys[5];
if (chartSimplest == null ||
(chart.difficulty!.index <= chartSimplest!.difficulty!.index &&
chart.numericalMeter! <= chartSimplest!.numericalMeter!)) {
List<List<String>> measures = [];
for (final measureRaw in value.split(',')) {
List<String> measure = [];
for (final noteRaw in measureRaw.split('\n')) {
String note = noteRaw.trim();
if (noteTypes.hasMatch(note)) {
measure.add(note);
}
}
measures.add(measure);
}
chart.measures = measures;
chartSimplest = chart;
}
}
}
}
|