1 /*********************************************************************
2
3 common.c
4
5 Generic functions, mostly ROM and graphics related.
6
7 *********************************************************************/
8
9 #include "driver.h"
10 #include "png.h"
11
12 /* These globals are only kept on a machine basis - LBO 042898 */
13 unsigned int dispensed_tickets;
14 unsigned int coins[COIN_COUNTERS];
15 unsigned int lastcoin[COIN_COUNTERS];
16 unsigned int coinlockedout[COIN_COUNTERS];
17
18 data_t flip_screen_x, flip_screen_y;
19
20
21
showdisclaimer(void)22 void showdisclaimer(void) /* MAURY_BEGIN: dichiarazione */
23 {
24 printf("MAME is an emulator: it reproduces, more or less faithfully, the behaviour of\n"
25 "several arcade machines. But hardware is useless without software, so an image\n"
26 "of the ROMs which run on that hardware is required. Such ROMs, like any other\n"
27 "commercial software, are copyrighted material and it is therefore illegal to\n"
28 "use them if you don't own the original arcade machine. Needless to say, ROMs\n"
29 "are not distributed together with MAME. Distribution of MAME together with ROM\n"
30 "images is a violation of copyright law and should be promptly reported to the\n"
31 "authors so that appropriate legal action can be taken.\n\n");
32 } /* MAURY_END: dichiarazione */
33
34
35 /***************************************************************************
36
37 Read ROMs into memory.
38
39 Arguments:
40 const struct RomModule *romp - pointer to an array of Rommodule structures,
41 as defined in common.h.
42
43 ***************************************************************************/
44
readroms(void)45 int readroms(void)
46 {
47 int region;
48 const struct RomModule *romp;
49 int warning = 0;
50 int fatalerror = 0;
51 int total_roms,current_rom;
52 char buf[4096] = "";
53
54
55 total_roms = current_rom = 0;
56 romp = Machine->gamedrv->rom;
57
58 if (!romp) return 0;
59
60 while (romp->name || romp->offset || romp->length)
61 {
62 if (romp->name && romp->name != (char *)-1)
63 total_roms++;
64
65 romp++;
66 }
67
68
69 romp = Machine->gamedrv->rom;
70
71 for (region = 0;region < MAX_MEMORY_REGIONS;region++)
72 Machine->memory_region[region] = 0;
73
74 region = 0;
75
76 while (romp->name || romp->offset || romp->length)
77 {
78 unsigned int region_size;
79 const char *name;
80
81 /* Mish: An 'optional' rom region, only loaded if sound emulation is turned on */
82 if (Machine->sample_rate==0 && (romp->crc & REGIONFLAG_SOUNDONLY)) {
83 logerror("readroms(): Ignoring rom region %d\n",region);
84 Machine->memory_region_type[region] = romp->crc;
85 region++;
86
87 romp++;
88 while (romp->name || romp->length)
89 romp++;
90
91 continue;
92 }
93
94 if (romp->name || romp->length)
95 {
96 printf("Error in RomModule definition: expecting ROM_REGION\n");
97 goto getout;
98 }
99
100 region_size = romp->offset;
101 if ((Machine->memory_region[region] = (unsigned char *) malloc(region_size)) == 0)
102 {
103 printf("readroms(): Unable to allocate %d bytes of RAM\n",region_size);
104 goto getout;
105 }
106 Machine->memory_region_length[region] = region_size;
107 Machine->memory_region_type[region] = romp->crc;
108
109 /* some games (i.e. Pleiades) want the memory clear on startup */
110 if (region_size <= 0x400000) /* don't clear large regions which will be filled anyway */
111 memset(Machine->memory_region[region],0,region_size);
112
113 romp++;
114
115 while (romp->length)
116 {
117 void *f;
118 int expchecksum = romp->crc;
119 int explength = 0;
120
121
122 if (romp->name == 0)
123 {
124 printf("Error in RomModule definition: ROM_CONTINUE not preceded by ROM_LOAD\n");
125 goto getout;
126 }
127 else if (romp->name == (char *)-1)
128 {
129 printf("Error in RomModule definition: ROM_RELOAD not preceded by ROM_LOAD\n");
130 goto getout;
131 }
132
133 name = romp->name;
134
135 /* update status display */
136 if (osd_display_loading_rom_message(name,++current_rom,total_roms) != 0)
137 goto getout;
138
139 {
140 const struct GameDriver *drv;
141
142 drv = Machine->gamedrv;
143 do
144 {
145 f = osd_fopen(drv->name,name,OSD_FILETYPE_ROM,0);
146 drv = drv->clone_of;
147 } while (f == 0 && drv);
148
149 if (f == 0)
150 {
151 /* NS981003: support for "load by CRC" */
152 char crc[9];
153
154 sprintf(crc,"%08x",romp->crc);
155 drv = Machine->gamedrv;
156 do
157 {
158 f = osd_fopen(drv->name,crc,OSD_FILETYPE_ROM,0);
159 drv = drv->clone_of;
160 } while (f == 0 && drv);
161 }
162 }
163
164 if (f)
165 {
166 do
167 {
168 unsigned char *c;
169 unsigned int i;
170 int length = romp->length & ~ROMFLAG_MASK;
171
172
173 if (romp->name == (char *)-1)
174 osd_fseek(f,0,SEEK_SET); /* ROM_RELOAD */
175 else
176 explength += length;
177
178 if (romp->offset + length > region_size ||
179 (!(romp->length & ROMFLAG_NIBBLE) && (romp->length & ROMFLAG_ALTERNATE)
180 && (romp->offset&~1) + 2*length > region_size))
181 {
182 printf("Error in RomModule definition: %s out of memory region space\n",name);
183 osd_fclose(f);
184 goto getout;
185 }
186
187 if (romp->length & ROMFLAG_NIBBLE)
188 {
189 unsigned char *temp;
190
191
192 temp = (unsigned char *) malloc(length);
193
194 if (!temp)
195 {
196 printf("Out of memory reading ROM %s\n",name);
197 osd_fclose(f);
198 goto getout;
199 }
200
201 if (osd_fread(f,temp,length) != length)
202 {
203 printf("Unable to read ROM %s\n",name);
204 }
205
206 /* ROM_LOAD_NIB_LOW and ROM_LOAD_NIB_HIGH */
207 c = Machine->memory_region[region] + romp->offset;
208 if (romp->length & ROMFLAG_ALTERNATE)
209 {
210 /* Load into the high nibble */
211 for (i = 0;i < length;i ++)
212 {
213 c[i] = (c[i] & 0x0f) | ((temp[i] & 0x0f) << 4);
214 }
215 }
216 else
217 {
218 /* Load into the low nibble */
219 for (i = 0;i < length;i ++)
220 {
221 c[i] = (c[i] & 0xf0) | (temp[i] & 0x0f);
222 }
223 }
224
225 free(temp);
226 }
227 else if (romp->length & ROMFLAG_ALTERNATE)
228 {
229 /* ROM_LOAD_EVEN and ROM_LOAD_ODD */
230 /* copy the ROM data */
231 #ifdef MSB_FIRST
232 c = Machine->memory_region[region] + romp->offset;
233 #else
234 c = Machine->memory_region[region] + (romp->offset ^ 1);
235 #endif
236
237 if (osd_fread_scatter(f,c,length,2) != length)
238 {
239 printf("Unable to read ROM %s\n",name);
240 }
241 }
242 else if (romp->length & ROMFLAG_QUAD) {
243 static int which_quad=0; /* This is multi session friendly, as we only care about the modulus */
244 unsigned char *temp;
245 int base=0;
246
247 temp = (unsigned char *) malloc(length); /* Need to load rom to temporary space */
248 osd_fread(f,temp,length);
249
250 /* Copy quad to region */
251 c = Machine->memory_region[region] + romp->offset;
252
253 #ifdef MSB_FIRST
254 switch (which_quad%4)
255 {
256 case 0:
257 base=0;
258 break;
259 case 1:
260 base=1;
261 break;
262 case 2:
263 base=2;
264 break;
265 case 3:
266 base=3;
267 break;
268 }
269 #else
270 switch (which_quad%4)
271 {
272 case 0:
273 base=1;
274 break;
275 case 1:
276 base=0;
277 break;
278 case 2:
279 base=3;
280 break;
281 case 3:
282 base=2;
283 break;
284 }
285 #endif
286
287 for (i=base; i< length*4; i += 4)
288 c[i]=temp[i/4];
289
290 which_quad++;
291 free(temp);
292 }
293 else
294 {
295 int wide = romp->length & ROMFLAG_WIDE;
296 #ifdef MSB_FIRST
297 int swap = romp->length & ROMFLAG_SWAP;
298 #else
299 int swap = (romp->length & ROMFLAG_SWAP) ^ ROMFLAG_SWAP;
300 #endif
301
302 osd_fread(f,Machine->memory_region[region] + romp->offset,length);
303
304 /* apply swappage */
305 c = Machine->memory_region[region] + romp->offset;
306 if (wide && swap)
307 {
308 for (i = 0; i < length; i += 2)
309 {
310 int temp = c[i];
311 c[i] = c[i+1];
312 c[i+1] = temp;
313 }
314 }
315 }
316
317 romp++;
318 } while (romp->length && (romp->name == 0 || romp->name == (char *)-1));
319
320 if (explength != osd_fsize (f))
321 {
322 sprintf (&buf[strlen(buf)], "%-12s WRONG LENGTH (expected: %08x found: %08x)\n",
323 name,explength,osd_fsize(f));
324 warning = 1;
325 }
326
327 if (expchecksum != osd_fcrc (f))
328 {
329 warning = 1;
330 if (expchecksum == 0)
331 sprintf(&buf[strlen(buf)],"%-12s NO GOOD DUMP KNOWN\n",name);
332 else if (expchecksum == BADCRC(osd_fcrc(f)))
333 sprintf(&buf[strlen(buf)],"%-12s ROM NEEDS REDUMP\n",name);
334 else
335 sprintf(&buf[strlen(buf)], "%-12s WRONG CRC (expected: %08x found: %08x)\n",
336 name,expchecksum,osd_fcrc(f));
337 }
338
339 osd_fclose(f);
340 }
341 else if (romp->length & ROMFLAG_OPTIONAL)
342 {
343 sprintf (&buf[strlen(buf)], "OPTIONAL %-12s NOT FOUND\n",name);
344 romp ++;
345 }
346 else
347 {
348 /* allow for a NO GOOD DUMP KNOWN rom to be missing */
349 if (expchecksum == 0)
350 {
351 sprintf (&buf[strlen(buf)], "%-12s NOT FOUND (NO GOOD DUMP KNOWN)\n",name);
352 warning = 1;
353 }
354 else
355 {
356 sprintf (&buf[strlen(buf)], "%-12s NOT FOUND\n",name);
357 fatalerror = 1;
358 }
359
360 do
361 {
362 if (fatalerror == 0)
363 {
364 int i;
365
366 /* fill space with random data */
367 if (romp->length & ROMFLAG_ALTERNATE)
368 {
369 unsigned char *c;
370
371 /* ROM_LOAD_EVEN and ROM_LOAD_ODD */
372 #ifdef MSB_FIRST
373 c = Machine->memory_region[region] + romp->offset;
374 #else
375 c = Machine->memory_region[region] + (romp->offset ^ 1);
376 #endif
377
378 for (i = 0;i < (romp->length & ~ROMFLAG_MASK);i++)
379 c[2*i] = rand();
380 }
381 else
382 {
383 for (i = 0;i < (romp->length & ~ROMFLAG_MASK);i++)
384 Machine->memory_region[region][romp->offset + i] = rand();
385 }
386 }
387 romp++;
388 } while (romp->length && (romp->name == 0 || romp->name == (char *)-1));
389 }
390 }
391
392 region++;
393 }
394
395 /* final status display */
396 osd_display_loading_rom_message(0,current_rom,total_roms);
397
398 if (warning || fatalerror)
399 {
400 extern int bailing;
401
402 if (fatalerror)
403 {
404 strcat (buf, "ERROR: required files are missing, the game cannot be run.\n");
405 bailing = 1;
406 }
407 else
408 strcat (buf, "WARNING: the game might not run correctly.\n");
409 printf ("%s", buf);
410
411 if (!options.gui_host && !bailing)
412 {
413 printf ("Press any key to continue\n");
414 keyboard_read_sync();
415 if (keyboard_pressed(KEYCODE_LCONTROL) && keyboard_pressed(KEYCODE_C))
416 return 1;
417 }
418 }
419
420 if (fatalerror) return 1;
421 else return 0;
422
423
424 getout:
425 /* final status display */
426 osd_display_loading_rom_message(0,current_rom,total_roms);
427
428 for (region = 0;region < MAX_MEMORY_REGIONS;region++)
429 {
430 free(Machine->memory_region[region]);
431 Machine->memory_region[region] = 0;
432 }
433
434 return 1;
435 }
436
437
printromlist(const struct RomModule * romp,const char * basename)438 void printromlist(const struct RomModule *romp,const char *basename)
439 {
440 if (!romp) return;
441
442 #ifdef MESS
443 if (!strcmp(basename,"nes")) return;
444 #endif
445
446 printf("This is the list of the ROMs required for driver \"%s\".\n"
447 "Name Size Checksum\n",basename);
448
449 while (romp->name || romp->offset || romp->length)
450 {
451 romp++; /* skip memory region definition */
452
453 while (romp->length)
454 {
455 const char *name;
456 int length,expchecksum;
457
458
459 name = romp->name;
460 expchecksum = romp->crc;
461
462 length = 0;
463
464 do
465 {
466 /* ROM_RELOAD */
467 if (romp->name == (char *)-1)
468 length = 0; /* restart */
469
470 length += romp->length & ~ROMFLAG_MASK;
471
472 romp++;
473 } while (romp->length && (romp->name == 0 || romp->name == (char *)-1));
474
475 if (expchecksum)
476 printf("%-12s %7d bytes %08x\n",name,length,expchecksum);
477 else
478 printf("%-12s %7d bytes NO GOOD DUMP KNOWN\n",name,length);
479 }
480 }
481 }
482
483
484
485 /***************************************************************************
486
487 Read samples into memory.
488 This function is different from readroms() because it doesn't fail if
489 it doesn't find a file: it will load as many samples as it can find.
490
491 ***************************************************************************/
492
493 #ifdef MSB_FIRST
494 #define intelLong(x) (((x << 24) | (((unsigned long) x) >> 24) | (( x & 0x0000ff00) << 8) | (( x & 0x00ff0000) >> 8)))
495 #else
496 #define intelLong(x) (x)
497 #endif
498
read_wav_sample(void * f)499 static struct GameSample *read_wav_sample(void *f)
500 {
501 unsigned long offset = 0;
502 UINT32 length, rate, filesize, temp32;
503 UINT16 bits, temp16;
504 char buf[32];
505 struct GameSample *result;
506
507 /* read the core header and make sure it's a WAVE file */
508 offset += osd_fread(f, buf, 4);
509 if (offset < 4)
510 return NULL;
511 if (memcmp(&buf[0], "RIFF", 4) != 0)
512 return NULL;
513
514 /* get the total size */
515 offset += osd_fread(f, &filesize, 4);
516 if (offset < 8)
517 return NULL;
518 filesize = intelLong(filesize);
519
520 /* read the RIFF file type and make sure it's a WAVE file */
521 offset += osd_fread(f, buf, 4);
522 if (offset < 12)
523 return NULL;
524 if (memcmp(&buf[0], "WAVE", 4) != 0)
525 return NULL;
526
527 /* seek until we find a format tag */
528 while (1)
529 {
530 offset += osd_fread(f, buf, 4);
531 offset += osd_fread(f, &length, 4);
532 length = intelLong(length);
533 if (memcmp(&buf[0], "fmt ", 4) == 0)
534 break;
535
536 /* seek to the next block */
537 osd_fseek(f, length, SEEK_CUR);
538 offset += length;
539 if (offset >= filesize)
540 return NULL;
541 }
542
543 /* read the format -- make sure it is PCM */
544 offset += osd_fread_lsbfirst(f, &temp16, 2);
545 if (temp16 != 1)
546 return NULL;
547
548 /* number of channels -- only mono is supported */
549 offset += osd_fread_lsbfirst(f, &temp16, 2);
550 if (temp16 != 1)
551 return NULL;
552
553 /* sample rate */
554 offset += osd_fread(f, &rate, 4);
555 rate = intelLong(rate);
556
557 /* bytes/second and block alignment are ignored */
558 offset += osd_fread(f, buf, 6);
559
560 /* bits/sample */
561 offset += osd_fread_lsbfirst(f, &bits, 2);
562 if (bits != 8 && bits != 16)
563 return NULL;
564
565 /* seek past any extra data */
566 osd_fseek(f, length - 16, SEEK_CUR);
567 offset += length - 16;
568
569 /* seek until we find a data tag */
570 while (1)
571 {
572 offset += osd_fread(f, buf, 4);
573 offset += osd_fread(f, &length, 4);
574 length = intelLong(length);
575 if (memcmp(&buf[0], "data", 4) == 0)
576 break;
577
578 /* seek to the next block */
579 osd_fseek(f, length, SEEK_CUR);
580 offset += length;
581 if (offset >= filesize)
582 return NULL;
583 }
584
585 /* allocate the game sample */
586 result = malloc(sizeof(struct GameSample) + length);
587 if (result == NULL)
588 return NULL;
589
590 /* fill in the sample data */
591 result->length = length;
592 result->smpfreq = rate;
593 result->resolution = bits;
594
595 /* read the data in */
596 if (bits == 8)
597 {
598 osd_fread(f, result->data, length);
599
600 /* convert 8-bit data to signed samples */
601 for (temp32 = 0; temp32 < length; temp32++)
602 result->data[temp32] ^= 0x80;
603 }
604 else
605 {
606 /* 16-bit data is fine as-is */
607 osd_fread_lsbfirst(f, result->data, length);
608 }
609
610 return result;
611 }
612
readsamples(const char ** samplenames,const char * basename)613 struct GameSamples *readsamples(const char **samplenames,const char *basename)
614 /* V.V - avoids samples duplication */
615 /* if first samplename is *dir, looks for samples into "basename" first, then "dir" */
616 {
617 int i;
618 struct GameSamples *samples;
619 int skipfirst = 0;
620
621 /* if the user doesn't want to use samples, bail */
622 if (!options.use_samples) return 0;
623
624 if (samplenames == 0 || samplenames[0] == 0) return 0;
625
626 if (samplenames[0][0] == '*')
627 skipfirst = 1;
628
629 i = 0;
630 while (samplenames[i+skipfirst] != 0) i++;
631
632 if (!i) return 0;
633
634 if ((samples = malloc(sizeof(struct GameSamples) + (i-1)*sizeof(struct GameSample))) == 0)
635 return 0;
636
637 samples->total = i;
638 for (i = 0;i < samples->total;i++)
639 samples->sample[i] = 0;
640
641 for (i = 0;i < samples->total;i++)
642 {
643 void *f;
644
645 if (samplenames[i+skipfirst][0])
646 {
647 if ((f = osd_fopen(basename,samplenames[i+skipfirst],OSD_FILETYPE_SAMPLE,0)) == 0)
648 if (skipfirst)
649 f = osd_fopen(samplenames[0]+1,samplenames[i+skipfirst],OSD_FILETYPE_SAMPLE,0);
650 if (f != 0)
651 {
652 samples->sample[i] = read_wav_sample(f);
653 osd_fclose(f);
654 }
655 }
656 }
657
658 return samples;
659 }
660
661
freesamples(struct GameSamples * samples)662 void freesamples(struct GameSamples *samples)
663 {
664 int i;
665
666
667 if (samples == 0) return;
668
669 for (i = 0;i < samples->total;i++)
670 free(samples->sample[i]);
671
672 free(samples);
673 }
674
675
676
memory_region(int num)677 unsigned char *memory_region(int num)
678 {
679 int i;
680
681 if (num < MAX_MEMORY_REGIONS)
682 return Machine->memory_region[num];
683 else
684 {
685 for (i = 0;i < MAX_MEMORY_REGIONS;i++)
686 {
687 if ((Machine->memory_region_type[i] & ~REGIONFLAG_MASK) == num)
688 return Machine->memory_region[i];
689 }
690 }
691
692 return 0;
693 }
694
memory_region_length(int num)695 int memory_region_length(int num)
696 {
697 int i;
698
699 if (num < MAX_MEMORY_REGIONS)
700 return Machine->memory_region_length[num];
701 else
702 {
703 for (i = 0;i < MAX_MEMORY_REGIONS;i++)
704 {
705 if ((Machine->memory_region_type[i] & ~REGIONFLAG_MASK) == num)
706 return Machine->memory_region_length[i];
707 }
708 }
709
710 return 0;
711 }
712
new_memory_region(int num,int length)713 int new_memory_region(int num, int length)
714 {
715 int i;
716
717 if (num < MAX_MEMORY_REGIONS)
718 {
719 Machine->memory_region_length[num] = length;
720 Machine->memory_region[num] = (unsigned char*) malloc(length);
721 return (Machine->memory_region[num] == NULL) ? 1 : 0;
722 }
723 else
724 {
725 for (i = 0;i < MAX_MEMORY_REGIONS;i++)
726 {
727 if (Machine->memory_region[i] == NULL)
728 {
729 Machine->memory_region_length[i] = length;
730 Machine->memory_region_type[i] = num;
731 Machine->memory_region[i] = (unsigned char*) malloc(length);
732 return (Machine->memory_region[i] == NULL) ? 1 : 0;
733 }
734 }
735 }
736 return 1;
737 }
738
free_memory_region(int num)739 void free_memory_region(int num)
740 {
741 int i;
742
743 if (num < MAX_MEMORY_REGIONS)
744 {
745 free(Machine->memory_region[num]);
746 Machine->memory_region[num] = 0;
747 }
748 else
749 {
750 for (i = 0;i < MAX_MEMORY_REGIONS;i++)
751 {
752 if ((Machine->memory_region_type[i] & ~REGIONFLAG_MASK) == num)
753 {
754 free(Machine->memory_region[i]);
755 Machine->memory_region[i] = 0;
756 return;
757 }
758 }
759 }
760 }
761
762
763 /* LBO 042898 - added coin counters */
WRITE_HANDLER(coin_counter_w)764 WRITE_HANDLER( coin_counter_w )
765 {
766 if (offset >= COIN_COUNTERS) return;
767 /* Count it only if the data has changed from 0 to non-zero */
768 if (data && (lastcoin[offset] == 0))
769 {
770 coins[offset] ++;
771 }
772 lastcoin[offset] = data;
773 }
774
WRITE_HANDLER(coin_lockout_w)775 WRITE_HANDLER( coin_lockout_w )
776 {
777 if (offset >= COIN_COUNTERS) return;
778
779 coinlockedout[offset] = data;
780 }
781
782 /* Locks out all the coin inputs */
WRITE_HANDLER(coin_lockout_global_w)783 WRITE_HANDLER( coin_lockout_global_w )
784 {
785 int i;
786
787 for (i = 0; i < COIN_COUNTERS; i++)
788 {
789 coin_lockout_w(i, data);
790 }
791 }
792
793
794 /* flipscreen handling functions */
updateflip(void)795 static void updateflip(void)
796 {
797 int min_x,max_x,min_y,max_y;
798
799 tilemap_set_flip(ALL_TILEMAPS,(TILEMAP_FLIPX & flip_screen_x) | (TILEMAP_FLIPY & flip_screen_y));
800
801 min_x = Machine->drv->default_visible_area.min_x;
802 max_x = Machine->drv->default_visible_area.max_x;
803 min_y = Machine->drv->default_visible_area.min_y;
804 max_y = Machine->drv->default_visible_area.max_y;
805
806 if (flip_screen_x)
807 {
808 int temp;
809
810 temp = Machine->drv->screen_width - min_x - 1;
811 min_x = Machine->drv->screen_width - max_x - 1;
812 max_x = temp;
813 }
814 if (flip_screen_y)
815 {
816 int temp;
817
818 temp = Machine->drv->screen_height - min_y - 1;
819 min_y = Machine->drv->screen_height - max_y - 1;
820 max_y = temp;
821 }
822
823 set_visible_area(min_x,max_x,min_y,max_y);
824 }
825
WRITE_HANDLER(flip_screen_w)826 WRITE_HANDLER( flip_screen_w )
827 {
828 flip_screen_x_w(offset,data);
829 flip_screen_y_w(offset,data);
830 }
831
WRITE_HANDLER(flip_screen_x_w)832 WRITE_HANDLER( flip_screen_x_w )
833 {
834 if (data) data = ~0;
835 if (flip_screen_x != data)
836 {
837 set_vh_global_attribute(&flip_screen_x,data);
838 updateflip();
839 }
840 }
841
WRITE_HANDLER(flip_screen_y_w)842 WRITE_HANDLER( flip_screen_y_w )
843 {
844 if (data) data = ~0;
845 if (flip_screen_y != data)
846 {
847 set_vh_global_attribute(&flip_screen_y,data);
848 updateflip();
849 }
850 }
851
852
set_vh_global_attribute(data_t * addr,data_t data)853 void set_vh_global_attribute( data_t *addr, data_t data )
854 {
855 if (*addr != data)
856 {
857 schedule_full_refresh();
858 *addr = data;
859 }
860 }
861
862
schedule_full_refresh(void)863 void schedule_full_refresh(void)
864 {
865 extern int bitmap_dirty;
866 bitmap_dirty = 1;
867 }
868
869
set_visible_area(int min_x,int max_x,int min_y,int max_y)870 void set_visible_area(int min_x,int max_x,int min_y,int max_y)
871 {
872 Machine->visible_area.min_x = min_x;
873 Machine->visible_area.max_x = max_x;
874 Machine->visible_area.min_y = min_y;
875 Machine->visible_area.max_y = max_y;
876
877 /* vector games always use the whole bitmap */
878 if (Machine->drv->video_attributes & VIDEO_TYPE_VECTOR)
879 {
880 min_x = 0;
881 max_x = Machine->scrbitmap->width - 1;
882 min_y = 0;
883 max_y = Machine->scrbitmap->height - 1;
884 }
885 else
886 {
887 int temp;
888
889 if (Machine->orientation & ORIENTATION_SWAP_XY)
890 {
891 temp = min_x; min_x = min_y; min_y = temp;
892 temp = max_x; max_x = max_y; max_y = temp;
893 }
894 if (Machine->orientation & ORIENTATION_FLIP_X)
895 {
896 temp = Machine->scrbitmap->width - min_x - 1;
897 min_x = Machine->scrbitmap->width - max_x - 1;
898 max_x = temp;
899 }
900 if (Machine->orientation & ORIENTATION_FLIP_Y)
901 {
902 temp = Machine->scrbitmap->height - min_y - 1;
903 min_y = Machine->scrbitmap->height - max_y - 1;
904 max_y = temp;
905 }
906 }
907
908 osd_set_visible_area(min_x,max_x,min_y,max_y);
909 }
910
911
bitmap_alloc(int width,int height)912 struct osd_bitmap *bitmap_alloc(int width,int height)
913 {
914 return bitmap_alloc_depth(width,height,Machine->scrbitmap->depth);
915 }
916
bitmap_alloc_depth(int width,int height,int depth)917 struct osd_bitmap *bitmap_alloc_depth(int width,int height,int depth)
918 {
919 if (Machine->orientation & ORIENTATION_SWAP_XY)
920 {
921 int temp;
922
923 temp = width; width = height; height = temp;
924 }
925
926 return osd_alloc_bitmap(width,height,depth);
927 }
928
bitmap_free(struct osd_bitmap * bitmap)929 void bitmap_free(struct osd_bitmap *bitmap)
930 {
931 osd_free_bitmap(bitmap);
932 }
933
934
save_screen_snapshot_as(void * fp,struct osd_bitmap * bitmap)935 void save_screen_snapshot_as(void *fp,struct osd_bitmap *bitmap)
936 {
937 }
938
939 int snapno;
940
save_screen_snapshot(struct osd_bitmap * bitmap)941 void save_screen_snapshot(struct osd_bitmap *bitmap)
942 {
943 void *fp;
944 char name[20];
945
946
947 /* avoid overwriting existing files */
948 /* first of all try with "gamename.png" */
949 sprintf(name,"%.8s", Machine->gamedrv->name);
950 if (osd_faccess(name,OSD_FILETYPE_SCREENSHOT))
951 {
952 do
953 {
954 /* otherwise use "nameNNNN.png" */
955 sprintf(name,"%.4s%04d",Machine->gamedrv->name,snapno++);
956 } while (osd_faccess(name, OSD_FILETYPE_SCREENSHOT));
957 }
958
959 if ((fp = osd_fopen(Machine->gamedrv->name, name, OSD_FILETYPE_SCREENSHOT, 1)) != NULL)
960 {
961 save_screen_snapshot_as(fp,bitmap);
962 osd_fclose(fp);
963 }
964 }
965