Skip to content

Commit

Permalink
prevent double transform of memref chain (#392)
Browse files Browse the repository at this point in the history
  • Loading branch information
Jamiras authored Jan 18, 2025
1 parent 3a91a58 commit 08999e0
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 2 deletions.
21 changes: 19 additions & 2 deletions src/rcheevos/operand.c
Original file line number Diff line number Diff line change
Expand Up @@ -465,6 +465,17 @@ int rc_operand_type_is_memref(uint8_t type) {
}
}

int rc_operand_type_is_transform(uint8_t type) {
switch (type) {
case RC_OPERAND_BCD:
case RC_OPERAND_INVERTED:
return 1;

default:
return 0;
}
}

int rc_operand_is_memref(const rc_operand_t* self) {
return rc_operand_type_is_memref(self->type);
}
Expand Down Expand Up @@ -603,9 +614,15 @@ void rc_operand_addsource(rc_operand_t* self, rc_parse_state_t* parse, uint8_t n

self->value.memref = (rc_memref_t*)modified_memref;

/* if adding a constant, change the type to be address (current value) */
if (!rc_operand_is_memref(self))
if (!rc_operand_is_memref(self)) {
/* if adding a constant, change the type to be address (current value) */
self->type = self->memref_access_type = RC_OPERAND_ADDRESS;
}
else if (rc_operand_type_is_transform(self->type)) {
/* transform is applied in the modified_memref. change the type to be
* address (current value) to avoid applying the transform again */
self->type = self->memref_access_type = RC_OPERAND_ADDRESS;
}

/* result of an AddSource operation is always a 32-bit integer (even if parent or modifier is a float) */
self->size = RC_MEMSIZE_32_BITS;
Expand Down
1 change: 1 addition & 0 deletions src/rcheevos/rc_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,7 @@ int rc_operand_is_float_memref(const rc_operand_t* self);
int rc_operand_is_float(const rc_operand_t* self);
int rc_operand_is_recall(const rc_operand_t* self);
int rc_operand_type_is_memref(uint8_t type);
int rc_operand_type_is_transform(uint8_t type);
int rc_operands_are_equal(const rc_operand_t* left, const rc_operand_t* right);
void rc_operand_addsource(rc_operand_t* self, rc_parse_state_t* parse, uint8_t new_size);
void rc_operand_set_const(rc_operand_t* self, uint32_t value);
Expand Down
62 changes: 62 additions & 0 deletions test/rcheevos/test_condset.c
Original file line number Diff line number Diff line change
Expand Up @@ -2657,6 +2657,66 @@ static void test_addsource_bits_change() {
assert_hit_count(condset, 5, 2);
}

static void test_addsource_bcd() {
uint8_t ram[] = { 0x00, 0x12, 0x34, 0xAB, 0x56 };
memory_t memory;
rc_condset_t* condset;
rc_memrefs_t memrefs;
char buffer[2048];

memory.ram = ram;
memory.size = sizeof(ram);

/* bcd(byte(0)) * 100 + bcd(byte(1)) > 4990 */
assert_parse_condset(&condset, &memrefs, buffer, "A:b0xH0000*100_b0xH0001>4990");

/* 0*100+12 = 12 */
assert_evaluate_condset(condset, memrefs, &memory, 0);

/* 49*100+89 = 4989 */
ram[0] = 0x49;
ram[1] = 0x89;
assert_evaluate_condset(condset, memrefs, &memory, 0);

/* 49*100+99 = 4999 */
ram[1] = 0x99;
assert_evaluate_condset(condset, memrefs, &memory, 1);

/* 50*100+00 = 5000 */
ram[0] = 0x50;
ram[1] = 0x00;
assert_evaluate_condset(condset, memrefs, &memory, 1);
}

static void test_addsource_invert() {
uint8_t ram[] = { 0x00, 0x12, 0x34, 0xAB, 0x56 };
memory_t memory;
rc_condset_t* condset;
rc_memrefs_t memrefs;
char buffer[2048];

memory.ram = ram;
memory.size = sizeof(ram);

/* ~low4(0) + ~high4(0) > 20 */
assert_parse_condset(&condset, &memrefs, buffer, "A:~0xL0000_~0xU0000>20");

/* ~0 (F) + ~0 (F) = 1E */
assert_evaluate_condset(condset, memrefs, &memory, 1);

/* ~4 (B) + ~9 (6) = 11 */
ram[0] = 0x49;
assert_evaluate_condset(condset, memrefs, &memory, 0);

/* ~9 (6) + ~9 (6) = 0C */
ram[1] = 0x99;
assert_evaluate_condset(condset, memrefs, &memory, 0);

/* ~5 (A) + ~1 (E) = 18 */
ram[0] = 0x51;
assert_evaluate_condset(condset, memrefs, &memory, 1);
}

static void test_addhits() {
uint8_t ram[] = {0x00, 0x12, 0x34, 0xAB, 0x56};
memory_t memory;
Expand Down Expand Up @@ -4519,6 +4579,8 @@ void test_condset(void) {
TEST(test_subsource_overflow_comparison_lesser_or_equal);
TEST(test_subsource_float);
TEST(test_addsource_bits_change);
TEST(test_addsource_bcd);
TEST(test_addsource_invert);

/* addhits/subhits */
TEST(test_addhits);
Expand Down
1 change: 1 addition & 0 deletions test/rcheevos/test_rc_validate.c
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,7 @@ void test_redundant_conditions() {
TEST_PARAMS2(test_validate_trigger, "0xH0000<5_0xH0000<3", "Condition 1: Redundant with Condition 2");
TEST_PARAMS2(test_validate_trigger, "0xH0000=1S0xH0000=1", "Alt1 Condition 1: Redundant with Core Condition 1");
TEST_PARAMS2(test_validate_trigger, "R:0xH0000=1_0xH0000!=1", "Condition 2: Redundant with Condition 1");
TEST_PARAMS2(test_validate_trigger, "R:0xH0000!=1_0xH0000!=0", "Condition 2: Redundant with Condition 1"); /* condition 1 effectively 0xH0000=1 */
TEST_PARAMS2(test_validate_trigger, "R:0xH0000=1_0xH0000=2", "");
TEST_PARAMS2(test_validate_trigger, "R:0xH0000=1_T:0xH0000=2", "");
TEST_PARAMS2(test_validate_trigger, "0xH0000=1_R:0xH0000!=1", "Condition 1: Redundant with Condition 2");
Expand Down

0 comments on commit 08999e0

Please sign in to comment.