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