Пример #1
0
        public bool DoIt(string[] args)
        {
            if (args.Length >= 2)
            {
                var mapFile = args[1];

                var linkFile = (args.Length >= 3) ? args[2] : null;

                var      map  = new MapFile(mapFile);
                LinkFile link = null;
                if (linkFile != null)
                {
                    link = new LinkFile(linkFile);
                }

                var debug_symbol_table = new HSDStruct((map.Entries.Count + 1) * 0xC);
                int symbol_index       = 0;
                foreach (var e in map.Entries)
                {
                    debug_symbol_table.SetInt32(symbol_index * 0xC, (int)e.Start);
                    debug_symbol_table.SetInt32(symbol_index * 0xC + 4, (int)e.End);

                    if (link != null && link.TryGetAddressSymbol(e.Start, out string sym))
                    {
                        debug_symbol_table.SetString(symbol_index * 0xC + 8, sym, true);
                    }
                    else
                    if (!e.Symbol.StartsWith("zz_"))
                    {
                        debug_symbol_table.SetString(symbol_index * 0xC + 8, e.Symbol, true);
                    }
                    symbol_index++;
                }

                var function = new HSDAccessor()
                {
                    _s = new HSDStruct(0x10)
                };
                function._s.SetInt32(0, map.Entries.Count);
                function._s.SetReferenceStruct(0x04, debug_symbol_table);

                HSDRawFile f = new HSDRawFile();
                f.Roots.Add(new HSDRootNode()
                {
                    Data = function,
                    Name = "mexDebug"
                });

                f.Save("MxDb.dat");


                return(true);
            }

            return(false);
        }
Пример #2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="root"></param>
        public static void AddRoot(string name, HSDAccessor accesor)
        {
            var root = new HSDRootNode()
            {
                Name = name,
                Data = accesor
            };

            Instance.RawHSDFile.Roots.Add(root);
            Instance.treeView1.Nodes.Add(new DataNode(name, accesor, root: root));
        }
Пример #3
0
 /// <summary>
 ///
 /// </summary>
 public void ExtractDataFromMap(HSDAccessor acc)
 {
     foreach (var p in acc.GetType().GetProperties())
     {
         if (dolMap.ContainsKey(p.Name))
         {
             var i = Activator.CreateInstance(p.PropertyType);
             ((HSDAccessor)i)._s = GetStruct(dolMap[p.Name]);
             p.SetValue(acc, i);
         }
     }
 }
Пример #4
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="sender"></param>
 /// <param name="e"></param>
 private void buttonClone_Click(object sender, EventArgs e)
 {
     if (mxListBox1.SelectedItem is MEXCostume costume)
     {
         _costumes.Add(new MEXCostume()
         {
             Costume = HSDAccessor.DeepClone <HSDRaw.MEX.MEX_CostumeFileSymbol>(costume.Costume),
             Icon    = HSDAccessor.DeepClone <HSD_TOBJ>(costume.Icon),
             CSP     = costume.CSP == null ? null : HSDAccessor.DeepClone <HSD_TOBJ>(costume.CSP)
         });
     }
 }
Пример #5
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="filePath"></param>
        private void LoadMnSlMap(HSDRawFile hsd)
        {
            if (StageMenuFile != null)
            {
                return;
            }

            var org = hsd["MnSelectStageDataTable"];
            var mex = hsd["mexMapData"];

            if (org != null && mex == null)
            {
                MessageBox.Show("MexMapData symbol not found. One will now be generated", "Symbol Not Found", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);

                // load and convert data from vanilla
                MexMapGenerator.LoadIconDataFromVanilla(org.Data as SBM_MnSelectStageDataTable, Icons);

                // generate mex data node
                hsd.Roots.Add(new HSDRootNode()
                {
                    Name = "mexMapData",
                    Data = MexMapGenerator.GenerateMexMap(org.Data as SBM_MnSelectStageDataTable, Icons)
                });

                mex = hsd["mexMapData"];
            }

            if (org != null && mex != null)
            {
                var stage  = org.Data as SBM_MnSelectStageDataTable;
                var mexMap = mex.Data as MEX_mexMapData;

                //StageMenuFilePath = filePath;
                StageMenuFile = hsd;

                // Load Data from Mex Symbol
                MexMapGenerator.LoadIconDataFromSymbol(mexMap, Icons);

                // Load Dummy Icon Model
                IconJOBJManager.RefreshRendering = true;
                var icon = HSDAccessor.DeepClone <HSD_JOBJ>(mexMap.IconModel);
                IconJOBJManager.SetJOBJ(icon);

                // Load Dummy Stage Name Model
                StageNameJOBJManager.RefreshRendering = true;
                var name = HSDAccessor.DeepClone <HSD_JOBJ>(stage.StageNameModel);
                StageNameJOBJManager.SetJOBJ(name);
                StageNameJOBJManager.SetAnimJoint(stage.StageNameAnimJoint);
                StageNameJOBJManager.Frame = 10;

                Enabled = true;
            }
        }
