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