14048c70516d18d12bca6f9a2b753cadb362d645
[blender.git] / source / gameengine / GamePlayer / ghost / GPG_ghost.cpp
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 * Start up of the Blender Player on GHOST.
29 */
30
31 /** \file gameengine/GamePlayer/ghost/GPG_ghost.cpp
32  *  \ingroup player
33  */
34
35
36 #include <iostream>
37 #include <math.h>
38
39 #ifdef __linux__
40 #ifdef __alpha__
41 #include <signal.h>
42 #endif /* __alpha__ */
43 #endif /* __linux__ */
44
45 #ifdef __APPLE__
46 // Can't use Carbon right now because of double defined type ID (In Carbon.h and DNA_ID.h, sigh)
47 //#include <Carbon/Carbon.h>
48 //#include <CFBundle.h>
49 #endif // __APPLE__
50 #include "KX_KetsjiEngine.h"
51 #include "KX_PythonInit.h"
52
53 /**********************************
54 * Begin Blender include block
55 **********************************/
56 #ifdef __cplusplus
57 extern "C"
58 {
59 #endif  // __cplusplus
60 #include "MEM_guardedalloc.h"
61 #include "BKE_blender.h"        
62 #include "BKE_global.h" 
63 #include "BKE_icons.h"  
64 #include "BKE_node.h"   
65 #include "BKE_report.h"
66 #include "BKE_library.h"
67 #include "BLI_blenlib.h"
68 #include "DNA_scene_types.h"
69 #include "DNA_userdef_types.h"
70 #include "BLO_readfile.h"
71 #include "BLO_runtime.h"
72 #include "IMB_imbuf.h"
73 #include "BKE_text.h"
74 #include "BKE_sound.h"
75         
76         int GHOST_HACK_getFirstFile(char buf[]);
77         
78 extern char bprogname[];        /* holds a copy of argv[0], from creator.c */
79 extern char btempdir[];         /* use this to store a valid temp directory */
80
81 // For BLF
82 #include "BLF_api.h"
83 extern int datatoc_bfont_ttf_size;
84 extern char datatoc_bfont_ttf[];
85
86 #ifdef __cplusplus
87 }
88 #endif // __cplusplus
89
90 #include "GPU_draw.h"
91
92 /**********************************
93 * End Blender include block
94 **********************************/
95
96 #include "BL_System.h"
97 #include "GPG_Application.h"
98
99 #include "GHOST_ISystem.h"
100 #include "RAS_IRasterizer.h"
101
102 #include "BKE_main.h"
103 #include "BKE_utildefines.h"
104
105 #include "RNA_define.h"
106
107 #ifdef WIN32
108 #include <windows.h>
109 #if !defined(DEBUG)
110 #include <wincon.h>
111 #endif // !defined(DEBUG)
112 #endif // WIN32
113
114 const int kMinWindowWidth = 100;
115 const int kMinWindowHeight = 100;
116
117 char bprogname[FILE_MAX];
118
119 static void mem_error_cb(const char *errorStr)
120 {
121         fprintf(stderr, "%s", errorStr);
122         fflush(stderr);
123 }
124
125 #ifdef WIN32
126 typedef enum 
127 {
128   SCREEN_SAVER_MODE_NONE = 0,
129   SCREEN_SAVER_MODE_PREVIEW,
130   SCREEN_SAVER_MODE_SAVER,
131   SCREEN_SAVER_MODE_CONFIGURATION,
132   SCREEN_SAVER_MODE_PASSWORD,
133 } ScreenSaverMode;
134
135 static ScreenSaverMode scr_saver_mode = SCREEN_SAVER_MODE_NONE;
136 static HWND scr_saver_hwnd = NULL;
137
138 static BOOL scr_saver_init(int argc, char **argv) 
139 {
140         scr_saver_mode = SCREEN_SAVER_MODE_NONE;
141         scr_saver_hwnd = NULL;
142         BOOL ret = FALSE;
143
144         int len = ::strlen(argv[0]);
145         if (len > 4 && !::stricmp(".scr", argv[0] + len - 4))
146         {
147                 scr_saver_mode = SCREEN_SAVER_MODE_CONFIGURATION;
148                 ret = TRUE;
149                 if (argc >= 2)
150                 {
151                         if (argc >= 3)
152                         {
153                                 scr_saver_hwnd = (HWND) ::atoi(argv[2]);
154                         }
155                         if (!::stricmp("/c", argv[1]))
156                         {
157                                 scr_saver_mode = SCREEN_SAVER_MODE_CONFIGURATION;
158                                 if (scr_saver_hwnd == NULL)
159                                         scr_saver_hwnd = ::GetForegroundWindow();
160                         }
161                         else if (!::stricmp("/s", argv[1]))
162                         {
163                                 scr_saver_mode = SCREEN_SAVER_MODE_SAVER;
164                         }
165                         else if (!::stricmp("/a", argv[1]))
166                         {
167                                 scr_saver_mode = SCREEN_SAVER_MODE_PASSWORD;
168                         }
169                         else if (!::stricmp("/p", argv[1])
170                                  || !::stricmp("/l", argv[1]))
171                         {
172                                 scr_saver_mode = SCREEN_SAVER_MODE_PREVIEW;
173                         }
174                 }
175         }
176         return ret;
177 }
178
179 #endif /* WIN32 */
180
181 void usage(const char* program, bool isBlenderPlayer)
182 {
183         const char * consoleoption;
184         const char * filename = "";
185         const char * pathname = "";
186
187 #ifdef _WIN32
188         consoleoption = "-c ";
189 #else
190         consoleoption = "";
191 #endif
192
193         if (isBlenderPlayer) {
194                 filename = "filename.blend";
195 #ifdef _WIN32
196                 pathname = "c:\\";
197 #else
198                 pathname = "//home//user//";
199 #endif
200         }
201         
202         printf("usage:   %s [-w [w h l t]] [-f [fw fh fb ff]] %s[-g gamengineoptions] "
203                 "[-s stereomode] [-m aasamples] %s\n", program, consoleoption, filename);
204         printf("  -h: Prints this command summary\n\n");
205         printf("  -w: display in a window\n");
206         printf("       --Optional parameters--\n"); 
207         printf("       w = window width\n");
208         printf("       h = window height\n\n");
209         printf("       l = window left coordinate\n");
210         printf("       t = window top coordinate\n");
211         printf("       Note: If w or h is defined, both must be defined.\n");
212         printf("          Also, if l or t is defined, all options must be used.\n\n");
213         printf("  -f: start game in full screen mode\n");
214         printf("       --Optional parameters--\n");
215         printf("       fw = full screen mode pixel width\n");
216         printf("       fh = full screen mode pixel height\n\n");
217         printf("       fb = full screen mode bits per pixel\n");
218         printf("       ff = full screen mode frequency\n");
219         printf("       Note: If fw or fh is defined, both must be defined.\n");
220         printf("          Also, if fb is used, fw and fh must be used. ff requires all options.\n\n");
221         printf("  -s: start player in stereo\n");
222         printf("       stereomode: hwpageflip       (Quad buffered shutter glasses)\n");
223         printf("                   syncdoubling     (Above Below)\n");
224         printf("                   sidebyside       (Left Right)\n");
225         printf("                   anaglyph         (Red-Blue glasses)\n");
226         printf("                   vinterlace       (Vertical interlace for autostereo display)\n");
227         printf("                             depending on the type of stereo you want\n\n");
228         printf("  -D: start player in dome mode\n");
229         printf("       --Optional parameters--\n");
230         printf("       angle    = field of view in degrees\n");
231         printf("       tilt     = tilt angle in degrees\n");
232         printf("       warpdata = a file to use for warping the image (absolute path)\n");      
233         printf("       mode: fisheye                (Fisheye)\n");
234         printf("             truncatedfront         (Front-Truncated)\n");
235         printf("             truncatedrear          (Rear-Truncated)\n");
236         printf("             cubemap                (Cube Map)\n");
237         printf("             sphericalpanoramic     (Spherical Panoramic)\n");
238         printf("                             depending on the type of dome you are using\n\n");
239         printf("  -m: maximum anti-aliasing (eg. 2,4,8,16)\n\n");
240         printf("  -i: parent windows ID \n\n");
241 #ifdef _WIN32
242         printf("  -c: keep console window open\n\n");
243 #endif
244         printf("  -d: turn debugging on\n\n");
245         printf("  -g: game engine options:\n\n");
246         printf("       Name                       Default      Description\n");
247         printf("       ------------------------------------------------------------------------\n");
248         printf("       fixedtime                      0         \"Enable all frames\"\n");
249         printf("       nomipmap                       0         Disable mipmaps\n");
250         printf("       show_framerate                 0         Show the frame rate\n");
251         printf("       show_properties                0         Show debug properties\n");
252         printf("       show_profile                   0         Show profiling information\n");
253         printf("       blender_material               0         Enable material settings\n");
254         printf("       ignore_deprecation_warnings    1         Ignore deprecation warnings\n");
255         printf("\n");
256         printf("  - : all arguments after this are ignored, allowing python to access them from sys.argv\n");
257         printf("\n");
258         printf("example: %s -w 320 200 10 10 -g noaudio%s%s\n", program, pathname, filename);
259         printf("example: %s -g show_framerate = 0 %s%s\n", program, pathname, filename);
260         printf("example: %s -i 232421 -m 16 %s%s\n\n", program, pathname, filename);
261 }
262
263 static void get_filename(int argc, char **argv, char *filename)
264 {
265 #ifdef __APPLE__
266 /* On Mac we park the game file (called game.blend) in the application bundle.
267 * The executable is located in the bundle as well.
268 * Therefore, we can locate the game relative to the executable.
269         */
270         int srclen = ::strlen(argv[0]);
271         int len = 0;
272         char *gamefile = NULL;
273         
274         filename[0] = '\0';
275
276         if (argc > 1) {
277                 if (BLI_exists(argv[argc-1])) {
278                         BLI_strncpy(filename, argv[argc-1], FILE_MAXDIR + FILE_MAXFILE);
279                 }
280                 if (::strncmp(argv[argc-1], "-psn_", 5)==0) {
281                         static char firstfilebuf[512];
282                         if (GHOST_HACK_getFirstFile(firstfilebuf)) {
283                                 BLI_strncpy(filename, firstfilebuf, FILE_MAXDIR + FILE_MAXFILE);
284                         }
285                 }                        
286         }
287         
288         srclen -= ::strlen("MacOS/blenderplayer");
289         if (srclen > 0) {
290                 len = srclen + ::strlen("Resources/game.blend"); 
291                 gamefile = new char [len + 1];
292                 ::strcpy(gamefile, argv[0]);
293                 ::strcpy(gamefile + srclen, "Resources/game.blend");
294                 //::printf("looking for file: %s\n", filename);
295                 
296                 if (BLI_exists(gamefile))
297                         BLI_strncpy(filename, gamefile, FILE_MAXDIR + FILE_MAXFILE);
298
299                 delete [] gamefile;
300         }
301         
302 #else
303         filename[0] = '\0';
304
305         if(argc > 1)
306                 BLI_strncpy(filename, argv[argc-1], FILE_MAXDIR + FILE_MAXFILE);
307 #endif // !_APPLE
308 }
309
310 static BlendFileData *load_game_data(char *progname, char *filename = NULL, char *relativename = NULL)
311 {
312         ReportList reports;
313         BlendFileData *bfd = NULL;
314
315         BKE_reports_init(&reports, RPT_STORE);
316         
317         /* try to load ourself, will only work if we are a runtime */
318         if (BLO_is_a_runtime(progname)) {
319                 bfd= BLO_read_runtime(progname, &reports);
320                 if (bfd) {
321                         bfd->type= BLENFILETYPE_RUNTIME;
322                         strcpy(bfd->main->name, progname);
323                 }
324         } else {
325                 bfd= BLO_read_from_file(progname, &reports);
326         }
327         
328         if (!bfd && filename) {
329                 bfd = load_game_data(filename);
330                 if (!bfd) {
331                         printf("Loading %s failed: ", filename);
332                         BKE_reports_print(&reports, RPT_ERROR);
333                 }
334         }
335
336         BKE_reports_clear(&reports);
337         
338         return bfd;
339 }
340
341 int main(int argc, char** argv)
342 {
343         int i;
344         int argc_py_clamped= argc; /* use this so python args can be added after ' - ' */
345         bool error = false;
346         SYS_SystemHandle syshandle = SYS_GetSystem();
347         bool fullScreen = false;
348         bool fullScreenParFound = false;
349         bool windowParFound = false;
350 #ifdef WIN32
351         bool closeConsole = true;
352 #endif
353         RAS_IRasterizer::StereoMode stereomode = RAS_IRasterizer::RAS_STEREO_NOSTEREO;
354         bool stereoWindow = false;
355         bool stereoParFound = false;
356         int stereoFlag = STEREO_NOSTEREO;
357         int domeFov = -1;
358         int domeTilt = -200;
359         int domeMode = 0;
360         char* domeWarp = NULL;
361         Text *domeText  = NULL;
362         int windowLeft = 100;
363         int windowTop = 100;
364         int windowWidth = 640;
365         int windowHeight = 480;
366         GHOST_TUns32 fullScreenWidth = 0;
367         GHOST_TUns32 fullScreenHeight= 0;
368         int fullScreenBpp = 32;
369         int fullScreenFrequency = 60;
370         GHOST_TEmbedderWindowID parentWindow = 0;
371         bool isBlenderPlayer = false;
372         int validArguments=0;
373         GHOST_TUns16 aasamples = 0;
374         
375 #ifdef __linux__
376 #ifdef __alpha__
377         signal (SIGFPE, SIG_IGN);
378 #endif /* __alpha__ */
379 #endif /* __linux__ */
380         BLI_where_am_i(bprogname, sizeof(bprogname), argv[0]);
381 #ifdef __APPLE__
382     // Can't use Carbon right now because of double defined type ID (In Carbon.h and DNA_ID.h, sigh)
383     /*
384     IBNibRef            nibRef;
385     WindowRef           window;
386     OSStatus            err;
387         
388           // Create a Nib reference passing the name of the nib file (without the .nib extension)
389           // CreateNibReference only searches into the application bundle.
390           err = ::CreateNibReference(CFSTR("main"), &nibRef);
391           if (err) return -1;
392           
393                 // Once the nib reference is created, set the menu bar. "MainMenu" is the name of the menu bar
394                 // object. This name is set in InterfaceBuilder when the nib is created.
395                 err = ::SetMenuBarFromNib(nibRef, CFSTR("MenuBar"));
396                 if (err) return -1;
397                 
398                   // We don't need the nib reference anymore.
399                   ::DisposeNibReference(nibRef);
400     */
401 #endif // __APPLE__
402
403         RNA_init();
404
405         init_nodesystem();
406         
407         initglobals();
408
409         // We load our own G.main, so free the one that initglobals() gives us
410         free_main(G.main);
411         G.main = NULL;
412
413         IMB_init();
414
415         // Setup builtin font for BLF (mostly copied from creator.c, wm_init_exit.c and interface_style.c)
416         BLF_init(11, U.dpi);
417         BLF_lang_init();
418         BLF_load_mem("default", (unsigned char*)datatoc_bfont_ttf, datatoc_bfont_ttf_size);
419  
420         // Parse command line options
421 #if defined(DEBUG)
422         printf("argv[0] = '%s'\n", argv[0]);
423 #endif
424
425 #ifdef WIN32
426         if (scr_saver_init(argc, argv))
427         {
428                 switch (scr_saver_mode)
429                 {
430                 case SCREEN_SAVER_MODE_CONFIGURATION:
431                         MessageBox(scr_saver_hwnd, "This screen saver has no options that you can set", "Screen Saver", MB_OK);
432                         break;
433                 case SCREEN_SAVER_MODE_PASSWORD:
434                         /* This is W95 only, which we currently do not support.
435                            Fall-back to normal screen saver behaviour in that case... */
436                 case SCREEN_SAVER_MODE_SAVER:
437                         fullScreen = true;
438                         fullScreenParFound = true;
439                         break;
440
441                 case SCREEN_SAVER_MODE_PREVIEW:
442                         /* This will actually be handled somewhere below... */
443                         break;
444                 }
445         }
446 #endif
447         // XXX add the ability to change this values to the command line parsing.
448         U.mixbufsize = 2048;
449         U.audiodevice = 2;
450         U.audiorate = 44100;
451         U.audioformat = 0x24;
452         U.audiochannels = 2;
453
454         // XXX this one too
455         U.anisotropic_filter = 2;
456
457         sound_init_once();
458
459         /* if running blenderplayer the last argument can't be parsed since it has to be the filename. */
460         isBlenderPlayer = !BLO_is_a_runtime(argv[0]);
461         if (isBlenderPlayer)
462                 validArguments = argc - 1;
463         else
464                 validArguments = argc;
465
466         for (i = 1; (i < validArguments) && !error 
467 #ifdef WIN32
468                 && scr_saver_mode == SCREEN_SAVER_MODE_NONE
469 #endif
470                 ;)
471
472         {
473 #if defined(DEBUG)
474                 printf("argv[%d] = '%s'   , %i\n", i, argv[i],argc);
475 #endif
476                 if (argv[i][0] == '-')
477                 {
478                         /* ignore all args after " - ", allow python to have own args */
479                         if (argv[i][1]=='\0') {
480                                 argc_py_clamped= i;
481                                 break;
482                         }
483                         
484                         switch (argv[i][1])
485                         {
486                         case 'g':
487                                 // Parse game options
488                                 {
489                                         i++;
490                                         if (i <= validArguments)
491                                         {
492                                                 char* paramname = argv[i];
493                                                 // Check for single value versus assignment
494                                                 if (i+1 <= validArguments && (*(argv[i+1]) == '='))
495                                                 {
496                                                         i++;
497                                                         if (i + 1 <= validArguments)
498                                                         {
499                                                                 i++;
500                                                                 // Assignment
501                                                                 SYS_WriteCommandLineInt(syshandle, paramname, atoi(argv[i]));
502                                                                 SYS_WriteCommandLineFloat(syshandle, paramname, atof(argv[i]));
503                                                                 SYS_WriteCommandLineString(syshandle, paramname, argv[i]);
504 #if defined(DEBUG)
505                                                                 printf("%s = '%s'\n", paramname, argv[i]);
506 #endif
507                                                                 i++;
508                                                         }
509                                                         else
510                                                         {
511                                                                 error = true;
512                                                                 printf("error: argument assignment %s without value.\n", paramname);
513                                                         }
514                                                 }
515                                                 else
516                                                 {
517 //                                                      SYS_WriteCommandLineInt(syshandle, argv[i++], 1);
518                                                 }
519                                         }
520                                 }
521                                 break;
522
523                         case 'd':
524                                 i++;
525                                 G.f |= G_DEBUG;     /* std output printf's */
526                                 MEM_set_memory_debug();
527                                 break;
528
529                         case 'f':
530                                 i++;
531                                 fullScreen = true;
532                                 fullScreenParFound = true;
533                                 if ((i + 2) <= validArguments && argv[i][0] != '-' && argv[i+1][0] != '-')
534                                 {
535                                         fullScreenWidth = atoi(argv[i++]);
536                                         fullScreenHeight = atoi(argv[i++]);
537                                         if ((i + 1) <= validArguments && argv[i][0] != '-')
538                                         {
539                                                 fullScreenBpp = atoi(argv[i++]);
540                                                 if ((i + 1) <= validArguments && argv[i][0] != '-')
541                                                         fullScreenFrequency = atoi(argv[i++]);
542                                         }
543                                 }
544                                 break;
545                         case 'w':
546                                 // Parse window position and size options
547                                 i++;
548                                 fullScreen = false;
549                                 windowParFound = true;
550
551                                 if ((i + 2) <= validArguments && argv[i][0] != '-' && argv[i+1][0] != '-')
552                                 {
553                                         windowWidth = atoi(argv[i++]);
554                                         windowHeight = atoi(argv[i++]);
555                                         if ((i + 2) <= validArguments && argv[i][0] != '-' && argv[i+1][0] != '-')
556                                         {
557                                                 windowLeft = atoi(argv[i++]);
558                                                 windowTop = atoi(argv[i++]);
559                                         }
560                                 }
561                                 break;
562                                         
563                         case 'h':
564                                 usage(argv[0], isBlenderPlayer);
565                                 return 0;
566                                 break;
567                         case 'i':
568                                 i++;
569                                 if ( (i + 1) <= validArguments )
570                                         parentWindow = atoi(argv[i++]); 
571                                 else {
572                                         error = true;
573                                         printf("error: too few options for parent window argument.\n");
574                                 }
575 #if defined(DEBUG)
576                                 printf("XWindows ID = %d\n", parentWindow);
577 #endif // defined(DEBUG)
578                                 break;
579                         case 'm':
580                                 i++;
581                                 if ((i+1) <= validArguments )
582                                 aasamples = atoi(argv[i++]);
583                                 break;
584                         case 'c':
585                                 i++;
586 #ifdef WIN32
587                                 closeConsole = false;
588 #endif
589                                 break;
590                         case 's':  // stereo
591                                 i++;
592                                 if ((i + 1) <= validArguments)
593                                 {
594                                         stereomode = (RAS_IRasterizer::StereoMode) atoi(argv[i]);
595                                         if (stereomode < RAS_IRasterizer::RAS_STEREO_NOSTEREO || stereomode >= RAS_IRasterizer::RAS_STEREO_MAXSTEREO)
596                                                 stereomode = RAS_IRasterizer::RAS_STEREO_NOSTEREO;
597                                         
598                                         if(!strcmp(argv[i], "nostereo"))  // ok, redundant but clear
599                                                 stereomode = RAS_IRasterizer::RAS_STEREO_NOSTEREO;
600                                         
601                                         // only the hardware pageflip method needs a stereo window
602                                         else if(!strcmp(argv[i], "hwpageflip")) {
603                                                 stereomode = RAS_IRasterizer::RAS_STEREO_QUADBUFFERED;
604                                                 stereoWindow = true;
605                                         }
606                                         else if(!strcmp(argv[i], "syncdoubling"))
607                                                 stereomode = RAS_IRasterizer::RAS_STEREO_ABOVEBELOW;
608                                         
609                                         else if(!strcmp(argv[i], "anaglyph"))
610                                                 stereomode = RAS_IRasterizer::RAS_STEREO_ANAGLYPH;
611                                         
612                                         else if(!strcmp(argv[i], "sidebyside"))
613                                                 stereomode = RAS_IRasterizer::RAS_STEREO_SIDEBYSIDE;
614                                         
615                                         else if(!strcmp(argv[i], "vinterlace"))
616                                                 stereomode = RAS_IRasterizer::RAS_STEREO_VINTERLACE;
617                                         
618 #if 0
619                                         // future stuff
620                                         else if(!strcmp(argv[i], "stencil")
621                                                 stereomode = RAS_STEREO_STENCIL;
622 #endif
623                                         
624                                         i++;
625                                         stereoParFound = true;
626                                         stereoFlag = STEREO_ENABLED;
627                                 }
628                                 else
629                                 {
630                                         error = true;
631                                         printf("error: too few options for stereo argument.\n");
632                                 }
633                                 break;
634                         case 'D':
635                                 stereoFlag = STEREO_DOME;
636                                 stereomode = RAS_IRasterizer::RAS_STEREO_DOME;
637                                 i++;
638                                 if ((i + 1) <= validArguments)
639                                 {
640                                         if(!strcmp(argv[i], "angle")){
641                                                 i++;
642                                                 domeFov = atoi(argv[i++]);
643                                         }
644                                         if(!strcmp(argv[i], "tilt")){
645                                                 i++;
646                                                 domeTilt = atoi(argv[i++]);
647                                         }
648                                         if(!strcmp(argv[i], "warpdata")){
649                                                 i++;
650                                                 domeWarp = argv[i++];
651                                         }
652                                         if(!strcmp(argv[i], "mode")){
653                                                 i++;
654                                                 if(!strcmp(argv[i], "fisheye"))
655                                                         domeMode = DOME_FISHEYE;
656                                                         
657                                                 else if(!strcmp(argv[i], "truncatedfront"))
658                                                         domeMode = DOME_TRUNCATED_FRONT;
659                                                         
660                                                 else if(!strcmp(argv[i], "truncatedrear"))
661                                                         domeMode = DOME_TRUNCATED_REAR;
662                                                         
663                                                 else if(!strcmp(argv[i], "cubemap"))
664                                                         domeMode = DOME_ENVMAP;
665                                                         
666                                                 else if(!strcmp(argv[i], "sphericalpanoramic"))
667                                                         domeMode = DOME_PANORAM_SPH;
668
669                                                 else
670                                                         printf("error: %s is not a valid dome mode.\n", argv[i]);
671                                         }
672                                         i++;
673                                 }
674                                 break;
675                         default:
676                                 printf("Unknown argument: %s\n", argv[i++]);
677                                 break;
678                         }
679                 }
680                 else
681                 {
682                         i++;
683                 }
684         }
685         
686         if ((windowWidth < kMinWindowWidth) || (windowHeight < kMinWindowHeight))
687         {
688                 error = true;
689                 printf("error: window size too small.\n");
690         }
691         
692         if (error )
693         {
694                 usage(argv[0], isBlenderPlayer);
695                 return 0;
696         }
697
698 #ifdef WIN32
699         if (scr_saver_mode != SCREEN_SAVER_MODE_CONFIGURATION)
700 #endif
701         {
702 #ifdef __APPLE__
703                 //SYS_WriteCommandLineInt(syshandle, "show_framerate", 1);
704                 //SYS_WriteCommandLineInt(syshandle, "nomipmap", 1);
705                 //fullScreen = false;           // Can't use full screen
706 #endif
707
708                 if (SYS_GetCommandLineInt(syshandle, "nomipmap", 0))
709                 {
710                         GPU_set_mipmap(0);
711                 }
712
713                 GPU_set_anisotropic(U.anisotropic_filter);
714                 
715                 // Create the system
716                 if (GHOST_ISystem::createSystem() == GHOST_kSuccess)
717                 {
718                         GHOST_ISystem* system = GHOST_ISystem::getSystem();
719                         assertd(system);
720                         
721                         if (!fullScreenWidth || !fullScreenHeight)
722                                 system->getMainDisplayDimensions(fullScreenWidth, fullScreenHeight);
723                         // process first batch of events. If the user
724                         // drops a file on top off the blenderplayer icon, we 
725                         // receive an event with the filename
726                         
727                         system->processEvents(0);
728                         
729                         // this bracket is needed for app (see below) to get out
730                         // of scope before GHOST_ISystem::disposeSystem() is called.
731                         {
732                                 int exitcode = KX_EXIT_REQUEST_NO_REQUEST;
733                                 STR_String exitstring = "";
734                                 GPG_Application app(system);
735                                 bool firstTimeRunning = true;
736                                 char filename[FILE_MAXDIR + FILE_MAXFILE];
737                                 char pathname[FILE_MAXDIR + FILE_MAXFILE];
738                                 char *titlename;
739
740                                 get_filename(argc_py_clamped, argv, filename);
741                                 if(filename[0])
742                                         BLI_path_cwd(filename);
743                                 
744                                 do
745                                 {
746                                         // Read the Blender file
747                                         BlendFileData *bfd;
748                                         
749                                         // if we got an exitcode 3 (KX_EXIT_REQUEST_START_OTHER_GAME) load a different file
750                                         if (exitcode == KX_EXIT_REQUEST_START_OTHER_GAME)
751                                         {
752                                                 char basedpath[240];
753                                                 
754                                                 // base the actuator filename relative to the last file
755                                                 strcpy(basedpath, exitstring.Ptr());
756                                                 BLI_path_abs(basedpath, pathname);
757                                                 
758                                                 bfd = load_game_data(basedpath);
759
760                                                 if (!bfd)
761                                                 {
762                                                         // just add "//" in front of it
763                                                         char temppath[242];
764                                                         strcpy(temppath, "//");
765                                                         strcat(temppath, basedpath);
766                                 
767                                                         BLI_path_abs(temppath, pathname);
768                                                         bfd = load_game_data(temppath);
769                                                 }
770                                         }
771                                         else
772                                         {
773                                                 bfd = load_game_data(bprogname, filename[0]? filename: NULL);
774                                         }
775                                         
776                                         //::printf("game data loaded from %s\n", filename);
777                                         
778                                         if (!bfd) {
779                                                 usage(argv[0], isBlenderPlayer);
780                                                 error = true;
781                                                 exitcode = KX_EXIT_REQUEST_QUIT_GAME;
782                                         } 
783                                         else 
784                                         {
785 #ifdef WIN32
786 #if !defined(DEBUG)
787                                                 if (closeConsole)
788                                                 {
789                                                         //::FreeConsole();    // Close a console window
790                                                 }
791 #endif // !defined(DEBUG)
792 #endif // WIN32
793                                                 Main *maggie = bfd->main;
794                                                 Scene *scene = bfd->curscene;
795                                                 G.main = maggie;
796
797                                                 if (firstTimeRunning)
798                                                         G.fileflags  = bfd->fileflags;
799
800                                                 //Seg Fault; icon.c gIcons == 0
801                                                 BKE_icons_init(1);
802                                                 
803                                                 titlename = maggie->name;
804                                                 
805                                                 // Check whether the game should be displayed full-screen
806                                                 if ((!fullScreenParFound) && (!windowParFound))
807                                                 {
808                                                         // Only use file settings when command line did not override
809                                                         if (scene->gm.fullscreen) {
810                                                                 //printf("fullscreen option found in Blender file\n");
811                                                                 fullScreen = true;
812                                                                 fullScreenWidth= scene->gm.xplay;
813                                                                 fullScreenHeight= scene->gm.yplay;
814                                                                 fullScreenFrequency= scene->gm.freqplay;
815                                                                 fullScreenBpp = scene->gm.depth;
816                                                         }
817                                                         else
818                                                         {
819                                                                 fullScreen = false;
820                                                                 windowWidth = scene->gm.xplay;
821                                                                 windowHeight = scene->gm.yplay;
822                                                         }
823                                                 }
824                                                 
825                                                 
826                                                 // Check whether the game should be displayed in stereo
827                                                 if (!stereoParFound)
828                                                 {
829                                                         if(scene->gm.stereoflag == STEREO_ENABLED){
830                                                                 stereomode = (RAS_IRasterizer::StereoMode) scene->gm.stereomode;
831                                                                 if (stereomode != RAS_IRasterizer::RAS_STEREO_QUADBUFFERED)
832                                                                         stereoWindow = true;
833                                                         }
834                                                 }
835                                                 else
836                                                         scene->gm.stereoflag = STEREO_ENABLED;
837
838                                                 if (stereoFlag == STEREO_DOME){
839                                                         stereomode = RAS_IRasterizer::RAS_STEREO_DOME;
840                                                         scene->gm.stereoflag = STEREO_DOME;
841                                                         if (domeFov > 89)
842                                                                 scene->gm.dome.angle = domeFov;
843                                                         if (domeTilt > -180)
844                                                                 scene->gm.dome.tilt = domeTilt;
845                                                         if (domeMode > 0)
846                                                                 scene->gm.dome.mode = domeMode;
847                                                         if (domeWarp)
848                                                         {
849                                                                 //XXX to do: convert relative to absolute path
850                                                                 domeText= add_text(domeWarp, "");
851                                                                 if(!domeText)
852                                                                         printf("error: invalid warpdata text file - %s\n", domeWarp);
853                                                                 else
854                                                                         scene->gm.dome.warptext = domeText;
855                                                         }
856                                                 }
857                                                 
858                                                 //                                      GPG_Application app (system, maggie, startscenename);
859                                                 app.SetGameEngineData(maggie, scene, argc, argv); /* this argc cant be argc_py_clamped, since python uses it */
860                                                 BLI_strncpy(pathname, maggie->name, sizeof(pathname));
861                                                 if(G.main != maggie) {
862                                                         BLI_strncpy(G.main->name, maggie->name, sizeof(G.main->name));
863                                                 }
864 #ifdef WITH_PYTHON
865                                                 setGamePythonPath(G.main->name);
866 #endif
867                                                 if (firstTimeRunning)
868                                                 {
869                                                         firstTimeRunning = false;
870
871                                                         if (fullScreen)
872                                                         {
873 #ifdef WIN32
874                                                                 if (scr_saver_mode == SCREEN_SAVER_MODE_SAVER)
875                                                                 {
876                                                                         app.startScreenSaverFullScreen(fullScreenWidth, fullScreenHeight, fullScreenBpp, fullScreenFrequency,
877                                                                                 stereoWindow, stereomode, aasamples);
878                                                                 }
879                                                                 else
880 #endif
881                                                                 {
882                                                                         app.startFullScreen(fullScreenWidth, fullScreenHeight, fullScreenBpp, fullScreenFrequency,
883                                                                                 stereoWindow, stereomode, aasamples);
884                                                                 }
885                                                         }
886                                                         else
887                                                         {
888 #ifdef __APPLE__
889                                                                 // on Mac's we'll show the executable name instead of the 'game.blend' name
890                                                                 char tempname[1024], *appstring;
891                                                                 ::strcpy(tempname, titlename);
892                                                                 
893                                                                 appstring = strstr(tempname, ".app/");
894                                                                 if (appstring) {
895                                                                         appstring[2] = 0;
896                                                                         titlename = &tempname[0];
897                                                                 }
898 #endif
899                                                                 // Strip the path so that we have the name of the game file
900                                                                 STR_String path = titlename;
901 #ifndef WIN32
902                                                                 vector<STR_String> parts = path.Explode('/');
903 #else  // WIN32
904                                                                 vector<STR_String> parts = path.Explode('\\');
905 #endif // WIN32                        
906                                                                 STR_String title;
907                                                                 if (parts.size())
908                                                                 {
909                                                                         title = parts[parts.size()-1];
910                                                                         parts = title.Explode('.');
911                                                                         if (parts.size() > 1)
912                                                                         {
913                                                                                 title = parts[0];
914                                                                         }
915                                                                 }
916                                                                 else
917                                                                 {
918                                                                         title = "blenderplayer";
919                                                                 }
920 #ifdef WIN32
921                                                                 if (scr_saver_mode == SCREEN_SAVER_MODE_PREVIEW)
922                                                                 {
923                                                                         app.startScreenSaverPreview(scr_saver_hwnd, stereoWindow, stereomode, aasamples);
924                                                                 }
925                                                                 else
926 #endif
927                                                                 {
928                                                                                                                                                                                                                 if (parentWindow != 0)
929                                                                                 app.startEmbeddedWindow(title, parentWindow, stereoWindow, stereomode, aasamples);
930                                                                         else
931                                                                                 app.startWindow(title, windowLeft, windowTop, windowWidth, windowHeight,
932                                                                                 stereoWindow, stereomode, aasamples);
933                                                                 }
934                                                         }
935                                                 }
936                                                 else
937                                                 {
938                                                         app.StartGameEngine(stereomode);
939                                                         exitcode = KX_EXIT_REQUEST_NO_REQUEST;
940                                                 }
941                                                 
942                                                 // Add the application as event consumer
943                                                 system->addEventConsumer(&app);
944                                                 
945                                                 // Enter main loop
946                                                 bool run = true;
947                                                 while (run)
948                                                 {
949                                                         system->processEvents(false);
950                                                         system->dispatchEvents();
951                                                         if ((exitcode = app.getExitRequested()))
952                                                         {
953                                                                 run = false;
954                                                                 exitstring = app.getExitString();
955                                                         }
956                                                 }
957                                                 app.StopGameEngine();
958
959                                                 /* 'app' is freed automatic when out of scope. 
960                                                  * removal is needed else the system will free an already freed value */
961                                                 system->removeEventConsumer(&app);
962
963                                                 BLO_blendfiledata_free(bfd);
964                                         }
965                                 } while (exitcode == KX_EXIT_REQUEST_RESTART_GAME || exitcode == KX_EXIT_REQUEST_START_OTHER_GAME);
966                         }
967
968                         // Seg Fault; icon.c gIcons == 0
969                         BKE_icons_free();
970
971                         // Dispose the system
972                         GHOST_ISystem::disposeSystem();
973                 } else {
974                         error = true;
975                         printf("error: couldn't create a system.\n");
976                 }
977         }
978
979         // Cleanup
980         RNA_exit();
981         BLF_exit();
982         IMB_exit();
983         free_nodesystem();
984
985         SYS_DeleteSystem(syshandle);
986
987         int totblock= MEM_get_memory_blocks_in_use();
988         if(totblock!=0) {
989                 printf("Error Totblock: %d\n",totblock);
990                 MEM_set_error_callback(mem_error_cb);
991                 MEM_printmemlist();
992         }
993
994         return error ? -1 : 0;
995 }
996
997