1 /***************************************************************************
2 
3 	mame.c
4 
5 	Controls execution of the core MAME system.
6 
7 ****************************************************************************
8 
9     libretro manages:
10         - platform-specific init
11         - calls init_game() from retro_load_game()
12         - calls run_game() from retro_load_game
13 
14 	mame.c manages:
15 		init_game()
16 			- constructs the machine driver
17 			- calls init_game_options()
18 
19 			init_game_options()
20 				- determines color depth from the options
21 				- computes orientation from the options
22 
23 			- initializes the savegame system
24 			- calls init_machine()
25 
26 			init_machine()
27 				- initializes the localized strings
28 				- initializes the input system
29 				- parses and allocates the game's input ports
30 				- initializes the hard disk system
31 				- loads the game's ROMs
32 				- resets the timer system
33 				- starts the refresh timer
34 				- initializes the CPUs
35 				- loads the configuration file
36 				- initializes the memory system for the game
37 				- calls the driver's DRIVER_INIT callback
38 
39 			- calls run_machine()
40 
41 			run_machine()
42 				- calls vh_open()
43 
44 				vh_open()
45 					- allocates the palette
46 					- decodes the graphics
47 					- computes vector game resolution
48 					- sets up the artwork
49 					- calls osd_create_display() to init the display
50 					- allocates the scrbitmap
51 					- sets the initial visible_area
52 					- sets up buffered spriteram
53 					- creates the user interface font
54 					- creates the debugger bitmap and font
55 					- finishes palette initialization
56 
57 				- initializes the tilemap system
58 				- calls the driver's VIDEO_START callback
59 				- starts the audio system
60 				- disposes of regions marked as disposable
61 				- calls ui_copyright_and_warnings()
62 
63 				pause_action_start_emulator()
64 					- initializes the user interface
65 					- initializes the cheat system
66 					- calls the driver's NVRAM_HANDLER
67 
68 	--------------( at this point, we're up and running )---------------------------
69 
70 					- calls the driver's NVRAM_HANDLER
71 					- tears down the cheat system
72 					- saves the game's configuration
73 
74 				- stops the audio system
75 				- calls the driver's VIDEO_STOP callback
76 				- tears down the tilemap system
77 				- calls vh_close()
78 
79 				vh_close()
80 					- frees the decoded graphics
81 					- frees the fonts
82 					- calls osd_close_display() to shut down the display
83 					- tears down the artwork
84 					- tears down the palette system
85 
86 			- calls shutdown_machine()
87 
88 			shutdown_machine()
89 				- tears down the memory system
90 				- frees all the memory regions
91 				- tears down the hard disks
92 				- tears down the CPU system
93 				- releases the input ports
94 				- tears down the input system
95 				- tears down the localized strings
96 				- resets the saved state system
97 
98 			- calls osd_exit() to do platform-specific cleanup
99 
100 		- exits the program
101 
102 ***************************************************************************/
103 
104 #include <ctype.h>
105 #include <stdarg.h>
106 #include <file/file_path.h>
107 #include "ui_text.h"
108 #include "mamedbg.h"
109 #include "artwork.h"
110 #include "state.h"
111 #include "vidhrdw/generic.h"
112 #include "vidhrdw/vector.h"
113 #include "palette.h"
114 #include "harddisk.h"
115 #include "driver.h"
116 #include "mame.h"
117 #include "bootstrap.h"
118 
119 /***************************************************************************
120 
121 	Constants
122 
123 ***************************************************************************/
124 
125 #define FRAMES_PER_FPS_UPDATE		12
126 
127 
128 
129 /***************************************************************************
130 
131 	Global variables
132 
133 ***************************************************************************/
134 
135 /* handy globals for other parts of the system */
136 int framerate_test = 0;
137 void *record;	/* for -record */
138 void *playback; /* for -playback */
139 int mame_debug; /* !0 when -debug option is specified */
140 int bailing;	/* set to 1 if the startup is aborted to prevent multiple error messages */
141 
142 extern int16_t XsoundBuffer[2048];
143 extern void (*pause_action)(void);
144 
145 /* the active machine */
146 static struct RunningMachine active_machine;
147 struct RunningMachine *Machine = &active_machine;
148 
149 /* the active game driver */
150 static const struct GameDriver *gamedrv;
151 static struct InternalMachineDriver internal_drv;
152 
153 /* various game options filled in by the OSD */
154 struct GameOptions options;
155 
156 /* the active video display */
157 static struct mame_display current_display;
158 static UINT8 visible_area_changed;
159 
160 /* video updating */
161 static UINT8 full_refresh_pending;
162 static int last_partial_scanline;
163 
164 /* speed computation */
165 static struct performance_info performance;
166 
167 /* misc other statics */
168 static int settingsloaded;
169 static int leds_status;
170 
171 /* artwork callbacks */
172 static struct artwork_callbacks mame_artwork_callbacks =
173 {
174 	NULL,
175 	artwork_load_artwork_file
176 };
177 
178 static int game_loaded;
179 
180 
181 
182 /***************************************************************************
183 
184 	Hard disk interface prototype
185 
186 ***************************************************************************/
187 
188 static struct chd_interface_file *mame_chd_open(const char *filename, const char *mode);
189 static void mame_chd_close(struct chd_interface_file *file);
190 static UINT32 mame_chd_read(struct chd_interface_file *file, UINT64 offset, UINT32 count, void *buffer);
191 static UINT32 mame_chd_write(struct chd_interface_file *file, UINT64 offset, UINT32 count, const void *buffer);
192 static UINT64 mame_chd_length(struct chd_interface_file *file);
193 
194 static struct chd_interface mame_chd_interface =
195 {
196 	mame_chd_open,
197 	mame_chd_close,
198 	mame_chd_read,
199 	mame_chd_write,
200 	mame_chd_length
201 };
202 
203 
204 
205 /***************************************************************************
206 
207 	Other function prototypes
208 
209 ***************************************************************************/
210 
211 static int init_machine(void);
212 static void shutdown_machine(void);
213 static int run_machine(void);
214 void pause_action_start_emulator(void);
215 
216 #ifdef MAME_DEBUG
217 static int validitychecks(void);
218 #endif
219 
220 static int vh_open(void);
221 static void vh_close(void);
222 static void init_game_options(void);
223 static int decode_graphics(const struct GfxDecodeInfo *gfxdecodeinfo);
224 static void compute_aspect_ratio(const struct InternalMachineDriver *drv, int *aspect_x, int *aspect_y);
225 static void scale_vectorgames(int gfx_width, int gfx_height, int *width, int *height);
226 static int init_buffered_spriteram(void);
227 
228 /***************************************************************************
229 
230 	Inline functions
231 
232 ***************************************************************************/
233 
234 /*-------------------------------------------------
235 	bail_and_print - set the bailing flag and
236 	print a message if one hasn't already been
237 	printed
238 -------------------------------------------------*/
239 
bail_and_print(const char * message)240 static INLINE void bail_and_print(const char *message)
241 {
242 	if (!bailing)
243 	{
244 		bailing = 1;
245 		log_cb(RETRO_LOG_ERROR, LOGPRE "%s\n", message);
246 	}
247 }
248 
249 
250 
251 
252 /***************************************************************************
253 
254 	Core system management
255 
256 ***************************************************************************/
257 
init_game(int game)258 bool init_game(int game)
259 {
260 	begin_resource_tracking();
261 
262 #ifdef MAME_DEBUG
263 	/* validity checks -- debug build only */
264 	if (validitychecks())
265 		return false;
266 #endif
267 
268 	/* first give the machine a good cleaning */
269 	memset(Machine, 0, sizeof(*Machine));
270 
271 	/* initialize the driver-related variables in the Machine */
272 	Machine->gamedrv = gamedrv = drivers[game];
273 	expand_machine_driver(gamedrv->drv, &internal_drv);
274 	Machine->drv = &internal_drv;
275   return true;
276 }
277 
278 
279 /*-------------------------------------------------
280 	run_game - run the given game in a session
281 -------------------------------------------------*/
282 
run_game(int game)283 bool run_game(int game)
284 {
285 	init_game_options();
286 
287 	/* here's the meat of it all */
288 	bailing = 0;
289 
290   begin_resource_tracking();
291 
292   /* finish setting up our local machine */
293   if (init_machine())
294       bail_and_print("Unable to initialize machine emulation");
295   else
296   {
297   /* then run it */
298       if (run_machine())
299           bail_and_print("Unable to start machine emulation");
300       else
301       {
302          game_loaded = 1;
303          return 0;
304       }
305 
306       /* shutdown the local machine */
307       shutdown_machine();
308   }
309   /* stop tracking resources and exit the OSD layer */
310   end_resource_tracking();
311 
312 	return 1;
313 }
314 
run_game_done(void)315 void run_game_done(void)
316 {
317 	shutdown_machine();
318 	end_resource_tracking();
319 }
320 
321 /*-------------------------------------------------
322 	init_machine - initialize the emulated machine
323 -------------------------------------------------*/
324 
init_machine(void)325 static int init_machine(void)
326 {
327 
328 	/* load the localization file */
329 	if (uistring_init(options.language_file) != 0)
330 	{
331 		log_cb(RETRO_LOG_ERROR, LOGPRE "uistring_init failed\n");
332 		goto cant_load_language_file;
333 	}
334 
335 	/* initialize the input system */
336 	if (code_init() != 0)
337 	{
338 		log_cb(RETRO_LOG_ERROR, LOGPRE "code_init failed\n");
339 		goto cant_init_input;
340 	}
341 
342 	/* if we have inputs, process them now */
343 	if (gamedrv->input_ports)
344 	{
345 		/* allocate input ports */
346 		Machine->input_ports = input_port_allocate(gamedrv->input_ports);
347 		if (!Machine->input_ports)
348 		{
349 			log_cb(RETRO_LOG_ERROR, LOGPRE "could not allocate Machine->input_ports\n");
350 			goto cant_allocate_input_ports;
351 		}
352 
353 		/* allocate default input ports */
354 		Machine->input_ports_default = input_port_allocate(gamedrv->input_ports);
355 		if (!Machine->input_ports_default)
356 		{
357 			log_cb(RETRO_LOG_ERROR, LOGPRE "could not allocate Machine->input_ports_default\n");
358 			goto cant_allocate_input_ports_default;
359 		}
360 	}
361 
362 	/* init the hard drive interface now, before attempting to load */
363 	chd_set_interface(&mame_chd_interface);
364 
365 	/* load the ROMs if we have some */
366 	if (gamedrv->rom && rom_load(gamedrv->rom) != 0)
367 	{
368 		log_cb(RETRO_LOG_ERROR, LOGPRE "readroms failed\n");
369 		goto cant_load_roms;
370 	}
371 
372 	/* first init the timers; some CPUs have built-in timers and will need */
373 	/* to allocate them up front */
374 	timer_init();
375 	cpu_init_refresh_timer();
376 
377 	/* now set up all the CPUs */
378 	cpu_init();
379 
380 	/* load input ports settings (keys, dip switches, and so on) */
381 	settingsloaded = load_input_port_settings();
382 
383 	/* multi-session safety - set spriteram size to zero before memory map is set up */
384 	spriteram_size = spriteram_2_size = 0;
385 
386 	/* initialize the memory system for this game */
387 	if (!memory_init())
388 	{
389 		log_cb(RETRO_LOG_ERROR, LOGPRE "memory_init failed\n");
390 		goto cant_init_memory;
391 	}
392 
393 	/* call the game driver's init function */
394 	if (gamedrv->driver_init)
395 		(*gamedrv->driver_init)();
396 
397 	return 0;
398 
399 cant_init_memory:
400 cant_load_roms:
401 	input_port_free(Machine->input_ports_default);
402 	Machine->input_ports_default = 0;
403 cant_allocate_input_ports_default:
404 	input_port_free(Machine->input_ports);
405 	Machine->input_ports = 0;
406 cant_allocate_input_ports:
407 	code_close();
408 cant_init_input:
409 cant_load_language_file:
410 	return 1;
411 }
412 
413 
414 
415 /*-------------------------------------------------
416 	run_machine - start the various subsystems
417 	and the CPU emulation; returns non zero in
418 	case of error
419 -------------------------------------------------*/
420 
run_machine(void)421 static int run_machine(void)
422 {
423 	int res = 1;
424 
425 	/* start the video hardware */
426 	if (vh_open())
427 		bail_and_print("Unable to start video emulation");
428 	else
429 	{
430 		/* initialize tilemaps */
431 		tilemap_init();
432 
433 		/* start up the driver's video */
434 		if (Machine->drv->video_start && (*Machine->drv->video_start)())
435 			bail_and_print("Unable to start video emulation");
436 		else
437 		{
438 			/* start the audio system */
439 			if (sound_start())
440 				bail_and_print("Unable to start audio emulation");
441 			else
442 			{
443 				int region;
444 
445 				/* free memory regions allocated with REGIONFLAG_DISPOSE (typically gfx roms) */
446 				for (region = 0; region < MAX_MEMORY_REGIONS; region++)
447 					if (Machine->memory_region[region].flags & ROMREGION_DISPOSE)
448 					{
449 						int i;
450 
451 						/* invalidate contents to avoid subtle bugs */
452 						for (i = 0; i < memory_region_length(region); i++)
453 							memory_region(region)[i] = rand();
454 						free(Machine->memory_region[region].base);
455 						Machine->memory_region[region].base = 0;
456 					}
457 
458 				ui_copyright_and_warnings();
459         pause_action = pause_action_start_emulator;
460 				return 0;
461 			}
462 
463 			/* shut down the driver's video and kill and artwork */
464 			if (Machine->drv->video_stop)
465 				(*Machine->drv->video_stop)();
466 		}
467 
468 		/* close down the tilemap and video systems */
469 		tilemap_close();
470 		vh_close();
471 	}
472 
473 	return res;
474 }
475 
run_machine_done(void)476 void run_machine_done(void)
477 {
478 	sound_stop();
479 
480     /* shut down the driver's video and kill and artwork */
481     if (Machine->drv->video_stop)
482         (*Machine->drv->video_stop)();
483 
484     /* close down the tilemap and video systems */
485     tilemap_close();
486     vh_close();
487 }
488 
pause_action_start_emulator(void)489 void pause_action_start_emulator(void)
490 {
491   init_user_interface();
492   artwork_enable(1);
493   InitCheat();
494 
495   /* load the NVRAM now */
496   if (Machine->drv->nvram_handler)
497   {
498     mame_file *nvram_file = mame_fopen(Machine->gamedrv->name, 0, FILETYPE_NVRAM, 0);
499 
500     if(!nvram_file)
501       log_cb(RETRO_LOG_INFO, LOGPRE "First run: NVRAM handler found for %s but no existing NVRAM file found.\n", Machine->gamedrv->name);
502 
503     log_cb(RETRO_LOG_INFO, LOGPRE "options.nvram_bootstrap: %i \n", options.nvram_bootstrap);
504     if(!nvram_file && (Machine->gamedrv->bootstrap != NULL))
505     {
506       if(options.nvram_bootstrap)
507       {
508         log_cb(RETRO_LOG_INFO, LOGPRE "Spwaning NVRAM bootstrap as the initial NVRAM image.\n");
509         nvram_file = spawn_bootstrap_nvram(Machine->gamedrv->bootstrap->data, Machine->gamedrv->bootstrap->length);
510       }
511       else
512         log_cb(RETRO_LOG_INFO, LOGPRE "NVRAM bootstrap available, but disabled via core option.\n");
513     }
514     else
515       log_cb(RETRO_LOG_INFO, LOGPRE "Delegating population of initial NVRAM to emulated system.\n");
516 
517     (*Machine->drv->nvram_handler)(nvram_file, 0);
518     if (nvram_file)
519         mame_fclose(nvram_file);
520   }
521 
522   /* run the emulation! */
523   cpu_run();
524 
525   /* Unpause */
526   pause_action = 0;
527 }
528 
run_machine_core_done(void)529 void run_machine_core_done(void)
530 {
531     /* save the NVRAM */
532     if (Machine->drv->nvram_handler)
533     {
534         mame_file *nvram_file = mame_fopen(Machine->gamedrv->name, 0, FILETYPE_NVRAM, 1);
535         if (nvram_file != NULL)
536         {
537             (*Machine->drv->nvram_handler)(nvram_file, 1);
538             mame_fclose(nvram_file);
539         }
540     }
541 
542     StopCheat();
543 
544     /* save input ports settings */
545     save_input_port_settings();
546 }
547 
548 /*-------------------------------------------------
549 	shutdown_machine - tear down the emulated
550 	machine
551 -------------------------------------------------*/
552 
shutdown_machine(void)553 static void shutdown_machine(void)
554 {
555 	int i;
556 
557 	/* release any allocated memory */
558 	memory_shutdown();
559 
560 	/* free the memory allocated for various regions */
561 	for (i = 0; i < MAX_MEMORY_REGIONS; i++)
562 		free_memory_region(i);
563 
564 	/* close all hard drives */
565 	chd_close_all();
566 
567 	/* reset the CPU system */
568 	cpu_exit();
569 
570 	/* free the memory allocated for input ports definition */
571 	input_port_free(Machine->input_ports);
572 	input_port_free(Machine->input_ports_default);
573 
574 	/* close down the input system */
575 	code_close();
576 
577 	/* reset the saved states */
578 	state_save_reset();
579 }
580 
581 /*-------------------------------------------------
582 	expand_machine_driver - construct a machine
583 	driver from the macroized state
584 -------------------------------------------------*/
585 
expand_machine_driver(void (* constructor)(struct InternalMachineDriver *),struct InternalMachineDriver * output)586 void expand_machine_driver(void (*constructor)(struct InternalMachineDriver *), struct InternalMachineDriver *output)
587 {
588 	/* keeping this function allows us to pre-init the driver before constructing it */
589 	memset(output, 0, sizeof(*output));
590 	(*constructor)(output);
591 }
592 
593 
594 
595 /*-------------------------------------------------
596 	vh_open - start up the video system
597 -------------------------------------------------*/
598 
vh_open(void)599 static int vh_open(void)
600 {
601 	struct osd_create_params params;
602 	struct artwork_callbacks *artcallbacks;
603 	int bmwidth = Machine->drv->screen_width;
604 	int bmheight = Machine->drv->screen_height;
605 
606 	/* first allocate the necessary palette structures */
607 	if (palette_start())
608 		goto cant_start_palette;
609 
610 	/* convert the gfx ROMs into character sets. This is done BEFORE calling the driver's */
611 	/* palette_init() routine because it might need to check the Machine->gfx[] data */
612 	if (Machine->drv->gfxdecodeinfo)
613 		if (decode_graphics(Machine->drv->gfxdecodeinfo))
614 			goto cant_decode_graphics;
615 
616 	/* if we're a vector game, override the screen width and height */
617 	if (Machine->drv->video_attributes & VIDEO_TYPE_VECTOR)
618     {
619        scale_vectorgames(options.vector_width, options.vector_height, &bmwidth, &bmheight);
620     }
621 	/* compute the visible area for raster games */
622 	if (!(Machine->drv->video_attributes & VIDEO_TYPE_VECTOR))
623 	{
624 		params.width = Machine->drv->default_visible_area.max_x - Machine->drv->default_visible_area.min_x + 1;
625 		params.height = Machine->drv->default_visible_area.max_y - Machine->drv->default_visible_area.min_y + 1;
626 	}
627 	else
628 	{
629 		params.width = bmwidth;
630 		params.height = bmheight;
631 	}
632 
633 	/* fill in the rest of the display parameters */
634 	compute_aspect_ratio(Machine->drv, &params.aspect_x, &params.aspect_y);
635 	params.depth = Machine->color_depth;
636 	params.colors = palette_get_total_colors_with_ui();
637 	params.fps = Machine->drv->frames_per_second;
638 	params.video_attributes = Machine->drv->video_attributes;
639 	params.orientation = Machine->orientation;
640 	artcallbacks = &mame_artwork_callbacks;
641 
642 	/* initialize the display through the artwork (and eventually the OSD) layer */
643 	if (artwork_create_display(&params, direct_rgb_components, artcallbacks))
644 		goto cant_create_display;
645 
646 	/* the create display process may update the vector width/height, so recompute */
647 	if (Machine->drv->video_attributes & VIDEO_TYPE_VECTOR)
648     {
649         scale_vectorgames(options.vector_width, options.vector_height, &bmwidth, &bmheight);
650     }
651 
652 
653 	/* now allocate the screen bitmap */
654 	Machine->scrbitmap = auto_bitmap_alloc_depth(bmwidth, bmheight, Machine->color_depth);
655 	if (!Machine->scrbitmap)
656 		goto cant_create_scrbitmap;
657 
658 	/* set the default visible area */
659 	set_visible_area(0,1,0,1);	/* make sure everything is recalculated on multiple runs */
660 	set_visible_area(
661 			Machine->drv->default_visible_area.min_x,
662 			Machine->drv->default_visible_area.max_x,
663 			Machine->drv->default_visible_area.min_y,
664 			Machine->drv->default_visible_area.max_y);
665 
666 	/* create spriteram buffers if necessary */
667 	if (Machine->drv->video_attributes & VIDEO_BUFFERS_SPRITERAM)
668 		if (init_buffered_spriteram())
669 			goto cant_init_buffered_spriteram;
670 
671 	/* build our private user interface font */
672 	/* This must be done AFTER osd_create_display() so the function knows the */
673 	/* resolution we are running at and can pick a different font depending on it. */
674 	/* It must be done BEFORE palette_init() because that will also initialize */
675 	/* (through osd_allocate_colors()) the uifont colortable. */
676 	Machine->uifont = builduifont();
677 	if (Machine->uifont == NULL)
678 		goto cant_build_uifont;
679 
680 #ifdef MAME_DEBUG
681 	/* if the debugger is enabled, initialize its bitmap and font */
682 	if (mame_debug)
683 	{
684 		int depth = options.debug_depth ? options.debug_depth : Machine->color_depth;
685 
686 		/* first allocate the debugger bitmap */
687 		Machine->debug_bitmap = auto_bitmap_alloc_depth(options.debug_width, options.debug_height, depth);
688 		if (!Machine->debug_bitmap)
689 			goto cant_create_debug_bitmap;
690 
691 		/* then create the debugger font */
692 		Machine->debugger_font = build_debugger_font();
693 		if (Machine->debugger_font == NULL)
694 			goto cant_build_debugger_font;
695 	}
696 #endif
697 
698 	/* initialize the palette - must be done after osd_create_display() */
699 	if (palette_init())
700 		goto cant_init_palette;
701 
702 	/* force the first update to be full */
703 	set_vh_global_attribute(NULL, 0);
704 
705 	/* reset video statics and get out of here */
706 	pdrawgfx_shadow_lowpri = 0;
707 	leds_status = 0;
708 
709 	return 0;
710 
711 cant_init_palette:
712 
713 #ifdef MAME_DEBUG
714 cant_build_debugger_font:
715 cant_create_debug_bitmap:
716 #endif
717 
718 cant_build_uifont:
719 cant_init_buffered_spriteram:
720 cant_create_scrbitmap:
721 cant_create_display:
722 cant_decode_graphics:
723 cant_start_palette:
724 	vh_close();
725 	return 1;
726 }
727 
728 
729 
730 /*-------------------------------------------------
731 	vh_close - close down the video system
732 -------------------------------------------------*/
733 
vh_close(void)734 static void vh_close(void)
735 {
736 	int i;
737 
738 	/* free all the graphics elements */
739 	for (i = 0; i < MAX_GFX_ELEMENTS; i++)
740 	{
741 		freegfx(Machine->gfx[i]);
742 		Machine->gfx[i] = 0;
743 	}
744 
745 	/* free the font elements */
746 	if (Machine->uifont)
747 	{
748 		freegfx(Machine->uifont);
749 		Machine->uifont = NULL;
750 	}
751 	if (Machine->debugger_font)
752 	{
753 		freegfx(Machine->debugger_font);
754 		Machine->debugger_font = NULL;
755 	}
756 
757 	/* close down the OSD layer's display */
758 	osd_close_display();
759 }
760 
761 
762 
763 /*-------------------------------------------------
764 	compute_aspect_ratio - determine the aspect
765 	ratio encoded in the video attributes
766 -------------------------------------------------*/
767 
compute_aspect_ratio(const struct InternalMachineDriver * drv,int * aspect_x,int * aspect_y)768 static void compute_aspect_ratio(const struct InternalMachineDriver *drv, int *aspect_x, int *aspect_y)
769 {
770 	/* if it's explicitly specified, use it */
771 	if (drv->aspect_x && drv->aspect_y)
772 	{
773 		*aspect_x = drv->aspect_x;
774 		*aspect_y = drv->aspect_y;
775 	}
776 
777 	/* otherwise, attempt to deduce the result */
778 	else if (!(drv->video_attributes & VIDEO_DUAL_MONITOR))
779 	{
780 		*aspect_x = 4;
781 		*aspect_y = (drv->video_attributes & VIDEO_DUAL_MONITOR) ? 6 : 3;
782 	}
783 }
784 
785 
786 
787 /*-------------------------------------------------
788 	init_game_options - initialize the various
789 	game options
790 -------------------------------------------------*/
791 
init_game_options(void)792 static void init_game_options(void)
793 {
794   /* copy some settings into easier-to-handle variables */
795   record	   = options.record;
796   playback   = options.playback;
797   mame_debug = options.mame_debug;
798 
799   /* determine the color depth */
800   Machine->color_depth = 16;
801   alpha_active = 0;
802   if (Machine->drv->video_attributes & VIDEO_RGB_DIRECT)
803   {
804     /* first pick a default */
805     if (Machine->drv->video_attributes & VIDEO_NEEDS_6BITS_PER_GUN)
806       Machine->color_depth = 32;
807     else
808       Machine->color_depth = 15;
809 
810     /* use 32-bit color output as default to skip color conversions */
811 	if (Machine->drv->video_attributes & VIDEO_TYPE_VECTOR) 	Machine->color_depth = 32;
812 
813     /* now allow overrides */
814     if (options.color_depth == 15 || options.color_depth == 32)
815       Machine->color_depth = options.color_depth;
816 
817     /* enable alpha for direct video modes */
818     alpha_active = 1;
819     alpha_init();
820   }
821 
822   /* update the vector width/height with libretro settings or use the default */
823   if (options.vector_width  == 0) options.vector_width  = Machine->drv->screen_width;
824   if (options.vector_height == 0) options.vector_height = Machine->drv->screen_height;
825 
826 
827 
828   /* get orientation right */
829   Machine->orientation    = ROT0;
830   Machine->ui_orientation = options.ui_orientation;
831 
832 
833 // set sample rate here as osd_start_audio_stream the logic must be the same in both some soundcores require setting here as well
834 // ie ymf271 will segfault without this.
835  if (options.machine_timing)
836   {
837     if ( ( Machine->drv->frames_per_second * 1000 < options.samplerate) || (Machine->drv->frames_per_second < 60) )
838       Machine->sample_rate = Machine->drv->frames_per_second * 1000;
839 
840     else Machine->sample_rate = options.samplerate;
841   }
842 
843   else
844   {
845     if ( Machine->drv->frames_per_second * 1000 < options.samplerate)
846       Machine->sample_rate=22050;
847 
848     else
849       Machine->sample_rate = options.samplerate;
850   }
851 
852 }
853 
854 
855 
856 /*-------------------------------------------------
857 	decode_graphics - decode the graphics
858 -------------------------------------------------*/
859 
decode_graphics(const struct GfxDecodeInfo * gfxdecodeinfo)860 static int decode_graphics(const struct GfxDecodeInfo *gfxdecodeinfo)
861 {
862 	int i;
863 
864 	/* loop over all elements */
865 	for (i = 0; i < MAX_GFX_ELEMENTS && gfxdecodeinfo[i].memory_region != -1; i++)
866 	{
867 		int region_length = 8 * memory_region_length(gfxdecodeinfo[i].memory_region);
868 		UINT8 *region_base = memory_region(gfxdecodeinfo[i].memory_region);
869 		struct GfxLayout glcopy;
870 		int j;
871 
872 		/* make a copy of the layout */
873 		glcopy = *gfxdecodeinfo[i].gfxlayout;
874 
875 		/* if the character count is a region fraction, compute the effective total */
876 		if (IS_FRAC(glcopy.total))
877 			glcopy.total = region_length / glcopy.charincrement * FRAC_NUM(glcopy.total) / FRAC_DEN(glcopy.total);
878 
879 		/* loop over all the planes, converting fractions */
880 		for (j = 0; j < MAX_GFX_PLANES; j++)
881 		{
882 			int value = glcopy.planeoffset[j];
883 			if (IS_FRAC(value))
884 				glcopy.planeoffset[j] = FRAC_OFFSET(value) + region_length * FRAC_NUM(value) / FRAC_DEN(value);
885 		}
886 
887 		/* loop over all the X/Y offsets, converting fractions */
888 		for (j = 0; j < MAX_GFX_SIZE; j++)
889 		{
890 			int value = glcopy.xoffset[j];
891 			if (IS_FRAC(value))
892 				glcopy.xoffset[j] = FRAC_OFFSET(value) + region_length * FRAC_NUM(value) / FRAC_DEN(value);
893 
894 			value = glcopy.yoffset[j];
895 			if (IS_FRAC(value))
896 				glcopy.yoffset[j] = FRAC_OFFSET(value) + region_length * FRAC_NUM(value) / FRAC_DEN(value);
897 		}
898 
899 		/* some games increment on partial tile boundaries; to handle this without reading */
900 		/* past the end of the region, we may need to truncate the count */
901 		/* an example is the games in metro.c */
902 		if (glcopy.planeoffset[0] == GFX_RAW)
903 		{
904 			int base = gfxdecodeinfo[i].start;
905 			int end = region_length/8;
906 			while (glcopy.total > 0)
907 			{
908 				int elementbase = base + (glcopy.total - 1) * glcopy.charincrement / 8;
909 				int lastpixelbase = elementbase + glcopy.height * glcopy.yoffset[0] / 8 - 1;
910 				if (lastpixelbase < end)
911 					break;
912 				glcopy.total--;
913 			}
914 		}
915 
916 		/* now decode the actual graphics */
917 		if ((Machine->gfx[i] = decodegfx(region_base + gfxdecodeinfo[i].start, &glcopy)) == 0)
918 		{
919 			bailing = 1;
920 			log_cb(RETRO_LOG_ERROR, LOGPRE "Out of memory decoding gfx\n");
921 			return 1;
922 		}
923 
924 		/* if we have a remapped colortable, point our local colortable to it */
925 		if (Machine->remapped_colortable)
926 			Machine->gfx[i]->colortable = &Machine->remapped_colortable[gfxdecodeinfo[i].color_codes_start];
927 		Machine->gfx[i]->total_colors = gfxdecodeinfo[i].total_color_codes;
928 	}
929 	return 0;
930 }
931 
932 
933 
934 /*-------------------------------------------------
935 	scale_vectorgames - scale the vector games
936 	to a given resolution
937 -------------------------------------------------*/
938 
scale_vectorgames(int gfx_width,int gfx_height,int * width,int * height)939 static void scale_vectorgames(int gfx_width, int gfx_height, int *width, int *height)
940 {
941 	double x_scale, y_scale, scale;
942 
943 	/* compute the scale values */
944 	x_scale = (double)gfx_width / (double)(*width);
945 	y_scale = (double)gfx_height / (double)(*height);
946 
947 	/* pick the smaller scale factor */
948 	scale = (x_scale < y_scale) ? x_scale : y_scale;
949 
950 	/* compute the new size */
951 	*width = (int)((double)*width * scale);
952 	*height = (int)((double)*height * scale);
953 
954 	/* round to the nearest 4 pixel value */
955 
956 }
957 
958 
959 
960 /*-------------------------------------------------
961 	init_buffered_spriteram - initialize the
962 	double-buffered spriteram
963 -------------------------------------------------*/
964 
init_buffered_spriteram(void)965 static int init_buffered_spriteram(void)
966 {
967 	/* make sure we have a valid size */
968 	if (spriteram_size == 0)
969 	{
970 		log_cb(RETRO_LOG_ERROR, LOGPRE "vh_open():  Video buffers spriteram but spriteram_size is 0\n");
971 		return 0;
972 	}
973 
974 	/* allocate memory for the back buffer */
975 	buffered_spriteram = auto_malloc(spriteram_size);
976 	if (!buffered_spriteram)
977 		return 1;
978 
979 	/* register for saving it */
980 	state_save_register_UINT8("generic_video", 0, "buffered_spriteram", buffered_spriteram, spriteram_size);
981 
982 	/* do the same for the secon back buffer, if present */
983 	if (spriteram_2_size)
984 	{
985 		/* allocate memory */
986 		buffered_spriteram_2 = auto_malloc(spriteram_2_size);
987 		if (!buffered_spriteram_2)
988 			return 1;
989 
990 		/* register for saving it */
991 		state_save_register_UINT8("generic_video", 0, "buffered_spriteram_2", buffered_spriteram_2, spriteram_2_size);
992 	}
993 
994 	/* make 16-bit and 32-bit pointer variants */
995 	buffered_spriteram16 = (data16_t *)buffered_spriteram;
996 	buffered_spriteram32 = (data32_t *)buffered_spriteram;
997 	buffered_spriteram16_2 = (data16_t *)buffered_spriteram_2;
998 	buffered_spriteram32_2 = (data32_t *)buffered_spriteram_2;
999 	return 0;
1000 }
1001 
1002 
1003 
1004 /***************************************************************************
1005 
1006 	Screen rendering and management.
1007 
1008 ***************************************************************************/
1009 
1010 /*-------------------------------------------------
1011 	set_visible_area - adjusts the visible portion
1012 	of the bitmap area dynamically
1013 -------------------------------------------------*/
1014 
set_visible_area(int min_x,int max_x,int min_y,int max_y)1015 void set_visible_area(int min_x, int max_x, int min_y, int max_y)
1016 {
1017 	if (       Machine->visible_area.min_x == min_x
1018 			&& Machine->visible_area.max_x == max_x
1019 			&& Machine->visible_area.min_y == min_y
1020 			&& Machine->visible_area.max_y == max_y)
1021 		return;
1022 
1023 	/* "dirty" the area for the next display update */
1024 	visible_area_changed = 1;
1025 
1026 	/* set the new values in the Machine struct */
1027 	Machine->visible_area.min_x = min_x;
1028 	Machine->visible_area.max_x = max_x;
1029 	Machine->visible_area.min_y = min_y;
1030 	Machine->visible_area.max_y = max_y;
1031 
1032 	/* vector games always use the whole bitmap */
1033 	if (Machine->drv->video_attributes & VIDEO_TYPE_VECTOR)
1034 	{
1035 		Machine->absolute_visible_area.min_x = 0;
1036 		Machine->absolute_visible_area.max_x = Machine->scrbitmap->width - 1;
1037 		Machine->absolute_visible_area.min_y = 0;
1038 		Machine->absolute_visible_area.max_y = Machine->scrbitmap->height - 1;
1039 	}
1040 
1041 	/* raster games need to use the visible area */
1042 	else
1043 		Machine->absolute_visible_area = Machine->visible_area;
1044 
1045 	/* recompute scanline timing */
1046 	cpu_compute_scanline_timing();
1047 }
1048 
1049 
1050 
1051 /*-------------------------------------------------
1052 	schedule_full_refresh - force a full erase
1053 	and refresh the next frame
1054 -------------------------------------------------*/
1055 
schedule_full_refresh(void)1056 void schedule_full_refresh(void)
1057 {
1058 	full_refresh_pending = 1;
1059 }
1060 
1061 
1062 
1063 /*-------------------------------------------------
1064 	reset_partial_updates - reset the partial
1065 	updating mechanism for a new frame
1066 -------------------------------------------------*/
1067 
reset_partial_updates(void)1068 void reset_partial_updates(void)
1069 {
1070 	last_partial_scanline = 0;
1071 	performance.partial_updates_this_frame = 0;
1072 }
1073 
1074 
1075 
1076 /*-------------------------------------------------
1077 	force_partial_update - perform a partial
1078 	update from the last scanline up to and
1079 	including the specified scanline
1080 -------------------------------------------------*/
1081 
force_partial_update(int scanline)1082 void force_partial_update(int scanline)
1083 {
1084 	struct rectangle clip = Machine->visible_area;
1085 
1086 	/* if skipping this frame, bail */
1087 	if (osd_skip_this_frame())
1088 		return;
1089 
1090 	/* skip if less than the lowest so far */
1091 	if (scanline < last_partial_scanline)
1092 		return;
1093 
1094 	/* if there's a dirty bitmap and we didn't do any partial updates yet, handle it now */
1095 	if (full_refresh_pending && last_partial_scanline == 0)
1096 	{
1097 		fillbitmap(Machine->scrbitmap, get_black_pen(), NULL);
1098 		full_refresh_pending = 0;
1099 	}
1100 
1101 	/* set the start/end scanlines */
1102 	if (last_partial_scanline > clip.min_y)
1103 		clip.min_y = last_partial_scanline;
1104 	if (scanline < clip.max_y)
1105 		clip.max_y = scanline;
1106 
1107 	/* render if necessary */
1108 	if (clip.min_y <= clip.max_y)
1109 	{
1110 		profiler_mark(PROFILER_VIDEO);
1111 		(*Machine->drv->video_update)(Machine->scrbitmap, &clip);
1112 		performance.partial_updates_this_frame++;
1113 		profiler_mark(PROFILER_END);
1114 	}
1115 
1116 	/* remember where we left off */
1117 	last_partial_scanline = scanline + 1;
1118 }
1119 
1120 
1121 
1122 /*-------------------------------------------------
1123 	draw_screen - render the final screen bitmap
1124 	and update any artwork
1125 -------------------------------------------------*/
1126 int gbPriorityBitmapIsDirty;
1127 
draw_screen(void)1128 void draw_screen(void)
1129 {
1130 	/* finish updating the screen */
1131 	force_partial_update(Machine->visible_area.max_y);
1132 	if( gbPriorityBitmapIsDirty )
1133 	{
1134 		fillbitmap( priority_bitmap, 0x00, NULL );
1135 		gbPriorityBitmapIsDirty = 0;
1136 	}
1137 }
1138 
1139 
1140 /*-------------------------------------------------
1141 	update_video_and_audio - actually call the
1142 	OSD layer to perform an update
1143 -------------------------------------------------*/
1144 
update_video_and_audio(void)1145 void update_video_and_audio(void)
1146 {
1147 	int skipped_it = osd_skip_this_frame();
1148 
1149 #ifdef MAME_DEBUG
1150 	debug_trace_delay = 0;
1151 #endif
1152 
1153 	/* fill in our portion of the display */
1154 	current_display.changed_flags = 0;
1155 
1156 	/* set the main game bitmap */
1157 	current_display.game_bitmap = Machine->scrbitmap;
1158 	current_display.game_bitmap_update = Machine->absolute_visible_area;
1159 	if (!skipped_it)
1160 		current_display.changed_flags |= GAME_BITMAP_CHANGED;
1161 
1162 	/* set the visible area */
1163 	current_display.game_visible_area = Machine->absolute_visible_area;
1164 	if (visible_area_changed)
1165 		current_display.changed_flags |= GAME_VISIBLE_AREA_CHANGED;
1166 
1167 	/* set the vector dirty list */
1168 	if (Machine->drv->video_attributes & VIDEO_TYPE_VECTOR)
1169 		if (!full_refresh_pending && !ui_dirty && !skipped_it)
1170 		{
1171 			current_display.vector_dirty_pixels = vector_dirty_list;
1172 			current_display.changed_flags |= VECTOR_PIXELS_CHANGED;
1173 		}
1174 
1175 #ifdef MAME_DEBUG
1176 	/* set the debugger bitmap */
1177 	current_display.debug_bitmap = Machine->debug_bitmap;
1178 	if (debugger_bitmap_changed)
1179 		current_display.changed_flags |= DEBUG_BITMAP_CHANGED;
1180 	debugger_bitmap_changed = 0;
1181 
1182 	/* adjust the debugger focus */
1183 	if (debugger_focus != current_display.debug_focus)
1184 	{
1185 		current_display.debug_focus = debugger_focus;
1186 		current_display.changed_flags |= DEBUG_FOCUS_CHANGED;
1187 	}
1188 #endif
1189 
1190 	/* set the LED status */
1191 	if (leds_status != current_display.led_state)
1192 	{
1193 		current_display.led_state = leds_status;
1194 		current_display.changed_flags |= LED_STATE_CHANGED;
1195 	}
1196 
1197 	/* update with data from other parts of the system */
1198 	palette_update_display(&current_display);
1199 
1200 	/* render */
1201 	artwork_update_video_and_audio(&current_display);
1202 
1203 	/* reset dirty flags */
1204 	visible_area_changed = 0;
1205 	if (ui_dirty) ui_dirty--;
1206 }
1207 
1208 
1209 
1210 /*-------------------------------------------------
1211 	updatescreen - handle frameskipping and UI,
1212 	plus updating the screen during normal
1213 	operations
1214 -------------------------------------------------*/
1215 
updatescreen(void)1216 int updatescreen(void)
1217 {
1218 	/* update sound */
1219 	sound_update();
1220 
1221 	/* if we're not skipping this frame, draw the screen */
1222 	if (osd_skip_this_frame() == 0)
1223 	{
1224 		profiler_mark(PROFILER_VIDEO);
1225 		draw_screen();
1226 		profiler_mark(PROFILER_END);
1227 	}
1228 
1229 	/* the user interface must be called between vh_update() and osd_update_video_and_audio(), */
1230 	/* to allow it to overlay things on the game display. We must call it even */
1231 	/* if the frame is skipped, to keep a consistent timing. */
1232 	if (handle_user_interface(artwork_get_ui_bitmap()))
1233 		/* quit if the user asked to */
1234 		return 1;
1235 
1236 	/* blit to the screen */
1237 	update_video_and_audio();
1238 
1239 	/* call the end-of-frame callback */
1240 	if (Machine->drv->video_eof)
1241 	{
1242 		profiler_mark(PROFILER_VIDEO);
1243 		(*Machine->drv->video_eof)();
1244 		profiler_mark(PROFILER_END);
1245 	}
1246 
1247 	return 0;
1248 }
1249 
1250 
1251 
1252 /*-------------------------------------------------
1253 	set_led_status - set the state of a given LED
1254 -------------------------------------------------*/
1255 
set_led_status(int num,int on)1256 void set_led_status(int num, int on)
1257 {
1258 	if (on)
1259 		leds_status |=	(1 << num);
1260 	else
1261 		leds_status &= ~(1 << num);
1262 }
1263 
1264 
1265 
1266 /*-------------------------------------------------
1267 	mame_get_performance_info - return performance
1268 	info
1269 -------------------------------------------------*/
1270 
mame_get_performance_info(void)1271 const struct performance_info *mame_get_performance_info(void)
1272 {
1273 	return &performance;
1274 }
1275 
1276 
1277 
1278 /*-------------------------------------------------
1279 	mame_find_cpu_index - return the index of the
1280 	given CPU, or -1 if not found
1281 -------------------------------------------------*/
1282 
mame_find_cpu_index(const char * tag)1283 int mame_find_cpu_index(const char *tag)
1284 {
1285 	int cpunum;
1286 
1287 	for (cpunum = 0; cpunum < MAX_CPU; cpunum++)
1288 		if (Machine->drv->cpu[cpunum].tag && strcmp(Machine->drv->cpu[cpunum].tag, tag) == 0)
1289 			return cpunum;
1290 
1291 	return -1;
1292 }
1293 
1294 
1295 
1296 /*-------------------------------------------------
1297 	machine_add_cpu - add a CPU during machine
1298 	driver expansion
1299 -------------------------------------------------*/
1300 
machine_add_cpu(struct InternalMachineDriver * machine,const char * tag,int type,int cpuclock)1301 struct MachineCPU *machine_add_cpu(struct InternalMachineDriver *machine, const char *tag, int type, int cpuclock)
1302 {
1303 	int cpunum;
1304 
1305 	for (cpunum = 0; cpunum < MAX_CPU; cpunum++)
1306 		if (machine->cpu[cpunum].cpu_type == 0)
1307 		{
1308 			machine->cpu[cpunum].tag = tag;
1309 			machine->cpu[cpunum].cpu_type = type;
1310 			machine->cpu[cpunum].cpu_clock = cpuclock;
1311 			return &machine->cpu[cpunum];
1312 		}
1313 
1314 	log_cb(RETRO_LOG_ERROR, LOGPRE "Out of CPU's!\n");
1315 	return NULL;
1316 }
1317 
1318 
1319 
1320 /*-------------------------------------------------
1321 	machine_find_cpu - find a tagged CPU during
1322 	machine driver expansion
1323 -------------------------------------------------*/
1324 
machine_find_cpu(struct InternalMachineDriver * machine,const char * tag)1325 struct MachineCPU *machine_find_cpu(struct InternalMachineDriver *machine, const char *tag)
1326 {
1327 	int cpunum;
1328 
1329 	for (cpunum = 0; cpunum < MAX_CPU; cpunum++)
1330 		if (machine->cpu[cpunum].tag && strcmp(machine->cpu[cpunum].tag, tag) == 0)
1331 			return &machine->cpu[cpunum];
1332 
1333 	log_cb(RETRO_LOG_ERROR, LOGPRE "Can't find CPU '%s'!\n", tag);
1334 	return NULL;
1335 }
1336 
1337 
1338 
1339 /*-------------------------------------------------
1340 	machine_remove_cpu - remove a tagged CPU
1341 	during machine driver expansion
1342 -------------------------------------------------*/
1343 
machine_remove_cpu(struct InternalMachineDriver * machine,const char * tag)1344 void machine_remove_cpu(struct InternalMachineDriver *machine, const char *tag)
1345 {
1346 	int cpunum;
1347 
1348 	for (cpunum = 0; cpunum < MAX_CPU; cpunum++)
1349 		if (machine->cpu[cpunum].tag && strcmp(machine->cpu[cpunum].tag, tag) == 0)
1350 		{
1351 			memmove(&machine->cpu[cpunum], &machine->cpu[cpunum + 1], sizeof(machine->cpu[0]) * (MAX_CPU - cpunum - 1));
1352 			memset(&machine->cpu[MAX_CPU - 1], 0, sizeof(machine->cpu[0]));
1353 			return;
1354 		}
1355 
1356 	log_cb(RETRO_LOG_ERROR, LOGPRE "Can't find CPU '%s'!\n", tag);
1357 }
1358 
1359 
1360 
1361 /*-------------------------------------------------
1362 	machine_add_sound - add a sound system during
1363 	machine driver expansion
1364 -------------------------------------------------*/
1365 
machine_add_sound(struct InternalMachineDriver * machine,const char * tag,int type,void * sndintf)1366 struct MachineSound *machine_add_sound(struct InternalMachineDriver *machine, const char *tag, int type, void *sndintf)
1367 {
1368 	int soundnum;
1369 
1370 	for (soundnum = 0; soundnum < MAX_SOUND; soundnum++)
1371 		if (machine->sound[soundnum].sound_type == 0)
1372 		{
1373 			machine->sound[soundnum].tag = tag;
1374 			machine->sound[soundnum].sound_type = type;
1375 			machine->sound[soundnum].sound_interface = sndintf;
1376 			return &machine->sound[soundnum];
1377 		}
1378 
1379 	log_cb(RETRO_LOG_ERROR, LOGPRE "Out of sounds!\n");
1380 	return NULL;
1381 
1382 }
1383 
1384 
1385 
1386 /*-------------------------------------------------
1387 	machine_find_sound - find a tagged sound
1388 	system during machine driver expansion
1389 -------------------------------------------------*/
1390 
machine_find_sound(struct InternalMachineDriver * machine,const char * tag)1391 struct MachineSound *machine_find_sound(struct InternalMachineDriver *machine, const char *tag)
1392 {
1393 	int soundnum;
1394 
1395 	for (soundnum = 0; soundnum < MAX_SOUND; soundnum++)
1396 		if (machine->sound[soundnum].tag && strcmp(machine->sound[soundnum].tag, tag) == 0)
1397 			return &machine->sound[soundnum];
1398 
1399 	log_cb(RETRO_LOG_ERROR, LOGPRE "Can't find sound '%s'!\n", tag);
1400 	return NULL;
1401 }
1402 
1403 
1404 
1405 /*-------------------------------------------------
1406 	machine_remove_sound - remove a tagged sound
1407 	system during machine driver expansion
1408 -------------------------------------------------*/
1409 
machine_remove_sound(struct InternalMachineDriver * machine,const char * tag)1410 void machine_remove_sound(struct InternalMachineDriver *machine, const char *tag)
1411 {
1412 	int soundnum;
1413 
1414 	for (soundnum = 0; soundnum < MAX_SOUND; soundnum++)
1415 		if (machine->sound[soundnum].tag && strcmp(machine->sound[soundnum].tag, tag) == 0)
1416 		{
1417 			memmove(&machine->sound[soundnum], &machine->sound[soundnum + 1], sizeof(machine->sound[0]) * (MAX_SOUND - soundnum - 1));
1418 			memset(&machine->sound[MAX_SOUND - 1], 0, sizeof(machine->sound[0]));
1419 			return;
1420 		}
1421 
1422 	log_cb(RETRO_LOG_ERROR, LOGPRE "Can't find sound '%s'!\n", tag);
1423 }
1424 
1425 
1426 
1427 /*-------------------------------------------------
1428 	mame_chd_open - interface for opening
1429 	a hard disk image
1430 -------------------------------------------------*/
1431 
mame_chd_open(const char * filename,const char * mode)1432 struct chd_interface_file *mame_chd_open(const char *filename, const char *mode)
1433 {
1434 	/* look for read-only drives first in the ROM path */
1435 	if (mode[0] == 'r' && !strchr(mode, '+'))
1436 	{
1437 		const struct GameDriver *drv;
1438 
1439 		/* attempt reading up the chain through the parents */
1440 		for (drv = Machine->gamedrv; drv != NULL; drv = drv->clone_of)
1441 		{
1442 			void* file = mame_fopen(drv->name, filename, FILETYPE_IMAGE, 0);
1443 
1444 			if (file != NULL)
1445 				return file;
1446 		}
1447 
1448 		return NULL;
1449 	}
1450 
1451 	/* look for read/write drives in the diff area */
1452 	return (struct chd_interface_file *)mame_fopen(NULL, filename, FILETYPE_IMAGE_DIFF, 1);
1453 }
1454 
1455 
1456 
1457 /*-------------------------------------------------
1458 	mame_chd_close - interface for closing
1459 	a hard disk image
1460 -------------------------------------------------*/
1461 
mame_chd_close(struct chd_interface_file * file)1462 void mame_chd_close(struct chd_interface_file *file)
1463 {
1464 	mame_fclose((mame_file *)file);
1465 }
1466 
1467 
1468 
1469 /*-------------------------------------------------
1470 	mame_chd_read - interface for reading
1471 	from a hard disk image
1472 -------------------------------------------------*/
1473 
mame_chd_read(struct chd_interface_file * file,UINT64 offset,UINT32 count,void * buffer)1474 UINT32 mame_chd_read(struct chd_interface_file *file, UINT64 offset, UINT32 count, void *buffer)
1475 {
1476 	mame_fseek((mame_file *)file, offset, SEEK_SET);
1477 	return mame_fread((mame_file *)file, buffer, count);
1478 }
1479 
1480 
1481 
1482 /*-------------------------------------------------
1483 	mame_chd_write - interface for writing
1484 	to a hard disk image
1485 -------------------------------------------------*/
1486 
mame_chd_write(struct chd_interface_file * file,UINT64 offset,UINT32 count,const void * buffer)1487 UINT32 mame_chd_write(struct chd_interface_file *file, UINT64 offset, UINT32 count, const void *buffer)
1488 {
1489 	mame_fseek((mame_file *)file, offset, SEEK_SET);
1490 	return mame_fwrite((mame_file *)file, buffer, count);
1491 }
1492 
1493 
1494 /*-------------------------------------------------
1495 	mame_chd_length - interface for getting
1496 	the length a hard disk image
1497 -------------------------------------------------*/
1498 
mame_chd_length(struct chd_interface_file * file)1499 UINT64 mame_chd_length(struct chd_interface_file *file)
1500 {
1501 	return mame_fsize((mame_file *)file);
1502 }
1503 
1504 
1505 
1506 /***************************************************************************
1507 
1508 	Huge bunch of validity checks for the debug build
1509 
1510 ***************************************************************************/
1511 
1512 #ifdef MAME_DEBUG
1513 
validitychecks(void)1514 static int validitychecks(void)
1515 {
1516 	int i,j,cpu;
1517 	UINT8 a,b;
1518 	int error = 0;
1519 
1520 
1521 	a = 0xff;
1522 	b = a + 1;
1523 	if (b > a)	{ log_cb(RETRO_LOG_ERROR, LOGPRE "UINT8 must be 8 bits\n"); error = 1; }
1524 
1525 	if (sizeof(INT8)   != 1)	{ log_cb(RETRO_LOG_ERROR, LOGPRE "INT8 must be 8 bits\n"); error = 1; }
1526 	if (sizeof(UINT8)  != 1)	{ log_cb(RETRO_LOG_ERROR, LOGPRE "UINT8 must be 8 bits\n"); error = 1; }
1527 	if (sizeof(INT16)  != 2)	{ log_cb(RETRO_LOG_ERROR, LOGPRE "INT16 must be 16 bits\n"); error = 1; }
1528 	if (sizeof(UINT16) != 2)	{ log_cb(RETRO_LOG_ERROR, LOGPRE "UINT16 must be 16 bits\n"); error = 1; }
1529 	if (sizeof(INT32)  != 4)	{ log_cb(RETRO_LOG_ERROR, LOGPRE "INT32 must be 32 bits\n"); error = 1; }
1530 	if (sizeof(UINT32) != 4)	{ log_cb(RETRO_LOG_ERROR, LOGPRE "UINT32 must be 32 bits\n"); error = 1; }
1531 	if (sizeof(INT64)  != 8)	{ log_cb(RETRO_LOG_ERROR, LOGPRE "INT64 must be 64 bits\n"); error = 1; }
1532 	if (sizeof(UINT64) != 8)	{ log_cb(RETRO_LOG_ERROR, LOGPRE "UINT64 must be 64 bits\n"); error = 1; }
1533 
1534 	for (i = 0;drivers[i];i++)
1535 	{
1536 		struct InternalMachineDriver drv;
1537 		const struct RomModule *romp;
1538 		const struct InputPortTiny *inp;
1539 
1540 		expand_machine_driver(drivers[i]->drv, &drv);
1541 
1542 		if (drivers[i]->clone_of == drivers[i])
1543 		{
1544 			log_cb(RETRO_LOG_ERROR, LOGPRE "%s: %s is set as a clone of itself\n",drivers[i]->source_file,drivers[i]->name);
1545 			error = 1;
1546 		}
1547 
1548 		if (drivers[i]->clone_of && drivers[i]->clone_of->clone_of)
1549 		{
1550 			if ((drivers[i]->clone_of->clone_of->flags & NOT_A_DRIVER) == 0)
1551 			{
1552 				log_cb(RETRO_LOG_ERROR, LOGPRE "%s: %s is a clone of a clone\n",drivers[i]->source_file,drivers[i]->name);
1553 				error = 1;
1554 			}
1555 		}
1556 
1557 #if 0
1558 /*		if (drivers[i]->drv->color_table_len == drivers[i]->drv->total_colors && */
1559 		if (drivers[i]->drv->color_table_len && drivers[i]->drv->total_colors &&
1560 				drivers[i]->drv->vh_init_palette == 0)
1561 		{
1562 			log_cb(RETRO_LOG_ERROR, LOGPRE "%s: %s could use color_table_len = 0\n",drivers[i]->source_file,drivers[i]->name);
1563 			error = 1;
1564 		}
1565 #endif
1566 
1567 		for (j = i+1;drivers[j];j++)
1568 		{
1569 			if (!strcmp(drivers[i]->name,drivers[j]->name))
1570 			{
1571 				log_cb(RETRO_LOG_ERROR, LOGPRE "%s: %s is a duplicate name (%s, %s)\n",drivers[i]->source_file,drivers[i]->name,drivers[i]->source_file,drivers[j]->source_file);
1572 				error = 1;
1573 			}
1574 			if (!strcmp(drivers[i]->description,drivers[j]->description))
1575 			{
1576 				log_cb(RETRO_LOG_ERROR, LOGPRE "%s: %s is a duplicate description (%s, %s)\n",drivers[i]->description,drivers[i]->source_file,drivers[i]->name,drivers[j]->name);
1577 				error = 1;
1578 			}
1579 			if (drivers[i]->rom && drivers[i]->rom == drivers[j]->rom
1580 					&& (drivers[i]->flags & NOT_A_DRIVER) == 0
1581 					&& (drivers[j]->flags & NOT_A_DRIVER) == 0)
1582 			{
1583 				log_cb(RETRO_LOG_ERROR, LOGPRE "%s: %s and %s use the same ROM set\n",drivers[i]->source_file,drivers[i]->name,drivers[j]->name);
1584 				error = 1;
1585 			}
1586 		}
1587 
1588 		if ((drivers[i]->flags & NOT_A_DRIVER) == 0)
1589 		{
1590 			if (drv.sound[0].sound_type == 0 && (drivers[i]->flags & GAME_NO_SOUND) == 0 &&
1591 					strcmp(drivers[i]->name,"minivadr"))
1592 			{
1593 				log_cb(RETRO_LOG_ERROR, LOGPRE "%s: %s missing GAME_NO_SOUND flag\n",drivers[i]->source_file,drivers[i]->name);
1594 				error = 1;
1595 			}
1596 		}
1597 
1598 		romp = drivers[i]->rom;
1599 
1600 		if (romp)
1601 		{
1602 			int region_type_used[REGION_MAX];
1603 			int region_length[REGION_MAX];
1604 			const char *last_name = 0;
1605 			int count = -1;
1606 
1607 			for (j = 0;j < REGION_MAX;j++)
1608 			{
1609 				region_type_used[j] = 0;
1610 				region_length[j] = 0;
1611 			}
1612 
1613 			while (!ROMENTRY_ISEND(romp))
1614 			{
1615 				const char *c;
1616 
1617 				if (ROMENTRY_ISREGION(romp))
1618 				{
1619 					int type = ROMREGION_GETTYPE(romp);
1620 
1621 					count++;
1622 					if (type && (type >= REGION_MAX || type <= REGION_INVALID))
1623 					{
1624 						log_cb(RETRO_LOG_ERROR, LOGPRE "%s: %s has invalid ROM_REGION type %x\n",drivers[i]->source_file,drivers[i]->name,type);
1625 						error = 1;
1626 					}
1627 
1628 					region_type_used[type]++;
1629 					region_length[type] = region_length[count] = ROMREGION_GETLENGTH(romp);
1630 				}
1631 				if (ROMENTRY_ISFILE(romp))
1632 				{
1633 					const char *hash;
1634 
1635 					last_name = c = ROM_GETNAME(romp);
1636 					while (*c)
1637 					{
1638 						if (tolower(*c) != *c)
1639 						{
1640 							log_cb(RETRO_LOG_ERROR, LOGPRE "%s: %s has upper case ROM name %s\n",drivers[i]->source_file,drivers[i]->name,ROM_GETNAME(romp));
1641 							error = 1;
1642 						}
1643 						c++;
1644 					}
1645 
1646 					hash = ROM_GETHASHDATA(romp);
1647 					if (!hash_verify_string(hash))
1648 					{
1649 						log_cb(RETRO_LOG_ERROR, LOGPRE "%s: rom '%s' has an invalid hash string '%s'\n", drivers[i]->name, ROM_GETNAME(romp), hash);
1650 						error = 1;
1651 					}
1652 				}
1653 				if (!ROMENTRY_ISREGIONEND(romp))						/* ROM_LOAD_XXX() */
1654 				{
1655 					if (ROM_GETOFFSET(romp) + ROM_GETLENGTH(romp) > region_length[count])
1656 					{
1657 						log_cb(RETRO_LOG_ERROR, LOGPRE "%s: %s has ROM %s extending past the defined memory region\n",drivers[i]->source_file,drivers[i]->name,last_name);
1658 						error = 1;
1659 					}
1660 				}
1661 				romp++;
1662 			}
1663 
1664 			for (j = 1;j < REGION_MAX;j++)
1665 			{
1666 				if (region_type_used[j] > 1)
1667 				{
1668 					log_cb(RETRO_LOG_ERROR, LOGPRE "%s: %s has duplicated ROM_REGION type %x\n",drivers[i]->source_file,drivers[i]->name,j);
1669 					error = 1;
1670 				}
1671 			}
1672 
1673 
1674 			for (cpu = 0;cpu < MAX_CPU;cpu++)
1675 			{
1676 				if (drv.cpu[cpu].cpu_type)
1677 				{
1678 					int alignunit,databus_width;
1679 
1680 
1681 					alignunit = cputype_align_unit(drv.cpu[cpu].cpu_type);
1682 					databus_width = cputype_databus_width(drv.cpu[cpu].cpu_type);
1683 
1684 					if (drv.cpu[cpu].memory_read)
1685 					{
1686 						const struct Memory_ReadAddress *mra = drv.cpu[cpu].memory_read;
1687 
1688 						if (!IS_MEMPORT_MARKER(mra) || (mra->end & MEMPORT_DIRECTION_MASK) != MEMPORT_DIRECTION_READ)
1689 						{
1690 							log_cb(RETRO_LOG_ERROR, LOGPRE "%s: %s wrong MEMPORT_READ_START\n",drivers[i]->source_file,drivers[i]->name);
1691 							error = 1;
1692 						}
1693 
1694 						switch (databus_width)
1695 						{
1696 							case 8:
1697 								if ((mra->end & MEMPORT_WIDTH_MASK) != MEMPORT_WIDTH_8)
1698 								{
1699 									log_cb(RETRO_LOG_ERROR, LOGPRE "%s: %s cpu #%d uses wrong data width memory handlers! (width = %d, memory = %08x)\n",drivers[i]->source_file,drivers[i]->name,cpu,databus_width,mra->end);
1700 									error = 1;
1701 								}
1702 								break;
1703 							case 16:
1704 								if ((mra->end & MEMPORT_WIDTH_MASK) != MEMPORT_WIDTH_16)
1705 								{
1706 									log_cb(RETRO_LOG_ERROR, LOGPRE "%s: %s cpu #%d uses wrong data width memory handlers! (width = %d, memory = %08x)\n",drivers[i]->source_file,drivers[i]->name,cpu,databus_width,mra->end);
1707 									error = 1;
1708 								}
1709 								break;
1710 							case 32:
1711 								if ((mra->end & MEMPORT_WIDTH_MASK) != MEMPORT_WIDTH_32)
1712 								{
1713 									log_cb(RETRO_LOG_ERROR, LOGPRE "%s: %s cpu #%d uses wrong data width memory handlers! (width = %d, memory = %08x)\n",drivers[i]->source_file,drivers[i]->name,cpu,databus_width,mra->end);
1714 									error = 1;
1715 								}
1716 								break;
1717 						}
1718 
1719 						while (!IS_MEMPORT_END(mra))
1720 						{
1721 							if (!IS_MEMPORT_MARKER(mra))
1722 							{
1723 								if (mra->end < mra->start)
1724 								{
1725 									log_cb(RETRO_LOG_ERROR, LOGPRE "%s: %s wrong memory read handler start = %08x > end = %08x\n",drivers[i]->source_file,drivers[i]->name,mra->start,mra->end);
1726 									error = 1;
1727 								}
1728 								if ((mra->start & (alignunit-1)) != 0 || (mra->end & (alignunit-1)) != (alignunit-1))
1729 								{
1730 									log_cb(RETRO_LOG_ERROR, LOGPRE "%s: %s wrong memory read handler start = %08x, end = %08x ALIGN = %d\n",drivers[i]->source_file,drivers[i]->name,mra->start,mra->end,alignunit);
1731 									error = 1;
1732 								}
1733 							}
1734 							mra++;
1735 						}
1736 					}
1737 					if (drv.cpu[cpu].memory_write)
1738 					{
1739 						const struct Memory_WriteAddress *mwa = drv.cpu[cpu].memory_write;
1740 
1741 						if (mwa->start != MEMPORT_MARKER ||
1742 								(mwa->end & MEMPORT_DIRECTION_MASK) != MEMPORT_DIRECTION_WRITE)
1743 						{
1744 							log_cb(RETRO_LOG_ERROR, LOGPRE "%s: %s wrong MEMPORT_WRITE_START\n",drivers[i]->source_file,drivers[i]->name);
1745 							error = 1;
1746 						}
1747 
1748 						switch (databus_width)
1749 						{
1750 							case 8:
1751 								if ((mwa->end & MEMPORT_WIDTH_MASK) != MEMPORT_WIDTH_8)
1752 								{
1753 									log_cb(RETRO_LOG_ERROR, LOGPRE "%s: %s cpu #%d uses wrong data width memory handlers! (width = %d, memory = %08x)\n",drivers[i]->source_file,drivers[i]->name,cpu,databus_width,mwa->end);
1754 									error = 1;
1755 								}
1756 								break;
1757 							case 16:
1758 								if ((mwa->end & MEMPORT_WIDTH_MASK) != MEMPORT_WIDTH_16)
1759 								{
1760 									log_cb(RETRO_LOG_ERROR, LOGPRE "%s: %s cpu #%d uses wrong data width memory handlers! (width = %d, memory = %08x)\n",drivers[i]->source_file,drivers[i]->name,cpu,databus_width,mwa->end);
1761 									error = 1;
1762 								}
1763 								break;
1764 							case 32:
1765 								if ((mwa->end & MEMPORT_WIDTH_MASK) != MEMPORT_WIDTH_32)
1766 								{
1767 									log_cb(RETRO_LOG_ERROR, LOGPRE "%s: %s cpu #%d uses wrong data width memory handlers! (width = %d, memory = %08x)\n",drivers[i]->source_file,drivers[i]->name,cpu,databus_width,mwa->end);
1768 									error = 1;
1769 								}
1770 								break;
1771 						}
1772 
1773 						while (!IS_MEMPORT_END(mwa))
1774 						{
1775 							if (!IS_MEMPORT_MARKER(mwa))
1776 							{
1777 								if (mwa->end < mwa->start)
1778 								{
1779 									log_cb(RETRO_LOG_ERROR, LOGPRE "%s: %s wrong memory write handler start = %08x > end = %08x\n",drivers[i]->source_file,drivers[i]->name,mwa->start,mwa->end);
1780 									error = 1;
1781 								}
1782 								if ((mwa->start & (alignunit-1)) != 0 || (mwa->end & (alignunit-1)) != (alignunit-1))
1783 								{
1784 									log_cb(RETRO_LOG_ERROR, LOGPRE "%s: %s wrong memory write handler start = %08x, end = %08x ALIGN = %d\n",drivers[i]->source_file,drivers[i]->name,mwa->start,mwa->end,alignunit);
1785 									error = 1;
1786 								}
1787 							}
1788 							mwa++;
1789 						}
1790 					}
1791 
1792 					if (drv.cpu[cpu].port_read)
1793 					{
1794 						const struct IO_ReadPort *pra = drv.cpu[cpu].port_read;
1795 
1796 						if (!IS_MEMPORT_MARKER(pra) || (pra->end & MEMPORT_DIRECTION_MASK) != MEMPORT_DIRECTION_READ)
1797 						{
1798 							log_cb(RETRO_LOG_ERROR, LOGPRE "%s: %s wrong PORT_READ_START\n",drivers[i]->source_file,drivers[i]->name);
1799 							error = 1;
1800 						}
1801 
1802 						switch (databus_width)
1803 						{
1804 							case 8:
1805 								if ((pra->end & MEMPORT_WIDTH_MASK) != MEMPORT_WIDTH_8)
1806 								{
1807 									log_cb(RETRO_LOG_ERROR, LOGPRE "%s: %s cpu #%d uses wrong data width port handlers! (width = %d, port = %08x)\n",drivers[i]->source_file,drivers[i]->name,cpu,databus_width,pra->end);
1808 									error = 1;
1809 								}
1810 								break;
1811 							case 16:
1812 								if ((pra->end & MEMPORT_WIDTH_MASK) != MEMPORT_WIDTH_16)
1813 								{
1814 									log_cb(RETRO_LOG_ERROR, LOGPRE "%s: %s cpu #%d uses wrong data width port handlers! (width = %d, port = %08x)\n",drivers[i]->source_file,drivers[i]->name,cpu,databus_width,pra->end);
1815 									error = 1;
1816 								}
1817 								break;
1818 							case 32:
1819 								if ((pra->end & MEMPORT_WIDTH_MASK) != MEMPORT_WIDTH_32)
1820 								{
1821 									log_cb(RETRO_LOG_ERROR, LOGPRE "%s: %s cpu #%d uses wrong data width port handlers! (width = %d, port = %08x)\n",drivers[i]->source_file,drivers[i]->name,cpu,databus_width,pra->end);
1822 									error = 1;
1823 								}
1824 								break;
1825 						}
1826 
1827 						while (!IS_MEMPORT_END(pra))
1828 						{
1829 							if (!IS_MEMPORT_MARKER(pra))
1830 							{
1831 								if (pra->end < pra->start)
1832 								{
1833 									log_cb(RETRO_LOG_ERROR, LOGPRE "%s: %s wrong port read handler start = %08x > end = %08x\n",drivers[i]->source_file,drivers[i]->name,pra->start,pra->end);
1834 									error = 1;
1835 								}
1836 								if ((pra->start & (alignunit-1)) != 0 || (pra->end & (alignunit-1)) != (alignunit-1))
1837 								{
1838 									log_cb(RETRO_LOG_ERROR, LOGPRE "%s: %s wrong port read handler start = %08x, end = %08x ALIGN = %d\n",drivers[i]->source_file,drivers[i]->name,pra->start,pra->end,alignunit);
1839 									error = 1;
1840 								}
1841 
1842 							}
1843 							pra++;
1844 						}
1845 					}
1846 
1847 					if (drv.cpu[cpu].port_write)
1848 					{
1849 						const struct IO_WritePort *pwa = drv.cpu[cpu].port_write;
1850 
1851 						if (pwa->start != MEMPORT_MARKER ||
1852 								(pwa->end & MEMPORT_DIRECTION_MASK) != MEMPORT_DIRECTION_WRITE)
1853 						{
1854 							log_cb(RETRO_LOG_ERROR, LOGPRE "%s: %s wrong PORT_WRITE_START\n",drivers[i]->source_file,drivers[i]->name);
1855 							error = 1;
1856 						}
1857 
1858 						switch (databus_width)
1859 						{
1860 							case 8:
1861 								if ((pwa->end & MEMPORT_WIDTH_MASK) != MEMPORT_WIDTH_8)
1862 								{
1863 									log_cb(RETRO_LOG_ERROR, LOGPRE "%s: %s cpu #%d uses wrong data width port handlers! (width = %d, port = %08x)\n",drivers[i]->source_file,drivers[i]->name,cpu,databus_width,pwa->end);
1864 									error = 1;
1865 								}
1866 								break;
1867 							case 16:
1868 								if ((pwa->end & MEMPORT_WIDTH_MASK) != MEMPORT_WIDTH_16)
1869 								{
1870 									log_cb(RETRO_LOG_ERROR, LOGPRE "%s: %s cpu #%d uses wrong data width port handlers! (width = %d, port = %08x)\n",drivers[i]->source_file,drivers[i]->name,cpu,databus_width,pwa->end);
1871 									error = 1;
1872 								}
1873 								break;
1874 							case 32:
1875 								if ((pwa->end & MEMPORT_WIDTH_MASK) != MEMPORT_WIDTH_32)
1876 								{
1877 									log_cb(RETRO_LOG_ERROR, LOGPRE "%s: %s cpu #%d uses wrong data width port handlers! (width = %d, port = %08x)\n",drivers[i]->source_file,drivers[i]->name,cpu,databus_width,pwa->end);
1878 									error = 1;
1879 								}
1880 								break;
1881 						}
1882 
1883 						while (!IS_MEMPORT_END(pwa))
1884 						{
1885 							if (!IS_MEMPORT_MARKER(pwa))
1886 							{
1887 								if (pwa->end < pwa->start)
1888 								{
1889 									log_cb(RETRO_LOG_ERROR, LOGPRE "%s: %s wrong port write handler start = %08x > end = %08x\n",drivers[i]->source_file,drivers[i]->name,pwa->start,pwa->end);
1890 									error = 1;
1891 								}
1892 								if ((pwa->start & (alignunit-1)) != 0 || (pwa->end & (alignunit-1)) != (alignunit-1))
1893 								{
1894 									log_cb(RETRO_LOG_ERROR, LOGPRE "%s: %s wrong port write handler start = %08x, end = %08x ALIGN = %d\n",drivers[i]->source_file,drivers[i]->name,pwa->start,pwa->end,alignunit);
1895 									error = 1;
1896 								}
1897 
1898 							}
1899 							pwa++;
1900 						}
1901 					}
1902 
1903 				}
1904 			}
1905 
1906 
1907 			if (drv.gfxdecodeinfo)
1908 			{
1909 				for (j = 0;j < MAX_GFX_ELEMENTS && drv.gfxdecodeinfo[j].memory_region != -1;j++)
1910 				{
1911 					int len,avail,k,start;
1912 					int type = drv.gfxdecodeinfo[j].memory_region;
1913 
1914 
1915 /*
1916 					if (type && (type >= REGION_MAX || type <= REGION_INVALID))
1917 					{
1918 						log_cb(RETRO_LOG_ERROR, LOGPRE "%s: %s has invalid memory region for gfx[%d]\n",drivers[i]->source_file,drivers[i]->name,j);
1919 						error = 1;
1920 					}
1921 */
1922 
1923 					if (!IS_FRAC(drv.gfxdecodeinfo[j].gfxlayout->total))
1924 					{
1925 						start = 0;
1926 						for (k = 0;k < MAX_GFX_PLANES;k++)
1927 						{
1928 							if (drv.gfxdecodeinfo[j].gfxlayout->planeoffset[k] > start)
1929 								start = drv.gfxdecodeinfo[j].gfxlayout->planeoffset[k];
1930 						}
1931 						start &= ~(drv.gfxdecodeinfo[j].gfxlayout->charincrement-1);
1932 						len = drv.gfxdecodeinfo[j].gfxlayout->total *
1933 								drv.gfxdecodeinfo[j].gfxlayout->charincrement;
1934 						avail = region_length[type]
1935 								- (drv.gfxdecodeinfo[j].start & ~(drv.gfxdecodeinfo[j].gfxlayout->charincrement/8-1));
1936 						if ((start + len) / 8 > avail)
1937 						{
1938 							log_cb(RETRO_LOG_ERROR, LOGPRE "%s: %s has gfx[%d] extending past allocated memory\n",drivers[i]->source_file,drivers[i]->name,j);
1939 							error = 1;
1940 						}
1941 					}
1942 				}
1943 			}
1944 		}
1945 
1946 
1947 		inp = drivers[i]->input_ports;
1948 
1949 		if (inp)
1950 		{
1951 			while (inp->type != IPT_END)
1952 			{
1953 				if (inp->name && inp->name != IP_NAME_DEFAULT)
1954 				{
1955 					j = 0;
1956 
1957 					for (j = 0;j < STR_TOTAL;j++)
1958 					{
1959 						if (inp->name == ipdn_defaultstrings[j]) break;
1960 						else if (!strcasecmp(inp->name,ipdn_defaultstrings[j]))
1961 						{
1962 							log_cb(RETRO_LOG_ERROR, LOGPRE "%s: %s must use DEF_STR( %s )\n",drivers[i]->source_file,drivers[i]->name,inp->name);
1963 							error = 1;
1964 						}
1965 					}
1966 
1967 					if (inp->name == DEF_STR( On ) && (inp+1)->name == DEF_STR( Off ))
1968 					{
1969 						log_cb(RETRO_LOG_ERROR, LOGPRE "%s: %s has inverted Off/On dipswitch order\n",drivers[i]->source_file,drivers[i]->name);
1970 						error = 1;
1971 					}
1972 
1973 					if (inp->name == DEF_STR( Yes ) && (inp+1)->name == DEF_STR( No ))
1974 					{
1975 						log_cb(RETRO_LOG_ERROR, LOGPRE "%s: %s has inverted No/Yes dipswitch order\n",drivers[i]->source_file,drivers[i]->name);
1976 						error = 1;
1977 					}
1978 
1979 					if (!strcasecmp(inp->name,"table"))
1980 					{
1981 						log_cb(RETRO_LOG_ERROR, LOGPRE "%s: %s must use DEF_STR( Cocktail ), not %s\n",drivers[i]->source_file,drivers[i]->name,inp->name);
1982 						error = 1;
1983 					}
1984 
1985 					if (inp->name == DEF_STR( Cabinet ) && (inp+1)->name == DEF_STR( Upright )
1986 							&& inp->default_value != (inp+1)->default_value)
1987 					{
1988 						log_cb(RETRO_LOG_ERROR, LOGPRE "%s: %s Cabinet must default to Upright\n",drivers[i]->source_file,drivers[i]->name);
1989 						error = 1;
1990 					}
1991 
1992 					if (inp->name == DEF_STR( Cocktail ) && (inp+1)->name == DEF_STR( Upright ))
1993 					{
1994 						log_cb(RETRO_LOG_ERROR, LOGPRE "%s: %s has inverted Upright/Cocktail dipswitch order\n",drivers[i]->source_file,drivers[i]->name);
1995 						error = 1;
1996 					}
1997 
1998 					if (inp->name >= DEF_STR( 9C_1C ) && inp->name <= DEF_STR( Free_Play )
1999 							&& (inp+1)->name >= DEF_STR( 9C_1C ) && (inp+1)->name <= DEF_STR( Free_Play )
2000 							&& inp->name >= (inp+1)->name)
2001 					{
2002 						log_cb(RETRO_LOG_ERROR, LOGPRE "%s: %s has unsorted coinage %s > %s\n",drivers[i]->source_file,drivers[i]->name,inp->name,(inp+1)->name);
2003 						error = 1;
2004 					}
2005 
2006 					if (inp->name == DEF_STR( Flip_Screen ) && (inp+1)->name != DEF_STR( Off ))
2007 					{
2008 						log_cb(RETRO_LOG_ERROR, LOGPRE "%s: %s has wrong Flip Screen option %s\n",drivers[i]->source_file,drivers[i]->name,(inp+1)->name);
2009 						error = 1;
2010 					}
2011 
2012 					if (inp->name == DEF_STR( Demo_Sounds ) && (inp+2)->name == DEF_STR( On )
2013 							&& inp->default_value != (inp+2)->default_value)
2014 					{
2015 						log_cb(RETRO_LOG_ERROR, LOGPRE "%s: %s Demo Sounds must default to On\n",drivers[i]->source_file,drivers[i]->name);
2016 						error = 1;
2017 					}
2018 
2019 					if (inp->name == DEF_STR( Demo_Sounds ) && (inp+1)->name == DEF_STR( No ))
2020 					{
2021 						log_cb(RETRO_LOG_ERROR, LOGPRE "%s: %s has wrong Demo Sounds option No instead of Off\n",drivers[i]->source_file,drivers[i]->name);
2022 						error = 1;
2023 					}
2024 				}
2025 
2026 				inp++;
2027 			}
2028 		}
2029 	}
2030 
2031 	return error;
2032 }
2033 #endif
2034 
2035 void cpu_run_done(void);
mame_done(void)2036 void mame_done(void)
2037 {
2038     if(game_loaded)
2039     {
2040         cpu_run_done();
2041         run_machine_core_done();
2042         run_machine_done();
2043         run_game_done();
2044     }
2045 
2046     game_loaded = 0;
2047 }
2048