Develop and Download Open Source Software

Browse CVS Repository

Contents of /mame32jp/mame32jp/src/artwork.c

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


Revision 1.5 - (show annotations) (download) (as text)
Wed Apr 24 03:53:20 2002 UTC (21 years, 11 months ago) by zero
Branch: MAIN
CVS Tags: ver_0_60_1, ver0_59_13, ver0_59_14, ver0_60_2, ver0_60_3, ver0_60_4, ver0_60_5, HEAD
Changes since 1.4: +0 -0 lines
File MIME type: text/x-csrc
*** empty log message ***

1 /*********************************************************************
2
3 artwork.c
4
5 Generic backdrop/overlay functions.
6
7 Created by Mike Balfour - 10/01/1998
8
9 Added some overlay and backdrop functions
10 for vector games. Mathis Rosenhauer - 10/09/1998
11
12 MAB - 09 MAR 1999 - made some changes to artwork_create
13 MLR - 29 MAR 1999 - added disks to artwork_create
14 MLR - 24 MAR 2000 - support for true color artwork
15 MLR - 17 JUL 2001 - removed 8bpp code
16
17 *********************************************************************/
18
19 #include "driver.h"
20 #include "png.h"
21 #include "artwork.h"
22 #include <ctype.h>
23
24 #define LIMIT5(x) ((x < 0x1f)? x : 0x1f)
25 #define LIMIT8(x) ((x < 0xff)? x : 0xff)
26
27 /* the backdrop instance */
28 struct artwork_info *artwork_backdrop = NULL;
29
30 /* the overlay instance */
31 struct artwork_info *artwork_overlay = NULL;
32
33 struct mame_bitmap *artwork_real_scrbitmap;
34
35 static int my_stricmp( const char *dst, const char *src)
36 {
37 while (*src && *dst)
38 {
39 if( tolower(*src) != tolower(*dst) ) return *dst - *src;
40 src++;
41 dst++;
42 }
43 return *dst - *src;
44 }
45
46 static void RGBtoHSV( float r, float g, float b, float *h, float *s, float *v )
47 {
48 float min, max, delta;
49
50 min = MIN( r, MIN( g, b ));
51 max = MAX( r, MAX( g, b ));
52 *v = max;
53
54 delta = max - min;
55
56 if( delta > 0 )
57 *s = delta / max;
58 else {
59 *s = 0;
60 *h = 0;
61 return;
62 }
63
64 if( r == max )
65 *h = ( g - b ) / delta;
66 else if( g == max )
67 *h = 2 + ( b - r ) / delta;
68 else
69 *h = 4 + ( r - g ) / delta;
70
71 *h *= 60;
72 if( *h < 0 )
73 *h += 360;
74 }
75
76 static void HSVtoRGB( float *r, float *g, float *b, float h, float s, float v )
77 {
78 int i;
79 float f, p, q, t;
80
81 if( s == 0 ) {
82 *r = *g = *b = v;
83 return;
84 }
85
86 h /= 60;
87 i = h;
88 f = h - i;
89 p = v * ( 1 - s );
90 q = v * ( 1 - s * f );
91 t = v * ( 1 - s * ( 1 - f ) );
92
93 switch( i ) {
94 case 0: *r = v; *g = t; *b = p; break;
95 case 1: *r = q; *g = v; *b = p; break;
96 case 2: *r = p; *g = v; *b = t; break;
97 case 3: *r = p; *g = q; *b = v; break;
98 case 4: *r = t; *g = p; *b = v; break;
99 default: *r = v; *g = p; *b = q; break;
100 }
101
102 }
103
104 static void merge_cmy(struct artwork_info *a, struct mame_bitmap *source, struct mame_bitmap *source_alpha,int sx, int sy)
105 {
106 int c1, c2, m1, m2, y1, y2, pen1, pen2, max, alpha;
107 int x, y, w, h;
108 struct mame_bitmap *dest, *dest_alpha;
109
110 dest = a->orig_artwork;
111 dest_alpha = a->alpha;
112
113 if (Machine->orientation & ORIENTATION_SWAP_XY)
114 {
115 w = source->height;
116 h = source->width;
117 }
118 else
119 {
120 h = source->height;
121 w = source->width;
122 }
123
124 for (y = 0; y < h; y++)
125 for (x = 0; x < w; x++)
126 {
127 pen1 = read_pixel(dest, sx + x, sy + y);
128
129 c1 = 0x1f - (pen1 >> 10);
130 m1 = 0x1f - ((pen1 >> 5) & 0x1f);
131 y1 = 0x1f - (pen1 & 0x1f);
132
133 pen2 = read_pixel(source, x, y);
134 c2 = 0x1f - (pen2 >> 10) + c1;
135 m2 = 0x1f - ((pen2 >> 5) & 0x1f) + m1;
136 y2 = 0x1f - (pen2 & 0x1f) + y1;
137
138 max = MAX(c2, MAX(m2, y2));
139 if (max > 0x1f)
140 {
141 c2 = (c2 * 0x1f) / max;
142 m2 = (m2 * 0x1f) / max;
143 y2 = (y2 * 0x1f) / max;
144 }
145
146 alpha = MIN (0xff, read_pixel(source_alpha, x, y)
147 + read_pixel(dest_alpha, sx + x, sy + y));
148 plot_pixel(dest, sx + x, sy + y,
149 ((0x1f - c2) << 10)
150 | ((0x1f - m2) << 5)
151 | (0x1f - y2));
152
153 plot_pixel(dest_alpha, sx + x, sy + y, alpha);
154 }
155 }
156
157 /*********************************************************************
158 allocate_artwork_mem
159
160 Allocates memory for all the bitmaps.
161 *********************************************************************/
162 static void allocate_artwork_mem (int width, int height, struct artwork_info **a)
163 {
164 if (Machine->orientation & ORIENTATION_SWAP_XY)
165 {
166 int temp;
167
168 temp = height;
169 height = width;
170 width = temp;
171 }
172
173 *a = (struct artwork_info *)auto_malloc(sizeof(struct artwork_info));
174 if (*a == 0)
175 {
176 logerror("Not enough memory for artwork!\n");
177 return;
178 }
179
180 if (((*a)->orig_artwork = auto_bitmap_alloc(width, height)) == 0)
181 {
182 logerror("Not enough memory for artwork!\n");
183 return;
184 }
185 fillbitmap((*a)->orig_artwork,0,0);
186
187 if (((*a)->alpha = auto_bitmap_alloc(width, height)) == 0)
188 {
189 logerror("Not enough memory for artwork!\n");
190 return;
191 }
192 fillbitmap((*a)->alpha,0,0);
193
194 if (((*a)->artwork = auto_bitmap_alloc(width,height)) == 0)
195 {
196 logerror("Not enough memory for artwork!\n");
197 return;
198 }
199
200 if (((*a)->artwork1 = auto_bitmap_alloc(width,height)) == 0)
201 {
202 logerror("Not enough memory for artwork!\n");
203 return;
204 }
205
206 if (((*a)->rgb = (UINT32*)auto_malloc(width*height*sizeof(UINT32)))==0)
207 {
208 logerror("Not enough memory.\n");
209 return;
210 }
211 }
212
213 /*********************************************************************
214 create_disk
215
216 Creates a disk with radius r in the color of pen. A new bitmap
217 is allocated for the disk.
218
219 *********************************************************************/
220 static struct mame_bitmap *create_disk (int r, int fg, int bg)
221 {
222 struct mame_bitmap *disk;
223
224 int x = 0, twox = 0;
225 int y = r;
226 int twoy = r+r;
227 int p = 1 - r;
228 int i;
229
230 if ((disk = bitmap_alloc(twoy, twoy)) == 0)
231 {
232 logerror("Not enough memory for artwork!\n");
233 return NULL;
234 }
235
236 /* background */
237 fillbitmap (disk, bg, 0);
238
239 while (x < y)
240 {
241 x++;
242 twox +=2;
243 if (p < 0)
244 p += twox + 1;
245 else
246 {
247 y--;
248 twoy -= 2;
249 p += twox - twoy + 1;
250 }
251
252 for (i = 0; i < twox; i++)
253 {
254 plot_pixel(disk, r-x+i, r-y , fg);
255 plot_pixel(disk, r-x+i, r+y-1, fg);
256 }
257
258 for (i = 0; i < twoy; i++)
259 {
260 plot_pixel(disk, r-y+i, r-x , fg);
261 plot_pixel(disk, r-y+i, r+x-1, fg);
262 }
263 }
264 return disk;
265 }
266
267 /*********************************************************************
268 artwork_remap
269
270 Creates the final artwork by adding the start_pen to the
271 original artwork.
272 *********************************************************************/
273 static void artwork_remap(struct artwork_info *a)
274 {
275 int x, y;
276 if (Machine->color_depth == 16)
277 {
278 for ( y = 0; y < a->orig_artwork->height; y++)
279 for (x = 0; x < a->orig_artwork->width; x++)
280 ((UINT16 *)a->artwork->line[y])[x] = ((UINT16 *)a->orig_artwork->line[y])[x]+a->start_pen;
281 }
282 else
283 copybitmap(a->artwork, a->orig_artwork ,0,0,0,0,NULL,TRANSPARENCY_NONE,0);
284 }
285
286 /*********************************************************************
287 init_palette
288
289 This sets the palette colors used by the backdrop. It is a simple
290 rgb555 palette of 32768 entries.
291 *********************************************************************/
292 static void init_palette(int start_pen)
293 {
294 int r, g, b;
295
296 for (r = 0; r < 32; r++)
297 for (g = 0; g < 32; g++)
298 for (b = 0; b < 32; b++)
299 palette_set_color(start_pen++, (r << 3) | (r >> 2), (g << 3) | (g >> 2), (b << 3) | (b >> 2));
300 }
301
302 /*********************************************************************
303
304 Reads a PNG for a artwork struct and converts it into a format
305 usable for mame.
306 *********************************************************************/
307 static int decode_png(const char *file_name, struct mame_bitmap **bitmap, struct mame_bitmap **alpha, struct png_info *p)
308 {
309 UINT8 *tmp;
310 UINT32 x, y, pen;
311 void *fp;
312 int file_name_len, depth;
313 char file_name2[256];
314
315 depth = Machine->color_depth;
316
317 /* check for .png */
318 strcpy(file_name2, file_name);
319 file_name_len = strlen(file_name2);
320 if ((file_name_len < 4) || my_stricmp(&file_name2[file_name_len - 4], ".png"))
321 {
322 strcat(file_name2, ".png");
323 }
324
325 if (!(fp = osd_fopen(Machine->gamedrv->name, file_name2, OSD_FILETYPE_ARTWORK, 0)))
326 {
327 logerror("Unable to open PNG %s\n", file_name);
328 return 0;
329 }
330
331 if (!png_read_file(fp, p))
332 {
333 osd_fclose (fp);
334 return 0;
335 }
336 osd_fclose (fp);
337
338 if (p->bit_depth > 8)
339 {
340 logerror("Unsupported bit depth %i (8 bit max.)\n", p->bit_depth);
341 return 0;
342 }
343
344 if (p->interlace_method != 0)
345 {
346 logerror("Interlace unsupported\n");
347 return 0;
348 }
349
350 switch (p->color_type)
351 {
352 case 3:
353 /* Convert to 8 bit */
354 png_expand_buffer_8bit (p);
355
356 png_delete_unused_colors (p);
357
358 if ((*bitmap = bitmap_alloc(p->width,p->height)) == 0)
359 {
360 logerror("Unable to allocate memory for artwork\n");
361 return 0;
362 }
363
364 tmp = p->image;
365 /* convert to 15/32 bit */
366 if (p->num_trans > 0)
367 if ((*alpha = bitmap_alloc(p->width,p->height)) == 0)
368 {
369 logerror("Unable to allocate memory for artwork\n");
370 return 0;
371 }
372
373 for (y=0; y<p->height; y++)
374 for (x=0; x<p->width; x++)
375 {
376 if (depth == 32)
377 pen = (p->palette[*tmp * 3] << 16) | (p->palette[*tmp * 3 + 1] << 8) | p->palette[*tmp * 3 + 2];
378 else
379 pen = ((p->palette[*tmp * 3] & 0xf8) << 7) | ((p->palette[*tmp * 3 + 1] & 0xf8) << 2) | (p->palette[*tmp * 3 + 2] >> 3);
380 plot_pixel(*bitmap, x, y, pen);
381
382 if (p->num_trans > 0)
383 {
384 if (*tmp < p->num_trans)
385 plot_pixel(*alpha, x, y, p->trans[*tmp]);
386 else
387 plot_pixel(*alpha, x, y, 255);
388 }
389 tmp++;
390 }
391
392 free (p->palette);
393 break;
394
395 case 6:
396 if ((*alpha = bitmap_alloc(p->width,p->height)) == 0)
397 {
398 logerror("Unable to allocate memory for artwork\n");
399 return 0;
400 }
401
402 case 2:
403 if ((*bitmap = bitmap_alloc(p->width,p->height)) == 0)
404 {
405 logerror("Unable to allocate memory for artwork\n");
406 return 0;
407 }
408
409 tmp = p->image;
410 for (y=0; y<p->height; y++)
411 for (x=0; x<p->width; x++)
412 {
413 if (depth == 32)
414 pen = (tmp[0] << 16) | (tmp[1] << 8) | tmp[2];
415 else
416 pen = ((tmp[0] & 0xf8) << 7) | ((tmp[1] & 0xf8) << 2) | (tmp[2] >> 3);
417 plot_pixel(*bitmap, x, y, pen);
418
419 if (p->color_type == 6)
420 {
421 plot_pixel(*alpha, x, y, tmp[3]);
422 tmp += 4;
423 }
424 else
425 tmp += 3;
426 }
427
428 break;
429
430 default:
431 logerror("Unsupported color type %i \n", p->color_type);
432 return 0;
433 break;
434 }
435 free (p->image);
436 return 1;
437 }
438
439 /*********************************************************************
440 load_png
441
442 This is what loads your backdrop in from disk.
443 start_pen = the first pen available for the backdrop to use
444 *********************************************************************/
445
446 static void load_png(const char *filename, unsigned int start_pen,
447 int width, int height, struct artwork_info **a)
448 {
449 struct mame_bitmap *picture = 0, *alpha = 0;
450 struct png_info p;
451 int scalex, scaley;
452
453 /* If the user turned artwork off, bail */
454 if (!options.use_artwork) return;
455
456 if (!decode_png(filename, &picture, &alpha, &p))
457 return;
458
459 allocate_artwork_mem(width, height, a);
460
461
462 if (*a==NULL)
463 return;
464
465 /* Scale the original picture to be the same size as the visible area */
466 scalex = 0x10000 * picture->width / (*a)->artwork->width;
467 scaley = 0x10000 * picture->height / (*a)->artwork->height;
468
469 if (Machine->orientation & ORIENTATION_SWAP_XY)
470 {
471 int tmp;
472 tmp = scalex;
473 scalex = scaley;
474 scaley = tmp;
475 }
476
477 copyrozbitmap((*a)->orig_artwork, picture, 0, 0, scalex, 0, 0, scaley, 0, 0, TRANSPARENCY_NONE, 0, 0);
478 /* We don't need the original any more */
479 bitmap_free(picture);
480
481 if (alpha)
482 {
483 copyrozbitmap((*a)->alpha, alpha, 0, 0, scalex, 0, 0, scaley, 0, 0, TRANSPARENCY_NONE, 0, 0);
484 bitmap_free(alpha);
485 }
486
487 if (Machine->color_depth == 16)
488 {
489 (*a)->start_pen = start_pen;
490 init_palette(start_pen);
491 }
492 else
493 (*a)->start_pen = 0;
494
495 artwork_remap(*a);
496 logerror("Png Loaded %d %d\n", width, height);
497 }
498
499 static void load_png_fit(const char *filename, unsigned int start_pen, struct artwork_info **a)
500 {
501 load_png(filename, start_pen, Machine->scrbitmap->width, Machine->scrbitmap->height, a);
502 }
503
504
505 /*********************************************************************
506 overlay_init
507
508
509 *********************************************************************/
510 static void overlay_init(struct artwork_info *a)
511 {
512 int i,j, rgb555;
513 UINT8 r,g,b;
514 float h, s, v, rf, gf, bf;
515 int offset, height, width;
516 struct mame_bitmap *overlay, *overlay1, *orig;
517
518 offset = a->start_pen;
519 height = a->artwork->height;
520 width = a->artwork->width;
521 overlay = a->artwork;
522 overlay1 = a->artwork1;
523 orig = a->orig_artwork;
524
525 if (a->alpha)
526 {
527 for ( j=0; j<height; j++)
528 for (i=0; i<width; i++)
529 {
530 UINT32 v1,v2;
531 UINT16 alpha = ((UINT16 *)a->alpha->line[j])[i];
532
533 rgb555 = ((UINT16 *)orig->line[j])[i];
534 r = rgb555 >> 10;
535 g = (rgb555 >> 5) & 0x1f;
536 b = rgb555 &0x1f;
537 v1 = (MAX(r, MAX(g, b)));
538 v2 = (v1 * (alpha >> 3)) / 0x1f;
539 a->rgb[j*width+i] = (v1 << 24) | (v2 << 16) | rgb555;
540
541 RGBtoHSV( r/31.0, g/31.0, b/31.0, &h, &s, &v );
542
543 HSVtoRGB( &rf, &gf, &bf, h, s, v * alpha/255.0);
544 r = rf*31; g = gf*31; b = bf*31;
545 ((UINT16 *)overlay->line[j])[i] = ((r << 10) | (g << 5) | b) + offset;
546
547 HSVtoRGB( &rf, &gf, &bf, h, s, 1);
548 r = rf*31; g = gf*31; b = bf*31;
549 ((UINT16 *)overlay1->line[j])[i] = ((r << 10) | (g << 5) | b) + offset;
550 }
551 }
552 }
553
554 /*********************************************************************
555 overlay_draw
556
557 Supports different levels of intensity on the screen and different
558 levels of transparancy of the overlay.
559 *********************************************************************/
560
561 static void overlay_draw(struct mame_bitmap *dest, struct mame_bitmap *source)
562 {
563 int i, j;
564 int height, width;
565 int r, g, b, bp, v, vn, black, start_pen;
566 UINT8 r8, g8, b8;
567 UINT16 *src, *dst, *bg, *fg;
568 UINT32 bright[65536];
569 UINT32 *rgb;
570
571 memset (bright, 0xff, sizeof(int)*65536);
572 height = source->height;
573 width = source->width;
574
575 switch (Machine->color_depth)
576 {
577 case 16:
578 if (artwork_overlay->start_pen == 2)
579 {
580 /* fast version */
581 height = artwork_overlay->artwork->height;
582 width = artwork_overlay->artwork->width;
583
584 for ( j = 0; j < height; j++)
585 {
586 dst = (UINT16 *)dest->line[j];
587 src = (UINT16 *)source->line[j];
588 bg = (UINT16 *)artwork_overlay->artwork->line[j];
589 fg = (UINT16 *)artwork_overlay->artwork1->line[j];
590 for (i = width; i > 0; i--)
591 {
592 if (*src!=0)
593 *dst = *fg;
594 else
595 *dst = *bg;
596 dst++;
597 src++;
598 fg++;
599 bg++;
600 }
601 }
602 }
603 else /* slow version */
604 {
605 rgb = artwork_overlay->rgb;
606 start_pen = artwork_overlay->start_pen;
607 copybitmap(dest, artwork_overlay->artwork ,0,0,0,0,NULL,TRANSPARENCY_NONE,0);
608 black = -1;
609 for ( j = 0; j < height; j++)
610 {
611 dst = (UINT16 *)dest->line[j];
612 src = (UINT16 *)source->line[j];
613
614 for (i = width; i > 0; i--)
615 {
616 if (*src != black)
617 {
618 bp = bright[*src];
619 if (bp)
620 {
621 if (bp == 0xffffffff)
622 {
623 palette_get_color(*src, &r8, &g8, &b8);
624 bright[*src]=bp=(222*r8+707*g8+71*b8)/1000;
625 }
626
627 v = *rgb >> 24;
628 vn =(*rgb >> 16) & 0x1f;
629 vn += ((0x1f - vn) * (bp >> 3)) / 0x1f;
630 if (v > 0)
631 {
632 r = (((*rgb >> 10) & 0x1f) * vn) / v;
633 g = (((*rgb >> 5) & 0x1f) * vn) / v;
634 b = ((*rgb & 0x1f) * vn) / v;
635 *dst = ((r << 10) | (g << 5) | b) + start_pen;
636 }
637 else
638 *dst = ((vn << 10) | (vn << 5) | vn) + start_pen;
639 }
640 else
641 black = *src;
642 }
643 src++;
644 dst++;
645 rgb++;
646 }
647 }
648
649 }
650 break;
651 case 15:
652 rgb = artwork_overlay->rgb;
653 start_pen = artwork_overlay->start_pen;
654 copybitmap(dest, artwork_overlay->artwork ,0,0,0,0,NULL,TRANSPARENCY_NONE,0);
655 black = -1;
656 for ( j = 0; j < height; j++)
657 {
658 dst = (UINT16 *)dest->line[j];
659 src = (UINT16 *)source->line[j];
660
661 for (i = width; i > 0; i--)
662 {
663 if (*src != black)
664 {
665 bp = bright[*src];
666 if (bp)
667 {
668 if (bp == 0xffffffff)
669 bright[*src]=bp=(222*(*src >> 10)
670 +707*((*src >> 5) & 0x1f)
671 +71*(*src & 0x1f))/1000;
672
673 v = *rgb >> 24;
674 vn =(*rgb >> 16) & 0x1f;
675 vn += ((0x1f - vn) * bp) / 0x1f;
676 if (v > 0)
677 {
678 r = (((*rgb >> 10) & 0x1f) * vn) / v;
679 g = (((*rgb >> 5) & 0x1f) * vn) / v;
680 b = ((*rgb & 0x1f) * vn) / v;
681 *dst = ((r << 10) | (g << 5) | b);
682 }
683 else
684 *dst = ((vn << 10) | (vn << 5) | vn);
685 }
686 else
687 black = *src;
688 }
689 src++;
690 dst++;
691 rgb++;
692 }
693 }
694 break;
695 default:
696 logerror ("Color depth of %d not supported with overlays\n", Machine->color_depth);
697 break;
698 }
699 }
700
701 /*********************************************************************
702 backdrop_draw
703
704 *********************************************************************/
705
706 static void backdrop_draw(struct mame_bitmap *dest, struct mame_bitmap *source)
707 {
708 int i, j;
709
710 copybitmap(dest, artwork_backdrop->artwork ,0,0,0,0,NULL,TRANSPARENCY_NONE,0);
711
712 switch (Machine->color_depth)
713 {
714 case 16:
715 {
716 int brgb, black = -1;
717 UINT8 r, g, b;
718 UINT16 *dst, *bdr, *src;
719
720 for ( j = 0; j < source->height; j++)
721 {
722 dst = (UINT16 *)dest->line[j];
723 src = (UINT16 *)source->line[j];
724 bdr = (UINT16 *)artwork_backdrop->artwork->line[j];
725 for (i = 0; i < source->width; i++)
726 {
727 if (*src != black)
728 {
729 palette_get_color(*src, &r, &g, &b);
730
731 if ((r == 0) && (g == 0) && (b == 0))
732 {
733 black = *src;
734 }
735
736 r >>= 3;
737 g >>= 3;
738 b >>= 3;
739 brgb = *bdr - artwork_backdrop->start_pen;
740 r += brgb >> 10;
741 if (r > 0x1f) r = 0x1f;
742 g += (brgb >> 5) & 0x1f;
743 if (g > 0x1f) g = 0x1f;
744 b += brgb & 0x1f;
745 if (b > 0x1f) b = 0x1f;
746 *dst = ((r << 10) | (g << 5) | b) + artwork_backdrop->start_pen;
747 }
748 dst++;
749 src++;
750 bdr++;
751 }
752 }
753 break;
754 }
755
756 case 15:
757 {
758 UINT16 *dst, *src, *bdr;
759
760 for ( j = 0; j < source->height; j++)
761 {
762 dst = (UINT16 *)dest->line[j];
763 src = (UINT16 *)source->line[j];
764 bdr = (UINT16 *)artwork_backdrop->artwork->line[j];
765 for (i = 0; i < source->width; i++)
766 {
767 if (*src)
768 {
769 *dst = LIMIT5((*src & 0x1f) + (*bdr & 0x1f))
770 | (LIMIT5(((*src >> 5) & 0x1f) + ((*bdr >> 5) & 0x1f)) << 5)
771 | (LIMIT5((*src >> 10) + (*bdr >> 10)) << 10);
772 }
773 dst++;
774 src++;
775 bdr++;
776 }
777 }
778 break;
779 }
780
781 case 32:
782 {
783 UINT32 *dst, *src, *bdr;
784
785 for ( j = 0; j < source->height; j++)
786 {
787 dst = (UINT32 *)dest->line[j];
788 src = (UINT32 *)source->line[j];
789 bdr = (UINT32 *)artwork_backdrop->artwork->line[j];
790 for (i = 0; i < source->width; i++)
791 {
792 if (*src)
793 {
794 *dst = LIMIT8((*src & 0xff) + (*bdr & 0xff))
795 | (LIMIT8(((*src >> 8) & 0xff) + ((*bdr >> 8) & 0xff)) << 8)
796 | (LIMIT8((*src >> 16) + (*bdr >> 16)) << 16);
797 }
798 dst++;
799 src++;
800 bdr++;
801 }
802 }
803 break;
804 }
805 }
806 }
807
808 void artwork_draw(struct mame_bitmap *dest, struct mame_bitmap *source, int full_refresh)
809 {
810 if (artwork_backdrop) backdrop_draw(dest, source);
811 if (artwork_overlay) overlay_draw(dest, source);
812 }
813
814 /*********************************************************************
815 artwork_free
816
817 Don't forget to clean up when you're done with the backdrop!!!
818 *********************************************************************/
819
820 void artwork_free(struct artwork_info **a)
821 {
822 if (*a)
823 {
824 if ((*a)->artwork)
825 bitmap_free((*a)->artwork);
826 if ((*a)->artwork1)
827 bitmap_free((*a)->artwork1);
828 if ((*a)->alpha)
829 bitmap_free((*a)->alpha);
830 if ((*a)->orig_artwork)
831 bitmap_free((*a)->orig_artwork);
832 if ((*a)->rgb)
833 free ((*a)->rgb);
834 free(*a);
835
836 *a = NULL;
837 }
838 }
839
840 void artwork_kill (void)
841 {
842 }
843
844 void overlay_load(const char *filename, unsigned int start_pen)
845 {
846 int width, height;
847
848 /* replace the real display with a fake one, this way drivers can access Machine->scrbitmap
849 the same way as before */
850
851 width = Machine->scrbitmap->width;
852 height = Machine->scrbitmap->height;
853
854 if (Machine->orientation & ORIENTATION_SWAP_XY)
855 {
856 int temp;
857
858 temp = height;
859 height = width;
860 width = temp;
861 }
862
863 load_png_fit(filename, start_pen, &artwork_overlay);
864
865 if (artwork_overlay)
866 {
867 if ((artwork_real_scrbitmap = auto_bitmap_alloc(width, height)) == 0)
868 {
869 artwork_kill();
870 logerror("Not enough memory for artwork!\n");
871 return;
872 }
873 overlay_init(artwork_overlay);
874 }
875 }
876
877 void backdrop_load(const char *filename, unsigned int start_pen)
878 {
879 int width, height;
880
881 /* replace the real display with a fake one, this way drivers can access Machine->scrbitmap
882 the same way as before */
883
884 load_png_fit(filename, start_pen, &artwork_backdrop);
885
886 if (artwork_backdrop)
887 {
888 width = artwork_backdrop->artwork->width;
889 height = artwork_backdrop->artwork->height;
890
891 if (Machine->orientation & ORIENTATION_SWAP_XY)
892 {
893 int temp;
894
895 temp = height;
896 height = width;
897 width = temp;
898 }
899
900 if ((artwork_real_scrbitmap = auto_bitmap_alloc(width, height)) == 0)
901 {
902 artwork_kill();
903 logerror("Not enough memory for artwork!\n");
904 return;
905 }
906 }
907 }
908
909 void artwork_load(struct artwork_info **a, const char *filename, unsigned int start_pen)
910 {
911 load_png_fit(filename, start_pen, a);
912 }
913
914 void artwork_load_size(struct artwork_info **a, const char *filename, unsigned int start_pen,
915 int width, int height)
916 {
917 load_png(filename, start_pen, width, height, a);
918 }
919
920 /*********************************************************************
921 artwork_elements scale
922
923 scales an array of artwork elements to width and height. The first
924 element (which has to be a box) is used as reference. This is useful
925 for atwork with disks.
926
927 *********************************************************************/
928
929 void artwork_elements_scale(struct artwork_element *ae, int width, int height)
930 {
931 int scale_w, scale_h;
932
933 if (Machine->orientation & ORIENTATION_SWAP_XY)
934 {
935 scale_w = (height << 16)/(ae->box.max_x + 1);
936 scale_h = (width << 16)/(ae->box.max_y + 1);
937 }
938 else
939 {
940 scale_w = (width << 16)/(ae->box.max_x + 1);
941 scale_h = (height << 16)/(ae->box.max_y + 1);
942 }
943 while (ae->box.min_x >= 0)
944 {
945 ae->box.min_x = (ae->box.min_x * scale_w) >> 16;
946 ae->box.max_x = (ae->box.max_x * scale_w) >> 16;
947 ae->box.min_y = (ae->box.min_y * scale_h) >> 16;
948 if (ae->box.max_y >= 0)
949 ae->box.max_y = (ae->box.max_y * scale_h) >> 16;
950 ae++;
951 }
952 }
953
954 /*********************************************************************
955 overlay_create
956
957 This works similar to artwork_load but generates artwork from
958 an array of artwork_element. This is useful for very simple artwork
959 like the overlay in the Space invaders series of games. The overlay
960 is defined to be the same size as the screen.
961 The end of the array is marked by an entry with negative coordinates.
962 Boxes and disks are supported. Disks are marked max_y == -1,
963 min_x == x coord. of center, min_y == y coord. of center, max_x == radius.
964 If there are transparent and opaque overlay elements, the opaque ones
965 have to be at the end of the list to stay compatible with the PNG
966 artwork.
967 *********************************************************************/
968 void overlay_create(const struct artwork_element *ae, unsigned int start_pen)
969 {
970 struct mame_bitmap *disk, *disk_alpha, *box, *box_alpha;
971 int pen, transparent_pen = -1, disk_type, white_pen;
972 int width, height;
973
974 allocate_artwork_mem(Machine->scrbitmap->width, Machine->scrbitmap->height, &artwork_overlay);
975
976 if (artwork_overlay==NULL)
977 return;
978
979 /* replace the real display with a fake one, this way drivers can access Machine->scrbitmap
980 the same way as before */
981
982 width = Machine->scrbitmap->width;
983 height = Machine->scrbitmap->height;
984
985 if (Machine->orientation & ORIENTATION_SWAP_XY)
986 {
987 int temp;
988
989 temp = height;
990 height = width;
991 width = temp;
992 }
993
994 if ((artwork_real_scrbitmap = auto_bitmap_alloc(width, height)) == 0)
995 {
996 artwork_kill();
997 logerror("Not enough memory for artwork!\n");
998 return;
999 }
1000
1001 transparent_pen = 0xffff;
1002 white_pen = 0x7fff;
1003 fillbitmap (artwork_overlay->orig_artwork, white_pen, 0);
1004 fillbitmap (artwork_overlay->alpha, 0, 0);
1005
1006 while (ae->box.min_x >= 0)
1007 {
1008 int alpha = ae->alpha;
1009
1010 if (alpha == OVERLAY_DEFAULT_OPACITY)
1011 {
1012 alpha = 0x18;
1013 }
1014
1015 pen = ((ae->red & 0xf8) << 7) | ((ae->green & 0xf8) << 2) | (ae->blue >> 3);
1016 if (ae->box.max_y < 0) /* disk */
1017 {
1018 int r = ae->box.max_x;
1019 disk_type = ae->box.max_y;
1020
1021 switch (disk_type)
1022 {
1023 case -1: /* disk overlay */
1024 if ((disk = create_disk (r, pen, white_pen)) == NULL)
1025 {
1026 artwork_kill();
1027 return;
1028 }
1029 if ((disk_alpha = create_disk (r, alpha, 0)) == NULL)
1030 {
1031 artwork_kill();
1032 return;
1033 }
1034 merge_cmy (artwork_overlay, disk, disk_alpha, ae->box.min_x - r, ae->box.min_y - r);
1035 bitmap_free(disk_alpha);
1036 bitmap_free(disk);
1037 break;
1038
1039 case -2: /* punched disk */
1040 if ((disk = create_disk (r, pen, transparent_pen)) == NULL)
1041 {
1042 artwork_kill();
1043 return;
1044 }
1045 copybitmap(artwork_overlay->orig_artwork,disk,0, 0,
1046 ae->box.min_x - r,
1047 ae->box.min_y - r,
1048 0,TRANSPARENCY_PEN, transparent_pen);
1049 /* alpha */
1050 if ((disk_alpha = create_disk (r, alpha, transparent_pen)) == NULL)
1051 {
1052 artwork_kill();
1053 return;
1054 }
1055 copybitmap(artwork_overlay->alpha,disk_alpha,0, 0,
1056 ae->box.min_x - r,
1057 ae->box.min_y - r,
1058 0,TRANSPARENCY_PEN, transparent_pen);
1059 bitmap_free(disk_alpha);
1060 bitmap_free(disk);
1061 break;
1062
1063 }
1064 }
1065 else
1066 {
1067 if ((box = bitmap_alloc(ae->box.max_x - ae->box.min_x + 1,
1068 ae->box.max_y - ae->box.min_y + 1)) == 0)
1069 {
1070 logerror("Not enough memory for artwork!\n");
1071 artwork_kill();
1072 return;
1073 }
1074 if ((box_alpha = bitmap_alloc(ae->box.max_x - ae->box.min_x + 1,
1075 ae->box.max_y - ae->box.min_y + 1)) == 0)
1076 {
1077 logerror("Not enough memory for artwork!\n");
1078 artwork_kill();
1079 return;
1080 }
1081 fillbitmap (box, pen, 0);
1082 fillbitmap (box_alpha, alpha, 0);
1083 merge_cmy (artwork_overlay, box, box_alpha, ae->box.min_x, ae->box.min_y);
1084 bitmap_free(box);
1085 bitmap_free(box_alpha);
1086 }
1087 ae++;
1088 }
1089
1090 if (Machine->color_depth == 16)
1091 {
1092 artwork_overlay->start_pen = start_pen;
1093 init_palette(start_pen);
1094 }
1095 else
1096 artwork_overlay->start_pen = 0;
1097
1098 artwork_remap(artwork_overlay);
1099 overlay_init(artwork_overlay);
1100 }
1101
1102 int artwork_get_size_info(const char *file_name, struct artwork_size_info *a)
1103 {
1104 void *fp;
1105 struct png_info p;
1106 int file_name_len;
1107 char file_name2[256];
1108
1109 /* If the user turned artwork off, bail */
1110 if (!options.use_artwork) return 0;
1111
1112 /* check for .png */
1113 strcpy(file_name2, file_name);
1114 file_name_len = strlen(file_name2);
1115 if ((file_name_len < 4) || my_stricmp(&file_name2[file_name_len - 4], ".png"))
1116 {
1117 strcat(file_name2, ".png");
1118 }
1119
1120 if (!(fp = osd_fopen(Machine->gamedrv->name, file_name2, OSD_FILETYPE_ARTWORK, 0)))
1121 {
1122 logerror("Unable to open PNG %s\n", file_name);
1123 return 0;
1124 }
1125
1126 if (!png_read_info(fp, &p))
1127 {
1128 osd_fclose (fp);
1129 return 0;
1130 }
1131 osd_fclose (fp);
1132
1133 a->width = p.width;
1134 a->height = p.height;
1135 a->screen = p.screen;
1136
1137 return 1;
1138 }
1139

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