Skip to content

Commit 84a39e5

Browse files
committed
[R] Chart相关重构(第二步)——使用BaseChart中提供的List对象
1 parent a0ff8b0 commit 84a39e5

10 files changed

Lines changed: 131 additions & 63 deletions

File tree

chart/chu/C2sChart.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using MuConvert.chart;
2+
using Rationals;
23

34
namespace MuConvert.chu;
45

@@ -15,7 +16,5 @@ public class C2sChart : BaseChart<ChuNote>, IChuChart
1516
public decimal Level { get; set; } // 定数,小数
1617
public string MusicId { get; set; } = "0";
1718
public int Resolution { get; set; } = 384;
18-
public List<(int Measure, int Offset, double Bpm)> BpmEvents = [];
19-
public List<(int Measure, int Offset, int Denom, int Num)> MetEvents = [];
20-
public List<(int Measure, int Offset, int Duration, double Multiplier)> SflEvents = [];
19+
public List<(Rational Time, Rational Duration, decimal Multiplier)> SflList = []; // 所有变速声明构成的列表。
2120
}

chart/chu/SusChart.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,4 @@ public class SusChart : BaseChart<ChuNote>, IChuChart
1111
public string Artist { get; set; } = "";
1212
public string Designer { get; set; } = "";
1313
public int TicksPerBeat { get; set; } = 480;
14-
public List<(int Measure, int Offset, double Bpm)> BpmEvents = [];
1514
}

chart/chu/UgcChart.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using MuConvert.chart;
2+
using Rationals;
23

34
namespace MuConvert.chu;
45

@@ -15,7 +16,5 @@ public class UgcChart : BaseChart<ChuNote>, IChuChart
1516
public decimal Level { get; set; }
1617
public string MusicId { get; set; } = "";
1718
public int TicksPerBeat { get; set; } = 480;
18-
public List<(int Measure, int Num, int Den)> BeatEvents = [];
19-
public List<(int Measure, int Offset, double Bpm)> BpmEvents = [];
20-
public List<(int Measure, int Offset, double Multiplier)> SpeedEvents = [];
19+
public List<(Rational Time, Rational Duration, decimal Multiplier)> SflList = []; // 所有变速声明构成的列表。
2120
}

generator/chu/C2sGenerator.cs

Lines changed: 28 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System.Globalization;
22
using System.Text;
3+
using MuConvert.chart;
34
using MuConvert.generator;
45
using MuConvert.utils;
56
using static MuConvert.utils.Alert.LEVEL;
@@ -12,8 +13,6 @@ namespace MuConvert.chu;
1213
*/
1314
public class C2sGenerator : IGenerator<IChuChart>
1415
{
15-
private const int C2sResolution = 384;
16-
1716
public (string, List<Alert>) Generate(IChuChart chart)
1817
{
1918
var alerts = new List<Alert>();
@@ -32,18 +31,19 @@ private static C2sChart ConvertToC2s(IChuChart chart, List<Alert> alerts)
3231
{
3332
Designer = ugc.Designer,
3433
};
35-
foreach (var b in ugc.BpmEvents)
36-
result.BpmEvents.Add((b.Measure, ScaleDown(b.Offset, ugc.TicksPerBeat), b.Bpm));
37-
foreach (var b in ugc.BeatEvents)
38-
result.MetEvents.Add((b.Measure, 0, b.Den, b.Num));
34+
result.BpmList.AddRange(ugc.BpmList);
35+
result.MetList.AddRange(ugc.MetList);
3936
result.Notes = ugc.Notes;
4037
return result;
4138
}
4239

4340
if (chart is SusChart sus)
4441
{
4542
var result = new C2sChart();
46-
// result.BpmEvents.Add((0, 0, sus.Bpm));
43+
if (sus.BpmList.Count > 0)
44+
result.BpmList.AddRange(sus.BpmList);
45+
else
46+
result.BpmList.Add(new BPM(0, 120m));
4747
result.Notes = sus.Notes;
4848
return result;
4949
}
@@ -52,8 +52,6 @@ private static C2sChart ConvertToC2s(IChuChart chart, List<Alert> alerts)
5252
throw new ConversionException(alerts);
5353
}
5454

