public static void ExportCPP(DllIniData IniData,
                                     Dictionary <string, bool> itemsToExport, string fileName)
        {
            using (TextWriter writer = File.CreateText(fileName))
            {
                bool            SA2      = IniData.Game == SA_Tools.SplitDLL.Game.SA2B;
                ModelFormat     modelfmt = SA2 ? ModelFormat.Chunk : ModelFormat.BasicDX;
                LandTableFormat landfmt  = SA2 ? LandTableFormat.SA2 : LandTableFormat.SADX;
                writer.WriteLine("// Generated by SA Tools DLL Mod Generator");
                writer.WriteLine();
                if (SA2)
                {
                    writer.WriteLine("#include \"SA2ModLoader.h\"");
                }
                else
                {
                    writer.WriteLine("#include \"SADXModLoader.h\"");
                }
                writer.WriteLine();
                List <string>             labels   = new List <string>();
                Dictionary <string, uint> texlists = new Dictionary <string, uint>();
                foreach (KeyValuePair <string, FileTypeHash> item in
                         IniData.Files.Where(i => itemsToExport[i.Key]))
                {
                    switch (item.Value.Type)
                    {
                    case "landtable":
                        LandTable tbl = LandTable.LoadFromFile(item.Key);
                        texlists.Add(tbl.Name, tbl.TextureList);
                        tbl.ToStructVariables(writer, landfmt, new List <string>());
                        labels.AddRange(tbl.GetLabels());
                        break;

                    case "model":
                        NJS_OBJECT mdl = new ModelFile(item.Key).Model;
                        mdl.ToStructVariables(writer, modelfmt == ModelFormat.BasicDX, new List <string>());
                        labels.AddRange(mdl.GetLabels());
                        break;

                    case "basicmodel":
                    case "chunkmodel":
                    case "gcmodel":
                        mdl = new ModelFile(item.Key).Model;
                        mdl.ToStructVariables(writer, false, new List <string>());
                        labels.AddRange(mdl.GetLabels());
                        break;

                    case "basicdxmodel":
                        mdl = new ModelFile(item.Key).Model;
                        mdl.ToStructVariables(writer, true, new List <string>());
                        labels.AddRange(mdl.GetLabels());
                        break;

                    case "animation":
                        NJS_MOTION ani = NJS_MOTION.Load(item.Key);
                        ani.ToStructVariables(writer);
                        labels.Add(ani.Name);
                        break;
                    }
                    writer.WriteLine();
                }
                foreach (var item in IniData.DataItems.Where(i => itemsToExport[i.Filename]))
                {
                    switch (item.Type)
                    {
                    case "animindexlist":
                    {
                        SortedDictionary <short, NJS_MOTION> anims = new SortedDictionary <short, NJS_MOTION>();
                        foreach (string file in Directory.GetFiles(item.Filename, "*.saanim"))
                        {
                            if (short.TryParse(Path.GetFileNameWithoutExtension(file), NumberStyles.Integer, NumberFormatInfo.InvariantInfo, out short i))
                            {
                                anims.Add(i, NJS_MOTION.Load(file));
                            }
                        }
                        foreach (KeyValuePair <short, NJS_MOTION> obj in anims)
                        {
                            obj.Value.ToStructVariables(writer);
                            writer.WriteLine();
                        }
                        writer.WriteLine("AnimationIndex {0}[] = {{", item.Export);
                        List <string> objs = new List <string>(anims.Count);
                        foreach (KeyValuePair <short, NJS_MOTION> obj in anims)
                        {
                            objs.Add($"{{ {obj.Key}, {obj.Value.ModelParts}, &{obj.Value.Name} }}");
                        }
                        objs.Add("{ -1 }");
                        writer.WriteLine("\t" + string.Join("," + Environment.NewLine + "\t", objs.ToArray()));
                        writer.WriteLine("};");
                    }
                    break;

                    case "charaobjectdatalist":
                    {
                        foreach (string file in Directory.GetFiles(item.Filename, "*.sa2mdl"))
                        {
                            new ModelFile(file).Model.ToStructVariables(writer, false, new List <string>());
                            writer.WriteLine();
                        }
                        foreach (string file in Directory.GetFiles(item.Filename, "*.saanim"))
                        {
                            NJS_MOTION.Load(file).ToStructVariables(writer);
                            writer.WriteLine();
                        }
                        var data = IniSerializer.Deserialize <CharaObjectData[]>(Path.Combine(item.Filename, "info.ini"));
                        writer.WriteLine("CharaObjectData {0}[] = {{", item.Export);
                        List <string> objs = new List <string>(data.Length);
                        foreach (var obj in data)
                        {
                            objs.Add(obj.ToStruct());
                        }
                        writer.WriteLine("\t" + string.Join("," + Environment.NewLine + "\t", objs.ToArray()));
                        writer.WriteLine("};");
                    }
                    break;

                    case "kartspecialinfolist":
                    {
                        foreach (string file in Directory.GetFiles(item.Filename, "*.sa2mdl"))
                        {
                            new ModelFile(file).Model.ToStructVariables(writer, false, new List <string>());
                            writer.WriteLine();
                        }
                        var data = IniSerializer.Deserialize <KartSpecialInfo[]>(Path.Combine(item.Filename, "info.ini"));
                        writer.WriteLine("KartSpecialInfo {0}[] = {{", item.Export);
                        List <string> objs = new List <string>(data.Length);
                        for (int i = 0; i < data.Length; i++)
                        {
                            KartSpecialInfo obj = data[i];
                            objs.Add(obj.ToStruct());
                            texlists.Add($"{item.Export}[{i}]", obj.TexList);
                        }
                        writer.WriteLine("\t" + string.Join("," + Environment.NewLine + "\t", objs.ToArray()));
                        writer.WriteLine("};");
                    }
                    break;

                    case "kartmodelsarray":
                    {
                        foreach (string file in Directory.GetFiles(item.Filename, "*.sa2bmdl"))
                        {
                            new ModelFile(file).Model.ToStructVariables(writer, false, new List <string>());
                            writer.WriteLine();
                        }
                        foreach (string file in Directory.GetFiles(item.Filename, "*.sa1mdl"))
                        {
                            new ModelFile(file).Model.ToStructVariables(writer, false, new List <string>());
                            writer.WriteLine();
                        }
                        var data = IniSerializer.Deserialize <CharaObjectData[]>(Path.Combine(item.Filename, "info.ini"));
                        writer.WriteLine("KartModelsArray {0}[] = {{", item.Export);
                        List <string> objs = new List <string>(data.Length);
                        foreach (var obj in data)
                        {
                            objs.Add(obj.ToStruct());
                        }
                        writer.WriteLine("\t" + string.Join("," + Environment.NewLine + "\t", objs.ToArray()));
                        writer.WriteLine("};");
                    }
                    break;

                    case "motiontable":
                    {
                        foreach (string file in Directory.GetFiles(item.Filename, "*.saanim"))
                        {
                            NJS_MOTION.Load(file).ToStructVariables(writer);
                            writer.WriteLine();
                        }
                        var data = IniSerializer.Deserialize <MotionTableEntry[]>(Path.Combine(item.Filename, "info.ini"));
                        writer.WriteLine("MotionTableEntry {0}[] = {{", item.Export);
                        List <string> objs = new List <string>(data.Length);
                        foreach (var obj in data)
                        {
                            objs.Add(obj.ToStruct());
                        }
                        writer.WriteLine("\t" + string.Join("," + Environment.NewLine + "\t", objs.ToArray()));
                        writer.WriteLine("};");
                    }
                    break;
                    }
                }
                writer.WriteLine("extern \"C\" __declspec(dllexport) void __cdecl Init(const char *path, const HelperFunctions &helperFunctions)");
                writer.WriteLine("{");
                writer.WriteLine("\tHMODULE handle = GetModuleHandle(L\"{0}\");", IniData.Name);
                List <string> exports = new List <string>(IniData.Items.Where(item => labels.Contains(item.Label)).Select(item => item.Export).Distinct());
                foreach (KeyValuePair <string, string> item in IniData.Exports.Where(item => exports.Contains(item.Key)))
                {
                    writer.WriteLine("\t{0}{1} = ({0})GetProcAddress(handle, \"{1}\");", typemap[item.Value], item.Key);
                }
                foreach (DllItemInfo item in IniData.Items.Where(item => labels.Contains(item.Label)))
                {
                    if (typemap[IniData.Exports[item.Export]].EndsWith("**"))
                    {
                        writer.WriteLine("\t{0} = &{1};", item.ToString(), item.Label);
                    }
                    else
                    {
                        writer.WriteLine("\t*{0} = {1};", item.ToString(), item.Label);
                    }
                }
                foreach (var item in IniData.DataItems.Where(item => itemsToExport[item.Filename]))
                {
                    switch (item.Type)
                    {
                    case "animindexlist":
                    case "charaobjectdatalist":
                    case "kartspecialinfolist":
                    case "kartmodelsarray":
                        writer.WriteLine("\tHookExport(handle, \"{0}\", {0});", item.Export);
                        break;

                    default:
                        writer.WriteLine("\t{0}{1}_exp = ({0})GetProcAddress(handle, \"{1}\");", typemap[item.Type], item.Export);
                        writer.WriteLine("\t*{0}_exp = {0};", item.Export);
                        break;
                    }
                }
                if (texlists.Count > 0 && IniData.TexLists != null && IniData.TexLists.Items != null)
                {
                    exports = new List <string>(IniData.TexLists.Where(item => texlists.Values.Contains(item.Key)).Select(item => item.Value.Export).Distinct());
                    foreach (KeyValuePair <string, string> item in IniData.Exports.Where(item => exports.Contains(item.Key)))
                    {
                        writer.WriteLine("\t{0}{1} = ({0})GetProcAddress(handle, \"{1}\");", typemap[item.Value], item.Key);
                    }
                    foreach (KeyValuePair <string, uint> item in texlists.Where(item => IniData.TexLists.ContainsKey(item.Value)))
                    {
                        DllTexListInfo tex = IniData.TexLists[item.Value];
                        string         str;
                        if (tex.Index.HasValue)
                        {
                            str = $"{tex.Export}[{tex.Index.Value}]";
                        }
                        else
                        {
                            str = tex.Export;
                        }
                        writer.WriteLine("\t{0}.TexList = {1};", item.Key, str);
                    }
                }
                writer.WriteLine("}");
                writer.WriteLine();
                writer.WriteLine("extern \"C\" __declspec(dllexport) const ModInfo {0}ModInfo = {{ ModLoaderVer }};", SA2 ? "SA2" : "SADX");
            }
        }
