Пример #1
0
        public MetaBuilderPointer AddItemArray <T>(MetaName type, T[] items) where T : struct
        {
            MetaBuilderBlock block = EnsureBlock(type);

            byte[] data    = MetaTypes.ConvertArrayToBytes(items);
            int    datalen = data.Length;
            int    newlen  = datalen;
            int    lenrem  = newlen % 16;

            if (lenrem != 0)
            {
                newlen += (16 - lenrem);
            }
            byte[] newdata = new byte[newlen];
            Buffer.BlockCopy(data, 0, newdata, 0, datalen);
            int offs             = block.TotalSize / 16;
            int idx              = block.AddItem(newdata);
            MetaBuilderPointer r = new MetaBuilderPointer();

            r.Block  = block.Index + 1;
            r.Offset = offs; //(idx * data.Length) / 16;
            r.Length = items.Length;
            return(r);
        }
Пример #2
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
                {
                }
            }
        }
Пример #3
0
 public PsoBuilderPointer AddItemArray <T>(MetaName type, T[] items) where T : struct
 {
     byte[] data = MetaTypes.ConvertArrayToBytes(items);
     return(AddItemArray(type, data, items.Length));
 }
Пример #4
0
 public override void Write(ResourceDataWriter writer, params object[] parameters)
 {
     byte[] data = MetaTypes.ConvertArrayToBytes(Items);
     writer.Write(data);
 }