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