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