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