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