diff --git a/Demos/SerializeDemo/SerializeDemo.cpp b/Demos/SerializeDemo/SerializeDemo.cpp index 3862dd20e..37e377e44 100644 --- a/Demos/SerializeDemo/SerializeDemo.cpp +++ b/Demos/SerializeDemo/SerializeDemo.cpp @@ -765,7 +765,7 @@ void SerializeDemo::initPhysics() - if (!m_fileLoader->loadFile("testFile.bullet")) + if (!m_fileLoader->loadFile("testFile.bullet", "testFileSwappedEndianness.bullet")) // if (!m_fileLoader->loadFile("../SoftDemo/testFile.bullet")) { ///create a few basic rigid bodies and save them to testFile.bullet diff --git a/Extras/Serialize/BulletFileLoader/bFile.cpp b/Extras/Serialize/BulletFileLoader/bFile.cpp index 22ea915f5..c90ab136f 100644 --- a/Extras/Serialize/BulletFileLoader/bFile.cpp +++ b/Extras/Serialize/BulletFileLoader/bFile.cpp @@ -300,7 +300,7 @@ void bFile::parseInternal(int verboseMode, char* memDna,int memDnaLength) // ----------------------------------------------------- // -void bFile::swap(char *head, bChunkInd& dataChunk) +void bFile::swap(char *head, bChunkInd& dataChunk, bool ignoreEndianFlag) { char *data = head; short *strc = mFileDNA->getStruct(dataChunk.dna_nr); @@ -308,18 +308,302 @@ void bFile::swap(char *head, bChunkInd& dataChunk) for (int i=0; icode & 0xFFFF)==0) + c->code >>=16; + SWITCH_INT(c->len); + SWITCH_INT(c->dna_nr); + SWITCH_INT(c->nr); + } else + { + bChunkPtr8* c = (bChunkPtr8*) dataPtr; + if ((c->code & 0xFFFF)==0) + c->code >>=16; + SWITCH_INT(c->len); + SWITCH_INT(c->dna_nr); + SWITCH_INT(c->nr); + + } + } else + { + if (mFlags &FD_BITS_VARIES) + { + bChunkPtr8*c = (bChunkPtr8*) dataPtr; + if ((c->code & 0xFFFF)==0) + c->code >>=16; + SWITCH_INT(c->len); + SWITCH_INT(c->dna_nr); + SWITCH_INT(c->nr); + + } else + { + bChunkPtr4* c = (bChunkPtr4*) dataPtr; + if ((c->code & 0xFFFF)==0) + c->code >>=16; + SWITCH_INT(c->len); + SWITCH_INT(c->dna_nr); + SWITCH_INT(c->nr); + + } + } + +} + + +void bFile::swapDNA(char* ptr) +{ + bool swap = ((mFlags & FD_ENDIAN_SWAP)!=0); + + char* data = &ptr[20]; +// void bDNA::init(char *data, int len, bool swap) + int *intPtr=0;short *shtPtr=0; + char *cp = 0;int dataLen =0;long nr=0; + intPtr = (int*)data; + + /* + SDNA (4 bytes) (magic number) + NAME (4 bytes) + (4 bytes) amount of names (int) + + + */ + + if (strncmp(data, "SDNA", 4)==0) + { + // skip ++ NAME + intPtr++; intPtr++; + } + + + + // Parse names + if (swap) + dataLen = ChunkUtils::swapInt(*intPtr); + else + dataLen = *intPtr; + + *intPtr = ChunkUtils::swapInt(*intPtr); + intPtr++; + + cp = (char*)intPtr; + int i; + for ( i=0; i amount of types (int) + + + */ + + intPtr = (int*)cp; + assert(strncmp(cp, "TYPE", 4)==0); intPtr++; + + if (swap) + dataLen = ChunkUtils::swapInt(*intPtr); + else + dataLen = *intPtr; + + *intPtr = ChunkUtils::swapInt(*intPtr); + + intPtr++; + + cp = (char*)intPtr; + for ( i=0; i (short) the lengths of types + + */ + + // Parse type lens + intPtr = (int*)cp; + assert(strncmp(cp, "TLEN", 4)==0); intPtr++; + + + shtPtr = (short*)intPtr; + for ( i=0; i amount of structs (int) + + + + + + + */ + + intPtr = (int*)shtPtr; + cp = (char*)intPtr; + assert(strncmp(cp, "STRC", 4)==0); + intPtr++; + + if (swap) + dataLen = ChunkUtils::swapInt(*intPtr); + else + dataLen = *intPtr; + + *intPtr = ChunkUtils::swapInt(*intPtr); + + intPtr++; + + + shtPtr = (short*)intPtr; + for ( i=0; i=0) + { + swap(dataPtrHead, dataChunk,ignoreEndianFlag); + } else + { + printf("unknown chunk\n"); + } + } + + // next please! + dataPtr += seek; + + seek = getNextBlock(&dataChunk, dataPtr, mFlags); + if (seek < 0) + break; + } + + if (mFlags & FD_ENDIAN_SWAP) + { + mFlags &= ~FD_ENDIAN_SWAP; + } else + { + mFlags |= FD_ENDIAN_SWAP; + } + + FILE* f = fopen(fileName,"wb"); + fwrite(mFileBuffer,1,mFileLen,f); + fclose(f); + + +} // ----------------------------------------------------- // char* bFile::readStruct(char *head, bChunkInd& dataChunk) { + bool ignoreEndianFlag = false; + if (mFlags & FD_ENDIAN_SWAP) - swap(head, dataChunk); + swap(head, dataChunk, ignoreEndianFlag); @@ -562,9 +846,9 @@ static void getElement(int arrayLen, const char *cur, const char *old, char *old // ----------------------------------------------------- // -void bFile::swapData(char *data, short type, int arraySize) +void bFile::swapData(char *data, short type, int arraySize,bool ignoreEndianFlag) { - if (mFlags &FD_ENDIAN_SWAP) + if (ignoreEndianFlag || (mFlags &FD_ENDIAN_SWAP)) { if (type == 2 || type == 3) { @@ -770,7 +1054,7 @@ char* bFile::getFileElement(short *firstStruct, char *lookupName, char *lookupTy // ----------------------------------------------------- // -void bFile::swapStruct(int dna_nr, char *data) +void bFile::swapStruct(int dna_nr, char *data,bool ignoreEndianFlag) { if (dna_nr == -1) return; @@ -795,13 +1079,13 @@ void bFile::swapStruct(int dna_nr, char *data) int arrayLen = mFileDNA->getArraySizeNew(strc[1]); if (arrayLen==1) { - swapStruct(old_nr,buf); + swapStruct(old_nr,buf,ignoreEndianFlag); } else { char* tmpBuf = buf; for (int i=0;igetArraySize(name); int arrayLen = mFileDNA->getArraySizeNew(strc[1]); //assert(arrayLenOld == arrayLen); - swapData(buf, strc[0], arrayLen); + swapData(buf, strc[0], arrayLen,ignoreEndianFlag); } buf+=size; } @@ -1301,8 +1585,10 @@ int bFile::getNextBlock(bChunkInd *dataChunk, const char *dataPtr, const int fl bool swap = false; bool varies = false; - if (flags &FD_ENDIAN_SWAP) swap = true; - if (flags &FD_BITS_VARIES) varies = true; + if (flags &FD_ENDIAN_SWAP) + swap = true; + if (flags &FD_BITS_VARIES) + varies = true; if (VOID_IS_8) { diff --git a/Extras/Serialize/BulletFileLoader/bFile.h b/Extras/Serialize/BulletFileLoader/bFile.h index 0da73670f..bb62d3609 100644 --- a/Extras/Serialize/BulletFileLoader/bFile.h +++ b/Extras/Serialize/BulletFileLoader/bFile.h @@ -96,12 +96,11 @@ namespace bParse { char* getFileElement(short *firstStruct, char *lookupName, char *lookupType, char *data, short **foundPos); - void swap(char *head, class bChunkInd& ch); - - void swapData(char *data, short type, int arraySize); - void swapStruct(int dna_nr, char *data); - - + void swap(char *head, class bChunkInd& ch, bool ignoreEndianFlag); + void swapData(char *data, short type, int arraySize, bool ignoreEndianFlag); + void swapStruct(int dna_nr, char *data, bool ignoreEndianFlag); + void swapLen(char *dataPtr); + void swapDNA(char* ptr); char* readStruct(char *head, class bChunkInd& chunk); @@ -155,8 +154,9 @@ namespace bParse { { return mVersion; } + //pre-swap the endianness, so that data loaded on a target with different endianness doesn't need to be swapped + void preSwap(const char* fileName); - }; } diff --git a/Extras/Serialize/BulletWorldImporter/btBulletWorldImporter.cpp b/Extras/Serialize/BulletWorldImporter/btBulletWorldImporter.cpp index bde40c960..23d2710ac 100644 --- a/Extras/Serialize/BulletWorldImporter/btBulletWorldImporter.cpp +++ b/Extras/Serialize/BulletWorldImporter/btBulletWorldImporter.cpp @@ -37,12 +37,18 @@ btBulletWorldImporter::~btBulletWorldImporter() } -bool btBulletWorldImporter::loadFile( const char* fileName) +bool btBulletWorldImporter::loadFile( const char* fileName, const char* preSwapFilenameOut) { bParse::btBulletFile* bulletFile2 = new bParse::btBulletFile(fileName); + + + bool result = loadFileFromMemory(bulletFile2); + if (preSwapFilenameOut) + bulletFile2->preSwap(preSwapFilenameOut); + delete bulletFile2; return result; diff --git a/Extras/Serialize/BulletWorldImporter/btBulletWorldImporter.h b/Extras/Serialize/BulletWorldImporter/btBulletWorldImporter.h index 4a3831894..27c1e7e33 100644 --- a/Extras/Serialize/BulletWorldImporter/btBulletWorldImporter.h +++ b/Extras/Serialize/BulletWorldImporter/btBulletWorldImporter.h @@ -47,7 +47,9 @@ public: virtual ~btBulletWorldImporter(); - bool loadFile(const char* fileName); + ///if you pass a valid preSwapFilenameOut, it will save a new file with a different endianness + ///this pre-swapped file can be loaded without swapping on a target platform of different endianness + bool loadFile(const char* fileName, const char* preSwapFilenameOut=0); ///the memoryBuffer might be modified (for example if endian swaps are necessary) bool loadFileFromMemory(char *memoryBuffer, int len);