Merged changes in the trunk up to revision 36408.
[blender.git] / source / creator / creator.c
1 /*
2  * $Id$
3  *
4  * ***** BEGIN GPL 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.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  *
20  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21  * All rights reserved.
22  *
23  * The Original Code is: all of this file.
24  *
25  * Contributor(s): none yet.
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  */
29
30 /** \file creator/creator.c
31  *  \ingroup creator
32  */
33
34
35 #if defined(__linux__) && defined(__GNUC__)
36 #define _GNU_SOURCE
37 #include <fenv.h>
38 #endif
39
40 #if (defined(__APPLE__) && (defined(__i386__) || defined(__x86_64__)))
41 #define OSX_SSE_FPE
42 #include <xmmintrin.h>
43 #endif
44
45 #include <stdlib.h>
46 #include <stddef.h>
47 #include <string.h>
48
49 /* for setuid / getuid */
50 #ifdef __sgi
51 #include <sys/types.h>
52 #include <unistd.h>
53 #endif
54
55 /* This little block needed for linking to Blender... */
56
57 #include "MEM_guardedalloc.h"
58
59 #ifdef WIN32
60 #include "BLI_winstuff.h"
61 #endif
62
63 #include "BLI_args.h"
64 #include "BLI_threads.h"
65 #include "BLI_scanfill.h" // for BLI_setErrorCallBack, TODO, move elsewhere
66 #include "BLI_utildefines.h"
67
68 #include "DNA_ID.h"
69 #include "DNA_scene_types.h"
70
71 #include "BLI_blenlib.h"
72
73 #include "BKE_utildefines.h"
74 #include "BKE_blender.h"
75 #include "BKE_context.h"
76 #include "BKE_depsgraph.h" // for DAG_on_visible_update
77 #include "BKE_font.h"
78 #include "BKE_global.h"
79 #include "BKE_main.h"
80 #include "BKE_material.h"
81 #include "BKE_packedFile.h"
82 #include "BKE_scene.h"
83 #include "BKE_node.h"
84 #include "BKE_report.h"
85 #include "BKE_sound.h"
86
87 #include "IMB_imbuf.h"  // for IMB_init
88
89 #ifdef WITH_PYTHON
90 #include "BPY_extern.h"
91 #endif
92
93 #include "RE_pipeline.h"
94
95 //XXX #include "playanim_ext.h"
96 #include "ED_datafiles.h"
97
98 #include "WM_api.h"
99
100 #include "RNA_define.h"
101
102 #include "GPU_draw.h"
103 #include "GPU_extensions.h"
104
105 #include "FRS_freestyle.h"
106
107 #ifdef WITH_BUILDINFO_HEADER
108 #define BUILD_DATE
109 #endif
110
111 /* for passing information between creator and gameengine */
112 #ifdef WITH_GAMEENGINE
113 #include "GEN_messaging.h"
114 #include "SYS_System.h"
115 #else /* dummy */
116 #define SYS_SystemHandle int
117 #endif
118
119 #include <signal.h>
120
121 #ifdef __FreeBSD__
122 # include <sys/types.h>
123 # include <floatingpoint.h>
124 # include <sys/rtprio.h>
125 #endif
126
127 #ifdef WITH_BINRELOC
128 #include "binreloc.h"
129 #endif
130
131 // from buildinfo.c
132 #ifdef BUILD_DATE
133 extern char build_date[];
134 extern char build_time[];
135 extern char build_rev[];
136 extern char build_platform[];
137 extern char build_type[];
138 extern char build_cflags[];
139 extern char build_cxxflags[];
140 extern char build_linkflags[];
141 extern char build_system[];
142 #endif
143
144 /*      Local Function prototypes */
145 static int print_help(int argc, const char **argv, void *data);
146 static int print_version(int argc, const char **argv, void *data);
147
148 /* for the callbacks: */
149
150 extern int pluginapi_force_ref(void);  /* from blenpluginapi:pluginapi.c */
151
152 char bprogname[FILE_MAX]; /* from blenpluginapi:pluginapi.c */
153 char btempdir[FILE_MAX];
154
155 #define BLEND_VERSION_STRING_FMT "Blender %d.%02d (sub %d)\n", BLENDER_VERSION/100, BLENDER_VERSION%100, BLENDER_SUBVERSION
156
157 /* Initialise callbacks for the modules that need them */
158 static void setCallbacks(void); 
159
160 /* set breakpoints here when running in debug mode, useful to catch floating point errors */
161 #if defined(__sgi) || defined(__linux__) || defined(_WIN32) || defined(OSX_SSE_FPE)
162 static void fpe_handler(int UNUSED(sig))
163 {
164         // printf("SIGFPE trapped\n");
165 }
166 #endif
167
168 #ifndef WITH_PYTHON_MODULE
169 /* handling ctrl-c event in console */
170 static void blender_esc(int sig)
171 {
172         static int count = 0;
173         
174         G.afbreek = 1;  /* forces render loop to read queue, not sure if its needed */
175         
176         if (sig == 2) {
177                 if (count) {
178                         printf("\nBlender killed\n");
179                         exit(2);
180                 }
181                 printf("\nSent an internal break event. Press ^C again to kill Blender\n");
182                 count++;
183         }
184 }
185 #endif
186
187 /* buildinfo can have quotes */
188 #ifdef BUILD_DATE
189 static void strip_quotes(char *str)
190 {
191         if(str[0] == '"') {
192                 int len= strlen(str) - 1;
193                 memmove(str, str+1, len);
194                 if(str[len-1] == '"') {
195                         str[len-1]= '\0';
196                 }
197         }
198 }
199 #endif
200
201 static int print_version(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
202 {
203         printf (BLEND_VERSION_STRING_FMT);
204 #ifdef BUILD_DATE
205         printf ("\tbuild date: %s\n", build_date);
206         printf ("\tbuild time: %s\n", build_time);
207         printf ("\tbuild revision: %s\n", build_rev);
208         printf ("\tbuild platform: %s\n", build_platform);
209         printf ("\tbuild type: %s\n", build_type);
210         printf ("\tbuild c flags: %s\n", build_cflags);
211         printf ("\tbuild c++ flags: %s\n", build_cxxflags);
212         printf ("\tbuild link flags: %s\n", build_linkflags);
213         printf ("\tbuild system: %s\n", build_system);
214 #endif
215         exit(0);
216
217         return 0;
218 }
219
220 static int print_help(int UNUSED(argc), const char **UNUSED(argv), void *data)
221 {
222         bArgs *ba = (bArgs*)data;
223
224         printf (BLEND_VERSION_STRING_FMT);
225         printf ("Usage: blender [args ...] [file] [args ...]\n\n");
226
227         printf ("Render Options:\n");
228         BLI_argsPrintArgDoc(ba, "--background");
229         BLI_argsPrintArgDoc(ba, "--render-anim");
230         BLI_argsPrintArgDoc(ba, "--scene");
231         BLI_argsPrintArgDoc(ba, "--render-frame");
232         BLI_argsPrintArgDoc(ba, "--frame-start");
233         BLI_argsPrintArgDoc(ba, "--frame-end");
234         BLI_argsPrintArgDoc(ba, "--frame-jump");
235         BLI_argsPrintArgDoc(ba, "--render-output");
236         BLI_argsPrintArgDoc(ba, "--engine");
237         
238         printf("\n");
239         printf ("Format Options:\n");
240         BLI_argsPrintArgDoc(ba, "--render-format");
241         BLI_argsPrintArgDoc(ba, "--use-extension");
242         BLI_argsPrintArgDoc(ba, "--threads");
243
244         printf("\n");
245         printf ("Animation Playback Options:\n");
246         BLI_argsPrintArgDoc(ba, "-a");
247                                 
248         printf("\n");
249         printf ("Window Options:\n");
250         BLI_argsPrintArgDoc(ba, "--window-border");
251         BLI_argsPrintArgDoc(ba, "--window-borderless");
252         BLI_argsPrintArgDoc(ba, "--window-geometry");
253         BLI_argsPrintArgDoc(ba, "--start-console");
254
255         printf("\n");
256         printf ("Game Engine Specific Options:\n");
257         BLI_argsPrintArgDoc(ba, "-g");
258
259         printf("\n");
260         printf ("Misc Options:\n");
261         BLI_argsPrintArgDoc(ba, "--debug");
262         BLI_argsPrintArgDoc(ba, "--debug-fpe");
263         printf("\n");
264         BLI_argsPrintArgDoc(ba, "--factory-startup");
265         printf("\n");
266         BLI_argsPrintArgDoc(ba, "--env-system-config");
267         BLI_argsPrintArgDoc(ba, "--env-system-datafiles");
268         BLI_argsPrintArgDoc(ba, "--env-system-scripts");
269         BLI_argsPrintArgDoc(ba, "--env-system-plugins");
270         BLI_argsPrintArgDoc(ba, "--env-system-python");
271         printf("\n");
272         BLI_argsPrintArgDoc(ba, "-nojoystick");
273         BLI_argsPrintArgDoc(ba, "-noglsl");
274         BLI_argsPrintArgDoc(ba, "-noaudio");
275         BLI_argsPrintArgDoc(ba, "-setaudio");
276
277         printf("\n");
278
279         BLI_argsPrintArgDoc(ba, "--help");
280
281         printf("\n");
282
283         BLI_argsPrintArgDoc(ba, "--enable-autoexec");
284         BLI_argsPrintArgDoc(ba, "--disable-autoexec");
285
286         printf("\n");
287
288         BLI_argsPrintArgDoc(ba, "--python");
289         BLI_argsPrintArgDoc(ba, "--python-console");
290         BLI_argsPrintArgDoc(ba, "--addons");
291
292 #ifdef WIN32
293         BLI_argsPrintArgDoc(ba, "-R");
294         BLI_argsPrintArgDoc(ba, "-r");
295 #endif
296         BLI_argsPrintArgDoc(ba, "--version");
297
298         BLI_argsPrintArgDoc(ba, "--");
299
300         printf ("Other Options:\n");
301         BLI_argsPrintOtherDoc(ba);
302
303         printf ("Argument Parsing:\n");
304         printf ("\targuments must be separated by white space. eg\n");
305         printf ("\t\t\"blender -ba test.blend\"\n");
306         printf ("\t...will ignore the 'a'\n");
307         printf ("\t\t\"blender -b test.blend -f8\"\n");
308         printf ("\t...will ignore 8 because there is no space between the -f and the frame value\n\n");
309
310         printf ("Argument Order:\n");
311         printf ("Arguments are executed in the order they are given. eg\n");
312         printf ("\t\t\"blender --background test.blend --render-frame 1 --render-output /tmp\"\n");
313         printf ("\t...will not render to /tmp because '--render-frame 1' renders before the output path is set\n");
314         printf ("\t\t\"blender --background --render-output /tmp test.blend --render-frame 1\"\n");
315         printf ("\t...will not render to /tmp because loading the blend file overwrites the render output that was set\n");
316         printf ("\t\t\"blender --background test.blend --render-output /tmp --render-frame 1\" works as expected.\n\n");
317
318         printf ("\nEnvironment Variables:\n");
319         printf ("  $BLENDER_USER_CONFIG      Directory for user configuration files.\n");
320         printf ("  $BLENDER_SYSTEM_CONFIG    Directory for system wide configuration files.\n");
321         printf ("  $BLENDER_USER_SCRIPTS     Directory for user scripts.\n");
322         printf ("  $BLENDER_SYSTEM_SCRIPTS   Directory for system wide scripts.\n");
323         printf ("  $BLENDER_USER_DATAFILES   Directory for user data files (icons, translations, ..).\n");
324         printf ("  $BLENDER_SYSTEM_DATAFILES Directory for system wide data files.\n");
325         printf ("  $BLENDER_SYSTEM_PYTHON    Directory for system python libraries.\n");
326 #ifdef WIN32
327         printf ("  $TEMP                     Store temporary files here.\n");
328 #else
329         printf ("  $TMP or $TMPDIR           Store temporary files here.\n");
330 #endif
331 #ifndef DISABLE_SDL
332         printf ("  $SDL_AUDIODRIVER          LibSDL audio driver - alsa, esd, dma.\n");
333 #endif
334         printf ("  $PYTHONHOME               Path to the python directory, eg. /usr/lib/python.\n\n");
335
336         exit(0);
337
338         return 0;
339 }
340
341
342 double PIL_check_seconds_timer(void);
343
344 /* XXX This was here to fix a crash when running python scripts
345  * with -P that used the screen.
346  *
347  * static void main_init_screen( void )
348 {
349         setscreen(G.curscreen);
350         
351         if(G.main->scene.first==0) {
352                 set_scene( add_scene("1") );
353         }
354 }*/
355
356 static int end_arguments(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
357 {
358         return -1;
359 }
360
361 static int enable_python(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
362 {
363         G.f |= G_SCRIPT_AUTOEXEC;
364         G.f |= G_SCRIPT_OVERRIDE_PREF;
365         return 0;
366 }
367
368 static int disable_python(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
369 {
370         G.f &= ~G_SCRIPT_AUTOEXEC;
371         G.f |= G_SCRIPT_OVERRIDE_PREF;
372         return 0;
373 }
374
375 static int background_mode(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
376 {
377         G.background = 1;
378         return 0;
379 }
380
381 static int debug_mode(int UNUSED(argc), const char **UNUSED(argv), void *data)
382 {
383         G.f |= G_DEBUG;         /* std output printf's */
384         printf(BLEND_VERSION_STRING_FMT);
385         MEM_set_memory_debug();
386
387 #ifdef NAN_BUILDINFO
388         printf("Build: %s %s %s %s\n", build_date, build_time, build_platform, build_type);
389 #endif // NAN_BUILDINFO
390
391         BLI_argsPrint(data);
392         return 0;
393 }
394
395 static int set_fpe(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
396 {
397 #if defined(__sgi) || defined(__linux__) || defined(_WIN32) || defined(OSX_SSE_FPE)
398         /* zealous but makes float issues a heck of a lot easier to find!
399          * set breakpoints on fpe_handler */
400         signal(SIGFPE, fpe_handler);
401
402 # if defined(__linux__) && defined(__GNUC__)
403         feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW );
404 # endif /* defined(__linux__) && defined(__GNUC__) */
405 # if defined(OSX_SSE_FPE)
406         /* OSX uses SSE for floating point by default, so here 
407          * use SSE instructions to throw floating point exceptions */
408         _MM_SET_EXCEPTION_MASK(_MM_MASK_MASK &~
409                         (_MM_MASK_OVERFLOW|_MM_MASK_INVALID|_MM_MASK_DIV_ZERO));
410 # endif /* OSX_SSE_FPE */
411 # if defined(_WIN32) && defined(_MSC_VER)
412         _controlfp_s(NULL, 0, _MCW_EM); /* enables all fp exceptions */
413         _controlfp_s(NULL, _EM_DENORMAL | _EM_UNDERFLOW | _EM_INEXACT, _MCW_EM); /* hide the ones we don't care about */
414 # endif /* _WIN32 && _MSC_VER */
415 #endif
416
417         return 0;
418 }
419
420 static int set_factory_startup(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
421 {
422         G.factory_startup= 1;
423         return 0;
424 }
425
426 static int set_env(int argc, const char **argv, void *UNUSED(data))
427 {
428         /* "--env-system-scripts" --> "BLENDER_SYSTEM_SCRIPTS" */
429
430         char env[64]= "BLENDER";
431         char *ch_dst= env + 7; /* skip BLENDER */
432         const char *ch_src= argv[0] + 5; /* skip --env */
433
434         if (argc < 2) {
435                 printf("%s requires one argument\n", argv[0]);
436                 exit(1);
437         }
438
439         for(; *ch_src; ch_src++, ch_dst++) {
440                 *ch_dst= (*ch_src == '-') ? '_' : (*ch_src)-32; /* toupper() */
441         }
442
443         *ch_dst= '\0';
444         BLI_setenv(env, argv[1]);
445         return 1;
446 }
447
448 static int playback_mode(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
449 {
450         /* not if -b was given first */
451         if (G.background == 0) {
452
453 // XXX                          playanim(argc, argv); /* not the same argc and argv as before */
454                 exit(0);
455         }
456
457         return -2;
458 }
459
460 static int prefsize(int argc, const char **argv, void *UNUSED(data))
461 {
462         int stax, stay, sizx, sizy;
463
464         if (argc < 5) {
465                 printf ("-p requires four arguments\n");
466                 exit(1);
467         }
468
469         stax= atoi(argv[1]);
470         stay= atoi(argv[2]);
471         sizx= atoi(argv[3]);
472         sizy= atoi(argv[4]);
473
474         WM_setprefsize(stax, stay, sizx, sizy);
475
476         return 4;
477 }
478
479 static int with_borders(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
480 {
481         WM_setinitialstate_normal();
482         return 0;
483 }
484
485 static int without_borders(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
486 {
487         WM_setinitialstate_fullscreen();
488         return 0;
489 }
490
491 extern int wm_start_with_console; // blender/windowmanager/intern/wm_init_exit.c
492 static int start_with_console(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
493 {
494         wm_start_with_console = 1;
495         return 0;
496 }
497
498 static int register_extension(int UNUSED(argc), const char **UNUSED(argv), void *data)
499 {
500 #ifdef WIN32
501         if (data)
502                 G.background = 1;
503         RegisterBlendExtension();
504 #else
505         (void)data; /* unused */
506 #endif
507         return 0;
508 }
509
510 static int no_joystick(int UNUSED(argc), const char **UNUSED(argv), void *data)
511 {
512 #ifndef WITH_GAMEENGINE
513         (void)data;
514 #else
515         SYS_SystemHandle *syshandle = data;
516
517         /**
518                 don't initialize joysticks if user doesn't want to use joysticks
519                 failed joystick initialization delays over 5 seconds, before game engine start
520         */
521         SYS_WriteCommandLineInt(*syshandle, "nojoystick",1);
522         if (G.f & G_DEBUG) printf("disabling nojoystick\n");
523 #endif
524
525         return 0;
526 }
527
528 static int no_glsl(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
529 {
530         GPU_extensions_disable();
531         return 0;
532 }
533
534 static int no_audio(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
535 {
536         sound_force_device(0);
537         return 0;
538 }
539
540 static int set_audio(int argc, const char **argv, void *UNUSED(data))
541 {
542         if (argc < 1) {
543                 printf("-setaudio require one argument\n");
544                 exit(1);
545         }
546
547         sound_force_device(sound_define_from_str(argv[1]));
548         return 1;
549 }
550
551 static int set_output(int argc, const char **argv, void *data)
552 {
553         bContext *C = data;
554         if (argc >= 1){
555                 if (CTX_data_scene(C)) {
556                         Scene *scene= CTX_data_scene(C);
557                         BLI_strncpy(scene->r.pic, argv[1], FILE_MAXDIR);
558                 } else {
559                         printf("\nError: no blend loaded. cannot use '-o / --render-output'.\n");
560                 }
561                 return 1;
562         } else {
563                 printf("\nError: you must specify a path after '-o  / --render-output'.\n");
564                 return 0;
565         }
566 }
567
568 static int set_engine(int argc, const char **argv, void *data)
569 {
570         bContext *C = data;
571         if (argc >= 1)
572         {
573                 if (!strcmp(argv[1],"help"))
574                 {
575                         RenderEngineType *type = NULL;
576
577                         for( type = R_engines.first; type; type = type->next )
578                         {
579                                 printf("\t%s\n", type->idname);
580                         }
581                         exit(0);
582                 }
583                 else
584                 {
585                         if (CTX_data_scene(C)==NULL)
586                         {
587                                 printf("\nError: no blend loaded. order the arguments so '-E  / --engine ' is after a blend is loaded.\n");
588                         }
589                         else {
590                                 Scene *scene= CTX_data_scene(C);
591                                 RenderData *rd = &scene->r;
592
593                                 if(BLI_findstring(&R_engines, argv[1], offsetof(RenderEngineType, idname))) {
594                                         BLI_strncpy(rd->engine, argv[1], sizeof(rd->engine));
595                                 }
596                         }
597                 }
598
599                 return 1;
600         }
601         else
602         {
603                 printf("\nEngine not specified.\n");
604                 return 0;
605         }
606 }
607
608 static int set_image_type(int argc, const char **argv, void *data)
609 {
610         bContext *C = data;
611         if (argc >= 1){
612                 const char *imtype = argv[1];
613                 if (CTX_data_scene(C)==NULL) {
614                         printf("\nError: no blend loaded. order the arguments so '-F  / --render-format' is after the blend is loaded.\n");
615                 } else {
616                         Scene *scene= CTX_data_scene(C);
617                         if      (!strcmp(imtype,"TGA")) scene->r.imtype = R_TARGA;
618                         else if (!strcmp(imtype,"IRIS")) scene->r.imtype = R_IRIS;
619 #ifdef WITH_DDS
620                         else if (!strcmp(imtype,"DDS")) scene->r.imtype = R_DDS;
621 #endif
622                         else if (!strcmp(imtype,"JPEG")) scene->r.imtype = R_JPEG90;
623                         else if (!strcmp(imtype,"IRIZ")) scene->r.imtype = R_IRIZ;
624                         else if (!strcmp(imtype,"RAWTGA")) scene->r.imtype = R_RAWTGA;
625                         else if (!strcmp(imtype,"AVIRAW")) scene->r.imtype = R_AVIRAW;
626                         else if (!strcmp(imtype,"AVIJPEG")) scene->r.imtype = R_AVIJPEG;
627                         else if (!strcmp(imtype,"PNG")) scene->r.imtype = R_PNG;
628                         else if (!strcmp(imtype,"AVICODEC")) scene->r.imtype = R_AVICODEC;
629                         else if (!strcmp(imtype,"QUICKTIME")) scene->r.imtype = R_QUICKTIME;
630                         else if (!strcmp(imtype,"BMP")) scene->r.imtype = R_BMP;
631 #ifdef WITH_HDR
632                         else if (!strcmp(imtype,"HDR")) scene->r.imtype = R_RADHDR;
633 #endif
634 #ifdef WITH_TIFF
635                         else if (!strcmp(imtype,"TIFF")) scene->r.imtype = R_TIFF;
636 #endif
637 #ifdef WITH_OPENEXR
638                         else if (!strcmp(imtype,"EXR")) scene->r.imtype = R_OPENEXR;
639                         else if (!strcmp(imtype,"MULTILAYER")) scene->r.imtype = R_MULTILAYER;
640 #endif
641                         else if (!strcmp(imtype,"MPEG")) scene->r.imtype = R_FFMPEG;
642                         else if (!strcmp(imtype,"FRAMESERVER")) scene->r.imtype = R_FRAMESERVER;
643 #ifdef WITH_CINEON
644                         else if (!strcmp(imtype,"CINEON")) scene->r.imtype = R_CINEON;
645                         else if (!strcmp(imtype,"DPX")) scene->r.imtype = R_DPX;
646 #endif
647 #if WITH_OPENJPEG
648                         else if (!strcmp(imtype,"JP2")) scene->r.imtype = R_JP2;
649 #endif
650                         else printf("\nError: Format from '-F / --render-format' not known or not compiled in this release.\n");
651                 }
652                 return 1;
653         } else {
654                 printf("\nError: you must specify a format after '-F  / --render-foramt'.\n");
655                 return 0;
656         }
657 }
658
659 static int set_threads(int argc, const char **argv, void *UNUSED(data))
660 {
661         if (argc >= 1) {
662                 if(G.background) {
663                         RE_set_max_threads(atoi(argv[1]));
664                 } else {
665                         printf("Warning: threads can only be set in background mode\n");
666                 }
667                 return 1;
668         } else {
669                 printf("\nError: you must specify a number of threads between 0 and 8 '-t  / --threads'.\n");
670                 return 0;
671         }
672 }
673
674 static int set_extension(int argc, const char **argv, void *data)
675 {
676         bContext *C = data;
677         if (argc >= 1) {
678                 if (CTX_data_scene(C)) {
679                         Scene *scene= CTX_data_scene(C);
680                         if (argv[1][0] == '0') {
681                                 scene->r.scemode &= ~R_EXTENSION;
682                         } else if (argv[1][0] == '1') {
683                                 scene->r.scemode |= R_EXTENSION;
684                         } else {
685                                 printf("\nError: Use '-x 1 / -x 0' To set the extension option or '--use-extension'\n");
686                         }
687                 } else {
688                         printf("\nError: no blend loaded. order the arguments so '-o ' is after '-x '.\n");
689                 }
690                 return 1;
691         } else {
692                 printf("\nError: you must specify a path after '- '.\n");
693                 return 0;
694         }
695 }
696
697 static int set_ge_parameters(int argc, const char **argv, void *data)
698 {
699         int a = 0;
700 #ifdef WITH_GAMEENGINE
701         SYS_SystemHandle syshandle = *(SYS_SystemHandle*)data;
702 #else
703         (void)data;
704 #endif
705
706 /**
707 gameengine parameters are automaticly put into system
708 -g [paramname = value]
709 -g [boolparamname]
710 example:
711 -g novertexarrays
712 -g maxvertexarraysize = 512
713 */
714
715         if(argc >= 1)
716         {
717                 const char *paramname = argv[a];
718                 /* check for single value versus assignment */
719                 if (a+1 < argc && (*(argv[a+1]) == '='))
720                 {
721                         a++;
722                         if (a+1 < argc)
723                         {
724                                 a++;
725                                 /* assignment */
726 #ifdef WITH_GAMEENGINE
727                                 SYS_WriteCommandLineString(syshandle,paramname,argv[a]);
728 #endif
729                         }  else
730                         {
731                                 printf("error: argument assignment (%s) without value.\n",paramname);
732                                 return 0;
733                         }
734                         /* name arg eaten */
735
736                 } else {
737 #ifdef WITH_GAMEENGINE
738                         SYS_WriteCommandLineInt(syshandle,argv[a],1);
739 #endif
740                         /* doMipMap */
741                         if (!strcmp(argv[a],"nomipmap"))
742                         {
743                                 GPU_set_mipmap(0); //doMipMap = 0;
744                         }
745                         /* linearMipMap */
746                         if (!strcmp(argv[a],"linearmipmap"))
747                         {
748                                 GPU_set_linear_mipmap(1); //linearMipMap = 1;
749                         }
750
751
752                 } /* if (*(argv[a+1]) == '=') */
753         }
754
755         return a;
756 }
757
758 static int render_frame(int argc, const char **argv, void *data)
759 {
760         bContext *C = data;
761         if (CTX_data_scene(C)) {
762                 Main *bmain= CTX_data_main(C);
763                 Scene *scene= CTX_data_scene(C);
764
765                 if (argc > 1) {
766                         Render *re = RE_NewRender(scene->id.name);
767                         int frame;
768                         ReportList reports;
769
770                         switch(*argv[1]) {
771                         case '+':
772                                 frame= scene->r.sfra + atoi(argv[1]+1);
773                                 break;
774                         case '-':
775                                 frame= (scene->r.efra - atoi(argv[1]+1)) + 1;
776                                 break;
777                         default:
778                                 frame= atoi(argv[1]);
779                                 break;
780                         }
781
782                         BKE_reports_init(&reports, RPT_PRINT);
783
784                         frame = MIN2(MAXFRAME, MAX2(MINAFRAME, frame));
785
786                         RE_BlenderAnim(re, bmain, scene, NULL, scene->lay, frame, frame, scene->r.frame_step, &reports);
787                         return 1;
788                 } else {
789                         printf("\nError: frame number must follow '-f / --render-frame'.\n");
790                         return 0;
791                 }
792         } else {
793                 printf("\nError: no blend loaded. cannot use '-f / --render-frame'.\n");
794                 return 0;
795         }
796 }
797
798 static int render_animation(int UNUSED(argc), const char **UNUSED(argv), void *data)
799 {
800         bContext *C = data;
801         if (CTX_data_scene(C)) {
802                 Main *bmain= CTX_data_main(C);
803                 Scene *scene= CTX_data_scene(C);
804                 Render *re= RE_NewRender(scene->id.name);
805                 ReportList reports;
806                 BKE_reports_init(&reports, RPT_PRINT);
807                 RE_BlenderAnim(re, bmain, scene, NULL, scene->lay, scene->r.sfra, scene->r.efra, scene->r.frame_step, &reports);
808         } else {
809                 printf("\nError: no blend loaded. cannot use '-a'.\n");
810         }
811         return 0;
812 }
813
814 static int set_scene(int argc, const char **argv, void *data)
815 {
816         if(argc > 1) {
817                 bContext *C= data;
818                 Scene *sce= set_scene_name(CTX_data_main(C), argv[1]);
819                 if(sce) {
820                         CTX_data_scene_set(C, sce);
821                 }
822                 return 1;
823         } else {
824                 printf("\nError: Scene name must follow '-S / --scene'.\n");
825                 return 0;
826         }
827 }
828
829 static int set_start_frame(int argc, const char **argv, void *data)
830 {
831         bContext *C = data;
832         if (CTX_data_scene(C)) {
833                 Scene *scene= CTX_data_scene(C);
834                 if (argc > 1) {
835                         int frame = atoi(argv[1]);
836                         (scene->r.sfra) = CLAMPIS(frame, MINFRAME, MAXFRAME);
837                         return 1;
838                 } else {
839                         printf("\nError: frame number must follow '-s / --frame-start'.\n");
840                         return 0;
841                 }
842         } else {
843                 printf("\nError: no blend loaded. cannot use '-s / --frame-start'.\n");
844                 return 0;
845         }
846 }
847
848 static int set_end_frame(int argc, const char **argv, void *data)
849 {
850         bContext *C = data;
851         if (CTX_data_scene(C)) {
852                 Scene *scene= CTX_data_scene(C);
853                 if (argc > 1) {
854                         int frame = atoi(argv[1]);
855                         (scene->r.efra) = CLAMPIS(frame, MINFRAME, MAXFRAME);
856                         return 1;
857                 } else {
858                         printf("\nError: frame number must follow '-e / --frame-end'.\n");
859                         return 0;
860                 }
861         } else {
862                 printf("\nError: no blend loaded. cannot use '-e / --frame-end'.\n");
863                 return 0;
864         }
865 }
866
867 static int set_skip_frame(int argc, const char **argv, void *data)
868 {
869         bContext *C = data;
870         if (CTX_data_scene(C)) {
871                 Scene *scene= CTX_data_scene(C);
872                 if (argc > 1) {
873                         int frame = atoi(argv[1]);
874                         (scene->r.frame_step) = CLAMPIS(frame, 1, MAXFRAME);
875                         return 1;
876                 } else {
877                         printf("\nError: number of frames to step must follow '-j / --frame-jump'.\n");
878                         return 0;
879                 }
880         } else {
881                 printf("\nError: no blend loaded. cannot use '-j / --frame-jump'.\n");
882                 return 0;
883         }
884 }
885
886 /* macro for ugly context setup/reset */
887 #ifdef WITH_PYTHON
888 #define BPY_CTX_SETUP(_cmd) \
889 { \
890         wmWindowManager *wm= CTX_wm_manager(C); \
891         wmWindow *prevwin= CTX_wm_window(C); \
892         Scene *prevscene= CTX_data_scene(C); \
893         if(wm->windows.first) { \
894                 CTX_wm_window_set(C, wm->windows.first); \
895                 _cmd; \
896                 CTX_wm_window_set(C, prevwin); \
897         } \
898         else { \
899                 fprintf(stderr, "Python script \"%s\" running with missing context data.\n", argv[1]); \
900                 _cmd; \
901         } \
902         CTX_data_scene_set(C, prevscene); \
903 } \
904
905 #endif /* WITH_PYTHON */
906
907 static int run_python(int argc, const char **argv, void *data)
908 {
909 #ifdef WITH_PYTHON
910         bContext *C = data;
911
912         /* workaround for scripts not getting a bpy.context.scene, causes internal errors elsewhere */
913         if (argc > 1) {
914                 /* Make the path absolute because its needed for relative linked blends to be found */
915                 char filename[FILE_MAXDIR + FILE_MAXFILE];
916                 BLI_strncpy(filename, argv[1], sizeof(filename));
917                 BLI_path_cwd(filename);
918
919                 BPY_CTX_SETUP(BPY_filepath_exec(C, filename, NULL))
920
921                 return 1;
922         } else {
923                 printf("\nError: you must specify a Python script after '-P / --python'.\n");
924                 return 0;
925         }
926 #else
927         (void)argc; (void)argv; (void)data; /* unused */
928         printf("This blender was built without python support\n");
929         return 0;
930 #endif /* WITH_PYTHON */
931 }
932
933 static int run_python_console(int UNUSED(argc), const char **argv, void *data)
934 {
935 #ifdef WITH_PYTHON
936         bContext *C = data;
937
938         BPY_CTX_SETUP(BPY_string_exec(C, "__import__('code').interact()"))
939
940         return 0;
941 #else
942         (void)argv; (void)data; /* unused */
943         printf("This blender was built without python support\n");
944         return 0;
945 #endif /* WITH_PYTHON */
946 }
947
948 static int set_addons(int argc, const char **argv, void *data)
949 {
950         /* workaround for scripts not getting a bpy.context.scene, causes internal errors elsewhere */
951         if (argc > 1) {
952 #ifdef WITH_PYTHON
953                 const int slen= strlen(argv[1]) + 128;
954                 char *str= malloc(slen);
955                 bContext *C= data;
956                 BLI_snprintf(str, slen, "[__import__('addon_utils').enable(i, default_set=False) for i in '%s'.split(',')]", argv[1]);
957                 BPY_CTX_SETUP(BPY_string_exec(C, str));
958                 free(str);
959 #else
960                 (void)argv; (void)data; /* unused */
961 #endif /* WITH_PYTHON */
962                 return 1;
963         }
964         else {
965                 printf("\nError: you must specify a comma separated list after '--addons'.\n");
966                 return 0;
967         }
968 }
969
970
971 static int load_file(int UNUSED(argc), const char **argv, void *data)
972 {
973         bContext *C = data;
974
975         /* Make the path absolute because its needed for relative linked blends to be found */
976         char filename[FILE_MAXDIR + FILE_MAXFILE];
977         BLI_strncpy(filename, argv[0], sizeof(filename));
978         BLI_path_cwd(filename);
979
980         if (G.background) {
981                 int retval = BKE_read_file(C, filename, NULL);
982
983                 /*we successfully loaded a blend file, get sure that
984                 pointcache works */
985                 if (retval != BKE_READ_FILE_FAIL) {
986                         wmWindowManager *wm= CTX_wm_manager(C);
987
988                         /* special case, 2.4x files */
989                         if(wm==NULL && CTX_data_main(C)->wm.first==NULL) {
990                                 extern void wm_add_default(bContext *C);
991
992                                 /* wm_add_default() needs the screen to be set. */
993                                 CTX_wm_screen_set(C, CTX_data_main(C)->screen.first);
994                                 wm_add_default(C);
995                         }
996
997                         CTX_wm_manager_set(C, NULL); /* remove wm to force check */
998                         WM_check(C);
999                         G.relbase_valid = 1;
1000                         if (CTX_wm_manager(C) == NULL) CTX_wm_manager_set(C, wm); /* reset wm */
1001
1002                         DAG_on_visible_update(CTX_data_main(C), TRUE);
1003                 }
1004
1005                 /* WM_read_file() runs normally but since we're in background mode do here */
1006 #ifdef WITH_PYTHON
1007                 /* run any texts that were loaded in and flagged as modules */
1008                 BPY_driver_reset();
1009                 BPY_modules_load_user(C);
1010 #endif
1011
1012                 /* happens for the UI on file reading too (huh? (ton))*/
1013         // XXX                  BKE_reset_undo();
1014         //                              BKE_write_undo("original");     /* save current state */
1015         } else {
1016                 /* we are not running in background mode here, but start blender in UI mode with
1017                    a file - this should do everything a 'load file' does */
1018                 ReportList reports;
1019                 BKE_reports_init(&reports, RPT_PRINT);
1020                 WM_read_file(C, filename, &reports);
1021                 BKE_reports_clear(&reports);
1022         }
1023
1024         G.file_loaded = 1;
1025
1026         return 0;
1027 }
1028
1029 static void setupArguments(bContext *C, bArgs *ba, SYS_SystemHandle *syshandle)
1030 {
1031         static char output_doc[] = "<path>"
1032                 "\n\tSet the render path and file name."
1033                 "\n\tUse // at the start of the path to"
1034                 "\n\t\trender relative to the blend file."
1035                 "\n\tThe # characters are replaced by the frame number, and used to define zero padding."
1036                 "\n\t\tani_##_test.png becomes ani_01_test.png"
1037                 "\n\t\ttest-######.png becomes test-000001.png"
1038                 "\n\t\tWhen the filename does not contain #, The suffix #### is added to the filename"
1039                 "\n\tThe frame number will be added at the end of the filename."
1040                 "\n\t\teg: blender -b foobar.blend -o //render_ -F PNG -x 1 -a"
1041                 "\n\t\t//render_ becomes //render_####, writing frames as //render_0001.png//";
1042
1043         static char format_doc[] = "<format>"
1044                 "\n\tSet the render format, Valid options are..."
1045                 "\n\t\tTGA IRIS JPEG MOVIE IRIZ RAWTGA"
1046                 "\n\t\tAVIRAW AVIJPEG PNG BMP FRAMESERVER"
1047                 "\n\t(formats that can be compiled into blender, not available on all systems)"
1048                 "\n\t\tHDR TIFF EXR MULTILAYER MPEG AVICODEC QUICKTIME CINEON DPX DDS";
1049
1050         static char playback_doc[] = "<options> <file(s)>"
1051                 "\n\tPlayback <file(s)>, only operates this way when not running in background."
1052                 "\n\t\t-p <sx> <sy>\tOpen with lower left corner at <sx>, <sy>"
1053                 "\n\t\t-m\t\tRead from disk (Don't buffer)"
1054                 "\n\t\t-f <fps> <fps-base>\t\tSpecify FPS to start with"
1055                 "\n\t\t-j <frame>\tSet frame step to <frame>";
1056
1057         static char game_doc[] = "Game Engine specific options"
1058                 "\n\t-g fixedtime\t\tRun on 50 hertz without dropping frames"
1059                 "\n\t-g vertexarrays\t\tUse Vertex Arrays for rendering (usually faster)"
1060                 "\n\t-g nomipmap\t\tNo Texture Mipmapping"
1061                 "\n\t-g linearmipmap\t\tLinear Texture Mipmapping instead of Nearest (default)";
1062
1063         static char debug_doc[] = "\n\tTurn debugging on\n"
1064                 "\n\t* Prints every operator call and their arguments"
1065                 "\n\t* Disables mouse grab (to interact with a debugger in some cases)"
1066                 "\n\t* Keeps python sys.stdin rather then setting it to None";
1067
1068         //BLI_argsAdd(ba, pass, short_arg, long_arg, doc, cb, C);
1069
1070         /* end argument processing after -- */
1071         BLI_argsAdd(ba, -1, "--", NULL, "\n\tEnds option processing, following arguments passed unchanged. Access via python's sys.argv", end_arguments, NULL);
1072
1073         /* first pass: background mode, disable python and commands that exit after usage */
1074         BLI_argsAdd(ba, 1, "-h", "--help", "\n\tPrint this help text and exit", print_help, ba);
1075         /* Windows only */
1076         BLI_argsAdd(ba, 1, "/?", NULL, "\n\tPrint this help text and exit (windows only)", print_help, ba);
1077
1078         BLI_argsAdd(ba, 1, "-v", "--version", "\n\tPrint Blender version and exit", print_version, NULL);
1079         
1080         /* only to give help message */
1081 #ifndef WITH_PYTHON_SECURITY /* default */
1082 #  define       PY_ENABLE_AUTO ", (default)"
1083 #  define       PY_DISABLE_AUTO ""
1084 #else
1085 #  define       PY_ENABLE_AUTO ""
1086 #  define       PY_DISABLE_AUTO ", (compiled as non-standard default)"
1087 #endif
1088
1089         BLI_argsAdd(ba, 1, "-y", "--enable-autoexec", "\n\tEnable automatic python script execution" PY_ENABLE_AUTO, enable_python, NULL);
1090         BLI_argsAdd(ba, 1, "-Y", "--disable-autoexec", "\n\tDisable automatic python script execution (pydrivers, pyconstraints, pynodes)" PY_DISABLE_AUTO, disable_python, NULL);
1091
1092 #undef PY_ENABLE_AUTO
1093 #undef PY_DISABLE_AUTO
1094         
1095         BLI_argsAdd(ba, 1, "-b", "--background", "<file>\n\tLoad <file> in background (often used for UI-less rendering)", background_mode, NULL);
1096
1097         BLI_argsAdd(ba, 1, "-a", NULL, playback_doc, playback_mode, NULL);
1098
1099         BLI_argsAdd(ba, 1, "-d", "--debug", debug_doc, debug_mode, ba);
1100         BLI_argsAdd(ba, 1, NULL, "--debug-fpe", "\n\tEnable floating point exceptions", set_fpe, NULL);
1101
1102         BLI_argsAdd(ba, 1, NULL, "--factory-startup", "\n\tSkip reading the "STRINGIFY(BLENDER_STARTUP_FILE)" in the users home directory", set_factory_startup, NULL);
1103
1104         /* TODO, add user env vars? */
1105         BLI_argsAdd(ba, 1, NULL, "--env-system-config",         "\n\tSet the "STRINGIFY_ARG(BLENDER_SYSTEM_CONFIG)" environment variable", set_env, NULL);
1106         BLI_argsAdd(ba, 1, NULL, "--env-system-datafiles",      "\n\tSet the "STRINGIFY_ARG(BLENDER_SYSTEM_DATAFILES)" environment variable", set_env, NULL);
1107         BLI_argsAdd(ba, 1, NULL, "--env-system-scripts",        "\n\tSet the "STRINGIFY_ARG(BLENDER_SYSTEM_SCRIPTS)" environment variable", set_env, NULL);
1108         BLI_argsAdd(ba, 1, NULL, "--env-system-plugins",        "\n\tSet the "STRINGIFY_ARG(BLENDER_SYSTEM_PLUGINS)" environment variable", set_env, NULL);
1109         BLI_argsAdd(ba, 1, NULL, "--env-system-python",         "\n\tSet the "STRINGIFY_ARG(BLENDER_SYSTEM_PYTHON)" environment variable", set_env, NULL);
1110
1111         /* second pass: custom window stuff */
1112         BLI_argsAdd(ba, 2, "-p", "--window-geometry", "<sx> <sy> <w> <h>\n\tOpen with lower left corner at <sx>, <sy> and width and height as <w>, <h>", prefsize, NULL);
1113         BLI_argsAdd(ba, 2, "-w", "--window-border", "\n\tForce opening with borders (default)", with_borders, NULL);
1114         BLI_argsAdd(ba, 2, "-W", "--window-borderless", "\n\tForce opening without borders", without_borders, NULL);
1115         BLI_argsAdd(ba, 2, "-con", "--start-console", "\n\tStart with the console window open (ignored if -b is set)", start_with_console, NULL);
1116         BLI_argsAdd(ba, 2, "-R", NULL, "\n\tRegister .blend extension, then exit (Windows only)", register_extension, NULL);
1117         BLI_argsAdd(ba, 2, "-r", NULL, "\n\tSilently register .blend extension, then exit (Windows only)", register_extension, ba);
1118
1119         /* third pass: disabling things and forcing settings */
1120         BLI_argsAddCase(ba, 3, "-nojoystick", 1, NULL, 0, "\n\tDisable joystick support", no_joystick, syshandle);
1121         BLI_argsAddCase(ba, 3, "-noglsl", 1, NULL, 0, "\n\tDisable GLSL shading", no_glsl, NULL);
1122         BLI_argsAddCase(ba, 3, "-noaudio", 1, NULL, 0, "\n\tForce sound system to None", no_audio, NULL);
1123         BLI_argsAddCase(ba, 3, "-setaudio", 1, NULL, 0, "\n\tForce sound system to a specific device\n\tNULL SDL OPENAL JACK", set_audio, NULL);
1124
1125         /* fourth pass: processing arguments */
1126         BLI_argsAdd(ba, 4, "-g", NULL, game_doc, set_ge_parameters, syshandle);
1127         BLI_argsAdd(ba, 4, "-f", "--render-frame", "<frame>\n\tRender frame <frame> and save it.\n\t+<frame> start frame relative, -<frame> end frame relative.", render_frame, C);
1128         BLI_argsAdd(ba, 4, "-a", "--render-anim", "\n\tRender frames from start to end (inclusive)", render_animation, C);
1129         BLI_argsAdd(ba, 4, "-S", "--scene", "<name>\n\tSet the active scene <name> for rendering", set_scene, C);
1130         BLI_argsAdd(ba, 4, "-s", "--frame-start", "<frame>\n\tSet start to frame <frame> (use before the -a argument)", set_start_frame, C);
1131         BLI_argsAdd(ba, 4, "-e", "--frame-end", "<frame>\n\tSet end to frame <frame> (use before the -a argument)", set_end_frame, C);
1132         BLI_argsAdd(ba, 4, "-j", "--frame-jump", "<frames>\n\tSet number of frames to step forward after each rendered frame", set_skip_frame, C);
1133         BLI_argsAdd(ba, 4, "-P", "--python", "<filename>\n\tRun the given Python script (filename or Blender Text)", run_python, C);
1134         BLI_argsAdd(ba, 4, NULL, "--python-console", "\n\tRun blender with an interactive console", run_python_console, C);
1135         BLI_argsAdd(ba, 4, NULL, "--addons", "\n\tComma separated list of addons (no spaces)", set_addons, C);
1136
1137         BLI_argsAdd(ba, 4, "-o", "--render-output", output_doc, set_output, C);
1138         BLI_argsAdd(ba, 4, "-E", "--engine", "<engine>\n\tSpecify the render engine\n\tuse -E help to list available engines", set_engine, C);
1139
1140         BLI_argsAdd(ba, 4, "-F", "--render-format", format_doc, set_image_type, C);
1141         BLI_argsAdd(ba, 4, "-t", "--threads", "<threads>\n\tUse amount of <threads> for rendering in background\n\t[1-" STRINGIFY(BLENDER_MAX_THREADS) "], 0 for systems processor count.", set_threads, NULL);
1142         BLI_argsAdd(ba, 4, "-x", "--use-extension", "<bool>\n\tSet option to add the file extension to the end of the file", set_extension, C);
1143
1144 }
1145
1146 #ifdef WITH_PYTHON_MODULE
1147 /* allow python module to call main */
1148 #define main main_python
1149 #endif
1150
1151 int main(int argc, const char **argv)
1152 {
1153         SYS_SystemHandle syshandle;
1154         bContext *C= CTX_create();
1155         bArgs *ba;
1156
1157 #ifdef WITH_PYTHON_MODULE
1158 #undef main
1159 #endif
1160
1161 #ifdef WITH_BINRELOC
1162         br_init( NULL );
1163 #endif
1164
1165         setCallbacks();
1166 #ifdef __APPLE__
1167                 /* patch to ignore argument finder gives us (pid?) */
1168         if (argc==2 && strncmp(argv[1], "-psn_", 5)==0) {
1169                 extern int GHOST_HACK_getFirstFile(char buf[]);
1170                 static char firstfilebuf[512];
1171
1172                 argc= 1;
1173
1174                 if (GHOST_HACK_getFirstFile(firstfilebuf)) {
1175                         argc= 2;
1176                         argv[1]= firstfilebuf;
1177                 }
1178         }
1179
1180 #endif
1181
1182 #ifdef __FreeBSD__
1183         fpsetmask(0);
1184 #endif
1185
1186         // copy path to executable in bprogname. playanim and creting runtimes
1187         // need this.
1188
1189         BLI_where_am_i(bprogname, sizeof(bprogname), argv[0]);
1190         
1191 #ifdef BUILD_DATE       
1192         strip_quotes(build_date);
1193         strip_quotes(build_time);
1194         strip_quotes(build_rev);
1195         strip_quotes(build_platform);
1196         strip_quotes(build_type);
1197         strip_quotes(build_cflags);
1198         strip_quotes(build_cxxflags);
1199         strip_quotes(build_linkflags);
1200         strip_quotes(build_system);
1201 #endif
1202
1203         BLI_threadapi_init();
1204
1205         RNA_init();
1206         RE_engines_init();
1207
1208                 /* Hack - force inclusion of the plugin api functions,
1209                  * see blenpluginapi:pluginapi.c
1210                  */
1211         pluginapi_force_ref();
1212
1213         init_nodesystem();
1214         
1215         initglobals();  /* blender.c */
1216
1217         IMB_init();
1218
1219 #ifdef WITH_GAMEENGINE
1220         syshandle = SYS_GetSystem();
1221         GEN_init_messaging_system();
1222 #else
1223         syshandle= 0;
1224 #endif
1225
1226         /* first test for background */
1227         ba = BLI_argsInit(argc, argv); /* skip binary path */
1228         setupArguments(C, ba, &syshandle);
1229
1230         BLI_argsParse(ba, 1, NULL, NULL);
1231
1232 #ifdef __sgi
1233         setuid(getuid()); /* end superuser */
1234 #endif
1235
1236 #ifdef WITH_PYTHON_MODULE
1237         G.background= 1; /* python module mode ALWAYS runs in background mode (for now) */
1238 #else
1239         /* for all platforms, even windos has it! */
1240         if(G.background) signal(SIGINT, blender_esc);   /* ctrl c out bg render */
1241 #endif
1242         
1243         /* background render uses this font too */
1244         BKE_font_register_builtin(datatoc_Bfont, datatoc_Bfont_size);
1245
1246         /* Initialiaze ffmpeg if built in, also needed for bg mode if videos are
1247            rendered via ffmpeg */
1248         sound_init_once();
1249         
1250         init_def_material();
1251
1252         if(G.background==0) {
1253                 BLI_argsParse(ba, 2, NULL, NULL);
1254                 BLI_argsParse(ba, 3, NULL, NULL);
1255
1256                 WM_init(C, argc, argv);
1257
1258                 /* this is properly initialized with user defs, but this is default */
1259                 BLI_where_is_temp(btempdir, FILE_MAX, 1); /* call after loading the startup.blend so we can read U.tempdir */
1260
1261 #ifndef DISABLE_SDL
1262         BLI_setenv("SDL_VIDEODRIVER", "dummy");
1263 #endif
1264         }
1265         else {
1266                 BLI_argsParse(ba, 3, NULL, NULL);
1267
1268                 WM_init(C, argc, argv);
1269
1270                 BLI_where_is_temp(btempdir, FILE_MAX, 0); /* call after loading the startup.blend so we can read U.tempdir */
1271         }
1272 #ifdef WITH_PYTHON
1273         /**
1274          * NOTE: the U.pythondir string is NULL until WM_init() is executed,
1275          * so we provide the BPY_ function below to append the user defined
1276          * pythondir to Python's sys.path at this point.  Simply putting
1277          * WM_init() before BPY_python_start() crashes Blender at startup.
1278          * Update: now this function also inits the bpymenus, which also depend
1279          * on U.pythondir.
1280          */
1281
1282         // TODO - U.pythondir
1283 #else
1284         printf("\n* WARNING * - Blender compiled without Python!\nthis is not intended for typical usage\n\n");
1285 #endif
1286         
1287         CTX_py_init_set(C, 1);
1288         WM_keymap_init(C);
1289
1290         /* initialize Freestyle */
1291         FRS_initialize();
1292         FRS_set_context(C);
1293
1294         /* OK we are ready for it */
1295         BLI_argsParse(ba, 4, load_file, C);
1296
1297         BLI_argsFree(ba);
1298
1299 #ifdef WITH_PYTHON_MODULE
1300         return 0; /* keep blender in background mode running */
1301 #endif
1302
1303         if(G.background) {
1304                 /* actually incorrect, but works for now (ton) */
1305                 WM_exit(C);
1306         }
1307
1308         else {
1309                 if((G.fileflags & G_FILE_AUTOPLAY) && (G.f & G_SCRIPT_AUTOEXEC))
1310                 {
1311                         if(WM_init_game(C))
1312                                 return 0;
1313                 }
1314                 else if(!G.file_loaded)
1315                         WM_init_splash(C);
1316         }
1317
1318         WM_main(C);
1319
1320
1321         /*XXX if (scr_init==0) {
1322                 main_init_screen();
1323         }
1324         
1325         screenmain();*/ /* main display loop */
1326
1327         return 0;
1328 } /* end of int main(argc,argv) */
1329
1330 static void error_cb(const char *err)
1331 {
1332         
1333         printf("%s\n", err);    /* XXX do this in WM too */
1334 }
1335
1336 static void mem_error_cb(const char *errorStr)
1337 {
1338         fputs(errorStr, stderr);
1339         fflush(stderr);
1340 }
1341
1342 static void setCallbacks(void)
1343 {
1344         /* Error output from the alloc routines: */
1345         MEM_set_error_callback(mem_error_cb);
1346
1347
1348         /* BLI_blenlib: */
1349
1350         BLI_setErrorCallBack(error_cb); /* */
1351 // XXX  BLI_setInterruptCallBack(blender_test_break);
1352
1353 }