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