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