trunk/src/emu/video/stvvdp2.c
| r21001 | r21002 | |
| 3004 | 3004 | } |
| 3005 | 3005 | |
| 3006 | 3006 | } |
| 3007 | } |
| 3007 | 3008 | |
| 3009 | void saturn_state::stv_vdp2_drawgfx_alpha(bitmap_rgb32 &dest_bmp,const rectangle &clip,gfx_element *gfx, |
| 3010 | UINT32 code,UINT32 color, int flipx,int flipy,int offsx,int offsy, |
| 3011 | int transparent_color, int alpha) |
| 3012 | { |
| 3013 | const pen_t *pal = &gfx->machine().pens[gfx->colorbase() + gfx->granularity() * (color % gfx->colors())]; |
| 3014 | const UINT8 *source_base = gfx->get_data(code % gfx->elements()); |
| 3015 | int x_index_base, y_index, sx, sy, ex, ey; |
| 3016 | int xinc, yinc; |
| 3017 | |
| 3018 | xinc = flipx ? -1 : 1; |
| 3019 | yinc = flipy ? -1 : 1; |
| 3020 | |
| 3021 | x_index_base = flipx ? gfx->width()-1 : 0; |
| 3022 | y_index = flipy ? gfx->height()-1 : 0; |
| 3023 | |
| 3024 | /* start coordinates */ |
| 3025 | sx = offsx; |
| 3026 | sy = offsy; |
| 3027 | |
| 3028 | /* end coordinates */ |
| 3029 | ex = sx + gfx->width(); |
| 3030 | ey = sy + gfx->height(); |
| 3031 | |
| 3032 | /* clip left */ |
| 3033 | if (sx < clip.min_x) |
| 3034 | { |
| 3035 | int pixels = clip.min_x-sx; |
| 3036 | sx += pixels; |
| 3037 | x_index_base += xinc*pixels; |
| 3038 | } |
| 3039 | |
| 3040 | /* clip top */ |
| 3041 | if (sy < clip.min_y) |
| 3042 | { int pixels = clip.min_y-sy; |
| 3043 | sy += pixels; |
| 3044 | y_index += yinc*pixels; |
| 3045 | } |
| 3046 | |
| 3047 | /* clip right */ |
| 3048 | if (ex > clip.max_x+1) |
| 3049 | { |
| 3050 | ex = clip.max_x+1; |
| 3051 | } |
| 3052 | /* clip bottom */ |
| 3053 | if (ey > clip.max_y+1) |
| 3054 | { |
| 3055 | ey = clip.max_y+1; |
| 3056 | } |
| 3057 | |
| 3058 | /* skip if inner loop doesn't draw anything */ |
| 3059 | if (ex > sx) |
| 3060 | { |
| 3061 | int x, y; |
| 3062 | |
| 3063 | { |
| 3064 | for (y = sy; y < ey; y++) |
| 3065 | { |
| 3066 | const UINT8 *source = source_base + y_index*gfx->rowbytes(); |
| 3067 | UINT32 *dest = &dest_bmp.pix32(y); |
| 3068 | int x_index = x_index_base; |
| 3069 | for (x = sx; x < ex; x++) |
| 3070 | { |
| 3071 | int c = (source[x_index]); |
| 3072 | if (c != transparent_color) |
| 3073 | dest[x] = alpha_blend_r32( dest[x], pal[c], alpha );; |
| 3074 | |
| 3075 | x_index += xinc; |
| 3076 | } |
| 3077 | y_index += yinc; |
| 3078 | } |
| 3079 | } |
| 3080 | } |
| 3008 | 3081 | } |
| 3009 | 3082 | |
| 3083 | void saturn_state::stv_vdp2_drawgfx_transpen(bitmap_rgb32 &dest_bmp,const rectangle &clip,gfx_element *gfx, |
| 3084 | UINT32 code,UINT32 color, int flipx,int flipy,int offsx,int offsy, |
| 3085 | int transparent_color) |
| 3086 | { |
| 3087 | const pen_t *pal = &gfx->machine().pens[gfx->colorbase() + gfx->granularity() * (color % gfx->colors())]; |
| 3088 | const UINT8 *source_base = gfx->get_data(code % gfx->elements()); |
| 3089 | int x_index_base, y_index, sx, sy, ex, ey; |
| 3090 | int xinc, yinc; |
| 3091 | |
| 3092 | xinc = flipx ? -1 : 1; |
| 3093 | yinc = flipy ? -1 : 1; |
| 3094 | |
| 3095 | x_index_base = flipx ? gfx->width()-1 : 0; |
| 3096 | y_index = flipy ? gfx->height()-1 : 0; |
| 3097 | |
| 3098 | /* start coordinates */ |
| 3099 | sx = offsx; |
| 3100 | sy = offsy; |
| 3101 | |
| 3102 | /* end coordinates */ |
| 3103 | ex = sx + gfx->width(); |
| 3104 | ey = sy + gfx->height(); |
| 3105 | |
| 3106 | /* clip left */ |
| 3107 | if (sx < clip.min_x) |
| 3108 | { |
| 3109 | int pixels = clip.min_x-sx; |
| 3110 | sx += pixels; |
| 3111 | x_index_base += xinc*pixels; |
| 3112 | } |
| 3113 | |
| 3114 | /* clip top */ |
| 3115 | if (sy < clip.min_y) |
| 3116 | { int pixels = clip.min_y-sy; |
| 3117 | sy += pixels; |
| 3118 | y_index += yinc*pixels; |
| 3119 | } |
| 3120 | |
| 3121 | /* clip right */ |
| 3122 | if (ex > clip.max_x+1) |
| 3123 | { |
| 3124 | ex = clip.max_x+1; |
| 3125 | } |
| 3126 | /* clip bottom */ |
| 3127 | if (ey > clip.max_y+1) |
| 3128 | { |
| 3129 | ey = clip.max_y+1; |
| 3130 | } |
| 3131 | |
| 3132 | /* skip if inner loop doesn't draw anything */ |
| 3133 | if (ex > sx) |
| 3134 | { |
| 3135 | int x, y; |
| 3136 | |
| 3137 | { |
| 3138 | for (y = sy; y < ey; y++) |
| 3139 | { |
| 3140 | const UINT8 *source = source_base + y_index*gfx->rowbytes(); |
| 3141 | UINT32 *dest = &dest_bmp.pix32(y); |
| 3142 | int x_index = x_index_base; |
| 3143 | for (x = sx; x < ex; x++) |
| 3144 | { |
| 3145 | if(!stv_vdp2_window_process(x,y)) |
| 3146 | continue; |
| 3147 | |
| 3148 | int c = (source[x_index]); |
| 3149 | if (c != transparent_color) |
| 3150 | dest[x] = pal[c]; |
| 3151 | |
| 3152 | x_index += xinc; |
| 3153 | } |
| 3154 | y_index += yinc; |
| 3155 | } |
| 3156 | } |
| 3157 | } |
| 3158 | } |
| 3159 | |
| 3010 | 3160 | void saturn_state::draw_4bpp_bitmap(bitmap_rgb32 &bitmap, const rectangle &cliprect) |
| 3011 | 3161 | { |
| 3012 | 3162 | int xsize, ysize, xsize_mask, ysize_mask; |
| r21001 | r21002 | |
| 3036 | 3186 | { |
| 3037 | 3187 | for(xdst=cliprect.min_x;xdst<=cliprect.max_x;xdst++) |
| 3038 | 3188 | { |
| 3039 | | if(stv_vdp2_window_process(xdst,ydst)) |
| 3189 | if(!stv_vdp2_window_process(xdst,ydst)) |
| 3040 | 3190 | continue; |
| 3041 | 3191 | |
| 3042 | 3192 | xsrc = (xdst + scrollx) & (xsize_mask-1); |
| r21001 | r21002 | |
| 3093 | 3243 | { |
| 3094 | 3244 | for(xdst=cliprect.min_x;xdst<=cliprect.max_x;xdst++) |
| 3095 | 3245 | { |
| 3096 | | if(stv_vdp2_window_process(xdst,ydst)) |
| 3246 | if(!stv_vdp2_window_process(xdst,ydst)) |
| 3097 | 3247 | continue; |
| 3098 | 3248 | |
| 3099 | 3249 | xf = stv2_current_tilemap.incx * xdst; |
| r21001 | r21002 | |
| 3145 | 3295 | { |
| 3146 | 3296 | for(xdst=cliprect.min_x;xdst<=cliprect.max_x;xdst++) |
| 3147 | 3297 | { |
| 3148 | | if(stv_vdp2_window_process(xdst,ydst)) |
| 3298 | if(!stv_vdp2_window_process(xdst,ydst)) |
| 3149 | 3299 | continue; |
| 3150 | 3300 | |
| 3151 | 3301 | xf = stv2_current_tilemap.incx * xdst; |
| r21001 | r21002 | |
| 3202 | 3352 | { |
| 3203 | 3353 | for(xdst=cliprect.min_x;xdst<=cliprect.max_x;xdst++) |
| 3204 | 3354 | { |
| 3205 | | if(stv_vdp2_window_process(xdst,ydst)) |
| 3355 | if(!stv_vdp2_window_process(xdst,ydst)) |
| 3206 | 3356 | continue; |
| 3207 | 3357 | |
| 3208 | 3358 | xsrc = (xdst + scrollx) & (xsize_mask-1); |
| r21001 | r21002 | |
| 4207 | 4357 | else if (stv2_current_tilemap.transparency == STV_TRANSPARENCY_ALPHA) |
| 4208 | 4358 | { |
| 4209 | 4359 | /* alpha */ |
| 4210 | | drawgfx_alpha(bitmap,cliprect,machine().gfx[gfx],tilecode+(0+(flipyx&1)+(flipyx&2))*tilecodespacing,pal,flipyx&1,flipyx&2,drawxpos, drawypos,0,stv2_current_tilemap.alpha); |
| 4211 | | drawgfx_alpha(bitmap,cliprect,machine().gfx[gfx],tilecode+(1-(flipyx&1)+(flipyx&2))*tilecodespacing,pal,flipyx&1,flipyx&2,drawxpos+8,drawypos,0,stv2_current_tilemap.alpha); |
| 4212 | | drawgfx_alpha(bitmap,cliprect,machine().gfx[gfx],tilecode+(2+(flipyx&1)-(flipyx&2))*tilecodespacing,pal,flipyx&1,flipyx&2,drawxpos,drawypos+8,0,stv2_current_tilemap.alpha); |
| 4213 | | drawgfx_alpha(bitmap,cliprect,machine().gfx[gfx],tilecode+(3-(flipyx&1)-(flipyx&2))*tilecodespacing,pal,flipyx&1,flipyx&2,drawxpos+8,drawypos+8,0,stv2_current_tilemap.alpha); |
| 4360 | stv_vdp2_drawgfx_alpha(bitmap,cliprect,machine().gfx[gfx],tilecode+(0+(flipyx&1)+(flipyx&2))*tilecodespacing,pal,flipyx&1,flipyx&2,drawxpos, drawypos,0,stv2_current_tilemap.alpha); |
| 4361 | stv_vdp2_drawgfx_alpha(bitmap,cliprect,machine().gfx[gfx],tilecode+(1-(flipyx&1)+(flipyx&2))*tilecodespacing,pal,flipyx&1,flipyx&2,drawxpos+8,drawypos,0,stv2_current_tilemap.alpha); |
| 4362 | stv_vdp2_drawgfx_alpha(bitmap,cliprect,machine().gfx[gfx],tilecode+(2+(flipyx&1)-(flipyx&2))*tilecodespacing,pal,flipyx&1,flipyx&2,drawxpos,drawypos+8,0,stv2_current_tilemap.alpha); |
| 4363 | stv_vdp2_drawgfx_alpha(bitmap,cliprect,machine().gfx[gfx],tilecode+(3-(flipyx&1)-(flipyx&2))*tilecodespacing,pal,flipyx&1,flipyx&2,drawxpos+8,drawypos+8,0,stv2_current_tilemap.alpha); |
| 4214 | 4364 | } |
| 4215 | 4365 | else |
| 4216 | 4366 | { |
| 4217 | 4367 | /* normal */ |
| 4218 | | drawgfx_transpen(bitmap,cliprect,machine().gfx[gfx],tilecode+(0+(flipyx&1)+(flipyx&2))*tilecodespacing,pal,flipyx&1,flipyx&2,drawxpos, drawypos,(stv2_current_tilemap.transparency==STV_TRANSPARENCY_PEN)?0:-1); |
| 4219 | | drawgfx_transpen(bitmap,cliprect,machine().gfx[gfx],tilecode+(1-(flipyx&1)+(flipyx&2))*tilecodespacing,pal,flipyx&1,flipyx&2,drawxpos+8,drawypos,(stv2_current_tilemap.transparency==STV_TRANSPARENCY_PEN)?0:-1); |
| 4220 | | drawgfx_transpen(bitmap,cliprect,machine().gfx[gfx],tilecode+(2+(flipyx&1)-(flipyx&2))*tilecodespacing,pal,flipyx&1,flipyx&2,drawxpos,drawypos+8,(stv2_current_tilemap.transparency==STV_TRANSPARENCY_PEN)?0:-1); |
| 4221 | | drawgfx_transpen(bitmap,cliprect,machine().gfx[gfx],tilecode+(3-(flipyx&1)-(flipyx&2))*tilecodespacing,pal,flipyx&1,flipyx&2,drawxpos+8,drawypos+8,(stv2_current_tilemap.transparency==STV_TRANSPARENCY_PEN)?0:-1); |
| 4368 | stv_vdp2_drawgfx_transpen(bitmap,cliprect,machine().gfx[gfx],tilecode+(0+(flipyx&1)+(flipyx&2))*tilecodespacing,pal,flipyx&1,flipyx&2,drawxpos, drawypos,(stv2_current_tilemap.transparency==STV_TRANSPARENCY_PEN)?0:-1); |
| 4369 | stv_vdp2_drawgfx_transpen(bitmap,cliprect,machine().gfx[gfx],tilecode+(1-(flipyx&1)+(flipyx&2))*tilecodespacing,pal,flipyx&1,flipyx&2,drawxpos+8,drawypos,(stv2_current_tilemap.transparency==STV_TRANSPARENCY_PEN)?0:-1); |
| 4370 | stv_vdp2_drawgfx_transpen(bitmap,cliprect,machine().gfx[gfx],tilecode+(2+(flipyx&1)-(flipyx&2))*tilecodespacing,pal,flipyx&1,flipyx&2,drawxpos,drawypos+8,(stv2_current_tilemap.transparency==STV_TRANSPARENCY_PEN)?0:-1); |
| 4371 | stv_vdp2_drawgfx_transpen(bitmap,cliprect,machine().gfx[gfx],tilecode+(3-(flipyx&1)-(flipyx&2))*tilecodespacing,pal,flipyx&1,flipyx&2,drawxpos+8,drawypos+8,(stv2_current_tilemap.transparency==STV_TRANSPARENCY_PEN)?0:-1); |
| 4222 | 4372 | } |
| 4223 | 4373 | } |
| 4224 | 4374 | else |
| r21001 | r21002 | |
| 4234 | 4384 | else |
| 4235 | 4385 | { |
| 4236 | 4386 | if (stv2_current_tilemap.transparency == STV_TRANSPARENCY_ALPHA) |
| 4237 | | drawgfx_alpha(bitmap,cliprect,machine().gfx[gfx],tilecode,pal,flipyx&1,flipyx&2, drawxpos, drawypos,0,stv2_current_tilemap.alpha); |
| 4387 | stv_vdp2_drawgfx_alpha(bitmap,cliprect,machine().gfx[gfx],tilecode,pal,flipyx&1,flipyx&2, drawxpos, drawypos,0,stv2_current_tilemap.alpha); |
| 4238 | 4388 | else |
| 4239 | | drawgfx_transpen(bitmap,cliprect,machine().gfx[gfx],tilecode,pal,flipyx&1,flipyx&2, drawxpos, drawypos,(stv2_current_tilemap.transparency==STV_TRANSPARENCY_PEN)?0:-1); |
| 4389 | stv_vdp2_drawgfx_transpen(bitmap,cliprect,machine().gfx[gfx],tilecode,pal,flipyx&1,flipyx&2, drawxpos, drawypos,(stv2_current_tilemap.transparency==STV_TRANSPARENCY_PEN)?0:-1); |
| 4240 | 4390 | } |
| 4241 | 4391 | } |
| 4242 | 4392 | drawxpos = olddrawxpos; |
| r21001 | r21002 | |
| 4426 | 4576 | } |
| 4427 | 4577 | else |
| 4428 | 4578 | { |
| 4429 | | stv_vdp2_apply_window_on_layer(mycliprect); |
| 4579 | //stv_vdp2_apply_window_on_layer(mycliprect); |
| 4430 | 4580 | stv_vdp2_draw_basic_tilemap(bitmap, mycliprect); |
| 4431 | 4581 | } |
| 4432 | 4582 | |
| r21001 | r21002 | |
| 4518 | 4668 | |
| 4519 | 4669 | if (stv2_current_tilemap.bitmap_enable) // this layer is a bitmap |
| 4520 | 4670 | { |
| 4521 | | /*elandore doesn't like current cliprect code,will be worked on...*/ |
| 4522 | | //if ( window_applied && stv2_current_tilemap.colour_depth != 4) |
| 4523 | | // stv2_current_tilemap.window_control = 0; |
| 4524 | | |
| 4525 | 4671 | stv_vdp2_draw_basic_bitmap(bitmap, mycliprect); |
| 4526 | 4672 | } |
| 4527 | 4673 | else |
| 4528 | 4674 | { |
| 4529 | | stv_vdp2_apply_window_on_layer(mycliprect); |
| 4675 | //stv_vdp2_apply_window_on_layer(mycliprect); |
| 4530 | 4676 | stv_vdp2_draw_basic_tilemap(bitmap, mycliprect); |
| 4531 | 4677 | } |
| 4532 | 4678 | |
| r21001 | r21002 | |
| 6296 | 6442 | (0 = OR,1 = AND) |
| 6297 | 6443 | ******************************************************************************************/ |
| 6298 | 6444 | |
| 6299 | | void saturn_state::stv_vdp2_get_window0_coordinates(UINT16 *s_x, UINT16 *e_x, UINT16 *s_y, UINT16 *e_y) |
| 6445 | void saturn_state::stv_vdp2_get_window0_coordinates(int *s_x, int *e_x, int *s_y, int *e_y) |
| 6300 | 6446 | { |
| 6301 | 6447 | /*W0*/ |
| 6302 | 6448 | switch(STV_VDP2_LSMD & 3) |
| r21001 | r21002 | |
| 6341 | 6487 | } |
| 6342 | 6488 | } |
| 6343 | 6489 | |
| 6344 | | void saturn_state::stv_vdp2_get_window1_coordinates(UINT16 *s_x, UINT16 *e_x, UINT16 *s_y, UINT16 *e_y) |
| 6490 | void saturn_state::stv_vdp2_get_window1_coordinates(int *s_x, int *e_x, int *s_y, int *e_y) |
| 6345 | 6491 | { |
| 6346 | 6492 | /*W1*/ |
| 6347 | 6493 | switch(STV_VDP2_LSMD & 3) |
| r21001 | r21002 | |
| 6387 | 6533 | |
| 6388 | 6534 | } |
| 6389 | 6535 | |
| 6390 | | int saturn_state::get_window_pixel(UINT16 s_x,UINT16 e_x,UINT16 s_y,UINT16 e_y,int x, int y,UINT8 win_num) |
| 6536 | int saturn_state::get_window_pixel(int s_x,int e_x,int s_y,int e_y,int x, int y,UINT8 win_num) |
| 6391 | 6537 | { |
| 6538 | int res; |
| 6539 | |
| 6540 | res = 1; |
| 6392 | 6541 | if(stv2_current_tilemap.window_control & (2 << win_num)) |
| 6393 | 6542 | { |
| 6394 | | /*Outside Area*/ |
| 6395 | 6543 | if(stv2_current_tilemap.window_control & (0x10 << win_num)) |
| 6396 | | { |
| 6397 | | if(y < s_y || y > e_y) |
| 6398 | | return 1; |
| 6399 | | else |
| 6400 | | { |
| 6401 | | if(x < s_x || x > e_x) |
| 6402 | | return 1; |
| 6403 | | //else |
| 6404 | | // return 0; |
| 6405 | | } |
| 6406 | | } |
| 6407 | | /*Inside Area*/ |
| 6544 | res = (y >= s_y && y <= e_y && x >= s_x && x <= e_x); |
| 6408 | 6545 | else |
| 6409 | | { |
| 6410 | | if(y > s_y && y < e_y) |
| 6411 | | { |
| 6412 | | if(x > s_x && x < e_x) |
| 6413 | | return 1; |
| 6414 | | } |
| 6415 | | //else |
| 6416 | | // return 0; |
| 6417 | | } |
| 6546 | res = (y >= s_y && y <= e_y && x >= s_x && x <= e_x) ^ 1; |
| 6418 | 6547 | } |
| 6419 | 6548 | |
| 6420 | | return 0; |
| 6549 | return res; |
| 6421 | 6550 | } |
| 6422 | 6551 | |
| 6423 | 6552 | int saturn_state::stv_vdp2_window_process(int x,int y) |
| 6424 | 6553 | { |
| 6425 | | UINT16 s_x=0,e_x=0,s_y=0,e_y=0; |
| 6426 | | UINT8 w0_pix, w1_pix; |
| 6554 | int s_x=0,e_x=0,s_y=0,e_y=0; |
| 6555 | int w0_pix, w1_pix; |
| 6427 | 6556 | |
| 6428 | 6557 | if ((stv2_current_tilemap.window_control & 6) == 0) |
| 6429 | | return 0; |
| 6558 | return 1; |
| 6430 | 6559 | |
| 6431 | 6560 | stv_vdp2_get_window0_coordinates(&s_x, &e_x, &s_y, &e_y); |
| 6432 | 6561 | w0_pix = get_window_pixel(s_x,e_x,s_y,e_y,x,y,0); |
| r21001 | r21002 | |
| 6434 | 6563 | stv_vdp2_get_window1_coordinates(&s_x, &e_x, &s_y, &e_y); |
| 6435 | 6564 | w1_pix = get_window_pixel(s_x,e_x,s_y,e_y,x,y,1); |
| 6436 | 6565 | |
| 6437 | | return stv2_current_tilemap.window_control & 1 ? (w0_pix & w1_pix) : (w0_pix | w1_pix); |
| 6566 | return stv2_current_tilemap.window_control & 1 ? (w0_pix | w1_pix) : (w0_pix & w1_pix); |
| 6438 | 6567 | } |
| 6439 | 6568 | |
| 6440 | 6569 | int saturn_state::stv_vdp2_apply_window_on_layer(rectangle &cliprect) |
| 6441 | 6570 | { |
| 6442 | | UINT16 s_x=0,e_x=0,s_y=0,e_y=0; |
| 6571 | int s_x=0,e_x=0,s_y=0,e_y=0; |
| 6443 | 6572 | |
| 6444 | 6573 | if ( stv2_current_tilemap.window_control == 0x12 ) |
| 6445 | 6574 | { |