- removed MESS dependency from config.c

- moved image legacy device implementation to devimage.c
- created image.c implementation with initialization of devices/configuration for image devices, used those calls from mame.c
- some minor cleanup of legacy device and initial implementation of some calls

(no whatsnew for now, this is just for log,will put more info on final commit)
This commit is contained in:
Miodrag Milanovic 2010-06-17 20:06:54 +00:00
parent 5f273b35d8
commit 826dba5923
15 changed files with 847 additions and 271 deletions

3
.gitattributes vendored
View File

@ -561,6 +561,7 @@ src/emu/devcb.h svneol=native#text/plain
src/emu/devconv.h svneol=native#text/plain src/emu/devconv.h svneol=native#text/plain
src/emu/devcpu.c svneol=native#text/plain src/emu/devcpu.c svneol=native#text/plain
src/emu/devcpu.h svneol=native#text/plain src/emu/devcpu.h svneol=native#text/plain
src/emu/devimage.c svneol=native#text/plain
src/emu/devintrf.c svneol=native#text/plain src/emu/devintrf.c svneol=native#text/plain
src/emu/devintrf.h svneol=native#text/plain src/emu/devintrf.h svneol=native#text/plain
src/emu/devlegcy.c svneol=native#text/plain src/emu/devlegcy.c svneol=native#text/plain
@ -606,6 +607,8 @@ src/emu/hash.c svneol=native#text/plain
src/emu/hash.h svneol=native#text/plain src/emu/hash.h svneol=native#text/plain
src/emu/hashfile.c svneol=native#text/plain src/emu/hashfile.c svneol=native#text/plain
src/emu/hashfile.h svneol=native#text/plain src/emu/hashfile.h svneol=native#text/plain
src/emu/image.c svneol=native#text/plain
src/emu/image.h svneol=native#text/plain
src/emu/info.c svneol=native#text/plain src/emu/info.c svneol=native#text/plain
src/emu/info.h svneol=native#text/plain src/emu/info.h svneol=native#text/plain
src/emu/inptport.c svneol=native#text/plain src/emu/inptport.c svneol=native#text/plain

View File

@ -64,10 +64,6 @@ static int config_save_xml(running_machine *machine, mame_file *file, int type);
void config_init(running_machine *machine) void config_init(running_machine *machine)
{ {
typelist = NULL; typelist = NULL;
#ifdef MESS
mess_config_init(machine);
#endif
} }

478
src/emu/devimage.c Normal file
View File

