MajSimai is an interpreter for Simai, written in C#.
- Basic metadata fields
- Comments
||Hello world! - Custom simai commands with '=' as separator
&commandPrefix=value
- BPM declaration
(float) - Beats declaration
- Common
{int} - Absolute time
{#float}
- Common
- Tap
1- Break flag
1b - EX flag
1x - Mine flag
1m - Force star flag
1$- Fake rotation
1$$
- Fake rotation
- Break flag
- Hold
1h[duration]- Short form
1h - Break flag
1bh1hb
- Mine flag
1bm1mb
- Duration format:
- Common
[int:int] - With absolute time
[#float] - With custom BPM
[float#int:int]
- Common
- Short form
- Slide
x-y[duration]- Same head
1-3[duration]*-7[duration] - Break flag
1-3[duration]b1-3b[duration]
- Mine flag
1-3[duration]m1-3m[duration]
- Conn slide
1-3-5-7[duration]1-3[duration]-5[duration]-7[duration]
- No head slide:
-
1?-3[duration] -
1!-3[duration]
-
- Duration format:
-
[160#2.0] -
[3.0##1.5] -
[3.0##4:1] -
[3.0##160#4:1]
-
- Same head
- Touch
B1- Hanabi flag
B1f - Break flag
B1b - Mine flag
B1m - Ex flag
B1x
- Hanabi flag
- Touch hold
B1h[duration]- Short form
B1h - Hanabi flag
B1hf[duration] - Break flag
B1hb[duration] - Mine flag
B1hm[duration] - Ex flag
B1hx[duration] - Duration format:
- Common
[int:int] - With absolute time
[#float] - With custom BPM
[float#int:int]
- Common
- Short form
- Each note
note/note- Fake each
1`2`3`4,
- Fake each
- EOF flag
E
To use MajSimai in your own project, you will need to add a reference to the MajSimai library in your solution.
// Specify the chart file
var filePath = "/path/to/your/chart.txt";
using var fileStream = File.OpenRead(filePath);
// Parse into SimaiFile
var simaiFile = await SimaiParser.ParseAsync(fileStream);
// With special encoding
simaiFile = await SimaiParser.ParseAsync(fileStream, Encoding.ASCII);
// Or parse only metadata
var simaiMetadata = await SimaiParser.ParseMetadataAsync(fileStream);
// With special encoding
simaiMetadata = await SimaiParser.ParseMetadataAsync(fileStream, Encoding.ASCII);
// Or parse from the chart text you provide
var fumen = "(197){8}1,1,1,1,1,1,1,1,2b,3h,4-1[8:1],";
var simaiChart = await SimaiParser.ParseChartAsync(fumen);If you want to compile MajSimai yourself, please make sure that dotnet is installed on your computer.
The target frameworks available for MajSimai are as follows:
netstandard2.1net5.0net6.0net7.0net8.0net9.0
Then, use the following method to compile it:
git clone https://github.com/LingFeng-bbben/MajSimai.git
cd MajSimai
dotnet restore
# Feel free to change the target framework
# If you want to generate nuget package, please remove /p:GeneratePackageOnBuild=false
dotnet publish -c release /p:PublishAot=false /p:GeneratePackageOnBuild=false -f netstandard2.1
MajSimai is AOT and Trim compatible.
If you want to compile native library, you need to specify the use of AOT.
dotnet publish -c release /p:PublishAot=true -f net9.0 -r linux-x64In the native library, MajSimai will export functions:
MajSimai!MajSimai_ParseMajSimai!MajSimai_FreeMajSimai!MajSimai_FreeHGlobal
You can use these exported functions in C++:
struct MajSimaiParseResult
{
int32_t code = -1;
int32_t errorAtLine = -1;
int32_t errorAtColumn = -1;
int32_t errorMsgLen = 0;
int32_t errorContentLen = 0;
void* simaiFile = NULL;
char* errorMsgAnsi = NULL;
char* errorContentAnsi = NULL;
};
extern "C" void __cdecl MajSimai_Parse(char*, int32_t, void*);
extern "C" bool __cdecl MajSimai_Free(MajSimaiParseResult*);
extern "C" bool __cdecl MajSimai_FreeHGlobal(void*);
int main()
{
const string FUMEN = R"(&title=Test
&artist=NULL
&first=0
&des=1
&lv_5=114514
&inote_5=
(197){8}1,2,3,4,5,6,7,8,)";
MajSimaiParseResult result = MajSimaiParseResult();
MajSimai_Parse(FUMEN.data(), FUMEN.length(), &result);
MajSimai_Free(&result);
}