Пример #6
0
        /// <summary>
        ///
        /// </summary>
        public static void ImportTextures(HSD_JOBJ jobj)
        {
            var folder = Tools.FileIO.OpenFolder();

            if (!string.IsNullOrEmpty(folder))
            {
                // get all tobjs
                Dictionary <int, HSD_TOBJ> hashToImage = new Dictionary <int, HSD_TOBJ>();

                // load all textures from file
                foreach (var tf in System.IO.Directory.GetFiles(folder))
                {
                    if (tf.ToLower().EndsWith(".png"))
                    {
                        var fn = System.IO.Path.GetFileNameWithoutExtension(tf);
                        if (fn.Length >= 8 &&
                            int.TryParse(fn.Substring(0, 8), System.Globalization.NumberStyles.HexNumber, CultureInfo.InvariantCulture, out int hash) &&
                            TOBJConverter.FormatFromString(fn, out HSDRaw.GX.GXTexFmt texFmt, out HSDRaw.GX.GXTlutFmt tlutFmt))
                        {
                            hashToImage.Add(hash, TOBJConverter.ImportTOBJFromFile(tf, texFmt, tlutFmt));
                        }
                    }
                }

                // get all tobjs
                foreach (var j in jobj.BreathFirstList)
                {
                    if (j.Dobj != null)
                    {
                        foreach (var dobj in j.Dobj.List)
                        {
                            if (dobj.Mobj != null && dobj.Mobj.Textures != null)
                            {
                                foreach (var tobj in dobj.Mobj.Textures.List)
                                {
                                    // generate hashes and export textures and formatting

                                    var hash = ComputeHash(tobj.GetDecodedImageData());

                                    if (hashToImage.ContainsKey(hash))
                                    {
                                        var imgClone = HSDAccessor.DeepClone <HSD_TOBJ>(hashToImage[hash]);
                                        tobj.ImageData = imgClone.ImageData;
                                        tobj.TlutData  = imgClone.TlutData;
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
Пример #7
0
 /// <summary>
 ///
 /// </summary>
 private static void ExtractDataFromResource(HSDRawFile resourceFile, HSDAccessor acc)
 {
     foreach (var p in acc.GetType().GetProperties())
     {
         var sym = resourceFile[p.Name];
         if (sym != null)
         {
             var i = Activator.CreateInstance(p.PropertyType);
             ((HSDAccessor)i)._s = sym.Data._s;
             p.SetValue(acc, i);
         }
     }
 }
Пример #8
0
        public void Render(JOBJManager jobjManager, List <SBM_Hurtbox> hurtboxes, HSDAccessor selected, Dictionary <int, int> states = null, int bodyState = -1)
        {
            foreach (SBM_Hurtbox v in hurtboxes)
            {
                var clr = HurtboxColor;
                var a   = 0.25f;
                if (selected == v)
                {
                    clr = SelectedHurtboxColor;
                    a   = 0.6f;
                }

                if (states != null)
                {
                    if (states.ContainsKey(v.BoneIndex))
                    {
                        switch (states[v.BoneIndex])
                        {
                        case 1:
                            clr = InvulColor;
                            break;

                        case 2:
                            clr = IntanColor;
                            break;
                        }
                    }
                }

                if (bodyState == 1)
                {
                    clr = InvulColor;
                }
                if (bodyState == 2)
                {
                    clr = IntanColor;
                }

                var transform = jobjManager.GetWorldTransform(v.BoneIndex);

                if (!HurtboxToCapsule.ContainsKey(v))
                {
                    HurtboxToCapsule.Add(v, new Capsule(new Vector3(v.X1, v.Y1, v.Z1), new Vector3(v.X2, v.Y2, v.Z2), v.Size));
                }

                var cap = HurtboxToCapsule[v];
                cap.SetParameters(new Vector3(v.X1, v.Y1, v.Z1), new Vector3(v.X2, v.Y2, v.Z2), v.Size);
                cap.Draw(transform, new Vector4(clr, a));
            }
        }
Пример #9
0
        public void Render(HSDAccessor a, int windowWidth, int windowHeight)
        {
            if (a is KAR_grCollisionNode cn && cn != Node)
            {
                Node      = cn;
                Vertices  = Node.Vertices;
                Triangles = Node.Triangles;
                Joints    = Node.Joints;

                ZoneVertices  = Node.ZoneVertices;
                ZoneTriangles = Node.ZoneTriangles;
                ZoneJoints    = Node.ZoneJoints;
            }

            if (Node == null)
            {
                return;
            }

            GL.PushAttrib(AttribMask.AllAttribBits);

            GL.Enable(EnableCap.Blend);
            GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha);

            GL.Begin(PrimitiveType.Triangles);

            foreach (var t in Triangles)
            {
                if ((t.Flags & 0x1) == 0x1)
                {
                    GL.Color4(1f, 0f, 0f, 0.5f);
                }
                if ((t.Flags & 0x2) == 0x2)
                {
                    GL.Color4(0f, 1f, 0f, 0.5f);
                }
                if ((t.Flags & 0x4) == 0x4)
                {
                    GL.Color4(0f, 0f, 1f, 0.5f);
                }

                GL.Vertex3(GXTranslator.toVector3(Vertices[t.V1]));
                GL.Vertex3(GXTranslator.toVector3(Vertices[t.V2]));
                GL.Vertex3(GXTranslator.toVector3(Vertices[t.V3]));
            }

            GL.End();

            GL.PopAttrib();
        }
Пример #10
0
        public void SetAccessor(HSDAccessor accessor)
        {
            if (accessor == null)
            {
                return;
            }

            propertyGrid1.SelectedObject = accessor;
            panel1.SetBytes(accessor._s.GetData());

            if (this.accessor != accessor)
            {
                offsetBox.Text = "0";
            }
        }
Пример #11
0
        /// <summary>
        /// Decompiles subaction byte code into script
        /// </summary>
        /// <param name="commanddata"></param>
        /// <returns></returns>
        public string Decompile(string name, HSDAccessor commanddata)
        {
            if (commanddata == null)
            {
                return("");
            }
            StringBuilder output = new StringBuilder();

            tempStructToName.Clear();
            DecompileGroup(output, name, commanddata._s);

            if (output.ToString() == "")
            {
                output.AppendLine("ref: " + structToFunctionName[commanddata._s]);
            }

            return(output.ToString());
        }
Пример #12
0
        /// <summary>
        /// Injects a given symbol into a dat
        /// If symbol already exists it is overwritten
        /// </summary>
        /// <param name="f"></param>
        /// <param name="symbolName"></param>
        /// <param name="function"></param>
        public static void InjectSymbolIntoDat(HSDRawFile f, string symbolName, HSDAccessor function)
        {
            // generate root
            var root = new HSDRootNode();

            root.Name = symbolName;
            root.Data = function;

            // if this symbol already exists in file, replace it
            foreach (var ro in f.Roots)
            {
                if (ro.Name.Equals(root.Name))
                {
                    ro.Data = root.Data;
                }
            }

            // if symbol is not in file, then add it
            if (f.Roots.FindIndex(e => e.Name == root.Name) == -1)
            {
                f.Roots.Add(root);
            }
        }
Пример #13
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="mobj"></param>
        /// <returns></returns>
        public HSD_Material GetMaterialState(HSD_MOBJ mobj)
        {
            HSD_Material mat = HSDAccessor.DeepClone <HSD_Material>(mobj.Material);

            if (Nodes.Count > JOBJIndex && Nodes[JOBJIndex].Nodes.Count > DOBJIndex)
            {
                var node = Nodes[JOBJIndex].Nodes[DOBJIndex];

                foreach (var t in node.Tracks)
                {
                    switch ((MatTrackType)t.TrackType)
                    {
                    case MatTrackType.HSD_A_M_ALPHA: mat.Alpha = t.GetValue(node.Frame); break;

                    case MatTrackType.HSD_A_M_AMBIENT_R: mat.AMB_R = (byte)(t.GetValue(node.Frame) * 0xFF); break;

                    case MatTrackType.HSD_A_M_AMBIENT_G: mat.AMB_G = (byte)(t.GetValue(node.Frame) * 0xFF); break;

                    case MatTrackType.HSD_A_M_AMBIENT_B: mat.AMB_B = (byte)(t.GetValue(node.Frame) * 0xFF); break;

                    case MatTrackType.HSD_A_M_DIFFUSE_R: mat.DIF_R = (byte)(t.GetValue(node.Frame) * 0xFF); break;

                    case MatTrackType.HSD_A_M_DIFFUSE_G: mat.DIF_G = (byte)(t.GetValue(node.Frame) * 0xFF); break;

                    case MatTrackType.HSD_A_M_DIFFUSE_B: mat.DIF_B = (byte)(t.GetValue(node.Frame) * 0xFF); break;

                    case MatTrackType.HSD_A_M_SPECULAR_R: mat.SPC_R = (byte)(t.GetValue(node.Frame) * 0xFF); break;

                    case MatTrackType.HSD_A_M_SPECULAR_G: mat.SPC_G = (byte)(t.GetValue(node.Frame) * 0xFF); break;

                    case MatTrackType.HSD_A_M_SPECULAR_B: mat.SPC_B = (byte)(t.GetValue(node.Frame) * 0xFF); break;
                    }
                }
            }

            return(mat);
        }
Пример #14
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="stage"></param>
        /// <param name="icons"></param>
        public static MEX_mexMapData GenerateMexMap(SBM_MnSelectStageDataTable stage, IEnumerable <MEXStageIconEntry> icons)
        {
            MEX_mexMapData mapData = new MEX_mexMapData();

            var nameTexAnim = new HSD_TexAnim();
            var nameKeys    = new List <FOBJKey>();

            var iconTexAnim = new HSD_TexAnim();
            var iconKeys    = new List <FOBJKey>();

            HSD_JOBJ root = new HSD_JOBJ()
            {
                SX    = 1, SY = 1, SZ = 1,
                Flags = JOBJ_FLAG.CLASSICAL_SCALING
            };

            HSD_AnimJoint animRoot = new HSD_AnimJoint();

            // extra
            {
                var tobjs = stage.IconLargeMatAnimJoint.Child.MaterialAnimation.Next.TextureAnimation.ToTOBJs();

                var index = iconTexAnim.AddImage(tobjs[0]);
                iconKeys.Add(new FOBJKey()
                {
                    Frame = index, Value = index, InterpolationType = GXInterpolationType.HSD_A_OP_CON
                });

                index = iconTexAnim.AddImage(tobjs[1]);
                iconKeys.Add(new FOBJKey()
                {
                    Frame = index, Value = index, InterpolationType = GXInterpolationType.HSD_A_OP_CON
                });
            }

            foreach (var v in icons)
            {
                var index = iconTexAnim.AddImage(v.IconTOBJ);
                if (index == -1)
                {
                    index = 0;
                }
                iconKeys.Add(new FOBJKey()
                {
                    Frame = index, Value = index, InterpolationType = GXInterpolationType.HSD_A_OP_CON
                });

                index = nameTexAnim.AddImage(v.NameTOBJ);
                if (index == -1)
                {
                    index = 0;
                }
                nameKeys.Add(new FOBJKey()
                {
                    Frame = index, Value = index, InterpolationType = GXInterpolationType.HSD_A_OP_CON
                });

                v.Joint.Next      = null;
                v.Joint.Child     = null;
                v.AnimJoint.Next  = null;
                v.AnimJoint.Child = null;

                root.AddChild(v.Joint);
                animRoot.AddChild(v.AnimJoint);
            }

            iconKeys.Add(new FOBJKey()
            {
                Frame = 1600, Value = 0, InterpolationType = GXInterpolationType.HSD_A_OP_CON
            });

            iconTexAnim.GXTexMapID               = HSDRaw.GX.GXTexMapID.GX_TEXMAP0;
            iconTexAnim.AnimationObject          = new HSD_AOBJ();
            iconTexAnim.AnimationObject.EndFrame = 1600;
            iconTexAnim.AnimationObject.FObjDesc = new HSD_FOBJDesc();
            iconTexAnim.AnimationObject.FObjDesc.SetKeys(iconKeys, (byte)TexTrackType.HSD_A_T_TIMG);
            iconTexAnim.AnimationObject.FObjDesc.Next = new HSD_FOBJDesc();
            iconTexAnim.AnimationObject.FObjDesc.Next.SetKeys(iconKeys, (byte)TexTrackType.HSD_A_T_TCLT);

            var iconJOBJ = HSDAccessor.DeepClone <HSD_JOBJ>(stage.IconDoubleModel);

            iconJOBJ.Child = iconJOBJ.Child.Next;

            var iconAnimJoint = HSDAccessor.DeepClone <HSD_AnimJoint>(stage.IconDoubleAnimJoint);

            iconAnimJoint.Child = iconAnimJoint.Child.Next;

            var iconMatAnimJoint = HSDAccessor.DeepClone <HSD_MatAnimJoint>(stage.IconDoubleMatAnimJoint);

            iconMatAnimJoint.Child = iconMatAnimJoint.Child.Next;
            iconMatAnimJoint.Child.MaterialAnimation.Next.TextureAnimation = iconTexAnim;

            var iconNameAnim = HSDAccessor.DeepClone <HSD_MatAnimJoint>(stage.StageNameMatAnimJoint);

            nameTexAnim.AnimationObject          = new HSD_AOBJ();
            nameTexAnim.AnimationObject.EndFrame = 1600;
            nameTexAnim.AnimationObject.FObjDesc = new HSD_FOBJDesc();
            nameTexAnim.AnimationObject.FObjDesc.SetKeys(nameKeys, (byte)TexTrackType.HSD_A_T_TIMG);
            iconNameAnim.Child.Child.MaterialAnimation.TextureAnimation = nameTexAnim;

            mapData.IconModel                  = iconJOBJ;
            mapData.IconAnimJoint              = iconAnimJoint;
            mapData.IconMatAnimJoint           = iconMatAnimJoint;
            mapData.PositionModel              = root;
            mapData.PositionAnimJoint          = animRoot;
            mapData.StageNameMaterialAnimation = iconNameAnim;

            return(mapData);
        }
Пример #15
0
        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        public static HSDAccessor GenerateFunctionDAT(LinkedELF lelf, LinkFile link, string[] functions, bool debug, bool quiet = false)
        {
            // Generate Function DAT
            var function = new HSDAccessor()
            {
                _s = new HSDStruct(0x20)
            };

            // Generate code section
            HSDStruct debug_symbol_table = null;
            int       debug_symbol_count = 0;
            Dictionary <SymbolData, long> dataToOffset = new Dictionary <SymbolData, long>();

            byte[] codedata;
            using (MemoryStream code = new MemoryStream())
            {
                // create debug symbol table
                if (debug)
                {
                    debug_symbol_table = new HSDStruct((lelf.AllSymbols.Count + 1) * 0xC);
                }

                // process all code
                foreach (var v in lelf.AllSymbols)
                {
                    // align
                    if (code.Length % 4 != 0)
                    {
                        code.Write(new byte[4 - (code.Length % 4)], 0, 4 - ((int)code.Length % 4));
                    }

                    int code_start = (int)code.Position;
                    // write code
                    if (v.Data.Length == 0 && link.TryGetSymbolAddress(CppSanatize(v.Symbol), out uint addr))
                    {
                        dataToOffset.Add(v, addr);
                    }
                    else
                    {
                        dataToOffset.Add(v, code.Length);
                        code.Write(v.Data, 0, v.Data.Length);
                    }
                    int code_end = (int)code.Position;

                    //Console.WriteLine($"{v.SectionName} {v.Symbol} Start: {code_start.ToString("X")} End: {code_end.ToString("X")} ");

                    if (debug && code_start != code_end)
                    {
                        debug_symbol_table.SetInt32(debug_symbol_count * 0xC, code_start);
                        debug_symbol_table.SetInt32(debug_symbol_count * 0xC + 4, code_end);
                        debug_symbol_table.SetString(debug_symbol_count * 0xC + 8, string.IsNullOrEmpty(v.Symbol) ? v.SectionName : v.Symbol, true);
                        debug_symbol_count++;
                    }
                }
                codedata = code.ToArray();

                // resize debug table
                if (debug)
                {
                    debug_symbol_table.Resize(debug_symbol_count * 0xC);
                }
            }

            // generate function table
            HSDStruct functionTable = new HSDStruct(8);
            var       funcCount     = 0;
            var       fl            = functions.ToList();

            foreach (var v in lelf.SymbolToData)
            {
                functionTable.Resize(8 * (funcCount + 1));
                functionTable.SetInt32(funcCount * 8, fl.IndexOf(v.Key));
                functionTable.SetInt32(funcCount * 8 + 4, (int)dataToOffset[v.Value]);
                funcCount++;
            }


            // set function table
            function._s.SetReferenceStruct(0x0C, functionTable);
            function._s.SetInt32(0x10, funcCount);


            // Generate Relocation Table
            HSDStruct relocationTable = new HSDStruct(0);
            var       relocCount      = 0;

            foreach (var v in lelf.AllSymbols)
            {
                // check data length
                if (v.Data.Length == 0)
                {
                    if (link.ContainsSymbol(CppSanatize(v.Symbol)))
                    {
                        continue;
                    }
                    else
                    {
                        throw new Exception($"Error: {v.Symbol} length is {v.Data.Length.ToString("X")}");
                    }
                }

                // print debug info
                if (!quiet)
                {
                    Console.WriteLine($"{v.Symbol,-30} {v.SectionName, -50} Offset: {dataToOffset[v].ToString("X8"), -16} Length: {v.Data.Length.ToString("X8")}");

                    if (v.Relocations.Count > 0)
                    {
                        Console.WriteLine($"\t {"Section:",-50} {"RelocType:",-20} {"FuncOffset:", -16} {"SectionOffset:"}");
                    }
                }

                // process and create relocation table
                foreach (var reloc in v.Relocations)
                {
                    if (!quiet)
                    {
                        Console.WriteLine($"\t {reloc.Symbol.SectionName, -50} {reloc.Type, -20} {reloc.Offset.ToString("X8"), -16} {reloc.AddEnd.ToString("X8")}");
                    }

                    // gather code positions
                    var codeOffset       = (int)(dataToOffset[v] + reloc.Offset);
                    var toFunctionOffset = (int)(dataToOffset[reloc.Symbol] + reloc.AddEnd);

                    // currently supported types check
                    switch (reloc.Type)
                    {
                    case RelocType.R_PPC_REL32:
                    case RelocType.R_PPC_REL24:
                    case RelocType.R_PPC_ADDR32:
                    case RelocType.R_PPC_ADDR16_LO:
                    case RelocType.R_PPC_ADDR16_HA:
                        break;

                    case (RelocType)0x6D:
                        break;

                    default:
                        // no exception, but not guarenteed to work
                        Console.WriteLine($"Warning: unsupported reloc type {toFunctionOffset.ToString("X")} " + reloc.Type.ToString("X") + $" in {v.Symbol} to {reloc.Symbol.Symbol} send this to Ploaj or UnclePunch");
                        break;
                    }

                    bool addEntry = true;

                    // only apply optimization if not external
                    if (!reloc.Symbol.External)
                    {
                        // calculate relative offset
                        var rel = toFunctionOffset - codeOffset;

                        // apply relocation automatically if possible
                        switch (reloc.Type)
                        {
                        case (RelocType)0x6D:
                        case RelocType.R_PPC_REL32:
                            codedata[codeOffset]     = (byte)((rel >> 24) & 0xFF);
                            codedata[codeOffset + 1] = (byte)((rel >> 16) & 0xFF);
                            codedata[codeOffset + 2] = (byte)((rel >> 8) & 0xFF);
                            codedata[codeOffset + 3] = (byte)((rel) & 0xFF);

                            addEntry = false;
                            break;

                        case RelocType.R_PPC_REL24:
                            var cur = ((codedata[codeOffset] & 0xFF) << 24) | ((codedata[codeOffset + 1] & 0xFF) << 16) | ((codedata[codeOffset + 2] & 0xFF) << 8) | ((codedata[codeOffset + 3] & 0xFF));
                            rel = cur | (rel & 0x03FFFFFC);

                            codedata[codeOffset]     = (byte)((rel >> 24) & 0xFF);
                            codedata[codeOffset + 1] = (byte)((rel >> 16) & 0xFF);
                            codedata[codeOffset + 2] = (byte)((rel >> 8) & 0xFF);
                            codedata[codeOffset + 3] = (byte)((rel) & 0xFF);

                            addEntry = false;
                            break;
                        }
                    }

                    // add relocation to table
                    if (addEntry)
                    {
                        relocationTable.Resize((relocCount + 1) * 0x08);
                        relocationTable.SetInt32(0x00 + relocCount * 8, codeOffset);
                        relocationTable.SetByte(0x00 + relocCount * 8, (byte)reloc.Type);
                        relocationTable.SetInt32(0x04 + relocCount * 8, toFunctionOffset);

                        relocCount++;
                    }
                }
            }

            function._s.SetReferenceStruct(0x00, new HSDStruct(codedata));
            function._s.SetReferenceStruct(0x04, relocationTable);
            function._s.SetInt32(0x08, relocCount);

            if (debug_symbol_table != null)
            {
                function._s.SetInt32(0x14, codedata.Length);
                function._s.SetInt32(0x18, debug_symbol_count);
                function._s.SetReferenceStruct(0x1C, debug_symbol_table);
            }

            return(function);
        }
Пример #16
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="args"></param>
        /// <returns></returns>
        public bool DoIt(string[] args)
        {
            // Parse Args
            List <Tuple <int, List <string> > > itemInputs = new List <Tuple <int, List <string> > >();
            List <string> inputs     = new List <string>();
            LinkFile      linkFile   = new LinkFile();
            string        output     = "";
            string        symbolName = "";
            string        datFile    = null;

            string[]      fightFuncTable  = null;
            string        buildPath       = null;
            bool          quiet           = true;
            bool          yesOverwrite    = false;
            bool          disableWarnings = true;
            bool          clean           = false;
            bool          debug           = false;
            int           opLevel         = 2;
            List <string> includes        = new List <string>();

            for (int i = 0; i < args.Length; i++)
            {
                if (args[i] == "-i")
                {
                    for (int j = i + 1; j < args.Length; j++)
                    {
                        if (File.Exists(args[j]))
                        {
                            inputs.Add(Path.GetFullPath(args[j]));
                        }
                        else
                        {
                            break;
                        }
                    }
                }

                if (args[i] == "-inc")
                {
                    for (int j = i + 1; j < args.Length; j++)
                    {
                        if (Directory.Exists(args[j]))
                        {
                            includes.Add(Path.GetFullPath(args[j]));
                        }
                        else
                        {
                            break;
                        }
                    }
                }

                if (args[i] == "-item" && i + 2 < args.Length)
                {
                    List <string> itemRefList = new List <string>();

                    for (int j = i + 2; j < args.Length; j++)
                    {
                        if (args[j] != "-item" && File.Exists(args[j]))
                        {
                            itemRefList.Add(Path.GetFullPath(args[j]));
                        }
                        else
                        {
                            break;
                        }
                    }

                    itemInputs.Add(new Tuple <int, List <string> >(int.Parse(args[i + 1]), itemRefList));
                }

                if (args[i] == "-op" && i + 1 < args.Length)
                {
                    opLevel = int.Parse(args[i + 1]);
                }

                if (args[i] == "-o" && i + 1 < args.Length)
                {
                    output = Path.GetFullPath(args[i + 1]);
                }

                if (args[i] == "-dat" && i + 1 < args.Length)
                {
                    datFile = Path.GetFullPath(args[i + 1]);
                }

                if (args[i] == "-s" && i + 1 < args.Length)
                {
                    symbolName = args[i + 1];
                }

                if (args[i] == "-ow")
                {
                    yesOverwrite = true;
                }

                if (args[i] == "-w")
                {
                    disableWarnings = false;
                }

                if (args[i] == "-d")
                {
                    debug = true;
                }

                if (args[i] == "-t" && i + 1 < args.Length)
                {
                    fightFuncTable = File.ReadAllLines(args[i + 1]);
                }

                if (args[i] == "-v")
                {
                    quiet = false;
                }

                if (args[i] == "-b" && i + 1 < args.Length)
                {
                    buildPath = Path.GetFullPath(args[i + 1]);
                }

                if (args[i] == "-l" && i + 1 < args.Length)
                {
                    linkFile.LoadLinkFile(args[i + 1]);
                }
            }

            //
            if (string.IsNullOrEmpty(symbolName))
            {
                Console.WriteLine("Error: Symbol Required; please specify a symbol Ex:\"-s ftFunction\"");
                return(false);
            }

            // if output is null set the name to the symbol name
            if (string.IsNullOrEmpty(datFile) &&
                string.IsNullOrEmpty(output) &&
                !string.IsNullOrEmpty(symbolName))
            {
                output = symbolName + ".dat";
            }

            var symbolPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, symbolName + ".txt");

            // if function table not specified attempt to get it from symbol name
            if (fightFuncTable == null &&
                !string.IsNullOrEmpty(symbolName) &&
                File.Exists(symbolPath))
            {
                fightFuncTable = File.ReadAllLines(symbolPath);
            }

            // load link file in mex directory
            foreach (var f in Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory))
            {
                if (Path.GetExtension(f).ToLower().Equals(".link"))
                {
                    linkFile.LoadLinkFile(f);
                }
            }

            // don't allow both item tables and normal tables
            if (inputs.Count > 0 && itemInputs.Count > 0)
            {
                Console.WriteLine("Only -i or -ii can be used at once, not both");
                return(false);
            }

            // print instruction and exit if no input
            if ((inputs.Count == 0 &&
                 itemInputs.Count == 0) ||
                args.Length == 0)
            {
                Console.WriteLine("No input files were given");
                return(false);
            }

            // check if symbol name is given
            if (string.IsNullOrEmpty(symbolName))
            {
                symbolName = "ftFunction";
                Console.WriteLine("No symbol name given, defaulting to \"ftFunction\"");
            }

            // create output path if one isn't entered
            if (string.IsNullOrEmpty(output) && string.IsNullOrEmpty(datFile))
            {
                output = Path.Combine(Path.GetDirectoryName(inputs[0]), Path.GetFileName(inputs[0]).Replace(Path.GetExtension(inputs[0]), ".dat"));
            }

            // check if output already exists
            if (File.Exists(output) && !yesOverwrite)
            {
                Console.WriteLine(output + " already exists, overwrite? (y/n)");
                if (Console.ReadLine().Trim().ToLower() != "y")
                {
                    return(false);
                }
            }

            // compile functions
            HSDAccessor function = null;

            // create file
            HSDRawFile      newfile    = null;
            HSDRawFile      injectfile = null;
            SBM_FighterData ftData     = null;

            // create new file
            if (!string.IsNullOrEmpty(output))
            {
                newfile = new HSDRawFile();
            }

            // inject existing dat file (or create new one if not found)
            if (!string.IsNullOrEmpty(datFile))
            {
                injectfile = File.Exists(datFile) ? new HSDRawFile(datFile) : new HSDRawFile();
            }

            // find fighter data if it exists
            if (injectfile != null && injectfile.Roots.Count > 0 && injectfile.Roots[0].Data is SBM_FighterData ftdata)
            {
                ftData = ftdata;
            }

            // static param table
            var param_table = new string[] { "param_ext" };

            // single table compile
            if (itemInputs.Count == 0)
            {
                var elfs = CompileElfs(inputs.ToArray(), disableWarnings, clean, opLevel, includes.ToArray(), buildPath, debug, quiet);

                //foreach (var f in Directory.GetFiles(@"C:\devkitPro\libogc\lib\cube"))
                //foreach (var f in Directory.GetFiles(@"C:\devkitPro\devkitPPC\powerpc-eabi\lib"))
                //{
                //    if (Path.GetExtension(f).Equals(".a"))
                //        elfs.AddRange(FighterFunction.LibArchive.GetElfs(f));
                //    if (Path.GetExtension(f).Equals(".o"))
                //        elfs.Add(new RelocELF(File.ReadAllBytes(f)));
                //}
                //elfs.AddRange(FighterFunction.LibArchive.GetElfs(@"C:\devkitPro\devkitPPC\lib\gcc\powerpc-eabi\10.2.0\libgcc.a"));
                //elfs.AddRange(FighterFunction.LibArchive.GetElfs(@"C:\Users\ploaj\Desktop\Modlee\libgc\MemCardDemo\libogc.a"));
                var lelf = GenerateLinkedElf(elfs, fightFuncTable, linkFile, quiet);

                // check for special attribute symbol
                if (ftData != null)
                {
                    foreach (var elf in elfs)
                    {
                        if (elf.SymbolEnumerator.Any(e => e.Symbol.Equals("param_ext")))
                        {
                            var special_attr = CmdGenerateDatFile.BuildDatFile(elf, param_table);

                            if (special_attr != null && special_attr.Roots.Count > 0 && special_attr["param_ext"] != null)
                            {
                                // Console.WriteLine("Found Param_Ext... adding to fighter data...");
                                ftData.Attributes2 = special_attr["param_ext"].Data;
                                break;
                            }
                        }
                    }
                }

                function = GenerateFunctionData(lelf, linkFile, fightFuncTable, quiet, debug);
            }
            else
            {
                // item table compile
                function = new HSDAccessor()
                {
                    _s = new HSDStruct(4)
                };

                int count = 0;
                foreach (var f in itemInputs)
                {
                    count = Math.Max(count, f.Item1 + 1);

                    if (4 + 4 * (f.Item1 + 1) > function._s.Length)
                    {
                        function._s.Resize(4 + 4 * (f.Item1 + 1));
                    }

                    var elfs = CompileElfs(f.Item2.ToArray(), disableWarnings, clean, opLevel, includes.ToArray(), buildPath, debug, quiet);
                    var lelf = GenerateLinkedElf(elfs, fightFuncTable, linkFile, quiet);

                    // check for special attribute symbol
                    if (ftData != null)
                    {
                        foreach (var elf in elfs)
                        {
                            if (elf.SymbolEnumerator.Any(e => e.Symbol.Equals("param_ext")))
                            {
                                var special_attr = CmdGenerateDatFile.BuildDatFile(elf, param_table);

                                if (special_attr != null && special_attr.Roots.Count > 0 && special_attr["param_ext"] != null)
                                {
                                    // Console.WriteLine("Found Param_Ext... adding to fighter data...");
                                    ftData.Articles.Articles[f.Item1].ParametersExt = special_attr["param_ext"].Data;
                                    break;
                                }
                            }
                        }
                    }

                    var relocFunc = GenerateFunctionData(lelf, linkFile, fightFuncTable, quiet, debug);
                    function._s.SetReference(4 + 0x04 * f.Item1, relocFunc);
                }
                function._s.SetInt32(0x00, count);
            }

            // inject symbol to dat file and save
            if (function != null)
            {
                if (newfile != null)
                {
                    DatTools.InjectSymbolIntoDat(newfile, symbolName, function);
                    newfile.Save(output);
                    Console.WriteLine("saving " + output + "...");
                }

                if (injectfile != null)
                {
                    DatTools.InjectSymbolIntoDat(injectfile, symbolName, function);
                    injectfile.Save(datFile);
                    Console.WriteLine("saving " + datFile + "...");
                }

                // We did it boys
                Console.WriteLine();
                Console.WriteLine("Sucessfully Compiled and Converted to DAT!");

                return(true);
            }

            return(false);
        }
Пример #17
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="table"></param>
        /// <param name="icons"></param>
        /// <returns></returns>
        private static MEX_mexSelectChr GenerateMexSelectChrSymbol(SBM_SelectChrDataTable table, MEX_CSSIcon[] cssIcons)
        {
            // create mexSelectChr struct
            MEX_mexSelectChr mex = new MEX_mexSelectChr();

            // generate icon model
            var icon_joint = HSDAccessor.DeepClone <HSD_JOBJ>(table.MenuModel.Children[2].Child);

            icon_joint.TX   = 0;
            icon_joint.TY   = 0;
            icon_joint.TZ   = 0;
            icon_joint.Next = null;
            var center = RegenerateIcon(icon_joint);

            // generate material_anim_joint
            var icon_matanim_joint = HSDAccessor.DeepClone <HSD_MatAnimJoint>(table.MenuMaterialAnimation.Children[2].Child);

            icon_matanim_joint.Next = null;

            // general base models
            HSD_JOBJ position_joint = new HSD_JOBJ();

            position_joint.Flags = JOBJ_FLAG.CLASSICAL_SCALING | JOBJ_FLAG.ROOT_XLU;
            position_joint.SX    = 1; position_joint.SY = 1; position_joint.SZ = 1;

            HSD_AnimJoint anim_joint = new HSD_AnimJoint();

            HSD_MatAnimJoint matanim_joint = new HSD_MatAnimJoint();

            // create icon data
            var joints   = table.MenuModel.BreathFirstList;
            var matanims = table.MenuAnimation.BreathFirstList;

            foreach (var ico in cssIcons)
            {
                if (joints[ico.JointID].Dobj == null)
                {
                    continue;
                }

                HSD_JOBJ joint = HSDAccessor.DeepClone <HSD_JOBJ>(icon_joint);
                joint.Dobj.Pobj.Attributes      = icon_joint.Dobj.Pobj.Attributes;
                joint.Dobj.Next.Pobj.Attributes = icon_joint.Dobj.Pobj.Attributes;
                joint.Dobj.Next.Mobj.Textures   = HSDAccessor.DeepClone <HSD_TOBJ>(joints[ico.JointID].Dobj.Next.Mobj.Textures);

                var worldPosition = new GXVector3(joints[ico.JointID].TX, joints[ico.JointID].TY, joints[ico.JointID].TZ);

                // get anim
                var anim = matanims[ico.JointID].AOBJ;

                // if it's a clone get parent location
                if (ico.JointID < 15)
                {
                    worldPosition = new GXVector3(joints[ico.JointID - 1].TX, joints[ico.JointID - 1].TY, joints[ico.JointID - 1].TZ);
                    anim          = matanims[ico.JointID - 1].AOBJ;
                }

                // check animation for world position
                if (anim != null)
                {
                    foreach (var v in anim.FObjDesc.List)
                    {
                        System.Diagnostics.Debug.WriteLine(v.JointTrackType);
                        if (v.JointTrackType == JointTrackType.HSD_A_J_TRAX)
                        {
                            var keys = v.GetDecodedKeys();
                            worldPosition.X = keys[keys.Count - 1].Value;
                        }
                    }
                }

                joint.TX = worldPosition.X + center.X;
                joint.TY = worldPosition.Y + center.Y;
                joint.TZ = worldPosition.Z + center.Z;

                position_joint.AddChild(joint);
                anim_joint.AddChild(new HSD_AnimJoint());
                matanim_joint.AddChild(HSDAccessor.DeepClone <HSD_MatAnimJoint>(icon_matanim_joint));
            }

            mex.IconModel        = position_joint;
            mex.IconAnimJoint    = anim_joint;
            mex.IconMatAnimJoint = matanim_joint;
            mex.CSPMatAnim       = HSDAccessor.DeepClone <HSD_MatAnim>(table.MenuMaterialAnimation.Children[6].Child.MaterialAnimation);

            var cspkeys = mex.CSPMatAnim.TextureAnimation.AnimationObject.FObjDesc.GetDecodedKeys();

            foreach (var k in cspkeys)
            {
                if ((k.Frame % 30) >= 19)
                {
                    k.Frame++;
                }
            }

            mex.CSPMatAnim.TextureAnimation.AnimationObject.FObjDesc.SetKeys(cspkeys, (byte)TexTrackType.HSD_A_T_TIMG);
            mex.CSPMatAnim.TextureAnimation.AnimationObject.FObjDesc.Next.SetKeys(cspkeys, (byte)TexTrackType.HSD_A_T_TCLT);

            mex.CSPStride = 30;

            return(mex);
        }
Пример #18
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="stage"></param>
        /// <returns></returns>
        public static MEX_mexMapData LoadIconDataFromVanilla(SBM_MnSelectStageDataTable stage)
        {
            List <HSD_TOBJ> nameTags = new List <HSD_TOBJ>();

            List <HSD_TOBJ> iconTOBJs = new List <HSD_TOBJ>();

            HSD_JOBJ root = new HSD_JOBJ()
            {
                SX    = 1,
                SY    = 1,
                SZ    = 1,
                Flags = JOBJ_FLAG.CLASSICAL_SCALING
            };

            HSD_AnimJoint animRoot = new HSD_AnimJoint();


            var tex0       = stage.IconDoubleMatAnimJoint.Child.Next.MaterialAnimation.Next.TextureAnimation.ToTOBJs();
            var tex0_extra = stage.IconDoubleMatAnimJoint.Child.MaterialAnimation.Next.TextureAnimation.ToTOBJs();
            var tex1       = stage.IconLargeMatAnimJoint.Child.MaterialAnimation.Next.TextureAnimation.ToTOBJs();
            var tex2       = stage.IconSpecialMatAnimJoint.Child.MaterialAnimation.Next.TextureAnimation.ToTOBJs();

            var nameTOBJs     = stage.StageNameMatAnimJoint.Child.Child.MaterialAnimation.TextureAnimation.ToTOBJs();
            var nameTOBJsAnim = stage.StageNameMatAnimJoint.Child.Child.MaterialAnimation.TextureAnimation.AnimationObject.FObjDesc.GetDecodedKeys();

            var positionAnimation = new List <HSD_AnimJoint>();

            foreach (var c in stage.PositionAnimation.Children)
            {
                var pos = new HSD_AnimJoint();
                pos.AOBJ = HSDAccessor.DeepClone <HSD_AOBJ>(c.AOBJ);
                positionAnimation.Add(pos);
            }

            var g1 = tex0.Length - 2;
            var g2 = tex0.Length - 2 + tex1.Length - 2;
            var g3 = tex0.Length - 2 + tex1.Length - 2 + tex2.Length - 2;

            for (int i = 0; i < stage.PositionModel.Children.Length; i++)
            {
                var childIndex = i;
                if (unswizzle.ContainsKey(i))
                {
                    childIndex = unswizzle[i];
                }

                HSD_TOBJ icon = null;
                HSD_TOBJ name = null;
                var      keys = positionAnimation[childIndex].AOBJ.FObjDesc.GetDecodedKeys();
                var      Y    = stage.PositionModel.Children[childIndex].TY;
                var      Z    = stage.PositionModel.Children[childIndex].TZ;
                var      SX   = 1f;
                var      SY   = 1f;

                if (i >= g3)
                {
                    //RandomIcon
                    name = nameTOBJs[(int)nameTOBJsAnim[nameTOBJsAnim.Count - 1].Value];
                }
                else
                if (i >= g2)
                {
                    name = nameTOBJs[(int)nameTOBJsAnim[24 + (i - g2)].Value];
                    icon = tex2[i - g2 + 2];
                    SX   = 0.8f;
                    SY   = 0.8f;
                }
                else
                if (i >= g1)
                {
                    name = nameTOBJs[(int)nameTOBJsAnim[22 + texunswizzle[i - g1]].Value];
                    icon = tex1[i - g1 + 2];
                    SY   = 1.1f;
                }
                else
                {
                    icon = tex0[texunswizzle[i] + 2];
                    name = nameTOBJs[(int)nameTOBJsAnim[texunswizzle[i]].Value * 2];

                    root.AddChild(new HSD_JOBJ()
                    {
                        TX    = keys[keys.Count - 1].Value,
                        TY    = Y,
                        TZ    = Z,
                        SX    = SX,
                        SY    = SY,
                        SZ    = 1,
                        Flags = JOBJ_FLAG.CLASSICAL_SCALING
                    });
                    iconTOBJs.Add(icon);
                    nameTags.Add(name);
                    animRoot.AddChild(HSDAccessor.DeepClone <HSD_AnimJoint>(positionAnimation[childIndex]));

                    Y   -= 5.6f;
                    Z    = 0;
                    icon = tex0_extra[texunswizzle[i] + 2];
                    name = nameTOBJs[(int)nameTOBJsAnim[texunswizzle[i]].Value * 2 + 1];
                }

                root.AddChild(new HSD_JOBJ()
                {
                    TX    = keys[keys.Count - 1].Value,
                    TY    = Y,
                    TZ    = Z,
                    SX    = SX,
                    SY    = SY,
                    SZ    = 1,
                    Flags = JOBJ_FLAG.CLASSICAL_SCALING
                });
                iconTOBJs.Add(icon);
                nameTags.Add(name);
                animRoot.AddChild(HSDAccessor.DeepClone <HSD_AnimJoint>(positionAnimation[childIndex]));
            }


            var extraIcons = stage.IconLargeMatAnimJoint.Child.MaterialAnimation.Next.TextureAnimation.ToTOBJs();

            iconTOBJs.Insert(0, extraIcons[0]);
            iconTOBJs.Insert(0, extraIcons[1]);
            iconTOBJs.Add(extraIcons[0]);


            var iconJOBJ = HSDAccessor.DeepClone <HSD_JOBJ>(stage.IconDoubleModel);

            iconJOBJ.Child = iconJOBJ.Child.Next;

            var iconAnimJoint = HSDAccessor.DeepClone <HSD_AnimJoint>(stage.IconDoubleAnimJoint);

            iconAnimJoint.Child = iconAnimJoint.Child.Next;

            var iconMatAnimJoint = HSDAccessor.DeepClone <HSD_MatAnimJoint>(stage.IconDoubleMatAnimJoint);

            iconMatAnimJoint.Child = iconMatAnimJoint.Child.Next;
            iconMatAnimJoint.Child.MaterialAnimation.Next.TextureAnimation.FromTOBJs(iconTOBJs.ToArray(), true);


            var mapdata = new MEX_mexMapData();

            mapdata.IconModel                  = iconJOBJ;
            mapdata.IconAnimJoint              = iconAnimJoint;
            mapdata.IconMatAnimJoint           = iconMatAnimJoint;
            mapdata.PositionModel              = root;
            mapdata.PositionAnimJoint          = animRoot;
            mapdata.StageNameMaterialAnimation = HSDAccessor.DeepClone <HSD_MatAnimJoint>(stage.StageNameMatAnimJoint);
            mapdata.StageNameMaterialAnimation.Child.Child.MaterialAnimation.TextureAnimation.FromTOBJs(nameTags, true);

            return(mapdata);
        }
        /// <summary>
        ///
        /// </summary>
        private bool BuildDemoAJFile(string symbol, string ajpath, int actionstart, int actionend)
        {
            if (string.IsNullOrEmpty(symbol))
            {
                return(false);
            }

            // get actions
            var actions = new Action[actionend - actionstart + 1];

            for (int i = actionstart; i <= actionend; i++)
            {
                actions[i - actionstart] = AllActions[i];
            }

            // rebuild aj file
            var data = AJManager.RebuildAJFile(actions.Select(e => e.Symbol).ToArray(), false);

            // update animation offset and sizes
            foreach (var a in actions)
            {
                // don't write subroutines
                if (a.Subroutine)
                {
                    continue;
                }

                // update animation size and offset
                if (!string.IsNullOrEmpty(a.Symbol))
                {
                    var offsize = AJManager.GetOffsetSize(a.Symbol);
                    a.AnimOffset = offsize.Item1;
                    a.AnimSize   = offsize.Item2;
                }
            }

            // save action changes to dat file
            SaveAllActionChanges();

            // save aj file
            HSDRawFile file = new HSDRawFile();

            if (File.Exists(ajpath))
            {
                file = new HSDRawFile(ajpath);
            }
            var dataAccessor = new HSDAccessor()
            {
                _s = new HSDStruct(data)
            };

            if (file[symbol] != null)
            {
                file[symbol].Data = dataAccessor;
            }
            else
            {
                file.Roots.Add(new HSDRootNode()
                {
                    Name = symbol, Data = dataAccessor
                });
            }
            file.Save(ajpath);

            return(true);
        }
Пример #20
0
        /// <summary>
        ///
        /// </summary>
        private void InstallUI(ZipFile pack, MEXFighterEntry fighter)
        {
            Console.WriteLine($"Installing UI data...");

            // LOAD Stock Icons
            var icons = pack.Where(e => Regex.IsMatch(e.FileName, "Icon/ico..\\.png")).ToArray();

            HSD_TOBJ[] iconTOBJs = new HSD_TOBJ[icons.Length];
            foreach (var c in icons)
            {
                var index = int.Parse(Regex.Match(c.FileName, @"\d\d").Value);
                using (MemoryStream stream = new MemoryStream(GetBytes(c)))
                    using (var bmp = new System.Drawing.Bitmap(stream))
                        iconTOBJs[index] = TOBJConverter.BitmapToTOBJ(bmp, HSDRaw.GX.GXTexFmt.CI4, HSDRaw.GX.GXTlutFmt.RGB5A3);
            }

            // Load Menu Icon

            // Load Emblem
            var      emblemPack    = pack["UI/emblem.obj"];
            HSD_TOBJ emblemTexture = null;
            HSD_JOBJ emblemModel   = null;

            if (emblemPack != null)
            {
                EmblemModel model;
                using (MemoryStream stream = new MemoryStream())
                {
                    emblemPack.Extract(stream);
                    stream.Position = 0;
                    model           = Converters.EmblemConverter.GenerateEmblemModelFromOBJ(stream);
                }
                emblemModel   = Converters.EmblemConverter.GenerateEmblemModel(model);
                emblemTexture = Converters.EmblemConverter.GenerateEmblemIconImage(model);
            }

            // Load Misc Name Tags and icons

            var      largeName        = pack["UI/result_victory_name.png"];
            var      smallName        = pack["UI/result_name.png"];
            HSD_TOBJ largeNameTexture = null;
            HSD_TOBJ smallNameTexture = null;

            if (largeName != null)
            {
                using (MemoryStream stream = new MemoryStream(GetBytes(largeName)))
                    using (var bmp = new System.Drawing.Bitmap(stream))
                        largeNameTexture = TOBJConverter.BitmapToTOBJ(bmp, HSDRaw.GX.GXTexFmt.I4, HSDRaw.GX.GXTlutFmt.IA8);
            }
            if (smallName != null)
            {
                using (MemoryStream stream = new MemoryStream(GetBytes(smallName)))
                    using (var bmp = new System.Drawing.Bitmap(stream))
                        smallNameTexture = TOBJConverter.BitmapToTOBJ(bmp, HSDRaw.GX.GXTexFmt.I4, HSDRaw.GX.GXTlutFmt.IA8);
            }

            // --------------------------------------------------------------------------

            var root = Path.GetDirectoryName(MainForm.Instance.FilePath);

            int stride     = editor.FighterControl.FighterEntries.Count - 3;
            int internalID = editor.FighterControl.FighterEntries.IndexOf(fighter);
            var externalId = MEXIdConverter.ToExternalID(internalID, editor.FighterControl.FighterEntries.Count);
            int GroupID    = externalId - (externalId > 18 ? 1 : 0);

            // Inject CSPs and Stock Icons into Character Select
            //var chrSelPath = Path.Combine(root, "MnSlChr.usd");
            //if (File.Exists(chrSelPath))
            //    InjectCharSelectImages(pack, chrSelPath, iconTOBJs, emblemTexture, fighter, stride, GroupID);

            // Inject Stock Icons into IfAll, GmRst

            var ifallPath = Path.Combine(root, "IfAll.usd");

            if (File.Exists(ifallPath))
            {
                var datFile = new HSDRawFile(ifallPath);

                var mark = datFile.Roots.Find(e => e.Name.Equals("Stc_scemdls")).Data as HSDNullPointerArrayAccessor <HSD_JOBJDesc>;

                for (int i = 0; i < 7; i++) // first 7
                {
                    InjectIntoMatTexAnim(mark[0].MaterialAnimations[0].Children[i].MaterialAnimation.TextureAnimation, iconTOBJs, GroupID, stride, MAX_COSTUME_COUNT);
                }


                var emblemGroup = datFile.Roots.Find(e => e.Name.Equals("DmgMrk_scene_models")).Data as HSDNullPointerArrayAccessor <HSD_JOBJDesc>;

                InjectIntoMatTexAnim(emblemGroup[0].MaterialAnimations[0].Child.MaterialAnimation.TextureAnimation, new HSDRaw.Common.HSD_TOBJ[] { emblemTexture }, GroupID, stride, 1, fighter.InsigniaID);


                editedFiles.Add(new Tuple <HSDRawFile, string, bool>(datFile, ifallPath, true));
            }


            var gmRst = Path.Combine(root, "GmRst.usd");

            if (File.Exists(gmRst))
            {
                var datFile = new HSDRawFile(gmRst);

                var flmsce = datFile.Roots.Find(e => e.Name.Equals("flmsce")).Data as HSD_SOBJ;
                var pnlsce = datFile.Roots.Find(e => e.Name.Equals("pnlsce")).Data as HSD_SOBJ;

                // Stock Icons-------------------------------------
                for (int i = 5; i <= 8; i++) // at 5-8, 2nd mat anim
                {
                    InjectIntoMatTexAnim(
                        pnlsce.JOBJDescs[0].MaterialAnimations[0].Children[i].MaterialAnimation.Next.TextureAnimation,
                        iconTOBJs,
                        GroupID,
                        stride,
                        MAX_COSTUME_COUNT);
                }

                // Emblem Textures--------------------------------------
                var matgroup = pnlsce.JOBJDescs[0].MaterialAnimations[0].Children[17];

                for (int i = 0; i < 4; i++)
                {
                    InjectIntoMatTexAnim(matgroup.Children[i].MaterialAnimation.TextureAnimation, new HSDRaw.Common.HSD_TOBJ[] { emblemTexture }, GroupID, stride, 1, fighter.InsigniaID);
                }

                // Emblem Model--------------------------------------
                var emblemGroup = flmsce.JOBJDescs[0];

                if (emblemModel != null)
                {
                    var modelIndex = emblemGroup.RootJoint.Children[4].Children.Length;

                    fighter.InsigniaID = (byte)modelIndex;

                    var jointClone = HSDAccessor.DeepClone <HSDRaw.Common.Animation.HSD_AnimJoint>(emblemGroup.JointAnimations[0].Children[4].Child);
                    jointClone.Next = null;

                    var matjointClone = HSDAccessor.DeepClone <HSDRaw.Common.Animation.HSD_MatAnimJoint>(emblemGroup.MaterialAnimations[0].Children[4].Child);
                    matjointClone.Next = null;

                    emblemGroup.JointAnimations[0].Children[4].AddChild(jointClone);
                    emblemGroup.MaterialAnimations[0].Children[4].AddChild(matjointClone);
                    emblemGroup.RootJoint.Children[4].AddChild(emblemModel);
                }


                // name textures
                var largenameGroup = pnlsce.JOBJDescs[0].MaterialAnimations[0].Children[0].Children[2].MaterialAnimation.Next.TextureAnimation;

                InjectIntoMatTexAnim(largenameGroup, new HSD_TOBJ[] { largeNameTexture }, GroupID, stride, 1);

                var smallnameGroup = pnlsce.JOBJDescs[0].MaterialAnimations[0];

                for (int i = 9; i < 13; i++)
                {
                    InjectIntoMatTexAnim(smallnameGroup.Children[i].Children[1].MaterialAnimation.TextureAnimation, new HSD_TOBJ[] { smallNameTexture }, GroupID, stride, 1);
                }


                editedFiles.Add(new Tuple <HSDRawFile, string, bool>(datFile, gmRst, true));
            }

            // Inject Emblem

            // Generate Emblem Models and Inject

            // Inject Misc Name Tags and icons
        }
Пример #21
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="table"></param>
        /// <param name="icons"></param>
        /// <returns></returns>
        public static MEX_mexSelectChr GenerateMEXMapFromVanilla(SBM_SelectChrDataTable table, MEX_CSSIconEntry[] icons)
        {
            // generate icon model
            var icon_joint = HSDAccessor.DeepClone <HSD_JOBJ>(table.MenuModel.Children[2].Child);

            icon_joint.TX   = 0;
            icon_joint.TY   = 0;
            icon_joint.TZ   = 0;
            icon_joint.Next = null;
            var center = RegenerateIcon(icon_joint);

            var icon_matanim_joint = HSDAccessor.DeepClone <HSD_MatAnimJoint>(table.MenuMaterialAnimation.Children[2].Child);

            icon_matanim_joint.Next = null;

            // generate mat anim node
            var joints = table.MenuModel.BreathFirstList;

            HSD_TOBJ[] tobjs = new HSD_TOBJ[icons.Max(e => e.FighterExternalID) + 1];

            JOBJManager m = new JOBJManager();

            m.SetJOBJ(table.MenuModel);
            m.SetAnimJoint(table.MenuAnimation);
            m.Frame = 600;
            m.UpdateNoRender();

            var csps    = table.MenuMaterialAnimation.Children[6].Child.MaterialAnimation.TextureAnimation.ToTOBJs();
            var cspKeys = table.MenuMaterialAnimation.Children[6].Child.MaterialAnimation.TextureAnimation.AnimationObject.FObjDesc.GetDecodedKeys();

            var stride = 30;

            foreach (var ico in icons)
            {
                if (joints[ico.icon.JointID].Dobj == null)
                {
                    continue;
                }

                HSD_JOBJ pos = HSDAccessor.DeepClone <HSD_JOBJ>(icon_joint);
                pos.Dobj.Pobj.Attributes      = icon_joint.Dobj.Pobj.Attributes;
                pos.Dobj.Next.Pobj.Attributes = icon_joint.Dobj.Pobj.Attributes;

                pos.Dobj.Next.Mobj.Textures = HSDAccessor.DeepClone <HSD_TOBJ>(joints[ico.icon.JointID].Dobj.Next.Mobj.Textures);

                var worldPosition = Vector3.TransformPosition(Vector3.Zero, m.GetWorldTransform(ico.icon.JointID));
                pos.TX = worldPosition.X + center.X;
                pos.TY = worldPosition.Y + center.Y;
                pos.TZ = worldPosition.Z + center.Z;

                ico.Joint        = pos;
                ico.Animation    = new MexMenuAnimation();
                ico.MatAnimJoint = HSDAccessor.DeepClone <HSD_MatAnimJoint>(icon_matanim_joint);

                // load csps
                // find key at stride
                var icocsps  = new List <HSD_TOBJ>();
                int cspIndex = 0;
                while (true)
                {
                    var key = ico.FighterExternalID + (cspIndex * stride);
                    if (ico.FighterExternalID > 0x13)
                    {
                        key = ico.FighterExternalID + (cspIndex * stride) - 1;
                    }

                    var k = cspKeys.Find(e => e.Frame == key);

                    if (k == null)
                    {
                        break;
                    }

                    icocsps.Add(csps[(int)k.Value]);

                    cspIndex++;
                }
                ico.CSPs = icocsps.Select(e => new TOBJProxy()
                {
                    TOBJ = e
                }).ToArray();
            }

            m.RefreshRendering = true;

            MEX_mexSelectChr mex = new MEX_mexSelectChr();

            SetMexNode(mex, icons);

            return(mex);
        }