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