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.
This commit is contained in:
Aaron Giles 2012-01-27 06:54:34 +00:00
parent f70b07ffe5
commit 52ccf5ffbc
6 changed files with 65 additions and 84 deletions

View File

@ -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<open_chd>;
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<open_chd> 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);
}
}

View File

@ -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;
}

View File

@ -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__ */

View File

@ -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()

View File

@ -86,4 +86,4 @@ extern WRITE8_HANDLER( gottlieb_paletteram_w );
VIDEO_START( gottlieb );
VIDEO_START( screwloo );
SCREEN_UPDATE_IND16( gottlieb );
SCREEN_UPDATE_RGB32( gottlieb );

View File

@ -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<gottlieb_state>();
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<gottlieb_state>();
/* 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);