Merged 15170:15635 from trunk (no conflicts or even merges)
[blender.git] / source / gameengine / GamePlayer / ghost / GPG_ghost.cpp
index 1d631a6f740241223e1fb92e1988e263dce5ba2b..8222e5c8bac8da78f5c7a0b14960db8aff3f4b3f 100644 (file)
@@ -1,15 +1,12 @@
 /**
 * $Id$
 *
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ * ***** BEGIN GPL 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.
+ * of the License, or (at your option) any later version.
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  *
  * Contributor(s): none yet.
  *
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ * ***** END GPL LICENSE BLOCK *****
 * Start up of the Blender Player on GHOST.
 */
 
 #include <iostream>
 #include <math.h>
 
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
 #ifdef __linux__
 #ifdef __alpha__
 #include <signal.h>
 extern "C"
 {
 #endif  // __cplusplus
-       
+#include "BKE_global.h"        
+#include "BKE_icons.h" 
 #include "BLI_blenlib.h"
 #include "DNA_scene_types.h"
 #include "BLO_readfile.h"
+#include "BLO_readblenfile.h"
        
        int GHOST_HACK_getFirstFile(char buf[]);
        
@@ -81,10 +76,11 @@ extern "C"
 #include "RAS_IRasterizer.h"
 
 #include "BKE_main.h"
+#include "BKE_utildefines.h"
 
 #ifdef WIN32
-#ifdef NDEBUG
 #include <windows.h>
+#ifdef NDEBUG
 #include <wincon.h>
 #endif // NDEBUG
 #endif // WIN32
@@ -92,6 +88,64 @@ extern "C"
 const int kMinWindowWidth = 100;
 const int kMinWindowHeight = 100;
 
+char bprogname[FILE_MAXDIR+FILE_MAXFILE];
+
+#ifdef WIN32
+typedef enum 
+{
+  SCREEN_SAVER_MODE_NONE = 0,
+  SCREEN_SAVER_MODE_PREVIEW,
+  SCREEN_SAVER_MODE_SAVER,
+  SCREEN_SAVER_MODE_CONFIGURATION,
+  SCREEN_SAVER_MODE_PASSWORD,
+} ScreenSaverMode;
+
+static ScreenSaverMode scr_saver_mode = SCREEN_SAVER_MODE_NONE;
+static HWND scr_saver_hwnd = NULL;
+
+static BOOL scr_saver_init(int argc, char **argv) 
+{
+       scr_saver_mode = SCREEN_SAVER_MODE_NONE;
+       scr_saver_hwnd = NULL;
+       BOOL ret = FALSE;
+
+       int len = ::strlen(argv[0]);
+       if (len > 4 && !::stricmp(".scr", argv[0] + len - 4))
+       {
+               scr_saver_mode = SCREEN_SAVER_MODE_CONFIGURATION;
+               ret = TRUE;
+               if (argc >= 2)
+               {
+                       if (argc >= 3)
+                       {
+                               scr_saver_hwnd = (HWND) ::atoi(argv[2]);
+                       }
+                       if (!::stricmp("/c", argv[1]))
+                       {
+                               scr_saver_mode = SCREEN_SAVER_MODE_CONFIGURATION;
+                               if (scr_saver_hwnd == NULL)
+                                       scr_saver_hwnd = ::GetForegroundWindow();
+                       }
+                       else if (!::stricmp("/s", argv[1]))
+                       {
+                               scr_saver_mode = SCREEN_SAVER_MODE_SAVER;
+                       }
+                       else if (!::stricmp("/a", argv[1]))
+                       {
+                               scr_saver_mode = SCREEN_SAVER_MODE_PASSWORD;
+                       }
+                       else if (!::stricmp("/p", argv[1])
+                                || !::stricmp("/l", argv[1]))
+                       {
+                               scr_saver_mode = SCREEN_SAVER_MODE_PREVIEW;
+                       }
+               }
+       }
+       return ret;
+}
+
+#endif /* WIN32 */
+
 void usage(char* program)
 {
        char * consoleoption;
@@ -101,8 +155,10 @@ void usage(char* program)
        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("usage:   %s [-w [-p l t w h]] %s[-g gamengineoptions] "
+               "[-s stereomode] filename.blend\n", program, consoleoption);
+       printf("  -h: Prints this command summary\n");
+       printf("  -w: display in a window\n");
        printf("  -p: specify window position\n");
        printf("       l = window left coordinate\n");
        printf("       t = window top coordinate\n");
@@ -114,12 +170,27 @@ void usage(char* program)
        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");
+       printf("       stereomode: hwpageflip       (Quad buffered shutter glasses)\n");
+       printf("                   syncdoubling     (Above Below)\n");
+       printf("                   sidebyside       (Left Right)\n");
+       printf("                   anaglyph         (Red-Blue glasses)\n");
+       printf("                   vinterlace       (Vertical interlace for autostereo display)\n");
+       printf("                             depending on the type of stereo you want\n");
 #ifdef _WIN32
        printf("  -c: keep console window open\n");
 #endif
+       printf("  -g: game engine options:\n");
+       printf("       Name            Default      Description\n");
+       printf("       ----------------------------------------\n");
+       printf("       fixedtime          0         Do the same timestep each frame \"Enable all frames\"\n");
+       printf("       nomipmap           0         Disable mipmaps\n");
+       printf("       show_framerate     0         Show the frame rate\n");
+       printf("       show_properties    0         Show debug properties\n");
+       printf("       show_profile       0         Show profiling information\n");
+       printf("       blender_material   0         Enable material settings\n");
        printf("\n");
        printf("example: %s -p 10 10 320 200 -g noaudio c:\\loadtest.blend\n", program);
+       printf("example: %s -g show_framerate = 0 c:\\loadtest.blend\n", program);
 }
 
 char *get_filename(int argc, char **argv) {
@@ -169,19 +240,21 @@ char *get_filename(int argc, char **argv) {
 #endif // !_APPLE
 }
 
-BlendFileData *load_game_data(char *progname, char *filename) {
+static BlendFileData *load_game_data(char *progname, char *filename = NULL) {
        BlendReadError error;
-       BlendFileData *bfd;
+       BlendFileData *bfd = NULL;
        
        /* 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 (blo_is_a_runtime(progname)) {
+               bfd= blo_read_runtime(progname, &error);
+               if (bfd) {
+                       bfd->type= BLENFILETYPE_RUNTIME;
+                       strcpy(bfd->main->name, progname);
                }
+       } else {
+               bfd= BLO_read_from_file(progname, &error);
        }
-       
+       
        /*
        if (bfd && bfd->type == BLENFILETYPE_BLEND) {
                BLO_blendfiledata_free(bfd);
@@ -190,8 +263,9 @@ BlendFileData *load_game_data(char *progname, char *filename) {
        }
        */
        
-       if (!bfd) {
-               if (filename) {
+       if (!bfd && filename) {
+               bfd = load_game_data(filename);
+               if (!bfd) {
                        printf("Loading %s failed: %s\n", filename, BLO_bre_as_string(error));
                }
        }
@@ -208,24 +282,24 @@ int main(int argc, char** argv)
        bool fullScreenParFound = false;
        bool windowParFound = false;
        bool closeConsole = true;
-       int stereomode = RAS_IRasterizer::RAS_STEREO_NOSTEREO;
+       RAS_IRasterizer::StereoMode stereomode;
        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;
+       GHOST_TUns32 fullScreenWidth = 0;
+       GHOST_TUns32 fullScreenHeight= 0;
+       int fullScreenBpp = 32;
        int fullScreenFrequency = 60;
-       
+
 #ifdef __linux__
 #ifdef __alpha__
        signal (SIGFPE, SIG_IGN);
 #endif /* __alpha__ */
 #endif /* __linux__ */
-       
+       BLI_where_am_i(bprogname, argv[0]);
 #ifdef __APPLE__
     // Can't use Carbon right now because of double defined type ID (In Carbon.h and DNA_ID.h, sigh)
     /*
@@ -249,17 +323,44 @@ int main(int argc, char** argv)
 #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++)
+
+#ifdef WIN32
+       if (scr_saver_init(argc, argv))
+       {
+               switch (scr_saver_mode)
+               {
+               case SCREEN_SAVER_MODE_CONFIGURATION:
+                       MessageBox(scr_saver_hwnd, "This screen saver has no options that you can set", "Screen Saver", MB_OK);
+                       break;
+               case SCREEN_SAVER_MODE_PASSWORD:
+                       /* This is W95 only, which we currently do not support.
+                          Fall-back to normal screen saver behaviour in that case... */
+               case SCREEN_SAVER_MODE_SAVER:
+                       fullScreen = true;
+                       fullScreenParFound = true;
+                       break;
+
+               case SCREEN_SAVER_MODE_PREVIEW:
+                       /* This will actually be handled somewhere below... */
+                       break;
+               }
+       }
+#endif
+       for (i = 1; (i < argc) && !error 
+#ifdef WIN32
+               && scr_saver_mode == SCREEN_SAVER_MODE_NONE
+#endif
+               ;)
+
        {
 #ifndef NDEBUG
-               printf("argv[%d] = '%s'\n", i, argv[i]);
+               printf("argv[%d] = '%s'   , %i\n", i, argv[i],argc);
 #endif
-               
                if (argv[i][0] == '-')
                {
                        switch (argv[i][1])
@@ -279,7 +380,13 @@ int main(int argc, char** argv)
                                                        {
                                                                i++;
                                                                // Assignment
+                                                               SYS_WriteCommandLineInt(syshandle, paramname, atoi(argv[i]));
+                                                               SYS_WriteCommandLineFloat(syshandle, paramname, atof(argv[i]));
                                                                SYS_WriteCommandLineString(syshandle, paramname, argv[i]);
+#ifndef NDEBUG
+                                                               printf("%s = '%s'\n", paramname, argv[i]);
+#endif
+                                                               i++;
                                                        }
                                                        else
                                                        {
@@ -289,7 +396,7 @@ int main(int argc, char** argv)
                                                }
                                                else
                                                {
-                                                       SYS_WriteCommandLineInt(syshandle, argv[i], 1);
+//                                                     SYS_WriteCommandLineInt(syshandle, argv[i++], 1);
                                                }
                                        }
                                }
@@ -304,7 +411,7 @@ int main(int argc, char** argv)
                                                windowLeft = atoi(argv[i++]);
                                                windowTop = atoi(argv[i++]);
                                                windowWidth = atoi(argv[i++]);
-                                               windowHeight = atoi(argv[i]);
+                                               windowHeight = atoi(argv[i++]);
                                                windowParFound = true;
                                        }
                                        else
@@ -312,29 +419,40 @@ int main(int argc, char** argv)
                                                error = true;
                                                printf("error: too few options for window argument.\n");
                                        }
+                               } else { /* mac specific */
+                               
+                    if (strncmp(argv[i], "-psn_", 5)==0) 
+                        i++; /* skip process serial number */
                                }
                                break;
-                               
                        case 'f':
-                               // Parse window position and size options
+                               i++;
+                               fullScreen = true;
+                               fullScreenParFound = true;
+                               if ((i + 2) < argc && argv[i][0] != '-' && argv[i+1][0] != '-')
                                {
-                                       fullScreen = true;
-                                       i++;
-                                       if ((i + 4) < argc)
+                                       fullScreenWidth = atoi(argv[i++]);
+                                       fullScreenHeight = atoi(argv[i++]);
+                                       if ((i + 1) < argc && argv[i][0] != '-')
                                        {
-                                               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");
+                                               if ((i + 1) < argc && argv[i][0] != '-')
+                                                       fullScreenFrequency = atoi(argv[i++]);
                                        }
                                }
                                break;
+                       case 'w':
+                               // Parse window position and size options
+                               {
+                                       fullScreen = false;
+                                       fullScreenParFound = true;
+                                       i++;
+                               }
+                               break;
+                       case 'h':
+                               usage(argv[0]);
+                               return 0;
+                               break;
                        case 'c':
                                i++;
                                closeConsole = false;
@@ -343,6 +461,10 @@ int main(int argc, char** argv)
                                i++;
                                if ((i + 1) < argc)
                                {
+                                       stereomode = (RAS_IRasterizer::StereoMode) atoi(argv[i]);
+                                       if (stereomode < RAS_IRasterizer::RAS_STEREO_NOSTEREO || stereomode >= RAS_IRasterizer::RAS_STEREO_MAXSTEREO)
+                                               stereomode = RAS_IRasterizer::RAS_STEREO_NOSTEREO;
+                                       
                                        if(!strcmp(argv[i], "nostereo"))  // ok, redundant but clear
                                                stereomode = RAS_IRasterizer::RAS_STEREO_NOSTEREO;
                                        
@@ -353,6 +475,16 @@ int main(int argc, char** argv)
                                        }
                                        if(!strcmp(argv[i], "syncdoubling"))
                                                stereomode = RAS_IRasterizer::RAS_STEREO_ABOVEBELOW;
+                                       
+                                       if(!strcmp(argv[i], "anaglyph"))
+                                               stereomode = RAS_IRasterizer::RAS_STEREO_ANAGLYPH;
+                                       
+                                       if(!strcmp(argv[i], "sidebyside"))
+                                               stereomode = RAS_IRasterizer::RAS_STEREO_SIDEBYSIDE;
+                                       
+                                       if(!strcmp(argv[i], "vinterlace"))
+                                               stereomode = RAS_IRasterizer::RAS_STEREO_VINTERLACE;
+                                       
 #if 0
                                        // future stuff
                                        if(strcmp(argv[i], "stencil")
@@ -368,10 +500,14 @@ int main(int argc, char** argv)
                                        printf("error: too few options for stereo argument.\n");
                                }
                                break;
+                       default:
+                               printf("Unkown argument: %s\n", argv[i++]);
+                               break;
                        }
                }
                else
                {
+                       i++;
                }
        }
        
