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