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