| 1 |
/* tilemap.c |
| 2 |
|
| 3 |
When the videoram for a tile changes, call tilemap_mark_tile_dirty |
| 4 |
with the appropriate memory offset. |
| 5 |
|
| 6 |
In the video driver, follow these steps: |
| 7 |
|
| 8 |
1) Set each tilemap's scroll registers. |
| 9 |
|
| 10 |
2) Call tilemap_draw to draw the tilemaps to the screen, from back to front. |
| 11 |
|
| 12 |
Notes: |
| 13 |
- You can currently configure a tilemap as xscroll + scrolling columns or |
| 14 |
yscroll + scrolling rows, but not both types of scrolling simultaneously. |
| 15 |
*/ |
| 16 |
|
| 17 |
#if !defined(DECLARE) && !defined(TRANSP) |
| 18 |
|
| 19 |
#include "driver.h" |
| 20 |
#include "osinline.h" |
| 21 |
#include "tilemap.h" |
| 22 |
#include "state.h" |
| 23 |
|
| 24 |
#ifdef MAME32JP |
| 25 |
// for asmtile.asm |
| 26 |
void (*_osd_pend)(void); |
| 27 |
void (*_osd_pdo16)( UINT16 *dest, const UINT16 *source, int count, UINT8 *pri, UINT32 pcode ); |
| 28 |
void (*_osd_pdt16)( UINT16 *dest, const UINT16 *source, const UINT8 *pMask, int mask, int value, int count, UINT8 *pri, UINT32 pcode ); |
| 29 |
void (*_osd_pdt16np)( UINT16 *dest, const UINT16 *source, const UINT8 *pMask, int mask, int value, int count, UINT8 *pri, UINT32 pcode ); |
| 30 |
#endif |
| 31 |
|
| 32 |
#define SWAP(X,Y) { UINT32 temp=X; X=Y; Y=temp; } |
| 33 |
#define MAX_TILESIZE 32 |
| 34 |
|
| 35 |
#define TILE_FLAG_DIRTY (0x80) |
| 36 |
|
| 37 |
typedef enum { eWHOLLY_TRANSPARENT, eWHOLLY_OPAQUE, eMASKED } trans_t; |
| 38 |
|
| 39 |
typedef void (*tilemap_draw_func)( struct tilemap *tilemap, int xpos, int ypos, int mask, int value ); |
| 40 |
|
| 41 |
struct tilemap |
| 42 |
{ |
| 43 |
UINT32 (*get_memory_offset)( UINT32 col, UINT32 row, UINT32 num_cols, UINT32 num_rows ); |
| 44 |
int *memory_offset_to_cached_indx; |
| 45 |
UINT32 *cached_indx_to_memory_offset; |
| 46 |
int logical_flip_to_cached_flip[4]; |
| 47 |
|
| 48 |
/* callback to interpret video RAM for the tilemap */ |
| 49 |
void (*tile_get_info)( int memory_offset ); |
| 50 |
|
| 51 |
UINT32 max_memory_offset; |
| 52 |
UINT32 num_tiles; |
| 53 |
UINT32 num_pens; |
| 54 |
|
| 55 |
UINT32 num_logical_rows, num_logical_cols; |
| 56 |
UINT32 num_cached_rows, num_cached_cols; |
| 57 |
|
| 58 |
UINT32 logical_tile_width, logical_tile_height; |
| 59 |
UINT32 cached_tile_width, cached_tile_height; |
| 60 |
|
| 61 |
UINT32 cached_width, cached_height; |
| 62 |
|
| 63 |
int dx, dx_if_flipped; |
| 64 |
int dy, dy_if_flipped; |
| 65 |
int scrollx_delta, scrolly_delta; |
| 66 |
|
| 67 |
int enable; |
| 68 |
int attributes; |
| 69 |
|
| 70 |
int type; |
| 71 |
int transparent_pen; |
| 72 |
UINT32 fgmask[4], bgmask[4]; /* for TILEMAP_SPLIT */ |
| 73 |
|
| 74 |
UINT32 *pPenToPixel[8]; |
| 75 |
|
| 76 |
UINT8 (*draw_tile)( struct tilemap *tilemap, UINT32 col, UINT32 row, UINT32 flags ); |
| 77 |
|
| 78 |
int cached_scroll_rows, cached_scroll_cols; |
| 79 |
int *cached_rowscroll, *cached_colscroll; |
| 80 |
|
| 81 |
int logical_scroll_rows, logical_scroll_cols; |
| 82 |
int *logical_rowscroll, *logical_colscroll; |
| 83 |
|
| 84 |
int orientation; |
| 85 |
int palette_offset; |
| 86 |
|
| 87 |
UINT16 tile_depth, tile_granularity; |
| 88 |
UINT8 *tile_dirty_map; |
| 89 |
UINT8 all_tiles_dirty; |
| 90 |
|
| 91 |
/* cached color data */ |
| 92 |
struct mame_bitmap *pixmap; |
| 93 |
UINT32 pixmap_pitch_line; |
| 94 |
UINT32 pixmap_pitch_row; |
| 95 |
|
| 96 |
struct mame_bitmap *transparency_bitmap; |
| 97 |
UINT32 transparency_bitmap_pitch_line; |
| 98 |
UINT32 transparency_bitmap_pitch_row; |
| 99 |
UINT8 *transparency_data, **transparency_data_row; |
| 100 |
|
| 101 |
struct tilemap *next; /* resource tracking */ |
| 102 |
}; |
| 103 |
|
| 104 |
struct mame_bitmap * priority_bitmap; |
| 105 |
UINT32 priority_bitmap_pitch_line; |
| 106 |
UINT32 priority_bitmap_pitch_row; |
| 107 |
|
| 108 |
static struct tilemap * first_tilemap; /* resource tracking */ |
| 109 |
static UINT32 screen_width, screen_height; |
| 110 |
struct tile_info tile_info; |
| 111 |
|
| 112 |
static UINT32 g_mask32[32]; |
| 113 |
|
| 114 |
typedef void (*blitmask_t)( void *dest, const void *source, const UINT8 *pMask, int mask, int value, int count, UINT8 *pri, UINT32 pcode ); |
| 115 |
typedef void (*blitopaque_t)( void *dest, const void *source, int count, UINT8 *pri, UINT32 pcode ); |
| 116 |
|
| 117 |
/* the following parameters are constant across tilemap_draw calls */ |
| 118 |
static struct |
| 119 |
{ |
| 120 |
blitmask_t draw_masked; |
| 121 |
blitopaque_t draw_opaque; |
| 122 |
int clip_left, clip_top, clip_right, clip_bottom; |
| 123 |
UINT32 tilemap_priority_code; |
| 124 |
struct mame_bitmap * screen_bitmap; |
| 125 |
UINT32 screen_bitmap_pitch_line; |
| 126 |
UINT32 screen_bitmap_pitch_row; |
| 127 |
} blit; |
| 128 |
|
| 129 |
/***********************************************************************************/ |
| 130 |
|
| 131 |
static int PenToPixel_Init( struct tilemap *tilemap ); |
| 132 |
static void PenToPixel_Term( struct tilemap *tilemap ); |
| 133 |
static int mappings_create( struct tilemap *tilemap ); |
| 134 |
static void mappings_dispose( struct tilemap *tilemap ); |
| 135 |
static void mappings_update( struct tilemap *tilemap ); |
| 136 |
static void recalculate_scroll( struct tilemap *tilemap ); |
| 137 |
|
| 138 |
static void install_draw_handlers( struct tilemap *tilemap ); |
| 139 |
static void tilemap_reset(void); |
| 140 |
|
| 141 |
static void update_tile_info( struct tilemap *tilemap, UINT32 cached_indx, UINT32 cached_col, UINT32 cached_row ); |
| 142 |
|
| 143 |
/***********************************************************************************/ |
| 144 |
|
| 145 |
static int PenToPixel_Init( struct tilemap *tilemap ) |
| 146 |
{ |
| 147 |
/* |
| 148 |
Construct a table for all tile orientations in advance. |
| 149 |
This simplifies drawing tiles and masks tremendously. |
| 150 |
If performance is an issue, we can always (re)introduce |
| 151 |
customized code for each case and forgo tables. |
| 152 |
*/ |
| 153 |
int i,x,y,tx,ty; |
| 154 |
UINT32 *pPenToPixel; |
| 155 |
int lError; |
| 156 |
|
| 157 |
lError = 0; |
| 158 |
for( i=0; i<8; i++ ) |
| 159 |
{ |
| 160 |
pPenToPixel = malloc( tilemap->num_pens*sizeof(UINT32) ); |
| 161 |
if( pPenToPixel==NULL ) |
| 162 |
{ |
| 163 |
lError = 1; |
| 164 |
} |
| 165 |
else |
| 166 |
{ |
| 167 |
tilemap->pPenToPixel[i] = pPenToPixel; |
| 168 |
for( ty=0; ty<tilemap->cached_tile_height; ty++ ) |
| 169 |
{ |
| 170 |
for( tx=0; tx<tilemap->cached_tile_width; tx++ ) |
| 171 |
{ |
| 172 |
if( i&TILE_SWAPXY ) |
| 173 |
{ |
| 174 |
x = ty; |
| 175 |
y = tx; |
| 176 |
} |
| 177 |
else |
| 178 |
{ |
| 179 |
x = tx; |
| 180 |
y = ty; |
| 181 |
} |
| 182 |
if( i&TILE_FLIPX ) x = tilemap->cached_tile_width-1-x; |
| 183 |
if( i&TILE_FLIPY ) y = tilemap->cached_tile_height-1-y; |
| 184 |
*pPenToPixel++ = x+y*MAX_TILESIZE; |
| 185 |
} |
| 186 |
} |
| 187 |
} |
| 188 |
} |
| 189 |
return lError; |
| 190 |
} |
| 191 |
|
| 192 |
static void PenToPixel_Term( struct tilemap *tilemap ) |
| 193 |
{ |
| 194 |
int i; |
| 195 |
for( i=0; i<8; i++ ) |
| 196 |
{ |
| 197 |
free( tilemap->pPenToPixel[i] ); |
| 198 |
} |
| 199 |
} |
| 200 |
|
| 201 |
static void InitMask32(void) |
| 202 |
{ |
| 203 |
int i; |
| 204 |
|
| 205 |
for (i=0;i<16;i++) |
| 206 |
{ |
| 207 |
UINT32 p1 = (i&1) ? 0xFFFF : 0; |
| 208 |
UINT32 p2 = (i&2) ? 0xFFFF : 0; |
| 209 |
UINT32 p3 = (i&4) ? 0xFFFF : 0; |
| 210 |
UINT32 p4 = (i&8) ? 0xFFFF : 0; |
| 211 |
|
| 212 |
g_mask32[i*2] = (p2 << 16) | p1; |
| 213 |
g_mask32[i*2+1] = (p4 << 16) | p3; |
| 214 |
} |
| 215 |
} |
| 216 |
|
| 217 |
|
| 218 |
void tilemap_set_transparent_pen( struct tilemap *tilemap, int pen ) |
| 219 |
{ |
| 220 |
tilemap->transparent_pen = pen; |
| 221 |
} |
| 222 |
|
| 223 |
void tilemap_set_transmask( struct tilemap *tilemap, int which, UINT32 fgmask, UINT32 bgmask ) |
| 224 |
{ |
| 225 |
if( tilemap->fgmask[which] != fgmask || tilemap->bgmask[which] != bgmask ) |
| 226 |
{ |
| 227 |
tilemap->fgmask[which] = fgmask; |
| 228 |
tilemap->bgmask[which] = bgmask; |
| 229 |
tilemap_mark_all_tiles_dirty( tilemap ); |
| 230 |
} |
| 231 |
} |
| 232 |
|
| 233 |
void tilemap_set_depth( struct tilemap *tilemap, int tile_depth, int tile_granularity ) |
| 234 |
{ |
| 235 |
if( tilemap->tile_dirty_map ) |
| 236 |
{ |
| 237 |
free( tilemap->tile_dirty_map); |
| 238 |
} |
| 239 |
tilemap->tile_dirty_map = malloc( Machine->drv->total_colors >> tile_granularity ); |
| 240 |
if( tilemap->tile_dirty_map ) |
| 241 |
{ |
| 242 |
tilemap->tile_depth = tile_depth; |
| 243 |
tilemap->tile_granularity = tile_granularity; |
| 244 |
} |
| 245 |
} |
| 246 |
|
| 247 |
/***********************************************************************************/ |
| 248 |
/* some common mappings */ |
| 249 |
|
| 250 |
UINT32 tilemap_scan_rows( UINT32 col, UINT32 row, UINT32 num_cols, UINT32 num_rows ) |
| 251 |
{ |
| 252 |
/* logical (col,row) -> memory offset */ |
| 253 |
return row*num_cols + col; |
| 254 |
} |
| 255 |
UINT32 tilemap_scan_cols( UINT32 col, UINT32 row, UINT32 num_cols, UINT32 num_rows ) |
| 256 |
{ |
| 257 |
/* logical (col,row) -> memory offset */ |
| 258 |
return col*num_rows + row; |
| 259 |
} |
| 260 |
|
| 261 |
/***********************************************************************************/ |
| 262 |
|
| 263 |
static int mappings_create( struct tilemap *tilemap ) |
| 264 |
{ |
| 265 |
int max_memory_offset = 0; |
| 266 |
UINT32 col,row; |
| 267 |
UINT32 num_logical_rows = tilemap->num_logical_rows; |
| 268 |
UINT32 num_logical_cols = tilemap->num_logical_cols; |
| 269 |
/* count offsets (might be larger than num_tiles) */ |
| 270 |
for( row=0; row<num_logical_rows; row++ ) |
| 271 |
{ |
| 272 |
for( col=0; col<num_logical_cols; col++ ) |
| 273 |
{ |
| 274 |
UINT32 memory_offset = tilemap->get_memory_offset( col, row, num_logical_cols, num_logical_rows ); |
| 275 |
if( memory_offset>max_memory_offset ) max_memory_offset = memory_offset; |
| 276 |
} |
| 277 |
} |
| 278 |
max_memory_offset++; |
| 279 |
tilemap->max_memory_offset = max_memory_offset; |
| 280 |
/* logical to cached (tilemap_mark_dirty) */ |
| 281 |
tilemap->memory_offset_to_cached_indx = malloc( sizeof(int)*max_memory_offset ); |
| 282 |
if( tilemap->memory_offset_to_cached_indx ) |
| 283 |
{ |
| 284 |
/* cached to logical (get_tile_info) */ |
| 285 |
tilemap->cached_indx_to_memory_offset = malloc( sizeof(UINT32)*tilemap->num_tiles ); |
| 286 |
if( tilemap->cached_indx_to_memory_offset ) return 0; /* no error */ |
| 287 |
free( tilemap->memory_offset_to_cached_indx ); |
| 288 |
} |
| 289 |
return -1; /* error */ |
| 290 |
} |
| 291 |
|
| 292 |
static void mappings_dispose( struct tilemap *tilemap ) |
| 293 |
{ |
| 294 |
free( tilemap->cached_indx_to_memory_offset ); |
| 295 |
free( tilemap->memory_offset_to_cached_indx ); |
| 296 |
} |
| 297 |
|
| 298 |
static void mappings_update( struct tilemap *tilemap ) |
| 299 |
{ |
| 300 |
int logical_flip; |
| 301 |
UINT32 logical_indx, cached_indx; |
| 302 |
UINT32 num_cached_rows = tilemap->num_cached_rows; |
| 303 |
UINT32 num_cached_cols = tilemap->num_cached_cols; |
| 304 |
UINT32 num_logical_rows = tilemap->num_logical_rows; |
| 305 |
UINT32 num_logical_cols = tilemap->num_logical_cols; |
| 306 |
for( logical_indx=0; logical_indx<tilemap->max_memory_offset; logical_indx++ ) |
| 307 |
{ |
| 308 |
tilemap->memory_offset_to_cached_indx[logical_indx] = -1; |
| 309 |
} |
| 310 |
|
| 311 |
for( logical_indx=0; logical_indx<tilemap->num_tiles; logical_indx++ ) |
| 312 |
{ |
| 313 |
UINT32 logical_col = logical_indx%num_logical_cols; |
| 314 |
UINT32 logical_row = logical_indx/num_logical_cols; |
| 315 |
int memory_offset = tilemap->get_memory_offset( logical_col, logical_row, num_logical_cols, num_logical_rows ); |
| 316 |
UINT32 cached_col = logical_col; |
| 317 |
UINT32 cached_row = logical_row; |
| 318 |
if( tilemap->orientation & ORIENTATION_SWAP_XY ) SWAP(cached_col,cached_row) |
| 319 |
if( tilemap->orientation & ORIENTATION_FLIP_X ) cached_col = (num_cached_cols-1)-cached_col; |
| 320 |
if( tilemap->orientation & ORIENTATION_FLIP_Y ) cached_row = (num_cached_rows-1)-cached_row; |
| 321 |
cached_indx = cached_row*num_cached_cols+cached_col; |
| 322 |
tilemap->memory_offset_to_cached_indx[memory_offset] = cached_indx; |
| 323 |
tilemap->cached_indx_to_memory_offset[cached_indx] = memory_offset; |
| 324 |
} |
| 325 |
for( logical_flip = 0; logical_flip<4; logical_flip++ ) |
| 326 |
{ |
| 327 |
int cached_flip = logical_flip; |
| 328 |
if( tilemap->attributes&TILEMAP_FLIPX ) cached_flip ^= TILE_FLIPX; |
| 329 |
if( tilemap->attributes&TILEMAP_FLIPY ) cached_flip ^= TILE_FLIPY; |
| 330 |
#ifndef PREROTATE_GFX |
| 331 |
if( Machine->orientation & ORIENTATION_SWAP_XY ) |
| 332 |
{ |
| 333 |
if( Machine->orientation & ORIENTATION_FLIP_X ) cached_flip ^= TILE_FLIPY; |
| 334 |
if( Machine->orientation & ORIENTATION_FLIP_Y ) cached_flip ^= TILE_FLIPX; |
| 335 |
} |
| 336 |
else |
| 337 |
{ |
| 338 |
if( Machine->orientation & ORIENTATION_FLIP_X ) cached_flip ^= TILE_FLIPX; |
| 339 |
if( Machine->orientation & ORIENTATION_FLIP_Y ) cached_flip ^= TILE_FLIPY; |
| 340 |
} |
| 341 |
#endif |
| 342 |
if( tilemap->orientation & ORIENTATION_SWAP_XY ) |
| 343 |
{ |
| 344 |
cached_flip = ((cached_flip&1)<<1) | ((cached_flip&2)>>1); |
| 345 |
} |
| 346 |
tilemap->logical_flip_to_cached_flip[logical_flip] = cached_flip; |
| 347 |
} |
| 348 |
} |
| 349 |
|
| 350 |
/***********************************************************************************/ |
| 351 |
|
| 352 |
static void pio( void *dest, const void *source, int count, UINT8 *pri, UINT32 pcode ) |
| 353 |
{ |
| 354 |
int i; |
| 355 |
|
| 356 |
if (pcode) |
| 357 |
for( i=0; i<count; i++ ) |
| 358 |
{ |
| 359 |
pri[i] |= pcode; |
| 360 |
} |
| 361 |
} |
| 362 |
|
| 363 |
static void pit( void *dest, const void *source, const UINT8 *pMask, int mask, int value, int count, UINT8 *pri, UINT32 pcode ) |
| 364 |
{ |
| 365 |
int i; |
| 366 |
|
| 367 |
if (pcode) |
| 368 |
for( i=0; i<count; i++ ) |
| 369 |
{ |
| 370 |
if( (pMask[i]&mask)==value ) |
| 371 |
{ |
| 372 |
pri[i] |= pcode; |
| 373 |
} |
| 374 |
} |
| 375 |
} |
| 376 |
|
| 377 |
/***********************************************************************************/ |
| 378 |
|
| 379 |
#ifdef MAME32JP |
| 380 |
static void __pdo16( UINT16 *dest, const UINT16 *source, int count, UINT8 *pri, UINT32 pcode ) |
| 381 |
{ |
| 382 |
int i; |
| 383 |
memcpy( dest,source,count*sizeof(UINT16) ); |
| 384 |
for( i=0; i<count; i++ ) |
| 385 |
{ |
| 386 |
pri[i] |= pcode; |
| 387 |
} |
| 388 |
} |
| 389 |
#else |
| 390 |
#ifndef pdo16 |
| 391 |
static void pdo16( UINT16 *dest, const UINT16 *source, int count, UINT8 *pri, UINT32 pcode ) |
| 392 |
{ |
| 393 |
int i; |
| 394 |
memcpy( dest,source,count*sizeof(UINT16) ); |
| 395 |
for( i=0; i<count; i++ ) |
| 396 |
{ |
| 397 |
pri[i] |= pcode; |
| 398 |
} |
| 399 |
} |
| 400 |
#endif |
| 401 |
#endif |
| 402 |
|
| 403 |
#ifndef pdo16pal |
| 404 |
static void pdo16pal( UINT16 *dest, const UINT16 *source, int count, UINT8 *pri, UINT32 pcode ) |
| 405 |
{ |
| 406 |
int pal = pcode >> 16; |
| 407 |
int i; |
| 408 |
for( i=0; i<count; i++ ) |
| 409 |
{ |
| 410 |
dest[i] = source[i] + pal; |
| 411 |
pri[i] |= pcode; |
| 412 |
} |
| 413 |
} |
| 414 |
#endif |
| 415 |
|
| 416 |
#ifndef pdo16np |
| 417 |
static void pdo16np( UINT16 *dest, const UINT16 *source, int count, UINT8 *pri, UINT32 pcode ) |
| 418 |
{ |
| 419 |
memcpy( dest,source,count*sizeof(UINT16) ); |
| 420 |
} |
| 421 |
#endif |
| 422 |
|
| 423 |
static void pdo15( UINT16 *dest, const UINT16 *source, int count, UINT8 *pri, UINT32 pcode ) |
| 424 |
{ |
| 425 |
int i; |
| 426 |
pen_t *clut = &Machine->remapped_colortable[pcode >> 16]; |
| 427 |
for( i=0; i<count; i++ ) |
| 428 |
{ |
| 429 |
dest[i] = clut[source[i]]; |
| 430 |
pri[i] |= pcode; |
| 431 |
} |
| 432 |
} |
| 433 |
|
| 434 |
static void pdo32( UINT32 *dest, const UINT16 *source, int count, UINT8 *pri, UINT32 pcode ) |
| 435 |
{ |
| 436 |
int i; |
| 437 |
pen_t *clut = &Machine->remapped_colortable[pcode >> 16]; |
| 438 |
for( i=0; i<count; i++ ) |
| 439 |
{ |
| 440 |
dest[i] = clut[source[i]]; |
| 441 |
pri[i] |= pcode; |
| 442 |
} |
| 443 |
} |
| 444 |
|
| 445 |
/***********************************************************************************/ |
| 446 |
|
| 447 |
#ifdef MAME32JP |
| 448 |
static void __pdt16( UINT16 *dest, const UINT16 *source, const UINT8 *pMask, int mask, int value, int count, UINT8 *pri, UINT32 pcode ) |
| 449 |
{ |
| 450 |
int i; |
| 451 |
|
| 452 |
for( i=0; i<count; i++ ) |
| 453 |
{ |
| 454 |
if( (pMask[i]&mask)==value ) |
| 455 |
{ |
| 456 |
dest[i] = source[i]; |
| 457 |
pri[i] |= pcode; |
| 458 |
} |
| 459 |
} |
| 460 |
} |
| 461 |
#else |
| 462 |
#ifndef pdt16 |
| 463 |
static void pdt16( UINT16 *dest, const UINT16 *source, const UINT8 *pMask, int mask, int value, int count, UINT8 *pri, UINT32 pcode ) |
| 464 |
{ |
| 465 |
int i; |
| 466 |
|
| 467 |
for( i=0; i<count; i++ ) |
| 468 |
{ |
| 469 |
if( (pMask[i]&mask)==value ) |
| 470 |
{ |
| 471 |
dest[i] = source[i]; |
| 472 |
pri[i] |= pcode; |
| 473 |
} |
| 474 |
} |
| 475 |
} |
| 476 |
#endif |
| 477 |
#endif |
| 478 |
|
| 479 |
#ifndef pdt16pal |
| 480 |
static void pdt16pal( UINT16 *dest, const UINT16 *source, const UINT8 *pMask, int mask, int value, int count, UINT8 *pri, UINT32 pcode ) |
| 481 |
{ |
| 482 |
int pal = pcode >> 16; |
| 483 |
int i; |
| 484 |
|
| 485 |
for( i=0; i<count; i++ ) |
| 486 |
{ |
| 487 |
if( (pMask[i]&mask)==value ) |
| 488 |
{ |
| 489 |
dest[i] = source[i] + pal; |
| 490 |
pri[i] |= pcode; |
| 491 |
} |
| 492 |
} |
| 493 |
} |
| 494 |
#endif |
| 495 |
|
| 496 |
#ifdef MAME32JP |
| 497 |
static void __pdt16np( UINT16 *dest, const UINT16 *source, const UINT8 *pMask, int mask, int value, int count, UINT8 *pri, UINT32 pcode ) |
| 498 |
{ |
| 499 |
int i; |
| 500 |
|
| 501 |
for( i=0; i<count; i++ ) |
| 502 |
{ |
| 503 |
if( (pMask[i]&mask)==value ) |
| 504 |
dest[i] = source[i]; |
| 505 |
} |
| 506 |
} |
| 507 |
#else |
| 508 |
#ifndef pdt16np |
| 509 |
static void pdt16np( UINT16 *dest, const UINT16 *source, const UINT8 *pMask, int mask, int value, int count, UINT8 *pri, UINT32 pcode ) |
| 510 |
{ |
| 511 |
int i; |
| 512 |
|
| 513 |
for( i=0; i<count; i++ ) |
| 514 |
{ |
| 515 |
if( (pMask[i]&mask)==value ) |
| 516 |
dest[i] = source[i]; |
| 517 |
} |
| 518 |
} |
| 519 |
#endif |
| 520 |
#endif |
| 521 |
|
| 522 |
static void pdt15( UINT16 *dest, const UINT16 *source, const UINT8 *pMask, int mask, int value, int count, UINT8 *pri, UINT32 pcode ) |
| 523 |
{ |
| 524 |
int i; |
| 525 |
pen_t *clut = &Machine->remapped_colortable[pcode >> 16]; |
| 526 |
for( i=0; i<count; i++ ) |
| 527 |
{ |
| 528 |
if( (pMask[i]&mask)==value ) |
| 529 |
{ |
| 530 |
dest[i] = clut[source[i]]; |
| 531 |
pri[i] |= pcode; |
| 532 |
} |
| 533 |
} |
| 534 |
} |
| 535 |
|
| 536 |
static void pdt32( UINT32 *dest, const UINT16 *source, const UINT8 *pMask, int mask, int value, int count, UINT8 *pri, UINT32 pcode ) |
| 537 |
{ |
| 538 |
int i; |
| 539 |
pen_t *clut = &Machine->remapped_colortable[pcode >> 16]; |
| 540 |
for( i=0; i<count; i++ ) |
| 541 |
{ |
| 542 |
if( (pMask[i]&mask)==value ) |
| 543 |
{ |
| 544 |
dest[i] = clut[source[i]]; |
| 545 |
pri[i] |= pcode; |
| 546 |
} |
| 547 |
} |
| 548 |
} |
| 549 |
|
| 550 |
/***********************************************************************************/ |
| 551 |
|
| 552 |
static void pbo15( UINT16 *dest, const UINT16 *source, int count, UINT8 *pri, UINT32 pcode ) |
| 553 |
{ |
| 554 |
int i; |
| 555 |
pen_t *clut = &Machine->remapped_colortable[pcode >> 16]; |
| 556 |
for( i=0; i<count; i++ ) |
| 557 |
{ |
| 558 |
dest[i] = alpha_blend16(dest[i], clut[source[i]]); |
| 559 |
pri[i] |= pcode; |
| 560 |
} |
| 561 |
} |
| 562 |
|
| 563 |
static void pbo32( UINT32 *dest, const UINT16 *source, int count, UINT8 *pri, UINT32 pcode ) |
| 564 |
{ |
| 565 |
int i; |
| 566 |
pen_t *clut = &Machine->remapped_colortable[pcode >> 16]; |
| 567 |
for( i=0; i<count; i++ ) |
| 568 |
{ |
| 569 |
dest[i] = alpha_blend32(dest[i], clut[source[i]]); |
| 570 |
pri[i] |= pcode; |
| 571 |
} |
| 572 |
} |
| 573 |
|
| 574 |
/***********************************************************************************/ |
| 575 |
|
| 576 |
static void pbt15( UINT16 *dest, const UINT16 *source, const UINT8 *pMask, int mask, int value, int count, UINT8 *pri, UINT32 pcode ) |
| 577 |
{ |
| 578 |
int i; |
| 579 |
pen_t *clut = &Machine->remapped_colortable[pcode >> 16]; |
| 580 |
for( i=0; i<count; i++ ) |
| 581 |
{ |
| 582 |
if( (pMask[i]&mask)==value ) |
| 583 |
{ |
| 584 |
dest[i] = alpha_blend16(dest[i], clut[source[i]]); |
| 585 |
pri[i] |= pcode; |
| 586 |
} |
| 587 |
} |
| 588 |
} |
| 589 |
|
| 590 |
static void pbt32( UINT32 *dest, const UINT16 *source, const UINT8 *pMask, int mask, int value, int count, UINT8 *pri, UINT32 pcode ) |
| 591 |
{ |
| 592 |
int i; |
| 593 |
pen_t *clut = &Machine->remapped_colortable[pcode >> 16]; |
| 594 |
for( i=0; i<count; i++ ) |
| 595 |
{ |
| 596 |
if( (pMask[i]&mask)==value ) |
| 597 |
{ |
| 598 |
dest[i] = alpha_blend32(dest[i], clut[source[i]]); |
| 599 |
pri[i] |= pcode; |
| 600 |
} |
| 601 |
} |
| 602 |
} |
| 603 |
|
| 604 |
#ifdef MAME32JP |
| 605 |
static void __pend(void) |
| 606 |
{ |
| 607 |
} |
| 608 |
|
| 609 |
void set_tilefunc( void ) |
| 610 |
{ |
| 611 |
BOOL UseTilemapMMX(void); |
| 612 |
_osd_pend = __pend; |
| 613 |
_osd_pdo16 = __pdo16; |
| 614 |
_osd_pdt16 = __pdt16; |
| 615 |
_osd_pdt16np = __pdt16np; |
| 616 |
if(UseTilemapMMX) { |
| 617 |
_osd_pend = __osd_pend; |
| 618 |
_osd_pdo16 = osd_pdo16; |
| 619 |
_osd_pdt16 = osd_pdt16; |
| 620 |
_osd_pdt16np = osd_pdt16np; |
| 621 |
} |
| 622 |
} |
| 623 |
#endif |
| 624 |
|
| 625 |
/***********************************************************************************/ |
| 626 |
|
| 627 |
#define DEPTH 16 |
| 628 |
#define DATA_TYPE UINT16 |
| 629 |
#define DECLARE(function,args,body) static void function##16BPP args body |
| 630 |
#include "tilemap.c" |
| 631 |
|
| 632 |
#define DEPTH 32 |
| 633 |
#define DATA_TYPE UINT32 |
| 634 |
#define DECLARE(function,args,body) static void function##32BPP args body |
| 635 |
#include "tilemap.c" |
| 636 |
|
| 637 |
#define PAL_INIT const pen_t *pPalData = tile_info.pal_data |
| 638 |
#define PAL_GET(pen) pPalData[pen] |
| 639 |
#define TRANSP(f) f ## _ind |
| 640 |
#include "tilemap.c" |
| 641 |
|
| 642 |
#define PAL_INIT int palBase = tile_info.pal_data - Machine->remapped_colortable |
| 643 |
#define PAL_GET(pen) (palBase + (pen)) |
| 644 |
#define TRANSP(f) f ## _raw |
| 645 |
#include "tilemap.c" |
| 646 |
|
| 647 |
/*********************************************************************************/ |
| 648 |
|
| 649 |
static void install_draw_handlers( struct tilemap *tilemap ) |
| 650 |
{ |
| 651 |
if( Machine->game_colortable ) |
| 652 |
{ |
| 653 |
if( tilemap->type & TILEMAP_BITMASK ) |
| 654 |
tilemap->draw_tile = HandleTransparencyBitmask_ind; |
| 655 |
else if( tilemap->type & TILEMAP_SPLIT_PENBIT ) |
| 656 |
tilemap->draw_tile = HandleTransparencyPenBit_ind; |
| 657 |
else if( tilemap->type & TILEMAP_SPLIT ) |
| 658 |
tilemap->draw_tile = HandleTransparencyPens_ind; |
| 659 |
else if( tilemap->type==TILEMAP_TRANSPARENT ) |
| 660 |
tilemap->draw_tile = HandleTransparencyPen_ind; |
| 661 |
else if( tilemap->type==TILEMAP_TRANSPARENT_COLOR ) |
| 662 |
tilemap->draw_tile = HandleTransparencyColor_ind; |
| 663 |
else |
| 664 |
tilemap->draw_tile = HandleTransparencyNone_ind; |
| 665 |
} |
| 666 |
else |
| 667 |
{ |
| 668 |
if( tilemap->type & TILEMAP_BITMASK ) |
| 669 |
tilemap->draw_tile = HandleTransparencyBitmask_raw; |
| 670 |
else if( tilemap->type & TILEMAP_SPLIT_PENBIT ) |
| 671 |
tilemap->draw_tile = HandleTransparencyPenBit_raw; |
| 672 |
else if( tilemap->type & TILEMAP_SPLIT ) |
| 673 |
tilemap->draw_tile = HandleTransparencyPens_raw; |
| 674 |
else if( tilemap->type==TILEMAP_TRANSPARENT ) |
| 675 |
tilemap->draw_tile = HandleTransparencyPen_raw; |
| 676 |
else if( tilemap->type==TILEMAP_TRANSPARENT_COLOR ) |
| 677 |
tilemap->draw_tile = HandleTransparencyColor_raw; |
| 678 |
else |
| 679 |
tilemap->draw_tile = HandleTransparencyNone_raw; |
| 680 |
} |
| 681 |
} |
| 682 |
|
| 683 |
INLINE tilemap_draw_func pick_draw_func( struct mame_bitmap *dest ) |
| 684 |
{ |
| 685 |
switch (dest ? dest->depth : Machine->scrbitmap->depth) |
| 686 |
{ |
| 687 |
case 32: |
| 688 |
return draw32BPP; |
| 689 |
|
| 690 |
case 16: |
| 691 |
case 15: |
| 692 |
return draw16BPP; |
| 693 |
} |
| 694 |
exit(1); |
| 695 |
return NULL; |
| 696 |
} |
| 697 |
|
| 698 |
|
| 699 |
/***********************************************************************************/ |
| 700 |
|
| 701 |
static void tilemap_reset(void) |
| 702 |
{ |
| 703 |
tilemap_mark_all_tiles_dirty(ALL_TILEMAPS); |
| 704 |
} |
| 705 |
|
| 706 |
int tilemap_init( void ) |
| 707 |
{ |
| 708 |
screen_width = Machine->scrbitmap->width; |
| 709 |
screen_height = Machine->scrbitmap->height; |
| 710 |
first_tilemap = NULL; |
| 711 |
|
| 712 |
state_save_register_func_postload(tilemap_reset); |
| 713 |
priority_bitmap = bitmap_alloc_depth( screen_width, screen_height, -8 ); |
| 714 |
if( priority_bitmap ) |
| 715 |
{ |
| 716 |
priority_bitmap_pitch_line = ((UINT8 *)priority_bitmap->line[1]) - ((UINT8 *)priority_bitmap->line[0]); |
| 717 |
return 0; |
| 718 |
} |
| 719 |
InitMask32(); |
| 720 |
return -1; |
| 721 |
} |
| 722 |
|
| 723 |
void tilemap_close( void ) |
| 724 |
{ |
| 725 |
struct tilemap *next; |
| 726 |
|
| 727 |
while( first_tilemap ) |
| 728 |
{ |
| 729 |
next = first_tilemap->next; |
| 730 |
tilemap_dispose( first_tilemap ); |
| 731 |
first_tilemap = next; |
| 732 |
} |
| 733 |
bitmap_free( priority_bitmap ); |
| 734 |
} |
| 735 |
|
| 736 |
/***********************************************************************************/ |
| 737 |
|
| 738 |
struct tilemap *tilemap_create( |
| 739 |
void (*tile_get_info)( int memory_offset ), |
| 740 |
UINT32 (*get_memory_offset)( UINT32 col, UINT32 row, UINT32 num_cols, UINT32 num_rows ), |
| 741 |
int type, |
| 742 |
int tile_width, int tile_height, |
| 743 |
int num_cols, int num_rows ) |
| 744 |
{ |
| 745 |
struct tilemap *tilemap; |
| 746 |
UINT32 row; |
| 747 |
int num_tiles; |
| 748 |
|
| 749 |
tilemap = calloc( 1,sizeof( struct tilemap ) ); |
| 750 |
if( tilemap ) |
| 751 |
{ |
| 752 |
num_tiles = num_cols*num_rows; |
| 753 |
tilemap->num_logical_cols = num_cols; |
| 754 |
tilemap->num_logical_rows = num_rows; |
| 755 |
tilemap->logical_tile_width = tile_width; |
| 756 |
tilemap->logical_tile_height = tile_height; |
| 757 |
tilemap->logical_colscroll = calloc(num_cols*tile_width,sizeof(int)); |
| 758 |
tilemap->logical_rowscroll = calloc(num_rows*tile_height,sizeof(int)); |
| 759 |
if( Machine->orientation & ORIENTATION_SWAP_XY ) |
| 760 |
{ |
| 761 |
SWAP( num_cols, num_rows ) |
| 762 |
SWAP( tile_width, tile_height ) |
| 763 |
} |
| 764 |
tilemap->num_cached_cols = num_cols; |
| 765 |
tilemap->num_cached_rows = num_rows; |
| 766 |
tilemap->num_tiles = num_tiles; |
| 767 |
tilemap->num_pens = tile_width*tile_height; |
| 768 |
tilemap->cached_tile_width = tile_width; |
| 769 |
tilemap->cached_tile_height = tile_height; |
| 770 |
tilemap->cached_width = tile_width*num_cols; |
| 771 |
tilemap->cached_height = tile_height*num_rows; |
| 772 |
tilemap->tile_get_info = tile_get_info; |
| 773 |
tilemap->get_memory_offset = get_memory_offset; |
| 774 |
tilemap->orientation = Machine->orientation; |
| 775 |
|
| 776 |
/* various defaults */ |
| 777 |
tilemap->enable = 1; |
| 778 |
tilemap->type = type; |
| 779 |
tilemap->logical_scroll_rows = tilemap->cached_scroll_rows = 1; |
| 780 |
tilemap->logical_scroll_cols = tilemap->cached_scroll_cols = 1; |
| 781 |
tilemap->transparent_pen = -1; |
| 782 |
tilemap->tile_depth = 0; |
| 783 |
tilemap->tile_granularity = 0; |
| 784 |
tilemap->tile_dirty_map = 0; |
| 785 |
|
| 786 |
tilemap->cached_rowscroll = calloc(tilemap->cached_height,sizeof(int)); |
| 787 |
tilemap->cached_colscroll = calloc(tilemap->cached_width, sizeof(int)); |
| 788 |
|
| 789 |
tilemap->transparency_data = malloc( num_tiles ); |
| 790 |
tilemap->transparency_data_row = malloc( sizeof(UINT8 *)*num_rows ); |
| 791 |
|
| 792 |
tilemap->pixmap = bitmap_alloc_depth( tilemap->cached_width, tilemap->cached_height, -16 ); |
| 793 |
tilemap->transparency_bitmap = bitmap_alloc_depth( tilemap->cached_width, tilemap->cached_height, -8 ); |
| 794 |
|
| 795 |
if( tilemap->logical_rowscroll && tilemap->cached_rowscroll && |
| 796 |
tilemap->logical_colscroll && tilemap->cached_colscroll && |
| 797 |
tilemap->pixmap && |
| 798 |
tilemap->transparency_data && |
| 799 |
tilemap->transparency_data_row && |
| 800 |
tilemap->transparency_bitmap && |
| 801 |
(mappings_create( tilemap )==0) ) |
| 802 |
{ |
| 803 |
tilemap->pixmap_pitch_line = tilemap->pixmap->rowpixels; |
| 804 |
tilemap->pixmap_pitch_row = tilemap->pixmap_pitch_line*tile_height; |
| 805 |
|
| 806 |
tilemap->transparency_bitmap_pitch_line = tilemap->transparency_bitmap->rowpixels; |
| 807 |
tilemap->transparency_bitmap_pitch_row = tilemap->transparency_bitmap_pitch_line*tile_height; |
| 808 |
|
| 809 |
for( row=0; row<num_rows; row++ ) |
| 810 |
{ |
| 811 |
tilemap->transparency_data_row[row] = tilemap->transparency_data+num_cols*row; |
| 812 |
} |
| 813 |
install_draw_handlers( tilemap ); |
| 814 |
mappings_update( tilemap ); |
| 815 |
memset( tilemap->transparency_data, TILE_FLAG_DIRTY, num_tiles ); |
| 816 |
tilemap->next = first_tilemap; |
| 817 |
first_tilemap = tilemap; |
| 818 |
if( PenToPixel_Init( tilemap ) == 0 ) |
| 819 |
{ |
| 820 |
recalculate_scroll(tilemap); |
| 821 |
return tilemap; |
| 822 |
} |
| 823 |
} |
| 824 |
tilemap_dispose( tilemap ); |
| 825 |
} |
| 826 |
return 0; |
| 827 |
} |
| 828 |
|
| 829 |
void tilemap_dispose( struct tilemap *tilemap ) |
| 830 |
{ |
| 831 |
struct tilemap *prev; |
| 832 |
|
| 833 |
if( tilemap==first_tilemap ) |
| 834 |
{ |
| 835 |
first_tilemap = tilemap->next; |
| 836 |
} |
| 837 |
else |
| 838 |
{ |
| 839 |
prev = first_tilemap; |
| 840 |
while( prev->next != tilemap ) prev = prev->next; |
| 841 |
prev->next =tilemap->next; |
| 842 |
} |
| 843 |
PenToPixel_Term( tilemap ); |
| 844 |
free( tilemap->logical_rowscroll ); |
| 845 |
free( tilemap->cached_rowscroll ); |
| 846 |
free( tilemap->logical_colscroll ); |
| 847 |
free( tilemap->cached_colscroll ); |
| 848 |
free( tilemap->transparency_data ); |
| 849 |
free( tilemap->transparency_data_row ); |
| 850 |
bitmap_free( tilemap->transparency_bitmap ); |
| 851 |
bitmap_free( tilemap->pixmap ); |
| 852 |
mappings_dispose( tilemap ); |
| 853 |
free( tilemap ); |
| 854 |
} |
| 855 |
|
| 856 |
/***********************************************************************************/ |
| 857 |
|
| 858 |
void tilemap_set_enable( struct tilemap *tilemap, int enable ) |
| 859 |
{ |
| 860 |
tilemap->enable = enable?1:0; |
| 861 |
} |
| 862 |
|
| 863 |
|
| 864 |
void tilemap_set_flip( struct tilemap *tilemap, int attributes ) |
| 865 |
{ |
| 866 |
if( tilemap==ALL_TILEMAPS ) |
| 867 |
{ |
| 868 |
tilemap = first_tilemap; |
| 869 |
while( tilemap ) |
| 870 |
{ |
| 871 |
tilemap_set_flip( tilemap, attributes ); |
| 872 |
tilemap = tilemap->next; |
| 873 |
} |
| 874 |
} |
| 875 |
else if( tilemap->attributes!=attributes ) |
| 876 |
{ |
| 877 |
tilemap->attributes = attributes; |
| 878 |
tilemap->orientation = Machine->orientation; |
| 879 |
if( attributes&TILEMAP_FLIPY ) |
| 880 |
{ |
| 881 |
tilemap->orientation ^= ORIENTATION_FLIP_Y; |
| 882 |
} |
| 883 |
|
| 884 |
if( attributes&TILEMAP_FLIPX ) |
| 885 |
{ |
| 886 |
tilemap->orientation ^= ORIENTATION_FLIP_X; |
| 887 |
} |
| 888 |
|
| 889 |
mappings_update( tilemap ); |
| 890 |
recalculate_scroll( tilemap ); |
| 891 |
tilemap_mark_all_tiles_dirty( tilemap ); |
| 892 |
} |
| 893 |
} |
| 894 |
|
| 895 |
/***********************************************************************************/ |
| 896 |
|
| 897 |
void tilemap_set_scroll_cols( struct tilemap *tilemap, int n ) |
| 898 |
{ |
| 899 |
tilemap->logical_scroll_cols = n; |
| 900 |
if( tilemap->orientation & ORIENTATION_SWAP_XY ) |
| 901 |
{ |
| 902 |
tilemap->cached_scroll_rows = n; |
| 903 |
} |
| 904 |
else |
| 905 |
{ |
| 906 |
tilemap->cached_scroll_cols = n; |
| 907 |
} |
| 908 |
} |
| 909 |
|
| 910 |
void tilemap_set_scroll_rows( struct tilemap *tilemap, int n ) |
| 911 |
{ |
| 912 |
tilemap->logical_scroll_rows = n; |
| 913 |
if( tilemap->orientation & ORIENTATION_SWAP_XY ) |
| 914 |
{ |
| 915 |
tilemap->cached_scroll_cols = n; |
| 916 |
} |
| 917 |
else |
| 918 |
{ |
| 919 |
tilemap->cached_scroll_rows = n; |
| 920 |
} |
| 921 |
} |
| 922 |
|
| 923 |
/***********************************************************************************/ |
| 924 |
|
| 925 |
void tilemap_mark_tile_dirty( struct tilemap *tilemap, int memory_offset ) |
| 926 |
{ |
| 927 |
if( memory_offset<tilemap->max_memory_offset ) |
| 928 |
{ |
| 929 |
int cached_indx = tilemap->memory_offset_to_cached_indx[memory_offset]; |
| 930 |
if( cached_indx>=0 ) |
| 931 |
{ |
| 932 |
tilemap->transparency_data[cached_indx] = TILE_FLAG_DIRTY; |
| 933 |
} |
| 934 |
} |
| 935 |
} |
| 936 |
|
| 937 |
void tilemap_mark_all_tiles_dirty( struct tilemap *tilemap ) |
| 938 |
{ |
| 939 |
if( tilemap==ALL_TILEMAPS ) |
| 940 |
{ |
| 941 |
tilemap = first_tilemap; |
| 942 |
while( tilemap ) |
| 943 |
{ |
| 944 |
tilemap_mark_all_tiles_dirty( tilemap ); |
| 945 |
tilemap = tilemap->next; |
| 946 |
} |
| 947 |
} |
| 948 |
else |
| 949 |
{ |
| 950 |
tilemap->all_tiles_dirty = 1; |
| 951 |
} |
| 952 |
} |
| 953 |
|
| 954 |
/***********************************************************************************/ |
| 955 |
|
| 956 |
static void update_tile_info( struct tilemap *tilemap, UINT32 cached_indx, UINT32 col, UINT32 row ) |
| 957 |
{ |
| 958 |
UINT32 x0; |
| 959 |
UINT32 y0; |
| 960 |
UINT32 memory_offset; |
| 961 |
UINT32 flags; |
| 962 |
|
| 963 |
profiler_mark(PROFILER_TILEMAP_UPDATE); |
| 964 |
|
| 965 |
memory_offset = tilemap->cached_indx_to_memory_offset[cached_indx]; |
| 966 |
tilemap->tile_get_info( memory_offset ); |
| 967 |
flags = tile_info.flags; |
| 968 |
flags = (flags&0xfc)|tilemap->logical_flip_to_cached_flip[flags&0x3]; |
| 969 |
x0 = tilemap->cached_tile_width*col; |
| 970 |
y0 = tilemap->cached_tile_height*row; |
| 971 |
|
| 972 |
tilemap->transparency_data[cached_indx] = tilemap->draw_tile(tilemap,x0,y0,flags ); |
| 973 |
|
| 974 |
profiler_mark(PROFILER_END); |
| 975 |
} |
| 976 |
|
| 977 |
struct mame_bitmap *tilemap_get_pixmap( struct tilemap * tilemap ) |
| 978 |
{ |
| 979 |
UINT32 cached_indx = 0; |
| 980 |
UINT32 row,col; |
| 981 |
|
| 982 |
profiler_mark(PROFILER_TILEMAP_DRAW); |
| 983 |
memset( &tile_info, 0x00, sizeof(tile_info) ); /* initialize defaults */ |
| 984 |
|
| 985 |
/* if the whole map is dirty, mark it as such */ |
| 986 |
if (tilemap->all_tiles_dirty) |
| 987 |
{ |
| 988 |
memset( tilemap->transparency_data, TILE_FLAG_DIRTY, tilemap->num_tiles ); |
| 989 |
tilemap->all_tiles_dirty = 0; |
| 990 |
} |
| 991 |
|
| 992 |
/* walk over cached rows/cols (better to walk screen coords) */ |
| 993 |
for( row=0; row<tilemap->num_cached_rows; row++ ) |
| 994 |
{ |
| 995 |
for( col=0; col<tilemap->num_cached_cols; col++ ) |
| 996 |
{ |
| 997 |
if( tilemap->transparency_data[cached_indx] == TILE_FLAG_DIRTY ) |
| 998 |
{ |
| 999 |
update_tile_info( tilemap, cached_indx, col, row ); |
| 1000 |
} |
| 1001 |
cached_indx++; |
| 1002 |
} /* next col */ |
| 1003 |
} /* next row */ |
| 1004 |
|
| 1005 |
profiler_mark(PROFILER_END); |
| 1006 |
return tilemap->pixmap; |
| 1007 |
} |
| 1008 |
|
| 1009 |
struct mame_bitmap *tilemap_get_transparency_bitmap( struct tilemap * tilemap ) |
| 1010 |
{ |
| 1011 |
return tilemap->transparency_bitmap; |
| 1012 |
} |
| 1013 |
|
| 1014 |
/***********************************************************************************/ |
| 1015 |
|
| 1016 |
static void |
| 1017 |
recalculate_scroll( struct tilemap *tilemap ) |
| 1018 |
{ |
| 1019 |
int i; |
| 1020 |
|
| 1021 |
tilemap->scrollx_delta = (tilemap->attributes & TILEMAP_FLIPX )?tilemap->dx_if_flipped:tilemap->dx; |
| 1022 |
tilemap->scrolly_delta = (tilemap->attributes & TILEMAP_FLIPY )?tilemap->dy_if_flipped:tilemap->dy; |
| 1023 |
|
| 1024 |
for( i=0; i<tilemap->logical_scroll_rows; i++ ) |
| 1025 |
{ |
| 1026 |
tilemap_set_scrollx( tilemap, i, tilemap->logical_rowscroll[i] ); |
| 1027 |
} |
| 1028 |
for( i=0; i<tilemap->logical_scroll_cols; i++ ) |
| 1029 |
{ |
| 1030 |
tilemap_set_scrolly( tilemap, i, tilemap->logical_colscroll[i] ); |
| 1031 |
} |
| 1032 |
} |
| 1033 |
|
| 1034 |
void |
| 1035 |
tilemap_set_scrolldx( struct tilemap *tilemap, int dx, int dx_if_flipped ) |
| 1036 |
{ |
| 1037 |
tilemap->dx = dx; |
| 1038 |
tilemap->dx_if_flipped = dx_if_flipped; |
| 1039 |
recalculate_scroll( tilemap ); |
| 1040 |
} |
| 1041 |
|
| 1042 |
void |
| 1043 |
tilemap_set_scrolldy( struct tilemap *tilemap, int dy, int dy_if_flipped ) |
| 1044 |
{ |
| 1045 |
tilemap->dy = dy; |
| 1046 |
tilemap->dy_if_flipped = dy_if_flipped; |
| 1047 |
recalculate_scroll( tilemap ); |
| 1048 |
} |
| 1049 |
|
| 1050 |
void tilemap_set_scrollx( struct tilemap *tilemap, int which, int value ) |
| 1051 |
{ |
| 1052 |
tilemap->logical_rowscroll[which] = value; |
| 1053 |
value = tilemap->scrollx_delta-value; /* adjust */ |
| 1054 |
|
| 1055 |
if( tilemap->orientation & ORIENTATION_SWAP_XY ) |
| 1056 |
{ |
| 1057 |
/* if xy are swapped, we are actually panning the screen bitmap vertically */ |
| 1058 |
if( tilemap->orientation & ORIENTATION_FLIP_X ) |
| 1059 |
{ |
| 1060 |
/* adjust affected col */ |
| 1061 |
which = tilemap->cached_scroll_cols-1 - which; |
| 1062 |
} |
| 1063 |
if( tilemap->orientation & ORIENTATION_FLIP_Y ) |
| 1064 |
{ |
| 1065 |
/* adjust scroll amount */ |
| 1066 |
value = screen_height-tilemap->cached_height-value; |
| 1067 |
} |
| 1068 |
tilemap->cached_colscroll[which] = value; |
| 1069 |
} |
| 1070 |
else |
| 1071 |
{ |
| 1072 |
if( tilemap->orientation & ORIENTATION_FLIP_Y ) |
| 1073 |
{ |
| 1074 |
/* adjust affected row */ |
| 1075 |
which = tilemap->cached_scroll_rows-1 - which; |
| 1076 |
} |
| 1077 |
if( tilemap->orientation & ORIENTATION_FLIP_X ) |
| 1078 |
{ |
| 1079 |
/* adjust scroll amount */ |
| 1080 |
value = screen_width-tilemap->cached_width-value; |
| 1081 |
} |
| 1082 |
tilemap->cached_rowscroll[which] = value; |
| 1083 |
} |
| 1084 |
} |
| 1085 |
|
| 1086 |
void tilemap_set_scrolly( struct tilemap *tilemap, int which, int value ) |
| 1087 |
{ |
| 1088 |
tilemap->logical_colscroll[which] = value; |
| 1089 |
value = tilemap->scrolly_delta - value; /* adjust */ |
| 1090 |
|
| 1091 |
if( tilemap->orientation & ORIENTATION_SWAP_XY ) |
| 1092 |
{ |
| 1093 |
/* if xy are swapped, we are actually panning the screen bitmap horizontally */ |
| 1094 |
if( tilemap->orientation & ORIENTATION_FLIP_Y ) |
| 1095 |
{ |
| 1096 |
/* adjust affected row */ |
| 1097 |
which = tilemap->cached_scroll_rows-1 - which; |
| 1098 |
} |
| 1099 |
if( tilemap->orientation & ORIENTATION_FLIP_X ) |
| 1100 |
{ |
| 1101 |
/* adjust scroll amount */ |
| 1102 |
value = screen_width-tilemap->cached_width-value; |
| 1103 |
} |
| 1104 |
tilemap->cached_rowscroll[which] = value; |
| 1105 |
} |
| 1106 |
else |
| 1107 |
{ |
| 1108 |
if( tilemap->orientation & ORIENTATION_FLIP_X ) |
| 1109 |
{ |
| 1110 |
/* adjust affected col */ |
| 1111 |
which = tilemap->cached_scroll_cols-1 - which; |
| 1112 |
} |
| 1113 |
if( tilemap->orientation & ORIENTATION_FLIP_Y ) |
| 1114 |
{ |
| 1115 |
/* adjust scroll amount */ |
| 1116 |
value = screen_height-tilemap->cached_height-value; |
| 1117 |
} |
| 1118 |
tilemap->cached_colscroll[which] = value; |
| 1119 |
} |
| 1120 |
} |
| 1121 |
|
| 1122 |
/***********************************************************************************/ |
| 1123 |
|
| 1124 |
void tilemap_set_palette_offset( struct tilemap *tilemap, int offset ) |
| 1125 |
{ |
| 1126 |
tilemap->palette_offset = offset; |
| 1127 |
} |
| 1128 |
|
| 1129 |
/***********************************************************************************/ |
| 1130 |
|
| 1131 |
void tilemap_draw( struct mame_bitmap *dest, const struct rectangle *cliprect, struct tilemap *tilemap, UINT32 flags, UINT32 priority ) |
| 1132 |
{ |
| 1133 |
tilemap_draw_func drawfunc = pick_draw_func(dest); |
| 1134 |
int xpos,ypos,mask,value; |
| 1135 |
int rows, cols; |
| 1136 |
const int *rowscroll, *colscroll; |
| 1137 |
int left, right, top, bottom; |
| 1138 |
|
| 1139 |
profiler_mark(PROFILER_TILEMAP_DRAW); |
| 1140 |
if( tilemap->enable ) |
| 1141 |
{ |
| 1142 |
/* scroll registers */ |
| 1143 |
rows = tilemap->cached_scroll_rows; |
| 1144 |
cols = tilemap->cached_scroll_cols; |
| 1145 |
rowscroll = tilemap->cached_rowscroll; |
| 1146 |
colscroll = tilemap->cached_colscroll; |
| 1147 |
|
| 1148 |
/* clipping */ |
| 1149 |
if( cliprect ) |
| 1150 |
{ |
| 1151 |
left = cliprect->min_x; |
| 1152 |
top = cliprect->min_y; |
| 1153 |
right = cliprect->max_x+1; |
| 1154 |
bottom = cliprect->max_y+1; |
| 1155 |
|
| 1156 |
if( Machine->orientation & ORIENTATION_SWAP_XY ) |
| 1157 |
{ |
| 1158 |
SWAP(left,top) |
| 1159 |
SWAP(right,bottom) |
| 1160 |
} |
| 1161 |
|
| 1162 |
if( Machine->orientation & ORIENTATION_FLIP_X ) |
| 1163 |
{ |
| 1164 |
SWAP(left,right) |
| 1165 |
left = screen_width-left; |
| 1166 |
right = screen_width-right; |
| 1167 |
} |
| 1168 |
|
| 1169 |
if( Machine->orientation & ORIENTATION_FLIP_Y ) |
| 1170 |
{ |
| 1171 |
SWAP(top,bottom) |
| 1172 |
top = screen_height-top; |
| 1173 |
bottom = screen_height-bottom; |
| 1174 |
} |
| 1175 |
} |
| 1176 |
else |
| 1177 |
{ |
| 1178 |
left = 0; |
| 1179 |
top = 0; |
| 1180 |
right = tilemap->cached_width; |
| 1181 |
bottom = tilemap->cached_height; |
| 1182 |
} |
| 1183 |
|
| 1184 |
/* tile priority */ |
| 1185 |
mask = TILE_FLAG_TILE_PRIORITY; |
| 1186 |
value = TILE_FLAG_TILE_PRIORITY&flags; |
| 1187 |
|
| 1188 |
/* initialize defaults */ |
| 1189 |
memset( &tile_info, 0x00, sizeof(tile_info) ); |
| 1190 |
|
| 1191 |
/* if the whole map is dirty, mark it as such */ |
| 1192 |
if (tilemap->all_tiles_dirty) |
| 1193 |
{ |
| 1194 |
memset( tilemap->transparency_data, TILE_FLAG_DIRTY, tilemap->num_tiles ); |
| 1195 |
tilemap->all_tiles_dirty = 0; |
| 1196 |
} |
| 1197 |
|
| 1198 |
/* priority_bitmap_pitch_row is tilemap-specific */ |
| 1199 |
priority_bitmap_pitch_row = priority_bitmap_pitch_line*tilemap->cached_tile_height; |
| 1200 |
|
| 1201 |
blit.screen_bitmap = dest; |
| 1202 |
if( dest == NULL ) |
| 1203 |
{ |
| 1204 |
blit.draw_masked = (blitmask_t)pit; |
| 1205 |
blit.draw_opaque = (blitopaque_t)pio; |
| 1206 |
} |
| 1207 |
else |
| 1208 |
{ |
| 1209 |
blit.screen_bitmap_pitch_line = ((UINT8 *)dest->line[1]) - ((UINT8 *)dest->line[0]); |
| 1210 |
switch( dest->depth ) |
| 1211 |
{ |
| 1212 |
case 32: |
| 1213 |
if( flags&TILEMAP_ALPHA ) |
| 1214 |
{ |
| 1215 |
blit.draw_masked = (blitmask_t)pbt32; |
| 1216 |
blit.draw_opaque = (blitopaque_t)pbo32; |
| 1217 |
} |
| 1218 |
else |
| 1219 |
{ |
| 1220 |
blit.draw_masked = (blitmask_t)pdt32; |
| 1221 |
blit.draw_opaque = (blitopaque_t)pdo32; |
| 1222 |
} |
| 1223 |
blit.screen_bitmap_pitch_line /= 4; |
| 1224 |
break; |
| 1225 |
|
| 1226 |
case 15: |
| 1227 |
if( flags&TILEMAP_ALPHA ) |
| 1228 |
{ |
| 1229 |
blit.draw_masked = (blitmask_t)pbt15; |
| 1230 |
blit.draw_opaque = (blitopaque_t)pbo15; |
| 1231 |
} |
| 1232 |
else |
| 1233 |
{ |
| 1234 |
blit.draw_masked = (blitmask_t)pdt15; |
| 1235 |
blit.draw_opaque = (blitopaque_t)pdo15; |
| 1236 |
} |
| 1237 |
blit.screen_bitmap_pitch_line /= 2; |
| 1238 |
break; |
| 1239 |
|
| 1240 |
case 16: |
| 1241 |
if (tilemap->palette_offset) |
| 1242 |
{ |
| 1243 |
blit.draw_masked = (blitmask_t)pdt16pal; |
| 1244 |
blit.draw_opaque = (blitopaque_t)pdo16pal; |
| 1245 |
} |
| 1246 |
else if (priority) |
| 1247 |
{ |
| 1248 |
blit.draw_masked = (blitmask_t)pdt16; |
| 1249 |
blit.draw_opaque = (blitopaque_t)pdo16; |
| 1250 |
} |
| 1251 |
else |
| 1252 |
{ |
| 1253 |
blit.draw_masked = (blitmask_t)pdt16np; |
| 1254 |
blit.draw_opaque = (blitopaque_t)pdo16np; |
| 1255 |
} |
| 1256 |
blit.screen_bitmap_pitch_line /= 2; |
| 1257 |
break; |
| 1258 |
|
| 1259 |
default: |
| 1260 |
exit(1); |
| 1261 |
break; |
| 1262 |
} |
| 1263 |
blit.screen_bitmap_pitch_row = blit.screen_bitmap_pitch_line*tilemap->cached_tile_height; |
| 1264 |
} /* dest == bitmap */ |
| 1265 |
|
| 1266 |
if( !(tilemap->type==TILEMAP_OPAQUE || (flags&TILEMAP_IGNORE_TRANSPARENCY)) ) |
| 1267 |
{ |
| 1268 |
if( flags&TILEMAP_BACK ) |
| 1269 |
{ |
| 1270 |
mask |= TILE_FLAG_BG_OPAQUE; |
| 1271 |
value |= TILE_FLAG_BG_OPAQUE; |
| 1272 |
} |
| 1273 |
else |
| 1274 |
{ |
| 1275 |
mask |= TILE_FLAG_FG_OPAQUE; |
| 1276 |
value |= TILE_FLAG_FG_OPAQUE; |
| 1277 |
} |
| 1278 |
} |
| 1279 |
|
| 1280 |
blit.tilemap_priority_code = (priority & 0xffff) | (tilemap->palette_offset << 16); |
| 1281 |
|
| 1282 |
if( rows == 1 && cols == 1 ) |
| 1283 |
{ /* XY scrolling playfield */ |
| 1284 |
int scrollx = rowscroll[0]; |
| 1285 |
int scrolly = colscroll[0]; |
| 1286 |
|
| 1287 |
if( scrollx < 0 ) |
| 1288 |
{ |
| 1289 |
scrollx = tilemap->cached_width - (-scrollx) % tilemap->cached_width; |
| 1290 |
} |
| 1291 |
else |
| 1292 |
{ |
| 1293 |
scrollx = scrollx % tilemap->cached_width; |
| 1294 |
} |
| 1295 |
|
| 1296 |
if( scrolly < 0 ) |
| 1297 |
{ |
| 1298 |
scrolly = tilemap->cached_height - (-scrolly) % tilemap->cached_height; |
| 1299 |
} |
| 1300 |
else |
| 1301 |
{ |
| 1302 |
scrolly = scrolly % tilemap->cached_height; |
| 1303 |
} |
| 1304 |
|
| 1305 |
blit.clip_left = left; |
| 1306 |
blit.clip_top = top; |
| 1307 |
blit.clip_right = right; |
| 1308 |
blit.clip_bottom = bottom; |
| 1309 |
|
| 1310 |
for( |
| 1311 |
ypos = scrolly - tilemap->cached_height; |
| 1312 |
ypos < blit.clip_bottom; |
| 1313 |
ypos += tilemap->cached_height ) |
| 1314 |
{ |
| 1315 |
for( |
| 1316 |
xpos = scrollx - tilemap->cached_width; |
| 1317 |
xpos < blit.clip_right; |
| 1318 |
xpos += tilemap->cached_width ) |
| 1319 |
{ |
| 1320 |
drawfunc( tilemap, xpos, ypos, mask, value ); |
| 1321 |
} |
| 1322 |
} |
| 1323 |
} |
| 1324 |
else if( rows == 1 ) |
| 1325 |
{ /* scrolling columns + horizontal scroll */ |
| 1326 |
int col = 0; |
| 1327 |
int colwidth = tilemap->cached_width / cols; |
| 1328 |
int scrollx = rowscroll[0]; |
| 1329 |
|
| 1330 |
if( scrollx < 0 ) |
| 1331 |
{ |
| 1332 |
scrollx = tilemap->cached_width - (-scrollx) % tilemap->cached_width; |
| 1333 |
} |
| 1334 |
else |
| 1335 |
{ |
| 1336 |
scrollx = scrollx % tilemap->cached_width; |
| 1337 |
} |
| 1338 |
|
| 1339 |
blit.clip_top = top; |
| 1340 |
blit.clip_bottom = bottom; |
| 1341 |
|
| 1342 |
while( col < cols ) |
| 1343 |
{ |
| 1344 |
int cons = 1; |
| 1345 |
int scrolly = colscroll[col]; |
| 1346 |
|
| 1347 |
/* count consecutive columns scrolled by the same amount */ |
| 1348 |
if( scrolly != TILE_LINE_DISABLED ) |
| 1349 |
{ |
| 1350 |
while( col + cons < cols && colscroll[col + cons] == scrolly ) cons++; |
| 1351 |
|
| 1352 |
if( scrolly < 0 ) |
| 1353 |
{ |
| 1354 |
scrolly = tilemap->cached_height - (-scrolly) % tilemap->cached_height; |
| 1355 |
} |
| 1356 |
else |
| 1357 |
{ |
| 1358 |
scrolly %= tilemap->cached_height; |
| 1359 |
} |
| 1360 |
|
| 1361 |
blit.clip_left = col * colwidth + scrollx; |
| 1362 |
if (blit.clip_left < left) blit.clip_left = left; |
| 1363 |
blit.clip_right = (col + cons) * colwidth + scrollx; |
| 1364 |
if (blit.clip_right > right) blit.clip_right = right; |
| 1365 |
|
| 1366 |
for( |
| 1367 |
ypos = scrolly - tilemap->cached_height; |
| 1368 |
ypos < blit.clip_bottom; |
| 1369 |
ypos += tilemap->cached_height ) |
| 1370 |
{ |
| 1371 |
drawfunc( tilemap, scrollx, ypos, mask, value ); |
| 1372 |
} |
| 1373 |
|
| 1374 |
blit.clip_left = col * colwidth + scrollx - tilemap->cached_width; |
| 1375 |
if (blit.clip_left < left) blit.clip_left = left; |
| 1376 |
blit.clip_right = (col + cons) * colwidth + scrollx - tilemap->cached_width; |
| 1377 |
if (blit.clip_right > right) blit.clip_right = right; |
| 1378 |
|
| 1379 |
for( |
| 1380 |
ypos = scrolly - tilemap->cached_height; |
| 1381 |
ypos < blit.clip_bottom; |
| 1382 |
ypos += tilemap->cached_height ) |
| 1383 |
{ |
| 1384 |
drawfunc( tilemap, scrollx - tilemap->cached_width, ypos, mask, value ); |
| 1385 |
} |
| 1386 |
} |
| 1387 |
col += cons; |
| 1388 |
} |
| 1389 |
} |
| 1390 |
else if( cols == 1 ) |
| 1391 |
{ /* scrolling rows + vertical scroll */ |
| 1392 |
int row = 0; |
| 1393 |
int rowheight = tilemap->cached_height / rows; |
| 1394 |
int scrolly = colscroll[0]; |
| 1395 |
if( scrolly < 0 ) |
| 1396 |
{ |
| 1397 |
scrolly = tilemap->cached_height - (-scrolly) % tilemap->cached_height; |
| 1398 |
} |
| 1399 |
else |
| 1400 |
{ |
| 1401 |
scrolly = scrolly % tilemap->cached_height; |
| 1402 |
} |
| 1403 |
blit.clip_left = left; |
| 1404 |
blit.clip_right = right; |
| 1405 |
while( row < rows ) |
| 1406 |
{ |
| 1407 |
int cons = 1; |
| 1408 |
int scrollx = rowscroll[row]; |
| 1409 |
/* count consecutive rows scrolled by the same amount */ |
| 1410 |
if( scrollx != TILE_LINE_DISABLED ) |
| 1411 |
{ |
| 1412 |
while( row + cons < rows && rowscroll[row + cons] == scrollx ) cons++; |
| 1413 |
if( scrollx < 0) |
| 1414 |
{ |
| 1415 |
scrollx = tilemap->cached_width - (-scrollx) % tilemap->cached_width; |
| 1416 |
} |
| 1417 |
else |
| 1418 |
{ |
| 1419 |
scrollx %= tilemap->cached_width; |
| 1420 |
} |
| 1421 |
blit.clip_top = row * rowheight + scrolly; |
| 1422 |
if (blit.clip_top < top) blit.clip_top = top; |
| 1423 |
blit.clip_bottom = (row + cons) * rowheight + scrolly; |
| 1424 |
if (blit.clip_bottom > bottom) blit.clip_bottom = bottom; |
| 1425 |
for( |
| 1426 |
xpos = scrollx - tilemap->cached_width; |
| 1427 |
xpos < blit.clip_right; |
| 1428 |
xpos += tilemap->cached_width ) |
| 1429 |
{ |
| 1430 |
drawfunc( tilemap, xpos, scrolly, mask, value ); |
| 1431 |
} |
| 1432 |
blit.clip_top = row * rowheight + scrolly - tilemap->cached_height; |
| 1433 |
if (blit.clip_top < top) blit.clip_top = top; |
| 1434 |
blit.clip_bottom = (row + cons) * rowheight + scrolly - tilemap->cached_height; |
| 1435 |
if (blit.clip_bottom > bottom) blit.clip_bottom = bottom; |
| 1436 |
for( |
| 1437 |
xpos = scrollx - tilemap->cached_width; |
| 1438 |
xpos < blit.clip_right; |
| 1439 |
xpos += tilemap->cached_width ) |
| 1440 |
{ |
| 1441 |
drawfunc( tilemap, xpos, scrolly - tilemap->cached_height, mask, value ); |
| 1442 |
} |
| 1443 |
} |
| 1444 |
row += cons; |
| 1445 |
} |
| 1446 |
} |
| 1447 |
} |
| 1448 |
profiler_mark(PROFILER_END); |
| 1449 |
} |
| 1450 |
|
| 1451 |
/* notes: |
| 1452 |
- startx and starty MUST be UINT32 for calculations to work correctly |
| 1453 |
- srcbitmap->width and height are assumed to be a power of 2 to speed up wraparound |
| 1454 |
*/ |
| 1455 |
void tilemap_draw_roz(struct mame_bitmap *dest,const struct rectangle *cliprect,struct tilemap *tilemap, |
| 1456 |
UINT32 startx,UINT32 starty,int incxx,int incxy,int incyx,int incyy, |
| 1457 |
int wraparound, |
| 1458 |
UINT32 flags, UINT32 priority ) |
| 1459 |
{ |
| 1460 |
int mask,value; |
| 1461 |
|
| 1462 |
profiler_mark(PROFILER_TILEMAP_DRAW_ROZ); |
| 1463 |
if( tilemap->enable ) |
| 1464 |
{ |
| 1465 |
/* tile priority */ |
| 1466 |
mask = TILE_FLAG_TILE_PRIORITY; |
| 1467 |
value = TILE_FLAG_TILE_PRIORITY&flags; |
| 1468 |
|
| 1469 |
tilemap_get_pixmap( tilemap ); /* force update */ |
| 1470 |
|
| 1471 |
if( !(tilemap->type==TILEMAP_OPAQUE || (flags&TILEMAP_IGNORE_TRANSPARENCY)) ) |
| 1472 |
{ |
| 1473 |
if( flags&TILEMAP_BACK ) |
| 1474 |
{ |
| 1475 |
mask |= TILE_FLAG_BG_OPAQUE; |
| 1476 |
value |= TILE_FLAG_BG_OPAQUE; |
| 1477 |
} |
| 1478 |
else |
| 1479 |
{ |
| 1480 |
mask |= TILE_FLAG_FG_OPAQUE; |
| 1481 |
value |= TILE_FLAG_FG_OPAQUE; |
| 1482 |
} |
| 1483 |
} |
| 1484 |
|
| 1485 |
switch( dest->depth ) |
| 1486 |
{ |
| 1487 |
|
| 1488 |
case 32: |
| 1489 |
copyrozbitmap_core32BPP(dest,tilemap,startx,starty,incxx,incxy,incyx,incyy, |
| 1490 |
wraparound,cliprect,mask,value,priority); |
| 1491 |
break; |
| 1492 |
|
| 1493 |
case 15: |
| 1494 |
case 16: |
| 1495 |
copyrozbitmap_core16BPP(dest,tilemap,startx,starty,incxx,incxy,incyx,incyy, |
| 1496 |
wraparound,cliprect,mask,value,priority); |
| 1497 |
break; |
| 1498 |
|
| 1499 |
default: |
| 1500 |
exit(1); |
| 1501 |
} |
| 1502 |
} /* tilemap->enable */ |
| 1503 |
profiler_mark(PROFILER_END); |
| 1504 |
} |
| 1505 |
|
| 1506 |
|
| 1507 |
|
| 1508 |
UINT32 tilemap_count( void ) |
| 1509 |
{ |
| 1510 |
UINT32 count = 0; |
| 1511 |
struct tilemap *tilemap = first_tilemap; |
| 1512 |
while( tilemap ) |
| 1513 |
{ |
| 1514 |
count++; |
| 1515 |
tilemap = tilemap->next; |
| 1516 |
} |
| 1517 |
return count; |
| 1518 |
} |
| 1519 |
|
| 1520 |
static struct tilemap *tilemap_nb_find( int number ) |
| 1521 |
{ |
| 1522 |
struct tilemap *tilemap = first_tilemap; |
| 1523 |
while( number-- ) |
| 1524 |
tilemap = tilemap->next; |
| 1525 |
return tilemap; |
| 1526 |
} |
| 1527 |
|
| 1528 |
void tilemap_nb_size( UINT32 number, UINT32 *width, UINT32 *height ) |
| 1529 |
{ |
| 1530 |
struct tilemap *tilemap = tilemap_nb_find( number ); |
| 1531 |
*width = tilemap->cached_width; |
| 1532 |
*height = tilemap->cached_height; |
| 1533 |
} |
| 1534 |
|
| 1535 |
void tilemap_nb_draw( struct mame_bitmap *dest, UINT32 number, UINT32 scrollx, UINT32 scrolly ) |
| 1536 |
{ |
| 1537 |
tilemap_draw_func drawfunc = pick_draw_func(dest); |
| 1538 |
int xpos,ypos; |
| 1539 |
struct tilemap *tilemap = tilemap_nb_find( number ); |
| 1540 |
|
| 1541 |
blit.screen_bitmap = dest; |
| 1542 |
blit.screen_bitmap_pitch_line = ((UINT8 *)dest->line[1]) - ((UINT8 *)dest->line[0]); |
| 1543 |
switch( dest->depth ) |
| 1544 |
{ |
| 1545 |
case 32: |
| 1546 |
blit.draw_masked = (blitmask_t)pdt32; |
| 1547 |
blit.draw_opaque = (blitopaque_t)pdo32; |
| 1548 |
blit.screen_bitmap_pitch_line /= 4; |
| 1549 |
break; |
| 1550 |
|
| 1551 |
case 15: |
| 1552 |
blit.draw_masked = (blitmask_t)pdt15; |
| 1553 |
blit.draw_opaque = (blitopaque_t)pdo15; |
| 1554 |
blit.screen_bitmap_pitch_line /= 2; |
| 1555 |
break; |
| 1556 |
|
| 1557 |
case 16: |
| 1558 |
blit.draw_masked = (blitmask_t)pdt16; |
| 1559 |
blit.draw_opaque = (blitopaque_t)pdo16; |
| 1560 |
blit.screen_bitmap_pitch_line /= 2; |
| 1561 |
break; |
| 1562 |
|
| 1563 |
default: |
| 1564 |
exit(1); |
| 1565 |
break; |
| 1566 |
} |
| 1567 |
blit.screen_bitmap_pitch_row = blit.screen_bitmap_pitch_line*tilemap->cached_tile_height; |
| 1568 |
blit.tilemap_priority_code = 0; |
| 1569 |
scrollx = tilemap->cached_width - scrollx % tilemap->cached_width; |
| 1570 |
scrolly = tilemap->cached_height - scrolly % tilemap->cached_height; |
| 1571 |
|
| 1572 |
blit.clip_left = 0; |
| 1573 |
blit.clip_top = 0; |
| 1574 |
blit.clip_right = dest->width; |
| 1575 |
blit.clip_bottom = dest->height; |
| 1576 |
|
| 1577 |
for( |
| 1578 |
ypos = scrolly - tilemap->cached_height; |
| 1579 |
ypos < blit.clip_bottom; |
| 1580 |
ypos += tilemap->cached_height ) |
| 1581 |
{ |
| 1582 |
for( |
| 1583 |
xpos = scrollx - tilemap->cached_width; |
| 1584 |
xpos < blit.clip_right; |
| 1585 |
xpos += tilemap->cached_width ) |
| 1586 |
{ |
| 1587 |
drawfunc( tilemap, xpos, ypos, 0, 0 ); |
| 1588 |
} |
| 1589 |
} |
| 1590 |
} |
| 1591 |
|
| 1592 |
|
| 1593 |
/***********************************************************************************/ |
| 1594 |
|
| 1595 |
#endif // !DECLARE && !TRANSP |
| 1596 |
|
| 1597 |
#ifdef DECLARE |
| 1598 |
|
| 1599 |
DECLARE(copyrozbitmap_core,(struct mame_bitmap *bitmap,struct tilemap *tilemap, |
| 1600 |
UINT32 startx,UINT32 starty,int incxx,int incxy,int incyx,int incyy,int wraparound, |
| 1601 |
const struct rectangle *clip, |
| 1602 |
int mask,int value, |
| 1603 |
UINT32 priority), |
| 1604 |
{ |
| 1605 |
UINT32 cx; |
| 1606 |
UINT32 cy; |
| 1607 |
int x; |
| 1608 |
int sx; |
| 1609 |
int sy; |
| 1610 |
int ex; |
| 1611 |
int ey; |
| 1612 |
struct mame_bitmap *srcbitmap = tilemap->pixmap; |
| 1613 |
struct mame_bitmap *transparency_bitmap = tilemap->transparency_bitmap; |
| 1614 |
const int xmask = srcbitmap->width-1; |
| 1615 |
const int ymask = srcbitmap->height-1; |
| 1616 |
const int widthshifted = srcbitmap->width << 16; |
| 1617 |
const int heightshifted = srcbitmap->height << 16; |
| 1618 |
DATA_TYPE *dest; |
| 1619 |
UINT8 *pri; |
| 1620 |
const UINT16 *src; |
| 1621 |
const UINT8 *pMask; |
| 1622 |
|
| 1623 |
if (clip) |
| 1624 |
{ |
| 1625 |
startx += clip->min_x * incxx + clip->min_y * incyx; |
| 1626 |
starty += clip->min_x * incxy + clip->min_y * incyy; |
| 1627 |
|
| 1628 |
sx = clip->min_x; |
| 1629 |
sy = clip->min_y; |
| 1630 |
ex = clip->max_x; |
| 1631 |
ey = clip->max_y; |
| 1632 |
} |
| 1633 |
else |
| 1634 |
{ |
| 1635 |
sx = 0; |
| 1636 |
sy = 0; |
| 1637 |
ex = bitmap->width-1; |
| 1638 |
ey = bitmap->height-1; |
| 1639 |
} |
| 1640 |
|
| 1641 |
|
| 1642 |
if (Machine->orientation & ORIENTATION_SWAP_XY) |
| 1643 |
{ |
| 1644 |
int t; |
| 1645 |
|
| 1646 |
t = startx; startx = starty; starty = t; |
| 1647 |
t = sx; sx = sy; sy = t; |
| 1648 |
t = ex; ex = ey; ey = t; |
| 1649 |
t = incxx; incxx = incyy; incyy = t; |
| 1650 |
t = incxy; incxy = incyx; incyx = t; |
| 1651 |
} |
| 1652 |
|
| 1653 |
if (Machine->orientation & ORIENTATION_FLIP_X) |
| 1654 |
{ |
| 1655 |
int w = ex - sx; |
| 1656 |
|
| 1657 |
incxy = -incxy; |
| 1658 |
incyx = -incyx; |
| 1659 |
startx = widthshifted - startx - 1; |
| 1660 |
startx -= incxx * w; |
| 1661 |
starty -= incxy * w; |
| 1662 |
|
| 1663 |
w = sx; |
| 1664 |
sx = bitmap->width-1 - ex; |
| 1665 |
ex = bitmap->width-1 - w; |
| 1666 |
} |
| 1667 |
|
| 1668 |
if (Machine->orientation & ORIENTATION_FLIP_Y) |
| 1669 |
{ |
| 1670 |
int h = ey - sy; |
| 1671 |
|
| 1672 |
incxy = -incxy; |
| 1673 |
incyx = -incyx; |
| 1674 |
starty = heightshifted - starty - 1; |
| 1675 |
startx -= incyx * h; |
| 1676 |
starty -= incyy * h; |
| 1677 |
|
| 1678 |
h = sy; |
| 1679 |
sy = bitmap->height-1 - ey; |
| 1680 |
ey = bitmap->height-1 - h; |
| 1681 |
} |
| 1682 |
|
| 1683 |
if (incxy == 0 && incyx == 0 && !wraparound) |
| 1684 |
{ |
| 1685 |
/* optimized loop for the not rotated case */ |
| 1686 |
|
| 1687 |
if (incxx == 0x10000) |
| 1688 |
{ |
| 1689 |
/* optimized loop for the not zoomed case */ |
| 1690 |
|
| 1691 |
/* startx is unsigned */ |
| 1692 |
startx = ((INT32)startx) >> 16; |
| 1693 |
|
| 1694 |
if (startx >= srcbitmap->width) |
| 1695 |
{ |
| 1696 |
sx += -startx; |
| 1697 |
startx = 0; |
| 1698 |
} |
| 1699 |
|
| 1700 |
if (sx <= ex) |
| 1701 |
{ |
| 1702 |
while (sy <= ey) |
| 1703 |
{ |
| 1704 |
if (starty < heightshifted) |
| 1705 |
{ |
| 1706 |
x = sx; |
| 1707 |
cx = startx; |
| 1708 |
cy = starty >> 16; |
| 1709 |
dest = ((DATA_TYPE *)bitmap->line[sy]) + sx; |
| 1710 |
|
| 1711 |
pri = ((UINT8 *)priority_bitmap->line[sy]) + sx; |
| 1712 |
src = (UINT16 *)srcbitmap->line[cy]; |
| 1713 |
pMask = (UINT8 *)transparency_bitmap->line[cy]; |
| 1714 |
|
| 1715 |
while (x <= ex && cx < srcbitmap->width) |
| 1716 |
{ |
| 1717 |
if ( (pMask[cx]&mask) == value ) |
| 1718 |
{ |
| 1719 |
*dest = src[cx]; |
| 1720 |
*pri |= priority; |
| 1721 |
} |
| 1722 |
cx++; |
| 1723 |
x++; |
| 1724 |
dest++; |
| 1725 |
pri++; |
| 1726 |
} |
| 1727 |
} |
| 1728 |
starty += incyy; |
| 1729 |
sy++; |
| 1730 |
} |
| 1731 |
} |
| 1732 |
} |
| 1733 |
else |
| 1734 |
{ |
| 1735 |
while (startx >= widthshifted && sx <= ex) |
| 1736 |
{ |
| 1737 |
startx += incxx; |
| 1738 |
sx++; |
| 1739 |
} |
| 1740 |
|
| 1741 |
if (sx <= ex) |
| 1742 |
{ |
| 1743 |
while (sy <= ey) |
| 1744 |
{ |
| 1745 |
if (starty < heightshifted) |
| 1746 |
{ |
| 1747 |
x = sx; |
| 1748 |
cx = startx; |
| 1749 |
cy = starty >> 16; |
| 1750 |
dest = ((DATA_TYPE *)bitmap->line[sy]) + sx; |
| 1751 |
|
| 1752 |
pri = ((UINT8 *)priority_bitmap->line[sy]) + sx; |
| 1753 |
src = (UINT16 *)srcbitmap->line[cy]; |
| 1754 |
pMask = (UINT8 *)transparency_bitmap->line[cy]; |
| 1755 |
while (x <= ex && cx < widthshifted) |
| 1756 |
{ |
| 1757 |
if ( (pMask[cx>>16]&mask) == value ) |
| 1758 |
{ |
| 1759 |
*dest = src[cx >> 16]; |
| 1760 |
*pri |= priority; |
| 1761 |
} |
| 1762 |
cx += incxx; |
| 1763 |
x++; |
| 1764 |
dest++; |
| 1765 |
pri++; |
| 1766 |
} |
| 1767 |
} |
| 1768 |
starty += incyy; |
| 1769 |
sy++; |
| 1770 |
} |
| 1771 |
} |
| 1772 |
} |
| 1773 |
} |
| 1774 |
else |
| 1775 |
{ |
| 1776 |
if (wraparound) |
| 1777 |
{ |
| 1778 |
/* plot with wraparound */ |
| 1779 |
while (sy <= ey) |
| 1780 |
{ |
| 1781 |
x = sx; |
| 1782 |
cx = startx; |
| 1783 |
cy = starty; |
| 1784 |
dest = ((DATA_TYPE *)bitmap->line[sy]) + sx; |
| 1785 |
pri = ((UINT8 *)priority_bitmap->line[sy]) + sx; |
| 1786 |
while (x <= ex) |
| 1787 |
{ |
| 1788 |
if( (((UINT8 *)transparency_bitmap->line[(cy>>16)&ymask])[(cx>>16)&xmask]&mask) == value ) |
| 1789 |
{ |
| 1790 |
*dest = ((UINT16 *)srcbitmap->line[(cy >> 16) & ymask])[(cx >> 16) & xmask]; |
| 1791 |
*pri |= priority; |
| 1792 |
} |
| 1793 |
cx += incxx; |
| 1794 |
cy += incxy; |
| 1795 |
x++; |
| 1796 |
dest++; |
| 1797 |
pri++; |
| 1798 |
} |
| 1799 |
startx += incyx; |
| 1800 |
starty += incyy; |
| 1801 |
sy++; |
| 1802 |
} |
| 1803 |
} |
| 1804 |
else |
| 1805 |
{ |
| 1806 |
while (sy <= ey) |
| 1807 |
{ |
| 1808 |
x = sx; |
| 1809 |
cx = startx; |
| 1810 |
cy = starty; |
| 1811 |
dest = ((DATA_TYPE *)bitmap->line[sy]) + sx; |
| 1812 |
pri = ((UINT8 *)priority_bitmap->line[sy]) + sx; |
| 1813 |
while (x <= ex) |
| 1814 |
{ |
| 1815 |
if (cx < widthshifted && cy < heightshifted) |
| 1816 |
{ |
| 1817 |
if( (((UINT8 *)transparency_bitmap->line[cy>>16])[cx>>16]&mask)==value ) |
| 1818 |
{ |
| 1819 |
*dest = ((UINT16 *)srcbitmap->line[cy >> 16])[cx >> 16]; |
| 1820 |
*pri |= priority; |
| 1821 |
} |
| 1822 |
} |
| 1823 |
cx += incxx; |
| 1824 |
cy += incxy; |
| 1825 |
x++; |
| 1826 |
dest++; |
| 1827 |
pri++; |
| 1828 |
} |
| 1829 |
startx += incyx; |
| 1830 |
starty += incyy; |
| 1831 |
sy++; |
| 1832 |
} |
| 1833 |
} |
| 1834 |
} |
| 1835 |
}) |
| 1836 |
|
| 1837 |
#ifndef osd_pend |
| 1838 |
#define osd_pend() do { } while (0) |
| 1839 |
#endif |
| 1840 |
|
| 1841 |
DECLARE( draw, (struct tilemap *tilemap, int xpos, int ypos, int mask, int value ), |
| 1842 |
{ |
| 1843 |
trans_t transPrev; |
| 1844 |
trans_t transCur; |
| 1845 |
const UINT8 *pTrans; |
| 1846 |
UINT32 cached_indx; |
| 1847 |
struct mame_bitmap *screen = blit.screen_bitmap; |
| 1848 |
int tilemap_priority_code = blit.tilemap_priority_code; |
| 1849 |
int x1 = xpos; |
| 1850 |
int y1 = ypos; |
| 1851 |
int x2 = xpos+tilemap->cached_width; |
| 1852 |
int y2 = ypos+tilemap->cached_height; |
| 1853 |
DATA_TYPE *dest_baseaddr = NULL; |
| 1854 |
DATA_TYPE *dest_next; |
| 1855 |
int dy; |
| 1856 |
int count; |
| 1857 |
const UINT16 *source0; |
| 1858 |
DATA_TYPE *dest0; |
| 1859 |
UINT8 *pmap0; |
| 1860 |
int i; |
| 1861 |
int row; |
| 1862 |
int x_start; |
| 1863 |
int x_end; |
| 1864 |
int column; |
| 1865 |
int c1; /* leftmost visible column in source tilemap */ |
| 1866 |
int c2; /* rightmost visible column in source tilemap */ |
| 1867 |
int y; /* current screen line to render */ |
| 1868 |
int y_next; |
| 1869 |
UINT8 *priority_bitmap_baseaddr; |
| 1870 |
UINT8 *priority_bitmap_next; |
| 1871 |
const UINT16 *source_baseaddr; |
| 1872 |
const UINT16 *source_next; |
| 1873 |
const UINT8 *mask0; |
| 1874 |
const UINT8 *mask_baseaddr; |
| 1875 |
const UINT8 *mask_next; |
| 1876 |
|
| 1877 |
/* clip source coordinates */ |
| 1878 |
if( x1<blit.clip_left ) x1 = blit.clip_left; |
| 1879 |
if( x2>blit.clip_right ) x2 = blit.clip_right; |
| 1880 |
if( y1<blit.clip_top ) y1 = blit.clip_top; |
| 1881 |
if( y2>blit.clip_bottom ) y2 = blit.clip_bottom; |
| 1882 |
|
| 1883 |
if( x1<x2 && y1<y2 ) /* do nothing if totally clipped */ |
| 1884 |
{ |
| 1885 |
priority_bitmap_baseaddr = xpos + (UINT8 *)priority_bitmap->line[y1]; |
| 1886 |
if( screen ) |
| 1887 |
{ |
| 1888 |
dest_baseaddr = xpos + (DATA_TYPE *)screen->line[y1]; |
| 1889 |
} |
| 1890 |
|
| 1891 |
/* convert screen coordinates to source tilemap coordinates */ |
| 1892 |
x1 -= xpos; |
| 1893 |
y1 -= ypos; |
| 1894 |
x2 -= xpos; |
| 1895 |
y2 -= ypos; |
| 1896 |
|
| 1897 |
source_baseaddr = (UINT16 *)tilemap->pixmap->line[y1]; |
| 1898 |
mask_baseaddr = tilemap->transparency_bitmap->line[y1]; |
| 1899 |
|
| 1900 |
c1 = x1/tilemap->cached_tile_width; /* round down */ |
| 1901 |
c2 = (x2+tilemap->cached_tile_width-1)/tilemap->cached_tile_width; /* round up */ |
| 1902 |
|
| 1903 |
y = y1; |
| 1904 |
y_next = tilemap->cached_tile_height*(y1/tilemap->cached_tile_height) + tilemap->cached_tile_height; |
| 1905 |
if( y_next>y2 ) y_next = y2; |
| 1906 |
|
| 1907 |
dy = y_next-y; |
| 1908 |
dest_next = dest_baseaddr + dy*blit.screen_bitmap_pitch_line; |
| 1909 |
priority_bitmap_next = priority_bitmap_baseaddr + dy*priority_bitmap_pitch_line; |
| 1910 |
source_next = source_baseaddr + dy*tilemap->pixmap_pitch_line; |
| 1911 |
mask_next = mask_baseaddr + dy*tilemap->transparency_bitmap_pitch_line; |
| 1912 |
for(;;) |
| 1913 |
{ |
| 1914 |
row = y/tilemap->cached_tile_height; |
| 1915 |
x_start = x1; |
| 1916 |
|
| 1917 |
transPrev = eWHOLLY_TRANSPARENT; |
| 1918 |
pTrans = mask_baseaddr + x_start; |
| 1919 |
|
| 1920 |
cached_indx = row*tilemap->num_cached_cols + c1; |
| 1921 |
for( column=c1; column<=c2; column++ ) |
| 1922 |
{ |
| 1923 |
if( column == c2 ) |
| 1924 |
{ |
| 1925 |
transCur = eWHOLLY_TRANSPARENT; |
| 1926 |
goto L_Skip; |
| 1927 |
} |
| 1928 |
|
| 1929 |
if( tilemap->transparency_data[cached_indx]==TILE_FLAG_DIRTY ) |
| 1930 |
{ |
| 1931 |
update_tile_info( tilemap, cached_indx, column, row ); |
| 1932 |
} |
| 1933 |
|
| 1934 |
if( (tilemap->transparency_data[cached_indx]&mask)!=0 ) |
| 1935 |
{ |
| 1936 |
transCur = eMASKED; |
| 1937 |
} |
| 1938 |
else |
| 1939 |
{ |
| 1940 |
transCur = (((*pTrans)&mask) == value)?eWHOLLY_OPAQUE:eWHOLLY_TRANSPARENT; |
| 1941 |
} |
| 1942 |
pTrans += tilemap->cached_tile_width; |
| 1943 |
|
| 1944 |
L_Skip: |
| 1945 |
if( transCur!=transPrev ) |
| 1946 |
{ |
| 1947 |
x_end = column*tilemap->cached_tile_width; |
| 1948 |
if( x_end<x1 ) x_end = x1; |
| 1949 |
if( x_end>x2 ) x_end = x2; |
| 1950 |
|
| 1951 |
if( transPrev != eWHOLLY_TRANSPARENT ) |
| 1952 |
{ |
| 1953 |
count = x_end - x_start; |
| 1954 |
source0 = source_baseaddr + x_start; |
| 1955 |
dest0 = dest_baseaddr + x_start; |
| 1956 |
pmap0 = priority_bitmap_baseaddr + x_start; |
| 1957 |
|
| 1958 |
if( transPrev == eWHOLLY_OPAQUE ) |
| 1959 |
{ |
| 1960 |
i = y; |
| 1961 |
for(;;) |
| 1962 |
{ |
| 1963 |
blit.draw_opaque( dest0, source0, count, pmap0, tilemap_priority_code ); |
| 1964 |
if( ++i == y_next ) break; |
| 1965 |
|
| 1966 |
dest0 += blit.screen_bitmap_pitch_line; |
| 1967 |
source0 += tilemap->pixmap_pitch_line; |
| 1968 |
pmap0 += priority_bitmap_pitch_line; |
| 1969 |
} |
| 1970 |
} /* transPrev == eWHOLLY_OPAQUE */ |
| 1971 |
else /* transPrev == eMASKED */ |
| 1972 |
{ |
| 1973 |
mask0 = mask_baseaddr + x_start; |
| 1974 |
i = y; |
| 1975 |
for(;;) |
| 1976 |
{ |
| 1977 |
blit.draw_masked( dest0, source0, mask0, mask, value, count, pmap0, tilemap_priority_code ); |
| 1978 |
if( ++i == y_next ) break; |
| 1979 |
|
| 1980 |
dest0 += blit.screen_bitmap_pitch_line; |
| 1981 |
source0 += tilemap->pixmap_pitch_line; |
| 1982 |
mask0 += tilemap->transparency_bitmap_pitch_line; |
| 1983 |
pmap0 += priority_bitmap_pitch_line; |
| 1984 |
} |
| 1985 |
} /* transPrev == eMASKED */ |
| 1986 |
} /* transPrev != eWHOLLY_TRANSPARENT */ |
| 1987 |
x_start = x_end; |
| 1988 |
transPrev = transCur; |
| 1989 |
} |
| 1990 |
cached_indx++; |
| 1991 |
} |
| 1992 |
if( y_next==y2 ) break; /* we are done! */ |
| 1993 |
|
| 1994 |
priority_bitmap_baseaddr = priority_bitmap_next; |
| 1995 |
dest_baseaddr = dest_next; |
| 1996 |
source_baseaddr = source_next; |
| 1997 |
mask_baseaddr = mask_next; |
| 1998 |
y = y_next; |
| 1999 |
y_next += tilemap->cached_tile_height; |
| 2000 |
|
| 2001 |
if( y_next>=y2 ) |
| 2002 |
{ |
| 2003 |
y_next = y2; |
| 2004 |
} |
| 2005 |
else |
| 2006 |
{ |
| 2007 |
dest_next += blit.screen_bitmap_pitch_row; |
| 2008 |
priority_bitmap_next += priority_bitmap_pitch_row; |
| 2009 |
source_next += tilemap->pixmap_pitch_row; |
| 2010 |
mask_next += tilemap->transparency_bitmap_pitch_row; |
| 2011 |
} |
| 2012 |
} /* process next row */ |
| 2013 |
} /* not totally clipped */ |
| 2014 |
|
| 2015 |
osd_pend(); |
| 2016 |
}) |
| 2017 |
|
| 2018 |
#undef DATA_TYPE |
| 2019 |
#undef DEPTH |
| 2020 |
#undef DECLARE |
| 2021 |
#endif /* DECLARE */ |
| 2022 |
|
| 2023 |
#ifdef TRANSP |
| 2024 |
/*************************************************************************************************/ |
| 2025 |
|
| 2026 |
/* Each of the following routines draws pixmap and transarency data for a single tile. |
| 2027 |
* |
| 2028 |
* This function returns a per-tile code. Each bit of this code is 0 if the corresponding |
| 2029 |
* bit is zero in every byte of transparency data in the tile, or 1 if that bit is not |
| 2030 |
* consistant within the tile. |
| 2031 |
* |
| 2032 |
* This precomputed value allows us for any particular tile and mask, to determine if all pixels |
| 2033 |
* in that tile have the same masked transparency value. |
| 2034 |
*/ |
| 2035 |
|
| 2036 |
static UINT8 TRANSP(HandleTransparencyBitmask)(struct tilemap *tilemap, UINT32 x0, UINT32 y0, UINT32 flags) |
| 2037 |
{ |
| 2038 |
UINT32 tile_width = tilemap->cached_tile_width; |
| 2039 |
UINT32 tile_height = tilemap->cached_tile_height; |
| 2040 |
struct mame_bitmap *pixmap = tilemap->pixmap; |
| 2041 |
struct mame_bitmap *transparency_bitmap = tilemap->transparency_bitmap; |
| 2042 |
int pitch = tile_width + tile_info.skip; |
| 2043 |
PAL_INIT; |
| 2044 |
UINT32 *pPenToPixel; |
| 2045 |
const UINT8 *pPenData = tile_info.pen_data; |
| 2046 |
const UINT8 *pSource; |
| 2047 |
UINT32 code_transparent = tile_info.priority; |
| 2048 |
UINT32 code_opaque = code_transparent | TILE_FLAG_FG_OPAQUE; |
| 2049 |
UINT32 tx; |
| 2050 |
UINT32 ty; |
| 2051 |
UINT32 data; |
| 2052 |
UINT32 yx; |
| 2053 |
UINT32 x; |
| 2054 |
UINT32 y; |
| 2055 |
UINT32 pen; |
| 2056 |
UINT8 *pBitmask = tile_info.mask_data; |
| 2057 |
UINT32 bitoffs; |
| 2058 |
int bWhollyOpaque; |
| 2059 |
int bWhollyTransparent; |
| 2060 |
int bDontIgnoreTransparency = !(flags&TILE_IGNORE_TRANSPARENCY); |
| 2061 |
|
| 2062 |
bWhollyOpaque = 1; |
| 2063 |
bWhollyTransparent = 1; |
| 2064 |
|
| 2065 |
pPenToPixel = tilemap->pPenToPixel[flags&(TILE_SWAPXY|TILE_FLIPY|TILE_FLIPX)]; |
| 2066 |
|
| 2067 |
if( flags&TILE_4BPP ) |
| 2068 |
{ |
| 2069 |
for( ty=tile_height; ty!=0; ty-- ) |
| 2070 |
{ |
| 2071 |
pSource = pPenData; |
| 2072 |
for( tx=tile_width/2; tx!=0; tx-- ) |
| 2073 |
{ |
| 2074 |
data = *pSource++; |
| 2075 |
|
| 2076 |
pen = data&0xf; |
| 2077 |
yx = *pPenToPixel++; |
| 2078 |
x = x0+(yx%MAX_TILESIZE); |
| 2079 |
y = y0+(yx/MAX_TILESIZE); |
| 2080 |
*(x+(UINT16 *)pixmap->line[y]) = PAL_GET(pen); |
| 2081 |
|
| 2082 |
pen = data>>4; |
| 2083 |
yx = *pPenToPixel++; |
| 2084 |
x = x0+(yx%MAX_TILESIZE); |
| 2085 |
y = y0+(yx/MAX_TILESIZE); |
| 2086 |
*(x+(UINT16 *)pixmap->line[y]) = PAL_GET(pen); |
| 2087 |
} |
| 2088 |
pPenData += pitch/2; |
| 2089 |
} |
| 2090 |
} |
| 2091 |
else |
| 2092 |
{ |
| 2093 |
for( ty=tile_height; ty!=0; ty-- ) |
| 2094 |
{ |
| 2095 |
pSource = pPenData; |
| 2096 |
for( tx=tile_width; tx!=0; tx-- ) |
| 2097 |
{ |
| 2098 |
pen = *pSource++; |
| 2099 |
yx = *pPenToPixel++; |
| 2100 |
x = x0+(yx%MAX_TILESIZE); |
| 2101 |
y = y0+(yx/MAX_TILESIZE); |
| 2102 |
*(x+(UINT16 *)pixmap->line[y]) = PAL_GET(pen); |
| 2103 |
} |
| 2104 |
pPenData += pitch; |
| 2105 |
} |
| 2106 |
} |
| 2107 |
|
| 2108 |
if( Machine->orientation & ORIENTATION_SWAP_XY ) |
| 2109 |
{ |
| 2110 |
flags ^= TILE_SWAPXY; |
| 2111 |
} |
| 2112 |
|
| 2113 |
pPenToPixel = tilemap->pPenToPixel[flags&(TILE_SWAPXY|TILE_FLIPY|TILE_FLIPX)]; |
| 2114 |
bitoffs = 0; |
| 2115 |
for( ty=tile_height; ty!=0; ty-- ) |
| 2116 |
{ |
| 2117 |
for( tx=tile_width; tx!=0; tx-- ) |
| 2118 |
{ |
| 2119 |
yx = *pPenToPixel++; |
| 2120 |
x = x0+(yx%MAX_TILESIZE); |
| 2121 |
y = y0+(yx/MAX_TILESIZE); |
| 2122 |
if( bDontIgnoreTransparency && (pBitmask[bitoffs/8]&(0x80>>(bitoffs&7))) == 0 ) |
| 2123 |
{ |
| 2124 |
((UINT8 *)transparency_bitmap->line[y])[x] = code_transparent; |
| 2125 |
bWhollyOpaque = 0; |
| 2126 |
} |
| 2127 |
else |
| 2128 |
{ |
| 2129 |
((UINT8 *)transparency_bitmap->line[y])[x] = code_opaque; |
| 2130 |
bWhollyTransparent = 0; |
| 2131 |
} |
| 2132 |
bitoffs++; |
| 2133 |
} |
| 2134 |
} |
| 2135 |
|
| 2136 |
return (bWhollyOpaque || bWhollyTransparent)?0:TILE_FLAG_FG_OPAQUE; |
| 2137 |
} |
| 2138 |
|
| 2139 |
static UINT8 TRANSP(HandleTransparencyColor)(struct tilemap *tilemap, UINT32 x0, UINT32 y0, UINT32 flags) |
| 2140 |
{ |
| 2141 |
UINT32 tile_width = tilemap->cached_tile_width; |
| 2142 |
UINT32 tile_height = tilemap->cached_tile_height; |
| 2143 |
struct mame_bitmap *pixmap = tilemap->pixmap; |
| 2144 |
struct mame_bitmap *transparency_bitmap = tilemap->transparency_bitmap; |
| 2145 |
int pitch = tile_width + tile_info.skip; |
| 2146 |
PAL_INIT; |
| 2147 |
UINT32 *pPenToPixel = tilemap->pPenToPixel[flags&(TILE_SWAPXY|TILE_FLIPY|TILE_FLIPX)]; |
| 2148 |
const UINT8 *pPenData = tile_info.pen_data; |
| 2149 |
const UINT8 *pSource; |
| 2150 |
UINT32 code_transparent = tile_info.priority; |
| 2151 |
UINT32 code_opaque = code_transparent | TILE_FLAG_FG_OPAQUE; |
| 2152 |
UINT32 tx; |
| 2153 |
UINT32 ty; |
| 2154 |
UINT32 data; |
| 2155 |
UINT32 yx; |
| 2156 |
UINT32 x; |
| 2157 |
UINT32 y; |
| 2158 |
UINT32 pen; |
| 2159 |
UINT32 transparent_color = tilemap->transparent_pen; |
| 2160 |
int bWhollyOpaque; |
| 2161 |
int bWhollyTransparent; |
| 2162 |
|
| 2163 |
bWhollyOpaque = 1; |
| 2164 |
bWhollyTransparent = 1; |
| 2165 |
|
| 2166 |
if( flags&TILE_4BPP ) |
| 2167 |
{ |
| 2168 |
for( ty=tile_height; ty!=0; ty-- ) |
| 2169 |
{ |
| 2170 |
pSource = pPenData; |
| 2171 |
for( tx=tile_width/2; tx!=0; tx-- ) |
| 2172 |
{ |
| 2173 |
data = *pSource++; |
| 2174 |
|
| 2175 |
pen = data&0xf; |
| 2176 |
yx = *pPenToPixel++; |
| 2177 |
x = x0+(yx%MAX_TILESIZE); |
| 2178 |
y = y0+(yx/MAX_TILESIZE); |
| 2179 |
*(x+(UINT16 *)pixmap->line[y]) = PAL_GET(pen); |
| 2180 |
if( PAL_GET(pen)==transparent_color ) |
| 2181 |
{ |
| 2182 |
((UINT8 *)transparency_bitmap->line[y])[x] = code_transparent; |
| 2183 |
bWhollyOpaque = 0; |
| 2184 |
} |
| 2185 |
else |
| 2186 |
{ |
| 2187 |
((UINT8 *)transparency_bitmap->line[y])[x] = code_opaque; |
| 2188 |
bWhollyTransparent = 0; |
| 2189 |
} |
| 2190 |
|
| 2191 |
pen = data>>4; |
| 2192 |
yx = *pPenToPixel++; |
| 2193 |
x = x0+(yx%MAX_TILESIZE); |
| 2194 |
y = y0+(yx/MAX_TILESIZE); |
| 2195 |
*(x+(UINT16 *)pixmap->line[y]) = PAL_GET(pen); |
| 2196 |
if( PAL_GET(pen)==transparent_color ) |
| 2197 |
{ |
| 2198 |
((UINT8 *)transparency_bitmap->line[y])[x] = code_transparent; |
| 2199 |
bWhollyOpaque = 0; |
| 2200 |
} |
| 2201 |
else |
| 2202 |
{ |
| 2203 |
((UINT8 *)transparency_bitmap->line[y])[x] = code_opaque; |
| 2204 |
bWhollyTransparent = 0; |
| 2205 |
} |
| 2206 |
} |
| 2207 |
pPenData += pitch/2; |
| 2208 |
} |
| 2209 |
} |
| 2210 |
else |
| 2211 |
{ |
| 2212 |
for( ty=tile_height; ty!=0; ty-- ) |
| 2213 |
{ |
| 2214 |
pSource = pPenData; |
| 2215 |
for( tx=tile_width; tx!=0; tx-- ) |
| 2216 |
{ |
| 2217 |
pen = *pSource++; |
| 2218 |
yx = *pPenToPixel++; |
| 2219 |
x = x0+(yx%MAX_TILESIZE); |
| 2220 |
y = y0+(yx/MAX_TILESIZE); |
| 2221 |
*(x+(UINT16 *)pixmap->line[y]) = PAL_GET(pen); |
| 2222 |
if( PAL_GET(pen)==transparent_color ) |
| 2223 |
{ |
| 2224 |
((UINT8 *)transparency_bitmap->line[y])[x] = code_transparent; |
| 2225 |
bWhollyOpaque = 0; |
| 2226 |
} |
| 2227 |
else |
| 2228 |
{ |
| 2229 |
((UINT8 *)transparency_bitmap->line[y])[x] = code_opaque; |
| 2230 |
bWhollyTransparent = 0; |
| 2231 |
} |
| 2232 |
} |
| 2233 |
pPenData += pitch; |
| 2234 |
} |
| 2235 |
} |
| 2236 |
return (bWhollyOpaque || bWhollyTransparent)?0:TILE_FLAG_FG_OPAQUE; |
| 2237 |
} |
| 2238 |
|
| 2239 |
static UINT8 TRANSP(HandleTransparencyPen)(struct tilemap *tilemap, UINT32 x0, UINT32 y0, UINT32 flags) |
| 2240 |
{ |
| 2241 |
UINT32 tile_width = tilemap->cached_tile_width; |
| 2242 |
UINT32 tile_height = tilemap->cached_tile_height; |
| 2243 |
struct mame_bitmap *pixmap = tilemap->pixmap; |
| 2244 |
struct mame_bitmap *transparency_bitmap = tilemap->transparency_bitmap; |
| 2245 |
int pitch = tile_width + tile_info.skip; |
| 2246 |
PAL_INIT; |
| 2247 |
UINT32 *pPenToPixel = tilemap->pPenToPixel[flags&(TILE_SWAPXY|TILE_FLIPY|TILE_FLIPX)]; |
| 2248 |
const UINT8 *pPenData = tile_info.pen_data; |
| 2249 |
const UINT8 *pSource; |
| 2250 |
UINT32 code_transparent = tile_info.priority; |
| 2251 |
UINT32 code_opaque = code_transparent | TILE_FLAG_FG_OPAQUE; |
| 2252 |
UINT32 tx; |
| 2253 |
UINT32 ty; |
| 2254 |
UINT32 data; |
| 2255 |
UINT32 yx; |
| 2256 |
UINT32 x; |
| 2257 |
UINT32 y; |
| 2258 |
UINT32 pen; |
| 2259 |
UINT32 transparent_pen = tilemap->transparent_pen; |
| 2260 |
int bWhollyOpaque; |
| 2261 |
int bWhollyTransparent; |
| 2262 |
|
| 2263 |
bWhollyOpaque = 1; |
| 2264 |
bWhollyTransparent = 1; |
| 2265 |
|
| 2266 |
if( flags&TILE_IGNORE_TRANSPARENCY ) |
| 2267 |
{ |
| 2268 |
transparent_pen = ~0; |
| 2269 |
} |
| 2270 |
|
| 2271 |
if( flags&TILE_4BPP ) |
| 2272 |
{ |
| 2273 |
for( ty=tile_height; ty!=0; ty-- ) |
| 2274 |
{ |
| 2275 |
pSource = pPenData; |
| 2276 |
for( tx=tile_width/2; tx!=0; tx-- ) |
| 2277 |
{ |
| 2278 |
data = *pSource++; |
| 2279 |
|
| 2280 |
pen = data&0xf; |
| 2281 |
yx = *pPenToPixel++; |
| 2282 |
x = x0+(yx%MAX_TILESIZE); |
| 2283 |
y = y0+(yx/MAX_TILESIZE); |
| 2284 |
*(x+(UINT16 *)pixmap->line[y]) = PAL_GET(pen); |
| 2285 |
if( pen==transparent_pen ) |
| 2286 |
{ |
| 2287 |
((UINT8 *)transparency_bitmap->line[y])[x] = code_transparent; |
| 2288 |
bWhollyOpaque = 0; |
| 2289 |
} |
| 2290 |
else |
| 2291 |
{ |
| 2292 |
((UINT8 *)transparency_bitmap->line[y])[x] = code_opaque; |
| 2293 |
bWhollyTransparent = 0; |
| 2294 |
} |
| 2295 |
|
| 2296 |
pen = data>>4; |
| 2297 |
yx = *pPenToPixel++; |
| 2298 |
x = x0+(yx%MAX_TILESIZE); |
| 2299 |
y = y0+(yx/MAX_TILESIZE); |
| 2300 |
*(x+(UINT16 *)pixmap->line[y]) = PAL_GET(pen); |
| 2301 |
((UINT8 *)transparency_bitmap->line[y])[x] = (pen==transparent_pen)?code_transparent:code_opaque; |
| 2302 |
} |
| 2303 |
pPenData += pitch/2; |
| 2304 |
} |
| 2305 |
} |
| 2306 |
else |
| 2307 |
{ |
| 2308 |
for( ty=tile_height; ty!=0; ty-- ) |
| 2309 |
{ |
| 2310 |
pSource = pPenData; |
| 2311 |
for( tx=tile_width; tx!=0; tx-- ) |
| 2312 |
{ |
| 2313 |
pen = *pSource++; |
| 2314 |
yx = *pPenToPixel++; |
| 2315 |
x = x0+(yx%MAX_TILESIZE); |
| 2316 |
y = y0+(yx/MAX_TILESIZE); |
| 2317 |
*(x+(UINT16 *)pixmap->line[y]) = PAL_GET(pen); |
| 2318 |
if( pen==transparent_pen ) |
| 2319 |
{ |
| 2320 |
((UINT8 *)transparency_bitmap->line[y])[x] = code_transparent; |
| 2321 |
bWhollyOpaque = 0; |
| 2322 |
|
| 2323 |
} |
| 2324 |
else |
| 2325 |
{ |
| 2326 |
((UINT8 *)transparency_bitmap->line[y])[x] = code_opaque; |
| 2327 |
bWhollyTransparent = 0; |
| 2328 |
} |
| 2329 |
} |
| 2330 |
pPenData += pitch; |
| 2331 |
} |
| 2332 |
} |
| 2333 |
|
| 2334 |
return (bWhollyOpaque || bWhollyTransparent)?0:TILE_FLAG_FG_OPAQUE; |
| 2335 |
} |
| 2336 |
|
| 2337 |
static UINT8 TRANSP(HandleTransparencyPenBit)(struct tilemap *tilemap, UINT32 x0, UINT32 y0, UINT32 flags) |
| 2338 |
{ |
| 2339 |
UINT32 tile_width = tilemap->cached_tile_width; |
| 2340 |
UINT32 tile_height = tilemap->cached_tile_height; |
| 2341 |
struct mame_bitmap *pixmap = tilemap->pixmap; |
| 2342 |
struct mame_bitmap *transparency_bitmap = tilemap->transparency_bitmap; |
| 2343 |
int pitch = tile_width + tile_info.skip; |
| 2344 |
PAL_INIT; |
| 2345 |
UINT32 *pPenToPixel = tilemap->pPenToPixel[flags&(TILE_SWAPXY|TILE_FLIPY|TILE_FLIPX)]; |
| 2346 |
const UINT8 *pPenData = tile_info.pen_data; |
| 2347 |
const UINT8 *pSource; |
| 2348 |
UINT32 tx; |
| 2349 |
UINT32 ty; |
| 2350 |
UINT32 data; |
| 2351 |
UINT32 yx; |
| 2352 |
UINT32 x; |
| 2353 |
UINT32 y; |
| 2354 |
UINT32 pen; |
| 2355 |
UINT32 penbit = tilemap->transparent_pen; |
| 2356 |
UINT32 code_front = tile_info.priority | TILE_FLAG_FG_OPAQUE; |
| 2357 |
UINT32 code_back = tile_info.priority | TILE_FLAG_BG_OPAQUE; |
| 2358 |
int code; |
| 2359 |
int and_flags = ~0; |
| 2360 |
int or_flags = 0; |
| 2361 |
|
| 2362 |
if( flags&TILE_4BPP ) |
| 2363 |
{ |
| 2364 |
for( ty=tile_height; ty!=0; ty-- ) |
| 2365 |
{ |
| 2366 |
pSource = pPenData; |
| 2367 |
for( tx=tile_width/2; tx!=0; tx-- ) |
| 2368 |
{ |
| 2369 |
data = *pSource++; |
| 2370 |
|
| 2371 |
pen = data&0xf; |
| 2372 |
yx = *pPenToPixel++; |
| 2373 |
x = x0+(yx%MAX_TILESIZE); |
| 2374 |
y = y0+(yx/MAX_TILESIZE); |
| 2375 |
*(x+(UINT16 *)pixmap->line[y]) = PAL_GET(pen); |
| 2376 |
code = ((pen&penbit)==penbit)?code_front:code_back; |
| 2377 |
and_flags &= code; |
| 2378 |
or_flags |= code; |
| 2379 |
((UINT8 *)transparency_bitmap->line[y])[x] = code; |
| 2380 |
|
| 2381 |
pen = data>>4; |
| 2382 |
yx = *pPenToPixel++; |
| 2383 |
x = x0+(yx%MAX_TILESIZE); |
| 2384 |
y = y0+(yx/MAX_TILESIZE); |
| 2385 |
*(x+(UINT16 *)pixmap->line[y]) = PAL_GET(pen); |
| 2386 |
code = ((pen&penbit)==penbit)?code_front:code_back; |
| 2387 |
and_flags &= code; |
| 2388 |
or_flags |= code; |
| 2389 |
((UINT8 *)transparency_bitmap->line[y])[x] = code; |
| 2390 |
} |
| 2391 |
pPenData += pitch/2; |
| 2392 |
} |
| 2393 |
} |
| 2394 |
else |
| 2395 |
{ |
| 2396 |
for( ty=tile_height; ty!=0; ty-- ) |
| 2397 |
{ |
| 2398 |
pSource = pPenData; |
| 2399 |
for( tx=tile_width; tx!=0; tx-- ) |
| 2400 |
{ |
| 2401 |
pen = *pSource++; |
| 2402 |
yx = *pPenToPixel++; |
| 2403 |
x = x0+(yx%MAX_TILESIZE); |
| 2404 |
y = y0+(yx/MAX_TILESIZE); |
| 2405 |
*(x+(UINT16 *)pixmap->line[y]) = PAL_GET(pen); |
| 2406 |
code = ((pen&penbit)==penbit)?code_front:code_back; |
| 2407 |
and_flags &= code; |
| 2408 |
or_flags |= code; |
| 2409 |
((UINT8 *)transparency_bitmap->line[y])[x] = code; |
| 2410 |
} |
| 2411 |
pPenData += pitch; |
| 2412 |
} |
| 2413 |
} |
| 2414 |
return or_flags ^ and_flags; |
| 2415 |
} |
| 2416 |
|
| 2417 |
static UINT8 TRANSP(HandleTransparencyPens)(struct tilemap *tilemap, UINT32 x0, UINT32 y0, UINT32 flags) |
| 2418 |
{ |
| 2419 |
UINT32 tile_width = tilemap->cached_tile_width; |
| 2420 |
UINT32 tile_height = tilemap->cached_tile_height; |
| 2421 |
struct mame_bitmap *pixmap = tilemap->pixmap; |
| 2422 |
struct mame_bitmap *transparency_bitmap = tilemap->transparency_bitmap; |
| 2423 |
int pitch = tile_width + tile_info.skip; |
| 2424 |
PAL_INIT; |
| 2425 |
UINT32 *pPenToPixel = tilemap->pPenToPixel[flags&(TILE_SWAPXY|TILE_FLIPY|TILE_FLIPX)]; |
| 2426 |
const UINT8 *pPenData = tile_info.pen_data; |
| 2427 |
const UINT8 *pSource; |
| 2428 |
UINT32 code_transparent = tile_info.priority; |
| 2429 |
UINT32 tx; |
| 2430 |
UINT32 ty; |
| 2431 |
UINT32 data; |
| 2432 |
UINT32 yx; |
| 2433 |
UINT32 x; |
| 2434 |
UINT32 y; |
| 2435 |
UINT32 pen; |
| 2436 |
UINT32 fgmask = tilemap->fgmask[(flags>>TILE_SPLIT_OFFSET)&3]; |
| 2437 |
UINT32 bgmask = tilemap->bgmask[(flags>>TILE_SPLIT_OFFSET)&3]; |
| 2438 |
UINT32 code; |
| 2439 |
int and_flags = ~0; |
| 2440 |
int or_flags = 0; |
| 2441 |
|
| 2442 |
if( flags&TILE_4BPP ) |
| 2443 |
{ |
| 2444 |
for( ty=tile_height; ty!=0; ty-- ) |
| 2445 |
{ |
| 2446 |
pSource = pPenData; |
| 2447 |
for( tx=tile_width/2; tx!=0; tx-- ) |
| 2448 |
{ |
| 2449 |
data = *pSource++; |
| 2450 |
|
| 2451 |
pen = data&0xf; |
| 2452 |
yx = *pPenToPixel++; |
| 2453 |
x = x0+(yx%MAX_TILESIZE); |
| 2454 |
y = y0+(yx/MAX_TILESIZE); |
| 2455 |
*(x+(UINT16 *)pixmap->line[y]) = PAL_GET(pen); |
| 2456 |
code = code_transparent; |
| 2457 |
if( !((1<<pen)&fgmask) ) code |= TILE_FLAG_FG_OPAQUE; |
| 2458 |
if( !((1<<pen)&bgmask) ) code |= TILE_FLAG_BG_OPAQUE; |
| 2459 |
and_flags &= code; |
| 2460 |
or_flags |= code; |
| 2461 |
((UINT8 *)transparency_bitmap->line[y])[x] = code; |
| 2462 |
|
| 2463 |
pen = data>>4; |
| 2464 |
yx = *pPenToPixel++; |
| 2465 |
x = x0+(yx%MAX_TILESIZE); |
| 2466 |
y = y0+(yx/MAX_TILESIZE); |
| 2467 |
*(x+(UINT16 *)pixmap->line[y]) = PAL_GET(pen); |
| 2468 |
code = code_transparent; |
| 2469 |
if( !((1<<pen)&fgmask) ) code |= TILE_FLAG_FG_OPAQUE; |
| 2470 |
if( !((1<<pen)&bgmask) ) code |= TILE_FLAG_BG_OPAQUE; |
| 2471 |
and_flags &= code; |
| 2472 |
or_flags |= code; |
| 2473 |
((UINT8 *)transparency_bitmap->line[y])[x] = code; |
| 2474 |
} |
| 2475 |
pPenData += pitch/2; |
| 2476 |
} |
| 2477 |
} |
| 2478 |
else |
| 2479 |
{ |
| 2480 |
for( ty=tile_height; ty!=0; ty-- ) |
| 2481 |
{ |
| 2482 |
pSource = pPenData; |
| 2483 |
for( tx=tile_width; tx!=0; tx-- ) |
| 2484 |
{ |
| 2485 |
pen = *pSource++; |
| 2486 |
yx = *pPenToPixel++; |
| 2487 |
x = x0+(yx%MAX_TILESIZE); |
| 2488 |
y = y0+(yx/MAX_TILESIZE); |
| 2489 |
*(x+(UINT16 *)pixmap->line[y]) = PAL_GET(pen); |
| 2490 |
code = code_transparent; |
| 2491 |
if( !((1<<pen)&fgmask) ) code |= TILE_FLAG_FG_OPAQUE; |
| 2492 |
if( !((1<<pen)&bgmask) ) code |= TILE_FLAG_BG_OPAQUE; |
| 2493 |
and_flags &= code; |
| 2494 |
or_flags |= code; |
| 2495 |
((UINT8 *)transparency_bitmap->line[y])[x] = code; |
| 2496 |
} |
| 2497 |
pPenData += pitch; |
| 2498 |
} |
| 2499 |
} |
| 2500 |
return and_flags ^ or_flags; |
| 2501 |
} |
| 2502 |
|
| 2503 |
static UINT8 TRANSP(HandleTransparencyNone)(struct tilemap *tilemap, UINT32 x0, UINT32 y0, UINT32 flags) |
| 2504 |
{ |
| 2505 |
UINT32 tile_width = tilemap->cached_tile_width; |
| 2506 |
UINT32 tile_height = tilemap->cached_tile_height; |
| 2507 |
struct mame_bitmap *pixmap = tilemap->pixmap; |
| 2508 |
struct mame_bitmap *transparency_bitmap = tilemap->transparency_bitmap; |
| 2509 |
int pitch = tile_width + tile_info.skip; |
| 2510 |
PAL_INIT; |
| 2511 |
UINT32 *pPenToPixel = tilemap->pPenToPixel[flags&(TILE_SWAPXY|TILE_FLIPY|TILE_FLIPX)]; |
| 2512 |
const UINT8 *pPenData = tile_info.pen_data; |
| 2513 |
const UINT8 *pSource; |
| 2514 |
UINT32 code_opaque = tile_info.priority; |
| 2515 |
UINT32 tx; |
| 2516 |
UINT32 ty; |
| 2517 |
UINT32 data; |
| 2518 |
UINT32 yx; |
| 2519 |
UINT32 x; |
| 2520 |
UINT32 y; |
| 2521 |
UINT32 pen; |
| 2522 |
|
| 2523 |
if( flags&TILE_4BPP ) |
| 2524 |
{ |
| 2525 |
for( ty=tile_height; ty!=0; ty-- ) |
| 2526 |
{ |
| 2527 |
pSource = pPenData; |
| 2528 |
for( tx=tile_width/2; tx!=0; tx-- ) |
| 2529 |
{ |
| 2530 |
data = *pSource++; |
| 2531 |
|
| 2532 |
pen = data&0xf; |
| 2533 |
yx = *pPenToPixel++; |
| 2534 |
x = x0+(yx%MAX_TILESIZE); |
| 2535 |
y = y0+(yx/MAX_TILESIZE); |
| 2536 |
*(x+(UINT16 *)pixmap->line[y]) = PAL_GET(pen); |
| 2537 |
((UINT8 *)transparency_bitmap->line[y])[x] = code_opaque; |
| 2538 |
|
| 2539 |
pen = data>>4; |
| 2540 |
yx = *pPenToPixel++; |
| 2541 |
x = x0+(yx%MAX_TILESIZE); |
| 2542 |
y = y0+(yx/MAX_TILESIZE); |
| 2543 |
*(x+(UINT16 *)pixmap->line[y]) = PAL_GET(pen); |
| 2544 |
((UINT8 *)transparency_bitmap->line[y])[x] = code_opaque; |
| 2545 |
} |
| 2546 |
pPenData += pitch/2; |
| 2547 |
} |
| 2548 |
} |
| 2549 |
else |
| 2550 |
{ |
| 2551 |
for( ty=tile_height; ty!=0; ty-- ) |
| 2552 |
{ |
| 2553 |
pSource = pPenData; |
| 2554 |
for( tx=tile_width; tx!=0; tx-- ) |
| 2555 |
{ |
| 2556 |
pen = *pSource++; |
| 2557 |
yx = *pPenToPixel++; |
| 2558 |
x = x0+(yx%MAX_TILESIZE); |
| 2559 |
y = y0+(yx/MAX_TILESIZE); |
| 2560 |
*(x+(UINT16 *)pixmap->line[y]) = PAL_GET(pen); |
| 2561 |
((UINT8 *)transparency_bitmap->line[y])[x] = code_opaque; |
| 2562 |
} |
| 2563 |
pPenData += pitch; |
| 2564 |
} |
| 2565 |
} |
| 2566 |
return 0; |
| 2567 |
} |
| 2568 |
|
| 2569 |
#undef TRANSP |
| 2570 |
#undef PAL_INIT |
| 2571 |
#undef PAL_GET |
| 2572 |
#endif // TRANSP |
| 2573 |
|