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