X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Flibgame%2Fsdl.c;h=a72bdcc0cc80e5c52df9c2267c70f36802e714a5;hb=6e022fe74edcab8e9b6be32bcfdd7006f478e2ab;hp=65057b61ba0cd221c273ab4283ed6110ef6eb696;hpb=ccbc62287e20cd3776b95980a77be3fee5ad7053;p=rocksndiamonds.git diff --git a/src/libgame/sdl.c b/src/libgame/sdl.c index 65057b61..a72bdcc0 100644 --- a/src/libgame/sdl.c +++ b/src/libgame/sdl.c @@ -26,9 +26,11 @@ /* SDL internal variables */ #if defined(TARGET_SDL2) -// static SDL_Window *sdl_window = NULL; -SDL_Window *sdl_window = NULL; -// static SDL_Renderer *sdl_renderer = NULL; +static SDL_Window *sdl_window = NULL; +static SDL_Renderer *sdl_renderer = NULL; +static SDL_Texture *sdl_texture = NULL; + +#define USE_RENDERER 1 #endif /* stuff needed to work around SDL/Windows fullscreen drawing bug */ @@ -42,6 +44,41 @@ static int video_yoffset; /* functions from SGE library */ void sge_Line(SDL_Surface *, Sint16, Sint16, Sint16, Sint16, Uint32); +#if defined(TARGET_SDL2) +static void UpdateScreen(SDL_Rect *rect) +{ +#if USE_RENDERER + SDL_Surface *screen = backbuffer->surface; + +#if 1 + if (rect) + { + int bytes_x = screen->pitch / video.width; + int bytes_y = screen->pitch; + + SDL_UpdateTexture(sdl_texture, rect, + screen->pixels + rect->x * bytes_x + rect->y * bytes_y, + screen->pitch); + } + else + { + SDL_UpdateTexture(sdl_texture, NULL, screen->pixels, screen->pitch); + } +#else + SDL_UpdateTexture(sdl_texture, NULL, screen->pixels, screen->pitch); +#endif + SDL_RenderClear(sdl_renderer); + SDL_RenderCopy(sdl_renderer, sdl_texture, NULL, NULL); + SDL_RenderPresent(sdl_renderer); +#else + if (rect) + SDL_UpdateWindowSurfaceRects(sdl_window, rect, 1); + else + SDL_UpdateWindowSurface(sdl_window); +#endif +} +#endif + static void setFullscreenParameters(char *fullscreen_mode_string) { struct ScreenModeInfo *fullscreen_mode; @@ -244,13 +281,21 @@ void SDLInitVideoBuffer(DrawBuffer **backbuffer, DrawWindow **window, } } +#if 0 /* set window icon */ SDLSetWindowIcon(program.sdl_icon_filename); +#endif /* open SDL video output device (window or fullscreen mode) */ if (!SDLSetVideoMode(backbuffer, fullscreen)) Error(ERR_EXIT, "setting video mode failed"); +#if 1 + /* !!! SDL2 can only set the window icon if the window already exists !!! */ + /* set window icon */ + SDLSetWindowIcon(program.sdl_icon_filename); +#endif + /* set window and icon title */ #if defined(TARGET_SDL2) SDL_SetWindowTitle(sdl_window, program.window_title); @@ -283,7 +328,8 @@ boolean SDLSetVideoMode(DrawBuffer **backbuffer, boolean fullscreen) { boolean success = TRUE; #if defined(TARGET_SDL2) - int surface_flags_fullscreen = SURFACE_FLAGS | SDL_WINDOW_FULLSCREEN; + // int surface_flags_fullscreen = SURFACE_FLAGS | SDL_WINDOW_FULLSCREEN; + int surface_flags_fullscreen = SURFACE_FLAGS | SDL_WINDOW_FULLSCREEN_DESKTOP; int surface_flags_window = SURFACE_FLAGS; #else int surface_flags_fullscreen = SURFACE_FLAGS | SDL_FULLSCREEN; @@ -316,7 +362,8 @@ boolean SDLSetVideoMode(DrawBuffer **backbuffer, boolean fullscreen) { new_surface = SDL_GetWindowSurface(sdl_window); - SDL_UpdateWindowSurface(sdl_window); // immediately map window + // SDL_UpdateWindowSurface(sdl_window); // immediately map window + // UpdateScreen(NULL); // immediately map window } #else new_surface = SDL_SetVideoMode(fullscreen_width, fullscreen_height, @@ -351,17 +398,88 @@ boolean SDLSetVideoMode(DrawBuffer **backbuffer, boolean fullscreen) /* switch display to window mode */ #if defined(TARGET_SDL2) + +#if USE_RENDERER + float scale_factor = 1.2; + int test_fullscreen = 0; + int surface_flags = (test_fullscreen ? surface_flags_fullscreen : + surface_flags_window); + + sdl_window = SDL_CreateWindow(program.window_title, + SDL_WINDOWPOS_CENTERED, + SDL_WINDOWPOS_CENTERED, + (int)(scale_factor * video.width), + (int)(scale_factor * video.height), + surface_flags); + + if (sdl_window != NULL) + { + sdl_renderer = SDL_CreateRenderer(sdl_window, -1, 0); + + if (sdl_renderer != NULL) + { + SDL_RenderSetLogicalSize(sdl_renderer, video.width, video.height); + SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear"); + + sdl_texture = SDL_CreateTexture(sdl_renderer, + SDL_PIXELFORMAT_ARGB8888, + SDL_TEXTUREACCESS_STREAMING, + video.width, video.height); + + if (sdl_texture != NULL) + { +#if 1 + // (do not use alpha channel) + new_surface = SDL_CreateRGBSurface(0, video.width, video.height, 32, + 0x00FF0000, + 0x0000FF00, + 0x000000FF, + 0x00000000); +#else + // (this uses an alpha channel, which we don't want here) + new_surface = SDL_CreateRGBSurface(0, video.width, video.height, 32, + 0x00FF0000, + 0x0000FF00, + 0x000000FF, + 0xFF000000); +#endif + + printf("::: pitch == %d\n", new_surface->pitch); + + if (new_surface == NULL) + Error(ERR_WARN, "SDL_CreateRGBSurface() failed: %s", + SDL_GetError()); + } + else + { + Error(ERR_WARN, "SDL_CreateTexture() failed: %s", SDL_GetError()); + } + } + else + { + Error(ERR_WARN, "SDL_CreateRenderer() failed: %s", SDL_GetError()); + } + } + else + { + Error(ERR_WARN, "SDL_CreateWindow() failed: %s", SDL_GetError()); + } +#else sdl_window = SDL_CreateWindow(program.window_title, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, video.width, video.height, surface_flags_window); + if (sdl_window != NULL) { new_surface = SDL_GetWindowSurface(sdl_window); - SDL_UpdateWindowSurface(sdl_window); // immediately map window + // SDL_UpdateWindowSurface(sdl_window); // immediately map window + // UpdateScreen(NULL); // immediately map window } +#endif + #else new_surface = SDL_SetVideoMode(video.width, video.height, video.depth, surface_flags_window); @@ -384,6 +502,10 @@ boolean SDLSetVideoMode(DrawBuffer **backbuffer, boolean fullscreen) } } +#if defined(TARGET_SDL2) + UpdateScreen(NULL); // map window +#endif + #if 1 SDL_EventState(SDL_SYSWMEVENT, SDL_ENABLE); @@ -463,14 +585,19 @@ void SDLCopyArea(Bitmap *src_bitmap, Bitmap *dst_bitmap, dst_rect.w = width; dst_rect.h = height; - if (src_bitmap != backbuffer || dst_bitmap != window) + // if (src_bitmap != backbuffer || dst_bitmap != window) + if (!(src_bitmap == backbuffer && dst_bitmap == window)) SDL_BlitSurface((mask_mode == BLIT_MASKED ? src_bitmap->surface_masked : src_bitmap->surface), &src_rect, real_dst_bitmap->surface, &dst_rect); #if defined(TARGET_SDL2) if (dst_bitmap == window) - SDL_UpdateWindowSurface(sdl_window); + { + // SDL_UpdateWindowSurface(sdl_window); + // SDL_UpdateWindowSurfaceRects(sdl_window, &dst_rect, 1); + UpdateScreen(&dst_rect); + } #else if (dst_bitmap == window) SDL_UpdateRect(backbuffer->surface, dst_x, dst_y, width, height); @@ -498,7 +625,11 @@ void SDLFillRectangle(Bitmap *dst_bitmap, int x, int y, int width, int height, #if defined(TARGET_SDL2) if (dst_bitmap == window) - SDL_UpdateWindowSurface(sdl_window); + { + // SDL_UpdateWindowSurface(sdl_window); + // SDL_UpdateWindowSurfaceRects(sdl_window, &rect, 1); + UpdateScreen(&rect); + } #else if (dst_bitmap == window) SDL_UpdateRect(backbuffer->surface, x, y, width, height); @@ -516,6 +647,9 @@ void SDLFadeRectangle(Bitmap *bitmap_cross, int x, int y, int width, int height, SDL_Surface *surface_screen = backbuffer->surface; SDL_Surface *surface_cross = (bitmap_cross ? bitmap_cross->surface : NULL); SDL_Rect src_rect, dst_rect; +#if defined(TARGET_SDL2) + SDL_Rect dst_rect2; +#endif int src_x = x, src_y = y; int dst_x = x, dst_y = y; unsigned int time_last, time_current; @@ -544,6 +678,10 @@ void SDLFadeRectangle(Bitmap *bitmap_cross, int x, int y, int width, int height, dst_rect.w = width; /* (ignored) */ dst_rect.h = height; /* (ignored) */ +#if defined(TARGET_SDL2) + dst_rect2 = dst_rect; +#endif + if (initialization_needed) { #if defined(TARGET_SDL2) @@ -739,7 +877,9 @@ void SDLFadeRectangle(Bitmap *bitmap_cross, int x, int y, int width, int height, draw_border_function(); #if defined(TARGET_SDL2) - SDL_UpdateWindowSurface(sdl_window); + // SDL_UpdateWindowSurface(sdl_window); + // SDL_UpdateWindowSurfaceRects(sdl_window, &dst_rect2, 1); + UpdateScreen(&dst_rect2); #else SDL_UpdateRect(surface_screen, dst_x, dst_y, width, height); #endif @@ -776,7 +916,9 @@ void SDLFadeRectangle(Bitmap *bitmap_cross, int x, int y, int width, int height, #if 1 /* only update the region of the screen that is affected from fading */ #if defined(TARGET_SDL2) - SDL_UpdateWindowSurface(sdl_window); + // SDL_UpdateWindowSurface(sdl_window); + // SDL_UpdateWindowSurfaceRects(sdl_window, &dst_rect, 1); + UpdateScreen(&dst_rect); #else SDL_UpdateRect(surface_screen, dst_x, dst_y, width, height); #endif