55-
private static int ScaleDown(int ticks, int tpb) => (int)((long)ticks * (C2sResolution / 4) / tpb);
56-
5755
private static string Serialize(C2sChart chart)
5856
{
5957
chart.Sort();
@@ -76,12 +74,25 @@ private static string Serialize(C2sChart chart)
7674
sb.AppendLine("TUTORIAL\t0");
7775
sb.AppendLine();
7876

79-
foreach (var b in chart.BpmEvents)
80-
sb.AppendLine($"BPM\t{b.Measure}\t{b.Offset}\t{Fmt(b.Bpm)}");
81-
foreach (var m in chart.MetEvents)
82-
sb.AppendLine($"MET\t{m.Measure}\t{m.Offset}\t{m.Denom}\t{m.Num}");
83-
foreach (var s in chart.SflEvents)
84-
sb.AppendLine($"SFL\t{s.Measure}\t{s.Offset}\t{s.Duration}\t{Mlt(s.Multiplier)}");
77+
var res = chart.Resolution;
78+
foreach (var b in chart.BpmList)
79+
{
80+
var (m, o) = Utils.BarAndTick(b.Time, res);
81+
sb.AppendLine($"BPM\t{m}\t{o}\t{b.Bpm:0.000}");
82+
}
83+
84+
foreach (var met in chart.MetList)
85+
{
86+
var (m, o) = Utils.BarAndTick(met.Time, res);
87+
sb.AppendLine($"MET\t{m}\t{o}\t{met.Denominator}\t{met.Numerator}");
88+
}
89+
90+
foreach (var s in chart.SflList.OrderBy(s => s.Time))
91+
{
92+
var (m, o) = Utils.BarAndTick(s.Time, res);
93+
var durTicks = Utils.Tick(s.Duration, res);
94+
sb.AppendLine($"SFL\t{m}\t{o}\t{durTicks}\t{s.Multiplier:0.000000}");
95+
}
8596
sb.AppendLine();
8697

8798
foreach (var n in chart.Notes)
@@ -93,8 +104,8 @@ private static string Serialize(C2sChart chart)
93104

94105
private static string FormatNote(ChuNote n, int tpm)
95106
{
96-
var (m, o) = Utils.BarAndTick(n.Time, tpm, 0);
97-
var durTicks = Utils.Tick(n.Duration, tpm, 0);
107+
var (m, o) = Utils.BarAndTick(n.Time, tpm);
108+
var durTicks = Utils.Tick(n.Duration, tpm);
98109
return n.Type switch
99110
{
100111
"TAP" => $"TAP\t{m}\t{o}\t{n.Cell}\t{n.Width}",
@@ -132,7 +143,4 @@ private static string FormatAld(ChuNote n, int m, int o)
132143
var tail = n.ExtraData.Count > 3 ? n.ExtraData[3] : 0;
133144
return $"ALD\t{m}\t{o}\t{n.Cell}\t{n.Width}\t{a}\t{b}\t{c}\t{n.EndCell}\t{n.EndWidth}\t{tail}";
134145
}
135-
136-
private static string Fmt(double v) => v.ToString("0.000", CultureInfo.InvariantCulture);
137-
private static string Mlt(double v) => v.ToString("0.000000", CultureInfo.InvariantCulture);
138146
}

generator/chu/SusGenerator.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System.Text;
2+
using MuConvert.chart;
23
using MuConvert.generator;
34
using MuConvert.utils;
45
using static MuConvert.utils.Alert.LEVEL;
@@ -30,16 +31,18 @@ private static SusChart ConvertToSus(IChuChart chart, List<Alert> alerts)
3031

3132
if (chart is C2sChart c2s)
3233
{
33-
bpm = c2s.BpmEvents[0].Bpm;
34+
bpm = c2s.BpmList.Count > 0 ? (double)c2s.BpmList[0].Bpm : 120.0;
3435
var result = new SusChart { TicksPerBeat = SusTpb, Title = title, Artist = artist };
36+
result.BpmList.Add(new BPM(0, (decimal)bpm));
3537
result.Notes = c2s.Notes;
3638
return result;
3739
}
3840

3941
if (chart is UgcChart ugc)
4042
{
41-
bpm = ugc.BpmEvents.Count > 0 ? ugc.BpmEvents[0].Bpm : 120.0;
43+
bpm = ugc.BpmList.Count > 0 ? (double)ugc.BpmList[0].Bpm : 120.0;
4244
var result = new SusChart { TicksPerBeat = SusTpb, Title = ugc.Title, Artist = ugc.Artist };
45+
result.BpmList.Add(new BPM(0, (decimal)bpm));
4346
result.Notes = ugc.Notes;
4447
return result;
4548
}

generator/chu/UgcGenerator.cs

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ namespace MuConvert.chu;
1212
public class UgcGenerator : IGenerator<IChuChart>
1313
{
1414
private const int UgcTicksPerBeat = 480;
15-
private const int C2sResolution = 384;
1615

1716
public (string, List<Alert>) Generate(IChuChart chart)
1817
{
@@ -35,10 +34,8 @@ private static UgcChart ConvertToUgc(IChuChart chart, List<Alert> alerts)
3534
Difficulty = c2s.Difficulty,
3635
MusicId = c2s.MusicId,
3736
};
38-
foreach (var b in c2s.BpmEvents)
39-
result.BpmEvents.Add((b.Measure, ScaleUp(b.Offset), b.Bpm));
40-
foreach (var m in c2s.MetEvents)
41-
result.BeatEvents.Add((m.Measure, m.Num, m.Denom));
37+
result.BpmList.AddRange(c2s.BpmList);
38+
result.MetList.AddRange(c2s.MetList);
4239
result.Notes = c2s.Notes;
4340
return result;
4441
}
@@ -47,8 +44,6 @@ private static UgcChart ConvertToUgc(IChuChart chart, List<Alert> alerts)
4744
throw new ConversionException(alerts);
4845
}
4946

