Merging r38780 through r38818 from trunk into soc-2011-tomato
[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 #include "BLI_callbacks.h"
68
69 #include "DNA_ID.h"
70 #include "DNA_scene_types.h"
71
72 #include "BLI_blenlib.h"
73
74 #include "BKE_utildefines.h"
75 #include "BKE_blender.h"
76 #include "BKE_context.h"
77 #include "BKE_depsgraph.h" // for DAG_on_visible_update
78 #include "BKE_font.h"
79 #include "BKE_global.h"
80 #include "BKE_main.h"
81 #include "BKE_material.h"
82 #include "BKE_packedFile.h"
83 #include "BKE_scene.h"
84 #include "BKE_node.h"
85 #include "BKE_report.h"
86 #include "BKE_sound.h"
87
88 #include "IMB_imbuf.h"  // for IMB_init
89
90 #ifdef WITH_PYTHON
91 #include "BPY_extern.h"
92 #endif
93
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 "BL_System.h"
113 #else /* dummy */
114 #define SYS_SystemHandle int
115 #endif
116
117 #include <signal.h>
118
119 #ifdef __FreeBSD__
120 # include <sys/types.h>
121 # include <floatingpoint.h>
122 # include <sys/rtprio.h>
123 #endif
124
125 #ifdef WITH_BINRELOC
126 #include "binreloc.h"
127 #endif
128
129 #ifdef WITH_LIBMV
130 #include "libmv-capi.h"
131 #endif
132
133 // from buildinfo.c
134 #ifdef BUILD_DATE
135 extern char build_date[];
136 extern char build_time[];
137 extern char build_rev[];
138 extern char build_platform[];
139 extern char build_type[];
140 extern char build_cflags[];
141 extern char build_cxxflags[];
142 extern char build_linkflags[];
143 extern char build_system[];
144 #endif
145
146 /*      Local Function prototypes */
147 static int print_help(int argc, const char **argv, void *data);
148 static int print_version(int argc, const char **argv, void *data);
149
150 /* for the callbacks: */
151
152 extern int pluginapi_force_ref(void);  /* from blenpluginapi:pluginapi.c */
153
154 char bprogname[FILE_MAX]; /* from blenpluginapi:pluginapi.c */
155 char btempdir[FILE_MAX];
156
157 #define BLEND_VERSION_STRING_FMT "Blender %d.%02d (sub %d)\n", BLENDER_VERSION/100, BLENDER_VERSION%100, BLENDER_SUBVERSION
158
159 /* Initialize callbacks for the modules that need them */
160 static void setCallbacks(void); 
161
162 /* set breakpoints here when running in debug mode, useful to catch floating point errors */
163 #if defined(__sgi) || defined(__linux__) || defined(_WIN32) || defined(OSX_SSE_FPE)
164 static void fpe_handler(int UNUSED(sig))
165 {
166         // printf("SIGFPE trapped\n");
167 }
168 #endif
169
170 #ifndef WITH_PYTHON_MODULE
171 /* handling ctrl-c event in console */
172 static void blender_esc(int sig)
173 {
174         static int count = 0;
175         
176         G.afbreek = 1;  /* forces render loop to read queue, not sure if its needed */
177         
178         if (sig == 2) {
179                 if (count) {
180                         printf("\nBlender killed\n");
181                         exit(2);
182                 }
183                 printf("\nSent an internal break event. Press ^C again to kill Blender\n");
184                 count++;
185         }
186 }
187 #endif
188
189 /* buildinfo can have quotes */
190 #ifdef BUILD_DATE
191 static void strip_quotes(char *str)
192 {
193         if(str[0] == '"') {
194                 int len= strlen(str) - 1;
195                 memmove(str, str+1, len);
196                 if(str[len-1] == '"') {
197                         str[len-1]= '\0';
198                 }
199         }
200 }
201 #endif
202
203 static int print_version(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
204 {
205         printf (BLEND_VERSION_STRING_FMT);
206 #ifdef BUILD_DATE
207         printf ("\tbuild date: %s\n", build_date);
208         printf ("\tbuild time: %s\n", build_time);
209         printf ("\tbuild revision: %s\n", build_rev);
210         printf ("\tbuild platform: %s\n", build_platform);
211         printf ("\tbuild type: %s\n", build_type);
212         printf ("\tbuild c flags: %s\n", build_cflags);
213         printf ("\tbuild c++ flags: %s\n", build_cxxflags);
214         printf ("\tbuild link flags: %s\n", build_linkflags);
215         printf ("\tbuild system: %s\n", build_system);
216 #endif
217         exit(0);
218
219         return 0;
220 }
221
222 static int print_help(int UNUSED(argc), const char **UNUSED(argv), void *data)
223 {
224         bArgs *ba = (bArgs*)data;
225
226         printf (BLEND_VERSION_STRING_FMT);
227         printf ("Usage: blender [args ...] [file] [args ...]\n\n");
228
229         printf ("Render Options:\n");
230         BLI_argsPrintArgDoc(ba, "--background");
231         BLI_argsPrintArgDoc(ba, "--render-anim");
232         BLI_argsPrintArgDoc(ba, "--scene");
233         BLI_argsPrintArgDoc(ba, "--render-frame");
234         BLI_argsPrintArgDoc(ba, "--frame-start");
235         BLI_argsPrintArgDoc(ba, "--frame-end");
236         BLI_argsPrintArgDoc(ba, "--frame-jump");
237         BLI_argsPrintArgDoc(ba, "--render-output");
238         BLI_argsPrintArgDoc(ba, "--engine");
239         
240         printf("\n");
241         printf ("Format Options:\n");
242         BLI_argsPrintArgDoc(ba, "--render-format");
243         BLI_argsPrintArgDoc(ba, "--use-extension");
244         BLI_argsPrintArgDoc(ba, "--threads");
245
246         printf("\n");
247         printf ("Animation Playback Options:\n");
248         BLI_argsPrintArgDoc(ba, "-a");
249                                 
250         printf("\n");
251         printf ("Window Options:\n");
252         BLI_argsPrintArgDoc(ba, "--window-border");
253         BLI_argsPrintArgDoc(ba, "--window-borderless");
254         BLI_argsPrintArgDoc(ba, "--window-geometry");
255         BLI_argsPrintArgDoc(ba, "--start-console");
256
257         printf("\n");
258         printf ("Game Engine Specific Options:\n");
259         BLI_argsPrintArgDoc(ba, "-g");
260
261         printf("\n");
262         printf ("Misc Options:\n");
263         BLI_argsPrintArgDoc(ba, "--debug");
264         BLI_argsPrintArgDoc(ba, "--debug-fpe");
265         printf("\n");
266         BLI_argsPrintArgDoc(ba, "--factory-startup");
267         printf("\n");
268         BLI_argsPrintArgDoc(ba, "--env-system-config");
269         BLI_argsPrintArgDoc(ba, "--env-system-datafiles");
270         BLI_argsPrintArgDoc(ba, "--env-system-scripts");
271         BLI_argsPrintArgDoc(ba, "--env-system-plugins");
272         BLI_argsPrintArgDoc(ba, "--env-system-python");
273         printf("\n");
274         BLI_argsPrintArgDoc(ba, "-nojoystick");
275         BLI_argsPrintArgDoc(ba, "-noglsl");
276         BLI_argsPrintArgDoc(ba, "-noaudio");
277         BLI_argsPrintArgDoc(ba, "-setaudio");
278
279         printf("\n");
280
281         BLI_argsPrintArgDoc(ba, "--help");
282
283         printf("\n");
284
285         BLI_argsPrintArgDoc(ba, "--enable-autoexec");
286         BLI_argsPrintArgDoc(ba, "--disable-autoexec");
287
288         printf("\n");
289
290         BLI_argsPrintArgDoc(ba, "--python");
291         BLI_argsPrintArgDoc(ba, "--python-console");
292         BLI_argsPrintArgDoc(ba, "--addons");
293
294 #ifdef WIN32
295         BLI_argsPrintArgDoc(ba, "-R");
296         BLI_argsPrintArgDoc(ba, "-r");
297 #endif
298         BLI_argsPrintArgDoc(ba, "--version");
299
300         BLI_argsPrintArgDoc(ba, "--");
301
302         printf ("Other Options:\n");
303         BLI_argsPrintOtherDoc(ba);
304
305         printf ("Argument Parsing:\n");
306         printf ("\targuments must be separated by white space. eg\n");
307         printf ("\t\t\"blender -ba test.blend\"\n");
308         printf ("\t...will ignore the 'a'\n");
309         printf ("\t\t\"blender -b test.blend -f8\"\n");
310         printf ("\t...will ignore 8 because there is no space between the -f and the frame value\n\n");
311
312         printf ("Argument Order:\n");
313         printf ("Arguments are executed in the order they are given. eg\n");
314         printf ("\t\t\"blender --background test.blend --render-frame 1 --render-output /tmp\"\n");
315         printf ("\t...will not render to /tmp because '--render-frame 1' renders before the output path is set\n");
316         printf ("\t\t\"blender --background --render-output /tmp test.blend --render-frame 1\"\n");
317         printf ("\t...will not render to /tmp because loading the blend file overwrites the render output that was set\n");
318         printf ("\t\t\"blender --background test.blend --render-output /tmp --render-frame 1\" works as expected.\n\n");
319
320         printf ("\nEnvironment Variables:\n");
321         printf ("  $BLENDER_USER_CONFIG      Directory for user configuration files.\n");
322         printf ("  $BLENDER_USER_SCRIPTS     Directory for user scripts.\n");
323         printf ("  $BLENDER_SYSTEM_SCRIPTS   Directory for system wide scripts.\n");
324         printf ("  $BLENDER_USER_DATAFILES   Directory for user data files (icons, translations, ..).\n");
325         printf ("  $BLENDER_SYSTEM_DATAFILES Directory for system wide data files.\n");
326         printf ("  $BLENDER_SYSTEM_PYTHON    Directory for system python libraries.\n");
327 #ifdef WIN32
328         printf ("  $TEMP                     Store temporary files here.\n");
329 #else
330         printf ("  $TMP or $TMPDIR           Store temporary files here.\n");
331 #endif
332 #ifndef DISABLE_SDL
333         printf ("  $SDL_AUDIODRIVER          LibSDL audio driver - alsa, esd, dma.\n");
334 #endif
335         printf ("  $PYTHONHOME               Path to the python directory, eg. /usr/lib/python.\n\n");
336
337         exit(0);
338
339         return 0;
340 }
341
342
343 double PIL_check_seconds_timer(void);
344
345 static int end_arguments(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
346 {
347         return -1;
348 }
349
350 static int enable_python(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
351 {
352         G.f |= G_SCRIPT_AUTOEXEC;
353         G.f |= G_SCRIPT_OVERRIDE_PREF;
354         return 0;
355 }
356
357 static int disable_python(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
358 {
359         G.f &= ~G_SCRIPT_AUTOEXEC;
360         G.f |= G_SCRIPT_OVERRIDE_PREF;
361         return 0;
362 }
363
364 static int background_mode(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
365 {
366         G.background = 1;
367         return 0;
368 }
369
370 static int debug_mode(int UNUSED(argc), const char **UNUSED(argv), void *data)
371 {
372         G.f |= G_DEBUG;         /* std output printf's */
373         printf(BLEND_VERSION_STRING_FMT);
374         MEM_set_memory_debug();
375
376 #ifdef NAN_BUILDINFO
377         printf("Build: %s %s %s %s\n", build_date, build_time, build_platform, build_type);
378 #endif // NAN_BUILDINFO
379
380 #ifdef WITH_LIBMV
381         libmv_startDebugLogging();
382 #endif
383
384         BLI_argsPrint(data);
385         return 0;
386 }
387
388 static int set_fpe(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
389 {
390 #if defined(__sgi) || defined(__linux__) || defined(_WIN32) || defined(OSX_SSE_FPE)
391         /* zealous but makes float issues a heck of a lot easier to find!
392          * set breakpoints on fpe_handler */
393         signal(SIGFPE, fpe_handler);
394
395 # if defined(__linux__) && defined(__GNUC__)
396         feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW );
397 # endif /* defined(__linux__) && defined(__GNUC__) */
398 # if defined(OSX_SSE_FPE)
399         /* OSX uses SSE for floating point by default, so here 
400          * use SSE instructions to throw floating point exceptions */
401         _MM_SET_EXCEPTION_MASK(_MM_MASK_MASK &~
402                         (_MM_MASK_OVERFLOW|_MM_MASK_INVALID|_MM_MASK_DIV_ZERO));
403 # endif /* OSX_SSE_FPE */
404 # if defined(_WIN32) && defined(_MSC_VER)
405         _controlfp_s(NULL, 0, _MCW_EM); /* enables all fp exceptions */
406         _controlfp_s(NULL, _EM_DENORMAL | _EM_UNDERFLOW | _EM_INEXACT, _MCW_EM); /* hide the ones we don't care about */
407 # endif /* _WIN32 && _MSC_VER */
408 #endif
409
410         return 0;
411 }
412
413 static int set_factory_startup(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
414 {
415         G.factory_startup= 1;
416         return 0;
417 }
418
419 static int set_env(int argc, const char **argv, void *UNUSED(data))
420 {
421         /* "--env-system-scripts" --> "BLENDER_SYSTEM_SCRIPTS" */
422
423         char env[64]= "BLENDER";
424         char *ch_dst= env + 7; /* skip BLENDER */
425         const char *ch_src= argv[0] + 5; /* skip --env */
426
427         if (argc < 2) {
428                 printf("%s requires one argument\n", argv[0]);
429                 exit(1);
430         }
431
432         for(; *ch_src; ch_src++, ch_dst++) {
433                 *ch_dst= (*ch_src == '-') ? '_' : (*ch_src)-32; /* toupper() */
434         }
435
436         *ch_dst= '\0';
437         BLI_setenv(env, argv[1]);
438         return 1;
439 }
440
441 static int playback_mode(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
442 {
443         /* not if -b was given first */
444         if (G.background == 0) {
445 #if 0   /* TODO, bring player back? */
446                 playanim(argc, argv); /* not the same argc and argv as before */
447 #else
448                 fprintf(stderr, "Playback mode not supported in blender 2.5x\n");
449                 exit(0);
450 #endif
451         }
452
453         return -2;
454 }
455
456 static int prefsize(int argc, const char **argv, void *UNUSED(data))
457 {
458         int stax, stay, sizx, sizy;
459
460         if (argc < 5) {
461                 printf ("-p requires four arguments\n");
462                 exit(1);
463         }
464
465         stax= atoi(argv[1]);
466         stay= atoi(argv[2]);
467         sizx= atoi(argv[3]);
468         sizy= atoi(argv[4]);
469
470         WM_setprefsize(stax, stay, sizx, sizy);
471
472         return 4;
473 }
474
475 static int with_borders(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
476 {
477         WM_setinitialstate_normal();
478         return 0;
479 }
480
481 static int without_borders(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
482 {
483         WM_setinitialstate_fullscreen();
484         return 0;
485 }
486
487 extern int wm_start_with_console; // blender/windowmanager/intern/wm_init_exit.c
488 static int start_with_console(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
489 {
490         wm_start_with_console = 1;
491         return 0;
492 }
493
494 static int register_extension(int UNUSED(argc), const char **UNUSED(argv), void *data)
495 {
496 #ifdef WIN32
497         if (data)
498                 G.background = 1;
499         RegisterBlendExtension();
500 #else
501         (void)data; /* unused */
502 #endif
503         return 0;
504 }
505
506 static int no_joystick(int UNUSED(argc), const char **UNUSED(argv), void *data)
507 {
508 #ifndef WITH_GAMEENGINE
509         (void)data;
510 #else
511         SYS_SystemHandle *syshandle = data;
512
513         /**
514                 don't initialize joysticks if user doesn't want to use joysticks
515                 failed joystick initialization delays over 5 seconds, before game engine start
516         */
517         SYS_WriteCommandLineInt(*syshandle, "nojoystick",1);
518         if (G.f & G_DEBUG) printf("disabling nojoystick\n");
519 #endif
520
521         return 0;
522 }
523
524 static int no_glsl(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
525 {
526         GPU_extensions_disable();
527         return 0;
528 }
529
530 static int no_audio(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
531 {
532         sound_force_device(0);
533         return 0;
534 }
535
536 static int set_audio(int argc, const char **argv, void *UNUSED(data))
537 {
538         if (argc < 1) {
539                 printf("-setaudio require one argument\n");
540                 exit(1);
541         }
542
543         sound_force_device(sound_define_from_str(argv[1]));
544         return 1;
545 }
546
547 static int set_output(int argc, const char **argv, void *data)
548 {
549         bContext *C = data;
550         if (argc >= 1){
551                 if (CTX_data_scene(C)) {
552                         Scene *scene= CTX_data_scene(C);
553                         BLI_strncpy(scene->r.pic, argv[1], sizeof(scene->r.pic));
554                 } else {
555                         printf("\nError: no blend loaded. cannot use '-o / --render-output'.\n");
556                 }
557                 return 1;
558         } else {
559                 printf("\nError: you must specify a path after '-o  / --render-output'.\n");
560                 return 0;
561         }
562 }
563
564 static int set_engine(int argc, const char **argv, void *data)
565 {
566         bContext *C = data;
567         if (argc >= 1)
568         {
569                 if (!strcmp(argv[1],"help"))
570                 {
571                         RenderEngineType *type = NULL;
572
573                         for( type = R_engines.first; type; type = type->next )
574                         {
575                                 printf("\t%s\n", type->idname);
576                         }
577                         exit(0);
578                 }
579                 else
580                 {
581                         if (CTX_data_scene(C)==NULL)
582                         {
583                                 printf("\nError: no blend loaded. order the arguments so '-E  / --engine ' is after a blend is loaded.\n");
584                         }
585                         else {
586                                 Scene *scene= CTX_data_scene(C);
587                                 RenderData *rd = &scene->r;
588
589                                 if(BLI_findstring(&R_engines, argv[1], offsetof(RenderEngineType, idname))) {
590                                         BLI_strncpy(rd->engine, argv[1], sizeof(rd->engine));
591                                 }
592                         }
593                 }
594
595                 return 1;
596         }
597         else
598         {
599                 printf("\nEngine not specified.\n");
600                 return 0;
601         }
602 }
603
604 static int set_image_type(int argc, const char **argv, void *data)
605 {
606         bContext *C = data;
607         if (argc >= 1){
608                 const char *imtype = argv[1];
609                 if (CTX_data_scene(C)==NULL) {
610                         printf("\nError: no blend loaded. order the arguments so '-F  / --render-format' is after the blend is loaded.\n");
611                 } else {
612                         Scene *scene= CTX_data_scene(C);
613                         if      (!strcmp(imtype,"TGA")) scene->r.imtype = R_TARGA;
614                         else if (!strcmp(imtype,"IRIS")) scene->r.imtype = R_IRIS;
615 #ifdef WITH_DDS
616                         else if (!strcmp(imtype,"DDS")) scene->r.imtype = R_DDS;
617 #endif
618                         else if (!strcmp(imtype,"JPEG")) scene->r.imtype = R_JPEG90;
619                         else if (!strcmp(imtype,"IRIZ")) scene->r.imtype = R_IRIZ;
620                         else if (!strcmp(imtype,"RAWTGA")) scene->r.imtype = R_RAWTGA;
621                         else if (!strcmp(imtype,"AVIRAW")) scene->r.imtype = R_AVIRAW;
622                         else if (!strcmp(imtype,"AVIJPEG")) scene->r.imtype = R_AVIJPEG;
623                         else if (!strcmp(imtype,"PNG")) scene->r.imtype = R_PNG;
624                         else if (!strcmp(imtype,"AVICODEC")) scene->r.imtype = R_AVICODEC;
625                         else if (!strcmp(imtype,"QUICKTIME")) scene->r.imtype = R_QUICKTIME;
626                         else if (!strcmp(imtype,"BMP")) scene->r.imtype = R_BMP;
627 #ifdef WITH_HDR
628                         else if (!strcmp(imtype,"HDR")) scene->r.imtype = R_RADHDR;
629 #endif
630 #ifdef WITH_TIFF
631                         else if (!strcmp(imtype,"TIFF")) scene->r.imtype = R_TIFF;
632 #endif
633 #ifdef WITH_OPENEXR
634                         else if (!strcmp(imtype,"EXR")) scene->r.imtype = R_OPENEXR;
635                         else if (!strcmp(imtype,"MULTILAYER")) scene->r.imtype = R_MULTILAYER;
636 #endif
637                         else if (!strcmp(imtype,"MPEG")) scene->r.imtype = R_FFMPEG;
638                         else if (!strcmp(imtype,"FRAMESERVER")) scene->r.imtype = R_FRAMESERVER;
639 #ifdef WITH_CINEON
640                         else if (!strcmp(imtype,"CINEON")) scene->r.imtype = R_CINEON;
641                         else if (!strcmp(imtype,"DPX")) scene->r.imtype = R_DPX;
642 #endif
643 #ifdef WITH_OPENJPEG
644                         else if (!strcmp(imtype,"JP2")) scene->r.imtype = R_JP2;
645 #endif
646                         else printf("\nError: Format from '-F / --render-format' not known or not compiled in this release.\n");
647                 }
648                 return 1;
649         } else {
650                 printf("\nError: you must specify a format after '-F  / --render-foramt'.\n");
651                 return 0;
652         }
653 }
654
655 static int set_threads(int argc, const char **argv, void *UNUSED(data))
656 {
657         if (argc >= 1) {
658                 if(G.background) {
659                         RE_set_max_threads(atoi(argv[1]));
660                 } else {
661                         printf("Warning: threads can only be set in background mode\n");
662                 }
663                 return 1;
664         } else {
665                 printf("\nError: you must specify a number of threads between 0 and 8 '-t  / --threads'.\n");
666                 return 0;
667         }
668 }
669
670 static int set_extension(int argc, const char **argv, void *data)
671 {
672         bContext *C = data;
673         if (argc >= 1) {
674                 if (CTX_data_scene(C)) {
675                         Scene *scene= CTX_data_scene(C);
676                         if (argv[1][0] == '0') {
677                                 scene->r.scemode &= ~R_EXTENSION;
678                         } else if (argv[1][0] == '1') {
679                                 scene->r.scemode |= R_EXTENSION;
680                         } else {
681                                 printf("\nError: Use '-x 1 / -x 0' To set the extension option or '--use-extension'\n");
682                         }
683                 } else {
684                         printf("\nError: no blend loaded. order the arguments so '-o ' is after '-x '.\n");
685                 }
686                 return 1;
687         } else {
688                 printf("\nError: you must specify a path after '- '.\n");
689                 return 0;
690         }
691 }
692
693 static int set_ge_parameters(int argc, const char **argv, void *data)
694 {
695         int a = 0;
696 #ifdef WITH_GAMEENGINE
697         SYS_SystemHandle syshandle = *(SYS_SystemHandle*)data;
698 #else
699         (void)data;
700 #endif
701
702 /**
703 gameengine parameters are automaticly put into system
704 -g [paramname = value]
705 -g [boolparamname]
706 example:
707 -g novertexarrays
708 -g maxvertexarraysize = 512
709 */
710
711         if(argc >= 1)
712         {
713                 const char *paramname = argv[a];
714                 /* check for single value versus assignment */
715                 if (a+1 < argc && (*(argv[a+1]) == '='))
716                 {
717                         a++;
718                         if (a+1 < argc)
719                         {
720                                 a++;
721                                 /* assignment */
722 #ifdef WITH_GAMEENGINE
723                                 SYS_WriteCommandLineString(syshandle,paramname,argv[a]);
724 #endif
725                         }  else
726                         {
727                                 printf("error: argument assignment (%s) without value.\n",paramname);
728                                 return 0;
729                         }
730                         /* name arg eaten */
731
732                 } else {
733 #ifdef WITH_GAMEENGINE
734                         SYS_WriteCommandLineInt(syshandle,argv[a],1);
735 #endif
736                         /* doMipMap */
737                         if (!strcmp(argv[a],"nomipmap"))
738                         {
739                                 GPU_set_mipmap(0); //doMipMap = 0;
740                         }
741                         /* linearMipMap */
742                         if (!strcmp(argv[a],"linearmipmap"))
743                         {
744                                 GPU_set_linear_mipmap(1); //linearMipMap = 1;
745                         }
746
747
748                 } /* if (*(argv[a+1]) == '=') */
749         }
750
751         return a;
752 }
753
754 static int render_frame(int argc, const char **argv, void *data)
755 {
756         bContext *C = data;
757         if (CTX_data_scene(C)) {
758                 Main *bmain= CTX_data_main(C);
759                 Scene *scene= CTX_data_scene(C);
760
761                 if (argc > 1) {
762                         Render *re = RE_NewRender(scene->id.name);
763                         int frame;
764                         ReportList reports;
765
766                         switch(*argv[1]) {
767                         case '+':
768                                 frame= scene->r.sfra + atoi(argv[1]+1);
769                                 break;
770                         case '-':
771                                 frame= (scene->r.efra - atoi(argv[1]+1)) + 1;
772                                 break;
773                         default:
774                                 frame= atoi(argv[1]);
775                                 break;
776                         }
777
778                         BKE_reports_init(&reports, RPT_PRINT);
779
780                         frame = MIN2(MAXFRAME, MAX2(MINAFRAME, frame));
781
782                         RE_SetReports(re, &reports);
783                         RE_BlenderAnim(re, bmain, scene, NULL, scene->lay, frame, frame, scene->r.frame_step);
784                         RE_SetReports(re, NULL);
785                         return 1;
786                 } else {
787                         printf("\nError: frame number must follow '-f / --render-frame'.\n");
788                         return 0;
789                 }
790         } else {
791                 printf("\nError: no blend loaded. cannot use '-f / --render-frame'.\n");
792                 return 0;
793         }
794 }
795
796 static int render_animation(int UNUSED(argc), const char **UNUSED(argv), void *data)
797 {
798         bContext *C = data;
799         if (CTX_data_scene(C)) {
800                 Main *bmain= CTX_data_main(C);
801                 Scene *scene= CTX_data_scene(C);
802                 Render *re= RE_NewRender(scene->id.name);
803                 ReportList reports;
804                 BKE_reports_init(&reports, RPT_PRINT);
805                 RE_SetReports(re, &reports);
806                 RE_BlenderAnim(re, bmain, scene, NULL, scene->lay, scene->r.sfra, scene->r.efra, scene->r.frame_step);
807                 RE_SetReports(re, NULL);
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_app_handlers_reset();
1010                 BPY_modules_load_user(C);
1011 #endif
1012
1013                 /* happens for the UI on file reading too (huh? (ton))*/
1014         // XXX                  BKE_reset_undo();
1015         //                              BKE_write_undo("original");     /* save current state */
1016         } else {
1017                 /* we are not running in background mode here, but start blender in UI mode with
1018                    a file - this should do everything a 'load file' does */
1019                 ReportList reports;
1020                 BKE_reports_init(&reports, RPT_PRINT);
1021                 WM_read_file(C, filename, &reports);
1022                 BKE_reports_clear(&reports);
1023         }
1024
1025         G.file_loaded = 1;
1026
1027         return 0;
1028 }
1029
1030 static void setupArguments(bContext *C, bArgs *ba, SYS_SystemHandle *syshandle)
1031 {
1032         static char output_doc[] = "<path>"
1033                 "\n\tSet the render path and file name."
1034                 "\n\tUse // at the start of the path to"
1035                 "\n\t\trender relative to the blend file."
1036                 "\n\tThe # characters are replaced by the frame number, and used to define zero padding."
1037                 "\n\t\tani_##_test.png becomes ani_01_test.png"
1038                 "\n\t\ttest-######.png becomes test-000001.png"
1039                 "\n\t\tWhen the filename does not contain #, The suffix #### is added to the filename"
1040                 "\n\tThe frame number will be added at the end of the filename."
1041                 "\n\t\teg: blender -b foobar.blend -o //render_ -F PNG -x 1 -a"
1042                 "\n\t\t//render_ becomes //render_####, writing frames as //render_0001.png//";
1043
1044         static char format_doc[] = "<format>"
1045                 "\n\tSet the render format, Valid options are..."
1046                 "\n\t\tTGA IRIS JPEG MOVIE IRIZ RAWTGA"
1047                 "\n\t\tAVIRAW AVIJPEG PNG BMP FRAMESERVER"
1048                 "\n\t(formats that can be compiled into blender, not available on all systems)"
1049                 "\n\t\tHDR TIFF EXR MULTILAYER MPEG AVICODEC QUICKTIME CINEON DPX DDS";
1050
1051         static char playback_doc[] = "<options> <file(s)>"
1052                 "\n\tPlayback <file(s)>, only operates this way when not running in background."
1053                 "\n\t\t-p <sx> <sy>\tOpen with lower left corner at <sx>, <sy>"
1054                 "\n\t\t-m\t\tRead from disk (Don't buffer)"
1055                 "\n\t\t-f <fps> <fps-base>\t\tSpecify FPS to start with"
1056                 "\n\t\t-j <frame>\tSet frame step to <frame>";
1057
1058         static char game_doc[] = "Game Engine specific options"
1059                 "\n\t-g fixedtime\t\tRun on 50 hertz without dropping frames"
1060                 "\n\t-g vertexarrays\t\tUse Vertex Arrays for rendering (usually faster)"
1061                 "\n\t-g nomipmap\t\tNo Texture Mipmapping"
1062                 "\n\t-g linearmipmap\t\tLinear Texture Mipmapping instead of Nearest (default)";
1063
1064         static char debug_doc[] = "\n\tTurn debugging on\n"
1065                 "\n\t* Prints every operator call and their arguments"
1066                 "\n\t* Disables mouse grab (to interact with a debugger in some cases)"
1067                 "\n\t* Keeps python sys.stdin rather than setting it to None";
1068
1069         //BLI_argsAdd(ba, pass, short_arg, long_arg, doc, cb, C);
1070
1071         /* end argument processing after -- */
1072         BLI_argsAdd(ba, -1, "--", NULL, "\n\tEnds option processing, following arguments passed unchanged. Access via python's sys.argv", end_arguments, NULL);
1073
1074         /* first pass: background mode, disable python and commands that exit after usage */
1075         BLI_argsAdd(ba, 1, "-h", "--help", "\n\tPrint this help text and exit", print_help, ba);
1076         /* Windows only */
1077         BLI_argsAdd(ba, 1, "/?", NULL, "\n\tPrint this help text and exit (windows only)", print_help, ba);
1078
1079         BLI_argsAdd(ba, 1, "-v", "--version", "\n\tPrint Blender version and exit", print_version, NULL);
1080         
1081         /* only to give help message */
1082 #ifndef WITH_PYTHON_SECURITY /* default */
1083 #  define       PY_ENABLE_AUTO ", (default)"
1084 #  define       PY_DISABLE_AUTO ""
1085 #else
1086 #  define       PY_ENABLE_AUTO ""
1087 #  define       PY_DISABLE_AUTO ", (compiled as non-standard default)"
1088 #endif
1089
1090         BLI_argsAdd(ba, 1, "-y", "--enable-autoexec", "\n\tEnable automatic python script execution" PY_ENABLE_AUTO, enable_python, NULL);
1091         BLI_argsAdd(ba, 1, "-Y", "--disable-autoexec", "\n\tDisable automatic python script execution (pydrivers, pyconstraints, pynodes)" PY_DISABLE_AUTO, disable_python, NULL);
1092
1093 #undef PY_ENABLE_AUTO
1094 #undef PY_DISABLE_AUTO
1095         
1096         BLI_argsAdd(ba, 1, "-b", "--background", "<file>\n\tLoad <file> in background (often used for UI-less rendering)", background_mode, NULL);
1097
1098         BLI_argsAdd(ba, 1, "-a", NULL, playback_doc, playback_mode, NULL);
1099
1100         BLI_argsAdd(ba, 1, "-d", "--debug", debug_doc, debug_mode, ba);
1101         BLI_argsAdd(ba, 1, NULL, "--debug-fpe", "\n\tEnable floating point exceptions", set_fpe, NULL);
1102
1103         BLI_argsAdd(ba, 1, NULL, "--factory-startup", "\n\tSkip reading the "STRINGIFY(BLENDER_STARTUP_FILE)" in the users home directory", set_factory_startup, NULL);
1104
1105         /* TODO, add user env vars? */
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_enter
1149 static void *evil_C= NULL;
1150 #endif
1151
1152 int main(int argc, const char **argv)
1153 {
1154         SYS_SystemHandle syshandle;
1155         bContext *C= CTX_create();
1156         bArgs *ba;
1157
1158 #ifdef WITH_PYTHON_MODULE
1159 #undef main
1160         evil_C= C;
1161 #endif
1162
1163 #ifdef WITH_BINRELOC
1164         br_init( NULL );
1165 #endif
1166
1167 #ifdef WITH_LIBMV
1168         libmv_initLogging(argv[0]);
1169 #endif
1170
1171         setCallbacks();
1172 #ifdef __APPLE__
1173                 /* patch to ignore argument finder gives us (pid?) */
1174         if (argc==2 && strncmp(argv[1], "-psn_", 5)==0) {
1175                 extern int GHOST_HACK_getFirstFile(char buf[]);
1176                 static char firstfilebuf[512];
1177
1178                 argc= 1;
1179
1180                 if (GHOST_HACK_getFirstFile(firstfilebuf)) {
1181                         argc= 2;
1182                         argv[1]= firstfilebuf;
1183                 }
1184         }
1185
1186 #endif
1187
1188 #ifdef __FreeBSD__
1189         fpsetmask(0);
1190 #endif
1191
1192         // copy path to executable in bprogname. playanim and creting runtimes
1193         // need this.
1194
1195         BLI_where_am_i(bprogname, sizeof(bprogname), argv[0]);
1196         
1197 #ifdef BUILD_DATE       
1198         strip_quotes(build_date);
1199         strip_quotes(build_time);
1200         strip_quotes(build_rev);
1201         strip_quotes(build_platform);
1202         strip_quotes(build_type);
1203         strip_quotes(build_cflags);
1204         strip_quotes(build_cxxflags);
1205         strip_quotes(build_linkflags);
1206         strip_quotes(build_system);
1207 #endif
1208
1209         BLI_threadapi_init();
1210
1211         RNA_init();
1212         RE_engines_init();
1213
1214                 /* Hack - force inclusion of the plugin api functions,
1215                  * see blenpluginapi:pluginapi.c
1216                  */
1217         pluginapi_force_ref();
1218
1219         init_nodesystem();
1220         
1221         initglobals();  /* blender.c */
1222
1223         IMB_init();
1224
1225         BLI_cb_init();
1226
1227 #ifdef WITH_GAMEENGINE
1228         syshandle = SYS_GetSystem();
1229 #else
1230         syshandle= 0;
1231 #endif
1232
1233         /* first test for background */
1234         ba = BLI_argsInit(argc, argv); /* skip binary path */
1235         setupArguments(C, ba, &syshandle);
1236
1237         BLI_argsParse(ba, 1, NULL, NULL);
1238
1239 #ifdef __sgi
1240         setuid(getuid()); /* end superuser */
1241 #endif
1242
1243 #if defined(WITH_PYTHON_MODULE) || defined(WITH_HEADLESS)
1244         G.background= 1; /* python module mode ALWAYS runs in background mode (for now) */
1245 #else
1246         /* for all platforms, even windos has it! */
1247         if(G.background) signal(SIGINT, blender_esc);   /* ctrl c out bg render */
1248 #endif
1249
1250         /* background render uses this font too */
1251         BKE_font_register_builtin(datatoc_Bfont, datatoc_Bfont_size);
1252
1253         /* Initialiaze ffmpeg if built in, also needed for bg mode if videos are
1254            rendered via ffmpeg */
1255         sound_init_once();
1256         
1257         init_def_material();
1258
1259         if(G.background==0) {
1260                 BLI_argsParse(ba, 2, NULL, NULL);
1261                 BLI_argsParse(ba, 3, NULL, NULL);
1262
1263                 WM_init(C, argc, argv);
1264
1265                 /* this is properly initialized with user defs, but this is default */
1266                 BLI_where_is_temp(btempdir, FILE_MAX, 1); /* call after loading the startup.blend so we can read U.tempdir */
1267
1268 #ifndef DISABLE_SDL
1269         BLI_setenv("SDL_VIDEODRIVER", "dummy");
1270 #endif
1271         }
1272         else {
1273                 BLI_argsParse(ba, 3, NULL, NULL);
1274
1275                 WM_init(C, argc, argv);
1276
1277                 BLI_where_is_temp(btempdir, FILE_MAX, 0); /* call after loading the startup.blend so we can read U.tempdir */
1278         }
1279 #ifdef WITH_PYTHON
1280         /**
1281          * NOTE: the U.pythondir string is NULL until WM_init() is executed,
1282          * so we provide the BPY_ function below to append the user defined
1283          * pythondir to Python's sys.path at this point.  Simply putting
1284          * WM_init() before BPY_python_start() crashes Blender at startup.
1285          * Update: now this function also inits the bpymenus, which also depend
1286          * on U.pythondir.
1287          */
1288
1289         // TODO - U.pythondir
1290 #else
1291         printf("\n* WARNING * - Blender compiled without Python!\nthis is not intended for typical usage\n\n");
1292 #endif
1293         
1294         CTX_py_init_set(C, 1);
1295         WM_keymap_init(C);
1296
1297         /* OK we are ready for it */
1298         BLI_argsParse(ba, 4, load_file, C);
1299
1300         BLI_argsFree(ba);
1301
1302 #ifdef WITH_PYTHON_MODULE
1303         return 0; /* keep blender in background mode running */
1304 #endif
1305
1306         if(G.background) {
1307                 /* actually incorrect, but works for now (ton) */
1308                 WM_exit(C);
1309         }
1310
1311         else {
1312                 if((G.fileflags & G_FILE_AUTOPLAY) && (G.f & G_SCRIPT_AUTOEXEC))
1313                 {
1314                         if(WM_init_game(C))
1315                                 return 0;
1316                 }
1317                 else if(!G.file_loaded)
1318                         WM_init_splash(C);
1319         }
1320
1321         WM_main(C);
1322
1323
1324         /*XXX if (scr_init==0) {
1325                 main_init_screen();
1326         }
1327         
1328         screenmain();*/ /* main display loop */
1329
1330         return 0;
1331 } /* end of int main(argc,argv) */
1332
1333 #ifdef WITH_PYTHON_MODULE
1334 void main_python_exit(void)
1335 {
1336         WM_exit((bContext *)evil_C);
1337         evil_C= NULL;
1338 }
1339 #endif
1340
1341 static void error_cb(const char *err)
1342 {
1343         
1344         printf("%s\n", err);    /* XXX do this in WM too */
1345 }
1346
1347 static void mem_error_cb(const char *errorStr)
1348 {
1349         fputs(errorStr, stderr);
1350         fflush(stderr);
1351 }
1352
1353 static void setCallbacks(void)
1354 {
1355         /* Error output from the alloc routines: */
1356         MEM_set_error_callback(mem_error_cb);
1357
1358
1359         /* BLI_blenlib: */
1360
1361         BLI_setErrorCallBack(error_cb); /* */
1362 // XXX  BLI_setInterruptCallBack(blender_test_break);
1363
1364 }