34175d042898e08dc7dce760a2bd1db088bfe151
[blender.git] / source / creator / creator.c
1 /* 
2  * $Id$
3  *
4  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. The Blender
10  * Foundation also sells licenses for use in proprietary software under
11  * the Blender License.  See http://www.blender.org/BL/ for information
12  * about this.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22  *
23  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24  * All rights reserved.
25  *
26  * The Original Code is: all of this file.
27  *
28  * Contributor(s): none yet.
29  *
30  * ***** END GPL/BL DUAL LICENSE BLOCK *****
31  */
32
33 #include <stdlib.h>
34
35 #ifdef HAVE_CONFIG_H
36 #include <config.h>
37 #endif
38
39 /* This little block needed for linking to Blender... */
40
41 #include "MEM_guardedalloc.h"
42
43 #ifdef WIN32
44 #include "BLI_winstuff.h"
45 #endif
46
47 #include "GEN_messaging.h"
48
49 #include "DNA_ID.h"
50
51 #include "BLI_blenlib.h"
52
53 #include "BKE_utildefines.h"
54 #include "BKE_blender.h"
55 #include "BKE_global.h"
56 #include "BKE_main.h"
57 #include "BKE_scene.h"
58
59 #include "BIF_gl.h"
60 #include "BIF_graphics.h"
61 #include "BIF_mainqueue.h"
62 #include "BIF_graphics.h"
63 #include "BIF_editsound.h"
64 #include "BIF_usiblender.h"
65 #include "BIF_drawscene.h"      /* set_scene() */
66 #include "BIF_screen.h"         /* waitcursor and more */
67 #include "BIF_usiblender.h"
68 #include "BIF_toolbox.h"
69
70 #include "BLO_writefile.h"
71 #include "BLO_readfile.h"
72
73 #include "BPY_extern.h"  // for init of blender python extension
74
75 #include "BSE_headerbuttons.h" // for BIF_read_homefile
76
77 #include "BDR_drawmesh.h"
78
79 #include "RE_renderconverter.h"
80
81 #include "playanim_ext.h"
82 #include "mydevice.h"
83 #include "render.h"
84 #include "nla.h"
85
86 /* for passing information between creator and gameengine */
87 #include "SYS_System.h"
88
89 #include <signal.h>
90 #ifdef __FreeBSD__
91   #ifndef __OpenBSD__
92     #include <floatingpoint.h>
93     #include <sys/rtprio.h>
94   #endif
95 #endif
96
97 #ifdef WITH_QUICKTIME
98 #ifdef _WIN32
99 #include <QTML.h>
100 #include <Movies.h>
101 #elif defined(__APPLE__)
102 #undef NDEBUG
103 #include <QuickTime/Movies.h>
104 #endif /* __APPLE__ */
105 #endif /* WITH_QUICKTIME */
106
107 // from buildinfo.c
108 extern char * build_date;
109 extern char * build_time;
110 extern char * build_platform;
111 extern char * build_type;
112
113 /*      Local Function prototypes */
114 static void print_help();
115
116 /* for the callbacks: */
117
118 extern int pluginapi_force_ref(void);  /* from blenpluginapi:pluginapi.c */
119
120 char bprogname[FILE_MAXDIR+FILE_MAXFILE];
121
122 /* Initialise callbacks for the modules that need them */
123 void setCallbacks(void); 
124
125 static void fpe_handler(int sig)
126 {
127         // printf("SIGFPE trapped\n");
128 }
129
130 static void print_help(void)
131 {
132                                 printf ("Blender V %d.%02d\n", G.version/100, G.version%100);
133                                 printf ("Usage: blender [options ...] [file]\n");
134                                 
135                                 printf ("\nRender options:\n");
136                                 printf ("  -b <file>\tRender <file> in background\n");
137                                 printf ("    -S <name>\tSet scene <name>\n");                           
138                                 printf ("    -f <frame>\tRender frame <frame> and save it\n");                          
139                                 printf ("    -s <frame>\tSet start to frame <frame> (use with -a)\n");
140                                 printf ("    -e <frame>\tSet end to frame (use with -a)<frame>\n");
141                                 printf ("    -a\t\tRender animation\n");
142                                 
143                                 printf ("\nAnimation options:\n");
144                                 printf ("  -a <file(s)>\tPlayback <file(s)>\n");
145                                 printf ("    -p <sx> <sy>\tOpen with lower left corner at <sx>, <sy>\n");
146                                 printf ("    -m\t\tRead from disk (Don't buffer)\n");
147                                 
148                                 printf ("\nWindow options:\n");
149                                 printf ("  -w\t\tForce opening with borders\n");
150 #ifdef WIN32
151                                 printf ("  -W\t\tForce opening without borders\n");
152 #endif                          
153                                 printf ("  -p <sx> <sy> <w> <h>\tOpen with lower left corner at <sx>, <sy>\n");
154                                 printf ("                      \tand width and height <w>, <h>\n");
155                                 printf ("\nGame Engine specific options:\n");
156                                 printf ("  -g fixedtime\t\tRun on 50 hertz without dropping frames\n");
157                                 printf ("  -g vertexarrays\tUse Vertex Arrays for rendering (usually faster)\n");
158                                 printf ("  -g noaudio\t\tNo audio in Game Engine\n");
159                                 printf ("  -g nomipmap\t\tNo Texture Mipmapping\n");
160                                 printf ("  -g linearmipmap\tLinear Texture Mipmapping instead of Nearest (default)\n");
161                                 
162                                 
163                                 
164                                 
165                                 printf ("\nMisc options:\n");
166                                 printf ("  -d\t\tTurn debugging on\n");
167                                 printf ("  -noaudio\tDisable audio on systems that support audio\n");
168                                 printf ("  -h\t\tPrint this help text\n");
169                                 printf ("  -y\t\tDisable OnLoad scene scripts, use -Y to find out why its -y\n");
170 #ifdef WIN32
171                                 printf ("  -R\t\tRegister .blend extension\n");
172 #endif
173 }
174
175
176 double PIL_check_seconds_timer(void);
177 extern void winlay_get_screensize(int *width_r, int *height_r);
178 int main(int argc, char **argv) 
179 {
180         int a, i, stax, stay, sizx, sizy;
181         SYS_SystemHandle syshandle;
182         Scene *sce;
183
184 #if defined(WIN32) || defined (__linux__)
185         int audio = 1;
186 #else
187         int audio = 0;
188 #endif
189
190         setCallbacks();
191
192 #ifdef __APPLE__
193                 /* patch to ignore argument finder gives us (pid?) */
194         if (argc==2 && strncmp(argv[1], "-psn_", 5)==0) {
195                 extern int GHOST_HACK_getFirstFile(char buf[]);
196                 static char firstfilebuf[512];
197                 
198                 argc= 1;
199                 
200                 if (GHOST_HACK_getFirstFile(firstfilebuf)) {
201                         argc= 2;
202                         argv[1]= firstfilebuf;
203                 }
204         }
205
206         winlay_get_screensize(&sizx, &sizy);
207         
208         /* make the main windows slightly smaller than the screen,
209          * to prevent it from hiding behind the menu bar */
210         setprefsize(0, 0, sizx, sizy-45);
211         
212         winlay_process_events(0);
213 #endif
214
215 #ifdef __FreeBSD__
216         fpsetmask(0);
217 #endif
218 #ifdef __linux__
219     #ifdef __alpha__
220         signal (SIGFPE, fpe_handler);
221     #endif
222 #endif
223 #if defined(__sgi)
224         signal (SIGFPE, fpe_handler);
225 #endif
226
227         // copy path to executable in bprogname. playanim and creting runtimes
228         // need this.
229
230         BLI_where_am_i(bprogname, argv[0]);
231         
232                 /* Hack - force inclusion of the plugin api functions,
233                  * see blenpluginapi:pluginapi.c
234                  */
235         pluginapi_force_ref();
236         
237         initglobals();  /* blender.c */
238
239         syshandle = SYS_GetSystem();
240         GEN_init_messaging_system();
241
242         /* first test for background */
243         G.f |= G_SCENESCRIPT; /* scenescript always set! */
244         for(a=1; a<argc; a++) {
245
246                 /* Handle unix and windows style help requests */
247                 if ((!strcmp(argv[a], "--help")) || (!strcmp(argv[a], "/?"))){
248                         print_help();
249                         exit(0);
250                 }
251
252                 /* Handle -* switches */
253                 else if(argv[a][0] == '-') {
254                         switch(argv[a][1]) {
255                         case 'a':
256                                 playanim(argc-1, argv+1);
257                                 exit(0);
258                                 break;
259                         case 'b':
260                         case 'B':
261                                 G.background = 1;
262                                 a= argc;
263                                 break;
264
265          case 'm':
266              /* unified render pipeline */
267 /*               G.magic = 1; has become obsolete */
268                          printf("-m: enable unified renderer has become obsolete. Set \n");
269                          printf("\tthis option per individual file now.\n");
270              break;
271
272                         case 'y':
273                                 G.f &= ~G_SCENESCRIPT;
274                                 break;
275
276                         case 'Y':
277                                 printf ("-y was used to disable scene scripts because,\n");
278                                 printf ("\t-p being taken, Ton was of the opinion that Y\n");
279                                 printf ("\tlooked like a split (disabled) snake, and also\n");
280                                 printf ("\twas similar to a python's tongue (unproven).\n\n");
281
282                                 printf ("\tZr agreed because it gave him a reason to add a\n");
283                                 printf ("\tcompletely useless text into Blender.\n\n");
284                                 
285                                 printf ("\tADDENDUM! Ton, in defense, found this picture of\n");
286                                 printf ("\tan Australian python, exhibiting her (his/its) forked\n");
287                                 printf ("\tY tongue. It could be part of an H Zr retorted!\n\n");
288                                 printf ("\thttp://www.users.bigpond.com/snake.man/\n");
289                                 
290                                 exit(252);
291                                 
292                         case 'h':                       
293                                 print_help();
294                                 exit(0);
295                                                                 
296                         default:
297                                 break;
298                         }
299                 }
300         }
301
302 #ifdef __sgi
303         setuid(getuid()); /* end superuser */
304 #endif
305
306         RE_init_render_data();  /* must be called here because R.winpos from default file */
307         
308         if(G.background==0) {
309                 for(a=1; a<argc; a++) {
310                         if(argv[a][0] == '-') {
311                                 switch(argv[a][1]) {
312                                 case 'p':       /* prefsize */
313                                         if (argc-a < 5) {
314                                                 printf ("-p requires four arguments\n");
315                                                 exit(1);
316                                         }
317                                         a++;
318                                         stax= atoi(argv[a]);
319                                         a++;
320                                         stay= atoi(argv[a]);
321                                         a++;
322                                         sizx= atoi(argv[a]);
323                                         a++;
324                                         sizy= atoi(argv[a]);
325         
326                                         setprefsize(stax, stay, sizx, sizy);
327                                         break;
328                                 case 'd':
329                                         G.f |= G_DEBUG;         /* std output printf's */ 
330                                         printf ("Blender V %d.%02d\n", G.version/100, G.version%100);
331 #ifdef NAN_BUILDINFO
332                                         printf("Build: %s %s %s %s\n", build_date, build_time, build_platform, build_type);
333
334 #endif // NAN_BUILDINFO
335                                         for (i = 0; i < argc; i++) {
336                                                 printf("argv[%d] = %s\n", i, argv[i]);
337                                         }
338                                         break;
339             
340                                 case 'w':
341                                         /* XXX, fixme zr, with borders */
342                                         /* there probably is a better way to do
343                                          * this, right now do as if blender was
344                                          * called with "-p 0 0 xres yres" -- sgefant
345                                          */ 
346                                         winlay_get_screensize(&sizx, &sizy);
347                                         setprefsize(0, 0, sizx, sizy);
348 #ifdef _WIN32   // FULLSCREEN
349                                         G.windowstate = G_WINDOWSTATE_BORDER;
350 #endif
351                                         break;
352                                 case 'W':
353                                                 /* XXX, fixme zr, borderless on win32 */
354 #ifdef _WIN32   // FULLSCREEN
355                                         G.windowstate = G_WINDOWSTATE_FULLSCREEN;
356 #endif
357                                         break;
358                                 case 'n':
359                                 case 'N':
360                                         if (strcasecmp(argv[a], "-noaudio") == 0|| strcasecmp(argv[a], "-nosound") == 0) {
361                                                 /**
362                                                         notify the gameengine that no audio is wanted, even if the user didn't give
363                                                         the flag -g noaudio 
364                                         */
365
366                                                 SYS_WriteCommandLineInt(syshandle,"noaudio",1);
367                                                 audio = 0;
368                                                 if (G.f & G_DEBUG) printf("setting audio to: %d\n", audio);
369                                         }
370                                         else if (strcasecmp(argv[a], "-nofrozen") == 0) {
371                                                 /* disable initialization of frozen python modules */
372                                                 if (G.f & G_DEBUG) printf("disable frozen modules\n");
373                                                 G.f |= G_NOFROZEN;
374                                         }
375                                         break;
376                                 }
377                         }
378                 }
379
380                 BPY_start_python();
381                 
382                 /* NOTE: initialize_sound *must be* after start_python,
383                  * at least on FreeBSD */
384
385                 sound_init_audio();
386
387                 BIF_init();
388         }
389         else {
390                 BPY_start_python();
391                 SYS_WriteCommandLineInt(syshandle,"noaudio",1);
392         audio = 0;
393         sound_init_audio();
394         if (G.f & G_DEBUG) printf("setting audio to: %d\n", audio);
395         }
396
397         RE_init_filt_mask();
398         
399 #ifdef WITH_QUICKTIME
400 #ifdef _WIN32
401         if (InitializeQTML(0) != noErr)
402             G.have_quicktime = FALSE;
403         else
404             G.have_quicktime = TRUE;
405 #endif /* _WIN32 */
406
407         /* Initialize QuickTime */
408 #if defined(_WIN32) || defined (__APPLE__)
409         if (EnterMovies() != noErr)
410             G.have_quicktime = FALSE;
411         else
412 #endif /* _WIN32 || __APPLE__ */
413 #ifdef __linux__
414                         /* inititalize quicktime codec registry */
415                         lqt_registry_init();
416 #endif
417                         G.have_quicktime = TRUE;
418 #endif /* WITH_QUICKTIME */
419
420                 /* OK we are ready for it */
421
422         for(a=1; a<argc; a++) {
423                 if (G.afbreek==1) break;
424
425                 if(argv[a][0] == '-') {
426                         switch(argv[a][1]) {
427                         case 'p':       /* prefsize */
428                                 a+= 4;
429                                 break;
430
431                         case 'g':
432                                 {
433                                 /**
434                                 gameengine parameters are automaticly put into system
435                                 -g [paramname = value]
436                                 -g [boolparamname]
437                                 example:
438                                 -g novertexarrays
439                                 -g maxvertexarraysize = 512
440                                 */
441
442                                         if(++a < argc) 
443                                         {
444                                                 char* paramname = argv[a];
445                                                 /* check for single value versus assignment */
446                                                 if (a+1 < argc && (*(argv[a+1]) == '='))
447                                                 {
448                                                         a++;
449                                                         if (a+1 < argc)
450                                                         {
451                                                                 a++;
452                                                                 /* assignment */
453                                                                 SYS_WriteCommandLineString(syshandle,paramname,argv[a]);
454                                                         }  else
455                                                         {
456                                                                 printf("error: argument assignment (%s) without value.\n",paramname);
457                                                         }
458                                                         /* name arg eaten */
459                                                         
460                                                 } else
461                                                 {
462                                                         
463                                                         SYS_WriteCommandLineInt(syshandle,argv[a],1);
464                                                         
465                                                         /* doMipMap */
466                                                         if (!strcmp(argv[a],"nomipmap"))
467                                                         {
468                                                                 set_mipmap(0); //doMipMap = 0;
469                                                         }
470                                                         /* linearMipMap */
471                                                         if (!strcmp(argv[a],"linearmipmap"))
472                                                         {
473                                                                 set_linear_mipmap(1); //linearMipMap = 1;
474                                                         }
475                                                 
476
477                                                 } /* if (*(argv[a+1]) == '=') */
478                                         } /*    if(++a < argc)  */
479                                         break;
480                                 }
481                         case 'f':
482                                 a++;
483                                 if (G.scene && a < argc) {
484                                         G.real_sfra = (G.scene->r.sfra);
485                                         G.real_efra = (G.scene->r.efra);
486                                         (G.scene->r.sfra) = atoi(argv[a]);
487                                         (G.scene->r.efra) = (G.scene->r.sfra);
488                                         RE_animrender(NULL);
489                                 }
490                                 break;
491                         case 'a':
492                                 if (G.scene) {
493                                         G.real_sfra = (G.scene->r.sfra);
494                                         G.real_efra = (G.scene->r.efra);
495                                         RE_animrender(NULL);
496                                 }
497                                 break;
498                         case 'S':
499                                 if(++a < argc) {
500                                         set_scene_name(argv[a]);
501                                 }
502                                 break;
503                         case 's':
504                                 a++;
505                                 if(G.scene) {
506                                         if (a < argc) (G.scene->r.sfra) = atoi(argv[a]);
507                                 }
508                                 break;
509                         case 'e':
510                                 a++;
511                                 if(G.scene) {
512                                         if (a < argc) (G.scene->r.efra) = atoi(argv[a]);
513                                 }
514                                 break;
515                         case 'R':
516                                 /* Registering filetypes only makes sense on windows...      */
517 #ifdef WIN32
518                                 RegisterBlendExtension(argv[0]);
519 #endif
520                                 break;
521                         }
522                 }
523                 else {
524                         BKE_read_file(argv[a], NULL);
525                         sound_initialize_sounds();
526                 }
527         }
528         
529         if(G.background) 
530         {
531                 exit_usiblender();
532         }
533
534         setscreen(G.curscreen);
535         
536         if(G.main->scene.first==0) {
537                 sce= add_scene("1");
538                 set_scene(sce);
539         }
540         
541         screenmain();
542
543         return 0;
544 } /* end of int main(argc,argv) */
545
546 static void error_cb(char *err)
547 {
548         error("%s", err);
549 }
550
551 void setCallbacks(void)
552 {
553         /* Error output from the alloc routines: */
554         MEM_set_error_stream(stderr);
555
556         
557         /* BLI_blenlib: */
558         
559         BLI_setErrorCallBack(error_cb); /* */
560         BLI_setInterruptCallBack(blender_test_break);
561
562         /* render module: execution flow, timers, cursors and display. */
563         RE_set_getrenderdata_callback(RE_rotateBlenderScene);
564         RE_set_freerenderdata_callback(RE_freeRotateBlenderScene);
565 }