1 #ifndef RC_RUNTIME_TYPES_H 2 #define RC_RUNTIME_TYPES_H 3 4 #ifdef __cplusplus 5 extern "C" { 6 #endif 7 8 #include "rc_error.h" 9 10 #ifndef RC_RUNTIME_H /* prevents pedantic redefiniton error */ 11 12 typedef struct lua_State lua_State; 13 14 typedef struct rc_trigger_t rc_trigger_t; 15 typedef struct rc_lboard_t rc_lboard_t; 16 typedef struct rc_richpresence_t rc_richpresence_t; 17 typedef struct rc_memref_t rc_memref_t; 18 typedef struct rc_value_t rc_value_t; 19 20 #endif 21 22 /*****************************************************************************\ 23 | Callbacks | 24 \*****************************************************************************/ 25 26 /** 27 * Callback used to read num_bytes bytes from memory starting at address. If 28 * num_bytes is greater than 1, the value is read in little-endian from 29 * memory. 30 */ 31 typedef unsigned (*rc_peek_t)(unsigned address, unsigned num_bytes, void* ud); 32 33 /*****************************************************************************\ 34 | Memory References | 35 \*****************************************************************************/ 36 37 /* Sizes. */ 38 enum { 39 RC_MEMSIZE_8_BITS, 40 RC_MEMSIZE_16_BITS, 41 RC_MEMSIZE_24_BITS, 42 RC_MEMSIZE_32_BITS, 43 RC_MEMSIZE_LOW, 44 RC_MEMSIZE_HIGH, 45 RC_MEMSIZE_BIT_0, 46 RC_MEMSIZE_BIT_1, 47 RC_MEMSIZE_BIT_2, 48 RC_MEMSIZE_BIT_3, 49 RC_MEMSIZE_BIT_4, 50 RC_MEMSIZE_BIT_5, 51 RC_MEMSIZE_BIT_6, 52 RC_MEMSIZE_BIT_7, 53 RC_MEMSIZE_BITCOUNT, 54 RC_MEMSIZE_VARIABLE 55 }; 56 57 typedef struct rc_memref_value_t { 58 /* The current value of this memory reference. */ 59 unsigned value; 60 /* The last differing value of this memory reference. */ 61 unsigned prior; 62 63 /* The size of the value. */ 64 char size; 65 /* True if the value changed this frame. */ 66 char changed; 67 /* True if the reference will be used in indirection. 68 * NOTE: This is actually a property of the rc_memref_t, but we put it here to save space */ 69 char is_indirect; 70 } 71 rc_memref_value_t; 72 73 struct rc_memref_t { 74 /* The current value at the specified memory address. */ 75 rc_memref_value_t value; 76 77 /* The memory address of this variable. */ 78 unsigned address; 79 80 /* The next memory reference in the chain. */ 81 rc_memref_t* next; 82 }; 83 84 /*****************************************************************************\ 85 | Operands | 86 \*****************************************************************************/ 87 88 /* types */ 89 enum { 90 RC_OPERAND_ADDRESS, /* The value of a live address in RAM. */ 91 RC_OPERAND_DELTA, /* The value last known at this address. */ 92 RC_OPERAND_CONST, /* A 32-bit unsigned integer. */ 93 RC_OPERAND_FP, /* A floating point value. */ 94 RC_OPERAND_LUA, /* A Lua function that provides the value. */ 95 RC_OPERAND_PRIOR, /* The last differing value at this address. */ 96 RC_OPERAND_BCD, /* The BCD-decoded value of a live address in RAM. */ 97 RC_OPERAND_INVERTED /* The twos-complement value of a live address in RAM. */ 98 }; 99 100 typedef struct rc_operand_t { 101 union { 102 /* A value read from memory. */ 103 rc_memref_t* memref; 104 105 /* An integer value. */ 106 unsigned num; 107 108 /* A floating point value. */ 109 double dbl; 110 111 /* A reference to the Lua function that provides the value. */ 112 int luafunc; 113 } value; 114 115 /* specifies which member of the value union is being used */ 116 char type; 117 118 /* the actual RC_MEMSIZE of the operand - memref.size may differ */ 119 char size; 120 } 121 rc_operand_t; 122 123 int rc_operand_is_memref(rc_operand_t* operand); 124 125 /*****************************************************************************\ 126 | Conditions | 127 \*****************************************************************************/ 128 129 /* types */ 130 enum { 131 /* NOTE: this enum is ordered to optimize the switch statements in rc_test_condset_internal. the values may change between releases */ 132 133 /* non-combining conditions (third switch) */ 134 RC_CONDITION_STANDARD, /* this should always be 0 */ 135 RC_CONDITION_PAUSE_IF, 136 RC_CONDITION_RESET_IF, 137 RC_CONDITION_MEASURED_IF, 138 RC_CONDITION_TRIGGER, 139 RC_CONDITION_MEASURED, /* measured also appears in the first switch, so place it at the border between them */ 140 141 /* modifiers (first switch) */ 142 RC_CONDITION_ADD_SOURCE, /* everything from this point on affects the condition after it */ 143 RC_CONDITION_SUB_SOURCE, 144 RC_CONDITION_ADD_ADDRESS, 145 146 /* logic flags (second switch) */ 147 RC_CONDITION_ADD_HITS, 148 RC_CONDITION_SUB_HITS, 149 RC_CONDITION_RESET_NEXT_IF, 150 RC_CONDITION_AND_NEXT, 151 RC_CONDITION_OR_NEXT 152 }; 153 154 /* operators */ 155 enum { 156 RC_OPERATOR_EQ, 157 RC_OPERATOR_LT, 158 RC_OPERATOR_LE, 159 RC_OPERATOR_GT, 160 RC_OPERATOR_GE, 161 RC_OPERATOR_NE, 162 RC_OPERATOR_NONE, 163 RC_OPERATOR_MULT, 164 RC_OPERATOR_DIV, 165 RC_OPERATOR_AND 166 }; 167 168 typedef struct rc_condition_t rc_condition_t; 169 170 struct rc_condition_t { 171 /* The condition's operands. */ 172 rc_operand_t operand1; 173 rc_operand_t operand2; 174 175 /* Required hits to fire this condition. */ 176 unsigned required_hits; 177 /* Number of hits so far. */ 178 unsigned current_hits; 179 180 /* The next condition in the chain. */ 181 rc_condition_t* next; 182 183 /* The type of the condition. */ 184 char type; 185 186 /* The comparison operator to use. */ 187 char oper; /* operator is a reserved word in C++. */ 188 189 /* Set if the condition needs to processed as part of the "check if paused" pass. */ 190 char pause; 191 192 /* Whether or not the condition evaluated true on the last check */ 193 char is_true; 194 }; 195 196 /*****************************************************************************\ 197 | Condition sets | 198 \*****************************************************************************/ 199 200 typedef struct rc_condset_t rc_condset_t; 201 202 struct rc_condset_t { 203 /* The next condition set in the chain. */ 204 rc_condset_t* next; 205 206 /* The list of conditions in this condition set. */ 207 rc_condition_t* conditions; 208 209 /* True if any condition in the set is a pause condition. */ 210 char has_pause; 211 212 /* True if the set is currently paused. */ 213 char is_paused; 214 215 /* True if the set has indirect memory references. */ 216 char has_indirect_memrefs; 217 }; 218 219 /*****************************************************************************\ 220 | Trigger | 221 \*****************************************************************************/ 222 223 enum { 224 RC_TRIGGER_STATE_INACTIVE, /* achievement is not being processed */ 225 RC_TRIGGER_STATE_WAITING, /* achievement cannot trigger until it has been false for at least one frame */ 226 RC_TRIGGER_STATE_ACTIVE, /* achievement is active and may trigger */ 227 RC_TRIGGER_STATE_PAUSED, /* achievement is currently paused and will not trigger */ 228 RC_TRIGGER_STATE_RESET, /* achievement hit counts were reset */ 229 RC_TRIGGER_STATE_TRIGGERED, /* achievement has triggered */ 230 RC_TRIGGER_STATE_PRIMED, /* all non-Trigger conditions are true */ 231 RC_TRIGGER_STATE_DISABLED /* achievement cannot be processed at this time */ 232 }; 233 234 struct rc_trigger_t { 235 /* The main condition set. */ 236 rc_condset_t* requirement; 237 238 /* The list of sub condition sets in this test. */ 239 rc_condset_t* alternative; 240 241 /* The memory references required by the trigger. */ 242 rc_memref_t* memrefs; 243 244 /* The current state of the MEASURED condition. */ 245 unsigned measured_value; 246 247 /* The target state of the MEASURED condition */ 248 unsigned measured_target; 249 250 /* The current state of the trigger */ 251 char state; 252 253 /* True if at least one condition has a non-zero hit count */ 254 char has_hits; 255 256 /* True if at least one condition has a non-zero required hit count */ 257 char has_required_hits; 258 }; 259 260 int rc_trigger_size(const char* memaddr); 261 rc_trigger_t* rc_parse_trigger(void* buffer, const char* memaddr, lua_State* L, int funcs_ndx); 262 int rc_evaluate_trigger(rc_trigger_t* trigger, rc_peek_t peek, void* ud, lua_State* L); 263 int rc_test_trigger(rc_trigger_t* trigger, rc_peek_t peek, void* ud, lua_State* L); 264 void rc_reset_trigger(rc_trigger_t* self); 265 266 /*****************************************************************************\ 267 | Values | 268 \*****************************************************************************/ 269 270 struct rc_value_t { 271 /* The current value of the variable. */ 272 rc_memref_value_t value; 273 274 /* The list of conditions to evaluate. */ 275 rc_condset_t* conditions; 276 277 /* The memory references required by the value. */ 278 rc_memref_t* memrefs; 279 280 /* The name of the variable. */ 281 const char* name; 282 283 /* The next variable in the chain. */ 284 rc_value_t* next; 285 }; 286 287 int rc_value_size(const char* memaddr); 288 rc_value_t* rc_parse_value(void* buffer, const char* memaddr, lua_State* L, int funcs_ndx); 289 int rc_evaluate_value(rc_value_t* value, rc_peek_t peek, void* ud, lua_State* L); 290 291 /*****************************************************************************\ 292 | Leaderboards | 293 \*****************************************************************************/ 294 295 /* Return values for rc_evaluate_lboard. */ 296 enum { 297 RC_LBOARD_STATE_INACTIVE, /* leaderboard is not being processed */ 298 RC_LBOARD_STATE_WAITING, /* leaderboard cannot activate until the start condition has been false for at least one frame */ 299 RC_LBOARD_STATE_ACTIVE, /* leaderboard is active and may start */ 300 RC_LBOARD_STATE_STARTED, /* leaderboard attempt in progress */ 301 RC_LBOARD_STATE_CANCELED, /* leaderboard attempt canceled */ 302 RC_LBOARD_STATE_TRIGGERED, /* leaderboard attempt complete, value should be submitted */ 303 RC_LBOARD_STATE_DISABLED /* leaderboard cannot be processed at this time */ 304 }; 305 306 struct rc_lboard_t { 307 rc_trigger_t start; 308 rc_trigger_t submit; 309 rc_trigger_t cancel; 310 rc_value_t value; 311 rc_value_t* progress; 312 rc_memref_t* memrefs; 313 314 char state; 315 }; 316 317 int rc_lboard_size(const char* memaddr); 318 rc_lboard_t* rc_parse_lboard(void* buffer, const char* memaddr, lua_State* L, int funcs_ndx); 319 int rc_evaluate_lboard(rc_lboard_t* lboard, int* value, rc_peek_t peek, void* peek_ud, lua_State* L); 320 void rc_reset_lboard(rc_lboard_t* lboard); 321 322 /*****************************************************************************\ 323 | Value formatting | 324 \*****************************************************************************/ 325 326 /* Supported formats. */ 327 enum { 328 RC_FORMAT_FRAMES, 329 RC_FORMAT_SECONDS, 330 RC_FORMAT_CENTISECS, 331 RC_FORMAT_SCORE, 332 RC_FORMAT_VALUE, 333 RC_FORMAT_MINUTES, 334 RC_FORMAT_SECONDS_AS_MINUTES 335 }; 336 337 int rc_parse_format(const char* format_str); 338 int rc_format_value(char* buffer, int size, int value, int format); 339 340 /*****************************************************************************\ 341 | Rich Presence | 342 \*****************************************************************************/ 343 344 typedef struct rc_richpresence_lookup_item_t rc_richpresence_lookup_item_t; 345 346 struct rc_richpresence_lookup_item_t { 347 unsigned first; 348 unsigned last; 349 rc_richpresence_lookup_item_t* left; 350 rc_richpresence_lookup_item_t* right; 351 const char* label; 352 }; 353 354 typedef struct rc_richpresence_lookup_t rc_richpresence_lookup_t; 355 356 struct rc_richpresence_lookup_t { 357 rc_richpresence_lookup_item_t* root; 358 rc_richpresence_lookup_t* next; 359 const char* name; 360 const char* default_label; 361 unsigned short format; 362 }; 363 364 typedef struct rc_richpresence_display_part_t rc_richpresence_display_part_t; 365 366 struct rc_richpresence_display_part_t { 367 rc_richpresence_display_part_t* next; 368 const char* text; 369 rc_richpresence_lookup_t* lookup; 370 rc_memref_value_t *value; 371 unsigned short display_type; 372 }; 373 374 typedef struct rc_richpresence_display_t rc_richpresence_display_t; 375 376 struct rc_richpresence_display_t { 377 rc_trigger_t trigger; 378 rc_richpresence_display_t* next; 379 rc_richpresence_display_part_t* display; 380 }; 381 382 struct rc_richpresence_t { 383 rc_richpresence_display_t* first_display; 384 rc_richpresence_lookup_t* first_lookup; 385 rc_memref_t* memrefs; 386 rc_value_t* variables; 387 }; 388 389 int rc_richpresence_size(const char* script); 390 int rc_richpresence_size_lines(const char* script, int* lines_read); 391 rc_richpresence_t* rc_parse_richpresence(void* buffer, const char* script, lua_State* L, int funcs_ndx); 392 int rc_evaluate_richpresence(rc_richpresence_t* richpresence, char* buffer, unsigned buffersize, rc_peek_t peek, void* peek_ud, lua_State* L); 393 void rc_update_richpresence(rc_richpresence_t* richpresence, rc_peek_t peek, void* peek_ud, lua_State* L); 394 int rc_get_richpresence_display_string(rc_richpresence_t* richpresence, char* buffer, unsigned buffersize, rc_peek_t peek, void* peek_ud, lua_State* L); 395 396 #ifdef __cplusplus 397 } 398 #endif 399 400 #endif /* RC_RUNTIME_TYPES_H */ 401