@ -0,0 +1,478 @@
/***************************************************************************
devimage.c
Legacy image device helpers.
****************************************************************************
Copyright Miodrag Milanovic
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
* Neither the name 'MAME' nor the names of its contributors may be
used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
***************************************************************************/
#include "emu.h"
#include "devlegcy.h"
#include "hashfile.h"
#include "zippath.h"
//**************************************************************************
// LEGACY IMAGE DEVICE CONFIGURATION
//**************************************************************************
//-------------------------------------------------
// legacy_image_device_config_base - constructor
//-------------------------------------------------
legacy_image_device_config_base::legacy_image_device_config_base(const machine_config &mconfig, device_type type, const char *tag, const device_config *owner, UINT32 clock, device_get_config_func get_config)
: legacy_device_config_base(mconfig, type, tag, owner, clock, get_config),
device_config_image_interface(mconfig, *this),
m_create_option_guide(NULL),
m_formatlist(NULL)
{
}
//-------------------------------------------------
// device_config_complete - update configuration
// based on completed device setup
//-------------------------------------------------
void legacy_image_device_config_base::device_config_complete()
{
const device_config_image_interface *image = NULL;
int count = 0;
int index = -1;
image_device_format **formatptr;
image_device_format *format;
formatptr = &m_formatlist;
int cnt = 0;
m_type = static_cast<iodevice_t>(get_legacy_config_int(DEVINFO_INT_IMAGE_TYPE));
m_readable = get_legacy_config_int(DEVINFO_INT_IMAGE_READABLE)!=0;
m_writeable = get_legacy_config_int(DEVINFO_INT_IMAGE_WRITEABLE)!=0;
m_creatable = get_legacy_config_int(DEVINFO_INT_IMAGE_CREATABLE)!=0;
m_must_be_loaded = get_legacy_config_int(DEVINFO_INT_IMAGE_MUST_BE_LOADED)!=0;
m_reset_on_load = get_legacy_config_int(DEVINFO_INT_IMAGE_RESET_ON_LOAD)!=0;
m_has_partial_hash = get_legacy_config_int(DEVINFO_FCT_IMAGE_PARTIAL_HASH)!=0;
m_interface_name = get_legacy_config_string(DEVINFO_STR_IMAGE_INTERFACE);
m_file_extensions = get_legacy_config_string(DEVINFO_STR_IMAGE_FILE_EXTENSIONS);
load = reinterpret_cast<device_image_load_func>(get_legacy_config_fct(DEVINFO_FCT_IMAGE_LOAD));
create = reinterpret_cast<device_image_create_func>(get_legacy_config_fct(DEVINFO_FCT_IMAGE_CREATE));
unload = reinterpret_cast<device_image_unload_func>(get_legacy_config_fct(DEVINFO_FCT_IMAGE_UNLOAD));
display = reinterpret_cast<device_image_display_func>(get_legacy_config_fct(DEVINFO_FCT_IMAGE_DISPLAY));
partialhash = reinterpret_cast<device_image_partialhash_func>(get_legacy_config_fct(DEVINFO_FCT_IMAGE_PARTIAL_HASH));
get_devices = reinterpret_cast<device_image_get_devices_func>(get_legacy_config_fct(DEVINFO_FCT_IMAGE_GET_DEVICES));
m_create_option_guide = reinterpret_cast<const option_guide *>(get_legacy_config_ptr(DEVINFO_PTR_IMAGE_CREATE_OPTGUIDE));
int format_count = get_legacy_config_int(DEVINFO_INT_IMAGE_CREATE_OPTCOUNT);
for (int i = 0; i < format_count; i++)
{
// only add if creatable
if (get_legacy_config_string(DEVINFO_PTR_IMAGE_CREATE_OPTSPEC + i)) {
// allocate a new format
format = global_alloc_clear(image_device_format);
// populate it
format->m_index = cnt;
format->m_name = get_legacy_config_string(DEVINFO_STR_IMAGE_CREATE_OPTNAME + i);
format->m_description = get_legacy_config_string(DEVINFO_STR_IMAGE_CREATE_OPTDESC + i);
format->m_extensions = get_legacy_config_string(DEVINFO_STR_IMAGE_CREATE_OPTEXTS + i);
format->m_optspec = get_legacy_config_string(DEVINFO_PTR_IMAGE_CREATE_OPTSPEC + i);
// and append it to the list
*formatptr = format;
formatptr = &format->m_next;
cnt++;
}
}
for (bool gotone = device_config_interface::m_machine_config.devicelist.first(image); gotone; gotone = image->next(image))
{
if (this == image)
index = count;
if (image->image_type_direct() == m_type)
count++;
}
if (count > 1) {
m_instance_name.printf("%s%d", device_typename(m_type), index + 1);
m_brief_instance_name.printf("%s%d", device_brieftypename(m_type), index + 1);
}
else
{
m_instance_name = device_typename(m_type);
m_brief_instance_name = device_brieftypename(m_type);
}
// Override in case of hardcoded values
if (strlen(get_legacy_config_string(DEVINFO_STR_IMAGE_INSTANCE_NAME))>0) {
m_instance_name = get_legacy_config_string(DEVINFO_STR_IMAGE_INSTANCE_NAME);
}
if (strlen(get_legacy_config_string(DEVINFO_STR_IMAGE_BRIEF_INSTANCE_NAME))>0) {
m_brief_instance_name = get_legacy_config_string(DEVINFO_STR_IMAGE_BRIEF_INSTANCE_NAME);
}
}
//-------------------------------------------------
// uses_file_extension - update configuration
// based on completed device setup
//-------------------------------------------------
bool legacy_image_device_config_base::uses_file_extension(const char *file_extension) const
{
bool result = FALSE;
if (file_extension[0] == '.')
file_extension++;
/* find the extensions */
char *ext = strtok((char*)m_file_extensions.cstr(),",");
while (ext != NULL)
{
if (!mame_stricmp(ext, file_extension))
{
result = TRUE;
break;
}
ext = strtok (NULL, ",");
}
return result;
}
//-------------------------------------------------
// ~legacy_device_config_base - destructor
//-------------------------------------------------
legacy_image_device_config_base::~legacy_image_device_config_base()
{
image_device_format **formatptr = &m_formatlist;
/* free all entries */
while (*formatptr != NULL)
{
image_device_format *entry = *formatptr;
*formatptr = entry->m_next;
global_free(entry);
}
}
//**************************************************************************
// LIVE LEGACY IMAGE DEVICE
//**************************************************************************
//-------------------------------------------------
// legacy_image_device_base - constructor
//-------------------------------------------------
legacy_image_device_base::legacy_image_device_base(running_machine &machine, const device_config &config)
: legacy_device_base(machine, config),
device_image_interface(machine, config, *this),
m_file(NULL)
{
}
/****************************************************************************
IMAGE LOADING
****************************************************************************/
/*-------------------------------------------------
set_image_filename - specifies the filename of
an image
-------------------------------------------------*/
image_error_t legacy_image_device_base::set_image_filename(const char *filename)
{
m_name = filename;
zippath_parent(&m_working_directory, filename);
return IMAGE_ERROR_SUCCESS;
}
/*-------------------------------------------------
load_image_by_path - loads an image with a
specific path
-------------------------------------------------*/
image_error_t legacy_image_device_base::load_image_by_path(UINT32 open_flags, const char *path)
{
file_error filerr = FILERR_NOT_FOUND;
image_error_t err = IMAGE_ERROR_FILENOTFOUND;
astring revised_path;
/* attempt to read the file */
filerr = zippath_fopen(path, open_flags, &m_file, &revised_path);
/* did the open succeed? */
switch(filerr)
{
case FILERR_NONE:
/* success! */
m_writeable = (open_flags & OPEN_FLAG_WRITE) ? 1 : 0;
m_created = (open_flags & OPEN_FLAG_CREATE) ? 1 : 0;
err = IMAGE_ERROR_SUCCESS;
break;
case FILERR_NOT_FOUND:
case FILERR_ACCESS_DENIED:
/* file not found (or otherwise cannot open); continue */
err = IMAGE_ERROR_FILENOTFOUND;
break;
case FILERR_OUT_OF_MEMORY:
/* out of memory */
err = IMAGE_ERROR_OUTOFMEMORY;
break;
case FILERR_ALREADY_OPEN:
/* this shouldn't happen */
err = IMAGE_ERROR_ALREADYOPEN;
break;
case FILERR_FAILURE:
case FILERR_TOO_MANY_FILES:
case FILERR_INVALID_DATA:
default:
/* other errors */
err = IMAGE_ERROR_INTERNAL;
break;
}
/* if successful, set the file name */
if (filerr == FILERR_NONE)
set_image_filename(revised_path);
return err;
}
/*-------------------------------------------------
determine_open_plan - determines which open
flags to use, and in what order
-------------------------------------------------*/
void legacy_image_device_base::determine_open_plan(int is_create, UINT32 *open_plan)
{
int i = 0;
/* emit flags */
if (!is_create && m_image_config.is_readable() && m_image_config.is_writeable())
open_plan[i++] = OPEN_FLAG_READ | OPEN_FLAG_WRITE;
if (!is_create && !m_image_config.is_readable() && m_image_config.is_writeable())
open_plan[i++] = OPEN_FLAG_WRITE;
if (!is_create && m_image_config.is_readable())
open_plan[i++] = OPEN_FLAG_READ;
if (m_image_config.is_writeable() && m_image_config.is_creatable())
open_plan[i++] = OPEN_FLAG_READ | OPEN_FLAG_WRITE | OPEN_FLAG_CREATE;
open_plan[i] = 0;
}
/*-------------------------------------------------
load_internal - core image loading
-------------------------------------------------*/
bool legacy_image_device_base::load_internal(const char *path, bool is_create, int create_format, option_resolution *create_args)
{
image_error_t err;
UINT32 open_plan[4];
int i;
/* first unload the image */
unload();
/* clear any possible error messages */
/* we are now loading */
/* record the filename */
err = set_image_filename(path);
if (err)
goto done;
/* Check if there's a software list defined for this device and use that if we're not creating an image */
/* determine open plan */
determine_open_plan(is_create, open_plan);
/* attempt to open the file in various ways */
for (i = 0; !m_file && open_plan[i]; i++)
{
/* open the file */
err = load_image_by_path(open_plan[i], path);
if (err && (err != IMAGE_ERROR_FILENOTFOUND))
goto done;
}
/* success! */
done:
if (err) {
clear();
}
else {
/* do we need to reset the CPU? only schedule it if load/create is successful */
if ((attotime_compare(timer_get_time(device().machine), attotime_zero) > 0) && m_image_config.is_reset_on_load())
mame_schedule_hard_reset(device().machine);
}
return err ? FALSE : TRUE;
}
/*-------------------------------------------------
load - load an image into MESS
-------------------------------------------------*/
bool legacy_image_device_base::load(const char *path)
{
return load_internal(path, FALSE, 0, NULL);
}
/*-------------------------------------------------
clear - clear all internal data pertaining
to an image
-------------------------------------------------*/
void legacy_image_device_base::clear()
{
if (m_file)
{
core_fclose(m_file);
m_file = NULL;
}
m_name.reset();
m_writeable = FALSE;
m_created = FALSE;
}
/*-------------------------------------------------
unload_internal - internal call to unload
images
-------------------------------------------------*/
void legacy_image_device_base::unload_internal()
{
clear();
}
/*-------------------------------------------------
unload - main call to unload an image
-------------------------------------------------*/
void legacy_image_device_base::unload()
{
unload_internal();
}
/***************************************************************************
WORKING DIRECTORIES
***************************************************************************/
/*-------------------------------------------------
try_change_working_directory - tries to change
the working directory, but only if the directory
actually exists
-------------------------------------------------*/
bool legacy_image_device_base::try_change_working_directory(const char *subdir)
{
osd_directory *directory;
const osd_directory_entry *entry;
bool success = FALSE;
bool done = FALSE;
directory = osd_opendir(m_working_directory.cstr());
if (directory != NULL)
{
while(!done && (entry = osd_readdir(directory)) != NULL)
{
if (!mame_stricmp(subdir, entry->name))
{
done = TRUE;
success = entry->type == ENTTYPE_DIR;
}
}
osd_closedir(directory);
}
/* did we successfully identify the directory? */
if (success)
zippath_combine(&m_working_directory, m_working_directory, subdir);
return success;
}
/*-------------------------------------------------
setup_working_directory - sets up the working
directory according to a few defaults
-------------------------------------------------*/
void legacy_image_device_base::setup_working_directory()
{
const game_driver *gamedrv;
char *dst = NULL;
osd_get_full_path(&dst,".");
/* first set up the working directory to be the starting directory */
m_working_directory = dst;
/* now try browsing down to "software" */
if (try_change_working_directory("software"))
{
/* now down to a directory for this computer */
gamedrv = device().machine->gamedrv;
while(gamedrv && !try_change_working_directory(gamedrv->name))
{
gamedrv = driver_get_compatible(gamedrv);
}
}
osd_free(dst);
}
//-------------------------------------------------
// working_directory - returns the working
// directory to use for this image; this is
// valid even if not mounted
//-------------------------------------------------
const char * legacy_image_device_base::working_directory()
{
/* check to see if we've never initialized the working directory */
if (m_working_directory.len() == 0)
setup_working_directory();
return m_working_directory;
}

