예제 #1
0
 public void AddStructureInfo(MetaName name)
 {
     if (!StructureInfos.ContainsKey(name))
     {
         PsoStructureInfo si = PsoTypes.GetStructureInfo(name);
         if (si != null)
         {
             StructureInfos[name] = si;
         }
     }
 }
예제 #2
0
        public static void EnsurePsoTypes(PsoFile pso)
        {
            if ((pso.SchemaSection == null) || (pso.SchemaSection.Entries == null) || (pso.SchemaSection.EntriesIdx == null))
            {
                return;
            }


            for (int i = 0; i < pso.SchemaSection.Entries.Length; i++)
            {
                var entry      = pso.SchemaSection.Entries[i];
                var enuminfo   = entry as PsoEnumInfo;
                var structinfo = entry as PsoStructureInfo;

                if (enuminfo != null)
                {
                    if (!EnumDict.ContainsKey(enuminfo.IndexInfo.NameHash))
                    {
                        EnumDict.Add(enuminfo.IndexInfo.NameHash, enuminfo);
                    }
                    else
                    {
                        PsoEnumInfo oldei = EnumDict[enuminfo.IndexInfo.NameHash];
                        if (!ComparePsoEnumInfos(oldei, enuminfo))
                        {
                        }
                    }
                }
                else if (structinfo != null)
                {
                    if (!StructDict.ContainsKey(structinfo.IndexInfo.NameHash))
                    {
                        StructDict.Add(structinfo.IndexInfo.NameHash, structinfo);
                    }
                    else
                    {
                        PsoStructureInfo oldsi = StructDict[structinfo.IndexInfo.NameHash];
                        if (!ComparePsoStructureInfos(oldsi, structinfo))
                        {
                        }
                    }
                }
            }
        }
예제 #3
0
파일: Pso.cs 프로젝트: fullike/CodeWalker
        public void Read(DataReader reader)
        {
            Ident  = reader.ReadInt32();
            Length = reader.ReadInt32();
            Count  = reader.ReadUInt32();

            this.EntriesIdx = new PsoElementIndexInfo[Count];
            for (int i = 0; i < Count; i++)
            {
                var entry = new PsoElementIndexInfo();
                entry.Read(reader);
                EntriesIdx[i] = entry;
            }

            this.Entries = new PsoElementInfo[Count];
            for (int i = 0; i < Count; i++)
            {
                reader.Position = EntriesIdx[i].Offset;
                var type = reader.ReadByte();

                reader.Position = EntriesIdx[i].Offset;
                if (type == 0)
                {
                    var entry = new PsoStructureInfo();
                    entry.Read(reader);
                    entry.IndexInfo = EntriesIdx[i];
                    Entries[i]      = entry;
                }
                else if (type == 1)
                {
                    var entry = new PsoEnumInfo();
                    entry.Read(reader);
                    entry.IndexInfo = EntriesIdx[i];
                    Entries[i]      = entry;
                }
                else
                {
                    throw new Exception("unknown type!");
                }
            }
        }
예제 #4
0
        public static bool ComparePsoStructureInfos(PsoStructureInfo a, PsoStructureInfo b)
        {
            //returns true if they are the same.

            if (a.Entries.Length != b.Entries.Length)
            {
                return(false);
            }

            for (int i = 0; i < a.Entries.Length; i++)
            {
                if ((a.Entries[i].EntryNameHash != b.Entries[i].EntryNameHash) ||
                    (a.Entries[i].DataOffset != b.Entries[i].DataOffset) ||
                    (a.Entries[i].Type != b.Entries[i].Type))
                {
                    return(false);
                }
            }

            return(true);
        }
