X-Git-Url: https://git.jsancho.org/?a=blobdiff_plain;f=Source%2FOpenGL_Windows.cpp;h=17766dbb66ead777eb92cc6700c692949ce4f1f6;hb=f415499bb932770841f668fb6dc1ea6c76cbf494;hp=e5e45492648294d632e9636f8b323ade4223a866;hpb=0ca5e88eabdd3aa3eb010460a73d10d8ebde61d8;p=lugaru.git diff --git a/Source/OpenGL_Windows.cpp b/Source/OpenGL_Windows.cpp index e5e4549..17766db 100644 --- a/Source/OpenGL_Windows.cpp +++ b/Source/OpenGL_Windows.cpp @@ -142,23 +142,22 @@ typedef struct tagPOINT { #include "glstubs.h" #undef GL_FUNC -static bool lookup_glsym(const char *funcname, void **func, const char *libname) +static bool lookup_glsym(const char *funcname, void **func) { *func = SDL_GL_GetProcAddress(funcname); if (*func == NULL) { - fprintf(stderr, "Failed to find OpenGL symbol \"%s\" in \"%s\"\n", - funcname, libname); + fprintf(stderr, "Failed to find OpenGL symbol \"%s\"\n", funcname); return false; } return true; } -static bool lookup_all_glsyms(const char *libname) +static bool lookup_all_glsyms(void) { bool retval = true; #define GL_FUNC(ret,fn,params,call,rt) \ - if (!lookup_glsym(#fn, (void **) &p##fn, libname)) retval = false; + if (!lookup_glsym(#fn, (void **) &p##fn)) retval = false; #include "glstubs.h" #undef GL_FUNC return retval; @@ -223,6 +222,25 @@ Boolean gDone = false, gfFrontProcess = true; Game * pgame = 0; + +static int _argc = 0; +static char **_argv = NULL; + +bool cmdline(const char *cmd) +{ + for (int i = 1; i < _argc; i++) + { + char *arg = _argv[i]; + while (*arg == '-') + arg++; + if (stricmp(arg, cmd) == 0) + return true; + } + + return false; +} + + // -------------------------------------------------------------------------- void ReportError (char * strError) @@ -438,6 +456,8 @@ static inline int clamp_sdl_mouse_button(Uint8 button) static void sdlEventProc(const SDL_Event &e, Game &game) { int val; + SDLMod mod; + switch(e.type) { case SDL_MOUSEMOTION: @@ -510,13 +530,14 @@ static void sdlEventProc(const SDL_Event &e, Game &game) SetKey(KeyTable[e.key.keysym.sym]); } - if (e.key.keysym.mod & KMOD_CTRL) + mod = SDL_GetModState(); + if (mod & KMOD_CTRL) SetKey(MAC_CONTROL_KEY); - if (e.key.keysym.mod & KMOD_ALT) + if (mod & KMOD_ALT) SetKey(MAC_OPTION_KEY); - if (e.key.keysym.mod & KMOD_SHIFT) + if (mod & KMOD_SHIFT) SetKey(MAC_SHIFT_KEY); - if (e.key.keysym.mod & KMOD_CAPS) + if (mod & KMOD_CAPS) SetKey(MAC_CAPS_LOCK_KEY); return; @@ -528,13 +549,14 @@ static void sdlEventProc(const SDL_Event &e, Game &game) ClearKey(KeyTable[e.key.keysym.sym]); } - if (e.key.keysym.mod & KMOD_CTRL) + mod = SDL_GetModState(); + if ((mod & KMOD_CTRL) == 0) ClearKey(MAC_CONTROL_KEY); - if (e.key.keysym.mod & KMOD_ALT) + if ((mod & KMOD_ALT) == 0) ClearKey(MAC_OPTION_KEY); - if (e.key.keysym.mod & KMOD_SHIFT) + if ((mod & KMOD_SHIFT) == 0) ClearKey(MAC_SHIFT_KEY); - if (e.key.keysym.mod & KMOD_CAPS) + if ((mod & KMOD_CAPS) == 0) ClearKey(MAC_CAPS_LOCK_KEY); return; } @@ -850,28 +872,36 @@ Boolean SetUp (Game & game) return false; } - const char *libname = "libGL.so.1"; // !!! FIXME: Linux specific! - if (SDL_GL_LoadLibrary(libname) == -1) + if (SDL_GL_LoadLibrary(NULL) == -1) { - fprintf(stderr, "SDL_GL_LoadLibrary(\"%s\") failed: %s\n", - libname, SDL_GetError()); + fprintf(stderr, "SDL_GL_LoadLibrary() failed: %s\n", SDL_GetError()); + SDL_Quit(); return false; } - - if (!lookup_all_glsyms(libname)) - return false; } - Uint32 sdlflags = SDL_OPENGL; // !!! FIXME: SDL_FULLSCREEN? + Uint32 sdlflags = SDL_OPENGL; + if (!cmdline("windowed")) + sdlflags |= SDL_FULLSCREEN; + SDL_WM_SetCaption("Lugaru", "lugaru"); + SDL_ShowCursor(0); + if (SDL_SetVideoMode(kContextWidth, kContextHeight, 0, sdlflags) == NULL) { fprintf(stderr, "SDL_SetVideoMode() failed: %s\n", SDL_GetError()); return false; } + if (!lookup_all_glsyms()) + { + SDL_Quit(); + return false; + } + if (!cmdline("nomousegrab")) + SDL_WM_GrabInput(SDL_GRAB_ON); #elif (defined WIN32) //------------------------------------------------------------------ @@ -1319,8 +1349,214 @@ static bool IsFocused() return true; } -int main (void) + +#if PLATFORM_LINUX +#include +#include +#include +static bool try_launch_browser(const char *browser, const char *url) +{ + // make sure string isn't empty... + while ( (*browser) && (isspace(*browser)) ) browser++; + if (*browser == '\0') return false; + + bool seenurl = false; + char buf[4096]; // !!! FIXME: we aren't checking for overflow here! + char *dst = buf; + while (*browser) + { + char ch = *(browser++); + if (ch == '%') + { + ch = *(browser++); + if (ch == '%') + *(dst++) = '%'; + else if (ch == 's') // "%s" == insert URL here. + { + *(dst++) = '\''; + strcpy(dst, url); + dst += strlen(url); + *(dst++) = '\''; + seenurl = true; + } + // (not %% or %s? Drop the char.) + } + else + { + *(dst++) = ch; + } + } + + *dst = '\0'; + if (!seenurl) + { + strcat(dst, " "); + strcat(dst, url); + } + + #define MAX_BROWSER_ARGS 512 + char *args[MAX_BROWSER_ARGS]; + char *path = NULL; + memset(args, '\0', sizeof (args)); + path = args[0] = strtok(buf, " "); + if (path == NULL) + return false; + + size_t i = 0; + for (i = 1; i < MAX_BROWSER_ARGS; i++) + { + args[i] = strtok(NULL, " "); + if (args[i] == NULL) + break; + } + + if (i == MAX_BROWSER_ARGS) + return false; + #undef MAX_BROWSER_ARGS + + //printf("calling execvp(\"%s\"", path); + //for (i = 0; args[i]; i++) + // printf(", \"%s\"", args[i]); + //printf("); ...\n\n\n"); + + execvp(path, args); + return(false); // exec shouldn't return unless there's an error. +} +#endif + + +static void launch_web_browser(const char *url) { +#ifdef WIN32 + ShellExecute(NULL, "open", url, NULL, NULL, SW_SHOWNORMAL); + +// lousy linux doesn't have a clean way to do this, but you can point people +// to docs on the BROWSER variable: +// http://www.catb.org/~esr/BROWSER/ +#elif PLATFORM_LINUX + if (strchr(url, '\'') != NULL) // Prevent simple shell injection. + return; + + const char *envr = getenv("BROWSER"); + if (envr == NULL) // not specified? We'll try a pseudo-sane list... + envr = "opera:mozilla:konqueror:firefox:netscape:xterm -e links:xterm -e lynx:"; + + char *ptr = (char *) alloca(strlen(envr) + 1); + if (ptr == NULL) + return; + strcpy(ptr, envr); + envr = ptr; + + while ((ptr = strchr(envr, ':')) != NULL) + { + *ptr = '\0'; + if (try_launch_browser(envr, url)) + return; + envr = ptr + 1; + } + + try_launch_browser(envr, url); +#endif +} + + +#ifndef WIN32 +// (code lifted from physfs: http://icculus.org/physfs/ ... zlib license.) +static char *findBinaryInPath(const char *bin, char *envr) +{ + size_t alloc_size = 0; + char *exe = NULL; + char *start = envr; + char *ptr; + + 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) + { + char *x = (char *) realloc(exe, size); + if (x == NULL) + { + if (exe != NULL) + free(exe); + return(NULL); + } /* if */ + + alloc_size = size; + exe = x; + } /* if */ + + /* build full binary path... */ + strcpy(exe, start); + if ((exe[0] == '\0') || (exe[strlen(exe) - 1] != '/')) + strcat(exe, "/"); + strcat(exe, bin); + + if (access(exe, X_OK) == 0) /* Exists as executable? We're done. */ + { + strcpy(exe, start); /* i'm lazy. piss off. */ + return(exe); + } /* if */ + + start = ptr + 1; /* start points to beginning of next element. */ + } while (ptr != NULL); + + if (exe != NULL) + free(exe); + + return(NULL); /* doesn't exist in path. */ +} /* findBinaryInPath */ + + +char *calcBaseDir(const char *argv0) +{ + /* If there isn't a path on argv0, then look through the $PATH for it. */ + char *retval; + char *envr; + + char *ptr = strrchr(argv0, '/'); + if (strchr(argv0, '/')) + { + retval = strdup(argv0); + if (retval) + *(strrchr(retval, '/')) = '\0'; + return(retval); + } + + envr = getenv("PATH"); + if (!envr) return NULL; + envr = strdup(envr); + if (!envr) return NULL; + retval = findBinaryInPath(argv0, envr); + free(envr); + return(retval); +} + +static inline void chdirToAppPath(const char *argv0) +{ + char *dir = calcBaseDir(argv0); + if (dir) + { + chdir(dir); + free(dir); + } +} +#endif + + +int main(int argc, char **argv) +{ + _argc = argc; + _argv = argv; +#ifndef WIN32 + chdirToAppPath(argv[0]); +#endif + LOGFUNC; #ifndef WIN32 // this is in WinMain, too. @@ -1434,15 +1670,16 @@ int main (void) // if(game.registernow){ if(regnow) { - #ifndef WIN32 - STUBBED("launch a web browser"); + #if PLATFORM_LINUX // (this may not be necessary any more.) + launch_web_browser("http://www.wolfire.com/registerlinux.html"); #else - char url[100]; - sprintf(url,"http://www.wolfire.com/registerpc.html"); - // LaunchURL(url); - ShellExecute(NULL, "open", url, NULL, NULL, SW_SHOWNORMAL); + launch_web_browser("http://www.wolfire.com/registerpc.html"); #endif } + + #if PLATFORM_LINUX // (this may not be necessary any more.) + _exit(0); // !!! FIXME: hack...crashes on exit! + #endif return 0; } catch (const std::exception& error) @@ -1995,6 +2232,7 @@ int main (void) if(width==840 && height==524)whichres=5; if(width==1024 && height==640)whichres=6; if(width==1344 && height==840)whichres=7; + if(width==1920 && height==1200)whichres=8; return whichres; } @@ -2011,6 +2249,7 @@ int main (void) if(width==840 && height==524)whichres=5; if(width==1024 && height==640)whichres=6; if(width==1344 && height==840)whichres=7; + if(width>=1920 && height>=1200)whichres=8; return whichres; } @@ -2022,7 +2261,7 @@ int main (void) while (true) { - if(whichres<=0 || whichres>7){ + if(whichres<=0 || whichres>8){ whichres = 0; width=640; height=480; @@ -2055,6 +2294,16 @@ int main (void) width=1344; height=840; } + if(whichres==8){ + width=1920; + height=1200; + } + + // currently with SDL, we just use whatever the native bitdepth + // of the display is and don't care. + #if USE_SDL + break; + #endif if ((detail != 0) && (resolutionDepths[whichres][1] != 0)) { @@ -2070,7 +2319,9 @@ int main (void) detail = 0; break; } - else if (0 == whichres) + else + + if (0 == whichres) { break; } @@ -2139,7 +2390,7 @@ int main (void) g_appInstance=hInstance; - main(); + main(0, NULL); UnregisterClass( g_wndClassName, hInstance); @@ -2150,7 +2401,7 @@ int main (void) extern int channels[100]; extern FSOUND_SAMPLE * samp[100]; - extern FSOUND_STREAM * strm[10]; + extern FSOUND_STREAM * strm[20]; extern "C" void PlaySoundEx(int chan, FSOUND_SAMPLE *sptr, FSOUND_DSPUNIT *dsp, signed char startpaused) { @@ -2429,10 +2680,6 @@ static bool load_png(const char *file_name, TGAImageRec &tex) if (!row_pointers) goto png_done; - retval = malloc(width * height * 4); - if (!retval) - goto png_done; - if (!hasalpha) { png_byte *dst = tex.data;