mirror of
https://github.com/libretro/RetroArch
synced 2025-02-15 00:40:06 +00:00
Merge pull request #10977 from Jamiras/rcheevos_91
upgrade to rcheevos 9.1
This commit is contained in:
commit
5eb0b96438
deps/rcheevos/src
18
deps/rcheevos/src/rcheevos/compat.c
vendored
18
deps/rcheevos/src/rcheevos/compat.c
vendored
@ -22,6 +22,24 @@ int rc_strncasecmp(const char* left, const char* right, size_t length)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rc_strcasecmp(const char* left, const char* right)
|
||||
{
|
||||
while (*left || *right)
|
||||
{
|
||||
if (*left != *right)
|
||||
{
|
||||
const int diff = tolower(*left) - tolower(*right);
|
||||
if (diff != 0)
|
||||
return diff;
|
||||
}
|
||||
|
||||
++left;
|
||||
++right;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
char* rc_strdup(const char* str)
|
||||
{
|
||||
const size_t length = strlen(str);
|
||||
|
5
deps/rcheevos/src/rcheevos/compat.h
vendored
5
deps/rcheevos/src/rcheevos/compat.h
vendored
@ -41,6 +41,11 @@ extern "C" {
|
||||
#define strncasecmp rc_strncasecmp
|
||||
#endif
|
||||
|
||||
#ifndef strcasecmp
|
||||
extern int rc_strcasecmp(const char* left, const char* right);
|
||||
#define strcasecmp rc_strcasecmp
|
||||
#endif
|
||||
|
||||
#ifndef strdup
|
||||
extern char* rc_strdup(const char* str);
|
||||
#define strdup rc_strdup
|
||||
|
15
deps/rcheevos/src/rcheevos/condition.c
vendored
15
deps/rcheevos/src/rcheevos/condition.c
vendored
@ -213,9 +213,20 @@ int rc_evaluate_condition_value(rc_condition_t* self, rc_eval_state_t* eval_stat
|
||||
|
||||
case RC_OPERATOR_DIV:
|
||||
if (self->operand2.type == RC_OPERAND_FP)
|
||||
value = (int)((double)value / self->operand2.value.dbl);
|
||||
{
|
||||
if (self->operand2.value.dbl == 0.0)
|
||||
value = 0;
|
||||
else
|
||||
value = (int)((double)value / self->operand2.value.dbl);
|
||||
}
|
||||
else
|
||||
value /= rc_evaluate_operand(&self->operand2, eval_state);
|
||||
{
|
||||
unsigned value2 = rc_evaluate_operand(&self->operand2, eval_state);
|
||||
if (value2 == 0)
|
||||
value = 0;
|
||||
else
|
||||
value /= value2;
|
||||
}
|
||||
break;
|
||||
|
||||
case RC_OPERATOR_AND:
|
||||
|
24
deps/rcheevos/src/rcheevos/condset.c
vendored
24
deps/rcheevos/src/rcheevos/condset.c
vendored
@ -114,6 +114,7 @@ static int rc_test_condset_internal(rc_condset_t* self, int processing_pause, rc
|
||||
rc_condition_t* condition;
|
||||
int set_valid, cond_valid, and_next, or_next;
|
||||
unsigned measured_value = 0;
|
||||
unsigned total_hits = 0;
|
||||
int can_measure = 1, measured_from_hits = 0;
|
||||
|
||||
eval_state->primed = 1;
|
||||
@ -207,12 +208,14 @@ static int rc_test_condset_internal(rc_condset_t* self, int processing_pause, rc
|
||||
break;
|
||||
}
|
||||
|
||||
/* STEP 4: calculate total hits */
|
||||
total_hits = condition->current_hits;
|
||||
|
||||
if (eval_state->add_hits) {
|
||||
if (condition->required_hits != 0) {
|
||||
/* if the condition has a target hit count, we have to recalculate cond_valid including the AddHits counter */
|
||||
measured_from_hits = 1;
|
||||
measured_value = condition->current_hits + eval_state->add_hits;
|
||||
cond_valid = (measured_value >= condition->required_hits);
|
||||
total_hits = condition->current_hits + eval_state->add_hits;
|
||||
cond_valid = (total_hits >= condition->required_hits);
|
||||
}
|
||||
else {
|
||||
/* no target hit count. we can't tell if the add_hits value is from this frame or not, so ignore it.
|
||||
@ -221,13 +224,8 @@ static int rc_test_condset_internal(rc_condset_t* self, int processing_pause, rc
|
||||
|
||||
eval_state->add_hits = 0;
|
||||
}
|
||||
else if (condition->required_hits != 0) {
|
||||
/* if there's a hit target, capture the current hits for recording Measured value later */
|
||||
measured_from_hits = 1;
|
||||
measured_value = condition->current_hits;
|
||||
}
|
||||
|
||||
/* STEP 4: handle special flags */
|
||||
/* STEP 5: handle special flags */
|
||||
switch (condition->type) {
|
||||
case RC_CONDITION_PAUSE_IF:
|
||||
/* as soon as we find a PauseIf that evaluates to true, stop processing the rest of the group */
|
||||
@ -256,6 +254,14 @@ static int rc_test_condset_internal(rc_condset_t* self, int processing_pause, rc
|
||||
}
|
||||
continue;
|
||||
|
||||
case RC_CONDITION_MEASURED:
|
||||
if (condition->required_hits != 0) {
|
||||
/* if there's a hit target, capture the current hits for recording Measured value later */
|
||||
measured_from_hits = 1;
|
||||
measured_value = total_hits;
|
||||
}
|
||||
break;
|
||||
|
||||
case RC_CONDITION_MEASURED_IF:
|
||||
if (!cond_valid)
|
||||
can_measure = 0;
|
||||
|
48
deps/rcheevos/src/rcheevos/consoleinfo.c
vendored
48
deps/rcheevos/src/rcheevos/consoleinfo.c
vendored
@ -113,7 +113,7 @@ const char* rc_console_name(int console_id)
|
||||
return "PC-9800";
|
||||
|
||||
case RC_CONSOLE_PCFX:
|
||||
return "PCFX";
|
||||
return "PC-FX";
|
||||
|
||||
case RC_CONSOLE_PC_ENGINE:
|
||||
return "PCEngine";
|
||||
@ -394,6 +394,15 @@ static const rc_memory_region_t _rc_memory_regions_pcengine[] = {
|
||||
};
|
||||
static const rc_memory_regions_t rc_memory_regions_pcengine = { _rc_memory_regions_pcengine, 4 };
|
||||
|
||||
/* ===== PC-FX ===== */
|
||||
/* http://daifukkat.su/pcfx/data/memmap.html */
|
||||
static const rc_memory_region_t _rc_memory_regions_pcfx[] = {
|
||||
{ 0x000000U, 0x1FFFFFU, 0x00000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" },
|
||||
{ 0x200000U, 0x207FFFU, 0xE0000000U, RC_MEMORY_TYPE_SAVE_RAM, "Internal Backup Memory" },
|
||||
{ 0x208000U, 0x20FFFFU, 0xE8000000U, RC_MEMORY_TYPE_SAVE_RAM, "External Backup Memory" },
|
||||
};
|
||||
static const rc_memory_regions_t rc_memory_regions_pcfx = { _rc_memory_regions_pcfx, 3 };
|
||||
|
||||
/* ===== PlayStation ===== */
|
||||
/* http://www.raphnet.net/electronique/psx_adaptor/Playstation.txt */
|
||||
static const rc_memory_region_t _rc_memory_regions_playstation[] = {
|
||||
@ -421,7 +430,7 @@ static const rc_memory_regions_t rc_memory_regions_segacd = { _rc_memory_regions
|
||||
/* https://segaretro.org/Sega_Saturn_hardware_notes_(2004-04-27) */
|
||||
static const rc_memory_region_t _rc_memory_regions_saturn[] = {
|
||||
{ 0x000000U, 0x0FFFFFU, 0x00200000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Work RAM Low" },
|
||||
{ 0x100000U, 0x1FFFFFU, 0x06000000U, RC_MEMORY_TYPE_SAVE_RAM, "Work RAM High" }
|
||||
{ 0x100000U, 0x1FFFFFU, 0x06000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Work RAM High" }
|
||||
};
|
||||
static const rc_memory_regions_t rc_memory_regions_saturn = { _rc_memory_regions_saturn, 2 };
|
||||
|
||||
@ -455,15 +464,6 @@ static const rc_memory_region_t _rc_memory_regions_snes[] = {
|
||||
};
|
||||
static const rc_memory_regions_t rc_memory_regions_snes = { _rc_memory_regions_snes, 2 };
|
||||
|
||||
/* ===== WonderSwan ===== */
|
||||
/* http://daifukkat.su/docs/wsman/#ovr_memmap */
|
||||
static const rc_memory_region_t _rc_memory_regions_wonderswan[] = {
|
||||
/* RAM ends at 0x3FFF for WonderSwan, WonderSwan color uses all 64KB */
|
||||
{ 0x000000U, 0x00FFFFU, 0x000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" },
|
||||
{ 0x010000U, 0x01FFFFU, 0x000000U, RC_MEMORY_TYPE_SAVE_RAM, "Cartridge RAM" }
|
||||
};
|
||||
static const rc_memory_regions_t rc_memory_regions_wonderswan = { _rc_memory_regions_wonderswan, 2 };
|
||||
|
||||
/* ===== Vectrex ===== */
|
||||
/* https://roadsidethoughts.com/vectrex/vectrex-memory-map.htm */
|
||||
static const rc_memory_region_t _rc_memory_regions_vectrex[] = {
|
||||
@ -478,6 +478,23 @@ static const rc_memory_region_t _rc_memory_regions_virtualboy[] = {
|
||||
};
|
||||
static const rc_memory_regions_t rc_memory_regions_virtualboy = { _rc_memory_regions_virtualboy, 2 };
|
||||
|
||||
/* ===== WonderSwan ===== */
|
||||
/* http://daifukkat.su/docs/wsman/#ovr_memmap */
|
||||
static const rc_memory_region_t _rc_memory_regions_wonderswan[] = {
|
||||
/* RAM ends at 0x3FFF for WonderSwan, WonderSwan color uses all 64KB */
|
||||
{ 0x000000U, 0x00FFFFU, 0x000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" },
|
||||
/* Only 64KB of SRAM is accessible via the addressing scheme, but the cartridge
|
||||
* may have up to 512KB of SRAM. http://daifukkat.su/docs/wsman/#cart_meta
|
||||
* Since beetle_wswan exposes it as a contiguous block, assume its contiguous
|
||||
* even though the documentation says $20000-$FFFFF is ROM data. If this causes
|
||||
* a conflict in the future, we can revisit. A new region with a virtual address
|
||||
* could be added to pick up the additional SRAM data. As long as it immediately
|
||||
* follows the 64KB at $10000, all existing achievements should be unaffected.
|
||||
*/
|
||||
{ 0x010000U, 0x08FFFFU, 0x010000U, RC_MEMORY_TYPE_SAVE_RAM, "Cartridge RAM" }
|
||||
};
|
||||
static const rc_memory_regions_t rc_memory_regions_wonderswan = { _rc_memory_regions_wonderswan, 2 };
|
||||
|
||||
/* ===== default ===== */
|
||||
static const rc_memory_regions_t rc_memory_regions_none = { 0, 0 };
|
||||
|
||||
@ -554,6 +571,9 @@ const rc_memory_regions_t* rc_console_memory_regions(int console_id)
|
||||
case RC_CONSOLE_PC_ENGINE:
|
||||
return &rc_memory_regions_pcengine;
|
||||
|
||||
case RC_CONSOLE_PCFX:
|
||||
return &rc_memory_regions_pcfx;
|
||||
|
||||
case RC_CONSOLE_PLAYSTATION:
|
||||
return &rc_memory_regions_playstation;
|
||||
|
||||
@ -575,15 +595,15 @@ const rc_memory_regions_t* rc_console_memory_regions(int console_id)
|
||||
case RC_CONSOLE_SUPER_NINTENDO:
|
||||
return &rc_memory_regions_snes;
|
||||
|
||||
case RC_CONSOLE_WONDERSWAN:
|
||||
return &rc_memory_regions_wonderswan;
|
||||
|
||||
case RC_CONSOLE_VECTREX:
|
||||
return &rc_memory_regions_vectrex;
|
||||
|
||||
case RC_CONSOLE_VIRTUAL_BOY:
|
||||
return &rc_memory_regions_virtualboy;
|
||||
|
||||
case RC_CONSOLE_WONDERSWAN:
|
||||
return &rc_memory_regions_wonderswan;
|
||||
|
||||
default:
|
||||
return &rc_memory_regions_none;
|
||||
}
|
||||
|
87
deps/rcheevos/src/rhash/hash.c
vendored
87
deps/rcheevos/src/rhash/hash.c
vendored
@ -399,7 +399,7 @@ static int rc_hash_3do(char hash[33], const char* path)
|
||||
{
|
||||
if (buffer[offset + 0x03] == 0x02) /* file */
|
||||
{
|
||||
if (strcasecmp((char*)&buffer[offset + 0x20], "LaunchMe") == 0)
|
||||
if (strcasecmp((const char*)&buffer[offset + 0x20], "LaunchMe") == 0)
|
||||
{
|
||||
/* the block size is at offset 0x0C (assume 0x0C is always 0) */
|
||||
block_size = buffer[offset + 0x0D] * 65536 + buffer[offset + 0x0E] * 256 + buffer[offset + 0x0F];
|
||||
@ -710,7 +710,7 @@ static int rc_hash_pce_cd(char hash[33], const char* path)
|
||||
rc_cd_read_sector(track_handle, 1, buffer, 128);
|
||||
|
||||
/* normal PC Engine CD will have a header block in sector 1 */
|
||||
if (strncmp("PC Engine CD-ROM SYSTEM", (const char*)&buffer[32], 23) == 0)
|
||||
if (memcmp("PC Engine CD-ROM SYSTEM", &buffer[32], 23) == 0)
|
||||
{
|
||||
/* the title of the disc is the last 22 bytes of the header */
|
||||
md5_init(&md5);
|
||||
@ -727,7 +727,7 @@ static int rc_hash_pce_cd(char hash[33], const char* path)
|
||||
/* the first three bytes specify the sector of the program data, and the fourth byte
|
||||
* is the number of sectors.
|
||||
*/
|
||||
sector = buffer[0] * 65536 + buffer[1] * 256 + buffer[2];
|
||||
sector = (buffer[0] << 16) + (buffer[1] << 8) + buffer[2];
|
||||
num_sectors = buffer[3];
|
||||
|
||||
if (verbose_message_callback)
|
||||
@ -776,6 +776,78 @@ static int rc_hash_pce_cd(char hash[33], const char* path)
|
||||
return rc_hash_finalize(&md5, hash);
|
||||
}
|
||||
|
||||
static int rc_hash_pcfx_cd(char hash[33], const char* path)
|
||||
{
|
||||
uint8_t buffer[2048];
|
||||
void* track_handle;
|
||||
md5_state_t md5;
|
||||
int sector, num_sectors;
|
||||
|
||||
track_handle = rc_cd_open_track(path, 0);
|
||||
if (!track_handle)
|
||||
return rc_hash_error("Could not open track");
|
||||
|
||||
/* PC-FX boot header fills the first two sectors of the disc
|
||||
* https://bitbucket.org/trap15/pcfxtools/src/master/pcfx-cdlink.c
|
||||
*/
|
||||
|
||||
/* PC-FX CD will have a header marker in sector 0 */
|
||||
rc_cd_read_sector(track_handle, 0, buffer, 32);
|
||||
if (memcmp("PC-FX:Hu_CD-ROM", &buffer[0], 15) == 0)
|
||||
{
|
||||
/* the important stuff is the first 128 bytes of the second sector (title being the first 32) */
|
||||
rc_cd_read_sector(track_handle, 1, buffer, 128);
|
||||
|
||||
md5_init(&md5);
|
||||
md5_append(&md5, buffer, 128);
|
||||
|
||||
if (verbose_message_callback)
|
||||
{
|
||||
char message[128];
|
||||
buffer[128] = '\0';
|
||||
snprintf(message, sizeof(message), "Found PC-FX CD, title=%.32s", &buffer[0]);
|
||||
verbose_message_callback(message);
|
||||
}
|
||||
|
||||
/* the program sector is in bytes 33-36 (assume byte 36 is 0) */
|
||||
sector = (buffer[34] << 16) + (buffer[33] << 8) + buffer[32];
|
||||
|
||||
/* the number of sectors the program occupies is in bytes 37-40 (assume byte 40 is 0) */
|
||||
num_sectors = (buffer[38] << 16) + (buffer[37] << 8) + buffer[36];
|
||||
|
||||
if (verbose_message_callback)
|
||||
{
|
||||
char message[128];
|
||||
snprintf(message, sizeof(message), "Hashing %d sectors starting at sector %d", num_sectors, sector);
|
||||
verbose_message_callback(message);
|
||||
}
|
||||
|
||||
while (num_sectors > 0)
|
||||
{
|
||||
rc_cd_read_sector(track_handle, sector, buffer, sizeof(buffer));
|
||||
md5_append(&md5, buffer, sizeof(buffer));
|
||||
|
||||
++sector;
|
||||
--num_sectors;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rc_cd_read_sector(track_handle, 1, buffer, 128);
|
||||
rc_cd_close_track(track_handle);
|
||||
|
||||
/* some PC-FX CDs still identify as PCE CDs */
|
||||
if (memcmp("PC Engine CD-ROM SYSTEM", &buffer[32], 23) == 0)
|
||||
return rc_hash_pce_cd(hash, path);
|
||||
|
||||
return rc_hash_error("Not a PC-FX CD");
|
||||
}
|
||||
|
||||
rc_cd_close_track(track_handle);
|
||||
|
||||
return rc_hash_finalize(&md5, hash);
|
||||
}
|
||||
|
||||
static int rc_hash_psx(char hash[33], const char* path)
|
||||
{
|
||||
uint8_t buffer[2048];
|
||||
@ -1297,6 +1369,12 @@ int rc_hash_generate_from_file(char hash[33], int console_id, const char* path)
|
||||
|
||||
return rc_hash_whole_file(hash, console_id, path);
|
||||
|
||||
case RC_CONSOLE_PCFX:
|
||||
if (rc_path_compare_extension(path, "m3u"))
|
||||
return rc_hash_generate_from_playlist(hash, console_id, path);
|
||||
|
||||
return rc_hash_pcfx_cd(hash, path);
|
||||
|
||||
case RC_CONSOLE_PLAYSTATION:
|
||||
if (rc_path_compare_extension(path, "m3u"))
|
||||
return rc_hash_generate_from_playlist(hash, console_id, path);
|
||||
@ -1452,8 +1530,9 @@ void rc_hash_initialize_iterator(struct rc_hash_iterator* iterator, const char*
|
||||
iterator->consoles[0] = RC_CONSOLE_PLAYSTATION;
|
||||
iterator->consoles[1] = RC_CONSOLE_PC_ENGINE;
|
||||
iterator->consoles[2] = RC_CONSOLE_3DO;
|
||||
iterator->consoles[3] = RC_CONSOLE_PCFX;
|
||||
/* SEGA CD hash doesn't have any logic to ensure it's being used against a SEGA CD, so it should always be last */
|
||||
iterator->consoles[3] = RC_CONSOLE_SEGA_CD;
|
||||
iterator->consoles[4] = RC_CONSOLE_SEGA_CD;
|
||||
need_path = 1;
|
||||
}
|
||||
else if (rc_path_compare_extension(ext, "col"))
|
||||
|
Loading…
x
Reference in New Issue
Block a user