Depsgraph: Report to the console when the new depsgraph is used
[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         printf("Using new dependency graph.\n");
946         DEG_depsgraph_switch_to_new();
947         return 0;
948 }
949
950 static int set_verbosity(int argc, const char **argv, void *UNUSED(data))
951 {
952         if (argc > 1) {
953                 int level = atoi(argv[1]);
954
955 #ifdef WITH_LIBMV
956                 libmv_setLoggingVerbosity(level);
957 #elif defined(WITH_CYCLES_LOGGING)
958                 CCL_logging_verbosity_set(level);
959 #else
960                 (void)level;
961 #endif
962
963                 return 1;
964         }
965         else {
966                 printf("\nError: you must specify a verbosity level.\n");
967                 return 0;
968         }
969 }
970
971 static int set_extension(int argc, const char **argv, void *data)
972 {
973         bContext *C = data;
974         if (argc > 1) {
975                 Scene *scene = CTX_data_scene(C);
976                 if (scene) {
977                         if (argv[1][0] == '0') {
978                                 scene->r.scemode &= ~R_EXTENSION;
979                         }
980                         else if (argv[1][0] == '1') {
981                                 scene->r.scemode |= R_EXTENSION;
982                         }
983                         else {
984                                 printf("\nError: Use '-x 1 / -x 0' To set the extension option or '--use-extension'\n");
985                         }
986                 }
987                 else {
988                         printf("\nError: no blend loaded. order the arguments so '-o ' is after '-x '.\n");
989                 }
990                 return 1;
991         }
992         else {
993                 printf("\nError: you must specify a path after '- '.\n");
994                 return 0;
995         }
996 }
997
998 static int set_ge_parameters(int argc, const char **argv, void *data)
999 {
1000         int a = 0;
1001 #ifdef WITH_GAMEENGINE
1002         SYS_SystemHandle syshandle = *(SYS_SystemHandle *)data;
1003 #else
1004         (void)data;
1005 #endif
1006
1007         /**
1008          * gameengine parameters are automatically put into system
1009          * -g [paramname = value]
1010          * -g [boolparamname]
1011          * example:
1012          * -g novertexarrays
1013          * -g maxvertexarraysize = 512
1014          */
1015
1016         if (argc >= 1) {
1017                 const char *paramname = argv[a];
1018                 /* check for single value versus assignment */
1019                 if (a + 1 < argc && (*(argv[a + 1]) == '=')) {
1020                         a++;
1021                         if (a + 1 < argc) {
1022                                 a++;
1023                                 /* assignment */
1024 #ifdef WITH_GAMEENGINE
1025                                 SYS_WriteCommandLineString(syshandle, paramname, argv[a]);
1026 #endif
1027                         }
1028                         else {
1029                                 printf("error: argument assignment (%s) without value.\n", paramname);
1030                                 return 0;
1031                         }
1032                         /* name arg eaten */
1033
1034                 }
1035                 else {
1036 #ifdef WITH_GAMEENGINE
1037                         SYS_WriteCommandLineInt(syshandle, argv[a], 1);
1038 #endif
1039                         /* doMipMap */
1040                         if (STREQ(argv[a], "nomipmap")) {
1041                                 GPU_set_mipmap(0); //doMipMap = 0;
1042                         }
1043                         /* linearMipMap */
1044                         if (STREQ(argv[a], "linearmipmap")) {
1045                                 GPU_set_mipmap(1);
1046                                 GPU_set_linear_mipmap(1); //linearMipMap = 1;
1047                         }
1048
1049
1050                 } /* if (*(argv[a + 1]) == '=') */
1051         }
1052
1053         return a;
1054 }
1055
1056 static int render_frame(int argc, const char **argv, void *data)
1057 {
1058         bContext *C = data;
1059         Scene *scene = CTX_data_scene(C);
1060         if (scene) {
1061                 Main *bmain = CTX_data_main(C);
1062
1063                 if (argc > 1) {
1064                         Render *re = RE_NewRender(scene->id.name);
1065                         int frame;
1066                         ReportList reports;
1067
1068                         switch (*argv[1]) {
1069                                 case '+':
1070                                         frame = scene->r.sfra + atoi(argv[1] + 1);
1071                                         break;
1072                                 case '-':
1073                                         frame = (scene->r.efra - atoi(argv[1] + 1)) + 1;
1074                                         break;
1075                                 default:
1076                                         frame = atoi(argv[1]);
1077                                         break;
1078                         }
1079
1080                         BLI_begin_threaded_malloc();
1081                         BKE_reports_init(&reports, RPT_PRINT);
1082
1083                         frame = CLAMPIS(frame, MINAFRAME, MAXFRAME);
1084
1085                         RE_SetReports(re, &reports);
1086                         RE_BlenderAnim(re, bmain, scene, NULL, scene->lay, frame, frame, scene->r.frame_step);
1087                         RE_SetReports(re, NULL);
1088                         BLI_end_threaded_malloc();
1089                         return 1;
1090                 }
1091                 else {
1092                         printf("\nError: frame number must follow '-f / --render-frame'.\n");
1093                         return 0;
1094                 }
1095         }
1096         else {
1097                 printf("\nError: no blend loaded. cannot use '-f / --render-frame'.\n");
1098                 return 0;
1099         }
1100 }
1101
1102 static int render_animation(int UNUSED(argc), const char **UNUSED(argv), void *data)
1103 {
1104         bContext *C = data;
1105         Scene *scene = CTX_data_scene(C);
1106         if (scene) {
1107                 Main *bmain = CTX_data_main(C);
1108                 Render *re = RE_NewRender(scene->id.name);
1109                 ReportList reports;
1110                 BLI_begin_threaded_malloc();
1111                 BKE_reports_init(&reports, RPT_PRINT);
1112                 RE_SetReports(re, &reports);
1113                 RE_BlenderAnim(re, bmain, scene, NULL, scene->lay, scene->r.sfra, scene->r.efra, scene->r.frame_step);
1114                 RE_SetReports(re, NULL);
1115                 BLI_end_threaded_malloc();
1116         }
1117         else {
1118                 printf("\nError: no blend loaded. cannot use '-a'.\n");
1119         }
1120         return 0;
1121 }
1122
1123 static int set_scene(int argc, const char **argv, void *data)
1124 {
1125         if (argc > 1) {
1126                 bContext *C = data;
1127                 Scene *scene = BKE_scene_set_name(CTX_data_main(C), argv[1]);
1128                 if (scene) {
1129                         CTX_data_scene_set(C, scene);
1130                 }
1131                 return 1;
1132         }
1133         else {
1134                 printf("\nError: Scene name must follow '-S / --scene'.\n");
1135                 return 0;
1136         }
1137 }
1138
1139 static int set_start_frame(int argc, const char **argv, void *data)
1140 {
1141         bContext *C = data;
1142         Scene *scene = CTX_data_scene(C);
1143         if (scene) {
1144                 if (argc > 1) {
1145                         int frame = atoi(argv[1]);
1146                         (scene->r.sfra) = CLAMPIS(frame, MINFRAME, MAXFRAME);
1147                         return 1;
1148                 }
1149                 else {
1150                         printf("\nError: frame number must follow '-s / --frame-start'.\n");
1151                         return 0;
1152                 }
1153         }
1154         else {
1155                 printf("\nError: no blend loaded. cannot use '-s / --frame-start'.\n");
1156                 return 0;
1157         }
1158 }
1159
1160 static int set_end_frame(int argc, const char **argv, void *data)
1161 {
1162         bContext *C = data;
1163         Scene *scene = CTX_data_scene(C);
1164         if (scene) {
1165                 if (argc > 1) {
1166                         int frame = atoi(argv[1]);
1167                         (scene->r.efra) = CLAMPIS(frame, MINFRAME, MAXFRAME);
1168                         return 1;
1169                 }
1170                 else {
1171                         printf("\nError: frame number must follow '-e / --frame-end'.\n");
1172                         return 0;
1173                 }
1174         }
1175         else {
1176                 printf("\nError: no blend loaded. cannot use '-e / --frame-end'.\n");
1177                 return 0;
1178         }
1179 }
1180
1181 static int set_skip_frame(int argc, const char **argv, void *data)
1182 {
1183         bContext *C = data;
1184         Scene *scene = CTX_data_scene(C);
1185         if (scene) {
1186                 if (argc > 1) {
1187                         int frame = atoi(argv[1]);
1188                         (scene->r.frame_step) = CLAMPIS(frame, 1, MAXFRAME);
1189                         return 1;
1190                 }
1191                 else {
1192                         printf("\nError: number of frames to step must follow '-j / --frame-jump'.\n");
1193                         return 0;
1194                 }
1195         }
1196         else {
1197                 printf("\nError: no blend loaded. cannot use '-j / --frame-jump'.\n");
1198                 return 0;
1199         }
1200 }
1201
1202 /* macro for ugly context setup/reset */
1203 #ifdef WITH_PYTHON
1204 #define BPY_CTX_SETUP(_cmd)                                                   \
1205         {                                                                         \
1206                 wmWindowManager *wm = CTX_wm_manager(C);                              \
1207                 Scene *scene_prev = CTX_data_scene(C);                                \
1208                 wmWindow *win_prev;                                                   \
1209                 const bool has_win = !BLI_listbase_is_empty(&wm->windows);            \
1210                 if (has_win) {                                                        \
1211                         win_prev = CTX_wm_window(C);                                      \
1212                         CTX_wm_window_set(C, wm->windows.first);                          \
1213                 }                                                                     \
1214                 else {                                                                \
1215                         fprintf(stderr, "Python script \"%s\" "                           \
1216                                 "running with missing context data.\n", argv[1]);         \
1217                 }                                                                     \
1218                 {                                                                     \
1219                         _cmd;                                                             \
1220                 }                                                                     \
1221                 if (has_win) {                                                        \
1222                         CTX_wm_window_set(C, win_prev);                                   \
1223                 }                                                                     \
1224                 CTX_data_scene_set(C, scene_prev);                                    \
1225         } (void)0                                                                 \
1226
1227 #endif /* WITH_PYTHON */
1228
1229 static int run_python_file(int argc, const char **argv, void *data)
1230 {
1231 #ifdef WITH_PYTHON
1232         bContext *C = data;
1233
1234         /* workaround for scripts not getting a bpy.context.scene, causes internal errors elsewhere */
1235         if (argc > 1) {
1236                 /* Make the path absolute because its needed for relative linked blends to be found */
1237                 char filename[FILE_MAX];
1238                 BLI_strncpy(filename, argv[1], sizeof(filename));
1239                 BLI_path_cwd(filename);
1240
1241                 BPY_CTX_SETUP(BPY_filepath_exec(C, filename, NULL));
1242
1243                 return 1;
1244         }
1245         else {
1246                 printf("\nError: you must specify a filepath after '%s'.\n", argv[0]);
1247                 return 0;
1248         }
1249 #else
1250         UNUSED_VARS(argc, argv, data);
1251         printf("This blender was built without python support\n");
1252         return 0;
1253 #endif /* WITH_PYTHON */
1254 }
1255
1256 static int run_python_text(int argc, const char **argv, void *data)
1257 {
1258 #ifdef WITH_PYTHON
1259         bContext *C = data;
1260
1261         /* workaround for scripts not getting a bpy.context.scene, causes internal errors elsewhere */
1262         if (argc > 1) {
1263                 /* Make the path absolute because its needed for relative linked blends to be found */
1264                 struct Text *text = (struct Text *)BKE_libblock_find_name(ID_TXT, argv[1]);
1265
1266                 if (text) {
1267                         BPY_CTX_SETUP(BPY_text_exec(C, text, NULL, false));
1268                         return 1;
1269                 }
1270                 else {
1271                         printf("\nError: text block not found %s.\n", argv[1]);
1272                         return 1;
1273                 }
1274         }
1275         else {
1276                 printf("\nError: you must specify a text block after '%s'.\n", argv[0]);
1277                 return 0;
1278         }
1279 #else
1280         UNUSED_VARS(argc, argv, data);
1281         printf("This blender was built without python support\n");
1282         return 0;
1283 #endif /* WITH_PYTHON */
1284 }
1285
1286 static int run_python_console(int UNUSED(argc), const char **argv, void *data)
1287 {
1288 #ifdef WITH_PYTHON
1289         bContext *C = data;
1290
1291         BPY_CTX_SETUP(BPY_string_exec(C, "__import__('code').interact()"));
1292
1293         return 0;
1294 #else
1295         UNUSED_VARS(argv, data);
1296         printf("This blender was built without python support\n");
1297         return 0;
1298 #endif /* WITH_PYTHON */
1299 }
1300
1301 static int set_addons(int argc, const char **argv, void *data)
1302 {
1303         /* workaround for scripts not getting a bpy.context.scene, causes internal errors elsewhere */
1304         if (argc > 1) {
1305 #ifdef WITH_PYTHON
1306                 const int slen = strlen(argv[1]) + 128;
1307                 char *str = malloc(slen);
1308                 bContext *C = data;
1309                 BLI_snprintf(str, slen, "[__import__('addon_utils').enable(i, default_set=False) for i in '%s'.split(',')]", argv[1]);
1310                 BPY_CTX_SETUP(BPY_string_exec(C, str));
1311                 free(str);
1312 #else
1313                 UNUSED_VARS(argv, data);
1314 #endif /* WITH_PYTHON */
1315                 return 1;
1316         }
1317         else {
1318                 printf("\nError: you must specify a comma separated list after '--addons'.\n");
1319                 return 0;
1320         }
1321 }
1322
1323 static int load_file(int UNUSED(argc), const char **argv, void *data)
1324 {
1325         bContext *C = data;
1326
1327         /* Make the path absolute because its needed for relative linked blends to be found */
1328         char filename[FILE_MAX];
1329
1330         /* note, we could skip these, but so far we always tried to load these files */
1331         if (argv[0][0] == '-') {
1332                 fprintf(stderr, "unknown argument, loading as file: %s\n", argv[0]);
1333         }
1334
1335         BLI_strncpy(filename, argv[0], sizeof(filename));
1336         BLI_path_cwd(filename);
1337
1338         if (G.background) {
1339                 int retval;
1340
1341                 BLI_callback_exec(CTX_data_main(C), NULL, BLI_CB_EVT_LOAD_PRE);
1342
1343                 retval = BKE_read_file(C, filename, NULL);
1344
1345                 /* we successfully loaded a blend file, get sure that
1346                  * pointcache works */
1347                 if (retval != BKE_READ_FILE_FAIL) {
1348                         wmWindowManager *wm = CTX_wm_manager(C);
1349                         Main *bmain = CTX_data_main(C);
1350
1351                         /* special case, 2.4x files */
1352                         if (wm == NULL && BLI_listbase_is_empty(&bmain->wm)) {
1353                                 extern void wm_add_default(bContext *C);
1354
1355                                 /* wm_add_default() needs the screen to be set. */
1356                                 CTX_wm_screen_set(C, bmain->screen.first);
1357                                 wm_add_default(C);
1358                         }
1359
1360                         CTX_wm_manager_set(C, NULL); /* remove wm to force check */
1361                         WM_check(C);
1362                         if (bmain->name[0]) {
1363                                 G.save_over = 1;
1364                                 G.relbase_valid = 1;
1365                         }
1366                         else {
1367                                 G.save_over = 0;
1368                                 G.relbase_valid = 0;
1369                         }
1370                         if (CTX_wm_manager(C) == NULL) CTX_wm_manager_set(C, wm);  /* reset wm */
1371
1372                         /* WM_file_read would call normally */
1373                         ED_editors_init(C);
1374                         DAG_on_visible_update(bmain, true);
1375                         BKE_scene_update_tagged(bmain->eval_ctx, bmain, CTX_data_scene(C));
1376                 }
1377                 else {
1378                         /* failed to load file, stop processing arguments */
1379                         return -1;
1380                 }
1381
1382                 /* WM_file_read() runs normally but since we're in background mode do here */
1383 #ifdef WITH_PYTHON
1384                 /* run any texts that were loaded in and flagged as modules */
1385                 BPY_python_reset(C);
1386 #endif
1387
1388                 BLI_callback_exec(CTX_data_main(C), NULL, BLI_CB_EVT_LOAD_POST);
1389
1390                 /* happens for the UI on file reading too (huh? (ton))*/
1391                 // XXX          BKE_undo_reset();
1392                 //                      BKE_undo_write("original");     /* save current state */
1393         }
1394         else {
1395                 /* we are not running in background mode here, but start blender in UI mode with
1396                  * a file - this should do everything a 'load file' does */
1397                 ReportList reports;
1398                 BKE_reports_init(&reports, RPT_PRINT);
1399                 WM_file_autoexec_init(filename);
1400                 WM_file_read(C, filename, &reports);
1401                 BKE_reports_clear(&reports);
1402         }
1403
1404         G.file_loaded = 1;
1405
1406         return 0;
1407 }
1408
1409 static void setupArguments(bContext *C, bArgs *ba, SYS_SystemHandle *syshandle)
1410 {
1411         static char output_doc[] = "<path>"
1412                 "\n\tSet the render path and file name."
1413                 "\n\tUse // at the start of the path to"
1414                 "\n\t\trender relative to the blend file."
1415                 "\n\tThe # characters are replaced by the frame number, and used to define zero padding."
1416                 "\n\t\tani_##_test.png becomes ani_01_test.png"
1417                 "\n\t\ttest-######.png becomes test-000001.png"
1418                 "\n\t\tWhen the filename does not contain #, The suffix #### is added to the filename"
1419                 "\n\tThe frame number will be added at the end of the filename."
1420                 "\n\t\teg: blender -b foobar.blend -o //render_ -F PNG -x 1 -a"
1421                 "\n\t\t//render_ becomes //render_####, writing frames as //render_0001.png//";
1422
1423         static char format_doc[] = "<format>"
1424                 "\n\tSet the render format, Valid options are..."
1425                 "\n\t\tTGA IRIS JPEG MOVIE IRIZ RAWTGA"
1426                 "\n\t\tAVIRAW AVIJPEG PNG BMP FRAMESERVER"
1427                 "\n\t(formats that can be compiled into blender, not available on all systems)"
1428                 "\n\t\tHDR TIFF EXR MULTILAYER MPEG AVICODEC QUICKTIME CINEON DPX DDS";
1429
1430         static char playback_doc[] = "<options> <file(s)>"
1431                 "\n\tPlayback <file(s)>, only operates this way when not running in background."
1432                 "\n\t\t-p <sx> <sy>\tOpen with lower left corner at <sx>, <sy>"
1433                 "\n\t\t-m\t\tRead from disk (Don't buffer)"
1434                 "\n\t\t-f <fps> <fps-base>\t\tSpecify FPS to start with"
1435                 "\n\t\t-j <frame>\tSet frame step to <frame>"
1436                 "\n\t\t-s <frame>\tPlay from <frame>"
1437                 "\n\t\t-e <frame>\tPlay until <frame>";
1438
1439         static char game_doc[] = "Game Engine specific options"
1440                 "\n\t-g fixedtime\t\tRun on 50 hertz without dropping frames"
1441                 "\n\t-g vertexarrays\t\tUse Vertex Arrays for rendering (usually faster)"
1442                 "\n\t-g nomipmap\t\tNo Texture Mipmapping"
1443                 "\n\t-g linearmipmap\t\tLinear Texture Mipmapping instead of Nearest (default)";
1444
1445         static char debug_doc[] = "\n\tTurn debugging on\n"
1446                 "\n\t* Prints every operator call and their arguments"
1447                 "\n\t* Disables mouse grab (to interact with a debugger in some cases)"
1448                 "\n\t* Keeps python sys.stdin rather than setting it to None";
1449
1450         //BLI_argsAdd(ba, pass, short_arg, long_arg, doc, cb, C);
1451
1452         /* end argument processing after -- */
1453         BLI_argsAdd(ba, -1, "--", NULL, "\n\tEnds option processing, following arguments passed unchanged. Access via python's sys.argv", end_arguments, NULL);
1454
1455         /* first pass: background mode, disable python and commands that exit after usage */
1456         BLI_argsAdd(ba, 1, "-h", "--help", "\n\tPrint this help text and exit", print_help, ba);
1457         /* Windows only */
1458         BLI_argsAdd(ba, 1, "/?", NULL, "\n\tPrint this help text and exit (windows only)", print_help, ba);
1459
1460         BLI_argsAdd(ba, 1, "-v", "--version", "\n\tPrint Blender version and exit", print_version, NULL);
1461         
1462         /* only to give help message */
1463 #ifndef WITH_PYTHON_SECURITY /* default */
1464 #  define   PY_ENABLE_AUTO ", (default)"
1465 #  define   PY_DISABLE_AUTO ""
1466 #else
1467 #  define   PY_ENABLE_AUTO ""
1468 #  define   PY_DISABLE_AUTO ", (compiled as non-standard default)"
1469 #endif
1470
1471         BLI_argsAdd(ba, 1, "-y", "--enable-autoexec", "\n\tEnable automatic python script execution" PY_ENABLE_AUTO, enable_python, NULL);
1472         BLI_argsAdd(ba, 1, "-Y", "--disable-autoexec", "\n\tDisable automatic python script execution (pydrivers & startup scripts)" PY_DISABLE_AUTO, disable_python, NULL);
1473
1474         BLI_argsAdd(ba, 1, NULL, "--disable-crash-handler", "\n\tDisable the crash handler", disable_crash_handler, NULL);
1475         BLI_argsAdd(ba, 1, NULL, "--disable-abort-handler", "\n\tDisable the abort handler", disable_abort_handler, NULL);
1476
1477 #undef PY_ENABLE_AUTO
1478 #undef PY_DISABLE_AUTO
1479         
1480         BLI_argsAdd(ba, 1, "-b", "--background", "\n\tRun in background (often used for UI-less rendering)", background_mode, NULL);
1481
1482         BLI_argsAdd(ba, 1, "-a", NULL, playback_doc, playback_mode, NULL);
1483
1484         BLI_argsAdd(ba, 1, "-d", "--debug", debug_doc, debug_mode, ba);
1485
1486 #ifdef WITH_FFMPEG
1487         BLI_argsAdd(ba, 1, NULL, "--debug-ffmpeg", "\n\tEnable debug messages from FFmpeg library", debug_mode_generic, (void *)G_DEBUG_FFMPEG);
1488 #endif
1489
1490 #ifdef WITH_FREESTYLE
1491         BLI_argsAdd(ba, 1, NULL, "--debug-freestyle", "\n\tEnable debug/profiling messages from Freestyle rendering", debug_mode_generic, (void *)G_DEBUG_FREESTYLE);
1492 #endif
1493
1494         BLI_argsAdd(ba, 1, NULL, "--debug-python", "\n\tEnable debug messages for python", debug_mode_generic, (void *)G_DEBUG_PYTHON);
1495         BLI_argsAdd(ba, 1, NULL, "--debug-events", "\n\tEnable debug messages for the event system", debug_mode_generic, (void *)G_DEBUG_EVENTS);
1496         BLI_argsAdd(ba, 1, NULL, "--debug-handlers", "\n\tEnable debug messages for event handling", debug_mode_generic, (void *)G_DEBUG_HANDLERS);
1497         BLI_argsAdd(ba, 1, NULL, "--debug-wm",     "\n\tEnable debug messages for the window manager", debug_mode_generic, (void *)G_DEBUG_WM);
1498         BLI_argsAdd(ba, 1, NULL, "--debug-all",    "\n\tEnable all debug messages (excludes libmv)", debug_mode_generic, (void *)G_DEBUG_ALL);
1499
1500         BLI_argsAdd(ba, 1, NULL, "--debug-fpe", "\n\tEnable floating point exceptions", set_fpe, NULL);
1501
1502 #ifdef WITH_LIBMV
1503         BLI_argsAdd(ba, 1, NULL, "--debug-libmv", "\n\tEnable debug messages from libmv library", debug_mode_libmv, NULL);
1504 #endif
1505 #ifdef WITH_CYCLES_LOGGING
1506         BLI_argsAdd(ba, 1, NULL, "--debug-cycles", "\n\tEnable debug messages from Cycles", debug_mode_cycles, NULL);
1507 #endif
1508         BLI_argsAdd(ba, 1, NULL, "--debug-memory", "\n\tEnable fully guarded memory allocation and debugging", debug_mode_memory, NULL);
1509
1510         BLI_argsAdd(ba, 1, NULL, "--debug-value", "<value>\n\tSet debug value of <value> on startup\n", set_debug_value, NULL);
1511         BLI_argsAdd(ba, 1, NULL, "--debug-jobs",  "\n\tEnable time profiling for background jobs.", debug_mode_generic, (void *)G_DEBUG_JOBS);
1512         BLI_argsAdd(ba, 1, NULL, "--debug-depsgraph", "\n\tEnable debug messages from dependency graph", debug_mode_generic, (void *)G_DEBUG_DEPSGRAPH);
1513         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);
1514         BLI_argsAdd(ba, 1, NULL, "--debug-gpumem", "\n\tEnable GPU memory stats in status bar", debug_mode_generic, (void *)G_DEBUG_GPU_MEM);
1515
1516         BLI_argsAdd(ba, 1, NULL, "--enable-new-depsgraph", "\n\tUse new dependency graph", depsgraph_use_new, NULL);
1517
1518         BLI_argsAdd(ba, 1, NULL, "--verbose", "<verbose>\n\tSet logging verbosity level.", set_verbosity, NULL);
1519
1520         BLI_argsAdd(ba, 1, NULL, "--factory-startup", "\n\tSkip reading the "STRINGIFY (BLENDER_STARTUP_FILE)" in the users home directory", set_factory_startup, NULL);
1521
1522         /* TODO, add user env vars? */
1523         BLI_argsAdd(ba, 1, NULL, "--env-system-datafiles",  "\n\tSet the "STRINGIFY_ARG (BLENDER_SYSTEM_DATAFILES)" environment variable", set_env, NULL);
1524         BLI_argsAdd(ba, 1, NULL, "--env-system-scripts",    "\n\tSet the "STRINGIFY_ARG (BLENDER_SYSTEM_SCRIPTS)" environment variable", set_env, NULL);
1525         BLI_argsAdd(ba, 1, NULL, "--env-system-python",     "\n\tSet the "STRINGIFY_ARG (BLENDER_SYSTEM_PYTHON)" environment variable", set_env, NULL);
1526
1527         /* second pass: custom window stuff */
1528         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);
1529         BLI_argsAdd(ba, 2, "-w", "--window-border", "\n\tForce opening with borders (default)", with_borders, NULL);
1530         BLI_argsAdd(ba, 2, "-W", "--window-borderless", "\n\tForce opening without borders", without_borders, NULL);
1531         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);
1532         BLI_argsAdd(ba, 2, "-R", NULL, "\n\tRegister .blend extension, then exit (Windows only)", register_extension, NULL);
1533         BLI_argsAdd(ba, 2, "-r", NULL, "\n\tSilently register .blend extension, then exit (Windows only)", register_extension, ba);
1534         BLI_argsAdd(ba, 2, NULL, "--no-native-pixels", "\n\tDo not use native pixel size, for high resolution displays (MacBook 'Retina')", native_pixels, ba);
1535
1536         /* third pass: disabling things and forcing settings */
1537         BLI_argsAddCase(ba, 3, "-nojoystick", 1, NULL, 0, "\n\tDisable joystick support", no_joystick, syshandle);
1538         BLI_argsAddCase(ba, 3, "-noglsl", 1, NULL, 0, "\n\tDisable GLSL shading", no_glsl, NULL);
1539         BLI_argsAddCase(ba, 3, "-noaudio", 1, NULL, 0, "\n\tForce sound system to None", no_audio, NULL);
1540         BLI_argsAddCase(ba, 3, "-setaudio", 1, NULL, 0, "\n\tForce sound system to a specific device\n\tNULL SDL OPENAL JACK", set_audio, NULL);
1541
1542         /* fourth pass: processing arguments */
1543         BLI_argsAdd(ba, 4, "-g", NULL, game_doc, set_ge_parameters, syshandle);
1544         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);
1545         BLI_argsAdd(ba, 4, "-a", "--render-anim", "\n\tRender frames from start to end (inclusive)", render_animation, C);
1546         BLI_argsAdd(ba, 4, "-S", "--scene", "<name>\n\tSet the active scene <name> for rendering", set_scene, C);
1547         BLI_argsAdd(ba, 4, "-s", "--frame-start", "<frame>\n\tSet start to frame <frame> (use before the -a argument)", set_start_frame, C);
1548         BLI_argsAdd(ba, 4, "-e", "--frame-end", "<frame>\n\tSet end to frame <frame> (use before the -a argument)", set_end_frame, C);
1549         BLI_argsAdd(ba, 4, "-j", "--frame-jump", "<frames>\n\tSet number of frames to step forward after each rendered frame", set_skip_frame, C);
1550         BLI_argsAdd(ba, 4, "-P", "--python", "<filename>\n\tRun the given Python script file", run_python_file, C);
1551         BLI_argsAdd(ba, 4, NULL, "--python-text", "<name>\n\tRun the given Python script text block", run_python_text, C);
1552         BLI_argsAdd(ba, 4, NULL, "--python-console", "\n\tRun blender with an interactive console", run_python_console, C);
1553         BLI_argsAdd(ba, 4, NULL, "--addons", "\n\tComma separated list of addons (no spaces)", set_addons, C);
1554
1555         BLI_argsAdd(ba, 4, "-o", "--render-output", output_doc, set_output, C);
1556         BLI_argsAdd(ba, 4, "-E", "--engine", "<engine>\n\tSpecify the render engine\n\tuse -E help to list available engines", set_engine, C);
1557
1558         BLI_argsAdd(ba, 4, "-F", "--render-format", format_doc, set_image_type, C);
1559         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);
1560         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);
1561
1562 }
1563 #endif /* WITH_PYTHON_MODULE */
1564
1565 #ifdef WITH_PYTHON_MODULE
1566 /* allow python module to call main */
1567 #  define main main_python_enter
1568 static void *evil_C = NULL;
1569
1570 #  ifdef __APPLE__
1571      /* environ is not available in mac shared libraries */
1572 #    include <crt_externs.h>
1573 char **environ = NULL;
1574 #  endif
1575 #endif
1576
1577 /**
1578  * Blender's main function responsabilities are:
1579  * - setup subsystems.
1580  * - handle arguments.
1581  * - run WM_main() event loop,
1582  *   or exit when running in background mode.
1583  */
1584 int main(
1585         int argc,
1586 #ifdef WIN32
1587         const char **UNUSED(argv_c)
1588 #else
1589         const char **argv
1590 #endif
1591         )
1592 {
1593         bContext *C;
1594         SYS_SystemHandle syshandle;
1595
1596 #ifndef WITH_PYTHON_MODULE
1597         bArgs *ba;
1598 #endif
1599
1600 #ifdef WIN32
1601         char **argv;
1602         int argv_num;
1603 #endif
1604
1605         /* --- end declarations --- */
1606
1607
1608 #ifdef WIN32
1609         /* FMA3 support in the 2013 CRT is broken on Vista and Windows 7 RTM (fixed in SP1). Just disable it. */
1610 #  if defined(_MSC_VER) && _MSC_VER >= 1800 && defined(_M_X64)
1611         _set_FMA3_enable(0);
1612 #  endif
1613
1614         /* Win32 Unicode Args */
1615         /* NOTE: cannot use guardedalloc malloc here, as it's not yet initialized
1616          *       (it depends on the args passed in, which is what we're getting here!)
1617          */
1618         {
1619                 wchar_t **argv_16 = CommandLineToArgvW(GetCommandLineW(), &argc);
1620                 argv = malloc(argc * sizeof(char *));
1621                 for (argv_num = 0; argv_num < argc; argv_num++) {
1622                         argv[argv_num] = alloc_utf_8_from_16(argv_16[argv_num], 0);
1623                 }
1624                 LocalFree(argv_16);
1625         }
1626 #endif  /* WIN32 */
1627
1628         /* NOTE: Special exception for guarded allocator type switch:
1629          *       we need to perform switch from lock-free to fully
1630          *       guarded allocator before any allocation happened.
1631          */
1632         {
1633                 int i;
1634                 for (i = 0; i < argc; i++) {
1635                         if (STREQ(argv[i], "--debug") || STREQ(argv[i], "-d") ||
1636                             STREQ(argv[i], "--debug-memory"))
1637                         {
1638                                 printf("Switching to fully guarded memory allocator.\n");
1639                                 MEM_use_guarded_allocator();
1640                                 break;
1641                         }
1642                         else if (STREQ(argv[i], "--")) {
1643                                 break;
1644                         }
1645                 }
1646         }
1647
1648 #ifdef BUILD_DATE
1649         {
1650                 time_t temp_time = build_commit_timestamp;
1651                 struct tm *tm = gmtime(&temp_time);
1652                 if (LIKELY(tm)) {
1653                         strftime(build_commit_date, sizeof(build_commit_date), "%Y-%m-%d", tm);
1654                         strftime(build_commit_time, sizeof(build_commit_time), "%H:%M", tm);
1655                 }
1656                 else {
1657                         const char *unknown = "date-unknown";
1658                         BLI_strncpy(build_commit_date, unknown, sizeof(build_commit_date));
1659                         BLI_strncpy(build_commit_time, unknown, sizeof(build_commit_time));
1660                 }
1661         }
1662 #endif
1663
1664 #ifdef WITH_SDL_DYNLOAD
1665         sdlewInit();
1666 #endif
1667
1668         C = CTX_create();
1669
1670 #ifdef WITH_PYTHON_MODULE
1671 #ifdef __APPLE__
1672         environ = *_NSGetEnviron();
1673 #endif
1674
1675 #undef main
1676         evil_C = C;
1677 #endif
1678
1679
1680
1681 #ifdef WITH_BINRELOC
1682         br_init(NULL);
1683 #endif
1684
1685 #ifdef WITH_LIBMV
1686         libmv_initLogging(argv[0]);
1687 #elif defined(WITH_CYCLES_LOGGING)
1688         CCL_init_logging(argv[0]);
1689 #endif
1690
1691         setCallbacks();
1692         
1693 #if defined(__APPLE__) && !defined(WITH_PYTHON_MODULE)
1694         /* patch to ignore argument finder gives us (pid?) */
1695         if (argc == 2 && STREQLEN(argv[1], "-psn_", 5)) {
1696                 extern int GHOST_HACK_getFirstFile(char buf[]);
1697                 static char firstfilebuf[512];
1698
1699                 argc = 1;
1700
1701                 if (GHOST_HACK_getFirstFile(firstfilebuf)) {
1702                         argc = 2;
1703                         argv[1] = firstfilebuf;
1704                 }
1705         }
1706 #endif
1707         
1708 #ifdef __FreeBSD__
1709         fpsetmask(0);
1710 #endif
1711
1712         /* initialize path to executable */
1713         BKE_appdir_program_path_init(argv[0]);
1714
1715         BLI_threadapi_init();
1716
1717         initglobals();  /* blender.c */
1718
1719         IMB_init();
1720         BKE_images_init();
1721         BKE_modifier_init();
1722         DAG_init();
1723
1724         BKE_brush_system_init();
1725         RE_init_texture_rng();
1726         
1727
1728         BLI_callback_global_init();
1729
1730 #ifdef WITH_GAMEENGINE
1731         syshandle = SYS_GetSystem();
1732 #else
1733         syshandle = 0;
1734 #endif
1735
1736         /* first test for background */
1737 #ifndef WITH_PYTHON_MODULE
1738         ba = BLI_argsInit(argc, (const char **)argv); /* skip binary path */
1739         setupArguments(C, ba, &syshandle);
1740
1741         BLI_argsParse(ba, 1, NULL, NULL);
1742
1743         if (use_crash_handler) {
1744 #ifdef WIN32
1745                 SetUnhandledExceptionFilter(windows_exception_handler);
1746 #else
1747                 /* after parsing args */
1748                 signal(SIGSEGV, blender_crash_handler);
1749 #endif
1750         }
1751
1752         if (use_abort_handler) {
1753                 signal(SIGABRT, blender_abort_handler);
1754         }
1755
1756 #else
1757         G.factory_startup = true;  /* using preferences or user startup makes no sense for py-as-module */
1758         (void)syshandle;
1759 #endif
1760
1761 #ifdef WITH_FFMPEG
1762         IMB_ffmpeg_init();
1763 #endif
1764
1765         /* after level 1 args, this is so playanim skips RNA init */
1766         RNA_init();
1767
1768         RE_engines_init();
1769         init_nodesystem();
1770         psys_init_rng();
1771         /* end second init */
1772
1773
1774 #if defined(WITH_PYTHON_MODULE) || defined(WITH_HEADLESS)
1775         G.background = true; /* python module mode ALWAYS runs in background mode (for now) */
1776 #else
1777         /* for all platforms, even windos has it! */
1778         if (G.background) {
1779                 signal(SIGINT, blender_esc);  /* ctrl c out bg render */
1780         }
1781 #endif
1782
1783         /* background render uses this font too */
1784         BKE_vfont_builtin_register(datatoc_bfont_pfb, datatoc_bfont_pfb_size);
1785
1786         /* Initialize ffmpeg if built in, also needed for bg mode if videos are
1787          * rendered via ffmpeg */
1788         BKE_sound_init_once();
1789         
1790         init_def_material();
1791
1792         if (G.background == 0) {
1793 #ifndef WITH_PYTHON_MODULE
1794                 BLI_argsParse(ba, 2, NULL, NULL);
1795                 BLI_argsParse(ba, 3, NULL, NULL);
1796 #endif
1797                 WM_init(C, argc, (const char **)argv);
1798
1799                 /* this is properly initialized with user defs, but this is default */
1800                 /* call after loading the startup.blend so we can read U.tempdir */
1801                 BKE_tempdir_init(U.tempdir);
1802         }
1803         else {
1804 #ifndef WITH_PYTHON_MODULE
1805                 BLI_argsParse(ba, 3, NULL, NULL);
1806 #endif
1807
1808                 WM_init(C, argc, (const char **)argv);
1809
1810                 /* don't use user preferences temp dir */
1811                 BKE_tempdir_init(NULL);
1812         }
1813 #ifdef WITH_PYTHON
1814         /**
1815          * NOTE: the U.pythondir string is NULL until WM_init() is executed,
1816          * so we provide the BPY_ function below to append the user defined
1817          * python-dir to Python's sys.path at this point.  Simply putting
1818          * WM_init() before #BPY_python_start() crashes Blender at startup.
1819          */
1820
1821         /* TODO - U.pythondir */
1822 #else
1823         printf("\n* WARNING * - Blender compiled without Python!\nthis is not intended for typical usage\n\n");
1824 #endif
1825         
1826         CTX_py_init_set(C, 1);
1827         WM_keymap_init(C);
1828
1829 #ifdef WITH_FREESTYLE
1830         /* initialize Freestyle */
1831         FRS_initialize();
1832         FRS_set_context(C);
1833 #endif
1834
1835         /* OK we are ready for it */
1836 #ifndef WITH_PYTHON_MODULE
1837         BLI_argsParse(ba, 4, load_file, C);
1838         
1839         if (G.background == 0) {
1840                 if (!G.file_loaded)
1841                         if (U.uiflag2 & USER_KEEP_SESSION)
1842                                 WM_recover_last_session(C, NULL);
1843         }
1844
1845 #endif
1846
1847 #ifndef WITH_PYTHON_MODULE
1848         BLI_argsFree(ba);
1849 #endif
1850
1851 #ifdef WIN32
1852         while (argv_num) {
1853                 free(argv[--argv_num]);
1854         }
1855         free(argv);
1856         argv = NULL;
1857 #endif
1858
1859 #ifdef WITH_PYTHON_MODULE
1860         return 0; /* keep blender in background mode running */
1861 #endif
1862
1863         if (G.background) {
1864                 /* actually incorrect, but works for now (ton) */
1865                 WM_exit(C);
1866         }
1867         else {
1868                 if (G.fileflags & G_FILE_AUTOPLAY) {
1869                         if (G.f & G_SCRIPT_AUTOEXEC) {
1870                                 if (WM_init_game(C)) {
1871                                         return 0;
1872                                 }
1873                         }
1874                         else {
1875                                 if (!(G.f & G_SCRIPT_AUTOEXEC_FAIL_QUIET)) {
1876                                         G.f |= G_SCRIPT_AUTOEXEC_FAIL;
1877                                         BLI_snprintf(G.autoexec_fail, sizeof(G.autoexec_fail), "Game AutoStart");
1878                                 }
1879                         }
1880                 }
1881
1882                 if (!G.file_loaded) {
1883                         WM_init_splash(C);
1884                 }
1885         }
1886
1887         WM_main(C);
1888
1889         return 0;
1890 } /* end of int main(argc, argv)        */
1891
1892 #ifdef WITH_PYTHON_MODULE
1893 void main_python_exit(void)
1894 {
1895         WM_exit_ext((bContext *)evil_C, true);
1896         evil_C = NULL;
1897 }
1898 #endif
1899
1900 static void mem_error_cb(const char *errorStr)
1901 {
1902         fputs(errorStr, stderr);
1903         fflush(stderr);
1904 }
1905
1906 static void setCallbacks(void)
1907 {
1908         /* Error output from the alloc routines: */
1909         MEM_set_error_callback(mem_error_cb);
1910 }