View File

@ -344,216 +344,3 @@ void legacy_nvram_device_base::nvram_write(mame_file &file)
device_nvram_func nvram_func = reinterpret_cast<device_nvram_func>(m_config.get_legacy_config_fct(DEVINFO_FCT_NVRAM)); device_nvram_func nvram_func = reinterpret_cast<device_nvram_func>(m_config.get_legacy_config_fct(DEVINFO_FCT_NVRAM));
(*nvram_func)(this, &file, TRUE); (*nvram_func)(this, &file, TRUE);
} }
//**************************************************************************
// LEGACY IMAGE DEVICE CONFIGURATION
//**************************************************************************
const image_device_type_info legacy_image_device_config_base::m_device_info_array[] =
{
{ IO_CARTSLOT, "cartridge", "cart" }, /* 0 */
{ IO_FLOPPY, "floppydisk", "flop" }, /* 1 */
{ IO_HARDDISK, "harddisk", "hard" }, /* 2 */
{ IO_CYLINDER, "cylinder", "cyln" }, /* 3 */
{ IO_CASSETTE, "cassette", "cass" }, /* 4 */
{ IO_PUNCHCARD, "punchcard", "pcrd" }, /* 5 */
{ IO_PUNCHTAPE, "punchtape", "ptap" }, /* 6 */
{ IO_PRINTER, "printer", "prin" }, /* 7 */
{ IO_SERIAL, "serial", "serl" }, /* 8 */
{ IO_PARALLEL, "parallel", "parl" }, /* 9 */
{ IO_SNAPSHOT, "snapshot", "dump" }, /* 10 */
{ IO_QUICKLOAD, "quickload", "quik" }, /* 11 */
{ IO_MEMCARD, "memcard", "memc" }, /* 12 */
{ IO_CDROM, "cdrom", "cdrm" }, /* 13 */
{ IO_MAGTAPE, "magtape", "magt" }, /* 14 */
};
//-------------------------------------------------
// legacy_image_device_config_base - constructor
//-------------------------------------------------
legacy_image_device_config_base::legacy_image_device_config_base(const machine_config &mconfig, device_type type, const char *tag, const device_config *owner, UINT32 clock, device_get_config_func get_config)
: legacy_device_config_base(mconfig, type, tag, owner, clock, get_config),
device_config_image_interface(mconfig, *this),
m_create_option_guide(NULL),
m_formatlist(NULL)
{
}
//-------------------------------------------------
// device_config_complete - update configuration
// based on completed device setup
//-------------------------------------------------
void legacy_image_device_config_base::device_config_complete()
{
const device_config_image_interface *image = NULL;
int count = 0;
int index = -1;
image_device_format **formatptr;
image_device_format *format;
formatptr = &m_formatlist;
int cnt = 0;
m_type = static_cast<iodevice_t>(get_legacy_config_int(DEVINFO_INT_IMAGE_TYPE));
m_readable = get_legacy_config_int(DEVINFO_INT_IMAGE_READABLE)!=0;
m_writeable = get_legacy_config_int(DEVINFO_INT_IMAGE_WRITEABLE)!=0;
m_creatable = get_legacy_config_int(DEVINFO_INT_IMAGE_CREATABLE)!=0;
m_must_be_loaded = get_legacy_config_int(DEVINFO_INT_IMAGE_MUST_BE_LOADED)!=0;
m_reset_on_load = get_legacy_config_int(DEVINFO_INT_IMAGE_RESET_ON_LOAD)!=0;
m_has_partial_hash = get_legacy_config_int(DEVINFO_FCT_IMAGE_PARTIAL_HASH)!=0;
m_interface_name = get_legacy_config_string(DEVINFO_STR_IMAGE_INTERFACE);
m_file_extensions = get_legacy_config_string(DEVINFO_STR_IMAGE_FILE_EXTENSIONS);
load = reinterpret_cast<device_image_load_func>(get_legacy_config_fct(DEVINFO_FCT_IMAGE_LOAD));
create = reinterpret_cast<device_image_create_func>(get_legacy_config_fct(DEVINFO_FCT_IMAGE_CREATE));
unload = reinterpret_cast<device_image_unload_func>(get_legacy_config_fct(DEVINFO_FCT_IMAGE_UNLOAD));
display = reinterpret_cast<device_image_display_func>(get_legacy_config_fct(DEVINFO_FCT_IMAGE_DISPLAY));
partialhash = reinterpret_cast<device_image_partialhash_func>(get_legacy_config_fct(DEVINFO_FCT_IMAGE_PARTIAL_HASH));
get_devices = reinterpret_cast<device_image_get_devices_func>(get_legacy_config_fct(DEVINFO_FCT_IMAGE_GET_DEVICES));
m_create_option_guide = reinterpret_cast<const option_guide *>(get_legacy_config_ptr(DEVINFO_PTR_IMAGE_CREATE_OPTGUIDE));
int format_count = get_legacy_config_int(DEVINFO_INT_IMAGE_CREATE_OPTCOUNT);
for (int i = 0; i < format_count; i++)
{
// only add if creatable
if (get_legacy_config_string(DEVINFO_PTR_IMAGE_CREATE_OPTSPEC + i)) {
// allocate a new format
format = global_alloc_clear(image_device_format);
// populate it
format->m_index = cnt;
format->m_name = get_legacy_config_string(DEVINFO_STR_IMAGE_CREATE_OPTNAME + i);
format->m_description = get_legacy_config_string(DEVINFO_STR_IMAGE_CREATE_OPTDESC + i);
format->m_extensions = get_legacy_config_string(DEVINFO_STR_IMAGE_CREATE_OPTEXTS + i);
format->m_optspec = get_legacy_config_string(DEVINFO_PTR_IMAGE_CREATE_OPTSPEC + i);
// and append it to the list
*formatptr = format;
formatptr = &format->m_next;
cnt++;
}
}
for (bool gotone = device_config_interface::m_machine_config.devicelist.first(image); gotone; gotone = image->next(image))
{
if (this == image)
index = count;
if (image->image_type_direct() == m_type)
count++;
}
if (count > 1) {
m_instance_name.printf("%s%d", device_typename(m_type), index + 1);
m_brief_instance_name.printf("%s%d", device_brieftypename(m_type), index + 1);
}
else
{
m_instance_name = device_typename(m_type);
m_brief_instance_name = device_brieftypename(m_type);
}
// Override in case of hardcoded values
if (strlen(get_legacy_config_string(DEVINFO_STR_IMAGE_INSTANCE_NAME))>0) {
m_instance_name = get_legacy_config_string(DEVINFO_STR_IMAGE_INSTANCE_NAME);
}
if (strlen(get_legacy_config_string(DEVINFO_STR_IMAGE_BRIEF_INSTANCE_NAME))>0) {
m_brief_instance_name = get_legacy_config_string(DEVINFO_STR_IMAGE_BRIEF_INSTANCE_NAME);
}
}
//-------------------------------------------------
// find_device_type - search trough list of
// device types to extact data
//-------------------------------------------------
const image_device_type_info *legacy_image_device_config_base::find_device_type(iodevice_t type)
{
int i;
for (i = 0; i < ARRAY_LENGTH(legacy_image_device_config_base::m_device_info_array); i++)
{
if (m_device_info_array[i].m_type == type)
return &m_device_info_array[i];
}
return NULL;
}
//-------------------------------------------------
// device_typename - retrieves device type name
//-------------------------------------------------
const char *legacy_image_device_config_base::device_typename(iodevice_t type)
{
const image_device_type_info *info = find_device_type(type);
return (info != NULL) ? info->m_name : NULL;
}
//-------------------------------------------------
// device_brieftypename - retrieves device
// brief type name
//-------------------------------------------------
const char *legacy_image_device_config_base::device_brieftypename(iodevice_t type)
{
const image_device_type_info *info = find_device_type(type);
return (info != NULL) ? info->m_shortname : NULL;
}
//-------------------------------------------------
// uses_file_extension - update configuration
// based on completed device setup
//-------------------------------------------------
bool legacy_image_device_config_base::uses_file_extension(const char *file_extension) const
{
bool result = FALSE;
if (file_extension[0] == '.')
file_extension++;
/* find the extensions */
char *ext = strtok((char*)m_file_extensions.cstr(),",");
while (ext != NULL)
{
if (!mame_stricmp(ext, file_extension))
{
result = TRUE;
break;
}
ext = strtok (NULL, ",");
}
return result;
}
//-------------------------------------------------
// ~legacy_device_config_base - destructor
//-------------------------------------------------
legacy_image_device_config_base::~legacy_image_device_config_base()
{
image_device_format **formatptr = &m_formatlist;
/* free all entries */
while (*formatptr != NULL)
{
image_device_format *entry = *formatptr;
*formatptr = entry->m_next;
global_free(entry);
}
}
//**************************************************************************
// LIVE LEGACY IMAGE DEVICE
//**************************************************************************
//-------------------------------------------------
// legacy_image_device_base - constructor
//-------------------------------------------------
legacy_image_device_base::legacy_image_device_base(running_machine &machine, const device_config &config)
: legacy_device_base(machine, config),
device_image_interface(machine, config, *this)
{
}

