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