예제 #5
0
        private static void TraverseArray(XmlNode node, PsoBuilder pb, PsoStructureEntryInfo entry, PsoStructureEntryInfo arrEntry, PsoArrayResults results, byte[] data, PsoStructureInfo structInfo)
        {
            int  offset = entry.DataOffset;
            uint aCount = (entry.ReferenceKey >> 16) & 0x0000FFFF;
            uint aPtr   = (entry.ReferenceKey) & 0x0000FFFF;

            byte[] adata = null;

            //how do we know when it's an "embedded" array?
            bool embedded = true;

            switch (entry.Unk_5h)
            {
            default:
                //ErrorXml(sb, indent, ename + ": WIP! Unsupported Array subtype: " + entry.Unk_5h.ToString());
                break;

            case 0:     //Array_Structure
                //var arrStruc = MetaTypes.ConvertData<Array_Structure>(data, eoffset);
                embedded = false;
                break;

            case 1:     //Raw in-line array
                break;

            case 2:     //also raw in-line array, but how different from above?
                break;

            case 4:                       //pointer array? default array?
                if (arrEntry.Unk_5h == 3) //pointers...
                {
                    //var arrStruc4 = MetaTypes.ConvertData<Array_Structure>(data, eoffset);
                    embedded = false;
                }
                else
                {
                }
                break;

            case 129:     //also raw inline array? in junctions.pso  (AutoJunctionAdjustments)
                break;
            }



            switch (arrEntry.Type)
            {
            case PsoDataType.Structure:
            {
                if (embedded)
                {
                    if (arrEntry.ReferenceKey != 0)
                    {
                        var datas   = TraverseArrayStructureRaw(node, pb, (MetaName)arrEntry.ReferenceKey);
                        int aoffset = offset;
                        for (int i = 0; i < datas.Length; i++)
                        {
                            Buffer.BlockCopy(datas[i], 0, data, aoffset, datas[i].Length);
                            aoffset += datas[i].Length;
                        }
                    }
                    else
                    {
                        var ptrs = TraverseArrayStructurePointerRaw(node, pb);
                        adata = MetaTypes.ConvertArrayToBytes(ptrs);
                    }
                }
                else
                {
                    if (arrEntry.ReferenceKey != 0)
                    {
                        results.Structures[offset] = TraverseArrayStructure(node, pb, (MetaName)arrEntry.ReferenceKey);
                    }
                    else
                    {
                        results.StructurePointers[offset] = TraverseArrayStructurePointer(node, pb);
                    }
                }
                break;
            }

            case PsoDataType.Float2:
            {
                var arr = TraverseVector2ArrayRaw(node);
                if (embedded)
                {
                    adata   = MetaTypes.ConvertArrayToBytes(arr);
                    aCount *= 8;
                }
                else
                {
                    results.Float_XYZs[offset] = pb.AddVector2ArrayPtr(arr);
                }
                break;
            }

            case PsoDataType.Float3:
            {
                var arr = TraverseVector3ArrayRaw(node);
                if (embedded)
                {
                    adata   = MetaTypes.ConvertArrayToBytes(arr);
                    aCount *= 16;
                }
                else
                {
                    results.Float_XYZs[offset] = pb.AddPaddedVector3ArrayPtr(arr);
                }
                break;
            }

            case PsoDataType.UByte:
            {
                var arr = TraverseUByteArrayRaw(node);
                if (embedded)
                {
                    adata = arr;
                }
                else
                {
                    results.UBytes[offset] = pb.AddByteArrayPtr(arr);
                }
                break;
            }

            case PsoDataType.Bool:
            {
                var arr = TraverseUByteArrayRaw(node);
                if (embedded)
                {
                    adata = arr;
                }
                else
                {
                    results.UBytes[offset] = pb.AddByteArrayPtr(arr);
                }
                break;
            }

            case PsoDataType.UInt:
            {
                var arr = TraverseUIntArrayRaw(node);
                if (embedded)
                {
                    adata   = MetaTypes.ConvertArrayToBytes(arr);
                    aCount *= 4;
                }
                else
                {
                    results.UInts[offset] = pb.AddUIntArrayPtr(arr);
                }
                break;
            }

            case PsoDataType.SInt:
            {
                var arr = TraverseSIntArrayRaw(node);
                if (embedded)
                {
                    adata   = MetaTypes.ConvertArrayToBytes(arr);
                    aCount *= 4;
                }
                else
                {
                    results.UInts[offset] = pb.AddSIntArrayPtr(arr);
                }
                break;
            }

            case PsoDataType.Float:
            {
                var arr = TraverseFloatArrayRaw(node);
                if (embedded)
                {
                    adata   = MetaTypes.ConvertArrayToBytes(arr);
                    aCount *= 4;
                }
                else
                {
                    results.Floats[offset] = pb.AddFloatArrayPtr(arr);
                }
                break;
            }

            case PsoDataType.UShort:
            {
                var arr = TraverseUShortArrayRaw(node);
                if (embedded)
                {
                    adata   = MetaTypes.ConvertArrayToBytes(arr);
                    aCount *= 2;
                }
                else
                {
                    results.UShorts[offset] = pb.AddUShortArrayPtr(arr);
                }
                break;
            }

            case PsoDataType.String:
            {
                switch (entry.Unk_5h)
                {
                default:
                    //ErrorXml(sb, indent, ename + ": Unexpected String array subtype: " + entry.Unk_5h.ToString());
                    break;

                case 0:             //hash array...
                    var hashes = TraverseHashArrayRaw(node);
                    if (embedded)
                    {
                        adata   = MetaTypes.ConvertArrayToBytes(hashes);
                        aCount *= 4;
                    }
                    else
                    {
                        results.Hashes[offset] = pb.AddHashArrayPtr(hashes);
                    }
                    break;
                }


                break;
            }


            case PsoDataType.Enum:
            {
                var hashes = TraverseHashArrayRaw(node);

                if (arrEntry.ReferenceKey != 0)
                {
                    var _infos = PsoTypes.GetEnumInfo((MetaName)arrEntry.ReferenceKey);
                    pb.AddEnumInfo(_infos.IndexInfo.NameHash);

                    var values = new uint[hashes.Length];
                    for (int i = 0; i < hashes.Length; i++)
                    {
                        var enumname = (MetaName)MetaTypes.SwapBytes(hashes[i]);        //yeah swap it back to little endian..!
                        var enuminf  = _infos.FindEntryByName(enumname);
                        if (enuminf != null)
                        {
                            values[i] = MetaTypes.SwapBytes((uint)enuminf.EntryKey);
                        }
                        else
                        {
                        }           //error?
                    }

                    if (embedded)
                    {
                    }           //TODO?
                    else
                    {
                        results.UInts[offset] = pb.AddUIntArrayPtr(values);
                    }
                }
                else
                {
                }


                break;
            }


            case PsoDataType.Array:
            {
                //array array...
                var rk0 = (entry.ReferenceKey >> 16) & 0x0000FFFF;
                var rk1 = arrEntry.ReferenceKey & 0x0000FFFF;
                if (rk0 > 0)         //should be count of items
                {
                    var subarrEntry = structInfo.GetEntry((int)rk1);
                    var subarrType  = (MetaName)subarrEntry.ReferenceKey;

                    var origOffset = arrEntry.DataOffset;
                    arrEntry.DataOffset = entry.DataOffset;        //slight hack for traversing array array
                    foreach (XmlNode cnode in node.ChildNodes)
                    {
                        TraverseArray(cnode, pb, arrEntry, subarrEntry, results, data, structInfo);

                        arrEntry.DataOffset += 16;        //ptr size... todo: what if not pointer array?
                    }
                    arrEntry.DataOffset = origOffset;
                }


                break;
            }



            default:
                break;
            }

            if (embedded)
            {
                if (adata?.Length > 0)
                {
                    if (adata.Length > aCount)
                    {
                    }  //bad! old data won't fit in new slot...

                    Buffer.BlockCopy(adata, 0, data, offset, adata.Length);
                }
                else
                {
                }
            }
        }
