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