.scr patch (from Raymond Penners)
[blender.git] / source / gameengine / GamePlayer / ghost / GPG_ghost.cpp
index f725d5c0dd38ae3378dad48f15f2ba8a9772f9c1..d7a9ad2b41dcb6754988ddebb20d0c417a660d0a 100644 (file)
@@ -63,6 +63,7 @@ extern "C"
 #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 +82,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 +94,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 +161,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 +176,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("       vertexarrays       1         Enable vertex arrays\n");
        printf("\n");
        printf("example: %s -p 10 10 320 200 -g noaudio c:\\loadtest.blend\n", program);
+       printf("example: %s -g vertexarrays = 0 c:\\loadtest.blend\n", program);
 }
 
 char *get_filename(int argc, char **argv) {
@@ -169,27 +246,32 @@ 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);
                bfd = NULL;
                error = BRE_NOT_A_PUBFILE;
        }
+       */
        
-       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));
                }
        }
@@ -206,16 +288,16 @@ 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 = 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;
+       GHOST_TUns32 fullScreenWidth = 0;
+       GHOST_TUns32 fullScreenHeight= 0;
+       int fullScreenBpp = 32;
        int fullScreenFrequency = 60;
        
 #ifdef __linux__
@@ -223,6 +305,7 @@ int main(int argc, char** argv)
        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)
@@ -247,17 +330,45 @@ 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])
@@ -277,7 +388,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
                                                        {
@@ -287,7 +404,7 @@ int main(int argc, char** argv)
                                                }
                                                else
                                                {
-                                                       SYS_WriteCommandLineInt(syshandle, argv[i], 1);
+                                                       SYS_WriteCommandLineInt(syshandle, argv[i++], 1);
                                                }
                                        }
                                }
@@ -302,7 +419,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
@@ -310,29 +427,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;
@@ -341,6 +469,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;
                                        
@@ -351,6 +483,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")
@@ -366,10 +508,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++;
                }
        }
        
@@ -384,6 +530,9 @@ int main(int argc, char** argv)
                usage(argv[0]);
        }
        else
+#ifdef WIN32
+               if (scr_saver_mode != SCREEN_SAVER_MODE_CONFIGURATION)
+#endif
        {
 #ifdef __APPLE__
                //SYS_WriteCommandLineInt(syshandle, "show_framerate", 1);
@@ -401,6 +550,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
@@ -433,7 +584,7 @@ int main(int argc, char** argv)
                                                strcpy(basedpath, exitstring.Ptr());
                                                BLI_convertstringcode(basedpath, pathname, 0);
                                                
-                                               bfd = load_game_data(NULL, basedpath);
+                                               bfd = load_game_data(basedpath);
                                        }
                                        else
                                        {
@@ -488,21 +639,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);
@@ -514,8 +653,18 @@ int main(int argc, char** argv)
                                                        
                                                        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
                                                        {
@@ -551,8 +700,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
@@ -568,9 +726,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();