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