mirror of
https://github.com/CTCaer/RetroArch.git
synced 2024-12-24 11:45:16 +00:00
Merge pull request #3912 from leiradel/master
Fixes to cheevos issues; added warning about the console IDs enumerat…
This commit is contained in:
commit
752d3a1804
500
cheevos.c
500
cheevos.c
@ -44,16 +44,19 @@
|
||||
#include "verbosity.h"
|
||||
|
||||
/* Define this macro to prevent cheevos from being deactivated. */
|
||||
#define CHEEVOS_DONT_DEACTIVATE
|
||||
#undef CHEEVOS_DONT_DEACTIVATE
|
||||
|
||||
/* Define this macro to log URLs (will log the user token). */
|
||||
#define CHEEVOS_LOG_URLS
|
||||
#undef CHEEVOS_LOG_URLS
|
||||
|
||||
/* Define this macro to dump all cheevos' addresses. */
|
||||
#undef CHEEVOS_DUMP_ADDRS
|
||||
|
||||
/* Define this macro to remove HTTP timeouts. */
|
||||
#define CHEEVOS_NO_TIMEOUT
|
||||
#undef CHEEVOS_NO_TIMEOUT
|
||||
|
||||
/* Define this macro to get extra-verbose log for cheevos. */
|
||||
#undef CHEEVOS_VERBOSE
|
||||
|
||||
#define JSON_KEY_GAMEID 0xb4960eecU
|
||||
#define JSON_KEY_ACHIEVEMENTS 0x69749ae1U
|
||||
@ -72,17 +75,19 @@
|
||||
|
||||
enum
|
||||
{
|
||||
/* Don't change those, the values match the console IDs
|
||||
* at retroachievements.org. */
|
||||
CHEEVOS_CONSOLE_MEGA_DRIVE = 1,
|
||||
CHEEVOS_CONSOLE_NINTENDO_64,
|
||||
CHEEVOS_CONSOLE_SUPER_NINTENDO,
|
||||
CHEEVOS_CONSOLE_GAMEBOY,
|
||||
CHEEVOS_CONSOLE_GAMEBOY_ADVANCE,
|
||||
CHEEVOS_CONSOLE_GAMEBOY_COLOR,
|
||||
CHEEVOS_CONSOLE_NINTENDO,
|
||||
CHEEVOS_CONSOLE_PC_ENGINE,
|
||||
CHEEVOS_CONSOLE_SEGA_CD,
|
||||
CHEEVOS_CONSOLE_SEGA_32X,
|
||||
CHEEVOS_CONSOLE_MASTER_SYSTEM
|
||||
CHEEVOS_CONSOLE_NINTENDO_64 = 2,
|
||||
CHEEVOS_CONSOLE_SUPER_NINTENDO = 3,
|
||||
CHEEVOS_CONSOLE_GAMEBOY = 4,
|
||||
CHEEVOS_CONSOLE_GAMEBOY_ADVANCE = 5,
|
||||
CHEEVOS_CONSOLE_GAMEBOY_COLOR = 6,
|
||||
CHEEVOS_CONSOLE_NINTENDO = 7,
|
||||
CHEEVOS_CONSOLE_PC_ENGINE = 8,
|
||||
CHEEVOS_CONSOLE_SEGA_CD = 9,
|
||||
CHEEVOS_CONSOLE_SEGA_32X = 10,
|
||||
CHEEVOS_CONSOLE_MASTER_SYSTEM = 11
|
||||
};
|
||||
|
||||
enum
|
||||
@ -187,6 +192,7 @@ typedef struct
|
||||
unsigned points;
|
||||
unsigned dirty;
|
||||
int active;
|
||||
int last;
|
||||
int modified;
|
||||
|
||||
cheevos_condset_t *condsets;
|
||||
@ -276,6 +282,267 @@ static int cheats_were_enabled = 0;
|
||||
Supporting functions.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifdef CHEEVOS_VERBOSE
|
||||
static void cheevos_add_char(char** aux, size_t* left, char k)
|
||||
{
|
||||
if (*left >= 1)
|
||||
{
|
||||
**aux = k;
|
||||
(*aux)++;
|
||||
(*left)--;
|
||||
}
|
||||
}
|
||||
|
||||
static void cheevos_add_string(char** aux, size_t* left, const char* s)
|
||||
{
|
||||
size_t len = strlen(s);
|
||||
|
||||
if (*left >= len)
|
||||
{
|
||||
strcpy(*aux, s);
|
||||
*aux += len;
|
||||
*left -= len;
|
||||
}
|
||||
}
|
||||
|
||||
static void cheevos_add_hex(char** aux, size_t* left, unsigned v)
|
||||
{
|
||||
char buffer[32];
|
||||
|
||||
snprintf(buffer, sizeof(buffer), "%06x", v);
|
||||
buffer[sizeof(buffer) - 1] = 0;
|
||||
|
||||
cheevos_add_string(aux, left, buffer);
|
||||
}
|
||||
|
||||
static void cheevos_add_uint(char** aux, size_t* left, unsigned v)
|
||||
{
|
||||
char buffer[32];
|
||||
|
||||
snprintf(buffer, sizeof(buffer), "%u", v);
|
||||
buffer[sizeof(buffer) - 1] = 0;
|
||||
|
||||
cheevos_add_string(aux, left, buffer);
|
||||
}
|
||||
|
||||
static void cheevos_log_var(const cheevos_var_t* var)
|
||||
{
|
||||
RARCH_LOG("CHEEVOS size: %s\n",
|
||||
var->size == CHEEVOS_VAR_SIZE_BIT_0 ? "bit 0" :
|
||||
var->size == CHEEVOS_VAR_SIZE_BIT_1 ? "bit 1" :
|
||||
var->size == CHEEVOS_VAR_SIZE_BIT_2 ? "bit 2" :
|
||||
var->size == CHEEVOS_VAR_SIZE_BIT_3 ? "bit 3" :
|
||||
var->size == CHEEVOS_VAR_SIZE_BIT_4 ? "bit 4" :
|
||||
var->size == CHEEVOS_VAR_SIZE_BIT_5 ? "bit 5" :
|
||||
var->size == CHEEVOS_VAR_SIZE_BIT_6 ? "bit 6" :
|
||||
var->size == CHEEVOS_VAR_SIZE_BIT_7 ? "bit 7" :
|
||||
var->size == CHEEVOS_VAR_SIZE_NIBBLE_LOWER ? "low nibble" :
|
||||
var->size == CHEEVOS_VAR_SIZE_NIBBLE_UPPER ? "high nibble" :
|
||||
var->size == CHEEVOS_VAR_SIZE_EIGHT_BITS ? "byte" :
|
||||
var->size == CHEEVOS_VAR_SIZE_SIXTEEN_BITS ? "word" :
|
||||
var->size == CHEEVOS_VAR_SIZE_THIRTYTWO_BITS ? "dword" :
|
||||
"?"
|
||||
);
|
||||
RARCH_LOG("CHEEVOS type: %s\n",
|
||||
var->type == CHEEVOS_VAR_TYPE_ADDRESS ? "address" :
|
||||
var->type == CHEEVOS_VAR_TYPE_VALUE_COMP ? "value" :
|
||||
var->type == CHEEVOS_VAR_TYPE_DELTA_MEM ? "delta" :
|
||||
var->type == CHEEVOS_VAR_TYPE_DYNAMIC_VAR ? "dynamic" :
|
||||
"?"
|
||||
);
|
||||
RARCH_LOG("CHEEVOS value: %u\n", var->value);
|
||||
}
|
||||
|
||||
static void cheevos_log_cond(const cheevos_cond_t* cond)
|
||||
{
|
||||
RARCH_LOG("CHEEVOS condition %p\n", cond);
|
||||
RARCH_LOG("CHEEVOS type: %s\n",
|
||||
cond->type == CHEEVOS_COND_TYPE_STANDARD ? "standard" :
|
||||
cond->type == CHEEVOS_COND_TYPE_PAUSE_IF ? "pause" :
|
||||
cond->type == CHEEVOS_COND_TYPE_RESET_IF ? "reset" :
|
||||
"?"
|
||||
);
|
||||
RARCH_LOG("CHEEVOS req_hits: %u\n", cond->req_hits);
|
||||
RARCH_LOG("CHEEVOS source:\n");
|
||||
cheevos_log_var(&cond->source);
|
||||
RARCH_LOG("CHEEVOS op: %s\n",
|
||||
cond->op == CHEEVOS_COND_OP_EQUALS ? "==" :
|
||||
cond->op == CHEEVOS_COND_OP_LESS_THAN ? "<" :
|
||||
cond->op == CHEEVOS_COND_OP_LESS_THAN_OR_EQUAL ? "<=" :
|
||||
cond->op == CHEEVOS_COND_OP_GREATER_THAN ? ">" :
|
||||
cond->op == CHEEVOS_COND_OP_GREATER_THAN_OR_EQUAL ? ">=" :
|
||||
cond->op == CHEEVOS_COND_OP_NOT_EQUAL_TO ? "!=" :
|
||||
"?"
|
||||
);
|
||||
RARCH_LOG("CHEEVOS target:\n");
|
||||
cheevos_log_var(&cond->target);
|
||||
}
|
||||
|
||||
static void cheevos_log_cheevo(const cheevo_t* cheevo,
|
||||
const cheevos_field_t* memaddr_ud)
|
||||
{
|
||||
char memaddr[256];
|
||||
size_t length;
|
||||
|
||||
length = memaddr_ud->length + 1;
|
||||
|
||||
if (length >= sizeof(memaddr))
|
||||
length = sizeof(memaddr);
|
||||
|
||||
strncpy(memaddr, memaddr_ud->string, length - 1);
|
||||
memaddr[length - 1] = 0;
|
||||
|
||||
RARCH_LOG("CHEEVOS cheevo %p\n", cheevo);
|
||||
RARCH_LOG("CHEEVOS id: %u\n", cheevo->id);
|
||||
RARCH_LOG("CHEEVOS title: %s\n", cheevo->title);
|
||||
RARCH_LOG("CHEEVOS desc: %s\n", cheevo->description);
|
||||
RARCH_LOG("CHEEVOS author: %s\n", cheevo->author);
|
||||
RARCH_LOG("CHEEVOS badge: %s\n", cheevo->badge);
|
||||
RARCH_LOG("CHEEVOS points: %u\n", cheevo->points);
|
||||
RARCH_LOG("CHEEVOS sets: %u\n", cheevo->count);
|
||||
RARCH_LOG("CHEEVOS memaddr: %s\n", memaddr);
|
||||
}
|
||||
|
||||
static void cheevos_add_var_size(char** aux, size_t* left,
|
||||
const cheevos_var_t* var)
|
||||
{
|
||||
switch( var->size )
|
||||
{
|
||||
case CHEEVOS_VAR_SIZE_BIT_0:
|
||||
cheevos_add_char(aux, left, 'M');
|
||||
break;
|
||||
case CHEEVOS_VAR_SIZE_BIT_1:
|
||||
cheevos_add_char(aux, left, 'N');
|
||||
break;
|
||||
case CHEEVOS_VAR_SIZE_BIT_2:
|
||||
cheevos_add_char(aux, left, 'O');
|
||||
break;
|
||||
case CHEEVOS_VAR_SIZE_BIT_3:
|
||||
cheevos_add_char(aux, left, 'P');
|
||||
break;
|
||||
case CHEEVOS_VAR_SIZE_BIT_4:
|
||||
cheevos_add_char(aux, left, 'Q');
|
||||
break;
|
||||
case CHEEVOS_VAR_SIZE_BIT_5:
|
||||
cheevos_add_char(aux, left, 'R');
|
||||
break;
|
||||
case CHEEVOS_VAR_SIZE_BIT_6:
|
||||
cheevos_add_char(aux, left, 'S');
|
||||
break;
|
||||
case CHEEVOS_VAR_SIZE_BIT_7:
|
||||
cheevos_add_char(aux, left, 'T');
|
||||
break;
|
||||
case CHEEVOS_VAR_SIZE_NIBBLE_LOWER:
|
||||
cheevos_add_char(aux, left, 'L');
|
||||
break;
|
||||
case CHEEVOS_VAR_SIZE_NIBBLE_UPPER:
|
||||
cheevos_add_char(aux, left, 'U');
|
||||
break;
|
||||
case CHEEVOS_VAR_SIZE_EIGHT_BITS:
|
||||
cheevos_add_char(aux, left, 'H');
|
||||
break;
|
||||
case CHEEVOS_VAR_SIZE_THIRTYTWO_BITS:
|
||||
cheevos_add_char(aux, left, 'X');
|
||||
break;
|
||||
case CHEEVOS_VAR_SIZE_SIXTEEN_BITS:
|
||||
default:
|
||||
cheevos_add_char(aux, left, ' ');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void cheevos_post_log_cheevo(const cheevo_t* cheevo)
|
||||
{
|
||||
char memaddr[256];
|
||||
char *aux = memaddr;
|
||||
size_t left = sizeof(memaddr);
|
||||
const cheevos_condset_t* condset;
|
||||
const cheevos_cond_t* cond;
|
||||
size_t i, j;
|
||||
|
||||
for (i = 0, condset = cheevo->condsets; i < cheevo->count; i++, condset++)
|
||||
{
|
||||
if (i != 0)
|
||||
cheevos_add_char(&aux, &left, 'S');
|
||||
|
||||
for (j = 0, cond = condset->conds; j < condset->count; j++, cond++)
|
||||
{
|
||||
if (j != 0)
|
||||
cheevos_add_char(&aux, &left, '_');
|
||||
|
||||
if (cond->type == CHEEVOS_COND_TYPE_RESET_IF)
|
||||
cheevos_add_string(&aux, &left, "R:");
|
||||
else if (cond->type == CHEEVOS_COND_TYPE_PAUSE_IF)
|
||||
cheevos_add_string(&aux, &left, "P:");
|
||||
|
||||
if ( cond->source.type == CHEEVOS_VAR_TYPE_ADDRESS
|
||||
|| cond->source.type == CHEEVOS_VAR_TYPE_DELTA_MEM)
|
||||
{
|
||||
if (cond->source.type == CHEEVOS_VAR_TYPE_DELTA_MEM)
|
||||
cheevos_add_char(&aux, &left, 'd');
|
||||
|
||||
cheevos_add_string(&aux, &left, "0x");
|
||||
cheevos_add_var_size(&aux, &left, &cond->source);
|
||||
cheevos_add_hex(&aux, &left, cond->source.value);
|
||||
}
|
||||
else if (cond->source.type == CHEEVOS_VAR_TYPE_VALUE_COMP)
|
||||
{
|
||||
cheevos_add_uint(&aux, &left, cond->source.value);
|
||||
}
|
||||
|
||||
switch (cond->op)
|
||||
{
|
||||
case CHEEVOS_COND_OP_EQUALS:
|
||||
cheevos_add_char(&aux, &left, '=');
|
||||
break;
|
||||
case CHEEVOS_COND_OP_GREATER_THAN:
|
||||
cheevos_add_char(&aux, &left, '>');
|
||||
break;
|
||||
case CHEEVOS_COND_OP_GREATER_THAN_OR_EQUAL:
|
||||
cheevos_add_string(&aux, &left, ">=");
|
||||
break;
|
||||
case CHEEVOS_COND_OP_LESS_THAN:
|
||||
cheevos_add_char(&aux, &left, '<');
|
||||
break;
|
||||
case CHEEVOS_COND_OP_LESS_THAN_OR_EQUAL:
|
||||
cheevos_add_string(&aux, &left, "<=");
|
||||
break;
|
||||
case CHEEVOS_COND_OP_NOT_EQUAL_TO:
|
||||
cheevos_add_string(&aux, &left, "!=");
|
||||
break;
|
||||
}
|
||||
|
||||
if ( cond->target.type == CHEEVOS_VAR_TYPE_ADDRESS
|
||||
|| cond->target.type == CHEEVOS_VAR_TYPE_DELTA_MEM)
|
||||
{
|
||||
if (cond->target.type == CHEEVOS_VAR_TYPE_DELTA_MEM)
|
||||
cheevos_add_char(&aux, &left, 'd');
|
||||
|
||||
cheevos_add_string(&aux, &left, "0x");
|
||||
cheevos_add_var_size(&aux, &left, &cond->target);
|
||||
cheevos_add_hex(&aux, &left, cond->target.value);
|
||||
}
|
||||
else if (cond->target.type == CHEEVOS_VAR_TYPE_VALUE_COMP)
|
||||
{
|
||||
cheevos_add_uint(&aux, &left, cond->target.value);
|
||||
}
|
||||
|
||||
if (cond->req_hits > 0)
|
||||
{
|
||||
cheevos_add_char(&aux, &left, '.');
|
||||
cheevos_add_uint(&aux, &left, cond->req_hits);
|
||||
cheevos_add_char(&aux, &left, '.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cheevos_add_char(&aux, &left, 0);
|
||||
memaddr[sizeof(memaddr) - 1] = 0;
|
||||
|
||||
RARCH_LOG("CHEEVOS memaddr (computed): %s\n", memaddr);
|
||||
}
|
||||
#endif
|
||||
|
||||
static uint32_t cheevos_djb2(const char* str, size_t length)
|
||||
{
|
||||
const unsigned char *aux = (const unsigned char*)str;
|
||||
@ -748,26 +1015,25 @@ static unsigned cheevos_count_cond_sets(const char *memaddr)
|
||||
cheevos_cond_t cond;
|
||||
unsigned count = 0;
|
||||
|
||||
do
|
||||
for (;;)
|
||||
{
|
||||
do
|
||||
{
|
||||
/* Skip any characters up until the start of the achievement condition */
|
||||
while ( *memaddr == ' '
|
||||
|| *memaddr == '_'
|
||||
|| *memaddr == '|'
|
||||
|| *memaddr == 'S')
|
||||
memaddr++;
|
||||
|
||||
cheevos_parse_cond(&cond, &memaddr);
|
||||
}
|
||||
while ( *memaddr == '_'
|
||||
|| *memaddr == 'R'
|
||||
|| *memaddr == 'P'); /* AND, ResetIf, PauseIf */
|
||||
|
||||
count++;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
cheevos_parse_cond(&cond, &memaddr);
|
||||
|
||||
if (*memaddr != '_')
|
||||
break;
|
||||
|
||||
memaddr++;
|
||||
}
|
||||
|
||||
if (*memaddr != 'S')
|
||||
break;
|
||||
|
||||
memaddr++;
|
||||
}
|
||||
while (*memaddr == 'S'); /* Repeat for all subconditions if they exist */
|
||||
|
||||
return count;
|
||||
}
|
||||
@ -778,47 +1044,68 @@ static unsigned cheevos_count_conds_in_set(const char *memaddr, unsigned set)
|
||||
unsigned index = 0;
|
||||
unsigned count = 0;
|
||||
|
||||
do
|
||||
for (;;)
|
||||
{
|
||||
do
|
||||
for (;;)
|
||||
{
|
||||
/* Skip any characters up until the start of the achievement condition */
|
||||
while ( *memaddr == ' '
|
||||
|| *memaddr == '_'
|
||||
|| *memaddr == '|'
|
||||
|| *memaddr == 'S')
|
||||
memaddr++;
|
||||
|
||||
cheevos_parse_cond(&cond, &memaddr);
|
||||
|
||||
if (index == set)
|
||||
count++;
|
||||
|
||||
if (*memaddr != '_')
|
||||
break;
|
||||
|
||||
memaddr++;
|
||||
}
|
||||
while (*memaddr == '_' || *memaddr == 'R' || *memaddr == 'P'); /* AND, ResetIf, PauseIf */
|
||||
|
||||
index++;
|
||||
|
||||
if (*memaddr != 'S')
|
||||
break;
|
||||
|
||||
memaddr++;
|
||||
}
|
||||
while (*memaddr == 'S'); /* Repeat for all subconditions if they exist */
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static void cheevos_parse_memaddr(cheevos_cond_t *cond, const char *memaddr)
|
||||
static void cheevos_parse_memaddr(cheevos_cond_t *cond, const char *memaddr, unsigned set)
|
||||
{
|
||||
do
|
||||
{
|
||||
do
|
||||
{
|
||||
/* Skip any characters up until the start of the achievement condition */
|
||||
while ( *memaddr == ' '
|
||||
|| *memaddr == '_'
|
||||
|| *memaddr == '|'
|
||||
|| *memaddr == 'S')
|
||||
memaddr++;
|
||||
cheevos_cond_t dummy;
|
||||
unsigned index = 0;
|
||||
|
||||
cheevos_parse_cond(cond++, &memaddr);
|
||||
for (;;)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
if (index == set)
|
||||
{
|
||||
cheevos_parse_cond(cond, &memaddr);
|
||||
#ifdef CHEEVOS_VERBOSE
|
||||
cheevos_log_cond(cond);
|
||||
#endif
|
||||
cond++;
|
||||
}
|
||||
else
|
||||
cheevos_parse_cond(&dummy, &memaddr);
|
||||
|
||||
if (*memaddr != '_')
|
||||
break;
|
||||
|
||||
memaddr++;
|
||||
}
|
||||
while (*memaddr == '_' || *memaddr == 'R' || *memaddr == 'P'); /* AND, ResetIf, PauseIf */
|
||||
|
||||
index++;
|
||||
|
||||
if (*memaddr != 'S')
|
||||
break;
|
||||
|
||||
memaddr++;
|
||||
}
|
||||
while (*memaddr == 'S'); /* Repeat for all subconditions if they exist */
|
||||
|
||||
if (*memaddr != '"')
|
||||
RARCH_LOG("CHEEVOS error parsing memaddr\n");
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
@ -840,7 +1127,7 @@ static INLINE const char *cheevos_dupstr(const cheevos_field_t *field)
|
||||
|
||||
static int cheevos_new_cheevo(cheevos_readud_t *ud)
|
||||
{
|
||||
cheevo_t *cheevo = NULL;
|
||||
cheevo_t *cheevo = NULL;
|
||||
|
||||
if (strtol(ud->flags.string, NULL, 10) == 3)
|
||||
cheevo = cheevos_locals.core.cheevos + ud->core_count++;
|
||||
@ -855,6 +1142,7 @@ static int cheevos_new_cheevo(cheevos_readud_t *ud)
|
||||
cheevo->points = strtol(ud->points.string, NULL, 10);
|
||||
cheevo->dirty = 0;
|
||||
cheevo->active = 1;
|
||||
cheevo->last = 1;
|
||||
cheevo->modified = 0;
|
||||
|
||||
if (!cheevo->title || !cheevo->description || !cheevo->author || !cheevo->badge)
|
||||
@ -862,13 +1150,18 @@ static int cheevos_new_cheevo(cheevos_readud_t *ud)
|
||||
|
||||
cheevo->count = cheevos_count_cond_sets(ud->memaddr.string);
|
||||
|
||||
#ifdef CHEEVOS_VERBOSE
|
||||
cheevos_log_cheevo(cheevo, &ud->memaddr);
|
||||
#endif
|
||||
|
||||
if (cheevo->count)
|
||||
{
|
||||
unsigned set = 0;
|
||||
const cheevos_condset_t *end = NULL;
|
||||
//const cheevos_condset_t *end = NULL;
|
||||
cheevos_condset_t *condset = NULL;
|
||||
cheevos_condset_t *conds = (cheevos_condset_t*)
|
||||
calloc(cheevo->count, sizeof(cheevos_condset_t));
|
||||
const cheevos_condset_t* end;
|
||||
|
||||
if (!conds)
|
||||
return -1;
|
||||
@ -876,12 +1169,17 @@ static int cheevos_new_cheevo(cheevos_readud_t *ud)
|
||||
cheevo->condsets = conds;
|
||||
end = cheevo->condsets + cheevo->count;
|
||||
|
||||
for (condset = cheevo->condsets; condset < end; condset++)
|
||||
for (condset = cheevo->condsets; condset < end; condset++, set++)
|
||||
{
|
||||
condset->count =
|
||||
cheevos_count_conds_in_set(ud->memaddr.string, set++);
|
||||
cheevos_count_conds_in_set(ud->memaddr.string, set);
|
||||
condset->conds = NULL;
|
||||
|
||||
#ifdef CHEEVOS_VERBOSE
|
||||
RARCH_LOG("CHEEVOS set %p (index=%u)\n", condset, set);
|
||||
RARCH_LOG("CHEEVOS conds: %u\n", condset->count);
|
||||
#endif
|
||||
|
||||
if (condset->count)
|
||||
{
|
||||
cheevos_cond_t *conds = (cheevos_cond_t*)
|
||||
@ -892,11 +1190,15 @@ static int cheevos_new_cheevo(cheevos_readud_t *ud)
|
||||
|
||||
condset->conds = conds;
|
||||
condset->expression = cheevos_dupstr(&ud->memaddr);
|
||||
cheevos_parse_memaddr(condset->conds, ud->memaddr.string);
|
||||
cheevos_parse_memaddr(condset->conds, ud->memaddr.string, set);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CHEEVOS_VERBOSE
|
||||
cheevos_post_log_cheevo(cheevo);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
@ -1193,7 +1495,7 @@ static int cheevos_test_condition(cheevos_cond_t *cond)
|
||||
break;
|
||||
}
|
||||
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cheevos_test_cond_set(const cheevos_condset_t *condset,
|
||||
@ -1209,28 +1511,27 @@ static int cheevos_test_cond_set(const cheevos_condset_t *condset,
|
||||
|
||||
for (cond = condset->conds; cond < end; cond++)
|
||||
{
|
||||
if (cond->type == CHEEVOS_COND_TYPE_PAUSE_IF)
|
||||
if (cond->type != CHEEVOS_COND_TYPE_PAUSE_IF)
|
||||
continue;
|
||||
|
||||
/* Reset by default, set to 1 if hit! */
|
||||
cond->curr_hits = 0;
|
||||
|
||||
if (cheevos_test_condition(cond))
|
||||
{
|
||||
/* Reset by default, set to 1 if hit! */
|
||||
cond->curr_hits = 0;
|
||||
cond->curr_hits = 1;
|
||||
*dirty_conds = 1;
|
||||
|
||||
if (cheevos_test_condition(cond))
|
||||
{
|
||||
cond->curr_hits = 1;
|
||||
*dirty_conds = 1;
|
||||
|
||||
/* Early out: this achievement is paused,
|
||||
* do not process any further! */
|
||||
return 0;
|
||||
}
|
||||
/* Early out: this achievement is paused,
|
||||
* do not process any further! */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Read all standard conditions, and process as normal: */
|
||||
for (cond = condset->conds; cond < end; cond++)
|
||||
{
|
||||
if ( cond->type == CHEEVOS_COND_TYPE_PAUSE_IF
|
||||
|| cond->type == CHEEVOS_COND_TYPE_RESET_IF)
|
||||
if (cond->type != CHEEVOS_COND_TYPE_STANDARD)
|
||||
continue;
|
||||
|
||||
if (cond->req_hits != 0 && cond->curr_hits >= cond->req_hits)
|
||||
@ -1260,16 +1561,16 @@ static int cheevos_test_cond_set(const cheevos_condset_t *condset,
|
||||
/* Now, ONLY read reset conditions! */
|
||||
for (cond = condset->conds; cond < end; cond++)
|
||||
{
|
||||
if (cond->type == CHEEVOS_COND_TYPE_RESET_IF)
|
||||
{
|
||||
cond_valid = cheevos_test_condition(cond);
|
||||
if (cond->type != CHEEVOS_COND_TYPE_RESET_IF)
|
||||
continue;
|
||||
|
||||
if (cond_valid)
|
||||
{
|
||||
*reset_conds = 1; /* Resets all hits found so far */
|
||||
set_valid = 0; /* Cannot be valid if we've hit a reset condition. */
|
||||
break; /* No point processing any further reset conditions. */
|
||||
}
|
||||
cond_valid = cheevos_test_condition(cond);
|
||||
|
||||
if (cond_valid)
|
||||
{
|
||||
*reset_conds = 1; /* Resets all hits found so far */
|
||||
set_valid = 0; /* Cannot be valid if we've hit a reset condition. */
|
||||
break; /* No point processing any further reset conditions. */
|
||||
}
|
||||
}
|
||||
|
||||
@ -1323,8 +1624,7 @@ static int cheevos_test_cheevo(cheevo_t *cheevo)
|
||||
|
||||
while (condset < end)
|
||||
{
|
||||
int res = cheevos_test_cond_set(condset, &dirty_conds, &reset_conds, 0);
|
||||
ret_val_sub_cond |= res;
|
||||
ret_val_sub_cond |= cheevos_test_cond_set(condset, &dirty_conds, &reset_conds, 0);
|
||||
condset++;
|
||||
}
|
||||
|
||||
@ -1484,25 +1784,33 @@ static void cheevos_test_cheevo_set(const cheevoset_t *set)
|
||||
{
|
||||
cheevo_t *cheevo = NULL;
|
||||
const cheevo_t *end = set->cheevos + set->count;
|
||||
int valid;
|
||||
|
||||
for (cheevo = set->cheevos; cheevo < end; cheevo++)
|
||||
{
|
||||
if (cheevo->active && cheevos_test_cheevo(cheevo))
|
||||
if (cheevo->active)
|
||||
{
|
||||
char url[256];
|
||||
valid = cheevos_test_cheevo(cheevo);
|
||||
|
||||
url[0] = '\0';
|
||||
if (valid && !cheevo->last)
|
||||
{
|
||||
char url[256];
|
||||
|
||||
cheevo->active = 0;
|
||||
url[0] = '\0';
|
||||
|
||||
RARCH_LOG("CHEEVOS awarding cheevo %u: %s (%s).\n",
|
||||
cheevo->id, cheevo->title, cheevo->description);
|
||||
cheevo->active = 0;
|
||||
|
||||
runloop_msg_queue_push(cheevo->title, 0, 3 * 60, false);
|
||||
runloop_msg_queue_push(cheevo->description, 0, 5 * 60, false);
|
||||
RARCH_LOG("CHEEVOS awarding cheevo %u: %s (%s).\n",
|
||||
cheevo->id, cheevo->title, cheevo->description);
|
||||
|
||||
cheevos_make_unlock_url(cheevo, url, sizeof(url));
|
||||
task_push_http_transfer(url, true, NULL, cheevos_unlocked, cheevo);
|
||||
runloop_msg_queue_push(cheevo->title, 0, 3 * 60, false);
|
||||
runloop_msg_queue_push(cheevo->description, 0, 5 * 60, false);
|
||||
|
||||
cheevos_make_unlock_url(cheevo, url, sizeof(url));
|
||||
task_push_http_transfer(url, true, NULL, cheevos_unlocked, cheevo);
|
||||
}
|
||||
|
||||
cheevo->last = valid;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user