예제 #6
0
        private static void TraverseMap(XmlNode node, PsoBuilder pb, PsoStructureEntryInfo entry, PsoStructureInfo infos, byte[] data, PsoArrayResults arrayResults)
        {
            var mapidx1     = entry.ReferenceKey & 0x0000FFFF;
            var mapidx2     = (entry.ReferenceKey >> 16) & 0x0000FFFF;
            var mapreftype1 = infos.Entries[mapidx2];
            var mapreftype2 = infos.Entries[mapidx1];

            if (mapreftype2.ReferenceKey != 0)
            {
            }

            var xStruct = pb.AddMapNodeStructureInfo((MetaName)mapreftype2.ReferenceKey);
            var xName   = xStruct.IndexInfo.NameHash;
            var kEntry  = xStruct?.FindEntry(MetaName.Key);
            var iEntry  = xStruct?.FindEntry(MetaName.Item);

            if (kEntry.Type != PsoDataType.String)
            {
            }



            List <byte[]> nodesData = new List <byte[]>();

            foreach (XmlNode cnode in node.ChildNodes)
            {
                var kattr = cnode.Attributes["key"].Value;
                var tattr = cnode.Attributes["type"].Value;//CW invention for convenience..!
                var khash = (MetaName)(uint)GetHash(kattr);
                var thash = (MetaName)(uint)GetHash(tattr);

                byte[] strucBytes = Traverse(cnode, pb, thash);
                byte[] nodeBytes  = new byte[xStruct.StructureLength];

                TraverseStringRaw(kattr, pb, kEntry, nodeBytes); //write the key

                if (xName != (MetaName)MetaTypeName.ARRAYINFO)   // (mapreftype2.ReferenceKey != 0)
                {
                    //value struct embedded in ARRAYINFO node
                    Buffer.BlockCopy(strucBytes, 0, nodeBytes, iEntry.DataOffset, strucBytes.Length);
                }
                else
                {
                    //normal ARRAYINFO with pointer value
                    var itemptr = pb.AddItemPtr(thash, strucBytes);
                    itemptr.SwapEnd(); //big schmigg
                    var ptrbytes = MetaTypes.ConvertToBytes(itemptr);
                    Buffer.BlockCopy(ptrbytes, 0, nodeBytes, iEntry.DataOffset, ptrbytes.Length);
                }

                nodesData.Add(nodeBytes);
            }



            Write(0x1000000, data, entry.DataOffset);
            Write(0, data, entry.DataOffset + 4);

            arrayResults.Structures[entry.DataOffset + 8] = pb.AddItemArrayPtr(xName, nodesData.ToArray());  //pb.AddPointerArray(nodeptrs);
        }
