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