Imported Upstream version 2.81
[platform/upstream/libbullet.git] / Extras / Serialize / BlenderSerialize / bBlenderFile.cpp
1 /*
2 bParse
3 Copyright (c) 2006-2009 Charlie C & Erwin Coumans  http://gamekit.googlecode.com
4
5 This software is provided 'as-is', without any express or implied warranty.
6 In no event will the authors be held liable for any damages arising from the use of this software.
7 Permission is granted to anyone to use this software for any purpose,
8 including commercial applications, and to alter it and redistribute it freely,
9 subject to the following restrictions:
10
11 1. 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.
12 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
13 3. This notice may not be removed or altered from any source distribution.
14 */
15
16 #include "bBlenderFile.h"
17 #include "bMain.h"
18 #include "bDefines.h"
19 #include "bDNA.h"
20 #include <stdio.h>
21 #include <string.h>
22
23 // 32 && 64 bit versions
24 extern unsigned char DNAstr[];
25 extern int DNAlen;
26
27 extern unsigned char DNAstr64[];
28 extern int DNAlen64;
29
30
31 using namespace bParse;
32
33 bBlenderFile::bBlenderFile(const char* fileName)
34 :bFile(fileName, "BLENDER")
35 {
36         mMain= new bMain(this, fileName, mVersion);
37 }
38
39
40
41 bBlenderFile::bBlenderFile(char *memoryBuffer, int len)
42 :bFile(memoryBuffer,len, "BLENDER"),
43 mMain(0)
44 {
45         mMain= new bMain(this, "memoryBuf", mVersion);
46 }
47
48
49 bBlenderFile::~bBlenderFile()
50 {
51         delete mMain;
52 }
53
54
55 bMain* bBlenderFile::getMain()
56 {
57         return mMain;
58 }
59
60 // ----------------------------------------------------- //
61 void bBlenderFile::parseData()
62 {
63 //      printf ("Building datablocks\n");
64 //      printf ("Chunk size = %d\n",CHUNK_HEADER_LEN);
65 //      printf ("File chunk size = %d\n", ChunkUtils::getOffset(mFlags));
66
67         const bool swap = (mFlags&FD_ENDIAN_SWAP)!=0;
68         
69
70
71         char *dataPtr = mFileBuffer+mDataStart;
72
73         bChunkInd dataChunk;
74         dataChunk.code = 0;
75
76
77         //dataPtr += ChunkUtils::getNextBlock(&dataChunk, dataPtr, mFlags);
78         int seek = getNextBlock(&dataChunk, dataPtr, mFlags);
79         //dataPtr += ChunkUtils::getOffset(mFlags);
80         char *dataPtrHead = 0;
81
82         while (dataChunk.code != DNA1)
83         {
84                 
85
86
87
88                 // one behind
89                 if (dataChunk.code == SDNA) break;
90                 //if (dataChunk.code == DNA1) break;
91
92                 // same as (BHEAD+DATA dependency)
93                 dataPtrHead = dataPtr+ChunkUtils::getOffset(mFlags);
94                 char *id = readStruct(dataPtrHead, dataChunk);
95
96                 // lookup maps
97                 if (id)
98                 {
99             m_chunkPtrPtrMap.insert(dataChunk.oldPtr, dataChunk);
100                         mLibPointers.insert(dataChunk.oldPtr, (bStructHandle*)id);
101
102                         m_chunks.push_back(dataChunk);
103                         // block it
104                         bListBasePtr *listID = mMain->getListBasePtr(dataChunk.code);
105                         if (listID)
106                                 listID->push_back((bStructHandle*)id);
107                 }
108
109                 if (dataChunk.code == GLOB)
110                 {
111                         m_glob = (bStructHandle*) id;
112                 }
113
114                 // next please!
115                 dataPtr += seek;
116
117                 seek =  getNextBlock(&dataChunk, dataPtr, mFlags);
118                 if (seek < 0)
119                         break;
120         }
121
122 }
123
124 void    bBlenderFile::addDataBlock(char* dataBlock)
125 {
126         mMain->addDatablock(dataBlock);
127 }
128
129
130
131
132
133 // 32 && 64 bit versions
134 extern unsigned char DNAstr[];
135 extern int DNAlen;
136
137 //unsigned char DNAstr[]={0};
138 //int DNAlen=0;
139
140
141 extern unsigned char DNAstr64[];
142 extern int DNAlen64;
143
144
145 void    bBlenderFile::writeDNA(FILE* fp)
146 {
147
148         bChunkInd dataChunk;
149         dataChunk.code = DNA1;
150         dataChunk.dna_nr = 0;
151         dataChunk.nr = 1;
152         
153         if (VOID_IS_8)
154         {
155                 dataChunk.len = DNAlen64;
156                 dataChunk.oldPtr = DNAstr64;
157                 fwrite(&dataChunk,sizeof(bChunkInd),1,fp);
158                 fwrite(DNAstr64, DNAlen64,1,fp);
159         }
160         else
161         {
162                 dataChunk.len = DNAlen;
163                 dataChunk.oldPtr = DNAstr;
164                 fwrite(&dataChunk,sizeof(bChunkInd),1,fp);
165                 fwrite(DNAstr, DNAlen,1,fp);
166         }
167 }
168
169 void    bBlenderFile::parse(int verboseMode)
170 {
171         if (VOID_IS_8)
172         {
173                 parseInternal(verboseMode,(char*)DNAstr64,DNAlen64);
174         }
175         else
176         {
177                 parseInternal(verboseMode,(char*)DNAstr,DNAlen);
178         }
179 }
180
181 // experimental
182 int             bBlenderFile::write(const char* fileName, bool fixupPointers)
183 {
184         FILE *fp = fopen(fileName, "wb");
185         if (fp)
186         {
187                 char header[SIZEOFBLENDERHEADER] ;
188                 memcpy(header, m_headerString, 7);
189                 int endian= 1;
190                 endian= ((char*)&endian)[0];
191
192                 if (endian)
193                 {
194                         header[7] = '_';
195                 } else
196                 {
197                         header[7] = '-';
198                 }
199                 if (VOID_IS_8)
200                 {
201                         header[8]='V';
202                 } else
203                 {
204                         header[8]='v';
205                 }
206
207                 header[9] = '2';
208                 header[10] = '4';
209                 header[11] = '9';
210                 
211                 fwrite(header,SIZEOFBLENDERHEADER,1,fp);
212
213                 writeChunks(fp, fixupPointers);
214
215                 writeDNA(fp);
216
217                 fclose(fp);
218                 
219         } else
220         {
221                 printf("Error: cannot open file %s for writing\n",fileName);
222                 return 0;
223         }
224         return 1;
225 }