]> git.jsancho.org Git - lugaru.git/blobdiff - Source/OpenGL_Windows.cpp
mingw: Temporarily disable glstubs logic to fix build
[lugaru.git] / Source / OpenGL_Windows.cpp
index a0ace20b7ac291148281b2d202ae3841fc8c20bb..d74b557c4aeb66f87a6f046389e9812d2792dca6 100644 (file)
@@ -21,29 +21,14 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 
 #ifdef WIN32
-#define UINT8 WIN32API_UINT8
-#define UINT16 WIN32API_UINT16
-#define boolean WIN32API_boolean
 #include <windows.h>
-#undef UINT8
-#undef UINT16
-#undef boolean
 #endif
 
-
-
 #include "Game.h"
-extern "C" {
-#include "zlib.h"
-#include "png.h"
-#ifdef WIN32
-#define INT32 INT32_jpeg
-#include "jpeglib.h"
-#undef INT32
-#else
-#include "jpeglib.h"
-#endif
-}
+
+#include <jpeglib.h>
+#include <png.h>
+#include <zlib.h>
 
 using namespace Game;
 
@@ -89,18 +74,11 @@ extern float slomofreq;
 #include "win-res/resource.h"
 #endif
 
+extern SDL_Window *sdlwindow;
+
 using namespace std;
 
 SDL_Rect **resolutions = NULL;
-static SDL_Rect rect_1024_768 = { 0, 0, 1024, 768 };
-static SDL_Rect rect_800_600  = { 0, 0, 800,  600 };
-static SDL_Rect rect_640_480  = { 0, 0, 640,  480 };
-static SDL_Rect *hardcoded_resolutions[] = {
-    &rect_1024_768,
-    &rect_800_600,
-    &rect_640_480,
-    NULL
-};
 
 Boolean SetUp ();
 void DoUpdate ();
@@ -114,6 +92,7 @@ void CleanUp (void);
 #pragma warning(disable: 4273)
 #endif
 
