Bullet Collision Detection & Physics Library
bFile.cpp
Go to the documentation of this file.
1/*
2bParse
3Copyright (c) 2006-2009 Charlie C & Erwin Coumans http://gamekit.googlecode.com
4
5This software is provided 'as-is', without any express or implied warranty.
6In no event will the authors be held liable for any damages arising from the use of this software.
7Permission is granted to anyone to use this software for any purpose,
8including commercial applications, and to alter it and redistribute it freely,
9subject to the following restrictions:
10
111. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
122. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
133. This notice may not be removed or altered from any source distribution.
14*/
15#include "bFile.h"
16#include "bCommon.h"
17#include "bChunk.h"
18#include "bDNA.h"
19#include <math.h>
20#include <string.h>
21#include <stdlib.h>
22#include "bDefines.h"
25#include "LinearMath/btMinMax.h"
26
27#define SIZEOFBLENDERHEADER 12
28#define MAX_ARRAY_LENGTH 512
29using namespace bParse;
30#define MAX_STRLEN 1024
31
32const char *getCleanName(const char *memName, char *buffer)
33{
34 int slen = strlen(memName);
35 assert(slen < MAX_STRLEN);
36 slen = btMin(slen, MAX_STRLEN);
37 for (int i = 0; i < slen; i++)
38 {
39 if (memName[i] == ']' || memName[i] == '[')
40 {
41 buffer[i] = 0; //'_';
42 }
43 else
44 {
45 buffer[i] = memName[i];
46 }
47 }
48 buffer[slen] = 0;
49 return buffer;
50}
51
52int numallocs = 0;
53
54// ----------------------------------------------------- //
55bFile::bFile(const char *filename, const char headerString[7])
56 : mOwnsBuffer(true),
57 mFileBuffer(0),
58 mFileLen(0),
59 mVersion(0),
60 mDataStart(0),
61 mFileDNA(0),
62 mMemoryDNA(0),
63 mFlags(FD_INVALID)
64{
65 for (int i = 0; i < 7; i++)
66 {
67 m_headerString[i] = headerString[i];
68 }
69
70 FILE *fp = fopen(filename, "rb");
71 if (fp)
72 {
73 fseek(fp, 0L, SEEK_END);
74 mFileLen = ftell(fp);
75 fseek(fp, 0L, SEEK_SET);
76
77 mFileBuffer = (char *)malloc(mFileLen + 1);
78 memset(mFileBuffer, 0, mFileLen+1);
79 size_t bytesRead;
80 bytesRead = fread(mFileBuffer, mFileLen, 1, fp);
81
82 fclose(fp);
83
84 //
86 }
87}
88
89// ----------------------------------------------------- //
90bFile::bFile(char *memoryBuffer, int len, const char headerString[7])
91 : mOwnsBuffer(false),
92 mFileBuffer(0),
93 mFileLen(0),
94 mVersion(0),
95 mDataStart(0),
96 mFileDNA(0),
97 mMemoryDNA(0),
98 mFlags(FD_INVALID)
99{
100 for (int i = 0; i < 7; i++)
101 {
102 m_headerString[i] = headerString[i];
103 }
104 mFileBuffer = memoryBuffer;
105 mFileLen = len;
106
107 parseHeader();
108}
109
110// ----------------------------------------------------- //
112{
114 {
115 free(mFileBuffer);
116 mFileBuffer = 0;
117 }
118
119 delete mMemoryDNA;
120 delete mFileDNA;
121}
122
123// ----------------------------------------------------- //
125{
126 if (!mFileLen || !mFileBuffer)
127 return;
128
129 char *blenderBuf = mFileBuffer;
130 char header[SIZEOFBLENDERHEADER + 1];
131 memcpy(header, blenderBuf, SIZEOFBLENDERHEADER);
132 header[SIZEOFBLENDERHEADER] = '\0';
133
134 if (strncmp(header, m_headerString, 6) != 0)
135 {
136 memcpy(header, m_headerString, SIZEOFBLENDERHEADER);
137 return;
138 }
139
140 if (header[6] == 'd')
141 {
143 }
144
145 char *ver = header + 9;
146 mVersion = atoi(ver);
147 if (mVersion <= 241)
148 {
149 //printf("Warning, %d not fully tested : <= 242\n", mVersion);
150 }
151
152 int littleEndian = 1;
153 littleEndian = ((char *)&littleEndian)[0];
154
155 // swap ptr sizes...
156 if (header[7] == '-')
157 {
159 if (!VOID_IS_8)
161 }
162 else if (VOID_IS_8)
164
165 // swap endian...
166 if (header[8] == 'V')
167 {
168 if (littleEndian == 1)
170 }
171 else if (littleEndian == 0)
173
174 mFlags |= FD_OK;
175}
176
177// ----------------------------------------------------- //
179{
180 return (mFlags & FD_OK) != 0;
181}
182
183void bFile::setFileDNA(int verboseMode, char *dnaBuffer, int dnaLen)
184{
185 mFileDNA = new bDNA();
186
188 mFileDNA->init((char *)dnaBuffer, dnaLen, (mFlags & FD_ENDIAN_SWAP) != 0);
189
190 if (verboseMode & FD_VERBOSE_DUMP_DNA_TYPE_DEFINITIONS)
192}
193
194// ----------------------------------------------------- //
195void bFile::parseInternal(int verboseMode, char *memDna, int memDnaLength)
196{
197 if ((mFlags & FD_OK) == 0)
198 return;
199
201 {
202 setFileDNA(verboseMode, memDna, memDnaLength);
203 }
204
205 if (mFileDNA == 0)
206 {
207 char *blenderData = mFileBuffer;
208 bChunkInd dna;
209 dna.oldPtr = 0;
210
211 char *tempBuffer = blenderData;
212 for (int i = 0; i < mFileLen; i++)
213 {
214 // looking for the data's starting position
215 // and the start of SDNA decls
216
217 if (!mDataStart && strncmp(tempBuffer, "REND", 4) == 0)
218 mDataStart = i;
219
220 if (strncmp(tempBuffer, "DNA1", 4) == 0)
221 {
222 // read the DNA1 block and extract SDNA
223 if (getNextBlock(&dna, tempBuffer, mFlags) > 0)
224 {
225 if (strncmp((tempBuffer + ChunkUtils::getOffset(mFlags)), "SDNANAME", 8) == 0)
226 dna.oldPtr = (tempBuffer + ChunkUtils::getOffset(mFlags));
227 else
228 dna.oldPtr = 0;
229 }
230 else
231 dna.oldPtr = 0;
232 }
233 // Some Bullet files are missing the DNA1 block
234 // In Blender it's DNA1 + ChunkUtils::getOffset() + SDNA + NAME
235 // In Bullet tests its SDNA + NAME
236 else if (strncmp(tempBuffer, "SDNANAME", 8) == 0)
237 {
238 dna.oldPtr = blenderData + i;
239 dna.len = mFileLen - i;
240
241 // Also no REND block, so exit now.
242 if (mVersion == 276) break;
243 }
244
245 if (mDataStart && dna.oldPtr) break;
246 tempBuffer++;
247 }
248 if (!dna.oldPtr || !dna.len)
249 {
250 //printf("Failed to find DNA1+SDNA pair\n");
251 mFlags &= ~FD_OK;
252 return;
253 }
254
255 mFileDNA = new bDNA();
256
258 mFileDNA->init((char *)dna.oldPtr, dna.len, (mFlags & FD_ENDIAN_SWAP) != 0);
259
260 if (mVersion == 276)
261 {
262 int i;
263 for (i = 0; i < mFileDNA->getNumNames(); i++)
264 {
265 if (strcmp(mFileDNA->getName(i), "int") == 0)
266 {
268 }
269 }
270 if ((mFlags & FD_BROKEN_DNA) != 0)
271 {
272 //printf("warning: fixing some broken DNA version\n");
273 }
274 }
275
276 if (verboseMode & FD_VERBOSE_DUMP_DNA_TYPE_DEFINITIONS)
278 }
279 mMemoryDNA = new bDNA();
280 int littleEndian = 1;
281 littleEndian = ((char *)&littleEndian)[0];
282
283 mMemoryDNA->init(memDna, memDnaLength, littleEndian == 0);
284
287 {
289 //printf ("Warning, file DNA is different than built in, performance is reduced. Best to re-export file with a matching version/platform");
290 }
291
292 // as long as it kept up to date it will be ok!!
294 {
295 //printf ("Warning, file DNA is newer than built in.");
296 }
297
299
300 parseData();
301
302 resolvePointers(verboseMode);
303
305}
306
307// ----------------------------------------------------- //
308void bFile::swap(char *head, bChunkInd &dataChunk, bool ignoreEndianFlag)
309{
310 char *data = head;
311 short *strc = mFileDNA->getStruct(dataChunk.dna_nr);
312
313 const char s[] = "SoftBodyMaterialData";
314 int szs = sizeof(s);
315 if (strncmp((char *)&dataChunk.code, "ARAY", 4) == 0)
316 {
317 short *oldStruct = mFileDNA->getStruct(dataChunk.dna_nr);
318 char *oldType = mFileDNA->getType(oldStruct[0]);
319 if (strncmp(oldType, s, szs) == 0)
320 {
321 return;
322 }
323 }
324
325 int len = mFileDNA->getLength(strc[0]);
326
327 for (int i = 0; i < dataChunk.nr; i++)
328 {
329 swapStruct(dataChunk.dna_nr, data, ignoreEndianFlag);
330 data += len;
331 }
332}
333
334void bFile::swapLen(char *dataPtr)
335{
336 const bool VOID_IS_8 = ((sizeof(void *) == 8));
337 if (VOID_IS_8)
338 {
340 {
341 bChunkPtr4 *c = (bChunkPtr4 *)dataPtr;
342 if ((c->code & 0xFFFF) == 0)
343 c->code >>= 16;
344 SWITCH_INT(c->len);
345 SWITCH_INT(c->dna_nr);
346 SWITCH_INT(c->nr);
347 }
348 else
349 {
350 bChunkPtr8 *c = (bChunkPtr8 *)dataPtr;
351 if ((c->code & 0xFFFF) == 0)
352 c->code >>= 16;
353 SWITCH_INT(c->len);
354 SWITCH_INT(c->dna_nr);
355 SWITCH_INT(c->nr);
356 }
357 }
358 else
359 {
361 {
362 bChunkPtr8 *c = (bChunkPtr8 *)dataPtr;
363 if ((c->code & 0xFFFF) == 0)
364 c->code >>= 16;
365 SWITCH_INT(c->len);
366 SWITCH_INT(c->dna_nr);
367 SWITCH_INT(c->nr);
368 }
369 else
370 {
371 bChunkPtr4 *c = (bChunkPtr4 *)dataPtr;
372 if ((c->code & 0xFFFF) == 0)
373 c->code >>= 16;
374 SWITCH_INT(c->len);
375
376 SWITCH_INT(c->dna_nr);
377 SWITCH_INT(c->nr);
378 }
379 }
380}
381
382void bFile::swapDNA(char *ptr)
383{
384 bool swap = ((mFlags & FD_ENDIAN_SWAP) != 0);
385
386 int offset = (mFlags & FD_FILE_64) ? 24 : 20;
387 char *data = &ptr[offset];
388
389 // void bDNA::init(char *data, int len, bool swap)
390 int *intPtr = 0;
391 short *shtPtr = 0;
392 char *cp = 0;
393 int dataLen = 0;
394 intPtr = (int *)data;
395
396 /*
397 SDNA (4 bytes) (magic number)
398 NAME (4 bytes)
399 <nr> (4 bytes) amount of names (int)
400 <string>
401 <string>
402 */
403
404 if (strncmp(data, "SDNA", 4) == 0)
405 {
406 // skip ++ NAME
407 intPtr++;
408 intPtr++;
409 }
410 else
411 {
412 if (strncmp(data + 4, "SDNA", 4) == 0)
413 {
414 // skip ++ NAME
415 intPtr++;
416 intPtr++;
417 intPtr++;
418 }
419 }
420
421 // Parse names
422 if (swap)
423 dataLen = ChunkUtils::swapInt(*intPtr);
424 else
425 dataLen = *intPtr;
426
427 *intPtr = ChunkUtils::swapInt(*intPtr);
428 intPtr++;
429
430 cp = (char *)intPtr;
431 int i;
432 for (i = 0; i < dataLen; i++)
433 {
434 while (*cp) cp++;
435 cp++;
436 }
437
438 cp = btAlignPointer(cp, 4);
439
440 /*
441 TYPE (4 bytes)
442 <nr> amount of types (int)
443 <string>
444 <string>
445 */
446
447 intPtr = (int *)cp;
448 assert(strncmp(cp, "TYPE", 4) == 0);
449 intPtr++;
450
451 if (swap)
452 dataLen = ChunkUtils::swapInt(*intPtr);
453 else
454 dataLen = *intPtr;
455
456 *intPtr = ChunkUtils::swapInt(*intPtr);
457
458 intPtr++;
459
460 cp = (char *)intPtr;
461 for (i = 0; i < dataLen; i++)
462 {
463 while (*cp) cp++;
464 cp++;
465 }
466
467 cp = btAlignPointer(cp, 4);
468
469 /*
470 TLEN (4 bytes)
471 <len> (short) the lengths of types
472 <len>
473 */
474
475 // Parse type lens
476 intPtr = (int *)cp;
477 assert(strncmp(cp, "TLEN", 4) == 0);
478 intPtr++;
479
480 shtPtr = (short *)intPtr;
481 for (i = 0; i < dataLen; i++, shtPtr++)
482 {
483 //??????if (swap)
484 shtPtr[0] = ChunkUtils::swapShort(shtPtr[0]);
485 }
486
487 if (dataLen & 1)
488 shtPtr++;
489
490 /*
491 STRC (4 bytes)
492 <nr> amount of structs (int)
493 <typenr>
494 <nr_of_elems>
495 <typenr>
496 <namenr>
497 <typenr>
498 <namenr>
499 */
500
501 intPtr = (int *)shtPtr;
502 cp = (char *)intPtr;
503 assert(strncmp(cp, "STRC", 4) == 0);
504 intPtr++;
505
506 if (swap)
507 dataLen = ChunkUtils::swapInt(*intPtr);
508 else
509 dataLen = *intPtr;
510
511 *intPtr = ChunkUtils::swapInt(*intPtr);
512
513 intPtr++;
514
515 shtPtr = (short *)intPtr;
516 for (i = 0; i < dataLen; i++)
517 {
518 //if (swap)
519 {
520 int len = shtPtr[1];
521
522 shtPtr[0] = ChunkUtils::swapShort(shtPtr[0]);
523 shtPtr[1] = ChunkUtils::swapShort(shtPtr[1]);
524
525 shtPtr += 2;
526
527 for (int a = 0; a < len; a++, shtPtr += 2)
528 {
529 shtPtr[0] = ChunkUtils::swapShort(shtPtr[0]);
530 shtPtr[1] = ChunkUtils::swapShort(shtPtr[1]);
531 }
532 }
533 // else
534 // shtPtr+= (2*shtPtr[1])+2;
535 }
536}
537
538void bFile::writeFile(const char *fileName)
539{
540 FILE *f = fopen(fileName, "wb");
541 fwrite(mFileBuffer, 1, mFileLen, f);
542 fclose(f);
543}
544
546{
547 //const bool brokenDNA = (mFlags&FD_BROKEN_DNA)!=0;
548 //FD_ENDIAN_SWAP
549 //byte 8 determines the endianness of the file, little (v) versus big (V)
550 int littleEndian = 1;
551 littleEndian = ((char *)&littleEndian)[0];
552
553 if (mFileBuffer[8] == 'V')
554 {
555 mFileBuffer[8] = 'v';
556 }
557 else
558 {
559 mFileBuffer[8] = 'V';
560 }
561
562 mDataStart = 12;
563
564 char *dataPtr = mFileBuffer + mDataStart;
565
566 bChunkInd dataChunk;
567 dataChunk.code = 0;
568 bool ignoreEndianFlag = true;
569
570 //we always want to swap here
571
572 int seek = getNextBlock(&dataChunk, dataPtr, mFlags);
573 //dataPtr += ChunkUtils::getOffset(mFlags);
574 char *dataPtrHead = 0;
575
576 while (1)
577 {
578 // one behind
579 if (dataChunk.code == SDNA || dataChunk.code == DNA1 || dataChunk.code == TYPE || dataChunk.code == TLEN || dataChunk.code == STRC)
580 {
581 swapDNA(dataPtr);
582 break;
583 }
584 else
585 {
586 //if (dataChunk.code == DNA1) break;
587 dataPtrHead = dataPtr + ChunkUtils::getOffset(mFlags);
588
589 swapLen(dataPtr);
590 if (dataChunk.dna_nr >= 0)
591 {
592 swap(dataPtrHead, dataChunk, ignoreEndianFlag);
593 }
594 else
595 {
596 //printf("unknown chunk\n");
597 }
598 }
599
600 // next please!
601 dataPtr += seek;
602
603 seek = getNextBlock(&dataChunk, dataPtr, mFlags);
604 if (seek < 0)
605 break;
606 }
607
609 {
610 mFlags &= ~FD_ENDIAN_SWAP;
611 }
612 else
613 {
615 }
616}
617
618// ----------------------------------------------------- //
619char *bFile::readStruct(char *head, bChunkInd &dataChunk)
620{
621 bool ignoreEndianFlag = false;
622
624 swap(head, dataChunk, ignoreEndianFlag);
625
626 if (!mFileDNA->flagEqual(dataChunk.dna_nr))
627 {
628 // Ouch! need to rebuild the struct
629 short *oldStruct, *curStruct;
630 char *oldType, *newType;
631 int oldLen, curLen, reverseOld;
632
633 oldStruct = mFileDNA->getStruct(dataChunk.dna_nr);
634 oldType = mFileDNA->getType(oldStruct[0]);
635
636 oldLen = mFileDNA->getLength(oldStruct[0]);
637
638 if ((mFlags & FD_BROKEN_DNA) != 0)
639 {
640 if ((strcmp(oldType, "btQuantizedBvhNodeData") == 0) && oldLen == 20)
641 {
642 return 0;
643 }
644 if ((strcmp(oldType, "btShortIntIndexData") == 0))
645 {
646 int allocLen = 2;
647 char *dataAlloc = new char[(dataChunk.nr * allocLen) + sizeof(void*)];
648 memset(dataAlloc, 0, (dataChunk.nr * allocLen) + sizeof(void*));
649 short *dest = (short *)dataAlloc;
650 const short *src = (short *)head;
651 for (int i = 0; i < dataChunk.nr; i++)
652 {
653 dest[i] = src[i];
655 {
656 SWITCH_SHORT(dest[i]);
657 }
658 }
659 addDataBlock(dataAlloc);
660 return dataAlloc;
661 }
662 }
663
665 if (strcmp("Link", oldType) != 0)
666 {
667 reverseOld = mMemoryDNA->getReverseType(oldType);
668
669 if ((reverseOld != -1))
670 {
671 // make sure it's here
672 //assert(reverseOld!= -1 && "getReverseType() returned -1, struct required!");
673
674 //
675 curStruct = mMemoryDNA->getStruct(reverseOld);
676 newType = mMemoryDNA->getType(curStruct[0]);
677 curLen = mMemoryDNA->getLength(curStruct[0]);
678
679 // make sure it's the same
680 assert((strcmp(oldType, newType) == 0) && "internal error, struct mismatch!");
681
682 numallocs++;
683 // numBlocks * length
684
685 int allocLen = (curLen);
686 char *dataAlloc = new char[(dataChunk.nr * allocLen) + sizeof(void*)];
687 memset(dataAlloc, 0, (dataChunk.nr * allocLen) + sizeof(void*));
688
689 // track allocated
690 addDataBlock(dataAlloc);
691
692 char *cur = dataAlloc;
693 char *old = head;
694 for (int block = 0; block < dataChunk.nr; block++)
695 {
696 bool fixupPointers = true;
697 parseStruct(cur, old, dataChunk.dna_nr, reverseOld, fixupPointers);
698 mLibPointers.insert(old, (bStructHandle *)cur);
699
700 cur += curLen;
701 old += oldLen;
702 }
703 return dataAlloc;
704 }
705 }
706 else
707 {
708 //printf("Link found\n");
709 }
710 }
711 else
712 {
713//#define DEBUG_EQUAL_STRUCTS
714#ifdef DEBUG_EQUAL_STRUCTS
715 short *oldStruct;
716 char *oldType;
717 oldStruct = mFileDNA->getStruct(dataChunk.dna_nr);
718 oldType = mFileDNA->getType(oldStruct[0]);
719 printf("%s equal structure, just memcpy\n", oldType);
720#endif //
721 }
722
723 char *dataAlloc = new char[(dataChunk.len) + sizeof(void*)];
724 memset(dataAlloc, 0, dataChunk.len + sizeof(void*));
725
726 // track allocated
727 addDataBlock(dataAlloc);
728
729 memcpy(dataAlloc, head, dataChunk.len);
730 return dataAlloc;
731}
732
733// ----------------------------------------------------- //
734void bFile::parseStruct(char *strcPtr, char *dtPtr, int old_dna, int new_dna, bool fixupPointers)
735{
736 if (old_dna == -1) return;
737 if (new_dna == -1) return;
738
739 //disable this, because we need to fixup pointers/ListBase
740 if (/* DISABLES CODE */ (0)) //mFileDNA->flagEqual(old_dna))
741 {
742 short *strc = mFileDNA->getStruct(old_dna);
743 int len = mFileDNA->getLength(strc[0]);
744
745 memcpy(strcPtr, dtPtr, len);
746 return;
747 }
748
749 // Ok, now build the struct
750 char *memType, *memName, *cpc, *cpo;
751 short *fileStruct, *filePtrOld, *memoryStruct, *firstStruct;
752 int elementLength, size, revType, old_nr, new_nr, fpLen;
753 short firstStructType;
754
755 // File to memory lookup
756 memoryStruct = mMemoryDNA->getStruct(new_dna);
757 fileStruct = mFileDNA->getStruct(old_dna);
758 firstStruct = fileStruct;
759
760 filePtrOld = fileStruct;
761 firstStructType = mMemoryDNA->getStruct(0)[0];
762
763 // Get number of elements
764 elementLength = memoryStruct[1];
765 memoryStruct += 2;
766
767 cpc = strcPtr;
768 cpo = 0;
769 for (int ele = 0; ele < elementLength; ele++, memoryStruct += 2)
770 {
771 memType = mMemoryDNA->getType(memoryStruct[0]);
772 memName = mMemoryDNA->getName(memoryStruct[1]);
773
774 size = mMemoryDNA->getElementSize(memoryStruct[0], memoryStruct[1]);
775 revType = mMemoryDNA->getReverseType(memoryStruct[0]);
776
777 if (revType != -1 && memoryStruct[0] >= firstStructType && memName[0] != '*')
778 {
779 cpo = getFileElement(firstStruct, memName, memType, dtPtr, &filePtrOld);
780 if (cpo)
781 {
782 int arrayLen = mFileDNA->getArraySizeNew(filePtrOld[1]);
783 old_nr = mFileDNA->getReverseType(memType);
784 new_nr = revType;
785 fpLen = mFileDNA->getElementSize(filePtrOld[0], filePtrOld[1]);
786 if (arrayLen == 1)
787 {
788 parseStruct(cpc, cpo, old_nr, new_nr, fixupPointers);
789 }
790 else
791 {
792 char *tmpCpc = cpc;
793 char *tmpCpo = cpo;
794
795 for (int i = 0; i < arrayLen; i++)
796 {
797 parseStruct(tmpCpc, tmpCpo, old_nr, new_nr, fixupPointers);
798 tmpCpc += size / arrayLen;
799 tmpCpo += fpLen / arrayLen;
800 }
801 }
802 cpc += size;
803 cpo += fpLen;
804 }
805 else
806 cpc += size;
807 }
808 else
809 {
810 getMatchingFileDNA(fileStruct, memName, memType, cpc, dtPtr, fixupPointers);
811 cpc += size;
812 }
813 }
814}
815
816// ----------------------------------------------------- //
817static void getElement(int arrayLen, const char *cur, const char *old, char *oldPtr, char *curData)
818{
819#define getEle(value, current, type, cast, size, ptr) \
820 if (strcmp(current, type) == 0) \
821 { \
822 value = (*(cast *)ptr); \
823 ptr += size; \
824 }
825
826#define setEle(value, current, type, cast, size, ptr) \
827 if (strcmp(current, type) == 0) \
828 { \
829 (*(cast *)ptr) = (cast)value; \
830 ptr += size; \
831 }
832 double value = 0.0;
833
834 for (int i = 0; i < arrayLen; i++)
835 {
836 getEle(value, old, "char", char, sizeof(char), oldPtr);
837 setEle(value, cur, "char", char, sizeof(char), curData);
838 getEle(value, old, "short", short, sizeof(short), oldPtr);
839 setEle(value, cur, "short", short, sizeof(short), curData);
840 getEle(value, old, "ushort", unsigned short, sizeof(unsigned short), oldPtr);
841 setEle(value, cur, "ushort", unsigned short, sizeof(unsigned short), curData);
842 getEle(value, old, "int", int, sizeof(int), oldPtr);
843 setEle(value, cur, "int", int, sizeof(int), curData);
844 getEle(value, old, "long", int, sizeof(int), oldPtr);
845 setEle(value, cur, "long", int, sizeof(int), curData);
846 getEle(value, old, "float", float, sizeof(float), oldPtr);
847 setEle(value, cur, "float", float, sizeof(float), curData);
848 getEle(value, old, "double", double, sizeof(double), oldPtr);
849 setEle(value, cur, "double", double, sizeof(double), curData);
850 }
851}
852
853// ----------------------------------------------------- //
854void bFile::swapData(char *data, short type, int arraySize, bool ignoreEndianFlag)
855{
856 if (ignoreEndianFlag || (mFlags & FD_ENDIAN_SWAP))
857 {
858 if (type == 2 || type == 3)
859 {
860 short *sp = (short *)data;
861 for (int i = 0; i < arraySize; i++)
862 {
863 sp[0] = ChunkUtils::swapShort(sp[0]);
864 sp++;
865 }
866 }
867 if (type > 3 && type < 8)
868 {
869 char c;
870 char *cp = data;
871 for (int i = 0; i < arraySize; i++)
872 {
873 c = cp[0];
874 cp[0] = cp[3];
875 cp[3] = c;
876 c = cp[1];
877 cp[1] = cp[2];
878 cp[2] = c;
879 cp += 4;
880 }
881 }
882 }
883}
884
885void bFile::safeSwapPtr(char *dst, const char *src)
886{
887 int ptrFile = mFileDNA->getPointerSize();
888 int ptrMem = mMemoryDNA->getPointerSize();
889
890 if (!src && !dst)
891 return;
892
893 if (ptrFile == ptrMem)
894 {
895 memcpy(dst, src, ptrMem);
896 }
897 else if (ptrMem == 4 && ptrFile == 8)
898 {
899 btPointerUid *oldPtr = (btPointerUid *)src;
900 btPointerUid *newPtr = (btPointerUid *)dst;
901
902 if (oldPtr->m_uniqueIds[0] == oldPtr->m_uniqueIds[1])
903 {
904 //Bullet stores the 32bit unique ID in both upper and lower part of 64bit pointers
905 //so it can be used to distinguish between .blend and .bullet
906 newPtr->m_uniqueIds[0] = oldPtr->m_uniqueIds[0];
907 }
908 else
909 {
910 //deal with pointers the Blender .blend style way, see
911 //readfile.c in the Blender source tree
912 long64 longValue = *((long64 *)src);
913 //endian swap for 64bit pointer otherwise truncation will fail due to trailing zeros
915 SWITCH_LONGINT(longValue);
916 *((int *)dst) = (int)(longValue >> 3);
917 }
918 }
919 else if (ptrMem == 8 && ptrFile == 4)
920 {
921 btPointerUid *oldPtr = (btPointerUid *)src;
922 btPointerUid *newPtr = (btPointerUid *)dst;
923 if (oldPtr->m_uniqueIds[0] == oldPtr->m_uniqueIds[1])
924 {
925 newPtr->m_uniqueIds[0] = oldPtr->m_uniqueIds[0];
926 newPtr->m_uniqueIds[1] = 0;
927 }
928 else
929 {
930 *((long64 *)dst) = *((int *)src);
931 }
932 }
933 else
934 {
935 printf("%d %d\n", ptrFile, ptrMem);
936 assert(0 && "Invalid pointer len");
937 }
938}
939
940// ----------------------------------------------------- //
941void bFile::getMatchingFileDNA(short *dna_addr, const char *lookupName, const char *lookupType, char *strcData, char *data, bool fixupPointers)
942{
943 // find the matching memory dna data
944 // to the file being loaded. Fill the
945 // memory with the file data...
946
947 int len = dna_addr[1];
948 dna_addr += 2;
949
950 for (int i = 0; i < len; i++, dna_addr += 2)
951 {
952 const char *type = mFileDNA->getType(dna_addr[0]);
953 const char *name = mFileDNA->getName(dna_addr[1]);
954
955 int eleLen = mFileDNA->getElementSize(dna_addr[0], dna_addr[1]);
956
957 if ((mFlags & FD_BROKEN_DNA) != 0)
958 {
959 if ((strcmp(type, "short") == 0) && (strcmp(name, "int") == 0))
960 {
961 eleLen = 0;
962 }
963 }
964
965 if (strcmp(lookupName, name) == 0)
966 {
967 //int arrayLenold = mFileDNA->getArraySize((char*)name.c_str());
968 int arrayLen = mFileDNA->getArraySizeNew(dna_addr[1]);
969 //assert(arrayLenold == arrayLen);
970
971 if (name[0] == '*')
972 {
973 // cast pointers
974 int ptrFile = mFileDNA->getPointerSize();
975 int ptrMem = mMemoryDNA->getPointerSize();
976 safeSwapPtr(strcData, data);
977
978 if (fixupPointers)
979 {
980 if (arrayLen > 1)
981 {
982 //void **sarray = (void**)strcData;
983 //void **darray = (void**)data;
984
985 char *cpc, *cpo;
986 cpc = (char *)strcData;
987 cpo = (char *)data;
988
989 for (int a = 0; a < arrayLen; a++)
990 {
991 safeSwapPtr(cpc, cpo);
993 cpc += ptrMem;
994 cpo += ptrFile;
995 }
996 }
997 else
998 {
999 if (name[1] == '*')
1001 else
1003 }
1004 }
1005 else
1006 {
1007 // printf("skipped %s %s : %x\n",type.c_str(),name.c_str(),strcData);
1008 }
1009 }
1010
1011 else if (strcmp(type, lookupType) == 0)
1012 memcpy(strcData, data, eleLen);
1013 else
1014 getElement(arrayLen, lookupType, type, data, strcData);
1015
1016 // --
1017 return;
1018 }
1019 data += eleLen;
1020 }
1021}
1022
1023// ----------------------------------------------------- //
1024char *bFile::getFileElement(short *firstStruct, char *lookupName, char *lookupType, char *data, short **foundPos)
1025{
1026 short *old = firstStruct; //mFileDNA->getStruct(old_nr);
1027 int elementLength = old[1];
1028 old += 2;
1029
1030 for (int i = 0; i < elementLength; i++, old += 2)
1031 {
1032 char *type = mFileDNA->getType(old[0]);
1033 char *name = mFileDNA->getName(old[1]);
1034 int len = mFileDNA->getElementSize(old[0], old[1]);
1035
1036 if (strcmp(lookupName, name) == 0)
1037 {
1038 if (strcmp(type, lookupType) == 0)
1039 {
1040 if (foundPos)
1041 *foundPos = old;
1042 return data;
1043 }
1044 return 0;
1045 }
1046 data += len;
1047 }
1048 return 0;
1049}
1050
1051// ----------------------------------------------------- //
1052void bFile::swapStruct(int dna_nr, char *data, bool ignoreEndianFlag)
1053{
1054 if (dna_nr == -1) return;
1055
1056 short *strc = mFileDNA->getStruct(dna_nr);
1057 //short *firstStrc = strc;
1058
1059 int elementLen = strc[1];
1060 strc += 2;
1061
1062 short first = mFileDNA->getStruct(0)[0];
1063
1064 char *buf = data;
1065 for (int i = 0; i < elementLen; i++, strc += 2)
1066 {
1067 char *type = mFileDNA->getType(strc[0]);
1068 char *name = mFileDNA->getName(strc[1]);
1069
1070 int size = mFileDNA->getElementSize(strc[0], strc[1]);
1071 if (strc[0] >= first && name[0] != '*')
1072 {
1073 int old_nr = mFileDNA->getReverseType(type);
1074 int arrayLen = mFileDNA->getArraySizeNew(strc[1]);
1075 if (arrayLen == 1)
1076 {
1077 swapStruct(old_nr, buf, ignoreEndianFlag);
1078 }
1079 else
1080 {
1081 char *tmpBuf = buf;
1082 for (int i = 0; i < arrayLen; i++)
1083 {
1084 swapStruct(old_nr, tmpBuf, ignoreEndianFlag);
1085 tmpBuf += size / arrayLen;
1086 }
1087 }
1088 }
1089 else
1090 {
1091 //int arrayLenOld = mFileDNA->getArraySize(name);
1092 int arrayLen = mFileDNA->getArraySizeNew(strc[1]);
1093 //assert(arrayLenOld == arrayLen);
1094 swapData(buf, strc[0], arrayLen, ignoreEndianFlag);
1095 }
1096 buf += size;
1097 }
1098}
1099
1101{
1102 // printf("resolvePointersStructMismatch\n");
1103
1104 int i;
1105
1106 for (i = 0; i < m_pointerFixupArray.size(); i++)
1107 {
1108 char *cur = m_pointerFixupArray.at(i);
1109 void **ptrptr = (void **)cur;
1110 void *ptr = *ptrptr;
1111 ptr = findLibPointer(ptr);
1112 if (ptr)
1113 {
1114 //printf("Fixup pointer!\n");
1115 *(ptrptr) = ptr;
1116 }
1117 else
1118 {
1119 // printf("pointer not found: %x\n",cur);
1120 }
1121 }
1122
1123 for (i = 0; i < m_pointerPtrFixupArray.size(); i++)
1124 {
1125 char *cur = m_pointerPtrFixupArray.at(i);
1126 void **ptrptr = (void **)cur;
1127
1128 bChunkInd *block = m_chunkPtrPtrMap.find(*ptrptr);
1129 if (block)
1130 {
1131 int ptrMem = mMemoryDNA->getPointerSize();
1132 int ptrFile = mFileDNA->getPointerSize();
1133
1134 int blockLen = block->len / ptrFile;
1135
1136 void *onptr = findLibPointer(*ptrptr);
1137 if (onptr)
1138 {
1139 char *newPtr = new char[blockLen * ptrMem];
1140 addDataBlock(newPtr);
1141 memset(newPtr, 0, blockLen * ptrMem);
1142
1143 void **onarray = (void **)onptr;
1144 char *oldPtr = (char *)onarray;
1145
1146 int p = 0;
1147 while (blockLen-- > 0)
1148 {
1149 btPointerUid dp = {{0}};
1150 safeSwapPtr((char *)dp.m_uniqueIds, oldPtr);
1151
1152 void **tptr = (void **)(newPtr + p * ptrMem);
1153 *tptr = findLibPointer(dp.m_ptr);
1154
1155 oldPtr += ptrFile;
1156 ++p;
1157 }
1158
1159 *ptrptr = newPtr;
1160 }
1161 }
1162 }
1163}
1164
1166void bFile::resolvePointersChunk(const bChunkInd &dataChunk, int verboseMode)
1167{
1169
1170 short int *oldStruct = fileDna->getStruct(dataChunk.dna_nr);
1171 short oldLen = fileDna->getLength(oldStruct[0]);
1172 //char* structType = fileDna->getType(oldStruct[0]);
1173
1174 char *cur = (char *)findLibPointer(dataChunk.oldPtr);
1175 for (int block = 0; block < dataChunk.nr; block++)
1176 {
1177 resolvePointersStructRecursive(cur, dataChunk.dna_nr, verboseMode, 1);
1178 cur += oldLen;
1179 }
1180}
1181
1182int bFile::resolvePointersStructRecursive(char *strcPtr, int dna_nr, int verboseMode, int recursion)
1183{
1185
1186 char *memType;
1187 char *memName;
1188 short firstStructType = fileDna->getStruct(0)[0];
1189
1190 char *elemPtr = strcPtr;
1191
1192 short int *oldStruct = fileDna->getStruct(dna_nr);
1193
1194 int elementLength = oldStruct[1];
1195 oldStruct += 2;
1196
1197 int totalSize = 0;
1198
1199 for (int ele = 0; ele < elementLength; ele++, oldStruct += 2)
1200 {
1201 memType = fileDna->getType(oldStruct[0]);
1202 memName = fileDna->getName(oldStruct[1]);
1203
1204 int arrayLen = fileDna->getArraySizeNew(oldStruct[1]);
1205 if (memName[0] == '*')
1206 {
1207 if (arrayLen > 1)
1208 {
1209 void **array = (void **)elemPtr;
1210 for (int a = 0; a < arrayLen; a++)
1211 {
1212 if (verboseMode & FD_VERBOSE_EXPORT_XML)
1213 {
1214 for (int i = 0; i < recursion; i++)
1215 {
1216 printf(" ");
1217 }
1218 //skip the *
1219 printf("<%s type=\"pointer\"> ", &memName[1]);
1220 printf("%p ", array[a]);
1221 printf("</%s>\n", &memName[1]);
1222 }
1223
1224 array[a] = findLibPointer(array[a]);
1225 }
1226 }
1227 else
1228 {
1229 void **ptrptr = (void **)elemPtr;
1230 void *ptr = *ptrptr;
1231 if (verboseMode & FD_VERBOSE_EXPORT_XML)
1232 {
1233 for (int i = 0; i < recursion; i++)
1234 {
1235 printf(" ");
1236 }
1237 printf("<%s type=\"pointer\"> ", &memName[1]);
1238 printf("%p ", ptr);
1239 printf("</%s>\n", &memName[1]);
1240 }
1241 ptr = findLibPointer(ptr);
1242
1243 if (ptr)
1244 {
1245 // printf("Fixup pointer at 0x%x from 0x%x to 0x%x!\n",ptrptr,*ptrptr,ptr);
1246 *(ptrptr) = ptr;
1247 if (memName[1] == '*' && ptrptr && *ptrptr)
1248 {
1249 // This will only work if the given **array is continuous
1250 void **array = (void **)*(ptrptr);
1251 void *np = array[0];
1252 int n = 0;
1253 while (np)
1254 {
1255 np = findLibPointer(array[n]);
1256 if (np) array[n] = np;
1257 n++;
1258 }
1259 }
1260 }
1261 else
1262 {
1263 // printf("Cannot fixup pointer at 0x%x from 0x%x to 0x%x!\n",ptrptr,*ptrptr,ptr);
1264 }
1265 }
1266 }
1267 else
1268 {
1269 int revType = fileDna->getReverseType(oldStruct[0]);
1270 if (oldStruct[0] >= firstStructType) //revType != -1 &&
1271 {
1272 char cleanName[MAX_STRLEN];
1273 getCleanName(memName, cleanName);
1274
1275 int arrayLen = fileDna->getArraySizeNew(oldStruct[1]);
1276 int byteOffset = 0;
1277
1278 if (verboseMode & FD_VERBOSE_EXPORT_XML)
1279 {
1280 for (int i = 0; i < recursion; i++)
1281 {
1282 printf(" ");
1283 }
1284
1285 if (arrayLen > 1)
1286 {
1287 printf("<%s type=\"%s\" count=%d>\n", cleanName, memType, arrayLen);
1288 }
1289 else
1290 {
1291 printf("<%s type=\"%s\">\n", cleanName, memType);
1292 }
1293 }
1294
1295 for (int i = 0; i < arrayLen; i++)
1296 {
1297 byteOffset += resolvePointersStructRecursive(elemPtr + byteOffset, revType, verboseMode, recursion + 1);
1298 }
1299 if (verboseMode & FD_VERBOSE_EXPORT_XML)
1300 {
1301 for (int i = 0; i < recursion; i++)
1302 {
1303 printf(" ");
1304 }
1305 printf("</%s>\n", cleanName);
1306 }
1307 }
1308 else
1309 {
1310 //export a simple type
1311 if (verboseMode & FD_VERBOSE_EXPORT_XML)
1312 {
1313 if (arrayLen > MAX_ARRAY_LENGTH)
1314 {
1315 printf("too long\n");
1316 }
1317 else
1318 {
1319 //printf("%s %s\n",memType,memName);
1320
1321 bool isIntegerType = (strcmp(memType, "char") == 0) || (strcmp(memType, "int") == 0) || (strcmp(memType, "short") == 0);
1322
1323 if (isIntegerType)
1324 {
1325 const char *newtype = "int";
1326 int dbarray[MAX_ARRAY_LENGTH];
1327 int *dbPtr = 0;
1328 char *tmp = elemPtr;
1329 dbPtr = &dbarray[0];
1330 if (dbPtr)
1331 {
1332 char cleanName[MAX_STRLEN];
1333 getCleanName(memName, cleanName);
1334
1335 int i;
1336 getElement(arrayLen, newtype, memType, tmp, (char *)dbPtr);
1337 for (i = 0; i < recursion; i++)
1338 printf(" ");
1339 if (arrayLen == 1)
1340 printf("<%s type=\"%s\">", cleanName, memType);
1341 else
1342 printf("<%s type=\"%s\" count=%d>", cleanName, memType, arrayLen);
1343 for (i = 0; i < arrayLen; i++)
1344 printf(" %d ", dbPtr[i]);
1345 printf("</%s>\n", cleanName);
1346 }
1347 }
1348 else
1349 {
1350 const char *newtype = "double";
1351 double dbarray[MAX_ARRAY_LENGTH];
1352 double *dbPtr = 0;
1353 char *tmp = elemPtr;
1354 dbPtr = &dbarray[0];
1355 if (dbPtr)
1356 {
1357 int i;
1358 getElement(arrayLen, newtype, memType, tmp, (char *)dbPtr);
1359 for (i = 0; i < recursion; i++)
1360 printf(" ");
1361 char cleanName[MAX_STRLEN];
1362 getCleanName(memName, cleanName);
1363
1364 if (arrayLen == 1)
1365 {
1366 printf("<%s type=\"%s\">", memName, memType);
1367 }
1368 else
1369 {
1370 printf("<%s type=\"%s\" count=%d>", cleanName, memType, arrayLen);
1371 }
1372 for (i = 0; i < arrayLen; i++)
1373 printf(" %f ", dbPtr[i]);
1374 printf("</%s>\n", cleanName);
1375 }
1376 }
1377 }
1378 }
1379 }
1380 }
1381
1382 int size = fileDna->getElementSize(oldStruct[0], oldStruct[1]);
1383 totalSize += size;
1384 elemPtr += size;
1385 }
1386
1387 return totalSize;
1388}
1389
1391void bFile::resolvePointers(int verboseMode)
1392{
1394
1395 //char *dataPtr = mFileBuffer+mDataStart;
1396
1397 if (1) //mFlags & (FD_BITS_VARIES | FD_VERSION_VARIES))
1398 {
1400 }
1401
1402 {
1403 if (verboseMode & FD_VERBOSE_EXPORT_XML)
1404 {
1405 printf("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
1406 int numitems = m_chunks.size();
1407 printf("<bullet_physics version=%d itemcount = %d>\n", btGetVersion(), numitems);
1408 }
1409 for (int i = 0; i < m_chunks.size(); i++)
1410 {
1411 const bChunkInd &dataChunk = m_chunks.at(i);
1412
1413 if (!mFileDNA || fileDna->flagEqual(dataChunk.dna_nr))
1414 {
1415 //dataChunk.len
1416 short int *oldStruct = fileDna->getStruct(dataChunk.dna_nr);
1417 char *oldType = fileDna->getType(oldStruct[0]);
1418
1419 if (verboseMode & FD_VERBOSE_EXPORT_XML)
1420 printf(" <%s pointer=%p>\n", oldType, dataChunk.oldPtr);
1421
1422 resolvePointersChunk(dataChunk, verboseMode);
1423
1424 if (verboseMode & FD_VERBOSE_EXPORT_XML)
1425 printf(" </%s>\n", oldType);
1426 }
1427 else
1428 {
1429 //printf("skipping mStruct\n");
1430 }
1431 }
1432 if (verboseMode & FD_VERBOSE_EXPORT_XML)
1433 {
1434 printf("</bullet_physics>\n");
1435 }
1436 }
1437}
1438
1439// ----------------------------------------------------- //
1441{
1442 bStructHandle **ptrptr = getLibPointers().find(ptr);
1443 if (ptrptr)
1444 return *ptrptr;
1445 return 0;
1446}
1447
1449{
1450 int i;
1451
1452 for (i = 0; i < m_chunks.size(); i++)
1453 {
1454 bChunkInd &dataChunk = m_chunks[i];
1455 dataChunk.oldPtr = findLibPointer(dataChunk.oldPtr);
1456 }
1457}
1459{
1460 int i;
1461
1462 for (i = 0; i < m_chunks.size(); i++)
1463 {
1464 bChunkInd &dataChunk = m_chunks[i];
1465 char *codeptr = (char *)&dataChunk.code;
1466 char codestr[5] = {codeptr[0], codeptr[1], codeptr[2], codeptr[3], 0};
1467
1468 short *newStruct = dna->getStruct(dataChunk.dna_nr);
1469 char *typeName = dna->getType(newStruct[0]);
1470 printf("%3d: %s ", i, typeName);
1471
1472 printf("code=%s ", codestr);
1473
1474 printf("ptr=%p ", dataChunk.oldPtr);
1475 printf("len=%d ", dataChunk.len);
1476 printf("nr=%d ", dataChunk.nr);
1477 if (dataChunk.nr != 1)
1478 {
1479 printf("not 1\n");
1480 }
1481 printf("\n");
1482 }
1483
1484#if 0
1485 IDFinderData ifd;
1486 ifd.success = 0;
1487 ifd.IDname = NULL;
1488 ifd.just_print_it = 1;
1489 for (i=0; i<bf->m_blocks.size(); ++i)
1490 {
1491 BlendBlock* bb = bf->m_blocks[i];
1492 printf("tag='%s'\tptr=%p\ttype=%s\t[%4d]", bb->tag, bb,bf->types[bb->type_index].name,bb->m_array_entries_.size());
1493 block_ID_finder(bb, bf, &ifd);
1494 printf("\n");
1495 }
1496#endif
1497}
1498
1499void bFile::writeChunks(FILE *fp, bool fixupPointers)
1500{
1502
1503 for (int i = 0; i < m_chunks.size(); i++)
1504 {
1505 bChunkInd &dataChunk = m_chunks.at(i);
1506
1507 // Ouch! need to rebuild the struct
1508 short *oldStruct, *curStruct;
1509 char *oldType, *newType;
1510 int curLen, reverseOld;
1511
1512 oldStruct = fileDna->getStruct(dataChunk.dna_nr);
1513 oldType = fileDna->getType(oldStruct[0]);
1514 //int oldLen = fileDna->getLength(oldStruct[0]);
1516 reverseOld = mMemoryDNA->getReverseType(oldType);
1517
1518 if ((reverseOld != -1))
1519 {
1520 // make sure it's here
1521 //assert(reverseOld!= -1 && "getReverseType() returned -1, struct required!");
1522 //
1523 curStruct = mMemoryDNA->getStruct(reverseOld);
1524 newType = mMemoryDNA->getType(curStruct[0]);
1525 // make sure it's the same
1526 assert((strcmp(oldType, newType) == 0) && "internal error, struct mismatch!");
1527
1528 curLen = mMemoryDNA->getLength(curStruct[0]);
1529 dataChunk.dna_nr = reverseOld;
1530 if (strcmp("Link", oldType) != 0)
1531 {
1532 dataChunk.len = curLen * dataChunk.nr;
1533 }
1534 else
1535 {
1536 // printf("keep length of link = %d\n",dataChunk.len);
1537 }
1538
1539 //write the structure header
1540 fwrite(&dataChunk, sizeof(bChunkInd), 1, fp);
1541
1542 short int *curStruct1;
1543 curStruct1 = mMemoryDNA->getStruct(dataChunk.dna_nr);
1544 assert(curStruct1 == curStruct);
1545
1546 char *cur = fixupPointers ? (char *)findLibPointer(dataChunk.oldPtr) : (char *)dataChunk.oldPtr;
1547
1548 //write the actual contents of the structure(s)
1549 fwrite(cur, dataChunk.len, 1, fp);
1550 }
1551 else
1552 {
1553 printf("serious error, struct mismatch: don't write\n");
1554 }
1555 }
1556}
1557
1558// ----------------------------------------------------- //
1559int bFile::getNextBlock(bChunkInd *dataChunk, const char *dataPtr, const int flags)
1560{
1561 bool swap = false;
1562 bool varies = false;
1563
1564 if (flags & FD_ENDIAN_SWAP)
1565 swap = true;
1566 if (flags & FD_BITS_VARIES)
1567 varies = true;
1568
1569 if (VOID_IS_8)
1570 {
1571 if (varies)
1572 {
1573 bChunkPtr4 head;
1574 memcpy(&head, dataPtr, sizeof(bChunkPtr4));
1575
1576 bChunkPtr8 chunk;
1577
1578 chunk.code = head.code;
1579 chunk.len = head.len;
1580 chunk.m_uniqueInts[0] = head.m_uniqueInt;
1581 chunk.m_uniqueInts[1] = 0;
1582 chunk.dna_nr = head.dna_nr;
1583 chunk.nr = head.nr;
1584
1585 if (swap)
1586 {
1587 if ((chunk.code & 0xFFFF) == 0)
1588 chunk.code >>= 16;
1589
1590 SWITCH_INT(chunk.len);
1591 SWITCH_INT(chunk.dna_nr);
1592 SWITCH_INT(chunk.nr);
1593 }
1594
1595 memcpy(dataChunk, &chunk, sizeof(bChunkInd));
1596 }
1597 else
1598 {
1599 bChunkPtr8 c;
1600 memcpy(&c, dataPtr, sizeof(bChunkPtr8));
1601
1602 if (swap)
1603 {
1604 if ((c.code & 0xFFFF) == 0)
1605 c.code >>= 16;
1606
1607 SWITCH_INT(c.len);
1608 SWITCH_INT(c.dna_nr);
1609 SWITCH_INT(c.nr);
1610 }
1611
1612 memcpy(dataChunk, &c, sizeof(bChunkInd));
1613 }
1614 }
1615 else
1616 {
1617 if (varies)
1618 {
1619 bChunkPtr8 head;
1620 memcpy(&head, dataPtr, sizeof(bChunkPtr8));
1621
1622 bChunkPtr4 chunk;
1623 chunk.code = head.code;
1624 chunk.len = head.len;
1625
1626 if (head.m_uniqueInts[0] == head.m_uniqueInts[1])
1627 {
1628 chunk.m_uniqueInt = head.m_uniqueInts[0];
1629 }
1630 else
1631 {
1632 long64 oldPtr = 0;
1633 memcpy(&oldPtr, &head.m_uniqueInts[0], 8);
1634 if (swap)
1635 SWITCH_LONGINT(oldPtr);
1636 chunk.m_uniqueInt = (int)(oldPtr >> 3);
1637 }
1638
1639 chunk.dna_nr = head.dna_nr;
1640 chunk.nr = head.nr;
1641
1642 if (swap)
1643 {
1644 if ((chunk.code & 0xFFFF) == 0)
1645 chunk.code >>= 16;
1646
1647 SWITCH_INT(chunk.len);
1648 SWITCH_INT(chunk.dna_nr);
1649 SWITCH_INT(chunk.nr);
1650 }
1651
1652 memcpy(dataChunk, &chunk, sizeof(bChunkInd));
1653 }
1654 else
1655 {
1656 bChunkPtr4 c;
1657 memcpy(&c, dataPtr, sizeof(bChunkPtr4));
1658
1659 if (swap)
1660 {
1661 if ((c.code & 0xFFFF) == 0)
1662 c.code >>= 16;
1663
1664 SWITCH_INT(c.len);
1665 SWITCH_INT(c.dna_nr);
1666 SWITCH_INT(c.nr);
1667 }
1668 memcpy(dataChunk, &c, sizeof(bChunkInd));
1669 }
1670 }
1671
1672 if (dataChunk->len < 0)
1673 return -1;
1674
1675#if 0
1676 print ("----------");
1677 print (dataChunk->code);
1678 print (dataChunk->len);
1679 print (dataChunk->old);
1680 print (dataChunk->dna_nr);
1681 print (dataChunk->nr);
1682#endif
1683 return (dataChunk->len + ChunkUtils::getOffset(flags));
1684}
1685
1686//eof
#define long64
Definition: bChunk.h:20
#define SWITCH_SHORT(a)
Definition: bDefines.h:124
#define TYPE
Definition: bDefines.h:106
#define TLEN
Definition: bDefines.h:107
#define STRC
Definition: bDefines.h:108
#define SWITCH_LONGINT(a)
Definition: bDefines.h:134
#define SWITCH_INT(a)
Definition: bDefines.h:111
#define DNA1
Definition: bDefines.h:101
#define SDNA
Definition: bDefines.h:105
#define setEle(value, current, type, cast, size, ptr)
const char * getCleanName(const char *memName, char *buffer)
Definition: bFile.cpp:32
static void getElement(int arrayLen, const char *cur, const char *old, char *oldPtr, char *curData)
Definition: bFile.cpp:817
#define MAX_ARRAY_LENGTH
Definition: bFile.cpp:28
#define MAX_STRLEN
Definition: bFile.cpp:30
#define SIZEOFBLENDERHEADER
Definition: bFile.cpp:27
int numallocs
Definition: bFile.cpp:52
#define getEle(value, current, type, cast, size, ptr)
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
const T & btMin(const T &a, const T &b)
Definition: btMinMax.h:21
int btGetVersion()
Definition: btScalar.h:30
T * btAlignPointer(T *unalignedPtr, size_t alignment)
align a pointer to the provided alignment, upwards
Definition: btScalar.h:814
static int getOffset(int flags)
Definition: bChunk.cpp:49
static short swapShort(short sht)
Definition: bChunk.cpp:28
static int swapInt(int inte)
Definition: bChunk.cpp:35
void * oldPtr
Definition: bChunk.h:63
int m_uniqueInts[2]
Definition: bChunk.h:52
int getArraySizeNew(short name)
Definition: bDNA.h:40
int getPointerSize()
Definition: bDNA.cpp:125
short getLength(int ind)
Definition: bDNA.cpp:69
void initCmpFlags(bDNA *memDNA)
Definition: bDNA.cpp:164
void init(char *data, int len, bool swap=false)
Definition: bDNA.cpp:345
bool flagEqual(int dna_nr)
Definition: bDNA.cpp:110
char * getName(int ind)
Definition: bDNA.cpp:48
int getNumNames() const
Definition: bDNA.h:52
void dumpTypeDefinitions()
Definition: bDNA.cpp:524
bool lessThan(bDNA *other)
Definition: bDNA.cpp:42
int getReverseType(short type)
Definition: bDNA.cpp:76
short * getStruct(int ind)
Definition: bDNA.cpp:62
int getElementSize(short type, short name)
Definition: bDNA.h:45
char * getType(int ind)
Definition: bDNA.cpp:55
bFile(const char *filename, const char headerString[7])
Definition: bFile.cpp:55
int mFileLen
Definition: bFile.h:55
bDNA * mMemoryDNA
Definition: bFile.h:62
virtual ~bFile()
Definition: bFile.cpp:111
virtual void addDataBlock(char *dataBlock)=0
void swap(char *head, class bChunkInd &ch, bool ignoreEndianFlag)
Definition: bFile.cpp:308
btAlignedObjectArray< char * > m_pointerFixupArray
Definition: bFile.h:64
void resolvePointersChunk(const bChunkInd &dataChunk, int verboseMode)
this loop only works fine if the Blender DNA structure of the file matches the headerfiles
Definition: bFile.cpp:1166
virtual void parseInternal(int verboseMode, char *memDna, int memDnaLength)
Definition: bFile.cpp:195
void writeFile(const char *fileName)
Definition: bFile.cpp:538
virtual void parseData()=0
btAlignedObjectArray< char * > m_pointerPtrFixupArray
Definition: bFile.h:65
virtual void setFileDNA(int verboseMode, char *buffer, int len)
Definition: bFile.cpp:183
virtual void parseHeader()
Definition: bFile.cpp:124
btAlignedObjectArray< bChunkInd > m_chunks
Definition: bFile.h:67
int mDataStart
Definition: bFile.h:60
void parseStruct(char *strcPtr, char *dtPtr, int old_dna, int new_dna, bool fixupPointers)
Definition: bFile.cpp:734
bPtrMap & getLibPointers()
Definition: bFile.h:132
btHashMap< btHashPtr, bChunkInd > m_chunkPtrPtrMap
Definition: bFile.h:68
void dumpChunks(bDNA *dna)
Definition: bFile.cpp:1458
int mVersion
Definition: bFile.h:56
void resolvePointers(int verboseMode)
Resolve pointers replaces the original pointers in structures, and linked lists by the new in-memory ...
Definition: bFile.cpp:1391
char * readStruct(char *head, class bChunkInd &chunk)
Definition: bFile.cpp:619
bPtrMap mLibPointers
Definition: bFile.h:58
virtual void writeChunks(FILE *fp, bool fixupPointers)
Definition: bFile.cpp:1499
char * mFileBuffer
Definition: bFile.h:54
void updateOldPointers()
Definition: bFile.cpp:1448
void swapLen(char *dataPtr)
Definition: bFile.cpp:334
int getNextBlock(bChunkInd *dataChunk, const char *dataPtr, const int flags)
Definition: bFile.cpp:1559
void safeSwapPtr(char *dst, const char *src)
Definition: bFile.cpp:885
char * getFileElement(short *firstStruct, char *lookupName, char *lookupType, char *data, short **foundPos)
Definition: bFile.cpp:1024
int resolvePointersStructRecursive(char *strcPtr, int old_dna, int verboseMode, int recursion)
Definition: bFile.cpp:1182
char m_headerString[7]
Definition: bFile.h:51
bool mOwnsBuffer
Definition: bFile.h:53
void resolvePointersMismatch()
Definition: bFile.cpp:1100
void swapStruct(int dna_nr, char *data, bool ignoreEndianFlag)
Definition: bFile.cpp:1052
void swapData(char *data, short type, int arraySize, bool ignoreEndianFlag)
Definition: bFile.cpp:854
int mFlags
Definition: bFile.h:74
void swapDNA(char *ptr)
Definition: bFile.cpp:382
void * findLibPointer(void *ptr)
Definition: bFile.cpp:1440
bool ok()
Definition: bFile.cpp:178
bDNA * mFileDNA
Definition: bFile.h:61
void preSwap()
Definition: bFile.cpp:545
void getMatchingFileDNA(short *old, const char *lookupName, const char *lookupType, char *strcData, char *data, bool fixupPointers)
Definition: bFile.cpp:941
int size() const
return the number of elements in the array
void push_back(const T &_Val)
const T & at(int n) const
void insert(const Key &key, const Value &value)
Definition: btHashMap.h:264
const Value * find(const Key &key) const
Definition: btHashMap.h:424
const bool VOID_IS_8
Definition: bChunk.h:81
@ FD_ENDIAN_SWAP
Definition: bFile.h:31
@ FD_FILE_64
Definition: bFile.h:32
@ FD_VERSION_VARIES
Definition: bFile.h:34
@ FD_FILEDNA_IS_MEMDNA
Definition: bFile.h:37
@ FD_INVALID
Definition: bFile.h:28
@ FD_BROKEN_DNA
Definition: bFile.h:36
@ FD_OK
Definition: bFile.h:29
@ FD_BITS_VARIES
Definition: bFile.h:33
@ FD_DOUBLE_PRECISION
Definition: bFile.h:35
@ FD_VERBOSE_DUMP_DNA_TYPE_DEFINITIONS
Definition: bFile.h:43
@ FD_VERBOSE_EXPORT_XML
Definition: bFile.h:42
int m_uniqueIds[2]
Definition: btSerializer.h:129