static int fullscreen_yoffset;
static int video_xoffset;
static int video_yoffset;
+static boolean limit_screen_updates = FALSE;
+
/* functions from SGE library */
void sge_Line(SDL_Surface *, Sint16, Sint16, Sint16, Sint16, Uint32);
-#if defined(TARGET_SDL2)
+void SDLLimitScreenUpdates(boolean enable)
+{
+ limit_screen_updates = enable;
+}
+
static void UpdateScreen(SDL_Rect *rect)
{
+ static unsigned int update_screen_delay = 0;
+ unsigned int update_screen_delay_value = 20; /* (milliseconds) */
+
+#if 1
+ if (limit_screen_updates &&
+ !DelayReached(&update_screen_delay, update_screen_delay_value))
+ return;
+
+ LimitScreenUpdates(FALSE);
+#endif
+
+#if defined(TARGET_SDL2)
#if USE_RENDERER
SDL_Surface *screen = backbuffer->surface;
else
SDL_UpdateWindowSurface(sdl_window);
#endif
-}
+
+#else // TARGET_SDL
+ if (rect)
+ SDL_UpdateRects(backbuffer->surface, 1, rect);
+ else
+ SDL_UpdateRect(backbuffer->surface, 0, 0, 0, 0);
#endif
+}
static void setFullscreenParameters(char *fullscreen_mode_string)
{
}
#if defined(TARGET_SDL2)
+
+static boolean equalSDLPixelFormat(SDL_PixelFormat *format1,
+ SDL_PixelFormat *format2)
+{
+ return (format1->format == format2->format &&
+ format1->BitsPerPixel == format2->BitsPerPixel &&
+ format1->BytesPerPixel == format2->BytesPerPixel &&
+ format1->Rmask == format2->Rmask &&
+ format1->Gmask == format2->Gmask &&
+ format1->Bmask == format2->Bmask &&
+ format1->Amask == format2->Amask);
+}
+
+boolean SDLSetNativeSurface(SDL_Surface **surface)
+{
+ SDL_Surface *new_surface;
+
+ if (surface == NULL ||
+ *surface == NULL ||
+ backbuffer == NULL ||
+ backbuffer->surface == NULL)
+ return FALSE;
+
+ // if pixel format already optimized for destination surface, do nothing
+ if (equalSDLPixelFormat((*surface)->format, backbuffer->surface->format))
+ return FALSE;
+
+ new_surface = SDL_ConvertSurface(*surface, backbuffer->surface->format, 0);
+
+ SDL_FreeSurface(*surface);
+
+ *surface = new_surface;
+
+ return TRUE;
+}
+
+SDL_Surface *SDLGetNativeSurface(SDL_Surface *surface)
+{
+ if (surface == NULL ||
+ backbuffer == NULL ||
+ backbuffer->surface == NULL)
+ return NULL;
+
+ return SDL_ConvertSurface(surface, backbuffer->surface->format, 0);
+}
+
SDL_Surface *SDL_DisplayFormat(SDL_Surface *surface)
{
- if (backbuffer == NULL ||
+ if (surface == NULL ||
+ backbuffer == NULL ||
backbuffer->surface == NULL)
return NULL;
+#if 0
+ boolean same_pixel_format =
+ equalSDLPixelFormat(surface->format, backbuffer->surface->format);
+
+ printf("::: SDL_DisplayFormat: %08x -> %08x [%08x, %08x, %08x -> %08x, %08x, %08x] [%d, %d -> %d, %d] => %s\n",
+ surface->format->format,
+ backbuffer->surface->format->format,
+ surface->format->Rmask,
+ surface->format->Gmask,
+ surface->format->Bmask,
+ backbuffer->surface->format->Rmask,
+ backbuffer->surface->format->Gmask,
+ backbuffer->surface->format->Bmask,
+ surface->format->BitsPerPixel,
+ surface->format->BytesPerPixel,
+ backbuffer->surface->format->BitsPerPixel,
+ backbuffer->surface->format->BytesPerPixel,
+ (same_pixel_format ? "SAME" : "DIFF"));
+#endif
+
return SDL_ConvertSurface(surface, backbuffer->surface->format, 0);
}
+
+#else
+
+boolean SDLSetNativeSurface(SDL_Surface **surface)
+{
+ SDL_Surface *new_surface;
+
+ if (surface == NULL)
+ return FALSE;
+
+ new_surface = SDL_DisplayFormat(*surface);
+
+ if (new_surface == NULL)
+ Error(ERR_EXIT, "SDL_DisplayFormat() failed: %s", SDL_GetError());
+
+ SDL_FreeSurface(*surface);
+
+ *surface = new_surface;
+
+ return TRUE;
+}
+
+SDL_Surface *SDLGetNativeSurface(SDL_Surface *surface)
+{
+ SDL_Surface *new_surface = SDL_DisplayFormat(surface);
+
+ if (new_surface == NULL)
+ Error(ERR_EXIT, "SDL_DisplayFormat() failed: %s", SDL_GetError());
+
+ return new_surface;
+}
+
#endif
void SDLInitVideoDisplay(void)
#endif
video.window_scaling_percent = setup.window_scaling_percent;
+ video.window_scaling_quality = setup.window_scaling_quality;
#if defined(TARGET_SDL2)
int num_displays = SDL_GetNumVideoDisplays();
boolean fullscreen)
{
SDL_Surface *new_surface = NULL;
- static boolean fullscreen_enabled = FALSE;
#if defined(TARGET_SDL2)
+ static boolean fullscreen_enabled = FALSE;
int surface_flags_window = SURFACE_FLAGS | SDL_WINDOW_RESIZABLE;
#if USE_DESKTOP_FULLSCREEN
int surface_flags_fullscreen = SURFACE_FLAGS | SDL_WINDOW_FULLSCREEN_DESKTOP;
#if USE_RENDERER
float window_scaling_factor = (float)setup.window_scaling_percent / 100;
+#if !USE_DESKTOP_FULLSCREEN
float screen_scaling_factor = (fullscreen ? 1 : window_scaling_factor);
+#endif
video.window_width = window_scaling_factor * width;
video.window_height = window_scaling_factor * height;
if (sdl_window != NULL)
{
+#if 0
+ /* if SDL_CreateRenderer() is called from within a VirtualBox Windows VM
+ *without* enabling 2D/3D acceleration and/or guest additions installed,
+ it will crash if flags are *not* set to SDL_RENDERER_SOFTWARE (because
+ it will try to use accelerated graphics and apparently fails miserably) */
+ if (sdl_renderer == NULL)
+ sdl_renderer = SDL_CreateRenderer(sdl_window, -1, SDL_RENDERER_SOFTWARE);
+#else
if (sdl_renderer == NULL)
sdl_renderer = SDL_CreateRenderer(sdl_window, -1, 0);
+#endif
if (sdl_renderer != NULL)
{
SDL_RenderSetLogicalSize(sdl_renderer, width, height);
- SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");
+ // SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");
+ SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, setup.window_scaling_quality);
sdl_texture = SDL_CreateTexture(sdl_renderer,
SDL_PIXELFORMAT_ARGB8888,
if (sdl_texture != NULL)
{
+#if 1
+ // use SDL default values for RGB masks and no alpha channel
+ new_surface = SDL_CreateRGBSurface(0, width, height, 32, 0,0,0, 0);
+#else
+
#if 1
// (do not use alpha channel)
new_surface = SDL_CreateRGBSurface(0, width, height, 32,
0x0000FF00,
0x000000FF,
0xFF000000);
+#endif
+
#endif
if (new_surface == NULL)
new_surface = SDL_SetVideoMode(width, height, video.depth, surface_flags);
#endif
+#if defined(TARGET_SDL2)
// store fullscreen state ("video.fullscreen_enabled" may not reflect this!)
if (new_surface != NULL)
fullscreen_enabled = fullscreen;
+#endif
return new_surface;
}
#endif
SDL_Surface *new_surface = NULL;
+ SetWindowTitle();
+
if (*backbuffer == NULL)
*backbuffer = CreateBitmapStruct();
video.fullscreen_enabled = FALSE;
video.window_scaling_percent = setup.window_scaling_percent;
+ video.window_scaling_quality = setup.window_scaling_quality;
success = TRUE;
}
{
SDL_SysWMinfo wminfo;
HWND hwnd;
+ boolean wminfo_success = FALSE;
SDL_VERSION(&wminfo.version);
- SDL_GetWMInfo(&wminfo);
+#if defined(TARGET_SDL2)
+ if (sdl_window)
+ wminfo_success = SDL_GetWindowWMInfo(sdl_window, &wminfo);
+#else
+ wminfo_success = (SDL_GetWMInfo(&wminfo) == 1);
+#endif
- hwnd = wminfo.window;
+ if (wminfo_success)
+ {
+#if defined(TARGET_SDL2)
+ hwnd = wminfo.info.win.window;
+#else
+ hwnd = wminfo.window;
+#endif
- DragAcceptFiles(hwnd, TRUE);
+ DragAcceptFiles(hwnd, TRUE);
+ }
}
#endif
#endif
return success;
}
+void SDLSetWindowTitle()
+{
+#if defined(TARGET_SDL2)
+ 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)
{
video.window_scaling_percent = window_scaling_percent;
video.window_width = new_window_width;
video.window_height = new_window_height;
+
+ SetWindowTitle();
+}
+
+void SDLSetWindowScalingQuality(char *window_scaling_quality)
+{
+ if (sdl_texture == NULL)
+ return;
+
+ SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, window_scaling_quality);
+
+ SDL_Texture *new_texture = SDL_CreateTexture(sdl_renderer,
+ SDL_PIXELFORMAT_ARGB8888,
+ SDL_TEXTUREACCESS_STREAMING,
+ video.width, video.height);
+
+ if (new_texture != NULL)
+ {
+ SDL_DestroyTexture(sdl_texture);
+
+ sdl_texture = new_texture;
+
+ SDLRedrawWindow();
+ }
+
+ video.window_scaling_quality = window_scaling_quality;
}
void SDLSetWindowFullscreen(boolean fullscreen)
}
#endif
-void SDLCreateBitmapContent(Bitmap *new_bitmap, int width, int height,
+void SDLCreateBitmapContent(Bitmap *bitmap, int width, int height,
int depth)
{
+#if 1
+ SDL_Surface *surface =
+ SDL_CreateRGBSurface(SURFACE_FLAGS, width, height, depth, 0,0,0, 0);
+
+ if (surface == NULL)
+ Error(ERR_EXIT, "SDL_CreateRGBSurface() failed: %s", SDL_GetError());
+
+ SDLSetNativeSurface(&surface);
+
+ bitmap->surface = surface;
+
+#else
+
SDL_Surface *surface_tmp, *surface_native;
if ((surface_tmp = SDL_CreateRGBSurface(SURFACE_FLAGS, width, height, depth,
SDL_FreeSurface(surface_tmp);
new_bitmap->surface = surface_native;
+#endif
}
void SDLFreeBitmapPointers(Bitmap *bitmap)
}
#else
if (dst_bitmap == window)
- SDL_UpdateRect(backbuffer->surface, dst_x, dst_y, width, height);
+ {
+ // SDL_UpdateRect(backbuffer->surface, dst_x, dst_y, width, height);
+ UpdateScreen(&dst_rect);
+ }
#endif
}
}
#else
if (dst_bitmap == window)
- SDL_UpdateRect(backbuffer->surface, x, y, width, height);
+ {
+ // SDL_UpdateRect(backbuffer->surface, x, y, width, height);
+ UpdateScreen(&rect);
+ }
#endif
}
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;
dst_rect.w = width; /* (ignored) */
dst_rect.h = height; /* (ignored) */
-#if defined(TARGET_SDL2)
dst_rect2 = dst_rect;
-#endif
if (initialization_needed)
{
// SDL_UpdateWindowSurfaceRects(sdl_window, &dst_rect2, 1);
UpdateScreen(&dst_rect2);
#else
- SDL_UpdateRect(surface_screen, dst_x, dst_y, width, height);
+ // SDL_UpdateRect(surface_screen, dst_x, dst_y, width, height);
+ UpdateScreen(&dst_rect2);
#endif
}
}
// SDL_UpdateWindowSurfaceRects(sdl_window, &dst_rect, 1);
UpdateScreen(&dst_rect);
#else
- SDL_UpdateRect(surface_screen, dst_x, dst_y, width, height);
+ // SDL_UpdateRect(surface_screen, dst_x, dst_y, width, height);
+ UpdateScreen(&dst_rect);
#endif
#else
SDL_Flip(surface_screen);
return 0;
}
+#if 1
+
+int zoomSurfaceRGBA(SDL_Surface *src, SDL_Surface *dst)
+{
+ int x, y, *sax, *say, *csax, *csay;
+ float sx, sy;
+ tColorRGBA *sp, *csp, *csp0, *dp;
+ int dgap;
+
+ /* use specialized zoom function when scaling down to exactly half size */
+ if (src->w == 2 * dst->w &&
+ src->h == 2 * dst->h)
+ return zoomSurfaceRGBA_scaleDownBy2(src, dst);
+
+#if 0
+ printf("::: zoomSurfaceRGBA: %d, %d -> %d, %d\n",
+ src->w, src->h, dst->w, dst->h);
+#endif
+
+ /* variable setup */
+ sx = (float) src->w / (float) dst->w;
+ sy = (float) src->h / (float) dst->h;
+
+ /* allocate memory for row increments */
+ csax = sax = (int *)checked_malloc((dst->w + 1) * sizeof(Uint32));
+ csay = say = (int *)checked_malloc((dst->h + 1) * sizeof(Uint32));
+
+ /* precalculate row increments */
+ for (x = 0; x <= dst->w; x++)
+ *csax++ = (int)(sx * x);
+
+ for (y = 0; y <= dst->h; y++)
+ *csay++ = (int)(sy * y);
+
+ /* pointer setup */
+ sp = csp = csp0 = (tColorRGBA *) src->pixels;
+ dp = (tColorRGBA *) dst->pixels;
+ dgap = dst->pitch - dst->w * 4;
+
+ csay = say;
+ for (y = 0; y < dst->h; y++)
+ {
+ sp = csp;
+ csax = sax;
+
+ for (x = 0; x < dst->w; x++)
+ {
+ /* draw */
+ *dp = *sp;
+
+ /* advance source pointers */
+ csax++;
+ sp = csp + *csax;
+
+ /* advance destination pointer */
+ dp++;
+ }
+
+ /* advance source pointer */
+ csay++;
+ csp = (tColorRGBA *) ((Uint8 *) csp0 + *csay * src->pitch);
+
+ /* advance destination pointers */
+ dp = (tColorRGBA *) ((Uint8 *) dp + dgap);
+ }
+
+ free(sax);
+ free(say);
+
+ return 0;
+}
+
+#else
+
int zoomSurfaceRGBA(SDL_Surface *src, SDL_Surface *dst)
{
int x, y, sx, sy, *sax, *say, *csax, *csay, csx, csy;
return 0;
}
+#endif
+
/*
-----------------------------------------------------------------------------
8 bit zoomer
else
{
/* new source surface is 32 bit with a defined RGB ordering */
- zoom_src = SDL_CreateRGBSurface(SDL_SWSURFACE, src->w, src->h, 32,
+ zoom_src = SDL_CreateRGBSurface(SURFACE_FLAGS, src->w, src->h, 32,
0x000000ff, 0x0000ff00, 0x00ff0000, 0);
SDL_BlitSurface(src, NULL, zoom_src, NULL);
is_32bit = TRUE;
if (is_32bit)
{
/* target surface is 32 bit with source RGBA/ABGR ordering */
- zoom_dst = SDL_CreateRGBSurface(SDL_SWSURFACE, dst_width, dst_height, 32,
+ zoom_dst = SDL_CreateRGBSurface(SURFACE_FLAGS, dst_width, dst_height, 32,
zoom_src->format->Rmask,
zoom_src->format->Gmask,
zoom_src->format->Bmask, 0);
else
{
/* target surface is 8 bit */
- zoom_dst = SDL_CreateRGBSurface(SDL_SWSURFACE, dst_width, dst_height, 8,
+ zoom_dst = SDL_CreateRGBSurface(SURFACE_FLAGS, dst_width, dst_height, 8,
0, 0, 0, 0);
}
return zoom_dst;
}
+#if 1
+
+Bitmap *SDLZoomBitmap(Bitmap *src_bitmap, int dst_width, int dst_height)
+{
+#if 1
+
+ Bitmap *dst_bitmap = CreateBitmapStruct();
+ SDL_Surface **dst_surface = &dst_bitmap->surface;
+
+ dst_width = MAX(1, dst_width); /* prevent zero bitmap width */
+ dst_height = MAX(1, dst_height); /* prevent zero bitmap height */
+
+ dst_bitmap->width = dst_width;
+ dst_bitmap->height = dst_height;
+
+ /* create zoomed temporary surface from source surface */
+ *dst_surface = zoomSurface(src_bitmap->surface, dst_width, dst_height);
+
+ /* create native format destination surface from zoomed temporary surface */
+ SDLSetNativeSurface(dst_surface);
+
+ return dst_bitmap;
+
+#else
+
+ Bitmap *dst_bitmap = CreateBitmapStruct();
+ SDL_Surface *sdl_surface_tmp;
+
+ dst_width = MAX(1, dst_width); /* prevent zero bitmap width */
+ dst_height = MAX(1, dst_height); /* prevent zero bitmap height */
+
+ dst_bitmap->width = dst_width;
+ dst_bitmap->height = dst_height;
+
+ print_timestamp_init("SDLZoomBitmap");
+
+ /* create zoomed temporary surface from source surface */
+ sdl_surface_tmp = zoomSurface(src_bitmap->surface, dst_width, dst_height);
+ print_timestamp_time("zoomSurface");
+
+ /* create native format destination surface from zoomed temporary surface */
+ dst_bitmap->surface = SDL_DisplayFormat(sdl_surface_tmp);
+ print_timestamp_time("SDL_DisplayFormat");
+
+ /* free temporary surface */
+ SDL_FreeSurface(sdl_surface_tmp);
+ print_timestamp_time("SDL_FreeSurface");
+
+ print_timestamp_done("SDLZoomBitmap");
+
+ return dst_bitmap;
+
+#endif
+}
+
+#else
+
void SDLZoomBitmap(Bitmap *src_bitmap, Bitmap *dst_bitmap)
{
SDL_Surface *sdl_surface_tmp;
int dst_width = dst_bitmap->width;
int dst_height = dst_bitmap->height;
+ print_timestamp_init("SDLZoomBitmap");
+
/* throw away old destination surface */
SDL_FreeSurface(dst_bitmap->surface);
+ print_timestamp_time("SDL_FreeSurface");
/* create zoomed temporary surface from source surface */
sdl_surface_tmp = zoomSurface(src_bitmap->surface, dst_width, dst_height);
+ print_timestamp_time("zoomSurface");
/* create native format destination surface from zoomed temporary surface */
dst_bitmap->surface = SDL_DisplayFormat(sdl_surface_tmp);
+ print_timestamp_time("SDL_DisplayFormat");
/* free temporary surface */
SDL_FreeSurface(sdl_surface_tmp);
+ print_timestamp_time("SDL_FreeSurface");
+
+ print_timestamp_done("SDLZoomBitmap");
}
+#endif
+
/* ========================================================================= */
/* load image to bitmap */
UPDATE_BUSY_STATE();
/* create native non-transparent surface for current image */
+#if 1
+ if ((new_bitmap->surface = SDLGetNativeSurface(sdl_image_tmp)) == NULL)
+ {
+ SetError("SDL_DisplayFormat(): %s", SDL_GetError());
+
+ return NULL;
+ }
+#else
if ((new_bitmap->surface = SDL_DisplayFormat(sdl_image_tmp)) == NULL)
{
SetError("SDL_DisplayFormat(): %s", SDL_GetError());
return NULL;
}
+#endif
print_timestamp_time("SDL_DisplayFormat (opaque)");
/* create native transparent surface for current image */
SDL_SetColorKey(sdl_image_tmp, SET_TRANSPARENT_PIXEL,
SDL_MapRGB(sdl_image_tmp->format, 0x00, 0x00, 0x00));
+#if 1
+ if ((new_bitmap->surface_masked = SDLGetNativeSurface(sdl_image_tmp)) == NULL)
+ {
+ SetError("SDL_DisplayFormat(): %s", SDL_GetError());
+
+ return NULL;
+ }
+#else
if ((new_bitmap->surface_masked = SDL_DisplayFormat(sdl_image_tmp)) == NULL)
{
SetError("SDL_DisplayFormat(): %s", SDL_GetError());
return NULL;
}
+#endif
print_timestamp_time("SDL_DisplayFormat (masked)");
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");
printf("::: - '%s'\n", buffer);
}
+#if defined(TARGET_SDL2)
+ DragFinish((HDROP)syswmmsg->msg.win.wParam);
+#else
DragFinish((HDROP)syswmmsg->wParam);
+#endif
}
#endif
}