X-Git-Url: https://git.jsancho.org/?a=blobdiff_plain;f=Source%2FOpenGL_Windows.cpp;h=e5e45492648294d632e9636f8b323ade4223a866;hb=0ca5e88eabdd3aa3eb010460a73d10d8ebde61d8;hp=302ec1dd6d94961f3743d83c1c8191cb5c379b67;hpb=ff50d2ebce620062b6988247293af3a7e3b7ab90;p=lugaru.git diff --git a/Source/OpenGL_Windows.cpp b/Source/OpenGL_Windows.cpp index 302ec1d..e5e4549 100644 --- a/Source/OpenGL_Windows.cpp +++ b/Source/OpenGL_Windows.cpp @@ -18,10 +18,15 @@ #else // just use libpng and libjpg directly; it's lighter-weight and easier // to manage the dependencies on Linux... - #include "png.h" + extern "C" { + #include "png.h" + #include "jpeglib.h" + } 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); + static bool save_png(const char * fname); #endif // ADDED GWC @@ -129,6 +134,43 @@ typedef struct tagPOINT { #endif #if USE_SDL +#define GL_FUNC(ret,fn,params,call,rt) \ + extern "C" { \ + static ret GLAPIENTRY (*p##fn) params = NULL; \ + ret GLAPIENTRY fn params { rt p##fn call; } \ + } +#include "glstubs.h" +#undef GL_FUNC + +static bool lookup_glsym(const char *funcname, void **func, const char *libname) +{ + *func = SDL_GL_GetProcAddress(funcname); + if (*func == NULL) + { + fprintf(stderr, "Failed to find OpenGL symbol \"%s\" in \"%s\"\n", + funcname, libname); + return false; + } + return true; +} + +static bool lookup_all_glsyms(const char *libname) +{ + bool retval = true; + #define GL_FUNC(ret,fn,params,call,rt) \ + if (!lookup_glsym(#fn, (void **) &p##fn, libname)) retval = false; + #include "glstubs.h" + #undef GL_FUNC + return retval; +} + +static void GLAPIENTRY glDeleteTextures_doNothing(GLsizei n, const GLuint *textures) +{ + // no-op. +} + + + void sdlGetCursorPos(POINT *pt) { int x, y; @@ -181,8 +223,6 @@ Boolean gDone = false, gfFrontProcess = true; Game * pgame = 0; -static bool gMouseGrabbed = true; - // -------------------------------------------------------------------------- void ReportError (char * strError) @@ -385,16 +425,26 @@ static void initSDLKeyTable(void) static inline int clamp_sdl_mouse_button(Uint8 button) { + if (button == 2) // right mouse button is button 3 in SDL. + button = 3; + else if (button == 3) + button = 2; + if ((button >= 1) && (button <= 3)) return button - 1; return -1; } -static void sdlEventProc(const SDL_Event &e) +static void sdlEventProc(const SDL_Event &e, Game &game) { int val; switch(e.type) { + case SDL_MOUSEMOTION: + game.deltah += e.motion.xrel; + game.deltav += e.motion.yrel; + return; + case SDL_MOUSEBUTTONDOWN: { val = clamp_sdl_mouse_button(e.button.button); @@ -437,7 +487,15 @@ static void sdlEventProc(const SDL_Event &e) if (e.key.keysym.sym == SDLK_g) { if (e.key.keysym.mod & KMOD_CTRL) - gMouseGrabbed = !gMouseGrabbed; + { + SDL_GrabMode mode = SDL_GRAB_ON; + if ((SDL_GetVideoSurface()->flags & SDL_FULLSCREEN) == 0) + { + mode = SDL_WM_GrabInput(SDL_GRAB_QUERY); + mode = (mode==SDL_GRAB_ON) ? SDL_GRAB_OFF:SDL_GRAB_ON; + } + SDL_WM_GrabInput(mode); + } } else if (e.key.keysym.sym == SDLK_RETURN) @@ -496,8 +554,7 @@ Boolean SetUp (Game & game) randSeed = UpTime().lo; osx = 0; -// ifstream ipstream(":Data:config.txt", std::ios::in /*| std::ios::nocreate*/); - ifstream ipstream("./Data/config.txt", std::ios::in /*| std::ios::nocreate*/); + ifstream ipstream(ConvertFileName(":Data:config.txt"), std::ios::in /*| std::ios::nocreate*/); detail=1; ismotionblur=0; usermousesensitivity=1; @@ -547,8 +604,7 @@ Boolean SetUp (Game & game) selectDetail(kContextWidth, kContextHeight, kBitsPerPixel, detail); if(!ipstream) { - //ofstream opstream(":Data:config.txt"); - ofstream opstream("./Data/config.txt"); + ofstream opstream(ConvertFileName(":Data:config.txt", "w")); opstream << "Screenwidth:\n"; opstream << kContextWidth; opstream << "\nScreenheight:\n"; @@ -793,9 +849,20 @@ Boolean SetUp (Game & game) fprintf(stderr, "SDL_Init() failed: %s\n", SDL_GetError()); return false; } + + const char *libname = "libGL.so.1"; // !!! FIXME: Linux specific! + if (SDL_GL_LoadLibrary(libname) == -1) + { + fprintf(stderr, "SDL_GL_LoadLibrary(\"%s\") failed: %s\n", + libname, SDL_GetError()); + return false; + } + + if (!lookup_all_glsyms(libname)) + return false; } - Uint32 sdlflags = SDL_OPENGL; + Uint32 sdlflags = SDL_OPENGL; // !!! FIXME: SDL_FULLSCREEN? SDL_WM_SetCaption("Lugaru", "lugaru"); SDL_ShowCursor(0); if (SDL_SetVideoMode(kContextWidth, kContextHeight, 0, sdlflags) == NULL) @@ -804,6 +871,8 @@ Boolean SetUp (Game & game) return false; } + + #elif (defined WIN32) //------------------------------------------------------------------ // create window @@ -994,6 +1063,23 @@ Boolean SetUp (Game & game) static void DoMouse(Game & game) { +#if USE_SDL + 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; + } +#else static Point lastMouse = {-1,-1}; Point globalMouse; @@ -1025,7 +1111,7 @@ static void DoMouse(Game & game) game.mousecoordv=globalMouse.v; } - if((!mainmenu)&&(gMouseGrabbed)) + if(!mainmenu) { if(lastMouse.h>gMidPoint.h+100||lastMouse.hgMidPoint.v+100||lastMouse.verr; + longjmp(err->setjmp_buffer, 1); +} + +/* stolen from public domain example.c code in libjpg distribution. */ static bool load_jpg(const char *file_name, TGAImageRec &tex) { - // !!! FIXME: write this. - STUBBED("load_jpg"); - return false; + 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 */ + FILE *infile = fopen(file_name, "rb"); + + if (infile == NULL) + return false; + + cinfo.err = jpeg_std_error(&jerr.pub); + jerr.pub.error_exit = my_error_exit; + if (setjmp(jerr.setjmp_buffer)) { + jpeg_destroy_decompress(&cinfo); + fclose(infile); + return false; + } + + jpeg_create_decompress(&cinfo); + jpeg_stdio_src(&cinfo, infile); + (void) jpeg_read_header(&cinfo, TRUE); + + cinfo.out_color_space = JCS_RGB; + cinfo.quantize_colors = 0; + (void) jpeg_calc_output_dimensions(&cinfo); + (void) jpeg_start_decompress(&cinfo); + + row_stride = cinfo.output_width * cinfo.output_components; + tex.sizeX = cinfo.output_width; + tex.sizeY = cinfo.output_height; + tex.bpp = 24; + + while (cinfo.output_scanline < cinfo.output_height) { + buffer[0] = (JSAMPROW)(char *)tex.data + + ((cinfo.output_height-1) - cinfo.output_scanline) * row_stride; + (void) jpeg_read_scanlines(&cinfo, buffer, 1); + } + + (void) jpeg_finish_decompress(&cinfo); + jpeg_destroy_decompress(&cinfo); + fclose(infile); + + return true; } + /* stolen from public domain example.c code in libpng distribution. */ static bool load_png(const char *file_name, TGAImageRec &tex) { @@ -2313,9 +2465,95 @@ static bool load_png(const char *file_name, TGAImageRec &tex) retval = true; png_done: - png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL); - fclose(fp); - return (retval); + png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL); + if (fp) + fclose(fp); + return (retval); +} + + +static bool save_image(const char *file_name) +{ + char *ptr = strrchr(file_name, '.'); + if (ptr) + { + if (stricmp(ptr+1, "png") == 0) + return save_png(file_name); + } + + STUBBED("Unsupported image type"); + return false; +} + + +static bool save_png(const char *file_name) +{ + FILE *fp = NULL; + png_structp png_ptr = NULL; + png_infop info_ptr = NULL; + bool retval = false; + + fp = fopen(file_name, "wb"); + if (fp == NULL) + return false; + + png_bytep *row_pointers = new png_bytep[kContextHeight]; + png_bytep screenshot = new png_byte[kContextWidth * kContextHeight * 3]; + if ((!screenshot) || (!row_pointers)) + goto save_png_done; + + glGetError(); + glReadPixels(0, 0, kContextWidth, kContextHeight, + GL_RGB, GL_UNSIGNED_BYTE, screenshot); + if (glGetError() != GL_NO_ERROR) + goto save_png_done; + + for (int i = 0; i < kContextHeight; i++) + 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) + goto save_png_done; + + info_ptr = png_create_info_struct(png_ptr); + if (info_ptr == NULL) + goto save_png_done; + + if (setjmp(png_jmpbuf(png_ptr))) + goto save_png_done; + + png_init_io(png_ptr, fp); + + if (setjmp(png_jmpbuf(png_ptr))) + goto save_png_done; + + png_set_IHDR(png_ptr, info_ptr, kContextWidth, kContextHeight, + 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, + PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); + + png_write_info(png_ptr, info_ptr); + + if (setjmp(png_jmpbuf(png_ptr))) + goto save_png_done; + + png_write_image(png_ptr, row_pointers); + + if (setjmp(png_jmpbuf(png_ptr))) + goto save_png_done; + + png_write_end(png_ptr, NULL); + retval = true; + +save_png_done: + png_destroy_write_struct(&png_ptr, &info_ptr); + delete[] screenshot; + delete[] row_pointers; + if (fp) + fclose(fp); + if (!retval) + unlink(ConvertFileName(file_name)); + return retval; } + #endif