dep/rcheevos: Bump to d54cf8f

This commit is contained in:
Stenzek
2024-06-24 11:27:43 +10:00
parent dd4b282ec5
commit 1a2ad89a17
30 changed files with 1282 additions and 280 deletions

View File

@@ -10,6 +10,7 @@
#if defined(_WIN32)
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <share.h>
#endif
/* arbitrary limit to prevent allocating and hashing large files */
@@ -52,9 +53,9 @@ static void rc_hash_verbose(const char* message)
static struct rc_hash_filereader filereader_funcs;
static struct rc_hash_filereader* filereader = NULL;
#if defined(WINVER) && WINVER >= 0x0500
static void* filereader_open(const char* path)
{
#if defined(WINVER) && WINVER >= 0x0500
/* Windows requires using wchar APIs for Unicode paths */
/* Note that MultiByteToWideChar will only be defined for >= Windows 2000 */
wchar_t* wpath;
@@ -75,21 +76,34 @@ static void* filereader_open(const char* path)
free(wpath);
return NULL;
}
#if defined(__STDC_WANT_SECURE_LIB__)
_wfopen_s(&fp, wpath, L"rb");
#else
#if defined(__STDC_WANT_SECURE_LIB__)
/* have to use _SH_DENYNO because some cores lock the file while its loaded */
fp = _wfsopen(wpath, L"rb", _SH_DENYNO);
#else
fp = _wfopen(wpath, L"rb");
#endif
#endif
free(wpath);
return fp;
#elif defined(__STDC_WANT_SECURE_LIB__)
FILE* fp;
fopen_s(&fp, path, "rb");
return fp;
#else
return fopen(path, "rb");
#endif
}
#else /* !WINVER >= 0x0500 */
static void* filereader_open(const char* path)
{
#if defined(__STDC_WANT_SECURE_LIB__)
#if defined(WINVER)
/* have to use _SH_DENYNO because some cores lock the file while its loaded */
return _fsopen(path, "rb", _SH_DENYNO);
#else /* !WINVER */
FILE *fp;
fopen_s(&fp, path, "rb");
return fp;
#endif
#else /* !__STDC_WANT_SECURE_LIB__ */
return fopen(path, "rb");
#endif
}
#endif /* WINVER >= 0x0500 */
static void filereader_seek(void* file_handle, int64_t offset, int origin)
{
@@ -818,12 +832,18 @@ static int rc_hash_zip_file(md5_state_t* md5, void* file_handle)
uint32_t filename_len = RC_ZIP_READ_LE16(cdir + 0x1C);
int32_t extra_len = RC_ZIP_READ_LE16(cdir + 0x1E);
int32_t comment_len = RC_ZIP_READ_LE16(cdir + 0x20);
int32_t external_attr = RC_ZIP_READ_LE16(cdir + 0x26);
uint64_t local_hdr_ofs = RC_ZIP_READ_LE32(cdir + 0x2A);
cdir_entry_len = cdirhdr_size + filename_len + extra_len + comment_len;
if (signature != 0x02014b50) /* expected central directory entry signature */
break;
/* Ignore records describing a directory (we only hash file records) */
name = (cdir + cdirhdr_size);
if (name[filename_len - 1] == '/' || name[filename_len - 1] == '\\' || (external_attr & 0x10))
continue;
/* Handle Zip64 fields */
if (decomp_size == 0xFFFFFFFF || comp_size == 0xFFFFFFFF || local_hdr_ofs == 0xFFFFFFFF)
{
@@ -877,7 +897,7 @@ static int rc_hash_zip_file(md5_state_t* md5, void* file_handle)
hashindex++;
/* Convert and store the file name in the hash data buffer */
for (name = (cdir + cdirhdr_size), name_end = name + filename_len; name != name_end; name++)
for (name_end = name + filename_len; name != name_end; name++)
{
*(hashdata++) =
(*name == '\\' ? '/' : /* convert back-slashes to regular slashes */
@@ -972,11 +992,12 @@ static int rc_hash_arcade(char hash[33], const char* path)
/* arcade hash is just the hash of the filename (no extension) - the cores are pretty stringent about having the right ROM data */
const char* filename = rc_path_get_filename(path);
const char* ext = rc_path_get_extension(filename);
char buffer[128]; /* realistically, this should never need more than ~32 characters */
size_t filename_length = ext - filename - 1;
/* fbneo supports loading subsystems by using specific folder names.
* if one is found, include it in the hash.
* https://github.com/libretro/FBNeo/blob/master/src/burner/libretro/README.md#emulating-consoles
* https://github.com/libretro/FBNeo/blob/master/src/burner/libretro/README.md#emulating-consoles-and-computers
*/
if (filename > path + 1)
{
@@ -993,31 +1014,67 @@ static int rc_hash_arcade(char hash[33], const char* path)
} while (folder > path);
parent_folder_length = filename - folder - 1;
if (parent_folder_length < 16)
{
char* ptr = buffer;
while (folder < filename - 1)
*ptr++ = tolower(*folder++);
*ptr = '\0';
folder = buffer;
}
switch (parent_folder_length)
{
case 3:
if (memcmp(folder, "nes", 3) == 0 ||
memcmp(folder, "fds", 3) == 0 ||
memcmp(folder, "sms", 3) == 0 ||
memcmp(folder, "msx", 3) == 0 ||
memcmp(folder, "ngp", 3) == 0 ||
memcmp(folder, "pce", 3) == 0 ||
memcmp(folder, "sgx", 3) == 0)
if (memcmp(folder, "nes", 3) == 0 || /* NES */
memcmp(folder, "fds", 3) == 0 || /* FDS */
memcmp(folder, "sms", 3) == 0 || /* Master System */
memcmp(folder, "msx", 3) == 0 || /* MSX */
memcmp(folder, "ngp", 3) == 0 || /* NeoGeo Pocket */
memcmp(folder, "pce", 3) == 0 || /* PCEngine */
memcmp(folder, "chf", 3) == 0 || /* ChannelF */
memcmp(folder, "sgx", 3) == 0) /* SuperGrafX */
include_folder = 1;
break;
case 4:
if (memcmp(folder, "tg16", 4) == 0)
if (memcmp(folder, "tg16", 4) == 0 || /* TurboGrafx-16 */
memcmp(folder, "msx1", 4) == 0) /* MSX */
include_folder = 1;
break;
case 5:
if (memcmp(folder, "neocd", 5) == 0) /* NeoGeo CD */
include_folder = 1;
break;
case 6:
if (memcmp(folder, "coleco", 6) == 0 ||
memcmp(folder, "sg1000", 6) == 0)
if (memcmp(folder, "coleco", 6) == 0 || /* Colecovision */
memcmp(folder, "sg1000", 6) == 0) /* SG-1000 */
include_folder = 1;
break;
case 7:
if (memcmp(folder, "genesis", 7) == 0) /* Megadrive (Genesis) */
include_folder = 1;
break;
case 8:
if (memcmp(folder, "gamegear", 8) == 0 ||
memcmp(folder, "megadriv", 8) == 0 ||
memcmp(folder, "spectrum", 8) == 0)
if (memcmp(folder, "gamegear", 8) == 0 || /* Game Gear */
memcmp(folder, "megadriv", 8) == 0 || /* Megadrive */
memcmp(folder, "pcengine", 8) == 0 || /* PCEngine */
memcmp(folder, "channelf", 8) == 0 || /* ChannelF */
memcmp(folder, "spectrum", 8) == 0) /* ZX Spectrum */
include_folder = 1;
break;
case 9:
if (memcmp(folder, "megadrive", 9) == 0) /* Megadrive */
include_folder = 1;
break;
case 10:
if (memcmp(folder, "supergrafx", 10) == 0 || /* SuperGrafX */
memcmp(folder, "zxspectrum", 10) == 0) /* ZX Spectrum */
include_folder = 1;
break;
case 12:
if (memcmp(folder, "mastersystem", 12) == 0 || /* Master System */
memcmp(folder, "colecovision", 12) == 0) /* Colecovision */
include_folder = 1;
break;
default:
@@ -1026,10 +1083,8 @@ static int rc_hash_arcade(char hash[33], const char* path)
if (include_folder)
{
char buffer[128]; /* realistically, this should never need more than ~20 characters */
if (parent_folder_length + filename_length + 1 < sizeof(buffer))
{
memcpy(&buffer[0], folder, parent_folder_length);
buffer[parent_folder_length] = '_';
memcpy(&buffer[parent_folder_length + 1], filename, filename_length);
return rc_hash_buffer(hash, (uint8_t*)&buffer[0], parent_folder_length + filename_length + 1);
@@ -2121,6 +2176,14 @@ static int rc_hash_psp(char hash[33], const char* path)
uint32_t size;
md5_state_t md5;
/* https://www.psdevwiki.com/psp/PBP
* A PBP file is an archive containing the PARAM.SFO, primary executable, and a bunch of metadata.
* While we could extract the PARAM.SFO and primary executable to mimic the normal PSP hashing logic,
* it's easier to just hash the entire file. This also helps alleviate issues where the primary
* executable is just a game engine and the only differentiating data would be the metadata. */
if (rc_path_compare_extension(path, "pbp"))
return rc_hash_whole_file(hash, path);
track_handle = rc_cd_open_track(path, 1);
if (!track_handle)
return rc_hash_error("Could not open track");
@@ -3134,6 +3197,10 @@ void rc_hash_initialize_iterator(struct rc_hash_iterator* iterator, const char*
{
iterator->consoles[0] = RC_CONSOLE_PC_ENGINE;
}
else if (rc_path_compare_extension(ext, "pbp"))
{
iterator->consoles[0] = RC_CONSOLE_PSP;
}
else if (rc_path_compare_extension(ext, "pgm"))
{
iterator->consoles[0] = RC_CONSOLE_ELEKTOR_TV_GAMES_COMPUTER;