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