Merging r41120 through from trunk r41139 into soc-2011-tomato
[blender.git] / source / creator / creator.c
1 /*
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  *
20  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21  * All rights reserved.
22  *
23  * The Original Code is: all of this file.
24  *
25  * Contributor(s): none yet.
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  */
29
30 /** \file creator/creator.c
31  *  \ingroup creator
32  */
33
34
35 #if defined(__linux__) && defined(__GNUC__)
36 #define _GNU_SOURCE
37 #include <fenv.h>
38 #endif
39
40 #if (defined(__APPLE__) && (defined(__i386__) || defined(__x86_64__)))
41 #define OSX_SSE_FPE
42 #include <xmmintrin.h>
43 #endif
44
45 #include <stdlib.h>
46 #include <stddef.h>
47 #include <string.h>
48
49 /* This little block needed for linking to Blender... */
50
51 #include "MEM_guardedalloc.h"
52
53 #ifdef WIN32
54 #include "BLI_winstuff.h"
55 #endif
56
57 #include "BLI_args.h"
58 #include "BLI_threads.h"
59 #include "BLI_scanfill.h" // for BLI_setErrorCallBack, TODO, move elsewhere
60 #include "BLI_utildefines.h"
61 #include "BLI_callbacks.h"
62
63 #include "DNA_ID.h"
64 #include "DNA_scene_types.h"
65
66 #include "BLI_blenlib.h"
67
68 #include "BKE_utildefines.h"
69 #include "BKE_blender.h"
70 #include "BKE_context.h"
71 #include "BKE_depsgraph.h" // for DAG_on_visible_update
72 #include "BKE_font.h"
73 #include "BKE_global.h"
74 #include "BKE_main.h"
75 #include "BKE_material.h"
76 #include "BKE_packedFile.h"
77 #include "BKE_scene.h"
78 #include "BKE_node.h"
79 #include "BKE_report.h"
80 #include "BKE_sound.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_pipeline.h"
89
90 //XXX #include "playanim_ext.h"
91 #include "ED_datafiles.h"
92
93 #include "WM_api.h"
94
95 #include "RNA_define.h"
96
97 #include "GPU_draw.h"
98 #include "GPU_extensions.h"
99
100 #ifdef WITH_BUILDINFO_HEADER
101 #define BUILD_DATE
102 #endif
103
104 /* for passing information between creator and gameengine */
105 #ifdef WITH_GAMEENGINE
106 #include "BL_System.h"
107 #else /* dummy */
108 #define SYS_SystemHandle int
109 #endif
110
111 #include <signal.h>
112
113 #ifdef __FreeBSD__
114 # include <sys/types.h>
115 # include <floatingpoint.h>
116 # include <sys/rtprio.h>
117 #endif
118
119 #ifdef WITH_BINRELOC
120 #include "binreloc.h"
121 #endif
122
123 #ifdef WITH_LIBMV
124 #include "libmv-capi.h"
125 #endif
126
127 // from buildinfo.c
128 #ifdef BUILD_DATE
129 extern char build_date[];
130 extern char build_time[];
131 extern char build_rev[];
132 extern char build_platform[];
133 extern char build_type[];
134 extern char build_cflags[];
135 extern char build_cxxflags[];
136 extern char build_linkflags[];
137 extern char build_system[];
138 #endif
139
140 /*      Local Function prototypes */
141 static int print_help(int argc, const char **argv, void *data);
142 static int print_version(int argc, const char **argv, void *data);
143
144 /* for the callbacks: */
145
146 extern int pluginapi_force_ref(void);  /* from blenpluginapi:pluginapi.c */
147
148 char bprogname[FILE_MAX]; /* from blenpluginapi:pluginapi.c */
149 char btempdir[FILE_MAX];
150
151 #define BLEND_VERSION_STRING_FMT "Blender %d.%02d (sub %d)\n", 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 ("  $BLENDER_USER_DATAFILES   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                 printf ("-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                 printf("-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         {
574                 printf("\nEngine not specified, give 'help' for a list of available engines.\n");
575                 return 0;
576         }
577 }
578
579 static int set_image_type(int argc, const char **argv, void *data)
580 {
581         bContext *C = data;
582         if (argc >= 1){
583                 const char *imtype = argv[1];
584                 Scene *scene= CTX_data_scene(C);
585                 if (scene) {
586                         if      (!strcmp(imtype,"TGA")) scene->r.imtype = R_TARGA;
587                         else if (!strcmp(imtype,"IRIS")) scene->r.imtype = R_IRIS;
588 #ifdef WITH_DDS
589                         else if (!strcmp(imtype,"DDS")) scene->r.imtype = R_DDS;
590 #endif
591                         else if (!strcmp(imtype,"JPEG")) scene->r.imtype = R_JPEG90;
592                         else if (!strcmp(imtype,"IRIZ")) scene->r.imtype = R_IRIZ;
593                         else if (!strcmp(imtype,"RAWTGA")) scene->r.imtype = R_RAWTGA;
594                         else if (!strcmp(imtype,"AVIRAW")) scene->r.imtype = R_AVIRAW;
595                         else if (!strcmp(imtype,"AVIJPEG")) scene->r.imtype = R_AVIJPEG;
596                         else if (!strcmp(imtype,"PNG")) scene->r.imtype = R_PNG;
597                         else if (!strcmp(imtype,"AVICODEC")) scene->r.imtype = R_AVICODEC;
598                         else if (!strcmp(imtype,"QUICKTIME")) scene->r.imtype = R_QUICKTIME;
599                         else if (!strcmp(imtype,"BMP")) scene->r.imtype = R_BMP;
600 #ifdef WITH_HDR
601                         else if (!strcmp(imtype,"HDR")) scene->r.imtype = R_RADHDR;
602 #endif
603 #ifdef WITH_TIFF
604                         else if (!strcmp(imtype,"TIFF")) scene->r.imtype = R_TIFF;
605 #endif
606 #ifdef WITH_OPENEXR
607                         else if (!strcmp(imtype,"EXR")) scene->r.imtype = R_OPENEXR;
608                         else if (!strcmp(imtype,"MULTILAYER")) scene->r.imtype = R_MULTILAYER;
609 #endif
610                         else if (!strcmp(imtype,"MPEG")) scene->r.imtype = R_FFMPEG;
611                         else if (!strcmp(imtype,"FRAMESERVER")) scene->r.imtype = R_FRAMESERVER;
612 #ifdef WITH_CINEON
613                         else if (!strcmp(imtype,"CINEON")) scene->r.imtype = R_CINEON;
614                         else if (!strcmp(imtype,"DPX")) scene->r.imtype = R_DPX;
615 #endif
616 #ifdef WITH_OPENJPEG
617                         else if (!strcmp(imtype,"JP2")) scene->r.imtype = R_JP2;
618 #endif
619                         else printf("\nError: Format from '-F / --render-format' not known or not compiled in this release.\n");
620                 }
621                 else {
622                         printf("\nError: no blend loaded. order the arguments so '-F  / --render-format' is after the blend is loaded.\n");
623                 }
624                 return 1;
625         } else {
626                 printf("\nError: you must specify a format after '-F  / --render-foramt'.\n");
627                 return 0;
628         }
629 }
630
631 static int set_threads(int argc, const char **argv, void *UNUSED(data))
632 {
633         if (argc >= 1) {
634                 if(G.background) {
635                         RE_set_max_threads(atoi(argv[1]));
636                 } else {
637                         printf("Warning: threads can only be set in background mode\n");
638                 }
639                 return 1;
640         } else {
641                 printf("\nError: you must specify a number of threads between 0 and 8 '-t  / --threads'.\n");
642                 return 0;
643         }
644 }
645
646 static int set_extension(int argc, const char **argv, void *data)
647 {
648         bContext *C = data;
649         if (argc >= 1) {
650                 Scene *scene= CTX_data_scene(C);
651                 if (scene) {
652                         if (argv[1][0] == '0') {
653                                 scene->r.scemode &= ~R_EXTENSION;
654                         } else if (argv[1][0] == '1') {
655                                 scene->r.scemode |= R_EXTENSION;
656                         } else {
657                                 printf("\nError: Use '-x 1 / -x 0' To set the extension option or '--use-extension'\n");
658                         }
659                 } else {
660                         printf("\nError: no blend loaded. order the arguments so '-o ' is after '-x '.\n");
661                 }
662                 return 1;
663         } else {
664                 printf("\nError: you must specify a path after '- '.\n");
665                 return 0;
666         }
667 }
668
669 static int set_ge_parameters(int argc, const char **argv, void *data)
670 {
671         int a = 0;
672 #ifdef WITH_GAMEENGINE
673         SYS_SystemHandle syshandle = *(SYS_SystemHandle*)data;
674 #else
675         (void)data;
676 #endif
677
678 /**
679 gameengine parameters are automaticly put into system
680 -g [paramname = value]
681 -g [boolparamname]
682 example:
683 -g novertexarrays
684 -g maxvertexarraysize = 512
685 */
686
687         if(argc >= 1)
688         {
689                 const char *paramname = argv[a];
690                 /* check for single value versus assignment */
691                 if (a+1 < argc && (*(argv[a+1]) == '='))
692                 {
693                         a++;
694                         if (a+1 < argc)
695                         {
696                                 a++;
697                                 /* assignment */
698 #ifdef WITH_GAMEENGINE
699                                 SYS_WriteCommandLineString(syshandle,paramname,argv[a]);
700 #endif
701                         }  else
702                         {
703                                 printf("error: argument assignment (%s) without value.\n",paramname);
704                                 return 0;
705                         }
706                         /* name arg eaten */
707
708                 } else {
709 #ifdef WITH_GAMEENGINE
710                         SYS_WriteCommandLineInt(syshandle,argv[a],1);
711 #endif
712                         /* doMipMap */
713                         if (!strcmp(argv[a],"nomipmap"))
714                         {
715                                 GPU_set_mipmap(0); //doMipMap = 0;
716                         }
717                         /* linearMipMap */
718                         if (!strcmp(argv[a],"linearmipmap"))
719                         {
720                                 GPU_set_linear_mipmap(1); //linearMipMap = 1;
721                         }
722
723
724                 } /* if (*(argv[a+1]) == '=') */
725         }
726
727         return a;
728 }
729
730 static int render_frame(int argc, const char **argv, void *data)
731 {
732         bContext *C = data;
733         Scene *scene= CTX_data_scene(C);
734         if (scene) {
735                 Main *bmain= CTX_data_main(C);
736
737                 if (argc > 1) {
738                         Render *re = RE_NewRender(scene->id.name);
739                         int frame;
740                         ReportList reports;
741
742                         switch(*argv[1]) {
743                         case '+':
744                                 frame= scene->r.sfra + atoi(argv[1]+1);
745                                 break;
746                         case '-':
747                                 frame= (scene->r.efra - atoi(argv[1]+1)) + 1;
748                                 break;
749                         default:
750                                 frame= atoi(argv[1]);
751                                 break;
752                         }
753
754                         BKE_reports_init(&reports, RPT_PRINT);
755
756                         frame = MIN2(MAXFRAME, MAX2(MINAFRAME, frame));
757
758                         RE_SetReports(re, &reports);
759                         RE_BlenderAnim(re, bmain, scene, NULL, scene->lay, frame, frame, scene->r.frame_step);
760                         RE_SetReports(re, NULL);
761                         return 1;
762                 } else {
763                         printf("\nError: frame number must follow '-f / --render-frame'.\n");
764                         return 0;
765                 }
766         } else {
767                 printf("\nError: no blend loaded. cannot use '-f / --render-frame'.\n");
768                 return 0;
769         }
770 }
771
772 static int render_animation(int UNUSED(argc), const char **UNUSED(argv), void *data)
773 {
774         bContext *C = data;
775         Scene *scene= CTX_data_scene(C);
776         if (scene) {
777                 Main *bmain= CTX_data_main(C);
778                 Render *re= RE_NewRender(scene->id.name);
779                 ReportList reports;
780                 BKE_reports_init(&reports, RPT_PRINT);
781                 RE_SetReports(re, &reports);
782                 RE_BlenderAnim(re, bmain, scene, NULL, scene->lay, scene->r.sfra, scene->r.efra, scene->r.frame_step);
783                 RE_SetReports(re, NULL);
784         } else {
785                 printf("\nError: no blend loaded. cannot use '-a'.\n");
786         }
787         return 0;
788 }
789
790 static int set_scene(int argc, const char **argv, void *data)
791 {
792         if(argc > 1) {
793                 bContext *C= data;
794                 Scene *scene= set_scene_name(CTX_data_main(C), argv[1]);
795                 if(scene) {
796                         CTX_data_scene_set(C, scene);
797                 }
798                 return 1;
799         } else {
800                 printf("\nError: Scene name must follow '-S / --scene'.\n");
801                 return 0;
802         }
803 }
804
805 static int set_start_frame(int argc, const char **argv, void *data)
806 {
807         bContext *C = data;
808         Scene *scene= CTX_data_scene(C);
809         if (scene) {
810                 if (argc > 1) {
811                         int frame = atoi(argv[1]);
812                         (scene->r.sfra) = CLAMPIS(frame, MINFRAME, MAXFRAME);
813                         return 1;
814                 } else {
815                         printf("\nError: frame number must follow '-s / --frame-start'.\n");
816                         return 0;
817                 }
818         } else {
819                 printf("\nError: no blend loaded. cannot use '-s / --frame-start'.\n");
820                 return 0;
821         }
822 }
823
824 static int set_end_frame(int argc, const char **argv, void *data)
825 {
826         bContext *C = data;
827         Scene *scene= CTX_data_scene(C);
828         if (scene) {
829                 if (argc > 1) {
830                         int frame = atoi(argv[1]);
831                         (scene->r.efra) = CLAMPIS(frame, MINFRAME, MAXFRAME);
832                         return 1;
833                 } else {
834                         printf("\nError: frame number must follow '-e / --frame-end'.\n");
835                         return 0;
836                 }
837         } else {
838                 printf("\nError: no blend loaded. cannot use '-e / --frame-end'.\n");
839                 return 0;
840         }
841 }
842
843 static int set_skip_frame(int argc, const char **argv, void *data)
844 {
845         bContext *C = data;
846         Scene *scene= CTX_data_scene(C);
847         if (scene) {
848                 if (argc > 1) {
849                         int frame = atoi(argv[1]);
850                         (scene->r.frame_step) = CLAMPIS(frame, 1, MAXFRAME);
851                         return 1;
852                 } else {
853                         printf("\nError: number of frames to step must follow '-j / --frame-jump'.\n");
854                         return 0;
855                 }
856         } else {
857                 printf("\nError: no blend loaded. cannot use '-j / --frame-jump'.\n");
858                 return 0;
859         }
860 }
861
862 /* macro for ugly context setup/reset */
863 #ifdef WITH_PYTHON
864 #define BPY_CTX_SETUP(_cmd) \
865 { \
866         wmWindowManager *wm= CTX_wm_manager(C); \
867         wmWindow *prevwin= CTX_wm_window(C); \
868         Scene *prevscene= CTX_data_scene(C); \
869         if(wm->windows.first) { \
870                 CTX_wm_window_set(C, wm->windows.first); \
871                 _cmd; \
872                 CTX_wm_window_set(C, prevwin); \
873         } \
874         else { \
875                 fprintf(stderr, "Python script \"%s\" running with missing context data.\n", argv[1]); \
876                 _cmd; \
877         } \
878         CTX_data_scene_set(C, prevscene); \
879 } \
880
881 #endif /* WITH_PYTHON */
882
883 static int run_python(int argc, const char **argv, void *data)
884 {
885 #ifdef WITH_PYTHON
886         bContext *C = data;
887
888         /* workaround for scripts not getting a bpy.context.scene, causes internal errors elsewhere */
889         if (argc > 1) {
890                 /* Make the path absolute because its needed for relative linked blends to be found */
891                 char filename[FILE_MAXDIR + FILE_MAXFILE];
892                 BLI_strncpy(filename, argv[1], sizeof(filename));
893                 BLI_path_cwd(filename);
894
895                 BPY_CTX_SETUP(BPY_filepath_exec(C, filename, NULL))
896
897                 return 1;
898         } else {
899                 printf("\nError: you must specify a Python script after '-P / --python'.\n");
900                 return 0;
901         }
902 #else
903         (void)argc; (void)argv; (void)data; /* unused */
904         printf("This blender was built without python support\n");
905         return 0;
906 #endif /* WITH_PYTHON */
907 }
908
909 static int run_python_console(int UNUSED(argc), const char **argv, void *data)
910 {
911 #ifdef WITH_PYTHON
912         bContext *C = data;
913
914         BPY_CTX_SETUP(BPY_string_exec(C, "__import__('code').interact()"))
915
916         return 0;
917 #else
918         (void)argv; (void)data; /* unused */
919         printf("This blender was built without python support\n");
920         return 0;
921 #endif /* WITH_PYTHON */
922 }
923
924 static int set_addons(int argc, const char **argv, void *data)
925 {
926         /* workaround for scripts not getting a bpy.context.scene, causes internal errors elsewhere */
927         if (argc > 1) {
928 #ifdef WITH_PYTHON
929                 const int slen= strlen(argv[1]) + 128;
930                 char *str= malloc(slen);
931                 bContext *C= data;
932                 BLI_snprintf(str, slen, "[__import__('addon_utils').enable(i, default_set=False) for i in '%s'.split(',')]", argv[1]);
933                 BPY_CTX_SETUP(BPY_string_exec(C, str));
934                 free(str);
935 #else
936                 (void)argv; (void)data; /* unused */
937 #endif /* WITH_PYTHON */
938                 return 1;
939         }
940         else {
941                 printf("\nError: you must specify a comma separated list after '--addons'.\n");
942                 return 0;
943         }
944 }
945
946
947 static int load_file(int UNUSED(argc), const char **argv, void *data)
948 {
949         bContext *C = data;
950
951         /* Make the path absolute because its needed for relative linked blends to be found */
952         char filename[FILE_MAXDIR + FILE_MAXFILE];
953         BLI_strncpy(filename, argv[0], sizeof(filename));
954         BLI_path_cwd(filename);
955
956         if (G.background) {
957                 int retval = BKE_read_file(C, filename, NULL);
958
959                 /*we successfully loaded a blend file, get sure that
960                 pointcache works */
961                 if (retval != BKE_READ_FILE_FAIL) {
962                         wmWindowManager *wm= CTX_wm_manager(C);
963
964                         /* special case, 2.4x files */
965                         if(wm==NULL && CTX_data_main(C)->wm.first==NULL) {
966                                 extern void wm_add_default(bContext *C);
967
968                                 /* wm_add_default() needs the screen to be set. */
969                                 CTX_wm_screen_set(C, CTX_data_main(C)->screen.first);
970                                 wm_add_default(C);
971                         }
972
973                         CTX_wm_manager_set(C, NULL); /* remove wm to force check */
974                         WM_check(C);
975                         G.relbase_valid = 1;
976                         if (CTX_wm_manager(C) == NULL) CTX_wm_manager_set(C, wm); /* reset wm */
977
978                         DAG_on_visible_update(CTX_data_main(C), TRUE);
979                 }
980
981                 /* WM_read_file() runs normally but since we're in background mode do here */
982 #ifdef WITH_PYTHON
983                 /* run any texts that were loaded in and flagged as modules */
984                 BPY_driver_reset();
985                 BPY_app_handlers_reset();
986                 BPY_modules_load_user(C);
987 #endif
988
989                 /* happens for the UI on file reading too (huh? (ton))*/
990         // XXX                  BKE_reset_undo();
991         //                              BKE_write_undo("original");     /* save current state */
992         } else {
993                 /* we are not running in background mode here, but start blender in UI mode with
994                    a file - this should do everything a 'load file' does */
995                 ReportList reports;
996                 BKE_reports_init(&reports, RPT_PRINT);
997                 WM_read_file(C, filename, &reports);
998                 BKE_reports_clear(&reports);
999         }
1000
1001         G.file_loaded = 1;
1002
1003         return 0;
1004 }
1005
1006 static void setupArguments(bContext *C, bArgs *ba, SYS_SystemHandle *syshandle)
1007 {
1008         static char output_doc[] = "<path>"
1009                 "\n\tSet the render path and file name."
1010                 "\n\tUse // at the start of the path to"
1011                 "\n\t\trender relative to the blend file."
1012                 "\n\tThe # characters are replaced by the frame number, and used to define zero padding."
1013                 "\n\t\tani_##_test.png becomes ani_01_test.png"
1014                 "\n\t\ttest-######.png becomes test-000001.png"
1015                 "\n\t\tWhen the filename does not contain #, The suffix #### is added to the filename"
1016                 "\n\tThe frame number will be added at the end of the filename."
1017                 "\n\t\teg: blender -b foobar.blend -o //render_ -F PNG -x 1 -a"
1018                 "\n\t\t//render_ becomes //render_####, writing frames as //render_0001.png//";
1019
1020         static char format_doc[] = "<format>"
1021                 "\n\tSet the render format, Valid options are..."
1022                 "\n\t\tTGA IRIS JPEG MOVIE IRIZ RAWTGA"
1023                 "\n\t\tAVIRAW AVIJPEG PNG BMP FRAMESERVER"
1024                 "\n\t(formats that can be compiled into blender, not available on all systems)"
1025                 "\n\t\tHDR TIFF EXR MULTILAYER MPEG AVICODEC QUICKTIME CINEON DPX DDS";
1026
1027         static char playback_doc[] = "<options> <file(s)>"
1028                 "\n\tPlayback <file(s)>, only operates this way when not running in background."
1029                 "\n\t\t-p <sx> <sy>\tOpen with lower left corner at <sx>, <sy>"
1030                 "\n\t\t-m\t\tRead from disk (Don't buffer)"
1031                 "\n\t\t-f <fps> <fps-base>\t\tSpecify FPS to start with"
1032                 "\n\t\t-j <frame>\tSet frame step to <frame>";
1033
1034         static char game_doc[] = "Game Engine specific options"
1035                 "\n\t-g fixedtime\t\tRun on 50 hertz without dropping frames"
1036                 "\n\t-g vertexarrays\t\tUse Vertex Arrays for rendering (usually faster)"
1037                 "\n\t-g nomipmap\t\tNo Texture Mipmapping"
1038                 "\n\t-g linearmipmap\t\tLinear Texture Mipmapping instead of Nearest (default)";
1039
1040         static char debug_doc[] = "\n\tTurn debugging on\n"
1041                 "\n\t* Prints every operator call and their arguments"
1042                 "\n\t* Disables mouse grab (to interact with a debugger in some cases)"
1043                 "\n\t* Keeps python sys.stdin rather than setting it to None";
1044
1045         //BLI_argsAdd(ba, pass, short_arg, long_arg, doc, cb, C);
1046
1047         /* end argument processing after -- */
1048         BLI_argsAdd(ba, -1, "--", NULL, "\n\tEnds option processing, following arguments passed unchanged. Access via python's sys.argv", end_arguments, NULL);
1049
1050         /* first pass: background mode, disable python and commands that exit after usage */
1051         BLI_argsAdd(ba, 1, "-h", "--help", "\n\tPrint this help text and exit", print_help, ba);
1052         /* Windows only */
1053         BLI_argsAdd(ba, 1, "/?", NULL, "\n\tPrint this help text and exit (windows only)", print_help, ba);
1054
1055         BLI_argsAdd(ba, 1, "-v", "--version", "\n\tPrint Blender version and exit", print_version, NULL);
1056         
1057         /* only to give help message */
1058 #ifndef WITH_PYTHON_SECURITY /* default */
1059 #  define       PY_ENABLE_AUTO ", (default)"
1060 #  define       PY_DISABLE_AUTO ""
1061 #else
1062 #  define       PY_ENABLE_AUTO ""
1063 #  define       PY_DISABLE_AUTO ", (compiled as non-standard default)"
1064 #endif
1065
1066         BLI_argsAdd(ba, 1, "-y", "--enable-autoexec", "\n\tEnable automatic python script execution" PY_ENABLE_AUTO, enable_python, NULL);
1067         BLI_argsAdd(ba, 1, "-Y", "--disable-autoexec", "\n\tDisable automatic python script execution (pydrivers, pyconstraints, pynodes)" PY_DISABLE_AUTO, disable_python, NULL);
1068
1069 #undef PY_ENABLE_AUTO
1070 #undef PY_DISABLE_AUTO
1071         
1072         BLI_argsAdd(ba, 1, "-b", "--background", "<file>\n\tLoad <file> in background (often used for UI-less rendering)", background_mode, NULL);
1073
1074         BLI_argsAdd(ba, 1, "-a", NULL, playback_doc, playback_mode, NULL);
1075
1076         BLI_argsAdd(ba, 1, "-d", "--debug", debug_doc, debug_mode, ba);
1077         BLI_argsAdd(ba, 1, NULL, "--debug-fpe", "\n\tEnable floating point exceptions", set_fpe, NULL);
1078
1079         BLI_argsAdd(ba, 1, NULL, "--factory-startup", "\n\tSkip reading the "STRINGIFY(BLENDER_STARTUP_FILE)" in the users home directory", set_factory_startup, NULL);
1080
1081         /* TODO, add user env vars? */
1082         BLI_argsAdd(ba, 1, NULL, "--env-system-datafiles",      "\n\tSet the "STRINGIFY_ARG(BLENDER_SYSTEM_DATAFILES)" environment variable", set_env, NULL);
1083         BLI_argsAdd(ba, 1, NULL, "--env-system-scripts",        "\n\tSet the "STRINGIFY_ARG(BLENDER_SYSTEM_SCRIPTS)" environment variable", set_env, NULL);
1084         BLI_argsAdd(ba, 1, NULL, "--env-system-plugins",        "\n\tSet the "STRINGIFY_ARG(BLENDER_SYSTEM_PLUGINS)" environment variable", set_env, NULL);
1085         BLI_argsAdd(ba, 1, NULL, "--env-system-python",         "\n\tSet the "STRINGIFY_ARG(BLENDER_SYSTEM_PYTHON)" environment variable", set_env, NULL);
1086
1087         /* second pass: custom window stuff */
1088         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);
1089         BLI_argsAdd(ba, 2, "-w", "--window-border", "\n\tForce opening with borders (default)", with_borders, NULL);
1090         BLI_argsAdd(ba, 2, "-W", "--window-borderless", "\n\tForce opening without borders", without_borders, NULL);
1091         BLI_argsAdd(ba, 2, "-con", "--start-console", "\n\tStart with the console window open (ignored if -b is set)", start_with_console, NULL);
1092         BLI_argsAdd(ba, 2, "-R", NULL, "\n\tRegister .blend extension, then exit (Windows only)", register_extension, NULL);
1093         BLI_argsAdd(ba, 2, "-r", NULL, "\n\tSilently register .blend extension, then exit (Windows only)", register_extension, ba);
1094
1095         /* third pass: disabling things and forcing settings */
1096         BLI_argsAddCase(ba, 3, "-nojoystick", 1, NULL, 0, "\n\tDisable joystick support", no_joystick, syshandle);
1097         BLI_argsAddCase(ba, 3, "-noglsl", 1, NULL, 0, "\n\tDisable GLSL shading", no_glsl, NULL);
1098         BLI_argsAddCase(ba, 3, "-noaudio", 1, NULL, 0, "\n\tForce sound system to None", no_audio, NULL);
1099         BLI_argsAddCase(ba, 3, "-setaudio", 1, NULL, 0, "\n\tForce sound system to a specific device\n\tNULL SDL OPENAL JACK", set_audio, NULL);
1100
1101         /* fourth pass: processing arguments */
1102         BLI_argsAdd(ba, 4, "-g", NULL, game_doc, set_ge_parameters, syshandle);
1103         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);
1104         BLI_argsAdd(ba, 4, "-a", "--render-anim", "\n\tRender frames from start to end (inclusive)", render_animation, C);
1105         BLI_argsAdd(ba, 4, "-S", "--scene", "<name>\n\tSet the active scene <name> for rendering", set_scene, C);
1106         BLI_argsAdd(ba, 4, "-s", "--frame-start", "<frame>\n\tSet start to frame <frame> (use before the -a argument)", set_start_frame, C);
1107         BLI_argsAdd(ba, 4, "-e", "--frame-end", "<frame>\n\tSet end to frame <frame> (use before the -a argument)", set_end_frame, C);
1108         BLI_argsAdd(ba, 4, "-j", "--frame-jump", "<frames>\n\tSet number of frames to step forward after each rendered frame", set_skip_frame, C);
1109         BLI_argsAdd(ba, 4, "-P", "--python", "<filename>\n\tRun the given Python script (filename or Blender Text)", run_python, C);
1110         BLI_argsAdd(ba, 4, NULL, "--python-console", "\n\tRun blender with an interactive console", run_python_console, C);
1111         BLI_argsAdd(ba, 4, NULL, "--addons", "\n\tComma separated list of addons (no spaces)", set_addons, C);
1112
1113         BLI_argsAdd(ba, 4, "-o", "--render-output", output_doc, set_output, C);
1114         BLI_argsAdd(ba, 4, "-E", "--engine", "<engine>\n\tSpecify the render engine\n\tuse -E help to list available engines", set_engine, C);
1115
1116         BLI_argsAdd(ba, 4, "-F", "--render-format", format_doc, set_image_type, C);
1117         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);
1118         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);
1119
1120 }
1121
1122 #ifdef WITH_PYTHON_MODULE
1123 /* allow python module to call main */
1124 #define main main_python_enter
1125 static void *evil_C= NULL;
1126 #endif
1127
1128 int main(int argc, const char **argv)
1129 {
1130         SYS_SystemHandle syshandle;
1131         bContext *C= CTX_create();
1132         bArgs *ba;
1133
1134 #ifdef WITH_PYTHON_MODULE
1135 #undef main
1136         evil_C= C;
1137 #endif
1138
1139 #ifdef WITH_BINRELOC
1140         br_init( NULL );
1141 #endif
1142
1143 #ifdef WITH_LIBMV
1144         libmv_initLogging(argv[0]);
1145 #endif
1146
1147         setCallbacks();
1148 #ifdef __APPLE__
1149                 /* patch to ignore argument finder gives us (pid?) */
1150         if (argc==2 && strncmp(argv[1], "-psn_", 5)==0) {
1151                 extern int GHOST_HACK_getFirstFile(char buf[]);
1152                 static char firstfilebuf[512];
1153
1154                 argc= 1;
1155
1156                 if (GHOST_HACK_getFirstFile(firstfilebuf)) {
1157                         argc= 2;
1158                         argv[1]= firstfilebuf;
1159                 }
1160         }
1161
1162 #endif
1163
1164 #ifdef __FreeBSD__
1165         fpsetmask(0);
1166 #endif
1167
1168         // copy path to executable in bprogname. playanim and creting runtimes
1169         // need this.
1170
1171         BLI_where_am_i(bprogname, sizeof(bprogname), argv[0]);
1172
1173         BLI_threadapi_init();
1174
1175         RNA_init();
1176         RE_engines_init();
1177
1178                 /* Hack - force inclusion of the plugin api functions,
1179                  * see blenpluginapi:pluginapi.c
1180                  */
1181         pluginapi_force_ref();
1182
1183         init_nodesystem();
1184         
1185         initglobals();  /* blender.c */
1186
1187         IMB_init();
1188
1189         BLI_cb_init();
1190
1191 #ifdef WITH_GAMEENGINE
1192         syshandle = SYS_GetSystem();
1193 #else
1194         syshandle= 0;
1195 #endif
1196
1197         /* first test for background */
1198         ba = BLI_argsInit(argc, argv); /* skip binary path */
1199         setupArguments(C, ba, &syshandle);
1200
1201         BLI_argsParse(ba, 1, NULL, NULL);
1202
1203 #if defined(WITH_PYTHON_MODULE) || defined(WITH_HEADLESS)
1204         G.background= 1; /* python module mode ALWAYS runs in background mode (for now) */
1205 #else
1206         /* for all platforms, even windos has it! */
1207         if(G.background) signal(SIGINT, blender_esc);   /* ctrl c out bg render */
1208 #endif
1209
1210         /* background render uses this font too */
1211         BKE_font_register_builtin(datatoc_Bfont, datatoc_Bfont_size);
1212
1213         /* Initialiaze ffmpeg if built in, also needed for bg mode if videos are
1214            rendered via ffmpeg */
1215         sound_init_once();
1216         
1217         init_def_material();
1218
1219         if(G.background==0) {
1220                 BLI_argsParse(ba, 2, NULL, NULL);
1221                 BLI_argsParse(ba, 3, NULL, NULL);
1222
1223                 WM_init(C, argc, argv);
1224
1225                 /* this is properly initialized with user defs, but this is default */
1226                 BLI_where_is_temp(btempdir, FILE_MAX, 1); /* call after loading the startup.blend so we can read U.tempdir */
1227
1228 #ifdef WITH_SDL
1229         BLI_setenv("SDL_VIDEODRIVER", "dummy");
1230 #endif
1231         }
1232         else {
1233                 BLI_argsParse(ba, 3, NULL, NULL);
1234
1235                 WM_init(C, argc, argv);
1236
1237                 BLI_where_is_temp(btempdir, FILE_MAX, 0); /* call after loading the startup.blend so we can read U.tempdir */
1238         }
1239 #ifdef WITH_PYTHON
1240         /**
1241          * NOTE: the U.pythondir string is NULL until WM_init() is executed,
1242          * so we provide the BPY_ function below to append the user defined
1243          * pythondir to Python's sys.path at this point.  Simply putting
1244          * WM_init() before BPY_python_start() crashes Blender at startup.
1245          * Update: now this function also inits the bpymenus, which also depend
1246          * on U.pythondir.
1247          */
1248
1249         // TODO - U.pythondir
1250 #else
1251         printf("\n* WARNING * - Blender compiled without Python!\nthis is not intended for typical usage\n\n");
1252 #endif
1253         
1254         CTX_py_init_set(C, 1);
1255         WM_keymap_init(C);
1256
1257         /* OK we are ready for it */
1258         BLI_argsParse(ba, 4, load_file, C);
1259
1260         BLI_argsFree(ba);
1261
1262 #ifdef WITH_PYTHON_MODULE
1263         return 0; /* keep blender in background mode running */
1264 #endif
1265
1266         if(G.background) {
1267                 /* actually incorrect, but works for now (ton) */
1268                 WM_exit(C);
1269         }
1270
1271         else {
1272                 if((G.fileflags & G_FILE_AUTOPLAY) && (G.f & G_SCRIPT_AUTOEXEC))
1273                 {
1274                         if(WM_init_game(C))
1275                                 return 0;
1276                 }
1277                 else if(!G.file_loaded)
1278                         WM_init_splash(C);
1279         }
1280
1281         WM_main(C);
1282
1283
1284         /*XXX if (scr_init==0) {
1285                 main_init_screen();
1286         }
1287         
1288         screenmain();*/ /* main display loop */
1289
1290         return 0;
1291 } /* end of int main(argc,argv) */
1292
1293 #ifdef WITH_PYTHON_MODULE
1294 void main_python_exit(void)
1295 {
1296         WM_exit((bContext *)evil_C);
1297         evil_C= NULL;
1298 }
1299 #endif
1300
1301 static void error_cb(const char *err)
1302 {
1303         
1304         printf("%s\n", err);    /* XXX do this in WM too */
1305 }
1306
1307 static void mem_error_cb(const char *errorStr)
1308 {
1309         fputs(errorStr, stderr);
1310         fflush(stderr);
1311 }
1312
1313 static void setCallbacks(void)
1314 {
1315         /* Error output from the alloc routines: */
1316         MEM_set_error_callback(mem_error_cb);
1317
1318
1319         /* BLI_blenlib: */
1320
1321         BLI_setErrorCallBack(error_cb); /* */
1322 // XXX  BLI_setInterruptCallBack(blender_test_break);
1323
1324 }