@@ -381,17 +517,24 @@ int main(int argc, char** argv)
                printf("error: window size too small.\n");
        }
        
-       if (error)
+       if (error )
        {
                usage(argv[0]);
+               return 0;
        }
-       else
+
+       if (!stereoParFound) stereomode = RAS_IRasterizer::RAS_STEREO_NOSTEREO;
+
+#ifdef WIN32
+       if (scr_saver_mode != SCREEN_SAVER_MODE_CONFIGURATION)
+#endif
        {
 #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);
@@ -403,6 +546,8 @@ int main(int argc, char** argv)
                        GHOST_ISystem* system = GHOST_ISystem::getSystem();
                        assertd(system);
                        
+                       if (!fullScreenWidth || !fullScreenHeight)
+                               system->getMainDisplayDimensions(fullScreenWidth, fullScreenHeight);
                        // process first batch of events. If the user
                        // drops a file on top off the blenderplayer icon, we 
                        // recieve an event with the filename
@@ -416,26 +561,37 @@ int main(int argc, char** argv)
                                STR_String exitstring = "";
                                GPG_Application app(system, NULL, exitstring);
                                bool firstTimeRunning = true;
+                               char *filename = get_filename(argc, argv);
+                               char *titlename;
+                               char pathname[160];
                                
                                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];
