Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/gameengine/GamePlayer/ghost/GPG_ghost.cpp')
-rw-r--r--source/gameengine/GamePlayer/ghost/GPG_ghost.cpp597
1 files changed, 597 insertions, 0 deletions
diff --git a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
new file mode 100644
index 00000000000..df683cb91cf
--- /dev/null
+++ b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
@@ -0,0 +1,597 @@
+/**
+* $Id$
+*
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+* Start up of the Blender Player on GHOST.
+*/
+
+#include <iostream>
+#include <math.h>
+
+#ifdef __linux__
+#ifdef __alpha__
+#include <signal.h>
+#endif /* __alpha__ */
+#endif /* __linux__ */
+
+#ifdef __APPLE__
+// Can't use Carbon right now because of double defined type ID (In Carbon.h and DNA_ID.h, sigh)
+//#include <Carbon/Carbon.h>
+//#include <CFBundle.h>
+#endif // __APPLE__
+#include "GEN_messaging.h"
+#include "KX_KetsjiEngine.h"
+
+/**********************************
+* Begin Blender include block
+**********************************/
+#ifdef __cplusplus
+extern "C"
+{
+#endif // __cplusplus
+
+#include "BLI_blenlib.h"
+#include "DNA_scene_types.h"
+#include "BLO_readfile.h"
+
+ int GHOST_HACK_getFirstFile(char buf[]);
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+/**********************************
+* End Blender include block
+**********************************/
+
+#include "SYS_System.h"
+#include "GPG_Application.h"
+#include "GPC_PolygonMaterial.h"
+
+#include "GHOST_ISystem.h"
+#include "RAS_IRasterizer.h"
+
+#include "BKE_main.h"
+
+#ifdef WIN32
+#ifdef NDEBUG
+#include <windows.h>
+#include <wincon.h>
+#endif // NDEBUG
+#endif // WIN32
+
+const int kMinWindowWidth = 100;
+const int kMinWindowHeight = 100;
+
+void usage(char* program)
+{
+ char * consoleoption;
+#ifdef _WIN32
+ consoleoption = "-c ";
+#else
+ consoleoption = "";
+#endif
+
+ printf("usage: %s [-p l t w h] [-f fw fh fb ff] %s[-g gamengineoptions] "
+ "-s stereomode filename.blend\n", program, consoleoption);
+ printf(" -p: specify window position\n");
+ printf(" l = window left coordinate\n");
+ printf(" t = window top coordinate\n");
+ printf(" w = window width\n");
+ printf(" h = window height\n");
+ printf(" -f: start game in full screen mode\n");
+ printf(" fw = full screen mode pixel width\n");
+ printf(" fh = full screen mode pixel height\n");
+ printf(" fb = full screen mode bits per pixel\n");
+ printf(" ff = full screen mode frequency\n");
+ printf(" -s: start player in stereo\n");
+ printf(" stereomode = hwpageflip or syncdoubling depending on the type of stereo you want\n");
+#ifdef _WIN32
+ printf(" -c: keep console window open\n");
+#endif
+ printf("\n");
+ printf("example: %s -p 10 10 320 200 -g noaudio c:\\loadtest.blend\n", program);
+}
+
+char *get_filename(int argc, char **argv) {
+#ifdef __APPLE__
+/* On Mac we park the game file (called game.blend) in the application bundle.
+* The executable is located in the bundle as well.
+* Therefore, we can locate the game relative to the executable.
+ */
+ int srclen = ::strlen(argv[0]);
+ int len = 0;
+ char *filename = NULL;
+
+ if (argc > 1) {
+ if (BLI_exists(argv[argc-1])) {
+ len = ::strlen(argv[argc-1]);
+ filename = new char [len + 1];
+ ::strcpy(filename, argv[argc-1]);
+ return(filename);
+ }
+ if (::strncmp(argv[argc-1], "-psn_", 5)==0) {
+ static char firstfilebuf[512];
+ if (GHOST_HACK_getFirstFile(firstfilebuf)) {
+ len = ::strlen(firstfilebuf);
+ filename = new char [len + 1];
+ ::strcpy(filename, firstfilebuf);
+ return(filename);
+ }
+ }
+ }
+
+ srclen -= ::strlen("MacOS/blenderplayer");
+ if (srclen > 0) {
+ len = srclen + ::strlen("Resources/game.blend");
+ filename = new char [len + 1];
+ ::strcpy(filename, argv[0]);
+ ::strcpy(filename + srclen, "Resources/game.blend");
+ //::printf("looking for file: %s\n", filename);
+
+ if (BLI_exists(filename)) {
+ return (filename);
+ }
+ }
+
+ return(NULL);
+#else
+ return (argc>1)?argv[argc-1]:NULL;
+#endif // !_APPLE
+}
+
+BlendFileData *load_game_data(char *progname, char *filename) {
+ BlendReadError error;
+ BlendFileData *bfd;
+
+ /* try to load ourself, will only work if we are a runtime */
+ bfd= BLO_read_from_file(progname, &error);
+
+ if (!bfd) {
+ if (filename) {
+ bfd= BLO_read_from_file(filename, &error);
+ }
+ }
+
+ if (bfd && bfd->type == BLENFILETYPE_BLEND) {
+ BLO_blendfiledata_free(bfd);
+ bfd = NULL;
+ error = BRE_NOT_A_PUBFILE;
+ }
+
+ if (!bfd) {
+ if (filename) {
+ printf("Loading %s failed: %s\n", filename, BLO_bre_as_string(error));
+ }
+ }
+
+ return bfd;
+}
+
+int main(int argc, char** argv)
+{
+ int i;
+ bool error = false;
+ SYS_SystemHandle syshandle = SYS_GetSystem();
+ bool fullScreen = false;
+ bool fullScreenParFound = false;
+ bool windowParFound = false;
+ bool closeConsole = true;
+ int stereomode = RAS_IRasterizer::RAS_STEREO_NOSTEREO;
+ bool stereoWindow = false;
+ bool stereoParFound = false;
+ int windowLeft = 100;
+ int windowTop = 100;
+ int windowWidth = 640;
+ int windowHeight = 480;
+ int fullScreenWidth = 640;
+ int fullScreenHeight= 480;
+ int fullScreenBpp = 16;
+ int fullScreenFrequency = 60;
+
+#ifdef __linux__
+#ifdef __alpha__
+ signal (SIGFPE, SIG_IGN);
+#endif /* __alpha__ */
+#endif /* __linux__ */
+
+#ifdef __APPLE__
+ // Can't use Carbon right now because of double defined type ID (In Carbon.h and DNA_ID.h, sigh)
+ /*
+ IBNibRef nibRef;
+ WindowRef window;
+ OSStatus err;
+
+ // Create a Nib reference passing the name of the nib file (without the .nib extension)
+ // CreateNibReference only searches into the application bundle.
+ err = ::CreateNibReference(CFSTR("main"), &nibRef);
+ if (err) return -1;
+
+ // Once the nib reference is created, set the menu bar. "MainMenu" is the name of the menu bar
+ // object. This name is set in InterfaceBuilder when the nib is created.
+ err = ::SetMenuBarFromNib(nibRef, CFSTR("MenuBar"));
+ if (err) return -1;
+
+ // We don't need the nib reference anymore.
+ ::DisposeNibReference(nibRef);
+ */
+#endif // __APPLE__
+
+ GEN_init_messaging_system();
+
+ // Parse command line options
+#ifndef NDEBUG
+ printf("argv[0] = '%s'\n", argv[0]);
+#endif
+ for (i = 1; (i < argc) && !error; i++)
+ {
+#ifndef NDEBUG
+ printf("argv[%d] = '%s'\n", i, argv[i]);
+#endif
+
+ if (argv[i][0] == '-')
+ {
+ switch (argv[i][1])
+ {
+ case 'g':
+ // Parse game options
+ {
+ i++;
+ if (i < argc)
+ {
+ char* paramname = argv[i];
+ // Check for single value versus assignment
+ if (i+1 < argc && (*(argv[i+1]) == '='))
+ {
+ i++;
+ if (i + 1 < argc)
+ {
+ i++;
+ // Assignment
+ SYS_WriteCommandLineString(syshandle, paramname, argv[i]);
+ }
+ else
+ {
+ error = true;
+ printf("error: argument assignment %s without value.\n", paramname);
+ }
+ }
+ else
+ {
+ SYS_WriteCommandLineInt(syshandle, argv[i], 1);
+ }
+ }
+ }
+ break;
+
+ case 'p':
+ // Parse window position and size options
+ if (argv[i][2] == 0) {
+ i++;
+ if ((i + 4) < argc)
+ {
+ windowLeft = atoi(argv[i++]);
+ windowTop = atoi(argv[i++]);
+ windowWidth = atoi(argv[i++]);
+ windowHeight = atoi(argv[i]);
+ windowParFound = true;
+ }
+ else
+ {
+ error = true;
+ printf("error: too few options for window argument.\n");
+ }
+ }
+ break;
+
+ case 'f':
+ // Parse window position and size options
+ {
+ fullScreen = true;
+ i++;
+ if ((i + 4) < argc)
+ {
+ fullScreenWidth = atoi(argv[i++]);
+ fullScreenHeight = atoi(argv[i++]);
+ fullScreenBpp = atoi(argv[i++]);
+ fullScreenFrequency = atoi(argv[i]);
+ fullScreenParFound = true;
+ }
+ else
+ {
+ error = true;
+ printf("error: too few options for fullscreen argument.\n");
+ }
+ }
+ break;
+ case 'c':
+ i++;
+ closeConsole = false;
+ break;
+ case 's': // stereo
+ i++;
+ if ((i + 1) < argc)
+ {
+ if(!strcmp(argv[i], "nostereo")) // ok, redundant but clear
+ stereomode = RAS_IRasterizer::RAS_STEREO_NOSTEREO;
+
+ // only the hardware pageflip method needs a stereo window
+ if(!strcmp(argv[i], "hwpageflip")) {
+ stereomode = RAS_IRasterizer::RAS_STEREO_QUADBUFFERED;
+ stereoWindow = true;
+ }
+ if(!strcmp(argv[i], "syncdoubling"))
+ stereomode = RAS_IRasterizer::RAS_STEREO_ABOVEBELOW;
+#if 0
+ // future stuff
+ if(strcmp(argv[i], "stencil")
+ stereomode = RAS_STEREO_STENCIL;
+#endif
+
+ i++;
+ stereoParFound = true;
+ }
+ else
+ {
+ error = true;
+ printf("error: too few options for stereo argument.\n");
+ }
+ break;
+ }
+ }
+ else
+ {
+ }
+ }
+
+ if ((windowWidth < kMinWindowWidth) || (windowHeight < kMinWindowHeight))
+ {
+ error = true;
+ printf("error: window size too small.\n");
+ }
+
+ if (error)
+ {
+ usage(argv[0]);
+ }
+ else
+ {
+#ifdef __APPLE__
+ //SYS_WriteCommandLineInt(syshandle, "show_framerate", 1);
+ SYS_WriteCommandLineInt(syshandle, "nomipmap", 1);
+ //fullScreen = false; // Can't use full screen
+#endif
+ if (SYS_GetCommandLineInt(syshandle, "nomipmap", 0))
+ {
+ GPC_PolygonMaterial::SetMipMappingEnabled(0);
+ }
+
+ // Create the system
+ if (GHOST_ISystem::createSystem() == GHOST_kSuccess)
+ {
+ GHOST_ISystem* system = GHOST_ISystem::getSystem();
+ assertd(system);
+
+ // process first batch of events. If the user
+ // drops a file on top off the blenderplayer icon, we
+ // recieve an event with the filename
+
+ system->processEvents(0);
+
+ // this bracket is needed for app (see below) to get out
+ // of scope before GHOST_ISystem::disposeSystem() is called.
+ {
+ int exitcode = KX_EXIT_REQUEST_NO_REQUEST;
+ STR_String exitstring = "";
+ GPG_Application app(system, NULL, exitstring);
+ bool firstTimeRunning = true;
+
+ do
+ {
+ // Read the Blender file
+ char *filename = get_filename(argc, argv);
+ char *titlename;
+ char pathname[160];
+ BlendFileData *bfd;
+
+ // if we got an exitcode 3 (KX_EXIT_REQUEST_START_OTHER_GAME) load a different file
+ if (exitcode == KX_EXIT_REQUEST_START_OTHER_GAME)
+ {
+ char basedpath[160];
+
+ // base the actuator filename with respect
+ // to the original file working directory
+ strcpy(basedpath, exitstring.Ptr());
+ BLI_convertstringcode(basedpath, pathname, 0);
+
+ bfd = load_game_data(NULL, basedpath);
+ }
+ else
+ {
+ bfd = load_game_data(argv[0], filename);
+ }
+
+ //::printf("game data loaded from %s\n", filename);
+
+ if (!bfd) {
+ usage(argv[0]);
+ error = true;
+ exitcode = KX_EXIT_REQUEST_QUIT_GAME;
+ }
+ else
+ {
+#ifdef WIN32
+#ifdef NDEBUG
+ if (closeConsole)
+ {
+ ::FreeConsole(); // Close a console window
+ }
+#endif // NDEBUG
+#endif // WIN32
+ Main *maggie = bfd->main;
+ Scene *scene = bfd->curscene;
+ strcpy (pathname, maggie->name);
+ char *startscenename = scene->id.name + 2;
+
+ titlename = maggie->name;
+
+ // Check whether the game should be displayed full-screen
+ if ((!fullScreenParFound) && (!windowParFound))
+ {
+ // Only use file settings when command line did not override
+ if (scene->r.fullscreen) {
+ //printf("fullscreen option found in Blender file\n");
+ fullScreen = true;
+ fullScreenWidth= scene->r.xplay;
+ fullScreenHeight= scene->r.yplay;
+ fullScreenFrequency= scene->r.freqplay;
+ fullScreenBpp = scene->r.depth;
+ }
+ else
+ {
+ fullScreen = false;
+ windowWidth = scene->r.xplay;
+ windowHeight = scene->r.yplay;
+ }
+ }
+
+
+ // Check whether the game should be displayed in stereo
+ if (!stereoParFound)
+ {
+ if(scene->r.stereomode == RAS_IRasterizer::RAS_STEREO_NOSTEREO) // ok, redundant but clear
+ stereomode = RAS_IRasterizer::RAS_STEREO_NOSTEREO;
+
+ // only the hardware pageflip method needs a stereo window
+ if(scene->r.stereomode == RAS_IRasterizer::RAS_STEREO_QUADBUFFERED) {
+ stereomode = RAS_IRasterizer::RAS_STEREO_QUADBUFFERED;
+ stereoWindow = true;
+ }
+ if(scene->r.stereomode == RAS_IRasterizer::RAS_STEREO_ABOVEBELOW)
+ stereomode = RAS_IRasterizer::RAS_STEREO_ABOVEBELOW;
+#if 0
+ // future stuff
+ if(scene->r.stereomode == RAS_IRasterizer::RAS_STEREO_STENCIL)
+ stereomode = RAS_STEREO_STENCIL;
+#endif
+ }
+
+ // GPG_Application app (system, maggie, startscenename);
+ app.SetGameEngineData(maggie, startscenename);
+
+ if (firstTimeRunning)
+ {
+ firstTimeRunning = false;
+
+ if (fullScreen)
+ {
+ app.startFullScreen(fullScreenWidth, fullScreenHeight, fullScreenBpp, fullScreenFrequency,
+ stereoWindow, stereomode);
+ }
+ else
+ {
+#ifdef __APPLE__
+ // on Mac's we'll show the executable name instead of the 'game.blend' name
+ char tempname[1024], *appstring;
+ ::strcpy(tempname, titlename);
+
+ appstring = strstr(tempname, ".app/");
+ if (appstring) {
+ appstring[2] = 0;
+ titlename = &tempname[0];
+ }
+#endif
+ // Strip the path so that we have the name of the game file
+ STR_String path = titlename;
+#ifndef WIN32
+ vector<STR_String> parts = path.Explode('/');
+#else // WIN32
+ vector<STR_String> parts = path.Explode('\\');
+#endif // WIN32
+ STR_String title;
+ if (parts.size())
+ {
+ title = parts[parts.size()-1];
+ parts = title.Explode('.');
+ if (parts.size() > 1)
+ {
+ title = parts[0];
+ }
+ }
+ else
+ {
+ title = "blenderplayer";
+ }
+ app.startWindow(title, windowLeft, windowTop, windowWidth, windowHeight,
+ stereoWindow, stereomode);
+ }
+ }
+ else
+ {
+ app.StartGameEngine(stereomode);
+ exitcode = KX_EXIT_REQUEST_NO_REQUEST;
+ }
+
+ // Add the application as event consumer
+ system->addEventConsumer(&app);
+
+ // Enter main loop
+ bool run = true;
+ while (run)
+ {
+ system->processEvents(true);
+ system->dispatchEvents();
+ if (exitcode = app.getExitRequested())
+ {
+ run = false;
+ exitstring = app.getExitString();
+ }
+ }
+ app.StopGameEngine();
+ BLO_blendfiledata_free(bfd);
+
+#ifdef __APPLE__
+ if (filename) {
+ delete [] filename;
+ }
+#endif // __APPLE__
+ }
+ } while (exitcode == KX_EXIT_REQUEST_RESTART_GAME || exitcode == KX_EXIT_REQUEST_START_OTHER_GAME);
+ }
+ // Dispose the system
+ GHOST_ISystem::disposeSystem();
+ } else {
+ error = true;
+ printf("error: couldn't create a system.\n");
+ }
+ }
+
+ return error ? -1 : 0;
+}
+
+