50-
private static int ScaleUp(int v) => (int)((long)v * UgcTicksPerBeat / (C2sResolution / 4));
51-
5247
private static string Serialize(UgcChart ugc)
5348
{
5449
ugc.Sort();
@@ -63,20 +58,28 @@ private static string Serialize(UgcChart ugc)
6358
sb.AppendLine($"@CONST\t{ugc.Level:F5}");
6459
sb.AppendLine($"@SONGID\t{ugc.MusicId}");
6560
sb.AppendLine($"@TICKS\t{ugc.TicksPerBeat}");
66-
foreach (var b in ugc.BeatEvents) sb.AppendLine($"@BEAT\t{b.Measure}\t{b.Num}\t{b.Den}");
67-
foreach (var b in ugc.BpmEvents) sb.AppendLine($"@BPM\t{b.Measure}'{b.Offset}\t{b.Bpm:F5}");
61+
var tpm = ugc.TicksPerBeat * 4;
62+
foreach (var met in ugc.MetList)
63+
{
64+
var (m, _) = Utils.BarAndTick(met.Time, tpm);
65+
sb.AppendLine($"@BEAT\t{m}\t{met.Numerator}\t{met.Denominator}");
66+
}
67+
foreach (var b in ugc.BpmList)
68+
{
69+
var (m, o) = Utils.BarAndTick(b.Time, tpm);
70+
sb.AppendLine($"@BPM\t{m}'{o}\t{b.Bpm:F5}");
71+
}
6872
sb.AppendLine("@TIL\t0\t0'0\t1.00000");
6973
sb.AppendLine("@MAINTIL\t0");
7074
sb.AppendLine("@ENDHEAD");
7175
sb.AppendLine();
7276

73-
var tpm = ugc.TicksPerBeat * 4;
7477
foreach (var n in ugc.Notes)
7578
{
76-
var (m, o) = Utils.BarAndTick(n.Time, tpm, 0);
79+
var (m, o) = Utils.BarAndTick(n.Time, tpm);
7780
sb.Append($"#{m}'{o}:{UCode(n, tpm)}");
7881
sb.AppendLine();
79-
var durTicks = Utils.Tick(n.Duration, tpm, 0);
82+
var durTicks = Utils.Tick(n.Duration, tpm);
8083
if (n.Type == "HLD" && durTicks > 0)
8184
sb.AppendLine($"#{durTicks}>s");
8285
else if (n.Type == "SLD" && durTicks > 0)
@@ -88,7 +91,7 @@ private static string Serialize(UgcChart ugc)
8891
private static string UCode(ChuNote n, int tpm)
8992
{
9093
string c = Hx(n.Cell), w = Hw(n.Width);
91-
var durTicks = Utils.Tick(n.Duration, tpm, 0);
94+
var durTicks = Utils.Tick(n.Duration, tpm);
9295
var targetNote = string.IsNullOrEmpty(n.TargetNote) ? "N" : n.TargetNote;
9396
return n.Type switch
9497
{

parser/chu/C2sParser.cs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System.Globalization;
2+
using MuConvert.chart;
23
using MuConvert.parser;
34
using MuConvert.utils;
45
using Rationals;
@@ -67,16 +68,20 @@ private static void ParseHeader(string[] p, C2sChart chart)
6768
private static void ParseTiming(string[] p, C2sChart chart)
6869
{
6970
var tag = p[0].ToUpperInvariant();
71+
var tpm = chart.Resolution;
7072
switch (tag)
7173
{
7274
case "BPM":
73-
chart.BpmEvents.Add((Int(p, 1), Int(p, 2), Dbl(p, 3, 120.0)));
75+
chart.BpmList.Add(new BPM(Int(p, 1) + new Rational(Int(p, 2), tpm), decimal.Parse(p[3])));
7476
break;
7577
case "MET":
76-
chart.MetEvents.Add((Int(p, 1), Int(p, 2), Int(p, 3, 4), Int(p, 4, 4)));
78+
chart.MetList.Add(new MET(Int(p, 1) + new Rational(Int(p, 2), tpm), Int(p, 4, 4), Int(p, 3, 4)));
7779
break;
7880
case "SFL":
79-
chart.SflEvents.Add((Int(p, 1), Int(p, 2), Int(p, 3), Dbl(p, 4, 1.0)));
81+
chart.SflList.Add((
82+
Int(p, 1) + new Rational(Int(p, 2), tpm),
83+
new Rational(Int(p, 3), tpm),
84+
decimal.Parse(p[4])));
8085
break;
8186
}
8287
}
@@ -144,6 +149,5 @@ private static void ParseNote(string[] p, C2sChart chart, List<Alert> alerts, in
144149
}
145150

146151
private static int Int(string[] p, int i, int def = 0) => i < p.Length && int.TryParse(p[i], NumberStyles.Integer, CultureInfo.InvariantCulture, out var v) ? v : def;
147-
private static double Dbl(string[] p, int i, double def = 0) => i < p.Length && double.TryParse(p[i], NumberStyles.Float, CultureInfo.InvariantCulture, out var v) ? v : def;
148152
private static string Str(string[] p, int i) => i < p.Length ? p[i] : "";
149153
}

parser/chu/SusParser.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System.Globalization;
2+
using MuConvert.chart;
23
using MuConvert.parser;
34
using MuConvert.utils;
45
using Rationals;
@@ -84,7 +85,7 @@ private static void ParseHeaderLine(string content, SusChart chart, List<Alert>
8485
{
8586
var bpmStr = content[8..].Trim().Trim('"');
8687
if (double.TryParse(bpmStr, NumberStyles.Float, CultureInfo.InvariantCulture, out var bpm))
87-
chart.BpmEvents.Add((0, 0, bpm));
88+
chart.BpmList.Add(new BPM(0, (decimal)bpm));
8889
else
8990
alerts.Add(new Alert(Warning, $"BPM_DEF 格式错误: {content}") { Line = lineNum });
9091
}

parser/chu/UgcParser.cs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System.Globalization;
2+
using MuConvert.chart;
23
using MuConvert.parser;
34
using MuConvert.utils;
45
using Rationals;
@@ -138,7 +139,7 @@ private static void ParseHeaderLine(string line, UgcChart chart, List<Alert> ale
138139
&& int.TryParse(beatParts[1], NumberStyles.Integer, CultureInfo.InvariantCulture, out var beatNum)
139140
&& int.TryParse(beatParts[2], NumberStyles.Integer, CultureInfo.InvariantCulture, out var beatDen))
140141
{
141-
chart.BeatEvents.Add((beatMeasure, beatNum, beatDen));
142+
chart.MetList.Add(new MET(beatMeasure, beatNum, beatDen));
142143
}
143144
else
144145
{
@@ -157,9 +158,10 @@ private static void ParseHeaderLine(string line, UgcChart chart, List<Alert> ale
157158
if (apostropheIdx > 0
158159
&& int.TryParse(measureOffset[..apostropheIdx], NumberStyles.Integer, CultureInfo.InvariantCulture, out var bpmMeasure)
159160
&& int.TryParse(measureOffset[(apostropheIdx + 1)..], NumberStyles.Integer, CultureInfo.InvariantCulture, out var bpmOffset)
160-
&& double.TryParse(bpmValueStr, NumberStyles.Float, CultureInfo.InvariantCulture, out var bpmValue))
161+
&& decimal.TryParse(bpmValueStr, NumberStyles.Float, CultureInfo.InvariantCulture, out var bpmValue))
161162
{
162-
chart.BpmEvents.Add((bpmMeasure, bpmOffset, bpmValue));
163+
var tpm = chart.TicksPerBeat * 4;
164+
chart.BpmList.Add(new BPM(bpmMeasure + new Rational(bpmOffset, tpm), bpmValue));
163165
}
164166
else
165167
{
@@ -176,15 +178,15 @@ private static void ParseHeaderLine(string line, UgcChart chart, List<Alert> ale
176178
case "@VER": case "@EXVER": case "@SORT": case "@BGM": case "@BGMOFS": case "@BGMPRV":
177179
case "@JACKET": case "@BGIMG": case "@BGMODE": case "@FLDCOL": case "@FLDIMG":
178180
case "@FLAG": case "@ATINFO": case "@DLURL": case "@COPYRIGHT": case "@LICENSE":
179-
case "@MAINTIL":
181+
case "@MAINTIL": case "@TIL":
180182
break;
181183

182-
case "@TIL": case "@SPDMOD":
184+
case "@SPDMOD":
183185
{
184186
var parts = value.Split(['\t', ' '], StringSplitOptions.RemoveEmptyEntries);
185187
if (parts.Length >= 2 && int.TryParse(parts[0], NumberStyles.Integer, CultureInfo.InvariantCulture, out var tilMeasure)
186188
&& double.TryParse(parts[1], NumberStyles.Float, CultureInfo.InvariantCulture, out var tilMult))
187-
chart.SpeedEvents.Add((tilMeasure, 0, tilMult));
189+
chart.SflList.Add((tilMeasure, Rational.Zero, (decimal)tilMult));
188190
}
189191
break;
190192

0 commit comments

Comments
 (0)