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