Develop and Download Open Source Software

Browse CVS Repository

Contents of /mame32jp/mame32jp/src/tilemap.c

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.6 - (show annotations) (download) (as text)
Tue May 7 00:17:30 2002 UTC (21 years, 11 months ago) by zero
Branch: MAIN
CVS Tags: ver_0_60_1, ver0_60_2, ver0_60_3, ver0_60_4, ver0_60_5, HEAD
Changes since 1.5: +33 -35 lines
File MIME type: text/x-csrc
*** empty log message ***

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

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26