Blender V2.61 - r43446
|
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