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