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