예제 #7
0
        public PsoStructureInfo AddMapNodeStructureInfo(MetaName valType)
        {
            PsoStructureInfo inf = null;

            if (valType == 0)
            {
                inf = PsoTypes.GetStructureInfo((MetaName)MetaTypeName.ARRAYINFO); //default ARRAYINFO with pointer
                if (!StructureInfos.ContainsKey(inf.IndexInfo.NameHash))
                {
                    StructureInfos[inf.IndexInfo.NameHash] = inf;
                }
                return(inf);
            }

            var structInfo = PsoTypes.GetStructureInfo(valType);

            if (structInfo == null)
            {
            }  //error?

            MetaName xName  = (MetaName)MetaTypeName.ARRAYINFO + 1; //257
            bool     nameOk = !StructureInfos.ContainsKey(xName);

            while (!nameOk)
            {
                var exInfo     = StructureInfos[xName];
                var exInfoItem = exInfo.FindEntry(MetaName.Item);
                if (((MetaName)(exInfoItem?.ReferenceKey ?? 0) == valType))
                {
                    return(exInfo); //this one already exists.. use it!
                }
                xName++;
                nameOk = !StructureInfos.ContainsKey(xName);
            }



            inf = new PsoStructureInfo(xName, 0, 2, 8 + structInfo.StructureLength,
                                       new PsoStructureEntryInfo(MetaName.Key, PsoDataType.String, 0, 7, 0),
                                       new PsoStructureEntryInfo(MetaName.Item, PsoDataType.Structure, 8, 0, valType)
                                       );

            if (!StructureInfos.ContainsKey(xName))
            {
                StructureInfos[xName] = inf;
            }

            return(inf);


            //switch (valType)
            //{
            //    case MetaName.fwClipDictionaryMetadata: return PsoTypes.GetStructureInfo((MetaName)257);
            //    case MetaName.fwMemoryGroupMetadata: return PsoTypes.GetStructureInfo((MetaName)258);
            //    case (MetaName)3219912345: return PsoTypes.GetStructureInfo((MetaName)259);
            //    case (MetaName)0: return PsoTypes.GetStructureInfo((MetaName)MetaTypeName.ARRAYINFO);
            //    default:
            //        return PsoTypes.GetStructureInfo((MetaName)MetaTypeName.ARRAYINFO);//error?
            //}
            //case (MetaName)257:
            //    return new PsoStructureInfo((MetaName)257, 0, 2, 32,
            //     new PsoStructureEntryInfo(MetaName.Key, PsoDataType.String, 0, 7, 0),
            //     new PsoStructureEntryInfo(MetaName.Item, PsoDataType.Structure, 8, 0, MetaName.fwClipDictionaryMetadata)
            //    );
            //case (MetaName)258:
            //    return new PsoStructureInfo((MetaName)258, 0, 2, 24,
            //        new PsoStructureEntryInfo(MetaName.Key, PsoDataType.String, 0, 7, 0),
            //        new PsoStructureEntryInfo(MetaName.Item, PsoDataType.Structure, 8, 0, MetaName.fwMemoryGroupMetadata)
            //    );
            //case (MetaName)259:
            //    return new PsoStructureInfo((MetaName)259, 0, 2, 32,
            //        new PsoStructureEntryInfo(MetaName.Key, PsoDataType.String, 0, 7, 0),
            //        new PsoStructureEntryInfo(MetaName.Item, PsoDataType.Structure, 8, 0, (MetaName)3219912345)
            //    );
            //case (MetaName)3219912345:
            //    return new PsoStructureInfo((MetaName)3219912345, 0, 0, 24,
            //        new PsoStructureEntryInfo((MetaName)MetaTypeName.ARRAYINFO, PsoDataType.Structure, 0, 0, (MetaName)2356519750),
            //        new PsoStructureEntryInfo(MetaName.Adjustments, PsoDataType.Array, 8, 0, 0)
            //    );
        }