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