mirror of
https://github.com/holub/mame
synced 2025-05-12 00:58:53 +03:00
02688: DIP switch settings are not being stored in INP files.
To fix this, I had to break old INP files. While I was in there, I added corefile support for compressing/decompressing data on the fly, and enabled it for INPs, meaning the newer format INPs are output and processed compressed.
This commit is contained in:
parent
85b961f5af
commit
013e6eff00
@ -384,6 +384,17 @@ void mame_fclose(mame_file *file)
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
mame_fcompress - enable/disable streaming file
|
||||
compression via zlib
|
||||
-------------------------------------------------*/
|
||||
|
||||
file_error mame_fcompress(mame_file *file, int compress)
|
||||
{
|
||||
return core_fcompress(file->file, compress);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
FILE POSITIONING
|
||||
@ -604,7 +615,6 @@ int CLIB_DECL mame_fprintf(mame_file *file, const char *fmt, ...)
|
||||
FILE ENUMERATION
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
mame_openpath - open a search path (multiple
|
||||
directories) for iteration
|
||||
|
@ -98,6 +98,9 @@ file_error mame_fopen_ram(const void *data, UINT32 length, UINT32 openflags, mam
|
||||
/* close an open file */
|
||||
void mame_fclose(mame_file *file);
|
||||
|
||||
/* enable/disable streaming file compression via zlib */
|
||||
file_error mame_fcompress(mame_file *file, int compress);
|
||||
|
||||
|
||||
|
||||
/* ----- file positioning ----- */
|
||||
@ -170,4 +173,5 @@ const char *mame_file_full_name(mame_file *file);
|
||||
const char *mame_fhash(mame_file *file, UINT32 functions);
|
||||
|
||||
|
||||
|
||||
#endif /* __FILEIO_H__ */
|
||||
|
@ -3973,6 +3973,9 @@ static time_t playback_init(running_machine *machine)
|
||||
if (memcmp(machine->gamedrv->name, header + 0x14, strlen(machine->gamedrv->name) + 1) != 0)
|
||||
fatalerror("Input file is for " GAMENOUN " '%s', not for current " GAMENOUN " '%s'\n", header + 0x14, machine->gamedrv->name);
|
||||
|
||||
/* enable compression */
|
||||
mame_fcompress(portdata->playback_file, TRUE);
|
||||
|
||||
return basetime;
|
||||
}
|
||||
|
||||
@ -4044,7 +4047,8 @@ static void playback_port(const input_port_config *port)
|
||||
{
|
||||
analog_field_state *analog;
|
||||
|
||||
/* read the digital value */
|
||||
/* read the default value and the digital state */
|
||||
port->state->defvalue = playback_read_uint32(port->machine);
|
||||
port->state->digital = playback_read_uint32(port->machine);
|
||||
|
||||
/* loop over analog ports and save their data */
|
||||
@ -4168,6 +4172,9 @@ static void record_init(running_machine *machine)
|
||||
|
||||
/* write it */
|
||||
mame_fwrite(portdata->record_file, header, sizeof(header));
|
||||
|
||||
/* enable compression */
|
||||
mame_fcompress(portdata->record_file, TRUE);
|
||||
}
|
||||
|
||||
|
||||
@ -4228,7 +4235,8 @@ static void record_port(const input_port_config *port)
|
||||
{
|
||||
analog_field_state *analog;
|
||||
|
||||
/* store the digital value */
|
||||
/* store the default value and digital state */
|
||||
record_write_uint32(port->machine, port->state->defvalue);
|
||||
record_write_uint32(port->machine, port->state->digital);
|
||||
|
||||
/* loop over analog ports and save their data */
|
||||
|
@ -46,7 +46,7 @@
|
||||
|
||||
/* INP file information */
|
||||
#define INP_HEADER_SIZE 64
|
||||
#define INP_HEADER_MAJVERSION 2
|
||||
#define INP_HEADER_MAJVERSION 3
|
||||
#define INP_HEADER_MINVERSION 0
|
||||
|
||||
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
#include "corefile.h"
|
||||
#include "unicode.h"
|
||||
#include "zlib.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <ctype.h>
|
||||
@ -53,10 +54,21 @@ enum _text_file_type
|
||||
typedef enum _text_file_type text_file_type;
|
||||
|
||||
|
||||
typedef struct _zlib_data zlib_data;
|
||||
struct _zlib_data
|
||||
{
|
||||
z_stream stream;
|
||||
UINT8 buffer[1024];
|
||||
UINT64 realoffset;
|
||||
UINT64 nextoffset;
|
||||
};
|
||||
|
||||
|
||||
/* typedef struct _core_file core_file -- declared in corefile.h */
|
||||
struct _core_file
|
||||
{
|
||||
osd_file * file; /* OSD file handle */
|
||||
zlib_data * zdata; /* compression data */
|
||||
UINT32 openflags; /* flags we were opened with */
|
||||
UINT8 data_allocated; /* was the data allocated by us? */
|
||||
UINT8 * data; /* file data, if RAM-based */
|
||||
@ -79,6 +91,8 @@ struct _core_file
|
||||
|
||||
/* misc helpers */
|
||||
static UINT32 safe_buffer_copy(const void *source, UINT32 sourceoffs, UINT32 sourcelen, void *dest, UINT32 destoffs, UINT32 destlen);
|
||||
static file_error osd_or_zlib_read(core_file *file, void *buffer, UINT64 offset, UINT32 length, UINT32 *actual);
|
||||
static file_error osd_or_zlib_write(core_file *file, const void *buffer, UINT64 offset, UINT32 length, UINT32 *actual);
|
||||
|
||||
|
||||
|
||||
@ -198,6 +212,8 @@ file_error core_fopen_ram_copy(const void *data, size_t length, UINT32 openflags
|
||||
void core_fclose(core_file *file)
|
||||
{
|
||||
/* close files and free memory */
|
||||
if (file->zdata != NULL)
|
||||
core_fcompress(file, FALSE);
|
||||
if (file->file != NULL)
|
||||
osd_close(file->file);
|
||||
if (file->data != NULL && file->data_allocated)
|
||||
@ -206,6 +222,102 @@ void core_fclose(core_file *file)
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
core_fcompress - enable/disable streaming file
|
||||
compression via zlib
|
||||
-------------------------------------------------*/
|
||||
|
||||
file_error core_fcompress(core_file *file, int compress)
|
||||
{
|
||||
file_error result = FILERR_NONE;
|
||||
|
||||
/* can only do this for read-only and write-only cases */
|
||||
if ((file->openflags & OPEN_FLAG_WRITE) != 0 && (file->openflags & OPEN_FLAG_READ) != 0)
|
||||
return FILERR_INVALID_ACCESS;
|
||||
|
||||
/* if we have been compressing, flush and free the data */
|
||||
if (file->zdata != NULL && !compress)
|
||||
{
|
||||
int zerr = Z_OK;
|
||||
|
||||
/* flush any remaining data if we are writing */
|
||||
while ((file->openflags & OPEN_FLAG_WRITE) != 0 && zerr != Z_STREAM_END)
|
||||
{
|
||||
UINT32 actualdata;
|
||||
file_error filerr;
|
||||
|
||||
/* deflate some more */
|
||||
zerr = deflate(&file->zdata->stream, Z_FINISH);
|
||||
if (zerr != Z_STREAM_END && zerr != Z_OK)
|
||||
{
|
||||
result = FILERR_INVALID_DATA;
|
||||
break;
|
||||
}
|
||||
|
||||
/* write the data */
|
||||
if (file->zdata->stream.avail_out != sizeof(file->zdata->buffer))
|
||||
{
|
||||
filerr = osd_write(file->file, file->zdata->buffer, file->zdata->realoffset, sizeof(file->zdata->buffer) - file->zdata->stream.avail_out, &actualdata);
|
||||
if (filerr != FILERR_NONE)
|
||||
break;
|
||||
file->zdata->realoffset += actualdata;
|
||||
file->zdata->stream.next_out = file->zdata->buffer;
|
||||
file->zdata->stream.avail_out = sizeof(file->zdata->buffer);
|
||||
}
|
||||
}
|
||||
|
||||
/* end the appropriate operation */
|
||||
if ((file->openflags & OPEN_FLAG_WRITE) != 0)
|
||||
deflateEnd(&file->zdata->stream);
|
||||
else
|
||||
inflateEnd(&file->zdata->stream);
|
||||
|
||||
/* free memory */
|
||||
free(file->zdata);
|
||||
file->zdata = NULL;
|
||||
}
|
||||
|
||||
/* if we are just starting to compress, allocate a new buffer */
|
||||
if (file->zdata == NULL && compress)
|
||||
{
|
||||
int zerr;
|
||||
|
||||
/* allocate memory */
|
||||
file->zdata = malloc(sizeof(*file->zdata));
|
||||
if (file->zdata == NULL)
|
||||
return FILERR_OUT_OF_MEMORY;
|
||||
memset(file->zdata, 0, sizeof(file->zdata));
|
||||
|
||||
/* initialize the stream and compressor */
|
||||
if ((file->openflags & OPEN_FLAG_WRITE) != 0)
|
||||
{
|
||||
file->zdata->stream.next_out = file->zdata->buffer;
|
||||
file->zdata->stream.avail_out = sizeof(file->zdata->buffer);
|
||||
zerr = deflateInit(&file->zdata->stream, Z_BEST_COMPRESSION);
|
||||
}
|
||||
else
|
||||
zerr = inflateInit(&file->zdata->stream);
|
||||
|
||||
/* on error, return an error */
|
||||
if (zerr != Z_OK)
|
||||
{
|
||||
free(file->zdata);
|
||||
file->zdata = NULL;
|
||||
return FILERR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
/* flush buffers */
|
||||
file->bufferbytes = 0;
|
||||
|
||||
/* set the initial offset */
|
||||
file->zdata->realoffset = file->offset;
|
||||
file->zdata->nextoffset = file->offset;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
FILE POSITIONING
|
||||
@ -218,6 +330,10 @@ void core_fclose(core_file *file)
|
||||
int core_fseek(core_file *file, INT64 offset, int whence)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
/* error if compressing */
|
||||
if (file->zdata != NULL)
|
||||
return 1;
|
||||
|
||||
/* flush any buffered char */
|
||||
file->back_char_head = 0;
|
||||
@ -312,7 +428,7 @@ UINT32 core_fread(core_file *file, void *buffer, UINT32 length)
|
||||
/* read as much as makes sense into the buffer */
|
||||
file->bufferbase = file->offset + bytes_read;
|
||||
file->bufferbytes = 0;
|
||||
filerr = osd_read(file->file, file->buffer, file->bufferbase, sizeof(file->buffer), &file->bufferbytes);
|
||||
filerr = osd_or_zlib_read(file, file->buffer, file->bufferbase, sizeof(file->buffer), &file->bufferbytes);
|
||||
|
||||
/* do a bounded copy from the buffer to the destination */
|
||||
bytes_read += safe_buffer_copy(file->buffer, 0, file->bufferbytes, buffer, bytes_read, length);
|
||||
@ -322,7 +438,7 @@ UINT32 core_fread(core_file *file, void *buffer, UINT32 length)
|
||||
else
|
||||
{
|
||||
UINT32 new_bytes_read = 0;
|
||||
filerr = osd_read(file->file, (UINT8 *)buffer + bytes_read, file->offset + bytes_read, length - bytes_read, &new_bytes_read);
|
||||
filerr = osd_or_zlib_read(file, (UINT8 *)buffer + bytes_read, file->offset + bytes_read, length - bytes_read, &new_bytes_read);
|
||||
bytes_read += new_bytes_read;
|
||||
}
|
||||
}
|
||||
@ -555,7 +671,7 @@ const void *core_fbuffer(core_file *file)
|
||||
file->data_allocated = TRUE;
|
||||
|
||||
/* read the file */
|
||||
filerr = osd_read(file->file, file->data, 0, file->length, &read_length);
|
||||
filerr = osd_or_zlib_read(file, file->data, 0, file->length, &read_length);
|
||||
if (filerr != FILERR_NONE || read_length != file->length)
|
||||
{
|
||||
free(file->data);
|
||||
@ -596,7 +712,7 @@ UINT32 core_fwrite(core_file *file, const void *buffer, UINT32 length)
|
||||
file->bufferbytes = 0;
|
||||
|
||||
/* do the write */
|
||||
filerr = osd_write(file->file, buffer, file->offset, length, &bytes_written);
|
||||
filerr = osd_or_zlib_write(file, buffer, file->offset, length, &bytes_written);
|
||||
|
||||
/* return the number of bytes read */
|
||||
file->offset += bytes_written;
|
||||
@ -755,3 +871,110 @@ static UINT32 safe_buffer_copy(const void *source, UINT32 sourceoffs, UINT32 sou
|
||||
memcpy((UINT8 *)dest + destoffs, (const UINT8 *)source + sourceoffs, bytes_to_copy);
|
||||
return bytes_to_copy;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
osd_or_zlib_read - wrapper for osd_read that
|
||||
handles zlib-compressed data
|
||||
-------------------------------------------------*/
|
||||
|
||||
static file_error osd_or_zlib_read(core_file *file, void *buffer, UINT64 offset, UINT32 length, UINT32 *actual)
|
||||
{
|
||||
/* if no compression, just pass through */
|
||||
if (file->zdata == NULL)
|
||||
return osd_read(file->file, buffer, offset, length, actual);
|
||||
|
||||
/* if the offset doesn't match the next offset, fail */
|
||||
if (offset != file->zdata->nextoffset)
|
||||
return FILERR_INVALID_ACCESS;
|
||||
|
||||
/* set up the destination */
|
||||
file->zdata->stream.next_out = buffer;
|
||||
file->zdata->stream.avail_out = length;
|
||||
while (file->zdata->stream.avail_out != 0)
|
||||
{
|
||||
file_error filerr;
|
||||
UINT32 actualdata;
|
||||
int zerr = Z_OK;
|
||||
|
||||
/* if we didn't make progress, report an error or the end */
|
||||
if (file->zdata->stream.avail_in != 0)
|
||||
zerr = inflate(&file->zdata->stream, Z_SYNC_FLUSH);
|
||||
if (zerr != Z_OK)
|
||||
{
|
||||
*actual = length - file->zdata->stream.avail_out;
|
||||
file->zdata->nextoffset += *actual;
|
||||
return (zerr == Z_STREAM_END) ? FILERR_NONE : FILERR_INVALID_DATA;
|
||||
}
|
||||
|
||||
/* fetch more data if needed */
|
||||
if (file->zdata->stream.avail_in == 0)
|
||||
{
|
||||
filerr = osd_read(file->file, file->zdata->buffer, file->zdata->realoffset, sizeof(file->zdata->buffer), &actualdata);
|
||||
if (filerr != FILERR_NONE)
|
||||
return filerr;
|
||||
file->zdata->realoffset += actualdata;
|
||||
file->zdata->stream.next_in = file->zdata->buffer;
|
||||
file->zdata->stream.avail_in = sizeof(file->zdata->buffer);
|
||||
}
|
||||
}
|
||||
|
||||
/* we read everything */
|
||||
*actual = length;
|
||||
file->zdata->nextoffset += *actual;
|
||||
return FILERR_NONE;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
osd_or_zlib_write - wrapper for osd_write that
|
||||
handles zlib-compressed data
|
||||
-------------------------------------------------*/
|
||||
|
||||
static file_error osd_or_zlib_write(core_file *file, const void *buffer, UINT64 offset, UINT32 length, UINT32 *actual)
|
||||
{
|
||||
/* if no compression, just pass through */
|
||||
if (file->zdata == NULL)
|
||||
return osd_write(file->file, buffer, offset, length, actual);
|
||||
|
||||
/* if the offset doesn't match the next offset, fail */
|
||||
if (offset != file->zdata->nextoffset)
|
||||
return FILERR_INVALID_ACCESS;
|
||||
|
||||
/* set up the source */
|
||||
file->zdata->stream.next_in = (void *)buffer;
|
||||
file->zdata->stream.avail_in = length;
|
||||
while (file->zdata->stream.avail_in != 0)
|
||||
{
|
||||
file_error filerr;
|
||||
UINT32 actualdata;
|
||||
int zerr;
|
||||
|
||||
/* if we didn't make progress, report an error or the end */
|
||||
zerr = deflate(&file->zdata->stream, Z_NO_FLUSH);
|
||||
if (zerr != Z_OK)
|
||||
{
|
||||
*actual = length - file->zdata->stream.avail_in;
|
||||
file->zdata->nextoffset += *actual;
|
||||
return FILERR_INVALID_DATA;
|
||||
}
|
||||
|
||||
/* write more data if we are full up */
|
||||
if (file->zdata->stream.avail_out == 0)
|
||||
{
|
||||
filerr = osd_write(file->file, file->zdata->buffer, file->zdata->realoffset, sizeof(file->zdata->buffer), &actualdata);
|
||||
if (filerr != FILERR_NONE)
|
||||
return filerr;
|
||||
file->zdata->realoffset += actualdata;
|
||||
file->zdata->stream.next_out = file->zdata->buffer;
|
||||
file->zdata->stream.avail_out = sizeof(file->zdata->buffer);
|
||||
}
|
||||
}
|
||||
|
||||
/* we read everything */
|
||||
*actual = length;
|
||||
file->zdata->nextoffset += *actual;
|
||||
return FILERR_NONE;
|
||||
}
|
||||
|
||||
|
||||
|
@ -55,6 +55,9 @@ file_error core_fopen_ram_copy(const void *data, size_t length, UINT32 openflags
|
||||
/* close an open file */
|
||||
void core_fclose(core_file *file);
|
||||
|
||||
/* enable/disable streaming file compression via zlib */
|
||||
file_error core_fcompress(core_file *file, int compress);
|
||||
|
||||
|
||||
|
||||
/* ----- file positioning ----- */
|
||||
|
@ -809,7 +809,7 @@ static png_error write_deflated_chunk(core_file *fp, UINT8 *data, UINT32 type, U
|
||||
memset(&stream, 0, sizeof(stream));
|
||||
stream.next_in = data;
|
||||
stream.avail_in = length;
|
||||
zerr = deflateInit(&stream, Z_DEFAULT_COMPRESSION);
|
||||
zerr = deflateInit(&stream, Z_BEST_COMPRESSION);
|
||||
if (zerr != Z_OK)
|
||||
return PNGERR_COMPRESS_ERROR;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user