Merged changes in the trunk up to revision 32684.
[blender.git] / source / creator / creator.c
1 /*
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  *
20  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21  * All rights reserved.
22  *
23  * The Original Code is: all of this file.
24  *
25  * Contributor(s): none yet.
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  */
29
30 #if defined(__linux__) && defined(__GNUC__)
31 #define _GNU_SOURCE
32 #include <fenv.h>
33 #endif
34
35 #define OSX_SSE_FPE (defined(__APPLE__) && (defined(__i386__) || defined(__x86_64__)))
36
37 #if OSX_SSE_FPE
38 #include <xmmintrin.h>
39 #endif
40
41 #include <stdlib.h>
42 #include <string.h>
43
44 /* for setuid / getuid */
45 #ifdef __sgi
46 #include <sys/types.h>
47 #include <unistd.h>
48 #endif
49
50 /* This little block needed for linking to Blender... */
51
52 #include "MEM_guardedalloc.h"
53
54 #ifdef WIN32
55 #include "BLI_winstuff.h"
56 #endif
57
58 #include "BLI_args.h"
59 #include "BLI_threads.h"
60
61 #include "GEN_messaging.h"
62
63 #include "DNA_ID.h"
64 #include "DNA_scene_types.h"
65
66 #include "BLI_blenlib.h"
67
68 #include "BKE_utildefines.h"
69 #include "BKE_blender.h"
70 #include "BKE_context.h"
71 #include "BKE_font.h"
72 #include "BKE_global.h"
73 #include "BKE_main.h"
74 #include "BKE_material.h"
75 #include "BKE_packedFile.h"
76 #include "BKE_scene.h"
77 #include "BKE_node.h"
78 #include "BKE_report.h"
79 #include "BKE_sound.h"
80
81 #include "IMB_imbuf.h"  // for IMB_init
82
83 #ifndef DISABLE_PYTHON
84 #include "BPY_extern.h"
85 #endif
86
87 #include "RE_pipeline.h"
88
89 //XXX #include "playanim_ext.h"
90 #include "ED_datafiles.h"
91
92 #include "WM_api.h"
93
94 #include "RNA_define.h"
95
96 #include "GPU_draw.h"
97 #include "GPU_extensions.h"
98
99 #include "FRS_freestyle.h"
100
101 /* for passing information between creator and gameengine */
102 #include "SYS_System.h"
103
104 #include <signal.h>
105
106 #ifdef __FreeBSD__
107 # include <sys/types.h>
108 # include <floatingpoint.h>
109 # include <sys/rtprio.h>
110 #endif
111
112 #ifdef WITH_BINRELOC
113 #include "binreloc.h"
114 #endif
115
116 // from buildinfo.c
117 #ifdef BUILD_DATE
118 extern char build_date[];
119 extern char build_time[];
120 extern char build_rev[];
121 extern char build_platform[];
122 extern char build_type[];
123 extern char build_cflags[];
124 extern char build_cxxflags[];
125 extern char build_linkflags[];
126 extern char build_system[];
127 #endif
128
129 /*      Local Function prototypes */
130 static int print_help(int argc, char **argv, void *data);
131 static int print_version(int argc, char **argv, void *data);
132
133 /* for the callbacks: */
134
135 extern int pluginapi_force_ref(void);  /* from blenpluginapi:pluginapi.c */
136
137 char bprogname[FILE_MAXDIR+FILE_MAXFILE]; /* from blenpluginapi:pluginapi.c */
138 char btempdir[FILE_MAXDIR+FILE_MAXFILE];
139
140 #define BLEND_VERSION_STRING_FMT "Blender %d.%02d (sub %d) Build\n", BLENDER_VERSION/100, BLENDER_VERSION%100, BLENDER_SUBVERSION
141
142 /* Initialise callbacks for the modules that need them */
143 static void setCallbacks(void); 
144
145 /* set breakpoints here when running in debug mode, useful to catch floating point errors */
146 #if defined(__sgi) || defined(__linux__) || defined(_WIN32) || OSX_SSE_FPE
147 static void fpe_handler(int UNUSED(sig))
148 {
149         // printf("SIGFPE trapped\n");
150 }
151 #endif
152
153 /* handling ctrl-c event in console */
154 static void blender_esc(int sig)
155 {
156         static int count = 0;
157         
158         G.afbreek = 1;  /* forces render loop to read queue, not sure if its needed */
159         
160         if (sig == 2) {
161                 if (count) {
162                         printf("\nBlender killed\n");
163                         exit(2);
164                 }
165                 printf("\nSent an internal break event. Press ^C again to kill Blender\n");
166                 count++;
167         }
168 }
169
170 /* buildinfo can have quotes */
171 #ifdef BUILD_DATE
172 static void strip_quotes(char *str)
173 {
174     if(str[0] == '"') {
175         int len= strlen(str) - 1;
176         memmove(str, str+1, len);
177         if(str[len-1] == '"') {
178             str[len-1]= '\0';
179         }
180     }
181 }
182 #endif
183
184 static int print_version(int UNUSED(argc), char **UNUSED(argv), void *UNUSED(data))
185 {
186         printf (BLEND_VERSION_STRING_FMT);
187 #ifdef BUILD_DATE
188         printf ("\tbuild date: %s\n", build_date);
189         printf ("\tbuild time: %s\n", build_time);
190         printf ("\tbuild revision: %s\n", build_rev);
191         printf ("\tbuild platform: %s\n", build_platform);
192         printf ("\tbuild type: %s\n", build_type);
193         printf ("\tbuild c flags: %s\n", build_cflags);
194         printf ("\tbuild c++ flags: %s\n", build_cxxflags);
195         printf ("\tbuild link flags: %s\n", build_linkflags);
196         printf ("\tbuild system: %s\n", build_system);
197 #endif
198         exit(0);
199
200         return 0;
201 }
202
203 static int print_help(int UNUSED(argc), char **UNUSED(argv), void *data)
204 {
205         bArgs *ba = (bArgs*)data;
206
207         printf (BLEND_VERSION_STRING_FMT);
208         printf ("Usage: blender [args ...] [file] [args ...]\n\n");
209
210         printf ("Render Options:\n");
211         BLI_argsPrintArgDoc(ba, "--background");
212         BLI_argsPrintArgDoc(ba, "--render-anim");
213         BLI_argsPrintArgDoc(ba, "--scene");
214         BLI_argsPrintArgDoc(ba, "--render-frame");
215         BLI_argsPrintArgDoc(ba, "--frame-start");
216         BLI_argsPrintArgDoc(ba, "--frame-end");
217         BLI_argsPrintArgDoc(ba, "--frame-jump");
218         BLI_argsPrintArgDoc(ba, "--render-output");
219         BLI_argsPrintArgDoc(ba, "--engine");
220         
221         printf("\n");
222         printf ("Format Options:\n");
223         BLI_argsPrintArgDoc(ba, "--render-format");
224         BLI_argsPrintArgDoc(ba, "--use-extension");
225         BLI_argsPrintArgDoc(ba, "--threads");
226
227         printf("\n");
228         printf ("Animation Playback Options:\n");
229         BLI_argsPrintArgDoc(ba, "-a");
230                                 
231         printf("\n");
232         printf ("Window Options:\n");
233         BLI_argsPrintArgDoc(ba, "--window-border");
234         BLI_argsPrintArgDoc(ba, "--window-borderless");
235         BLI_argsPrintArgDoc(ba, "--window-geometry");
236
237         printf("\n");
238         printf ("Game Engine Specific Options:\n");
239         BLI_argsPrintArgDoc(ba, "-g");
240
241         printf("\n");
242         printf ("Misc Options:\n");
243         BLI_argsPrintArgDoc(ba, "--debug");
244         BLI_argsPrintArgDoc(ba, "--debug-fpe");
245
246         printf("\n");
247
248         BLI_argsPrintArgDoc(ba, "-nojoystick");
249         BLI_argsPrintArgDoc(ba, "-noglsl");
250         BLI_argsPrintArgDoc(ba, "-noaudio");
251         BLI_argsPrintArgDoc(ba, "-setaudio");
252
253         printf("\n");
254
255         BLI_argsPrintArgDoc(ba, "--help");
256
257         printf("\n");
258
259         BLI_argsPrintArgDoc(ba, "--enable-autoexec");
260         BLI_argsPrintArgDoc(ba, "--disable-autoexec");
261
262         printf("\n");
263
264         BLI_argsPrintArgDoc(ba, "--python");
265         BLI_argsPrintArgDoc(ba, "--python-console");
266
267 #ifdef WIN32
268         BLI_argsPrintArgDoc(ba, "-R");
269 #endif
270         BLI_argsPrintArgDoc(ba, "--version");
271
272         BLI_argsPrintArgDoc(ba, "--");
273
274         printf ("Other Options:\n");
275         BLI_argsPrintOtherDoc(ba);
276
277         printf ("Argument Parsing:\n");
278         printf ("\targuments must be separated by white space. eg\n");
279         printf ("\t\t\"blender -ba test.blend\"\n");
280         printf ("\t...will ignore the 'a'\n");
281         printf ("\t\t\"blender -b test.blend -f8\"\n");
282         printf ("\t...will ignore 8 because there is no space between the -f and the frame value\n\n");
283
284         printf ("Argument Order:\n");
285         printf ("Arguments are executed in the order they are given. eg\n");
286         printf ("\t\t\"blender --background test.blend --render-frame 1 --render-output /tmp\"\n");
287         printf ("\t...will not render to /tmp because '--render-frame 1' renders before the output path is set\n");
288         printf ("\t\t\"blender --background --render-output /tmp test.blend --render-frame 1\"\n");
289         printf ("\t...will not render to /tmp because loading the blend file overwrites the render output that was set\n");
290         printf ("\t\t\"blender --background test.blend --render-output /tmp --render-frame 1\" works as expected.\n\n");
291
292         printf ("\nEnvironment Variables:\n");
293         printf ("  $BLENDER_USER_CONFIG      Directory for user configuration files.\n");
294         printf ("  $BLENDER_SYSTEM_CONFIG    Directory for system wide configuration files.\n");
295         printf ("  $BLENDER_USER_SCRIPTS     Directory for user scripts.\n");
296         printf ("  $BLENDER_SYSTEM_SCRIPTS   Directory for system wide scripts.\n");
297         printf ("  $BLENDER_USER_DATAFILES   Directory for user data files (icons, translations, ..).\n");
298         printf ("  $BLENDER_SYSTEM_DATAFILES Directory for system wide data files.\n");
299         printf ("  $BLENDER_SYSTEM_PYTHON    Directory for system python libraries.\n");
300 #ifdef WIN32
301         printf ("  $TEMP                     Store temporary files here.\n");
302 #else
303         printf ("  $TMP or $TMPDIR           Store temporary files here.\n");
304 #endif
305 #ifndef DISABLE_SDL
306         printf ("  $SDL_AUDIODRIVER          LibSDL audio driver - alsa, esd, dma.\n");
307 #endif
308         printf ("  $PYTHONHOME               Path to the python directory, eg. /usr/lib/python.\n\n");
309
310         exit(0);
311
312         return 0;
313 }
314
315
316 double PIL_check_seconds_timer(void);
317
318 /* XXX This was here to fix a crash when running python scripts
319  * with -P that used the screen.
320  *
321  * static void main_init_screen( void )
322 {
323         setscreen(G.curscreen);
324         
325         if(G.main->scene.first==0) {
326                 set_scene( add_scene("1") );
327         }
328 }*/
329
330 static int end_arguments(int UNUSED(argc), char **UNUSED(argv), void *UNUSED(data))
331 {
332         return -1;
333 }
334
335 static int enable_python(int UNUSED(argc), char **UNUSED(argv), void *UNUSED(data))
336 {
337         G.f |= G_SCRIPT_AUTOEXEC;
338         return 0;
339 }
340
341 static int disable_python(int UNUSED(argc), char **UNUSED(argv), void *UNUSED(data))
342 {
343         G.f &= ~G_SCRIPT_AUTOEXEC;
344         return 0;
345 }
346
347 static int background_mode(int UNUSED(argc), char **UNUSED(argv), void *UNUSED(data))
348 {
349         G.background = 1;
350         return 0;
351 }
352
353 static int debug_mode(int UNUSED(argc), char **UNUSED(argv), void *data)
354 {
355         G.f |= G_DEBUG;         /* std output printf's */
356         printf(BLEND_VERSION_STRING_FMT);
357         MEM_set_memory_debug();
358
359 #ifdef NAN_BUILDINFO
360         printf("Build: %s %s %s %s\n", build_date, build_time, build_platform, build_type);
361 #endif // NAN_BUILDINFO
362
363         BLI_argsPrint(data);
364         return 0;
365 }
366
367 static int set_fpe(int UNUSED(argc), char **UNUSED(argv), void *UNUSED(data))
368 {
369 #if defined(__sgi) || defined(__linux__) || defined(_WIN32) || OSX_SSE_FPE
370         /* zealous but makes float issues a heck of a lot easier to find!
371          * set breakpoints on fpe_handler */
372         signal(SIGFPE, fpe_handler);
373
374 # if defined(__linux__) && defined(__GNUC__)
375         feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW );
376 # endif /* defined(__linux__) && defined(__GNUC__) */
377 # if OSX_SSE_FPE
378         /* OSX uses SSE for floating point by default, so here 
379          * use SSE instructions to throw floating point exceptions */
380         _MM_SET_EXCEPTION_MASK(_MM_MASK_MASK &~
381                                                    (_MM_MASK_OVERFLOW|_MM_MASK_INVALID|_MM_MASK_DIV_ZERO));
382 # endif /* OSX_SSE_FPE */
383 # if defined(_WIN32) && defined(_MSC_VER)
384         _controlfp_s(NULL, 0, _MCW_EM); /* enables all fp exceptions */
385         _controlfp_s(NULL, _EM_DENORMAL | _EM_UNDERFLOW | _EM_INEXACT, _MCW_EM); /* hide the ones we don't care about */
386 # endif /* _WIN32 && _MSC_VER */
387 #endif
388
389         return 0;
390 }
391
392 static int playback_mode(int UNUSED(argc), char **UNUSED(argv), void *UNUSED(data))
393 {
394         /* not if -b was given first */
395         if (G.background == 0) {
396
397 // XXX                          playanim(argc, argv); /* not the same argc and argv as before */
398                 exit(0);
399         }
400
401         return -2;
402 }
403
404 static int prefsize(int argc, char **argv, void *UNUSED(data))
405 {
406         int stax, stay, sizx, sizy;
407
408         if (argc < 5) {
409                 printf ("-p requires four arguments\n");
410                 exit(1);
411         }
412
413         stax= atoi(argv[1]);
414         stay= atoi(argv[2]);
415         sizx= atoi(argv[3]);
416         sizy= atoi(argv[4]);
417
418         WM_setprefsize(stax, stay, sizx, sizy);
419
420         return 4;
421 }
422
423 static int with_borders(int UNUSED(argc), char **UNUSED(argv), void *UNUSED(data))
424 {
425         WM_setinitialstate_normal();
426         return 0;
427 }
428
429 static int without_borders(int UNUSED(argc), char **UNUSED(argv), void *UNUSED(data))
430 {
431         WM_setinitialstate_fullscreen();
432         return 0;
433 }
434
435 static int register_extension(int UNUSED(argc), char **UNUSED(argv), void *data)
436 {
437 #ifdef WIN32
438         char *path = BLI_argsArgv(data)[0];
439         RegisterBlendExtension(path);
440 #else
441         (void)data; /* unused */
442 #endif
443
444         return 0;
445 }
446
447 static int no_joystick(int UNUSED(argc), char **UNUSED(argv), void *data)
448 {
449         SYS_SystemHandle *syshandle = data;
450
451         /**
452                 don't initialize joysticks if user doesn't want to use joysticks
453                 failed joystick initialization delays over 5 seconds, before game engine start
454         */
455         SYS_WriteCommandLineInt(*syshandle, "nojoystick",1);
456         if (G.f & G_DEBUG) printf("disabling nojoystick\n");
457
458         return 0;
459 }
460
461 static int no_glsl(int UNUSED(argc), char **UNUSED(argv), void *UNUSED(data))
462 {
463         GPU_extensions_disable();
464         return 0;
465 }
466
467 static int no_audio(int UNUSED(argc), char **UNUSED(argv), void *UNUSED(data))
468 {
469         sound_force_device(0);
470         return 0;
471 }
472
473 static int set_audio(int argc, char **argv, void *UNUSED(data))
474 {
475         if (argc < 1) {
476                 printf("-setaudio require one argument\n");
477                 exit(1);
478         }
479
480         sound_force_device(sound_define_from_str(argv[1]));
481         return 1;
482 }
483
484 static int set_output(int argc, char **argv, void *data)
485 {
486         bContext *C = data;
487         if (argc >= 1){
488                 if (CTX_data_scene(C)) {
489                         Scene *scene= CTX_data_scene(C);
490                         BLI_strncpy(scene->r.pic, argv[1], FILE_MAXDIR);
491                 } else {
492                         printf("\nError: no blend loaded. cannot use '-o / --render-output'.\n");
493                 }
494                 return 1;
495         } else {
496                 printf("\nError: you must specify a path after '-o  / --render-output'.\n");
497                 return 0;
498         }
499 }
500
501 static int set_engine(int argc, char **argv, void *data)
502 {
503         bContext *C = data;
504         if (argc >= 1)
505         {
506                 if (!strcmp(argv[1],"help"))
507                 {
508                         RenderEngineType *type = NULL;
509
510                         for( type = R_engines.first; type; type = type->next )
511                         {
512                                 printf("\t%s\n", type->idname);
513                         }
514                         exit(0);
515                 }
516                 else
517                 {
518                         if (CTX_data_scene(C)==NULL)
519                         {
520                                 printf("\nError: no blend loaded. order the arguments so '-E  / --engine ' is after a blend is loaded.\n");
521                         }
522                         else
523                         {
524                                 Scene *scene= CTX_data_scene(C);
525                                 RenderData *rd = &scene->r;
526                                 RenderEngineType *type = NULL;
527
528                                 for( type = R_engines.first; type; type = type->next )
529                                 {
530                                         if (!strcmp(argv[1],type->idname))
531                                         {
532                                                 BLI_strncpy(rd->engine, type->idname, sizeof(rd->engine));
533                                         }
534                                 }
535                         }
536                 }
537
538                 return 1;
539         }
540         else
541         {
542                 printf("\nEngine not specified.\n");
543                 return 0;
544         }
545 }
546
547 static int set_image_type(int argc, char **argv, void *data)
548 {
549         bContext *C = data;
550         if (argc >= 1){
551                 char *imtype = argv[1];
552                 if (CTX_data_scene(C)==NULL) {
553                         printf("\nError: no blend loaded. order the arguments so '-F  / --render-format' is after the blend is loaded.\n");
554                 } else {
555                         Scene *scene= CTX_data_scene(C);
556                         if      (!strcmp(imtype,"TGA")) scene->r.imtype = R_TARGA;
557                         else if (!strcmp(imtype,"IRIS")) scene->r.imtype = R_IRIS;
558 #ifdef WITH_DDS
559                         else if (!strcmp(imtype,"DDS")) scene->r.imtype = R_DDS;
560 #endif
561                         else if (!strcmp(imtype,"JPEG")) scene->r.imtype = R_JPEG90;
562                         else if (!strcmp(imtype,"IRIZ")) scene->r.imtype = R_IRIZ;
563                         else if (!strcmp(imtype,"RAWTGA")) scene->r.imtype = R_RAWTGA;
564                         else if (!strcmp(imtype,"AVIRAW")) scene->r.imtype = R_AVIRAW;
565                         else if (!strcmp(imtype,"AVIJPEG")) scene->r.imtype = R_AVIJPEG;
566                         else if (!strcmp(imtype,"PNG")) scene->r.imtype = R_PNG;
567                         else if (!strcmp(imtype,"AVICODEC")) scene->r.imtype = R_AVICODEC;
568                         else if (!strcmp(imtype,"QUICKTIME")) scene->r.imtype = R_QUICKTIME;
569                         else if (!strcmp(imtype,"BMP")) scene->r.imtype = R_BMP;
570 #ifdef WITH_HDR
571                         else if (!strcmp(imtype,"HDR")) scene->r.imtype = R_RADHDR;
572 #endif
573 #ifdef WITH_TIFF
574                         else if (!strcmp(imtype,"TIFF")) scene->r.imtype = R_TIFF;
575 #endif
576 #ifdef WITH_OPENEXR
577                         else if (!strcmp(imtype,"EXR")) scene->r.imtype = R_OPENEXR;
578                         else if (!strcmp(imtype,"MULTILAYER")) scene->r.imtype = R_MULTILAYER;
579 #endif
580                         else if (!strcmp(imtype,"MPEG")) scene->r.imtype = R_FFMPEG;
581                         else if (!strcmp(imtype,"FRAMESERVER")) scene->r.imtype = R_FRAMESERVER;
582 #ifdef WITH_CINEON
583                         else if (!strcmp(imtype,"CINEON")) scene->r.imtype = R_CINEON;
584                         else if (!strcmp(imtype,"DPX")) scene->r.imtype = R_DPX;
585 #endif
586 #if WITH_OPENJPEG
587                         else if (!strcmp(imtype,"JP2")) scene->r.imtype = R_JP2;
588 #endif
589                         else printf("\nError: Format from '-F / --render-format' not known or not compiled in this release.\n");
590                 }
591                 return 1;
592         } else {
593                 printf("\nError: you must specify a format after '-F  / --render-foramt'.\n");
594                 return 0;
595         }
596 }
597
598 static int set_threads(int argc, char **argv, void *UNUSED(data))
599 {
600         if (argc >= 1) {
601                 if(G.background) {
602                         RE_set_max_threads(atoi(argv[1]));
603                 } else {
604                         printf("Warning: threads can only be set in background mode\n");
605                 }
606                 return 1;
607         } else {
608                 printf("\nError: you must specify a number of threads between 0 and 8 '-t  / --threads'.\n");
609                 return 0;
610         }
611 }
612
613 static int set_extension(int argc, char **argv, void *data)
614 {
615         bContext *C = data;
616         if (argc >= 1) {
617                 if (CTX_data_scene(C)) {
618                         Scene *scene= CTX_data_scene(C);
619                         if (argv[1][0] == '0') {
620                                 scene->r.scemode &= ~R_EXTENSION;
621                         } else if (argv[1][0] == '1') {
622                                 scene->r.scemode |= R_EXTENSION;
623                         } else {
624                                 printf("\nError: Use '-x 1 / -x 0' To set the extension option or '--use-extension'\n");
625                         }
626                 } else {
627                         printf("\nError: no blend loaded. order the arguments so '-o ' is after '-x '.\n");
628                 }
629                 return 1;
630         } else {
631                 printf("\nError: you must specify a path after '- '.\n");
632                 return 0;
633         }
634 }
635
636 static int set_ge_parameters(int argc, char **argv, void *data)
637 {
638         SYS_SystemHandle syshandle = *(SYS_SystemHandle*)data;
639         int a = 0;
640 /**
641 gameengine parameters are automaticly put into system
642 -g [paramname = value]
643 -g [boolparamname]
644 example:
645 -g novertexarrays
646 -g maxvertexarraysize = 512
647 */
648
649         if(argc >= 1)
650         {
651                 char* paramname = argv[a];
652                 /* check for single value versus assignment */
653                 if (a+1 < argc && (*(argv[a+1]) == '='))
654                 {
655                         a++;
656                         if (a+1 < argc)
657                         {
658                                 a++;
659                                 /* assignment */
660                                 SYS_WriteCommandLineString(syshandle,paramname,argv[a]);
661                         }  else
662                         {
663                                 printf("error: argument assignment (%s) without value.\n",paramname);
664                                 return 0;
665                         }
666                         /* name arg eaten */
667
668                 } else {
669                         SYS_WriteCommandLineInt(syshandle,argv[a],1);
670
671                         /* doMipMap */
672                         if (!strcmp(argv[a],"nomipmap"))
673                         {
674                                 GPU_set_mipmap(0); //doMipMap = 0;
675                         }
676                         /* linearMipMap */
677                         if (!strcmp(argv[a],"linearmipmap"))
678                         {
679                                 GPU_set_linear_mipmap(1); //linearMipMap = 1;
680                         }
681
682
683                 } /* if (*(argv[a+1]) == '=') */
684         }
685
686         return a;
687 }
688
689 static int render_frame(int argc, char **argv, void *data)
690 {
691         bContext *C = data;
692         if (CTX_data_scene(C)) {
693                 Main *bmain= CTX_data_main(C);
694                 Scene *scene= CTX_data_scene(C);
695
696                 if (argc > 1) {
697                         Render *re = RE_NewRender(scene->id.name);
698                         int frame;
699                         ReportList reports;
700
701                         switch(*argv[1]) {
702                         case '+':
703                                 frame= scene->r.sfra + atoi(argv[1]+1);
704                                 break;
705                         case '-':
706                                 frame= (scene->r.efra - atoi(argv[1]+1)) + 1;
707                                 break;
708                         default:
709                                 frame= atoi(argv[1]);
710                                 break;
711                         }
712
713                         BKE_reports_init(&reports, RPT_PRINT);
714
715                         frame = MIN2(MAXFRAME, MAX2(MINAFRAME, frame));
716
717                         RE_BlenderAnim(re, bmain, scene, scene->lay, frame, frame, scene->r.frame_step, &reports);
718                         return 1;
719                 } else {
720                         printf("\nError: frame number must follow '-f / --render-frame'.\n");
721                         return 0;
722                 }
723         } else {
724                 printf("\nError: no blend loaded. cannot use '-f / --render-frame'.\n");
725                 return 0;
726         }
727 }
728
729 static int render_animation(int UNUSED(argc), char **UNUSED(argv), void *data)
730 {
731         bContext *C = data;
732         if (CTX_data_scene(C)) {
733                 Main *bmain= CTX_data_main(C);
734                 Scene *scene= CTX_data_scene(C);
735                 Render *re= RE_NewRender(scene->id.name);
736                 ReportList reports;
737                 BKE_reports_init(&reports, RPT_PRINT);
738                 RE_BlenderAnim(re, bmain, scene, scene->lay, scene->r.sfra, scene->r.efra, scene->r.frame_step, &reports);
739         } else {
740                 printf("\nError: no blend loaded. cannot use '-a'.\n");
741         }
742         return 0;
743 }
744
745 static int set_scene(int argc, char **argv, void *data)
746 {
747         if(argc > 1) {
748                 bContext *C= data;
749                 Scene *sce= set_scene_name(CTX_data_main(C), argv[1]);
750                 if(sce) {
751                         CTX_data_scene_set(C, sce);
752                 }
753                 return 1;
754         } else {
755                 printf("\nError: Scene name must follow '-S / --scene'.\n");
756                 return 0;
757         }
758 }
759
760 static int set_start_frame(int argc, char **argv, void *data)
761 {
762         bContext *C = data;
763         if (CTX_data_scene(C)) {
764                 Scene *scene= CTX_data_scene(C);
765                 if (argc > 1) {
766                         int frame = atoi(argv[1]);
767                         (scene->r.sfra) = CLAMPIS(frame, MINFRAME, MAXFRAME);
768                         return 1;
769                 } else {
770                         printf("\nError: frame number must follow '-s / --frame-start'.\n");
771                         return 0;
772                 }
773         } else {
774                 printf("\nError: no blend loaded. cannot use '-s / --frame-start'.\n");
775                 return 0;
776         }
777 }
778
779 static int set_end_frame(int argc, char **argv, void *data)
780 {
781         bContext *C = data;
782         if (CTX_data_scene(C)) {
783                 Scene *scene= CTX_data_scene(C);
784                 if (argc > 1) {
785                         int frame = atoi(argv[1]);
786                         (scene->r.efra) = CLAMPIS(frame, MINFRAME, MAXFRAME);
787                         return 1;
788                 } else {
789                         printf("\nError: frame number must follow '-e / --frame-end'.\n");
790                         return 0;
791                 }
792         } else {
793                 printf("\nError: no blend loaded. cannot use '-e / --frame-end'.\n");
794                 return 0;
795         }
796 }
797
798 static int set_skip_frame(int argc, char **argv, void *data)
799 {
800         bContext *C = data;
801         if (CTX_data_scene(C)) {
802                 Scene *scene= CTX_data_scene(C);
803                 if (argc > 1) {
804                         int frame = atoi(argv[1]);
805                         (scene->r.frame_step) = CLAMPIS(frame, 1, MAXFRAME);
806                         return 1;
807                 } else {
808                         printf("\nError: number of frames to step must follow '-j / --frame-jump'.\n");
809                         return 0;
810                 }
811         } else {
812                 printf("\nError: no blend loaded. cannot use '-j / --frame-jump'.\n");
813                 return 0;
814         }
815 }
816
817 /* macro for ugly context setup/reset */
818 #ifndef DISABLE_PYTHON
819 #define BPY_CTX_SETUP(_cmd) \
820 { \
821         wmWindowManager *wm= CTX_wm_manager(C); \
822         wmWindow *prevwin= CTX_wm_window(C); \
823         Scene *prevscene= CTX_data_scene(C); \
824         if(wm->windows.first) { \
825                 CTX_wm_window_set(C, wm->windows.first); \
826                 _cmd; \
827                 CTX_wm_window_set(C, prevwin); \
828         } \
829         else { \
830                 fprintf(stderr, "Python script \"%s\" running with missing context data.\n", argv[1]); \
831                 _cmd; \
832         } \
833         CTX_data_scene_set(C, prevscene); \
834 } \
835
836 #endif /* DISABLE_PYTHON */
837
838 static int run_python(int argc, char **argv, void *data)
839 {
840 #ifndef DISABLE_PYTHON
841         bContext *C = data;
842
843         /* workaround for scripts not getting a bpy.context.scene, causes internal errors elsewhere */
844         if (argc > 1) {
845                 /* Make the path absolute because its needed for relative linked blends to be found */
846                 char filename[FILE_MAXDIR + FILE_MAXFILE];
847                 BLI_strncpy(filename, argv[1], sizeof(filename));
848                 BLI_path_cwd(filename);
849
850                 BPY_CTX_SETUP( BPY_run_python_script(C, filename, NULL, NULL) )
851
852                 return 1;
853         } else {
854                 printf("\nError: you must specify a Python script after '-P / --python'.\n");
855                 return 0;
856         }
857 #else
858         (void)argc; (void)argv; (void)data; /* unused */
859         printf("This blender was built without python support\n");
860         return 0;
861 #endif /* DISABLE_PYTHON */
862 }
863
864 static int run_python_console(int UNUSED(argc), char **argv, void *data)
865 {
866 #ifndef DISABLE_PYTHON
867         bContext *C = data;     
868         const char *expr= "__import__('code').interact()";
869
870         BPY_CTX_SETUP( BPY_eval_string(C, expr) )
871
872         return 0;
873 #else
874         (void)argv; (void)data; /* unused */
875         printf("This blender was built without python support\n");
876         return 0;
877 #endif /* DISABLE_PYTHON */
878 }
879
880 static int load_file(int UNUSED(argc), char **argv, void *data)
881 {
882         bContext *C = data;
883
884         /* Make the path absolute because its needed for relative linked blends to be found */
885         char filename[FILE_MAXDIR + FILE_MAXFILE];
886         BLI_strncpy(filename, argv[0], sizeof(filename));
887         BLI_path_cwd(filename);
888
889         if (G.background) {
890                 int retval = BKE_read_file(C, filename, NULL);
891
892                 /*we successfully loaded a blend file, get sure that
893                 pointcache works */
894                 if (retval!=0) {
895                         wmWindowManager *wm= CTX_wm_manager(C);
896                         CTX_wm_manager_set(C, NULL); /* remove wm to force check */
897                         WM_check(C);
898                         G.relbase_valid = 1;
899                         if (CTX_wm_manager(C) == NULL) CTX_wm_manager_set(C, wm); /* reset wm */
900                 }
901
902                 /* WM_read_file() runs normally but since we're in background mode do here */
903 #ifndef DISABLE_PYTHON
904                 /* run any texts that were loaded in and flagged as modules */
905                 BPY_load_user_modules(C);
906 #endif
907
908                 /* happens for the UI on file reading too (huh? (ton))*/
909         // XXX                  BKE_reset_undo();
910         //                              BKE_write_undo("original");     /* save current state */
911         } else {
912                 /* we are not running in background mode here, but start blender in UI mode with
913                    a file - this should do everything a 'load file' does */
914                 ReportList reports;
915                 BKE_reports_init(&reports, RPT_PRINT);
916                 WM_read_file(C, filename, &reports);
917                 BKE_reports_clear(&reports);
918         }
919
920         G.file_loaded = 1;
921
922         return 0;
923 }
924
925 void setupArguments(bContext *C, bArgs *ba, SYS_SystemHandle *syshandle)
926 {
927         static char output_doc[] = "<path>"
928                 "\n\tSet the render path and file name."
929                 "\n\tUse // at the start of the path to"
930                 "\n\t\trender relative to the blend file."
931                 "\n\tThe # characters are replaced by the frame number, and used to define zero padding."
932                 "\n\t\tani_##_test.png becomes ani_01_test.png"
933                 "\n\t\ttest-######.png becomes test-000001.png"
934                 "\n\t\tWhen the filename does not contain #, The suffix #### is added to the filename"
935                 "\n\tThe frame number will be added at the end of the filename."
936                 "\n\t\teg: blender -b foobar.blend -o //render_ -F PNG -x 1 -a"
937                 "\n\t\t//render_ becomes //render_####, writing frames as //render_0001.png//";
938
939         static char format_doc[] = "<format>"
940                 "\n\tSet the render format, Valid options are..."
941                 "\n\t\tTGA IRIS JPEG MOVIE IRIZ RAWTGA"
942                 "\n\t\tAVIRAW AVIJPEG PNG BMP FRAMESERVER"
943                 "\n\t(formats that can be compiled into blender, not available on all systems)"
944                 "\n\t\tHDR TIFF EXR MULTILAYER MPEG AVICODEC QUICKTIME CINEON DPX DDS";
945
946         static char playback_doc[] = "<options> <file(s)>"
947                 "\n\tPlayback <file(s)>, only operates this way when not running in background."
948                 "\n\t\t-p <sx> <sy>\tOpen with lower left corner at <sx>, <sy>"
949                 "\n\t\t-m\t\tRead from disk (Don't buffer)"
950                 "\n\t\t-f <fps> <fps-base>\t\tSpecify FPS to start with"
951                 "\n\t\t-j <frame>\tSet frame step to <frame>";
952
953         static char game_doc[] = "Game Engine specific options"
954                 "\n\t-g fixedtime\t\tRun on 50 hertz without dropping frames"
955                 "\n\t-g vertexarrays\tUse Vertex Arrays for rendering (usually faster)"
956                 "\n\t-g nomipmap\t\tNo Texture Mipmapping"
957                 "\n\t-g linearmipmap\tLinear Texture Mipmapping instead of Nearest (default)";
958
959         static char debug_doc[] = "\n\tTurn debugging on\n"
960                 "\n\t* Prints every operator call and their arguments"
961                 "\n\t* Disables mouse grab (to interact with a debugger in some cases)"
962                 "\n\t* Keeps python sys.stdin rather then setting it to None";
963
964         //BLI_argsAdd(ba, pass, short_arg, long_arg, doc, cb, C);
965
966         /* end argument processing after -- */
967         BLI_argsAdd(ba, -1, "--", NULL, "\n\tEnds option processing, following arguments passed unchanged. Access via python's sys.argv", end_arguments, NULL);
968
969         /* first pass: background mode, disable python and commands that exit after usage */
970         BLI_argsAdd(ba, 1, "-h", "--help", "\n\tPrint this help text and exit", print_help, ba);
971         /* Windows only */
972         BLI_argsAdd(ba, 1, "/?", NULL, "\n\tPrint this help text and exit (windows only)", print_help, ba);
973
974         BLI_argsAdd(ba, 1, "-v", "--version", "\n\tPrint Blender version and exit", print_version, NULL);
975
976         BLI_argsAdd(ba, 1, "-y", "--enable-autoexec", "\n\tEnable automatic python script execution (default)", enable_python, NULL);
977         BLI_argsAdd(ba, 1, "-Y", "--disable-autoexec", "\n\tDisable automatic python script execution (pydrivers, pyconstraints, pynodes)", disable_python, NULL);
978
979         BLI_argsAdd(ba, 1, "-b", "--background", "<file>\n\tLoad <file> in background (often used for UI-less rendering)", background_mode, NULL);
980
981         BLI_argsAdd(ba, 1, "-a", NULL, playback_doc, playback_mode, NULL);
982
983         BLI_argsAdd(ba, 1, "-d", "--debug", debug_doc, debug_mode, ba);
984     BLI_argsAdd(ba, 1, NULL, "--debug-fpe", "\n\tEnable floating point exceptions", set_fpe, NULL);
985
986         /* second pass: custom window stuff */
987         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);
988         BLI_argsAdd(ba, 2, "-w", "--window-border", "\n\tForce opening with borders (default)", with_borders, NULL);
989         BLI_argsAdd(ba, 2, "-W", "--window-borderless", "\n\tForce opening with without borders", without_borders, NULL);
990         BLI_argsAdd(ba, 2, "-R", NULL, "\n\tRegister .blend extension (windows only)", register_extension, ba);
991
992         /* third pass: disabling things and forcing settings */
993         BLI_argsAddCase(ba, 3, "-nojoystick", 1, NULL, 0, "\n\tDisable joystick support", no_joystick, syshandle);
994         BLI_argsAddCase(ba, 3, "-noglsl", 1, NULL, 0, "\n\tDisable GLSL shading", no_glsl, NULL);
995         BLI_argsAddCase(ba, 3, "-noaudio", 1, NULL, 0, "\n\tForce sound system to None", no_audio, NULL);
996         BLI_argsAddCase(ba, 3, "-setaudio", 1, NULL, 0, "\n\tForce sound system to a specific device\n\tNULL SDL OPENAL JACK", set_audio, NULL);
997
998         /* fourth pass: processing arguments */
999         BLI_argsAdd(ba, 4, "-g", NULL, game_doc, set_ge_parameters, syshandle);
1000         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);
1001         BLI_argsAdd(ba, 4, "-a", "--render-anim", "\n\tRender frames from start to end (inclusive)", render_animation, C);
1002         BLI_argsAdd(ba, 4, "-S", "--scene", "<name>\n\tSet the active scene <name> for rendering", set_scene, C);
1003         BLI_argsAdd(ba, 4, "-s", "--frame-start", "<frame>\n\tSet start to frame <frame> (use before the -a argument)", set_start_frame, C);
1004         BLI_argsAdd(ba, 4, "-e", "--frame-end", "<frame>\n\tSet end to frame <frame> (use before the -a argument)", set_end_frame, C);
1005         BLI_argsAdd(ba, 4, "-j", "--frame-jump", "<frames>\n\tSet number of frames to step forward after each rendered frame", set_skip_frame, C);
1006         BLI_argsAdd(ba, 4, "-P", "--python", "<filename>\n\tRun the given Python script (filename or Blender Text)", run_python, C);
1007         BLI_argsAdd(ba, 4, NULL, "--python-console", "\n\tRun blender with an interactive console", run_python_console, C);
1008
1009         BLI_argsAdd(ba, 4, "-o", "--render-output", output_doc, set_output, C);
1010         BLI_argsAdd(ba, 4, "-E", "--engine", "<engine>\n\tSpecify the render engine\n\tuse -E help to list available engines", set_engine, C);
1011
1012         BLI_argsAdd(ba, 4, "-F", "--render-format", format_doc, set_image_type, C);
1013         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);
1014         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);
1015
1016 }
1017
1018 int main(int argc, char **argv)
1019 {
1020         SYS_SystemHandle syshandle;
1021         bContext *C= CTX_create();
1022         bArgs *ba;
1023
1024 #ifdef WITH_BINRELOC
1025         br_init( NULL );
1026 #endif
1027
1028         setCallbacks();
1029 #ifdef __APPLE__
1030                 /* patch to ignore argument finder gives us (pid?) */
1031         if (argc==2 && strncmp(argv[1], "-psn_", 5)==0) {
1032                 extern int GHOST_HACK_getFirstFile(char buf[]);
1033                 static char firstfilebuf[512];
1034
1035                 argc= 1;
1036
1037                 if (GHOST_HACK_getFirstFile(firstfilebuf)) {
1038                         argc= 2;
1039                         argv[1]= firstfilebuf;
1040                 }
1041         }
1042
1043 #endif
1044
1045 #ifdef __FreeBSD__
1046         fpsetmask(0);
1047 #endif
1048
1049         // copy path to executable in bprogname. playanim and creting runtimes
1050         // need this.
1051
1052         BLI_where_am_i(bprogname, argv[0]);
1053         
1054 #ifdef BUILD_DATE       
1055         strip_quotes(build_date);
1056         strip_quotes(build_time);
1057         strip_quotes(build_rev);
1058         strip_quotes(build_platform);
1059         strip_quotes(build_type);
1060         strip_quotes(build_cflags);
1061         strip_quotes(build_cxxflags);
1062         strip_quotes(build_linkflags);
1063         strip_quotes(build_system);
1064 #endif
1065
1066         BLI_threadapi_init();
1067
1068         RNA_init();
1069         RE_engines_init();
1070
1071                 /* Hack - force inclusion of the plugin api functions,
1072                  * see blenpluginapi:pluginapi.c
1073                  */
1074         pluginapi_force_ref();
1075
1076         init_nodesystem();
1077         
1078         initglobals();  /* blender.c */
1079
1080         IMB_init();
1081
1082         syshandle = SYS_GetSystem();
1083         GEN_init_messaging_system();
1084
1085         /* first test for background */
1086         ba = BLI_argsInit(argc, argv); /* skip binary path */
1087         setupArguments(C, ba, &syshandle);
1088
1089         BLI_argsParse(ba, 1, NULL, NULL);
1090
1091 #ifdef __sgi
1092         setuid(getuid()); /* end superuser */
1093 #endif
1094
1095
1096         /* for all platforms, even windos has it! */
1097         if(G.background) signal(SIGINT, blender_esc);   /* ctrl c out bg render */
1098         
1099         /* background render uses this font too */
1100         BKE_font_register_builtin(datatoc_Bfont, datatoc_Bfont_size);
1101
1102         /* Initialiaze ffmpeg if built in, also needed for bg mode if videos are
1103            rendered via ffmpeg */
1104         sound_init_once();
1105         
1106         init_def_material();
1107
1108         if(G.background==0) {
1109                 BLI_argsParse(ba, 2, NULL, NULL);
1110                 BLI_argsParse(ba, 3, NULL, NULL);
1111
1112                 WM_init(C, argc, argv);
1113                 
1114                 /* this is properly initialized with user defs, but this is default */
1115                 BLI_where_is_temp( btempdir, 1 ); /* call after loading the startup.blend so we can read U.tempdir */
1116
1117 #ifndef DISABLE_SDL
1118         BLI_setenv("SDL_VIDEODRIVER", "dummy");
1119 /* I think this is not necessary anymore (04-24-2010 neXyon)
1120 #ifdef __linux__
1121         // On linux the default SDL driver dma often would not play
1122         // use alsa if none is set
1123         setenv("SDL_AUDIODRIVER", "alsa", 0);
1124 #endif
1125 */
1126 #endif
1127         }
1128         else {
1129                 BLI_argsParse(ba, 3, NULL, NULL);
1130
1131                 WM_init(C, argc, argv);
1132
1133                 BLI_where_is_temp( btempdir, 0 ); /* call after loading the startup.blend so we can read U.tempdir */
1134         }
1135 #ifndef DISABLE_PYTHON
1136         /**
1137          * NOTE: the U.pythondir string is NULL until WM_init() is executed,
1138          * so we provide the BPY_ function below to append the user defined
1139          * pythondir to Python's sys.path at this point.  Simply putting
1140          * WM_init() before BPY_start_python() crashes Blender at startup.
1141          * Update: now this function also inits the bpymenus, which also depend
1142          * on U.pythondir.
1143          */
1144
1145         // TODO - U.pythondir
1146
1147 #endif
1148         
1149         CTX_py_init_set(C, 1);
1150         WM_keymap_init(C);
1151
1152         /* initialize Freestyle */
1153         FRS_initialize();
1154         FRS_set_context(C);
1155
1156         /* OK we are ready for it */
1157         BLI_argsParse(ba, 4, load_file, C);
1158
1159         BLI_argsFree(ba);
1160
1161         if(G.background) {
1162                 /* actually incorrect, but works for now (ton) */
1163                 WM_exit(C);
1164         }
1165
1166         else {
1167                 if((G.fileflags & G_FILE_AUTOPLAY) && (G.f & G_SCRIPT_AUTOEXEC))
1168                 {
1169                         if(WM_init_game(C))
1170                                 return 0;
1171                 }
1172                 else if(!G.file_loaded)
1173                         WM_init_splash(C);
1174         }
1175
1176         WM_main(C);
1177
1178
1179         /*XXX if (scr_init==0) {
1180                 main_init_screen();
1181         }
1182         
1183         screenmain();*/ /* main display loop */
1184
1185         return 0;
1186 } /* end of int main(argc,argv) */
1187
1188 static void error_cb(char *err)
1189 {
1190         
1191         printf("%s\n", err);    /* XXX do this in WM too */
1192 }
1193
1194 static void mem_error_cb(const char *errorStr)
1195 {
1196         fputs(errorStr, stderr);
1197         fflush(stderr);
1198 }
1199
1200 static void setCallbacks(void)
1201 {
1202         /* Error output from the alloc routines: */
1203         MEM_set_error_callback(mem_error_cb);
1204
1205
1206         /* BLI_blenlib: */
1207
1208         BLI_setErrorCallBack(error_cb); /* */
1209 // XXX  BLI_setInterruptCallBack(blender_test_break);
1210
1211 }