diff --git a/sim_video.c b/sim_video.c index 02d84162..4cade8dc 100644 --- a/sim_video.c +++ b/sim_video.c @@ -370,6 +370,7 @@ t_bool vid_cursor_visible; /* cursor visibility sta DEVICE *vid_dev; t_bool vid_key_state[SDL_NUM_SCANCODES]; VID_DISPLAY *next; +t_bool vid_blending; }; SDL_Thread *vid_thread_handle = NULL; /* event thread handle */ @@ -625,6 +626,7 @@ vptr->vid_width = width; vptr->vid_height = height; vptr->vid_mouse_captured = FALSE; vptr->vid_cursor_visible = (vptr->vid_flags & SIM_VID_INPUTCAPTURED); +vptr->vid_blending = FALSE; if (!vid_active) { vid_key_events.head = 0; @@ -786,6 +788,11 @@ uint32 vid_map_rgb (uint8 r, uint8 g, uint8 b) return vid_map_rgb_window (&vid_first, r, g, b); } +uint32 vid_map_rgba_window (VID_DISPLAY *vptr, uint8 r, uint8 g, uint8 b, uint8 a) +{ +return SDL_MapRGBA (vptr->vid_format, r, g, b, a); +} + static SDL_Rect *vid_dst_last; static uint32 *vid_data_last; @@ -1574,11 +1581,15 @@ vid_stretch(vptr, &vid_dst); sim_debug (SIM_VID_DBG_VIDEO, vptr->vid_dev, "Video Update Event: \n"); if (sim_deb) fflush (sim_deb); -if (SDL_RenderClear (vptr->vid_renderer)) - sim_printf ("%s: Video Update Event: SDL_RenderClear error: %s\n", vid_dname(vptr->vid_dev), SDL_GetError()); -if (SDL_RenderCopy (vptr->vid_renderer, vptr->vid_texture, NULL, &vid_dst)) - sim_printf ("%s: Video Update Event: SDL_RenderCopy error: %s\n", vid_dname(vptr->vid_dev), SDL_GetError()); -SDL_RenderPresent (vptr->vid_renderer); +if (vptr->vid_blending) + SDL_RenderPresent (vptr->vid_renderer); +else { + if (SDL_RenderClear (vptr->vid_renderer)) + sim_printf ("%s: Video Update Event: SDL_RenderClear error: %s\n", vid_dname(vptr->vid_dev), SDL_GetError()); + if (SDL_RenderCopy (vptr->vid_renderer, vptr->vid_texture, NULL, &vid_dst)) + sim_printf ("%s: Video Update Event: SDL_RenderCopy error: %s\n", vid_dname(vptr->vid_dev), SDL_GetError()); + SDL_RenderPresent (vptr->vid_renderer); + } } void vid_update_cursor (VID_DISPLAY *vptr, SDL_Cursor *cursor, t_bool visible) @@ -1620,8 +1631,13 @@ if (vid_dst == vid_dst_last) { } SDL_UnlockMutex (vptr->vid_draw_mutex); -if (SDL_UpdateTexture(vptr->vid_texture, vid_dst, buf, vid_dst->w*sizeof(*buf))) - sim_printf ("%s: vid_draw_region() - SDL_UpdateTexture error: %s\n", vid_dname(vptr->vid_dev), SDL_GetError()); +if (vptr->vid_blending) { + SDL_UpdateTexture(vptr->vid_texture, vid_dst, buf, vid_dst->w*sizeof(*buf)); + SDL_RenderCopy (vptr->vid_renderer, vptr->vid_texture, vid_dst, vid_dst); + } +else + if (SDL_UpdateTexture(vptr->vid_texture, vid_dst, buf, vid_dst->w*sizeof(*buf))) + sim_printf ("%s: vid_draw_region() - SDL_UpdateTexture error: %s\n", vid_dname(vptr->vid_dev), SDL_GetError()); free (vid_dst); free (buf); @@ -1688,6 +1704,36 @@ vid_active++; return 1; } +t_stat vid_set_alpha_mode (VID_DISPLAY *vptr, int mode) +{ +SDL_BlendMode x; +switch (mode) { + case SIM_ALPHA_NONE: + vptr->vid_blending = FALSE; + x = SDL_BLENDMODE_NONE; + break; + case SIM_ALPHA_BLEND: + vptr->vid_blending = TRUE; + x = SDL_BLENDMODE_BLEND; + break; + case SIM_ALPHA_ADD: + vptr->vid_blending = TRUE; + x = SDL_BLENDMODE_ADD; + break; + case SIM_ALPHA_MOD: + vptr->vid_blending = TRUE; + x = SDL_BLENDMODE_MOD; + break; + default: + return SCPE_ARG; + } +if (SDL_SetTextureBlendMode (vptr->vid_texture, x)) + return SCPE_IERR; +if (SDL_SetRenderDrawBlendMode (vptr->vid_renderer, x)) + return SCPE_IERR; +return SCPE_OK; +} + static void vid_destroy (VID_DISPLAY *vptr) { VID_DISPLAY *parent; diff --git a/sim_video.h b/sim_video.h index 6e9ebea0..3127b453 100644 --- a/sim_video.h +++ b/sim_video.h @@ -157,6 +157,11 @@ extern "C" { #define SIM_KEY_UNKNOWN 200 +#define SIM_ALPHA_NONE 1 +#define SIM_ALPHA_BLEND 2 +#define SIM_ALPHA_ADD 3 +#define SIM_ALPHA_MOD 4 + typedef struct VID_DISPLAY VID_DISPLAY; struct mouse_event { @@ -214,12 +219,14 @@ t_stat vid_open_window (VID_DISPLAY **vptr, DEVICE *dptr, const char *title, uin t_stat vid_close_window (VID_DISPLAY *vptr); t_stat vid_close_all (void); uint32 vid_map_rgb_window (VID_DISPLAY *vptr, uint8 r, uint8 g, uint8 b); +uint32 vid_map_rgba_window (VID_DISPLAY *vptr, uint8 r, uint8 g, uint8 b, uint8 a); void vid_draw_window (VID_DISPLAY *vptr, int32 x, int32 y, int32 w, int32 h, uint32 *buf); void vid_refresh_window (VID_DISPLAY *vptr); t_stat vid_set_cursor_window (VID_DISPLAY *vptr, t_bool visible, uint32 width, uint32 height, uint8 *data, uint8 *mask, uint32 hot_x, uint32 hot_y); t_bool vid_is_fullscreen_window (VID_DISPLAY *vptr); t_stat vid_set_fullscreen_window (VID_DISPLAY *vptr, t_bool flag); void vid_set_cursor_position_window (VID_DISPLAY *vptr, int32 x, int32 y); /* cursor position (set by calling code) */ +t_stat vid_set_alpha_mode (VID_DISPLAY *vptr, int mode); /* A device simulator can optionally set the vid_display_kb_event_process * routine pointer to the address of a routine.