From 1512d81eab0683f8c95cf841e1f9177fb098612f Mon Sep 17 00:00:00 2001 From: Kevin Shanahan Date: Sat, 8 Dec 2012 07:34:49 +1030 Subject: [PATCH] vid: update the sdl driver(s) to the SDL2 API Still quite a few things broken, especially mouse input, but video works much better and now compiles and works on OS X too. We now expect sdl2-config in the path and use that in the Makefile instead of the old SDLBASE guesswork. I broke out a couple of things into sdl_common.[ch] just to coordinate init and share the main window pointer. Still quite some limitations in the driver, only supports RBG888 modes right now, but adding RGB565 should be straight forward. Still quite a bit slower than the Win/MGL driver... would like to understand why that is at some point. But it's already much faster than the SDL1.2 version. Signed-off-by: Kevin Shanahan --- Makefile | 26 +--- common/in_sdl.c | 51 ++++--- common/sdl_common.c | 41 ++++++ common/snd_sdl.c | 23 ++- common/vid_sdl.c | 337 +++++++++++++++++++++++++++++-------------- include/sdl_common.h | 30 ++++ 6 files changed, 356 insertions(+), 152 deletions(-) create mode 100644 common/sdl_common.c create mode 100644 include/sdl_common.h diff --git a/Makefile b/Makefile index dba05fe..50bdf36 100644 --- a/Makefile +++ b/Makefile @@ -161,10 +161,6 @@ X11DIRS = /usr/X11R7 /usr/local/X11R7 /usr/X11R6 /usr/local/X11R6 /opt/X11 /opt/ X11BASE_GUESS := $(call find-localbase,X11/Xlib.h,X11,$(X11DIRS)) X11BASE ?= $(X11BASE_GUESS) -SDLDIRS = /opt/local -SDLBASE_GUESS := $(call find-localbase,SDL/SDL.h,SDL,$(SDLDIRS)) -SDLBASE ?= $(SDLBASE_GUESS) - # ------------------------------------------------------------------------ # Try to guess the MinGW cross compiler executables # - I've seen i386-mingw32msvc, i586-mingw32msvc (Debian) and now @@ -693,13 +689,10 @@ GL_LIBS += comctl32 SW_LFLAGS += $(call libdir-check,$(ST_LIBDIR)) endif ifeq ($(VID_TARGET),sdl) -SW_OBJS += vid_sdl.o -GL_OBJS += vid_sgl.o -CL_LIBS += SDL -ifneq ($(SDLBASE),) -CL_CPPFLAGS += -idirafter $(SDLBASE)/include -CL_LFLAGS += $(call libdir-check,$(SDLBASE)/lib); -endif +SW_OBJS += vid_sdl.o sdl_common.o +GL_OBJS += vid_sgl.o sdl_common.o +CL_CPPFLAGS += $(shell sdl2-config --cflags) +CL_LFLAGS += $(shell sdl2-config --libs) endif # ---------------- @@ -719,7 +712,7 @@ ifeq ($(IN_TARGET),win) CL_OBJS += in_win.o endif ifeq ($(IN_TARGET),sdl) -CL_OBJS += in_sdl.o +CL_OBJS += in_sdl.o sdl_common.o endif # ---------------- @@ -759,12 +752,9 @@ CL_OBJS += snd_sndio.o CL_LIBS += sndio endif ifeq ($(SND_TARGET),sdl) -CL_OBJS += snd_sdl.o -CL_LIBS += SDL -ifneq ($(SDLBASE),) -CL_CPPFLAGS += -idirafter $(SDLBASE)/include -CL_LFLAGS += $(call libdir-check,$(SDLBASE)/lib) -endif +CL_OBJS += snd_sdl.o sdl_common.o +CL_CPPFLAGS += $(shell sdl2-config --cflags) +CL_LFLAGS += $(shell sdl2-config --libs) endif # ---------------------------------------------------------------------------- diff --git a/common/in_sdl.c b/common/in_sdl.c index 937e089..937425e 100644 --- a/common/in_sdl.c +++ b/common/in_sdl.c @@ -18,7 +18,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include +#include "SDL.h" #include "cdaudio.h" #include "common.h" @@ -26,6 +26,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "input.h" #include "keys.h" #include "mathlib.h" +#include "sdl_common.h" #include "sound.h" #include "sys.h" #include "vid.h" @@ -71,14 +72,17 @@ IN_ProcessEvents(void) // Ugly key repeat handling. Should use a key_dest callback... if (old_key_dest != key_dest) { old_key_dest = key_dest; +#if 0 // KeyRepeat API changed? (repeat attribute on SDL_KeyboardEvent) if (key_dest == key_game) SDL_EnableKeyRepeat(0, SDL_DEFAULT_REPEAT_INTERVAL); else SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL); +#endif } switch (event.type) { +#if 0 // ACTIVEEVENT disappeared?? case SDL_ACTIVEEVENT: if (event.active.state == SDL_APPINPUTFOCUS) { if (event.active.gain) @@ -87,7 +91,7 @@ IN_ProcessEvents(void) event_focusout (); } break; - +#endif case SDL_KEYDOWN: case SDL_KEYUP: sym = event.key.keysym.sym; @@ -310,34 +314,34 @@ IN_ProcessEvents(void) case SDLK_DELETE: ksym = K_DEL; break; - case SDLK_KP0: + case SDLK_KP_0: ksym = K_KP0; break; - case SDLK_KP1: + case SDLK_KP_1: ksym = K_KP1; break; - case SDLK_KP2: + case SDLK_KP_2: ksym = K_KP2; break; - case SDLK_KP3: + case SDLK_KP_3: ksym = K_KP3; break; - case SDLK_KP4: + case SDLK_KP_4: ksym = K_KP4; break; - case SDLK_KP5: + case SDLK_KP_5: ksym = K_KP5; break; - case SDLK_KP6: + case SDLK_KP_6: ksym = K_KP6; break; - case SDLK_KP7: + case SDLK_KP_7: ksym = K_KP7; break; - case SDLK_KP8: + case SDLK_KP_8: ksym = K_KP8; break; - case SDLK_KP9: + case SDLK_KP_9: ksym = K_KP9; break; case SDLK_KP_PERIOD: @@ -433,13 +437,13 @@ IN_ProcessEvents(void) case SDLK_F15: ksym = K_F15; break; - case SDLK_NUMLOCK: + case SDLK_NUMLOCKCLEAR: ksym = K_NUMLOCK; break; case SDLK_CAPSLOCK: ksym = K_CAPSLOCK; break; - case SDLK_SCROLLOCK: + case SDLK_SCROLLLOCK: ksym = K_SCROLLOCK; break; case SDLK_RSHIFT: @@ -460,6 +464,7 @@ IN_ProcessEvents(void) case SDLK_LALT: ksym = K_LALT; break; +#if 0 // these keycodes now missing? case SDLK_RMETA: ksym = K_RMETA; break; @@ -472,39 +477,45 @@ IN_ProcessEvents(void) case SDLK_RSUPER: ksym = K_RSUPER; break; +#endif case SDLK_MODE: ksym = K_MODE; break; +#if 0 // these keycodes now missing? case SDLK_COMPOSE: ksym = K_COMPOSE; break; +#endif case SDLK_HELP: ksym = K_HELP; break; +#if 0 // these keycodes now missing? case SDLK_PRINT: ksym = K_PRINT; break; +#endif case SDLK_SYSREQ: ksym = K_SYSREQ; break; +#if 0 // these keycodes now missing? case SDLK_BREAK: ksym = K_BREAK; break; +#endif case SDLK_MENU: ksym = K_MENU; break; case SDLK_POWER: ksym = K_POWER; break; +#if 0 // these keycodes now missing? case SDLK_EURO: ksym = K_EURO; break; +#endif case SDLK_UNDO: ksym = K_UNDO; break; - case SDLK_LAST: - ksym = K_LAST; - break; default: #if 0 if (sym >= SDLK_a && sym <= SDLK_z) @@ -575,14 +586,20 @@ IN_LL_Grab_Input(int grab) if ((input_grabbed && grab) || (!input_grabbed && !grab)) return; +#if 0 // API changed... input_grabbed = (SDL_GRAB_ON == SDL_WM_GrabInput(grab ? SDL_GRAB_ON : SDL_GRAB_OFF)); +#endif } void IN_Init(void) { + Q_SDL_InitOnce(); + +#if 0 SDL_EnableUNICODE(1); // Enable UNICODE translation for keyboard input +#endif if (COM_CheckParm("-nomouse")) return; diff --git a/common/sdl_common.c b/common/sdl_common.c new file mode 100644 index 0000000..b2e25d3 --- /dev/null +++ b/common/sdl_common.c @@ -0,0 +1,41 @@ +/* +Copyright (C) 1996-1997 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. + +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. + +*/ + +#include "sdl.h" + +#include "qtypes.h" +#include "sdl_common.h" +#include "sys.h" + +SDL_Window *sdl_window = NULL; + +void +Q_SDL_InitOnce(void) +{ + static qboolean init_done = false; + + if (init_done) + return; + + if (SDL_Init(0) < 0) + Sys_Error("SDL_Init(0) failed: %s", SDL_GetError()); + + init_done = true; +} diff --git a/common/snd_sdl.c b/common/snd_sdl.c index 78e011e..0d6e0e5 100644 --- a/common/snd_sdl.c +++ b/common/snd_sdl.c @@ -18,11 +18,14 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include -#include -#include + +#include "SDL.h" +#include "SDL_audio.h" +#include "SDL_endian.h" #include "console.h" #include "quakedef.h" +#include "sdl_common.h" #include "sound.h" #include "sys.h" @@ -90,6 +93,13 @@ SNDDMA_Init(void) desired.samples = 512; /* FIXME ~= rate * _s_mixahead / 2 ? */ desired.callback = paint_audio; + /* Init the SDL Audio Sub-system */ + Q_SDL_InitOnce(); + if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) { + Con_Printf("Couldn't init SDL audio: %s\n", SDL_GetError()); + return false; + } + /* Open the audio device */ if (SDL_OpenAudio(&desired, &obtained) < 0) { Con_Printf("Couldn't open SDL audio: %s\n", SDL_GetError()); @@ -123,8 +133,6 @@ SNDDMA_Init(void) break; } - SDL_PauseAudio(0); - /* Fill the audio DMA information block */ shm = &the_shm; shm->samplebits = (obtained.format & 0xFF); @@ -149,6 +157,11 @@ SNDDMA_Init(void) rpos = wpos = 0; snd_inited = 1; + /* FIXME - hack because sys_win does this differently */ + snd_blocked = 0; + + SDL_PauseAudio(0); + return true; } @@ -211,7 +224,7 @@ void SNDDMA_Submit(void) SDL_UnlockAudio(); } -#ifdef WIN32 +#ifdef _WIN32 void S_BlockSound(void) { diff --git a/common/vid_sdl.c b/common/vid_sdl.c index bbe69b9..9cfc527 100644 --- a/common/vid_sdl.c +++ b/common/vid_sdl.c @@ -19,7 +19,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include -#include + +#include "SDL.h" #include "cdaudio.h" #include "cmd.h" @@ -34,12 +35,16 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "menu.h" #include "quakedef.h" #include "screen.h" +#include "sdl_common.h" #include "sound.h" #include "sys.h" #include "vid.h" #include "view.h" #include "wad.h" + +#ifdef _WIN32 #include "winquake.h" +#endif #ifdef NQ_HACK #include "host.h" @@ -51,12 +56,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // FIXME: evil hack to get full DirectSound support with SDL #ifdef _WIN32 #include -#include HWND mainwindow; +qboolean DDActive = false; #endif -SDL_Surface *screen = NULL; - +static SDL_Renderer *renderer = NULL; +static SDL_Texture *texture = NULL; /* ------------------------------------------------------------------------- */ @@ -77,22 +82,32 @@ unsigned short d_8to16table[256]; unsigned d_8to24table[256]; viddef_t vid; /* global video state */ +#ifdef _WIN32 static HICON hIcon; -qboolean DDActive; /* FIXME - remove this from SDL driver! */ +RECT window_rect; +#endif + int window_center_x, window_center_y; static int window_x, window_y; -RECT window_rect; /* Placeholders */ void VID_ForceLockState(int lk) { } int VID_ForceUnlockedAndReturnState(void) { return 0; } void VID_Shutdown(void) { } -void VID_ShiftPalette(unsigned char *palette) { } + +static qboolean palette_changed; + +void +VID_ShiftPalette(unsigned char *palette) +{ + VID_SetPalette(palette); +} + void VID_SetDefaultMode(void) { } static qboolean VID_SetWindowedMode(int modenum) { return true; } static qboolean VID_FullScreenMode(int modenum) { return true; } -#define MAX_MODE_LIST 80 +#define MAX_MODE_LIST 200 #define VID_ROW_SIZE 3 #define VID_MODE_NONE (-1) @@ -161,6 +176,7 @@ typedef struct { int modenum; int fullscreen; int bpp; + int refresh; char modedesc[13]; } vmode_t; @@ -201,69 +217,59 @@ InitMode(vmode_t *mode, int num, int fullscreen, int width, int height) mode->bpp = 8; mode->width = width; mode->height = height; - snprintf(mode->modedesc, 13, "%dx%d", width, height); - mode->modedesc[12] = 0; + snprintf(mode->modedesc, sizeof(mode->modedesc), "%dx%d", width, height); + mode->modedesc[sizeof(mode->modedesc) - 1] = 0; } static void VID_InitModeList(void) { - int i; - SDL_Rect **modes; - Uint32 flags = SDL_SWSURFACE | SDL_HWPALETTE; - SDL_PixelFormat fmt = { - .palette = NULL, - .BitsPerPixel = 8, - .BytesPerPixel = 1 - }; + int i, err; + int displays, sdlmodes; + SDL_DisplayMode mode; + + displays = SDL_GetNumVideoDisplays(); + if (displays < 1) + Sys_Error("%s: no displays found (%s)", __func__, SDL_GetError()); + + /* FIXME - allow use of more than one display */ + sdlmodes = SDL_GetNumDisplayModes(1); + + printf("%s: %d modes on display 1\n", __func__, sdlmodes); nummodes = 0; - /* - * Check availability of windowed video modes - * Usually any mode is allowed, but the API allows for systems where only - * specific modes are possible. - */ - modes = SDL_ListModes(&fmt, flags); - if (modes == (SDL_Rect **)-1) { - InitMode(&modelist[0], 0, 0, 320, 240); - InitMode(&modelist[1], 1, 0, 640, 480); - InitMode(&modelist[2], 2, 0, 800, 600); - InitMode(&modelist[3], 3, 0, 1024, 768); - InitMode(&modelist[4], 4, 0, 1280, 960); - nummodes = 5; - } else { - for (i = 0; modes[i] && i < NUM_WINDOWED_MODES; i++) { - if (modes[i]->h > MAXHEIGHT) - continue; - InitMode(modelist + nummodes, nummodes, 0, modes[i]->w, modes[i]->h); - nummodes++; - } - /* FIXME - still kind of broken due to hard coded constants */ - while (i < NUM_WINDOWED_MODES) { - InitMode(modelist + nummodes, nummodes, 0, 0, 0); - strcpy(modelist[nummodes].modedesc, ""); - nummodes++; - } - } + InitMode(&modelist[0], 0, 0, 320, 240); + InitMode(&modelist[1], 1, 0, 640, 480); + InitMode(&modelist[2], 2, 0, 800, 600); + InitMode(&modelist[3], 3, 0, 1024, 768); + InitMode(&modelist[4], 4, 0, 1280, 960); + nummodes = 5; - /* Get available fullscreen modes */ - modes = SDL_ListModes(&fmt, SDL_FULLSCREEN | flags); - if (!modes) - Sys_Error("No fullscreen video modes available?"); - for (i = 0; modes[i]; i++) { - if (modes[i]->h > MAXHEIGHT) + /* + * Check availability of fullscreen modes + */ + for (i = 0; i < sdlmodes && nummodes < MAX_MODE_LIST; i++) { + err = SDL_GetDisplayMode(1, i, &mode); + if (err) + Sys_Error("%s: couldn't get mode %d info (%s)", + __func__, i, SDL_GetError()); + + printf("%s: checking mode %i: %dx%d, %s\n", __func__, + i, mode.w, mode.h, SDL_GetPixelFormatName(mode.format)); + + if (mode.format != SDL_PIXELFORMAT_RGB888 || mode.h > MAXHEIGHT) continue; + modelist[nummodes].modenum = nummodes; modelist[nummodes].fullscreen = 1; modelist[nummodes].bpp = 8; - modelist[nummodes].width = modes[i]->w; - modelist[nummodes].height = modes[i]->h; - sprintf(modelist[nummodes].modedesc, "%dx%d", modes[i]->w, modes[i]->h); + modelist[nummodes].width = mode.w; + modelist[nummodes].height = mode.h; + modelist[nummodes].refresh = mode.refresh_rate; + sprintf(modelist[nummodes].modedesc, "%dx%d", mode.w, mode.h); nummodes++; } - - //Sys_Error("Not fully implemented...\n%s", txtbuf); } static int vid_line; @@ -721,7 +727,7 @@ VID_GetModeDescription2(int mode) pv = VID_GetModePtr(mode); if (modelist[mode].fullscreen) { - sprintf(pinfo, "%4d x %4d fullscreen", pv->width, pv->height); + sprintf(pinfo, "%4d x %4d @ %dHz", pv->width, pv->height, pv->refresh); } else { sprintf(pinfo, "%4d x %4d windowed", pv->width, pv->height); } @@ -801,6 +807,7 @@ VID_UpdateWindowStatus static void VID_UpdateWindowStatus(void) { +#ifdef _WIN32 window_rect.left = window_x; window_rect.top = window_y; window_rect.right = window_x + window_width; @@ -809,6 +816,7 @@ VID_UpdateWindowStatus(void) window_center_y = (window_rect.top + window_rect.bottom) / 2; IN_UpdateClipCursor(); +#endif } static int @@ -821,16 +829,32 @@ VID_SetMode(int modenum, unsigned char *palette) mode = VID_GetModePtr(modenum); w = mode->width; h = mode->height; - flags = SDL_SWSURFACE | SDL_HWPALETTE; + flags = SDL_WINDOW_SHOWN; if (mode->fullscreen) - flags |= SDL_FULLSCREEN; + flags |= SDL_WINDOW_FULLSCREEN; - /* - * Placeholder code - just set one video mode for now - */ - screen = SDL_SetVideoMode(w, h, 8, flags); - if (!screen) - Sys_Error("VID: Couldn't set video mode: %s", SDL_GetError()); + if (renderer) + SDL_DestroyRenderer(renderer); + if (sdl_window) + SDL_DestroyWindow(sdl_window); + + sdl_window = SDL_CreateWindow("TyrQuake", + SDL_WINDOWPOS_UNDEFINED, + SDL_WINDOWPOS_UNDEFINED, + w, h, flags); + if (!sdl_window) + Sys_Error("%s: Unable to create window: %s", __func__, SDL_GetError()); + + renderer = SDL_CreateRenderer(sdl_window, -1, SDL_RENDERER_ACCELERATED); + if (!renderer) + Sys_Error("%s: Unable to create renderer: %s", __func__, SDL_GetError()); + + texture = SDL_CreateTexture(renderer, + SDL_PIXELFORMAT_RGB888, + SDL_TEXTUREACCESS_STREAMING, + w, h); + if (!texture) + Sys_Error("%s: Unable to create texture: %s", __func__, SDL_GetError()); //VID_InitGamma(palette); VID_SetPalette(palette); @@ -841,13 +865,16 @@ VID_SetMode(int modenum, unsigned char *palette) vid.maxwarpwidth = WARP_WIDTH; vid.maxwarpheight = WARP_HEIGHT; vid.aspect = ((float)vid.height / (float)vid.width) * (320.0 / 240.0); - vid.buffer = vid.conbuffer = vid.direct = screen->pixels; - vid.rowbytes = vid.conrowbytes = screen->pitch; vid.colormap = host_colormap; vid.fullbright = 256 - LittleLong(*((int *)vid.colormap + 2048)); VID_AllocBuffers(vid.width, vid.height); + + // In-memory buffer which we upload via SDL texture + vid.buffer = vid.conbuffer = vid.direct = Hunk_HighAllocName(vid.width * vid.height, "vidbuf"); + vid.rowbytes = vid.conrowbytes = vid.width; + D_InitCaches(vid_surfcache, vid_surfcachesize); window_width = vid.width; @@ -859,9 +886,11 @@ VID_SetMode(int modenum, unsigned char *palette) vid.recalc_refdef = 1; +#ifdef _WIN32 mainwindow=GetActiveWindow(); SendMessage(mainwindow, WM_SETICON, (WPARAM)ICON_BIG, (LPARAM)hIcon); SendMessage(mainwindow, WM_SETICON, (WPARAM)ICON_SMALL, (LPARAM)hIcon); +#endif return true; } @@ -878,15 +907,20 @@ int VGA_width, VGA_height, VGA_rowbytes, VGA_bufferrowbytes = 0; void VID_SetPalette(unsigned char *palette) { - SDL_Color colors[256]; - int i; + unsigned i, r, g, b; + SDL_PixelFormat *fmt; + fmt = SDL_AllocFormat(SDL_PIXELFORMAT_RGB888); for (i = 0; i < 256; i++) { - colors[i].r = *palette++; - colors[i].g = *palette++; - colors[i].b = *palette++; + r = palette[0]; + g = palette[1]; + b = palette[2]; + palette += 3; + d_8to24table[i] = SDL_MapRGB(fmt, r, g, b); } - SDL_SetColors(screen, colors, 0, 256); + SDL_FreeFormat(fmt); + + palette_changed = true; } static void @@ -897,19 +931,22 @@ do_screen_buffer(void) void VID_Init(unsigned char *palette) /* (byte *palette, byte *colormap) */ { - Uint32 flags; - - // Load the SDL library - if (SDL_Init(SDL_INIT_VIDEO) < 0) + /* + * Init SDL and the video subsystem + */ + Q_SDL_InitOnce(); + if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) Sys_Error("VID: Couldn't load SDL: %s", SDL_GetError()); VID_InitModeList(); VID_SetMode(0, palette); +#ifdef _WIN32 mainwindow=GetActiveWindow(); SendMessage(mainwindow, WM_SETICON, (WPARAM)ICON_BIG, (LPARAM)hIcon); SendMessage(mainwindow, WM_SETICON, (WPARAM)ICON_SMALL, (LPARAM)hIcon); +#endif vid_menudrawfn = VID_MenuDraw; vid_menukeyfn = VID_MenuKey; @@ -933,63 +970,132 @@ VID_Init(unsigned char *palette) /* (byte *palette, byte *colormap) */ void VID_Update(vrect_t *rects) { - SDL_Rect *sdlrects; - int i, n; + SDL_Rect subrect; + int i; vrect_t *rect; + vrect_t fullrect; + byte *src; + unsigned *dst; + int pitch; + int height; + int err; /* * Check for vid_mode changes - * FIXME - not sure this is the best place to do this */ - if ((int)vid_mode.value != vid_modenum) + if ((int)vid_mode.value != vid_modenum) { VID_SetMode((int)vid_mode.value, host_basepal); - - // Two-pass system, since Quake doesn't do it the SDL way... - - // First, count the number of rectangles - n = 0; - for (rect = rects; rect; rect = rect->pnext) - ++n; - - // Second, copy them to SDL rectangles and update - if (!(sdlrects = (SDL_Rect *)calloc(1, n * sizeof(SDL_Rect)))) - Sys_Error("Out of memory!"); - i = 0; - for (rect = rects; rect; rect = rect->pnext) { - sdlrects[i].x = rect->x; - sdlrects[i].y = rect->y; - sdlrects[i].w = rect->width; - sdlrects[i].h = rect->height; - i++; + /* FIXME - not the right place! redraw the scene to buffer first */ + return; } - SDL_UpdateRects(screen, n, sdlrects); + + /* + * If the palette changed, refresh the whole screen + */ + if (palette_changed) { + palette_changed = false; + fullrect.x = 0; + fullrect.y = 0; + fullrect.width = vid.width; + fullrect.height = vid.height; + fullrect.pnext = NULL; + rects = &fullrect; + } + + for (rect = rects; rect; rect = rect->pnext) { + subrect.x = rect->x; + subrect.y = rect->y; + subrect.w = rect->width; + subrect.h = rect->height; + + err = SDL_LockTexture(texture, &subrect, (void **)&dst, &pitch); + if (err) + Sys_Error("%s: unable to lock texture (%s)", + __func__, SDL_GetError()); + src = vid.buffer + rect->y * vid.width + rect->x; + height = subrect.h; + while (height--) { + for (i = 0; i < rect->width; i++) + dst[i] = d_8to24table[src[i]]; + dst += pitch / sizeof(*dst); + src += vid.width; + } + SDL_UnlockTexture(texture); + } + err = SDL_RenderCopy(renderer, texture, NULL, NULL); + if (err) + Sys_Error("%s: unable to render texture (%s)", __func__, SDL_GetError()); + SDL_RenderPresent(renderer); } void D_BeginDirectRect(int x, int y, byte *pbitmap, int width, int height) { - Uint8 *offset; + int err, i; + byte *src; + unsigned *dst; + int pitch; + SDL_Rect subrect; - if (!screen) + if (!texture || !renderer) return; - if (x < 0) - x = screen->w + x - 1; - offset = (Uint8 *)screen->pixels + y * screen->pitch + x; + + subrect.x = (x < 0) ? vid.width + x - 1 : x; + subrect.y = y; + subrect.w = width; + subrect.h = height; + + err = SDL_LockTexture(texture, &subrect, (void **)&dst, &pitch); + if (err) + Sys_Error("%s: unable to lock texture (%s)", __func__, SDL_GetError()); + src = pbitmap; while (height--) { - memcpy(offset, pbitmap, width); - offset += screen->pitch; - pbitmap += width; + for (i = 0; i < width; i++) + dst[i] = d_8to24table[src[i]]; + dst += pitch / sizeof(*dst); + src += width; } + SDL_UnlockTexture(texture); + + err = SDL_RenderCopy(renderer, texture, NULL, NULL); + if (err) + Sys_Error("%s: unable to render texture (%s)", __func__, SDL_GetError()); + SDL_RenderPresent(renderer); } void D_EndDirectRect(int x, int y, int width, int height) { - if (!screen) + int err, i; + byte *src; + unsigned *dst; + int pitch; + SDL_Rect subrect; + + if (!texture || !renderer) return; - if (x < 0) - x = screen->w + x - 1; - SDL_UpdateRect(screen, x, y, width, height); + + subrect.x = (x < 0) ? vid.width + x - 1 : x; + subrect.y = y; + subrect.w = width; + subrect.h = height; + + err = SDL_LockTexture(texture, &subrect, (void **)&dst, &pitch); + if (err) + Sys_Error("%s: unable to lock texture (%s)", __func__, SDL_GetError()); + src = vid.buffer + y * vid.width + subrect.x; + while (height--) { + for (i = 0; i < width; i++) + dst[i] = d_8to24table[src[i]]; + dst += pitch / sizeof(*dst); + src += vid.width; + } + SDL_UnlockTexture(texture); + + err = SDL_RenderCopy(renderer, texture, NULL, NULL); + if (err) + Sys_Error("%s: unable to render texture (%s)", __func__, SDL_GetError()); + SDL_RenderPresent(renderer); } void @@ -1001,3 +1107,10 @@ void VID_UnlockBuffer(void) { } + +#ifndef _WIN32 +void +Sys_SendKeyEvents(void) +{ +} +#endif diff --git a/include/sdl_common.h b/include/sdl_common.h new file mode 100644 index 0000000..33f3a21 --- /dev/null +++ b/include/sdl_common.h @@ -0,0 +1,30 @@ +/* +Copyright (C) 1996-1997 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. + +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. + +*/ + +#include "sdl.h" + +extern SDL_Window *sdl_window; + +/* + * Independent subsystems can call this to ensure the main SDL_Init() + * has been called at least once before they init their subsystem + * via SDL_InitSubSystem(SDL_INIT_FOO) + */ +void Q_SDL_InitOnce(void);