Skip to content

Commit

Permalink
add rc_modified_memref_t (#362)
Browse files Browse the repository at this point in the history
  • Loading branch information
Jamiras authored Oct 26, 2024
1 parent 51fee2d commit ed684fc
Show file tree
Hide file tree
Showing 27 changed files with 1,790 additions and 494 deletions.
27 changes: 15 additions & 12 deletions include/rc_runtime_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,15 +70,14 @@ typedef struct rc_memref_value_t {
/* The last differing value of this memory reference. */
uint32_t prior;

/* The size of the value. */
/* The size of the value. (RC_MEMSIZE_*) */
uint8_t size;
/* True if the value changed this frame. */
uint8_t changed;
/* The value type of the value (for variables) */
/* The value type of the value. (RC_VALUE_TYPE_*) */
uint8_t type;
/* True if the reference will be used in indirection.
* NOTE: This is actually a property of the rc_memref_t, but we put it here to save space */
uint8_t is_indirect;
/* The type of memref (RC_MEMREF_TYPE_*) */
uint8_t memref_type;
}
rc_memref_value_t;

Expand All @@ -93,6 +92,7 @@ struct rc_memref_t {
rc_memref_t* next;
};


/*****************************************************************************\
| Operands |
\*****************************************************************************/
Expand Down Expand Up @@ -125,11 +125,14 @@ typedef struct rc_operand_t {
int luafunc;
} value;

/* specifies which member of the value union is being used */
/* specifies which member of the value union is being used (RC_OPERAND_*) */
uint8_t type;

/* the actual RC_MEMSIZE of the operand - memref.size may differ */
/* the RC_MEMSIZE of the operand specified in the condition definition - memref.size may differ */
uint8_t size;

/* specifies how to read the memref for some types (RC_OPERAND_*) */
uint8_t memref_access_type;
}
rc_operand_t;

Expand Down Expand Up @@ -180,7 +183,10 @@ enum {
RC_OPERATOR_XOR,
RC_OPERATOR_MOD,
RC_OPERATOR_ADD,
RC_OPERATOR_SUB
RC_OPERATOR_SUB,

RC_OPERATOR_SUB_PARENT, /* internal use */
RC_OPERATOR_INDIRECT_READ /* internal use */
};

typedef struct rc_condition_t rc_condition_t;
Expand Down Expand Up @@ -224,17 +230,14 @@ struct rc_condset_t {
/* The next condition set in the chain. */
rc_condset_t* next;

/* The list of conditions in this condition set. */
/* The first condition in this condition set. Then follow ->next chain. */
rc_condition_t* conditions;

/* True if any condition in the set is a pause condition. */
uint8_t has_pause;

/* True if the set is currently paused. */
uint8_t is_paused;

/* True if the set has indirect memory references. */
uint8_t has_indirect_memrefs;
};

/*****************************************************************************\
Expand Down
31 changes: 20 additions & 11 deletions src/rc_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -1068,7 +1068,7 @@ static void rc_client_validate_addresses(rc_client_game_info_t* game, rc_client_
rc_memref_t** last_memref = &game->runtime.memrefs;
rc_memref_t* memref = game->runtime.memrefs;
for (; memref; memref = memref->next) {
if (!memref->value.is_indirect) {
if (memref->value.memref_type == RC_MEMREF_TYPE_MEMREF) {
total_count++;

if (memref->address > max_address ||
Expand Down Expand Up @@ -4913,19 +4913,28 @@ static void rc_client_update_memref_values(rc_client_t* client)
int invalidated_memref = 0;

for (; memref; memref = memref->next) {
if (memref->value.is_indirect)
continue;
switch (memref->value.memref_type) {
case RC_MEMREF_TYPE_MEMREF:
/* if processing_memref is set, and the memory read fails, all dependent achievements will be disabled */
client->state.processing_memref = memref;

client->state.processing_memref = memref;
value = rc_peek_value(memref->address, memref->value.size, client->state.legacy_peek, client);

value = rc_peek_value(memref->address, memref->value.size, client->state.legacy_peek, client);
if (client->state.processing_memref) {
rc_update_memref_value(&memref->value, value);
}
else {
/* if the peek function cleared the processing_memref, the memref was invalidated */
invalidated_memref = 1;
}
break;

if (client->state.processing_memref) {
rc_update_memref_value(&memref->value, value);
}
else {
/* if the peek function cleared the processing_memref, the memref was invalidated */
invalidated_memref = 1;
case RC_MEMREF_TYPE_MODIFIED_MEMREF:
/* clear processing_memref so an invalid read doesn't disable anything */
client->state.processing_memref = NULL;
rc_update_memref_value(&memref->value,
rc_get_modified_memref_value((rc_modified_memref_t*)memref, client->state.legacy_peek, client));
break;
}
}

Expand Down
8 changes: 6 additions & 2 deletions src/rcheevos/alloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,10 +104,14 @@ void rc_init_parse_state(rc_parse_state_t* parse, void* buffer, lua_State* L, in
parse->scratch.strings = NULL;
rc_buffer_init(&parse->scratch.buffer);
memset(&parse->scratch.objs, 0, sizeof(parse->scratch.objs));
parse->first_memref = 0;
parse->variables = 0;
parse->first_memref = NULL;
parse->variables = NULL;
parse->measured_target = 0;
parse->lines_read = 0;
parse->addsource_parent.type = RC_OPERAND_NONE;
parse->indirect_parent.type = RC_OPERAND_NONE;
parse->remember.type = RC_OPERAND_NONE;
parse->is_value = 0;
parse->has_required_hits = 0;
parse->measured_as_percent = 0;
}
Expand Down
Loading

0 comments on commit ed684fc

Please sign in to comment.