PageRenderTime 50ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/blender-2.63a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp

#
C++ | 1026 lines | 914 code | 55 blank | 57 comment | 64 complexity | 36c90d29b3104a408eb996b2cf0cbf7e MD5 | raw file
Possible License(s): GPL-3.0, GPL-2.0, BSD-3-Clause, LGPL-3.0, BSD-2-Clause, Apache-2.0, AGPL-1.0
  1. /*
  2. * ***** BEGIN GPL LICENSE BLOCK *****
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License
  6. * as published by the Free Software Foundation; either version 2
  7. * of the License, or (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software Foundation,
  16. * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  17. *
  18. * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
  19. * All rights reserved.
  20. *
  21. * The Original Code is: all of this file.
  22. *
  23. * Contributor(s): none yet.
  24. *
  25. * ***** END GPL LICENSE BLOCK *****
  26. * Start up of the Blender Player on GHOST.
  27. */
  28. /** \file gameengine/GamePlayer/ghost/GPG_ghost.cpp
  29. * \ingroup player
  30. */
  31. #include <iostream>
  32. #include <math.h>
  33. #ifdef __linux__
  34. #ifdef __alpha__
  35. #include <signal.h>
  36. #endif /* __alpha__ */
  37. #endif /* __linux__ */
  38. #ifdef __APPLE__
  39. // Can't use Carbon right now because of double defined type ID (In Carbon.h and DNA_ID.h, sigh)
  40. //#include <Carbon/Carbon.h>
  41. //#include <CFBundle.h>
  42. #endif // __APPLE__
  43. #include "KX_KetsjiEngine.h"
  44. #include "KX_PythonInit.h"
  45. /**********************************
  46. * Begin Blender include block
  47. **********************************/
  48. #ifdef __cplusplus
  49. extern "C"
  50. {
  51. #endif // __cplusplus
  52. #include "MEM_guardedalloc.h"
  53. #include "BKE_blender.h"
  54. #include "BKE_global.h"
  55. #include "BKE_icons.h"
  56. #include "BKE_node.h"
  57. #include "BKE_report.h"
  58. #include "BKE_library.h"
  59. #include "BLI_threads.h"
  60. #include "BLI_blenlib.h"
  61. #include "DNA_scene_types.h"
  62. #include "DNA_userdef_types.h"
  63. #include "BLO_readfile.h"
  64. #include "BLO_runtime.h"
  65. #include "IMB_imbuf.h"
  66. #include "BKE_text.h"
  67. #include "BKE_sound.h"
  68. int GHOST_HACK_getFirstFile(char buf[]);
  69. // For BLF
  70. #include "BLF_api.h"
  71. #include "BLF_translation.h"
  72. extern int datatoc_bfont_ttf_size;
  73. extern char datatoc_bfont_ttf[];
  74. #ifdef __cplusplus
  75. }
  76. #endif // __cplusplus
  77. #include "GPU_draw.h"
  78. /**********************************
  79. * End Blender include block
  80. **********************************/
  81. #include "BL_System.h"
  82. #include "GPG_Application.h"
  83. #include "GHOST_ISystem.h"
  84. #include "RAS_IRasterizer.h"
  85. #include "BKE_main.h"
  86. #include "BKE_utildefines.h"
  87. #include "RNA_define.h"
  88. #ifdef WIN32
  89. #include <windows.h>
  90. #if !defined(DEBUG)
  91. #include <wincon.h>
  92. #endif // !defined(DEBUG)
  93. #endif // WIN32
  94. const int kMinWindowWidth = 100;
  95. const int kMinWindowHeight = 100;
  96. static void mem_error_cb(const char *errorStr)
  97. {
  98. fprintf(stderr, "%s", errorStr);
  99. fflush(stderr);
  100. }
  101. #ifdef WIN32
  102. typedef enum
  103. {
  104. SCREEN_SAVER_MODE_NONE = 0,
  105. SCREEN_SAVER_MODE_PREVIEW,
  106. SCREEN_SAVER_MODE_SAVER,
  107. SCREEN_SAVER_MODE_CONFIGURATION,
  108. SCREEN_SAVER_MODE_PASSWORD,
  109. } ScreenSaverMode;
  110. static ScreenSaverMode scr_saver_mode = SCREEN_SAVER_MODE_NONE;
  111. static HWND scr_saver_hwnd = NULL;
  112. static BOOL scr_saver_init(int argc, char **argv)
  113. {
  114. scr_saver_mode = SCREEN_SAVER_MODE_NONE;
  115. scr_saver_hwnd = NULL;
  116. BOOL ret = FALSE;
  117. int len = ::strlen(argv[0]);
  118. if (len > 4 && !::stricmp(".scr", argv[0] + len - 4))
  119. {
  120. scr_saver_mode = SCREEN_SAVER_MODE_CONFIGURATION;
  121. ret = TRUE;
  122. if (argc >= 2)
  123. {
  124. if (argc >= 3)
  125. {
  126. scr_saver_hwnd = (HWND) ::atoi(argv[2]);
  127. }
  128. if (!::stricmp("/c", argv[1]))
  129. {
  130. scr_saver_mode = SCREEN_SAVER_MODE_CONFIGURATION;
  131. if (scr_saver_hwnd == NULL)
  132. scr_saver_hwnd = ::GetForegroundWindow();
  133. }
  134. else if (!::stricmp("/s", argv[1]))
  135. {
  136. scr_saver_mode = SCREEN_SAVER_MODE_SAVER;
  137. }
  138. else if (!::stricmp("/a", argv[1]))
  139. {
  140. scr_saver_mode = SCREEN_SAVER_MODE_PASSWORD;
  141. }
  142. else if (!::stricmp("/p", argv[1])
  143. || !::stricmp("/l", argv[1]))
  144. {
  145. scr_saver_mode = SCREEN_SAVER_MODE_PREVIEW;
  146. }
  147. }
  148. }
  149. return ret;
  150. }
  151. #endif /* WIN32 */
  152. void usage(const char* program, bool isBlenderPlayer)
  153. {
  154. const char * consoleoption;
  155. const char * example_filename = "";
  156. const char * example_pathname = "";
  157. #ifdef _WIN32
  158. consoleoption = "-c ";
  159. #else
  160. consoleoption = "";
  161. #endif
  162. if (isBlenderPlayer) {
  163. example_filename = "filename.blend";
  164. #ifdef _WIN32
  165. example_pathname = "c:\\";
  166. #else
  167. example_pathname = "/home/user/";
  168. #endif
  169. }
  170. printf("usage: %s [-w [w h l t]] [-f [fw fh fb ff]] %s[-g gamengineoptions] "
  171. "[-s stereomode] [-m aasamples] %s\n", program, consoleoption, example_filename);
  172. printf(" -h: Prints this command summary\n\n");
  173. printf(" -w: display in a window\n");
  174. printf(" --Optional parameters--\n");
  175. printf(" w = window width\n");
  176. printf(" h = window height\n\n");
  177. printf(" l = window left coordinate\n");
  178. printf(" t = window top coordinate\n");
  179. printf(" Note: If w or h is defined, both must be defined.\n");
  180. printf(" Also, if l or t is defined, all options must be used.\n\n");
  181. printf(" -f: start game in full screen mode\n");
  182. printf(" --Optional parameters--\n");
  183. printf(" fw = full screen mode pixel width\n");
  184. printf(" fh = full screen mode pixel height\n\n");
  185. printf(" fb = full screen mode bits per pixel\n");
  186. printf(" ff = full screen mode frequency\n");
  187. printf(" Note: If fw or fh is defined, both must be defined.\n");
  188. printf(" Also, if fb is used, fw and fh must be used. ff requires all options.\n\n");
  189. printf(" -s: start player in stereo\n");
  190. printf(" stereomode: hwpageflip (Quad buffered shutter glasses)\n");
  191. printf(" syncdoubling (Above Below)\n");
  192. printf(" sidebyside (Left Right)\n");
  193. printf(" anaglyph (Red-Blue glasses)\n");
  194. printf(" vinterlace (Vertical interlace for autostereo display)\n");
  195. printf(" depending on the type of stereo you want\n\n");
  196. printf(" -D: start player in dome mode\n");
  197. printf(" --Optional parameters--\n");
  198. printf(" angle = field of view in degrees\n");
  199. printf(" tilt = tilt angle in degrees\n");
  200. printf(" warpdata = a file to use for warping the image (absolute path)\n");
  201. printf(" mode: fisheye (Fisheye)\n");
  202. printf(" truncatedfront (Front-Truncated)\n");
  203. printf(" truncatedrear (Rear-Truncated)\n");
  204. printf(" cubemap (Cube Map)\n");
  205. printf(" sphericalpanoramic (Spherical Panoramic)\n");
  206. printf(" depending on the type of dome you are using\n\n");
  207. printf(" -m: maximum anti-aliasing (eg. 2,4,8,16)\n\n");
  208. printf(" -i: parent windows ID\n\n");
  209. #ifdef _WIN32
  210. printf(" -c: keep console window open\n\n");
  211. #endif
  212. printf(" -d: turn debugging on\n\n");
  213. printf(" -g: game engine options:\n\n");
  214. printf(" Name Default Description\n");
  215. printf(" ------------------------------------------------------------------------\n");
  216. printf(" fixedtime 0 \"Enable all frames\"\n");
  217. printf(" nomipmap 0 Disable mipmaps\n");
  218. printf(" show_framerate 0 Show the frame rate\n");
  219. printf(" show_properties 0 Show debug properties\n");
  220. printf(" show_profile 0 Show profiling information\n");
  221. printf(" blender_material 0 Enable material settings\n");
  222. printf(" ignore_deprecation_warnings 1 Ignore deprecation warnings\n");
  223. printf("\n");
  224. printf(" - : all arguments after this are ignored, allowing python to access them from sys.argv\n");
  225. printf("\n");
  226. printf("example: %s -w 320 200 10 10 -g noaudio%s%s\n", program, example_pathname, example_filename);
  227. printf("example: %s -g show_framerate = 0 %s%s\n", program, example_pathname, example_filename);
  228. printf("example: %s -i 232421 -m 16 %s%s\n\n", program, example_pathname, example_filename);
  229. }
  230. static void get_filename(int argc, char **argv, char *filename)
  231. {
  232. #ifdef __APPLE__
  233. /* On Mac we park the game file (called game.blend) in the application bundle.
  234. * The executable is located in the bundle as well.
  235. * Therefore, we can locate the game relative to the executable.
  236. */
  237. int srclen = ::strlen(argv[0]);
  238. int len = 0;
  239. char *gamefile = NULL;
  240. filename[0] = '\0';
  241. if (argc > 1) {
  242. if (BLI_exists(argv[argc-1])) {
  243. BLI_strncpy(filename, argv[argc-1], FILE_MAX);
  244. }
  245. if (::strncmp(argv[argc-1], "-psn_", 5)==0) {
  246. static char firstfilebuf[512];
  247. if (GHOST_HACK_getFirstFile(firstfilebuf)) {
  248. BLI_strncpy(filename, firstfilebuf, FILE_MAX);
  249. }
  250. }
  251. }
  252. srclen -= ::strlen("MacOS/blenderplayer");
  253. if (srclen > 0) {
  254. len = srclen + ::strlen("Resources/game.blend");
  255. gamefile = new char [len + 1];
  256. ::strcpy(gamefile, argv[0]);
  257. ::strcpy(gamefile + srclen, "Resources/game.blend");
  258. //::printf("looking for file: %s\n", filename);
  259. if (BLI_exists(gamefile))
  260. BLI_strncpy(filename, gamefile, FILE_MAX);
  261. delete [] gamefile;
  262. }
  263. #else
  264. filename[0] = '\0';
  265. if (argc > 1)
  266. BLI_strncpy(filename, argv[argc-1], FILE_MAX);
  267. #endif // !_APPLE
  268. }
  269. static BlendFileData *load_game_data(const char *progname, char *filename = NULL, char *relativename = NULL)
  270. {
  271. ReportList reports;
  272. BlendFileData *bfd = NULL;
  273. BKE_reports_init(&reports, RPT_STORE);
  274. /* try to load ourself, will only work if we are a runtime */
  275. if (BLO_is_a_runtime(progname)) {
  276. bfd= BLO_read_runtime(progname, &reports);
  277. if (bfd) {
  278. bfd->type= BLENFILETYPE_RUNTIME;
  279. BLI_strncpy(bfd->main->name, progname, sizeof(bfd->main->name));
  280. }
  281. } else {
  282. bfd= BLO_read_from_file(progname, &reports);
  283. }
  284. if (!bfd && filename) {
  285. bfd = load_game_data(filename);
  286. if (!bfd) {
  287. printf("Loading %s failed: ", filename);
  288. BKE_reports_print(&reports, RPT_ERROR);
  289. }
  290. }
  291. BKE_reports_clear(&reports);
  292. return bfd;
  293. }
  294. int main(int argc, char** argv)
  295. {
  296. int i;
  297. int argc_py_clamped= argc; /* use this so python args can be added after ' - ' */
  298. bool error = false;
  299. SYS_SystemHandle syshandle = SYS_GetSystem();
  300. bool fullScreen = false;
  301. bool fullScreenParFound = false;
  302. bool windowParFound = false;
  303. #ifdef WIN32
  304. bool closeConsole = true;
  305. #endif
  306. RAS_IRasterizer::StereoMode stereomode = RAS_IRasterizer::RAS_STEREO_NOSTEREO;
  307. bool stereoWindow = false;
  308. bool stereoParFound = false;
  309. int stereoFlag = STEREO_NOSTEREO;
  310. int domeFov = -1;
  311. int domeTilt = -200;
  312. int domeMode = 0;
  313. char* domeWarp = NULL;
  314. Text *domeText = NULL;
  315. int windowLeft = 100;
  316. int windowTop = 100;
  317. int windowWidth = 640;
  318. int windowHeight = 480;
  319. GHOST_TUns32 fullScreenWidth = 0;
  320. GHOST_TUns32 fullScreenHeight= 0;
  321. int fullScreenBpp = 32;
  322. int fullScreenFrequency = 60;
  323. GHOST_TEmbedderWindowID parentWindow = 0;
  324. bool isBlenderPlayer = false;
  325. int validArguments=0;
  326. bool samplesParFound = false;
  327. GHOST_TUns16 aasamples = 0;
  328. #ifdef __linux__
  329. #ifdef __alpha__
  330. signal (SIGFPE, SIG_IGN);
  331. #endif /* __alpha__ */
  332. #endif /* __linux__ */
  333. BLI_init_program_path(argv[0]);
  334. BLI_init_temporary_dir(NULL);
  335. #ifdef __APPLE__
  336. // Can't use Carbon right now because of double defined type ID (In Carbon.h and DNA_ID.h, sigh)
  337. /*
  338. IBNibRef nibRef;
  339. WindowRef window;
  340. OSStatus err;
  341. // Create a Nib reference passing the name of the nib file (without the .nib extension)
  342. // CreateNibReference only searches into the application bundle.
  343. err = ::CreateNibReference(CFSTR("main"), &nibRef);
  344. if (err) return -1;
  345. // Once the nib reference is created, set the menu bar. "MainMenu" is the name of the menu bar
  346. // object. This name is set in InterfaceBuilder when the nib is created.
  347. err = ::SetMenuBarFromNib(nibRef, CFSTR("MenuBar"));
  348. if (err) return -1;
  349. // We don't need the nib reference anymore.
  350. ::DisposeNibReference(nibRef);
  351. */
  352. #endif // __APPLE__
  353. // We don't use threads directly in the BGE, but we need to call this so things like
  354. // freeing up GPU_Textures works correctly.
  355. BLI_threadapi_init();
  356. RNA_init();
  357. init_nodesystem();
  358. initglobals();
  359. U.gameflags |= USER_DISABLE_VBO;
  360. // We load our own G.main, so free the one that initglobals() gives us
  361. free_main(G.main);
  362. G.main = NULL;
  363. IMB_init();
  364. // Setup builtin font for BLF (mostly copied from creator.c, wm_init_exit.c and interface_style.c)
  365. BLF_init(11, U.dpi);
  366. BLF_lang_init();
  367. BLF_lang_encoding("");
  368. BLF_lang_set("");
  369. BLF_load_mem("default", (unsigned char*)datatoc_bfont_ttf, datatoc_bfont_ttf_size);
  370. // Parse command line options
  371. #if defined(DEBUG)
  372. printf("argv[0] = '%s'\n", argv[0]);
  373. #endif
  374. #ifdef WIN32
  375. if (scr_saver_init(argc, argv))
  376. {
  377. switch (scr_saver_mode)
  378. {
  379. case SCREEN_SAVER_MODE_CONFIGURATION:
  380. MessageBox(scr_saver_hwnd, "This screen saver has no options that you can set", "Screen Saver", MB_OK);
  381. break;
  382. case SCREEN_SAVER_MODE_PASSWORD:
  383. /* This is W95 only, which we currently do not support.
  384. Fall-back to normal screen saver behavior in that case... */
  385. case SCREEN_SAVER_MODE_SAVER:
  386. fullScreen = true;
  387. fullScreenParFound = true;
  388. break;
  389. case SCREEN_SAVER_MODE_PREVIEW:
  390. /* This will actually be handled somewhere below... */
  391. break;
  392. }
  393. }
  394. #endif
  395. // XXX add the ability to change this values to the command line parsing.
  396. U.mixbufsize = 2048;
  397. U.audiodevice = 2;
  398. U.audiorate = 44100;
  399. U.audioformat = 0x24;
  400. U.audiochannels = 2;
  401. // XXX this one too
  402. U.anisotropic_filter = 2;
  403. sound_init_once();
  404. /* if running blenderplayer the last argument can't be parsed since it has to be the filename. */
  405. isBlenderPlayer = !BLO_is_a_runtime(argv[0]);
  406. if (isBlenderPlayer)
  407. validArguments = argc - 1;
  408. else
  409. validArguments = argc;
  410. for (i = 1; (i < validArguments) && !error
  411. #ifdef WIN32
  412. && scr_saver_mode == SCREEN_SAVER_MODE_NONE
  413. #endif
  414. ;)
  415. {
  416. #if defined(DEBUG)
  417. printf("argv[%d] = '%s' , %i\n", i, argv[i],argc);
  418. #endif
  419. if (argv[i][0] == '-')
  420. {
  421. /* ignore all args after " - ", allow python to have own args */
  422. if (argv[i][1]=='\0') {
  423. argc_py_clamped= i;
  424. break;
  425. }
  426. switch (argv[i][1])
  427. {
  428. case 'g':
  429. // Parse game options
  430. {
  431. i++;
  432. if (i <= validArguments)
  433. {
  434. char* paramname = argv[i];
  435. // Check for single value versus assignment
  436. if (i+1 <= validArguments && (*(argv[i+1]) == '='))
  437. {
  438. i++;
  439. if (i + 1 <= validArguments)
  440. {
  441. i++;
  442. // Assignment
  443. SYS_WriteCommandLineInt(syshandle, paramname, atoi(argv[i]));
  444. SYS_WriteCommandLineFloat(syshandle, paramname, atof(argv[i]));
  445. SYS_WriteCommandLineString(syshandle, paramname, argv[i]);
  446. #if defined(DEBUG)
  447. printf("%s = '%s'\n", paramname, argv[i]);
  448. #endif
  449. i++;
  450. }
  451. else
  452. {
  453. error = true;
  454. printf("error: argument assignment %s without value.\n", paramname);
  455. }
  456. }
  457. else
  458. {
  459. // SYS_WriteCommandLineInt(syshandle, argv[i++], 1);
  460. }
  461. }
  462. }
  463. break;
  464. case 'd':
  465. i++;
  466. G.debug |= G_DEBUG; /* std output printf's */
  467. MEM_set_memory_debug();
  468. break;
  469. case 'f':
  470. i++;
  471. fullScreen = true;
  472. fullScreenParFound = true;
  473. if ((i + 2) <= validArguments && argv[i][0] != '-' && argv[i+1][0] != '-')
  474. {
  475. fullScreenWidth = atoi(argv[i++]);
  476. fullScreenHeight = atoi(argv[i++]);
  477. if ((i + 1) <= validArguments && argv[i][0] != '-')
  478. {
  479. fullScreenBpp = atoi(argv[i++]);
  480. if ((i + 1) <= validArguments && argv[i][0] != '-')
  481. fullScreenFrequency = atoi(argv[i++]);
  482. }
  483. }
  484. break;
  485. case 'w':
  486. // Parse window position and size options
  487. i++;
  488. fullScreen = false;
  489. windowParFound = true;
  490. if ((i + 2) <= validArguments && argv[i][0] != '-' && argv[i+1][0] != '-')
  491. {
  492. windowWidth = atoi(argv[i++]);
  493. windowHeight = atoi(argv[i++]);
  494. if ((i + 2) <= validArguments && argv[i][0] != '-' && argv[i+1][0] != '-')
  495. {
  496. windowLeft = atoi(argv[i++]);
  497. windowTop = atoi(argv[i++]);
  498. }
  499. }
  500. break;
  501. case 'h':
  502. usage(argv[0], isBlenderPlayer);
  503. return 0;
  504. break;
  505. case 'i':
  506. i++;
  507. if ( (i + 1) <= validArguments )
  508. parentWindow = atoi(argv[i++]);
  509. else {
  510. error = true;
  511. printf("error: too few options for parent window argument.\n");
  512. }
  513. #if defined(DEBUG)
  514. printf("XWindows ID = %d\n", parentWindow);
  515. #endif // defined(DEBUG)
  516. break;
  517. case 'm':
  518. i++;
  519. samplesParFound = true;
  520. if ((i+1) <= validArguments )
  521. aasamples = atoi(argv[i++]);
  522. else
  523. {
  524. error = true;
  525. printf("error: No argument supplied for -m");
  526. }
  527. break;
  528. case 'c':
  529. i++;
  530. #ifdef WIN32
  531. closeConsole = false;
  532. #endif
  533. break;
  534. case 's': // stereo
  535. i++;
  536. if ((i + 1) <= validArguments)
  537. {
  538. stereomode = (RAS_IRasterizer::StereoMode) atoi(argv[i]);
  539. if (stereomode < RAS_IRasterizer::RAS_STEREO_NOSTEREO || stereomode >= RAS_IRasterizer::RAS_STEREO_MAXSTEREO)
  540. stereomode = RAS_IRasterizer::RAS_STEREO_NOSTEREO;
  541. if (!strcmp(argv[i], "nostereo")) // ok, redundant but clear
  542. stereomode = RAS_IRasterizer::RAS_STEREO_NOSTEREO;
  543. // only the hardware pageflip method needs a stereo window
  544. else if (!strcmp(argv[i], "hwpageflip")) {
  545. stereomode = RAS_IRasterizer::RAS_STEREO_QUADBUFFERED;
  546. stereoWindow = true;
  547. }
  548. else if (!strcmp(argv[i], "syncdoubling"))
  549. stereomode = RAS_IRasterizer::RAS_STEREO_ABOVEBELOW;
  550. else if (!strcmp(argv[i], "anaglyph"))
  551. stereomode = RAS_IRasterizer::RAS_STEREO_ANAGLYPH;
  552. else if (!strcmp(argv[i], "sidebyside"))
  553. stereomode = RAS_IRasterizer::RAS_STEREO_SIDEBYSIDE;
  554. else if (!strcmp(argv[i], "vinterlace"))
  555. stereomode = RAS_IRasterizer::RAS_STEREO_VINTERLACE;
  556. #if 0
  557. // future stuff
  558. else if (!strcmp(argv[i], "stencil")
  559. stereomode = RAS_STEREO_STENCIL;
  560. #endif
  561. i++;
  562. stereoParFound = true;
  563. stereoFlag = STEREO_ENABLED;
  564. }
  565. else
  566. {
  567. error = true;
  568. printf("error: too few options for stereo argument.\n");
  569. }
  570. break;
  571. case 'D':
  572. stereoFlag = STEREO_DOME;
  573. stereomode = RAS_IRasterizer::RAS_STEREO_DOME;
  574. i++;
  575. if ((i + 1) <= validArguments)
  576. {
  577. if (!strcmp(argv[i], "angle")) {
  578. i++;
  579. domeFov = atoi(argv[i++]);
  580. }
  581. if (!strcmp(argv[i], "tilt")) {
  582. i++;
  583. domeTilt = atoi(argv[i++]);
  584. }
  585. if (!strcmp(argv[i], "warpdata")) {
  586. i++;
  587. domeWarp = argv[i++];
  588. }
  589. if (!strcmp(argv[i], "mode")) {
  590. i++;
  591. if (!strcmp(argv[i], "fisheye"))
  592. domeMode = DOME_FISHEYE;
  593. else if (!strcmp(argv[i], "truncatedfront"))
  594. domeMode = DOME_TRUNCATED_FRONT;
  595. else if (!strcmp(argv[i], "truncatedrear"))
  596. domeMode = DOME_TRUNCATED_REAR;
  597. else if (!strcmp(argv[i], "cubemap"))
  598. domeMode = DOME_ENVMAP;
  599. else if (!strcmp(argv[i], "sphericalpanoramic"))
  600. domeMode = DOME_PANORAM_SPH;
  601. else
  602. printf("error: %s is not a valid dome mode.\n", argv[i]);
  603. }
  604. i++;
  605. }
  606. break;
  607. default:
  608. printf("Unknown argument: %s\n", argv[i++]);
  609. break;
  610. }
  611. }
  612. else
  613. {
  614. i++;
  615. }
  616. }
  617. if ((windowWidth < kMinWindowWidth) || (windowHeight < kMinWindowHeight))
  618. {
  619. error = true;
  620. printf("error: window size too small.\n");
  621. }
  622. if (error )
  623. {
  624. usage(argv[0], isBlenderPlayer);
  625. return 0;
  626. }
  627. #ifdef WIN32
  628. if (scr_saver_mode != SCREEN_SAVER_MODE_CONFIGURATION)
  629. #endif
  630. {
  631. #ifdef __APPLE__
  632. //SYS_WriteCommandLineInt(syshandle, "show_framerate", 1);
  633. //SYS_WriteCommandLineInt(syshandle, "nomipmap", 1);
  634. //fullScreen = false; // Can't use full screen
  635. #endif
  636. if (SYS_GetCommandLineInt(syshandle, "nomipmap", 0))
  637. {
  638. GPU_set_mipmap(0);
  639. }
  640. GPU_set_anisotropic(U.anisotropic_filter);
  641. // Create the system
  642. if (GHOST_ISystem::createSystem() == GHOST_kSuccess)
  643. {
  644. GHOST_ISystem* system = GHOST_ISystem::getSystem();
  645. assertd(system);
  646. if (!fullScreenWidth || !fullScreenHeight)
  647. system->getMainDisplayDimensions(fullScreenWidth, fullScreenHeight);
  648. // process first batch of events. If the user
  649. // drops a file on top off the blenderplayer icon, we
  650. // receive an event with the filename
  651. system->processEvents(0);
  652. // this bracket is needed for app (see below) to get out
  653. // of scope before GHOST_ISystem::disposeSystem() is called.
  654. {
  655. int exitcode = KX_EXIT_REQUEST_NO_REQUEST;
  656. STR_String exitstring = "";
  657. GPG_Application app(system);
  658. bool firstTimeRunning = true;
  659. char filename[FILE_MAX];
  660. char pathname[FILE_MAX];
  661. char *titlename;
  662. get_filename(argc_py_clamped, argv, filename);
  663. if (filename[0])
  664. BLI_path_cwd(filename);
  665. // fill the GlobalSettings with the first scene files
  666. // those may change during the game and persist after using Game Actuator
  667. GlobalSettings gs;
  668. do
  669. {
  670. // Read the Blender file
  671. BlendFileData *bfd;
  672. // if we got an exitcode 3 (KX_EXIT_REQUEST_START_OTHER_GAME) load a different file
  673. if (exitcode == KX_EXIT_REQUEST_START_OTHER_GAME)
  674. {
  675. char basedpath[FILE_MAX];
  676. // base the actuator filename relative to the last file
  677. BLI_strncpy(basedpath, exitstring.Ptr(), sizeof(basedpath));
  678. BLI_path_abs(basedpath, pathname);
  679. bfd = load_game_data(basedpath);
  680. if (!bfd)
  681. {
  682. // just add "//" in front of it
  683. char temppath[242];
  684. strcpy(temppath, "//");
  685. strcat(temppath, basedpath);
  686. BLI_path_abs(temppath, pathname);
  687. bfd = load_game_data(temppath);
  688. }
  689. }
  690. else
  691. {
  692. bfd = load_game_data(BLI_program_path(), filename[0]? filename: NULL);
  693. }
  694. //::printf("game data loaded from %s\n", filename);
  695. if (!bfd) {
  696. usage(argv[0], isBlenderPlayer);
  697. error = true;
  698. exitcode = KX_EXIT_REQUEST_QUIT_GAME;
  699. }
  700. else
  701. {
  702. #ifdef WIN32
  703. #if !defined(DEBUG)
  704. if (closeConsole)
  705. {
  706. system->toggleConsole(0); // Close a console window
  707. }
  708. #endif // !defined(DEBUG)
  709. #endif // WIN32
  710. Main *maggie = bfd->main;
  711. Scene *scene = bfd->curscene;
  712. G.main = maggie;
  713. if (firstTimeRunning) {
  714. G.fileflags = bfd->fileflags;
  715. gs.matmode= scene->gm.matmode;
  716. gs.glslflag= scene->gm.flag;
  717. }
  718. //Seg Fault; icon.c gIcons == 0
  719. BKE_icons_init(1);
  720. titlename = maggie->name;
  721. // Check whether the game should be displayed full-screen
  722. if ((!fullScreenParFound) && (!windowParFound))
  723. {
  724. // Only use file settings when command line did not override
  725. if ((scene->gm.playerflag & GAME_PLAYER_FULLSCREEN)) {
  726. //printf("fullscreen option found in Blender file\n");
  727. fullScreen = true;
  728. fullScreenWidth= scene->gm.xplay;
  729. fullScreenHeight= scene->gm.yplay;
  730. fullScreenFrequency= scene->gm.freqplay;
  731. fullScreenBpp = scene->gm.depth;
  732. }
  733. else
  734. {
  735. fullScreen = false;
  736. windowWidth = scene->gm.xplay;
  737. windowHeight = scene->gm.yplay;
  738. }
  739. }
  740. // Check whether the game should be displayed in stereo
  741. if (!stereoParFound)
  742. {
  743. if (scene->gm.stereoflag == STEREO_ENABLED) {
  744. stereomode = (RAS_IRasterizer::StereoMode) scene->gm.stereomode;
  745. if (stereomode != RAS_IRasterizer::RAS_STEREO_QUADBUFFERED)
  746. stereoWindow = true;
  747. }
  748. }
  749. else
  750. scene->gm.stereoflag = STEREO_ENABLED;
  751. if (!samplesParFound)
  752. aasamples = scene->gm.aasamples;
  753. if (stereoFlag == STEREO_DOME) {
  754. stereomode = RAS_IRasterizer::RAS_STEREO_DOME;
  755. scene->gm.stereoflag = STEREO_DOME;
  756. if (domeFov > 89)
  757. scene->gm.dome.angle = domeFov;
  758. if (domeTilt > -180)
  759. scene->gm.dome.tilt = domeTilt;
  760. if (domeMode > 0)
  761. scene->gm.dome.mode = domeMode;
  762. if (domeWarp)
  763. {
  764. //XXX to do: convert relative to absolute path
  765. domeText= add_text(domeWarp, "");
  766. if (!domeText)
  767. printf("error: invalid warpdata text file - %s\n", domeWarp);
  768. else
  769. scene->gm.dome.warptext = domeText;
  770. }
  771. }
  772. // GPG_Application app (system, maggie, startscenename);
  773. app.SetGameEngineData(maggie, scene, &gs, argc, argv); /* this argc cant be argc_py_clamped, since python uses it */
  774. BLI_strncpy(pathname, maggie->name, sizeof(pathname));
  775. if (G.main != maggie) {
  776. BLI_strncpy(G.main->name, maggie->name, sizeof(G.main->name));
  777. }
  778. #ifdef WITH_PYTHON
  779. setGamePythonPath(G.main->name);
  780. #endif
  781. if (firstTimeRunning)
  782. {
  783. firstTimeRunning = false;
  784. if (fullScreen)
  785. {
  786. #ifdef WIN32
  787. if (scr_saver_mode == SCREEN_SAVER_MODE_SAVER)
  788. {
  789. app.startScreenSaverFullScreen(fullScreenWidth, fullScreenHeight, fullScreenBpp, fullScreenFrequency,
  790. stereoWindow, stereomode, aasamples);
  791. }
  792. else
  793. #endif
  794. {
  795. app.startFullScreen(fullScreenWidth, fullScreenHeight, fullScreenBpp, fullScreenFrequency,
  796. stereoWindow, stereomode, aasamples, (scene->gm.playerflag & GAME_PLAYER_DESKTOP_RESOLUTION));
  797. }
  798. }
  799. else
  800. {
  801. #ifdef __APPLE__
  802. // on Mac's we'll show the executable name instead of the 'game.blend' name
  803. char tempname[1024], *appstring;
  804. ::strcpy(tempname, titlename);
  805. appstring = strstr(tempname, ".app/");
  806. if (appstring) {
  807. appstring[2] = 0;
  808. titlename = &tempname[0];
  809. }
  810. #endif
  811. // Strip the path so that we have the name of the game file
  812. STR_String path = titlename;
  813. #ifndef WIN32
  814. vector<STR_String> parts = path.Explode('/');
  815. #else // WIN32
  816. vector<STR_String> parts = path.Explode('\\');
  817. #endif // WIN32
  818. STR_String title;
  819. if (parts.size())
  820. {
  821. title = parts[parts.size()-1];
  822. parts = title.Explode('.');
  823. if (parts.size() > 1)
  824. {
  825. title = parts[0];
  826. }
  827. }
  828. else
  829. {
  830. title = "blenderplayer";
  831. }
  832. #ifdef WIN32
  833. if (scr_saver_mode == SCREEN_SAVER_MODE_PREVIEW)
  834. {
  835. app.startScreenSaverPreview(scr_saver_hwnd, stereoWindow, stereomode, aasamples);
  836. }
  837. else
  838. #endif
  839. {
  840. if (parentWindow != 0)
  841. app.startEmbeddedWindow(title, parentWindow, stereoWindow, stereomode, aasamples);
  842. else
  843. app.startWindow(title, windowLeft, windowTop, windowWidth, windowHeight,
  844. stereoWindow, stereomode, aasamples);
  845. }
  846. }
  847. }
  848. else
  849. {
  850. app.StartGameEngine(stereomode);
  851. exitcode = KX_EXIT_REQUEST_NO_REQUEST;
  852. }
  853. // Add the application as event consumer
  854. system->addEventConsumer(&app);
  855. // Enter main loop
  856. bool run = true;
  857. while (run)
  858. {
  859. system->processEvents(false);
  860. system->dispatchEvents();
  861. if ((exitcode = app.getExitRequested()))
  862. {
  863. run = false;
  864. exitstring = app.getExitString();
  865. gs = *app.getGlobalSettings();
  866. }
  867. }
  868. app.StopGameEngine();
  869. /* 'app' is freed automatic when out of scope.
  870. * removal is needed else the system will free an already freed value */
  871. system->removeEventConsumer(&app);
  872. BLO_blendfiledata_free(bfd);
  873. }
  874. } while (exitcode == KX_EXIT_REQUEST_RESTART_GAME || exitcode == KX_EXIT_REQUEST_START_OTHER_GAME);
  875. }
  876. // Seg Fault; icon.c gIcons == 0
  877. BKE_icons_free();
  878. // Dispose the system
  879. GHOST_ISystem::disposeSystem();
  880. } else {
  881. error = true;
  882. printf("error: couldn't create a system.\n");
  883. }
  884. }
  885. // Cleanup
  886. RNA_exit();
  887. BLF_exit();
  888. #ifdef WITH_INTERNATIONAL
  889. BLF_free_unifont();
  890. #endif
  891. IMB_exit();
  892. free_nodesystem();
  893. SYS_DeleteSystem(syshandle);
  894. int totblock= MEM_get_memory_blocks_in_use();
  895. if (totblock!=0) {
  896. printf("Error Totblock: %d\n",totblock);
  897. MEM_set_error_callback(mem_error_cb);
  898. MEM_printmemlist();
  899. }
  900. return error ? -1 : 0;
  901. }