module cm3d2.menu; import std.conv; import std.math; import std.array; import std.range; import sdlang; import cm3d2; 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(); assert(data.readString() == "CM3D2_MENU", "Not a valid .menu file"); menu.fileVersion = data.readInt(); menu.path = data.readString(); menu.name = data.readString(); menu.category = data.readString(); menu.description = data.readString(); assert(data.readInt() == data.length, "Unexpected data at end of file"); while (data.length > 0) { string[] line; foreach (_; 0 .. data.readByte()) { line ~= data.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(); } }