Exemplo n.º 1
0
        static void ExtractBg(string bgPath, string basePath = null)
        {
            if (basePath == null)
            {
                basePath = Path.ChangeExtension(bgPath, null);
            }
            else
            {
                basePath = Path.Combine(basePath, Path.GetFileNameWithoutExtension(bgPath));
            }

            DatReader dat = new DatReader(Utils.CheckDecompress(File.OpenRead(bgPath)));

            using ObjConverter converter = new ObjConverter(dat);
            string mtlPath = basePath + ".mtl";
            string mtlName = Path.GetFileName(mtlPath);

            for (int i = 0; i < 3; ++i)
            {
                using MemoryStream ms = new MemoryStream(dat.GetData(i));
                DatReader innerDat = new DatReader(ms);
                for (int j = 0; j < innerDat.EntriesCount; ++j)
                {
                    using BinaryReader br = new BinaryReader(new MemoryStream(innerDat.GetData(j)));
                    Tdb tdb = new Tdb();
                    tdb.Read(br);

                    // Remap textures (only known for Windows version, PS2 todo when files obtained)
                    if (i == 0)
                    {
                        tdb.Textures[0].DatIndex = 4;
                        tdb.Textures[1].DatIndex = 3;
                    }
                    else
                    {
                        tdb.Textures[0].DatIndex = 5;
                    }

                    using StreamWriter sw = File.CreateText($"{basePath}.{i}_{j}.obj");
                    sw.WriteLine($"mtllib {mtlName}");
                    sw.WriteLine();

                    converter.ConvertObj(tdb, sw);
                }
            }

            using (StreamWriter sw = File.CreateText(mtlPath))
            {
                converter.ExportTextures(sw, basePath + ".", true);
            }
        }
