Blender V2.61 - r43446

GPG_ghost.cpp

Go to the documentation of this file.
00001 /*
00002  * ***** BEGIN GPL LICENSE BLOCK *****
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License
00006  * as published by the Free Software Foundation; either version 2
00007  * of the License, or (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software Foundation,
00016  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017  *
00018  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
00019  * All rights reserved.
00020  *
00021  * The Original Code is: all of this file.
00022  *
00023  * Contributor(s): none yet.
00024  *
00025  * ***** END GPL LICENSE BLOCK *****
00026  * Start up of the Blender Player on GHOST.
00027  */
00028 
00034 #include <iostream>
00035 #include <math.h>
00036 
00037 #ifdef __linux__
00038 #ifdef __alpha__
00039 #include <signal.h>
00040 #endif /* __alpha__ */
00041 #endif /* __linux__ */
00042 
00043 #ifdef __APPLE__
00044 // Can't use Carbon right now because of double defined type ID (In Carbon.h and DNA_ID.h, sigh)
00045 //#include <Carbon/Carbon.h>
00046 //#include <CFBundle.h>
00047 #endif // __APPLE__
00048 #include "KX_KetsjiEngine.h"
00049 #include "KX_PythonInit.h"
00050 
00051 /**********************************
00052 * Begin Blender include block
00053 **********************************/
00054 #ifdef __cplusplus
00055 extern "C"
00056 {
00057 #endif  // __cplusplus
00058 #include "MEM_guardedalloc.h"
00059 #include "BKE_blender.h"    
00060 #include "BKE_global.h" 
00061 #include "BKE_icons.h"  
00062 #include "BKE_node.h"   
00063 #include "BKE_report.h"
00064 #include "BKE_library.h"
00065 #include "BLI_threads.h"
00066 #include "BLI_blenlib.h"
00067 #include "DNA_scene_types.h"
00068 #include "DNA_userdef_types.h"
00069 #include "BLO_readfile.h"
00070 #include "BLO_runtime.h"
00071 #include "IMB_imbuf.h"
00072 #include "BKE_text.h"
00073 #include "BKE_sound.h"
00074     
00075     int GHOST_HACK_getFirstFile(char buf[]);
00076     
00077 // For BLF
00078 #include "BLF_api.h"
00079 #include "BLF_translation.h"
00080 extern int datatoc_bfont_ttf_size;
00081 extern char datatoc_bfont_ttf[];
00082 
00083 #ifdef __cplusplus
00084 }
00085 #endif // __cplusplus
00086 
00087 #include "GPU_draw.h"
00088 
00089 /**********************************
00090 * End Blender include block
00091 **********************************/
00092 
00093 #include "BL_System.h"
00094 #include "GPG_Application.h"
00095 
00096 #include "GHOST_ISystem.h"
00097 #include "RAS_IRasterizer.h"
00098 
00099 #include "BKE_main.h"
00100 #include "BKE_utildefines.h"
00101 
00102 #include "RNA_define.h"
00103 
00104 #ifdef WIN32
00105 #include <windows.h>
00106 #if !defined(DEBUG)
00107 #include <wincon.h>
00108 #endif // !defined(DEBUG)
00109 #endif // WIN32
00110 
00111 const int kMinWindowWidth = 100;
00112 const int kMinWindowHeight = 100;
00113 
00114 static void mem_error_cb(const char *errorStr)
00115 {
00116     fprintf(stderr, "%s", errorStr);
00117     fflush(stderr);
00118 }
00119 
00120 #ifdef WIN32
00121 typedef enum 
00122 {
00123   SCREEN_SAVER_MODE_NONE = 0,
00124   SCREEN_SAVER_MODE_PREVIEW,
00125   SCREEN_SAVER_MODE_SAVER,
00126   SCREEN_SAVER_MODE_CONFIGURATION,
00127   SCREEN_SAVER_MODE_PASSWORD,
00128 } ScreenSaverMode;
00129 
00130 static ScreenSaverMode scr_saver_mode = SCREEN_SAVER_MODE_NONE;
00131 static HWND scr_saver_hwnd = NULL;
00132 
00133 static BOOL scr_saver_init(int argc, char **argv) 
00134 {
00135     scr_saver_mode = SCREEN_SAVER_MODE_NONE;
00136     scr_saver_hwnd = NULL;
00137     BOOL ret = FALSE;
00138 
00139     int len = ::strlen(argv[0]);
00140     if (len > 4 && !::stricmp(".scr", argv[0] + len - 4))
00141     {
00142         scr_saver_mode = SCREEN_SAVER_MODE_CONFIGURATION;
00143         ret = TRUE;
00144         if (argc >= 2)
00145         {
00146             if (argc >= 3)
00147             {
00148                 scr_saver_hwnd = (HWND) ::atoi(argv[2]);
00149             }
00150             if (!::stricmp("/c", argv[1]))
00151             {
00152                 scr_saver_mode = SCREEN_SAVER_MODE_CONFIGURATION;
00153                 if (scr_saver_hwnd == NULL)
00154                     scr_saver_hwnd = ::GetForegroundWindow();
00155             }
00156             else if (!::stricmp("/s", argv[1]))
00157             {
00158                 scr_saver_mode = SCREEN_SAVER_MODE_SAVER;
00159             }
00160             else if (!::stricmp("/a", argv[1]))
00161             {
00162                 scr_saver_mode = SCREEN_SAVER_MODE_PASSWORD;
00163             }
00164             else if (!::stricmp("/p", argv[1])
00165                  || !::stricmp("/l", argv[1]))
00166             {
00167                 scr_saver_mode = SCREEN_SAVER_MODE_PREVIEW;
00168             }
00169         }
00170     }
00171     return ret;
00172 }
00173 
00174 #endif /* WIN32 */
00175 
00176 void usage(const char* program, bool isBlenderPlayer)
00177 {
00178     const char * consoleoption;
00179     const char * example_filename = "";
00180     const char * example_pathname = "";
00181 
00182 #ifdef _WIN32
00183     consoleoption = "-c ";
00184 #else
00185     consoleoption = "";
00186 #endif
00187 
00188     if (isBlenderPlayer) {
00189         example_filename = "filename.blend";
00190 #ifdef _WIN32
00191         example_pathname = "c:\\";
00192 #else
00193         example_pathname = "/home/user/";
00194 #endif
00195     }
00196     
00197     printf("usage:   %s [-w [w h l t]] [-f [fw fh fb ff]] %s[-g gamengineoptions] "
00198         "[-s stereomode] [-m aasamples] %s\n", program, consoleoption, example_filename);
00199     printf("  -h: Prints this command summary\n\n");
00200     printf("  -w: display in a window\n");
00201     printf("       --Optional parameters--\n"); 
00202     printf("       w = window width\n");
00203     printf("       h = window height\n\n");
00204     printf("       l = window left coordinate\n");
00205     printf("       t = window top coordinate\n");
00206     printf("       Note: If w or h is defined, both must be defined.\n");
00207     printf("          Also, if l or t is defined, all options must be used.\n\n");
00208     printf("  -f: start game in full screen mode\n");
00209     printf("       --Optional parameters--\n");
00210     printf("       fw = full screen mode pixel width\n");
00211     printf("       fh = full screen mode pixel height\n\n");
00212     printf("       fb = full screen mode bits per pixel\n");
00213     printf("       ff = full screen mode frequency\n");
00214     printf("       Note: If fw or fh is defined, both must be defined.\n");
00215     printf("          Also, if fb is used, fw and fh must be used. ff requires all options.\n\n");
00216     printf("  -s: start player in stereo\n");
00217     printf("       stereomode: hwpageflip       (Quad buffered shutter glasses)\n");
00218     printf("                   syncdoubling     (Above Below)\n");
00219     printf("                   sidebyside       (Left Right)\n");
00220     printf("                   anaglyph         (Red-Blue glasses)\n");
00221     printf("                   vinterlace       (Vertical interlace for autostereo display)\n");
00222     printf("                             depending on the type of stereo you want\n\n");
00223     printf("  -D: start player in dome mode\n");
00224     printf("       --Optional parameters--\n");
00225     printf("       angle    = field of view in degrees\n");
00226     printf("       tilt     = tilt angle in degrees\n");
00227     printf("       warpdata = a file to use for warping the image (absolute path)\n");  
00228     printf("       mode: fisheye                (Fisheye)\n");
00229     printf("             truncatedfront         (Front-Truncated)\n");
00230     printf("             truncatedrear          (Rear-Truncated)\n");
00231     printf("             cubemap                (Cube Map)\n");
00232     printf("             sphericalpanoramic     (Spherical Panoramic)\n");
00233     printf("                             depending on the type of dome you are using\n\n");
00234     printf("  -m: maximum anti-aliasing (eg. 2,4,8,16)\n\n");
00235     printf("  -i: parent windows ID \n\n");
00236 #ifdef _WIN32
00237     printf("  -c: keep console window open\n\n");
00238 #endif
00239     printf("  -d: turn debugging on\n\n");
00240     printf("  -g: game engine options:\n\n");
00241     printf("       Name                       Default      Description\n");
00242     printf("       ------------------------------------------------------------------------\n");
00243     printf("       fixedtime                      0         \"Enable all frames\"\n");
00244     printf("       nomipmap                       0         Disable mipmaps\n");
00245     printf("       show_framerate                 0         Show the frame rate\n");
00246     printf("       show_properties                0         Show debug properties\n");
00247     printf("       show_profile                   0         Show profiling information\n");
00248     printf("       blender_material               0         Enable material settings\n");
00249     printf("       ignore_deprecation_warnings    1         Ignore deprecation warnings\n");
00250     printf("\n");
00251     printf("  - : all arguments after this are ignored, allowing python to access them from sys.argv\n");
00252     printf("\n");
00253     printf("example: %s -w 320 200 10 10 -g noaudio%s%s\n", program, example_pathname, example_filename);
00254     printf("example: %s -g show_framerate = 0 %s%s\n", program, example_pathname, example_filename);
00255     printf("example: %s -i 232421 -m 16 %s%s\n\n", program, example_pathname, example_filename);
00256 }
00257 
00258 static void get_filename(int argc, char **argv, char *filename)
00259 {
00260 #ifdef __APPLE__
00261 /* On Mac we park the game file (called game.blend) in the application bundle.
00262 * The executable is located in the bundle as well.
00263 * Therefore, we can locate the game relative to the executable.
00264     */
00265     int srclen = ::strlen(argv[0]);
00266     int len = 0;
00267     char *gamefile = NULL;
00268     
00269     filename[0] = '\0';
00270 
00271     if (argc > 1) {
00272         if (BLI_exists(argv[argc-1])) {
00273             BLI_strncpy(filename, argv[argc-1], FILE_MAX);
00274         }
00275         if (::strncmp(argv[argc-1], "-psn_", 5)==0) {
00276             static char firstfilebuf[512];
00277             if (GHOST_HACK_getFirstFile(firstfilebuf)) {
00278                 BLI_strncpy(filename, firstfilebuf, FILE_MAX);
00279             }
00280         }                        
00281     }
00282     
00283     srclen -= ::strlen("MacOS/blenderplayer");
00284     if (srclen > 0) {
00285         len = srclen + ::strlen("Resources/game.blend"); 
00286         gamefile = new char [len + 1];
00287         ::strcpy(gamefile, argv[0]);
00288         ::strcpy(gamefile + srclen, "Resources/game.blend");
00289         //::printf("looking for file: %s\n", filename);
00290         
00291         if (BLI_exists(gamefile))
00292             BLI_strncpy(filename, gamefile, FILE_MAX);
00293 
00294         delete [] gamefile;
00295     }
00296     
00297 #else
00298     filename[0] = '\0';
00299 
00300     if(argc > 1)
00301         BLI_strncpy(filename, argv[argc-1], FILE_MAX);
00302 #endif // !_APPLE
00303 }
00304 
00305 static BlendFileData *load_game_data(const char *progname, char *filename = NULL, char *relativename = NULL)
00306 {
00307     ReportList reports;
00308     BlendFileData *bfd = NULL;
00309 
00310     BKE_reports_init(&reports, RPT_STORE);
00311     
00312     /* try to load ourself, will only work if we are a runtime */
00313     if (BLO_is_a_runtime(progname)) {
00314         bfd= BLO_read_runtime(progname, &reports);
00315         if (bfd) {
00316             bfd->type= BLENFILETYPE_RUNTIME;
00317             BLI_strncpy(bfd->main->name, progname, sizeof(bfd->main->name));
00318         }
00319     } else {
00320         bfd= BLO_read_from_file(progname, &reports);
00321     }
00322     
00323     if (!bfd && filename) {
00324         bfd = load_game_data(filename);
00325         if (!bfd) {
00326             printf("Loading %s failed: ", filename);
00327             BKE_reports_print(&reports, RPT_ERROR);
00328         }
00329     }
00330 
00331     BKE_reports_clear(&reports);
00332     
00333     return bfd;
00334 }
00335 
00336 int main(int argc, char** argv)
00337 {
00338     int i;
00339     int argc_py_clamped= argc; /* use this so python args can be added after ' - ' */
00340     bool error = false;
00341     SYS_SystemHandle syshandle = SYS_GetSystem();
00342     bool fullScreen = false;
00343     bool fullScreenParFound = false;
00344     bool windowParFound = false;
00345 #ifdef WIN32
00346     bool closeConsole = true;
00347 #endif
00348     RAS_IRasterizer::StereoMode stereomode = RAS_IRasterizer::RAS_STEREO_NOSTEREO;
00349     bool stereoWindow = false;
00350     bool stereoParFound = false;
00351     int stereoFlag = STEREO_NOSTEREO;
00352     int domeFov = -1;
00353     int domeTilt = -200;
00354     int domeMode = 0;
00355     char* domeWarp = NULL;
00356     Text *domeText  = NULL;
00357     int windowLeft = 100;
00358     int windowTop = 100;
00359     int windowWidth = 640;
00360     int windowHeight = 480;
00361     GHOST_TUns32 fullScreenWidth = 0;
00362     GHOST_TUns32 fullScreenHeight= 0;
00363     int fullScreenBpp = 32;
00364     int fullScreenFrequency = 60;
00365     GHOST_TEmbedderWindowID parentWindow = 0;
00366     bool isBlenderPlayer = false;
00367     int validArguments=0;
00368     bool samplesParFound = false;
00369     GHOST_TUns16 aasamples = 0;
00370     
00371 #ifdef __linux__
00372 #ifdef __alpha__
00373     signal (SIGFPE, SIG_IGN);
00374 #endif /* __alpha__ */
00375 #endif /* __linux__ */
00376     BLI_init_program_path(argv[0]);
00377     BLI_init_temporary_dir(NULL);
00378 #ifdef __APPLE__
00379     // Can't use Carbon right now because of double defined type ID (In Carbon.h and DNA_ID.h, sigh)
00380     /*
00381     IBNibRef        nibRef;
00382     WindowRef       window;
00383     OSStatus        err;
00384 
00385       // Create a Nib reference passing the name of the nib file (without the .nib extension)
00386       // CreateNibReference only searches into the application bundle.
00387       err = ::CreateNibReference(CFSTR("main"), &nibRef);
00388       if (err) return -1;
00389       
00390         // Once the nib reference is created, set the menu bar. "MainMenu" is the name of the menu bar
00391         // object. This name is set in InterfaceBuilder when the nib is created.
00392         err = ::SetMenuBarFromNib(nibRef, CFSTR("MenuBar"));
00393         if (err) return -1;
00394         
00395           // We don't need the nib reference anymore.
00396           ::DisposeNibReference(nibRef);
00397     */
00398 #endif // __APPLE__
00399     
00400     // We don't use threads directly in the BGE, but we need to call this so things like
00401     // freeing up GPU_Textures works correctly.
00402     BLI_threadapi_init();
00403 
00404     RNA_init();
00405 
00406     init_nodesystem();
00407     
00408     initglobals();
00409 
00410     U.gameflags |= USER_DISABLE_VBO;
00411     // We load our own G.main, so free the one that initglobals() gives us
00412     free_main(G.main);
00413     G.main = NULL;
00414 
00415     IMB_init();
00416 
00417     // Setup builtin font for BLF (mostly copied from creator.c, wm_init_exit.c and interface_style.c)
00418     BLF_init(11, U.dpi);
00419     BLF_lang_init();
00420     BLF_lang_encoding("");
00421     BLF_lang_set("");
00422 
00423     BLF_load_mem("default", (unsigned char*)datatoc_bfont_ttf, datatoc_bfont_ttf_size);
00424 
00425     // Parse command line options
00426 #if defined(DEBUG)
00427     printf("argv[0] = '%s'\n", argv[0]);
00428 #endif
00429 
00430 #ifdef WIN32
00431     if (scr_saver_init(argc, argv))
00432     {
00433         switch (scr_saver_mode)
00434         {
00435         case SCREEN_SAVER_MODE_CONFIGURATION:
00436             MessageBox(scr_saver_hwnd, "This screen saver has no options that you can set", "Screen Saver", MB_OK);
00437             break;
00438         case SCREEN_SAVER_MODE_PASSWORD:
00439             /* This is W95 only, which we currently do not support.
00440                Fall-back to normal screen saver behaviour in that case... */
00441         case SCREEN_SAVER_MODE_SAVER:
00442             fullScreen = true;
00443             fullScreenParFound = true;
00444             break;
00445 
00446         case SCREEN_SAVER_MODE_PREVIEW:
00447             /* This will actually be handled somewhere below... */
00448             break;
00449         }
00450     }
00451 #endif
00452     // XXX add the ability to change this values to the command line parsing.
00453     U.mixbufsize = 2048;
00454     U.audiodevice = 2;
00455     U.audiorate = 44100;
00456     U.audioformat = 0x24;
00457     U.audiochannels = 2;
00458 
00459     // XXX this one too
00460     U.anisotropic_filter = 2;
00461 
00462     sound_init_once();
00463 
00464     /* if running blenderplayer the last argument can't be parsed since it has to be the filename. */
00465     isBlenderPlayer = !BLO_is_a_runtime(argv[0]);
00466     if (isBlenderPlayer)
00467         validArguments = argc - 1;
00468     else
00469         validArguments = argc;
00470 
00471     for (i = 1; (i < validArguments) && !error 
00472 #ifdef WIN32
00473         && scr_saver_mode == SCREEN_SAVER_MODE_NONE
00474 #endif
00475         ;)
00476 
00477     {
00478 #if defined(DEBUG)
00479         printf("argv[%d] = '%s'   , %i\n", i, argv[i],argc);
00480 #endif
00481         if (argv[i][0] == '-')
00482         {
00483             /* ignore all args after " - ", allow python to have own args */
00484             if (argv[i][1]=='\0') {
00485                 argc_py_clamped= i;
00486                 break;
00487             }
00488             
00489             switch (argv[i][1])
00490             {
00491             case 'g':
00492                 // Parse game options
00493                 {
00494                     i++;
00495                     if (i <= validArguments)
00496                     {
00497                         char* paramname = argv[i];
00498                         // Check for single value versus assignment
00499                         if (i+1 <= validArguments && (*(argv[i+1]) == '='))
00500                         {
00501                             i++;
00502                             if (i + 1 <= validArguments)
00503                             {
00504                                 i++;
00505                                 // Assignment
00506                                 SYS_WriteCommandLineInt(syshandle, paramname, atoi(argv[i]));
00507                                 SYS_WriteCommandLineFloat(syshandle, paramname, atof(argv[i]));
00508                                 SYS_WriteCommandLineString(syshandle, paramname, argv[i]);
00509 #if defined(DEBUG)
00510                                 printf("%s = '%s'\n", paramname, argv[i]);
00511 #endif
00512                                 i++;
00513                             }
00514                             else
00515                             {
00516                                 error = true;
00517                                 printf("error: argument assignment %s without value.\n", paramname);
00518                             }
00519                         }
00520                         else
00521                         {
00522 //                          SYS_WriteCommandLineInt(syshandle, argv[i++], 1);
00523                         }
00524                     }
00525                 }
00526                 break;
00527 
00528             case 'd':
00529                 i++;
00530                 G.f |= G_DEBUG;     /* std output printf's */
00531                 MEM_set_memory_debug();
00532                 break;
00533 
00534             case 'f':
00535                 i++;
00536                 fullScreen = true;
00537                 fullScreenParFound = true;
00538                 if ((i + 2) <= validArguments && argv[i][0] != '-' && argv[i+1][0] != '-')
00539                 {
00540                     fullScreenWidth = atoi(argv[i++]);
00541                     fullScreenHeight = atoi(argv[i++]);
00542                     if ((i + 1) <= validArguments && argv[i][0] != '-')
00543                     {
00544                         fullScreenBpp = atoi(argv[i++]);
00545                         if ((i + 1) <= validArguments && argv[i][0] != '-')
00546                             fullScreenFrequency = atoi(argv[i++]);
00547                     }
00548                 }
00549                 break;
00550             case 'w':
00551                 // Parse window position and size options
00552                 i++;
00553                 fullScreen = false;
00554                 windowParFound = true;
00555 
00556                 if ((i + 2) <= validArguments && argv[i][0] != '-' && argv[i+1][0] != '-')
00557                 {
00558                     windowWidth = atoi(argv[i++]);
00559                     windowHeight = atoi(argv[i++]);
00560                     if ((i + 2) <= validArguments && argv[i][0] != '-' && argv[i+1][0] != '-')
00561                     {
00562                         windowLeft = atoi(argv[i++]);
00563                         windowTop = atoi(argv[i++]);
00564                     }
00565                 }
00566                 break;
00567                     
00568             case 'h':
00569                 usage(argv[0], isBlenderPlayer);
00570                 return 0;
00571                 break;
00572             case 'i':
00573                 i++;
00574                 if ( (i + 1) <= validArguments )
00575                     parentWindow = atoi(argv[i++]); 
00576                 else {
00577                     error = true;
00578                     printf("error: too few options for parent window argument.\n");
00579                 }
00580 #if defined(DEBUG)
00581                 printf("XWindows ID = %d\n", parentWindow);
00582 #endif // defined(DEBUG)
00583                 break;
00584             case 'm':
00585                 i++;
00586                 samplesParFound = true;
00587                 if ((i+1) <= validArguments )
00588                     aasamples = atoi(argv[i++]);
00589                 else
00590                 {
00591                     error = true;
00592                     printf("error: No argument supplied for -m");
00593                 }
00594                 break;
00595             case 'c':
00596                 i++;
00597 #ifdef WIN32
00598                 closeConsole = false;
00599 #endif
00600                 break;
00601             case 's':  // stereo
00602                 i++;
00603                 if ((i + 1) <= validArguments)
00604                 {
00605                     stereomode = (RAS_IRasterizer::StereoMode) atoi(argv[i]);
00606                     if (stereomode < RAS_IRasterizer::RAS_STEREO_NOSTEREO || stereomode >= RAS_IRasterizer::RAS_STEREO_MAXSTEREO)
00607                         stereomode = RAS_IRasterizer::RAS_STEREO_NOSTEREO;
00608                     
00609                     if(!strcmp(argv[i], "nostereo"))  // ok, redundant but clear
00610                         stereomode = RAS_IRasterizer::RAS_STEREO_NOSTEREO;
00611                     
00612                     // only the hardware pageflip method needs a stereo window
00613                     else if(!strcmp(argv[i], "hwpageflip")) {
00614                         stereomode = RAS_IRasterizer::RAS_STEREO_QUADBUFFERED;
00615                         stereoWindow = true;
00616                     }
00617                     else if(!strcmp(argv[i], "syncdoubling"))
00618                         stereomode = RAS_IRasterizer::RAS_STEREO_ABOVEBELOW;
00619                     
00620                     else if(!strcmp(argv[i], "anaglyph"))
00621                         stereomode = RAS_IRasterizer::RAS_STEREO_ANAGLYPH;
00622                     
00623                     else if(!strcmp(argv[i], "sidebyside"))
00624                         stereomode = RAS_IRasterizer::RAS_STEREO_SIDEBYSIDE;
00625                     
00626                     else if(!strcmp(argv[i], "vinterlace"))
00627                         stereomode = RAS_IRasterizer::RAS_STEREO_VINTERLACE;
00628                     
00629 #if 0
00630                     // future stuff
00631                     else if(!strcmp(argv[i], "stencil")
00632                         stereomode = RAS_STEREO_STENCIL;
00633 #endif
00634                     
00635                     i++;
00636                     stereoParFound = true;
00637                     stereoFlag = STEREO_ENABLED;
00638                 }
00639                 else
00640                 {
00641                     error = true;
00642                     printf("error: too few options for stereo argument.\n");
00643                 }
00644                 break;
00645             case 'D':
00646                 stereoFlag = STEREO_DOME;
00647                 stereomode = RAS_IRasterizer::RAS_STEREO_DOME;
00648                 i++;
00649                 if ((i + 1) <= validArguments)
00650                 {
00651                     if(!strcmp(argv[i], "angle")){
00652                         i++;
00653                         domeFov = atoi(argv[i++]);
00654                     }
00655                     if(!strcmp(argv[i], "tilt")){
00656                         i++;
00657                         domeTilt = atoi(argv[i++]);
00658                     }
00659                     if(!strcmp(argv[i], "warpdata")){
00660                         i++;
00661                         domeWarp = argv[i++];
00662                     }
00663                     if(!strcmp(argv[i], "mode")){
00664                         i++;
00665                         if(!strcmp(argv[i], "fisheye"))
00666                             domeMode = DOME_FISHEYE;
00667                             
00668                         else if(!strcmp(argv[i], "truncatedfront"))
00669                             domeMode = DOME_TRUNCATED_FRONT;
00670                             
00671                         else if(!strcmp(argv[i], "truncatedrear"))
00672                             domeMode = DOME_TRUNCATED_REAR;
00673                             
00674                         else if(!strcmp(argv[i], "cubemap"))
00675                             domeMode = DOME_ENVMAP;
00676                             
00677                         else if(!strcmp(argv[i], "sphericalpanoramic"))
00678                             domeMode = DOME_PANORAM_SPH;
00679 
00680                         else
00681                             printf("error: %s is not a valid dome mode.\n", argv[i]);
00682                     }
00683                     i++;
00684                 }
00685                 break;
00686             default:
00687                 printf("Unknown argument: %s\n", argv[i++]);
00688                 break;
00689             }
00690         }
00691         else
00692         {
00693             i++;
00694         }
00695     }
00696     
00697     if ((windowWidth < kMinWindowWidth) || (windowHeight < kMinWindowHeight))
00698     {
00699         error = true;
00700         printf("error: window size too small.\n");
00701     }
00702     
00703     if (error )
00704     {
00705         usage(argv[0], isBlenderPlayer);
00706         return 0;
00707     }
00708 
00709 #ifdef WIN32
00710     if (scr_saver_mode != SCREEN_SAVER_MODE_CONFIGURATION)
00711 #endif
00712     {
00713 #ifdef __APPLE__
00714         //SYS_WriteCommandLineInt(syshandle, "show_framerate", 1);
00715         //SYS_WriteCommandLineInt(syshandle, "nomipmap", 1);
00716         //fullScreen = false;       // Can't use full screen
00717 #endif
00718 
00719         if (SYS_GetCommandLineInt(syshandle, "nomipmap", 0))
00720         {
00721             GPU_set_mipmap(0);
00722         }
00723 
00724         GPU_set_anisotropic(U.anisotropic_filter);
00725         
00726         // Create the system
00727         if (GHOST_ISystem::createSystem() == GHOST_kSuccess)
00728         {
00729             GHOST_ISystem* system = GHOST_ISystem::getSystem();
00730             assertd(system);
00731             
00732             if (!fullScreenWidth || !fullScreenHeight)
00733                 system->getMainDisplayDimensions(fullScreenWidth, fullScreenHeight);
00734             // process first batch of events. If the user
00735             // drops a file on top off the blenderplayer icon, we 
00736             // receive an event with the filename
00737             
00738             system->processEvents(0);
00739             
00740             // this bracket is needed for app (see below) to get out
00741             // of scope before GHOST_ISystem::disposeSystem() is called.
00742             {
00743                 int exitcode = KX_EXIT_REQUEST_NO_REQUEST;
00744                 STR_String exitstring = "";
00745                 GPG_Application app(system);
00746                 bool firstTimeRunning = true;
00747                 char filename[FILE_MAX];
00748                 char pathname[FILE_MAX];
00749                 char *titlename;
00750 
00751                 get_filename(argc_py_clamped, argv, filename);
00752                 if(filename[0])
00753                     BLI_path_cwd(filename);
00754                 
00755 
00756                 // fill the GlobalSettings with the first scene files
00757                 // those may change during the game and persist after using Game Actuator
00758                 GlobalSettings gs;
00759 
00760                 do
00761                 {
00762                     // Read the Blender file
00763                     BlendFileData *bfd;
00764                     
00765                     // if we got an exitcode 3 (KX_EXIT_REQUEST_START_OTHER_GAME) load a different file
00766                     if (exitcode == KX_EXIT_REQUEST_START_OTHER_GAME)
00767                     {
00768                         char basedpath[FILE_MAX];
00769                         
00770                         // base the actuator filename relative to the last file
00771                         BLI_strncpy(basedpath, exitstring.Ptr(), sizeof(basedpath));
00772                         BLI_path_abs(basedpath, pathname);
00773                         
00774                         bfd = load_game_data(basedpath);
00775 
00776                         if (!bfd)
00777                         {
00778                             // just add "//" in front of it
00779                             char temppath[242];
00780                             strcpy(temppath, "//");
00781                             strcat(temppath, basedpath);
00782                 
00783                             BLI_path_abs(temppath, pathname);
00784                             bfd = load_game_data(temppath);
00785                         }
00786                     }
00787                     else
00788                     {
00789                         bfd = load_game_data(BLI_program_path(), filename[0]? filename: NULL);
00790                     }
00791                     
00792                     //::printf("game data loaded from %s\n", filename);
00793                     
00794                     if (!bfd) {
00795                         usage(argv[0], isBlenderPlayer);
00796                         error = true;
00797                         exitcode = KX_EXIT_REQUEST_QUIT_GAME;
00798                     } 
00799                     else 
00800                     {
00801 #ifdef WIN32
00802 #if !defined(DEBUG)
00803                         if (closeConsole)
00804                         {
00805                             //::FreeConsole();    // Close a console window
00806                         }
00807 #endif // !defined(DEBUG)
00808 #endif // WIN32
00809                         Main *maggie = bfd->main;
00810                         Scene *scene = bfd->curscene;
00811                         G.main = maggie;
00812 
00813                         if (firstTimeRunning) {
00814                             G.fileflags  = bfd->fileflags;
00815 
00816                             gs.matmode= scene->gm.matmode;
00817                             gs.glslflag= scene->gm.flag;
00818                         }
00819 
00820                         //Seg Fault; icon.c gIcons == 0
00821                         BKE_icons_init(1);
00822                         
00823                         titlename = maggie->name;
00824                         
00825                         // Check whether the game should be displayed full-screen
00826                         if ((!fullScreenParFound) && (!windowParFound))
00827                         {
00828                             // Only use file settings when command line did not override
00829                             if ((scene->gm.playerflag & GAME_PLAYER_FULLSCREEN)) {
00830                                 //printf("fullscreen option found in Blender file\n");
00831                                 fullScreen = true;
00832                                 fullScreenWidth= scene->gm.xplay;
00833                                 fullScreenHeight= scene->gm.yplay;
00834                                 fullScreenFrequency= scene->gm.freqplay;
00835                                 fullScreenBpp = scene->gm.depth;
00836                             }
00837                             else
00838                             {
00839                                 fullScreen = false;
00840                                 windowWidth = scene->gm.xplay;
00841                                 windowHeight = scene->gm.yplay;
00842                             }
00843                         }
00844                         
00845                         
00846                         // Check whether the game should be displayed in stereo
00847                         if (!stereoParFound)
00848                         {
00849                             if(scene->gm.stereoflag == STEREO_ENABLED){
00850                                 stereomode = (RAS_IRasterizer::StereoMode) scene->gm.stereomode;
00851                                 if (stereomode != RAS_IRasterizer::RAS_STEREO_QUADBUFFERED)
00852                                     stereoWindow = true;
00853                             }
00854                         }
00855                         else
00856                             scene->gm.stereoflag = STEREO_ENABLED;
00857 
00858                         if (!samplesParFound)
00859                             aasamples = scene->gm.aasamples;
00860 
00861                         if (stereoFlag == STEREO_DOME){
00862                             stereomode = RAS_IRasterizer::RAS_STEREO_DOME;
00863                             scene->gm.stereoflag = STEREO_DOME;
00864                             if (domeFov > 89)
00865                                 scene->gm.dome.angle = domeFov;
00866                             if (domeTilt > -180)
00867                                 scene->gm.dome.tilt = domeTilt;
00868                             if (domeMode > 0)
00869                                 scene->gm.dome.mode = domeMode;
00870                             if (domeWarp)
00871                             {
00872                                 //XXX to do: convert relative to absolute path
00873                                 domeText= add_text(domeWarp, "");
00874                                 if(!domeText)
00875                                     printf("error: invalid warpdata text file - %s\n", domeWarp);
00876                                 else
00877                                     scene->gm.dome.warptext = domeText;
00878                             }
00879                         }
00880                         
00881                         //                  GPG_Application app (system, maggie, startscenename);
00882                         app.SetGameEngineData(maggie, scene, &gs, argc, argv); /* this argc cant be argc_py_clamped, since python uses it */
00883                         BLI_strncpy(pathname, maggie->name, sizeof(pathname));
00884                         if(G.main != maggie) {
00885                             BLI_strncpy(G.main->name, maggie->name, sizeof(G.main->name));
00886                         }
00887 #ifdef WITH_PYTHON
00888                         setGamePythonPath(G.main->name);
00889 #endif
00890                         if (firstTimeRunning)
00891                         {
00892                             firstTimeRunning = false;
00893 
00894                             if (fullScreen)
00895                             {
00896 #ifdef WIN32
00897                                 if (scr_saver_mode == SCREEN_SAVER_MODE_SAVER)
00898                                 {
00899                                     app.startScreenSaverFullScreen(fullScreenWidth, fullScreenHeight, fullScreenBpp, fullScreenFrequency,
00900                                         stereoWindow, stereomode, aasamples);
00901                                 }
00902                                 else
00903 #endif
00904                                 {
00905                                     app.startFullScreen(fullScreenWidth, fullScreenHeight, fullScreenBpp, fullScreenFrequency,
00906                                         stereoWindow, stereomode, aasamples, (scene->gm.playerflag & GAME_PLAYER_DESKTOP_RESOLUTION));
00907                                 }
00908                             }
00909                             else
00910                             {
00911 #ifdef __APPLE__
00912                                 // on Mac's we'll show the executable name instead of the 'game.blend' name
00913                                 char tempname[1024], *appstring;
00914                                 ::strcpy(tempname, titlename);
00915                                 
00916                                 appstring = strstr(tempname, ".app/");
00917                                 if (appstring) {
00918                                     appstring[2] = 0;
00919                                     titlename = &tempname[0];
00920                                 }
00921 #endif
00922                                 // Strip the path so that we have the name of the game file
00923                                 STR_String path = titlename;
00924 #ifndef WIN32
00925                                 vector<STR_String> parts = path.Explode('/');
00926 #else  // WIN32
00927                                 vector<STR_String> parts = path.Explode('\\');
00928 #endif // WIN32                        
00929                                 STR_String title;
00930                                 if (parts.size())
00931                                 {
00932                                     title = parts[parts.size()-1];
00933                                     parts = title.Explode('.');
00934                                     if (parts.size() > 1)
00935                                     {
00936                                         title = parts[0];
00937                                     }
00938                                 }
00939                                 else
00940                                 {
00941                                     title = "blenderplayer";
00942                                 }
00943 #ifdef WIN32
00944                                 if (scr_saver_mode == SCREEN_SAVER_MODE_PREVIEW)
00945                                 {
00946                                     app.startScreenSaverPreview(scr_saver_hwnd, stereoWindow, stereomode, aasamples);
00947                                 }
00948                                 else
00949 #endif
00950                                 {
00951                                                                                                         if (parentWindow != 0)
00952                                         app.startEmbeddedWindow(title, parentWindow, stereoWindow, stereomode, aasamples);
00953                                     else
00954                                         app.startWindow(title, windowLeft, windowTop, windowWidth, windowHeight,
00955                                         stereoWindow, stereomode, aasamples);
00956                                 }
00957                             }
00958                         }
00959                         else
00960                         {
00961                             app.StartGameEngine(stereomode);
00962                             exitcode = KX_EXIT_REQUEST_NO_REQUEST;
00963                         }
00964                         
00965                         // Add the application as event consumer
00966                         system->addEventConsumer(&app);
00967                         
00968                         // Enter main loop
00969                         bool run = true;
00970                         while (run)
00971                         {
00972                             system->processEvents(false);
00973                             system->dispatchEvents();
00974                             if ((exitcode = app.getExitRequested()))
00975                             {
00976                                 run = false;
00977                                 exitstring = app.getExitString();
00978                                 gs = *app.getGlobalSettings();
00979                             }
00980                         }
00981                         app.StopGameEngine();
00982 
00983                         /* 'app' is freed automatic when out of scope. 
00984                          * removal is needed else the system will free an already freed value */
00985                         system->removeEventConsumer(&app);
00986 
00987                         BLO_blendfiledata_free(bfd);
00988                     }
00989                 } while (exitcode == KX_EXIT_REQUEST_RESTART_GAME || exitcode == KX_EXIT_REQUEST_START_OTHER_GAME);
00990             }
00991 
00992             // Seg Fault; icon.c gIcons == 0
00993             BKE_icons_free();
00994 
00995             // Dispose the system
00996             GHOST_ISystem::disposeSystem();
00997         } else {
00998             error = true;
00999             printf("error: couldn't create a system.\n");
01000         }
01001     }
01002 
01003     // Cleanup
01004     RNA_exit();
01005     BLF_exit();
01006 
01007 #ifdef WITH_INTERNATIONAL
01008     BLF_free_unifont();
01009 #endif
01010 
01011     IMB_exit();
01012     free_nodesystem();
01013 
01014     SYS_DeleteSystem(syshandle);
01015 
01016     int totblock= MEM_get_memory_blocks_in_use();
01017     if(totblock!=0) {
01018         printf("Error Totblock: %d\n",totblock);
01019         MEM_set_error_callback(mem_error_cb);
01020         MEM_printmemlist();
01021     }
01022 
01023     return error ? -1 : 0;
01024 }
01025 
01026