4 * ***** BEGIN GPL LICENSE BLOCK *****
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21 * All rights reserved.
23 * The Original Code is: all of this file.
25 * Contributor(s): none yet.
27 * ***** END GPL LICENSE BLOCK *****
28 * Start up of the Blender Player on GHOST.
31 /** \file gameengine/GamePlayer/ghost/GPG_ghost.cpp
42 #endif /* __alpha__ */
43 #endif /* __linux__ */
46 // Can't use Carbon right now because of double defined type ID (In Carbon.h and DNA_ID.h, sigh)
47 //#include <Carbon/Carbon.h>
48 //#include <CFBundle.h>
50 #include "KX_KetsjiEngine.h"
51 #include "KX_PythonInit.h"
53 /**********************************
54 * Begin Blender include block
55 **********************************/
60 #include "MEM_guardedalloc.h"
61 #include "BKE_blender.h"
62 #include "BKE_global.h"
63 #include "BKE_icons.h"
65 #include "BKE_report.h"
66 #include "BKE_library.h"
67 #include "BLI_threads.h"
68 #include "BLI_blenlib.h"
69 #include "DNA_scene_types.h"
70 #include "DNA_userdef_types.h"
71 #include "BLO_readfile.h"
72 #include "BLO_runtime.h"
73 #include "IMB_imbuf.h"
75 #include "BKE_sound.h"
77 int GHOST_HACK_getFirstFile(char buf[]);
81 #include "BLF_translation.h"
82 extern int datatoc_bfont_ttf_size;
83 extern char datatoc_bfont_ttf[];
91 /**********************************
92 * End Blender include block
93 **********************************/
95 #include "BL_System.h"
96 #include "GPG_Application.h"
98 #include "GHOST_ISystem.h"
99 #include "RAS_IRasterizer.h"
101 #include "BKE_main.h"
102 #include "BKE_utildefines.h"
104 #include "RNA_define.h"
110 #endif // !defined(DEBUG)
113 const int kMinWindowWidth = 100;
114 const int kMinWindowHeight = 100;
116 static void mem_error_cb(const char *errorStr)
118 fprintf(stderr, "%s", errorStr);
125 SCREEN_SAVER_MODE_NONE = 0,
126 SCREEN_SAVER_MODE_PREVIEW,
127 SCREEN_SAVER_MODE_SAVER,
128 SCREEN_SAVER_MODE_CONFIGURATION,
129 SCREEN_SAVER_MODE_PASSWORD,
132 static ScreenSaverMode scr_saver_mode = SCREEN_SAVER_MODE_NONE;
133 static HWND scr_saver_hwnd = NULL;
135 static BOOL scr_saver_init(int argc, char **argv)
137 scr_saver_mode = SCREEN_SAVER_MODE_NONE;
138 scr_saver_hwnd = NULL;
141 int len = ::strlen(argv[0]);
142 if (len > 4 && !::stricmp(".scr", argv[0] + len - 4))
144 scr_saver_mode = SCREEN_SAVER_MODE_CONFIGURATION;
150 scr_saver_hwnd = (HWND) ::atoi(argv[2]);
152 if (!::stricmp("/c", argv[1]))
154 scr_saver_mode = SCREEN_SAVER_MODE_CONFIGURATION;
155 if (scr_saver_hwnd == NULL)
156 scr_saver_hwnd = ::GetForegroundWindow();
158 else if (!::stricmp("/s", argv[1]))
160 scr_saver_mode = SCREEN_SAVER_MODE_SAVER;
162 else if (!::stricmp("/a", argv[1]))
164 scr_saver_mode = SCREEN_SAVER_MODE_PASSWORD;
166 else if (!::stricmp("/p", argv[1])
167 || !::stricmp("/l", argv[1]))
169 scr_saver_mode = SCREEN_SAVER_MODE_PREVIEW;
178 void usage(const char* program, bool isBlenderPlayer)
180 const char * consoleoption;
181 const char * filename = "";
182 const char * pathname = "";
185 consoleoption = "-c ";
190 if (isBlenderPlayer) {
191 filename = "filename.blend";
195 pathname = "//home//user//";
199 printf("usage: %s [-w [w h l t]] [-f [fw fh fb ff]] %s[-g gamengineoptions] "
200 "[-s stereomode] [-m aasamples] %s\n", program, consoleoption, filename);
201 printf(" -h: Prints this command summary\n\n");
202 printf(" -w: display in a window\n");
203 printf(" --Optional parameters--\n");
204 printf(" w = window width\n");
205 printf(" h = window height\n\n");
206 printf(" l = window left coordinate\n");
207 printf(" t = window top coordinate\n");
208 printf(" Note: If w or h is defined, both must be defined.\n");
209 printf(" Also, if l or t is defined, all options must be used.\n\n");
210 printf(" -f: start game in full screen mode\n");
211 printf(" --Optional parameters--\n");
212 printf(" fw = full screen mode pixel width\n");
213 printf(" fh = full screen mode pixel height\n\n");
214 printf(" fb = full screen mode bits per pixel\n");
215 printf(" ff = full screen mode frequency\n");
216 printf(" Note: If fw or fh is defined, both must be defined.\n");
217 printf(" Also, if fb is used, fw and fh must be used. ff requires all options.\n\n");
218 printf(" -s: start player in stereo\n");
219 printf(" stereomode: hwpageflip (Quad buffered shutter glasses)\n");
220 printf(" syncdoubling (Above Below)\n");
221 printf(" sidebyside (Left Right)\n");
222 printf(" anaglyph (Red-Blue glasses)\n");
223 printf(" vinterlace (Vertical interlace for autostereo display)\n");
224 printf(" depending on the type of stereo you want\n\n");
225 printf(" -D: start player in dome mode\n");
226 printf(" --Optional parameters--\n");
227 printf(" angle = field of view in degrees\n");
228 printf(" tilt = tilt angle in degrees\n");
229 printf(" warpdata = a file to use for warping the image (absolute path)\n");
230 printf(" mode: fisheye (Fisheye)\n");
231 printf(" truncatedfront (Front-Truncated)\n");
232 printf(" truncatedrear (Rear-Truncated)\n");
233 printf(" cubemap (Cube Map)\n");
234 printf(" sphericalpanoramic (Spherical Panoramic)\n");
235 printf(" depending on the type of dome you are using\n\n");
236 printf(" -m: maximum anti-aliasing (eg. 2,4,8,16)\n\n");
237 printf(" -i: parent windows ID \n\n");
239 printf(" -c: keep console window open\n\n");
241 printf(" -d: turn debugging on\n\n");
242 printf(" -g: game engine options:\n\n");
243 printf(" Name Default Description\n");
244 printf(" ------------------------------------------------------------------------\n");
245 printf(" fixedtime 0 \"Enable all frames\"\n");
246 printf(" nomipmap 0 Disable mipmaps\n");
247 printf(" show_framerate 0 Show the frame rate\n");
248 printf(" show_properties 0 Show debug properties\n");
249 printf(" show_profile 0 Show profiling information\n");
250 printf(" blender_material 0 Enable material settings\n");
251 printf(" ignore_deprecation_warnings 1 Ignore deprecation warnings\n");
253 printf(" - : all arguments after this are ignored, allowing python to access them from sys.argv\n");
255 printf("example: %s -w 320 200 10 10 -g noaudio%s%s\n", program, pathname, filename);
256 printf("example: %s -g show_framerate = 0 %s%s\n", program, pathname, filename);
257 printf("example: %s -i 232421 -m 16 %s%s\n\n", program, pathname, filename);
260 static void get_filename(int argc, char **argv, char *filename)
263 /* On Mac we park the game file (called game.blend) in the application bundle.
264 * The executable is located in the bundle as well.
265 * Therefore, we can locate the game relative to the executable.
267 int srclen = ::strlen(argv[0]);
269 char *gamefile = NULL;
274 if (BLI_exists(argv[argc-1])) {
275 BLI_strncpy(filename, argv[argc-1], FILE_MAXDIR + FILE_MAXFILE);
277 if (::strncmp(argv[argc-1], "-psn_", 5)==0) {
278 static char firstfilebuf[512];
279 if (GHOST_HACK_getFirstFile(firstfilebuf)) {
280 BLI_strncpy(filename, firstfilebuf, FILE_MAXDIR + FILE_MAXFILE);
285 srclen -= ::strlen("MacOS/blenderplayer");
287 len = srclen + ::strlen("Resources/game.blend");
288 gamefile = new char [len + 1];
289 ::strcpy(gamefile, argv[0]);
290 ::strcpy(gamefile + srclen, "Resources/game.blend");
291 //::printf("looking for file: %s\n", filename);
293 if (BLI_exists(gamefile))
294 BLI_strncpy(filename, gamefile, FILE_MAXDIR + FILE_MAXFILE);
303 BLI_strncpy(filename, argv[argc-1], FILE_MAXDIR + FILE_MAXFILE);
307 static BlendFileData *load_game_data(const char *progname, char *filename = NULL, char *relativename = NULL)
310 BlendFileData *bfd = NULL;
312 BKE_reports_init(&reports, RPT_STORE);
314 /* try to load ourself, will only work if we are a runtime */
315 if (BLO_is_a_runtime(progname)) {
316 bfd= BLO_read_runtime(progname, &reports);
318 bfd->type= BLENFILETYPE_RUNTIME;
319 BLI_strncpy(bfd->main->name, progname, sizeof(bfd->main->name));
322 bfd= BLO_read_from_file(progname, &reports);
325 if (!bfd && filename) {
326 bfd = load_game_data(filename);
328 printf("Loading %s failed: ", filename);
329 BKE_reports_print(&reports, RPT_ERROR);
333 BKE_reports_clear(&reports);
338 int main(int argc, char** argv)
341 int argc_py_clamped= argc; /* use this so python args can be added after ' - ' */
343 SYS_SystemHandle syshandle = SYS_GetSystem();
344 bool fullScreen = false;
345 bool fullScreenParFound = false;
346 bool windowParFound = false;
348 bool closeConsole = true;
350 RAS_IRasterizer::StereoMode stereomode = RAS_IRasterizer::RAS_STEREO_NOSTEREO;
351 bool stereoWindow = false;
352 bool stereoParFound = false;
353 int stereoFlag = STEREO_NOSTEREO;
357 char* domeWarp = NULL;
358 Text *domeText = NULL;
359 int windowLeft = 100;
361 int windowWidth = 640;
362 int windowHeight = 480;
363 GHOST_TUns32 fullScreenWidth = 0;
364 GHOST_TUns32 fullScreenHeight= 0;
365 int fullScreenBpp = 32;
366 int fullScreenFrequency = 60;
367 GHOST_TEmbedderWindowID parentWindow = 0;
368 bool isBlenderPlayer = false;
369 int validArguments=0;
370 GHOST_TUns16 aasamples = 0;
374 signal (SIGFPE, SIG_IGN);
375 #endif /* __alpha__ */
376 #endif /* __linux__ */
377 BLI_init_program_path(argv[0]);
378 BLI_init_temporary_dir(NULL);
380 // Can't use Carbon right now because of double defined type ID (In Carbon.h and DNA_ID.h, sigh)
386 // Create a Nib reference passing the name of the nib file (without the .nib extension)
387 // CreateNibReference only searches into the application bundle.
388 err = ::CreateNibReference(CFSTR("main"), &nibRef);
391 // Once the nib reference is created, set the menu bar. "MainMenu" is the name of the menu bar
392 // object. This name is set in InterfaceBuilder when the nib is created.
393 err = ::SetMenuBarFromNib(nibRef, CFSTR("MenuBar"));
396 // We don't need the nib reference anymore.
397 ::DisposeNibReference(nibRef);
401 // We don't use threads directly in the BGE, but we need to call this so things like
402 // freeing up GPU_Textures works correctly.
403 BLI_threadapi_init();
411 // We load our own G.main, so free the one that initglobals() gives us
417 // Setup builtin font for BLF (mostly copied from creator.c, wm_init_exit.c and interface_style.c)
420 BLF_lang_encoding("");
423 BLF_load_mem("default", (unsigned char*)datatoc_bfont_ttf, datatoc_bfont_ttf_size);
425 // Parse command line options
427 printf("argv[0] = '%s'\n", argv[0]);
431 if (scr_saver_init(argc, argv))
433 switch (scr_saver_mode)
435 case SCREEN_SAVER_MODE_CONFIGURATION:
436 MessageBox(scr_saver_hwnd, "This screen saver has no options that you can set", "Screen Saver", MB_OK);
438 case SCREEN_SAVER_MODE_PASSWORD:
439 /* This is W95 only, which we currently do not support.
440 Fall-back to normal screen saver behaviour in that case... */
441 case SCREEN_SAVER_MODE_SAVER:
443 fullScreenParFound = true;
446 case SCREEN_SAVER_MODE_PREVIEW:
447 /* This will actually be handled somewhere below... */
452 // XXX add the ability to change this values to the command line parsing.
456 U.audioformat = 0x24;
460 U.anisotropic_filter = 2;
464 /* if running blenderplayer the last argument can't be parsed since it has to be the filename. */
465 isBlenderPlayer = !BLO_is_a_runtime(argv[0]);
467 validArguments = argc - 1;
469 validArguments = argc;
471 for (i = 1; (i < validArguments) && !error
473 && scr_saver_mode == SCREEN_SAVER_MODE_NONE
479 printf("argv[%d] = '%s' , %i\n", i, argv[i],argc);
481 if (argv[i][0] == '-')
483 /* ignore all args after " - ", allow python to have own args */
484 if (argv[i][1]=='\0') {
492 // Parse game options
495 if (i <= validArguments)
497 char* paramname = argv[i];
498 // Check for single value versus assignment
499 if (i+1 <= validArguments && (*(argv[i+1]) == '='))
502 if (i + 1 <= validArguments)
506 SYS_WriteCommandLineInt(syshandle, paramname, atoi(argv[i]));
507 SYS_WriteCommandLineFloat(syshandle, paramname, atof(argv[i]));
508 SYS_WriteCommandLineString(syshandle, paramname, argv[i]);
510 printf("%s = '%s'\n", paramname, argv[i]);
517 printf("error: argument assignment %s without value.\n", paramname);
522 // SYS_WriteCommandLineInt(syshandle, argv[i++], 1);
530 G.f |= G_DEBUG; /* std output printf's */
531 MEM_set_memory_debug();
537 fullScreenParFound = true;
538 if ((i + 2) <= validArguments && argv[i][0] != '-' && argv[i+1][0] != '-')
540 fullScreenWidth = atoi(argv[i++]);
541 fullScreenHeight = atoi(argv[i++]);
542 if ((i + 1) <= validArguments && argv[i][0] != '-')
544 fullScreenBpp = atoi(argv[i++]);
545 if ((i + 1) <= validArguments && argv[i][0] != '-')
546 fullScreenFrequency = atoi(argv[i++]);
551 // Parse window position and size options
554 windowParFound = true;
556 if ((i + 2) <= validArguments && argv[i][0] != '-' && argv[i+1][0] != '-')
558 windowWidth = atoi(argv[i++]);
559 windowHeight = atoi(argv[i++]);
560 if ((i + 2) <= validArguments && argv[i][0] != '-' && argv[i+1][0] != '-')
562 windowLeft = atoi(argv[i++]);
563 windowTop = atoi(argv[i++]);
569 usage(argv[0], isBlenderPlayer);
574 if ( (i + 1) <= validArguments )
575 parentWindow = atoi(argv[i++]);
578 printf("error: too few options for parent window argument.\n");
581 printf("XWindows ID = %d\n", parentWindow);
582 #endif // defined(DEBUG)
586 if ((i+1) <= validArguments )
587 aasamples = atoi(argv[i++]);
592 closeConsole = false;
597 if ((i + 1) <= validArguments)
599 stereomode = (RAS_IRasterizer::StereoMode) atoi(argv[i]);
600 if (stereomode < RAS_IRasterizer::RAS_STEREO_NOSTEREO || stereomode >= RAS_IRasterizer::RAS_STEREO_MAXSTEREO)
601 stereomode = RAS_IRasterizer::RAS_STEREO_NOSTEREO;
603 if(!strcmp(argv[i], "nostereo")) // ok, redundant but clear
604 stereomode = RAS_IRasterizer::RAS_STEREO_NOSTEREO;
606 // only the hardware pageflip method needs a stereo window
607 else if(!strcmp(argv[i], "hwpageflip")) {
608 stereomode = RAS_IRasterizer::RAS_STEREO_QUADBUFFERED;
611 else if(!strcmp(argv[i], "syncdoubling"))
612 stereomode = RAS_IRasterizer::RAS_STEREO_ABOVEBELOW;
614 else if(!strcmp(argv[i], "anaglyph"))
615 stereomode = RAS_IRasterizer::RAS_STEREO_ANAGLYPH;
617 else if(!strcmp(argv[i], "sidebyside"))
618 stereomode = RAS_IRasterizer::RAS_STEREO_SIDEBYSIDE;
620 else if(!strcmp(argv[i], "vinterlace"))
621 stereomode = RAS_IRasterizer::RAS_STEREO_VINTERLACE;
625 else if(!strcmp(argv[i], "stencil")
626 stereomode = RAS_STEREO_STENCIL;
630 stereoParFound = true;
631 stereoFlag = STEREO_ENABLED;
636 printf("error: too few options for stereo argument.\n");
640 stereoFlag = STEREO_DOME;
641 stereomode = RAS_IRasterizer::RAS_STEREO_DOME;
643 if ((i + 1) <= validArguments)
645 if(!strcmp(argv[i], "angle")){
647 domeFov = atoi(argv[i++]);
649 if(!strcmp(argv[i], "tilt")){
651 domeTilt = atoi(argv[i++]);
653 if(!strcmp(argv[i], "warpdata")){
655 domeWarp = argv[i++];
657 if(!strcmp(argv[i], "mode")){
659 if(!strcmp(argv[i], "fisheye"))
660 domeMode = DOME_FISHEYE;
662 else if(!strcmp(argv[i], "truncatedfront"))
663 domeMode = DOME_TRUNCATED_FRONT;
665 else if(!strcmp(argv[i], "truncatedrear"))
666 domeMode = DOME_TRUNCATED_REAR;
668 else if(!strcmp(argv[i], "cubemap"))
669 domeMode = DOME_ENVMAP;
671 else if(!strcmp(argv[i], "sphericalpanoramic"))
672 domeMode = DOME_PANORAM_SPH;
675 printf("error: %s is not a valid dome mode.\n", argv[i]);
681 printf("Unknown argument: %s\n", argv[i++]);
691 if ((windowWidth < kMinWindowWidth) || (windowHeight < kMinWindowHeight))
694 printf("error: window size too small.\n");
699 usage(argv[0], isBlenderPlayer);
704 if (scr_saver_mode != SCREEN_SAVER_MODE_CONFIGURATION)
708 //SYS_WriteCommandLineInt(syshandle, "show_framerate", 1);
709 //SYS_WriteCommandLineInt(syshandle, "nomipmap", 1);
710 //fullScreen = false; // Can't use full screen
713 if (SYS_GetCommandLineInt(syshandle, "nomipmap", 0))
718 GPU_set_anisotropic(U.anisotropic_filter);
721 if (GHOST_ISystem::createSystem() == GHOST_kSuccess)
723 GHOST_ISystem* system = GHOST_ISystem::getSystem();
726 if (!fullScreenWidth || !fullScreenHeight)
727 system->getMainDisplayDimensions(fullScreenWidth, fullScreenHeight);
728 // process first batch of events. If the user
729 // drops a file on top off the blenderplayer icon, we
730 // receive an event with the filename
732 system->processEvents(0);
734 // this bracket is needed for app (see below) to get out
735 // of scope before GHOST_ISystem::disposeSystem() is called.
737 int exitcode = KX_EXIT_REQUEST_NO_REQUEST;
738 STR_String exitstring = "";
739 GPG_Application app(system);
740 bool firstTimeRunning = true;
741 char filename[FILE_MAXDIR + FILE_MAXFILE];
742 char pathname[FILE_MAXDIR + FILE_MAXFILE];
745 get_filename(argc_py_clamped, argv, filename);
747 BLI_path_cwd(filename);
750 // fill the GlobalSettings with the first scene files
751 // those may change during the game and persist after using Game Actuator
756 // Read the Blender file
759 // if we got an exitcode 3 (KX_EXIT_REQUEST_START_OTHER_GAME) load a different file
760 if (exitcode == KX_EXIT_REQUEST_START_OTHER_GAME)
764 // base the actuator filename relative to the last file
765 BLI_strncpy(basedpath, exitstring.Ptr(), sizeof(basedpath));
766 BLI_path_abs(basedpath, pathname);
768 bfd = load_game_data(basedpath);
772 // just add "//" in front of it
774 strcpy(temppath, "//");
775 strcat(temppath, basedpath);
777 BLI_path_abs(temppath, pathname);
778 bfd = load_game_data(temppath);
783 bfd = load_game_data(BLI_program_path(), filename[0]? filename: NULL);
786 //::printf("game data loaded from %s\n", filename);
789 usage(argv[0], isBlenderPlayer);
791 exitcode = KX_EXIT_REQUEST_QUIT_GAME;
799 //::FreeConsole(); // Close a console window
801 #endif // !defined(DEBUG)
803 Main *maggie = bfd->main;
804 Scene *scene = bfd->curscene;
807 if (firstTimeRunning) {
808 G.fileflags = bfd->fileflags;
810 gs.matmode= scene->gm.matmode;
811 gs.glslflag= scene->gm.flag;
814 //Seg Fault; icon.c gIcons == 0
817 titlename = maggie->name;
819 // Check whether the game should be displayed full-screen
820 if ((!fullScreenParFound) && (!windowParFound))
822 // Only use file settings when command line did not override
823 if (scene->gm.fullscreen) {
824 //printf("fullscreen option found in Blender file\n");
826 fullScreenWidth= scene->gm.xplay;
827 fullScreenHeight= scene->gm.yplay;
828 fullScreenFrequency= scene->gm.freqplay;
829 fullScreenBpp = scene->gm.depth;
834 windowWidth = scene->gm.xplay;
835 windowHeight = scene->gm.yplay;
840 // Check whether the game should be displayed in stereo
843 if(scene->gm.stereoflag == STEREO_ENABLED){
844 stereomode = (RAS_IRasterizer::StereoMode) scene->gm.stereomode;
845 if (stereomode != RAS_IRasterizer::RAS_STEREO_QUADBUFFERED)
850 scene->gm.stereoflag = STEREO_ENABLED;
852 if (stereoFlag == STEREO_DOME){
853 stereomode = RAS_IRasterizer::RAS_STEREO_DOME;
854 scene->gm.stereoflag = STEREO_DOME;
856 scene->gm.dome.angle = domeFov;
858 scene->gm.dome.tilt = domeTilt;
860 scene->gm.dome.mode = domeMode;
863 //XXX to do: convert relative to absolute path
864 domeText= add_text(domeWarp, "");
866 printf("error: invalid warpdata text file - %s\n", domeWarp);
868 scene->gm.dome.warptext = domeText;
872 // GPG_Application app (system, maggie, startscenename);
873 app.SetGameEngineData(maggie, scene, &gs, argc, argv); /* this argc cant be argc_py_clamped, since python uses it */
874 BLI_strncpy(pathname, maggie->name, sizeof(pathname));
875 if(G.main != maggie) {
876 BLI_strncpy(G.main->name, maggie->name, sizeof(G.main->name));
879 setGamePythonPath(G.main->name);
881 if (firstTimeRunning)
883 firstTimeRunning = false;
888 if (scr_saver_mode == SCREEN_SAVER_MODE_SAVER)
890 app.startScreenSaverFullScreen(fullScreenWidth, fullScreenHeight, fullScreenBpp, fullScreenFrequency,
891 stereoWindow, stereomode, aasamples);
896 app.startFullScreen(fullScreenWidth, fullScreenHeight, fullScreenBpp, fullScreenFrequency,
897 stereoWindow, stereomode, aasamples);
903 // on Mac's we'll show the executable name instead of the 'game.blend' name
904 char tempname[1024], *appstring;
905 ::strcpy(tempname, titlename);
907 appstring = strstr(tempname, ".app/");
910 titlename = &tempname[0];
913 // Strip the path so that we have the name of the game file
914 STR_String path = titlename;
916 vector<STR_String> parts = path.Explode('/');
918 vector<STR_String> parts = path.Explode('\\');
923 title = parts[parts.size()-1];
924 parts = title.Explode('.');
925 if (parts.size() > 1)
932 title = "blenderplayer";
935 if (scr_saver_mode == SCREEN_SAVER_MODE_PREVIEW)
937 app.startScreenSaverPreview(scr_saver_hwnd, stereoWindow, stereomode, aasamples);
942 if (parentWindow != 0)
943 app.startEmbeddedWindow(title, parentWindow, stereoWindow, stereomode, aasamples);
945 app.startWindow(title, windowLeft, windowTop, windowWidth, windowHeight,
946 stereoWindow, stereomode, aasamples);
952 app.StartGameEngine(stereomode);
953 exitcode = KX_EXIT_REQUEST_NO_REQUEST;
956 // Add the application as event consumer
957 system->addEventConsumer(&app);
963 system->processEvents(false);
964 system->dispatchEvents();
965 if ((exitcode = app.getExitRequested()))
968 exitstring = app.getExitString();
969 gs = *app.getGlobalSettings();
972 app.StopGameEngine();
974 /* 'app' is freed automatic when out of scope.
975 * removal is needed else the system will free an already freed value */
976 system->removeEventConsumer(&app);
978 BLO_blendfiledata_free(bfd);
980 } while (exitcode == KX_EXIT_REQUEST_RESTART_GAME || exitcode == KX_EXIT_REQUEST_START_OTHER_GAME);
983 // Seg Fault; icon.c gIcons == 0
986 // Dispose the system
987 GHOST_ISystem::disposeSystem();
990 printf("error: couldn't create a system.\n");
998 #ifdef WITH_INTERNATIONAL
1005 SYS_DeleteSystem(syshandle);
1007 int totblock= MEM_get_memory_blocks_in_use();
1009 printf("Error Totblock: %d\n",totblock);
1010 MEM_set_error_callback(mem_error_cb);
1014 return error ? -1 : 0;