Initial revision
[blender.git] / source / blender / blenkernel / intern / blender.c
1
2 /*  blender.c   jan 94     MIXED MODEL
3  * 
4  * algemene hulp funkties en data
5  * 
6  * $Id$
7  *
8  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version. The Blender
14  * Foundation also sells licenses for use in proprietary software under
15  * the Blender License.  See http://www.blender.org/BL/ for information
16  * about this.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
26  *
27  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
28  * All rights reserved.
29  *
30  * The Original Code is: all of this file.
31  *
32  * Contributor(s): none yet.
33  *
34  * ***** END GPL/BL DUAL LICENSE BLOCK *****
35  */
36
37 #ifndef WIN32 
38     #include <unistd.h> // for read close
39     #include <sys/param.h> // for MAXPATHLEN
40 #else
41     #include <io.h> // for open close read
42 #endif
43
44 #include <stdlib.h>
45 #include <stdio.h>
46 #include <string.h>
47 #include <fcntl.h> // for open
48
49 #include "MEM_guardedalloc.h"
50 #include "DNA_listBase.h"
51 #include "DNA_sdna_types.h"
52 #include "DNA_userdef_types.h"
53 #include "DNA_object_types.h"
54 #include "DNA_curve_types.h"
55
56 #include "BLI_blenlib.h"
57 #include "IMB_imbuf_types.h"
58 #include "IMB_imbuf.h"
59
60 #ifdef WIN32
61 #include "BLI_winstuff.h"
62 #endif
63
64 #include "DNA_screen_types.h"
65
66 #include "BKE_library.h"
67 #include "BKE_blender.h"
68 #include "BKE_displist.h"
69 #include "BKE_global.h"
70 #include "BKE_main.h"
71 #include "BKE_object.h"
72 #include "BKE_scene.h"
73 #include "BKE_effect.h"
74 #include "BKE_curve.h"
75 #include "BKE_font.h"
76
77 #include "BKE_bad_level_calls.h" /* for BPY_do_pyscript */
78
79 #include "BLO_readfile.h" /* for BLO_read_file */
80
81 #include "BKE_bad_level_calls.h" // for freeAllRad editNurb free_editMesh free_editText free_editArmature
82 #include "BKE_utildefines.h" // O_BINARY FALSE
83
84 #include "nla.h"
85
86 Global G;
87 UserDef U;
88
89 char versionstr[48]= "";
90
91 /* ************************************************ */
92 /* pushpop faciliteit: om tijdelijk data te bewaren */
93
94 ListBase ppmain={0, 0};
95
96 typedef struct PushPop {
97         struct PushPop *next, *prev;
98         void *data;
99         int len;
100 } PushPop;
101
102 void pushdata(void *data, int len)
103 {
104         PushPop *pp;
105         
106         pp= MEM_mallocN(sizeof(PushPop), "pushpop");
107         BLI_addtail(&ppmain, pp);
108         pp->data= MEM_mallocN(len, "pushpop");
109         pp->len= len;
110         memcpy(pp->data, data, len);
111 }
112
113 void popfirst(void *data)
114 {
115         PushPop *pp;
116         
117         pp= ppmain.first;
118         if(pp) {
119                 memcpy(data, pp->data, pp->len);
120                 BLI_remlink(&ppmain, pp);
121                 MEM_freeN(pp->data);
122                 MEM_freeN(pp);
123         }
124         else printf("error in popfirst\n");
125 }
126
127 void poplast(void *data)
128 {
129         PushPop *pp;
130         
131         pp= ppmain.last;
132         if(pp) {
133                 memcpy(data, pp->data, pp->len);
134                 BLI_remlink(&ppmain, pp);
135                 MEM_freeN(pp->data);
136                 MEM_freeN(pp);
137         }
138         else printf("error in poplast\n");
139 }
140
141 void free_pushpop()
142 {
143         PushPop *pp;
144
145         pp= ppmain.first;
146         while(pp) {
147                 BLI_remlink(&ppmain, pp);
148                 MEM_freeN(pp->data);
149                 MEM_freeN(pp);
150         }       
151 }
152
153 void pushpop_test()
154 {
155         if(ppmain.first) printf("pushpop not empty\n");
156         free_pushpop();
157 }
158
159
160
161 /* ********** vrijgeven ********** */
162
163 void free_blender(void)
164 {
165         free_main(G.main);
166         G.main= NULL;
167
168         IMB_freeImBufdata();            /* imbuf lib */
169 }
170
171 void duplicatelist(ListBase *list1, ListBase *list2)  /* kopie van 2 naar 1 */
172 {
173         struct Link *link1, *link2;
174         
175         list1->first= list1->last= 0;
176         
177         link2= list2->first;
178         while(link2) {
179
180                 link1= MEM_dupallocN(link2);
181                 BLI_addtail(list1, link1);
182                 
183                 link2= link2->next;
184         }       
185 }
186
187 void initglobals(void)
188 {
189         memset(&G, 0, sizeof(Global));
190         
191         U.savetime= 1;
192
193         G.animspeed= 4;
194
195         G.main= MEM_callocN(sizeof(Main), "initglobals");
196
197         strcpy(G.ima, "//");
198
199         G.version= BLENDER_VERSION;
200
201         G.order= 1;
202         G.order= (((char*)&G.order)[0])?L_ENDIAN:B_ENDIAN;
203
204         sprintf(versionstr, "www.blender.nl %d", G.version);
205
206         clear_workob(); /* object.c */
207 }
208
209 /***/
210
211 static void clear_global(void) {
212         extern short winqueue_break;    /* screen.c */
213
214         freeAllRad();
215         free_main(G.main); /* free all lib data */
216         freefastshade();        /* anders oude lampgegevens */
217
218
219         /* hangende vars voorkomen */   
220         R.backbuf= 0;
221         
222         /* force all queues to be left */
223         winqueue_break= 1;
224         
225         if (G.obedit) {
226                 freeNurblist(&editNurb);
227                 free_editMesh();
228                 free_editText();
229                 free_editArmature();
230         }
231
232         G.curscreen= NULL;
233         G.scene= NULL;
234         G.main= NULL;
235         
236         G.obedit= NULL;
237         G.obpose= NULL;
238         G.saction= NULL;
239         G.buts= NULL;
240         G.v2d= NULL;
241         G.vd= NULL;
242         G.soops= NULL;
243         G.sima= NULL;
244         G.sipo= NULL;
245         
246         G.f &= ~(G_WEIGHTPAINT + G_VERTEXPAINT + G_FACESELECT);
247 }
248
249 static void setup_app_data(BlendFileData *bfd, char *filename) {
250         Object *ob;
251         
252         clear_global();
253         
254         G.save_over = 1;
255         
256         G.main= bfd->main;
257         if (bfd->user) {
258                 U= *bfd->user;
259                 MEM_freeN(bfd->user);
260         }
261         
262         R.winpos= bfd->winpos;
263         R.displaymode= bfd->displaymode;
264         G.curscreen= bfd->curscreen;
265         G.fileflags= bfd->fileflags;
266         
267         G.scene= G.curscreen->scene;
268         
269                 /* weinig DispListen, wel text_to_curve */
270         // this should be removed!!! But first a better displist system (ton)
271         for (ob= G.main->object.first; ob; ob= ob->id.next) {
272                 if(ob->type==OB_FONT) {
273                         Curve *cu= ob->data;
274                         if(cu->nurb.first==0) text_to_curve(ob, 0);
275                 }
276                 else if(ob->type==OB_MESH) {
277                         makeDispList(ob);
278                         if(ob->effect.first) object_wave(ob);
279                 }
280         }
281         
282         if (!G.background) {
283                 setscreen(G.curscreen);
284         }
285                 /* baseflags */
286         set_scene_bg(G.scene);
287         
288         if (G.f & G_SCENESCRIPT) {
289                 BPY_do_pyscript(&G.scene->id, SCRIPT_ONLOAD);
290         }
291         
292         strcpy(G.sce, filename);
293         strcpy(G.main->name, filename); /* is gegarandeerd current file */
294         
295         MEM_freeN(bfd);
296 }
297
298 int BKE_read_file(char *dir, void *type_r) {
299         BlendReadError bre;
300         BlendFileData *bfd;
301         
302         if (!G.background)
303                 waitcursor(1);
304                 
305         bfd= BLO_read_from_file(dir, &bre);
306         if (bfd) {
307                 if (type_r)
308                         *((BlenFileType*)type_r)= bfd->type;
309                 
310                 setup_app_data(bfd, dir);
311         } else {
312                 error("Loading %s failed: %s", dir, BLO_bre_as_string(bre));
313         }
314         
315         if (!G.background)
316                 waitcursor(0);
317         
318         return (bfd?1:0);
319 }
320
321 int BKE_read_file_from_memory(char* filebuf, int filelength, void *type_r)
322 {
323         BlendReadError bre;
324         BlendFileData *bfd;
325         
326         if (!G.background)
327                 waitcursor(1);
328                 
329         bfd= BLO_read_from_memory(filebuf, filelength, &bre);
330         if (bfd) {
331                 if (type_r)
332                         *((BlenFileType*)type_r)= bfd->type;
333                 
334                 setup_app_data(bfd, "<memory>");
335         } else {
336                 error("Loading failed: %s", BLO_bre_as_string(bre));
337         }
338         
339         if (!G.background)
340                 waitcursor(0);
341         
342         return (bfd?1:0);
343 }