]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
Picasso IV hardware overlay support, overlay color key updates.
authorToni Wilen <twilen@winuae.net>
Sun, 6 Jan 2019 08:55:30 +0000 (10:55 +0200)
committerToni Wilen <twilen@winuae.net>
Sun, 6 Jan 2019 08:55:30 +0000 (10:55 +0200)
gfxboard.cpp
od-win32/picasso96_win.cpp
qemuvga/cirrus_vga.cpp
qemuvga/vga.cpp
qemuvga/vga_int.h

index c5f998bca579206768dc53dc3365778592a7e74d..d2e35a433b98cf87bff639662bf5fe16b6902149 100644 (file)
@@ -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);
 }
 
index ced124bea72a51e3473b7ac068a3417883177839..52650fe20ba0f9097eab1085cd7886c1078ffd64 100644 (file)
@@ -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;
        }
 }
index de66a825106c7f34306f9f901dfe76c9fefef4f7..a677878dcd47687dc84f6fd7335feb474a137f65 100644 (file)
@@ -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
index bdabcb93eade758f4e874567eb7b03d0d153804c..b63353937b65e6548a974a79c05ea2d67184dfa5 100644 (file)
@@ -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,
index e81854a83844a41ed1cff90583feeca9b1e24a61..f8aeae6096aee1f0197567abb0fded3f93ab6e89 100644 (file)
@@ -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)