public static Dna Load(BulletReader dnaReader, bool swap) { var dna = new Dna(); dna.Init(dnaReader, swap); return(dna); }
public void InitCmpFlags(Dna memoryDna) { // compare the file to memory // this ptr should be the file data Debug.Assert(_names.Length != 0); // SDNA empty! _cmpFlags = new FileDnaFlags[_structs.Length]; for (int i = 0; i < _structs.Length; i++) { Dna.StructDecl oldStruct = _structs[i]; int oldLookup = GetReverseType(oldStruct.Type.Name); if (oldLookup == -1) { _cmpFlags[i] = FileDnaFlags.None; continue; } if (oldLookup < memoryDna._structs.Length) { Dna.StructDecl curStruct = memoryDna.GetStruct(oldLookup); _cmpFlags[i] = oldStruct.Equals(curStruct) ? FileDnaFlags.StructEqual : FileDnaFlags.StructNotEqual; } } // Recurse in for (int i = 0; i < _structs.Length; i++) { if (_cmpFlags[i] == FileDnaFlags.StructNotEqual) { InitRecurseCmpFlags(_structs[i]); } } }
private void InitDna() { _dnaData = IntPtr.Size == 8 ? GetBulletDna64() : GetBulletDna(); bool swap = !BitConverter.IsLittleEndian; using (var stream = new MemoryStream(_dnaData)) { using (var reader = new BulletReader(stream)) { _dna = Dna.Load(reader, swap); } } }
public void ResolvePointers(FileVerboseMode verboseMode) { Dna fileDna = (_fileDna != null) ? _fileDna : _memoryDna; if (true) // && ((_flags & FileFlags.BitsVaries | FileFlags.VersionVaries) != 0)) { //ResolvePointersMismatch(); } if ((verboseMode & FileVerboseMode.ExportXml) != 0) { Console.WriteLine("<?xml version=\"1.0\" encoding=\"utf-8\"?>"); Console.WriteLine("<bullet_physics version=\"{0}\" itemcount=\"{1}\">", Version, _chunks.Count); } foreach (ChunkInd dataChunk in _chunks) { if (_fileDna == null || fileDna.FlagEqual(dataChunk.DnaNR)) { Dna.StructDecl oldStruct = fileDna.GetStruct(dataChunk.DnaNR); if ((verboseMode & FileVerboseMode.ExportXml) != 0) { Console.WriteLine(" <{0} pointer=\"{1}\">", oldStruct.Type.Name, dataChunk.OldPtr); } ResolvePointersChunk(dataChunk, verboseMode); if ((verboseMode & FileVerboseMode.ExportXml) != 0) { Console.WriteLine(" </{0}>", oldStruct.Type.Name); } } else { //Console.WriteLine("skipping struct"); } } if ((verboseMode & FileVerboseMode.ExportXml) != 0) { Console.WriteLine("</bullet_physics>"); } }
public ElementDecl FindElement(Dna dna, bool brokenDna, NameInfo name, out int offset) { offset = 0; foreach (ElementDecl element in Elements) { if (element.NameInfo.Equals(name)) { return(element); } int eleLen = dna.GetElementSize(element); if (brokenDna) { if (element.Type.Name.Equals("short") && element.NameInfo.Name.Equals("int")) { eleLen = 0; } } offset += eleLen; } return(null); }
protected void ResolvePointersChunk(ChunkInd dataChunk, FileVerboseMode verboseMode) { Dna fileDna = (_fileDna != null) ? _fileDna : _memoryDna; Dna.StructDecl oldStruct = fileDna.GetStruct(dataChunk.DnaNR); int oldLen = oldStruct.Type.Length; byte[] cur = FindLibPointer(dataChunk.OldPtr); using (MemoryStream stream = new MemoryStream(cur, false)) { using (BinaryReader reader = new BinaryReader(stream)) { for (int block = 0; block < dataChunk.NR; block++) { long streamPosition = stream.Position; ResolvePointersStructRecursive(reader, dataChunk.DnaNR, verboseMode, 1); System.Diagnostics.Debug.Assert(stream.Position == streamPosition + oldLen); } } } }
public bool[] Compare(Dna memoryDna) { bool[] _structChanged = new bool[_structs.Length]; for (int i = 0; i < _structs.Length; i++) { StructDecl oldStruct = _structs[i]; StructDecl curStruct = memoryDna.GetStruct(oldStruct.Type.Name); _structChanged[i] = !_structs[i].Equals(curStruct); } // Recurse in for (int i = 0; i < _structs.Length; i++) { if (_structChanged[i]) { CompareStruct(_structs[i], _structChanged); } } return _structChanged; }
public bool[] Compare(Dna memoryDna) { bool[] _structChanged = new bool[_structs.Length]; for (int i = 0; i < _structs.Length; i++) { StructDecl oldStruct = _structs[i]; StructDecl curStruct = memoryDna.GetStruct(oldStruct.Type.Name); _structChanged[i] = !_structs[i].Equals(curStruct); } // Recurse in for (int i = 0; i < _structs.Length; i++) { if (_structChanged[i]) { CompareStruct(_structs[i], _structChanged); } } return(_structChanged); }
private void LoadDna(FileVerboseMode verboseMode) { bool swap = (Flags & FileFlags.EndianSwap) != 0; using (var stream = new MemoryStream(_fileBuffer, false)) { using (var reader = new BulletReader(stream)) { long dnaStart = FindDnaChunk(reader); OK = dnaStart != -1; if (!OK) { return; } stream.Position = dnaStart; _fileDna = Dna.Load(reader, swap); } } if (_fileDna.IsBroken(_version)) { Console.WriteLine("Warning: broken DNA version"); Flags |= FileFlags.BrokenDna; } //if ((verboseMode & FileVerboseMode.DumpDnaTypeDefinitions) != 0) // _fileDna.DumpTypeDefinitions(); byte[] memoryDnaData = IntPtr.Size == 8 ? Serializer.GetBulletDna64() : Serializer.GetBulletDna(); _memoryDna = Dna.Load(memoryDnaData, !BitConverter.IsLittleEndian); _structChanged = _fileDna.Compare(_memoryDna); }
protected void GetMatchingFileDna(Dna.StructDecl dna, Dna.ElementDecl lookupElement, BinaryWriter strcData, long data, bool fixupPointers) { // find the matching memory dna data // to the file being loaded. Fill the // memory with the file data... foreach (Dna.ElementDecl element in dna.Elements) { int eleLen = _fileDna.GetElementSize(element); if ((_flags & FileFlags.BrokenDna) != 0) { if (element.Type.Name.Equals("short") && element.Name.Name.Equals("int")) { eleLen = 0; } } if (lookupElement.Name.Equals(element.Name)) { int arrayLen = element.Name.ArraySizeNew; MemoryStream dataStream = new MemoryStream(_fileBuffer, false); dataStream.Position = data; BinaryReader dataReader = new BinaryReader(dataStream); if (element.Name.Name[0] == '*') { SafeSwapPtr(strcData, dataReader); if (fixupPointers) { if (arrayLen > 1) { throw new NotImplementedException(); } else { if (element.Name.Name[1] == '*') { throw new NotImplementedException(); } else { //_chunkPointerFixupArray.Add(strcData.BaseStream.Position); } } } else { //Console.WriteLine("skipped {0} {1} : {2:X}", element.Type.Name, element.Name.Name, strcData.BaseStream.Position); } } else if (element.Type.Name.Equals(lookupElement.Type.Name)) { byte[] mem = new byte[eleLen]; dataReader.Read(mem, 0, eleLen); strcData.Write(mem); } else { throw new NotImplementedException(); //GetElement(arrayLen, lookupType, type, data, strcData); } dataReader.Dispose(); dataStream.Dispose(); break; } data += eleLen; } }
protected long GetFileElement(Dna.StructDecl firstStruct, Dna.ElementDecl lookupElement, long data, out Dna.ElementDecl found) { foreach (Dna.ElementDecl element in firstStruct.Elements) { if (element.Name.Equals(lookupElement.Name)) { if (element.Type.Name.Equals(lookupElement.Type.Name)) { found = element; return data; } found = null; return 0; } data += _fileDna.GetElementSize(element); } found = null; return 0; }
protected void WriteElement(BinaryWriter writer, Dna.StructDecl fileStruct, Dna.ElementDecl memoryElement, long structOffset) { bool brokenDna = (Flags & FileFlags.BrokenDna) != 0; int elementOffset; Dna.ElementDecl fileElement = fileStruct.FindElement(_fileDna, brokenDna, memoryElement.NameInfo, out elementOffset); ChunkReader.BaseStream.Position = structOffset + elementOffset; if (fileElement == null) { int elementLength = _memoryDna.GetElementSize(memoryElement); writer.BaseStream.Position += elementLength; } else if (fileElement.NameInfo.Name[0] == '*') { SafeSwapPtr(writer, ChunkReader); } else if (fileElement.Type.Name.Equals(memoryElement.Type.Name)) { int elementLength = _fileDna.GetElementSize(fileElement); if (elementLength != _memoryDna.GetElementSize(memoryElement)) { throw new InvalidDataException(); } byte[] mem = new byte[elementLength]; ChunkReader.Read(mem, 0, elementLength); writer.Write(mem); } else { throw new InvalidDataException(); //GetElement(arrayLen, lookupType, type, data, strcData); } }
protected int ResolvePointersStructRecursive(BinaryReader reader, Dna.StructDecl oldStruct, FileVerboseMode verboseMode, int recursion) { Dna fileDna = (_fileDna != null) ? _fileDna : _memoryDna; int totalSize = 0; foreach (Dna.ElementDecl element in oldStruct.Elements) { int size = fileDna.GetElementSize(element); int arrayLen = element.NameInfo.ArrayLength; if (element.NameInfo.Name[0] == '*') { if (arrayLen > 1) { throw new NotImplementedException(); } else { long ptr = (IntPtr.Size == 8) ? reader.ReadInt64() : reader.ReadInt32(); if ((verboseMode & FileVerboseMode.ExportXml) != 0) { for (int i = 0; i < recursion; i++) { Console.Write(" "); } Console.WriteLine("<{0} type=\"pointer\"> {1} </{0}>", element.NameInfo.Name.Substring(1), ptr); } byte[] ptrChunk = FindLibPointer(ptr); if (ptrChunk != null) { //throw new NotImplementedException(); } else { //Console.WriteLine("Cannot fixup pointer at {0} from {1} to {2}!", ptrptr, *ptrptr, ptr); } } } else { if (element.Type.Struct != null) { if ((verboseMode & FileVerboseMode.ExportXml) != 0) { for (int i = 0; i < recursion; i++) { Console.Write(" "); } if (arrayLen > 1) { Console.WriteLine("<{0} type=\"{1}\" count={2}>", element.NameInfo.CleanName, element.Type.Name, arrayLen); } else { Console.WriteLine("<{0} type=\"{1}\">", element.NameInfo.CleanName, element.Type.Name); } } for (int i = 0; i < arrayLen; i++) { Dna.StructDecl revType = _fileDna.GetStruct(element.Type.Name); ResolvePointersStructRecursive(reader, revType, verboseMode, recursion + 1); //throw new NotImplementedException(); } if ((verboseMode & FileVerboseMode.ExportXml) != 0) { for (int i = 0; i < recursion; i++) { Console.Write(" "); } Console.WriteLine("</{0}>", element.NameInfo.CleanName); } } else { // export a simple type if ((verboseMode & FileVerboseMode.ExportXml) != 0) { if (arrayLen > MaxArrayLength) { Console.WriteLine("too long"); } else { bool isIntegerType; switch (element.Type.Name) { case "char": case "short": case "int": isIntegerType = true; break; default: isIntegerType = false; break; } if (isIntegerType) { throw new NotImplementedException(); /* const char* newtype="int"; int dbarray[MAX_ARRAY_LENGTH]; int* dbPtr = 0; char* tmp = elemPtr; dbPtr = &dbarray[0]; if (dbPtr) { char cleanName[MAX_STRLEN]; getCleanName(memName,cleanName); int i; getElement(arrayLen, newtype,memType, tmp, (char*)dbPtr); for (i=0;i<recursion;i++) printf(" "); if (arrayLen==1) printf("<%s type=\"%s\">",cleanName,memType); else printf("<%s type=\"%s\" count=%d>",cleanName,memType,arrayLen); for (i=0;i<arrayLen;i++) printf(" %d ",dbPtr[i]); printf("</%s>\n",cleanName); }*/ } else { double[] dbArray = new double[arrayLen]; GetElement(reader, arrayLen, element.Type, dbArray); for (int i = 0; i < recursion; i++) { Console.Write(" "); } if (arrayLen == 1) { Console.Write("<{0} type=\"{1}\">", element.NameInfo.Name, element.Type.Name); } else { Console.Write("<{0} type=\"{1}\" count=\"{2}\">", element.NameInfo.CleanName, element.Type.Name, arrayLen); } for (int i = 0; i < arrayLen; i++) { Console.Write(" {0} ", dbArray[i].ToString(CultureInfo.InvariantCulture)); } Console.WriteLine("</{0}>", element.NameInfo.CleanName); } } } reader.BaseStream.Position += size; } } totalSize += size; } return totalSize; }
protected void ParseStruct(BinaryWriter writer, Dna.StructDecl memoryStruct, Dna.StructDecl fileStruct, long structOffset) { Debug.Assert(memoryStruct != null); Debug.Assert(fileStruct != null); foreach (Dna.ElementDecl element in memoryStruct.Elements) { if (element.Type.Struct != null && element.NameInfo.Name[0] != '*') { ParseElement(writer, fileStruct, element, structOffset); } else { WriteElement(writer, fileStruct, element, structOffset); } } }
private void GetElement(BinaryReader reader, int ArrayLen, Dna.TypeDecl type, double[] data) { if (type.Name.Equals("float")) { for (int i = 0; i < ArrayLen; i++) { data[i] = reader.ReadSingle(); } } else { for (int i = 0; i < ArrayLen; i++) { data[i] = reader.ReadDouble(); } } }
public ElementDecl FindElement(Dna dna, bool brokenDna, NameInfo name, out int offset) { offset = 0; foreach (ElementDecl element in Elements) { if (element.NameInfo.Equals(name)) { return element; } int eleLen = dna.GetElementSize(element); if (brokenDna) { if (element.Type.Name.Equals("short") && element.NameInfo.Name.Equals("int")) { eleLen = 0; } } offset += eleLen; } return null; }
public static Dna Load(BulletReader dnaReader, bool swap) { var dna = new Dna(); dna.Init(dnaReader, swap); return dna; }
public bool LessThan(Dna file) { return(_names.Length < _names.Length); }
// Structs containing non-equal structs are also non-equal private void InitRecurseCmpFlags(Dna.StructDecl iter) { for (int i = 0; i < _structs.Length; i++) { Dna.StructDecl curStruct = _structs[i]; if (curStruct != iter && _cmpFlags[i] == FileDnaFlags.StructEqual) { foreach (Dna.ElementDecl element in curStruct.Elements) { if (curStruct.Type == iter.Type && element.Name.IsPointer) { _cmpFlags[i] = FileDnaFlags.StructNotEqual; InitRecurseCmpFlags(curStruct); } } } } }
public bool LessThan(Dna file) { return _names.Length < _names.Length; }
protected void ParseInternal(FileVerboseMode verboseMode, byte[] memDna) { if ((_flags & FileFlags.OK) != FileFlags.OK) { return; } ChunkInd dna = new ChunkInd(); dna.OldPtr = 0; MemoryStream memory = new MemoryStream(_fileBuffer, false); BinaryReader reader = new BinaryReader(memory); int i = 0; while (memory.Position < memory.Length) { // looking for the data's starting position // and the start of SDNA decls byte[] code = reader.ReadBytes(4); string codes = ASCIIEncoding.ASCII.GetString(code); if (_dataStart == 0 && codes.Equals("REND")) { _dataStart = memory.Position; } if (codes.Equals("DNA1")) { // read the DNA1 block and extract SDNA reader.BaseStream.Position = i; if (GetNextBlock(out dna, reader, _flags) > 0) { string sdnaname = ASCIIEncoding.ASCII.GetString(reader.ReadBytes(8)); if (sdnaname.Equals("SDNANAME")) { dna.OldPtr = i + ChunkUtils.GetOffset(_flags); } else { dna.OldPtr = 0; } } else { dna.OldPtr = 0; } } else if (codes.Equals("SDNA")) { // Some Bullet files are missing the DNA1 block // In Blender it's DNA1 + ChunkUtils::getOffset() + SDNA + NAME // In Bullet tests its SDNA + NAME dna.OldPtr = i; dna.Length = (int)memory.Length - i; // Also no REND block, so exit now. if (_version == 276) { break; } } if (_dataStart != 0 && dna.OldPtr != 0) { break; } i++; memory.Position = i; } if (dna.OldPtr == 0 || dna.Length == 0) { //Console.WriteLine("Failed to find DNA1+SDNA pair"); _flags &= ~FileFlags.OK; reader.Dispose(); memory.Dispose(); return; } _fileDna = new Dna(); // _fileDna.Init will convert part of DNA file endianness to current CPU endianness if necessary memory.Position = dna.OldPtr; _fileDna.Init(reader, (_flags & FileFlags.EndianSwap) != 0); if (_version == 276) { for (i = 0; i < _fileDna.NumNames; i++) { if (_fileDna.GetName(i).Equals("int")) { _flags |= FileFlags.BrokenDna; } } if ((_flags & FileFlags.BrokenDna) == FileFlags.BrokenDna) { //Console.WriteLine("warning: fixing some broken DNA version"); } } //if ((verboseMode & FileVerboseMode.DumpDnaTypeDefinitions) == FileVerboseMode.DumpDnaTypeDefinitions) // _fileDna.DumpTypeDefinitions(); _memoryDna = new Dna(); using (MemoryStream memory2 = new MemoryStream(memDna, false)) { using (BinaryReader reader2 = new BinaryReader(memory2)) { _memoryDna.Init(reader2, !BitConverter.IsLittleEndian); } } if (_memoryDna.NumNames != _fileDna.NumNames) { _flags |= FileFlags.VersionVaries; //Console.WriteLine ("Warning, file DNA is different than built in, performance is reduced. Best to re-export file with a matching version/platform"); } if (_memoryDna.LessThan(_fileDna)) { //Console.WriteLine ("Warning, file DNA is newer than built in."); } _fileDna.InitCmpFlags(_memoryDna); ParseData(); ResolvePointers(verboseMode); UpdateOldPointers(); reader.Dispose(); memory.Dispose(); }
protected int ResolvePointersStructRecursive(BinaryReader reader, int dnaNr, FileVerboseMode verboseMode, int recursion) { Dna fileDna = (_fileDna != null) ? _fileDna : _memoryDna; Dna.StructDecl oldStruct = fileDna.GetStruct(dnaNr); int totalSize = 0; foreach (Dna.ElementDecl element in oldStruct.Elements) { int size = fileDna.GetElementSize(element); int arrayLen = element.Name.ArraySizeNew; if (element.Name.Name[0] == '*') { if (arrayLen > 1) { throw new NotImplementedException(); } else { long ptr = (IntPtr.Size == 8) ? reader.ReadInt64() : reader.ReadInt32(); if ((verboseMode & FileVerboseMode.ExportXml) != 0) { for (int i = 0; i < recursion; i++) { Console.Write(" "); } Console.WriteLine("<{0} type=\"pointer\"> {1} </{0}>", element.Name.Name.Substring(1), ptr); } byte[] ptrChunk = FindLibPointer(ptr); if (ptrChunk != null) { //throw new NotImplementedException(); } else { //Console.WriteLine("Cannot fixup pointer at {0} from {1} to {2}!", ptrptr, *ptrptr, ptr); } } } else { if (element.Type.Struct != null) { if ((verboseMode & FileVerboseMode.ExportXml) != 0) { for (int i = 0; i < recursion; i++) { Console.Write(" "); } if (arrayLen > 1) { Console.WriteLine("<{0} type=\"{1}\" count={2}>", element.Name.CleanName, element.Type.Name, arrayLen); } else { Console.WriteLine("<{0} type=\"{1}\">", element.Name.CleanName, element.Type.Name); } } for (int i = 0; i < arrayLen; i++) { int revType = _fileDna.GetReverseType(element.Type.Name); ResolvePointersStructRecursive(reader, revType, verboseMode, recursion + 1); //throw new NotImplementedException(); } if ((verboseMode & FileVerboseMode.ExportXml) != 0) { for (int i = 0; i < recursion; i++) { Console.Write(" "); } Console.WriteLine("</{0}>", element.Name.CleanName); } } else { // export a simple type if ((verboseMode & FileVerboseMode.ExportXml) != 0) { if (arrayLen > MaxArrayLength) { Console.WriteLine("too long"); } else { bool isIntegerType; switch (element.Type.Name) { case "char": case "short": case "int": isIntegerType = true; break; default: isIntegerType = false; break; } if (isIntegerType) { throw new NotImplementedException(); /* * const char* newtype="int"; * int dbarray[MAX_ARRAY_LENGTH]; * int* dbPtr = 0; * char* tmp = elemPtr; * dbPtr = &dbarray[0]; * if (dbPtr) * { * char cleanName[MAX_STRLEN]; * getCleanName(memName,cleanName); * * int i; * getElement(arrayLen, newtype,memType, tmp, (char*)dbPtr); * for (i=0;i<recursion;i++) * printf(" "); * if (arrayLen==1) * printf("<%s type=\"%s\">",cleanName,memType); * else * printf("<%s type=\"%s\" count=%d>",cleanName,memType,arrayLen); * for (i=0;i<arrayLen;i++) * printf(" %d ",dbPtr[i]); * printf("</%s>\n",cleanName); * }*/ } else { double[] dbArray = new double[arrayLen]; GetElement(reader, arrayLen, element.Type, dbArray); for (int i = 0; i < recursion; i++) { Console.Write(" "); } if (arrayLen == 1) { Console.Write("<{0} type=\"{1}\">", element.Name.Name, element.Type.Name); } else { Console.Write("<{0} type=\"{1}\" count=\"{2}\">", element.Name.CleanName, element.Type.Name, arrayLen); } for (int i = 0; i < arrayLen; i++) { Console.Write(" {0} ", dbArray[i].ToString(CultureInfo.InvariantCulture)); } Console.WriteLine("</{0}>", element.Name.CleanName); } } } reader.BaseStream.Position += size; } } totalSize += size; } return(totalSize); }
protected void ParseStruct(BinaryWriter strc, BinaryReader data, Dna.StructDecl fileStruct, Dna.StructDecl memoryStruct, bool fixupPointers) { if (fileStruct == null) return; if (memoryStruct == null) return; long dataPtr = data.BaseStream.Position; long strcPtr = strc.BaseStream.Position; foreach (Dna.ElementDecl element in memoryStruct.Elements) { int memorySize = _memoryDna.GetElementSize(element); if (element.Type.Struct != null && element.Name.Name[0] != '*') { Dna.ElementDecl elementOld; long elementOffset = GetFileElement(fileStruct, element, dataPtr, out elementOld); if (elementOffset != 0) { Dna.StructDecl oldStruct = _fileDna.GetStruct(_fileDna.GetReverseType(element.Type.Name)); data.BaseStream.Position = elementOffset; int arrayLen = elementOld.Name.ArraySizeNew; if (arrayLen == 1) { strc.BaseStream.Position = strcPtr; ParseStruct(strc, data, oldStruct, element.Type.Struct, fixupPointers); strcPtr += memorySize; } else { int fileSize = _fileDna.GetElementSize(elementOld) / arrayLen; memorySize /= arrayLen; for (int i = 0; i < arrayLen; i++) { strc.BaseStream.Position = strcPtr; ParseStruct(strc, data, oldStruct, element.Type.Struct, fixupPointers); data.BaseStream.Position += fileSize; strcPtr += memorySize; } } } } else { strc.BaseStream.Position = strcPtr; GetMatchingFileDna(fileStruct, element, strc, dataPtr, fixupPointers); strcPtr += memorySize; } } }
protected Dna.ElementDecl GetFileElement(Dna.StructDecl fileStruct, Dna.ElementDecl lookupElement, out long elementOffset) { elementOffset = 0; foreach (Dna.ElementDecl element in fileStruct.Elements) { if (element.NameInfo.Equals(lookupElement.NameInfo)) { if (element.Type.Name.Equals(lookupElement.Type.Name)) { return element; } break; } elementOffset += _fileDna.GetElementSize(element); } return null; }