mirror of
https://github.com/holub/mame
synced 2025-10-05 08:41:31 +03:00
image_manager modernized and move some things around (nw)
This commit is contained in:
parent
e0358a4ce4
commit
f0dc809ab8
@ -16,7 +16,6 @@
|
|||||||
|
|
||||||
#include "sc499.h"
|
#include "sc499.h"
|
||||||
#include "formats/ioprocs.h"
|
#include "formats/ioprocs.h"
|
||||||
#include "image.h"
|
|
||||||
|
|
||||||
#define VERBOSE 0
|
#define VERBOSE 0
|
||||||
|
|
||||||
|
@ -134,6 +134,52 @@
|
|||||||
#define GKRACKER_ROM_TAG "gkracker_rom"
|
#define GKRACKER_ROM_TAG "gkracker_rom"
|
||||||
#define GKRACKER_NVRAM_TAG "gkracker_nvram"
|
#define GKRACKER_NVRAM_TAG "gkracker_nvram"
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
image_battery_load_by_name - retrieves the battery
|
||||||
|
backed RAM for an image. A filename may be supplied
|
||||||
|
to the function.
|
||||||
|
|
||||||
|
The function comes in two flavors, depending on
|
||||||
|
what should happen when no battery is available:
|
||||||
|
we could fill the memory with a given value, or
|
||||||
|
pass a default battery (for a pre-initialized
|
||||||
|
battery from factory)
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
static void image_battery_load_by_name(emu_options &options, const char *filename, void *buffer, int length, int fill)
|
||||||
|
{
|
||||||
|
file_error filerr;
|
||||||
|
int bytes_read = 0;
|
||||||
|
|
||||||
|
assert_always(buffer && (length > 0), "Must specify sensical buffer/length");
|
||||||
|
|
||||||
|
/* try to open the battery file and read it in, if possible */
|
||||||
|
emu_file file(options.nvram_directory(), OPEN_FLAG_READ);
|
||||||
|
filerr = file.open(filename);
|
||||||
|
if (filerr == FILERR_NONE)
|
||||||
|
bytes_read = file.read(buffer, length);
|
||||||
|
|
||||||
|
/* fill remaining bytes (if necessary) */
|
||||||
|
memset(((char *) buffer) + bytes_read, fill, length - bytes_read);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
image_battery_save_by_name - stores the battery
|
||||||
|
backed RAM for an image. A filename may be supplied
|
||||||
|
to the function.
|
||||||
|
-------------------------------------------------*/
|
||||||
|
static void image_battery_save_by_name(emu_options &options, const char *filename, const void *buffer, int length)
|
||||||
|
{
|
||||||
|
assert_always(buffer && (length > 0), "Must specify sensical buffer/length");
|
||||||
|
|
||||||
|
/* try to open the battery file and write it out, if possible */
|
||||||
|
emu_file file(options.nvram_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
|
||||||
|
file_error filerr = file.open(filename);
|
||||||
|
if (filerr == FILERR_NONE)
|
||||||
|
file.write(buffer, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
gromport_device::gromport_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
gromport_device::gromport_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||||
: bus8z_device(mconfig, GROMPORT, "Cartridge port", tag, owner, clock, "gromport", __FILE__),
|
: bus8z_device(mconfig, GROMPORT, "Cartridge port", tag, owner, clock, "gromport", __FILE__),
|
||||||
device_slot_interface(mconfig, *this),
|
device_slot_interface(mconfig, *this),
|
||||||
|
@ -12,7 +12,6 @@
|
|||||||
#include "formats/imageutl.h"
|
#include "formats/imageutl.h"
|
||||||
#include "cassette.h"
|
#include "cassette.h"
|
||||||
#include "ui/ui.h"
|
#include "ui/ui.h"
|
||||||
#include "image.h"
|
|
||||||
|
|
||||||
|
|
||||||
#define ANIMATION_FPS 1
|
#define ANIMATION_FPS 1
|
||||||
|
@ -16,7 +16,6 @@
|
|||||||
#include "emu.h"
|
#include "emu.h"
|
||||||
#include "formats/imageutl.h"
|
#include "formats/imageutl.h"
|
||||||
#include "flopdrv.h"
|
#include "flopdrv.h"
|
||||||
#include "image.h"
|
|
||||||
|
|
||||||
#define VERBOSE 0
|
#define VERBOSE 0
|
||||||
#define LOG(x) do { if (VERBOSE) logerror x; } while (0)
|
#define LOG(x) do { if (VERBOSE) logerror x; } while (0)
|
||||||
|
@ -12,7 +12,6 @@
|
|||||||
#include "zippath.h"
|
#include "zippath.h"
|
||||||
#include "floppy.h"
|
#include "floppy.h"
|
||||||
#include "formats/imageutl.h"
|
#include "formats/imageutl.h"
|
||||||
#include "image.h"
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Debugging flags. Set to 0 or 1.
|
Debugging flags. Set to 0 or 1.
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
#include "ui/imgcntrl.h"
|
#include "ui/imgcntrl.h"
|
||||||
#include "softlist.h"
|
#include "softlist.h"
|
||||||
#include "image.h"
|
#include "image.h"
|
||||||
|
#include "formats/ioprocs.h"
|
||||||
|
|
||||||
//**************************************************************************
|
//**************************************************************************
|
||||||
// DEVICE CONFIG IMAGE INTERFACE
|
// DEVICE CONFIG IMAGE INTERFACE
|
||||||
@ -508,14 +509,39 @@ UINT32 device_image_interface::crc()
|
|||||||
-------------------------------------------------*/
|
-------------------------------------------------*/
|
||||||
void device_image_interface::battery_load(void *buffer, int length, int fill)
|
void device_image_interface::battery_load(void *buffer, int length, int fill)
|
||||||
{
|
{
|
||||||
|
assert_always(buffer && (length > 0), "Must specify sensical buffer/length");
|
||||||
|
|
||||||
|
file_error filerr;
|
||||||
|
int bytes_read = 0;
|
||||||
std::string fname = std::string(device().machine().system().name).append(PATH_SEPARATOR).append(m_basename_noext.c_str()).append(".nv");
|
std::string fname = std::string(device().machine().system().name).append(PATH_SEPARATOR).append(m_basename_noext.c_str()).append(".nv");
|
||||||
image_battery_load_by_name(device().machine().options(), fname.c_str(), buffer, length, fill);
|
|
||||||
|
/* try to open the battery file and read it in, if possible */
|
||||||
|
emu_file file(device().machine().options().nvram_directory(), OPEN_FLAG_READ);
|
||||||
|
filerr = file.open(fname.c_str());
|
||||||
|
if (filerr == FILERR_NONE)
|
||||||
|
bytes_read = file.read(buffer, length);
|
||||||
|
|
||||||
|
/* fill remaining bytes (if necessary) */
|
||||||
|
memset(((char *)buffer) + bytes_read, fill, length - bytes_read);
|
||||||
}
|
}
|
||||||
|
|
||||||
void device_image_interface::battery_load(void *buffer, int length, void *def_buffer)
|
void device_image_interface::battery_load(void *buffer, int length, void *def_buffer)
|
||||||
{
|
{
|
||||||
|
assert_always(buffer && (length > 0), "Must specify sensical buffer/length");
|
||||||
|
|
||||||
|
file_error filerr;
|
||||||
|
int bytes_read = 0;
|
||||||
std::string fname = std::string(device().machine().system().name).append(PATH_SEPARATOR).append(m_basename_noext.c_str()).append(".nv");
|
std::string fname = std::string(device().machine().system().name).append(PATH_SEPARATOR).append(m_basename_noext.c_str()).append(".nv");
|
||||||
image_battery_load_by_name(device().machine().options(), fname.c_str(), buffer, length, def_buffer);
|
|
||||||
|
/* try to open the battery file and read it in, if possible */
|
||||||
|
emu_file file(device().machine().options().nvram_directory(), OPEN_FLAG_READ);
|
||||||
|
filerr = file.open(fname.c_str());
|
||||||
|
if (filerr == FILERR_NONE)
|
||||||
|
bytes_read = file.read(buffer, length);
|
||||||
|
|
||||||
|
/* if no file was present, copy the default battery */
|
||||||
|
if (bytes_read == 0 && def_buffer)
|
||||||
|
memcpy((char *)buffer, (char *)def_buffer, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-------------------------------------------------
|
/*-------------------------------------------------
|
||||||
@ -526,9 +552,14 @@ void device_image_interface::battery_load(void *buffer, int length, void *def_bu
|
|||||||
-------------------------------------------------*/
|
-------------------------------------------------*/
|
||||||
void device_image_interface::battery_save(const void *buffer, int length)
|
void device_image_interface::battery_save(const void *buffer, int length)
|
||||||
{
|
{
|
||||||
|
assert_always(buffer && (length > 0), "Must specify sensical buffer/length");
|
||||||
std::string fname = std::string(device().machine().system().name).append(PATH_SEPARATOR).append(m_basename_noext.c_str()).append(".nv");
|
std::string fname = std::string(device().machine().system().name).append(PATH_SEPARATOR).append(m_basename_noext.c_str()).append(".nv");
|
||||||
|
|
||||||
image_battery_save_by_name(device().machine().options(), fname.c_str(), buffer, length);
|
/* try to open the battery file and write it out, if possible */
|
||||||
|
emu_file file(device().machine().options().nvram_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
|
||||||
|
file_error filerr = file.open(fname.c_str());
|
||||||
|
if (filerr == FILERR_NONE)
|
||||||
|
file.write(buffer, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
@ -1350,3 +1381,41 @@ ui_menu *device_image_interface::get_selection_menu(running_machine &machine, re
|
|||||||
{
|
{
|
||||||
return auto_alloc_clear(machine, <ui_menu_control_device_image>(machine, container, this));
|
return auto_alloc_clear(machine, <ui_menu_control_device_image>(machine, container, this));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
static int image_fseek_thunk(void *file, INT64 offset, int whence)
|
||||||
|
{
|
||||||
|
device_image_interface *image = (device_image_interface *) file;
|
||||||
|
return image->fseek(offset, whence);
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t image_fread_thunk(void *file, void *buffer, size_t length)
|
||||||
|
{
|
||||||
|
device_image_interface *image = (device_image_interface *) file;
|
||||||
|
return image->fread(buffer, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t image_fwrite_thunk(void *file, const void *buffer, size_t length)
|
||||||
|
{
|
||||||
|
device_image_interface *image = (device_image_interface *) file;
|
||||||
|
return image->fwrite(buffer, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
static UINT64 image_fsize_thunk(void *file)
|
||||||
|
{
|
||||||
|
device_image_interface *image = (device_image_interface *) file;
|
||||||
|
return image->length();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
struct io_procs image_ioprocs =
|
||||||
|
{
|
||||||
|
nullptr,
|
||||||
|
image_fseek_thunk,
|
||||||
|
image_fread_thunk,
|
||||||
|
image_fwrite_thunk,
|
||||||
|
image_fsize_thunk
|
||||||
|
};
|
||||||
|
|
||||||
|
@ -21,6 +21,8 @@
|
|||||||
// TYPE DEFINITIONS
|
// TYPE DEFINITIONS
|
||||||
//**************************************************************************
|
//**************************************************************************
|
||||||
|
|
||||||
|
extern struct io_procs image_ioprocs;
|
||||||
|
|
||||||
class software_list;
|
class software_list;
|
||||||
|
|
||||||
enum iodevice_t
|
enum iodevice_t
|
||||||
|
@ -211,7 +211,7 @@ void driver_device::device_start()
|
|||||||
(*m_system->driver_init)(machine());
|
(*m_system->driver_init)(machine());
|
||||||
|
|
||||||
// finish image devices init process
|
// finish image devices init process
|
||||||
image_postdevice_init(machine());
|
machine().image().postdevice_init();
|
||||||
|
|
||||||
// start the various pieces
|
// start the various pieces
|
||||||
driver_start();
|
driver_start();
|
||||||
|
@ -15,192 +15,17 @@
|
|||||||
#include "image.h"
|
#include "image.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "xmlfile.h"
|
#include "xmlfile.h"
|
||||||
#include "formats/ioprocs.h"
|
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------- */
|
//**************************************************************************
|
||||||
|
// IMAGE MANAGER
|
||||||
|
//**************************************************************************
|
||||||
|
|
||||||
static int image_fseek_thunk(void *file, INT64 offset, int whence)
|
//-------------------------------------------------
|
||||||
{
|
// image_manager - constructor
|
||||||
device_image_interface *image = (device_image_interface *) file;
|
//-------------------------------------------------
|
||||||
return image->fseek(offset, whence);
|
|
||||||
}
|
|
||||||
|
|
||||||
static size_t image_fread_thunk(void *file, void *buffer, size_t length)
|
image_manager::image_manager(running_machine &machine)
|
||||||
{
|
: m_machine(machine)
|
||||||
device_image_interface *image = (device_image_interface *) file;
|
|
||||||
return image->fread(buffer, length);
|
|
||||||
}
|
|
||||||
|
|
||||||
static size_t image_fwrite_thunk(void *file, const void *buffer, size_t length)
|
|
||||||
{
|
|
||||||
device_image_interface *image = (device_image_interface *) file;
|
|
||||||
return image->fwrite(buffer, length);
|
|
||||||
}
|
|
||||||
|
|
||||||
static UINT64 image_fsize_thunk(void *file)
|
|
||||||
{
|
|
||||||
device_image_interface *image = (device_image_interface *) file;
|
|
||||||
return image->length();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
struct io_procs image_ioprocs =
|
|
||||||
{
|
|
||||||
nullptr,
|
|
||||||
image_fseek_thunk,
|
|
||||||
image_fread_thunk,
|
|
||||||
image_fwrite_thunk,
|
|
||||||
image_fsize_thunk
|
|
||||||
};
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
INITIALIZATION HELPERS
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
/*-------------------------------------------------
|
|
||||||
image_dirs_load - loads image device directory
|
|
||||||
configuration items
|
|
||||||
-------------------------------------------------*/
|
|
||||||
|
|
||||||
static void image_dirs_load(running_machine &machine, config_type cfg_type, xml_data_node *parentnode)
|
|
||||||
{
|
|
||||||
xml_data_node *node;
|
|
||||||
const char *dev_instance;
|
|
||||||
const char *working_directory;
|
|
||||||
|
|
||||||
if ((cfg_type == config_type::CONFIG_TYPE_GAME) && (parentnode != nullptr))
|
|
||||||
{
|
|
||||||
for (node = xml_get_sibling(parentnode->child, "device"); node; node = xml_get_sibling(node->next, "device"))
|
|
||||||
{
|
|
||||||
dev_instance = xml_get_attribute_string(node, "instance", nullptr);
|
|
||||||
|
|
||||||
if ((dev_instance != nullptr) && (dev_instance[0] != '\0'))
|
|
||||||
{
|
|
||||||
image_interface_iterator iter(machine.root_device());
|
|
||||||
for (device_image_interface *image = iter.first(); image != nullptr; image = iter.next())
|
|
||||||
{
|
|
||||||
if (!strcmp(dev_instance, image->instance_name())) {
|
|
||||||
working_directory = xml_get_attribute_string(node, "directory", nullptr);
|
|
||||||
if (working_directory != nullptr)
|
|
||||||
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, config_type cfg_type, xml_data_node *parentnode)
|
|
||||||
{
|
|
||||||
xml_data_node *node;
|
|
||||||
const char *dev_instance;
|
|
||||||
|
|
||||||
/* only care about game-specific data */
|
|
||||||
if (cfg_type == config_type::CONFIG_TYPE_GAME)
|
|
||||||
{
|
|
||||||
image_interface_iterator iter(machine.root_device());
|
|
||||||
for (device_image_interface *image = iter.first(); image != nullptr; image = iter.next())
|
|
||||||
{
|
|
||||||
dev_instance = image->instance_name();
|
|
||||||
|
|
||||||
node = xml_add_child(parentnode, "device", nullptr);
|
|
||||||
if (node != nullptr)
|
|
||||||
{
|
|
||||||
xml_set_attribute(node, "instance", dev_instance);
|
|
||||||
xml_set_attribute(node, "directory", image->working_directory());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*-------------------------------------------------
|
|
||||||
write_config - emit current option statuses as
|
|
||||||
INI files
|
|
||||||
-------------------------------------------------*/
|
|
||||||
|
|
||||||
static int write_config(emu_options &options, const char *filename, const game_driver *gamedrv)
|
|
||||||
{
|
|
||||||
char buffer[128];
|
|
||||||
int retval = 1;
|
|
||||||
|
|
||||||
if (gamedrv != nullptr)
|
|
||||||
{
|
|
||||||
sprintf(buffer, "%s.ini", gamedrv->name);
|
|
||||||
filename = buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
emu_file file(options.ini_path(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE);
|
|
||||||
file_error filerr = file.open(filename);
|
|
||||||
if (filerr == FILERR_NONE)
|
|
||||||
{
|
|
||||||
std::string inistring = options.output_ini();
|
|
||||||
file.puts(inistring.c_str());
|
|
||||||
retval = 0;
|
|
||||||
}
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*-------------------------------------------------
|
|
||||||
image_options_extract - extract device options
|
|
||||||
out of core into the options
|
|
||||||
-------------------------------------------------*/
|
|
||||||
|
|
||||||
static void image_options_extract(running_machine &machine)
|
|
||||||
{
|
|
||||||
/* only extract the device options if we've added them
|
|
||||||
no need to assert in case they are missing */
|
|
||||||
{
|
|
||||||
int index = 0;
|
|
||||||
|
|
||||||
image_interface_iterator iter(machine.root_device());
|
|
||||||
for (device_image_interface *image = iter.first(); image != nullptr; image = iter.next())
|
|
||||||
{
|
|
||||||
const char *filename = image->filename();
|
|
||||||
|
|
||||||
/* and set the option */
|
|
||||||
std::string error;
|
|
||||||
machine.options().set_value(image->instance_name(), filename ? filename : "", OPTION_PRIORITY_CMDLINE, error);
|
|
||||||
|
|
||||||
index++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* write the config, if appropriate */
|
|
||||||
if (machine.options().write_config())
|
|
||||||
write_config(machine.options(), nullptr, &machine.system());
|
|
||||||
}
|
|
||||||
|
|
||||||
/*-------------------------------------------------
|
|
||||||
image_unload_all - unload all images and
|
|
||||||
extract options
|
|
||||||
-------------------------------------------------*/
|
|
||||||
|
|
||||||
void image_unload_all(running_machine &machine)
|
|
||||||
{
|
|
||||||
// extract the options
|
|
||||||
image_options_extract(machine);
|
|
||||||
|
|
||||||
image_interface_iterator iter(machine.root_device());
|
|
||||||
for (device_image_interface *image = iter.first(); image != nullptr; image = iter.next())
|
|
||||||
{
|
|
||||||
// unload this image
|
|
||||||
image->unload();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*-------------------------------------------------
|
|
||||||
image_device_init - initialize devices for a specific
|
|
||||||
running_machine
|
|
||||||
-------------------------------------------------*/
|
|
||||||
|
|
||||||
void image_device_init(running_machine &machine)
|
|
||||||
{
|
{
|
||||||
const char *image_name;
|
const char *image_name;
|
||||||
|
|
||||||
@ -226,9 +51,6 @@ void image_device_init(running_machine &machine)
|
|||||||
std::string image_err = std::string(image->error());
|
std::string image_err = std::string(image->error());
|
||||||
std::string image_basename(image_name);
|
std::string image_basename(image_name);
|
||||||
|
|
||||||
/* unload all images */
|
|
||||||
image_unload_all(machine);
|
|
||||||
|
|
||||||
fatalerror_exitcode(machine, MAMERR_DEVICE, "Device %s load (%s) failed: %s",
|
fatalerror_exitcode(machine, MAMERR_DEVICE, "Device %s load (%s) failed: %s",
|
||||||
image->device().name(),
|
image->device().name(),
|
||||||
image_basename.c_str(),
|
image_basename.c_str(),
|
||||||
@ -236,18 +58,150 @@ void image_device_init(running_machine &machine)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
machine.configuration().config_register("image_directories", config_saveload_delegate(FUNC(image_manager::config_load), this), config_saveload_delegate(FUNC(image_manager::config_save), this));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// image_manager - destructor
|
||||||
|
//-------------------------------------------------
|
||||||
|
image_manager::~image_manager()
|
||||||
|
{
|
||||||
|
// extract the options
|
||||||
|
options_extract();
|
||||||
|
|
||||||
|
image_interface_iterator iter(machine().root_device());
|
||||||
|
for (device_image_interface *image = iter.first(); image != nullptr; image = iter.next())
|
||||||
|
{
|
||||||
|
// unload this image
|
||||||
|
image->unload();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void image_manager::config_load(config_type cfg_type, xml_data_node *parentnode)
|
||||||
|
{
|
||||||
|
xml_data_node *node;
|
||||||
|
const char *dev_instance;
|
||||||
|
const char *working_directory;
|
||||||
|
|
||||||
|
if ((cfg_type == config_type::CONFIG_TYPE_GAME) && (parentnode != nullptr))
|
||||||
|
{
|
||||||
|
for (node = xml_get_sibling(parentnode->child, "device"); node; node = xml_get_sibling(node->next, "device"))
|
||||||
|
{
|
||||||
|
dev_instance = xml_get_attribute_string(node, "instance", nullptr);
|
||||||
|
|
||||||
|
if ((dev_instance != nullptr) && (dev_instance[0] != '\0'))
|
||||||
|
{
|
||||||
|
image_interface_iterator iter(machine().root_device());
|
||||||
|
for (device_image_interface *image = iter.first(); image != nullptr; image = iter.next())
|
||||||
|
{
|
||||||
|
if (!strcmp(dev_instance, image->instance_name())) {
|
||||||
|
working_directory = xml_get_attribute_string(node, "directory", nullptr);
|
||||||
|
if (working_directory != nullptr)
|
||||||
|
image->set_working_directory(working_directory);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
config_save - saves out image device
|
||||||
|
directories to the configuration file
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
void image_manager::config_save(config_type cfg_type, xml_data_node *parentnode)
|
||||||
|
{
|
||||||
|
xml_data_node *node;
|
||||||
|
const char *dev_instance;
|
||||||
|
|
||||||
|
/* only care about game-specific data */
|
||||||
|
if (cfg_type == config_type::CONFIG_TYPE_GAME)
|
||||||
|
{
|
||||||
|
image_interface_iterator iter(machine().root_device());
|
||||||
|
for (device_image_interface *image = iter.first(); image != nullptr; image = iter.next())
|
||||||
|
{
|
||||||
|
dev_instance = image->instance_name();
|
||||||
|
|
||||||
|
node = xml_add_child(parentnode, "device", nullptr);
|
||||||
|
if (node != nullptr)
|
||||||
|
{
|
||||||
|
xml_set_attribute(node, "instance", dev_instance);
|
||||||
|
xml_set_attribute(node, "directory", image->working_directory());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
write_config - emit current option statuses as
|
||||||
|
INI files
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
int image_manager::write_config(emu_options &options, const char *filename, const game_driver *gamedrv)
|
||||||
|
{
|
||||||
|
char buffer[128];
|
||||||
|
int retval = 1;
|
||||||
|
|
||||||
|
if (gamedrv != nullptr)
|
||||||
|
{
|
||||||
|
sprintf(buffer, "%s.ini", gamedrv->name);
|
||||||
|
filename = buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
emu_file file(options.ini_path(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE);
|
||||||
|
file_error filerr = file.open(filename);
|
||||||
|
if (filerr == FILERR_NONE)
|
||||||
|
{
|
||||||
|
std::string inistring = options.output_ini();
|
||||||
|
file.puts(inistring.c_str());
|
||||||
|
retval = 0;
|
||||||
|
}
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
options_extract - extract device options
|
||||||
|
out of core into the options
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
void image_manager::options_extract()
|
||||||
|
{
|
||||||
|
/* only extract the device options if we've added them
|
||||||
|
no need to assert in case they are missing */
|
||||||
|
{
|
||||||
|
int index = 0;
|
||||||
|
|
||||||
|
image_interface_iterator iter(machine().root_device());
|
||||||
|
for (device_image_interface *image = iter.first(); image != nullptr; image = iter.next())
|
||||||
|
{
|
||||||
|
const char *filename = image->filename();
|
||||||
|
|
||||||
|
/* and set the option */
|
||||||
|
std::string error;
|
||||||
|
machine().options().set_value(image->instance_name(), filename ? filename : "", OPTION_PRIORITY_CMDLINE, error);
|
||||||
|
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* write the config, if appropriate */
|
||||||
|
if (machine().options().write_config())
|
||||||
|
write_config(machine().options(), nullptr, &machine().system());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*-------------------------------------------------
|
/*-------------------------------------------------
|
||||||
image_mandatory_scan - search for devices which
|
image_mandatory_scan - search for devices which
|
||||||
need an image to be loaded
|
need an image to be loaded
|
||||||
-------------------------------------------------*/
|
-------------------------------------------------*/
|
||||||
|
|
||||||
std::string &image_mandatory_scan(running_machine &machine, std::string &mandatory)
|
std::string &image_manager::mandatory_scan(std::string &mandatory)
|
||||||
{
|
{
|
||||||
mandatory.clear();
|
mandatory.clear();
|
||||||
// make sure that any required image has a mounted file
|
// make sure that any required image has a mounted file
|
||||||
image_interface_iterator iter(machine.root_device());
|
image_interface_iterator iter(machine().root_device());
|
||||||
for (device_image_interface *image = iter.first(); image != nullptr; image = iter.next())
|
for (device_image_interface *image = iter.first(); image != nullptr; image = iter.next())
|
||||||
{
|
{
|
||||||
if (image->filename() == nullptr && image->must_be_loaded())
|
if (image->filename() == nullptr && image->must_be_loaded())
|
||||||
@ -257,14 +211,14 @@ std::string &image_mandatory_scan(running_machine &machine, std::string &mandato
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*-------------------------------------------------
|
/*-------------------------------------------------
|
||||||
image_postdevice_init - initialize devices for a specific
|
postdevice_init - initialize devices for a specific
|
||||||
running_machine
|
running_machine
|
||||||
-------------------------------------------------*/
|
-------------------------------------------------*/
|
||||||
|
|
||||||
void image_postdevice_init(running_machine &machine)
|
void image_manager::postdevice_init()
|
||||||
{
|
{
|
||||||
/* make sure that any required devices have been allocated */
|
/* make sure that any required devices have been allocated */
|
||||||
image_interface_iterator iter(machine.root_device());
|
image_interface_iterator iter(machine().root_device());
|
||||||
for (device_image_interface *image = iter.first(); image != nullptr; image = iter.next())
|
for (device_image_interface *image = iter.first(); image != nullptr; image = iter.next())
|
||||||
{
|
{
|
||||||
int result = image->finish_load();
|
int result = image->finish_load();
|
||||||
@ -274,99 +228,10 @@ void image_postdevice_init(running_machine &machine)
|
|||||||
/* retrieve image error message */
|
/* retrieve image error message */
|
||||||
std::string image_err = std::string(image->error());
|
std::string image_err = std::string(image->error());
|
||||||
|
|
||||||
/* unload all images */
|
fatalerror_exitcode(machine(), MAMERR_DEVICE, "Device %s load failed: %s",
|
||||||
image_unload_all(machine);
|
|
||||||
|
|
||||||
fatalerror_exitcode(machine, MAMERR_DEVICE, "Device %s load failed: %s",
|
|
||||||
image->device().name(),
|
image->device().name(),
|
||||||
image_err.c_str());
|
image_err.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add a callback for when we shut down */
|
|
||||||
machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(image_unload_all), &machine));
|
|
||||||
}
|
|
||||||
/***************************************************************************
|
|
||||||
INITIALIZATION
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
/*-------------------------------------------------
|
|
||||||
image_init - start up the image system
|
|
||||||
-------------------------------------------------*/
|
|
||||||
|
|
||||||
void image_init(running_machine &machine)
|
|
||||||
{
|
|
||||||
image_device_init(machine);
|
|
||||||
machine.configuration().config_register("image_directories", config_saveload_delegate(FUNC(image_dirs_load), &machine), config_saveload_delegate(FUNC(image_dirs_save), &machine));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
Battery functions
|
|
||||||
|
|
||||||
These functions provide transparent access to battery-backed RAM on an
|
|
||||||
image; typically for cartridges.
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/*-------------------------------------------------
|
|
||||||
image_battery_load_by_name - retrieves the battery
|
|
||||||
backed RAM for an image. A filename may be supplied
|
|
||||||
to the function.
|
|
||||||
|
|
||||||
The function comes in two flavors, depending on
|
|
||||||
what should happen when no battery is available:
|
|
||||||
we could fill the memory with a given value, or
|
|
||||||
pass a default battery (for a pre-initialized
|
|
||||||
battery from factory)
|
|
||||||
-------------------------------------------------*/
|
|
||||||
|
|
||||||
void image_battery_load_by_name(emu_options &options, const char *filename, void *buffer, int length, int fill)
|
|
||||||
{
|
|
||||||
file_error filerr;
|
|
||||||
int bytes_read = 0;
|
|
||||||
|
|
||||||
assert_always(buffer && (length > 0), "Must specify sensical buffer/length");
|
|
||||||
|
|
||||||
/* try to open the battery file and read it in, if possible */
|
|
||||||
emu_file file(options.nvram_directory(), OPEN_FLAG_READ);
|
|
||||||
filerr = file.open(filename);
|
|
||||||
if (filerr == FILERR_NONE)
|
|
||||||
bytes_read = file.read(buffer, length);
|
|
||||||
|
|
||||||
/* fill remaining bytes (if necessary) */
|
|
||||||
memset(((char *) buffer) + bytes_read, fill, length - bytes_read);
|
|
||||||
}
|
|
||||||
|
|
||||||
void image_battery_load_by_name(emu_options &options, const char *filename, void *buffer, int length, void *def_buffer)
|
|
||||||
{
|
|
||||||
file_error filerr;
|
|
||||||
int bytes_read = 0;
|
|
||||||
|
|
||||||
assert_always(buffer && (length > 0), "Must specify sensical buffer/length");
|
|
||||||
|
|
||||||
/* try to open the battery file and read it in, if possible */
|
|
||||||
emu_file file(options.nvram_directory(), OPEN_FLAG_READ);
|
|
||||||
filerr = file.open(filename);
|
|
||||||
if (filerr == FILERR_NONE)
|
|
||||||
bytes_read = file.read(buffer, length);
|
|
||||||
|
|
||||||
/* if no file was present, copy the default battery */
|
|
||||||
if (bytes_read == 0 && def_buffer)
|
|
||||||
memcpy((char *) buffer, (char *) def_buffer, length);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*-------------------------------------------------
|
|
||||||
image_battery_save_by_name - stores the battery
|
|
||||||
backed RAM for an image. A filename may be supplied
|
|
||||||
to the function.
|
|
||||||
-------------------------------------------------*/
|
|
||||||
void image_battery_save_by_name(emu_options &options, const char *filename, const void *buffer, int length)
|
|
||||||
{
|
|
||||||
assert_always(buffer && (length > 0), "Must specify sensical buffer/length");
|
|
||||||
|
|
||||||
/* try to open the battery file and write it out, if possible */
|
|
||||||
emu_file file(options.nvram_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
|
|
||||||
file_error filerr = file.open(filename);
|
|
||||||
if (filerr == FILERR_NONE)
|
|
||||||
file.write(buffer, length);
|
|
||||||
}
|
|
||||||
|
@ -13,14 +13,29 @@
|
|||||||
#ifndef __IMAGE_H__
|
#ifndef __IMAGE_H__
|
||||||
#define __IMAGE_H__
|
#define __IMAGE_H__
|
||||||
|
|
||||||
void image_init(running_machine &machine);
|
// ======================> image_manager
|
||||||
void image_postdevice_init(running_machine &machine);
|
|
||||||
std::string &image_mandatory_scan(running_machine &machine, std::string &mandatory);
|
|
||||||
|
|
||||||
extern struct io_procs image_ioprocs;
|
class image_manager
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// construction/destruction
|
||||||
|
image_manager(running_machine &machine);
|
||||||
|
~image_manager();
|
||||||
|
|
||||||
void image_battery_load_by_name(emu_options &options, const char *filename, void *buffer, int length, int fill);
|
void postdevice_init();
|
||||||
void image_battery_load_by_name(emu_options &options, const char *filename, void *buffer, int length, void *def_buffer);
|
std::string &mandatory_scan(std::string &mandatory);
|
||||||
void image_battery_save_by_name(emu_options &options, const char *filename, const void *buffer, int length);
|
|
||||||
|
// getters
|
||||||
|
running_machine &machine() const { return m_machine; }
|
||||||
|
private:
|
||||||
|
void config_load(config_type cfg_type, xml_data_node *parentnode);
|
||||||
|
void config_save(config_type cfg_type, xml_data_node *parentnode);
|
||||||
|
|
||||||
|
void options_extract();
|
||||||
|
int write_config(emu_options &options, const char *filename, const game_driver *gamedrv);
|
||||||
|
|
||||||
|
// internal state
|
||||||
|
running_machine & m_machine; // reference to our machine
|
||||||
|
};
|
||||||
|
|
||||||
#endif /* __IMAGE_H__ */
|
#endif /* __IMAGE_H__ */
|
||||||
|
@ -264,7 +264,7 @@ void running_machine::start()
|
|||||||
save().save_item(NAME(m_rand_seed));
|
save().save_item(NAME(m_rand_seed));
|
||||||
|
|
||||||
// initialize image devices
|
// initialize image devices
|
||||||
image_init(*this);
|
m_image = std::make_unique<image_manager>(*this);
|
||||||
m_tilemap = std::make_unique<tilemap_manager>(*this);
|
m_tilemap = std::make_unique<tilemap_manager>(*this);
|
||||||
m_crosshair = make_unique_clear<crosshair_manager>(*this);
|
m_crosshair = make_unique_clear<crosshair_manager>(*this);
|
||||||
m_network = std::make_unique<network_manager>(*this);
|
m_network = std::make_unique<network_manager>(*this);
|
||||||
|
@ -91,6 +91,7 @@ class configuration_manager;
|
|||||||
class output_manager;
|
class output_manager;
|
||||||
class ui_input_manager;
|
class ui_input_manager;
|
||||||
class crosshair_manager;
|
class crosshair_manager;
|
||||||
|
class image_manager;
|
||||||
class osd_interface;
|
class osd_interface;
|
||||||
enum class config_type;
|
enum class config_type;
|
||||||
|
|
||||||
@ -175,6 +176,7 @@ public:
|
|||||||
ui_manager &ui() const { assert(m_ui != nullptr); return *m_ui; }
|
ui_manager &ui() const { assert(m_ui != nullptr); return *m_ui; }
|
||||||
ui_input_manager &ui_input() const { assert(m_ui_input != nullptr); return *m_ui_input; }
|
ui_input_manager &ui_input() const { assert(m_ui_input != nullptr); return *m_ui_input; }
|
||||||
crosshair_manager &crosshair() const { assert(m_crosshair != nullptr); return *m_crosshair; }
|
crosshair_manager &crosshair() const { assert(m_crosshair != nullptr); return *m_crosshair; }
|
||||||
|
image_manager &image() const { assert(m_image != nullptr); return *m_image; }
|
||||||
tilemap_manager &tilemap() const { assert(m_tilemap != nullptr); return *m_tilemap; }
|
tilemap_manager &tilemap() const { assert(m_tilemap != nullptr); return *m_tilemap; }
|
||||||
debug_view_manager &debug_view() const { assert(m_debug_view != nullptr); return *m_debug_view; }
|
debug_view_manager &debug_view() const { assert(m_debug_view != nullptr); return *m_debug_view; }
|
||||||
driver_device *driver_data() const { return &downcast<driver_device &>(root_device()); }
|
driver_device *driver_data() const { return &downcast<driver_device &>(root_device()); }
|
||||||
@ -293,6 +295,7 @@ private:
|
|||||||
std::unique_ptr<configuration_manager> m_configuration; // internal data from config.c
|
std::unique_ptr<configuration_manager> m_configuration; // internal data from config.c
|
||||||
std::unique_ptr<output_manager> m_output; // internal data from output.c
|
std::unique_ptr<output_manager> m_output; // internal data from output.c
|
||||||
std::unique_ptr<crosshair_manager> m_crosshair; // internal data from crsshair.c
|
std::unique_ptr<crosshair_manager> m_crosshair; // internal data from crsshair.c
|
||||||
|
std::unique_ptr<image_manager> m_image; // internal data from image.c
|
||||||
|
|
||||||
// system state
|
// system state
|
||||||
machine_phase m_current_phase; // current execution phase
|
machine_phase m_current_phase; // current execution phase
|
||||||
|
@ -358,7 +358,7 @@ void ui_manager::display_startup_screens(bool first_time, bool show_disclaimer)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 3:
|
case 3:
|
||||||
if (show_mandatory_fileman && image_mandatory_scan(machine(), messagebox_text).length() > 0)
|
if (show_mandatory_fileman && machine().image().mandatory_scan(messagebox_text).length() > 0)
|
||||||
{
|
{
|
||||||
std::string warning;
|
std::string warning;
|
||||||
warning.assign("This driver requires images to be loaded in the following device(s): ").append(messagebox_text.substr(0, messagebox_text.length() - 2));
|
warning.assign("This driver requires images to be loaded in the following device(s): ").append(messagebox_text.substr(0, messagebox_text.length() - 2));
|
||||||
|
Loading…
Reference in New Issue
Block a user