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