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