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