X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Flibgame%2Fsdl.c;h=0325c45f038383c8a5e971be60c59dd1d9930906;hb=41b805f296b21b950aa8372c2f1792bf301f4ef9;hp=6d2cb4d1133c18352b13b7bdcdf6c4a3eb6c558b;hpb=64e7c54dce6ea8c063f04198c64c5057d751c928;p=rocksndiamonds.git diff --git a/src/libgame/sdl.c b/src/libgame/sdl.c index 6d2cb4d1..0325c45f 100644 --- a/src/libgame/sdl.c +++ b/src/libgame/sdl.c @@ -4,7 +4,7 @@ // (c) 1995-2014 by Artsoft Entertainment // Holger Schemel // info@artsoft.org -// http://www.artsoft.org/ +// https://www.artsoft.org/ // ---------------------------------------------------------------------------- // sdl.c // ============================================================================ @@ -14,6 +14,7 @@ #include "joystick.h" #include "misc.h" #include "setup.h" +#include "gadgets.h" #define ENABLE_UNUSED_CODE 0 // currently unused functions @@ -25,14 +26,11 @@ // ============================================================================ // SDL internal variables -#if defined(TARGET_SDL2) static SDL_Window *sdl_window = NULL; static SDL_Renderer *sdl_renderer = NULL; static SDL_Texture *sdl_texture_stream = NULL; static SDL_Texture *sdl_texture_target = NULL; static boolean fullscreen_enabled = FALSE; -#endif - static boolean limit_screen_updates = FALSE; @@ -41,7 +39,8 @@ void sge_Line(SDL_Surface *, Sint16, Sint16, Sint16, Sint16, Uint32); #if defined(USE_TOUCH_INPUT_OVERLAY) // functions to draw overlay graphics for touch device input -static void DrawTouchInputOverlay(); +static void DrawTouchInputOverlay(void); +static void DrawTouchGadgetsOverlay(void); #endif void SDLLimitScreenUpdates(boolean enable) @@ -85,8 +84,8 @@ static void UpdateScreenExt(SDL_Rect *rect, boolean with_frame_delay) static int LastFrameCounter = 0; boolean changed = (FrameCounter != LastFrameCounter); - printf("::: FrameCounter == %d [%s]\n", FrameCounter, - (changed ? "-" : "SAME FRAME UPDATED")); + Debug("internal:frame", "FrameCounter == %d [%s]", FrameCounter, + (changed ? "-" : "SAME FRAME UPDATED")); LastFrameCounter = FrameCounter; @@ -114,7 +113,6 @@ static void UpdateScreenExt(SDL_Rect *rect, boolean with_frame_delay) rect = NULL; } -#if defined(TARGET_SDL2) SDL_Texture *sdl_texture = sdl_texture_stream; // deactivate use of target texture if render targets are not supported @@ -216,27 +214,25 @@ static void UpdateScreenExt(SDL_Rect *rect, boolean with_frame_delay) #if defined(USE_TOUCH_INPUT_OVERLAY) // draw overlay graphics for touch device input, if needed DrawTouchInputOverlay(); -#endif + // draw overlay gadgets for touch device input, if needed + DrawTouchGadgetsOverlay(); #endif // global synchronization point of the game to align video frame delay if (with_frame_delay) WaitUntilDelayReached(&video.frame_delay, video.frame_delay_value); -#if defined(TARGET_SDL2) - // show render target buffer on screen + video.frame_counter++; + + // show render target buffer on screen SDL_RenderPresent(sdl_renderer); -#else // TARGET_SDL - if (rect) - SDL_UpdateRects(screen, 1, rect); - else - SDL_UpdateRect(screen, 0, 0, 0, 0); -#endif } static void UpdateScreen_WithFrameDelay(SDL_Rect *rect) { + PumpEvents(); // execute event filter actions while waiting + UpdateScreenExt(rect, TRUE); } @@ -261,8 +257,8 @@ void Delay_WithScreenUpdates(unsigned int delay) static void SDLSetWindowIcon(char *basename) { - /* (setting the window icon on Mac OS X would replace the high-quality - dock icon with the currently smaller (and uglier) icon from file) */ + // (setting the window icon on Mac OS X would replace the high-quality + // dock icon with the currently smaller (and uglier) icon from file) #if !defined(PLATFORM_MACOSX) char *filename = getCustomImageFilename(basename); @@ -270,14 +266,14 @@ static void SDLSetWindowIcon(char *basename) if (filename == NULL) { - Error(ERR_WARN, "SDLSetWindowIcon(): cannot find file '%s'", basename); + Warn("SDLSetWindowIcon(): cannot find file '%s'", basename); return; } if ((surface = IMG_Load(filename)) == NULL) { - Error(ERR_WARN, "IMG_Load() failed: %s", SDL_GetError()); + Warn("IMG_Load('%s') failed: %s", basename, SDL_GetError()); return; } @@ -286,16 +282,10 @@ static void SDLSetWindowIcon(char *basename) SDL_SetColorKey(surface, SET_TRANSPARENT_PIXEL, SDL_MapRGB(surface->format, 0x00, 0x00, 0x00)); -#if defined(TARGET_SDL2) SDL_SetWindowIcon(sdl_window, surface); -#else - SDL_WM_SetIcon(surface, NULL); -#endif #endif } -#if defined(TARGET_SDL2) - static boolean equalSDLPixelFormat(SDL_PixelFormat *format1, SDL_PixelFormat *format2) { @@ -307,6 +297,7 @@ static boolean equalSDLPixelFormat(SDL_PixelFormat *format1, format1->Bmask == format2->Bmask); } +#if 0 static Pixel SDLGetColorKey(SDL_Surface *surface) { Pixel color_key; @@ -316,10 +307,37 @@ static Pixel SDLGetColorKey(SDL_Surface *surface) return color_key; } +#endif + +static void SDLCopyColorKey(SDL_Surface *src_surface, SDL_Surface *dst_surface) +{ + Pixel color_key; + Uint8 r, g, b; + + // check if source surface has a color key + if (SDL_GetColorKey(src_surface, &color_key) == 0) + { + // get RGB values of color key of source surface + SDL_GetRGB(color_key, src_surface->format, &r, &g, &b); + + // get color key from RGB values in destination surface format + color_key = SDL_MapRGB(dst_surface->format, r, g, b); + + // set color key in destination surface + SDL_SetColorKey(dst_surface, SET_TRANSPARENT_PIXEL, color_key); + } + else + { + // unset color key in destination surface + SDL_SetColorKey(dst_surface, UNSET_TRANSPARENT_PIXEL, 0); + } +} static boolean SDLHasColorKey(SDL_Surface *surface) { - return (SDLGetColorKey(surface) != -1); + Pixel color_key; + + return (SDL_GetColorKey(surface, &color_key) == 0); } static boolean SDLHasAlpha(SDL_Surface *surface) @@ -340,6 +358,15 @@ static void SDLSetAlpha(SDL_Surface *surface, boolean set, int alpha) SDL_SetSurfaceAlphaMod(surface, alpha); } +const char *SDLGetRendererName(void) +{ + static SDL_RendererInfo renderer_info; + + SDL_GetRendererInfo(sdl_renderer, &renderer_info); + + return renderer_info.name; +} + SDL_Surface *SDLGetNativeSurface(SDL_Surface *surface) { SDL_PixelFormat format; @@ -361,7 +388,11 @@ SDL_Surface *SDLGetNativeSurface(SDL_Surface *surface) new_surface = SDL_ConvertSurface(surface, &format, 0); if (new_surface == NULL) - Error(ERR_EXIT, "SDL_ConvertSurface() failed: %s", SDL_GetError()); + Fail("SDL_ConvertSurface() failed: %s", SDL_GetError()); + + // workaround for a bug in SDL 2.0.12 (which does not convert the color key) + if (SDLHasColorKey(surface) && !SDLHasColorKey(new_surface)) + SDLCopyColorKey(surface, new_surface); return new_surface; } @@ -389,74 +420,6 @@ boolean SDLSetNativeSurface(SDL_Surface **surface) return TRUE; } -#else - -static Pixel SDLGetColorKey(SDL_Surface *surface) -{ - if ((surface->flags & SDL_SRCCOLORKEY) == 0) - return -1; - - return surface->format->colorkey; -} - -static boolean SDLHasColorKey(SDL_Surface *surface) -{ - return (SDLGetColorKey(surface) != -1); -} - -static boolean SDLHasAlpha(SDL_Surface *surface) -{ - return ((surface->flags & SDL_SRCALPHA) != 0); -} - -static void SDLSetAlpha(SDL_Surface *surface, boolean set, int alpha) -{ - SDL_SetAlpha(surface, (set ? SDL_SRCALPHA : 0), alpha); -} - -SDL_Surface *SDLGetNativeSurface(SDL_Surface *surface) -{ - SDL_Surface *new_surface; - - if (surface == NULL) - return NULL; - - if (!video.initialized) - new_surface = SDL_ConvertSurface(surface, surface->format, SURFACE_FLAGS); - else if (SDLHasAlpha(surface)) - new_surface = SDL_DisplayFormatAlpha(surface); - else - new_surface = SDL_DisplayFormat(surface); - - if (new_surface == NULL) - Error(ERR_EXIT, "%s() failed: %s", - (video.initialized ? "SDL_DisplayFormat" : "SDL_ConvertSurface"), - SDL_GetError()); - - return new_surface; -} - -boolean SDLSetNativeSurface(SDL_Surface **surface) -{ - SDL_Surface *new_surface; - - if (surface == NULL || - *surface == NULL || - !video.initialized) - return FALSE; - - new_surface = SDLGetNativeSurface(*surface); - - SDL_FreeSurface(*surface); - - *surface = new_surface; - - return TRUE; -} - -#endif - -#if defined(TARGET_SDL2) static SDL_Texture *SDLCreateTextureFromSurface(SDL_Surface *surface) { if (program.headless) @@ -465,16 +428,13 @@ static SDL_Texture *SDLCreateTextureFromSurface(SDL_Surface *surface) SDL_Texture *texture = SDL_CreateTextureFromSurface(sdl_renderer, surface); if (texture == NULL) - Error(ERR_EXIT, "SDL_CreateTextureFromSurface() failed: %s", - SDL_GetError()); + Fail("SDL_CreateTextureFromSurface() failed: %s", SDL_GetError()); return texture; } -#endif void SDLCreateBitmapTextures(Bitmap *bitmap) { -#if defined(TARGET_SDL2) if (bitmap == NULL) return; @@ -485,12 +445,10 @@ void SDLCreateBitmapTextures(Bitmap *bitmap) bitmap->texture = SDLCreateTextureFromSurface(bitmap->surface); bitmap->texture_masked = SDLCreateTextureFromSurface(bitmap->surface_masked); -#endif } void SDLFreeBitmapTextures(Bitmap *bitmap) { -#if defined(TARGET_SDL2) if (bitmap == NULL) return; @@ -501,28 +459,23 @@ void SDLFreeBitmapTextures(Bitmap *bitmap) bitmap->texture = NULL; bitmap->texture_masked = NULL; -#endif } void SDLInitVideoDisplay(void) { -#if !defined(TARGET_SDL2) - if (!strEqual(setup.system.sdl_videodriver, ARG_DEFAULT)) - SDL_putenv(getStringCat2("SDL_VIDEODRIVER=", setup.system.sdl_videodriver)); - - SDL_putenv("SDL_VIDEO_CENTERED=1"); -#endif + // set hint to select render driver as specified in setup config file + if (!strEqual(setup.system.sdl_renderdriver, ARG_DEFAULT)) + SDL_SetHint(SDL_HINT_RENDER_DRIVER, setup.system.sdl_renderdriver); // initialize SDL video if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) - Error(ERR_EXIT, "SDL_InitSubSystem() failed: %s", SDL_GetError()); + Fail("SDL_InitSubSystem() failed: %s", SDL_GetError()); // set default SDL depth -#if !defined(TARGET_SDL2) - video.default_depth = SDL_GetVideoInfo()->vfmt->BitsPerPixel; -#else video.default_depth = 32; // (how to determine video depth in SDL2?) -#endif + // + // Code used with SDL 1.2: + // video.default_depth = SDL_GetVideoInfo()->vfmt->BitsPerPixel; } static void SDLInitVideoBuffer_VideoBuffer(boolean fullscreen) @@ -535,17 +488,12 @@ static void SDLInitVideoBuffer_VideoBuffer(boolean fullscreen) SDLSetScreenRenderingMode(setup.screen_rendering_mode); -#if defined(TARGET_SDL2) // SDL 2.0: support for (desktop) fullscreen mode available video.fullscreen_available = TRUE; -#else - // SDL 1.2: no support for fullscreen mode in R'n'D anymore - video.fullscreen_available = FALSE; -#endif // open SDL video output device (window or fullscreen mode) if (!SDLSetVideoMode(fullscreen)) - Error(ERR_EXIT, "setting video mode failed"); + Fail("setting video mode failed"); // !!! SDL2 can only set the window icon if the window already exists !!! // set window icon @@ -588,17 +536,19 @@ static boolean SDLCreateScreen(boolean fullscreen) { SDL_Surface *new_surface = NULL; -#if defined(TARGET_SDL2) - int surface_flags_window = SURFACE_FLAGS | SDL_WINDOW_RESIZABLE; - int surface_flags_fullscreen = SURFACE_FLAGS | SDL_WINDOW_FULLSCREEN_DESKTOP; -#else int surface_flags_window = SURFACE_FLAGS; - int surface_flags_fullscreen = SURFACE_FLAGS; // (no fullscreen in SDL 1.2) -#endif + int surface_flags_fullscreen = SURFACE_FLAGS | SDL_WINDOW_FULLSCREEN_DESKTOP; -#if defined(TARGET_SDL2) #if 1 int renderer_flags = SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE; + + video.vsync_mode = VSYNC_MODE_OFF; + + if (!strEqual(setup.vsync_mode, STR_VSYNC_MODE_OFF)) + { + renderer_flags |= SDL_RENDERER_PRESENTVSYNC; + video.vsync_mode = VSYNC_MODE_NORMAL; + } #else /* If SDL_CreateRenderer() is called from within a VirtualBox Windows VM _without_ enabling 2D/3D acceleration and/or guest additions installed, @@ -607,9 +557,6 @@ static boolean SDLCreateScreen(boolean fullscreen) int renderer_flags = SDL_RENDERER_SOFTWARE; #endif - SDLSetScreenSizeAndOffsets(video.width, video.height); -#endif - int width = video.width; int height = video.height; int screen_width = video.screen_width; @@ -621,8 +568,6 @@ static boolean SDLCreateScreen(boolean fullscreen) video.window_width = screen_width; video.window_height = screen_height; -#if defined(TARGET_SDL2) - // store if initial screen mode is fullscreen mode when changing screen size video.fullscreen_initial = fullscreen; @@ -673,10 +618,10 @@ static boolean SDLCreateScreen(boolean fullscreen) if (sdl_renderer != NULL) { - SDL_RenderSetLogicalSize(sdl_renderer, screen_width, screen_height); // SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear"); SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, setup.window_scaling_quality); + // required for setting adaptive vsync when using OpenGL renderer SDLSetScreenVsyncMode(setup.vsync_mode); sdl_texture_stream = SDL_CreateTexture(sdl_renderer, @@ -696,59 +641,28 @@ static boolean SDLCreateScreen(boolean fullscreen) new_surface = SDL_CreateRGBSurface(0, width, height, 32, 0,0,0, 0); if (new_surface == NULL) - Error(ERR_WARN, "SDL_CreateRGBSurface() failed: %s", SDL_GetError()); + Warn("SDL_CreateRGBSurface() failed: %s", SDL_GetError()); } else { - Error(ERR_WARN, "SDL_CreateTexture() failed: %s", SDL_GetError()); + Warn("SDL_CreateTexture() failed: %s", SDL_GetError()); } } else { - Error(ERR_WARN, "SDL_CreateRenderer() failed: %s", SDL_GetError()); + Warn("SDL_CreateRenderer() failed: %s", SDL_GetError()); } } else { - Error(ERR_WARN, "SDL_CreateWindow() failed: %s", SDL_GetError()); + Warn("SDL_CreateWindow() failed: %s", SDL_GetError()); } -#else // TARGET_SDL - - if (gfx.final_screen_bitmap == NULL) - gfx.final_screen_bitmap = CreateBitmapStruct(); - - gfx.final_screen_bitmap->width = width; - gfx.final_screen_bitmap->height = height; - - gfx.final_screen_bitmap->surface = - SDL_SetVideoMode(width, height, video.depth, surface_flags); - - if (gfx.final_screen_bitmap->surface != NULL) - { - new_surface = - SDL_CreateRGBSurface(surface_flags, width, height, video.depth, 0,0,0, 0); - - if (new_surface == NULL) - Error(ERR_WARN, "SDL_CreateRGBSurface() failed: %s", SDL_GetError()); - -#if 0 - new_surface = gfx.final_screen_bitmap->surface; - gfx.final_screen_bitmap = NULL; -#endif - - } - else - { - Error(ERR_WARN, "SDL_SetVideoMode() failed: %s", SDL_GetError()); - } -#endif + SDLSetScreenProperties(); -#if defined(TARGET_SDL2) // store fullscreen state ("video.fullscreen_enabled" may not reflect this!) if (new_surface != NULL) fullscreen_enabled = fullscreen; -#endif if (backbuffer == NULL) backbuffer = CreateBitmapStruct(); @@ -805,59 +719,19 @@ boolean SDLSetVideoMode(boolean fullscreen) } } -#if defined(TARGET_SDL2) SDLRedrawWindow(); // map window -#endif - -#ifdef DEBUG -#if defined(PLATFORM_WIN32) - // experimental drag and drop code - - SDL_EventState(SDL_SYSWMEVENT, SDL_ENABLE); - - { - SDL_SysWMinfo wminfo; - HWND hwnd; - boolean wminfo_success = FALSE; - - SDL_VERSION(&wminfo.version); -#if defined(TARGET_SDL2) - if (sdl_window) - wminfo_success = SDL_GetWindowWMInfo(sdl_window, &wminfo); -#else - wminfo_success = (SDL_GetWMInfo(&wminfo) == 1); -#endif - - if (wminfo_success) - { -#if defined(TARGET_SDL2) - hwnd = wminfo.info.win.window; -#else - hwnd = wminfo.window; -#endif - - DragAcceptFiles(hwnd, TRUE); - } - } -#endif -#endif return success; } void SDLSetWindowTitle(void) { -#if defined(TARGET_SDL2) if (sdl_window == NULL) return; SDL_SetWindowTitle(sdl_window, program.window_title); -#else - SDL_WM_SetCaption(program.window_title, program.window_title); -#endif } -#if defined(TARGET_SDL2) void SDLSetWindowScaling(int window_scaling_percent) { if (sdl_window == NULL) @@ -940,17 +814,34 @@ void SDLSetWindowFullscreen(boolean fullscreen) void SDLSetDisplaySize(void) { - SDL_Rect display_bounds; + if (sdl_renderer != NULL) + { + int w, h; - SDL_GetDisplayBounds(0, &display_bounds); + SDL_GetRendererOutputSize(sdl_renderer, &w, &h); - video.display_width = display_bounds.w; - video.display_height = display_bounds.h; + video.display_width = w; + video.display_height = h; #if 0 - Error(ERR_DEBUG, "SDL real screen size: %d x %d", - video.display_width, video.display_height); + Debug("video", "SDL renderer size: %d x %d", + video.display_width, video.display_height); #endif + } + else + { + SDL_Rect display_bounds; + + SDL_GetDisplayBounds(0, &display_bounds); + + video.display_width = display_bounds.w; + video.display_height = display_bounds.h; + +#if 0 + Debug("video", "SDL display size: %d x %d", + video.display_width, video.display_height); +#endif + } } void SDLSetScreenSizeAndOffsets(int width, int height) @@ -978,7 +869,7 @@ void SDLSetScreenSizeAndOffsets(int width, int height) video.screen_yoffset = (video.screen_height - height) / 2; #if 0 - Error(ERR_DEBUG, "Changing screen from %dx%d to %dx%d (%.2f to %.2f)", + Debug("video", "Changing screen from %dx%d to %dx%d (%.2f to %.2f)", width, height, video.screen_width, video.screen_height, ratio_video, ratio_display); @@ -994,15 +885,13 @@ void SDLSetScreenSizeForRenderer(int width, int height) void SDLSetScreenProperties(void) { + SDLSetDisplaySize(); SDLSetScreenSizeAndOffsets(video.width, video.height); SDLSetScreenSizeForRenderer(video.screen_width, video.screen_height); } -#endif - void SDLSetScreenRenderingMode(char *screen_rendering_mode) { -#if defined(TARGET_SDL2) video.screen_rendering_mode = (strEqual(screen_rendering_mode, STR_SPECIAL_RENDERING_BITMAP) ? SPECIAL_RENDERING_BITMAP : @@ -1010,24 +899,29 @@ void SDLSetScreenRenderingMode(char *screen_rendering_mode) SPECIAL_RENDERING_TARGET: strEqual(screen_rendering_mode, STR_SPECIAL_RENDERING_DOUBLE) ? SPECIAL_RENDERING_DOUBLE : SPECIAL_RENDERING_OFF); -#else - video.screen_rendering_mode = SPECIAL_RENDERING_BITMAP; -#endif } void SDLSetScreenVsyncMode(char *vsync_mode) { -#if defined(TARGET_SDL2) - int interval = - (strEqual(vsync_mode, STR_VSYNC_MODE_NORMAL) ? VSYNC_MODE_NORMAL : - strEqual(vsync_mode, STR_VSYNC_MODE_ADAPTIVE) ? VSYNC_MODE_ADAPTIVE : - VSYNC_MODE_OFF); + // changing vsync mode without re-creating renderer only supported by OpenGL + if (!strPrefixLower((char *)SDLGetRendererName(), "opengl")) + return; + + int interval = VSYNC_MODE_STR_TO_INT(vsync_mode); int result = SDL_GL_SetSwapInterval(interval); // if adaptive vsync requested, but not supported, retry with normal vsync if (result == -1 && interval == VSYNC_MODE_ADAPTIVE) - SDL_GL_SetSwapInterval(VSYNC_MODE_NORMAL); -#endif + { + interval = VSYNC_MODE_NORMAL; + + result = SDL_GL_SetSwapInterval(interval); + } + + if (result == -1) + interval = VSYNC_MODE_OFF; + + video.vsync_mode = interval; } void SDLRedrawWindow(void) @@ -1045,7 +939,7 @@ void SDLCreateBitmapContent(Bitmap *bitmap, int width, int height, SDL_CreateRGBSurface(SURFACE_FLAGS, width, height, depth, 0,0,0, 0); if (surface == NULL) - Error(ERR_EXIT, "SDL_CreateRGBSurface() failed: %s", SDL_GetError()); + Fail("SDL_CreateRGBSurface() failed: %s", SDL_GetError()); SDLSetNativeSurface(&surface); @@ -1062,7 +956,6 @@ void SDLFreeBitmapPointers(Bitmap *bitmap) bitmap->surface = NULL; bitmap->surface_masked = NULL; -#if defined(TARGET_SDL2) if (bitmap->texture) SDL_DestroyTexture(bitmap->texture); if (bitmap->texture_masked) @@ -1070,7 +963,6 @@ void SDLFreeBitmapPointers(Bitmap *bitmap) bitmap->texture = NULL; bitmap->texture_masked = NULL; -#endif } void SDLCopyArea(Bitmap *src_bitmap, Bitmap *dst_bitmap, @@ -1104,7 +996,6 @@ void SDLBlitTexture(Bitmap *bitmap, int src_x, int src_y, int width, int height, int dst_x, int dst_y, int mask_mode) { -#if defined(TARGET_SDL2) SDL_Texture *texture; SDL_Rect src_rect; SDL_Rect dst_rect; @@ -1126,7 +1017,6 @@ void SDLBlitTexture(Bitmap *bitmap, dst_rect.h = height; SDL_RenderCopy(sdl_renderer, texture, &src_rect, &dst_rect); -#endif } void SDLFillRectangle(Bitmap *dst_bitmap, int x, int y, int width, int height, @@ -1218,6 +1108,17 @@ void SDLFadeRectangle(int x, int y, int width, int height, time_current = SDL_GetTicks(); + if (fade_delay <= 0) + { + // immediately draw final target frame without delay + fade_mode &= (FADE_MODE_FADE | FADE_MODE_TRANSFORM); + fade_delay = 1; + time_current -= 1; + + // when fading without delay, also skip post delay + post_delay = 0; + } + if (fade_mode == FADE_MODE_MELT) { boolean done = FALSE; @@ -1996,11 +1897,9 @@ void SDLPutPixel(Bitmap *dst_bitmap, int x, int y, Pixel pixel) } -/* - ----------------------------------------------------------------------------- - quick (no, it's slow) and dirty hack to "invert" rectangle inside SDL surface - ----------------------------------------------------------------------------- -*/ +// ---------------------------------------------------------------------------- +// quick (no, it's slow) and dirty hack to "invert" rectangle inside SDL surface +// ---------------------------------------------------------------------------- void SDLInvertArea(Bitmap *bitmap, int src_x, int src_y, int width, int height, Uint32 color) @@ -2043,13 +1942,11 @@ void SDLCopyInverseMasked(Bitmap *src_bitmap, Bitmap *dst_bitmap, // http://www.ferzkopp.net/Software/SDL_gfx-2.0/index.html // ============================================================================ -/* - ----------------------------------------------------------------------------- - 32 bit zoomer - - zoomes 32bit RGBA/ABGR 'src' surface to 'dst' surface. - ----------------------------------------------------------------------------- -*/ +// ---------------------------------------------------------------------------- +// 32 bit zoomer +// +// zoomes 32bit RGBA/ABGR 'src' surface to 'dst' surface. +// ---------------------------------------------------------------------------- typedef struct { @@ -2175,13 +2072,11 @@ static int zoomSurfaceRGBA(SDL_Surface *src, SDL_Surface *dst) return 0; } -/* - ----------------------------------------------------------------------------- - 8 bit zoomer - - zoomes 8 bit palette/Y 'src' surface to 'dst' surface - ----------------------------------------------------------------------------- -*/ +// ---------------------------------------------------------------------------- +// 8 bit zoomer +// +// zoomes 8 bit palette/Y 'src' surface to 'dst' surface +// ---------------------------------------------------------------------------- static int zoomSurfaceY(SDL_Surface * src, SDL_Surface * dst) { @@ -2272,16 +2167,14 @@ static int zoomSurfaceY(SDL_Surface * src, SDL_Surface * dst) return 0; } -/* - ----------------------------------------------------------------------------- - zoomSurface() - - Zooms a 32bit or 8bit 'src' surface to newly created 'dst' surface. - 'zoomx' and 'zoomy' are scaling factors for width and height. - If the surface is not 8bit or 32bit RGBA/ABGR it will be converted - into a 32bit RGBA format on the fly. - ----------------------------------------------------------------------------- -*/ +// ---------------------------------------------------------------------------- +// zoomSurface() +// +// Zooms a 32bit or 8bit 'src' surface to newly created 'dst' surface. +// 'zoomx' and 'zoomy' are scaling factors for width and height. +// If the surface is not 8bit or 32bit RGBA/ABGR it will be converted +// into a 32bit RGBA format on the fly. +// ---------------------------------------------------------------------------- static SDL_Surface *zoomSurface(SDL_Surface *src, int dst_width, int dst_height) { @@ -2370,7 +2263,7 @@ static SDL_Surface *SDLGetOpaqueSurface(SDL_Surface *surface) return NULL; if ((new_surface = SDLGetNativeSurface(surface)) == NULL) - Error(ERR_EXIT, "SDLGetNativeSurface() failed"); + Fail("SDLGetNativeSurface() failed"); // remove alpha channel from native non-transparent surface, if defined SDLSetAlpha(new_surface, FALSE, 0); @@ -2401,8 +2294,7 @@ Bitmap *SDLZoomBitmap(Bitmap *src_bitmap, int dst_width, int dst_height) // set color key for zoomed surface from source surface, if defined if (SDLHasColorKey(src_surface)) - SDL_SetColorKey(dst_surface, SET_TRANSPARENT_PIXEL, - SDLGetColorKey(src_surface)); + SDLCopyColorKey(src_surface, dst_surface); // create native non-transparent surface for opaque blitting dst_bitmap->surface = SDLGetOpaqueSurface(dst_surface); @@ -2437,7 +2329,7 @@ Bitmap *SDLLoadImage(char *filename) // load image to temporary surface if ((sdl_image_tmp = IMG_Load(filename)) == NULL) - Error(ERR_EXIT, "IMG_Load() failed: %s", SDL_GetError()); + Fail("IMG_Load('%s') failed: %s", getBaseNamePtr(filename), SDL_GetError()); print_timestamp_time("IMG_Load"); @@ -2445,7 +2337,7 @@ Bitmap *SDLLoadImage(char *filename) // create native non-transparent surface for current image if ((new_bitmap->surface = SDLGetOpaqueSurface(sdl_image_tmp)) == NULL) - Error(ERR_EXIT, "SDLGetOpaqueSurface() failed"); + Fail("SDLGetOpaqueSurface() failed"); print_timestamp_time("SDLGetNativeSurface (opaque)"); @@ -2459,7 +2351,7 @@ Bitmap *SDLLoadImage(char *filename) // create native transparent surface for current image if ((new_bitmap->surface_masked = SDLGetNativeSurface(sdl_image_tmp)) == NULL) - Error(ERR_EXIT, "SDLGetNativeSurface() failed"); + Fail("SDLGetNativeSurface() failed"); print_timestamp_time("SDLGetNativeSurface (masked)"); @@ -2523,14 +2415,10 @@ void SDLOpenAudio(void) if (program.headless) return; -#if !defined(TARGET_SDL2) - if (!strEqual(setup.system.sdl_audiodriver, ARG_DEFAULT)) - SDL_putenv(getStringCat2("SDL_AUDIODRIVER=", setup.system.sdl_audiodriver)); -#endif - if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) { - Error(ERR_WARN, "SDL_InitSubSystem() failed: %s", SDL_GetError()); + Warn("SDL_InitSubSystem() failed: %s", SDL_GetError()); + return; } @@ -2538,7 +2426,8 @@ void SDLOpenAudio(void) AUDIO_NUM_CHANNELS_STEREO, setup.system.audio_fragment_size) < 0) { - Error(ERR_WARN, "Mix_OpenAudio() failed: %s", SDL_GetError()); + Warn("Mix_OpenAudio() failed: %s", SDL_GetError()); + return; } @@ -2574,50 +2463,25 @@ void SDLWaitEvent(Event *event) SDL_WaitEvent(event); } -void SDLHandleWindowManagerEvent(Event *event) +void SDLCorrectRawMousePosition(int *x, int *y) { -#ifdef DEBUG -#if defined(PLATFORM_WIN32) - // experimental drag and drop code - - SDL_SysWMEvent *syswmevent = (SDL_SysWMEvent *)event; - SDL_SysWMmsg *syswmmsg = (SDL_SysWMmsg *)(syswmevent->msg); - -#if defined(TARGET_SDL2) - if (syswmmsg->msg.win.msg == WM_DROPFILES) -#else - if (syswmmsg->msg == WM_DROPFILES) -#endif - { -#if defined(TARGET_SDL2) - HDROP hdrop = (HDROP)syswmmsg->msg.win.wParam; -#else - HDROP hdrop = (HDROP)syswmmsg->wParam; -#endif - int i, num_files; - - printf("::: SDL_SYSWMEVENT:\n"); + if (sdl_renderer == NULL) + return; - num_files = DragQueryFile(hdrop, 0xffffffff, NULL, 0); + // this corrects the raw mouse position for logical screen size within event + // filters (correction done later by SDL library when handling mouse events) - for (i = 0; i < num_files; i++) - { - int buffer_len = DragQueryFile(hdrop, i, NULL, 0); - char buffer[buffer_len + 1]; + SDL_Rect viewport; + float scale_x, scale_y; - DragQueryFile(hdrop, i, buffer, buffer_len + 1); + SDL_RenderGetViewport(sdl_renderer, &viewport); + SDL_RenderGetScale(sdl_renderer, &scale_x, &scale_y); - printf("::: - '%s'\n", buffer); - } + *x = (int)(*x / scale_x); + *y = (int)(*y / scale_y); -#if defined(TARGET_SDL2) - DragFinish((HDROP)syswmmsg->msg.win.wParam); -#else - DragFinish((HDROP)syswmmsg->wParam); -#endif - } -#endif -#endif + *x -= viewport.x; + *y -= viewport.y; } @@ -2625,11 +2489,7 @@ void SDLHandleWindowManagerEvent(Event *event) // joystick functions // ============================================================================ -#if defined(TARGET_SDL2) static void *sdl_joystick[MAX_PLAYERS]; // game controller or joystick -#else -static SDL_Joystick *sdl_joystick[MAX_PLAYERS]; // only joysticks supported -#endif static int sdl_js_axis_raw[MAX_PLAYERS][2]; static int sdl_js_axis[MAX_PLAYERS][2]; static int sdl_js_button[MAX_PLAYERS][2]; @@ -2655,25 +2515,17 @@ boolean SDLOpenJoystick(int nr) if (nr < 0 || nr >= MAX_PLAYERS) return FALSE; -#if defined(TARGET_SDL2) sdl_is_controller[nr] = SDL_IsGameController(nr); -#else - sdl_is_controller[nr] = FALSE; -#endif #if DEBUG_JOYSTICKS - Error(ERR_DEBUG, "opening joystick %d (%s)", + Debug("joystick", "opening joystick %d (%s)", nr, (sdl_is_controller[nr] ? "game controller" : "joystick")); #endif -#if defined(TARGET_SDL2) if (sdl_is_controller[nr]) sdl_joystick[nr] = SDL_GameControllerOpen(nr); else sdl_joystick[nr] = SDL_JoystickOpen(nr); -#else - sdl_joystick[nr] = SDL_JoystickOpen(nr); -#endif return (sdl_joystick[nr] != NULL); } @@ -2684,17 +2536,13 @@ void SDLCloseJoystick(int nr) return; #if DEBUG_JOYSTICKS - Error(ERR_DEBUG, "closing joystick %d", nr); + Debug("joystick", "closing joystick %d", nr); #endif -#if defined(TARGET_SDL2) if (sdl_is_controller[nr]) SDL_GameControllerClose(sdl_joystick[nr]); else SDL_JoystickClose(sdl_joystick[nr]); -#else - SDL_JoystickClose(sdl_joystick[nr]); -#endif sdl_joystick[nr] = NULL; } @@ -2704,23 +2552,15 @@ boolean SDLCheckJoystickOpened(int nr) if (nr < 0 || nr >= MAX_PLAYERS) return FALSE; -#if defined(TARGET_SDL2) return (sdl_joystick[nr] != NULL ? TRUE : FALSE); -#else - return (SDL_JoystickOpened(nr) ? TRUE : FALSE); -#endif } static void setJoystickAxis(int nr, int axis_id_raw, int axis_value) { -#if defined(TARGET_SDL2) int axis_id = (axis_id_raw == SDL_CONTROLLER_AXIS_LEFTX || axis_id_raw == SDL_CONTROLLER_AXIS_RIGHTX ? 0 : axis_id_raw == SDL_CONTROLLER_AXIS_LEFTY || axis_id_raw == SDL_CONTROLLER_AXIS_RIGHTY ? 1 : -1); -#else - int axis_id = axis_id_raw % 2; -#endif if (nr < 0 || nr >= MAX_PLAYERS) return; @@ -2739,7 +2579,6 @@ static void setJoystickAxis(int nr, int axis_id_raw, int axis_value) static void setJoystickButton(int nr, int button_id_raw, int button_state) { -#if defined(TARGET_SDL2) int button_id = (button_id_raw == SDL_CONTROLLER_BUTTON_A || button_id_raw == SDL_CONTROLLER_BUTTON_X || button_id_raw == SDL_CONTROLLER_BUTTON_LEFTSHOULDER || @@ -2764,9 +2603,6 @@ static void setJoystickButton(int nr, int button_id_raw, int button_state) button_id_raw == SDL_CONTROLLER_BUTTON_DPAD_UP || button_id_raw == SDL_CONTROLLER_BUTTON_DPAD_DOWN) sdl_js_axis_raw[nr][0] = sdl_js_axis_raw[nr][1] = -1; -#else - int button_id = button_id_raw % 2; -#endif if (nr < 0 || nr >= MAX_PLAYERS) return; @@ -2779,12 +2615,14 @@ static void setJoystickButton(int nr, int button_id_raw, int button_state) void HandleJoystickEvent(Event *event) { - switch(event->type) + // when using joystick, disable overlay touch buttons + runtime.uses_touch_device = FALSE; + + switch (event->type) { -#if defined(TARGET_SDL2) case SDL_CONTROLLERDEVICEADDED: #if DEBUG_JOYSTICKS - Error(ERR_DEBUG, "SDL_CONTROLLERDEVICEADDED: device %d added", + Debug("joystick", "SDL_CONTROLLERDEVICEADDED: device %d added", event->cdevice.which); #endif InitJoysticks(); @@ -2792,7 +2630,7 @@ void HandleJoystickEvent(Event *event) case SDL_CONTROLLERDEVICEREMOVED: #if DEBUG_JOYSTICKS - Error(ERR_DEBUG, "SDL_CONTROLLERDEVICEREMOVED: device %d removed", + Debug("joystick", "SDL_CONTROLLERDEVICEREMOVED: device %d removed", event->cdevice.which); #endif InitJoysticks(); @@ -2800,7 +2638,7 @@ void HandleJoystickEvent(Event *event) case SDL_CONTROLLERAXISMOTION: #if DEBUG_JOYSTICKS - Error(ERR_DEBUG, "SDL_CONTROLLERAXISMOTION: device %d, axis %d: %d", + Debug("joystick", "SDL_CONTROLLERAXISMOTION: device %d, axis %d: %d", event->caxis.which, event->caxis.axis, event->caxis.value); #endif setJoystickAxis(event->caxis.which, @@ -2810,7 +2648,7 @@ void HandleJoystickEvent(Event *event) case SDL_CONTROLLERBUTTONDOWN: #if DEBUG_JOYSTICKS - Error(ERR_DEBUG, "SDL_CONTROLLERBUTTONDOWN: device %d, button %d", + Debug("joystick", "SDL_CONTROLLERBUTTONDOWN: device %d, button %d", event->cbutton.which, event->cbutton.button); #endif setJoystickButton(event->cbutton.which, @@ -2820,21 +2658,20 @@ void HandleJoystickEvent(Event *event) case SDL_CONTROLLERBUTTONUP: #if DEBUG_JOYSTICKS - Error(ERR_DEBUG, "SDL_CONTROLLERBUTTONUP: device %d, button %d", + Debug("joystick", "SDL_CONTROLLERBUTTONUP: device %d, button %d", event->cbutton.which, event->cbutton.button); #endif setJoystickButton(event->cbutton.which, event->cbutton.button, FALSE); break; -#endif case SDL_JOYAXISMOTION: if (sdl_is_controller[event->jaxis.which]) break; #if DEBUG_JOYSTICKS - Error(ERR_DEBUG, "SDL_JOYAXISMOTION: device %d, axis %d: %d", + Debug("joystick", "SDL_JOYAXISMOTION: device %d, axis %d: %d", event->jaxis.which, event->jaxis.axis, event->jaxis.value); #endif if (event->jaxis.axis < 4) @@ -2848,7 +2685,7 @@ void HandleJoystickEvent(Event *event) break; #if DEBUG_JOYSTICKS - Error(ERR_DEBUG, "SDL_JOYBUTTONDOWN: device %d, button %d", + Debug("joystick", "SDL_JOYBUTTONDOWN: device %d, button %d", event->jbutton.which, event->jbutton.button); #endif if (event->jbutton.button < 4) @@ -2862,7 +2699,7 @@ void HandleJoystickEvent(Event *event) break; #if DEBUG_JOYSTICKS - Error(ERR_DEBUG, "SDL_JOYBUTTONUP: device %d, button %d", + Debug("joystick", "SDL_JOYBUTTONUP: device %d, button %d", event->jbutton.which, event->jbutton.button); #endif if (event->jbutton.button < 4) @@ -2880,40 +2717,31 @@ void SDLInitJoysticks(void) { static boolean sdl_joystick_subsystem_initialized = FALSE; boolean print_warning = !sdl_joystick_subsystem_initialized; -#if defined(TARGET_SDL2) char *mappings_file_base = getPath2(options.conf_directory, GAMECONTROLLER_BASENAME); char *mappings_file_user = getPath2(getUserGameDataDir(), GAMECONTROLLER_BASENAME); int num_mappings; -#endif int i; if (!sdl_joystick_subsystem_initialized) { sdl_joystick_subsystem_initialized = TRUE; -#if defined(TARGET_SDL2) SDL_SetHint(SDL_HINT_ACCELEROMETER_AS_JOYSTICK, "0"); if (SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER) < 0) -#else - if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) < 0) -#endif - { - Error(ERR_EXIT, "SDL_Init() failed: %s", SDL_GetError()); - return; - } + Fail("SDL_Init() failed: %s", SDL_GetError()); -#if defined(TARGET_SDL2) num_mappings = SDL_GameControllerAddMappingsFromFile(mappings_file_base); // the included game controller base mappings should always be found if (num_mappings == -1) - Error(ERR_WARN, "no game controller base mappings found"); + Warn("no game controller base mappings found"); #if DEBUG_JOYSTICKS else - Error(ERR_INFO, "%d game controller base mapping(s) added", num_mappings); + Debug("joystick", "%d game controller base mapping(s) added", + num_mappings); #endif num_mappings = SDL_GameControllerAddMappingsFromFile(mappings_file_user); @@ -2921,11 +2749,12 @@ void SDLInitJoysticks(void) #if DEBUG_JOYSTICKS // the personal game controller user mappings may or may not be found if (num_mappings == -1) - Error(ERR_WARN, "no game controller user mappings found"); + Warn("no game controller user mappings found"); else - Error(ERR_INFO, "%d game controller user mapping(s) added", num_mappings); + Debug("joystick", , "%d game controller user mapping(s) added", + num_mappings); - Error(ERR_INFO, "%d joystick(s) found:", SDL_NumJoysticks()); + Debug("joystick", "%d joystick(s) found:", SDL_NumJoysticks()); #endif checked_free(mappings_file_base); @@ -2947,10 +2776,9 @@ void SDLInitJoysticks(void) type = "joystick"; } - Error(ERR_INFO, "- joystick %d (%s): '%s'", + Debug("joystick", "- joystick %d (%s): '%s'", i, type, (name ? name : "(Unknown)")); } -#endif #endif } @@ -2964,7 +2792,7 @@ void SDLInitJoysticks(void) if (joystick_nr >= SDL_NumJoysticks()) { if (setup.input[i].use_joystick && print_warning) - Error(ERR_WARN, "cannot find joystick %d", joystick_nr); + Warn("cannot find joystick %d", joystick_nr); joystick_nr = -1; } @@ -2983,7 +2811,7 @@ void SDLInitJoysticks(void) if (SDLOpenJoystick(i)) joystick.status = JOYSTICK_ACTIVATED; else if (print_warning) - Error(ERR_WARN, "cannot open joystick %d", i); + Warn("cannot open joystick %d", i); } SDLClearJoystickState(); @@ -3100,7 +2928,10 @@ static void DrawTouchInputOverlay_ShowGridButtons(int alpha) continue; if (grid_button == overlay.grid_button_highlight) - alpha_draw = alpha_highlight; + { + draw_outlined = FALSE; + alpha_draw = MIN((float)alpha_highlight * 1.5, SDL_ALPHA_OPAQUE); + } if (draw_pressed && overlay.grid_button_action & grid_button_action) { @@ -3181,12 +3012,8 @@ static void DrawTouchInputOverlay_ShowGridButtons(int alpha) static void DrawTouchInputOverlay(void) { - static SDL_Texture *texture = NULL; - static boolean initialized = FALSE; static boolean deactivated = TRUE; static boolean show_grid = FALSE; - static int width = 0, height = 0; - static int alpha_last = -1; static int alpha = 0; int alpha_max = ALPHA_FROM_TRANSPARENCY(setup.touch.transparency); int alpha_step = ALPHA_FADING_STEPSIZE(alpha_max); @@ -3219,72 +3046,10 @@ static void DrawTouchInputOverlay(void) DrawTouchInputOverlay_ShowGrid(alpha); DrawTouchInputOverlay_ShowGridButtons(alpha); +} - return; - - - // !!! VIRTUAL BUTTONS FROM IMAGE FILE NOT USED ANYMORE !!! - - if (!initialized) - { - char *basename = "overlay/VirtualButtons.png"; - char *filename = getCustomImageFilename(basename); - - if (filename == NULL) - Error(ERR_EXIT, "LoadCustomImage(): cannot find file '%s'", basename); - - SDL_Surface *surface; - - if ((surface = IMG_Load(filename)) == NULL) - Error(ERR_EXIT, "IMG_Load() failed: %s", SDL_GetError()); - - width = surface->w; - height = surface->h; - - // set black pixel to transparent if no alpha channel / transparent color - if (!SDLHasAlpha(surface) && - !SDLHasColorKey(surface)) - SDL_SetColorKey(surface, SET_TRANSPARENT_PIXEL, - SDL_MapRGB(surface->format, 0x00, 0x00, 0x00)); - - if ((texture = SDLCreateTextureFromSurface(surface)) == NULL) - Error(ERR_EXIT, "SDLCreateTextureFromSurface() failed"); - - SDL_FreeSurface(surface); - - SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND); - - initialized = TRUE; - } - - if (alpha != alpha_last) - SDL_SetTextureAlphaMod(texture, alpha); - - alpha_last = alpha; - - float ratio_overlay = (float) width / height; - float ratio_screen = (float) video.screen_width / video.screen_height; - int width_scaled, height_scaled; - int xpos, ypos; - - if (ratio_overlay > ratio_screen) - { - width_scaled = video.screen_width; - height_scaled = video.screen_height * ratio_screen / ratio_overlay; - xpos = 0; - ypos = video.screen_height - height_scaled; - } - else - { - width_scaled = video.screen_width * ratio_overlay / ratio_screen; - height_scaled = video.screen_height; - xpos = (video.screen_width - width_scaled) / 2; - ypos = 0; - } - - SDL_Rect src_rect = { 0, 0, width, height }; - SDL_Rect dst_rect = { xpos, ypos, width_scaled, height_scaled }; - - SDL_RenderCopy(sdl_renderer, texture, &src_rect, &dst_rect); +static void DrawTouchGadgetsOverlay(void) +{ + DrawGadgets_OverlayTouchButtons(); } #endif