Skip to content

Commit 7a11bde

Browse files
committed
rg_display: osd support transparent background
1 parent 417ab3d commit 7a11bde

File tree

1 file changed

+38
-10
lines changed

1 file changed

+38
-10
lines changed

components/retro-go/rg_display.c

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)