X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Flibgame%2Fsdl.c;h=ece4e3f7c0b7beb98a1608a01eead8ec3b671ab3;hb=a99a1803e5097bc598b4c6f73259715da148ab27;hp=5b43d6c8e54d48f62a8aad41750539a7bb8863c0;hpb=5d1f7067db786914303167fd036d18424dce413f;p=rocksndiamonds.git diff --git a/src/libgame/sdl.c b/src/libgame/sdl.c index 5b43d6c8..ece4e3f7 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 @@ -39,6 +40,7 @@ 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(void); +static void DrawTouchGadgetsOverlay(void); #endif void SDLLimitScreenUpdates(boolean enable) @@ -82,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; @@ -212,6 +214,9 @@ 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(); + + // draw overlay gadgets for touch device input, if needed + DrawTouchGadgetsOverlay(); #endif // global synchronization point of the game to align video frame delay @@ -261,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; } @@ -325,6 +330,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; @@ -348,6 +362,11 @@ SDL_Surface *SDLGetNativeSurface(SDL_Surface *surface) if (new_surface == NULL) Error(ERR_EXIT, "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)) + SDL_SetColorKey(new_surface, SET_TRANSPARENT_PIXEL, + SDLGetColorKey(surface)); + return new_surface; } @@ -418,6 +437,10 @@ void SDLFreeBitmapTextures(Bitmap *bitmap) void SDLInitVideoDisplay(void) { + // 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()); @@ -487,11 +510,19 @@ static boolean SDLCreateScreen(boolean fullscreen) { SDL_Surface *new_surface = NULL; - int surface_flags_window = SURFACE_FLAGS | SDL_WINDOW_RESIZABLE; + int surface_flags_window = SURFACE_FLAGS; int surface_flags_fullscreen = SURFACE_FLAGS | SDL_WINDOW_FULLSCREEN_DESKTOP; #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, @@ -500,8 +531,6 @@ static boolean SDLCreateScreen(boolean fullscreen) int renderer_flags = SDL_RENDERER_SOFTWARE; #endif - SDLSetScreenSizeAndOffsets(video.width, video.height); - int width = video.width; int height = video.height; int screen_width = video.screen_width; @@ -563,10 +592,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, @@ -586,23 +615,25 @@ 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()); } + SDLSetScreenProperties(); + // store fullscreen state ("video.fullscreen_enabled" may not reflect this!) if (new_surface != NULL) fullscreen_enabled = fullscreen; @@ -757,17 +788,34 @@ void SDLSetWindowFullscreen(boolean fullscreen) void SDLSetDisplaySize(void) { - SDL_Rect display_bounds; + if (sdl_renderer != NULL) + { + int w, h; + + SDL_GetRendererOutputSize(sdl_renderer, &w, &h); + + video.display_width = w; + video.display_height = h; + +#if 0 + 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); + SDL_GetDisplayBounds(0, &display_bounds); - video.display_width = display_bounds.w; - video.display_height = display_bounds.h; + video.display_width = display_bounds.w; + video.display_height = display_bounds.h; #if 0 - Error(ERR_DEBUG, "SDL real screen size: %d x %d", - video.display_width, video.display_height); + Debug("video", "SDL display size: %d x %d", + video.display_width, video.display_height); #endif + } } void SDLSetScreenSizeAndOffsets(int width, int height) @@ -795,7 +843,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); @@ -811,6 +859,7 @@ void SDLSetScreenSizeForRenderer(int width, int height) void SDLSetScreenProperties(void) { + SDLSetDisplaySize(); SDLSetScreenSizeAndOffsets(video.width, video.height); SDLSetScreenSizeForRenderer(video.screen_width, video.screen_height); } @@ -828,15 +877,25 @@ void SDLSetScreenRenderingMode(char *screen_rendering_mode) void SDLSetScreenVsyncMode(char *vsync_mode) { - 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); + { + interval = VSYNC_MODE_NORMAL; + + result = SDL_GL_SetSwapInterval(interval); + } + + if (result == -1) + interval = VSYNC_MODE_OFF; + + video.vsync_mode = interval; } void SDLRedrawWindow(void) @@ -1023,6 +1082,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; @@ -2234,7 +2304,8 @@ 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()); + Error(ERR_EXIT, "IMG_Load('%s') failed: %s", getBaseNamePtr(filename), + SDL_GetError()); print_timestamp_time("IMG_Load"); @@ -2322,7 +2393,8 @@ void SDLOpenAudio(void) if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) { - Error(ERR_WARN, "SDL_InitSubSystem() failed: %s", SDL_GetError()); + Warn("SDL_InitSubSystem() failed: %s", SDL_GetError()); + return; } @@ -2330,7 +2402,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; } @@ -2421,7 +2494,7 @@ boolean SDLOpenJoystick(int nr) sdl_is_controller[nr] = SDL_IsGameController(nr); #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 @@ -2439,7 +2512,7 @@ void SDLCloseJoystick(int nr) return; #if DEBUG_JOYSTICKS - Error(ERR_DEBUG, "closing joystick %d", nr); + Debug("joystick", "closing joystick %d", nr); #endif if (sdl_is_controller[nr]) @@ -2518,11 +2591,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) { 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(); @@ -2530,7 +2606,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(); @@ -2538,7 +2614,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, @@ -2548,7 +2624,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, @@ -2558,7 +2634,7 @@ 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, @@ -2571,7 +2647,7 @@ void HandleJoystickEvent(Event *event) 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) @@ -2585,7 +2661,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) @@ -2599,7 +2675,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) @@ -2633,6 +2709,7 @@ void SDLInitJoysticks(void) if (SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER) < 0) { Error(ERR_EXIT, "SDL_Init() failed: %s", SDL_GetError()); + return; } @@ -2640,10 +2717,11 @@ void SDLInitJoysticks(void) // 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); @@ -2651,11 +2729,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); @@ -2677,7 +2756,7 @@ void SDLInitJoysticks(void) type = "joystick"; } - Error(ERR_INFO, "- joystick %d (%s): '%s'", + Debug("joystick", "- joystick %d (%s): '%s'", i, type, (name ? name : "(Unknown)")); } #endif @@ -2693,7 +2772,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; } @@ -2712,7 +2791,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(); @@ -2948,4 +3027,9 @@ static void DrawTouchInputOverlay(void) DrawTouchInputOverlay_ShowGridButtons(alpha); } + +static void DrawTouchGadgetsOverlay(void) +{ + DrawGadgets_OverlayTouchButtons(); +} #endif