View File

@ -386,14 +386,6 @@ typedef INT32 (*device_execute_func)(device_t *device, INT32 clocks);
typedef void (*device_reset_func)(device_t *device); typedef void (*device_reset_func)(device_t *device);
typedef void (*device_nvram_func)(device_t *device, mame_file *file, int read_or_write); typedef void (*device_nvram_func)(device_t *device, mame_file *file, int read_or_write);
// device image interface function types
typedef int (*device_image_load_func)(device_t *image);
typedef int (*device_image_create_func)(device_t *image, int format_type, option_resolution *format_options);
typedef void (*device_image_unload_func)(device_t *image);
typedef void (*device_image_display_func)(device_t *image);
typedef void (*device_image_partialhash_func)(char *, const unsigned char *, unsigned long, unsigned int);
typedef void (*device_image_get_devices_func)(device_t *device);
// the actual deviceinfo union // the actual deviceinfo union
union deviceinfo union deviceinfo
{ {
@ -578,28 +570,14 @@ protected:
}; };
// ======================> legacy_image_device_config // ======================> legacy_image_device_config
struct image_device_format
{
image_device_format *m_next;
int m_index;
astring m_name;
astring m_description;
astring m_extensions;
astring m_optspec;
};
struct image_device_type_info
{
iodevice_t m_type;
astring m_name;
astring m_shortname;
};
// legacy_image_device_config is a device_config with a image interface // legacy_image_device_config is a device_config with a image interface
class legacy_image_device_config_base : public legacy_device_config_base, class legacy_image_device_config_base : public legacy_device_config_base,
public device_config_image_interface public device_config_image_interface
{ {
friend class legacy_image_device_base;
public: public:
virtual const char *name() const { return get_legacy_config_string(DEVINFO_STR_NAME); }
virtual iodevice_t image_type() const { return m_type; } virtual iodevice_t image_type() const { return m_type; }
virtual const char *image_type_name() const { return device_typename(m_type); } virtual const char *image_type_name() const { return device_typename(m_type); }
virtual iodevice_t image_type_direct() const { return static_cast<iodevice_t>(get_legacy_config_int(DEVINFO_INT_IMAGE_TYPE)); } virtual iodevice_t image_type_direct() const { return static_cast<iodevice_t>(get_legacy_config_int(DEVINFO_INT_IMAGE_TYPE)); }
@ -614,8 +592,7 @@ public:
virtual const char *instance_name() const { return m_instance_name; } virtual const char *instance_name() const { return m_instance_name; }
virtual const char *brief_instance_name() const { return m_brief_instance_name; } virtual const char *brief_instance_name() const { return m_brief_instance_name; }
virtual bool uses_file_extension(const char *file_extension) const; virtual bool uses_file_extension(const char *file_extension) const;
static const char *device_typename(iodevice_t type);
static const char *device_brieftypename(iodevice_t type);
protected: protected:
// construction/destruction // construction/destruction
legacy_image_device_config_base(const machine_config &mconfig, device_type type, const char *tag, const device_config *owner, UINT32 clock, device_get_config_func get_config); legacy_image_device_config_base(const machine_config &mconfig, device_type type, const char *tag, const device_config *owner, UINT32 clock, device_get_config_func get_config);
@ -624,10 +601,6 @@ protected:
// device_config overrides // device_config overrides
virtual void device_config_complete(); virtual void device_config_complete();
static const image_device_type_info *find_device_type(iodevice_t type);
static const image_device_type_info m_device_info_array[];
iodevice_t m_type; iodevice_t m_type;
bool m_readable; bool m_readable;
bool m_writeable; bool m_writeable;
@ -659,11 +632,42 @@ protected:
class legacy_image_device_base : public legacy_device_base, class legacy_image_device_base : public legacy_device_base,
public device_image_interface public device_image_interface
{ {
friend class legacy_image_device_config_base;
public:
virtual void set_working_directory(const char *working_directory) { m_working_directory = working_directory; }
virtual const char * working_directory();
virtual bool load(const char *path);
virtual void unload();
protected: protected:
// construction/destruction // construction/destruction
legacy_image_device_base(running_machine &machine, const device_config &config); legacy_image_device_base(running_machine &machine, const device_config &config);
// device_image_interface overrides // device_image_interface overrides
/* working directory; persists across mounts */
astring m_working_directory;
/* variables that are only non-zero when an image is mounted */
core_file *m_file;
astring m_name;
/* error related info */
image_error_t err;
astring err_message;
void setup_working_directory();
bool try_change_working_directory(const char *subdir);
bool load_internal(const char *path, bool is_create, int create_format, option_resolution *create_args);
void determine_open_plan(int is_create, UINT32 *open_plan);
image_error_t set_image_filename(const char *filename);
image_error_t load_image_by_path(UINT32 open_flags, const char *path);
void clear();
void unload_internal();
/* flags */
bool m_writeable;
bool m_created;
}; };

View File

@ -44,9 +44,27 @@
//************************************************************************** //**************************************************************************
// DEVICE CONFIG IMAGE INTERFACE // DEVICE CONFIG IMAGE INTERFACE
//************************************************************************** //**************************************************************************
const image_device_type_info device_config_image_interface::m_device_info_array[] =
{
{ IO_CARTSLOT, "cartridge", "cart" }, /* 0 */
{ IO_FLOPPY, "floppydisk", "flop" }, /* 1 */
{ IO_HARDDISK, "harddisk", "hard" }, /* 2 */
{ IO_CYLINDER, "cylinder", "cyln" }, /* 3 */
{ IO_CASSETTE, "cassette", "cass" }, /* 4 */
{ IO_PUNCHCARD, "punchcard", "pcrd" }, /* 5 */
{ IO_PUNCHTAPE, "punchtape", "ptap" }, /* 6 */
{ IO_PRINTER, "printer", "prin" }, /* 7 */
{ IO_SERIAL, "serial", "serl" }, /* 8 */
{ IO_PARALLEL, "parallel", "parl" }, /* 9 */
{ IO_SNAPSHOT, "snapshot", "dump" }, /* 10 */
{ IO_QUICKLOAD, "quickload", "quik" }, /* 11 */
{ IO_MEMCARD, "memcard", "memc" }, /* 12 */
{ IO_CDROM, "cdrom", "cdrm" }, /* 13 */
{ IO_MAGTAPE, "magtape", "magt" }, /* 14 */
};
//------------------------------------------------- //-------------------------------------------------
// device_config_nvram_interface - constructor // device_config_image_interface - constructor
//------------------------------------------------- //-------------------------------------------------
device_config_image_interface::device_config_image_interface(const machine_config &mconfig, device_config &devconfig) device_config_image_interface::device_config_image_interface(const machine_config &mconfig, device_config &devconfig)
@ -64,6 +82,42 @@ device_config_image_interface::~device_config_image_interface()
} }
//-------------------------------------------------
// find_device_type - search trough list of
// device types to extact data
//-------------------------------------------------
const image_device_type_info *device_config_image_interface::find_device_type(iodevice_t type)
{
int i;
for (i = 0; i < ARRAY_LENGTH(device_config_image_interface::m_device_info_array); i++)
{
if (m_device_info_array[i].m_type == type)
return &m_device_info_array[i];
}
return NULL;
}
//-------------------------------------------------
// device_typename - retrieves device type name
//-------------------------------------------------
const char *device_config_image_interface::device_typename(iodevice_t type)
{
const image_device_type_info *info = find_device_type(type);
return (info != NULL) ? info->m_name : NULL;
}
//-------------------------------------------------
// device_brieftypename - retrieves device
// brief type name
//-------------------------------------------------
const char *device_config_image_interface::device_brieftypename(iodevice_t type)
{
const image_device_type_info *info = find_device_type(type);
return (info != NULL) ? info->m_shortname : NULL;
}
//************************************************************************** //**************************************************************************
// DEVICE image INTERFACE // DEVICE image INTERFACE

