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