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