Commit 96cf2df87cf9e3c39b147ee85b2e90d3620bdd41
1 parent
2bb081f7
Cirrus transparent BITBLT (w/o color expand), by Hitoshi Osada.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3101 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
2 changed files
with
172 additions
and
10 deletions
hw/cirrus_vga.c
| ... | ... | @@ -402,7 +402,54 @@ static const cirrus_bitblt_rop_t cirrus_bkwd_rop[16] = { |
| 402 | 402 | cirrus_bitblt_rop_bkwd_notsrc_or_dst, |
| 403 | 403 | cirrus_bitblt_rop_bkwd_notsrc_and_notdst, |
| 404 | 404 | }; |
| 405 | - | |
| 405 | + | |
| 406 | +#define TRANSP_ROP(name) {\ | |
| 407 | + name ## _8,\ | |
| 408 | + name ## _16,\ | |
| 409 | + } | |
| 410 | +#define TRANSP_NOP(func) {\ | |
| 411 | + func,\ | |
| 412 | + func,\ | |
| 413 | + } | |
| 414 | + | |
| 415 | +static const cirrus_bitblt_rop_t cirrus_fwd_transp_rop[16][2] = { | |
| 416 | + TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_0), | |
| 417 | + TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src_and_dst), | |
| 418 | + TRANSP_NOP(cirrus_bitblt_rop_nop), | |
| 419 | + TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src_and_notdst), | |
| 420 | + TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_notdst), | |
| 421 | + TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src), | |
| 422 | + TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_1), | |
| 423 | + TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_notsrc_and_dst), | |
| 424 | + TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src_xor_dst), | |
| 425 | + TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src_or_dst), | |
| 426 | + TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_notsrc_or_notdst), | |
| 427 | + TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src_notxor_dst), | |
| 428 | + TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src_or_notdst), | |
| 429 | + TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_notsrc), | |
| 430 | + TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_notsrc_or_dst), | |
| 431 | + TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_notsrc_and_notdst), | |
| 432 | +}; | |
| 433 | + | |
| 434 | +static const cirrus_bitblt_rop_t cirrus_bkwd_transp_rop[16][2] = { | |
| 435 | + TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_0), | |
| 436 | + TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src_and_dst), | |
| 437 | + TRANSP_NOP(cirrus_bitblt_rop_nop), | |
| 438 | + TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src_and_notdst), | |
| 439 | + TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_notdst), | |
| 440 | + TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src), | |
| 441 | + TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_1), | |
| 442 | + TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_notsrc_and_dst), | |
| 443 | + TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src_xor_dst), | |
| 444 | + TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src_or_dst), | |
| 445 | + TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_notsrc_or_notdst), | |
| 446 | + TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src_notxor_dst), | |
| 447 | + TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src_or_notdst), | |
| 448 | + TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_notsrc), | |
| 449 | + TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_notsrc_or_dst), | |
| 450 | + TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_notsrc_and_notdst), | |
| 451 | +}; | |
| 452 | + | |
| 406 | 453 | #define ROP2(name) {\ |
| 407 | 454 | name ## _8,\ |
| 408 | 455 | name ## _16,\ |
| ... | ... | @@ -950,15 +997,28 @@ static void cirrus_bitblt_start(CirrusVGAState * s) |
| 950 | 997 | s->cirrus_rop = cirrus_patternfill[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1]; |
| 951 | 998 | } |
| 952 | 999 | } else { |
| 953 | - if (s->cirrus_blt_mode & CIRRUS_BLTMODE_BACKWARDS) { | |
| 954 | - s->cirrus_blt_dstpitch = -s->cirrus_blt_dstpitch; | |
| 955 | - s->cirrus_blt_srcpitch = -s->cirrus_blt_srcpitch; | |
| 956 | - s->cirrus_rop = cirrus_bkwd_rop[rop_to_index[blt_rop]]; | |
| 957 | - } else { | |
| 958 | - s->cirrus_rop = cirrus_fwd_rop[rop_to_index[blt_rop]]; | |
| 959 | - } | |
| 960 | - } | |
| 961 | - | |
| 1000 | + if (s->cirrus_blt_mode & CIRRUS_BLTMODE_TRANSPARENTCOMP) { | |
| 1001 | + if (s->cirrus_blt_pixelwidth > 2) { | |
| 1002 | + printf("src transparent without colorexpand must be 8bpp or 16bpp\n"); | |
| 1003 | + goto bitblt_ignore; | |
| 1004 | + } | |
| 1005 | + if (s->cirrus_blt_mode & CIRRUS_BLTMODE_BACKWARDS) { | |
| 1006 | + s->cirrus_blt_dstpitch = -s->cirrus_blt_dstpitch; | |
| 1007 | + s->cirrus_blt_srcpitch = -s->cirrus_blt_srcpitch; | |
| 1008 | + s->cirrus_rop = cirrus_bkwd_transp_rop[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1]; | |
| 1009 | + } else { | |
| 1010 | + s->cirrus_rop = cirrus_fwd_transp_rop[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1]; | |
| 1011 | + } | |
| 1012 | + } else { | |
| 1013 | + if (s->cirrus_blt_mode & CIRRUS_BLTMODE_BACKWARDS) { | |
| 1014 | + s->cirrus_blt_dstpitch = -s->cirrus_blt_dstpitch; | |
| 1015 | + s->cirrus_blt_srcpitch = -s->cirrus_blt_srcpitch; | |
| 1016 | + s->cirrus_rop = cirrus_bkwd_rop[rop_to_index[blt_rop]]; | |
| 1017 | + } else { | |
| 1018 | + s->cirrus_rop = cirrus_fwd_rop[rop_to_index[blt_rop]]; | |
| 1019 | + } | |
| 1020 | + } | |
| 1021 | + } | |
| 962 | 1022 | // setup bitblt engine. |
| 963 | 1023 | if (s->cirrus_blt_mode & CIRRUS_BLTMODE_MEMSYSSRC) { |
| 964 | 1024 | if (!cirrus_bitblt_cputovideo(s)) | ... | ... |
hw/cirrus_vga_rop.h
| ... | ... | @@ -62,6 +62,108 @@ glue(cirrus_bitblt_rop_bkwd_, ROP_NAME)(CirrusVGAState *s, |
| 62 | 62 | } |
| 63 | 63 | } |
| 64 | 64 | |
| 65 | +static void | |
| 66 | +glue(glue(cirrus_bitblt_rop_fwd_transp_, ROP_NAME),_8)(CirrusVGAState *s, | |
| 67 | + uint8_t *dst,const uint8_t *src, | |
| 68 | + int dstpitch,int srcpitch, | |
| 69 | + int bltwidth,int bltheight) | |
| 70 | +{ | |
| 71 | + int x,y; | |
| 72 | + uint8_t p; | |
| 73 | + dstpitch -= bltwidth; | |
| 74 | + srcpitch -= bltwidth; | |
| 75 | + for (y = 0; y < bltheight; y++) { | |
| 76 | + for (x = 0; x < bltwidth; x++) { | |
| 77 | + p = *dst; | |
| 78 | + ROP_OP(p, *src); | |
| 79 | + if (p != s->gr[0x34]) *dst = p; | |
| 80 | + dst++; | |
| 81 | + src++; | |
| 82 | + } | |
| 83 | + dst += dstpitch; | |
| 84 | + src += srcpitch; | |
| 85 | + } | |
| 86 | +} | |
| 87 | + | |
| 88 | +static void | |
| 89 | +glue(glue(cirrus_bitblt_rop_bkwd_transp_, ROP_NAME),_8)(CirrusVGAState *s, | |
| 90 | + uint8_t *dst,const uint8_t *src, | |
| 91 | + int dstpitch,int srcpitch, | |
| 92 | + int bltwidth,int bltheight) | |
| 93 | +{ | |
| 94 | + int x,y; | |
| 95 | + uint8_t p; | |
| 96 | + dstpitch += bltwidth; | |
| 97 | + srcpitch += bltwidth; | |
| 98 | + for (y = 0; y < bltheight; y++) { | |
| 99 | + for (x = 0; x < bltwidth; x++) { | |
| 100 | + p = *dst; | |
| 101 | + ROP_OP(p, *src); | |
| 102 | + if (p != s->gr[0x34]) *dst = p; | |
| 103 | + dst--; | |
| 104 | + src--; | |
| 105 | + } | |
| 106 | + dst += dstpitch; | |
| 107 | + src += srcpitch; | |
| 108 | + } | |
| 109 | +} | |
| 110 | + | |
| 111 | +static void | |
| 112 | +glue(glue(cirrus_bitblt_rop_fwd_transp_, ROP_NAME),_16)(CirrusVGAState *s, | |
| 113 | + uint8_t *dst,const uint8_t *src, | |
| 114 | + int dstpitch,int srcpitch, | |
| 115 | + int bltwidth,int bltheight) | |
| 116 | +{ | |
| 117 | + int x,y; | |
| 118 | + uint8_t p1, p2; | |
| 119 | + dstpitch -= bltwidth; | |
| 120 | + srcpitch -= bltwidth; | |
| 121 | + for (y = 0; y < bltheight; y++) { | |
| 122 | + for (x = 0; x < bltwidth; x+=2) { | |
| 123 | + p1 = *dst; | |
| 124 | + p2 = *(dst+1); | |
| 125 | + ROP_OP(p1, *src); | |
| 126 | + ROP_OP(p2, *(src+1)); | |
| 127 | + if ((p1 != s->gr[0x34]) || (p2 != s->gr[0x35])) { | |
| 128 | + *dst = p1; | |
| 129 | + *(dst+1) = p2; | |
| 130 | + } | |
| 131 | + dst+=2; | |
| 132 | + src+=2; | |
| 133 | + } | |
| 134 | + dst += dstpitch; | |
| 135 | + src += srcpitch; | |
| 136 | + } | |
| 137 | +} | |
| 138 | + | |
| 139 | +static void | |
| 140 | +glue(glue(cirrus_bitblt_rop_bkwd_transp_, ROP_NAME),_16)(CirrusVGAState *s, | |
| 141 | + uint8_t *dst,const uint8_t *src, | |
| 142 | + int dstpitch,int srcpitch, | |
| 143 | + int bltwidth,int bltheight) | |
| 144 | +{ | |
| 145 | + int x,y; | |
| 146 | + uint8_t p1, p2; | |
| 147 | + dstpitch += bltwidth; | |
| 148 | + srcpitch += bltwidth; | |
| 149 | + for (y = 0; y < bltheight; y++) { | |
| 150 | + for (x = 0; x < bltwidth; x+=2) { | |
| 151 | + p1 = *(dst-1); | |
| 152 | + p2 = *dst; | |
| 153 | + ROP_OP(p1, *(src-1)); | |
| 154 | + ROP_OP(p2, *src); | |
| 155 | + if ((p1 != s->gr[0x34]) || (p2 != s->gr[0x35])) { | |
| 156 | + *(dst-1) = p1; | |
| 157 | + *dst = p2; | |
| 158 | + } | |
| 159 | + dst-=2; | |
| 160 | + src-=2; | |
| 161 | + } | |
| 162 | + dst += dstpitch; | |
| 163 | + src += srcpitch; | |
| 164 | + } | |
| 165 | +} | |
| 166 | + | |
| 65 | 167 | #define DEPTH 8 |
| 66 | 168 | #include "cirrus_vga_rop2.h" |
| 67 | 169 | ... | ... |