Skip to content

Commit 178664f

Browse files
committed
[+] Support for MA2 102
1 parent 7215b3f commit 178664f

17 files changed

Lines changed: 4755 additions & 17 deletions

File tree

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,6 @@ riderModule.iml
55
/_ReSharper.Caches/
66
/.idea/
77
*.DotSettings.user
8-
.cursor
8+
.cursor
9+
/.tmp*
10+
*scratch*

i18n/Locale.Designer.cs

Lines changed: 10 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

i18n/Locale.resx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,10 @@
128128
<value>The chart has no BPM line; parsing cannot continue!</value>
129129
</data>
130130
<data name="UnsuppoertedMA2Version" xml:space="preserve">
131-
<value>This MA2 version is not supported yet. Currently only MA2 1.03–1.05 are supported.</value>
131+
<value>This MA2 version is not supported yet. Currently only MA2 1.02–1.05 are supported.</value>
132+
</data>
133+
<data name="WarnNonStdMA2Version" xml:space="preserve">
134+
<value>Non-standard MA2 version encountered: {0}</value>
132135
</data>
133136
<data name="UnsuppoertedMA2MET_DEF" xml:space="preserve">
134137
<value>Charts whose MET_DEF is not "4 4" are not supported yet!</value>

i18n/Locale.zh-hans.resx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,10 @@
128128
<value>谱面中没有BPM语句,无法完成解析!</value>
129129
</data>
130130
<data name="UnsuppoertedMA2Version" xml:space="preserve">
131-
<value>此MA2的版本尚不支持!目前仅支持MA2 1.03~1.05。</value>
131+
<value>此MA2的版本尚不支持!目前仅支持MA2 1.02~1.05。</value>
132+
</data>
133+
<data name="WarnNonStdMA2Version" xml:space="preserve">
134+
<value>遇到了非标准的MA2版本号: {0}</value>
132135
</data>
133136
<data name="UnsuppoertedMA2MET_DEF" xml:space="preserve">
134137
<value>暂不支持MET_DEF不为"4 4"的谱面!</value>

i18n/Locale.zh-hant.resx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,10 @@
128128
<value>譜面中沒有 BPM 語句,無法完成解析!</value>
129129
</data>
130130
<data name="UnsuppoertedMA2Version" xml:space="preserve">
131-
<value>此 MA2 的版本尚不支援!目前僅支援 MA2 1.03~1.05。</value>
131+
<value>此 MA2 的版本尚不支援!目前僅支援 MA2 1.02~1.05。</value>
132+
</data>
133+
<data name="WarnNonStdMA2Version" xml:space="preserve">
134+
<value>遇到了非標準的 MA2 版本號: {0}</value>
132135
</data>
133136
<data name="UnsuppoertedMA2MET_DEF" xml:space="preserve">
134137
<value>暫不支援 MET_DEF 不為 "4 4" 的譜面!</value>

parser/MA2Parser.cs

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System.Text.RegularExpressions;
12
using MuConvert.chart;
23
using MuConvert.utils;
34
using Rationals;
@@ -12,6 +13,7 @@ public class MA2Parser : IParser
1213

1314
private bool bpmRead = false;
1415
private int RSL = 384;
16+
public int MA2Version;
1517

1618
private Dictionary<(Rational, int), List<Slide>> _slides = new();
1719

