update rcheevos files

This commit is contained in:
meleu 2019-03-30 15:44:03 -03:00
parent a77327d20e
commit 6e730cf2dd
15 changed files with 616 additions and 369 deletions

View File

@ -1709,6 +1709,8 @@ ifeq ($(HAVE_NETWORKING), 1)
deps/rcheevos/src/rcheevos/lboard.o \ deps/rcheevos/src/rcheevos/lboard.o \
deps/rcheevos/src/rcheevos/alloc.o \ deps/rcheevos/src/rcheevos/alloc.o \
deps/rcheevos/src/rcheevos/format.o \ deps/rcheevos/src/rcheevos/format.o \
deps/rcheevos/src/rcheevos/memref.o \
deps/rcheevos/src/rcheevos/richpresence.o \
deps/rcheevos/src/rurl/url.o deps/rcheevos/src/rurl/url.o
ifeq ($(HAVE_LUA), 1) ifeq ($(HAVE_LUA), 1)

View File

@ -30,7 +30,8 @@ enum {
RC_MISSING_SUBMIT = -15, RC_MISSING_SUBMIT = -15,
RC_MISSING_VALUE = -16, RC_MISSING_VALUE = -16,
RC_INVALID_LBOARD_FIELD = -17, RC_INVALID_LBOARD_FIELD = -17,
RC_MISSING_DISPLAY_STRING = -18 RC_MISSING_DISPLAY_STRING = -18,
RC_OUT_OF_MEMORY = -19
}; };
/*****************************************************************************\ /*****************************************************************************\
@ -83,27 +84,57 @@ enum {
typedef unsigned (*rc_peek_t)(unsigned address, unsigned num_bytes, void* ud); typedef unsigned (*rc_peek_t)(unsigned address, unsigned num_bytes, void* ud);
/*****************************************************************************\ /*****************************************************************************\
| Operands | | Memory References |
\*****************************************************************************/ \*****************************************************************************/
/* Sizes. */ /* Sizes. */
enum { enum {
RC_OPERAND_BIT_0, RC_MEMSIZE_BIT_0,
RC_OPERAND_BIT_1, RC_MEMSIZE_BIT_1,
RC_OPERAND_BIT_2, RC_MEMSIZE_BIT_2,
RC_OPERAND_BIT_3, RC_MEMSIZE_BIT_3,
RC_OPERAND_BIT_4, RC_MEMSIZE_BIT_4,
RC_OPERAND_BIT_5, RC_MEMSIZE_BIT_5,
RC_OPERAND_BIT_6, RC_MEMSIZE_BIT_6,
RC_OPERAND_BIT_7, RC_MEMSIZE_BIT_7,
RC_OPERAND_LOW, RC_MEMSIZE_LOW,
RC_OPERAND_HIGH, RC_MEMSIZE_HIGH,
RC_OPERAND_8_BITS, RC_MEMSIZE_8_BITS,
RC_OPERAND_16_BITS, RC_MEMSIZE_16_BITS,
RC_OPERAND_24_BITS, RC_MEMSIZE_24_BITS,
RC_OPERAND_32_BITS RC_MEMSIZE_32_BITS
}; };
typedef struct {
/* The memory address of this variable. */
unsigned address;
/* The size of the variable. */
char size;
/* True if the value is in BCD. */
char is_bcd;
} rc_memref_t;
typedef struct rc_memref_value_t rc_memref_value_t;
struct rc_memref_value_t {
/* The value of this memory reference. */
unsigned value;
/* The previous value of this memory reference. */
unsigned previous;
/* The last differing value of this memory reference. */
unsigned prior;
/* The referenced memory */
rc_memref_t memref;
/* The next memory reference in the chain */
rc_memref_value_t* next;
};
/*****************************************************************************\
| Operands |
\*****************************************************************************/
/* types */ /* types */
enum { enum {
RC_OPERAND_ADDRESS, /* Compare to the value of a live address in RAM. */ RC_OPERAND_ADDRESS, /* Compare to the value of a live address in RAM. */
@ -117,20 +148,10 @@ enum {
typedef struct { typedef struct {
union { union {
/* A value read from memory. */ /* A value read from memory. */
struct { rc_memref_value_t* memref;
/* The memory address or constant value of this variable. */
unsigned value;
/* The previous memory contents if RC_OPERAND_DELTA or RC_OPERAND_PRIOR. */
unsigned previous;
/* The last differing value if RC_OPERAND_PRIOR. */
unsigned prior;
/* The size of the variable. */ /* A value. */
char size; unsigned value;
/* True if the value is in BCD. */
char is_bcd;
/* The type of the variable. */
};
/* A floating point value. */ /* A floating point value. */
double fp_value; double fp_value;
@ -171,9 +192,6 @@ enum {
typedef struct rc_condition_t rc_condition_t; typedef struct rc_condition_t rc_condition_t;
struct rc_condition_t { struct rc_condition_t {
/* The next condition in the chain. */
rc_condition_t* next;
/* The condition's operands. */ /* The condition's operands. */
rc_operand_t operand1; rc_operand_t operand1;
rc_operand_t operand2; rc_operand_t operand2;
@ -183,6 +201,9 @@ struct rc_condition_t {
/* Number of hits so far. */ /* Number of hits so far. */
unsigned current_hits; unsigned current_hits;
/* The next condition in the chain. */
rc_condition_t* next;
/** /**
* Set if the condition needs to processed as part of the "check if paused" * Set if the condition needs to processed as part of the "check if paused"
* pass * pass
@ -222,6 +243,9 @@ typedef struct {
/* The list of sub condition sets in this test. */ /* The list of sub condition sets in this test. */
rc_condset_t* alternative; rc_condset_t* alternative;
/* The memory references required by the trigger. */
rc_memref_value_t* memrefs;
} }
rc_trigger_t; rc_trigger_t;
@ -262,6 +286,9 @@ struct rc_expression_t {
typedef struct { typedef struct {
/* The list of expression to evaluate. */ /* The list of expression to evaluate. */
rc_expression_t* expressions; rc_expression_t* expressions;
/* The memory references required by the value. */
rc_memref_value_t* memrefs;
} }
rc_value_t; rc_value_t;
@ -288,6 +315,7 @@ typedef struct {
rc_trigger_t cancel; rc_trigger_t cancel;
rc_value_t value; rc_value_t value;
rc_value_t* progress; rc_value_t* progress;
rc_memref_value_t* memrefs;
char started; char started;
char submitted; char submitted;
@ -358,6 +386,7 @@ struct rc_richpresence_display_t {
typedef struct { typedef struct {
rc_richpresence_display_t* first_display; rc_richpresence_display_t* first_display;
rc_richpresence_lookup_t* first_lookup; rc_richpresence_lookup_t* first_lookup;
rc_memref_value_t* memrefs;
} }
rc_richpresence_t; rc_richpresence_t;

View File

@ -1,6 +1,7 @@
#include "internal.h" #include "internal.h"
#include <memory.h> #include <stdlib.h>
#include <string.h>
void* rc_alloc(void* pointer, int* offset, int size, int alignment, rc_scratch_t* scratch) { void* rc_alloc(void* pointer, int* offset, int size, int alignment, rc_scratch_t* scratch) {
void* ptr; void* ptr;
@ -10,18 +11,21 @@ void* rc_alloc(void* pointer, int* offset, int size, int alignment, rc_scratch_t
if (pointer != 0) { if (pointer != 0) {
ptr = (void*)((char*)pointer + *offset); ptr = (void*)((char*)pointer + *offset);
} }
else if (scratch != 0) {
ptr = &scratch->obj;
}
else { else {
ptr = scratch; ptr = 0;
} }
*offset += size; *offset += size;
return ptr; return ptr;
} }
char* rc_alloc_str(void* pointer, int* offset, const char* text, int length) { char* rc_alloc_str(rc_parse_state_t* parse, const char* text, int length) {
char* ptr; char* ptr;
ptr = (char*)rc_alloc(pointer, offset, length + 1, RC_ALIGNOF(char), 0); ptr = (char*)rc_alloc(parse->buffer, &parse->offset, length + 1, RC_ALIGNOF(char), 0);
if (ptr) { if (ptr) {
memcpy(ptr, text, length); memcpy(ptr, text, length);
ptr[length] = '\0'; ptr[length] = '\0';
@ -29,3 +33,21 @@ char* rc_alloc_str(void* pointer, int* offset, const char* text, int length) {
return ptr; return ptr;
} }
void rc_init_parse_state(rc_parse_state_t* parse, void* buffer, lua_State* L, int funcs_ndx)
{
parse->offset = 0;
parse->L = L;
parse->funcs_ndx = funcs_ndx;
parse->buffer = buffer;
parse->scratch.memref = parse->scratch.memref_buffer;
parse->scratch.memref_size = sizeof(parse->scratch.memref_buffer) / sizeof(parse->scratch.memref_buffer[0]);
parse->scratch.memref_count = 0;
parse->first_memref = 0;
}
void rc_destroy_parse_state(rc_parse_state_t* parse)
{
if (parse->scratch.memref != parse->scratch.memref_buffer)
free(parse->scratch.memref);
}

View File

@ -2,13 +2,13 @@
#include <stdlib.h> #include <stdlib.h>
rc_condition_t* rc_parse_condition(int* ret, void* buffer, rc_scratch_t* scratch, const char** memaddr, lua_State* L, int funcs_ndx) { rc_condition_t* rc_parse_condition(const char** memaddr, rc_parse_state_t* parse) {
rc_condition_t* self; rc_condition_t* self;
const char* aux; const char* aux;
int ret2; int ret2;
aux = *memaddr; aux = *memaddr;
self = RC_ALLOC(rc_condition_t, buffer, ret, scratch); self = RC_ALLOC(rc_condition_t, parse);
self->current_hits = 0; self->current_hits = 0;
if (*aux != 0 && aux[1] == ':') { if (*aux != 0 && aux[1] == ':') {
@ -19,7 +19,7 @@ rc_condition_t* rc_parse_condition(int* ret, void* buffer, rc_scratch_t* scratch
case 'b': case 'B': self->type = RC_CONDITION_SUB_SOURCE; break; case 'b': case 'B': self->type = RC_CONDITION_SUB_SOURCE; break;
case 'c': case 'C': self->type = RC_CONDITION_ADD_HITS; break; case 'c': case 'C': self->type = RC_CONDITION_ADD_HITS; break;
case 'n': case 'N': self->type = RC_CONDITION_AND_NEXT; break; case 'n': case 'N': self->type = RC_CONDITION_AND_NEXT; break;
default: *ret = RC_INVALID_CONDITION_TYPE; return 0; default: parse->offset = RC_INVALID_CONDITION_TYPE; return 0;
} }
aux += 2; aux += 2;
@ -28,10 +28,10 @@ rc_condition_t* rc_parse_condition(int* ret, void* buffer, rc_scratch_t* scratch
self->type = RC_CONDITION_STANDARD; self->type = RC_CONDITION_STANDARD;
} }
ret2 = rc_parse_operand(&self->operand1, &aux, 1, L, funcs_ndx); ret2 = rc_parse_operand(&self->operand1, &aux, 1, parse);
if (ret2 < 0) { if (ret2 < 0) {
*ret = ret2; parse->offset = ret2;
return 0; return 0;
} }
@ -45,7 +45,7 @@ rc_condition_t* rc_parse_condition(int* ret, void* buffer, rc_scratch_t* scratch
if (*aux++ != '=') { if (*aux++ != '=') {
/* fall through */ /* fall through */
default: default:
*ret = RC_INVALID_OPERATOR; parse->offset = RC_INVALID_OPERATOR;
return 0; return 0;
} }
@ -73,10 +73,10 @@ rc_condition_t* rc_parse_condition(int* ret, void* buffer, rc_scratch_t* scratch
break; break;
} }
ret2 = rc_parse_operand(&self->operand2, &aux, 1, L, funcs_ndx); ret2 = rc_parse_operand(&self->operand2, &aux, 1, parse);
if (ret2 < 0) { if (ret2 < 0) {
*ret = ret2; parse->offset = ret2;
return 0; return 0;
} }
@ -85,7 +85,7 @@ rc_condition_t* rc_parse_condition(int* ret, void* buffer, rc_scratch_t* scratch
self->required_hits = (unsigned)strtoul(++aux, &end, 10); self->required_hits = (unsigned)strtoul(++aux, &end, 10);
if (end == aux || *end != ')') { if (end == aux || *end != ')') {
*ret = RC_INVALID_REQUIRED_HITS; parse->offset = RC_INVALID_REQUIRED_HITS;
return 0; return 0;
} }
@ -96,7 +96,7 @@ rc_condition_t* rc_parse_condition(int* ret, void* buffer, rc_scratch_t* scratch
self->required_hits = (unsigned)strtoul(++aux, &end, 10); self->required_hits = (unsigned)strtoul(++aux, &end, 10);
if (end == aux || *end != '.') { if (end == aux || *end != '.') {
*ret = RC_INVALID_REQUIRED_HITS; parse->offset = RC_INVALID_REQUIRED_HITS;
return 0; return 0;
} }

View File

@ -23,19 +23,25 @@ static void rc_update_condition_pause(rc_condition_t* condition, int* in_pause)
} }
} }
rc_condset_t* rc_parse_condset(int* ret, void* buffer, rc_scratch_t* scratch, const char** memaddr, lua_State* L, int funcs_ndx) { rc_condset_t* rc_parse_condset(const char** memaddr, rc_parse_state_t* parse) {
rc_condset_t* self; rc_condset_t* self;
rc_condition_t** next; rc_condition_t** next;
int in_pause; int in_pause;
self = RC_ALLOC(rc_condset_t, buffer, ret, scratch); self = RC_ALLOC(rc_condset_t, parse);
self->has_pause = 0; self->has_pause = 0;
next = &self->conditions; next = &self->conditions;
for (;;) { if (**memaddr == 'S' || **memaddr == 's' || !**memaddr) {
*next = rc_parse_condition(ret, buffer, scratch, memaddr, L, funcs_ndx); /* empty group - editor allows it, so we have to support it */
*next = 0;
return self;
}
if (*ret < 0) { for (;;) {
*next = rc_parse_condition(memaddr, parse);
if (parse->offset < 0) {
return 0; return 0;
} }
@ -52,7 +58,7 @@ rc_condset_t* rc_parse_condset(int* ret, void* buffer, rc_scratch_t* scratch, co
*next = 0; *next = 0;
if (buffer != 0) { if (parse->buffer != 0) {
in_pause = 0; in_pause = 0;
rc_update_condition_pause(self->conditions, &in_pause); rc_update_condition_pause(self->conditions, &in_pause);
} }

View File

@ -1,16 +1,16 @@
#include "internal.h" #include "internal.h"
rc_expression_t* rc_parse_expression(int* ret, void* buffer, rc_scratch_t* scratch, const char** memaddr, lua_State* L, int funcs_ndx) { rc_expression_t* rc_parse_expression(const char** memaddr, rc_parse_state_t* parse) {
rc_expression_t* self; rc_expression_t* self;
rc_term_t** next; rc_term_t** next;
self = RC_ALLOC(rc_expression_t, buffer, ret, scratch); self = RC_ALLOC(rc_expression_t, parse);
next = &self->terms; next = &self->terms;
for (;;) { for (;;) {
*next = rc_parse_term(ret, buffer, scratch, memaddr, L, funcs_ndx); *next = rc_parse_term(memaddr, parse);
if (*ret < 0) { if (parse->offset < 0) {
return 0; return 0;
} }

View File

@ -8,50 +8,78 @@
#define RC_OFFSETOF(s, f) ((int)(long long)(&((s*)0)->f)) #define RC_OFFSETOF(s, f) ((int)(long long)(&((s*)0)->f))
#define RC_ALIGNOF(t) RC_OFFSETOF(struct RC_TAG(_unnamed, __LINE__) {char c; t d;}, d) #define RC_ALIGNOF(t) RC_OFFSETOF(struct RC_TAG(_unnamed, __LINE__) {char c; t d;}, d)
#define RC_ALLOC(t, p, o, s) ((t*)rc_alloc(p, o, sizeof(t), RC_ALIGNOF(t), s)) #define RC_ALLOC(t, p) ((t*)rc_alloc((p)->buffer, &(p)->offset, sizeof(t), RC_ALIGNOF(t), &(p)->scratch))
typedef union { typedef struct {
rc_operand_t operand; rc_memref_t memref_buffer[16];
rc_condition_t condition; rc_memref_t *memref;
rc_condset_t condset; int memref_count;
rc_trigger_t trigger; int memref_size;
rc_term_t term;
rc_expression_t expression; union
rc_lboard_t lboard; {
rc_richpresence_t richpresence; rc_operand_t operand;
rc_richpresence_display_t richpresence_display; rc_condition_t condition;
rc_richpresence_display_part_t richpresence_part; rc_condset_t condset;
rc_richpresence_lookup_t richpresence_lookup; rc_trigger_t trigger;
rc_richpresence_lookup_item_t richpresence_lookup_item; rc_term_t term;
rc_expression_t expression;
rc_lboard_t lboard;
rc_memref_value_t memref_value;
rc_richpresence_t richpresence;
rc_richpresence_display_t richpresence_display;
rc_richpresence_display_part_t richpresence_part;
rc_richpresence_lookup_t richpresence_lookup;
rc_richpresence_lookup_item_t richpresence_lookup_item;
} obj;
} }
rc_scratch_t; rc_scratch_t;
typedef struct {
int offset;
lua_State* L;
int funcs_ndx;
void* buffer;
rc_scratch_t scratch;
rc_memref_value_t** first_memref;
}
rc_parse_state_t;
void rc_init_parse_state(rc_parse_state_t* parse, void* buffer, lua_State* L, int funcs_ndx);
void rc_init_parse_state_memrefs(rc_parse_state_t* parse, rc_memref_value_t** memrefs);
void rc_destroy_parse_state(rc_parse_state_t* parse);
void* rc_alloc(void* pointer, int* offset, int size, int alignment, rc_scratch_t* scratch); void* rc_alloc(void* pointer, int* offset, int size, int alignment, rc_scratch_t* scratch);
char* rc_alloc_str(void* pointer, int* offset, const char* text, int length); char* rc_alloc_str(rc_parse_state_t* parse, const char* text, int length);
void rc_parse_trigger_internal(rc_trigger_t* self, int* ret, void* buffer, rc_scratch_t* scratch, const char** memaddr, lua_State* L, int funcs_ndx); rc_memref_value_t* rc_alloc_memref_value(rc_parse_state_t* parse, unsigned address, char size, char is_bcd);
void rc_update_memref_values(rc_memref_value_t* memref, rc_peek_t peek, void* ud);
rc_condset_t* rc_parse_condset(int* ret, void* buffer, rc_scratch_t* scratch, const char** memaddr, lua_State* L, int funcs_ndx); void rc_parse_trigger_internal(rc_trigger_t* self, const char** memaddr, rc_parse_state_t* parse);
rc_condset_t* rc_parse_condset(const char** memaddr, rc_parse_state_t* parse);
int rc_test_condset(rc_condset_t* self, int* reset, rc_peek_t peek, void* ud, lua_State* L); int rc_test_condset(rc_condset_t* self, int* reset, rc_peek_t peek, void* ud, lua_State* L);
void rc_reset_condset(rc_condset_t* self); void rc_reset_condset(rc_condset_t* self);
rc_condition_t* rc_parse_condition(int* ret, void* buffer, rc_scratch_t* scratch, const char** memaddr, lua_State* L, int funcs_ndx); rc_condition_t* rc_parse_condition(const char** memaddr, rc_parse_state_t* parse);
int rc_test_condition(rc_condition_t* self, unsigned add_buffer, rc_peek_t peek, void* ud, lua_State* L); int rc_test_condition(rc_condition_t* self, unsigned add_buffer, rc_peek_t peek, void* ud, lua_State* L);
int rc_parse_operand(rc_operand_t* self, const char** memaddr, int is_trigger, lua_State* L, int funcs_ndx); int rc_parse_operand(rc_operand_t* self, const char** memaddr, int is_trigger, rc_parse_state_t* parse);
unsigned rc_evaluate_operand(rc_operand_t* self, rc_peek_t peek, void* ud, lua_State* L); unsigned rc_evaluate_operand(rc_operand_t* self, rc_peek_t peek, void* ud, lua_State* L);
rc_term_t* rc_parse_term(int* ret, void* buffer, rc_scratch_t* scratch, const char** memaddr, lua_State* L, int funcs_ndx); rc_term_t* rc_parse_term(const char** memaddr, rc_parse_state_t* parse);
unsigned rc_evaluate_term(rc_term_t* self, rc_peek_t peek, void* ud, lua_State* L); unsigned rc_evaluate_term(rc_term_t* self, rc_peek_t peek, void* ud, lua_State* L);
rc_expression_t* rc_parse_expression(int* ret, void* buffer, rc_scratch_t* scratch, const char** memaddr, lua_State* L, int funcs_ndx); rc_expression_t* rc_parse_expression(const char** memaddr, rc_parse_state_t* parse);
unsigned rc_evaluate_expression(rc_expression_t* self, rc_peek_t peek, void* ud, lua_State* L); unsigned rc_evaluate_expression(rc_expression_t* self, rc_peek_t peek, void* ud, lua_State* L);
void rc_parse_value_internal(rc_value_t* self, int* ret, void* buffer, void* scratch, const char** memaddr, lua_State* L, int funcs_ndx); void rc_parse_value_internal(rc_value_t* self, const char** memaddr, rc_parse_state_t* parse);
void rc_parse_lboard_internal(rc_lboard_t* self, int* ret, void* buffer, void* scratch, const char* memaddr, lua_State* L, int funcs_ndx); void rc_parse_lboard_internal(rc_lboard_t* self, const char* memaddr, rc_parse_state_t* parse);
const char* rc_parse_line(const char* line, const char** end); void rc_parse_richpresence_internal(rc_richpresence_t* self, const char* script, rc_parse_state_t* parse);
void rc_parse_richpresence_internal(rc_richpresence_t* self, int* ret, void* buffer, void* scratch, const char* script, lua_State* L, int funcs_ndx);
#endif /* INTERNAL_H */ #endif /* INTERNAL_H */

View File

@ -9,7 +9,7 @@ enum {
RC_LBOARD_COMPLETE = RC_LBOARD_START | RC_LBOARD_CANCEL | RC_LBOARD_SUBMIT | RC_LBOARD_VALUE RC_LBOARD_COMPLETE = RC_LBOARD_START | RC_LBOARD_CANCEL | RC_LBOARD_SUBMIT | RC_LBOARD_VALUE
}; };
void rc_parse_lboard_internal(rc_lboard_t* self, int* ret, void* buffer, void* scratch, const char* memaddr, lua_State* L, int funcs_ndx) { void rc_parse_lboard_internal(rc_lboard_t* self, const char* memaddr, rc_parse_state_t* parse) {
int found; int found;
self->progress = 0; self->progress = 0;
@ -21,15 +21,16 @@ void rc_parse_lboard_internal(rc_lboard_t* self, int* ret, void* buffer, void* s
(memaddr[1] == 't' || memaddr[1] == 'T') && (memaddr[1] == 't' || memaddr[1] == 'T') &&
(memaddr[2] == 'a' || memaddr[2] == 'A') && memaddr[3] == ':') { (memaddr[2] == 'a' || memaddr[2] == 'A') && memaddr[3] == ':') {
if ((found & RC_LBOARD_START) != 0) { if ((found & RC_LBOARD_START) != 0) {
*ret = RC_DUPLICATED_START; parse->offset = RC_DUPLICATED_START;
return; return;
} }
found |= RC_LBOARD_START; found |= RC_LBOARD_START;
memaddr += 4; memaddr += 4;
rc_parse_trigger_internal(&self->start, ret, buffer, scratch, &memaddr, L, funcs_ndx); rc_parse_trigger_internal(&self->start, &memaddr, parse);
self->start.memrefs = 0;
if (*ret < 0) { if (parse->offset < 0) {
return; return;
} }
} }
@ -37,15 +38,16 @@ void rc_parse_lboard_internal(rc_lboard_t* self, int* ret, void* buffer, void* s
(memaddr[1] == 'a' || memaddr[1] == 'A') && (memaddr[1] == 'a' || memaddr[1] == 'A') &&
(memaddr[2] == 'n' || memaddr[2] == 'N') && memaddr[3] == ':') { (memaddr[2] == 'n' || memaddr[2] == 'N') && memaddr[3] == ':') {
if ((found & RC_LBOARD_CANCEL) != 0) { if ((found & RC_LBOARD_CANCEL) != 0) {
*ret = RC_DUPLICATED_CANCEL; parse->offset = RC_DUPLICATED_CANCEL;
return; return;
} }
found |= RC_LBOARD_CANCEL; found |= RC_LBOARD_CANCEL;
memaddr += 4; memaddr += 4;
rc_parse_trigger_internal(&self->cancel, ret, buffer, scratch, &memaddr, L, funcs_ndx); rc_parse_trigger_internal(&self->cancel, &memaddr, parse);
self->cancel.memrefs = 0;
if (*ret < 0) { if (parse->offset < 0) {
return; return;
} }
} }
@ -53,15 +55,16 @@ void rc_parse_lboard_internal(rc_lboard_t* self, int* ret, void* buffer, void* s
(memaddr[1] == 'u' || memaddr[1] == 'U') && (memaddr[1] == 'u' || memaddr[1] == 'U') &&
(memaddr[2] == 'b' || memaddr[2] == 'B') && memaddr[3] == ':') { (memaddr[2] == 'b' || memaddr[2] == 'B') && memaddr[3] == ':') {
if ((found & RC_LBOARD_SUBMIT) != 0) { if ((found & RC_LBOARD_SUBMIT) != 0) {
*ret = RC_DUPLICATED_SUBMIT; parse->offset = RC_DUPLICATED_SUBMIT;
return; return;
} }
found |= RC_LBOARD_SUBMIT; found |= RC_LBOARD_SUBMIT;
memaddr += 4; memaddr += 4;
rc_parse_trigger_internal(&self->submit, ret, buffer, scratch, &memaddr, L, funcs_ndx); rc_parse_trigger_internal(&self->submit, &memaddr, parse);
self->submit.memrefs = 0;
if (*ret < 0) { if (parse->offset < 0) {
return; return;
} }
} }
@ -69,15 +72,16 @@ void rc_parse_lboard_internal(rc_lboard_t* self, int* ret, void* buffer, void* s
(memaddr[1] == 'a' || memaddr[1] == 'A') && (memaddr[1] == 'a' || memaddr[1] == 'A') &&
(memaddr[2] == 'l' || memaddr[2] == 'L') && memaddr[3] == ':') { (memaddr[2] == 'l' || memaddr[2] == 'L') && memaddr[3] == ':') {
if ((found & RC_LBOARD_VALUE) != 0) { if ((found & RC_LBOARD_VALUE) != 0) {
*ret = RC_DUPLICATED_VALUE; parse->offset = RC_DUPLICATED_VALUE;
return; return;
} }
found |= RC_LBOARD_VALUE; found |= RC_LBOARD_VALUE;
memaddr += 4; memaddr += 4;
rc_parse_value_internal(&self->value, ret, buffer, scratch, &memaddr, L, funcs_ndx); rc_parse_value_internal(&self->value, &memaddr, parse);
self->value.memrefs = 0;
if (*ret < 0) { if (parse->offset < 0) {
return; return;
} }
} }
@ -85,22 +89,23 @@ void rc_parse_lboard_internal(rc_lboard_t* self, int* ret, void* buffer, void* s
(memaddr[1] == 'r' || memaddr[1] == 'R') && (memaddr[1] == 'r' || memaddr[1] == 'R') &&
(memaddr[2] == 'o' || memaddr[2] == 'O') && memaddr[3] == ':') { (memaddr[2] == 'o' || memaddr[2] == 'O') && memaddr[3] == ':') {
if ((found & RC_LBOARD_PROGRESS) != 0) { if ((found & RC_LBOARD_PROGRESS) != 0) {
*ret = RC_DUPLICATED_PROGRESS; parse->offset = RC_DUPLICATED_PROGRESS;
return; return;
} }
found |= RC_LBOARD_PROGRESS; found |= RC_LBOARD_PROGRESS;
memaddr += 4; memaddr += 4;
self->progress = RC_ALLOC(rc_value_t, buffer, ret, scratch); self->progress = RC_ALLOC(rc_value_t, parse);
rc_parse_value_internal(self->progress, ret, buffer, scratch, &memaddr, L, funcs_ndx); rc_parse_value_internal(self->progress, &memaddr, parse);
self->progress->memrefs = 0;
if (*ret < 0) { if (parse->offset < 0) {
return; return;
} }
} }
else { else {
*ret = RC_INVALID_LBOARD_FIELD; parse->offset = RC_INVALID_LBOARD_FIELD;
return; return;
} }
@ -113,16 +118,16 @@ void rc_parse_lboard_internal(rc_lboard_t* self, int* ret, void* buffer, void* s
if ((found & RC_LBOARD_COMPLETE) != RC_LBOARD_COMPLETE) { if ((found & RC_LBOARD_COMPLETE) != RC_LBOARD_COMPLETE) {
if ((found & RC_LBOARD_START) == 0) { if ((found & RC_LBOARD_START) == 0) {
*ret = RC_MISSING_START; parse->offset = RC_MISSING_START;
} }
else if ((found & RC_LBOARD_CANCEL) == 0) { else if ((found & RC_LBOARD_CANCEL) == 0) {
*ret = RC_MISSING_CANCEL; parse->offset = RC_MISSING_CANCEL;
} }
else if ((found & RC_LBOARD_SUBMIT) == 0) { else if ((found & RC_LBOARD_SUBMIT) == 0) {
*ret = RC_MISSING_SUBMIT; parse->offset = RC_MISSING_SUBMIT;
} }
else if ((found & RC_LBOARD_VALUE) == 0) { else if ((found & RC_LBOARD_VALUE) == 0) {
*ret = RC_MISSING_VALUE; parse->offset = RC_MISSING_VALUE;
} }
return; return;
@ -132,31 +137,37 @@ void rc_parse_lboard_internal(rc_lboard_t* self, int* ret, void* buffer, void* s
} }
int rc_lboard_size(const char* memaddr) { int rc_lboard_size(const char* memaddr) {
int ret;
rc_lboard_t* self; rc_lboard_t* self;
rc_scratch_t scratch; rc_parse_state_t parse;
rc_init_parse_state(&parse, 0, 0, 0);
ret = 0; self = RC_ALLOC(rc_lboard_t, &parse);
self = RC_ALLOC(rc_lboard_t, 0, &ret, &scratch); rc_parse_lboard_internal(self, memaddr, &parse);
rc_parse_lboard_internal(self, &ret, 0, &scratch, memaddr, 0, 0);
return ret; rc_destroy_parse_state(&parse);
return parse.offset;
} }
rc_lboard_t* rc_parse_lboard(void* buffer, const char* memaddr, lua_State* L, int funcs_ndx) { rc_lboard_t* rc_parse_lboard(void* buffer, const char* memaddr, lua_State* L, int funcs_ndx) {
int ret;
rc_lboard_t* self; rc_lboard_t* self;
rc_scratch_t scratch; rc_parse_state_t parse;
rc_init_parse_state(&parse, buffer, L, funcs_ndx);
ret = 0; self = RC_ALLOC(rc_lboard_t, &parse);
self = RC_ALLOC(rc_lboard_t, buffer, &ret, &scratch); rc_init_parse_state_memrefs(&parse, &self->memrefs);
rc_parse_lboard_internal(self, &ret, buffer, 0, memaddr, L, funcs_ndx);
return ret >= 0 ? self : 0; rc_parse_lboard_internal(self, memaddr, &parse);
rc_destroy_parse_state(&parse);
return parse.offset >= 0 ? self : 0;
} }
int rc_evaluate_lboard(rc_lboard_t* self, unsigned* value, rc_peek_t peek, void* peek_ud, lua_State* L) { int rc_evaluate_lboard(rc_lboard_t* self, unsigned* value, rc_peek_t peek, void* peek_ud, lua_State* L) {
int start_ok, cancel_ok, submit_ok; int start_ok, cancel_ok, submit_ok;
int action = -1; int action = -1;
rc_update_memref_values(self->memrefs, peek, peek_ud);
/* ASSERT: these are always tested once every frame, to ensure delta variables work properly */ /* ASSERT: these are always tested once every frame, to ensure delta variables work properly */
start_ok = rc_test_trigger(&self->start, peek, peek_ud, L); start_ok = rc_test_trigger(&self->start, peek, peek_ud, L);
cancel_ok = rc_test_trigger(&self->cancel, peek, peek_ud, L); cancel_ok = rc_test_trigger(&self->cancel, peek, peek_ud, L);

204
deps/rcheevos/src/rcheevos/memref.c vendored Normal file
View File

@ -0,0 +1,204 @@
#include "internal.h"
#include <stdlib.h> /* malloc/realloc */
#include <string.h> /* memcpy */
rc_memref_value_t* rc_alloc_memref_value(rc_parse_state_t* parse, unsigned address, char size, char is_bcd) {
rc_memref_value_t** next_memref_value;
rc_memref_value_t* memref_value;
rc_memref_t* memref;
int i;
if (!parse->first_memref) {
/* sizing mode - have to track unique address/size/bcd combinations */
for (i = 0; i < parse->scratch.memref_count; ++i) {
memref = &parse->scratch.memref[i];
if (memref->address == address && memref->size == size && memref->is_bcd == is_bcd) {
return &parse->scratch.obj.memref_value;
}
}
/* resize unique tracking buffer if necessary */
if (parse->scratch.memref_count == parse->scratch.memref_size) {
if (parse->scratch.memref == parse->scratch.memref_buffer) {
parse->scratch.memref_size += 16;
memref = malloc(parse->scratch.memref_size * sizeof(parse->scratch.memref_buffer[0]));
if (memref) {
parse->scratch.memref = memref;
memcpy(memref, parse->scratch.memref_buffer, parse->scratch.memref_count * sizeof(parse->scratch.memref_buffer[0]));
}
else {
parse->offset = RC_OUT_OF_MEMORY;
return 0;
}
}
else {
parse->scratch.memref_size += 32;
memref = realloc(parse->scratch.memref, parse->scratch.memref_size * sizeof(parse->scratch.memref_buffer[0]));
if (memref) {
parse->scratch.memref = memref;
}
else {
parse->offset = RC_OUT_OF_MEMORY;
return 0;
}
}
}
/* add new unique tracking entry */
if (parse->scratch.memref) {
memref = &parse->scratch.memref[parse->scratch.memref_count++];
memref->address = address;
memref->size = size;
memref->is_bcd = is_bcd;
}
/* allocate memory but don't actually populate, as it might overwrite the self object referencing the rc_memref_value_t */
return RC_ALLOC(rc_memref_value_t, parse);
}
/* construction mode - find or create the appropriate rc_memref_value_t */
next_memref_value = parse->first_memref;
while (*next_memref_value) {
memref_value = *next_memref_value;
if (memref_value->memref.address == address && memref_value->memref.size == size && memref_value->memref.is_bcd == is_bcd) {
return memref_value;
}
next_memref_value = &memref_value->next;
}
memref_value = RC_ALLOC(rc_memref_value_t, parse);
memref_value->memref.address = address;
memref_value->memref.size = size;
memref_value->memref.is_bcd = is_bcd;
memref_value->value = 0;
memref_value->previous = 0;
memref_value->prior = 0;
memref_value->next = 0;
*next_memref_value = memref_value;
return memref_value;
}
static unsigned rc_memref_get_value(rc_memref_t* self, rc_peek_t peek, void* ud) {
unsigned value;
switch (self->size)
{
case RC_MEMSIZE_BIT_0:
value = (peek(self->address, 1, ud) >> 0) & 1;
break;
case RC_MEMSIZE_BIT_1:
value = (peek(self->address, 1, ud) >> 1) & 1;
break;
case RC_MEMSIZE_BIT_2:
value = (peek(self->address, 1, ud) >> 2) & 1;
break;
case RC_MEMSIZE_BIT_3:
value = (peek(self->address, 1, ud) >> 3) & 1;
break;
case RC_MEMSIZE_BIT_4:
value = (peek(self->address, 1, ud) >> 4) & 1;
break;
case RC_MEMSIZE_BIT_5:
value = (peek(self->address, 1, ud) >> 5) & 1;
break;
case RC_MEMSIZE_BIT_6:
value = (peek(self->address, 1, ud) >> 6) & 1;
break;
case RC_MEMSIZE_BIT_7:
value = (peek(self->address, 1, ud) >> 7) & 1;
break;
case RC_MEMSIZE_LOW:
value = peek(self->address, 1, ud) & 0x0f;
break;
case RC_MEMSIZE_HIGH:
value = (peek(self->address, 1, ud) >> 4) & 0x0f;
break;
case RC_MEMSIZE_8_BITS:
value = peek(self->address, 1, ud);
if (self->is_bcd) {
value = ((value >> 4) & 0x0f) * 10 + (value & 0x0f);
}
break;
case RC_MEMSIZE_16_BITS:
value = peek(self->address, 2, ud);
if (self->is_bcd) {
value = ((value >> 12) & 0x0f) * 1000
+ ((value >> 8) & 0x0f) * 100
+ ((value >> 4) & 0x0f) * 10
+ ((value >> 0) & 0x0f) * 1;
}
break;
case RC_MEMSIZE_24_BITS:
value = peek(self->address, 4, ud);
if (self->is_bcd) {
value = ((value >> 20) & 0x0f) * 100000
+ ((value >> 16) & 0x0f) * 10000
+ ((value >> 12) & 0x0f) * 1000
+ ((value >> 8) & 0x0f) * 100
+ ((value >> 4) & 0x0f) * 10
+ ((value >> 0) & 0x0f) * 1;
}
break;
case RC_MEMSIZE_32_BITS:
value = peek(self->address, 4, ud);
if (self->is_bcd) {
value = ((value >> 28) & 0x0f) * 10000000
+ ((value >> 24) & 0x0f) * 1000000
+ ((value >> 20) & 0x0f) * 100000
+ ((value >> 16) & 0x0f) * 10000
+ ((value >> 12) & 0x0f) * 1000
+ ((value >> 8) & 0x0f) * 100
+ ((value >> 4) & 0x0f) * 10
+ ((value >> 0) & 0x0f) * 1;
}
break;
default:
value = 0;
break;
}
return value;
}
void rc_update_memref_values(rc_memref_value_t* memref, rc_peek_t peek, void* ud) {
while (memref) {
memref->previous = memref->value;
memref->value = rc_memref_get_value(&memref->memref, peek, ud);
if (memref->value != memref->previous)
memref->prior = memref->previous;
memref = memref->next;
}
}
void rc_init_parse_state_memrefs(rc_parse_state_t* parse, rc_memref_value_t** memrefs)
{
parse->first_memref = memrefs;
*memrefs = 0;
}

View File

@ -2,6 +2,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <ctype.h> #include <ctype.h>
#include <math.h>
#ifndef RC_DISABLE_LUA #ifndef RC_DISABLE_LUA
@ -18,7 +19,7 @@ extern "C" {
#endif /* RC_DISABLE_LUA */ #endif /* RC_DISABLE_LUA */
static int rc_parse_operand_lua(rc_operand_t* self, const char** memaddr, lua_State* L, int funcs_ndx) { static int rc_parse_operand_lua(rc_operand_t* self, const char** memaddr, rc_parse_state_t* parse) {
const char* aux = *memaddr; const char* aux = *memaddr;
const char* id; const char* id;
@ -38,20 +39,20 @@ static int rc_parse_operand_lua(rc_operand_t* self, const char** memaddr, lua_St
#ifndef RC_DISABLE_LUA #ifndef RC_DISABLE_LUA
if (L != 0) { if (parse->L != 0) {
if (!lua_istable(L, funcs_ndx)) { if (!lua_istable(parse->L, parse->funcs_ndx)) {
return RC_INVALID_LUA_OPERAND; return RC_INVALID_LUA_OPERAND;
} }
lua_pushlstring(L, id, aux - id); lua_pushlstring(parse->L, id, aux - id);
lua_gettable(L, funcs_ndx); lua_gettable(parse->L, parse->funcs_ndx);
if (!lua_isfunction(L, -1)) { if (!lua_isfunction(parse->L, -1)) {
lua_pop(L, 1); lua_pop(parse->L, 1);
return RC_INVALID_LUA_OPERAND; return RC_INVALID_LUA_OPERAND;
} }
self->function_ref = luaL_ref(L, LUA_REGISTRYINDEX); self->function_ref = luaL_ref(parse->L, LUA_REGISTRYINDEX);
} }
#endif /* RC_DISABLE_LUA */ #endif /* RC_DISABLE_LUA */
@ -61,10 +62,12 @@ static int rc_parse_operand_lua(rc_operand_t* self, const char** memaddr, lua_St
return RC_OK; return RC_OK;
} }
static int rc_parse_operand_memory(rc_operand_t* self, const char** memaddr) { static int rc_parse_operand_memory(rc_operand_t* self, const char** memaddr, rc_parse_state_t* parse) {
const char* aux = *memaddr; const char* aux = *memaddr;
char* end; char* end;
unsigned long value; unsigned long address;
char is_bcd = 0;
char size;
switch (*aux++) { switch (*aux++) {
case 'd': case 'D': case 'd': case 'D':
@ -73,7 +76,7 @@ static int rc_parse_operand_memory(rc_operand_t* self, const char** memaddr) {
case 'b': case 'B': case 'b': case 'B':
self->type = RC_OPERAND_ADDRESS; self->type = RC_OPERAND_ADDRESS;
self->is_bcd = 1; is_bcd = 1;
break; break;
case 'p': case 'P': case 'p': case 'P':
@ -97,44 +100,46 @@ static int rc_parse_operand_memory(rc_operand_t* self, const char** memaddr) {
aux++; aux++;
switch (*aux++) { switch (*aux++) {
case 'm': case 'M': self->size = RC_OPERAND_BIT_0; break; case 'm': case 'M': size = RC_MEMSIZE_BIT_0; break;
case 'n': case 'N': self->size = RC_OPERAND_BIT_1; break; case 'n': case 'N': size = RC_MEMSIZE_BIT_1; break;
case 'o': case 'O': self->size = RC_OPERAND_BIT_2; break; case 'o': case 'O': size = RC_MEMSIZE_BIT_2; break;
case 'p': case 'P': self->size = RC_OPERAND_BIT_3; break; case 'p': case 'P': size = RC_MEMSIZE_BIT_3; break;
case 'q': case 'Q': self->size = RC_OPERAND_BIT_4; break; case 'q': case 'Q': size = RC_MEMSIZE_BIT_4; break;
case 'r': case 'R': self->size = RC_OPERAND_BIT_5; break; case 'r': case 'R': size = RC_MEMSIZE_BIT_5; break;
case 's': case 'S': self->size = RC_OPERAND_BIT_6; break; case 's': case 'S': size = RC_MEMSIZE_BIT_6; break;
case 't': case 'T': self->size = RC_OPERAND_BIT_7; break; case 't': case 'T': size = RC_MEMSIZE_BIT_7; break;
case 'l': case 'L': self->size = RC_OPERAND_LOW; break; case 'l': case 'L': size = RC_MEMSIZE_LOW; break;
case 'u': case 'U': self->size = RC_OPERAND_HIGH; break; case 'u': case 'U': size = RC_MEMSIZE_HIGH; break;
case 'h': case 'H': self->size = RC_OPERAND_8_BITS; break; case 'h': case 'H': size = RC_MEMSIZE_8_BITS; break;
case 'w': case 'W': self->size = RC_OPERAND_24_BITS; break; case 'w': case 'W': size = RC_MEMSIZE_24_BITS; break;
case 'x': case 'X': self->size = RC_OPERAND_32_BITS; break; case 'x': case 'X': size = RC_MEMSIZE_32_BITS; break;
default: /* fall through */ default: /* fall through */
aux--; aux--;
case ' ': case ' ':
self->size = RC_OPERAND_16_BITS; size = RC_MEMSIZE_16_BITS;
break; break;
} }
value = strtoul(aux, &end, 16); address = strtoul(aux, &end, 16);
if (end == aux) { if (end == aux) {
return RC_INVALID_MEMORY_OPERAND; return RC_INVALID_MEMORY_OPERAND;
} }
if (value > 0xffffffffU) { if (address > 0xffffffffU) {
value = 0xffffffffU; address = 0xffffffffU;
} }
self->value = (unsigned)value; self->memref = rc_alloc_memref_value(parse, address, size, is_bcd);
if (parse->offset < 0)
return parse->offset;
*memaddr = end; *memaddr = end;
return RC_OK; return RC_OK;
} }
static int rc_parse_operand_trigger(rc_operand_t* self, const char** memaddr, lua_State* L, int funcs_ndx) { static int rc_parse_operand_trigger(rc_operand_t* self, const char** memaddr, rc_parse_state_t* parse) {
const char* aux = *memaddr; const char* aux = *memaddr;
char* end; char* end;
int ret; int ret;
@ -162,7 +167,7 @@ static int rc_parse_operand_trigger(rc_operand_t* self, const char** memaddr, lu
if (aux[1] == 'x' || aux[1] == 'X') { if (aux[1] == 'x' || aux[1] == 'X') {
/* fall through */ /* fall through */
default: default:
ret = rc_parse_operand_memory(self, &aux); ret = rc_parse_operand_memory(self, &aux, parse);
if (ret < 0) { if (ret < 0) {
return ret; return ret;
@ -192,7 +197,7 @@ static int rc_parse_operand_trigger(rc_operand_t* self, const char** memaddr, lu
break; break;
case '@': case '@':
ret = rc_parse_operand_lua(self, &aux, L, funcs_ndx); ret = rc_parse_operand_lua(self, &aux, parse);
if (ret < 0) { if (ret < 0) {
return ret; return ret;
@ -205,7 +210,7 @@ static int rc_parse_operand_trigger(rc_operand_t* self, const char** memaddr, lu
return RC_OK; return RC_OK;
} }
static int rc_parse_operand_term(rc_operand_t* self, const char** memaddr, lua_State* L, int funcs_ndx) { static int rc_parse_operand_term(rc_operand_t* self, const char** memaddr, rc_parse_state_t* parse) {
const char* aux = *memaddr; const char* aux = *memaddr;
char* end; char* end;
int ret; int ret;
@ -250,7 +255,7 @@ static int rc_parse_operand_term(rc_operand_t* self, const char** memaddr, lua_S
if (aux[1] == 'x' || aux[1] == 'X') { if (aux[1] == 'x' || aux[1] == 'X') {
/* fall through */ /* fall through */
default: default:
ret = rc_parse_operand_memory(self, &aux); ret = rc_parse_operand_memory(self, &aux, parse);
if (ret < 0) { if (ret < 0) {
return ret; return ret;
@ -264,18 +269,24 @@ static int rc_parse_operand_term(rc_operand_t* self, const char** memaddr, lua_S
case '+': case '-': case '+': case '-':
case '1': case '2': case '3': case '4': case '5': case '1': case '2': case '3': case '4': case '5':
case '6': case '7': case '8': case '9': case '6': case '7': case '8': case '9':
self->type = RC_OPERAND_FP;
self->fp_value = strtod(aux, &end); self->fp_value = strtod(aux, &end);
if (end == aux) { if (end == aux) {
return RC_INVALID_FP_OPERAND; return RC_INVALID_FP_OPERAND;
} }
if (floor(self->fp_value) == self->fp_value) {
self->type = RC_OPERAND_CONST;
self->value = (unsigned)floor(self->fp_value);
}
else {
self->type = RC_OPERAND_FP;
}
aux = end; aux = end;
break; break;
case '@': case '@':
ret = rc_parse_operand_lua(self, &aux, L, funcs_ndx); ret = rc_parse_operand_lua(self, &aux, parse);
if (ret < 0) { if (ret < 0) {
return ret; return ret;
@ -288,17 +299,12 @@ static int rc_parse_operand_term(rc_operand_t* self, const char** memaddr, lua_S
return RC_OK; return RC_OK;
} }
int rc_parse_operand(rc_operand_t* self, const char** memaddr, int is_trigger, lua_State* L, int funcs_ndx) { int rc_parse_operand(rc_operand_t* self, const char** memaddr, int is_trigger, rc_parse_state_t* parse) {
self->size = RC_OPERAND_8_BITS;
self->is_bcd = 0;
self->previous = 0;
self->prior = 0;
if (is_trigger) { if (is_trigger) {
return rc_parse_operand_trigger(self, memaddr, L, funcs_ndx); return rc_parse_operand_trigger(self, memaddr, parse);
} }
else { else {
return rc_parse_operand_term(self, memaddr, L, funcs_ndx); return rc_parse_operand_term(self, memaddr, parse);
} }
} }
@ -368,113 +374,15 @@ unsigned rc_evaluate_operand(rc_operand_t* self, rc_peek_t peek, void* ud, lua_S
break; break;
case RC_OPERAND_ADDRESS: case RC_OPERAND_ADDRESS:
value = self->memref->value;
break;
case RC_OPERAND_DELTA: case RC_OPERAND_DELTA:
value = self->memref->previous;
break;
case RC_OPERAND_PRIOR: case RC_OPERAND_PRIOR:
switch (self->size) { value = self->memref->prior;
case RC_OPERAND_BIT_0:
value = (peek(self->value, 1, ud) >> 0) & 1;
break;
case RC_OPERAND_BIT_1:
value = (peek(self->value, 1, ud) >> 1) & 1;
break;
case RC_OPERAND_BIT_2:
value = (peek(self->value, 1, ud) >> 2) & 1;
break;
case RC_OPERAND_BIT_3:
value = (peek(self->value, 1, ud) >> 3) & 1;
break;
case RC_OPERAND_BIT_4:
value = (peek(self->value, 1, ud) >> 4) & 1;
break;
case RC_OPERAND_BIT_5:
value = (peek(self->value, 1, ud) >> 5 ) & 1;
break;
case RC_OPERAND_BIT_6:
value = (peek(self->value, 1, ud) >> 6) & 1;
break;
case RC_OPERAND_BIT_7:
value = (peek(self->value, 1, ud) >> 7) & 1;
break;
case RC_OPERAND_LOW:
value = peek(self->value, 1, ud) & 0x0f;
break;
case RC_OPERAND_HIGH:
value = (peek(self->value, 1, ud) >> 4) & 0x0f;
break;
case RC_OPERAND_8_BITS:
value = peek(self->value, 1, ud);
if (self->is_bcd) {
value = ((value >> 4) & 0x0f) * 10 + (value & 0x0f);
}
break;
case RC_OPERAND_16_BITS:
value = peek(self->value, 2, ud);
if (self->is_bcd) {
value = ((value >> 12) & 0x0f) * 1000
+ ((value >> 8) & 0x0f) * 100
+ ((value >> 4) & 0x0f) * 10
+ ((value >> 0) & 0x0f) * 1;
}
break;
case RC_OPERAND_24_BITS:
value = peek(self->value, 4, ud);
if (self->is_bcd) {
value = ((value >> 20) & 0x0f) * 100000
+ ((value >> 16) & 0x0f) * 10000
+ ((value >> 12) & 0x0f) * 1000
+ ((value >> 8) & 0x0f) * 100
+ ((value >> 4) & 0x0f) * 10
+ ((value >> 0) & 0x0f) * 1;
}
break;
case RC_OPERAND_32_BITS:
value = peek(self->value, 4, ud);
if (self->is_bcd) {
value = ((value >> 28) & 0x0f) * 10000000
+ ((value >> 24) & 0x0f) * 1000000
+ ((value >> 20) & 0x0f) * 100000
+ ((value >> 16) & 0x0f) * 10000
+ ((value >> 12) & 0x0f) * 1000
+ ((value >> 8) & 0x0f) * 100
+ ((value >> 4) & 0x0f) * 10
+ ((value >> 0) & 0x0f) * 1;
}
break;
}
if (self->type == RC_OPERAND_DELTA) {
unsigned previous = self->previous;
self->previous = value;
value = previous;
} else if (self->type == RC_OPERAND_PRIOR) {
if (self->previous != value) {
self->prior = self->previous;
self->previous = value;
}
value = self->prior;
}
break; break;
} }

View File

@ -11,7 +11,7 @@ enum {
RC_FORMAT_LOOKUP = 102 RC_FORMAT_LOOKUP = 102
}; };
const char* rc_parse_line(const char* line, const char** end) { static const char* rc_parse_line(const char* line, const char** end) {
const char* nextline; const char* nextline;
const char* endline; const char* endline;
@ -42,7 +42,7 @@ const char* rc_parse_line(const char* line, const char** end) {
return nextline; return nextline;
} }
rc_richpresence_display_t* rc_parse_richpresence_display_internal(void* buffer, int* ret, rc_scratch_t* scratch, const char* line, const char* endline, lua_State* L, int funcs_ndx, rc_richpresence_t* richpresence) { static rc_richpresence_display_t* rc_parse_richpresence_display_internal(const char* line, const char* endline, rc_parse_state_t* parse, rc_richpresence_t* richpresence) {
rc_richpresence_display_t* self; rc_richpresence_display_t* self;
rc_richpresence_display_part_t* part; rc_richpresence_display_part_t* part;
rc_richpresence_display_part_t** next; rc_richpresence_display_part_t** next;
@ -55,7 +55,7 @@ rc_richpresence_display_t* rc_parse_richpresence_display_internal(void* buffer,
return 0; return 0;
{ {
self = RC_ALLOC(rc_richpresence_display_t, buffer, ret, scratch); self = RC_ALLOC(rc_richpresence_display_t, parse);
memset(self, 0, sizeof(rc_richpresence_display_t)); memset(self, 0, sizeof(rc_richpresence_display_t));
next = &self->display; next = &self->display;
} }
@ -71,14 +71,14 @@ rc_richpresence_display_t* rc_parse_richpresence_display_internal(void* buffer,
} }
if (ptr > line) { if (ptr > line) {
part = RC_ALLOC(rc_richpresence_display_part_t, buffer, ret, scratch); part = RC_ALLOC(rc_richpresence_display_part_t, parse);
memset(part, 0, sizeof(rc_richpresence_display_part_t)); memset(part, 0, sizeof(rc_richpresence_display_part_t));
*next = part; *next = part;
next = &part->next; next = &part->next;
/* handle string part */ /* handle string part */
part->display_type = RC_FORMAT_STRING; part->display_type = RC_FORMAT_STRING;
part->text = rc_alloc_str(buffer, ret, line, ptr - line); part->text = rc_alloc_str(parse, line, ptr - line);
if (part->text) { if (part->text) {
/* remove backslashes used for escaping */ /* remove backslashes used for escaping */
in = part->text; in = part->text;
@ -104,16 +104,16 @@ rc_richpresence_display_t* rc_parse_richpresence_display_internal(void* buffer,
++ptr; ++ptr;
if (ptr > line) { if (ptr > line) {
if (!buffer) { if (!parse->buffer) {
/* just calculating size, can't confirm lookup exists */ /* just calculating size, can't confirm lookup exists */
part = RC_ALLOC(rc_richpresence_display_part_t, buffer, ret, scratch); part = RC_ALLOC(rc_richpresence_display_part_t, parse);
line = ++ptr; line = ++ptr;
while (ptr < endline && *ptr != ')') while (ptr < endline && *ptr != ')')
++ptr; ++ptr;
if (*ptr == ')') { if (*ptr == ')') {
rc_parse_value_internal(&part->value, ret, buffer, scratch, &line, L, funcs_ndx); rc_parse_value_internal(&part->value, &line, parse);
if (ret < 0) if (parse->offset < 0)
return 0; return 0;
++ptr; ++ptr;
} }
@ -123,7 +123,7 @@ rc_richpresence_display_t* rc_parse_richpresence_display_internal(void* buffer,
lookup = richpresence->first_lookup; lookup = richpresence->first_lookup;
while (lookup) { while (lookup) {
if (strncmp(lookup->name, line, ptr - line) == 0 && lookup->name[ptr - line] == '\0') { if (strncmp(lookup->name, line, ptr - line) == 0 && lookup->name[ptr - line] == '\0') {
part = RC_ALLOC(rc_richpresence_display_part_t, buffer, ret, scratch); part = RC_ALLOC(rc_richpresence_display_part_t, parse);
*next = part; *next = part;
next = &part->next; next = &part->next;
@ -135,8 +135,9 @@ rc_richpresence_display_t* rc_parse_richpresence_display_internal(void* buffer,
while (ptr < endline && *ptr != ')') while (ptr < endline && *ptr != ')')
++ptr; ++ptr;
if (*ptr == ')') { if (*ptr == ')') {
rc_parse_value_internal(&part->value, ret, buffer, scratch, &line, L, funcs_ndx); rc_parse_value_internal(&part->value, &line, parse);
if (ret < 0) part->value.memrefs = 0;
if (parse->offset < 0)
return 0; return 0;
++ptr; ++ptr;
} }
@ -148,7 +149,7 @@ rc_richpresence_display_t* rc_parse_richpresence_display_internal(void* buffer,
} }
if (!lookup) { if (!lookup) {
part = RC_ALLOC(rc_richpresence_display_part_t, buffer, ret, scratch); part = RC_ALLOC(rc_richpresence_display_part_t, parse);
memset(part, 0, sizeof(rc_richpresence_display_part_t)); memset(part, 0, sizeof(rc_richpresence_display_part_t));
*next = part; *next = part;
next = &part->next; next = &part->next;
@ -156,7 +157,7 @@ rc_richpresence_display_t* rc_parse_richpresence_display_internal(void* buffer,
ptr = line; ptr = line;
part->display_type = RC_FORMAT_STRING; part->display_type = RC_FORMAT_STRING;
part->text = rc_alloc_str(buffer, ret, "[Unknown macro]", 15); part->text = rc_alloc_str(parse, "[Unknown macro]", 15);
} }
} }
} }
@ -170,7 +171,7 @@ rc_richpresence_display_t* rc_parse_richpresence_display_internal(void* buffer,
return self; return self;
} }
const char* rc_parse_richpresence_lookup(rc_richpresence_lookup_t* lookup, const char* nextline, int* ret, void* buffer, void* scratch, lua_State* L, int funcs_ndx) static const char* rc_parse_richpresence_lookup(rc_richpresence_lookup_t* lookup, const char* nextline, rc_parse_state_t* parse)
{ {
rc_richpresence_lookup_item_t** next; rc_richpresence_lookup_item_t** next;
rc_richpresence_lookup_item_t* item; rc_richpresence_lookup_item_t* item;
@ -202,7 +203,7 @@ const char* rc_parse_richpresence_lookup(rc_richpresence_lookup_t* lookup, const
line += chars + 1; line += chars + 1;
if (chars == 1 && number[0] == '*') { if (chars == 1 && number[0] == '*') {
defaultlabel = rc_alloc_str(buffer, ret, line, endline - line); defaultlabel = rc_alloc_str(parse, line, endline - line);
continue; continue;
} }
@ -211,18 +212,18 @@ const char* rc_parse_richpresence_lookup(rc_richpresence_lookup_t* lookup, const
else else
key = strtoul(&number[0], 0, 10); key = strtoul(&number[0], 0, 10);
item = RC_ALLOC(rc_richpresence_lookup_item_t, buffer, ret, scratch); item = RC_ALLOC(rc_richpresence_lookup_item_t, parse);
item->value = key; item->value = key;
item->label = rc_alloc_str(buffer, ret, line, endline - line); item->label = rc_alloc_str(parse, line, endline - line);
*next = item; *next = item;
next = &item->next_item; next = &item->next_item;
} }
} while (1); } while (1);
if (!defaultlabel) if (!defaultlabel)
defaultlabel = rc_alloc_str(buffer, ret, "", 0); defaultlabel = rc_alloc_str(parse, "", 0);
item = RC_ALLOC(rc_richpresence_lookup_item_t, buffer, ret, scratch); item = RC_ALLOC(rc_richpresence_lookup_item_t, parse);
item->value = 0; item->value = 0;
item->label = defaultlabel; item->label = defaultlabel;
item->next_item = 0; item->next_item = 0;
@ -231,10 +232,11 @@ const char* rc_parse_richpresence_lookup(rc_richpresence_lookup_t* lookup, const
return nextline; return nextline;
} }
void rc_parse_richpresence_internal(rc_richpresence_t* self, int* ret, void* buffer, void* scratch, const char* script, lua_State* L, int funcs_ndx) { void rc_parse_richpresence_internal(rc_richpresence_t* self, const char* script, rc_parse_state_t* parse) {
rc_richpresence_display_t** nextdisplay; rc_richpresence_display_t** nextdisplay;
rc_richpresence_lookup_t** nextlookup; rc_richpresence_lookup_t** nextlookup;
rc_richpresence_lookup_t* lookup; rc_richpresence_lookup_t* lookup;
rc_trigger_t* trigger;
char format[64]; char format[64];
const char* display = 0; const char* display = 0;
const char* line; const char* line;
@ -254,26 +256,26 @@ void rc_parse_richpresence_internal(rc_richpresence_t* self, int* ret, void* buf
if (strncmp(line, "Lookup:", 7) == 0) { if (strncmp(line, "Lookup:", 7) == 0) {
line += 7; line += 7;
lookup = RC_ALLOC(rc_richpresence_lookup_t, buffer, ret, scratch); lookup = RC_ALLOC(rc_richpresence_lookup_t, parse);
lookup->name = rc_alloc_str(buffer, ret, line, endline - line); lookup->name = rc_alloc_str(parse, line, endline - line);
lookup->format = RC_FORMAT_LOOKUP; lookup->format = RC_FORMAT_LOOKUP;
*nextlookup = lookup; *nextlookup = lookup;
nextlookup = &lookup->next; nextlookup = &lookup->next;
nextline = rc_parse_richpresence_lookup(lookup, nextline, ret, buffer, scratch, L, funcs_ndx); nextline = rc_parse_richpresence_lookup(lookup, nextline, parse);
} else if (strncmp(line, "Format:", 7) == 0) { } else if (strncmp(line, "Format:", 7) == 0) {
line += 7; line += 7;
lookup = RC_ALLOC(rc_richpresence_lookup_t, buffer, ret, scratch); lookup = RC_ALLOC(rc_richpresence_lookup_t, parse);
lookup->name = rc_alloc_str(buffer, ret, line, endline - line); lookup->name = rc_alloc_str(parse, line, endline - line);
lookup->first_item = 0; lookup->first_item = 0;
*nextlookup = lookup; *nextlookup = lookup;
nextlookup = &lookup->next; nextlookup = &lookup->next;
line = nextline; line = nextline;
nextline = rc_parse_line(line, &endline); nextline = rc_parse_line(line, &endline);
if (buffer && strncmp(line, "FormatType=", 11) == 0) { if (parse->buffer && strncmp(line, "FormatType=", 11) == 0) {
line += 11; line += 11;
chars = endline - line; chars = endline - line;
@ -313,11 +315,13 @@ void rc_parse_richpresence_internal(rc_richpresence_t* self, int* ret, void* buf
++ptr; ++ptr;
if (ptr < endline) { if (ptr < endline) {
*nextdisplay = rc_parse_richpresence_display_internal(buffer, ret, scratch, ptr + 1, endline, L, funcs_ndx, self); *nextdisplay = rc_parse_richpresence_display_internal(ptr + 1, endline, parse, self);
rc_parse_trigger_internal(&((*nextdisplay)->trigger), ret, buffer, scratch, &line, L, funcs_ndx); trigger = &((*nextdisplay)->trigger);
if (*ret < 0) rc_parse_trigger_internal(trigger, &line, parse);
trigger->memrefs = 0;
if (parse->offset < 0)
return; return;
if (buffer) if (parse->buffer)
nextdisplay = &((*nextdisplay)->next); nextdisplay = &((*nextdisplay)->next);
} }
@ -326,39 +330,45 @@ void rc_parse_richpresence_internal(rc_richpresence_t* self, int* ret, void* buf
} }
/* non-conditional display: string */ /* non-conditional display: string */
*nextdisplay = rc_parse_richpresence_display_internal(buffer, ret, scratch, line, endline, L, funcs_ndx, self); *nextdisplay = rc_parse_richpresence_display_internal(line, endline, parse, self);
hasdisplay = (*nextdisplay != NULL); if (*nextdisplay) {
if (buffer) hasdisplay = 1;
nextdisplay = &((*nextdisplay)->next); nextdisplay = &((*nextdisplay)->next);
}
} }
/* finalize */ /* finalize */
*nextdisplay = 0; *nextdisplay = 0;
if (!hasdisplay && ret > 0) if (!hasdisplay && parse->offset > 0) {
*ret = RC_MISSING_DISPLAY_STRING; parse->offset = RC_MISSING_DISPLAY_STRING;
}
} }
int rc_richpresence_size(const char* script) { int rc_richpresence_size(const char* script) {
int ret;
rc_richpresence_t* self; rc_richpresence_t* self;
rc_scratch_t scratch; rc_parse_state_t parse;
rc_init_parse_state(&parse, 0, 0, 0);
self = RC_ALLOC(rc_richpresence_t, &parse);
rc_parse_richpresence_internal(self, script, &parse);
ret = 0; rc_destroy_parse_state(&parse);
self = RC_ALLOC(rc_richpresence_t, 0, &ret, &scratch); return parse.offset;
rc_parse_richpresence_internal(self, &ret, 0, &scratch, script, 0, 0);
return ret;
} }
rc_richpresence_t* rc_parse_richpresence(void* buffer, const char* script, lua_State* L, int funcs_ndx) { rc_richpresence_t* rc_parse_richpresence(void* buffer, const char* script, lua_State* L, int funcs_ndx) {
int ret;
rc_richpresence_t* self; rc_richpresence_t* self;
rc_scratch_t scratch; rc_parse_state_t parse;
rc_init_parse_state(&parse, buffer, L, funcs_ndx);
ret = 0; self = RC_ALLOC(rc_richpresence_t, &parse);
self = RC_ALLOC(rc_richpresence_t, buffer, &ret, &scratch); rc_init_parse_state_memrefs(&parse, &self->memrefs);
rc_parse_richpresence_internal(self, &ret, buffer, 0, script, L, funcs_ndx);
return ret >= 0 ? self : 0; rc_parse_richpresence_internal(self, script, &parse);
rc_destroy_parse_state(&parse);
return parse.offset >= 0 ? self : 0;
} }
int rc_evaluate_richpresence(rc_richpresence_t* richpresence, char* buffer, unsigned buffersize, rc_peek_t peek, void* peek_ud, lua_State* L) { int rc_evaluate_richpresence(rc_richpresence_t* richpresence, char* buffer, unsigned buffersize, rc_peek_t peek, void* peek_ud, lua_State* L) {
@ -369,6 +379,8 @@ int rc_evaluate_richpresence(rc_richpresence_t* richpresence, char* buffer, unsi
int chars; int chars;
unsigned value; unsigned value;
rc_update_memref_values(richpresence->memrefs, peek, peek_ud);
ptr = buffer; ptr = buffer;
display = richpresence->first_display; display = richpresence->first_display;
while (display) { while (display) {

View File

@ -1,18 +1,19 @@
#include "internal.h" #include "internal.h"
rc_term_t* rc_parse_term(int* ret, void* buffer, rc_scratch_t* scratch, const char** memaddr, lua_State* L, int funcs_ndx) { rc_term_t* rc_parse_term(const char** memaddr, rc_parse_state_t* parse) {
rc_term_t* self; rc_term_t* self;
const char* aux; const char* aux;
char size;
int ret2; int ret2;
aux = *memaddr; aux = *memaddr;
self = RC_ALLOC(rc_term_t, buffer, ret, scratch); self = RC_ALLOC(rc_term_t, parse);
self->invert = 0; self->invert = 0;
ret2 = rc_parse_operand(&self->operand1, &aux, 0, L, funcs_ndx); ret2 = rc_parse_operand(&self->operand1, &aux, 0, parse);
if (ret2 < 0) { if (ret2 < 0) {
*ret = ret2; parse->offset = ret2;
return 0; return 0;
} }
@ -24,53 +25,63 @@ rc_term_t* rc_parse_term(int* ret, void* buffer, rc_scratch_t* scratch, const ch
self->invert = 1; self->invert = 1;
} }
ret2 = rc_parse_operand(&self->operand2, &aux, 0, L, funcs_ndx); ret2 = rc_parse_operand(&self->operand2, &aux, 0, parse);
if (ret2 < 0) { if (ret2 < 0) {
*ret = ret2; parse->offset = ret2;
return 0; return 0;
} }
if (self->invert) { if (self->invert) {
switch (self->operand2.size) { switch (self->operand2.type) {
case RC_OPERAND_BIT_0: case RC_OPERAND_ADDRESS:
case RC_OPERAND_BIT_1: case RC_OPERAND_DELTA:
case RC_OPERAND_BIT_2: case RC_OPERAND_PRIOR:
case RC_OPERAND_BIT_3: size = self->operand2.memref->memref.size;
case RC_OPERAND_BIT_4: break;
case RC_OPERAND_BIT_5: default:
case RC_OPERAND_BIT_6: size = RC_MEMSIZE_32_BITS;
case RC_OPERAND_BIT_7: break;
}
switch (size) {
case RC_MEMSIZE_BIT_0:
case RC_MEMSIZE_BIT_1:
case RC_MEMSIZE_BIT_2:
case RC_MEMSIZE_BIT_3:
case RC_MEMSIZE_BIT_4:
case RC_MEMSIZE_BIT_5:
case RC_MEMSIZE_BIT_6:
case RC_MEMSIZE_BIT_7:
/* invert is already 1 */ /* invert is already 1 */
break; break;
case RC_OPERAND_LOW: case RC_MEMSIZE_LOW:
case RC_OPERAND_HIGH: case RC_MEMSIZE_HIGH:
self->invert = 0xf; self->invert = 0xf;
break; break;
case RC_OPERAND_8_BITS: case RC_MEMSIZE_8_BITS:
self->invert = 0xffU; self->invert = 0xffU;
break; break;
case RC_OPERAND_16_BITS: case RC_MEMSIZE_16_BITS:
self->invert = 0xffffU; self->invert = 0xffffU;
break; break;
case RC_OPERAND_24_BITS: case RC_MEMSIZE_24_BITS:
self->invert = 0xffffffU; self->invert = 0xffffffU;
break; break;
case RC_OPERAND_32_BITS: case RC_MEMSIZE_32_BITS:
self->invert = 0xffffffffU; self->invert = 0xffffffffU;
break; break;
} }
} }
} }
else { else {
self->operand2.type = RC_OPERAND_FP; self->operand2.type = RC_OPERAND_CONST;
self->operand2.size = RC_OPERAND_8_BITS; self->operand2.value = 1;
self->operand2.fp_value = 1.0;
} }
*memaddr = aux; *memaddr = aux;
@ -84,5 +95,5 @@ unsigned rc_evaluate_term(rc_term_t* self, rc_peek_t peek, void* ud, lua_State*
return value * (rc_evaluate_operand(&self->operand2, peek, ud, L) ^ self->invert); return value * (rc_evaluate_operand(&self->operand2, peek, ud, L) ^ self->invert);
} }
return (unsigned)(value * self->operand2.fp_value); return (unsigned)((double)value * self->operand2.fp_value);
} }

View File

@ -2,7 +2,7 @@
#include <stddef.h> #include <stddef.h>
void rc_parse_trigger_internal(rc_trigger_t* self, int* ret, void* buffer, rc_scratch_t* scratch, const char** memaddr, lua_State* L, int funcs_ndx) { void rc_parse_trigger_internal(rc_trigger_t* self, const char** memaddr, rc_parse_state_t* parse) {
rc_condset_t** next; rc_condset_t** next;
const char* aux; const char* aux;
@ -13,9 +13,9 @@ void rc_parse_trigger_internal(rc_trigger_t* self, int* ret, void* buffer, rc_sc
self->requirement = 0; self->requirement = 0;
} }
else { else {
self->requirement = rc_parse_condset(ret, buffer, scratch, &aux, L, funcs_ndx); self->requirement = rc_parse_condset(&aux, parse);
if (*ret < 0) { if (parse->offset < 0) {
return; return;
} }
@ -24,9 +24,9 @@ void rc_parse_trigger_internal(rc_trigger_t* self, int* ret, void* buffer, rc_sc
while (*aux == 's' || *aux == 'S') { while (*aux == 's' || *aux == 'S') {
aux++; aux++;
*next = rc_parse_condset(ret, buffer, scratch, &aux, L, funcs_ndx); *next = rc_parse_condset(&aux, parse);
if (*ret < 0) { if (parse->offset < 0) {
return; return;
} }
@ -38,31 +38,37 @@ void rc_parse_trigger_internal(rc_trigger_t* self, int* ret, void* buffer, rc_sc
} }
int rc_trigger_size(const char* memaddr) { int rc_trigger_size(const char* memaddr) {
int ret;
rc_trigger_t* self; rc_trigger_t* self;
rc_scratch_t scratch; rc_parse_state_t parse;
rc_init_parse_state(&parse, 0, 0, 0);
ret = 0; self = RC_ALLOC(rc_trigger_t, &parse);
self = RC_ALLOC(rc_trigger_t, 0, &ret, &scratch); rc_parse_trigger_internal(self, &memaddr, &parse);
rc_parse_trigger_internal(self, &ret, 0, &scratch, &memaddr, 0, 0);
return ret; rc_destroy_parse_state(&parse);
return parse.offset;
} }
rc_trigger_t* rc_parse_trigger(void* buffer, const char* memaddr, lua_State* L, int funcs_ndx) { rc_trigger_t* rc_parse_trigger(void* buffer, const char* memaddr, lua_State* L, int funcs_ndx) {
int ret;
rc_trigger_t* self; rc_trigger_t* self;
rc_scratch_t scratch; rc_parse_state_t parse;
rc_init_parse_state(&parse, buffer, L, funcs_ndx);
ret = 0; self = RC_ALLOC(rc_trigger_t, &parse);
self = RC_ALLOC(rc_trigger_t, buffer, &ret, &scratch); rc_init_parse_state_memrefs(&parse, &self->memrefs);
rc_parse_trigger_internal(self, &ret, buffer, 0, &memaddr, L, funcs_ndx);
return ret >= 0 ? self : 0; rc_parse_trigger_internal(self, &memaddr, &parse);
rc_destroy_parse_state(&parse);
return parse.offset >= 0 ? self : 0;
} }
int rc_test_trigger(rc_trigger_t* self, rc_peek_t peek, void* ud, lua_State* L) { int rc_test_trigger(rc_trigger_t* self, rc_peek_t peek, void* ud, lua_State* L) {
int ret, reset; int ret, reset;
rc_condset_t* condset; rc_condset_t* condset;
rc_update_memref_values(self->memrefs, peek, ud);
reset = 0; reset = 0;
ret = self->requirement != 0 ? rc_test_condset(self->requirement, &reset, peek, ud, L) : 1; ret = self->requirement != 0 ? rc_test_condset(self->requirement, &reset, peek, ud, L) : 1;
condset = self->alternative; condset = self->alternative;

View File

@ -1,14 +1,14 @@
#include "internal.h" #include "internal.h"
void rc_parse_value_internal(rc_value_t* self, int* ret, void* buffer, void* scratch, const char** memaddr, lua_State* L, int funcs_ndx) { void rc_parse_value_internal(rc_value_t* self, const char** memaddr, rc_parse_state_t* parse) {
rc_expression_t** next; rc_expression_t** next;
next = &self->expressions; next = &self->expressions;
for (;;) { for (;;) {
*next = rc_parse_expression(ret, buffer, scratch, memaddr, L, funcs_ndx); *next = rc_parse_expression(memaddr, parse);
if (*ret < 0) { if (parse->offset < 0) {
return; return;
} }
@ -25,31 +25,37 @@ void rc_parse_value_internal(rc_value_t* self, int* ret, void* buffer, void* scr
} }
int rc_value_size(const char* memaddr) { int rc_value_size(const char* memaddr) {
int ret;
rc_value_t* self; rc_value_t* self;
rc_scratch_t scratch; rc_parse_state_t parse;
rc_init_parse_state(&parse, 0, 0, 0);
ret = 0; self = RC_ALLOC(rc_value_t, &parse);
self = RC_ALLOC(rc_value_t, 0, &ret, &scratch); rc_parse_value_internal(self, &memaddr, &parse);
rc_parse_value_internal(self, &ret, 0, &scratch, &memaddr, 0, 0);
return ret; rc_destroy_parse_state(&parse);
return parse.offset;
} }
rc_value_t* rc_parse_value(void* buffer, const char* memaddr, lua_State* L, int funcs_ndx) { rc_value_t* rc_parse_value(void* buffer, const char* memaddr, lua_State* L, int funcs_ndx) {
int ret;
rc_value_t* self; rc_value_t* self;
rc_scratch_t scratch; rc_parse_state_t parse;
rc_init_parse_state(&parse, buffer, L, funcs_ndx);
ret = 0; self = RC_ALLOC(rc_value_t, &parse);
self = RC_ALLOC(rc_value_t, buffer, &ret, &scratch); rc_init_parse_state_memrefs(&parse, &self->memrefs);
rc_parse_value_internal(self, &ret, buffer, 0, &memaddr, L, funcs_ndx);
return ret >= 0 ? self : 0; rc_parse_value_internal(self, &memaddr, &parse);
rc_destroy_parse_state(&parse);
return parse.offset >= 0 ? self : 0;
} }
unsigned rc_evaluate_value(rc_value_t* self, rc_peek_t peek, void* ud, lua_State* L) { unsigned rc_evaluate_value(rc_value_t* self, rc_peek_t peek, void* ud, lua_State* L) {
rc_expression_t* exp; rc_expression_t* exp;
unsigned value, max; unsigned value, max;
rc_update_memref_values(self->memrefs, peek, ud);
exp = self->expressions; exp = self->expressions;
max = rc_evaluate_expression(exp, peek, ud, L); max = rc_evaluate_expression(exp, peek, ud, L);

View File

@ -178,6 +178,8 @@ ACHIEVEMENTS
#include "../deps/rcheevos/src/rcheevos/term.c" #include "../deps/rcheevos/src/rcheevos/term.c"
#include "../deps/rcheevos/src/rcheevos/trigger.c" #include "../deps/rcheevos/src/rcheevos/trigger.c"
#include "../deps/rcheevos/src/rcheevos/value.c" #include "../deps/rcheevos/src/rcheevos/value.c"
#include "../deps/rcheevos/src/rcheevos/memref.c"
#include "../deps/rcheevos/src/rcheevos/richpresence.c"
#include "../deps/rcheevos/src/rurl/url.c" #include "../deps/rcheevos/src/rurl/url.c"
#endif #endif