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