trunk/src/mame/video/deco_mlc.c
| r21877 | r21878 | |
| 59 | 59 | } |
| 60 | 60 | #endif |
| 61 | 61 | |
| 62 | | static void mlc_drawgfxzoom( |
| 62 | static void mlc_drawgfxzoomline( |
| 63 | 63 | bitmap_rgb32 &dest_bmp,const rectangle &clip,gfx_element *gfx, |
| 64 | | UINT32 code1,UINT32 code2, UINT32 color,int flipx,int flipy,int sx,int sy, |
| 64 | UINT32 code1,UINT32 code2, UINT32 color,int flipx,int sx, |
| 65 | 65 | int transparent_color,int use8bpp, |
| 66 | | int scalex, int scaley,int alpha) |
| 66 | int scalex, int alpha, int usey, int srcline ) |
| 67 | 67 | { |
| 68 | 68 | rectangle myclip; |
| 69 | 69 | |
| 70 | | if (!scalex || !scaley) return; |
| 70 | if (!scalex) return; |
| 71 | 71 | |
| 72 | 72 | /* |
| 73 | 73 | scalex and scaley are 16.16 fixed point numbers |
| r21877 | r21878 | |
| 80 | 80 | myclip = clip; |
| 81 | 81 | myclip &= dest_bmp.cliprect(); |
| 82 | 82 | |
| 83 | |
| 84 | const pen_t *pal = &gfx->machine().pens[gfx->colorbase() + gfx->granularity() * (color % gfx->colors())]; |
| 85 | const UINT8 *code_base1 = gfx->get_data(code1 % gfx->elements()); |
| 86 | const UINT8 *code_base2 = gfx->get_data(code2 % gfx->elements()); |
| 87 | |
| 88 | int sprite_screen_width = (scalex*16+(sx&0xffff))>>16; |
| 89 | |
| 90 | sx>>=16; |
| 91 | int sy = usey; |
| 92 | if (sprite_screen_width) |
| 83 | 93 | { |
| 84 | | if( gfx ) |
| 94 | /* compute sprite increment per screen pixel */ |
| 95 | int dx = (16<<16)/sprite_screen_width; |
| 96 | |
| 97 | int ex = sx+sprite_screen_width; |
| 98 | |
| 99 | int x_index_base; |
| 100 | |
| 101 | if( flipx ) |
| 85 | 102 | { |
| 86 | | const pen_t *pal = &gfx->machine().pens[gfx->colorbase() + gfx->granularity() * (color % gfx->colors())]; |
| 87 | | const UINT8 *code_base1 = gfx->get_data(code1 % gfx->elements()); |
| 88 | | const UINT8 *code_base2 = gfx->get_data(code2 % gfx->elements()); |
| 103 | x_index_base = (sprite_screen_width-1)*dx; |
| 104 | dx = -dx; |
| 105 | } |
| 106 | else |
| 107 | { |
| 108 | x_index_base = 0; |
| 109 | } |
| 89 | 110 | |
| 90 | | int sprite_screen_height = (scaley*gfx->height()+(sy&0xffff))>>16; |
| 91 | | int sprite_screen_width = (scalex*gfx->width()+(sx&0xffff))>>16; |
| 92 | 111 | |
| 93 | | sx>>=16; |
| 94 | | sy>>=16; |
| 95 | 112 | |
| 96 | | if (sprite_screen_width && sprite_screen_height) |
| 97 | | { |
| 98 | | /* compute sprite increment per screen pixel */ |
| 99 | | int dx = (gfx->width()<<16)/sprite_screen_width; |
| 100 | | int dy = (gfx->height()<<16)/sprite_screen_height; |
| 113 | if( sx < myclip.min_x) |
| 114 | { /* clip left */ |
| 115 | int pixels = myclip.min_x-sx; |
| 116 | sx += pixels; |
| 117 | x_index_base += pixels*dx; |
| 118 | } |
| 119 | /* NS 980211 - fixed incorrect clipping */ |
| 120 | if( ex > myclip.max_x+1 ) |
| 121 | { /* clip right */ |
| 122 | int pixels = ex-myclip.max_x-1; |
| 123 | ex -= pixels; |
| 124 | } |
| 101 | 125 | |
| 102 | | int ex = sx+sprite_screen_width; |
| 103 | | int ey = sy+sprite_screen_height; |
| 126 | if( ex>sx ) |
| 127 | { /* skip if inner loop doesn't draw anything */ |
| 128 | int y; |
| 104 | 129 | |
| 105 | | int x_index_base; |
| 106 | | int y_index; |
| 130 | /* case 1: no alpha */ |
| 131 | if (alpha == 0xff) |
| 132 | { |
| 133 | y = sy; |
| 107 | 134 | |
| 108 | | if( flipx ) |
| 109 | | { |
| 110 | | x_index_base = (sprite_screen_width-1)*dx; |
| 111 | | dx = -dx; |
| 112 | | } |
| 113 | | else |
| 114 | | { |
| 115 | | x_index_base = 0; |
| 116 | | } |
| 135 | if( y < myclip.min_y ) |
| 136 | return; |
| 117 | 137 | |
| 118 | | if( flipy ) |
| 138 | if( y > myclip.max_y+1 ) |
| 139 | return; |
| 140 | |
| 141 | |
| 142 | |
| 119 | 143 | { |
| 120 | | y_index = (sprite_screen_height-1)*dy; |
| 121 | | dy = -dy; |
| 122 | | } |
| 123 | | else |
| 124 | | { |
| 125 | | y_index = 0; |
| 126 | | } |
| 144 | const UINT8 *source1 = code_base1 + (srcline) * gfx->rowbytes(); |
| 145 | const UINT8 *source2 = code_base2 + (srcline) * gfx->rowbytes(); |
| 146 | UINT32 *dest = &dest_bmp.pix32(y); |
| 127 | 147 | |
| 128 | | if( sx < myclip.min_x) |
| 129 | | { /* clip left */ |
| 130 | | int pixels = myclip.min_x-sx; |
| 131 | | sx += pixels; |
| 132 | | x_index_base += pixels*dx; |
| 133 | | } |
| 134 | | if( sy < myclip.min_y ) |
| 135 | | { /* clip top */ |
| 136 | | int pixels = myclip.min_y-sy; |
| 137 | | sy += pixels; |
| 138 | | y_index += pixels*dy; |
| 139 | | } |
| 140 | | /* NS 980211 - fixed incorrect clipping */ |
| 141 | | if( ex > myclip.max_x+1 ) |
| 142 | | { /* clip right */ |
| 143 | | int pixels = ex-myclip.max_x-1; |
| 144 | | ex -= pixels; |
| 145 | | } |
| 146 | | if( ey > myclip.max_y+1 ) |
| 147 | | { /* clip bottom */ |
| 148 | | int pixels = ey-myclip.max_y-1; |
| 149 | | ey -= pixels; |
| 150 | | } |
| 148 | int x, x_index = x_index_base; |
| 151 | 149 | |
| 152 | | if( ex>sx ) |
| 153 | | { /* skip if inner loop doesn't draw anything */ |
| 154 | | int y; |
| 155 | | |
| 156 | | /* case 1: no alpha */ |
| 157 | | if (alpha == 0xff) |
| 150 | for( x=sx; x<ex; x++ ) |
| 158 | 151 | { |
| 159 | | { |
| 160 | | for( y=sy; y<ey; y++ ) |
| 161 | | { |
| 162 | | const UINT8 *source1 = code_base1 + (y_index>>16) * gfx->rowbytes(); |
| 163 | | const UINT8 *source2 = code_base2 + (y_index>>16) * gfx->rowbytes(); |
| 164 | | UINT32 *dest = &dest_bmp.pix32(y); |
| 152 | int c = source1[x_index>>16]; |
| 153 | if (use8bpp) |
| 154 | c=(c<<4)|source2[x_index>>16]; |
| 165 | 155 | |
| 166 | | int x, x_index = x_index_base; |
| 156 | if( c != transparent_color ) dest[x] = pal[c]; |
| 167 | 157 | |
| 168 | | for( x=sx; x<ex; x++ ) |
| 169 | | { |
| 170 | | int c = source1[x_index>>16]; |
| 171 | | if (use8bpp) |
| 172 | | c=(c<<4)|source2[x_index>>16]; |
| 158 | x_index += dx; |
| 159 | } |
| 160 | } |
| 161 | } |
| 173 | 162 | |
| 174 | | if( c != transparent_color ) dest[x] = pal[c]; |
| 163 | /* case 6: alpha blended */ |
| 164 | else |
| 165 | { |
| 166 | y = sy; |
| 175 | 167 | |
| 176 | | x_index += dx; |
| 177 | | } |
| 168 | if( y < myclip.min_y ) |
| 169 | return; |
| 178 | 170 | |
| 179 | | y_index += dy; |
| 180 | | } |
| 181 | | } |
| 182 | | } |
| 171 | if( y > myclip.max_y+1 ) |
| 172 | return; |
| 183 | 173 | |
| 184 | | /* case 6: alpha blended */ |
| 185 | | else |
| 174 | { |
| 175 | const UINT8 *source = code_base1 + (srcline) * gfx->rowbytes(); |
| 176 | UINT32 *dest = &dest_bmp.pix32(y); |
| 177 | |
| 178 | int x, x_index = x_index_base; |
| 179 | for( x=sx; x<ex; x++ ) |
| 186 | 180 | { |
| 187 | | { |
| 188 | | for( y=sy; y<ey; y++ ) |
| 189 | | { |
| 190 | | const UINT8 *source = code_base1 + (y_index>>16) * gfx->rowbytes(); |
| 191 | | UINT32 *dest = &dest_bmp.pix32(y); |
| 181 | int c = source[x_index>>16]; |
| 182 | if( c != transparent_color ) dest[x] = alpha_blend_r32(dest[x], 0, alpha); //pal[c]); |
| 183 | x_index += dx; |
| 184 | } |
| 192 | 185 | |
| 193 | | int x, x_index = x_index_base; |
| 194 | | for( x=sx; x<ex; x++ ) |
| 195 | | { |
| 196 | | int c = source[x_index>>16]; |
| 197 | | if( c != transparent_color ) dest[x] = alpha_blend_r32(dest[x], 0, alpha); //pal[c]); |
| 198 | | x_index += dx; |
| 199 | | } |
| 186 | |
| 187 | } |
| 200 | 188 | |
| 201 | | y_index += dy; |
| 202 | | } |
| 203 | | } |
| 204 | | } |
| 205 | | } |
| 206 | 189 | } |
| 207 | 190 | } |
| 208 | 191 | } |
| r21877 | r21878 | |
| 218 | 201 | int blockIsTilemapIndex=0; |
| 219 | 202 | int sprite2=0,indx2=0,use8bppMode=0; |
| 220 | 203 | int yscale,xscale; |
| 221 | | int ybase,yinc; |
| 222 | 204 | int alpha; |
| 223 | 205 | int useIndicesInRom=0; |
| 224 | 206 | int hibits=0; |
| r21877 | r21878 | |
| 387 | 369 | if(fx1&1) fx^=0x8000; |
| 388 | 370 | if(fy1&1) fy^=0x4000; |
| 389 | 371 | |
| 390 | | ybase=y<<16; |
| 372 | int ybase=y<<16; |
| 373 | int yinc=(yscale<<8)*16; |
| 374 | |
| 391 | 375 | if (fy) |
| 392 | | ybase+=(yoffs-15) * (yscale<<8); |
| 376 | ybase+=(yoffs-15) * (yscale<<8) - ((h-1)*yinc); |
| 393 | 377 | else |
| 394 | 378 | ybase-=yoffs * (yscale<<8); |
| 395 | 379 | |
| 396 | | yinc=(yscale<<8)*16; |
| 380 | int xbase=x<<16; |
| 381 | int xinc=(xscale<<8)*16; |
| 382 | |
| 383 | if (fx) |
| 384 | xbase+=(xoffs-15) * (xscale<<8) - ((w-1)*xinc); |
| 385 | else |
| 386 | xbase-=xoffs * (xscale<<8); |
| 397 | 387 | |
| 398 | | if (fy) yinc=-yinc; |
| 399 | 388 | |
| 389 | |
| 390 | |
| 391 | |
| 400 | 392 | for (by=0; by<h; by++) { |
| 401 | | int xbase=x<<16; |
| 402 | | int xinc=(xscale<<8)*16; |
| 403 | 393 | |
| 404 | | if (fx) |
| 405 | | xbase+=(xoffs-15) * (xscale<<8); |
| 406 | | else |
| 407 | | xbase-=xoffs * (xscale<<8); |
| 394 | int realybase = ybase + by * yinc; |
| 408 | 395 | |
| 409 | | if (fx) xinc=-xinc; |
| 396 | //for (int y=0; |
| 397 | int sprite_screen_height = ((yscale<<8)*16+(realybase&0xffff))>>16; |
| 398 | int ey = (realybase>>16)+sprite_screen_height; |
| 399 | realybase >>= 16; |
| 410 | 400 | |
| 411 | | for (bx=0; bx<w; bx++) { |
| 412 | | int tile=sprite; |
| 413 | | int tile2=sprite2; |
| 401 | if (!sprite_screen_height) |
| 402 | continue; |
| 414 | 403 | |
| 415 | | if (blockIsTilemapIndex) { |
| 416 | | if (useIndicesInRom) |
| 417 | | { |
| 418 | | const UINT8* ptr=rawrom+(sprite*2); |
| 419 | | tile=(*ptr) + ((*(ptr+1))<<8); |
| 404 | int dy = (16<<16)/sprite_screen_height; |
| 420 | 405 | |
| 421 | | if (use8bppMode) { |
| 422 | | const UINT8* ptr2=rawrom+(sprite2*2); |
| 423 | | tile2=(*ptr2) + ((*(ptr2+1))<<8); |
| 424 | | } |
| 425 | | else |
| 426 | | { |
| 427 | | tile2=0; |
| 428 | | } |
| 429 | 406 | |
| 430 | | if (tileFormat) |
| 431 | | { |
| 432 | | colorOffset=(tile&0xf000)>>12; |
| 433 | | tile=(tile&0x0fff)|hibits; |
| 434 | | tile2=(tile2&0x0fff)|hibits; |
| 435 | | } |
| 407 | |
| 408 | int counter = 0; |
| 409 | for (int y=realybase;y<ey;y++) |
| 410 | { |
| 411 | int dystuff = counter * dy; |
| 412 | counter++; |
| 413 | |
| 414 | int y_index; |
| 415 | if( fy ) |
| 416 | { |
| 417 | y_index = (sprite_screen_height-1)*dy-dystuff; |
| 418 | } |
| 419 | else |
| 420 | { |
| 421 | y_index = dystuff; |
| 422 | } |
| 423 | |
| 424 | for (bx=0; bx<w; bx++) { |
| 425 | |
| 426 | int realxbase = xbase + bx * xinc; |
| 427 | int count = 0; |
| 428 | if (fx) |
| 429 | { |
| 430 | if (fy) |
| 431 | count = (h-1-by) * w + (w-1-bx); |
| 436 | 432 | else |
| 437 | | { |
| 438 | | colorOffset=0; |
| 439 | | tile=(tile&0xffff)|(hibits<<2); |
| 440 | | tile2=(tile2&0xffff)|(hibits<<2); |
| 441 | | } |
| 433 | count = by * w + (w-1-bx); |
| 442 | 434 | } |
| 443 | 435 | else |
| 444 | 436 | { |
| 445 | | const UINT32* ptr=m_mlc_vram + ((sprite)&0x7fff); |
| 446 | | tile=(*ptr)&0xffff; |
| 437 | if (fy) |
| 438 | count = (h-1-by) * w + bx; |
| 439 | else |
| 440 | count = by * w + bx; |
| 441 | } |
| 447 | 442 | |
| 448 | | if (tileFormat) |
| 443 | int tile=sprite + count; |
| 444 | int tile2=sprite2 + count; |
| 445 | |
| 446 | if (blockIsTilemapIndex) { |
| 447 | if (useIndicesInRom) |
| 449 | 448 | { |
| 450 | | colorOffset=(tile&0xf000)>>12; |
| 451 | | tile=(tile&0x0fff)|hibits; |
| 449 | const UINT8* ptr=rawrom+(tile*2); |
| 450 | tile=(*ptr) + ((*(ptr+1))<<8); |
| 451 | |
| 452 | if (use8bppMode) { |
| 453 | const UINT8* ptr2=rawrom+(tile2*2); |
| 454 | tile2=(*ptr2) + ((*(ptr2+1))<<8); |
| 455 | } |
| 456 | else |
| 457 | { |
| 458 | tile2=0; |
| 459 | } |
| 460 | |
| 461 | if (tileFormat) |
| 462 | { |
| 463 | colorOffset=(tile&0xf000)>>12; |
| 464 | tile=(tile&0x0fff)|hibits; |
| 465 | tile2=(tile2&0x0fff)|hibits; |
| 466 | } |
| 467 | else |
| 468 | { |
| 469 | colorOffset=0; |
| 470 | tile=(tile&0xffff)|(hibits<<2); |
| 471 | tile2=(tile2&0xffff)|(hibits<<2); |
| 472 | } |
| 452 | 473 | } |
| 453 | 474 | else |
| 454 | 475 | { |
| 455 | | colorOffset=0; |
| 456 | | tile=(tile&0xffff)|(hibits<<2); |
| 476 | const UINT32* ptr=m_mlc_vram + ((tile)&0x7fff); |
| 477 | tile=(*ptr)&0xffff; |
| 478 | |
| 479 | if (tileFormat) |
| 480 | { |
| 481 | colorOffset=(tile&0xf000)>>12; |
| 482 | tile=(tile&0x0fff)|hibits; |
| 483 | } |
| 484 | else |
| 485 | { |
| 486 | colorOffset=0; |
| 487 | tile=(tile&0xffff)|(hibits<<2); |
| 488 | } |
| 489 | |
| 490 | tile2=0; |
| 457 | 491 | } |
| 458 | | |
| 459 | | tile2=0; |
| 460 | 492 | } |
| 461 | | } |
| 462 | 493 | |
| 463 | | // if (rasterMode) |
| 464 | | // rasterDirty=1; |
| 494 | // if (rasterMode) |
| 495 | // rasterDirty=1; |
| 465 | 496 | |
| 466 | | mlc_drawgfxzoom( |
| 467 | | /*rasterMode ? temp_bitmap : */bitmap,user_clip,machine().gfx[0], |
| 468 | | tile,tile2, |
| 469 | | color + colorOffset,fx,fy,xbase,ybase, |
| 470 | | 0, |
| 471 | | use8bppMode,(xscale<<8),(yscale<<8),alpha); |
| 497 | mlc_drawgfxzoomline( |
| 498 | /*rasterMode ? temp_bitmap : */bitmap,user_clip,machine().gfx[0], |
| 499 | tile,tile2, |
| 500 | color + colorOffset,fx,realxbase, |
| 501 | 0, |
| 502 | use8bppMode,(xscale<<8),alpha, y, y_index>>16); |
| 472 | 503 | |
| 473 | | sprite++; |
| 474 | | sprite2++; |
| 504 | } |
| 475 | 505 | |
| 476 | | xbase+=xinc; |
| 506 | |
| 477 | 507 | } |
| 478 | | ybase+=yinc; |
| 479 | 508 | } |
| 480 | 509 | |
| 481 | 510 | // if (lastRasterMode!=0 && rasterDirty) |