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