Skip to content

Commit

Permalink
Add Addition and Subtraction Operators (#342)
Browse files Browse the repository at this point in the history
  • Loading branch information
redwizard42 authored May 22, 2024
1 parent d62d26d commit 47b0bcd
Show file tree
Hide file tree
Showing 8 changed files with 67 additions and 1 deletion.
4 changes: 3 additions & 1 deletion include/rc_runtime_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,9 @@ enum {
RC_OPERATOR_DIV,
RC_OPERATOR_AND,
RC_OPERATOR_XOR,
RC_OPERATOR_MOD
RC_OPERATOR_MOD,
RC_OPERATOR_ADD,
RC_OPERATOR_SUB
};

typedef struct rc_condition_t rc_condition_t;
Expand Down
19 changes: 19 additions & 0 deletions src/rcheevos/condition.c
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,14 @@ static int rc_parse_operator(const char** memaddr) {
++(*memaddr);
return RC_OPERATOR_MOD;

case '+':
++(*memaddr);
return RC_OPERATOR_ADD;

case '-':
++(*memaddr);
return RC_OPERATOR_SUB;

case '\0':/* end of string */
case '_': /* next condition */
case 'S': /* next condset */
Expand Down Expand Up @@ -231,6 +239,8 @@ rc_condition_t* rc_parse_condition(const char** memaddr, rc_parse_state_t* parse
case RC_OPERATOR_AND:
case RC_OPERATOR_XOR:
case RC_OPERATOR_MOD:
case RC_OPERATOR_ADD:
case RC_OPERATOR_SUB:
/* modifying operators are only valid on modifying statements */
if (can_modify)
break;
Expand Down Expand Up @@ -560,5 +570,14 @@ void rc_evaluate_condition_value(rc_typed_value_t* value, rc_condition_t* self,
case RC_OPERATOR_MOD:
rc_typed_value_modulus(value, &amount);
break;

case RC_OPERATOR_ADD:
rc_typed_value_add(value, &amount);
break;

case RC_OPERATOR_SUB:
rc_typed_value_negate(&amount);
rc_typed_value_add(value, &amount);
break;
}
}
2 changes: 2 additions & 0 deletions src/rcheevos/condset.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ rc_condset_t* rc_parse_condset(const char** memaddr, rc_parse_state_t* parse, in
case RC_OPERATOR_DIV:
case RC_OPERATOR_MULT:
case RC_OPERATOR_MOD:
case RC_OPERATOR_ADD:
case RC_OPERATOR_SUB:
case RC_OPERATOR_NONE:
/* measuring value. leave required_hits at 0 */
break;
Expand Down
19 changes: 19 additions & 0 deletions src/rcheevos/rc_validate.c
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,25 @@ static uint32_t rc_scale_value(uint32_t value, uint8_t oper, const rc_operand_t*
return (divisor >= value) ? (divisor - 1) : value;
}

case RC_OPERATOR_ADD:
{
unsigned long scaled = ((unsigned long)value) + rc_max_value(operand);
if (scaled > 0xFFFFFFFF)
return 0xFFFFFFFF;

return (uint32_t)scaled;
}

case RC_OPERATOR_SUB:
{
if (operand->type == RC_OPERAND_CONST)
return value - operand->value.num;
else if (value > rc_max_value(operand))
return value - rc_max_value(operand);

return 0xFFFFFFFF;
}

default:
return value;
}
Expand Down
2 changes: 2 additions & 0 deletions src/rcheevos/value.c
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,8 @@ void rc_parse_legacy_value(rc_value_t* self, const char** memaddr, rc_parse_stat
case RC_OPERATOR_AND:
case RC_OPERATOR_XOR:
case RC_OPERATOR_MOD:
case RC_OPERATOR_ADD:
case RC_OPERATOR_SUB:
case RC_OPERATOR_NONE:
break;

Expand Down
2 changes: 2 additions & 0 deletions test/rcheevos/test_condition.c
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,8 @@ void test_condition(void) {
TEST_PARAMS5(test_parse_condition, "A:0xH1234&8", RC_CONDITION_ADD_SOURCE, RC_OPERAND_ADDRESS, RC_OPERATOR_AND, 0);
TEST_PARAMS5(test_parse_condition, "A:0xH1234^8", RC_CONDITION_ADD_SOURCE, RC_OPERAND_ADDRESS, RC_OPERATOR_XOR, 0);
TEST_PARAMS5(test_parse_condition, "A:0xH1234%8", RC_CONDITION_ADD_SOURCE, RC_OPERAND_ADDRESS, RC_OPERATOR_MOD, 0);
TEST_PARAMS5(test_parse_condition, "A:0xH1234+8", RC_CONDITION_ADD_SOURCE, RC_OPERAND_ADDRESS, RC_OPERATOR_ADD, 0);
TEST_PARAMS5(test_parse_condition, "A:0xH1234-8", RC_CONDITION_ADD_SOURCE, RC_OPERAND_ADDRESS, RC_OPERATOR_SUB, 0);

TEST_PARAMS4(test_parse_modifier, "A:0xH1234", RC_OPERATOR_NONE, RC_OPERAND_CONST, 1);
TEST_PARAMS4(test_parse_modifier, "A:0xH1234*1", RC_OPERATOR_MULT, RC_OPERAND_CONST, 1);
Expand Down
18 changes: 18 additions & 0 deletions test/rcheevos/test_value.c
Original file line number Diff line number Diff line change
Expand Up @@ -646,12 +646,30 @@ void test_value(void) {
TEST_PARAMS2(test_evaluate_value, "A:f123.7%f5.65_M:0", 5) /* 123.7 % 5.65 = 5.05 -> 5 */
TEST_PARAMS2(test_evaluate_value, "A:0xH01%f7.5_A:0xH02%f5.5_M:0", 5); /* 18%7.3 = 3.4, 52%5.5=2.5, becomes 3+2=5*/

/* addition */
TEST_PARAMS2(test_evaluate_value, "A:0xH0001+3_M:0", 21); /* 18+3 = 21 */
TEST_PARAMS2(test_evaluate_value, "A:0xH0002+0xH0001_M:0", 70); /* 52+18 = 70 */
TEST_PARAMS2(test_evaluate_value, "A:fF5+f2_M:0", 5) /* PI + 2.0 = 5.141592 -> 5 */
TEST_PARAMS2(test_evaluate_value, "A:f5.5+f2.0_M:0", 7) /* 5.5 + 2.0 = 7.5 -> 7 */
TEST_PARAMS2(test_evaluate_value, "A:f5.5+f2.7_M:0", 8) /* 5.5 + 2.7 = 8.2 -> 8 */
TEST_PARAMS2(test_evaluate_value, "B:0xH0001+3_M:100", 79) /* 100 - (18+3) = 79 */
TEST_PARAMS2(test_evaluate_value, "I:0xH0000+3_M:0x0", 0x56AB) /* Add Address (0+3) -> Offset 0. 16-Bit Read @ Byte 3 = 0x56AB */

/* subtraction */
TEST_PARAMS2(test_evaluate_value, "A:0xH0001-3_M:0", 15); /* 18-3 = 15 */
TEST_PARAMS2(test_evaluate_value, "A:0xH0002-0xH0001_M:0", 34); /* 52-18 = 34 */
TEST_PARAMS2(test_evaluate_value, "A:fF5-f2_M:0", 1) /* PI - 2.0 = 1.141592 -> 1 */
TEST_PARAMS2(test_evaluate_value, "A:f5.5-f2.0_M:0", 3) /* 5.5 - 2.0 = 2.5 -> 3 */
TEST_PARAMS2(test_evaluate_value, "A:f5.5-f2.7_M:0", 2) /* 5.5 - 2.7 = 2.8 -> 2 */
TEST_PARAMS2(test_evaluate_value, "B:0xH0001-3_M:100",85) /* 100 - (18-3) = 85 */

/* rounding */
TEST_PARAMS2(test_evaluate_value, "0xH03/2_0xH03/2", 0xAA); /* integer division results in rounding */
TEST_PARAMS2(test_evaluate_value, "0xH03/f2.0_0xH03/f2.0", 0xAB); /* float division does not result in rounding */
TEST_PARAMS2(test_evaluate_value, "0xH03*0.5_0xH03*0.5", 0xAB); /* float multiplication does not result in rounding */
TEST_PARAMS2(test_evaluate_value, "A:0xH03/2_A:0xH03/2_M:0", 0xAA); /* integer division results in rounding */
TEST_PARAMS2(test_evaluate_value, "A:0xH03/f2.0_A:0xH03/f2.0_M:0", 0xAB); /* float division does not result in rounding */
TEST_PARAMS2(test_evaluate_value, "I:0xH0001-17_M:0x0", 0x3412) /* Add Address (18-17) -> Offset 0. 16-Bit Read @ Byte 1 = 0x3412 */

/* using measured_if */
TEST_PARAMS2(test_evaluate_value, "Q:0xH0001!=0_M:0xH0002", 0x34);
Expand Down
2 changes: 2 additions & 0 deletions validator/validator.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ static const char* operator_string(char oper) {
case RC_OPERATOR_MULT: return "*";
case RC_OPERATOR_DIV: return "/";
case RC_OPERATOR_MOD: return "%";
case RC_OPERATOR_ADD: return "+";
case RC_OPERATOR_SUB: return "-";
case RC_OPERATOR_EQ: return "=";
case RC_OPERATOR_NE: return "!=";
case RC_OPERATOR_GE: return ">=";
Expand Down

0 comments on commit 47b0bcd

Please sign in to comment.