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