Exemplo n.º 2
0
        TxmHeader CreateTexture(Tdb tdb, int index, out ulong textureId)
        {
            var tdbTexture = tdb.Textures[index];

            textureId = ((ulong)tdbTexture.DatIndex << 32) | ((ulong)tdbTexture.ImageBufferBase << 16) | tdbTexture.ClutBufferBase;
            if (!textureCache.ContainsKey(textureId))
            {
                TxmHeader txm = new TxmHeader();
                txm.ImageBufferBase = tdbTexture.ImageBufferBase;
                txm.ClutBufferBase  = tdbTexture.ClutBufferBase;
                textureCache.Add(textureId, txm);
                return(txm);
            }
            return(null);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Returns stacks by select command.
        /// </summary>
        /// <param name="selectcommand">Select command.</param>
        public MochaArray <MochaStack> GetStacks(string selectcommand)
        {
            var regex = new Regex(selectcommand);

            return(new MochaArray <MochaStack>(Tdb.GetStacks(x => regex.IsMatch(x.Name))));
        }
Exemplo n.º 4
0
        /// <summary>
        /// Returns table by use command.
        /// </summary>
        /// <param name="usecommand">Use command.</param>
        public MochaTableResult GetTable(string usecommand, bool from)
        {
            MochaColumn GetColumn(string cmd, IList <MochaColumn> cols)
            {
                string decomposeBrackets(string value)
                {
                    int dex;

                    if ((dex = value.IndexOf('(')) != -1)
                    {
                        return(value.Substring(dex + 1, value.Length - dex - 2));
                    }
                    return(value);
                }

                string name = Mhql_AS.GetAS(ref cmd);

                if (Mhql_GRAMMAR.UseFunctions.MatchKey(cmd))
                {
                    MochaColumn column = new MochaColumn();
                    column.MHQLAsText = name;
                    column.Tag        =
                        Mhql_GRAMMAR.UseFunctions.GetValueByMatchKey(cmd);
                    if (column.Tag != "COUNT")
                    {
                        column.Description =
                            Mhql_GRAMMAR.GetIndexOfColumn(decomposeBrackets(cmd), cols, from).ToString();
                    }
                    return(column);
                }
                else
                {
                    string colname = cmd.StartsWith("$") ? cmd.Substring(1).Trim() : cmd;
                    IEnumerable <MochaColumn> result = cols.Where(x => x.Name == colname);
                    if (!result.Any())
                    {
                        throw new Exception($"Could not find a column with the name '{cmd}'!");
                    }
                    MochaColumn column = result.First();
                    column.Tag        = colname != cmd ? "$" : null;
                    column.MHQLAsText = name;
                    return(column);
                }
            }

            List <MochaColumn> columns     = new List <MochaColumn>();
            MochaTableResult   resulttable = new MochaTableResult();

            if (from)
            {
                int                dex       = Mhql_FROM.GetIndex(ref usecommand);
                string             tablename = usecommand.Substring(dex + 5).Trim();
                List <string>      parts     = Mhql_LEXER.SplitUseParameters(usecommand.Substring(0, dex));
                List <MochaColumn> _columns  = Tdb.GetColumns(tablename);
                if (parts.Count == 1 && parts[0].Trim() == "*")
                {
                    columns.AddRange(_columns);
                }
                else
                {
                    if (parts[0].TrimStart().StartsWith("$") &&
                        parts[0].TrimStart().Substring(1).TrimStart().StartsWith($"{Mhql_LEXER.LBRACE}"))
                    {
                        throw new InvalidOperationException("Cannot be used with subquery FROM keyword!");
                    }
                    for (int index = 0; index < parts.Count; ++index)
                    {
                        columns.Add(GetColumn(parts[index].Trim(), _columns));
                    }
                }
            }
            else
            {
                List <string> parts = Mhql_LEXER.SplitUseParameters(usecommand);
                for (int index = 0; index < parts.Count; ++index)
                {
                    string callcmd = parts[index].Trim();
                    if (callcmd == "*")
                    {
                        List <MochaTable> tables = Tdb.GetTables();
                        for (int tindex = 0; tindex < tables.Count; ++tindex)
                        {
                            columns.AddRange(tables[tindex].Columns);
                        }
                        continue;
                    }
                    int obrace = callcmd.IndexOf(Mhql_LEXER.LBRACE);
                    if (obrace != -1)
                    {
                        IList <MochaColumn> _cols = (new MochaDbCommand(Tdb).ExecuteScalar(Mhql_LEXER.RangeSubqueryBrace(
                                                                                               callcmd.Substring(obrace).Trim()))).Columns;
                        string mode =
                            callcmd.Substring(0, obrace).TrimStart().StartsWith("$") ?
                            "$" : string.Empty;
                        for (int cindex = 0; cindex < _cols.Count; ++cindex)
                        {
                            columns.Add(GetColumn($"{mode}{_cols[cindex].Name}", _cols));
                        }
                        continue;
                    }
                    if (callcmd.StartsWith("$"))
                    {
                        callcmd = callcmd.Substring(1).Trim();
                        List <MochaColumn> _cols = Tdb.GetColumns(callcmd);
                        for (int cindex = 0; cindex < _cols.Count; ++cindex)
                        {
                            columns.Add(GetColumn($"${_cols[cindex].Name}", _cols));
                        }
                        continue;
                    }

                    string[] callparts = Mhql_LEXER.SplitSubCalls(callcmd);
                    if (callparts.Length > 2)
                    {
                        throw new InvalidOperationException($"'{callcmd}' command is cannot processed!");
                    }
                    for (byte partindex = 0; partindex < callparts.Length; ++partindex)
                    {
                        callparts[partindex] = callparts[partindex].Trim();
                    }
                    List <MochaColumn> _columns = Tdb.GetColumns(callparts[0]);
                    if (callparts.Length == 1)
                    {
                        columns.AddRange(_columns);
                    }
                    else
                    {
                        columns.Add(GetColumn(callparts[1], _columns));
                    }
                }
            }
            resulttable.Columns = columns.ToArray();
            resulttable.SetRowsByDatas();
            return(resulttable);
        }
Exemplo n.º 5
0
 public void ConvertObj(Tdb tdb, StreamWriter sw)
 {
     WriteObj(tdb, sw, 1);
 }
Exemplo n.º 6
0
        int WriteObj(Tdb tdb, StreamWriter sw, int startVert)
        {
            for (int i = 0; i < tdb.Mesh.Elements.Count; ++i)
            {
                var elem = tdb.Mesh.Elements[i];
                sw.WriteLine($"g elem_{i}");

                TxmHeader txm = CreateTexture(tdb, elem.TextureIndex, out var textureId);
                sw.WriteLine($"usemtl tex_{textureId:x12}");
                if (txm != null)
                {
                    FillTxm(elem, txm);
                }

                // Write vertices
                foreach (var vert in elem.Vertices)
                {
                    sw.WriteLine($"v {(double)vert.X} {(double)vert.Y} {(double)vert.Z}");
                }

                foreach (var norm in elem.VertexNormals)
                {
                    sw.WriteLine($"vn {norm.Item1} {norm.Item2} {norm.Item3}");
                }

                foreach (var uv in elem.STCoordinates)
                {
                    sw.WriteLine($"vt {uv.Item1} {1 - uv.Item2}");
                }

                // Write faces
                int[] initVerts = new int[2];
                bool  clockwise = true;
                if (elem.GifTagIndex == 3) // Triangle fans
                {
                    int initVertPos = 0;
                    for (int j = 0; j < elem.Vertices.Count; ++j)
                    {
                        if ((elem.Vertices[j].W.Packed & 0x00008000) != 0)
                        {
                            initVerts[initVertPos++] = startVert + j;
                        }
                        else
                        {
                            int currVert = startVert + j;
                            if (clockwise)
                            {
                                sw.WriteLine($"f {initVerts[0]}/{initVerts[0]}/{initVerts[0]} {initVerts[1]}/{initVerts[1]}/{initVerts[1]} {currVert}/{currVert}/{currVert}");
                            }
                            else
                            {
                                sw.WriteLine($"f {currVert}/{currVert}/{currVert} {initVerts[1]}/{initVerts[1]}/{initVerts[1]} {initVerts[0]}/{initVerts[0]}/{initVerts[0]}");
                            }
                            initVerts[1] = currVert;
                            initVertPos  = 0;
                        }
                        clockwise = !clockwise;
                    }
                }
                else if (elem.GifTagIndex == 4) // Triangle strips
                {
                    for (int j = 0; j < elem.Vertices.Count; ++j)
                    {
                        int currVert = startVert + j;
                        if ((elem.Vertices[j].W.Packed & 0x00008000) == 0)
                        {
                            if (clockwise)
                            {
                                sw.WriteLine($"f {initVerts[0]}/{initVerts[0]}/{initVerts[0]} {initVerts[1]}/{initVerts[1]}/{initVerts[1]} {currVert}/{currVert}/{currVert}");
                            }
                            else
                            {
                                sw.WriteLine($"f {currVert}/{currVert}/{currVert} {initVerts[1]}/{initVerts[1]}/{initVerts[1]} {initVerts[0]}/{initVerts[0]}/{initVerts[0]}");
                            }
                        }
                        initVerts[0] = initVerts[1];
                        initVerts[1] = currVert;
                        clockwise    = !clockwise;
                    }
                }
                else
                {
                    throw new NotSupportedException("Unknown face construction type");
                }
                startVert += elem.Vertices.Count;
                sw.WriteLine();
            }

            return(startVert);
        }
Exemplo n.º 7
0
        /// <summary>
        /// Returns table by use command.
        /// </summary>
        /// <param name="usecommand">Use command.</param>
        public MochaTableResult GetTable(string usecommand, bool from)
        {
            var columns     = new List <MochaColumn>();
            var resulttable = new MochaTableResult();

            if (from)
            {
                var dex       = usecommand.IndexOf("FROM", StringComparison.OrdinalIgnoreCase);
                var tablename = usecommand.Substring(dex + 4).TrimStart().TrimEnd();
                var parts     = usecommand.Substring(0, dex).Split(',');

                var table = Tdb.GetTable(tablename);

                if (parts.Length == 1 && parts[0].Trim() == "*")
                {
                    columns.AddRange(table.Columns);
                }
                else
                {
                    for (var index = 0; index < parts.Length; index++)
                    {
                        var callcmd = parts[index].Trim();
                        var name    = Mhql_AS.GetAS(ref callcmd);
                        var column  = table.Columns[callcmd];
                        column.Name = name;
                        columns.Add(column);
                    }
                }
            }
            else
            {
                var parts = usecommand.Split(',');
                for (var index = 0; index < parts.Length; index++)
                {
                    var callcmd = parts[index].Trim();
                    if (callcmd == "*")
                    {
                        var tables = Tdb.GetTables();
                        for (int tindex = 0; tindex < tables.Count; tindex++)
                        {
                            columns.AddRange(tables[tindex].Columns);
                        }
                        continue;
                    }

                    var callparts = callcmd.Split('.');
                    if (callparts.Length > 2)
                    {
                        throw new MochaException($"'{callcmd}' command is cannot processed!");
                    }
                    for (byte partindex = 0; partindex < callparts.Length; partindex++)
                    {
                        callparts[partindex] = callparts[partindex].Trim();
                    }
                    var table = Tdb.GetTable(callparts[0]);
                    if (callparts.Length == 1)
                    {
                        columns.AddRange(table.Columns);
                    }
                    else
                    {
                        var callp1 = callparts[1];
                        var name   = Mhql_AS.GetAS(ref callp1);
                        var column = table.Columns[callp1];
                        column.Name = name;
                        columns.Add(column);
                    }
                }
            }

            resulttable.Columns = columns.ToArray();
            resulttable.SetRowsByDatas();

            return(resulttable);
        }
Exemplo n.º 8
0
        /// <summary>
        /// Returns sector table by use command.
        /// </summary>
        /// <param name="usecommand">Use command.</param>
        public MochaTableResult GetSector(string usecommand, bool from)
        {
            if (from)
            {
                throw new MochaException("FROM keyword is cannot used with @SECTORS marked commands!");
            }

            var resulttable = new MochaTableResult {
                Columns = new[] {
                    new MochaColumn("Name"),
                    new MochaColumn("Description"),
                    new MochaColumn("Data")
                }
            };
            var rows = new List <MochaRow>();

            var parts = usecommand.Split(',');

            for (var index = 0; index < parts.Length; index++)
            {
                var callcmd = parts[index].TrimStart().TrimEnd();
                if (callcmd == "*")
                {
                    var sectors = Tdb.GetSectors();
                    for (int sindex = 0; sindex < sectors.Count; sindex++)
                    {
                        var currentsector = sectors.ElementAt(sindex);
                        rows.Add(new MochaRow(
                                     new MochaData {
                            data     = currentsector.Name,
                            dataType = MochaDataType.String
                        },
                                     new MochaData {
                            data     = currentsector.Description,
                            dataType = MochaDataType.String
                        },
                                     new MochaData {
                            data     = currentsector.Data,
                            dataType = MochaDataType.String
                        }
                                     ));
                    }
                }
                else
                {
                    var sector = Tdb.GetSector(callcmd);
                    rows.Add(new MochaRow(
                                 new MochaData {
                        data     = sector.Name,
                        dataType = MochaDataType.String
                    },
                                 new MochaData {
                        data     = sector.Description,
                        dataType = MochaDataType.String
                    },
                                 new MochaData {
                        data     = sector.Data,
                        dataType = MochaDataType.String
                    }
                                 ));
                }
            }
            resulttable.Rows = rows.ToArray();

            return(resulttable);
        }