mirror of
https://github.com/holub/mame
synced 2025-04-25 09:50:04 +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 "formats/ioprocs.h"
|
||||
#include "image.h"
|
||||
|
||||
#define VERBOSE 0
|
||||
|
||||
|
@ -134,6 +134,52 @@
|
||||
#define GKRACKER_ROM_TAG "gkracker_rom"
|
||||
#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)
|
||||
: bus8z_device(mconfig, GROMPORT, "Cartridge port", tag, owner, clock, "gromport", __FILE__),
|
||||
device_slot_interface(mconfig, *this),
|
||||
|
@ -12,7 +12,6 @@
|
||||
#include "formats/imageutl.h"
|
||||
#include "cassette.h"
|
||||
#include "ui/ui.h"
|
||||
#include "image.h"
|
||||
|
||||
|
||||
#define ANIMATION_FPS 1
|
||||
|
@ -16,7 +16,6 @@
|
||||
#include "emu.h"
|
||||
#include "formats/imageutl.h"
|
||||
#include "flopdrv.h"
|
||||
#include "image.h"
|
||||
|
||||
#define VERBOSE 0
|
||||
#define LOG(x) do { if (VERBOSE) logerror x; } while (0)
|
||||
|
@ -12,7 +12,6 @@
|
||||
#include "zippath.h"
|
||||
#include "floppy.h"
|
||||
#include "formats/imageutl.h"
|
||||
#include "image.h"
|
||||
|
||||
/*
|
||||
Debugging flags. Set to 0 or 1.
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "ui/imgcntrl.h"
|
||||
#include "softlist.h"
|
||||
#include "image.h"
|
||||
#include "formats/ioprocs.h"
|
||||
|
||||
//**************************************************************************
|
||||
// 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)
|
||||
{
|
||||
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");
|
||||
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)
|
||||
{
|
||||
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");
|
||||
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)
|
||||
{
|
||||
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");
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
||||
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
|
||||
//**************************************************************************
|
||||
|
||||
extern struct io_procs image_ioprocs;
|
||||
|
||||
class software_list;
|
||||
|
||||
enum iodevice_t
|
||||
|
@ -211,7 +211,7 @@ void driver_device::device_start()
|
||||
(*m_system->driver_init)(machine());
|
||||
|
||||
// finish image devices init process
|
||||
image_postdevice_init(machine());
|
||||
machine().image().postdevice_init();
|
||||
|
||||
// start the various pieces
|
||||
driver_start();
|
||||
|
@ -15,192 +15,17 @@
|
||||
#include "image.h"
|
||||
#include "config.h"
|
||||
#include "xmlfile.h"
|
||||
#include "formats/ioprocs.h"
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
//**************************************************************************
|
||||
// IMAGE MANAGER
|
||||
//**************************************************************************
|
||||
|
||||
static int image_fseek_thunk(void *file, INT64 offset, int whence)
|
||||
{
|
||||
device_image_interface *image = (device_image_interface *) file;
|
||||
return image->fseek(offset, whence);
|
||||
}
|
||||
//-------------------------------------------------
|
||||
// image_manager - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
/***************************************************************************
|
||||
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)
|
||||
image_manager::image_manager(running_machine &machine)
|
||||
: m_machine(machine)
|
||||
{
|
||||
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_basename(image_name);
|
||||
|
||||
/* unload all images */
|
||||
image_unload_all(machine);
|
||||
|
||||
fatalerror_exitcode(machine, MAMERR_DEVICE, "Device %s load (%s) failed: %s",
|
||||
image->device().name(),
|
||||
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
|
||||
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();
|
||||
// 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())
|
||||
{
|
||||
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
|
||||
-------------------------------------------------*/
|
||||
|
||||
void image_postdevice_init(running_machine &machine)
|
||||
void image_manager::postdevice_init()
|
||||
{
|
||||
/* 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())
|
||||
{
|
||||
int result = image->finish_load();
|
||||
@ -274,99 +228,10 @@ void image_postdevice_init(running_machine &machine)
|
||||
/* retrieve image error message */
|
||||
std::string image_err = std::string(image->error());
|
||||
|
||||
/* unload all images */
|
||||
image_unload_all(machine);
|
||||
|
||||
fatalerror_exitcode(machine, MAMERR_DEVICE, "Device %s load failed: %s",
|
||||
fatalerror_exitcode(machine(), MAMERR_DEVICE, "Device %s load failed: %s",
|
||||
image->device().name(),
|
||||
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__
|
||||
#define __IMAGE_H__
|
||||
|
||||
void image_init(running_machine &machine);
|
||||
void image_postdevice_init(running_machine &machine);
|
||||
std::string &image_mandatory_scan(running_machine &machine, std::string &mandatory);
|
||||
// ======================> image_manager
|
||||
|
||||
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 image_battery_load_by_name(emu_options &options, const char *filename, void *buffer, int length, void *def_buffer);
|
||||
void image_battery_save_by_name(emu_options &options, const char *filename, const void *buffer, int length);
|
||||
void postdevice_init();
|
||||
std::string &mandatory_scan(std::string &mandatory);
|
||||
|
||||
// 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__ */
|
||||
|
@ -264,7 +264,7 @@ void running_machine::start()
|
||||
save().save_item(NAME(m_rand_seed));
|
||||
|
||||
// initialize image devices
|
||||
image_init(*this);
|
||||
m_image = std::make_unique<image_manager>(*this);
|
||||
m_tilemap = std::make_unique<tilemap_manager>(*this);
|
||||
m_crosshair = make_unique_clear<crosshair_manager>(*this);
|
||||
m_network = std::make_unique<network_manager>(*this);
|
||||
|
@ -91,6 +91,7 @@ class configuration_manager;
|
||||
class output_manager;
|
||||
class ui_input_manager;
|
||||
class crosshair_manager;
|
||||
class image_manager;
|
||||
class osd_interface;
|
||||
enum class config_type;
|
||||
|
||||
@ -175,6 +176,7 @@ public:
|
||||
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; }
|
||||
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; }
|
||||
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()); }
|
||||
@ -293,6 +295,7 @@ private:
|
||||
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<crosshair_manager> m_crosshair; // internal data from crsshair.c
|
||||
std::unique_ptr<image_manager> m_image; // internal data from image.c
|
||||
|
||||
// system state
|
||||
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;
|
||||
|
||||
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;
|
||||
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