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:
Aaron Giles 2008-12-04 08:34:30 +00:00
parent 85b961f5af
commit 013e6eff00
7 changed files with 257 additions and 9 deletions

View File

@ -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

View File

@ -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__ */

View File

@ -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 */

View File

@ -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

View File

@ -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;
}

View File

@ -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 ----- */

View File

@ -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;