mirror of
https://github.com/libretro/RetroArch
synced 2025-02-10 21:40:22 +00:00
upgrade to rcheevos 10.6 (#14911)
This commit is contained in:
parent
46cf1d795a
commit
5ecdc4c170
@ -672,6 +672,7 @@ bool rcheevos_unload(void)
|
||||
|
||||
if (rcheevos_locals.loaded)
|
||||
{
|
||||
unsigned count = 0;
|
||||
#ifdef HAVE_MENU
|
||||
rcheevos_menu_reset_badges();
|
||||
|
||||
@ -684,6 +685,45 @@ bool rcheevos_unload(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
count = rcheevos_locals.game.achievement_count;
|
||||
rcheevos_locals.game.achievement_count = 0;
|
||||
if (rcheevos_locals.game.achievements)
|
||||
{
|
||||
rcheevos_racheevo_t* achievement = rcheevos_locals.game.achievements;
|
||||
rcheevos_racheevo_t* end = achievement + count;
|
||||
while (achievement < end)
|
||||
{
|
||||
CHEEVOS_FREE(achievement->title);
|
||||
CHEEVOS_FREE(achievement->description);
|
||||
CHEEVOS_FREE(achievement->badge);
|
||||
CHEEVOS_FREE(achievement->memaddr);
|
||||
|
||||
++achievement;
|
||||
}
|
||||
|
||||
CHEEVOS_FREE(rcheevos_locals.game.achievements);
|
||||
rcheevos_locals.game.achievements = NULL;
|
||||
}
|
||||
|
||||
count = rcheevos_locals.game.leaderboard_count;
|
||||
rcheevos_locals.game.leaderboard_count = 0;
|
||||
if (rcheevos_locals.game.leaderboards)
|
||||
{
|
||||
rcheevos_ralboard_t* lboard = rcheevos_locals.game.leaderboards;
|
||||
rcheevos_ralboard_t* end = lboard + count;
|
||||
while (lboard < end)
|
||||
{
|
||||
CHEEVOS_FREE(lboard->title);
|
||||
CHEEVOS_FREE(lboard->description);
|
||||
CHEEVOS_FREE(lboard->mem);
|
||||
|
||||
++lboard;
|
||||
}
|
||||
|
||||
CHEEVOS_FREE(rcheevos_locals.game.leaderboards);
|
||||
rcheevos_locals.game.leaderboards = NULL;
|
||||
}
|
||||
|
||||
if (rcheevos_locals.game.title)
|
||||
{
|
||||
CHEEVOS_FREE(rcheevos_locals.game.title);
|
||||
@ -1535,6 +1575,9 @@ static void rcheevos_show_game_placard(void)
|
||||
int number_of_core = 0;
|
||||
int mode = RCHEEVOS_ACTIVE_SOFTCORE;
|
||||
|
||||
if (rcheevos_locals.game.id < 0) /* make sure there's actually a game loaded */
|
||||
return;
|
||||
|
||||
if (rcheevos_locals.hardcore_active)
|
||||
mode = RCHEEVOS_ACTIVE_HARDCORE;
|
||||
|
||||
|
64
deps/rcheevos/CHANGELOG.md
vendored
64
deps/rcheevos/CHANGELOG.md
vendored
@ -1,3 +1,67 @@
|
||||
# v10.6.0
|
||||
* add RC_RUNTIME_EVENT_ACHIEVEMENT_PROGRESS_UPDATED
|
||||
* use optimized comparators for most common condition logic
|
||||
* fix game identification of psx ISOs that have extra slashes in their boot path
|
||||
* fix game identification of ndd files
|
||||
|
||||
# v10.5.0
|
||||
* add RC_MEMSIZE_MBF32_LE
|
||||
* add RC_OPERATOR_XOR
|
||||
* add RC_CONSOLE_ATARI_JAGUAR_CD and hash/memory map for Atari Jaguar CD
|
||||
* add RC_CONSOLE_ARCADIA_2001 and hash/memory map for Arcadia 2001
|
||||
* add RC_CONSOLE_INTERTON_VC_4000 and hash/memory map for Interton VC 4000
|
||||
* add RC_CONSOLE_ELEKTOR_TV_GAMES_COMPUTER and hash/memory map for Elektor TV Games Computer
|
||||
* split RC_CONSOLE_PC_ENGINE_CD off of RC_CONSOLE_PC_ENGINE
|
||||
* add hash/memory map for RC_CONSOLE_NEO_GEO_CD
|
||||
* add additional 256KB of RAM to memory map for RC_CONSOLE_SEGA_32X
|
||||
* validation: don't report redundancy between trigger and non-trigger conditions
|
||||
* validation: don't report range validation errors for float comparisons
|
||||
* change default image host to media.retroachievements.org
|
||||
* fix decoding of denormalized floats
|
||||
* fix full line comments in the middle of Display: section causing RC_MISSING_DISPLAY_STRING
|
||||
|
||||
# v10.4.0
|
||||
* add rc_libretro_hash_set_t with support for #SAVEDISK: m3u extension
|
||||
* add rc_libretro_is_system_allowed for finer-grain control over core support
|
||||
* fix measured value from hitcount not resetting while paused
|
||||
* add RC_CONSOLE_WASM and hash/memory map for WASM-4
|
||||
* add scratchpad memory to RC_CONSOLE_PLAYSTATION_2 memory map
|
||||
* add hash/memory map for RC_CONSOLE_FAIRCHILD_CHANNEL_F
|
||||
* add hash/memory map for RC_CONSOLE_COMMODORE_64
|
||||
* add memory map for RC_CONSOLE_AMIGA
|
||||
|
||||
# v10.3.3
|
||||
* add RC_CONSOLE_ARDUBOY and hash/memory map for Arduboy
|
||||
* add display_name to rc_api_login_response_t
|
||||
* detect logical conflicts and redundancies in validator
|
||||
* fix tab sequences in JSON responses being turned into t
|
||||
* fix overflow when float value has more than 9 digits after the decimal
|
||||
* fix libretro memory mapping when disconnect mask breaks a region into multiple blocks
|
||||
* fix non-virtualized file system call when reading some iso files
|
||||
|
||||
# v10.3.2
|
||||
* fix RC_OPERAND_PRIOR for bit sizes other than RC_MEMSIZE_BIT_0
|
||||
* add memory map and hash for Amstrad CPC
|
||||
* fix an issue where fetch_game_data and fetch_user_unlocks could return RC_MISSING_VALUE instead of acknowledging a server error
|
||||
|
||||
# v10.3.1
|
||||
* allow empty description in rc_api_init_update_leaderboard_request
|
||||
* fix buffered n64 hash when no filereader is registered
|
||||
* add memory map and hash for Mega Duck
|
||||
|
||||
# v10.3.0
|
||||
* support for floating point memory sizes and logic
|
||||
* add built-in macros for rich presence: @Number, @Score, @Centisecs, @Seconds, @Minutes, @ASCIIChar, @UnicodeChar
|
||||
* add rapi functions for fetch_code_notes, update_code_note, upload_achievement, update_leaderboard, fetch_badge_range, and add_game_hash
|
||||
* add lower_is_better and hidden flags to leaderboards in rc_api_fetch_game_data_response_t
|
||||
* add achievements_remaining to rc_api_award_achievement_response_t
|
||||
* add console enums for PC6000, PICO, MEGADUCK and ZEEBO
|
||||
* add memory map for Dreamcast
|
||||
* capture leaderboard/rich presence state in rc_runtime_progress data
|
||||
* support for hashing Dreamcast bin/cues
|
||||
* support for hashing buffered NDS ROMs
|
||||
* fix prior for sizes smaller than a byte sometimes returning current value
|
||||
|
||||
# v10.2.0
|
||||
|
||||
* add RC_MEMSIZE_16_BITS_BE, RC_MEMSIZE_24_BITS_BE, and RC_MEMSIZE_32_BITS_BE
|
||||
|
3
deps/rcheevos/include/rc_runtime_types.h
vendored
3
deps/rcheevos/include/rc_runtime_types.h
vendored
@ -200,6 +200,9 @@ struct rc_condition_t {
|
||||
|
||||
/* Whether or not the condition evaluated true on the last check */
|
||||
char is_true;
|
||||
|
||||
/* Unique identifier of optimized comparator to use */
|
||||
char optimized_comparator;
|
||||
};
|
||||
|
||||
/*****************************************************************************\
|
||||
|
284
deps/rcheevos/src/rcheevos/condition.c
vendored
284
deps/rcheevos/src/rcheevos/condition.c
vendored
@ -1,6 +1,91 @@
|
||||
#include "rc_internal.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
static int rc_test_condition_compare(unsigned value1, unsigned value2, char oper) {
|
||||
switch (oper) {
|
||||
case RC_OPERATOR_EQ: return value1 == value2;
|
||||
case RC_OPERATOR_NE: return value1 != value2;
|
||||
case RC_OPERATOR_LT: return value1 < value2;
|
||||
case RC_OPERATOR_LE: return value1 <= value2;
|
||||
case RC_OPERATOR_GT: return value1 > value2;
|
||||
case RC_OPERATOR_GE: return value1 >= value2;
|
||||
default: return 1;
|
||||
}
|
||||
}
|
||||
|
||||
static char rc_condition_determine_comparator(const rc_condition_t* self) {
|
||||
switch (self->oper) {
|
||||
case RC_OPERATOR_EQ:
|
||||
case RC_OPERATOR_NE:
|
||||
case RC_OPERATOR_LT:
|
||||
case RC_OPERATOR_LE:
|
||||
case RC_OPERATOR_GT:
|
||||
case RC_OPERATOR_GE:
|
||||
break;
|
||||
|
||||
default:
|
||||
/* not a comparison. should not be getting compared. but if it is, legacy behavior was to return 1 */
|
||||
return RC_PROCESSING_COMPARE_ALWAYS_TRUE;
|
||||
}
|
||||
|
||||
if ((self->operand1.type == RC_OPERAND_ADDRESS || self->operand1.type == RC_OPERAND_DELTA) &&
|
||||
!self->operand1.value.memref->value.is_indirect && !rc_operand_is_float(&self->operand1)) {
|
||||
/* left side is an integer memory reference */
|
||||
int needs_translate = (self->operand1.size != self->operand1.value.memref->value.size);
|
||||
|
||||
if (self->operand2.type == RC_OPERAND_CONST) {
|
||||
/* right side is a constant */
|
||||
if (self->operand1.type == RC_OPERAND_ADDRESS)
|
||||
return needs_translate ? RC_PROCESSING_COMPARE_MEMREF_TO_CONST_TRANSFORMED : RC_PROCESSING_COMPARE_MEMREF_TO_CONST;
|
||||
|
||||
return needs_translate ? RC_PROCESSING_COMPARE_DELTA_TO_CONST_TRANSFORMED : RC_PROCESSING_COMPARE_DELTA_TO_CONST;
|
||||
}
|
||||
else if ((self->operand2.type == RC_OPERAND_ADDRESS || self->operand2.type == RC_OPERAND_DELTA) &&
|
||||
!self->operand2.value.memref->value.is_indirect && !rc_operand_is_float(&self->operand2)) {
|
||||
/* right side is an integer memory reference */
|
||||
const int is_same_memref = (self->operand1.value.memref == self->operand2.value.memref);
|
||||
needs_translate |= (self->operand2.size != self->operand2.value.memref->value.size);
|
||||
|
||||
if (self->operand1.type == RC_OPERAND_ADDRESS) {
|
||||
if (self->operand2.type == RC_OPERAND_ADDRESS) {
|
||||
if (is_same_memref && !needs_translate) {
|
||||
/* comparing a memref to itself, will evaluate to a constant */
|
||||
return rc_test_condition_compare(0, 0, self->oper) ? RC_PROCESSING_COMPARE_ALWAYS_TRUE : RC_PROCESSING_COMPARE_ALWAYS_FALSE;
|
||||
}
|
||||
|
||||
return needs_translate ? RC_PROCESSING_COMPARE_MEMREF_TO_MEMREF_TRANSFORMED : RC_PROCESSING_COMPARE_MEMREF_TO_MEMREF;
|
||||
}
|
||||
|
||||
assert(self->operand2.type == RC_OPERAND_DELTA);
|
||||
|
||||
if (is_same_memref) {
|
||||
/* delta comparison is optimized to compare with itself (for detecting change) */
|
||||
return needs_translate ? RC_PROCESSING_COMPARE_MEMREF_TO_DELTA_TRANSFORMED : RC_PROCESSING_COMPARE_MEMREF_TO_DELTA;
|
||||
}
|
||||
}
|
||||
else {
|
||||
assert(self->operand1.type == RC_OPERAND_DELTA);
|
||||
|
||||
if (self->operand2.type == RC_OPERAND_ADDRESS) {
|
||||
if (is_same_memref) {
|
||||
/* delta comparison is optimized to compare with itself (for detecting change) */
|
||||
return needs_translate ? RC_PROCESSING_COMPARE_DELTA_TO_MEMREF_TRANSFORMED : RC_PROCESSING_COMPARE_DELTA_TO_MEMREF;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (self->operand1.type == RC_OPERAND_CONST && self->operand2.type == RC_OPERAND_CONST) {
|
||||
/* comparing constants will always generate a constant result */
|
||||
return rc_test_condition_compare(self->operand1.value.num, self->operand2.value.num, self->oper) ?
|
||||
RC_PROCESSING_COMPARE_ALWAYS_TRUE : RC_PROCESSING_COMPARE_ALWAYS_FALSE;
|
||||
}
|
||||
|
||||
return RC_PROCESSING_COMPARE_DEFAULT;
|
||||
}
|
||||
|
||||
static int rc_parse_operator(const char** memaddr) {
|
||||
const char* oper = *memaddr;
|
||||
@ -75,6 +160,7 @@ rc_condition_t* rc_parse_condition(const char** memaddr, rc_parse_state_t* parse
|
||||
self->current_hits = 0;
|
||||
self->is_true = 0;
|
||||
self->pause = 0;
|
||||
self->optimized_comparator = RC_PROCESSING_COMPARE_DEFAULT;
|
||||
|
||||
if (*aux != 0 && aux[1] == ':') {
|
||||
switch (*aux) {
|
||||
@ -214,6 +300,9 @@ rc_condition_t* rc_parse_condition(const char** memaddr, rc_parse_state_t* parse
|
||||
self->required_hits = 0;
|
||||
}
|
||||
|
||||
if (parse->buffer != 0)
|
||||
self->optimized_comparator = rc_condition_determine_comparator(self);
|
||||
|
||||
*memaddr = aux;
|
||||
return self;
|
||||
}
|
||||
@ -233,12 +322,203 @@ int rc_condition_is_combining(const rc_condition_t* self) {
|
||||
}
|
||||
}
|
||||
|
||||
static int rc_test_condition_compare_memref_to_const(rc_condition_t* self) {
|
||||
const unsigned value1 = self->operand1.value.memref->value.value;
|
||||
const unsigned value2 = self->operand2.value.num;
|
||||
assert(self->operand1.size == self->operand1.value.memref->value.size);
|
||||
return rc_test_condition_compare(value1, value2, self->oper);
|
||||
}
|
||||
|
||||
static int rc_test_condition_compare_delta_to_const(rc_condition_t* self) {
|
||||
const rc_memref_value_t* memref1 = &self->operand1.value.memref->value;
|
||||
const unsigned value1 = (memref1->changed) ? memref1->prior : memref1->value;
|
||||
const unsigned value2 = self->operand2.value.num;
|
||||
assert(self->operand1.size == self->operand1.value.memref->value.size);
|
||||
return rc_test_condition_compare(value1, value2, self->oper);
|
||||
}
|
||||
|
||||
static int rc_test_condition_compare_memref_to_memref(rc_condition_t* self) {
|
||||
const unsigned value1 = self->operand1.value.memref->value.value;
|
||||
const unsigned value2 = self->operand2.value.memref->value.value;
|
||||
assert(self->operand1.size == self->operand1.value.memref->value.size);
|
||||
assert(self->operand2.size == self->operand2.value.memref->value.size);
|
||||
return rc_test_condition_compare(value1, value2, self->oper);
|
||||
}
|
||||
|
||||
static int rc_test_condition_compare_memref_to_delta(rc_condition_t* self) {
|
||||
const rc_memref_value_t* memref = &self->operand1.value.memref->value;
|
||||
assert(self->operand1.value.memref == self->operand2.value.memref);
|
||||
assert(self->operand1.size == self->operand1.value.memref->value.size);
|
||||
assert(self->operand2.size == self->operand2.value.memref->value.size);
|
||||
|
||||
if (memref->changed)
|
||||
return rc_test_condition_compare(memref->value, memref->prior, self->oper);
|
||||
|
||||
switch (self->oper) {
|
||||
case RC_OPERATOR_EQ:
|
||||
case RC_OPERATOR_GE:
|
||||
case RC_OPERATOR_LE:
|
||||
return 1;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int rc_test_condition_compare_delta_to_memref(rc_condition_t* self) {
|
||||
const rc_memref_value_t* memref = &self->operand1.value.memref->value;
|
||||
assert(self->operand1.value.memref == self->operand2.value.memref);
|
||||
assert(self->operand1.size == self->operand1.value.memref->value.size);
|
||||
assert(self->operand2.size == self->operand2.value.memref->value.size);
|
||||
|
||||
if (memref->changed)
|
||||
return rc_test_condition_compare(memref->prior, memref->value, self->oper);
|
||||
|
||||
switch (self->oper) {
|
||||
case RC_OPERATOR_EQ:
|
||||
case RC_OPERATOR_GE:
|
||||
case RC_OPERATOR_LE:
|
||||
return 1;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int rc_test_condition_compare_memref_to_const_transformed(rc_condition_t* self) {
|
||||
rc_typed_value_t value1;
|
||||
const unsigned value2 = self->operand2.value.num;
|
||||
|
||||
value1.type = RC_VALUE_TYPE_UNSIGNED;
|
||||
value1.value.u32 = self->operand1.value.memref->value.value;
|
||||
rc_transform_memref_value(&value1, self->operand1.size);
|
||||
|
||||
return rc_test_condition_compare(value1.value.u32, value2, self->oper);
|
||||
}
|
||||
|
||||
static int rc_test_condition_compare_delta_to_const_transformed(rc_condition_t* self) {
|
||||
rc_typed_value_t value1;
|
||||
const rc_memref_value_t* memref1 = &self->operand1.value.memref->value;
|
||||
const unsigned value2 = self->operand2.value.num;
|
||||
|
||||
value1.type = RC_VALUE_TYPE_UNSIGNED;
|
||||
value1.value.u32 = (memref1->changed) ? memref1->prior : memref1->value;
|
||||
rc_transform_memref_value(&value1, self->operand1.size);
|
||||
|
||||
return rc_test_condition_compare(value1.value.u32, value2, self->oper);
|
||||
}
|
||||
|
||||
static int rc_test_condition_compare_memref_to_memref_transformed(rc_condition_t* self) {
|
||||
rc_typed_value_t value1, value2;
|
||||
|
||||
value1.type = RC_VALUE_TYPE_UNSIGNED;
|
||||
value1.value.u32 = self->operand1.value.memref->value.value;
|
||||
rc_transform_memref_value(&value1, self->operand1.size);
|
||||
|
||||
value2.type = RC_VALUE_TYPE_UNSIGNED;
|
||||
value2.value.u32 = self->operand2.value.memref->value.value;
|
||||
rc_transform_memref_value(&value2, self->operand2.size);
|
||||
|
||||
return rc_test_condition_compare(value1.value.u32, value2.value.u32, self->oper);
|
||||
}
|
||||
|
||||
static int rc_test_condition_compare_memref_to_delta_transformed(rc_condition_t* self) {
|
||||
const rc_memref_value_t* memref = &self->operand1.value.memref->value;
|
||||
assert(self->operand1.value.memref == self->operand2.value.memref);
|
||||
|
||||
if (memref->changed) {
|
||||
rc_typed_value_t value1, value2;
|
||||
|
||||
value1.type = RC_VALUE_TYPE_UNSIGNED;
|
||||
value1.value.u32 = memref->value;
|
||||
rc_transform_memref_value(&value1, self->operand1.size);
|
||||
|
||||
value2.type = RC_VALUE_TYPE_UNSIGNED;
|
||||
value2.value.u32 = memref->prior;
|
||||
rc_transform_memref_value(&value2, self->operand2.size);
|
||||
|
||||
return rc_test_condition_compare(value1.value.u32, value2.value.u32, self->oper);
|
||||
}
|
||||
|
||||
switch (self->oper) {
|
||||
case RC_OPERATOR_EQ:
|
||||
case RC_OPERATOR_GE:
|
||||
case RC_OPERATOR_LE:
|
||||
return 1;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int rc_test_condition_compare_delta_to_memref_transformed(rc_condition_t* self) {
|
||||
const rc_memref_value_t* memref = &self->operand1.value.memref->value;
|
||||
assert(self->operand1.value.memref == self->operand2.value.memref);
|
||||
|
||||
if (memref->changed) {
|
||||
rc_typed_value_t value1, value2;
|
||||
|
||||
value1.type = RC_VALUE_TYPE_UNSIGNED;
|
||||
value1.value.u32 = memref->prior;
|
||||
rc_transform_memref_value(&value1, self->operand1.size);
|
||||
|
||||
value2.type = RC_VALUE_TYPE_UNSIGNED;
|
||||
value2.value.u32 = memref->value;
|
||||
rc_transform_memref_value(&value2, self->operand2.size);
|
||||
|
||||
return rc_test_condition_compare(value1.value.u32, value2.value.u32, self->oper);
|
||||
}
|
||||
|
||||
switch (self->oper) {
|
||||
case RC_OPERATOR_EQ:
|
||||
case RC_OPERATOR_GE:
|
||||
case RC_OPERATOR_LE:
|
||||
return 1;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int rc_test_condition(rc_condition_t* self, rc_eval_state_t* eval_state) {
|
||||
rc_typed_value_t value1, value2;
|
||||
|
||||
rc_evaluate_operand(&value1, &self->operand1, eval_state);
|
||||
if (eval_state->add_value.type != RC_VALUE_TYPE_NONE)
|
||||
if (eval_state->add_value.type != RC_VALUE_TYPE_NONE) {
|
||||
/* if there's an accumulator, we can't use the optimized comparators */
|
||||
rc_evaluate_operand(&value1, &self->operand1, eval_state);
|
||||
rc_typed_value_add(&value1, &eval_state->add_value);
|
||||
} else {
|
||||
/* use an optimized comparator whenever possible */
|
||||
switch (self->optimized_comparator) {
|
||||
case RC_PROCESSING_COMPARE_MEMREF_TO_CONST:
|
||||
return rc_test_condition_compare_memref_to_const(self);
|
||||
case RC_PROCESSING_COMPARE_MEMREF_TO_DELTA:
|
||||
return rc_test_condition_compare_memref_to_delta(self);
|
||||
case RC_PROCESSING_COMPARE_MEMREF_TO_MEMREF:
|
||||
return rc_test_condition_compare_memref_to_memref(self);
|
||||
case RC_PROCESSING_COMPARE_DELTA_TO_CONST:
|
||||
return rc_test_condition_compare_delta_to_const(self);
|
||||
case RC_PROCESSING_COMPARE_DELTA_TO_MEMREF:
|
||||
return rc_test_condition_compare_delta_to_memref(self);
|
||||
case RC_PROCESSING_COMPARE_MEMREF_TO_CONST_TRANSFORMED:
|
||||
return rc_test_condition_compare_memref_to_const_transformed(self);
|
||||
case RC_PROCESSING_COMPARE_MEMREF_TO_DELTA_TRANSFORMED:
|
||||
return rc_test_condition_compare_memref_to_delta_transformed(self);
|
||||
case RC_PROCESSING_COMPARE_MEMREF_TO_MEMREF_TRANSFORMED:
|
||||
return rc_test_condition_compare_memref_to_memref_transformed(self);
|
||||
case RC_PROCESSING_COMPARE_DELTA_TO_CONST_TRANSFORMED:
|
||||
return rc_test_condition_compare_delta_to_const_transformed(self);
|
||||
case RC_PROCESSING_COMPARE_DELTA_TO_MEMREF_TRANSFORMED:
|
||||
return rc_test_condition_compare_delta_to_memref_transformed(self);
|
||||
case RC_PROCESSING_COMPARE_ALWAYS_TRUE:
|
||||
return 1;
|
||||
case RC_PROCESSING_COMPARE_ALWAYS_FALSE:
|
||||
return 0;
|
||||
default:
|
||||
rc_evaluate_operand(&value1, &self->operand1, eval_state);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
rc_evaluate_operand(&value2, &self->operand2, eval_state);
|
||||
|
||||
|
2
deps/rcheevos/src/rcheevos/memref.c
vendored
2
deps/rcheevos/src/rcheevos/memref.c
vendored
@ -444,7 +444,7 @@ void rc_init_parse_state_memrefs(rc_parse_state_t* parse, rc_memref_t** memrefs)
|
||||
*memrefs = 0;
|
||||
}
|
||||
|
||||
static unsigned rc_get_memref_value_value(rc_memref_value_t* memref, int operand_type) {
|
||||
static unsigned rc_get_memref_value_value(const rc_memref_value_t* memref, int operand_type) {
|
||||
switch (operand_type)
|
||||
{
|
||||
/* most common case explicitly first, even though it could be handled by default case.
|
||||
|
16
deps/rcheevos/src/rcheevos/rc_internal.h
vendored
16
deps/rcheevos/src/rcheevos/rc_internal.h
vendored
@ -146,6 +146,22 @@ rc_condset_t* rc_parse_condset(const char** memaddr, rc_parse_state_t* parse, in
|
||||
int rc_test_condset(rc_condset_t* self, rc_eval_state_t* eval_state);
|
||||
void rc_reset_condset(rc_condset_t* self);
|
||||
|
||||
enum {
|
||||
RC_PROCESSING_COMPARE_DEFAULT = 0,
|
||||
RC_PROCESSING_COMPARE_MEMREF_TO_CONST,
|
||||
RC_PROCESSING_COMPARE_MEMREF_TO_DELTA,
|
||||
RC_PROCESSING_COMPARE_MEMREF_TO_MEMREF,
|
||||
RC_PROCESSING_COMPARE_DELTA_TO_MEMREF,
|
||||
RC_PROCESSING_COMPARE_DELTA_TO_CONST,
|
||||
RC_PROCESSING_COMPARE_MEMREF_TO_CONST_TRANSFORMED,
|
||||
RC_PROCESSING_COMPARE_MEMREF_TO_DELTA_TRANSFORMED,
|
||||
RC_PROCESSING_COMPARE_MEMREF_TO_MEMREF_TRANSFORMED,
|
||||
RC_PROCESSING_COMPARE_DELTA_TO_MEMREF_TRANSFORMED,
|
||||
RC_PROCESSING_COMPARE_DELTA_TO_CONST_TRANSFORMED,
|
||||
RC_PROCESSING_COMPARE_ALWAYS_TRUE,
|
||||
RC_PROCESSING_COMPARE_ALWAYS_FALSE
|
||||
};
|
||||
|
||||
rc_condition_t* rc_parse_condition(const char** memaddr, rc_parse_state_t* parse, int is_indirect);
|
||||
int rc_test_condition(rc_condition_t* self, rc_eval_state_t* eval_state);
|
||||
void rc_evaluate_condition_value(rc_typed_value_t* value, rc_condition_t* self, rc_eval_state_t* eval_state);
|
||||
|
9
deps/rcheevos/src/rcheevos/rc_libretro.c
vendored
9
deps/rcheevos/src/rcheevos/rc_libretro.c
vendored
@ -129,6 +129,12 @@ static const rc_disallowed_setting_t _rc_disallowed_snes9x_settings[] = {
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static const rc_disallowed_setting_t _rc_disallowed_vice_settings[] = {
|
||||
{ "vice_autostart", "disabled" }, /* autostart dictates initial load and reset from menu */
|
||||
{ "vice_reset", "!autostart" }, /* reset dictates behavior when pressing reset button (END) */
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static const rc_disallowed_setting_t _rc_disallowed_virtual_jaguar_settings[] = {
|
||||
{ "virtualjaguar_pal", "enabled" },
|
||||
{ NULL, NULL }
|
||||
@ -152,6 +158,7 @@ static const rc_disallowed_core_settings_t rc_disallowed_core_settings[] = {
|
||||
{ "QUASI88", _rc_disallowed_quasi88_settings },
|
||||
{ "SMS Plus GX", _rc_disallowed_smsplus_settings },
|
||||
{ "Snes9x", _rc_disallowed_snes9x_settings },
|
||||
{ "VICE x64", _rc_disallowed_vice_settings },
|
||||
{ "Virtual Jaguar", _rc_disallowed_virtual_jaguar_settings },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
@ -613,7 +620,7 @@ void rc_libretro_hash_set_init(struct rc_libretro_hash_set_t* hash_set,
|
||||
char image_path[1024];
|
||||
char* m3u_contents;
|
||||
char* ptr;
|
||||
size_t file_len;
|
||||
int64_t file_len;
|
||||
void* file_handle;
|
||||
int index = 0;
|
||||
|
||||
|
15
deps/rcheevos/src/rcheevos/trigger.c
vendored
15
deps/rcheevos/src/rcheevos/trigger.c
vendored
@ -197,14 +197,6 @@ int rc_evaluate_trigger(rc_trigger_t* self, rc_peek_t peek, void* ud, lua_State*
|
||||
self->measured_value = eval_state.measured_value.value.u32;
|
||||
}
|
||||
|
||||
/* if the state is WAITING and the trigger is ready to fire, ignore it and reset the hit counts */
|
||||
/* otherwise, if the state is WAITING, proceed to activating the trigger */
|
||||
if (self->state == RC_TRIGGER_STATE_WAITING && ret) {
|
||||
rc_reset_trigger(self);
|
||||
self->has_hits = 0;
|
||||
return RC_TRIGGER_STATE_WAITING;
|
||||
}
|
||||
|
||||
/* if any ResetIf condition was true, reset the hit counts */
|
||||
if (eval_state.was_reset) {
|
||||
/* if the measured value came from a hit count, reset it. do this before calling
|
||||
@ -247,6 +239,13 @@ int rc_evaluate_trigger(rc_trigger_t* self, rc_peek_t peek, void* ud, lua_State*
|
||||
is_primed = 0;
|
||||
}
|
||||
else if (ret) {
|
||||
/* if the state is WAITING and the trigger is ready to fire, ignore it and reset the hit counts */
|
||||
if (self->state == RC_TRIGGER_STATE_WAITING) {
|
||||
rc_reset_trigger(self);
|
||||
self->has_hits = 0;
|
||||
return RC_TRIGGER_STATE_WAITING;
|
||||
}
|
||||
|
||||
/* trigger was triggered */
|
||||
self->state = RC_TRIGGER_STATE_TRIGGERED;
|
||||
return RC_TRIGGER_STATE_TRIGGERED;
|
||||
|
9
deps/rcheevos/src/rhash/hash.c
vendored
9
deps/rcheevos/src/rhash/hash.c
vendored
@ -230,6 +230,10 @@ static uint32_t rc_cd_find_file_sector(void* track_handle, const char* path, uns
|
||||
if (!track_handle)
|
||||
return 0;
|
||||
|
||||
/* we start at the root. don't need to explicitly find it */
|
||||
if (*path == '\\')
|
||||
++path;
|
||||
|
||||
filename_length = strlen(path);
|
||||
slash = strrchr(path, '\\');
|
||||
if (slash)
|
||||
@ -966,6 +970,9 @@ static int rc_hash_n64(char hash[33], const char* path)
|
||||
rc_hash_verbose("converting n64 to z64");
|
||||
is_n64 = 1;
|
||||
}
|
||||
else if (buffer[0] == 0xE8 || buffer[0] == 0x22) /* ndd format (don't byteswap) */
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
free(buffer);
|
||||
@ -1469,7 +1476,7 @@ static int rc_hash_find_playstation_executable(void* track_handle, const char* b
|
||||
|
||||
if (strncmp(ptr, cdrom_prefix, cdrom_prefix_len) == 0)
|
||||
ptr += cdrom_prefix_len;
|
||||
if (*ptr == '\\')
|
||||
while (*ptr == '\\')
|
||||
++ptr;
|
||||
|
||||
start = ptr;
|
||||
|
Loading…
x
Reference in New Issue
Block a user