@@ -280,18 +280,21 @@ static inline void write_update(const rg_surface_t *update)
280280 {
281281 // TODO: Draw on screen display. By default it should be bottom left which is fine
282282 // for both virtual keyboard and info labels. Maybe make it configurable later...
283- int * buffer = osd .surface -> data ;
283+ const int * buffer = osd .surface -> data ;
284284 RG_ASSERT_ARG (buffer );
285285
286- int width = osd .surface -> width ;
287- int height = osd .surface -> height ;
286+ const int width = osd .surface -> width ;
287+ const int height = osd .surface -> height ;
288288
289- int top = osd .top ;
290- int left = osd .left ;
289+ const int min_width = RG_MIN (draw_width , osd .surface -> width );
290+ const int min_height = RG_MIN (draw_height , osd .surface -> height );
291+
292+ const int x0 = RG_MAX (draw_left , osd .left );
293+ const int y0 = RG_MAX (draw_top , osd .top );
291294
292295 lcd_set_window (osd .left + display .screen .margin_left , osd .top + display .screen .margin_top , width , height );
293296
294- // TODO : find a way to get the background pixels
297+ // FIXME: only redraw when background has changed
295298 for (size_t y = 0 ; y < height ;)
296299 {
297300 uint16_t * lcd_buffer = lcd_get_buffer (LCD_BUFFER_LENGTH );
@@ -300,11 +303,36 @@ static inline void write_update(const rg_surface_t *update)
300303 // Copy line by line because stride may not match width
301304 for (size_t line = 0 ; line < num_lines ; ++ line )
302305 {
303- uint16_t * src = (void * )buffer + ((y + line ) * osd .surface -> width * 2 );
306+ uint16_t * viewport = (void * )data + map_viewport_to_source_y [y + line ] * stride ;
307+ uint16_t * osd_buffer = (void * )buffer + (y + line ) * osd .surface -> width * 2 ;
304308 uint16_t * dst = lcd_buffer + (line * width );
305- for (size_t i = 0 ; i < width ; ++ i ){
306- if (src [i ] != C_TRANSPARENT ) // only overwrite pixels that aren't transparent
307- dst [i ] = (src [i ] >> 8 ) | (src [i ] << 8 );
309+ for (size_t i = 0 ; i < width ; ++ i )
310+ {
311+ if (osd .has_transparency && osd_buffer [i ] == C_TRANSPARENT )
312+ {
313+ if ((y + line )>=y0 && (i - draw_left )>=x0 && (y + line )<=min_height && (i - draw_left )<=min_width )
314+ { // the pixel is within the display surface and within the OSD
315+ switch (format )
316+ {
317+ case RG_PIXEL_PALETTE :
318+ dst [i ] = palette [viewport [map_viewport_to_source_x [i ]]];
319+ break ;
320+ case RG_PIXEL_565_LE :
321+ dst [i ] = (viewport [map_viewport_to_source_x [i ]] >> 8 ) | (viewport [map_viewport_to_source_x [i ]] << 8 );
322+ break ;
323+ default :
324+ dst [i ] = viewport [map_viewport_to_source_x [i ]];
325+ }
326+ }
327+ else
328+ {
329+ dst [i ] = 0x0000 ; // the ideal would be to put a "background" color
330+ }
331+ }
332+ else
333+ {
334+ dst [i ] = (osd_buffer [i ] >> 8 ) | (osd_buffer [i ] << 8 );
335+ }
308336 }
309337 }
310338
0 commit comments