View File

@ -73,18 +73,77 @@ enum iodevice_t
IO_COUNT /* 16 - Total Number of IO_devices for searching */ IO_COUNT /* 16 - Total Number of IO_devices for searching */
}; };
enum image_error_t
{
IMAGE_ERROR_SUCCESS,
IMAGE_ERROR_INTERNAL,
IMAGE_ERROR_UNSUPPORTED,
IMAGE_ERROR_OUTOFMEMORY,
IMAGE_ERROR_FILENOTFOUND,
IMAGE_ERROR_INVALIDIMAGE,
IMAGE_ERROR_ALREADYOPEN,
IMAGE_ERROR_UNSPECIFIED
};
struct image_device_type_info
{
iodevice_t m_type;
const char *m_name;
const char *m_shortname;
};
struct image_device_format
{
image_device_format *m_next;
int m_index;
astring m_name;
astring m_description;
astring m_extensions;
astring m_optspec;
};
// device image interface function types
typedef int (*device_image_load_func)(device_t *image);
typedef int (*device_image_create_func)(device_t *image, int format_type, option_resolution *format_options);
typedef void (*device_image_unload_func)(device_t *image);
typedef void (*device_image_display_func)(device_t *image);
typedef void (*device_image_partialhash_func)(char *, const unsigned char *, unsigned long, unsigned int);
typedef void (*device_image_get_devices_func)(device_t *device);
//**************************************************************************
// MACROS
//**************************************************************************
#define DEVICE_IMAGE_LOAD_NAME(name) device_load_##name
#define DEVICE_IMAGE_LOAD(name) int DEVICE_IMAGE_LOAD_NAME(name)(device_t *image)
#define DEVICE_IMAGE_CREATE_NAME(name) device_create_##name
#define DEVICE_IMAGE_CREATE(name) int DEVICE_IMAGE_CREATE_NAME(name)(device_t *image, int create_format, option_resolution *create_args)
#define DEVICE_IMAGE_UNLOAD_NAME(name) device_unload_##name
#define DEVICE_IMAGE_UNLOAD(name) void DEVICE_IMAGE_UNLOAD_NAME(name)(device_t *image)
#define DEVICE_IMAGE_DISPLAY_NAME(name) device_image_display_func##name
#define DEVICE_IMAGE_DISPLAY(name) void DEVICE_IMAGE_DISPLAY_NAME(name)(device_t *image)
#define DEVICE_IMAGE_GET_DEVICES_NAME(name) device_image_get_devices_##name
#define DEVICE_IMAGE_GET_DEVICES(name) void DEVICE_IMAGE_GET_DEVICES_NAME(name)(device_t *device)
// ======================> device_config_image_interface // ======================> device_config_image_interface
// class representing interface-specific configuration image // class representing interface-specific configuration image
class device_config_image_interface : public device_config_interface class device_config_image_interface : public device_config_interface
{ {
friend class device_image_interface;
public: public:
// construction/destruction // construction/destruction
device_config_image_interface(const machine_config &mconfig, device_config &device); device_config_image_interface(const machine_config &mconfig, device_config &device);
virtual ~device_config_image_interface(); virtual ~device_config_image_interface();
// public accessors... for now // public accessors... for now
virtual const char *name() const = 0;
virtual iodevice_t image_type() const = 0; virtual iodevice_t image_type() const = 0;
virtual const char *image_type_name() const = 0; virtual const char *image_type_name() const = 0;
virtual iodevice_t image_type_direct() const = 0; virtual iodevice_t image_type_direct() const = 0;
@ -99,6 +158,12 @@ public:
virtual const char *instance_name() const = 0; virtual const char *instance_name() const = 0;
virtual const char *brief_instance_name() const = 0; virtual const char *brief_instance_name() const = 0;
virtual bool uses_file_extension(const char *file_extension) const = 0; virtual bool uses_file_extension(const char *file_extension) const = 0;
static const char *device_typename(iodevice_t type);
static const char *device_brieftypename(iodevice_t type);
protected:
static const image_device_type_info *find_device_type(iodevice_t type);
static const image_device_type_info m_device_info_array[];
}; };
@ -108,14 +173,19 @@ public:
// class representing interface-specific live image // class representing interface-specific live image
class device_image_interface : public device_interface class device_image_interface : public device_interface
{ {
friend class device_config_image_interface;
public: public:
// construction/destruction // construction/destruction
device_image_interface(running_machine &machine, const device_config &config, device_t &device); device_image_interface(running_machine &machine, const device_config &config, device_t &device);
virtual ~device_image_interface(); virtual ~device_image_interface();
virtual void set_working_directory(const char *working_directory) = 0;
virtual const char * working_directory() = 0;
virtual bool load(const char *path) = 0;
virtual void unload() = 0;
// configuration access // configuration access
const device_config_image_interface &image_config() const { return m_image_config; } const device_config_image_interface &image_config() const { return m_image_config; }
protected: protected:
// derived class overrides // derived class overrides

View File

@ -98,10 +98,12 @@
#include "romload.h" #include "romload.h"
#include "state.h" #include "state.h"
// image-related
#include "image.h"
// the running machine // the running machine
#ifdef MESS #ifdef MESS
#include "mess.h" #include "mess.h"
#include "image.h"
#include "messdrv.h" #include "messdrv.h"
#endif /* MESS */ #endif /* MESS */
#include "mame.h" #include "mame.h"

View File

@ -46,6 +46,7 @@ EMUOBJS = \
$(EMUOBJ)/debugger.o \ $(EMUOBJ)/debugger.o \
$(EMUOBJ)/devcb.o \ $(EMUOBJ)/devcb.o \
$(EMUOBJ)/devcpu.o \ $(EMUOBJ)/devcpu.o \
$(EMUOBJ)/devimage.o \
$(EMUOBJ)/devlegcy.o \ $(EMUOBJ)/devlegcy.o \
$(EMUOBJ)/devintrf.o \ $(EMUOBJ)/devintrf.o \
$(EMUOBJ)/didisasm.o \ $(EMUOBJ)/didisasm.o \
@ -64,6 +65,7 @@ EMUOBJS = \
$(EMUOBJ)/fileio.o \ $(EMUOBJ)/fileio.o \
$(EMUOBJ)/hash.o \ $(EMUOBJ)/hash.o \
$(EMUOBJ)/hashfile.o \ $(EMUOBJ)/hashfile.o \
$(EMUOBJ)/image.o \
$(EMUOBJ)/info.o \ $(EMUOBJ)/info.o \
$(EMUOBJ)/input.o \ $(EMUOBJ)/input.o \
$(EMUOBJ)/inputseq.o \ $(EMUOBJ)/inputseq.o \

View File

@ -207,14 +207,14 @@ static void mame_puts_error(const char *s)
option option
-------------------------------------------------*/ -------------------------------------------------*/
const char *image_get_device_option(device_t *image) const char *image_get_device_option(device_image_interface *image)
{ {
const char *result = NULL; const char *result = NULL;
if (options_get_bool(mame_options(), OPTION_ADDED_DEVICE_OPTIONS)) if (options_get_bool(mame_options(), OPTION_ADDED_DEVICE_OPTIONS))
{ {
/* access the option */ /* access the option */
result = options_get_string(mame_options(), downcast<const legacy_image_device_config_base *>(&image->baseconfig())->instance_name()); result = options_get_string(mame_options(), image->image_config().instance_name());
} }
return result; return result;
} }

View File

@ -182,6 +182,6 @@ core_options *mame_options_init(const options_entry *entries);
/* add the device options for a specified device */ /* add the device options for a specified device */
void image_add_device_options(core_options *opts, const game_driver *driver); void image_add_device_options(core_options *opts, const game_driver *driver);
/* accesses a device option, by device and index */ /* accesses a device option, by device and index */
const char *image_get_device_option(device_t *image); const char *image_get_device_option(device_image_interface *image);
#endif /* __EMUOPTS_H__ */ #endif /* __EMUOPTS_H__ */

168
src/emu/image.c Normal file
View File

@ -0,0 +1,168 @@
/***************************************************************************
image.c
Core image functions and definitions.
Copyright Nicola Salmoria and the MAME Team.
Visit http://mamedev.org for licensing and usage restrictions.
***************************************************************************/
#include "emu.h"
#include "emuopts.h"
#include "image.h"
#include "config.h"
#include "xmlfile.h"
/***************************************************************************
INITIALIZATION HELPERS
***************************************************************************/
//============================================================
// filename_basename
//============================================================
static const char *filename_basename(const char *filename)
{
const char *c;
// NULL begets NULL
if (!filename)
return NULL;
// start at the end and return when we hit a slash or colon
for (c = filename + strlen(filename) - 1; c >= filename; c--)
if (*c == '\\' || *c == '/' || *c == ':')
return c + 1;
// otherwise, return the whole thing
return filename;
}
/*-------------------------------------------------
image_dirs_load - loads image device directory
configuration items
-------------------------------------------------*/
static void image_dirs_load(running_machine *machine, int config_type, xml_data_node *parentnode)
{
xml_data_node *node;
const char *dev_instance;
const char *working_directory;
device_image_interface *image = NULL;
if ((config_type == CONFIG_TYPE_GAME) && (parentnode != NULL))
{
for (node = xml_get_sibling(parentnode->child, "device"); node; node = xml_get_sibling(node->next, "device"))
{
dev_instance = xml_get_attribute_string(node, "instance", NULL);
if ((dev_instance != NULL) && (dev_instance[0] != '\0'))
{
for (bool gotone = machine->devicelist.first(image); gotone; gotone = image->next(image))
{
if (!strcmp(dev_instance, image->image_config().instance_name())) {
working_directory = xml_get_attribute_string(node, "directory", NULL);
if (working_directory != NULL)
image->set_working_directory(working_directory);
}
}
}
}
}
}
/*-------------------------------------------------
image_dirs_save - saves out image device
directories to the configuration file
-------------------------------------------------*/
static void image_dirs_save(running_machine *machine, int config_type, xml_data_node *parentnode)
{
xml_data_node *node;
const char *dev_instance;
device_image_interface *image = NULL;
/* only care about game-specific data */
if (config_type == CONFIG_TYPE_GAME)
{
for (bool gotone = machine->devicelist.first(image); gotone; gotone = image->next(image))
{
dev_instance = image->image_config().instance_name();
node = xml_add_child(parentnode, "device", NULL);
if (node != NULL)
{
xml_set_attribute(node, "instance", dev_instance);
xml_set_attribute(node, "directory", image->working_directory());
}
}
}
}
/*-------------------------------------------------
image_device_init - initialize devices for a specific
running_machine
-------------------------------------------------*/
void image_device_init(running_machine *machine)
{
const char *image_name;
device_image_interface *image = NULL;
/* make sure that any required devices have been allocated */
for (bool gotone = machine->devicelist.first(image); gotone; gotone = image->next(image))
{
/* is an image specified for this image */
image_name = image_get_device_option(image);
if ((image_name != NULL) && (image_name[0] != '\0'))
{
bool result = FALSE;
/* try to load this image */
result = image->load(image_name);
/* did the image load fail? */
if (!result)
{
/* retrieve image error message */
const char *image_err = "error";// image_error(image);
char *image_basename = auto_strdup(machine, filename_basename(image_name));
/* unload all images */
//image_unload_all(machine);
fatalerror_exitcode(machine, MAMERR_DEVICE, "Device %s load (%s) failed: %s",
image->image_config().name(),
image_basename,
image_err);
}
}
else
{
/* no image... must this device be loaded? */
if (image->image_config().must_be_loaded())
{
fatalerror_exitcode(machine, MAMERR_DEVICE, "Driver requires that device \"%s\" must have an image to load", image->image_config().instance_name());
}
}
}
}
/***************************************************************************
INITIALIZATION
***************************************************************************/
/*-------------------------------------------------
image_init - start up the image system
-------------------------------------------------*/
void image_init(running_machine *machine)
{
image_device_init(machine);
config_register(machine, "image_directories", image_dirs_load, image_dirs_save);
}

23
src/emu/image.h Normal file
View File

@ -0,0 +1,23 @@
/***************************************************************************
image.h
Core image interface functions and definitions.
Copyright Nicola Salmoria and the MAME Team.
Visit http://mamedev.org for licensing and usage restrictions.
***************************************************************************/
#pragma once
#ifndef __EMU_H__
#error Dont include this file directly; include emu.h instead.
#endif
#ifndef __IMAGE_H__
#define __IMAGE_H__
void image_init(running_machine *machine);
#endif /* __IMAGE_H__ */

View File

@ -52,6 +52,7 @@
- calls the driver's MACHINE_START, SOUND_START, and VIDEO_START callbacks - calls the driver's MACHINE_START, SOUND_START, and VIDEO_START callbacks
- calls saveload_init() [mame.c] to set up for save/load - calls saveload_init() [mame.c] to set up for save/load
- calls cheat_init() [cheat.c] to initialize the cheat system - calls cheat_init() [cheat.c] to initialize the cheat system
- calls image_init() [image.c] to initialize the image system
- calls config_load_settings() [config.c] to load the configuration file - calls config_load_settings() [config.c] to load the configuration file
- calls nvram_load [machine/generic.c] to load NVRAM - calls nvram_load [machine/generic.c] to load NVRAM
@ -77,6 +78,7 @@
#include "osdepend.h" #include "osdepend.h"
#include "config.h" #include "config.h"
#include "debugger.h" #include "debugger.h"
#include "image.h"
#include "profiler.h" #include "profiler.h"
#include "render.h" #include "render.h"
#include "cheat.h" #include "cheat.h"
@ -1267,9 +1269,6 @@ running_machine::running_machine(const game_driver *driver)
generic_machine_data(NULL), generic_machine_data(NULL),
generic_video_data(NULL), generic_video_data(NULL),
generic_audio_data(NULL), generic_audio_data(NULL),
#ifdef MESS
images_data(NULL),
#endif /* MESS */
driver_data(NULL) driver_data(NULL)
{ {
try try
@ -1418,10 +1417,8 @@ static void init_machine(running_machine *machine)
/* initialize natural keyboard support */ /* initialize natural keyboard support */
inputx_init(machine); inputx_init(machine);
#ifdef MESS /* initialize image devices */
/* first MESS initialization */ image_init(machine);
mess_predevice_init(machine);
#endif /* MESS */
/* start up the devices */ /* start up the devices */
machine->devicelist.start_all(); machine->devicelist.start_all();
@ -1433,11 +1430,6 @@ static void init_machine(running_machine *machine)
if (machine->gamedrv->driver_init != NULL) if (machine->gamedrv->driver_init != NULL)
(*machine->gamedrv->driver_init)(machine); (*machine->gamedrv->driver_init)(machine);
#ifdef MESS
/* second MESS initialization */
mess_postdevice_init(machine);
#endif /* MESS */
/* start the video and audio hardware */ /* start the video and audio hardware */
video_init(machine); video_init(machine);
tilemap_init(machine); tilemap_init(machine);

View File

@ -291,9 +291,6 @@ public:
generic_machine_private *generic_machine_data; /* internal data from machine/generic.c */ generic_machine_private *generic_machine_data; /* internal data from machine/generic.c */
generic_video_private * generic_video_data; /* internal data from video/generic.c */ generic_video_private * generic_video_data; /* internal data from video/generic.c */
generic_audio_private * generic_audio_data; /* internal data from audio/generic.c */ generic_audio_private * generic_audio_data; /* internal data from audio/generic.c */
#ifdef MESS
images_private * images_data; /* internal data from image.c */
#endif /* MESS */
/* driver-specific information */ /* driver-specific information */
void * driver_data; /* drivers can hang data off of here instead of using globals */ void * driver_data; /* drivers can hang data off of here instead of using globals */