From 52ccf5ffbce1cfd5b49f365ba38089dcc4ab2e39 Mon Sep 17 00:00:00 2001 From: Aaron Giles Date: Fri, 27 Jan 2012 06:54:34 +0000 Subject: [PATCH] Fixed disk loading so that it handles full region tags. Fixes laserdisc and hard disk based games falling over. Upgraded gottlieb driver to render RGB32 to fix laserdisc overlays. Improved out-of-bounds pixel detection helper. --- src/emu/romload.c | 110 +++++++++++++++-------------------- src/emu/video.c | 17 +++--- src/emu/video.h | 2 +- src/mame/drivers/gottlieb.c | 12 ++-- src/mame/includes/gottlieb.h | 2 +- src/mame/video/gottlieb.c | 6 +- 6 files changed, 65 insertions(+), 84 deletions(-) diff --git a/src/emu/romload.c b/src/emu/romload.c index 9289d692189..efb2858ca0a 100644 --- a/src/emu/romload.c +++ b/src/emu/romload.c @@ -34,15 +34,38 @@ TYPE DEFINITIONS ***************************************************************************/ -typedef struct _open_chd open_chd; -struct _open_chd +class open_chd { - open_chd * next; /* pointer to next in the list */ - const char * region; /* disk region we came from */ - chd_file * origchd; /* handle to the original CHD */ - emu_file * origfile; /* file handle to the original CHD file */ - chd_file * diffchd; /* handle to the diff CHD */ - emu_file * difffile; /* file handle to the diff CHD file */ + friend class simple_list; + +public: + open_chd(const char *region, emu_file &file, chd_file &chdfile, emu_file *difffile = NULL, chd_file *diffchd = NULL) + : m_next(NULL), + m_region(region), + m_origchd(&chdfile), + m_origfile(&file), + m_diffchd(diffchd), + m_difffile(difffile) { } + + ~open_chd() + { + if (m_diffchd != NULL) chd_close(m_diffchd); + global_free(m_difffile); + chd_close(m_origchd); + global_free(m_origfile); + } + + open_chd *next() const { return m_next; } + const char *region() const { return m_region; } + chd_file *chd() const { return (m_diffchd != NULL) ? m_diffchd : m_origchd; } + +private: + open_chd * m_next; /* pointer to next in the list */ + astring m_region; /* disk region we came from */ + chd_file * m_origchd; /* handle to the original CHD */ + emu_file * m_origfile; /* file handle to the original CHD file */ + chd_file * m_diffchd; /* handle to the diff CHD */ + emu_file * m_difffile; /* file handle to the diff CHD file */ }; @@ -65,8 +88,7 @@ struct _romload_private UINT32 romstotalsize; /* total size of ROMs to read */ emu_file * file; /* current file */ - open_chd * chd_list; /* disks */ - open_chd ** chd_list_tailptr; + simple_list chd_list; /* disks */ memory_region * region; /* info about current region */ @@ -132,30 +154,13 @@ file_error common_process_file(emu_options &options, const char *location, bool chd_file *get_disk_handle(running_machine &machine, const char *region) { - open_chd *curdisk; - - for (curdisk = machine.romload_data->chd_list; curdisk != NULL; curdisk = curdisk->next) - if (strcmp(curdisk->region, region) == 0) - return (curdisk->diffchd != NULL) ? curdisk->diffchd : curdisk->origchd; + for (open_chd *curdisk = machine.romload_data->chd_list.first(); curdisk != NULL; curdisk = curdisk->next()) + if (strcmp(curdisk->region(), region) == 0) + return curdisk->chd(); return NULL; } -/*------------------------------------------------- - add_disk_handle - add a disk to the to the - list of CHD files --------------------------------------------------*/ - -static void add_disk_handle(running_machine &machine, open_chd *chd) -{ - romload_private *romload_data = machine.romload_data; - - *romload_data->chd_list_tailptr = auto_alloc(machine, open_chd); - **romload_data->chd_list_tailptr = *chd; - romload_data->chd_list_tailptr = &(*romload_data->chd_list_tailptr)->next; -} - - /*------------------------------------------------- set_disk_handle - set a pointer to the CHD file associated with the given region @@ -163,15 +168,7 @@ static void add_disk_handle(running_machine &machine, open_chd *chd) void set_disk_handle(running_machine &machine, const char *region, emu_file &file, chd_file &chdfile) { - open_chd chd = { 0 }; - - /* note the region we are in */ - chd.region = region; - chd.origchd = &chdfile; - chd.origfile = &file; - - /* we're okay, add to the list of disks */ - add_disk_handle(machine, &chd); + machine.romload_data->chd_list.append(*global_alloc(open_chd(region, file, chdfile))); } @@ -1224,19 +1221,17 @@ static void process_disk_entries(rom_load_data *romdata, const char *regiontag, if (ROMENTRY_ISFILE(romp)) { hash_collection hashes(ROM_GETHASHDATA(romp)); - open_chd chd = { 0 }; chd_header header; chd_error err; - /* note the region we are in */ - chd.region = regiontag; - /* make the filename of the source */ astring filename(ROM_GETNAME(romp), ".chd"); /* first open the source drive */ + chd_file *origchd; + emu_file *origfile; LOG(("Opening disk image: %s\n", filename.cstr())); - err = open_disk_image(romdata->machine().options(), &romdata->machine().system(), romp, &chd.origfile, &chd.origchd, locationtag); + err = open_disk_image(romdata->machine().options(), &romdata->machine().system(), romp, &origfile, &origchd, locationtag); if (err != CHDERR_NONE) { if (err == CHDERR_FILE_NOT_FOUND) @@ -1255,7 +1250,7 @@ static void process_disk_entries(rom_load_data *romdata, const char *regiontag, } /* get the header and extract the SHA1 */ - header = *chd_get_header(chd.origchd); + header = *chd_get_header(origchd); hash_collection acthashes; acthashes.add_from_buffer(hash_collection::HASH_SHA1, header.sha1, sizeof(header.sha1)); @@ -1273,10 +1268,12 @@ static void process_disk_entries(rom_load_data *romdata, const char *regiontag, } /* if not read-only, make the diff file */ + chd_file *diffchd = NULL; + emu_file *difffile = NULL; if (!DISK_ISREADONLY(romp)) { /* try to open or create the diff */ - err = open_disk_diff(romdata->machine().options(), romp, chd.origchd, &chd.difffile, &chd.diffchd); + err = open_disk_diff(romdata->machine().options(), romp, origchd, &difffile, &diffchd); if (err != CHDERR_NONE) { romdata->errorstring.catprintf("%s DIFF CHD ERROR: %s\n", filename.cstr(), chd_error_string(err)); @@ -1287,7 +1284,7 @@ static void process_disk_entries(rom_load_data *romdata, const char *regiontag, /* we're okay, add to the list of disks */ LOG(("Assigning to handle %d\n", DISK_GETINDEX(romp))); - add_disk_handle(romdata->machine(), &chd); + romdata->machine().romload_data->chd_list.append(*global_alloc(open_chd(regiontag, *origfile, *origchd, difffile, diffchd))); } } } @@ -1502,7 +1499,7 @@ static void process_region_list(rom_load_data *romdata) process_rom_entries(romdata, (source->shortname()!=NULL) ? source->shortname() : NULL, region, region + 1); } else if (ROMREGION_ISDISKDATA(region)) - process_disk_entries(romdata, ROMREGION_GETTAG(region), region, region + 1, NULL); + process_disk_entries(romdata, regiontag, region, region + 1, NULL); } /* now go back and post-process all the regions */ @@ -1539,8 +1536,7 @@ void rom_init(running_machine &machine) count_roms(romdata); /* reset the disk list */ - romdata->chd_list = NULL; - romdata->chd_list_tailptr = &machine.romload_data->chd_list; + romdata->chd_list.reset(); /* process the ROM entries we were passed */ process_region_list(romdata); @@ -1556,20 +1552,6 @@ void rom_init(running_machine &machine) static void rom_exit(running_machine &machine) { - open_chd *curchd; - - /* close all hard drives */ - for (curchd = machine.romload_data->chd_list; curchd != NULL; curchd = curchd->next) - { - if (curchd->diffchd != NULL) - chd_close(curchd->diffchd); - if (curchd->difffile != NULL) - global_free(curchd->difffile); - if (curchd->origchd != NULL) - chd_close(curchd->origchd); - if (curchd->origfile != NULL) - global_free(curchd->origfile); - } } diff --git a/src/emu/video.c b/src/emu/video.c index e2956bc37ad..2408f5e4109 100644 --- a/src/emu/video.c +++ b/src/emu/video.c @@ -1281,20 +1281,23 @@ void video_manager::record_frame() invalid palette index -------------------------------------------------*/ -void video_assert_out_of_range_pixels(running_machine &machine, bitmap_ind16 &bitmap) +bool video_assert_out_of_range_pixels(running_machine &machine, bitmap_ind16 &bitmap) { #ifdef MAME_DEBUG - int maxindex = palette_get_max_index(machine.palette); - int x, y; - // iterate over rows - for (y = 0; y < bitmap.height(); y++) + int maxindex = palette_get_max_index(machine.palette); + for (int y = 0; y < bitmap.height(); y++) { UINT16 *rowbase = &bitmap.pix16(y); - for (x = 0; x < bitmap.width(); x++) - assert(rowbase[x] < maxindex); + for (int x = 0; x < bitmap.width(); x++) + if (rowbase[x] > maxindex) + { + osd_break_into_debugger("Out of range pixel"); + return true; + } } #endif + return false; } diff --git a/src/emu/video.h b/src/emu/video.h index c6b629dd7d5..ba37e1d9b38 100644 --- a/src/emu/video.h +++ b/src/emu/video.h @@ -204,7 +204,7 @@ private: // ----- debugging helpers ----- // assert if any pixels in the given bitmap contain an invalid palette index -void video_assert_out_of_range_pixels(running_machine &machine, bitmap_ind16 &bitmap); +bool video_assert_out_of_range_pixels(running_machine &machine, bitmap_ind16 &bitmap); #endif /* __VIDEO_H__ */ diff --git a/src/mame/drivers/gottlieb.c b/src/mame/drivers/gottlieb.c index 64cc8ba2ab9..85f6e0740a6 100644 --- a/src/mame/drivers/gottlieb.c +++ b/src/mame/drivers/gottlieb.c @@ -1884,13 +1884,11 @@ static MACHINE_CONFIG_DERIVED( g2laser, gottlieb_core ) MCFG_LASERDISC_AUDIO(laserdisc_audio_delegate(FUNC(laserdisc_audio_process), device)) MCFG_LASERDISC_OVERLAY_STATIC(GOTTLIEB_VIDEO_HCOUNT, GOTTLIEB_VIDEO_VCOUNT, gottlieb) MCFG_LASERDISC_OVERLAY_CLIP(0, GOTTLIEB_VIDEO_HBLANK-1, 0, GOTTLIEB_VIDEO_VBLANK-8) + MCFG_SOUND_ROUTE(0, "mono", 1.0) + /* right channel is processed as data */ MCFG_DEVICE_REMOVE("screen") MCFG_LASERDISC_SCREEN_ADD_NTSC("screen", "laserdisc") - - MCFG_SOUND_MODIFY("laserdisc") - MCFG_SOUND_ROUTE(0, "mono", 1.0) - /* right channel is processed as data */ MACHINE_CONFIG_END @@ -1936,14 +1934,12 @@ static MACHINE_CONFIG_DERIVED( cobram3, gottlieb_core ) MCFG_LASERDISC_AUDIO(laserdisc_audio_delegate(FUNC(laserdisc_audio_process), device)) MCFG_LASERDISC_OVERLAY_STATIC(GOTTLIEB_VIDEO_HCOUNT, GOTTLIEB_VIDEO_VCOUNT, gottlieb) MCFG_LASERDISC_OVERLAY_CLIP(0, GOTTLIEB_VIDEO_HBLANK-1, 0, GOTTLIEB_VIDEO_VBLANK-8) + MCFG_SOUND_ROUTE(0, "mono", 1.0) + /* right channel is processed as data */ MCFG_DEVICE_REMOVE("screen") MCFG_LASERDISC_SCREEN_ADD_NTSC("screen", "laserdisc") - MCFG_SOUND_MODIFY("laserdisc") - MCFG_SOUND_ROUTE(0, "mono", 1.0) - /* right channel is processed as data */ - /* sound hardware */ MCFG_SOUND_MODIFY("dac1") MCFG_SOUND_ROUTES_RESET() diff --git a/src/mame/includes/gottlieb.h b/src/mame/includes/gottlieb.h index e955876c9dc..615a5b49571 100644 --- a/src/mame/includes/gottlieb.h +++ b/src/mame/includes/gottlieb.h @@ -86,4 +86,4 @@ extern WRITE8_HANDLER( gottlieb_paletteram_w ); VIDEO_START( gottlieb ); VIDEO_START( screwloo ); -SCREEN_UPDATE_IND16( gottlieb ); +SCREEN_UPDATE_RGB32( gottlieb ); diff --git a/src/mame/video/gottlieb.c b/src/mame/video/gottlieb.c index 97e9b7ad632..40dea50d396 100644 --- a/src/mame/video/gottlieb.c +++ b/src/mame/video/gottlieb.c @@ -211,7 +211,7 @@ VIDEO_START( screwloo ) * *************************************/ -static void draw_sprites(running_machine &machine, bitmap_ind16 &bitmap, const rectangle &cliprect) +static void draw_sprites(running_machine &machine, bitmap_rgb32 &bitmap, const rectangle &cliprect) { gottlieb_state *state = machine.driver_data(); UINT8 *spriteram = state->m_spriteram; @@ -249,14 +249,14 @@ static void draw_sprites(running_machine &machine, bitmap_ind16 &bitmap, const r * *************************************/ -SCREEN_UPDATE_IND16( gottlieb ) +SCREEN_UPDATE_RGB32( gottlieb ) { gottlieb_state *state = screen.machine().driver_data(); /* if the background has lower priority, render it first, else clear the screen */ if (!state->m_background_priority) state->m_bg_tilemap->draw(bitmap, cliprect, TILEMAP_DRAW_OPAQUE, 0); else - bitmap.fill(0, cliprect); + bitmap.fill(screen.machine().pens[0], cliprect); /* draw the sprites */ draw_sprites(screen.machine(), bitmap, cliprect);