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