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