X-Git-Url: https://git.jsancho.org/?a=blobdiff_plain;f=Source%2FOpenGL_Windows.cpp;h=8ce1a4ce34e88a150d2c357054a4601a096d30e6;hb=d72054c5ab036810ee8a09ce57950aa977fcab06;hp=5c70e5fd2c9b9dd69cec14263996e0f8f3628b66;hpb=40a3dd7b76b6b10ae05dbd074f1f80ea7b4aa96d;p=lugaru.git diff --git a/Source/OpenGL_Windows.cpp b/Source/OpenGL_Windows.cpp index 5c70e5f..8ce1a4c 100644 --- a/Source/OpenGL_Windows.cpp +++ b/Source/OpenGL_Windows.cpp @@ -1,10 +1,38 @@ + +#ifdef WIN32 #include +#endif + #include "Game.h" +#ifndef USE_DEVIL +# ifdef WIN32 +# define USE_DEVIL +# endif +#endif + +#if USE_DEVIL + #include "IL/il.h" + #include "IL/ilu.h" + #include "IL/ilut.h" +#else + // just use libpng and libjpg directly; it's lighter-weight and easier + // to manage the dependencies on Linux... + 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); +#endif + // ADDED GWC +#ifdef _MSC_VER #pragma comment(lib, "opengl32.lib") #pragma comment(lib, "glu32.lib") #pragma comment(lib, "glaux.lib") +#endif extern bool buttons[3]; extern float multiplier; @@ -61,7 +89,11 @@ extern float volume; #include #include "gamegl.h" #include "MacCompatibility.h" + +#ifdef WIN32 #include +#endif + #include "fmod.h" #include "res/resource.h" @@ -92,14 +124,37 @@ void CleanUp (void); // statics/globals (internal only) ------------------------------------------ +#ifndef WIN32 +typedef struct tagPOINT { + int x; + int y; +} POINT, *PPOINT; +#endif + +#if USE_SDL +void sdlGetCursorPos(POINT *pt) +{ + int x, y; + SDL_GetMouseState(&x, &y); + pt->x = x; + pt->y = y; +} +#define GetCursorPos(x) sdlGetCursorPos(x) +#define SetCursorPos(x, y) SDL_WarpMouse(x, y) +#define ScreenToClient(x, pt) +#define ClientToScreen(x, pt) +#define MessageBox(hwnd,text,title,flags) STUBBED("msgbox") +#endif Point delta; +#ifdef WIN32 static const char g_wndClassName[]={ "LUGARUWINDOWCLASS" }; - static HINSTANCE g_appInstance; static HWND g_windowHandle; static HGLRC hRC; +#endif + static bool g_button, fullscreen = true; @@ -121,7 +176,6 @@ int kContextHeight; const RGBColor rgbBlack = { 0x0000, 0x0000, 0x0000 }; -extern HDC hDC; GLuint gFontList; char gcstrMode [256] = ""; @@ -130,11 +184,15 @@ Boolean gDone = false, gfFrontProcess = true; Game * pgame = 0; +static bool gMouseGrabbed = true; + // -------------------------------------------------------------------------- void ReportError (char * strError) { +#ifdef WIN32 // !!! FIXME. --ryan. throw std::exception( strError); +#endif /* char errMsgCStr [256]; Str255 strErr; @@ -149,6 +207,7 @@ void ReportError (char * strError) void SetupDSpFullScreen () { +#ifdef WIN32 LOGFUNC; if (fullscreen) @@ -170,11 +229,13 @@ void SetupDSpFullScreen () } ShowCursor(FALSE); +#endif } void ShutdownDSp () { +#ifdef WIN32 LOGFUNC; if (fullscreen) @@ -183,6 +244,7 @@ void ShutdownDSp () } ShowCursor(TRUE); +#endif } @@ -192,13 +254,237 @@ void ShutdownDSp () void DrawGL (Game & game) { +#ifdef WIN32 if (hDC == 0) return; +#endif game.DrawGLScene(); } +static KeyMap g_theKeys; + +void SetKey( int key) +{ + g_theKeys[ key >> 3] |= (1 << (key & 7)); +} + +void ClearKey( int key) +{ + g_theKeys[ key >> 3] &= (0xff ^ (1 << (key & 7))); +} + +void GetKeys( unsigned char theKeys[16]) +{ + memcpy( theKeys, &g_theKeys, 16); +} + +Boolean Button() +{ + return g_button; +} + +#if !USE_SDL +static void initSDLKeyTable(void) {} +#else +#define MAX_SDLKEYS SDLK_LAST +static unsigned short KeyTable[MAX_SDLKEYS]; + +static void initSDLKeyTable(void) +{ + memset(KeyTable, 0xFF, sizeof (KeyTable)); + KeyTable[SDLK_BACKSPACE] = MAC_DELETE_KEY; + KeyTable[SDLK_TAB] = MAC_TAB_KEY; + KeyTable[SDLK_RETURN] = MAC_RETURN_KEY; + KeyTable[SDLK_ESCAPE] = MAC_ESCAPE_KEY; + KeyTable[SDLK_SPACE] = MAC_SPACE_KEY; + KeyTable[SDLK_PAGEUP] = MAC_PAGE_UP_KEY; + KeyTable[SDLK_PAGEDOWN] = MAC_PAGE_DOWN_KEY; + KeyTable[SDLK_END] = MAC_END_KEY; + KeyTable[SDLK_HOME] = MAC_HOME_KEY; + KeyTable[SDLK_LEFT] = MAC_ARROW_LEFT_KEY; + KeyTable[SDLK_UP] = MAC_ARROW_UP_KEY; + KeyTable[SDLK_RIGHT] = MAC_ARROW_RIGHT_KEY; + KeyTable[SDLK_DOWN] = MAC_ARROW_DOWN_KEY; + KeyTable[SDLK_INSERT] = MAC_INSERT_KEY; + KeyTable[SDLK_DELETE] = MAC_DEL_KEY; + KeyTable[SDLK_0] = MAC_0_KEY; + KeyTable[SDLK_1] = MAC_1_KEY; + KeyTable[SDLK_2] = MAC_2_KEY; + KeyTable[SDLK_3] = MAC_3_KEY; + KeyTable[SDLK_4] = MAC_4_KEY; + KeyTable[SDLK_5] = MAC_5_KEY; + KeyTable[SDLK_6] = MAC_6_KEY; + KeyTable[SDLK_7] = MAC_7_KEY; + KeyTable[SDLK_8] = MAC_8_KEY; + KeyTable[SDLK_9] = MAC_9_KEY; + KeyTable[SDLK_a] = MAC_A_KEY; + KeyTable[SDLK_b] = MAC_B_KEY; + KeyTable[SDLK_c] = MAC_C_KEY; + KeyTable[SDLK_d] = MAC_D_KEY; + KeyTable[SDLK_e] = MAC_E_KEY; + KeyTable[SDLK_f] = MAC_F_KEY; + KeyTable[SDLK_g] = MAC_G_KEY; + KeyTable[SDLK_h] = MAC_H_KEY; + KeyTable[SDLK_i] = MAC_I_KEY; + KeyTable[SDLK_j] = MAC_J_KEY; + KeyTable[SDLK_k] = MAC_K_KEY; + KeyTable[SDLK_l] = MAC_L_KEY; + KeyTable[SDLK_m] = MAC_M_KEY; + KeyTable[SDLK_n] = MAC_N_KEY; + KeyTable[SDLK_o] = MAC_O_KEY; + KeyTable[SDLK_p] = MAC_P_KEY; + KeyTable[SDLK_q] = MAC_Q_KEY; + KeyTable[SDLK_r] = MAC_R_KEY; + KeyTable[SDLK_s] = MAC_S_KEY; + KeyTable[SDLK_t] = MAC_T_KEY; + KeyTable[SDLK_u] = MAC_U_KEY; + KeyTable[SDLK_v] = MAC_V_KEY; + KeyTable[SDLK_w] = MAC_W_KEY; + KeyTable[SDLK_x] = MAC_X_KEY; + KeyTable[SDLK_y] = MAC_Y_KEY; + KeyTable[SDLK_z] = MAC_Z_KEY; + KeyTable[SDLK_KP0] = MAC_NUMPAD_0_KEY; + KeyTable[SDLK_KP1] = MAC_NUMPAD_1_KEY; + KeyTable[SDLK_KP2] = MAC_NUMPAD_2_KEY; + KeyTable[SDLK_KP3] = MAC_NUMPAD_3_KEY; + KeyTable[SDLK_KP4] = MAC_NUMPAD_4_KEY; + KeyTable[SDLK_KP5] = MAC_NUMPAD_5_KEY; + KeyTable[SDLK_KP6] = MAC_NUMPAD_6_KEY; + KeyTable[SDLK_KP7] = MAC_NUMPAD_7_KEY; + KeyTable[SDLK_KP8] = MAC_NUMPAD_8_KEY; + KeyTable[SDLK_KP9] = MAC_NUMPAD_9_KEY; + KeyTable[SDLK_KP_MULTIPLY] = MAC_NUMPAD_ASTERISK_KEY; + KeyTable[SDLK_KP_PLUS] = MAC_NUMPAD_PLUS_KEY; + KeyTable[SDLK_KP_ENTER] = MAC_NUMPAD_ENTER_KEY; + KeyTable[SDLK_KP_MINUS] = MAC_NUMPAD_MINUS_KEY; + KeyTable[SDLK_KP_PERIOD] = MAC_NUMPAD_PERIOD_KEY; + KeyTable[SDLK_KP_DIVIDE] = MAC_NUMPAD_SLASH_KEY; + KeyTable[SDLK_F1] = MAC_F1_KEY; + KeyTable[SDLK_F2] = MAC_F2_KEY; + KeyTable[SDLK_F3] = MAC_F3_KEY; + KeyTable[SDLK_F4] = MAC_F4_KEY; + KeyTable[SDLK_F5] = MAC_F5_KEY; + KeyTable[SDLK_F6] = MAC_F6_KEY; + KeyTable[SDLK_F7] = MAC_F7_KEY; + KeyTable[SDLK_F8] = MAC_F8_KEY; + KeyTable[SDLK_F9] = MAC_F9_KEY; + KeyTable[SDLK_F10] = MAC_F10_KEY; + KeyTable[SDLK_F11] = MAC_F11_KEY; + KeyTable[SDLK_F12] = MAC_F12_KEY; + KeyTable[SDLK_SEMICOLON] = MAC_SEMICOLON_KEY; + KeyTable[SDLK_PLUS] = MAC_PLUS_KEY; + KeyTable[SDLK_COMMA] = MAC_COMMA_KEY; + KeyTable[SDLK_MINUS] = MAC_MINUS_KEY; + KeyTable[SDLK_PERIOD] = MAC_PERIOD_KEY; + KeyTable[SDLK_SLASH] = MAC_SLASH_KEY; + KeyTable[SDLK_BACKQUOTE] = MAC_TILDE_KEY; + KeyTable[SDLK_LEFTBRACKET] = MAC_LEFTBRACKET_KEY; + KeyTable[SDLK_BACKSLASH] = MAC_BACKSLASH_KEY; + KeyTable[SDLK_RIGHTBRACKET] = MAC_RIGHTBRACKET_KEY; + KeyTable[SDLK_QUOTE] = MAC_APOSTROPHE_KEY; +} + +static inline int clamp_sdl_mouse_button(Uint8 button) +{ + if ((button >= 1) && (button <= 3)) + return button - 1; + return -1; +} + +static void sdlEventProc(const SDL_Event &e) +{ + int val; + switch(e.type) + { + case SDL_MOUSEBUTTONDOWN: + { + val = clamp_sdl_mouse_button(e.button.button); + if (val >= 0) + { + if (val == 0) + { + g_button = true; + SetKey(MAC_MOUSEBUTTON1); + } + + else if (val == 1) + SetKey(MAC_MOUSEBUTTON2); + + buttons[val] = true; + } + } + return; + + case SDL_MOUSEBUTTONUP: + { + val = clamp_sdl_mouse_button(e.button.button); + if (val >= 0) + { + if (val == 0) + { + g_button = false; + ClearKey(MAC_MOUSEBUTTON1); + } + + else if (val == 1) + ClearKey(MAC_MOUSEBUTTON2); + + buttons[val] = false; + } + } + return; + + case SDL_KEYDOWN: + if (e.key.keysym.sym == SDLK_g) + { + if (e.key.keysym.mod & KMOD_CTRL) + gMouseGrabbed = !gMouseGrabbed; + } + + else if (e.key.keysym.sym == SDLK_RETURN) + { + if (e.key.keysym.mod & KMOD_ALT) + SDL_WM_ToggleFullScreen(SDL_GetVideoSurface()); + } + + if (e.key.keysym.sym < SDLK_LAST) + { + if (KeyTable[e.key.keysym.sym] != 0xffff) + SetKey(KeyTable[e.key.keysym.sym]); + } + + if (e.key.keysym.mod & KMOD_CTRL) + SetKey(MAC_CONTROL_KEY); + if (e.key.keysym.mod & KMOD_ALT) + SetKey(MAC_OPTION_KEY); + if (e.key.keysym.mod & KMOD_SHIFT) + SetKey(MAC_SHIFT_KEY); + if (e.key.keysym.mod & KMOD_CAPS) + SetKey(MAC_CAPS_LOCK_KEY); + + return; + + case SDL_KEYUP: + if (e.key.keysym.sym < SDLK_LAST) + { + if (KeyTable[e.key.keysym.sym] != 0xffff) + ClearKey(KeyTable[e.key.keysym.sym]); + } + + if (e.key.keysym.mod & KMOD_CTRL) + ClearKey(MAC_CONTROL_KEY); + if (e.key.keysym.mod & KMOD_ALT) + ClearKey(MAC_OPTION_KEY); + if (e.key.keysym.mod & KMOD_SHIFT) + ClearKey(MAC_SHIFT_KEY); + if (e.key.keysym.mod & KMOD_CAPS) + ClearKey(MAC_CAPS_LOCK_KEY); + return; + } +} +#endif // -------------------------------------------------------------------------- @@ -502,6 +788,26 @@ Boolean SetUp (Game & game) SetupDSpFullScreen(); +#if USE_SDL + if (!SDL_WasInit(SDL_INIT_VIDEO)) + { + if (SDL_Init(SDL_INIT_VIDEO) == -1) + { + fprintf(stderr, "SDL_Init() failed: %s\n", SDL_GetError()); + return false; + } + } + + Uint32 sdlflags = SDL_OPENGL; + 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; + } + +#elif (defined WIN32) //------------------------------------------------------------------ // create window int x = 0, y = 0; @@ -541,7 +847,6 @@ Boolean SetUp (Game & game) return false; } - //------------------------------------------------------------------ // setup OpenGL @@ -610,9 +915,10 @@ Boolean SetUp (Game & game) SetForegroundWindow(g_windowHandle); SetFocus(g_windowHandle); +#endif glClear( GL_COLOR_BUFFER_BIT ); - SwapBuffers( hDC ); + swap_gl_buffers(); // clear all states glDisable( GL_ALPHA_TEST); @@ -653,6 +959,7 @@ Boolean SetUp (Game & game) glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glAlphaFunc( GL_GREATER, 0.5f); +#if USE_DEVIL if (ilGetInteger(IL_VERSION_NUM) < IL_VERSION || iluGetInteger(ILU_VERSION_NUM) < ILU_VERSION || ilutGetInteger(ILUT_VERSION_NUM) < ILUT_VERSION) @@ -669,6 +976,7 @@ Boolean SetUp (Game & game) ilEnable(IL_ORIGIN_SET); ilOriginFunc(IL_ORIGIN_LOWER_LEFT); +#endif GLint width = kContextWidth; GLint height = kContextHeight; @@ -720,7 +1028,7 @@ static void DoMouse(Game & game) game.mousecoordv=globalMouse.v; } - if(!mainmenu) + if((!mainmenu)&&(gMouseGrabbed)) { if(lastMouse.h>gMidPoint.h+100||lastMouse.hgMidPoint.v+100||lastMouse.v> 3] |= (1 << (key & 7)); - } - - void ClearKey( int key) - { - g_theKeys[ key >> 3] &= (0xff ^ (1 << (key & 7))); - } - - void GetKeys( unsigned char theKeys[16]) - { - memcpy( theKeys, &g_theKeys, 16); - } - - Boolean Button() - { - return g_button; - } - - void ClipMouseToWindow(HWND window) { RECT wRect; @@ -1566,6 +1887,7 @@ int main (void) return TRUE; } +#endif int resolutionID(int width, int height) { @@ -1667,6 +1989,7 @@ int main (void) return res; } + #ifdef WIN32 int __stdcall WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd) { int argc = 0; @@ -1729,6 +2052,7 @@ int main (void) return TRUE; } + #endif extern int channels[100]; extern FSOUND_SAMPLE * samp[100]; @@ -1795,6 +2119,7 @@ int main (void) return false; } + #if USE_DEVIL ILstring f = strdup(ConvertFileName(fname)); if (!f) { @@ -1851,12 +2176,17 @@ int main (void) } */ free(f); + #else + res = load_image(fname, tex); + //if (!res) printf("failed to load %s\n", fname); + #endif return res; } void ScreenShot(const char * fname) { + #if USE_DEVIL ILstring f = strdup(fname); if (!f) { @@ -1873,4 +2203,220 @@ int main (void) ilDeleteImages(1, &iid); free(f); + #else + STUBBED("Non-DevIL screenshot"); + #endif } + + +#if !USE_DEVIL +static bool load_image(const char *file_name, TGAImageRec &tex) +{ + char *ptr = strrchr(file_name, '.'); + if (ptr) + { + if (stricmp(ptr+1, "png") == 0) + return load_png(file_name, tex); + else if (stricmp(ptr+1, "jpg") == 0) + return load_jpg(file_name, tex); + } + + STUBBED("Unsupported image type"); + return false; +} + + +struct my_error_mgr { + 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); +} + +/* stolen from public domain example.c code in libjpg distribution. */ +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 */ + 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) +{ + bool hasalpha = false; + png_structp png_ptr = NULL; + 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) + return(NULL); + + png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + if (png_ptr == NULL) + goto png_done; + + info_ptr = png_create_info_struct(png_ptr); + if (info_ptr == NULL) + goto png_done; + + if (setjmp(png_jmpbuf(png_ptr))) + goto png_done; + + png_init_io(png_ptr, fp); + png_read_png(png_ptr, info_ptr, + PNG_TRANSFORM_STRIP_16 | PNG_TRANSFORM_PACKING, + png_voidp_NULL); + png_get_IHDR(png_ptr, info_ptr, &width, &height, + &bit_depth, &color_type, &interlace_type, NULL, NULL); + + if (bit_depth != 8) // transform SHOULD handle this... + goto png_done; + + if (color_type & PNG_COLOR_MASK_PALETTE) // !!! FIXME? + goto png_done; + + if ((color_type & PNG_COLOR_MASK_COLOR) == 0) // !!! FIXME? + goto png_done; + + hasalpha = ((color_type & PNG_COLOR_MASK_ALPHA) != 0); + row_pointers = png_get_rows(png_ptr, info_ptr); + if (!row_pointers) + goto png_done; + + retval = malloc(width * height * 4); + if (!retval) + goto png_done; + + if (!hasalpha) + { + png_byte *dst = tex.data; + for (int i = height-1; i >= 0; i--) + { + png_byte *src = row_pointers[i]; + for (int j = 0; j < width; j++) + { + dst[0] = src[0]; + dst[1] = src[1]; + dst[2] = src[2]; + dst[3] = 0xFF; + src += 3; + dst += 4; + } + } + } + + else + { + png_byte *dst = tex.data; + int pitch = width * 4; + for (int i = height-1; i >= 0; i--, dst += pitch) + memcpy(dst, row_pointers[i], pitch); + } + + tex.sizeX = width; + tex.sizeY = height; + tex.bpp = 32; + retval = true; + +png_done: + png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL); + fclose(fp); + return (retval); +} + +#if 0 +void save_png(char *file_name /* , ... other image information ... */) +{ + FILE *fp; + png_structp png_ptr; + png_infop info_ptr; + + /* open the file */ + fp = fopen(file_name, "wb"); + if (fp == NULL) + return (ERROR); + + png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + if (png_ptr == NULL) + { + fclose(fp); + return (ERROR); + } + + info_ptr = png_create_info_struct(png_ptr); + if (info_ptr == NULL) + { + fclose(fp); + png_destroy_write_struct(&png_ptr, png_infopp_NULL); + return (ERROR); + } + + if (setjmp(png_jmpbuf(png_ptr))) + { + /* If we get here, we had a problem reading the file */ + fclose(fp); + png_destroy_write_struct(&png_ptr, &info_ptr); + return (ERROR); + } + + png_init_io(png_ptr, fp); + png_write_png(png_ptr, info_ptr, png_transforms, png_voidp_NULL); + png_destroy_write_struct(&png_ptr, &info_ptr); + fclose(fp); + return (OK); +} +#endif + +#endif +