From: Toni Wilen Date: Sun, 6 Jan 2019 08:55:30 +0000 (+0200) Subject: Picasso IV hardware overlay support, overlay color key updates. X-Git-Tag: 4200~87 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=eecaa2e88e0f8f7c4d318dad8bbf4dbc85a337c3;p=francis%2Fwinuae.git Picasso IV hardware overlay support, overlay color key updates. --- diff --git a/gfxboard.cpp b/gfxboard.cpp index c5f998bc..d2e35a43 100644 --- a/gfxboard.cpp +++ b/gfxboard.cpp @@ -639,6 +639,7 @@ static void vga_update_size(struct rtggfxboard *gb) { // this forces qemu_console_resize() call gb->vga.vga.graphic_mode = -1; + gb->vga.vga.monid = gb->monitor_id; gb->vga.vga.hw_ops->gfx_update(&gb->vga); } diff --git a/od-win32/picasso96_win.cpp b/od-win32/picasso96_win.cpp index ced124be..52650fe2 100644 --- a/od-win32/picasso96_win.cpp +++ b/od-win32/picasso96_win.cpp @@ -908,7 +908,7 @@ enum { RGBFB_CLUT_8 }; -static int getconvert(int rgbformat, int pixbytes) +int getconvert(int rgbformat, int pixbytes) { int v = 0; int d = pixbytes; @@ -4465,7 +4465,12 @@ static void copyrow (int monid, uae_u8 *src, uae_u8 *dst, int x, int y, int widt } -static void copyrow_scale(int monid, uae_u8 *src, uae_u8 *src_screen, uae_u8 *dst, +#define CKCHECK if (!ck || (screenpixbytes == 4 && colorkey == ((uae_u32*)srcs)[dx]) \ + || (screenpixbytes == 2 && (uae_u16)colorkey == ((uae_u16*)srcs)[dx]) \ + || (screenpixbytes == 1 && (uae_u8)colorkey == ((uae_u8*)srcs)[dx]) \ + || (screenpixbytes == 3 && ckbytes[0] == srcs[dx * 3 + 0] && ckbytes[1] == srcs[dx * 3 + 1] && ckbytes[2] == srcs[dx * 3 + 2])) + +void copyrow_scale(int monid, uae_u8 *src, uae_u8 *src_screen, uae_u8 *dst, int sx, int sy, int sxadd, int width, int srcbytesperrow, int srcpixbytes, int screenbytesperrow, int screenpixbytes, int dx, int dy, int dstbytesperrow, int dstpixbytes, @@ -4480,6 +4485,20 @@ static void copyrow_scale(int monid, uae_u8 *src, uae_u8 *src_screen, uae_u8 *ds int dstpix = dstpixbytes; int srcpix = srcpixbytes; int x; + uae_u8 ckbytes[3]; + + switch (convert_mode) + { + case RGBFB_Y4U2V2_32: + case RGBFB_Y4U2V2_16: + case RGBFB_Y4U1V1_32: + case RGBFB_Y4U1V1_16: + endx /= 2; + break; + } + ckbytes[0] = colorkey >> 16; + ckbytes[1] = colorkey >> 8; + ckbytes[2] = colorkey >> 0; endx4 = endx & ~(3 << 8); @@ -4490,7 +4509,7 @@ static void copyrow_scale(int monid, uae_u8 *src, uae_u8 *src_screen, uae_u8 *ds while (sx < endx) { x = sx >> 8; sx += sxadd; - if (!ck || colorkey == ((uae_u32*)srcs)[dx]) + CKCHECK ((uae_u32*)dst2)[dx] = (src2[x * 3 + 0] << 16) | (src2[x * 3 + 1] << 8) | (src2[x * 3 + 2] << 0); dx++; } @@ -4499,7 +4518,7 @@ static void copyrow_scale(int monid, uae_u8 *src, uae_u8 *src_screen, uae_u8 *ds while (sx < endx) { x = sx >> 8; sx += sxadd; - if (!ck || colorkey == ((uae_u32*)srcs)[dx]) + CKCHECK ((uae_u32*)dst2)[dx] = ((uae_u32*)(src2 + x * 3))[0] & 0x00ffffff; dx++; } @@ -4510,7 +4529,7 @@ static void copyrow_scale(int monid, uae_u8 *src, uae_u8 *src_screen, uae_u8 *ds while (sx < endx) { x = sx >> 8; sx += sxadd; - if (!ck || colorkey == ((uae_u32*)srcs)[dx]) + CKCHECK ((uae_u32*)dst2)[dx] = (src2[x * 4 + 0] << 16) | (src2[x * 4 + 1] << 8) | (src2[x * 4 + 2] << 0); dx++; } @@ -4519,7 +4538,7 @@ static void copyrow_scale(int monid, uae_u8 *src, uae_u8 *src_screen, uae_u8 *ds while (sx < endx) { x = sx >> 8; sx += sxadd; - if (!ck || colorkey == ((uae_u32*)srcs)[dx]) + CKCHECK ((uae_u32*)dst2)[dx] = (src2[x * 4 + 1] << 16) | (src2[x * 4 + 2] << 8) | (src2[x * 4 + 3] << 0); dx++; } @@ -4528,7 +4547,7 @@ static void copyrow_scale(int monid, uae_u8 *src, uae_u8 *src_screen, uae_u8 *ds while (sx < endx) { x = sx >> 8; sx += sxadd; - if (!ck || colorkey == ((uae_u32*)srcs)[dx]) + CKCHECK ((uae_u32*)dst2)[dx] = ((uae_u32*)src2)[x] >> 8; dx++; } @@ -4541,49 +4560,78 @@ static void copyrow_scale(int monid, uae_u8 *src, uae_u8 *src_screen, uae_u8 *ds case RGBFB_R5G5B5_32: case RGBFB_B5G6R5PC_32: case RGBFB_B5G5R5PC_32: - - case RGBFB_Y4U1V1_32: - case RGBFB_Y4U2V2_32: { while ((sx & (3 << 8)) && sx < endx) { x = sx >> 8; sx += sxadd; - if (!ck || colorkey == ((uae_u32*)srcs)[dx]) + CKCHECK ((uae_u32*)dst2)[dx] = p96_rgbx16p[((uae_u16*)src2)[x]]; dx++; } while (sx < endx4) { x = sx >> 8; sx += sxadd; - if (!ck || colorkey == ((uae_u32*)srcs)[dx]) + CKCHECK ((uae_u32*)dst2)[dx] = p96_rgbx16p[((uae_u16*)src2)[x]]; dx++; x = sx >> 8; sx += sxadd; - if (!ck || colorkey == ((uae_u32*)srcs)[dx]) + CKCHECK ((uae_u32*)dst2)[dx] = p96_rgbx16p[((uae_u16*)src2)[x]]; dx++; x = sx >> 8; sx += sxadd; - if (!ck || colorkey == ((uae_u32*)srcs)[dx]) + CKCHECK ((uae_u32*)dst2)[dx] = p96_rgbx16p[((uae_u16*)src2)[x]]; dx++; x = sx >> 8; sx += sxadd; - if (!ck || colorkey == ((uae_u32*)srcs)[dx]) + CKCHECK ((uae_u32*)dst2)[dx] = p96_rgbx16p[((uae_u16*)src2)[x]]; dx++; } while (sx < endx) { x = sx >> 8; sx += sxadd; - if (!ck || colorkey == ((uae_u32*)srcs)[dx]) + CKCHECK ((uae_u32*)dst2)[dx] = p96_rgbx16p[((uae_u16*)src2)[x]]; dx++; } } break; + case RGBFB_Y4U2V2_32: + { + while (sx < endx) { + x = sx >> 8; + sx += sxadd; + uae_u32 v = p96_rgbx16p[((uae_u16*)src2)[x]]; + CKCHECK + ((uae_u32*)dst2)[dx + 0] = v; + dx++; + CKCHECK + ((uae_u32*)dst2)[dx + 1] = v; + dx++; + } + } + break; + + case RGBFB_Y4U1V1_32: + { + while (sx < endx) { + x = sx >> 8; + sx += sxadd; + uae_u32 v = p96_rgbx16p[((uae_u16*)src2)[x]]; + CKCHECK + ((uae_u32*)dst2)[dx + 0] = v; + dx++; + CKCHECK + ((uae_u32*)dst2)[dx + 1] = v; + dx++; + } + } + break; + /* 16/15bit->16bit */ case RGBFB_R5G5B5PC_16: case RGBFB_R5G6B5_16: @@ -4591,48 +4639,78 @@ static void copyrow_scale(int monid, uae_u8 *src, uae_u8 *src_screen, uae_u8 *ds case RGBFB_B5G5R5PC_16: case RGBFB_B5G6R5PC_16: case RGBFB_R5G6B5PC_16: - - case RGBFB_Y4U1V1_16: - case RGBFB_Y4U2V2_16: { while ((sx & (3 << 8)) && sx < endx) { x = sx >> 8; sx += sxadd; - if (!ck || colorkey == ((uae_u16*)srcs)[dx]) + CKCHECK ((uae_u16*)dst2)[dx] = (uae_u16)p96_rgbx16p[((uae_u16*)src2)[x]]; dx++; } while (sx < endx4) { x = sx >> 8; sx += sxadd; - if (!ck || colorkey == ((uae_u16*)srcs)[dx]) + CKCHECK ((uae_u16*)dst2)[dx] = (uae_u16)p96_rgbx16p[((uae_u16*)src2)[x]]; dx++; x = sx >> 8; sx += sxadd; - if (!ck || colorkey == ((uae_u16*)srcs)[dx]) + CKCHECK ((uae_u16*)dst2)[dx] = (uae_u16)p96_rgbx16p[((uae_u16*)src2)[x]]; dx++; x = sx >> 8; sx += sxadd; - if (!ck || colorkey == ((uae_u16*)srcs)[dx]) + CKCHECK ((uae_u16*)dst2)[dx] = (uae_u16)p96_rgbx16p[((uae_u16*)src2)[x]]; dx++; x = sx >> 8; sx += sxadd; - if (!ck || colorkey == ((uae_u16*)srcs)[dx]) + CKCHECK ((uae_u16*)dst2)[dx] = (uae_u16)p96_rgbx16p[((uae_u16*)src2)[x]]; dx++; } while (sx < endx) { x = sx >> 8; sx += sxadd; - if (!ck || colorkey == ((uae_u16*)srcs)[dx]) + CKCHECK ((uae_u16*)dst2)[dx] = (uae_u16)p96_rgbx16p[((uae_u16*)src2)[x]]; dx++; } } break; + + case RGBFB_Y4U2V2_16: + { + while (sx < endx) { + x = sx >> 8; + sx += sxadd; + uae_u16 v = p96_rgbx16p[((uae_u16*)src2)[x]]; + CKCHECK + ((uae_u16*)dst2)[dx + 0] = v; + dx++; + CKCHECK + ((uae_u16*)dst2)[dx + 1] = v; + dx++; + } + } + break; + + case RGBFB_Y4U1V1_16: + { + while (sx < endx) { + x = sx >> 8; + sx += sxadd; + uae_u16 v = p96_rgbx16p[((uae_u16*)src2)[x]]; + CKCHECK + ((uae_u16*)dst2)[dx + 0] = v; + dx++; + CKCHECK + ((uae_u16*)dst2)[dx + 1] = v; + dx++; + } + } + break; + } } @@ -4643,12 +4721,19 @@ static void picasso_flushoverlay(int index, uae_u8 *src, int scr_offset, uae_u8 struct picasso96_state_struct *state = &picasso96_state[monid]; struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[monid]; + uae_u8 *vram_end = src + gfxmem_banks[0]->allocated_size; uae_u8 *s = src + overlay_vram_offset; uae_u8 *ss = src + scr_offset; int mx = overlay_src_width * 256 / overlay_w; int my = overlay_src_height * 256 / overlay_h; int y = 0; for (int dy = 0; dy < overlay_h; dy++) { + if (s + (y >> 8) * overlay_src_width * overlay_pix > vram_end) + break; + if (ss + (overlay_y + dy) * state->BytesPerRow > vram_end) + break; + if (dst + (overlay_y + dy) * vidinfo->rowbytes > vram_end) + break; copyrow_scale(monid, s, ss, dst, 0, (y >> 8), mx, overlay_src_width, overlay_src_width * overlay_pix, overlay_pix, state->BytesPerRow, state->BytesPerPixel, @@ -5197,7 +5282,7 @@ static void overlaygettag(uae_u32 tag, uae_u32 val) break; case FA_Color: overlay_color = val; - endianswap(&overlay_color, picasso_vidinfo[0].pixbytes); + endianswap(&overlay_color, picasso96_state[0].BytesPerPixel); break; } } diff --git a/qemuvga/cirrus_vga.cpp b/qemuvga/cirrus_vga.cpp index de66a825..a677878d 100644 --- a/qemuvga/cirrus_vga.cpp +++ b/qemuvga/cirrus_vga.cpp @@ -1553,6 +1553,8 @@ cirrus_vga_write_gr(CirrusVGAState * s, unsigned reg_index, int reg_value) cirrus_update_bank_ptr(s, 1); cirrus_update_memory_access(s); break; + case 0x0C: // Colorkey + case 0x0D: // Colorkey case 0x10: // BGCOLOR 0x0000ff00 case 0x11: // FGCOLOR 0x0000ff00 case 0x12: // BGCOLOR 0x00ff0000 @@ -1567,7 +1569,7 @@ cirrus_vga_write_gr(CirrusVGAState * s, unsigned reg_index, int reg_value) case 0x29: // BLT DEST ADDR 0x00ff00 case 0x2c: // BLT SRC ADDR 0x0000ff case 0x2d: // BLT SRC ADDR 0x00ff00 - case 0x2f: // BLT WRITEMASK + case 0x2f: // BLT WRITEMASK case 0x32: // RASTER OP case 0x33: // BLT MODEEXT case 0x34: // BLT TRANSPARENT COLOR 0x00ff @@ -1641,12 +1643,12 @@ cirrus_vga_write_gr(CirrusVGAState * s, unsigned reg_index, int reg_value) static int cirrus_vga_read_cr(CirrusVGAState * s, unsigned reg_index) { -#if 0 - if (reg_index >= 0x31) { + if ((reg_index >= 0x31 && reg_index < 0x3f) || reg_index >= 0x50) { +#ifdef DEBUG_CIRRUS write_log ("READ CR%02X = %02X\n", reg_index, s->vga.cr[s->vga.cr_index]); +#endif return s->vga.cr[s->vga.cr_index]; } -#endif switch (reg_index) { case 0x00: // Standard VGA case 0x01: // Standard VGA diff --git a/qemuvga/vga.cpp b/qemuvga/vga.cpp index bdabcb93..b6335393 100644 --- a/qemuvga/vga.cpp +++ b/qemuvga/vga.cpp @@ -1711,7 +1711,7 @@ static void vga_draw_graphic(VGACommonState *s, int full_update) int width, height, shift_control, line_offset, bwidth, bits; ram_addr_t page0, page1, page_min, page_max; int disp_width, multi_scan, multi_run; - uint8_t *d; + uint8_t *d, *d2; uint32_t v, addr1, addr; vga_draw_line_func *vga_draw_line; #if defined(HOST_WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN) @@ -1867,7 +1867,8 @@ static void vga_draw_graphic(VGACommonState *s, int full_update) d = surface_data(surface); if (!d) return; - linesize = surface_stride(surface); + d2 = d; + linesize = surface_stride(surface); y1 = 0; for(y = 0; y < height; y++) { addr = addr1; @@ -1926,6 +1927,100 @@ static void vga_draw_graphic(VGACommonState *s, int full_update) addr1 = 0; d += linesize; } + + // video window (overlay) + if ((s->cr[0x3e] & 1) && bits >= 8) { + + void copyrow_scale(int monid, uint8_t *src, uint8_t *src_screen, uint8_t *dst, + int sx, int sy, int sxadd, int width, int srcbytesperrow, int srcpixbytes, + int screenbytesperrow, int screenpixbytes, + int dx, int dy, int dstbytesperrow, int dstpixbytes, + bool ck, uint32_t colorkey, + int convert_mode, uint32_t *p96_rgbx16p); + void alloc_colors_picasso(int rw, int gw, int bw, int rs, int gs, int bs, int rgbfmt, uint32_t *rgbx16); + int getconvert(int rgbformat, int pixbytes); + + int outbpp = surface_bits_per_pixel(surface) / 8; + if (!s->cirrus_rgbx16) { + s->cirrus_rgbx16 = (uint32_t*)malloc(65536 * 4); + } + int ovl_format = 5; + if (s->old_ovl_format != ovl_format) { + alloc_colors_picasso(8, 8, 8, 16, 8, 0, ovl_format, s->cirrus_rgbx16); + s->old_ovl_format = ovl_format; + } + + uint32_t gfxbpp = bits; + uint32_t vptr = ((s->cr[0x3c] & 15) << 18) | (s->cr[0x3b] << 10) | (s->cr[0x3a] << 2) | ((s->cr[0x5d] >> 2) & 3); + uint32_t bytesperrow = (((s->cr[0x3c] >> 5) & 1) << 11) | (s->cr[0x3d] << 3); + uint32_t r1sz = s->cr[0x33] | (((s->cr[0x36] >> 0) & 3) << 8); + uint32_t r1adjust = s->cr[0x5d] & 3; + uint32_t r2sz = s->cr[0x34] | (((s->cr[0x36] >> 2) & 3) << 8); + uint32_t r2adjust = (s->cr[0x5d] >> 4) & 3; + uint32_t r2dsz = s->cr[0x35] | (((s->cr[0x36] >> 4) & 3) << 8); + uint32_t wvs = s->cr[0x37] | (((s->cr[0x39] >> 0) & 3) << 8); + uint32_t wve = s->cr[0x38] | (((s->cr[0x39] >> 2) & 3) << 8); + uint32_t format = (s->cr[0x3e] >> 1) & 7; + bool occlusion = ((s->cr[0x3e] >> 7) & 1) != 0 && bits < 24; + uint32_t region1size = 32 * r1sz / gfxbpp + (r1adjust * 8 / gfxbpp); + uint32_t region2size = 32 * r2sz / gfxbpp + (r2adjust * 8 / gfxbpp); + uint32_t hzoom = s->cr[0x31]; + uint32_t vzoom = s->cr[0x32]; + uint32_t colorkey = 0; + + int keymode = (s->cr[0x1d] >> 3) & 7; + // mask and chroma key ignored. + if (keymode == 0) { + colorkey = s->gr[0x0c]; + } else if (keymode == 1) { + colorkey = s->gr[0x0c] | (s->gr[0x0d] << 8); + } else { + occlusion = false; + } + + int overlaybpp = 2; + int overlay_width = overlaybpp * r2dsz; + int vertical_height = wve - wvs + 1; + int convert = getconvert(5, outbpp); + + if (!hzoom) + hzoom = 256; + if (!vzoom) + vzoom = 256; + + int y = 0; + for (int oy = 0; oy < vertical_height; oy++) { + if (vptr + (y >> 8) * bytesperrow > s->vram_size) + break; + if (s->start_addr * 4 + wvs * line_offset > s->vram_size) + break; + if (d2 + wvs * linesize > s->vram_ptr + s->vram_size) + break; + copyrow_scale(s->monid, s->vram_ptr + vptr, s->vram_ptr + s->start_addr * 4, d2, + 0, y >> 8, hzoom, overlay_width, bytesperrow, overlaybpp, + line_offset, bits / 8, + region1size, wvs, linesize, outbpp, + occlusion, colorkey, + convert, s->cirrus_rgbx16); + wvs++; + y += vzoom; + } + + s->last_width = -1; + s->old_overlay = 1; + + if (y_start < 0 || y_start > wvs) + y_start = wvs; + if (y < wve) + y = wve + 1; + + } else if (s->old_overlay) { + + s->old_overlay = 0; + s->last_width = -1; + + } + if (y_start >= 0) { /* flush to display */ dpy_gfx_update(s->con, 0, y_start, diff --git a/qemuvga/vga_int.h b/qemuvga/vga_int.h index e81854a8..f8aeae60 100644 --- a/qemuvga/vga_int.h +++ b/qemuvga/vga_int.h @@ -170,6 +170,11 @@ typedef struct VGACommonState { vga_update_retrace_info_fn update_retrace_info; union vga_retrace retrace_info; uint8_t is_vbe_vmstate; + + uint32_t *cirrus_rgbx16; + int monid; + int old_ovl_format; + int old_overlay; } VGACommonState; STATIC_INLINE int c6_to_8(int v)