@@ -55,17 +57,17 @@ private void WarnParamsCount(int lineNo, ReadOnlySpan<char> line, Rational? time
5557
// 头字段
5658
if (cmd == "VERSION" && AssertInHeader(lineNo, line))
5759
{
58-
if (!(values[2] == "1.03.00" || values[2] == "1.04.00" || values[2] == "1.05.00")) Fail(Locale.UnsuppoertedMA2Version, lineNo, line);
59-
}
60-
else if (cmd == "MET_DEF" && AssertInHeader(lineNo, line))
61-
{
62-
if (!(values[1] == "4" && values[2] == "4")) Fail(Locale.UnsuppoertedMA2MET_DEF, lineNo, line);
60+
var version = Regex.Match(values[2], @"1\.(0?[2-5])\.(\d+)");
61+
MA2Version = 100 + int.Parse(version.Groups[1].Value);
62+
if (!version.Success) Fail(Locale.UnsuppoertedMA2Version, lineNo, line);
63+
else if (!(MA2Version is 103 or 104 or 105 && int.Parse(version.Groups[2].Value) == 0))
64+
alerts.Add(new Alert(Warning, string.Format(Locale.WarnNonStdMA2Version, values[2]), line: lineNo, relevantNote: line.ToString()));
6365
}
6466
else if (cmd == "COMPATIBLE_CODE" && AssertInHeader(lineNo, line))
6567
{
6668
if (values[1] != "MA2") Fail(Locale.UnsuppoertedMA2Version, lineNo, line);
6769
}
68-
else if (cmd is "FES_MODE" or "BPM_DEF" or "GENERATED_BY" && AssertInHeader(lineNo, line)) {} // 这些不用解析,无事可做
70+
else if (cmd is "FES_MODE" or "MET_DEF" or "BPM_DEF" or "GENERATED_BY" && AssertInHeader(lineNo, line)) {} // 这些不用解析,无事可做
6971
else if (cmd == "RESOLUTION" && AssertInHeader(lineNo, line))
7072
RSL = int.Parse(values[1]);
7173
else if (cmd == "CLK_DEF" && AssertInHeader(lineNo, line))
@@ -115,17 +117,21 @@ private void WarnParamsCount(int lineNo, ReadOnlySpan<char> line, Rational? time
115117
note.Duration = duration;
116118
if (values.Length != 5) WarnParamsCount(lineNo, line, time);
117119
}
118-
else if (cc == "TTP" && values.Length >= 7)
120+
else if (cc == "TTP" && values.Length >= 6)
119121
{
120-
note = new Touch(chart, time) { TouchArea = GetTouchArea(values[4], key), IsFirework = values[5] == "1", TouchSize = values[6]};
121-
if (values.Length != 7) WarnParamsCount(lineNo, line, time);
122+
var touch = new Touch(chart, time) { TouchArea = GetTouchArea(values[4], key), IsFirework = values[5] == "1"};
123+
note = touch;
124+
if (values.Length >= 7) touch.TouchSize = values[6];
125+
if (!(values.Length == 7 || (values.Length == 6 && MA2Version == 102))) WarnParamsCount(lineNo, line, time);
122126
}
123-
else if (cc == "THO" && values.Length >= 8 && int.TryParse(values[4], out len))
127+
else if (cc == "THO" && values.Length >= 7 && int.TryParse(values[4], out len))
124128
{
125-
note = new TouchHold(chart, time) { TouchArea = GetTouchArea(values[5], key), IsFirework = values[6] == "1", TouchSize = values[7]};
129+
var touchHold = new TouchHold(chart, time) { TouchArea = GetTouchArea(values[5], key), IsFirework = values[6] == "1"};
130+
note = touchHold;
131+
if (values.Length >= 8) touchHold.TouchSize = values[7];
126132
var duration = new Duration(note) { Bar = new Rational(len, RSL) };
127133
note.Duration = duration;
128-
if (values.Length != 8) WarnParamsCount(lineNo, line, time);
134+
if (!(values.Length == 8 || (values.Length == 7 && MA2Version == 102))) WarnParamsCount(lineNo, line, time);
129135
}
130136
else if (SlideTypeTool.IsSlide(cc) && values.Length >= 7 && int.TryParse(values[4], out var waitLen)
131137
&& int.TryParse(values[5], out len) && int.TryParse(values[6], out var endKey))

tests/TestUtils.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ namespace MuConvert.Tests;
1111
internal static class TestUtils
1212
{
1313
private static readonly Regex Ma2ClkDefLineRegex = new(@"^CLK_DEF\t(\d+)\s*$", RegexOptions.Multiline | RegexOptions.CultureInvariant);
14+
private static readonly Regex Ma2ClkLineRegex = new(@"^CLK\t(\d+)\s", RegexOptions.Multiline | RegexOptions.CultureInvariant);
1415

1516
/// <summary>
1617
/// 从测试运行目录向上查找包含 MuConvert.csproj 的仓库根目录。
@@ -31,6 +32,11 @@ public static DirectoryInfo FindRepoRoot()
3132
{
3233
var m = Ma2ClkDefLineRegex.Match(ma2Text);
3334
if (!m.Success || !int.TryParse(m.Groups[1].Value, out var v)) return null;
35+
if (v == 0)
36+
{ // 对CLK_DEF为0的情况,就数一下CLK指令的个数,等效一下
37+
var rawClkLines = Ma2ClkLineRegex.Matches(ma2Text);
38+
v = rawClkLines.Count * 96;
39+
}
3440
return v;
3541
}
3642

0 commit comments

Comments
 (0)