190 lines
5.0 KiB
D
190 lines
5.0 KiB
D
module cm3d2.menu;
|
|
|
|
import std.bitmanip;
|
|
import std.conv;
|
|
import std.math;
|
|
import std.array;
|
|
import std.range;
|
|
|
|
import sdlang;
|
|
|
|
class Menu
|
|
{
|
|
private static string[string] _translations;
|
|
|
|
static this()
|
|
{
|
|
_translations["メニューフォルダ"] = "menufolder";
|
|
_translations["setumei"] = "description";
|
|
_translations["アタッチポイントの設定"] = "attachpoint";
|
|
_translations["属性追加"] = "addattribute";
|
|
}
|
|
|
|
uint fileVersion;
|
|
string path;
|
|
|
|
string name;
|
|
string category;
|
|
string description;
|
|
|
|
string[][] lines;
|
|
|
|
public static Menu fromSDL(string sdl)
|
|
{
|
|
throw new Exception("Not implemented yet");
|
|
}
|
|
|
|
public static Menu fromMenu(ubyte[] data)
|
|
{
|
|
auto menu = new Menu();
|
|
|
|
ubyte readByte()
|
|
{
|
|
auto value = data[0];
|
|
data = data[1 .. $];
|
|
return value;
|
|
}
|
|
|
|
string readString()
|
|
{
|
|
auto length = 0;
|
|
ubyte[] chars;
|
|
|
|
while (true)
|
|
{
|
|
auto lengthByte = readByte();
|
|
|
|
if (length != 0 && lengthByte < 128)
|
|
{
|
|
break;
|
|
}
|
|
|
|
length = length << 8 | lengthByte;
|
|
|
|
if (lengthByte < 128)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
auto value = cast(string) data[0 .. length];
|
|
data = data[length .. $];
|
|
|
|
return value;
|
|
}
|
|
|
|
uint readInt()
|
|
{
|
|
auto value = littleEndianToNative!uint(data[0 .. 4]);
|
|
data = data[4 .. $];
|
|
return value;
|
|
}
|
|
|
|
assert(readString() == "CM3D2_MENU", "Not a valid .menu file");
|
|
|
|
menu.fileVersion = readInt();
|
|
menu.path = readString();
|
|
menu.name = readString();
|
|
menu.category = readString();
|
|
menu.description = readString();
|
|
|
|
assert(readInt() == data.length, "Unexpected data at end of file");
|
|
|
|
while(data.length > 0)
|
|
{
|
|
string[] line;
|
|
|
|
foreach (_; 0 .. readByte())
|
|
{
|
|
line ~= readString();
|
|
}
|
|
|
|
if (line.length > 0)
|
|
{
|
|
menu.lines ~= line;
|
|
}
|
|
}
|
|
|
|
return menu;
|
|
}
|
|
|
|
public string toMenu()
|
|
{
|
|
throw new Exception("Not implemented yet");
|
|
}
|
|
|
|
public string toSDL()
|
|
{
|
|
auto versionTag = new Tag(null, "version", [Value(cast(int) fileVersion)]);
|
|
auto pathTag = new Tag(null, "path", [Value(path)]);
|
|
auto nameTag = new Tag(null, "name", [Value(name)]);
|
|
auto categoryTag = new Tag(null, "category", [Value(category)]);
|
|
auto descriptionTag = new Tag(null, "description", [Value(description)]);
|
|
|
|
auto root = new Tag(null, null, null, null, [versionTag, pathTag, nameTag, categoryTag, descriptionTag]);
|
|
|
|
Tag[] dataTags;
|
|
foreach (line; lines)
|
|
{
|
|
if (line[0] in _translations)
|
|
{
|
|
line[0] = _translations[line[0]];
|
|
}
|
|
|
|
auto lineTag = new Tag(null, null, line[0], null, null, null);
|
|
|
|
if (line[0] == "blendset" || line[0] == "paramset")
|
|
{
|
|
lineTag.values = [Value(line[1])];
|
|
|
|
foreach (setting; line[2 .. $].chunks(2))
|
|
{
|
|
auto settingTag = new Tag(null, null, setting[0], null, null, null);
|
|
if (line[0] == "blendset")
|
|
{
|
|
settingTag.values = [Value(setting[1].to!int)];
|
|
}
|
|
else
|
|
{
|
|
settingTag.values = [Value(setting[1])];
|
|
}
|
|
lineTag.add(settingTag);
|
|
}
|
|
}
|
|
else if (line[0] == "attachpoint")
|
|
{
|
|
lineTag.values = [Value(line[1])];
|
|
|
|
auto xTag = new Tag(null, null, "x", [Value(line[2])]);
|
|
auto yTag = new Tag(null, null, "y", [Value(line[3])]);
|
|
auto zTag = new Tag(null, null, "z", [Value(line[4])]);
|
|
auto rxTag = new Tag(null, null, "rx", [Value(line[5])]);
|
|
auto ryTag = new Tag(null, null, "ry", [Value(line[6])]);
|
|
auto rzTag = new Tag(null, null, "rz", [Value(line[7])]);
|
|
|
|
lineTag.add([xTag, yTag, zTag, rxTag, ryTag, rzTag]);
|
|
}
|
|
else if (line.length > 2)
|
|
{
|
|
foreach (item; line[1 .. $])
|
|
{
|
|
lineTag.add(Value(item));
|
|
}
|
|
}
|
|
else if (line.length == 2)
|
|
{
|
|
line[1] = line[1].replace("《改行》", "\n");
|
|
|
|
lineTag.values = [Value(line[1])];
|
|
}
|
|
|
|
dataTags ~= lineTag;
|
|
}
|
|
|
|
auto dataTag = new Tag(null, "data", null, null, dataTags);
|
|
root.add(dataTag);
|
|
|
|
return root.toSDLDocument();
|
|
}
|
|
}
|