+                                               char basedpath[240];
                                                
                                                // base the actuator filename with respect
                                                // to the original file working directory
                                                strcpy(basedpath, exitstring.Ptr());
-                                               BLI_convertstringcode(basedpath, pathname, 0);
+                                               BLI_convertstringcode(basedpath, pathname);
                                                
-                                               bfd = load_game_data(NULL, basedpath);
+                                               bfd = load_game_data(basedpath);
+
+                                               if (!bfd)
+                                               {
+                                                       // just add "//" in front of it
+                                                       char temppath[242];
+                                                       strcpy(temppath, "//");
+                                                       strcat(temppath, basedpath);
+                               
+                                                       BLI_convertstringcode(temppath, pathname);
+                                                       bfd = load_game_data(temppath);
+                                               }
                                        }
                                        else
                                        {
@@ -455,14 +611,17 @@ int main(int argc, char** argv)
 #ifdef NDEBUG
                                                if (closeConsole)
                                                {
-                                                       ::FreeConsole();    // Close a console window
+                                                       //::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;
+                                               G.fileflags  = bfd->fileflags;
+
+                                               //Seg Fault; icon.c gIcons == 0
+                                               BKE_icons_init(1);
                                                
                                                titlename = maggie->name;
                                                
@@ -490,21 +649,9 @@ int main(int argc, char** argv)
                                                // 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;
+                                                       stereomode = (RAS_IRasterizer::StereoMode) scene->r.stereomode;
+                                                       if (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);
@@ -513,11 +660,26 @@ int main(int argc, char** argv)
                                                if (firstTimeRunning)
                                                {
                                                        firstTimeRunning = false;
-                                                       
+
+                                                       // set the filename only the first time as in KetsjiEmbedded
+                                                       strcpy (pathname, maggie->name);
+                                                       // also copy here (used by GameLogic.getBaseDirectory)
+                                                       strcpy (G.sce, maggie->name);
+
                                                        if (fullScreen)
                                                        {
-                                                               app.startFullScreen(fullScreenWidth, fullScreenHeight, fullScreenBpp, fullScreenFrequency,
-                                                                       stereoWindow, stereomode);
+#ifdef WIN32
+                                                               if (scr_saver_mode == SCREEN_SAVER_MODE_SAVER)
+                                                               {
+                                                                       app.startScreenSaverFullScreen(fullScreenWidth, fullScreenHeight, fullScreenBpp, fullScreenFrequency,
+                                                                               stereoWindow, stereomode);
+                                                               }
+                                                               else
+#endif
+                                                               {
+                                                                       app.startFullScreen(fullScreenWidth, fullScreenHeight, fullScreenBpp, fullScreenFrequency,
+                                                                               stereoWindow, stereomode);
+                                                               }
                                                        }
                                                        else
                                                        {
@@ -553,8 +715,17 @@ int main(int argc, char** argv)
                                                                {
                                                                        title = "blenderplayer";
                                                                }
-                                                               app.startWindow(title, windowLeft, windowTop, windowWidth, windowHeight,
-                                                                       stereoWindow, stereomode);
+#ifdef WIN32
+                                                               if (scr_saver_mode == SCREEN_SAVER_MODE_PREVIEW)
+                                                               {
+                                                                       app.startScreenSaverPreview(scr_saver_hwnd, stereoWindow, stereomode);
+                                                               }
+                                                               else
+#endif
+                                                               {
+                                                                       app.startWindow(title, windowLeft, windowTop, windowWidth, windowHeight,
+                                                                               stereoWindow, stereomode);
+                                                               }
                                                        }
                                                }
                                                else
@@ -570,9 +741,9 @@ int main(int argc, char** argv)
                                                bool run = true;
                                                while (run)
                                                {
-                                                       system->processEvents(true);
+                                                       system->processEvents(false);
                                                        system->dispatchEvents();
-                                                       if (exitcode = app.getExitRequested())
+                                                       if ((exitcode = app.getExitRequested()))
                                                        {
                                                                run = false;
                                                                exitstring = app.getExitString();
@@ -589,6 +760,10 @@ int main(int argc, char** argv)
                                        }
                                } while (exitcode == KX_EXIT_REQUEST_RESTART_GAME || exitcode == KX_EXIT_REQUEST_START_OTHER_GAME);
                        }
+
+                       // Seg Fault; icon.c gIcons == 0
+                       BKE_icons_free();
+
                        // Dispose the system
                        GHOST_ISystem::disposeSystem();
                } else {
@@ -596,7 +771,7 @@ int main(int argc, char** argv)
                        printf("error: couldn't create a system.\n");
                }
        }
-       
+
        return error ? -1 : 0;
 }