// Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // $Id:$ // // Copyright (C) 1993-1996 by id Software, Inc. // // This program 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, // 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. // // $Log:$ // // DESCRIPTION: // DOOM graphics stuff for X11, UNIX. // //----------------------------------------------------------------------------- #include #include #include #include "SDL.h" #include "../doomstat.h" #include "../i_system.h" #include "../v_video.h" #include "../m_argv.h" #include "../d_main.h" #include "../doomdef.h" #include "../ib_video.h" #if SDL_MAJOR_VERSION >= 2 static SDL_Window *window; #endif static SDL_Surface *surface; #if SDL_MAJOR_VERSION >= 2 static int xlatekey(SDL_Keycode keysym) #else static int xlatekey(SDLKey keysym) #endif { int rc; switch(rc = keysym) { case SDLK_LEFT: rc = KEY_LEFTARROW; break; case SDLK_RIGHT: rc = KEY_RIGHTARROW; break; case SDLK_DOWN: rc = KEY_DOWNARROW; break; case SDLK_UP: rc = KEY_UPARROW; break; case SDLK_ESCAPE: rc = KEY_ESCAPE; break; case SDLK_RETURN: rc = KEY_ENTER; break; case SDLK_TAB: rc = KEY_TAB; break; case SDLK_F1: rc = KEY_F1; break; case SDLK_F2: rc = KEY_F2; break; case SDLK_F3: rc = KEY_F3; break; case SDLK_F4: rc = KEY_F4; break; case SDLK_F5: rc = KEY_F5; break; case SDLK_F6: rc = KEY_F6; break; case SDLK_F7: rc = KEY_F7; break; case SDLK_F8: rc = KEY_F8; break; case SDLK_F9: rc = KEY_F9; break; case SDLK_F10: rc = KEY_F10; break; case SDLK_F11: rc = KEY_F11; break; case SDLK_F12: rc = KEY_F12; break; case SDLK_BACKSPACE: case SDLK_DELETE: rc = KEY_BACKSPACE; break; case SDLK_PAUSE: rc = KEY_PAUSE; break; case SDLK_KP_EQUALS: case SDLK_EQUALS: rc = KEY_EQUALS; break; case SDLK_KP_MINUS: case SDLK_MINUS: rc = KEY_MINUS; break; case SDLK_LSHIFT: case SDLK_RSHIFT: rc = KEY_RSHIFT; break; case SDLK_LCTRL: case SDLK_RCTRL: rc = KEY_RCTRL; break; case SDLK_LALT: case SDLK_RALT: #if SDL_MAJOR_VERSION >= 2 case SDLK_LGUI: case SDLK_RGUI: #else case SDLK_LMETA: case SDLK_RMETA: #endif rc = KEY_RALT; break; default: if (rc >= SDLK_SPACE && rc <= SDLK_BACKQUOTE) rc = rc - SDLK_SPACE + ' '; else if (rc >= 'A' && rc <= 'Z') rc = rc - 'A' + 'a'; break; } return rc; } // // IB_StartTic // void IB_StartTic (void) { event_t event; static int button_state; SDL_Event sdl_event; while (SDL_PollEvent(&sdl_event)) { switch (sdl_event.type) { case SDL_QUIT: I_Quit(); break; case SDL_KEYDOWN: event.type = ev_keydown; event.data1 = xlatekey(sdl_event.key.keysym.sym); D_PostEvent(&event); // fprintf(stderr, "k"); break; case SDL_KEYUP: event.type = ev_keyup; event.data1 = xlatekey(sdl_event.key.keysym.sym); D_PostEvent(&event); // fprintf(stderr, "ku"); break; case SDL_MOUSEBUTTONDOWN: switch (sdl_event.button.button) { case SDL_BUTTON_LEFT: button_state |= 1; break; case SDL_BUTTON_MIDDLE: button_state |= 2; break; case SDL_BUTTON_RIGHT: button_state |= 4; break; } event.type = ev_mouse; event.data1 = button_state; event.data2 = event.data3 = 0; D_PostEvent(&event); // fprintf(stderr, "b"); break; case SDL_MOUSEBUTTONUP: switch (sdl_event.button.button) { case SDL_BUTTON_LEFT: button_state &= ~1; break; case SDL_BUTTON_MIDDLE: button_state &= ~2; break; case SDL_BUTTON_RIGHT: button_state &= ~4; break; } event.type = ev_mouse; event.data1 = button_state; event.data2 = event.data3 = 0; D_PostEvent(&event); // fprintf(stderr, "bu"); break; case SDL_MOUSEMOTION: event.type = ev_mouse; event.data1 = button_state; event.data2 = sdl_event.motion.xrel * (1 << 5); event.data3 = -sdl_event.motion.yrel * (1 << 5); if (event.data2 || event.data3) { D_PostEvent(&event); // fprintf(stderr, "m"); } break; } } } void IB_GetFramebuffer(unsigned char **pixels, size_t *pitch) { SDL_LockSurface(surface); *pixels = surface->pixels; *pitch = surface->pitch; } // // IB_FinishUpdate // void IB_FinishUpdate (void) { SDL_UnlockSurface(surface); #if SDL_MAJOR_VERSION >= 2 SDL_UpdateWindowSurface(window); #else SDL_Flip(surface); #endif } void IB_GetColor(unsigned char *bytes, unsigned char red, unsigned char green, unsigned char blue) { Uint32 color = SDL_MapRGB(surface->format, red, green, blue); for (Uint8 i = 0; i < surface->format->BytesPerPixel; ++i) bytes[i] = (color >> (i * 8)) & 0xFF; } void IB_InitGraphics(const char *title, size_t screen_width, size_t screen_height, size_t *bytes_per_pixel) { #if SDL_MAJOR_VERSION >= 2 SDL_InitSubSystem(SDL_INIT_VIDEO | SDL_INIT_EVENTS); #else SDL_InitSubSystem(SDL_INIT_VIDEO); #endif #if SDL_MAJOR_VERSION >= 2 window = SDL_CreateWindow(title, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, screen_width, screen_height, 0); if (window == NULL) I_Error("Could not create SDL window"); surface = SDL_GetWindowSurface(window); #else surface = SDL_SetVideoMode(screen_width, screen_height, 32, SDL_SWSURFACE | SDL_ANYFORMAT); if (surface == NULL) I_Error("Could not create SDL window surface"); SDL_WM_SetCaption(title, title); #endif *bytes_per_pixel = surface->format->BytesPerPixel; } void IB_ShutdownGraphics(void) { #if SDL_MAJOR_VERSION >= 2 SDL_FreeSurface(surface); SDL_DestroyWindow(window); #endif #if SDL_MAJOR_VERSION >= 2 SDL_QuitSubSystem(SDL_INIT_VIDEO | SDL_INIT_EVENTS); #else SDL_QuitSubSystem(SDL_INIT_VIDEO); #endif } void IB_GrabMouse(boolean grab) { #if SDL_MAJOR_VERSION >= 2 SDL_SetRelativeMouseMode(grab ? SDL_ENABLE : SDL_DISABLE); #else SDL_WM_GrabInput(grab ? SDL_GRAB_ON : SDL_GRAB_OFF); SDL_ShowCursor(!grab); #endif }