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