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