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