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