- Moved ioproc implementation from MESS [Miodrag Milanovic]

- Implemented more image device calls, and did some cleanup (no whatsnew)
This commit is contained in:
Miodrag Milanovic 2010-06-23 19:35:49 +00:00
parent c660837bb3
commit ea8dd94677
13 changed files with 617 additions and 169 deletions

2
.gitattributes vendored
View File

@ -618,6 +618,8 @@ src/emu/input.c svneol=native#text/plain
src/emu/input.h svneol=native#text/plain
src/emu/inputseq.c svneol=native#text/plain
src/emu/inputseq.h svneol=native#text/plain
src/emu/ioprocs.c svneol=native#text/plain
src/emu/ioprocs.h svneol=native#text/plain
src/emu/layout/dualhovu.lay svneol=native#text/plain
src/emu/layout/dualhsxs.lay svneol=native#text/plain
src/emu/layout/dualhuov.lay svneol=native#text/plain

View File

@ -87,13 +87,6 @@ void legacy_image_device_config_base::device_config_complete()
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);
@ -414,19 +407,19 @@ bool legacy_image_device_base::finish_load()
if (m_is_loading)
{
if (has_been_created() && ((*m_image_config.create_func()) != NULL))
if (has_been_created())
{
err = (*m_image_config.create_func())(*this, m_create_format, m_create_args);
err = call_create(m_create_format, m_create_args);
if (err)
{
if (!m_err)
m_err = IMAGE_ERROR_UNSPECIFIED;
}
}
else if ((*m_image_config.load_func()) != NULL)
else
{
/* using device load */
err = (*m_image_config.load_func())(*this);
err = call_load();
if (err)
{
if (!m_err)
@ -492,3 +485,51 @@ void legacy_image_device_base::unload()
clear();
}
int legacy_image_device_base::call_load()
{
device_image_load_func func = reinterpret_cast<device_image_load_func>(m_config.get_legacy_config_fct(DEVINFO_FCT_IMAGE_LOAD));
if (func) {
return (*func)(*this);
} else {
return FALSE;
}
}
int legacy_image_device_base::call_create(int format_type, option_resolution *format_options)
{
device_image_create_func func = reinterpret_cast<device_image_create_func>(m_config.get_legacy_config_fct(DEVINFO_FCT_IMAGE_CREATE));
if (func) {
return (*func)(*this,format_type,format_options);
} else {
return FALSE;
}
}
void legacy_image_device_base::call_unload()
{
device_image_unload_func func = reinterpret_cast<device_image_unload_func>(m_config.get_legacy_config_fct(DEVINFO_FCT_IMAGE_UNLOAD));
if (func) (*func)(*this);
}
void legacy_image_device_base::call_display()
{
device_image_display_func func = reinterpret_cast<device_image_display_func>(m_config.get_legacy_config_fct(DEVINFO_FCT_IMAGE_DISPLAY));
if (func) (*func)(*this);
}
void legacy_image_device_base::call_partial_hash(char *dest, const unsigned char *data, unsigned long length, unsigned int functions)
{
device_image_partialhash_func func = reinterpret_cast<device_image_partialhash_func>(m_config.get_legacy_config_fct(DEVINFO_FCT_IMAGE_PARTIAL_HASH));
if (func) (*func)(dest,data,length,functions);
}
void legacy_image_device_base::call_get_devices()
{
device_image_get_devices_func func = reinterpret_cast<device_image_get_devices_func>(m_config.get_legacy_config_fct(DEVINFO_FCT_IMAGE_GET_DEVICES));
if (func) (*func)(*this);
}
void *legacy_image_device_base::get_device_specific_call()
{
return (void*) m_config.get_legacy_config_fct(DEVINFO_FCT_DEVICE_SPECIFIC);
}

View File

@ -419,6 +419,7 @@ class legacy_device_config_base : public device_config
{
friend class legacy_device_base;
friend class legacy_nvram_device_base;
friend class legacy_image_device_base;
protected:
// construction/destruction
@ -575,7 +576,6 @@ protected:
class legacy_image_device_config_base : public legacy_device_config_base,
public device_config_image_interface
{
friend class legacy_image_device_base;
public:
virtual const char *name() const { return get_legacy_config_string(DEVINFO_STR_NAME); }
virtual iodevice_t image_type() const { return m_type; }
@ -594,9 +594,6 @@ public:
virtual bool uses_file_extension(const char *file_extension) const;
virtual const option_guide *create_option_guide() const { return m_create_option_guide; }
virtual image_device_format *formatlist() const { return m_formatlist; }
virtual device_image_load_func load_func() const { return load; }
virtual device_image_create_func create_func() const { return create; }
virtual device_image_unload_func unload_func() const { return unload; }
protected:
// 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);
@ -616,14 +613,7 @@ protected:
astring m_instance_name;
astring m_brief_instance_name;
astring m_interface_name;
device_image_load_func load;
device_image_create_func create;
device_image_unload_func unload;
device_image_display_func display;
device_image_partialhash_func partialhash;
device_image_get_devices_func get_devices;
/* creation info */
const option_guide *m_create_option_guide;
image_device_format *m_formatlist;
@ -636,12 +626,20 @@ protected:
class legacy_image_device_base : public legacy_device_base,
public device_image_interface
{
friend class legacy_image_device_config_base;
public:
virtual bool load(const char *path);
virtual bool finish_load();
virtual void unload();
virtual bool create(const char *path, const image_device_format *create_format, option_resolution *create_args);
virtual int call_load();
virtual int call_create(int format_type, option_resolution *format_options);
virtual void call_unload();
virtual void call_display();
virtual void call_partial_hash(char *, const unsigned char *, unsigned long, unsigned int);
virtual void call_get_devices();
virtual void *get_device_specific_call();
protected:
// construction/destruction
legacy_image_device_base(running_machine &machine, const device_config &config);

View File

@ -39,6 +39,7 @@
#include "emu.h"
#include "ui.h"
#include "pool.h"
#include "zippath.h"
@ -124,6 +125,16 @@ const char *device_config_image_interface::device_brieftypename(iodevice_t type)
// DEVICE image INTERFACE
//**************************************************************************
/*-------------------------------------------------
memory_error - report a memory error
-------------------------------------------------*/
static void memory_error(const char *message)
{
fatalerror("%s", message);
}
//-------------------------------------------------
// device_image_interface - constructor
//-------------------------------------------------
@ -136,6 +147,7 @@ device_image_interface::device_image_interface(running_machine &machine, const d
m_software_info_ptr(NULL),
m_software_part_ptr(NULL)
{
m_mempool = pool_alloc_lib(memory_error);
}
@ -145,17 +157,9 @@ device_image_interface::device_image_interface(running_machine &machine, const d
device_image_interface::~device_image_interface()
{
pool_free_lib(m_mempool);
}
/*-------------------------------------------------
display - call image display callback function
-------------------------------------------------*/
void device_image_interface::display()
{
}
/*-------------------------------------------------
set_image_filename - specifies the filename of
an image
@ -432,3 +436,30 @@ const char *device_image_interface::get_feature(const char *feature_name)
return NULL;
}
/****************************************************************************
Memory allocators
These allow memory to be allocated for the lifetime of a mounted image.
If these (and the above accessors) are used well enough, they should be
able to eliminate the need for a unload function.
****************************************************************************/
void *device_image_interface::image_malloc(size_t size)
{
return image_realloc(NULL, size);
}
char *device_image_interface::image_strdup(const char *src)
{
return pool_strdup_lib(m_mempool, src);
}
void *device_image_interface::image_realloc(void *ptr, size_t size)
{
return pool_realloc_lib(m_mempool, ptr, size);
}
void device_image_interface::image_freeptr(void *ptr)
{
pool_object_remove(m_mempool, ptr, 0);
}

View File

@ -46,6 +46,7 @@
#ifndef __DIIMAGE_H__
#define __DIIMAGE_H__
#include "pool.h"
//**************************************************************************
// TYPE DEFINITIONS
@ -168,11 +169,6 @@ public:
static const char *device_typename(iodevice_t type);
static const char *device_brieftypename(iodevice_t type);
virtual device_image_load_func load_func() const = 0;
virtual device_image_create_func create_func() const = 0;
virtual device_image_unload_func unload_func() const = 0;
protected:
static const image_device_type_info *find_device_type(iodevice_t type);
static const image_device_type_info m_device_info_array[];
@ -195,11 +191,17 @@ public:
virtual bool finish_load() = 0;
virtual void unload() = 0;
virtual void display();
virtual int call_load() = 0;
virtual int call_create(int format_type, option_resolution *format_options) = 0;
virtual void call_unload() = 0;
virtual void call_display() = 0;
virtual void call_partial_hash(char *, const unsigned char *, unsigned long, unsigned int) = 0;
virtual void call_get_devices() = 0;
virtual void *get_device_specific_call() = 0;
virtual const image_device_format *device_get_indexed_creatable_format(int index);
virtual const image_device_format *device_get_named_creatable_format(const char *format_name);
const option_guide *image_device_get_creation_option_guide() { return m_image_config.create_option_guide(); }
const option_guide *device_get_creation_option_guide() { return m_image_config.create_option_guide(); }
const image_device_format *device_get_creatable_formats() { return m_image_config.formatlist(); }
virtual bool create(const char *path, const image_device_format *create_format, option_resolution *create_args) = 0;
@ -246,6 +248,16 @@ public:
UINT8 *get_software_region(const char *tag);
UINT32 get_software_region_length(const char *tag);
const char *get_feature(const char *feature_name);
void *image_malloc(size_t size);
char *image_strdup(const char *src);
void *image_realloc(void *ptr, size_t size);
void image_freeptr(void *ptr);
UINT32 crc() { return 0; }
void battery_load(void *buffer, int length, int fill) { }
void battery_save(const void *buffer, int length) { }
protected:
image_error_t set_image_filename(const char *filename);
@ -297,6 +309,8 @@ protected:
/* special - used when creating */
int m_create_format;
option_resolution *m_create_args;
object_pool *m_mempool;
};

View File

@ -70,6 +70,7 @@ EMUOBJS = \
$(EMUOBJ)/input.o \
$(EMUOBJ)/inputseq.o \
$(EMUOBJ)/inptport.o \
$(EMUOBJ)/ioprocs.o \
$(EMUOBJ)/mame.o \
$(EMUOBJ)/mconfig.o \
$(EMUOBJ)/memory.o \

View File

@ -8,6 +8,7 @@
Visit http://mamedev.org for licensing and usage restrictions.
***************************************************************************/
#include <ctype.h>
#include "emu.h"
#include "emuopts.h"
@ -15,6 +16,42 @@
#include "config.h"
#include "xmlfile.h"
/* ----------------------------------------------------------------------- */
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 =
{
NULL,
image_fseek_thunk,
image_fread_thunk,
image_fwrite_thunk,
image_fsize_thunk
};
/***************************************************************************
INITIALIZATION HELPERS
@ -259,3 +296,205 @@ void image_init(running_machine *machine)
image_device_init(machine);
config_register(machine, "image_directories", image_dirs_load, image_dirs_save);
}
/****************************************************************************
Battery functions
These functions provide transparent access to battery-backed RAM on an
image; typically for cartridges.
****************************************************************************/
/*-------------------------------------------------
open_battery_file_by_name - opens the battery backed
NVRAM file for an image
-------------------------------------------------*/
static file_error open_battery_file_by_name(const char *filename, UINT32 openflags, mame_file **file)
{
file_error filerr;
filerr = mame_fopen(SEARCHPATH_NVRAM, filename, openflags, file);
return filerr;
}
static char *stripspace(const char *src)
{
static char buff[512];
if( src )
{
char *dst;
while( *src && isspace(*src) )
src++;
strcpy(buff, src);
dst = buff + strlen(buff);
while( dst >= buff && isspace(*--dst) )
*dst = '\0';
return buff;
}
return NULL;
}
//============================================================
// strip_extension
//============================================================
static char *strip_extension(const char *filename)
{
char *newname;
char *c;
// NULL begets NULL
if (!filename)
return NULL;
// allocate space for it
newname = (char *) malloc(strlen(filename) + 1);
if (!newname)
return NULL;
// copy in the name
strcpy(newname, filename);
// search backward for a period, failing if we hit a slash or a colon
for (c = newname + strlen(newname) - 1; c >= newname; c--)
{
// if we hit a period, NULL terminate and break
if (*c == '.')
{
*c = 0;
break;
}
// if we hit a slash or colon just stop
if (*c == '\\' || *c == '/' || *c == ':')
break;
}
return newname;
}
/*-------------------------------------------------
image_info_astring - populate an allocated
string with the image info text
-------------------------------------------------*/
astring *image_info_astring(running_machine *machine, astring *string)
{
device_image_interface *image = NULL;
astring_printf(string, "%s\n\n", machine->gamedrv->description);
#if 0
if (mess_ram_size > 0)
{
char buf2[RAM_STRING_BUFLEN];
astring_catprintf(string, "RAM: %s\n\n", ram_string(buf2, mess_ram_size));
}
#endif
for (bool gotone = machine->devicelist.first(image); gotone; gotone = image->next(image))
{
const char *name = image->filename();
if (name != NULL)
{
const char *base_filename;
const char *info;
char *base_filename_noextension;
base_filename = image->basename();
base_filename_noextension = strip_extension(base_filename);
/* display device type and filename */
astring_catprintf(string, "%s: %s\n", image->image_config().name(), base_filename);
/* display long filename, if present and doesn't correspond to name */
info = image->longname();
if (info && (!base_filename_noextension || mame_stricmp(info, base_filename_noextension)))
astring_catprintf(string, "%s\n", info);
/* display manufacturer, if available */
info = image->manufacturer();
if (info != NULL)
{
astring_catprintf(string, "%s", info);
info = stripspace(image->year());
if (info && *info)
astring_catprintf(string, ", %s", info);
astring_catprintf(string,"\n");
}
/* display playable information, if available */
info = image->playable();
if (info != NULL)
astring_catprintf(string, "%s\n", info);
if (base_filename_noextension != NULL)
free(base_filename_noextension);
}
else
{
astring_catprintf(string, "%s: ---\n", image->image_config().name());
}
}
return string;
}
/*-------------------------------------------------
image_battery_load_by_name - retrieves the battery
backed RAM for an image. A filename may be supplied
to the function.
-------------------------------------------------*/
void image_battery_load_by_name(const char *filename, void *buffer, int length, int fill)
{
file_error filerr;
mame_file *file;
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 */
filerr = open_battery_file_by_name(filename, OPEN_FLAG_READ, &file);
if (filerr == FILERR_NONE)
{
bytes_read = mame_fread(file, buffer, length);
mame_fclose(file);
}
/* 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.
-------------------------------------------------*/
void image_battery_save_by_name(const char *filename, const void *buffer, int length)
{
file_error filerr;
mame_file *file;
assert_always(buffer && (length > 0), "Must specify sensical buffer/length");
/* try to open the battery file and write it out, if possible */
filerr = open_battery_file_by_name(filename, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS, &file);
if (filerr == FILERR_NONE)
{
mame_fwrite(file, buffer, length);
mame_fclose(file);
}
}
device_image_interface *image_from_absolute_index(running_machine *machine, int absolute_index)
{
device_image_interface *image = NULL;
int cnt = 0;
/* make sure that any required devices have been allocated */
for (bool gotone = machine->devicelist.first(image); gotone; gotone = image->next(image))
{
if (cnt==absolute_index) return image;
cnt++;
}
}

View File

@ -18,7 +18,17 @@
#ifndef __IMAGE_H__
#define __IMAGE_H__
#include "ioprocs.h"
void image_init(running_machine *machine);
void image_postdevice_init(running_machine *machine);
extern struct io_procs image_ioprocs;
void image_battery_load_by_name(const char *filename, void *buffer, int length, int fill);
void image_battery_save_by_name(const char *filename, const void *buffer, int length);
astring *image_info_astring(running_machine *machine, astring *string);
device_image_interface *image_from_absolute_index(running_machine *machine, int absolute_index);
#endif /* __IMAGE_H__ */

165
src/emu/ioprocs.c Normal file
View File

@ -0,0 +1,165 @@
#include <stdio.h>
#include <string.h>
#include "ioprocs.h"
/*********************************************************************
ioprocs implementation on stdio
*********************************************************************/
static void stdio_closeproc(void *file)
{
fclose((FILE*)file);
}
static int stdio_seekproc(void *file, INT64 offset, int whence)
{
return fseek((FILE*)file, (long) offset, whence);
}
static size_t stdio_readproc(void *file, void *buffer, size_t length)
{
return fread(buffer, 1, length, (FILE*)file);
}
static size_t stdio_writeproc(void *file, const void *buffer, size_t length)
{
return fwrite(buffer, 1, length, (FILE*)file);
}
static UINT64 stdio_filesizeproc(void *file)
{
long l, sz;
l = ftell((FILE*)file);
if (fseek((FILE*)file, 0, SEEK_END))
return (size_t) -1;
sz = ftell((FILE*)file);
if (fseek((FILE*)file, l, SEEK_SET))
return (size_t) -1;
return (size_t) sz;
}
const struct io_procs stdio_ioprocs =
{
stdio_closeproc,
stdio_seekproc,
stdio_readproc,
stdio_writeproc,
stdio_filesizeproc
};
const struct io_procs stdio_ioprocs_noclose =
{
NULL,
stdio_seekproc,
stdio_readproc,
stdio_writeproc,
stdio_filesizeproc
};
/*********************************************************************
calls for accessing generic IO
*********************************************************************/
static void io_generic_seek(struct io_generic *generic, UINT64 offset)
{
generic->procs->seekproc(generic->file, offset, SEEK_SET);
}
void io_generic_close(struct io_generic *generic)
{
if (generic->procs->closeproc)
generic->procs->closeproc(generic->file);
}
void io_generic_read(struct io_generic *generic, void *buffer, UINT64 offset, size_t length)
{
UINT64 size;
size_t bytes_read;
size = io_generic_size(generic);
if (size <= offset)
{
bytes_read = 0;
}
else
{
io_generic_seek(generic, offset);
bytes_read = generic->procs->readproc(generic->file, buffer, length);
}
memset(((UINT8 *) buffer) + bytes_read, generic->filler, length - bytes_read);
}
void io_generic_write(struct io_generic *generic, const void *buffer, UINT64 offset, size_t length)
{
UINT64 filler_size = 0;
char filler_buffer[1024];
size_t bytes_to_write;
UINT64 size;
if (offset > 0x29c50)
{
offset = offset;
}
size = io_generic_size(generic);
if (size < offset)
{
filler_size = offset - size;
offset = size;
}
io_generic_seek(generic, offset);
if (filler_size)
{
memset(filler_buffer, generic->filler, sizeof(buffer));
do
{
bytes_to_write = (filler_size > sizeof(filler_buffer)) ? sizeof(filler_buffer) : (size_t) filler_size;
generic->procs->writeproc(generic->file, filler_buffer, bytes_to_write);
filler_size -= bytes_to_write;
}
while(filler_size > 0);
}
if (length > 0)
generic->procs->writeproc(generic->file, buffer, length);
}
void io_generic_write_filler(struct io_generic *generic, UINT8 filler, UINT64 offset, size_t length)
{
UINT8 buffer[512];
size_t this_length;
memset(buffer, filler, MIN(length, sizeof(buffer)));
while(length > 0)
{
this_length = MIN(length, sizeof(buffer));
io_generic_write(generic, buffer, offset, this_length);
offset += this_length;
length -= this_length;
}
}
UINT64 io_generic_size(struct io_generic *generic)
{
return generic->procs->filesizeproc(generic->file);
}

69
src/emu/ioprocs.h Normal file
View File

@ -0,0 +1,69 @@
/*********************************************************************
ioprocs.h
File IO abstraction layer
*********************************************************************/
#ifndef IOPROCS_H
#define IOPROCS_H
#include <stdlib.h>
#include "emu.h"
/***************************************************************************
Type definitions
***************************************************************************/
struct io_procs
{
void (*closeproc)(void *file);
int (*seekproc)(void *file, INT64 offset, int whence);
size_t (*readproc)(void *file, void *buffer, size_t length);
size_t (*writeproc)(void *file, const void *buffer, size_t length);
UINT64 (*filesizeproc)(void *file);
};
struct io_generic
{
const struct io_procs *procs;
void *file;
UINT8 filler;
};
/***************************************************************************
Globals
***************************************************************************/
extern const struct io_procs stdio_ioprocs;
extern const struct io_procs stdio_ioprocs_noclose;
/***************************************************************************
Prototypes
***************************************************************************/
void io_generic_close(struct io_generic *generic);
void io_generic_read(struct io_generic *generic, void *buffer, UINT64 offset, size_t length);
void io_generic_write(struct io_generic *generic, const void *buffer, UINT64 offset, size_t length);
void io_generic_write_filler(struct io_generic *generic, UINT8 filler, UINT64 offset, size_t length);
UINT64 io_generic_size(struct io_generic *generic);
#endif /* IOPROCS_H */

View File

@ -1016,11 +1016,13 @@ bool load_software_part(device_image_interface *image, const char *path, softwar
if ( swlists )
{
software_list_config *swlist = (software_list_config *)downcast<const legacy_device_config_base *>(&swlists->baseconfig())->inline_config();
UINT32 i = DEVINFO_STR_SWLIST_0;
for ( int i = 0; i < DEVINFO_STR_SWLIST_MAX - DEVINFO_STR_SWLIST_0; i++ )
while ( ! software_part_ptr && i <= DEVINFO_STR_SWLIST_MAX )
{
swlist_name = swlist->list_name[i];
swlist_name = swlist->list_name[i-DEVINFO_STR_SWLIST_0];
if ( swlist_name && *swlist_name )
{
@ -1041,6 +1043,7 @@ bool load_software_part(device_image_interface *image, const char *path, softwar
}
}
}
i++;
}
}

View File

@ -1274,7 +1274,7 @@ void ui_image_handler_ingame(running_machine *machine)
{
for (bool gotone = machine->devicelist.first(image); gotone; gotone = image->next(image))
{
image->display();
image->call_display();
}
}

View File

@ -115,63 +115,6 @@ struct _confirm_save_as_menu_state
int *yes;
};
char *stripspace(const char *src)
{
static char buff[512];
if( src )
{
char *dst;
while( *src && isspace(*src) )
src++;
strcpy(buff, src);
dst = buff + strlen(buff);
while( dst >= buff && isspace(*--dst) )
*dst = '\0';
return buff;
}
return NULL;
}
//============================================================
// strip_extension
//============================================================
char *strip_extension(const char *filename)
{
char *newname;
char *c;
// NULL begets NULL
if (!filename)
return NULL;
// allocate space for it
newname = (char *) malloc(strlen(filename) + 1);
if (!newname)
return NULL;
// copy in the name
strcpy(newname, filename);
// search backward for a period, failing if we hit a slash or a colon
for (c = newname + strlen(newname) - 1; c >= newname; c--)
{
// if we hit a period, NULL terminate and break
if (*c == '.')
{
*c = 0;
break;
}
// if we hit a slash or colon just stop
if (*c == '\\' || *c == '/' || *c == ':')
break;
}
return newname;
}
/***************************************************************************
MENU HELPERS
***************************************************************************/
@ -1042,74 +985,6 @@ void ui_image_menu_file_manager(running_machine *machine, ui_menu *menu, void *p
}
}
/*-------------------------------------------------
image_info_astring - populate an allocated
string with the image info text
-------------------------------------------------*/
static astring *image_info_astring(running_machine *machine, astring *string)
{
device_image_interface *image = NULL;
astring_printf(string, "%s\n\n", machine->gamedrv->description);
#if 0
if (mess_ram_size > 0)
{
char buf2[RAM_STRING_BUFLEN];
astring_catprintf(string, "RAM: %s\n\n", ram_string(buf2, mess_ram_size));
}
#endif
for (bool gotone = machine->devicelist.first(image); gotone; gotone = image->next(image))
{
const char *name = image->filename();
if (name != NULL)
{
const char *base_filename;
const char *info;
char *base_filename_noextension;
base_filename = image->basename();
base_filename_noextension = strip_extension(base_filename);
/* display device type and filename */
astring_catprintf(string, "%s: %s\n", image->image_config().name(), base_filename);
/* display long filename, if present and doesn't correspond to name */
info = image->longname();
if (info && (!base_filename_noextension || mame_stricmp(info, base_filename_noextension)))
astring_catprintf(string, "%s\n", info);
/* display manufacturer, if available */
info = image->manufacturer();
if (info != NULL)
{
astring_catprintf(string, "%s", info);
info = stripspace(image->year());
if (info && *info)
astring_catprintf(string, ", %s", info);
astring_catprintf(string,"\n");
}
/* display playable information, if available */
info = image->playable();
if (info != NULL)
astring_catprintf(string, "%s\n", info);
if (base_filename_noextension != NULL)
free(base_filename_noextension);
}
else
{
astring_catprintf(string, "%s: ---\n", image->image_config().name());
}
}
return string;
}
/*-------------------------------------------------
ui_image_menu_image_info - menu that shows info
on all loaded images