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