remove po/ since the workflow for translations uses branches which isnt that useful...
[blender.git] / source / creator / creator.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): none yet.
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file creator/creator.c
29  *  \ingroup creator
30  */
31
32
33 #if defined(__linux__) && defined(__GNUC__)
34 #define _GNU_SOURCE
35 #include <fenv.h>
36 #endif
37
38 #if (defined(__APPLE__) && (defined(__i386__) || defined(__x86_64__)))
39 #define OSX_SSE_FPE
40 #include <xmmintrin.h>
41 #endif
42
43 #include <stdlib.h>
44 #include <stddef.h>
45 #include <string.h>
46
47 /* This little block needed for linking to Blender... */
48
49 #include "MEM_guardedalloc.h"
50
51 #ifdef WIN32
52 #include "BLI_winstuff.h"
53 #endif
54
55 #include "BLI_args.h"
56 #include "BLI_threads.h"
57 #include "BLI_scanfill.h" // for BLI_setErrorCallBack, TODO, move elsewhere
58 #include "BLI_utildefines.h"
59 #include "BLI_callbacks.h"
60
61 #include "DNA_ID.h"
62 #include "DNA_scene_types.h"
63 #include "DNA_userdef_types.h"
64
65 #include "BLI_blenlib.h"
66
67 #include "BKE_utildefines.h"
68 #include "BKE_blender.h"
69 #include "BKE_context.h"
70 #include "BKE_depsgraph.h" // for DAG_on_visible_update
71 #include "BKE_font.h"
72 #include "BKE_global.h"
73 #include "BKE_main.h"
74 #include "BKE_material.h"
75 #include "BKE_packedFile.h"
76 #include "BKE_scene.h"
77 #include "BKE_node.h"
78 #include "BKE_report.h"
79 #include "BKE_sound.h"
80
81 #include "IMB_imbuf.h"  // for IMB_init
82
83 #ifdef WITH_PYTHON
84 #include "BPY_extern.h"
85 #endif
86
87 #include "RE_engine.h"
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 #define BLEND_VERSION_STRING_FMT                                              \
145         "Blender %d.%02d (sub %d)\n",                                             \
146         BLENDER_VERSION/100, BLENDER_VERSION%100, BLENDER_SUBVERSION              \
147
148 /* Initialize callbacks for the modules that need them */
149 static void setCallbacks(void); 
150
151 /* set breakpoints here when running in debug mode, useful to catch floating point errors */
152 #if defined(__linux__) || defined(_WIN32) || defined(OSX_SSE_FPE)
153 static void fpe_handler(int UNUSED(sig))
154 {
155         // printf("SIGFPE trapped\n");
156 }
157 #endif
158
159 #ifndef WITH_PYTHON_MODULE
160 /* handling ctrl-c event in console */
161 static void blender_esc(int sig)
162 {
163         static int count = 0;
164         
165         G.afbreek = 1;  /* forces render loop to read queue, not sure if its needed */
166         
167         if (sig == 2) {
168                 if (count) {
169                         printf("\nBlender killed\n");
170                         exit(2);
171                 }
172                 printf("\nSent an internal break event. Press ^C again to kill Blender\n");
173                 count++;
174         }
175 }
176 #endif
177
178 static int print_version(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
179 {
180         printf (BLEND_VERSION_STRING_FMT);
181 #ifdef BUILD_DATE
182         printf ("\tbuild date: %s\n", build_date);
183         printf ("\tbuild time: %s\n", build_time);
184         printf ("\tbuild revision: %s\n", build_rev);
185         printf ("\tbuild platform: %s\n", build_platform);
186         printf ("\tbuild type: %s\n", build_type);
187         printf ("\tbuild c flags: %s\n", build_cflags);
188         printf ("\tbuild c++ flags: %s\n", build_cxxflags);
189         printf ("\tbuild link flags: %s\n", build_linkflags);
190         printf ("\tbuild system: %s\n", build_system);
191 #endif
192         exit(0);
193
194         return 0;
195 }
196
197 static int print_help(int UNUSED(argc), const char **UNUSED(argv), void *data)
198 {
199         bArgs *ba = (bArgs*)data;
200
201         printf (BLEND_VERSION_STRING_FMT);
202         printf ("Usage: blender [args ...] [file] [args ...]\n\n");
203
204         printf ("Render Options:\n");
205         BLI_argsPrintArgDoc(ba, "--background");
206         BLI_argsPrintArgDoc(ba, "--render-anim");
207         BLI_argsPrintArgDoc(ba, "--scene");
208         BLI_argsPrintArgDoc(ba, "--render-frame");
209         BLI_argsPrintArgDoc(ba, "--frame-start");
210         BLI_argsPrintArgDoc(ba, "--frame-end");
211         BLI_argsPrintArgDoc(ba, "--frame-jump");
212         BLI_argsPrintArgDoc(ba, "--render-output");
213         BLI_argsPrintArgDoc(ba, "--engine");
214         
215         printf("\n");
216         printf ("Format Options:\n");
217         BLI_argsPrintArgDoc(ba, "--render-format");
218         BLI_argsPrintArgDoc(ba, "--use-extension");
219         BLI_argsPrintArgDoc(ba, "--threads");
220
221         printf("\n");
222         printf ("Animation Playback Options:\n");
223         BLI_argsPrintArgDoc(ba, "-a");
224                                 
225         printf("\n");
226         printf ("Window Options:\n");
227         BLI_argsPrintArgDoc(ba, "--window-border");
228         BLI_argsPrintArgDoc(ba, "--window-borderless");
229         BLI_argsPrintArgDoc(ba, "--window-geometry");
230         BLI_argsPrintArgDoc(ba, "--start-console");
231
232         printf("\n");
233         printf ("Game Engine Specific Options:\n");
234         BLI_argsPrintArgDoc(ba, "-g");
235
236         printf("\n");
237         printf ("Misc Options:\n");
238         BLI_argsPrintArgDoc(ba, "--debug");
239         BLI_argsPrintArgDoc(ba, "--debug-fpe");
240         printf("\n");
241         BLI_argsPrintArgDoc(ba, "--factory-startup");
242         printf("\n");
243         BLI_argsPrintArgDoc(ba, "--env-system-config");
244         BLI_argsPrintArgDoc(ba, "--env-system-datafiles");
245         BLI_argsPrintArgDoc(ba, "--env-system-scripts");
246         BLI_argsPrintArgDoc(ba, "--env-system-plugins");
247         BLI_argsPrintArgDoc(ba, "--env-system-python");
248         printf("\n");
249         BLI_argsPrintArgDoc(ba, "-nojoystick");
250         BLI_argsPrintArgDoc(ba, "-noglsl");
251         BLI_argsPrintArgDoc(ba, "-noaudio");
252         BLI_argsPrintArgDoc(ba, "-setaudio");
253
254         printf("\n");
255
256         BLI_argsPrintArgDoc(ba, "--help");
257
258         printf("\n");
259
260         BLI_argsPrintArgDoc(ba, "--enable-autoexec");
261         BLI_argsPrintArgDoc(ba, "--disable-autoexec");
262
263         printf("\n");
264
265         BLI_argsPrintArgDoc(ba, "--python");
266         BLI_argsPrintArgDoc(ba, "--python-console");
267         BLI_argsPrintArgDoc(ba, "--addons");
268
269 #ifdef WIN32
270         BLI_argsPrintArgDoc(ba, "-R");
271         BLI_argsPrintArgDoc(ba, "-r");
272 #endif
273         BLI_argsPrintArgDoc(ba, "--version");
274
275         BLI_argsPrintArgDoc(ba, "--");
276
277         printf ("Other Options:\n");
278         BLI_argsPrintOtherDoc(ba);
279
280         printf ("Argument Parsing:\n");
281         printf ("\targuments must be separated by white space. eg\n");
282         printf ("\t\t\"blender -ba test.blend\"\n");
283         printf ("\t...will ignore the 'a'\n");
284         printf ("\t\t\"blender -b test.blend -f8\"\n");
285         printf ("\t...will ignore 8 because there is no space between the -f and the frame value\n\n");
286
287         printf ("Argument Order:\n");
288         printf ("Arguments are executed in the order they are given. eg\n");
289         printf ("\t\t\"blender --background test.blend --render-frame 1 --render-output /tmp\"\n");
290         printf ("\t...will not render to /tmp because '--render-frame 1' renders before the output path is set\n");
291         printf ("\t\t\"blender --background --render-output /tmp test.blend --render-frame 1\"\n");
292         printf ("\t...will not render to /tmp because loading the blend file overwrites the render output that was set\n");
293         printf ("\t\t\"blender --background test.blend --render-output /tmp --render-frame 1\" works as expected.\n\n");
294
295         printf ("\nEnvironment Variables:\n");
296         printf ("  $BLENDER_USER_CONFIG      Directory for user configuration files.\n");
297         printf ("  $BLENDER_USER_SCRIPTS     Directory for user scripts.\n");
298         printf ("  $BLENDER_SYSTEM_SCRIPTS   Directory for system wide scripts.\n");
299         printf ("  $BLENDER_USER_DATAFILES   Directory for user data files (icons, translations, ..).\n");
300         printf ("  $BLENDER_SYSTEM_DATAFILES Directory for system wide data files.\n");
301         printf ("  $BLENDER_SYSTEM_PYTHON    Directory for system python libraries.\n");
302 #ifdef WIN32
303         printf ("  $TEMP                     Store temporary files here.\n");
304 #else
305         printf ("  $TMP or $TMPDIR           Store temporary files here.\n");
306 #endif
307 #ifdef WITH_SDL
308         printf ("  $SDL_AUDIODRIVER          LibSDL audio driver - alsa, esd, dma.\n");
309 #endif
310         printf ("  $PYTHONHOME               Path to the python directory, eg. /usr/lib/python.\n\n");
311
312         exit(0);
313
314         return 0;
315 }
316
317
318 double PIL_check_seconds_timer(void);
319
320 static int end_arguments(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
321 {
322         return -1;
323 }
324
325 static int enable_python(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
326 {
327         G.f |= G_SCRIPT_AUTOEXEC;
328         G.f |= G_SCRIPT_OVERRIDE_PREF;
329         return 0;
330 }
331
332 static int disable_python(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
333 {
334         G.f &= ~G_SCRIPT_AUTOEXEC;
335         G.f |= G_SCRIPT_OVERRIDE_PREF;
336         return 0;
337 }
338
339 static int background_mode(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
340 {
341         G.background = 1;
342         return 0;
343 }
344
345 static int debug_mode(int UNUSED(argc), const char **UNUSED(argv), void *data)
346 {
347         G.f |= G_DEBUG;         /* std output printf's */
348         printf(BLEND_VERSION_STRING_FMT);
349         MEM_set_memory_debug();
350
351 #ifdef WITH_BUILDINFO
352         printf("Build: %s %s %s %s\n", build_date, build_time, build_platform, build_type);
353 #endif // WITH_BUILDINFO
354
355         BLI_argsPrint(data);
356         return 0;
357 }
358
359 static int set_fpe(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
360 {
361 #if defined(__linux__) || defined(_WIN32) || defined(OSX_SSE_FPE)
362         /* zealous but makes float issues a heck of a lot easier to find!
363          * set breakpoints on fpe_handler */
364         signal(SIGFPE, fpe_handler);
365
366 # if defined(__linux__) && defined(__GNUC__)
367         feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW );
368 # endif /* defined(__linux__) && defined(__GNUC__) */
369 # if defined(OSX_SSE_FPE)
370         /* OSX uses SSE for floating point by default, so here 
371          * use SSE instructions to throw floating point exceptions */
372         _MM_SET_EXCEPTION_MASK(_MM_MASK_MASK &~
373                         (_MM_MASK_OVERFLOW|_MM_MASK_INVALID|_MM_MASK_DIV_ZERO));
374 # endif /* OSX_SSE_FPE */
375 # if defined(_WIN32) && defined(_MSC_VER)
376         _controlfp_s(NULL, 0, _MCW_EM); /* enables all fp exceptions */
377         _controlfp_s(NULL, _EM_DENORMAL | _EM_UNDERFLOW | _EM_INEXACT, _MCW_EM); /* hide the ones we don't care about */
378 # endif /* _WIN32 && _MSC_VER */
379 #endif
380
381         return 0;
382 }
383
384 static int set_factory_startup(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
385 {
386         G.factory_startup= 1;
387         return 0;
388 }
389
390 static int set_env(int argc, const char **argv, void *UNUSED(data))
391 {
392         /* "--env-system-scripts" --> "BLENDER_SYSTEM_SCRIPTS" */
393
394         char env[64]= "BLENDER";
395         char *ch_dst= env + 7; /* skip BLENDER */
396         const char *ch_src= argv[0] + 5; /* skip --env */
397
398         if (argc < 2) {
399                 printf("%s requires one argument\n", argv[0]);
400                 exit(1);
401         }
402
403         for(; *ch_src; ch_src++, ch_dst++) {
404                 *ch_dst= (*ch_src == '-') ? '_' : (*ch_src)-32; /* toupper() */
405         }
406
407         *ch_dst= '\0';
408         BLI_setenv(env, argv[1]);
409         return 1;
410 }
411
412 static int playback_mode(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
413 {
414         /* not if -b was given first */
415         if (G.background == 0) {
416 #if 0   /* TODO, bring player back? */
417                 playanim(argc, argv); /* not the same argc and argv as before */
418 #else
419                 fprintf(stderr, "Playback mode not supported in blender 2.5x\n");
420                 exit(0);
421 #endif
422         }
423
424         return -2;
425 }
426
427 static int prefsize(int argc, const char **argv, void *UNUSED(data))
428 {
429         int stax, stay, sizx, sizy;
430
431         if (argc < 5) {
432                 printf ("-p requires four arguments\n");
433                 exit(1);
434         }
435
436         stax= atoi(argv[1]);
437         stay= atoi(argv[2]);
438         sizx= atoi(argv[3]);
439         sizy= atoi(argv[4]);
440
441         WM_setprefsize(stax, stay, sizx, sizy);
442
443         return 4;
444 }
445
446 static int with_borders(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
447 {
448         WM_setinitialstate_normal();
449         return 0;
450 }
451
452 static int without_borders(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
453 {
454         WM_setinitialstate_fullscreen();
455         return 0;
456 }
457
458 extern int wm_start_with_console; // blender/windowmanager/intern/wm_init_exit.c
459 static int start_with_console(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
460 {
461         wm_start_with_console = 1;
462         return 0;
463 }
464
465 static int register_extension(int UNUSED(argc), const char **UNUSED(argv), void *data)
466 {
467 #ifdef WIN32
468         if (data)
469                 G.background = 1;
470         RegisterBlendExtension();
471 #else
472         (void)data; /* unused */
473 #endif
474         return 0;
475 }
476
477 static int no_joystick(int UNUSED(argc), const char **UNUSED(argv), void *data)
478 {
479 #ifndef WITH_GAMEENGINE
480         (void)data;
481 #else
482         SYS_SystemHandle *syshandle = data;
483
484         /**
485                 don't initialize joysticks if user doesn't want to use joysticks
486                 failed joystick initialization delays over 5 seconds, before game engine start
487         */
488         SYS_WriteCommandLineInt(*syshandle, "nojoystick",1);
489         if (G.f & G_DEBUG) printf("disabling nojoystick\n");
490 #endif
491
492         return 0;
493 }
494
495 static int no_glsl(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
496 {
497         GPU_extensions_disable();
498         return 0;
499 }
500
501 static int no_audio(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
502 {
503         sound_force_device(0);
504         return 0;
505 }
506
507 static int set_audio(int argc, const char **argv, void *UNUSED(data))
508 {
509         if (argc < 1) {
510                 printf("-setaudio require one argument\n");
511                 exit(1);
512         }
513
514         sound_force_device(sound_define_from_str(argv[1]));
515         return 1;
516 }
517
518 static int set_output(int argc, const char **argv, void *data)
519 {
520         bContext *C = data;
521         if (argc >= 1){
522                 Scene *scene= CTX_data_scene(C);
523                 if (scene) {
524                         BLI_strncpy(scene->r.pic, argv[1], sizeof(scene->r.pic));
525                 } else {
526                         printf("\nError: no blend loaded. cannot use '-o / --render-output'.\n");
527                 }
528                 return 1;
529         } else {
530                 printf("\nError: you must specify a path after '-o  / --render-output'.\n");
531                 return 0;
532         }
533 }
534
535 static int set_engine(int argc, const char **argv, void *data)
536 {
537         bContext *C = data;
538         if (argc >= 2) {
539                 if (!strcmp(argv[1], "help")) {
540                         RenderEngineType *type = NULL;
541                         printf("Blender Engine Listing:\n");
542                         for( type = R_engines.first; type; type = type->next ) {
543                                 printf("\t%s\n", type->idname);
544                         }
545                         exit(0);
546                 }
547                 else {
548                         Scene *scene= CTX_data_scene(C);
549                         if (scene) {
550                                 RenderData *rd = &scene->r;
551
552                                 if(BLI_findstring(&R_engines, argv[1], offsetof(RenderEngineType, idname))) {
553                                         BLI_strncpy_utf8(rd->engine, argv[1], sizeof(rd->engine));
554                                 }
555                         }
556                         else {
557                                 printf("\nError: no blend loaded. order the arguments so '-E  / --engine ' is after a blend is loaded.\n");
558                         }
559                 }
560
561                 return 1;
562         }
563         else
564         {
565                 printf("\nEngine not specified, give 'help' for a list of available engines.\n");
566                 return 0;
567         }
568 }
569
570 static int set_image_type(int argc, const char **argv, void *data)
571 {
572         bContext *C = data;
573         if (argc >= 1){
574                 const char *imtype = argv[1];
575                 Scene *scene= CTX_data_scene(C);
576                 if (scene) {
577                         if      (!strcmp(imtype,"TGA")) scene->r.imtype = R_TARGA;
578                         else if (!strcmp(imtype,"IRIS")) scene->r.imtype = R_IRIS;
579 #ifdef WITH_DDS
580                         else if (!strcmp(imtype,"DDS")) scene->r.imtype = R_DDS;
581 #endif
582                         else if (!strcmp(imtype,"JPEG")) scene->r.imtype = R_JPEG90;
583                         else if (!strcmp(imtype,"IRIZ")) scene->r.imtype = R_IRIZ;
584                         else if (!strcmp(imtype,"RAWTGA")) scene->r.imtype = R_RAWTGA;
585                         else if (!strcmp(imtype,"AVIRAW")) scene->r.imtype = R_AVIRAW;
586                         else if (!strcmp(imtype,"AVIJPEG")) scene->r.imtype = R_AVIJPEG;
587                         else if (!strcmp(imtype,"PNG")) scene->r.imtype = R_PNG;
588                         else if (!strcmp(imtype,"AVICODEC")) scene->r.imtype = R_AVICODEC;
589                         else if (!strcmp(imtype,"QUICKTIME")) scene->r.imtype = R_QUICKTIME;
590                         else if (!strcmp(imtype,"BMP")) scene->r.imtype = R_BMP;
591 #ifdef WITH_HDR
592                         else if (!strcmp(imtype,"HDR")) scene->r.imtype = R_RADHDR;
593 #endif
594 #ifdef WITH_TIFF
595                         else if (!strcmp(imtype,"TIFF")) scene->r.imtype = R_TIFF;
596 #endif
597 #ifdef WITH_OPENEXR
598                         else if (!strcmp(imtype,"EXR")) scene->r.imtype = R_OPENEXR;
599                         else if (!strcmp(imtype,"MULTILAYER")) scene->r.imtype = R_MULTILAYER;
600 #endif
601                         else if (!strcmp(imtype,"MPEG")) scene->r.imtype = R_FFMPEG;
602                         else if (!strcmp(imtype,"FRAMESERVER")) scene->r.imtype = R_FRAMESERVER;
603 #ifdef WITH_CINEON
604                         else if (!strcmp(imtype,"CINEON")) scene->r.imtype = R_CINEON;
605                         else if (!strcmp(imtype,"DPX")) scene->r.imtype = R_DPX;
606 #endif
607 #ifdef WITH_OPENJPEG
608                         else if (!strcmp(imtype,"JP2")) scene->r.imtype = R_JP2;
609 #endif
610                         else printf("\nError: Format from '-F / --render-format' not known or not compiled in this release.\n");
611                 }
612                 else {
613                         printf("\nError: no blend loaded. order the arguments so '-F  / --render-format' is after the blend is loaded.\n");
614                 }
615                 return 1;
616         } else {
617                 printf("\nError: you must specify a format after '-F  / --render-foramt'.\n");
618                 return 0;
619         }
620 }
621
622 static int set_threads(int argc, const char **argv, void *UNUSED(data))
623 {
624         if (argc >= 1) {
625                 if(G.background) {
626                         RE_set_max_threads(atoi(argv[1]));
627                 } else {
628                         printf("Warning: threads can only be set in background mode\n");
629                 }
630                 return 1;
631         } else {
632                 printf("\nError: you must specify a number of threads between 0 and 8 '-t  / --threads'.\n");
633                 return 0;
634         }
635 }
636
637 static int set_extension(int argc, const char **argv, void *data)
638 {
639         bContext *C = data;
640         if (argc >= 1) {
641                 Scene *scene= CTX_data_scene(C);
642                 if (scene) {
643                         if (argv[1][0] == '0') {
644                                 scene->r.scemode &= ~R_EXTENSION;
645                         } else if (argv[1][0] == '1') {
646                                 scene->r.scemode |= R_EXTENSION;
647                         } else {
648                                 printf("\nError: Use '-x 1 / -x 0' To set the extension option or '--use-extension'\n");
649                         }
650                 } else {
651                         printf("\nError: no blend loaded. order the arguments so '-o ' is after '-x '.\n");
652                 }
653                 return 1;
654         } else {
655                 printf("\nError: you must specify a path after '- '.\n");
656                 return 0;
657         }
658 }
659
660 static int set_ge_parameters(int argc, const char **argv, void *data)
661 {
662         int a = 0;
663 #ifdef WITH_GAMEENGINE
664         SYS_SystemHandle syshandle = *(SYS_SystemHandle*)data;
665 #else
666         (void)data;
667 #endif
668
669 /**
670 gameengine parameters are automaticly put into system
671 -g [paramname = value]
672 -g [boolparamname]
673 example:
674 -g novertexarrays
675 -g maxvertexarraysize = 512
676 */
677
678         if(argc >= 1)
679         {
680                 const char *paramname = argv[a];
681                 /* check for single value versus assignment */
682                 if (a+1 < argc && (*(argv[a+1]) == '='))
683                 {
684                         a++;
685                         if (a+1 < argc)
686                         {
687                                 a++;
688                                 /* assignment */
689 #ifdef WITH_GAMEENGINE
690                                 SYS_WriteCommandLineString(syshandle,paramname,argv[a]);
691 #endif
692                         }  else
693                         {
694                                 printf("error: argument assignment (%s) without value.\n",paramname);
695                                 return 0;
696                         }
697                         /* name arg eaten */
698
699                 } else {
700 #ifdef WITH_GAMEENGINE
701                         SYS_WriteCommandLineInt(syshandle,argv[a],1);
702 #endif
703                         /* doMipMap */
704                         if (!strcmp(argv[a],"nomipmap"))
705                         {
706                                 GPU_set_mipmap(0); //doMipMap = 0;
707                         }
708                         /* linearMipMap */
709                         if (!strcmp(argv[a],"linearmipmap"))
710                         {
711                                 GPU_set_linear_mipmap(1); //linearMipMap = 1;
712                         }
713
714
715                 } /* if (*(argv[a+1]) == '=') */
716         }
717
718         return a;
719 }
720
721 static int render_frame(int argc, const char **argv, void *data)
722 {
723         bContext *C = data;
724         Scene *scene= CTX_data_scene(C);
725         if (scene) {
726                 Main *bmain= CTX_data_main(C);
727
728                 if (argc > 1) {
729                         Render *re = RE_NewRender(scene->id.name);
730                         int frame;
731                         ReportList reports;
732
733                         switch(*argv[1]) {
734                         case '+':
735                                 frame= scene->r.sfra + atoi(argv[1]+1);
736                                 break;
737                         case '-':
738                                 frame= (scene->r.efra - atoi(argv[1]+1)) + 1;
739                                 break;
740                         default:
741                                 frame= atoi(argv[1]);
742                                 break;
743                         }
744
745                         BKE_reports_init(&reports, RPT_PRINT);
746
747                         frame = MIN2(MAXFRAME, MAX2(MINAFRAME, frame));
748
749                         RE_SetReports(re, &reports);
750                         RE_BlenderAnim(re, bmain, scene, NULL, scene->lay, frame, frame, scene->r.frame_step);
751                         RE_SetReports(re, NULL);
752                         return 1;
753                 } else {
754                         printf("\nError: frame number must follow '-f / --render-frame'.\n");
755                         return 0;
756                 }
757         } else {
758                 printf("\nError: no blend loaded. cannot use '-f / --render-frame'.\n");
759                 return 0;
760         }
761 }
762
763 static int render_animation(int UNUSED(argc), const char **UNUSED(argv), void *data)
764 {
765         bContext *C = data;
766         Scene *scene= CTX_data_scene(C);
767         if (scene) {
768                 Main *bmain= CTX_data_main(C);
769                 Render *re= RE_NewRender(scene->id.name);
770                 ReportList reports;
771                 BKE_reports_init(&reports, RPT_PRINT);
772                 RE_SetReports(re, &reports);
773                 RE_BlenderAnim(re, bmain, scene, NULL, scene->lay, scene->r.sfra, scene->r.efra, scene->r.frame_step);
774                 RE_SetReports(re, NULL);
775         } else {
776                 printf("\nError: no blend loaded. cannot use '-a'.\n");
777         }
778         return 0;
779 }
780
781 static int set_scene(int argc, const char **argv, void *data)
782 {
783         if(argc > 1) {
784                 bContext *C= data;
785                 Scene *scene= set_scene_name(CTX_data_main(C), argv[1]);
786                 if(scene) {
787                         CTX_data_scene_set(C, scene);
788                 }
789                 return 1;
790         } else {
791                 printf("\nError: Scene name must follow '-S / --scene'.\n");
792                 return 0;
793         }
794 }
795
796 static int set_start_frame(int argc, const char **argv, void *data)
797 {
798         bContext *C = data;
799         Scene *scene= CTX_data_scene(C);
800         if (scene) {
801                 if (argc > 1) {
802                         int frame = atoi(argv[1]);
803                         (scene->r.sfra) = CLAMPIS(frame, MINFRAME, MAXFRAME);
804                         return 1;
805                 } else {
806                         printf("\nError: frame number must follow '-s / --frame-start'.\n");
807                         return 0;
808                 }
809         } else {
810                 printf("\nError: no blend loaded. cannot use '-s / --frame-start'.\n");
811                 return 0;
812         }
813 }
814
815 static int set_end_frame(int argc, const char **argv, void *data)
816 {
817         bContext *C = data;
818         Scene *scene= CTX_data_scene(C);
819         if (scene) {
820                 if (argc > 1) {
821                         int frame = atoi(argv[1]);
822                         (scene->r.efra) = CLAMPIS(frame, MINFRAME, MAXFRAME);
823                         return 1;
824                 } else {
825                         printf("\nError: frame number must follow '-e / --frame-end'.\n");
826                         return 0;
827                 }
828         } else {
829                 printf("\nError: no blend loaded. cannot use '-e / --frame-end'.\n");
830                 return 0;
831         }
832 }
833
834 static int set_skip_frame(int argc, const char **argv, void *data)
835 {
836         bContext *C = data;
837         Scene *scene= CTX_data_scene(C);
838         if (scene) {
839                 if (argc > 1) {
840                         int frame = atoi(argv[1]);
841                         (scene->r.frame_step) = CLAMPIS(frame, 1, MAXFRAME);
842                         return 1;
843                 } else {
844                         printf("\nError: number of frames to step must follow '-j / --frame-jump'.\n");
845                         return 0;
846                 }
847         } else {
848                 printf("\nError: no blend loaded. cannot use '-j / --frame-jump'.\n");
849                 return 0;
850         }
851 }
852
853 /* macro for ugly context setup/reset */
854 #ifdef WITH_PYTHON
855 #define BPY_CTX_SETUP(_cmd)                                                   \
856 {                                                                             \
857         wmWindowManager *wm= CTX_wm_manager(C);                                   \
858         wmWindow *prevwin= CTX_wm_window(C);                                      \
859         Scene *prevscene= CTX_data_scene(C);                                      \
860         if(wm->windows.first) {                                                   \
861                 CTX_wm_window_set(C, wm->windows.first);                              \
862                 _cmd;                                                                 \
863                 CTX_wm_window_set(C, prevwin);                                        \
864         }                                                                         \
865         else {                                                                    \
866                 fprintf(stderr, "Python script \"%s\" "                               \
867                                 "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(FALSE);
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         // initialize path to executable
1157         BLI_init_program_path(argv[0]);
1158
1159         BLI_threadapi_init();
1160
1161         RNA_init();
1162         RE_engines_init();
1163
1164                 /* Hack - force inclusion of the plugin api functions,
1165                  * see blenpluginapi:pluginapi.c
1166                  */
1167         pluginapi_force_ref();
1168
1169         init_nodesystem();
1170         
1171         initglobals();  /* blender.c */
1172
1173         IMB_init();
1174
1175         BLI_cb_init();
1176
1177 #ifdef WITH_GAMEENGINE
1178         syshandle = SYS_GetSystem();
1179 #else
1180         syshandle= 0;
1181 #endif
1182
1183         /* first test for background */
1184         ba = BLI_argsInit(argc, argv); /* skip binary path */
1185         setupArguments(C, ba, &syshandle);
1186
1187         BLI_argsParse(ba, 1, NULL, NULL);
1188
1189 #if defined(WITH_PYTHON_MODULE) || defined(WITH_HEADLESS)
1190         G.background= 1; /* python module mode ALWAYS runs in background mode (for now) */
1191 #else
1192         /* for all platforms, even windos has it! */
1193         if(G.background) signal(SIGINT, blender_esc);   /* ctrl c out bg render */
1194 #endif
1195
1196         /* background render uses this font too */
1197         BKE_font_register_builtin(datatoc_Bfont, datatoc_Bfont_size);
1198
1199         /* Initialiaze ffmpeg if built in, also needed for bg mode if videos are
1200            rendered via ffmpeg */
1201         sound_init_once();
1202         
1203         init_def_material();
1204
1205         if(G.background==0) {
1206                 BLI_argsParse(ba, 2, NULL, NULL);
1207                 BLI_argsParse(ba, 3, NULL, NULL);
1208
1209                 WM_init(C, argc, argv);
1210
1211                 /* this is properly initialized with user defs, but this is default */
1212                 /* call after loading the startup.blend so we can read U.tempdir */
1213                 BLI_init_temporary_dir(U.tempdir);
1214
1215 #ifdef WITH_SDL
1216         BLI_setenv("SDL_VIDEODRIVER", "dummy");
1217 #endif
1218         }
1219         else {
1220                 BLI_argsParse(ba, 3, NULL, NULL);
1221
1222                 WM_init(C, argc, argv);
1223
1224                 /* don't use user preferences temp dir */
1225                 BLI_init_temporary_dir(NULL);
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 }