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