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