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