// copy tile selection cursor to render target buffer, if defined (above all)
if (gfx.draw_tile_cursor_function != NULL)
gfx.draw_tile_cursor_function(draw_target);
+
+ // copy envelope request to render target buffer, if needed (above all)
+ if (gfx.draw_envelope_request_function != NULL)
+ gfx.draw_envelope_request_function(draw_target);
+
+ // copy global animations to render target buffer, if defined (mouse pointer)
+ if (gfx.draw_global_anim_function != NULL)
+ gfx.draw_global_anim_function(draw_target, DRAW_GLOBAL_ANIM_STAGE_3);
}
static void UpdateScreenExt(SDL_Rect *rect, boolean with_frame_delay)
{
- static unsigned int update_screen_delay = 0;
- unsigned int update_screen_delay_value = 50; // (milliseconds)
+ if (program.headless)
+ return;
+
+ static DelayCounter update_screen_delay = { 50 }; // (milliseconds)
SDL_Surface *screen = backbuffer->surface;
if (limit_screen_updates &&
- !DelayReached(&update_screen_delay, update_screen_delay_value))
+ !DelayReached(&update_screen_delay))
return;
LimitScreenUpdates(FALSE);
SDL_Rect src_rect_up = { 0, 0, video.width, video.height };
SDL_Rect dst_rect_up = dst_rect_screen;
- if (video.shifted_up || video.shifted_up_delay)
+ if (video.shifted_up || video.shifted_up_delay.count)
{
int time_current = SDL_GetTicks();
int pos = video.shifted_up_pos;
int pos_last = video.shifted_up_pos_last;
- if (!DelayReachedExt(&video.shifted_up_delay, video.shifted_up_delay_value,
- time_current))
+ if (!DelayReachedExt(&video.shifted_up_delay, time_current))
{
- int delay = time_current - video.shifted_up_delay;
- int delay_value = video.shifted_up_delay_value;
+ int delay_count = time_current - video.shifted_up_delay.count;
+ int delay_value = video.shifted_up_delay.value;
- pos = pos_last + (pos - pos_last) * delay / delay_value;
+ pos = pos_last + (pos - pos_last) * delay_count / delay_value;
}
else
{
video.shifted_up_pos_last = pos;
- video.shifted_up_delay = 0;
+ video.shifted_up_delay.count = 0;
}
src_rect_up.y = pos;
// global synchronization point of the game to align video frame delay
if (with_frame_delay)
- WaitUntilDelayReached(&video.frame_delay, video.frame_delay_value);
+ WaitUntilDelayReached(&video.frame_delay);
video.frame_counter++;
return (blend_mode == SDL_BLENDMODE_BLEND);
}
-void SDLSetAlpha(SDL_Surface *surface, boolean set, int alpha)
+static void SDLSetSurfaceAlpha(SDL_Surface *surface, boolean set, int alpha)
{
SDL_BlendMode blend_mode = (set ? SDL_BLENDMODE_BLEND : SDL_BLENDMODE_NONE);
SDL_SetSurfaceAlphaMod(surface, alpha);
}
+static void SDLSetTextureAlpha(SDL_Texture *texture, boolean set, int alpha)
+{
+ SDL_BlendMode blend_mode = (set ? SDL_BLENDMODE_BLEND : SDL_BLENDMODE_NONE);
+
+ SDL_SetTextureBlendMode(texture, blend_mode);
+ SDL_SetTextureAlphaMod(texture, alpha);
+}
+
+static void SDLSetBitmapAlpha(Bitmap *bitmap, boolean is_texture,
+ boolean is_masked)
+{
+ int alpha_next_blit = bitmap->alpha_next_blit;
+
+ // alpha value must be requested every time before blitting, if needed
+ bitmap->alpha_next_blit = -1;
+
+ // nothing to do if requested alpha value is already set
+ if (bitmap->alpha[is_texture][is_masked] == alpha_next_blit)
+ return;
+
+ // store requested alpha value for masked/unmasked surface/texture
+ bitmap->alpha[is_texture][is_masked] = alpha_next_blit;
+
+ // set blend mode if bitmap is masked or if alpha value is defined
+ boolean set_blend_mode = (is_masked || alpha_next_blit != -1);
+
+ // if alpha value is undefined, use default (opaque) alpha value
+ if (alpha_next_blit == -1)
+ alpha_next_blit = SDL_ALPHA_OPAQUE;
+
+ if (is_texture)
+ SDLSetTextureAlpha(is_masked ? bitmap->texture_masked : bitmap->texture,
+ set_blend_mode, alpha_next_blit);
+ else
+ SDLSetSurfaceAlpha(is_masked ? bitmap->surface_masked : bitmap->surface,
+ set_blend_mode, alpha_next_blit);
+}
+
+void SDLSetAlpha(SDL_Surface *surface, boolean set, int alpha)
+{
+ SDLSetSurfaceAlpha(surface, set, alpha);
+}
+
const char *SDLGetRendererName(void)
{
static SDL_RendererInfo renderer_info;
int screen_height = video.screen_height;
int surface_flags = (fullscreen ? surface_flags_fullscreen :
surface_flags_window);
+ int display_nr = options.display_nr;
// default window size is unscaled
video.window_width = screen_width;
if (sdl_window)
{
- SDL_DestroyWindow(sdl_window);
- sdl_window = NULL;
+ SDL_SetWindowSize(sdl_window, video.window_width, video.window_height);
}
}
if (sdl_window == NULL)
sdl_window = SDL_CreateWindow(program.window_title,
- SDL_WINDOWPOS_CENTERED,
- SDL_WINDOWPOS_CENTERED,
+ SDL_WINDOWPOS_CENTERED_DISPLAY(display_nr),
+ SDL_WINDOWPOS_CENTERED_DISPLAY(display_nr),
video.window_width,
video.window_height,
surface_flags);
{
SDLSetWindowScaling(setup.window_scaling_percent);
SDL_SetWindowPosition(sdl_window,
- SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
+ SDL_WINDOWPOS_CENTERED_DISPLAY(options.display_nr),
+ SDL_WINDOWPOS_CENTERED_DISPLAY(options.display_nr));
video.fullscreen_initial = FALSE;
}
dst_rect.w = width;
dst_rect.h = height;
+ SDLSetBitmapAlpha(src_bitmap, FALSE, mask_mode == BLIT_MASKED);
+
// if (src_bitmap != backbuffer || dst_bitmap != window)
if (!(src_bitmap == backbuffer && dst_bitmap == window))
SDL_BlitSurface((mask_mode == BLIT_MASKED ?
dst_rect.w = width;
dst_rect.h = height;
+ SDLSetBitmapAlpha(bitmap, TRUE, mask_mode == BLIT_MASKED);
+
SDL_RenderCopy(sdl_renderer, texture, &src_rect, &dst_rect);
}
case 1:
{
// Assuming 8-bpp
- *((Uint8 *)surface->pixels + y*surface->pitch + x) = color;
+ *((Uint8 *)surface->pixels + y * surface->pitch + x) = color;
}
break;
case 2:
{
// Probably 15-bpp or 16-bpp
- *((Uint16 *)surface->pixels + y*surface->pitch/2 + x) = color;
+ *((Uint16 *)surface->pixels + y * surface->pitch / 2 + x) = color;
}
break;
int shift;
// Gack - slow, but endian correct
- pix = (Uint8 *)surface->pixels + y * surface->pitch + x*3;
+ pix = (Uint8 *)surface->pixels + y * surface->pitch + x * 3;
shift = surface->format->Rshift;
- *(pix+shift/8) = color>>shift;
+ *(pix + shift / 8) = color>>shift;
shift = surface->format->Gshift;
- *(pix+shift/8) = color>>shift;
+ *(pix + shift / 8) = color>>shift;
shift = surface->format->Bshift;
- *(pix+shift/8) = color>>shift;
+ *(pix + shift / 8) = color>>shift;
}
break;
case 4:
{
// Probably 32-bpp
- *((Uint32 *)surface->pixels + y*surface->pitch/4 + x) = color;
+ *((Uint32 *)surface->pixels + y * surface->pitch / 4 + x) = color;
}
break;
}
static void _PutPixel8(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color)
{
- *((Uint8 *)surface->pixels + y*surface->pitch + x) = color;
+ *((Uint8 *)surface->pixels + y * surface->pitch + x) = color;
}
static void _PutPixel16(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color)
{
- *((Uint16 *)surface->pixels + y*surface->pitch/2 + x) = color;
+ *((Uint16 *)surface->pixels + y * surface->pitch / 2 + x) = color;
}
static void _PutPixel24(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color)
int shift;
// Gack - slow, but endian correct
- pix = (Uint8 *)surface->pixels + y * surface->pitch + x*3;
+ pix = (Uint8 *)surface->pixels + y * surface->pitch + x * 3;
shift = surface->format->Rshift;
- *(pix+shift/8) = color>>shift;
+ *(pix + shift / 8) = color>>shift;
shift = surface->format->Gshift;
- *(pix+shift/8) = color>>shift;
+ *(pix + shift / 8) = color>>shift;
shift = surface->format->Bshift;
- *(pix+shift/8) = color>>shift;
+ *(pix + shift / 8) = color>>shift;
}
static void _PutPixel32(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color)
{
- *((Uint32 *)surface->pixels + y*surface->pitch/4 + x) = color;
+ *((Uint32 *)surface->pixels + y * surface->pitch / 4 + x) = color;
}
-static void _PutPixelX(SDL_Surface *dest,Sint16 x,Sint16 y,Uint32 color)
+static void _PutPixelX(SDL_Surface *dest, Sint16 x, Sint16 y, Uint32 color)
{
switch (dest->format->BytesPerPixel)
{
case 1:
- *((Uint8 *)dest->pixels + y*dest->pitch + x) = color;
+ *((Uint8 *)dest->pixels + y * dest->pitch + x) = color;
break;
case 2:
- *((Uint16 *)dest->pixels + y*dest->pitch/2 + x) = color;
+ *((Uint16 *)dest->pixels + y * dest->pitch / 2 + x) = color;
break;
case 3:
- _PutPixel24(dest,x,y,color);
+ _PutPixel24(dest, x, y, color);
break;
case 4:
- *((Uint32 *)dest->pixels + y*dest->pitch/4 + x) = color;
+ *((Uint32 *)dest->pixels + y * dest->pitch / 4 + x) = color;
break;
}
}
switch (dest->format->BytesPerPixel)
{
case 1:
- return y*dest->pitch;
+ return y * dest->pitch;
break;
case 2:
- return y*dest->pitch/2;
+ return y * dest->pitch / 2;
break;
case 3:
- return y*dest->pitch;
+ return y * dest->pitch;
break;
case 4:
- return y*dest->pitch/4;
+ return y * dest->pitch / 4;
break;
}
}
int shift;
// Gack - slow, but endian correct
- pix = (Uint8 *)surface->pixels + ypitch + x*3;
+ pix = (Uint8 *)surface->pixels + ypitch + x * 3;
shift = surface->format->Rshift;
- *(pix+shift/8) = color>>shift;
+ *(pix + shift / 8) = color>>shift;
shift = surface->format->Gshift;
- *(pix+shift/8) = color>>shift;
+ *(pix + shift / 8) = color>>shift;
shift = surface->format->Bshift;
- *(pix+shift/8) = color>>shift;
+ *(pix + shift / 8) = color>>shift;
}
break;
// 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)
-{
- int x, y;
-
- for (y = src_y; y < src_y + height; y++)
- {
- for (x = src_x; x < src_x + width; x++)
- {
- Uint32 pixel = SDLGetPixel(bitmap, x, y);
-
- SDLPutPixel(bitmap, x, y, pixel == BLACK_PIXEL ? color : BLACK_PIXEL);
- }
- }
-}
-
void SDLCopyInverseMasked(Bitmap *src_bitmap, Bitmap *dst_bitmap,
int src_x, int src_y, int width, int height,
int dst_x, int dst_y)