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