dep/rcheevos: Bump to d54cf8f
This commit is contained in:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user