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