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