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