X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Flibgame%2Fsdl.c;h=e275149fea202b723e4348394568394fc294f0d7;hb=71c4b8d626b4a731a72840facb6bd548c7e33da9;hp=661bf6fb7546aeb8611b974ae74b478e50a3c812;hpb=bf9e47bb97f16c998644758a383209fa4d4fc87b;p=rocksndiamonds.git diff --git a/src/libgame/sdl.c b/src/libgame/sdl.c index 661bf6fb..e275149f 100644 --- a/src/libgame/sdl.c +++ b/src/libgame/sdl.c @@ -37,6 +37,11 @@ static boolean limit_screen_updates = FALSE; /* functions from SGE library */ 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(); +#endif + void SDLLimitScreenUpdates(boolean enable) { limit_screen_updates = enable; @@ -201,6 +206,12 @@ static void UpdateScreenExt(SDL_Rect *rect, boolean with_frame_delay) SDL_SetRenderTarget(sdl_renderer, NULL); SDL_RenderCopy(sdl_renderer, sdl_texture_target, src_rect2, dst_rect2); } + +#if defined(USE_TOUCH_INPUT_OVERLAY) + // draw overlay graphics for touch device input, if needed + DrawTouchInputOverlay(); +#endif + #endif // global synchronization point of the game to align video frame delay @@ -428,6 +439,9 @@ boolean SDLSetNativeSurface(SDL_Surface **surface) #if defined(TARGET_SDL2) static SDL_Texture *SDLCreateTextureFromSurface(SDL_Surface *surface) { + if (program.headless) + return NULL; + SDL_Texture *texture = SDL_CreateTextureFromSurface(sdl_renderer, surface); if (texture == NULL) @@ -491,8 +505,11 @@ void SDLInitVideoDisplay(void) #endif } -void SDLInitVideoBuffer(boolean fullscreen) +inline static void SDLInitVideoBuffer_VideoBuffer(boolean fullscreen) { + if (program.headless) + return; + video.window_scaling_percent = setup.window_scaling_percent; video.window_scaling_quality = setup.window_scaling_quality; @@ -520,7 +537,10 @@ void SDLInitVideoBuffer(boolean fullscreen) #else SDL_WM_SetCaption(program.window_title, program.window_title); #endif +} +inline static void SDLInitVideoBuffer_DrawBuffer() +{ /* SDL cannot directly draw to the visible video framebuffer like X11, but always uses a backbuffer, which is then blitted to the visible video framebuffer with 'SDL_UpdateRect' (or replaced with the current @@ -536,6 +556,16 @@ void SDLInitVideoBuffer(boolean fullscreen) /* create additional (symbolic) buffer for double-buffering */ ReCreateBitmap(&window, video.width, video.height); + + /* create dummy drawing buffer for headless mode, if needed */ + if (program.headless) + ReCreateBitmap(&backbuffer, video.width, video.height); +} + +void SDLInitVideoBuffer(boolean fullscreen) +{ + SDLInitVideoBuffer_VideoBuffer(fullscreen); + SDLInitVideoBuffer_DrawBuffer(); } static boolean SDLCreateScreen(boolean fullscreen) @@ -559,10 +589,10 @@ static boolean SDLCreateScreen(boolean fullscreen) it will crash if flags are *not* set to SDL_RENDERER_SOFTWARE (because it will try to use accelerated graphics and apparently fails miserably) */ int renderer_flags = SDL_RENDERER_SOFTWARE; -#endif #endif SDLSetScreenSizeAndOffsets(video.width, video.height); +#endif int width = video.width; int height = video.height; @@ -910,7 +940,7 @@ void SDLSetScreenSizeAndOffsets(int width, int height) video.screen_xoffset = 0; video.screen_yoffset = 0; -#if defined(PLATFORM_ANDROID) +#if defined(USE_COMPLETE_DISPLAY) float ratio_video = (float) width / height; float ratio_display = (float) video.display_width / video.display_height; @@ -972,6 +1002,9 @@ void SDLRedrawWindow() void SDLCreateBitmapContent(Bitmap *bitmap, int width, int height, int depth) { + if (program.headless) + return; + SDL_Surface *surface = SDL_CreateRGBSurface(SURFACE_FLAGS, width, height, depth, 0,0,0, 0); @@ -2356,6 +2389,14 @@ Bitmap *SDLLoadImage(char *filename) Bitmap *new_bitmap = CreateBitmapStruct(); SDL_Surface *sdl_image_tmp; + if (program.headless) + { + /* prevent sanity check warnings at later stage */ + new_bitmap->width = new_bitmap->height = 1; + + return new_bitmap; + } + print_timestamp_init("SDLLoadImage"); print_timestamp_time(getBaseNamePtr(filename)); @@ -2445,6 +2486,9 @@ void SDLSetMouseCursor(struct MouseCursorInfo *cursor_info) 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)); @@ -2678,3 +2722,98 @@ boolean SDLReadJoystick(int nr, int *x, int *y, boolean *b1, boolean *b2) return TRUE; } + +#if defined(USE_TOUCH_INPUT_OVERLAY) +static void DrawTouchInputOverlay() +{ + static SDL_Texture *texture = NULL; + static boolean initialized = FALSE; + static boolean deactivated = TRUE; + static int width = 0, height = 0; + static int alpha_max = SDL_ALPHA_OPAQUE / 2; + static int alpha_step = 5; + static int alpha_last = 0; + static int alpha = 0; + + if (!overlay.active && deactivated) + return; + + if (overlay.active) + { + if (alpha < alpha_max) + alpha = MIN(alpha + alpha_step, alpha_max); + + deactivated = FALSE; + } + else + { + alpha = MAX(0, alpha - alpha_step); + + if (alpha == 0) + deactivated = TRUE; + } + + 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); + SDL_SetTextureAlphaMod(texture, alpha_max); + + 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); +} +#endif