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/alloc.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
ifeq ($(HAVE_LUA), 1)

View File

@ -30,7 +30,8 @@ enum {
RC_MISSING_SUBMIT = -15,
RC_MISSING_VALUE = -16,
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);
/*****************************************************************************\
| Operands |
| Memory References |
\*****************************************************************************/
/* Sizes. */
enum {
RC_OPERAND_BIT_0,
RC_OPERAND_BIT_1,
RC_OPERAND_BIT_2,
RC_OPERAND_BIT_3,
RC_OPERAND_BIT_4,
RC_OPERAND_BIT_5,
RC_OPERAND_BIT_6,
RC_OPERAND_BIT_7,
RC_OPERAND_LOW,
RC_OPERAND_HIGH,
RC_OPERAND_8_BITS,
RC_OPERAND_16_BITS,
RC_OPERAND_24_BITS,
RC_OPERAND_32_BITS
RC_MEMSIZE_BIT_0,
RC_MEMSIZE_BIT_1,
RC_MEMSIZE_BIT_2,
RC_MEMSIZE_BIT_3,
RC_MEMSIZE_BIT_4,
RC_MEMSIZE_BIT_5,
RC_MEMSIZE_BIT_6,
RC_MEMSIZE_BIT_7,
RC_MEMSIZE_LOW,
RC_MEMSIZE_HIGH,
RC_MEMSIZE_8_BITS,
RC_MEMSIZE_16_BITS,
RC_MEMSIZE_24_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 */
enum {
RC_OPERAND_ADDRESS, /* Compare to the value of a live address in RAM. */
@ -117,20 +148,10 @@ enum {
typedef struct {
union {
/* A value read from memory. */
struct {
/* 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;
rc_memref_value_t* memref;
/* The size of the variable. */
char size;
/* True if the value is in BCD. */
char is_bcd;
/* The type of the variable. */
};
/* A value. */
unsigned value;
/* A floating point value. */
double fp_value;
@ -171,9 +192,6 @@ enum {
typedef struct rc_condition_t rc_condition_t;
struct rc_condition_t {
/* The next condition in the chain. */
rc_condition_t* next;
/* The condition's operands. */
rc_operand_t operand1;
rc_operand_t operand2;
@ -183,6 +201,9 @@ struct rc_condition_t {
/* Number of hits so far. */
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"
* pass
@ -222,6 +243,9 @@ typedef struct {
/* The list of sub condition sets in this test. */
rc_condset_t* alternative;
/* The memory references required by the trigger. */
rc_memref_value_t* memrefs;
}
rc_trigger_t;
@ -262,6 +286,9 @@ struct rc_expression_t {
typedef struct {
/* The list of expression to evaluate. */
rc_expression_t* expressions;
/* The memory references required by the value. */
rc_memref_value_t* memrefs;
}
rc_value_t;
@ -288,6 +315,7 @@ typedef struct {
rc_trigger_t cancel;
rc_value_t value;
rc_value_t* progress;
rc_memref_value_t* memrefs;
char started;
char submitted;
@ -358,6 +386,7 @@ struct rc_richpresence_display_t {
typedef struct {
rc_richpresence_display_t* first_display;
rc_richpresence_lookup_t* first_lookup;
rc_memref_value_t* memrefs;
}
rc_richpresence_t;

View File

@ -1,6 +1,7 @@
#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* ptr;
@ -10,18 +11,21 @@ void* rc_alloc(void* pointer, int* offset, int size, int alignment, rc_scratch_t
if (pointer != 0) {
ptr = (void*)((char*)pointer + *offset);
}
else if (scratch != 0) {
ptr = &scratch->obj;
}
else {
ptr = scratch;
ptr = 0;
}
*offset += size;
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;
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) {
memcpy(ptr, text, length);
ptr[length] = '\0';
@ -29,3 +33,21 @@ char* rc_alloc_str(void* pointer, int* offset, const char* text, int length) {
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>
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;
const char* aux;
int ret2;
aux = *memaddr;
self = RC_ALLOC(rc_condition_t, buffer, ret, scratch);
self = RC_ALLOC(rc_condition_t, parse);
self->current_hits = 0;
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 'c': case 'C': self->type = RC_CONDITION_ADD_HITS; 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;
@ -28,10 +28,10 @@ rc_condition_t* rc_parse_condition(int* ret, void* buffer, rc_scratch_t* scratch
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) {
*ret = ret2;
parse->offset = ret2;
return 0;
}
@ -45,7 +45,7 @@ rc_condition_t* rc_parse_condition(int* ret, void* buffer, rc_scratch_t* scratch
if (*aux++ != '=') {
/* fall through */
default:
*ret = RC_INVALID_OPERATOR;
parse->offset = RC_INVALID_OPERATOR;
return 0;
}
@ -73,10 +73,10 @@ rc_condition_t* rc_parse_condition(int* ret, void* buffer, rc_scratch_t* scratch
break;
}
ret2 = rc_parse_operand(&self->operand2, &aux, 1, L, funcs_ndx);
ret2 = rc_parse_operand(&self->operand2, &aux, 1, parse);
if (ret2 < 0) {
*ret = ret2;
parse->offset = ret2;
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);
if (end == aux || *end != ')') {
*ret = RC_INVALID_REQUIRED_HITS;
parse->offset = RC_INVALID_REQUIRED_HITS;
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);
if (end == aux || *end != '.') {
*ret = RC_INVALID_REQUIRED_HITS;
parse->offset = RC_INVALID_REQUIRED_HITS;
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_condition_t** next;
int in_pause;
self = RC_ALLOC(rc_condset_t, buffer, ret, scratch);
self = RC_ALLOC(rc_condset_t, parse);
self->has_pause = 0;
next = &self->conditions;
for (;;) {
*next = rc_parse_condition(ret, buffer, scratch, memaddr, L, funcs_ndx);
if (**memaddr == 'S' || **memaddr == 's' || !**memaddr) {
/* 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;
}
@ -52,7 +58,7 @@ rc_condset_t* rc_parse_condset(int* ret, void* buffer, rc_scratch_t* scratch, co
*next = 0;
if (buffer != 0) {
if (parse->buffer != 0) {
in_pause = 0;
rc_update_condition_pause(self->conditions, &in_pause);
}

View File

@ -1,16 +1,16 @@
#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_term_t** next;
self = RC_ALLOC(rc_expression_t, buffer, ret, scratch);
self = RC_ALLOC(rc_expression_t, parse);
next = &self->terms;
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;
}

View File

@ -8,50 +8,78 @@
#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_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 {
rc_operand_t operand;
rc_condition_t condition;
rc_condset_t condset;
rc_trigger_t trigger;
rc_term_t term;
rc_expression_t expression;
rc_lboard_t lboard;
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;
typedef struct {
rc_memref_t memref_buffer[16];
rc_memref_t *memref;
int memref_count;
int memref_size;
union
{
rc_operand_t operand;
rc_condition_t condition;
rc_condset_t condset;
rc_trigger_t trigger;
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;
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);
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);
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_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);
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);
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);
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, 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);
#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
};
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;
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[2] == 'a' || memaddr[2] == 'A') && memaddr[3] == ':') {
if ((found & RC_LBOARD_START) != 0) {
*ret = RC_DUPLICATED_START;
parse->offset = RC_DUPLICATED_START;
return;
}
found |= RC_LBOARD_START;
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;
}
}
@ -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[2] == 'n' || memaddr[2] == 'N') && memaddr[3] == ':') {
if ((found & RC_LBOARD_CANCEL) != 0) {
*ret = RC_DUPLICATED_CANCEL;
parse->offset = RC_DUPLICATED_CANCEL;
return;
}
found |= RC_LBOARD_CANCEL;
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;
}
}
@ -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[2] == 'b' || memaddr[2] == 'B') && memaddr[3] == ':') {
if ((found & RC_LBOARD_SUBMIT) != 0) {
*ret = RC_DUPLICATED_SUBMIT;
parse->offset = RC_DUPLICATED_SUBMIT;
return;
}
found |= RC_LBOARD_SUBMIT;
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;
}
}
@ -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[2] == 'l' || memaddr[2] == 'L') && memaddr[3] == ':') {
if ((found & RC_LBOARD_VALUE) != 0) {
*ret = RC_DUPLICATED_VALUE;
parse->offset = RC_DUPLICATED_VALUE;
return;
}
found |= RC_LBOARD_VALUE;
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;
}
}
@ -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[2] == 'o' || memaddr[2] == 'O') && memaddr[3] == ':') {
if ((found & RC_LBOARD_PROGRESS) != 0) {
*ret = RC_DUPLICATED_PROGRESS;
parse->offset = RC_DUPLICATED_PROGRESS;
return;
}
found |= RC_LBOARD_PROGRESS;
memaddr += 4;
self->progress = RC_ALLOC(rc_value_t, buffer, ret, scratch);
rc_parse_value_internal(self->progress, ret, buffer, scratch, &memaddr, L, funcs_ndx);
self->progress = RC_ALLOC(rc_value_t, parse);
rc_parse_value_internal(self->progress, &memaddr, parse);
self->progress->memrefs = 0;
if (*ret < 0) {
if (parse->offset < 0) {
return;
}
}
else {
*ret = RC_INVALID_LBOARD_FIELD;
parse->offset = RC_INVALID_LBOARD_FIELD;
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_START) == 0) {
*ret = RC_MISSING_START;
parse->offset = RC_MISSING_START;
}
else if ((found & RC_LBOARD_CANCEL) == 0) {
*ret = RC_MISSING_CANCEL;
parse->offset = RC_MISSING_CANCEL;
}
else if ((found & RC_LBOARD_SUBMIT) == 0) {
*ret = RC_MISSING_SUBMIT;
parse->offset = RC_MISSING_SUBMIT;
}
else if ((found & RC_LBOARD_VALUE) == 0) {
*ret = RC_MISSING_VALUE;
parse->offset = RC_MISSING_VALUE;
}
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 ret;
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, 0, &ret, &scratch);
rc_parse_lboard_internal(self, &ret, 0, &scratch, memaddr, 0, 0);
return ret;
self = RC_ALLOC(rc_lboard_t, &parse);
rc_parse_lboard_internal(self, memaddr, &parse);
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) {
int ret;
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, buffer, &ret, &scratch);
rc_parse_lboard_internal(self, &ret, buffer, 0, memaddr, L, funcs_ndx);
return ret >= 0 ? self : 0;
self = RC_ALLOC(rc_lboard_t, &parse);
rc_init_parse_state_memrefs(&parse, &self->memrefs);
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 start_ok, cancel_ok, submit_ok;
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 */
start_ok = rc_test_trigger(&self->start, 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 <ctype.h>
#include <math.h>
#ifndef RC_DISABLE_LUA
@ -18,7 +19,7 @@ extern "C" {
#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* id;
@ -38,20 +39,20 @@ static int rc_parse_operand_lua(rc_operand_t* self, const char** memaddr, lua_St
#ifndef RC_DISABLE_LUA
if (L != 0) {
if (!lua_istable(L, funcs_ndx)) {
if (parse->L != 0) {
if (!lua_istable(parse->L, parse->funcs_ndx)) {
return RC_INVALID_LUA_OPERAND;
}
lua_pushlstring(L, id, aux - id);
lua_gettable(L, funcs_ndx);
lua_pushlstring(parse->L, id, aux - id);
lua_gettable(parse->L, parse->funcs_ndx);
if (!lua_isfunction(L, -1)) {
lua_pop(L, 1);
if (!lua_isfunction(parse->L, -1)) {
lua_pop(parse->L, 1);
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 */
@ -61,10 +62,12 @@ static int rc_parse_operand_lua(rc_operand_t* self, const char** memaddr, lua_St
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;
char* end;
unsigned long value;
unsigned long address;
char is_bcd = 0;
char size;
switch (*aux++) {
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':
self->type = RC_OPERAND_ADDRESS;
self->is_bcd = 1;
is_bcd = 1;
break;
case 'p': case 'P':
@ -97,44 +100,46 @@ static int rc_parse_operand_memory(rc_operand_t* self, const char** memaddr) {
aux++;
switch (*aux++) {
case 'm': case 'M': self->size = RC_OPERAND_BIT_0; break;
case 'n': case 'N': self->size = RC_OPERAND_BIT_1; break;
case 'o': case 'O': self->size = RC_OPERAND_BIT_2; break;
case 'p': case 'P': self->size = RC_OPERAND_BIT_3; break;
case 'q': case 'Q': self->size = RC_OPERAND_BIT_4; break;
case 'r': case 'R': self->size = RC_OPERAND_BIT_5; break;
case 's': case 'S': self->size = RC_OPERAND_BIT_6; break;
case 't': case 'T': self->size = RC_OPERAND_BIT_7; break;
case 'l': case 'L': self->size = RC_OPERAND_LOW; break;
case 'u': case 'U': self->size = RC_OPERAND_HIGH; break;
case 'h': case 'H': self->size = RC_OPERAND_8_BITS; break;
case 'w': case 'W': self->size = RC_OPERAND_24_BITS; break;
case 'x': case 'X': self->size = RC_OPERAND_32_BITS; break;
case 'm': case 'M': size = RC_MEMSIZE_BIT_0; break;
case 'n': case 'N': size = RC_MEMSIZE_BIT_1; break;
case 'o': case 'O': size = RC_MEMSIZE_BIT_2; break;
case 'p': case 'P': size = RC_MEMSIZE_BIT_3; break;
case 'q': case 'Q': size = RC_MEMSIZE_BIT_4; break;
case 'r': case 'R': size = RC_MEMSIZE_BIT_5; break;
case 's': case 'S': size = RC_MEMSIZE_BIT_6; break;
case 't': case 'T': size = RC_MEMSIZE_BIT_7; break;
case 'l': case 'L': size = RC_MEMSIZE_LOW; break;
case 'u': case 'U': size = RC_MEMSIZE_HIGH; break;
case 'h': case 'H': size = RC_MEMSIZE_8_BITS; break;
case 'w': case 'W': size = RC_MEMSIZE_24_BITS; break;
case 'x': case 'X': size = RC_MEMSIZE_32_BITS; break;
default: /* fall through */
aux--;
case ' ':
self->size = RC_OPERAND_16_BITS;
size = RC_MEMSIZE_16_BITS;
break;
}
value = strtoul(aux, &end, 16);
address = strtoul(aux, &end, 16);
if (end == aux) {
return RC_INVALID_MEMORY_OPERAND;
}
if (value > 0xffffffffU) {
value = 0xffffffffU;
if (address > 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;
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;
char* end;
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') {
/* fall through */
default:
ret = rc_parse_operand_memory(self, &aux);
ret = rc_parse_operand_memory(self, &aux, parse);
if (ret < 0) {
return ret;
@ -192,7 +197,7 @@ static int rc_parse_operand_trigger(rc_operand_t* self, const char** memaddr, lu
break;
case '@':
ret = rc_parse_operand_lua(self, &aux, L, funcs_ndx);
ret = rc_parse_operand_lua(self, &aux, parse);
if (ret < 0) {
return ret;
@ -205,7 +210,7 @@ static int rc_parse_operand_trigger(rc_operand_t* self, const char** memaddr, lu
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;
char* end;
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') {
/* fall through */
default:
ret = rc_parse_operand_memory(self, &aux);
ret = rc_parse_operand_memory(self, &aux, parse);
if (ret < 0) {
return ret;
@ -264,18 +269,24 @@ static int rc_parse_operand_term(rc_operand_t* self, const char** memaddr, lua_S
case '+': case '-':
case '1': case '2': case '3': case '4': case '5':
case '6': case '7': case '8': case '9':
self->type = RC_OPERAND_FP;
self->fp_value = strtod(aux, &end);
if (end == aux) {
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;
break;
case '@':
ret = rc_parse_operand_lua(self, &aux, L, funcs_ndx);
ret = rc_parse_operand_lua(self, &aux, parse);
if (ret < 0) {
return ret;
@ -288,17 +299,12 @@ static int rc_parse_operand_term(rc_operand_t* self, const char** memaddr, lua_S
return RC_OK;
}
int rc_parse_operand(rc_operand_t* self, const char** memaddr, int is_trigger, lua_State* L, int funcs_ndx) {
self->size = RC_OPERAND_8_BITS;
self->is_bcd = 0;
self->previous = 0;
self->prior = 0;
int rc_parse_operand(rc_operand_t* self, const char** memaddr, int is_trigger, rc_parse_state_t* parse) {
if (is_trigger) {
return rc_parse_operand_trigger(self, memaddr, L, funcs_ndx);
return rc_parse_operand_trigger(self, memaddr, parse);
}
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;
case RC_OPERAND_ADDRESS:
value = self->memref->value;
break;
case RC_OPERAND_DELTA:
value = self->memref->previous;
break;
case RC_OPERAND_PRIOR:
switch (self->size) {
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;
}
value = self->memref->prior;
break;
}

View File

@ -11,7 +11,7 @@ enum {
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* endline;
@ -42,7 +42,7 @@ const char* rc_parse_line(const char* line, const char** end) {
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_part_t* part;
rc_richpresence_display_part_t** next;
@ -55,7 +55,7 @@ rc_richpresence_display_t* rc_parse_richpresence_display_internal(void* buffer,
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));
next = &self->display;
}
@ -71,14 +71,14 @@ rc_richpresence_display_t* rc_parse_richpresence_display_internal(void* buffer,
}
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));
*next = part;
next = &part->next;
/* handle string part */
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) {
/* remove backslashes used for escaping */
in = part->text;
@ -104,16 +104,16 @@ rc_richpresence_display_t* rc_parse_richpresence_display_internal(void* buffer,
++ptr;
if (ptr > line) {
if (!buffer) {
if (!parse->buffer) {
/* 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;
while (ptr < endline && *ptr != ')')
++ptr;
if (*ptr == ')') {
rc_parse_value_internal(&part->value, ret, buffer, scratch, &line, L, funcs_ndx);
if (ret < 0)
rc_parse_value_internal(&part->value, &line, parse);
if (parse->offset < 0)
return 0;
++ptr;
}
@ -123,7 +123,7 @@ rc_richpresence_display_t* rc_parse_richpresence_display_internal(void* buffer,
lookup = richpresence->first_lookup;
while (lookup) {
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;
@ -135,8 +135,9 @@ rc_richpresence_display_t* rc_parse_richpresence_display_internal(void* buffer,
while (ptr < endline && *ptr != ')')
++ptr;
if (*ptr == ')') {
rc_parse_value_internal(&part->value, ret, buffer, scratch, &line, L, funcs_ndx);
if (ret < 0)
rc_parse_value_internal(&part->value, &line, parse);
part->value.memrefs = 0;
if (parse->offset < 0)
return 0;
++ptr;
}
@ -148,7 +149,7 @@ rc_richpresence_display_t* rc_parse_richpresence_display_internal(void* buffer,
}
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));
*next = part;
next = &part->next;
@ -156,7 +157,7 @@ rc_richpresence_display_t* rc_parse_richpresence_display_internal(void* buffer,
ptr = line;
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;
}
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* item;
@ -202,7 +203,7 @@ const char* rc_parse_richpresence_lookup(rc_richpresence_lookup_t* lookup, const
line += chars + 1;
if (chars == 1 && number[0] == '*') {
defaultlabel = rc_alloc_str(buffer, ret, line, endline - line);
defaultlabel = rc_alloc_str(parse, line, endline - line);
continue;
}
@ -211,18 +212,18 @@ const char* rc_parse_richpresence_lookup(rc_richpresence_lookup_t* lookup, const
else
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->label = rc_alloc_str(buffer, ret, line, endline - line);
item->label = rc_alloc_str(parse, line, endline - line);
*next = item;
next = &item->next_item;
}
} while (1);
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->label = defaultlabel;
item->next_item = 0;
@ -231,10 +232,11 @@ const char* rc_parse_richpresence_lookup(rc_richpresence_lookup_t* lookup, const
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_lookup_t** nextlookup;
rc_richpresence_lookup_t* lookup;
rc_trigger_t* trigger;
char format[64];
const char* display = 0;
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) {
line += 7;
lookup = RC_ALLOC(rc_richpresence_lookup_t, buffer, ret, scratch);
lookup->name = rc_alloc_str(buffer, ret, line, endline - line);
lookup = RC_ALLOC(rc_richpresence_lookup_t, parse);
lookup->name = rc_alloc_str(parse, line, endline - line);
lookup->format = RC_FORMAT_LOOKUP;
*nextlookup = lookup;
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) {
line += 7;
lookup = RC_ALLOC(rc_richpresence_lookup_t, buffer, ret, scratch);
lookup->name = rc_alloc_str(buffer, ret, line, endline - line);
lookup = RC_ALLOC(rc_richpresence_lookup_t, parse);
lookup->name = rc_alloc_str(parse, line, endline - line);
lookup->first_item = 0;
*nextlookup = lookup;
nextlookup = &lookup->next;
line = nextline;
nextline = rc_parse_line(line, &endline);
if (buffer && strncmp(line, "FormatType=", 11) == 0) {
if (parse->buffer && strncmp(line, "FormatType=", 11) == 0) {
line += 11;
chars = endline - line;
@ -313,11 +315,13 @@ void rc_parse_richpresence_internal(rc_richpresence_t* self, int* ret, void* buf
++ptr;
if (ptr < endline) {
*nextdisplay = rc_parse_richpresence_display_internal(buffer, ret, scratch, ptr + 1, endline, L, funcs_ndx, self);
rc_parse_trigger_internal(&((*nextdisplay)->trigger), ret, buffer, scratch, &line, L, funcs_ndx);
if (*ret < 0)
*nextdisplay = rc_parse_richpresence_display_internal(ptr + 1, endline, parse, self);
trigger = &((*nextdisplay)->trigger);
rc_parse_trigger_internal(trigger, &line, parse);
trigger->memrefs = 0;
if (parse->offset < 0)
return;
if (buffer)
if (parse->buffer)
nextdisplay = &((*nextdisplay)->next);
}
@ -326,39 +330,45 @@ void rc_parse_richpresence_internal(rc_richpresence_t* self, int* ret, void* buf
}
/* non-conditional display: string */
*nextdisplay = rc_parse_richpresence_display_internal(buffer, ret, scratch, line, endline, L, funcs_ndx, self);
hasdisplay = (*nextdisplay != NULL);
if (buffer)
*nextdisplay = rc_parse_richpresence_display_internal(line, endline, parse, self);
if (*nextdisplay) {
hasdisplay = 1;
nextdisplay = &((*nextdisplay)->next);
}
}
/* finalize */
*nextdisplay = 0;
if (!hasdisplay && ret > 0)
*ret = RC_MISSING_DISPLAY_STRING;
if (!hasdisplay && parse->offset > 0) {
parse->offset = RC_MISSING_DISPLAY_STRING;
}
}
int rc_richpresence_size(const char* script) {
int ret;
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;
self = RC_ALLOC(rc_richpresence_t, 0, &ret, &scratch);
rc_parse_richpresence_internal(self, &ret, 0, &scratch, script, 0, 0);
return ret;
rc_destroy_parse_state(&parse);
return parse.offset;
}
rc_richpresence_t* rc_parse_richpresence(void* buffer, const char* script, lua_State* L, int funcs_ndx) {
int ret;
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, buffer, &ret, &scratch);
rc_parse_richpresence_internal(self, &ret, buffer, 0, script, L, funcs_ndx);
return ret >= 0 ? self : 0;
self = RC_ALLOC(rc_richpresence_t, &parse);
rc_init_parse_state_memrefs(&parse, &self->memrefs);
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) {
@ -369,6 +379,8 @@ int rc_evaluate_richpresence(rc_richpresence_t* richpresence, char* buffer, unsi
int chars;
unsigned value;
rc_update_memref_values(richpresence->memrefs, peek, peek_ud);
ptr = buffer;
display = richpresence->first_display;
while (display) {

View File

@ -1,18 +1,19 @@
#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;
const char* aux;
char size;
int ret2;
aux = *memaddr;
self = RC_ALLOC(rc_term_t, buffer, ret, scratch);
self = RC_ALLOC(rc_term_t, parse);
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) {
*ret = ret2;
parse->offset = ret2;
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;
}
ret2 = rc_parse_operand(&self->operand2, &aux, 0, L, funcs_ndx);
ret2 = rc_parse_operand(&self->operand2, &aux, 0, parse);
if (ret2 < 0) {
*ret = ret2;
parse->offset = ret2;
return 0;
}
if (self->invert) {
switch (self->operand2.size) {
case RC_OPERAND_BIT_0:
case RC_OPERAND_BIT_1:
case RC_OPERAND_BIT_2:
case RC_OPERAND_BIT_3:
case RC_OPERAND_BIT_4:
case RC_OPERAND_BIT_5:
case RC_OPERAND_BIT_6:
case RC_OPERAND_BIT_7:
switch (self->operand2.type) {
case RC_OPERAND_ADDRESS:
case RC_OPERAND_DELTA:
case RC_OPERAND_PRIOR:
size = self->operand2.memref->memref.size;
break;
default:
size = RC_MEMSIZE_32_BITS;
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 */
break;
case RC_OPERAND_LOW:
case RC_OPERAND_HIGH:
case RC_MEMSIZE_LOW:
case RC_MEMSIZE_HIGH:
self->invert = 0xf;
break;
case RC_OPERAND_8_BITS:
case RC_MEMSIZE_8_BITS:
self->invert = 0xffU;
break;
case RC_OPERAND_16_BITS:
case RC_MEMSIZE_16_BITS:
self->invert = 0xffffU;
break;
case RC_OPERAND_24_BITS:
case RC_MEMSIZE_24_BITS:
self->invert = 0xffffffU;
break;
case RC_OPERAND_32_BITS:
case RC_MEMSIZE_32_BITS:
self->invert = 0xffffffffU;
break;
}
}
}
else {
self->operand2.type = RC_OPERAND_FP;
self->operand2.size = RC_OPERAND_8_BITS;
self->operand2.fp_value = 1.0;
self->operand2.type = RC_OPERAND_CONST;
self->operand2.value = 1;
}
*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 (unsigned)(value * self->operand2.fp_value);
return (unsigned)((double)value * self->operand2.fp_value);
}

View File

@ -2,7 +2,7 @@
#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;
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;
}
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;
}
@ -24,9 +24,9 @@ void rc_parse_trigger_internal(rc_trigger_t* self, int* ret, void* buffer, rc_sc
while (*aux == 's' || *aux == 'S') {
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;
}
@ -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 ret;
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, 0, &ret, &scratch);
rc_parse_trigger_internal(self, &ret, 0, &scratch, &memaddr, 0, 0);
return ret;
self = RC_ALLOC(rc_trigger_t, &parse);
rc_parse_trigger_internal(self, &memaddr, &parse);
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) {
int ret;
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, buffer, &ret, &scratch);
rc_parse_trigger_internal(self, &ret, buffer, 0, &memaddr, L, funcs_ndx);
return ret >= 0 ? self : 0;
self = RC_ALLOC(rc_trigger_t, &parse);
rc_init_parse_state_memrefs(&parse, &self->memrefs);
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 ret, reset;
rc_condset_t* condset;
rc_update_memref_values(self->memrefs, peek, ud);
reset = 0;
ret = self->requirement != 0 ? rc_test_condset(self->requirement, &reset, peek, ud, L) : 1;
condset = self->alternative;

View File

@ -1,14 +1,14 @@
#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;
next = &self->expressions;
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;
}
@ -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 ret;
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, 0, &ret, &scratch);
rc_parse_value_internal(self, &ret, 0, &scratch, &memaddr, 0, 0);
return ret;
self = RC_ALLOC(rc_value_t, &parse);
rc_parse_value_internal(self, &memaddr, &parse);
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) {
int ret;
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, buffer, &ret, &scratch);
rc_parse_value_internal(self, &ret, buffer, 0, &memaddr, L, funcs_ndx);
return ret >= 0 ? self : 0;
self = RC_ALLOC(rc_value_t, &parse);
rc_init_parse_state_memrefs(&parse, &self->memrefs);
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) {
rc_expression_t* exp;
unsigned value, max;
rc_update_memref_values(self->memrefs, peek, ud);
exp = self->expressions;
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/trigger.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"
#endif