X-Git-Url: https://git.jsancho.org/?a=blobdiff_plain;f=Source%2FOpenGL_Windows.cpp;h=6d684ba1d2cbe4e413aebc9264cf924459d2d065;hb=cd043e3f9e26c2b3406b40a354c2840941e9db7f;hp=ac4a13ad6d3543a58de4707a0e3c0ba8164b549a;hpb=a9aed3805eda148c6962ab79473fb9788f9d2a72;p=lugaru.git diff --git a/Source/OpenGL_Windows.cpp b/Source/OpenGL_Windows.cpp index ac4a13a..6d684ba 100644 --- a/Source/OpenGL_Windows.cpp +++ b/Source/OpenGL_Windows.cpp @@ -3,82 +3,55 @@ Copyright (C) 2003, 2010 - Wolfire Games This file is part of Lugaru. -Lugaru 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. +Lugaru 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. -This program is distributed in the hope that it will be useful, +Lugaru 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. +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. +along with Lugaru. If not, see . */ #ifdef WIN32 -#define UINT8 WIN32API_UINT8 -#define UINT16 WIN32API_UINT16 -#define boolean WIN32API_boolean #include -#undef UINT8 -#undef UINT16 -#undef boolean #endif +#include "Game.h" +#include +#include +#include -#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 -} +using namespace Game; static bool load_image(const char * fname, TGAImageRec & tex); static bool load_png(const char * fname, TGAImageRec & tex); static bool load_jpg(const char * fname, TGAImageRec & tex); -static bool save_image(const char * fname); +bool save_image(const char * fname); static bool save_png(const char * fname); #include "openal_wrapper.h" -// ADDED GWC -#ifdef _MSC_VER -#pragma comment(lib, "opengl32.lib") -#pragma comment(lib, "glu32.lib") -#pragma comment(lib, "glaux.lib") -#endif - extern float multiplier; extern float sps; extern float realmultiplier; extern int slomo; extern bool cellophane; -// MODIFIED GWC -//extern int terraindetail; -//extern int texdetail; -extern float terraindetail; extern float texdetail; extern bool osx; -extern int numplayers; extern bool freeze; -extern Person player[maxplayers]; extern bool stillloading; extern int mainmenu; -/*extern*/ bool gameFocused; +/*extern*/ +bool gameFocused; extern float slomospeed; extern float slomofreq; @@ -90,6 +63,7 @@ extern float slomofreq; #include #include #include +#include #include "gamegl.h" #include "MacCompatibility.h" #include "Settings.h" @@ -99,55 +73,25 @@ extern float slomofreq; #include "win-res/resource.h" #endif -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 -}; +extern SDL_Window *sdlwindow; +using namespace std; +set> resolutions; -unsigned int resolutionDepths[8][2] = {0}; - -int closestResolution(int width, int height); -int resolutionID(int width, int height); - -void ReportError (char * strError); - -void DrawGL(Game & game); - -void CreateGLWindow (void); -Boolean SetUp (Game & game); -void DoUpdate (Game & game); +Boolean SetUp (); +void DoUpdate (); -void DoEvent (void); void CleanUp (void); - // statics/globals (internal only) ------------------------------------------ -#ifndef WIN32 -typedef struct tagPOINT { - int x; - int y; -} POINT, *PPOINT; -#endif - - #ifdef _MSC_VER #pragma warning(push) #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; \ @@ -155,6 +99,7 @@ typedef struct tagPOINT { } #include "glstubs.h" #undef GL_FUNC +#endif // __MINGW32__ #ifdef _MSC_VER #pragma warning(pop) @@ -163,8 +108,7 @@ typedef struct tagPOINT { static bool lookup_glsym(const char *funcname, void **func) { *func = SDL_GL_GetProcAddress(funcname); - if (*func == NULL) - { + if (*func == NULL) { fprintf(stderr, "Failed to find OpenGL symbol \"%s\"\n", funcname); return false; } @@ -174,74 +118,40 @@ static bool lookup_glsym(const char *funcname, void **func) static bool lookup_all_glsyms(void) { bool retval = true; - #define GL_FUNC(ret,fn,params,call,rt) \ +#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 +#include "glstubs.h" +#undef GL_FUNC +#endif // __MINGW32__ return retval; } +#ifndef __MINGW32__ // FIXME: Temporary workaround for GL-8 static void GLAPIENTRY glDeleteTextures_doNothing(GLsizei n, const GLuint *textures) { // no-op. } +#endif // __MINGW32__ - - -void sdlGetCursorPos(POINT *pt) -{ - SDL_GetMouseState(&(pt->x), &(pt->y)); -} -#define GetCursorPos(x) sdlGetCursorPos(x) -#define SetCursorPos(x, y) SDL_WarpMouse(x, y) -#define ScreenToClient(x, pt) -#define ClientToScreen(x, pt) #ifdef MessageBox #undef MessageBox #endif #define MessageBox(hwnd,text,title,flags) STUBBED("msgbox") - -Point delta; - -static bool g_button, fullscreen = true; - - // Menu defs -enum -{ - kFileQuit = 1 -}; - -enum -{ - kForegroundSleep = 10, - kBackgroundSleep = 10000 -}; - int kContextWidth; int kContextHeight; -const RGBColor rgbBlack = { 0x0000, 0x0000, 0x0000 }; - -GLuint gFontList; -char gcstrMode [256] = ""; +Boolean gDone = false; -UInt32 gSleepTime = kForegroundSleep; -Boolean gDone = false, gfFrontProcess = true; - -Game * pgame = 0; - -#ifndef __MINGW32__ static int _argc = 0; static char **_argv = NULL; -#endif bool cmdline(const char *cmd) { - for (int i = 1; i < _argc; i++) - { + for (int i = 1; i < _argc; i++) { char *arg = _argv[i]; while (*arg == '-') arg++; @@ -252,408 +162,416 @@ bool cmdline(const char *cmd) return false; } +//----------------------------------------------------------------------------------------------------------------------- -// -------------------------------------------------------------------------- +// OpenGL Drawing -void ReportError (char * strError) +void initGL() { -#ifdef _MSC_VER // !!! FIXME. --ryan. - throw std::exception( strError); -#endif - - /* char errMsgCStr [256]; - Str255 strErr; - - sprintf (errMsgCStr, "%s", strError); - - // out as debug string - CToPStr (strErr, errMsgCStr); - DebugStr (strErr); - */ + glClear( GL_COLOR_BUFFER_BIT ); + swap_gl_buffers(); + + // clear all states + glDisable( GL_ALPHA_TEST); + glDisable( GL_BLEND); + glDisable( GL_DEPTH_TEST); + //glDisable( GL_DITHER); + glDisable( GL_FOG); + glDisable( GL_LIGHTING); + glDisable( GL_LOGIC_OP); + glDisable( GL_TEXTURE_1D); + glDisable( GL_TEXTURE_2D); + glPixelTransferi( GL_MAP_COLOR, GL_FALSE); + glPixelTransferi( GL_RED_SCALE, 1); + glPixelTransferi( GL_RED_BIAS, 0); + glPixelTransferi( GL_GREEN_SCALE, 1); + glPixelTransferi( GL_GREEN_BIAS, 0); + glPixelTransferi( GL_BLUE_SCALE, 1); + glPixelTransferi( GL_BLUE_BIAS, 0); + glPixelTransferi( GL_ALPHA_SCALE, 1); + glPixelTransferi( GL_ALPHA_BIAS, 0); + + // set initial rendering states + glShadeModel( GL_SMOOTH); + glClearDepth( 1.0f); + glDepthFunc( GL_LEQUAL); + glDepthMask( GL_TRUE); + //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_DITHER); + glEnable( GL_COLOR_MATERIAL); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glAlphaFunc( GL_GREATER, 0.5f); + + if ( CanInitStereo(stereomode) ) { + InitStereo(stereomode); + } else { + fprintf(stderr, "Failed to initialize stereo, disabling.\n"); + stereomode = stereoNone; + } } -//----------------------------------------------------------------------------------------------------------------------- - -// OpenGL Drawing - -void DrawGL (Game & game) +void toggleFullscreen() { - if ( stereomode == stereoNone ) { - game.DrawGLScene(stereoCenter); - } else { - game.DrawGLScene(stereoLeft); - game.DrawGLScene(stereoRight); - } + fullscreen = !fullscreen; + 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, Game &game) +static SDL_bool sdlEventProc(const SDL_Event &e) { - int val; - SDLMod mod; + switch (e.type) { + case SDL_QUIT: + return SDL_FALSE; + + case SDL_WINDOWEVENT: + if (e.window.event == SDL_WINDOWEVENT_CLOSE) { + return SDL_FALSE; + } + break; - switch(e.type) - { case SDL_MOUSEMOTION: - game.deltah += e.motion.xrel; - game.deltav += e.motion.yrel; - return; + deltah += e.motion.xrel; + deltav += e.motion.yrel; + 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) ) { - SDL_WM_ToggleFullScreen(SDL_GetVideoSurface()); + 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(); } - return; + break; } + return SDL_TRUE; } + // -------------------------------------------------------------------------- static Point gMidPoint; -Boolean SetUp (Game & game) +Boolean SetUp () { - char string[10]; + LOGFUNC; - LOGFUNC; + osx = 0; + cellophane = 0; + texdetail = 4; + slomospeed = 0.25; + slomofreq = 8012; - randSeed = UpTime().lo; - - osx = 0; - cellophane=0; - texdetail=4; - terraindetail=2; - slomospeed=0.25; - slomofreq=8012; - numplayers=1; - - DefaultSettings(game); + DefaultSettings(); if (!SDL_WasInit(SDL_INIT_VIDEO)) - if (SDL_Init(SDL_INIT_VIDEO) == -1) - { + if (SDL_Init(SDL_INIT_VIDEO) == -1) { fprintf(stderr, "SDL_Init() failed: %s\n", SDL_GetError()); return false; } - if(!LoadSettings(game)) { - fprintf(stderr, "Failed to load config, creating default\n"); - SaveSettings(game); - } - if(kBitsPerPixel!=32&&kBitsPerPixel!=16){ - kBitsPerPixel=16; - } - - if (SDL_GL_LoadLibrary(NULL) == -1) - { - fprintf(stderr, "SDL_GL_LoadLibrary() failed: %s\n", SDL_GetError()); - SDL_Quit(); - 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; - - // 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. - } - - static SDL_Rect *resolutions_block = NULL; - resolutions_block = (SDL_Rect*) realloc(resolutions_block, sizeof (SDL_Rect) * count); - resolutions = (SDL_Rect**) realloc(resolutions, sizeof (SDL_Rect *) * (count + 1)); - if ((resolutions_block == NULL) || (resolutions == NULL)) - { - SDL_Quit(); - fprintf(stderr, "Out of memory!\n"); - return false; - } - - resolutions[count--] = NULL; - for (int i = 0; count >= 0; i++, count--) - { - memcpy(&resolutions_block[count], res[i], sizeof (SDL_Rect)); - resolutions[count] = &resolutions_block[count]; - } - - if (cmdline("showresolutions")) - { - printf("Resolutions we think are okay:\n"); - for (int i = 0; resolutions[i]; i++) - printf(" %d x %d\n", (int) resolutions[i]->w, (int) resolutions[i]->h); - } - - Uint32 sdlflags = SDL_OPENGL; - if (!cmdline("windowed")) - sdlflags |= SDL_FULLSCREEN; - - SDL_WM_SetCaption("Lugaru", "Lugaru"); + if (!LoadSettings()) { + fprintf(stderr, "Failed to load config, creating default\n"); + SaveSettings(); + } + if (kBitsPerPixel != 32 && kBitsPerPixel != 16) { + kBitsPerPixel = 16; + } - SDL_ShowCursor(0); + if (SDL_GL_LoadLibrary(NULL) == -1) { + fprintf(stderr, "SDL_GL_LoadLibrary() failed: %s\n", SDL_GetError()); + SDL_Quit(); + return false; + } + + for (int displayIdx = 0; displayIdx < SDL_GetNumVideoDisplays(); ++displayIdx) { + for (int i = 0; i < SDL_GetNumDisplayModes(displayIdx); ++i) { + SDL_DisplayMode mode; + if (SDL_GetDisplayMode(displayIdx, i, &mode) == -1) + continue; + if ((mode.w < 640) || (mode.h < 480)) + continue; // sane lower limit. + pair resolution(mode.w, mode.h); + resolutions.insert(resolution); + } + } + + if (resolutions.empty()) { + 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; + } + + if (cmdline("showresolutions")) { + printf("Available resolutions:\n"); + for (auto resolution = resolutions.begin(); resolution != resolutions.end(); resolution++) { + printf(" %d x %d\n", (int) resolution->first, (int) resolution->second); + } + } SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 1); - - if (SDL_SetVideoMode(kContextWidth, kContextHeight, 0, sdlflags) == NULL) - { - fprintf(stderr, "SDL_SetVideoMode() failed: %s\n", SDL_GetError()); + + Uint32 sdlflags = SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN; + if ((fullscreen || cmdline("fullscreen")) && !cmdline("windowed")) { + fullscreen = 1; + sdlflags |= SDL_WINDOW_FULLSCREEN; + } + if (!cmdline("nomousegrab")) + sdlflags |= SDL_WINDOW_INPUT_GRABBED; + + sdlwindow = SDL_CreateWindow("Lugaru", SDL_WINDOWPOS_CENTERED_DISPLAY(0), SDL_WINDOWPOS_CENTERED_DISPLAY(0), + kContextWidth, kContextHeight, sdlflags); + + 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(0), SDL_WINDOWPOS_CENTERED_DISPLAY(0), + 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(0), SDL_WINDOWPOS_CENTERED_DISPLAY(0), + 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 (!lookup_all_glsyms()) + 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); if (!cmdline("nomousegrab")) - SDL_WM_GrabInput(SDL_GRAB_ON); - - - glClear( GL_COLOR_BUFFER_BIT ); - swap_gl_buffers(); - - // clear all states - glDisable( GL_ALPHA_TEST); - glDisable( GL_BLEND); - glDisable( GL_DEPTH_TEST); - // glDisable( GL_DITHER); - glDisable( GL_FOG); - glDisable( GL_LIGHTING); - glDisable( GL_LOGIC_OP); - glDisable( GL_TEXTURE_1D); - glDisable( GL_TEXTURE_2D); - glPixelTransferi( GL_MAP_COLOR, GL_FALSE); - glPixelTransferi( GL_RED_SCALE, 1); - glPixelTransferi( GL_RED_BIAS, 0); - glPixelTransferi( GL_GREEN_SCALE, 1); - glPixelTransferi( GL_GREEN_BIAS, 0); - glPixelTransferi( GL_BLUE_SCALE, 1); - glPixelTransferi( GL_BLUE_BIAS, 0); - glPixelTransferi( GL_ALPHA_SCALE, 1); - glPixelTransferi( GL_ALPHA_BIAS, 0); - - // set initial rendering states - glShadeModel( GL_SMOOTH); - glClearDepth( 1.0f); - glDepthFunc( GL_LEQUAL); - glDepthMask( GL_TRUE); - // 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_DITHER); - glEnable( GL_COLOR_MATERIAL); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glAlphaFunc( GL_GREATER, 0.5f); - - GLint width = kContextWidth; - GLint height = kContextHeight; - gMidPoint.h = width / 2; - gMidPoint.v = height / 2; - screenwidth=width; - screenheight=height; - - game.newdetail=detail; - game.newscreenwidth=screenwidth; - game.newscreenheight=screenheight; - - if ( CanInitStereo(stereomode) ) { - InitStereo(stereomode); - } else { - fprintf(stderr, "Failed to initialize stereo, disabling.\n"); - stereomode = stereoNone; - } - - game.InitGame(); - - return true; + SDL_SetRelativeMouseMode(SDL_TRUE); + + initGL(); + + GLint width = kContextWidth; + GLint height = kContextHeight; + gMidPoint.h = width / 2; + gMidPoint.v = height / 2; + screenwidth = width; + screenheight = height; + + newdetail = detail; + newscreenwidth = screenwidth; + newscreenheight = screenheight; + + /* If saved resolution is not in the list, add it to the list (so that it’s selectable in the options) */ + pair startresolution(width,height); + if (resolutions.find(startresolution) == resolutions.end()) { + resolutions.insert(startresolution); + } + + InitGame(); + + return true; } -static void DoMouse(Game & game) +static void DoMouse() { - if(mainmenu||(abs(game.deltah)<10*realmultiplier*1000&&abs(game.deltav)<10*realmultiplier*1000)) - { - game.deltah *= usermousesensitivity; - game.deltav *= usermousesensitivity; - game.mousecoordh += game.deltah; - game.mousecoordv += game.deltav; - if (game.mousecoordh < 0) - game.mousecoordh = 0; - else if (game.mousecoordh >= kContextWidth) - game.mousecoordh = kContextWidth - 1; - if (game.mousecoordv < 0) - game.mousecoordv = 0; - else if (game.mousecoordv >= kContextHeight) - game.mousecoordv = kContextHeight - 1; - } + if (mainmenu || ( (abs(deltah) < 10 * realmultiplier * 1000) && (abs(deltav) < 10 * realmultiplier * 1000) )) { + deltah *= usermousesensitivity; + deltav *= usermousesensitivity; + mousecoordh += deltah; + mousecoordv += deltav; + if (mousecoordh < 0) + mousecoordh = 0; + else if (mousecoordh >= kContextWidth) + mousecoordh = kContextWidth - 1; + if (mousecoordv < 0) + mousecoordv = 0; + else if (mousecoordv >= kContextHeight) + mousecoordv = kContextHeight - 1; + } } void DoFrameRate (int update) -{ - static long frames = 0; - - static AbsoluteTime time = {0,0}; - static AbsoluteTime frametime = {0,0}; - AbsoluteTime currTime = UpTime (); - double deltaTime = (float) AbsoluteDeltaToDuration (currTime, frametime); - - if (0 > deltaTime) // if negative microseconds - deltaTime /= -1000000.0; - 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 - - deltaTime = (float) AbsoluteDeltaToDuration (currTime, time); - - if (0 > deltaTime) // if negative microseconds - deltaTime /= -1000000.0; - else // else milliseconds - deltaTime /= 1000.0; - frames++; - if (0.001 <= deltaTime) // has update interval passed - { - if(update){ - time = currTime; // reset for next time interval - frames = 0; - } - } +{ + static long frames = 0; + + static AbsoluteTime time = {0, 0}; + static AbsoluteTime frametime = {0, 0}; + AbsoluteTime currTime = UpTime (); + double deltaTime = (float) AbsoluteDeltaToDuration (currTime, frametime); + + if (0 > deltaTime) // if negative microseconds + deltaTime /= -1000000.0; + 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 + + deltaTime = (float) AbsoluteDeltaToDuration (currTime, time); + + if (0 > deltaTime) // if negative microseconds + deltaTime /= -1000000.0; + else // else milliseconds + deltaTime /= 1000.0; + frames++; + if (0.001 <= deltaTime) { // has update interval passed + if (update) { + time = currTime; // reset for next time interval + frames = 0; + } + } } -void DoUpdate (Game & game) +void DoUpdate () { - static float sps=200; - static int count; - static float oldmult; - - DoFrameRate(1); - if(multiplier>.6)multiplier=.6; - - game.fps=1/multiplier; - - count = multiplier*sps; - if(count<2)count=2; - //if(count>10)count=10; - - realmultiplier=multiplier; - multiplier*=gamespeed; - if(difficulty==1)multiplier*=.9; - if(difficulty==0)multiplier*=.8; - - if(game.loading==4)multiplier*=.00001; - //multiplier*.9; - if(slomo&&!mainmenu)multiplier*=slomospeed; - //if(freeze)multiplier*=0.00001; - oldmult=multiplier; - multiplier/=(float)count; - - DoMouse(game); - - game.TickOnce(); - - for(int i=0;i 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; - } -*/ - DrawGL (game); -} + static float sps = 200; + static int count; + static float oldmult; -// -------------------------------------------------------------------------- + DoFrameRate(1); + if (multiplier > .6) + multiplier = .6; + fps = 1 / multiplier; -void CleanUp (void) -{ - LOGFUNC; + count = multiplier * sps; + 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; + oldmult = multiplier; + multiplier /= (float)count; + + DoMouse(); + + TickOnce(); -// game.Dispose(); + for (int i = 0; i < count; i++) { + Tick(); + } + multiplier = oldmult; + + 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; + } + */ + if ( stereomode == stereoNone ) { + DrawGLScene(stereoCenter); + } else { + DrawGLScene(stereoLeft); + DrawGLScene(stereoRight); + } +} + +// -------------------------------------------------------------------------- + + +void CleanUp (void) +{ + LOGFUNC; SDL_Quit(); - #define GL_FUNC(ret,fn,params,call,rt) p##fn = NULL; - #include "glstubs.h" - #undef GL_FUNC +#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__ } @@ -661,33 +579,10 @@ void CleanUp (void) static bool IsFocused() { - return ((SDL_GetAppState() & SDL_APPINPUTFOCUS) != 0); + return ((SDL_GetWindowFlags(sdlwindow) & SDL_WINDOW_INPUT_FOCUS) != 0); } -static void launch_web_browser(const char *url) -{ -#ifdef WIN32 - ShellExecute(NULL, "open", url, NULL, NULL, SW_SHOWNORMAL); - -#elif (defined(__APPLE__) && defined(__MACH__)) - const char *fmt = "open '%s'"; - const size_t len = strlen(fmt) + strlen(url) + 16; - char *buf = new char[len]; - snprintf(buf, len, fmt, url); - system(buf); - delete[] buf; - -#elif PLATFORM_LINUX - const char *fmt = "PATH=$PATH:. xdg-open '%s'"; - const size_t len = strlen(fmt) + strlen(url) + 16; - char *buf = new char[len]; - snprintf(buf, len, fmt, url); - system(buf); - delete[] buf; -#endif -} - #ifndef WIN32 // (code lifted from physfs: http://icculus.org/physfs/ ... zlib license.) @@ -698,19 +593,16 @@ static char *findBinaryInPath(const char *bin, char *envr) char *start = envr; char *ptr; - do - { + do { size_t size; ptr = strchr(start, ':'); /* find next $PATH separator. */ if (ptr) *ptr = '\0'; size = strlen(start) + strlen(bin) + 2; - if (size > alloc_size) - { + if (size > alloc_size) { char *x = (char *) realloc(exe, size); - if (x == NULL) - { + if (x == NULL) { if (exe != NULL) free(exe); return(NULL); @@ -726,8 +618,7 @@ static char *findBinaryInPath(const char *bin, char *envr) strcat(exe, "/"); strcat(exe, bin); - if (access(exe, X_OK) == 0) /* Exists as executable? We're done. */ - { + if (access(exe, X_OK) == 0) { /* Exists as executable? We're done. */ strcpy(exe, start); /* i'm lazy. piss off. */ return(exe); } /* if */ @@ -748,9 +639,7 @@ char *calcBaseDir(const char *argv0) char *retval; char *envr; - const char *ptr = strrchr((char *)argv0, '/'); - if (strchr(argv0, '/')) - { + if (strchr(argv0, '/')) { retval = strdup(argv0); if (retval) *((char *) strrchr(retval, '/')) = '\0'; @@ -758,9 +647,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); @@ -769,21 +660,19 @@ char *calcBaseDir(const char *argv0) static inline void chdirToAppPath(const char *argv0) { char *dir = calcBaseDir(argv0); - if (dir) - { - #if (defined(__APPLE__) && defined(__MACH__)) + if (dir) { +#if (defined(__APPLE__) && defined(__MACH__)) // Chop off /Contents/MacOS if it's at the end of the string, so we // land in the base of the app bundle. const size_t len = strlen(dir); const char *bundledirs = "/Contents/MacOS"; const size_t bundledirslen = strlen(bundledirs); - if (len > bundledirslen) - { + if (len > bundledirslen) { char *ptr = (dir + len) - bundledirslen; if (strcasecmp(ptr, bundledirs) == 0) *ptr = '\0'; } - #endif +#endif chdir(dir); free(dir); } @@ -793,192 +682,110 @@ 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 chdirToAppPath(argv[0]); #endif - LOGFUNC; + LOGFUNC; - //memset( &g_theKeys, 0, sizeof( KeyMap)); + try { + { + newGame(); + + //ofstream os("error.txt"); + //os.close(); + //ofstream os("log.txt"); + //os.close(); - //initSDLKeyTable(); + if (!SetUp ()) + return 42; - try - { - bool regnow = false; - { - Game game; - pgame = &game; + while (!gDone && !tryquit) { + if (IsFocused()) { + gameFocused = true; + + // check windows messages + + deltah = 0; + deltav = 0; + SDL_Event e; + if (!waiting) { + // message pump + while ( SDL_PollEvent( &e ) ) { + if (!sdlEventProc(e)) { + gDone = true; + break; + } + } + } + + // game + DoUpdate(); + } else { + if (gameFocused) { + // allow game chance to pause + gameFocused = false; + DoUpdate(); + } + + // game is not in focus, give CPU time to other apps by waiting for messages instead of 'peeking' + SDL_WaitEvent(0); + } + } - //ofstream os("error.txt"); - //os.close(); - //ofstream os("log.txt"); - //os.close(); + deleteGame(); + } - if (!SetUp (game)) - return 42; + CleanUp (); + + return 0; + } catch (const std::exception& error) { + CleanUp(); + + std::string e = "Caught exception: "; + e += error.what(); + + LOG(e); + + MessageBox(g_windowHandle, error.what(), "ERROR", MB_OK | MB_ICONEXCLAMATION); + } - while (!gDone&&!game.quit&&(!game.tryquit)) - { - if (IsFocused()) - { - gameFocused = true; - - // check windows messages - - game.deltah = 0; - game.deltav = 0; - SDL_Event e; - if(!game.isWaiting()) { - // message pump - while( SDL_PollEvent( &e ) ) - { - if( e.type == SDL_QUIT ) - { - gDone=true; - break; - } - sdlEventProc(e, game); - } - } - - // game - DoUpdate(game); - } - else - { - if (gameFocused) - { - // allow game chance to pause - gameFocused = false; - DoUpdate(game); - } - - // 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; - } - } - - regnow = game.registernow; - } - pgame = 0; - - CleanUp (); - - return 0; - } - catch (const std::exception& error) - { - CleanUp(); - - std::string e = "Caught exception: "; - e += error.what(); - - LOG(e); - - MessageBox(g_windowHandle, error.what(), "ERROR", MB_OK | MB_ICONEXCLAMATION); - } - - CleanUp(); - - return -1; + CleanUp(); + + return -1; } - // -------------------------------------------------------------------------- - - extern int channels[100]; - extern OPENAL_SAMPLE * samp[100]; - extern OPENAL_STREAM * strm[20]; - - extern "C" void PlaySoundEx(int chan, OPENAL_SAMPLE *sptr, OPENAL_DSPUNIT *dsp, signed char startpaused) - { - const OPENAL_SAMPLE * currSample = OPENAL_GetCurrentSample(channels[chan]); - if (currSample && currSample == samp[chan]) - { - if (OPENAL_GetPaused(channels[chan])) - { - OPENAL_StopSound(channels[chan]); - channels[chan] = OPENAL_FREE; - } - else if (OPENAL_IsPlaying(channels[chan])) - { - int loop_mode = OPENAL_GetLoopMode(channels[chan]); - if (loop_mode & OPENAL_LOOP_OFF) - { - channels[chan] = OPENAL_FREE; - } - } - } - else - { - channels[chan] = OPENAL_FREE; - } - - channels[chan] = OPENAL_PlaySoundEx(channels[chan], sptr, dsp, startpaused); - if (channels[chan] < 0) - { - channels[chan] = OPENAL_PlaySoundEx(OPENAL_FREE, sptr, dsp, startpaused); - } - } - - extern "C" void PlayStreamEx(int chan, OPENAL_STREAM *sptr, OPENAL_DSPUNIT *dsp, signed char startpaused) - { - const OPENAL_SAMPLE * currSample = OPENAL_GetCurrentSample(channels[chan]); - if (currSample && currSample == OPENAL_Stream_GetSample(sptr)) - { - OPENAL_StopSound(channels[chan]); - OPENAL_Stream_Stop(sptr); - } - else - { - OPENAL_Stream_Stop(sptr); - channels[chan] = OPENAL_FREE; - } - - channels[chan] = OPENAL_Stream_PlayEx(channels[chan], sptr, dsp, startpaused); - if (channels[chan] < 0) - { - channels[chan] = OPENAL_Stream_PlayEx(OPENAL_FREE, sptr, dsp, startpaused); - } - } - - - bool LoadImage(const char * fname, TGAImageRec & tex) - { - if ( tex.data == NULL ) - return false; - else - return load_image(fname, tex); - } - - void ScreenShot(const char * fname) - { - save_image(fname); - } +// -------------------------------------------------------------------------- + + +bool LoadImage(const char * fname, TGAImageRec & tex) +{ + if ( tex.data == NULL ) + return false; + else + return load_image(fname, tex); +} + +void ScreenShot(const char * fname) +{ + +} static bool load_image(const char *file_name, TGAImageRec &tex) { const char *ptr = strrchr((char *)file_name, '.'); - if (ptr) - { - if (strcasecmp(ptr+1, "png") == 0) + if (ptr) { + if (strcasecmp(ptr + 1, "png") == 0) return load_png(file_name, tex); - else if (strcasecmp(ptr+1, "jpg") == 0) + else if (strcasecmp(ptr + 1, "jpg") == 0) return load_jpg(file_name, tex); } @@ -988,16 +795,16 @@ 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; static void my_error_exit(j_common_ptr cinfo) { - struct my_error_mgr *err = (struct my_error_mgr *)cinfo->err; - longjmp(err->setjmp_buffer, 1); + struct my_error_mgr *err = (struct my_error_mgr *)cinfo->err; + longjmp(err->setjmp_buffer, 1); } /* stolen from public domain example.c code in libjpg distribution. */ @@ -1005,8 +812,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) @@ -1036,7 +843,7 @@ static bool load_jpg(const char *file_name, TGAImageRec &tex) while (cinfo.output_scanline < cinfo.output_height) { buffer[0] = (JSAMPROW)(char *)tex.data + - ((cinfo.output_height-1) - cinfo.output_scanline) * row_stride; + ((cinfo.output_height - 1) - cinfo.output_scanline) * row_stride; (void) jpeg_read_scanlines(&cinfo, buffer, 1); } @@ -1056,13 +863,14 @@ static bool load_png(const char *file_name, TGAImageRec &tex) png_infop info_ptr = NULL; png_uint_32 width, height; int bit_depth, color_type, interlace_type; - png_byte **rows = NULL; bool retval = false; png_byte **row_pointers = NULL; FILE *fp = fopen(file_name, "rb"); - if (fp == NULL) + if (fp == NULL) { + cerr << file_name << " not found" << endl; return(NULL); + } png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (png_ptr == NULL) @@ -1096,14 +904,11 @@ static bool load_png(const char *file_name, TGAImageRec &tex) if (!row_pointers) goto png_done; - if (!hasalpha) - { + if (!hasalpha) { png_byte *dst = tex.data; - for (int i = height-1; i >= 0; i--) - { + for (int i = height - 1; i >= 0; i--) { png_byte *src = row_pointers[i]; - for (int j = 0; j < width; j++) - { + for (unsigned j = 0; j < width; j++) { dst[0] = src[0]; dst[1] = src[1]; dst[2] = src[2]; @@ -1114,11 +919,10 @@ static bool load_png(const char *file_name, TGAImageRec &tex) } } - else - { + else { png_byte *dst = tex.data; int pitch = width * 4; - for (int i = height-1; i >= 0; i--, dst += pitch) + for (int i = height - 1; i >= 0; i--, dst += pitch) memcpy(dst, row_pointers[i], pitch); } @@ -1128,6 +932,9 @@ static bool load_png(const char *file_name, TGAImageRec &tex) retval = true; png_done: + if (!retval) { + cerr << "There was a problem loading " << file_name << endl; + } png_destroy_read_struct(&png_ptr, &info_ptr, NULL); if (fp) fclose(fp); @@ -1135,12 +942,11 @@ png_done: } -static bool save_image(const char *file_name) +bool save_image(const char *file_name) { const char *ptr = strrchr((char *)file_name, '.'); - if (ptr) - { - if (strcasecmp(ptr+1, "png") == 0) + if (ptr) { + if (strcasecmp(ptr + 1, "png") == 0) return save_png(file_name); } @@ -1172,7 +978,7 @@ static bool save_png(const char *file_name) goto save_png_done; for (int i = 0; i < kContextHeight; i++) - row_pointers[i] = screenshot + ((kContextWidth * ((kContextHeight-1) - i)) * 3); + row_pointers[i] = screenshot + ((kContextWidth * ((kContextHeight - 1) - i)) * 3); png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (png_ptr == NULL) @@ -1199,9 +1005,9 @@ static bool save_png(const char *file_name) if (setjmp(png_jmpbuf(png_ptr))) goto save_png_done; - png_write_image(png_ptr, row_pointers); + png_write_image(png_ptr, row_pointers); - if (setjmp(png_jmpbuf(png_ptr))) + if (setjmp(png_jmpbuf(png_ptr))) goto save_png_done; png_write_end(png_ptr, NULL);