Use rzip to speed up cheat.dat loading (#496)

This commit is contained in:
mahoneyt944 2022-01-24 09:30:37 -05:00 committed by GitHub
parent cecbaba580
commit b648dbbac1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 109 additions and 85 deletions

View File

@ -802,6 +802,9 @@ CFLAGS += -DHAVE_SOCKLEN_T
CFLAGS += -D_LARGEFILE_SOURCE
CFLAGS += -D_FILE_OFFSET_BITS=64
# Required for RZIP support in cheat.c
CFLAGS += -DHAVE_ZLIB
# In theory, the RETRO_PROFILE could be set to different values for different
# architectures or for special builds to hint to the host system how many
# resources to allocate. In practice, there seems to be no standard way to

View File

@ -2625,10 +2625,19 @@ SOURCES_C += \
$(LIBRETRO_COMM_DIR)/compat/compat_strcasestr.c \
$(LIBRETRO_COMM_DIR)/compat/compat_strl.c \
$(LIBRETRO_COMM_DIR)/compat/fopen_utf8.c \
$(LIBRETRO_COMM_DIR)/encodings/encoding_crc32.c \
$(LIBRETRO_COMM_DIR)/encodings/encoding_utf.c \
$(LIBRETRO_COMM_DIR)/file/file_path.c \
$(LIBRETRO_COMM_DIR)/file/file_path_io.c \
$(LIBRETRO_COMM_DIR)/streams/file_stream.c \
$(LIBRETRO_COMM_DIR)/streams/file_stream_transforms.c \
$(LIBRETRO_COMM_DIR)/streams/interface_stream.c \
$(LIBRETRO_COMM_DIR)/streams/memory_stream.c \
$(LIBRETRO_COMM_DIR)/streams/rzip_stream.c \
$(LIBRETRO_COMM_DIR)/streams/stdin_stream.c \
$(LIBRETRO_COMM_DIR)/streams/trans_stream.c \
$(LIBRETRO_COMM_DIR)/streams/trans_stream_pipe.c \
$(LIBRETRO_COMM_DIR)/streams/trans_stream_zlib.c \
$(LIBRETRO_COMM_DIR)/string/stdstring.c \
$(LIBRETRO_COMM_DIR)/utils/md5.c \
$(LIBRETRO_COMM_DIR)/vfs/vfs_implementation.c \

View File

@ -5,7 +5,7 @@ CORE_DIR := $(ROOT_DIR)/src
include $(ROOT_DIR)/Makefile.common
COREFLAGS := $(DEFS) $(COREDEFS) $(CPUDEFS) $(SOUNDDEFS) $(ASMDEFS) $(DBGDEFS) -ffast-math -funroll-loops -DANDROID $(INCFLAGS)
COREFLAGS := $(DEFS) $(COREDEFS) $(CPUDEFS) $(SOUNDDEFS) $(ASMDEFS) $(DBGDEFS) -ffast-math -funroll-loops -DANDROID -DHAVE_ZLIB $(INCFLAGS)
GIT_VERSION := " $(shell git rev-parse --short HEAD || echo unknown)"
ifneq ($(GIT_VERSION)," unknown")

View File

@ -376,8 +376,12 @@ is selected
#include "artwork.h"
#include "machine/eeprom.h"
#include <ctype.h>
#include <streams/interface_stream.h>
#define CHEAT_DATABASE_RZIP_FILENAME "cheat.rzip"
#define CHEAT_DATABASE_FILENAME "cheat.dat"
#define CHEAT_SAVE_FILENAME "save_cheat.dat"
#define OSD_READKEY_KLUDGE 1
@ -396,8 +400,6 @@ is selected
k##name##_ShiftedMask = (int)(0xFFFFFFFF >> (32 - (start - end + 1))), \
k##name##_Mask = (int)(k##name##_ShiftedMask << k##name##_Shift)
#define CHEAT_FILENAME_MAX_LEN 255
#define kRegionListLength (REGION_MAX - REGION_INVALID)
/**** Enums ******************************************************************/
@ -826,11 +828,6 @@ struct MenuItemInfoStruct
typedef struct MenuItemInfoStruct MenuItemInfoStruct;
/**** Exported Globals *******************************************************/
int he_did_cheat = 0;
const char * cheatfile = NULL;
/**** Local Globals **********************************************************/
static CheatEntry * cheatList = NULL;
@ -853,8 +850,6 @@ static int watchesDisabled = 0;
static int fullMenuPageHeight = 0;
static char mainDatabaseName[CHEAT_FILENAME_MAX_LEN + 1];
static MenuStringList menuStrings;
static MenuItemInfoStruct * menuItemInfo;
@ -1155,7 +1150,6 @@ static int ConvertOldCode(int code, int cpu, int * data, int * extendData);
static int MatchCommandCheatLine(char * buf);
static void HandleLocalCommandCheat(UINT32 type, UINT32 address, UINT32 data, UINT32 extendData, char * name, char * description);
static void LoadCheatFile(char * fileName);
static void LoadCheatDatabase(void);
static void DisposeCheatDatabase(void);
@ -1674,8 +1668,6 @@ void InitCheat(void)
artwork_get_screensize(&screenWidth, &screenHeight);
he_did_cheat = 0;
cheatList = NULL;
cheatListLength = 0;
@ -1758,7 +1750,6 @@ void StopCheat(void)
foundCheatDatabase = 0;
cheatsDisabled = 0;
watchesDisabled = 0;
mainDatabaseName[0] = 0;
menuItemInfoLength = 0;
useClassicSearchBox = 1;
dontPrintNewLabels = 0;
@ -8235,18 +8226,78 @@ static void HandleLocalCommandCheat(UINT32 type, UINT32 address, UINT32 data, UI
}
}
static void LoadCheatFile(char * fileName)
static void LoadCheatDatabase()
{
mame_file * theFile;
intfstream_t * in_file = NULL;
intfstream_t * out_file = NULL;
char cheat_directory[PATH_MAX_LENGTH];
char cheat_path[PATH_MAX_LENGTH];
char formatString[256];
char oldFormatString[256];
char buf[2048];
int recordNames = 0;
theFile = mame_fopen(NULL, fileName, FILETYPE_CHEAT, 0);
cheat_directory[0] = '\0';
cheat_path[0] = '\0';
if(!theFile)
return;
/* Open existing cheat.rzip */
osd_get_path(FILETYPE_CHEAT, cheat_directory);
snprintf(cheat_path, PATH_MAX_LENGTH, "%s%c%s", cheat_directory, PATH_DEFAULT_SLASH_C(), CHEAT_DATABASE_RZIP_FILENAME);
in_file = intfstream_open_rzip_file(cheat_path, RETRO_VFS_FILE_ACCESS_READ);
if(!in_file)
{
/* Try to open cheat.dat */
cheat_path[0] = '\0';
snprintf(cheat_path, PATH_MAX_LENGTH, "%s%c%s", cheat_directory, PATH_DEFAULT_SLASH_C(), CHEAT_DATABASE_FILENAME);
in_file = intfstream_open_file(cheat_path, RETRO_VFS_FILE_ACCESS_READ, RETRO_VFS_FILE_ACCESS_HINT_NONE);
if(!in_file)
goto end;
/* Create new cheat.rzip file */
cheat_path[0] = '\0';
snprintf(cheat_path, PATH_MAX_LENGTH, "%s%c%s", cheat_directory, PATH_DEFAULT_SLASH_C(), CHEAT_DATABASE_RZIP_FILENAME);
out_file = intfstream_open_rzip_file(cheat_path, RETRO_VFS_FILE_ACCESS_WRITE);
if(!out_file)
{
log_cb(RETRO_LOG_ERROR, LOGPRE "Failed to create cheat.rzip\n");
goto end;
}
/* Compression loop */
for(;;)
{
int64_t data_read = intfstream_read(in_file, buf, sizeof(buf));
int64_t data_write = 0;
if (data_read < 0)
{
log_cb(RETRO_LOG_ERROR, LOGPRE "Failed to read from cheat.dat\n");
goto end;
}
if (data_read == 0)
{
/* Finished, close cheat.rzip and rewind input file */
intfstream_close(out_file);
free(out_file);
out_file = NULL;
intfstream_rewind(in_file);
break;
}
data_write = intfstream_write(out_file, buf, data_read);
if (data_write != data_read)
{
log_cb(RETRO_LOG_ERROR, LOGPRE "Failed to write to cheat.rzip\n");
goto end;
}
}
}
foundCheatDatabase = 1;
@ -8254,7 +8305,7 @@ static void LoadCheatFile(char * fileName)
sprintf(formatString, ":%s:%s", Machine->gamedrv->name, "%x:%x:%x:%x:%[^:\n\r]:%[^:\n\r]");
sprintf(oldFormatString, "%s:%s", Machine->gamedrv->name, "%d:%x:%x:%d:%[^:\n\r]:%[^:\n\r]");
while(mame_fgets(buf, 2048, theFile))
while(intfstream_gets(in_file, buf, 2048))
{
int type;
int address;
@ -8293,7 +8344,6 @@ static void LoadCheatFile(char * fileName)
}
}
/*logerror("cheat: processing %s\n", buf);*/
if(TEST_FIELD(type, RemoveFromList))
@ -8308,9 +8358,8 @@ static void LoadCheatFile(char * fileName)
{
if(cheatListLength == 0)
{
log_cb(RETRO_LOG_ERROR, LOGPRE "LoadCheatFile: first cheat found was link cheat; bailing\n");
goto bail;
log_cb(RETRO_LOG_ERROR, LOGPRE "LoadCheatDatabase: first cheat found was link cheat; bailing\n");
goto end;
}
/*logerror("cheat: doing link cheat\n");*/
@ -8326,9 +8375,8 @@ static void LoadCheatFile(char * fileName)
if(cheatListLength == 0)
{
log_cb(RETRO_LOG_ERROR, LOGPRE "LoadCheatFile: cheat list resize failed; bailing\n");
goto bail;
log_cb(RETRO_LOG_ERROR, LOGPRE "LoadCheatDatabase: cheat list resize failed; bailing\n");
goto end;
}
entry = &cheatList[cheatListLength - 1];
@ -8354,9 +8402,8 @@ static void LoadCheatFile(char * fileName)
if(entry->actionListLength == 0)
{
log_cb(RETRO_LOG_ERROR, LOGPRE "LoadCheatFile: action list resize failed; bailing\n");
goto bail;
log_cb(RETRO_LOG_ERROR, LOGPRE "LoadCheatDatabase: action list resize failed; bailing\n");
goto end;
}
action = &entry->actionList[entry->actionListLength - 1];
@ -8374,59 +8421,19 @@ static void LoadCheatFile(char * fileName)
}
}
bail:
end:
mame_fclose(theFile);
}
static void LoadCheatDatabase(void)
{
char buf[4096];
const char * inTraverse;
char * outTraverse;
char * mainTraverse;
int first = 1;
char data;
if(!cheatfile)
cheatfile = "cheat.dat";
inTraverse = cheatfile;
outTraverse = buf;
mainTraverse = mainDatabaseName;
buf[0] = 0;
do
if(in_file)
{
data = *inTraverse;
if( (data == ';') ||
(data == 0))
{
*outTraverse++ = 0;
if(first)
*mainTraverse++ = 0;
if(buf[0])
{
LoadCheatFile(buf);
outTraverse = buf;
buf[0] = 0;
first = 0;
}
}
else
{
*outTraverse++ = data;
if(first)
*mainTraverse++ = data;
}
inTraverse++;
intfstream_close(in_file);
free(in_file);
}
if(out_file)
{
intfstream_close(out_file);
free(out_file);
}
while(data);
UpdateAllCheatInfo();
}
@ -8458,7 +8465,7 @@ static void SaveCheat(CheatEntry * entry)
if(!entry || !entry->actionList)
return;
theFile = mame_fopen(NULL, mainDatabaseName, FILETYPE_CHEAT, 1);
theFile = mame_fopen(NULL, CHEAT_SAVE_FILENAME, FILETYPE_CHEAT, 1);
if(!theFile)
return;
@ -9602,8 +9609,6 @@ static void ActivateCheat(CheatEntry * entry)
}
entry->flags |= kCheatFlag_Active;
he_did_cheat = 1;
}
static void DeactivateCheat(CheatEntry * entry)

View File

@ -7,8 +7,6 @@
#ifndef CHEAT_H
#define CHEAT_H
extern int he_did_cheat;
void InitCheat(void);
void StopCheat(void);

View File

@ -11,6 +11,7 @@
#include <string/stdstring.h>
#include <libretro.h>
#include <file/file_path.h>
#include <streams/file_stream.h>
#include <math.h>
#include <string.h>
@ -162,7 +163,15 @@ static void check_system_specs(void)
void retro_set_environment(retro_environment_t cb)
{
struct retro_vfs_interface_info vfs_iface_info;
environ_cb = cb;
/* Initialise VFS */
vfs_iface_info.required_interface_version = 1;
vfs_iface_info.iface = NULL;
if (environ_cb(RETRO_ENVIRONMENT_GET_VFS_INTERFACE, &vfs_iface_info))
filestream_vfs_init(&vfs_iface_info);
}
void retro_get_system_av_info(struct retro_system_av_info *info)