diff --git a/CodeWalker.csproj b/CodeWalker.csproj index 1025f1f..6183c66 100644 --- a/CodeWalker.csproj +++ b/CodeWalker.csproj @@ -275,6 +275,7 @@ + diff --git a/GameFiles/MetaTypes/Meta.cs b/GameFiles/MetaTypes/Meta.cs index 79250b5..7ee83cc 100644 --- a/GameFiles/MetaTypes/Meta.cs +++ b/GameFiles/MetaTypes/Meta.cs @@ -730,7 +730,6 @@ namespace CodeWalker.GameFiles Unk1 = 0; } - public void SwapEnd() { Pointer = MetaTypes.SwapBytes(Pointer); @@ -756,6 +755,23 @@ namespace CodeWalker.GameFiles public uint PointerDataIndex { get { return (Pointer & 0xFFF) - 1; } } public uint PointerDataOffset { get { return ((Pointer >> 12) & 0xFFFFF); } } + public Array_byte(uint ptr, int cnt) + { + Pointer = ptr; + Unk0 = 0; + Count1 = (ushort)cnt; + Count2 = Count1; + Unk1 = 0; + } + public Array_byte(MetaBuilderPointer ptr) + { + Pointer = ptr.Pointer; + Unk0 = 0; + Count1 = (ushort)ptr.Length; + Count2 = Count1; + Unk1 = 0; + } + public void SwapEnd() { Pointer = MetaTypes.SwapBytes(Pointer); @@ -781,6 +797,23 @@ namespace CodeWalker.GameFiles public uint PointerDataIndex { get { return (Pointer & 0xFFF) - 1; } } public uint PointerDataOffset { get { return ((Pointer >> 12) & 0xFFFFF); } } + public Array_float(uint ptr, int cnt) + { + Pointer = ptr; + Unk0 = 0; + Count1 = (ushort)cnt; + Count2 = Count1; + Unk1 = 0; + } + public Array_float(MetaBuilderPointer ptr) + { + Pointer = ptr.Pointer; + Unk0 = 0; + Count1 = (ushort)ptr.Length; + Count2 = Count1; + Unk1 = 0; + } + public void SwapEnd() { Pointer = MetaTypes.SwapBytes(Pointer); diff --git a/GameFiles/MetaTypes/MetaBuilder.cs b/GameFiles/MetaTypes/MetaBuilder.cs index 5903cc3..9c70545 100644 --- a/GameFiles/MetaTypes/MetaBuilder.cs +++ b/GameFiles/MetaTypes/MetaBuilder.cs @@ -35,8 +35,13 @@ namespace CodeWalker.GameFiles public MetaBuilderPointer AddItem(MetaName type, T item) where T : struct { - MetaBuilderBlock block = EnsureBlock(type); byte[] data = MetaTypes.ConvertToBytes(item); + return AddItem(type, data); + } + + public MetaBuilderPointer AddItem(MetaName type, byte[] data) + { + MetaBuilderBlock block = EnsureBlock(type); int brem = data.Length % 16; if (brem > 0) { @@ -52,10 +57,16 @@ namespace CodeWalker.GameFiles r.Length = data.Length; return r; } + public MetaBuilderPointer AddItemArray(MetaName type, T[] items) where T : struct { - MetaBuilderBlock block = EnsureBlock(type); byte[] data = MetaTypes.ConvertArrayToBytes(items); + return AddItemArray(type, data, items.Length); + } + + public MetaBuilderPointer AddItemArray(MetaName type, byte[] data, int length) + { + MetaBuilderBlock block = EnsureBlock(type); int datalen = data.Length; int newlen = datalen; int lenrem = newlen % 16; @@ -70,9 +81,10 @@ namespace CodeWalker.GameFiles MetaBuilderPointer r = new MetaBuilderPointer(); r.BlockID = block.Index + 1; r.Offset = offs; //(idx * data.Length);; - r.Length = items.Length; + r.Length = length; return r; } + public MetaBuilderPointer AddString(string str) { MetaBuilderBlock block = EnsureBlock(MetaName.STRING); @@ -100,12 +112,45 @@ namespace CodeWalker.GameFiles var ptr = AddItem(type, item); return new MetaPOINTER(ptr.BlockID, ptr.Offset, 0); } + + public MetaPOINTER AddItemPtr(MetaName type, byte[] data)//helper method for AddItem + { + var ptr = AddItem(type, data); + return new MetaPOINTER(ptr.BlockID, ptr.Offset, 0); + } + public Array_Structure AddItemArrayPtr(MetaName type, T[] items) where T : struct //helper method for AddItemArray { if ((items == null) || (items.Length == 0)) return new Array_Structure(); var ptr = AddItemArray(type, items); return new Array_Structure(ptr); } + + public Array_Structure AddItemArrayPtr(MetaName type, byte[][] data) //helper method for AddItemArray + { + if ((data == null) || (data.Length == 0)) return new Array_Structure(); + + int len = 0; + + for (int i = 0; i < data.Length; i++) + { + len += data[i].Length; + } + + var newdata = new byte[len]; + + int offset = 0; + + for (int i = 0; i < data.Length; i++) + { + Buffer.BlockCopy(data[i], 0, newdata, offset, data[i].Length); + offset += data[i].Length; + } + + var ptr = AddItemArray(type, newdata, data.Length); + return new Array_Structure(ptr); + } + public Array_Vector3 AddPaddedVector3ArrayPtr(SharpDX.Vector4[] items) { if ((items == null) || (items.Length == 0)) return new Array_Vector3(); @@ -121,7 +166,7 @@ namespace CodeWalker.GameFiles public Array_uint AddUintArrayPtr(uint[] items) { if ((items == null) || (items.Length == 0)) return new Array_uint(); - var ptr = AddItemArray(MetaName.HASH, items); + var ptr = AddItemArray(MetaName.UINT, items); return new Array_uint(ptr); } public Array_ushort AddUshortArrayPtr(ushort[] items) @@ -130,6 +175,18 @@ namespace CodeWalker.GameFiles var ptr = AddItemArray(MetaName.USHORT, items); return new Array_ushort(ptr); } + public Array_byte AddByteArrayPtr(byte[] items) + { + if ((items == null) || (items.Length == 0)) return new Array_byte(); + var ptr = AddItemArray(MetaName.BYTE, items); + return new Array_byte(ptr); + } + public Array_float AddFloatArrayPtr(float[] items) + { + if ((items == null) || (items.Length == 0)) return new Array_float(); + var ptr = AddItemArray(MetaName.FLOAT, items); + return new Array_float(ptr); + } public CharPointer AddStringPtr(string str) //helper method for AddString { var ptr = AddString(str); diff --git a/GameFiles/MetaTypes/MetaNames.cs b/GameFiles/MetaTypes/MetaNames.cs index cb05183..45fad0f 100644 --- a/GameFiles/MetaTypes/MetaNames.cs +++ b/GameFiles/MetaTypes/MetaNames.cs @@ -1428,8 +1428,6 @@ namespace CodeWalker.GameFiles RumbleDuration = 79170607, RUpOffset = 3943427752, SAT_NONE = 836773056, - scale = 1342385372, - Scale = 1018839014, SCALEFORM_DLC_FILE = 258049916, ScaleRange = 2691059430, ScaleRangeXYZ = 4267248400, @@ -2929,7 +2927,10 @@ namespace CodeWalker.GameFiles sampFiltered = 200703167, sampleAngle = 1030071922, sampleScale = 65527032, - Scale_ = 1342385372, + Scale_ = 116180525, + scale_ = 3279249823, + Scale = 1018839014, + scale = 1342385372, ScaleIn = 1489667163, scalerLum = 1241172112, ScanlineFilterParams = 3994711222, diff --git a/GameFiles/MetaTypes/MetaTypes.cs b/GameFiles/MetaTypes/MetaTypes.cs index bc8d99f..585e51c 100644 --- a/GameFiles/MetaTypes/MetaTypes.cs +++ b/GameFiles/MetaTypes/MetaTypes.cs @@ -255,6 +255,12 @@ namespace CodeWalker.GameFiles { /* YMAP types */ + case MetaName.VECTOR3: + return new MetaStructureInfo(MetaName.VECTOR3, 2751397072, 512, 12, + new MetaStructureEntryInfo_s(MetaName.x, 0, MetaStructureEntryDataType.Float, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.y, 4, MetaStructureEntryDataType.Float, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.z, 8, MetaStructureEntryDataType.Float, 0, 0, 0) + ); case MetaName.rage__fwInstancedMapData: return new MetaStructureInfo(MetaName.rage__fwInstancedMapData, 1836780118, 768, 48, new MetaStructureEntryInfo_s(MetaName.ImapLink, 8, MetaStructureEntryDataType.Hash, 0, 0, 0), @@ -263,6 +269,36 @@ namespace CodeWalker.GameFiles new MetaStructureEntryInfo_s(MetaName.ARRAYINFO, 0, MetaStructureEntryDataType.Structure, 0, 0, MetaName.rage__fwGrassInstanceListDef), new MetaStructureEntryInfo_s(MetaName.GrassInstanceList, 32, MetaStructureEntryDataType.Array, 0, 3, 0) ); + case MetaName.rage__fwGrassInstanceListDef: + return new MetaStructureInfo(MetaName.rage__fwGrassInstanceListDef, 941808164, 1024, 96, + new MetaStructureEntryInfo_s(MetaName.BatchAABB, 0, MetaStructureEntryDataType.Structure, 0, 0, MetaName.rage__spdAABB), + new MetaStructureEntryInfo_s(MetaName.ScaleRange, 32, MetaStructureEntryDataType.Float_XYZ, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.archetypeName, 48, MetaStructureEntryDataType.Hash, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.lodDist, 52, MetaStructureEntryDataType.UnsignedInt, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.LodFadeStartDist, 56, MetaStructureEntryDataType.Float, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.LodInstFadeRange, 60, MetaStructureEntryDataType.Float, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.OrientToTerrain, 64, MetaStructureEntryDataType.Float, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.ARRAYINFO, 0, MetaStructureEntryDataType.Structure, 0, 0, MetaName.rage__fwGrassInstanceListDef__InstanceData), + new MetaStructureEntryInfo_s(MetaName.InstanceList, 72, MetaStructureEntryDataType.Array, 36, 7, 0) + ); + case MetaName.rage__fwGrassInstanceListDef__InstanceData: + return new MetaStructureInfo(MetaName.rage__fwGrassInstanceListDef__InstanceData, 2740378365, 256, 16, + new MetaStructureEntryInfo_s(MetaName.ARRAYINFO, 0, MetaStructureEntryDataType.UnsignedShort, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.Position, 0, MetaStructureEntryDataType.ArrayOfBytes, 0, 0, (MetaName)3), + new MetaStructureEntryInfo_s(MetaName.NormalX, 6, MetaStructureEntryDataType.UnsignedByte, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.NormalY, 7, MetaStructureEntryDataType.UnsignedByte, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.ARRAYINFO, 0, MetaStructureEntryDataType.UnsignedByte, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.Color, 8, MetaStructureEntryDataType.ArrayOfBytes, 0, 4, (MetaName)3), + new MetaStructureEntryInfo_s(MetaName.Scale, 11, MetaStructureEntryDataType.UnsignedByte, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.Ao, 12, MetaStructureEntryDataType.UnsignedByte, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.ARRAYINFO, 0, MetaStructureEntryDataType.UnsignedByte, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.Pad, 13, MetaStructureEntryDataType.ArrayOfBytes, 0, 8, (MetaName)3) + ); + case MetaName.rage__spdAABB: + return new MetaStructureInfo(MetaName.rage__spdAABB, 1158138379, 1024, 32, + new MetaStructureEntryInfo_s(MetaName.min, 0, MetaStructureEntryDataType.Float_XYZW, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.max, 16, MetaStructureEntryDataType.Float_XYZW, 0, 0, 0) + ); case MetaName.CLODLight: return new MetaStructureInfo(MetaName.CLODLight, 2325189228, 768, 136, new MetaStructureEntryInfo_s(MetaName.ARRAYINFO, 0, MetaStructureEntryDataType.Structure, 0, 0, MetaName.VECTOR3), @@ -377,6 +413,132 @@ namespace CodeWalker.GameFiles new MetaStructureEntryInfo_s(MetaName.numExitPortals, 152, MetaStructureEntryDataType.UnsignedInt, 0, 0, 0), new MetaStructureEntryInfo_s(MetaName.MLOInstflags, 156, MetaStructureEntryDataType.UnsignedInt, 0, 0, 0) ); + case MetaName.CMloPortalDef: + return new MetaStructureInfo(MetaName.CMloPortalDef, 1110221513, 768, 64, + new MetaStructureEntryInfo_s(MetaName.roomFrom, 8, MetaStructureEntryDataType.UnsignedInt, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.roomTo, 12, MetaStructureEntryDataType.UnsignedInt, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.flags, 16, MetaStructureEntryDataType.UnsignedInt, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.mirrorPriority, 20, MetaStructureEntryDataType.UnsignedInt, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.opacity, 24, MetaStructureEntryDataType.UnsignedInt, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.audioOcclusion, 28, MetaStructureEntryDataType.UnsignedInt, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.ARRAYINFO, 0, MetaStructureEntryDataType.Float_XYZ, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.corners, 32, MetaStructureEntryDataType.Array, 0, 6, 0), + new MetaStructureEntryInfo_s(MetaName.ARRAYINFO, 0, MetaStructureEntryDataType.UnsignedInt, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.attachedObjects, 48, MetaStructureEntryDataType.Array, 0, 8, 0) + ); + case MetaName.CMapTypes: + return new MetaStructureInfo(MetaName.CMapTypes, 2608875220, 768, 80, + new MetaStructureEntryInfo_s(MetaName.ARRAYINFO, 0, MetaStructureEntryDataType.StructurePointer, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.extensions, 8, MetaStructureEntryDataType.Array, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.ARRAYINFO, 0, MetaStructureEntryDataType.StructurePointer, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.archetypes, 24, MetaStructureEntryDataType.Array, 0, 2, 0), + new MetaStructureEntryInfo_s(MetaName.name, 40, MetaStructureEntryDataType.Hash, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.ARRAYINFO, 0, MetaStructureEntryDataType.Hash, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.dependencies, 48, MetaStructureEntryDataType.Array, 0, 5, 0), + new MetaStructureEntryInfo_s(MetaName.ARRAYINFO, 0, MetaStructureEntryDataType.Structure, 0, 0, MetaName.CCompositeEntityType), + new MetaStructureEntryInfo_s(MetaName.compositeEntityTypes, 64, MetaStructureEntryDataType.Array, 0, 7, 0) + ); + case MetaName.CBaseArchetypeDef: + return new MetaStructureInfo(MetaName.CBaseArchetypeDef, 2411387556, 1024, 144, + new MetaStructureEntryInfo_s(MetaName.lodDist, 8, MetaStructureEntryDataType.Float, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.flags, 12, MetaStructureEntryDataType.UnsignedInt, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.specialAttribute, 16, MetaStructureEntryDataType.UnsignedInt, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.bbMin, 32, MetaStructureEntryDataType.Float_XYZ, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.bbMax, 48, MetaStructureEntryDataType.Float_XYZ, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.bsCentre, 64, MetaStructureEntryDataType.Float_XYZ, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.bsRadius, 80, MetaStructureEntryDataType.Float, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.hdTextureDist, 84, MetaStructureEntryDataType.Float, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.name, 88, MetaStructureEntryDataType.Hash, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.textureDictionary, 92, MetaStructureEntryDataType.Hash, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.clipDictionary, 96, MetaStructureEntryDataType.Hash, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.drawableDictionary, 100, MetaStructureEntryDataType.Hash, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.physicsDictionary, 104, MetaStructureEntryDataType.Hash, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.assetType, 108, MetaStructureEntryDataType.IntEnum, 0, 0, (MetaName)1991964615), + new MetaStructureEntryInfo_s(MetaName.assetName, 112, MetaStructureEntryDataType.Hash, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.ARRAYINFO, 0, MetaStructureEntryDataType.StructurePointer, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.extensions, 120, MetaStructureEntryDataType.Array, 0, 15, 0) + ); + case MetaName.CExtensionDefParticleEffect: + return new MetaStructureInfo(MetaName.CExtensionDefParticleEffect, 466596385, 1024, 96, + new MetaStructureEntryInfo_s(MetaName.name, 8, MetaStructureEntryDataType.Hash, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.offsetPosition, 16, MetaStructureEntryDataType.Float_XYZ, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.offsetRotation, 32, MetaStructureEntryDataType.Float_XYZW, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.fxName, 48, MetaStructureEntryDataType.CharPointer, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.fxType, 64, MetaStructureEntryDataType.SignedInt, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.boneTag, 68, MetaStructureEntryDataType.SignedInt, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.Scale_, 72, MetaStructureEntryDataType.Float, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.probability, 76, MetaStructureEntryDataType.SignedInt, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.flags, 80, MetaStructureEntryDataType.SignedInt, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.color, 84, MetaStructureEntryDataType.UnsignedInt, 0, 0, 0) + ); + case MetaName.CMloArchetypeDef: + return new MetaStructureInfo(MetaName.CMloArchetypeDef, 937664754, 1024, 240, + new MetaStructureEntryInfo_s(MetaName.lodDist, 8, MetaStructureEntryDataType.Float, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.flags, 12, MetaStructureEntryDataType.UnsignedInt, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.specialAttribute, 16, MetaStructureEntryDataType.UnsignedInt, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.bbMin, 32, MetaStructureEntryDataType.Float_XYZ, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.bbMax, 48, MetaStructureEntryDataType.Float_XYZ, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.bsCentre, 64, MetaStructureEntryDataType.Float_XYZ, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.bsRadius, 80, MetaStructureEntryDataType.Float, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.hdTextureDist, 84, MetaStructureEntryDataType.Float, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.name, 88, MetaStructureEntryDataType.Hash, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.textureDictionary, 92, MetaStructureEntryDataType.Hash, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.clipDictionary, 96, MetaStructureEntryDataType.Hash, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.drawableDictionary, 100, MetaStructureEntryDataType.Hash, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.physicsDictionary, 104, MetaStructureEntryDataType.Hash, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.assetType, 108, MetaStructureEntryDataType.IntEnum, 0, 0, (MetaName)1991964615), + new MetaStructureEntryInfo_s(MetaName.assetName, 112, MetaStructureEntryDataType.Hash, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.ARRAYINFO, 0, MetaStructureEntryDataType.StructurePointer, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.extensions, 120, MetaStructureEntryDataType.Array, 0, 15, 0), + new MetaStructureEntryInfo_s(MetaName.mloFlags, 144, MetaStructureEntryDataType.UnsignedInt, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.ARRAYINFO, 0, MetaStructureEntryDataType.StructurePointer, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.entities, 152, MetaStructureEntryDataType.Array, 0, 18, 0), + new MetaStructureEntryInfo_s(MetaName.ARRAYINFO, 0, MetaStructureEntryDataType.Structure, 0, 0, MetaName.CMloRoomDef), + new MetaStructureEntryInfo_s(MetaName.rooms, 168, MetaStructureEntryDataType.Array, 0, 20, 0), + new MetaStructureEntryInfo_s(MetaName.ARRAYINFO, 0, MetaStructureEntryDataType.Structure, 0, 0, MetaName.CMloPortalDef), + new MetaStructureEntryInfo_s(MetaName.portals, 184, MetaStructureEntryDataType.Array, 0, 22, 0), + new MetaStructureEntryInfo_s(MetaName.ARRAYINFO, 0, MetaStructureEntryDataType.Structure, 0, 0, MetaName.CMloEntitySet), + new MetaStructureEntryInfo_s(MetaName.entitySets, 200, MetaStructureEntryDataType.Array, 0, 24, 0), + new MetaStructureEntryInfo_s(MetaName.ARRAYINFO, 0, MetaStructureEntryDataType.Structure, 0, 0, MetaName.CMloTimeCycleModifier), + new MetaStructureEntryInfo_s(MetaName.timeCycleModifiers, 216, MetaStructureEntryDataType.Array, 0, 26, 0) + ); + case MetaName.CMloRoomDef: + return new MetaStructureInfo(MetaName.CMloRoomDef, 3885428245, 1024, 112, + new MetaStructureEntryInfo_s(MetaName.name, 8, MetaStructureEntryDataType.CharPointer, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.bbMin, 32, MetaStructureEntryDataType.Float_XYZ, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.bbMax, 48, MetaStructureEntryDataType.Float_XYZ, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.blend, 64, MetaStructureEntryDataType.Float, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.timecycleName, 68, MetaStructureEntryDataType.Hash, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.secondaryTimecycleName, 72, MetaStructureEntryDataType.Hash, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.flags, 76, MetaStructureEntryDataType.UnsignedInt, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.portalCount, 80, MetaStructureEntryDataType.UnsignedInt, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.floorId, 84, MetaStructureEntryDataType.SignedInt, 0, 0, 0), + new MetaStructureEntryInfo_s((MetaName)552849982, 88, MetaStructureEntryDataType.SignedInt, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.ARRAYINFO, 0, MetaStructureEntryDataType.UnsignedInt, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.attachedObjects, 96, MetaStructureEntryDataType.Array, 0, 10, 0) + ); + case MetaName.CTimeArchetypeDef: + return new MetaStructureInfo(MetaName.CTimeArchetypeDef, 2520619910, 1024, 160, + new MetaStructureEntryInfo_s(MetaName.lodDist, 8, MetaStructureEntryDataType.Float, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.flags, 12, MetaStructureEntryDataType.UnsignedInt, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.specialAttribute, 16, MetaStructureEntryDataType.UnsignedInt, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.bbMin, 32, MetaStructureEntryDataType.Float_XYZ, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.bbMax, 48, MetaStructureEntryDataType.Float_XYZ, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.bsCentre, 64, MetaStructureEntryDataType.Float_XYZ, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.bsRadius, 80, MetaStructureEntryDataType.Float, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.hdTextureDist, 84, MetaStructureEntryDataType.Float, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.name, 88, MetaStructureEntryDataType.Hash, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.textureDictionary, 92, MetaStructureEntryDataType.Hash, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.clipDictionary, 96, MetaStructureEntryDataType.Hash, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.drawableDictionary, 100, MetaStructureEntryDataType.Hash, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.physicsDictionary, 104, MetaStructureEntryDataType.Hash, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.assetType, 108, MetaStructureEntryDataType.IntEnum, 0, 0, (MetaName)1991964615), + new MetaStructureEntryInfo_s(MetaName.assetName, 112, MetaStructureEntryDataType.Hash, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.ARRAYINFO, 0, MetaStructureEntryDataType.StructurePointer, 0, 0, 0), + new MetaStructureEntryInfo_s(MetaName.extensions, 120, MetaStructureEntryDataType.Array, 0, 15, 0), + new MetaStructureEntryInfo_s(MetaName.timeFlags, 144, MetaStructureEntryDataType.UnsignedInt, 0, 0, 0) + ); + case MetaName.CTimeCycleModifier: return new MetaStructureInfo(MetaName.CTimeCycleModifier, 2683420777, 1024, 64, new MetaStructureEntryInfo_s(MetaName.name, 8, MetaStructureEntryDataType.Hash, 0, 0, 0), @@ -741,6 +903,14 @@ namespace CodeWalker.GameFiles new MetaEnumEntryInfo_s((MetaName)3717649022, 14), new MetaEnumEntryInfo_s((MetaName)3356026130, 15) ); + case (MetaName)1991964615: + return new MetaEnumInfo((MetaName)1991964615, 1866031916, + new MetaEnumEntryInfo_s(MetaName.ASSET_TYPE_UNINITIALIZED, 0), + new MetaEnumEntryInfo_s(MetaName.ASSET_TYPE_FRAGMENT, 1), + new MetaEnumEntryInfo_s(MetaName.ASSET_TYPE_DRAWABLE, 2), + new MetaEnumEntryInfo_s(MetaName.ASSET_TYPE_DRAWABLEDICTIONARY, 3), + new MetaEnumEntryInfo_s(MetaName.ASSET_TYPE_ASSETLESS, 4) + ); default: diff --git a/GameFiles/MetaTypes/XmlMeta.cs b/GameFiles/MetaTypes/XmlMeta.cs new file mode 100644 index 0000000..f0a8693 --- /dev/null +++ b/GameFiles/MetaTypes/XmlMeta.cs @@ -0,0 +1,665 @@ +using System; +using System.Collections.Generic; +using System.Text.RegularExpressions; +using System.Xml; +using SharpDX; + +namespace CodeWalker.GameFiles +{ + class XmlMeta + { + public static Meta GetMeta(XmlDocument doc) + { + MetaBuilder mb = new MetaBuilder(); + + Traverse(doc.DocumentElement, mb, 0, true); + + var meta = mb.GetMeta(); + + return meta; + } + + private static byte[] Traverse(XmlNode node, MetaBuilder mb, MetaName type = 0, bool isRoot = false) + { + if(type == 0) + { + type = (MetaName)(uint)GetHash(node.Name); + } + + var infos = MetaTypes.GetStructureInfo(type); + + if (infos != null) + { + byte[] data = new byte[infos.StructureSize]; + var arrayResults = new ArrayResults(); + + arrayResults.Structures = new Dictionary(); + arrayResults.StructurePointers = new Dictionary(); + arrayResults.UInts = new Dictionary(); + arrayResults.UShorts = new Dictionary(); + arrayResults.UBytes = new Dictionary(); + arrayResults.Floats = new Dictionary(); + arrayResults.Float_XYZs = new Dictionary(); + arrayResults.Hashes = new Dictionary(); + + Array.Clear(data, 0, infos.StructureSize); + + MetaStructureEntryInfo_s arrEntry = new MetaStructureEntryInfo_s(); + + if (isRoot) + { + mb.EnsureBlock(type); + } + + for (int i = 0; i < infos.Entries.Length; i++) + { + var entry = infos.Entries[i]; + + var cnode = GetEntryNode(node.ChildNodes, entry); + + if (entry.EntryNameHash == MetaName.ARRAYINFO) + { + arrEntry = entry; + continue; + } + + if (cnode == null) + { + continue; + } + + switch (entry.DataType) + { + case MetaStructureEntryDataType.Array: + { + TraverseArray(cnode, mb, arrEntry, entry.DataOffset, arrayResults); + break; + } + + case MetaStructureEntryDataType.ArrayOfBytes: + case MetaStructureEntryDataType.ArrayOfChars: + { + int offset = entry.DataOffset; + var split = Split(cnode.InnerText, 2); + + for (int j = 0; j < split.Length; j++) + { + byte val = Convert.ToByte(split[j], 16); + data[offset] = val; + offset += sizeof(byte); + } + + break; + } + + case MetaStructureEntryDataType.Boolean: + { + byte val = (cnode.Attributes["value"].Value == "false") ? (byte)0 : (byte)1; + data[entry.DataOffset] = val; + break; + } + + case MetaStructureEntryDataType.ByteEnum: + { + byte val = Convert.ToByte(cnode.Attributes["value"].Value); + data[entry.DataOffset] = val; + break; + } + + + case MetaStructureEntryDataType.CharPointer: + { + if (!string.IsNullOrEmpty(cnode.InnerText)) + { + var ptr = mb.AddStringPtr(cnode.InnerText); + var val = MetaTypes.ConvertToBytes(ptr); + + Buffer.BlockCopy(val, 0, data, entry.DataOffset, val.Length); + } + + break; + } + + case MetaStructureEntryDataType.DataBlockPointer: + { + // TODO + break; + } + + case MetaStructureEntryDataType.Float: + { + float val = FloatUtil.Parse(cnode.Attributes["value"].Value); + Write(val, data, entry.DataOffset); + break; + } + + case MetaStructureEntryDataType.Float_XYZ: + { + float x = FloatUtil.Parse(cnode.Attributes["x"].Value); + float y = FloatUtil.Parse(cnode.Attributes["y"].Value); + float z = FloatUtil.Parse(cnode.Attributes["z"].Value); + + Write(x, data, entry.DataOffset); + Write(y, data, entry.DataOffset + sizeof(float)); + Write(z, data, entry.DataOffset + sizeof(float) * 2); + + break; + } + + + case MetaStructureEntryDataType.Float_XYZW: + { + float x = FloatUtil.Parse(cnode.Attributes["x"].Value); + float y = FloatUtil.Parse(cnode.Attributes["y"].Value); + float z = FloatUtil.Parse(cnode.Attributes["z"].Value); + float w = FloatUtil.Parse(cnode.Attributes["w"].Value); + + Write(x, data, entry.DataOffset); + Write(y, data, entry.DataOffset + sizeof(float)); + Write(z, data, entry.DataOffset + sizeof(float) * 2); + Write(w, data, entry.DataOffset + sizeof(float) * 3); + + break; + } + + case MetaStructureEntryDataType.Hash: + { + var hash = GetHash(cnode.InnerText); + Write(hash, data, entry.DataOffset); + break; + } + + case MetaStructureEntryDataType.IntEnum: + case MetaStructureEntryDataType.IntFlags1: + case MetaStructureEntryDataType.IntFlags2: + { + var _infos = MetaTypes.GetEnumInfo(entry.ReferenceKey); + + mb.AddEnumInfo(_infos.EnumNameHash); + + int val = GetEnumInt(entry.ReferenceKey, cnode.InnerText); + Write(val, data, entry.DataOffset); + break; + } + + case MetaStructureEntryDataType.ShortFlags: + { + var _infos = MetaTypes.GetEnumInfo(entry.ReferenceKey); + + mb.AddEnumInfo(_infos.EnumNameHash); + + int val = GetEnumInt(entry.ReferenceKey, cnode.InnerText); + Write((short)val, data, entry.DataOffset); + break; + } + + case MetaStructureEntryDataType.SignedByte: + { + var val = Convert.ToSByte(cnode.Attributes["value"].Value); + data[entry.DataOffset] = (byte)val; + break; + } + + case MetaStructureEntryDataType.SignedInt: + { + var val = Convert.ToInt32(cnode.Attributes["value"].Value); + Write(val, data, entry.DataOffset); + break; + } + + case MetaStructureEntryDataType.SignedShort: + { + var val = Convert.ToInt16(cnode.Attributes["value"].Value); + Write(val, data, entry.DataOffset); + break; + } + + case MetaStructureEntryDataType.Structure: + { + var struc = Traverse(cnode, mb, entry.ReferenceKey); + + if(struc != null) + { + Buffer.BlockCopy(struc, 0, data, entry.DataOffset, struc.Length); + } + + break; + } + + case MetaStructureEntryDataType.StructurePointer: + { + // TODO + break; + } + + case MetaStructureEntryDataType.UnsignedByte: + { + var val = Convert.ToByte(cnode.Attributes["value"].Value); + data[entry.DataOffset] = val; + break; + } + + case MetaStructureEntryDataType.UnsignedInt: + { + switch (entry.EntryNameHash) + { + case MetaName.color: + { + var val = Convert.ToUInt32(cnode.Attributes["value"].Value, 16); + Write(val, data, entry.DataOffset); + break; + } + + default: + { + var val = Convert.ToUInt32(cnode.Attributes["value"].Value); + Write(val, data, entry.DataOffset); + break; + } + } + + break; + } + + case MetaStructureEntryDataType.UnsignedShort: + { + var val = Convert.ToUInt16(cnode.Attributes["value"].Value); + Write(val, data, entry.DataOffset); + break; + } + + default: break; + + } + } + + arrayResults.WriteArrays(data); + + mb.AddStructureInfo(infos.StructureNameHash); + + if (isRoot) + { + mb.AddItem(type, data); + } + + return data; + } + + return null; + } + + private static void TraverseArray(XmlNode node, MetaBuilder mb, MetaStructureEntryInfo_s arrEntry, int offset, ArrayResults results) + { + switch (arrEntry.DataType) + { + case MetaStructureEntryDataType.Structure: + { + results.Structures[offset] = TraverseArrayStructure(node, mb, arrEntry.ReferenceKey); + break; + } + + case MetaStructureEntryDataType.StructurePointer: + { + results.StructurePointers[offset] = TraverseArrayStructurePointer(node, mb); + break; + } + + case MetaStructureEntryDataType.UnsignedInt: + { + results.UInts[offset] = TraverseRawUIntArray(node, mb); + break; + } + case MetaStructureEntryDataType.UnsignedShort: + { + results.UShorts[offset] = TraverseRawUShortArray(node, mb); + break; + } + case MetaStructureEntryDataType.UnsignedByte: + { + results.UBytes[offset] = TraverseRawUByteArray(node, mb); + break; + } + case MetaStructureEntryDataType.Float: + { + results.Floats[offset] = TraverseRawFloatArray(node, mb); + break; + } + case MetaStructureEntryDataType.Float_XYZ: + { + results.Float_XYZs[offset] = TraverseRawVector3Array(node, mb); + break; + } + case MetaStructureEntryDataType.Hash: + { + results.Hashes[offset] = TraverseHashArray(node, mb); + break; + } + case MetaStructureEntryDataType.CharPointer: + { + // TODO + break; + } + case MetaStructureEntryDataType.DataBlockPointer: + { + // TODO + break; + } + + default: break; + } + + } + + private static Array_Structure TraverseArrayStructure(XmlNode node, MetaBuilder mb, MetaName type) + { + var strucs = new List(); + + foreach (XmlNode cnode in node.ChildNodes) + { + var struc = Traverse(cnode, mb, type); + + if (struc != null) + { + strucs.Add(struc); + } + } + + return mb.AddItemArrayPtr(type, strucs.ToArray()); + } + + private static Array_StructurePointer TraverseArrayStructurePointer(XmlNode node, MetaBuilder mb) + { + var ptrs = new List(); + + foreach (XmlNode cnode in node.ChildNodes) + { + var type = (MetaName)(uint)GetHash(cnode.Attributes["type"].Value); + var struc = Traverse(cnode, mb, type); + + if(struc != null) + { + var ptr = mb.AddItemPtr(type, struc); + ptrs.Add(ptr); + } + + } + + return mb.AddPointerArray(ptrs.ToArray()); + + } + + private static Array_uint TraverseRawUIntArray(XmlNode node, MetaBuilder mb) + { + var data = new List(); + + if (node.InnerText != "") + { + var split = Regex.Split(node.InnerText, @"[\s\r\n\t]"); + + for (int i = 0; i < split.Length; i++) + { + if(!string.IsNullOrEmpty(split[i])) + { + var val = Convert.ToUInt32(split[i]); + data.Add(val); + } + + } + } + + return mb.AddUintArrayPtr(data.ToArray()); + } + + private static Array_ushort TraverseRawUShortArray(XmlNode node, MetaBuilder mb) + { + var data = new List(); + + if (node.InnerText != "") + { + var split = Regex.Split(node.InnerText, @"[\s\r\n\t]"); + + for (int i = 0; i < split.Length; i++) + { + if (!string.IsNullOrEmpty(split[i])) + { + var val = Convert.ToUInt16(split[i]); + data.Add(val); + } + } + } + + return mb.AddUshortArrayPtr(data.ToArray()); + } + + private static Array_byte TraverseRawUByteArray(XmlNode node, MetaBuilder mb) + { + var data = new List(); + + if (node.InnerText != "") + { + var split = Regex.Split(node.InnerText, @"[\s\r\n\t]"); + + for (int i = 0; i < split.Length; i++) + { + if (!string.IsNullOrEmpty(split[i])) + { + var val = Convert.ToByte(split[i]); + data.Add(val); + } + } + } + + return mb.AddByteArrayPtr(data.ToArray()); + } + + private static Array_float TraverseRawFloatArray(XmlNode node, MetaBuilder mb) + { + var data = new List(); + + if(node.InnerText != "") + { + var split = Regex.Split(node.InnerText, @"[\s\r\n\t]"); + + for (int i = 0; i < split.Length; i++) + { + if (!string.IsNullOrEmpty(split[i])) + { + var val = Convert.ToSingle(split[i]); + data.Add(val); + } + } + } + + return mb.AddFloatArrayPtr(data.ToArray()); + } + + private static Array_Vector3 TraverseRawVector3Array(XmlNode node, MetaBuilder mb) + { + var items = new List(); + + foreach (XmlNode cnode in node.ChildNodes) + { + + var split = Regex.Split(node.InnerText, @",\s"); + + float x = FloatUtil.Parse(split[0]); + float y = FloatUtil.Parse(split[1]); + float z = FloatUtil.Parse(split[2]); + float w = 0f; + + var val = new Vector4(x, y, z, w); + + items.Add(val); + break; + } + + return mb.AddPaddedVector3ArrayPtr(items.ToArray()); + } + + private static Array_uint TraverseHashArray(XmlNode node, MetaBuilder mb) + { + var items = new List(); + + foreach (XmlNode cnode in node.ChildNodes) + { + var val = GetHash(cnode.InnerText); + items.Add(val); + } + + return mb.AddHashArrayPtr(items.ToArray()); + } + + private static void Write(int val, byte[] data, int offset) + { + byte[] bytes = BitConverter.GetBytes(val); + Buffer.BlockCopy(bytes, 0, data, offset, sizeof(int)); + } + + private static void Write(uint val, byte[] data, int offset) + { + byte[] bytes = BitConverter.GetBytes(val); + Buffer.BlockCopy(bytes, 0, data, offset, sizeof(uint)); + } + + private static void Write(short val, byte[] data, int offset) + { + byte[] bytes = BitConverter.GetBytes(val); + Buffer.BlockCopy(bytes, 0, data, offset, sizeof(short)); + } + + private static void Write(ushort val, byte[] data, int offset) + { + byte[] bytes = BitConverter.GetBytes(val); + Buffer.BlockCopy(bytes, 0, data, offset, sizeof(ushort)); + } + + private static void Write(float val, byte[] data, int offset) + { + byte[] bytes = BitConverter.GetBytes(val); + Buffer.BlockCopy(bytes, 0, data, offset, sizeof(float)); + } + + private static MetaHash GetHash(string str) + { + if (str.StartsWith("hash_")) + { + return (MetaHash) Convert.ToUInt32(str.Substring(5), 16); + } + else + { + return JenkHash.GenHash(str); + } + } + + private static XmlNode GetEntryNode(XmlNodeList nodes, MetaStructureEntryInfo_s entry) + { + foreach (XmlNode node in nodes) + { + if (GetHash(node.Name) == (uint)entry.EntryNameHash) + { + return node; + } + } + + return null; + } + + private static string[] Split(string str, int maxChunkSize) + { + var chunks = new List(); + + for (int i = 0; i < str.Length; i += maxChunkSize) + { + chunks.Add(str.Substring(i, Math.Min(maxChunkSize, str.Length - i))); + } + + return chunks.ToArray(); + } + + private static int GetEnumInt(MetaName type, string enumString) + { + var enumName = (MetaName)(uint)GetHash(enumString); + var infos = MetaTypes.GetEnumInfo(type); + + if (infos == null) + { + return 0; + } + + for (int j = 0; j < infos.Entries.Length; j++) + { + var entry = infos.Entries[j]; + + if (entry.EntryNameHash == enumName) + { + return entry.EntryValue; + } + } + + return 0; + } + } + + struct ArrayResults + { + public Dictionary Structures; + public Dictionary StructurePointers; + public Dictionary UInts; + public Dictionary UShorts; + public Dictionary UBytes; + public Dictionary Floats; + public Dictionary Float_XYZs; + public Dictionary Hashes; + + public void WriteArrays(byte[] data) + { + foreach (KeyValuePair ptr in Structures) + { + var _data = MetaTypes.ConvertToBytes(ptr.Value); + Buffer.BlockCopy(_data, 0, data, ptr.Key, _data.Length); + } + + foreach (KeyValuePair ptr in StructurePointers) + { + var _data = MetaTypes.ConvertToBytes(ptr.Value); + Buffer.BlockCopy(_data, 0, data, ptr.Key, _data.Length); + } + + foreach (KeyValuePair ptr in UInts) + { + var _data = MetaTypes.ConvertToBytes(ptr.Value); + Buffer.BlockCopy(_data, 0, data, ptr.Key, _data.Length); + } + + foreach (KeyValuePair ptr in UShorts) + { + var _data = MetaTypes.ConvertToBytes(ptr.Value); + Buffer.BlockCopy(_data, 0, data, ptr.Key, _data.Length); + } + + foreach (KeyValuePair ptr in UBytes) + { + var _data = MetaTypes.ConvertToBytes(ptr.Value); + Buffer.BlockCopy(_data, 0, data, ptr.Key, _data.Length); + } + + foreach (KeyValuePair ptr in Floats) + { + var _data = MetaTypes.ConvertToBytes(ptr.Value); + Buffer.BlockCopy(_data, 0, data, ptr.Key, _data.Length); + } + + foreach (KeyValuePair ptr in Float_XYZs) + { + var _data = MetaTypes.ConvertToBytes(ptr.Value); + Buffer.BlockCopy(_data, 0, data, ptr.Key, _data.Length); + } + + foreach (KeyValuePair ptr in Hashes) + { + var _data = MetaTypes.ConvertToBytes(ptr.Value); + Buffer.BlockCopy(_data, 0, data, ptr.Key, _data.Length); + } + } + } +}