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