diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/level.dart | 71 | ||||
| -rw-r--r-- | lib/simfile.dart | 20 | 
2 files changed, 74 insertions, 17 deletions
| diff --git a/lib/level.dart b/lib/level.dart index 369a162..01083e2 100644 --- a/lib/level.dart +++ b/lib/level.dart @@ -13,6 +13,24 @@ class Level extends StatefulWidget {    State<Level> createState() => _LevelState();  } +enum ArrowDirection { +  left(Icons.arrow_back), +  down(Icons.arrow_downward), +  up(Icons.arrow_upward), +  right(Icons.arrow_forward); + +  const ArrowDirection(this.icon); + +  final IconData icon; +} + +class Note { +  final double time; +  final ArrowDirection direction; + +  const Note({required this.time, required this.direction}); +} +  class _LevelState extends State<Level> {    final player = AudioPlayer();    Simfile? simfile; @@ -23,6 +41,8 @@ class _LevelState extends State<Level> {    StreamSubscription? _durationSubscription;    StreamSubscription? _positionSubscription; +  List<Note> notes = []; +    @override    void setState(VoidCallback fn) {      // Subscriptions only can be closed asynchronously, @@ -79,6 +99,25 @@ class _LevelState extends State<Level> {      simfile = Simfile(simfilePath);      simfile!.load(); +    double bpm = simfile!.bpms.entries.first.value; + +    for (final (measureIndex, measure) +        in simfile!.chartSimplest!.measures!.indexed) { +      for (final (noteIndex, noteData) in measure.indexed) { +        int arrowIndex = noteData.indexOf('1'); +        if (arrowIndex < 0 || arrowIndex > 3) { +          continue; +        } +        notes.add(Note( +            time: (measureIndex * 4.0 + +                        (noteIndex.toDouble() / measure.length) * 4.0) * +                    1.0 / +                    bpm + +                simfile!.offset / 60.0, +            direction: ArrowDirection.values[arrowIndex])); +      } +    } +      print(audioPath);      player.play(DeviceFileSource(audioPath)); @@ -86,7 +125,6 @@ class _LevelState extends State<Level> {    @override    Widget build(BuildContext context) { -      return Scaffold(          appBar: AppBar(            leading: IconButton( @@ -123,18 +161,16 @@ class _LevelState extends State<Level> {                )),          ),          body: Stack(children: [ -          Arrow( -            position: -100.0, -          ), -          Arrow( -            position: 00.0, -          ), -          Arrow( -            position: 100.0, -          ), -          Arrow( -            position: 200.0, -          ), +          ...notes.map((note) { +            return Arrow( +              position: _position != null +                  ? (note.time - _position!.inMilliseconds / 60000.0) * +                      20 * +                      MediaQuery.of(context).size.height +                  : 0.0, +              direction: note.direction, +            ); +          }),            Positioned(              top: 50,              width: MediaQuery.of(context).size.width, @@ -171,15 +207,16 @@ class _LevelState extends State<Level> {  class Arrow extends StatelessWidget {    final double position; +  final ArrowDirection direction; -  const Arrow({super.key, required this.position}); +  const Arrow({super.key, required this.position, required this.direction});    @override    Widget build(BuildContext context) {      return Positioned( -      left: MediaQuery.of(context).size.width / 2 - 25, // Center the arrow -      top: position, -      child: Icon(size: 100, Icons.arrow_forward), +      left: MediaQuery.of(context).size.width / 2 - 50, // Center the arrow +      bottom: position + 50, +      child: Icon(size: 100, color: Colors.redAccent.shade400, direction.icon),      );    }  } diff --git a/lib/simfile.dart b/lib/simfile.dart index 20e79e8..2174de9 100644 --- a/lib/simfile.dart +++ b/lib/simfile.dart @@ -1,3 +1,4 @@ +import 'dart:ffi';  import 'dart:io';  enum Difficulty { Beginner, Easy, Medium, Hard, Challenge, Edit } @@ -42,6 +43,9 @@ class Simfile {    Chart? chartSimplest; +  Map<double, double> bpms = {}; +  double offset = 0; +    Simfile(this.path);    void load() { @@ -55,6 +59,22 @@ class Simfile {        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; | 