+#ifndef __MINGW32__ // FIXME: Temporary workaround for GL-8
 #define GL_FUNC(ret,fn,params,call,rt) \
     extern "C" { \
         static ret (GLAPIENTRY *p##fn) params = NULL; \
@@ -121,6 +100,7 @@ void CleanUp (void);
     }
 #include "glstubs.h"
 #undef GL_FUNC
+#endif // __MINGW32__
 
 #ifdef _MSC_VER
 #pragma warning(pop)
@@ -139,10 +119,12 @@ static bool lookup_glsym(const char *funcname, void **func)
 static bool lookup_all_glsyms(void)
 {
     bool retval = true;
+#ifndef __MINGW32__ // FIXME: Temporary workaround for GL-8
 #define GL_FUNC(ret,fn,params,call,rt) \
         if (!lookup_glsym(#fn, (void **) &p##fn)) retval = false;
 #include "glstubs.h"
 #undef GL_FUNC
+#endif // __MINGW32__
     return retval;
 }
 
@@ -163,10 +145,8 @@ int kContextHeight;
 
 Boolean gDone = false;
 
-#ifndef __MINGW32__
 static int _argc = 0;
 static char **_argv = NULL;
-#endif
 
 bool cmdline(const char *cmd)
 {
@@ -194,7 +174,7 @@ void initGL()
     glDisable( GL_ALPHA_TEST);
     glDisable( GL_BLEND);
     glDisable( GL_DEPTH_TEST);
-    // glDisable( GL_DITHER);
+    //glDisable( GL_DITHER);
     glDisable( GL_FOG);
     glDisable( GL_LIGHTING);
     glDisable( GL_LOGIC_OP);
@@ -215,13 +195,13 @@ void initGL()
     glClearDepth( 1.0f);
     glDepthFunc( GL_LEQUAL);
     glDepthMask( GL_TRUE);
-    // glDepthRange( FRONT_CLIP, BACK_CLIP);
+    //glDepthRange( FRONT_CLIP, BACK_CLIP);
     glEnable( GL_DEPTH_TEST);
     glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
     glCullFace( GL_FRONT);
     glEnable( GL_CULL_FACE);
     glEnable( GL_LIGHTING);
-//     glEnable( GL_LIGHT_MODEL_AMBIENT);
+    //glEnable( GL_LIGHT_MODEL_AMBIENT);
     glEnable( GL_DITHER);
     glEnable( GL_COLOR_MATERIAL);
     glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
@@ -238,45 +218,46 @@ void initGL()
 
 static void toggleFullscreen()
 {
-    if (!SDL_WM_ToggleFullScreen(SDL_GetVideoSurface())) {
-        SDL_Surface* screen = SDL_GetVideoSurface();
-        Uint32 flags = screen->flags;
-        screen = SDL_SetVideoMode(0, 0, 0, flags ^ SDL_FULLSCREEN);
-        if (!screen)
-            screen = SDL_SetVideoMode(0, 0, 0, flags);
-        if (!screen)
-            exit(1);
-        //reload opengl state
-        initGL();
-        Texture::reloadAll();
-        if (text)
-            text->BuildFont();
-        if (firstload) {
-            screentexture = 0;
-            LoadScreenTexture();
-        }
-        screentexture2 = 0;
+    Uint32 flags = SDL_GetWindowFlags(sdlwindow);
+    if (flags & SDL_WINDOW_FULLSCREEN) {
+        flags &= ~SDL_WINDOW_FULLSCREEN;
+    } else {
+        flags |= SDL_WINDOW_FULLSCREEN;
     }
+    SDL_SetWindowFullscreen(sdlwindow, flags);
 }
 
-static void sdlEventProc(const SDL_Event &e)
+static SDL_bool sdlEventProc(const SDL_Event &e)
 {
     switch (e.type) {
-    case SDL_MOUSEMOTION:
-        deltah += e.motion.xrel;
-        deltav += e.motion.yrel;
+        case SDL_QUIT:
+            return SDL_FALSE;
+
+        case SDL_WINDOWEVENT:
+            if (e.window.event == SDL_WINDOWEVENT_CLOSE) {
+                return SDL_FALSE;
+            }
         break;
 
-    case SDL_KEYDOWN:
-        if ((e.key.keysym.sym == SDLK_g) &&
-                (e.key.keysym.mod & KMOD_CTRL) &&
-                !(SDL_GetVideoSurface()->flags & SDL_FULLSCREEN) ) {
-            SDL_WM_GrabInput( ((SDL_WM_GrabInput(SDL_GRAB_QUERY) == SDL_GRAB_ON) ? SDL_GRAB_OFF : SDL_GRAB_ON) );
-        } else if ( (e.key.keysym.sym == SDLK_RETURN) && (e.key.keysym.mod & KMOD_ALT) ) {
-            toggleFullscreen();
-        }
+        case SDL_MOUSEMOTION:
+            deltah += e.motion.xrel;
+            deltav += e.motion.yrel;
+        break;
+
+        case SDL_KEYDOWN:
+            if ((e.key.keysym.scancode == SDL_SCANCODE_G) &&
+                (e.key.keysym.mod & KMOD_CTRL)) {
+                SDL_bool mode = SDL_TRUE;
+                if ((SDL_GetWindowFlags(sdlwindow) & SDL_WINDOW_FULLSCREEN) == 0)
+                    mode = (SDL_GetWindowGrab(sdlwindow) ? SDL_FALSE : SDL_TRUE);
+                SDL_SetWindowGrab(sdlwindow, mode);
+                SDL_SetRelativeMouseMode(mode);
+            } else if ( (e.key.keysym.scancode == SDL_SCANCODE_RETURN) && (e.key.keysym.mod & KMOD_ALT) ) {
+                toggleFullscreen();
+            }
         break;
     }
+    return SDL_TRUE;
 }
 
 
@@ -296,10 +277,11 @@ Boolean SetUp ()
     texdetail = 4;
     slomospeed = 0.25;
     slomofreq = 8012;
-    numplayers = 1;
 
     DefaultSettings();
 
+    const int displayIdx = 0;  // !!! FIXME: other monitors?
+
     if (!SDL_WasInit(SDL_INIT_VIDEO))
         if (SDL_Init(SDL_INIT_VIDEO) == -1) {
             fprintf(stderr, "SDL_Init() failed: %s\n", SDL_GetError());
@@ -319,15 +301,24 @@ Boolean SetUp ()
         return false;
     }
 
-    SDL_Rect **res = SDL_ListModes(NULL, SDL_FULLSCREEN | SDL_OPENGL);
-    if ( (res == NULL) || (res == ((SDL_Rect **) - 1)) || (res[0] == NULL) || (res[0]->w < 640) || (res[0]->h < 480) )
-        res = hardcoded_resolutions;
+    int count = 0;
+    const int nummodes = SDL_GetNumDisplayModes(displayIdx);
+    for (int i = 0; i < nummodes; i++)
+    {
+        SDL_DisplayMode mode;
+        if (SDL_GetDisplayMode(displayIdx, i, &mode) == -1)
+            continue;
+        if ((mode.w < 640) || (mode.h < 480))
+            continue;  // sane lower limit.
+        count++;
+    }
 
-    // reverse list (it was sorted biggest to smallest by SDL)...
-    int count;
-    for (count = 0; res[count]; count++) {
-        if ((res[count]->w < 640) || (res[count]->h < 480))
-            break;   // sane lower limit.
+    if (count == 0) {
+        const std::string error = "No suitable video resolutions found.";
+        cerr << error << endl;
+        SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Lugaru init failed!", error.c_str(), NULL);
+        SDL_Quit();
+        return false;
     }
 
     static SDL_Rect *resolutions_block = NULL;
@@ -341,7 +332,15 @@ Boolean SetUp ()
 
     resolutions[count--] = NULL;
     for (int i = 0; count >= 0; i++, count--) {
-        memcpy(&resolutions_block[count], res[i], sizeof (SDL_Rect));
+        /* FIXME - Pretty sure this should use nummodes and not count */
+        SDL_DisplayMode mode;
+        if (SDL_GetDisplayMode(displayIdx, i, &mode) == -1)
+            continue;
+        if ((mode.w < 640) || (mode.h < 480))
+            continue;  // sane lower limit.
+        resolutions_block[count].x = resolutions_block[count].y = 0;
+        resolutions_block[count].w = mode.w;
+        resolutions_block[count].h = mode.h;
         resolutions[count] = &resolutions_block[count];
     }
 
@@ -351,51 +350,68 @@ Boolean SetUp ()
             printf("  %d x %d\n", (int) resolutions[i]->w, (int) resolutions[i]->h);
     }
 
-    Uint32 sdlflags = SDL_OPENGL;
+    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
+    SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 1);
 
+    Uint32 sdlflags = SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN;
     if (!cmdline("windowed"))
-        sdlflags |= SDL_FULLSCREEN;
-
-    SDL_WM_SetCaption("Lugaru", "Lugaru");
+        sdlflags |= SDL_WINDOW_FULLSCREEN;
+    if (!cmdline("nomousegrab"))
+        sdlflags |= SDL_WINDOW_INPUT_GRABBED;
 
-    SDL_ShowCursor(0);
+    sdlwindow = SDL_CreateWindow("Lugaru", SDL_WINDOWPOS_CENTERED_DISPLAY(displayIdx), SDL_WINDOWPOS_CENTERED_DISPLAY(displayIdx),
+                                 kContextWidth, kContextHeight, sdlflags);
 
-    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
-    SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 1);
-#if SDL_VERSION_ATLEAST(1, 2, 10)
-    SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, vblsync);
-#endif
-
-    if (SDL_SetVideoMode(kContextWidth, kContextHeight, 0, sdlflags) == NULL) {
-        fprintf(stderr, "SDL_SetVideoMode() failed: %s\n", SDL_GetError());
+    if (!sdlwindow) {
+        fprintf(stderr, "SDL_CreateWindow() failed: %s\n", SDL_GetError());
         fprintf(stderr, "forcing 640x480...\n");
         kContextWidth = 640;
         kContextHeight = 480;
-        if (SDL_SetVideoMode(kContextWidth, kContextHeight, 0, sdlflags) == NULL) {
-            fprintf(stderr, "SDL_SetVideoMode() failed: %s\n", SDL_GetError());
+        sdlwindow = SDL_CreateWindow("Lugaru", SDL_WINDOWPOS_CENTERED_DISPLAY(displayIdx), SDL_WINDOWPOS_CENTERED_DISPLAY(displayIdx),
+                                     kContextWidth, kContextHeight, sdlflags);
+        if (!sdlwindow) {
+            fprintf(stderr, "SDL_CreateWindow() failed: %s\n", SDL_GetError());
             fprintf(stderr, "forcing 640x480 windowed mode...\n");
-            sdlflags &= ~SDL_FULLSCREEN;
-            if (SDL_SetVideoMode(kContextWidth, kContextHeight, 0, sdlflags) == NULL) {
-                fprintf(stderr, "SDL_SetVideoMode() failed: %s\n", SDL_GetError());
+            sdlflags &= ~SDL_WINDOW_FULLSCREEN;
+            sdlwindow = SDL_CreateWindow("Lugaru", SDL_WINDOWPOS_CENTERED_DISPLAY(displayIdx), SDL_WINDOWPOS_CENTERED_DISPLAY(displayIdx),
+                                         kContextWidth, kContextHeight, sdlflags);
+
+            if (!sdlwindow) {
+                fprintf(stderr, "SDL_CreateWindow() failed: %s\n", SDL_GetError());
                 return false;
             }
         }
     }
 
-    int dblbuf = 0;
-    if ((SDL_GL_GetAttribute(SDL_GL_DOUBLEBUFFER, &dblbuf) == -1) || (!dblbuf)) {
-        fprintf(stderr, "Failed to get double buffered GL context!\n");
+    SDL_GLContext glctx = SDL_GL_CreateContext(sdlwindow);
+    if (!glctx) {
+        fprintf(stderr, "SDL_GL_CreateContext() failed: %s\n", SDL_GetError());
         SDL_Quit();
         return false;
     }
 
+    SDL_GL_MakeCurrent(sdlwindow, glctx);
+
     if (!lookup_all_glsyms()) {
+        fprintf(stderr, "Missing required OpenGL functions.\n");
         SDL_Quit();
         return false;
     }
 
-    if (!cmdline("nomousegrab"))
-        SDL_WM_GrabInput(SDL_GRAB_ON);
+    int dblbuf = 0;
+    if ((SDL_GL_GetAttribute(SDL_GL_DOUBLEBUFFER, &dblbuf) == -1) || (!dblbuf))
+    {
+        fprintf(stderr, "Failed to get a double-buffered context.\n");
+        SDL_Quit();
+        return false;
+    }
+
+    if (SDL_GL_SetSwapInterval(-1) == -1)  // try swap_tear first.
+        SDL_GL_SetSwapInterval(1);
+
+    SDL_ShowCursor(0);
+    SDL_SetWindowGrab(sdlwindow, SDL_TRUE);
+    SDL_SetRelativeMouseMode(SDL_TRUE);
 
 
     initGL();
@@ -446,26 +462,29 @@ void DoFrameRate (int update)
     AbsoluteTime currTime = UpTime ();
     double deltaTime = (float) AbsoluteDeltaToDuration (currTime, frametime);
 
-    if (0 > deltaTime) // if negative microseconds
+    if (0 > deltaTime) // if negative microseconds
         deltaTime /= -1000000.0;
-    else                               // else milliseconds
+    else // else milliseconds
         deltaTime /= 1000.0;
 
     multiplier = deltaTime;
-    if (multiplier < .001) multiplier = .001;
-    if (multiplier > 10) multiplier = 10;
-    if (update) frametime = currTime;  // reset for next time interval
+    if (multiplier < .001)
+        multiplier = .001;
+    if (multiplier > 10)
+        multiplier = 10;
+    if (update)
+        frametime = currTime; // reset for next time interval
 
     deltaTime = (float) AbsoluteDeltaToDuration (currTime, time);
 
-    if (0 > deltaTime) // if negative microseconds
+    if (0 > deltaTime) // if negative microseconds
         deltaTime /= -1000000.0;
-    else                               // else milliseconds
+    else // else milliseconds
         deltaTime /= 1000.0;
     frames++;
-    if (0.001 <= deltaTime) {  // has update interval passed
+    if (0.001 <= deltaTime) { // has update interval passed
         if (update) {
-            time = currTime;   // reset for next time interval
+            time = currTime; // reset for next time interval
             frames = 0;
         }
     }
@@ -479,20 +498,26 @@ void DoUpdate ()
     static float oldmult;
 
     DoFrameRate(1);
-    if (multiplier > .6)multiplier = .6;
+    if (multiplier > .6)
+        multiplier = .6;
 
     fps = 1 / multiplier;
 
     count = multiplier * sps;
-    if (count < 2)count = 2;
+    if (count < 2)
+        count = 2;
 
     realmultiplier = multiplier;
     multiplier *= gamespeed;
-    if (difficulty == 1)multiplier *= .9;
-    if (difficulty == 0)multiplier *= .8;
-
-    if (loading == 4)multiplier *= .00001;
-    if (slomo && !mainmenu)multiplier *= slomospeed;
+    if (difficulty == 1)
+        multiplier *= .9;
+    if (difficulty == 0)
+        multiplier *= .8;
+
+    if (loading == 4)
+        multiplier *= .00001;
+    if (slomo && !mainmenu)
+        multiplier *= slomospeed;
     oldmult = multiplier;
     multiplier /= (float)count;
 
@@ -507,38 +532,38 @@ void DoUpdate ()
 
     TickOnceAfter();
     /* - Debug code to test how many channels were active on average per frame
-       static long frames = 0;
-
-       static AbsoluteTime start = {0,0};
-       AbsoluteTime currTime = UpTime ();
-       static int num_channels = 0;
-
-       num_channels += OPENAL_GetChannelsPlaying();
-       double deltaTime = (float) AbsoluteDeltaToDuration (currTime, start);
-
-       if (0 > deltaTime)      // if negative microseconds
-               deltaTime /= -1000000.0;
-       else                            // else milliseconds
-               deltaTime /= 1000.0;
-
-       ++frames;
-
-       if (deltaTime >= 1)
-       {
-               start = currTime;
-               float avg_channels = (float)num_channels / (float)frames;
-
-               ofstream opstream("log.txt",ios::app);
-               opstream << "Average frame count: ";
-               opstream << frames;
-               opstream << " frames - ";
-               opstream << avg_channels;
-               opstream << " per frame.\n";
-               opstream.close();
-
-               frames = 0;
-               num_channels = 0;
-       }
+        static long frames = 0;
+
+        static AbsoluteTime start = {0,0};
+        AbsoluteTime currTime = UpTime ();
+        static int num_channels = 0;
+
+        num_channels += OPENAL_GetChannelsPlaying();
+        double deltaTime = (float) AbsoluteDeltaToDuration (currTime, start);
+
+        if (0 > deltaTime)  // if negative microseconds
+            deltaTime /= -1000000.0;
+        else                // else milliseconds
+            deltaTime /= 1000.0;
+
+        ++frames;
+
+        if (deltaTime >= 1)
+        {
+            start = currTime;
+            float avg_channels = (float)num_channels / (float)frames;
+
+            ofstream opstream("log.txt",ios::app);
+            opstream << "Average frame count: ";
+            opstream << frames;
+            opstream << " frames - ";
+            opstream << avg_channels;
+            opstream << " per frame.\n";
+            opstream.close();
+
+            frames = 0;
+            num_channels = 0;
+        }
     */
     if ( stereomode == stereoNone ) {
         DrawGLScene(stereoCenter);
@@ -556,12 +581,14 @@ void CleanUp (void)
     LOGFUNC;
 
     SDL_Quit();
+#ifndef __MINGW32__ // FIXME: Temporary workaround for GL-8
 #define GL_FUNC(ret,fn,params,call,rt) p##fn = NULL;
 #include "glstubs.h"
 #undef GL_FUNC
     // cheat here...static destructors are calling glDeleteTexture() after
     //  the context is destroyed and libGL unloaded by SDL_Quit().
     pglDeleteTextures = glDeleteTextures_doNothing;
+#endif // __MINGW32__
 
 }
 
@@ -569,7 +596,7 @@ void CleanUp (void)
 
 static bool IsFocused()
 {
-    return ((SDL_GetAppState() & SDL_APPINPUTFOCUS) != 0);
+    return ((SDL_GetWindowFlags(sdlwindow) & SDL_WINDOW_INPUT_FOCUS) != 0);
 }
 
 
@@ -638,9 +665,11 @@ char *calcBaseDir(const char *argv0)
     }
 
     envr = getenv("PATH");
-    if (!envr) return NULL;
+    if (!envr)
+        return NULL;
     envr = strdup(envr);
-    if (!envr) return NULL;
+    if (!envr)
+        return NULL;
     retval = findBinaryInPath(argv0, envr);
     free(envr);
     return(retval);
@@ -671,10 +700,8 @@ static inline void chdirToAppPath(const char *argv0)
 
 int main(int argc, char **argv)
 {
-#ifndef __MINGW32__
     _argc = argc;
     _argv = argv;
-#endif
 
     // !!! FIXME: we could use a Win32 API for this.  --ryan.
 #ifndef WIN32
@@ -707,11 +734,10 @@ int main(int argc, char **argv)
                     if (!waiting) {
                         // message pump
                         while ( SDL_PollEvent( &e ) ) {
-                            if ( e.type == SDL_QUIT ) {
+                            if (!sdlEventProc(e)) {
                                 gDone = true;
                                 break;
                             }
-                            sdlEventProc(e);
                         }
                     }
 
@@ -725,12 +751,7 @@ int main(int argc, char **argv)
                     }
 
                     // game is not in focus, give CPU time to other apps by waiting for messages instead of 'peeking'
-                    SDL_ActiveEvent evt;
-                    SDL_WaitEvent((SDL_Event*)&evt);
-                    if (evt.type == SDL_ACTIVEEVENT && evt.gain == 1)
-                        gameFocused = true;
-                    else if (evt.type == SDL_QUIT)
-                        gDone = true;
+                    SDL_WaitEvent(0);
                 }
             }
 
@@ -792,8 +813,8 @@ static bool load_image(const char *file_name, TGAImageRec &tex)
 
 
 struct my_error_mgr {
-    struct jpeg_error_mgr pub; /* "public" fields */
-    jmp_buf setjmp_buffer;     /* for return to caller */
+    struct jpeg_error_mgr pub; /* "public" fields */
+    jmp_buf setjmp_buffer; /* for return to caller */
 };
 typedef struct my_error_mgr * my_error_ptr;
 
@@ -809,8 +830,8 @@ static bool load_jpg(const char *file_name, TGAImageRec &tex)
 {
     struct jpeg_decompress_struct cinfo;
     struct my_error_mgr jerr;
-    JSAMPROW buffer[1];                /* Output row buffer */
-    int row_stride;            /* physical row width in output buffer */
+    JSAMPROW buffer[1]; /* Output row buffer */
+    int row_stride; /* physical row width in output buffer */
     FILE *infile = fopen(file_name, "rb");
 
     if (infile == NULL)