Exemple #2
0
        public static void ExportCPP(DllIniData IniData,
                                     Dictionary <string, bool> itemsToExport, string fileName)
        {
            using (TextWriter writer = File.CreateText(fileName))
            {
                bool            SA2      = IniData.Game == Game.SA2B;
                ModelFormat     modelfmt = SA2 ? ModelFormat.Chunk : ModelFormat.BasicDX;
                LandTableFormat landfmt  = SA2 ? LandTableFormat.SA2 : LandTableFormat.SADX;
                writer.WriteLine("// Generated by SA Tools DLL Mod Generator");
                writer.WriteLine();
                if (SA2)
                {
                    writer.WriteLine("#include \"SA2ModLoader.h\"");
                }
                else
                {
                    writer.WriteLine("#include \"SADXModLoader.h\"");
                }
                writer.WriteLine();
                List <string>             labels   = new List <string>();
                Dictionary <string, uint> texlists = new Dictionary <string, uint>();
                foreach (KeyValuePair <string, FileTypeHash> item in
                         IniData.Files.Where(i => itemsToExport[i.Key]))
                {
                    switch (item.Value.Type)
                    {
                    case "landtable":
                        LandTable tbl = LandTable.LoadFromFile(item.Key);
                        texlists.Add(tbl.Name, tbl.TextureList);
                        tbl.ToStructVariables(writer, landfmt, new List <string>());
                        labels.AddRange(tbl.GetLabels());
                        break;

                    case "model":
                        NJS_OBJECT mdl = new ModelFile(item.Key).Model;
                        mdl.ToStructVariables(writer, modelfmt == ModelFormat.BasicDX, new List <string>());
                        labels.AddRange(mdl.GetLabels());
                        break;

                    case "basicmodel":
                    case "chunkmodel":
                        mdl = new ModelFile(item.Key).Model;
                        mdl.ToStructVariables(writer, false, new List <string>());
                        labels.AddRange(mdl.GetLabels());
                        break;

                    case "basicdxmodel":
                        mdl = new ModelFile(item.Key).Model;
                        mdl.ToStructVariables(writer, true, new List <string>());
                        labels.AddRange(mdl.GetLabels());
                        break;

                    case "animation":
                    case "animindex":
                        NJS_MOTION ani = NJS_MOTION.Load(item.Key);
                        ani.ToStructVariables(writer);
                        labels.Add(ani.Name);
                        break;
                    }
                    writer.WriteLine();
                }
                writer.WriteLine("extern \"C\" __declspec(dllexport) void __cdecl Init(const char *path, const HelperFunctions &helperFunctions)");
                writer.WriteLine("{");
                writer.WriteLine("\tHMODULE handle = GetModuleHandle(L\"{0}\");", IniData.Name);
                List <string> exports = new List <string>(IniData.Items.Where(item => labels.Contains(item.Label)).Select(item => item.Export).Distinct());
                foreach (KeyValuePair <string, string> item in IniData.Exports.Where(item => exports.Contains(item.Key)))
                {
                    writer.WriteLine("\t{0}{1} = ({0})GetProcAddress(handle, \"{1}\");", typemap[item.Value], item.Key);
                }
                foreach (DllItemInfo item in IniData.Items.Where(item => labels.Contains(item.Label)))
                {
                    writer.WriteLine("\t{0} = &{1};", item.ToString(), item.Label);
                }
                if (texlists.Count > 0 && IniData.TexLists != null && IniData.TexLists.Items != null)
                {
                    exports = new List <string>(IniData.TexLists.Where(item => texlists.Values.Contains(item.Key)).Select(item => item.Value.Export).Distinct());
                    foreach (KeyValuePair <string, string> item in IniData.Exports.Where(item => exports.Contains(item.Key)))
                    {
                        writer.WriteLine("\t{0}{1} = ({0})GetProcAddress(handle, \"{1}\");", typemap[item.Value], item.Key);
                    }
                    foreach (KeyValuePair <string, uint> item in texlists.Where(item => IniData.TexLists.ContainsKey(item.Value)))
                    {
                        DllTexListInfo tex = IniData.TexLists[item.Value];
                        string         str;
                        if (tex.Index.HasValue)
                        {
                            str = $"{tex.Export}[{tex.Index.Value}]";
                        }
                        else
                        {
                            str = tex.Export;
                        }
                        writer.WriteLine("\t{0}.TexList = {1};", item.Key, str);
                    }
                }
                writer.WriteLine("}");
                writer.WriteLine();
                writer.WriteLine("extern \"C\" __declspec(dllexport) const ModInfo {0}ModInfo = {{ ModLoaderVer }};", SA2 ? "SA2" : "SADX");
            }
        }