1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286
|
/* RetroArch - A frontend for libretro.
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
* Copyright (C) 2011-2017 - Daniel De Matteis
*
* RetroArch is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with RetroArch.
* If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __CHEAT_MANAGER_H
#define __CHEAT_MANAGER_H
#include <boolean.h>
#include <retro_common_api.h>
#include "../setting_list.h"
RETRO_BEGIN_DECLS
enum cheat_handler_type
{
CHEAT_HANDLER_TYPE_EMU = 0,
CHEAT_HANDLER_TYPE_RETRO,
CHEAT_HANDLER_TYPE_END
};
enum cheat_type
{
CHEAT_TYPE_DISABLED = 0,
CHEAT_TYPE_SET_TO_VALUE,
CHEAT_TYPE_INCREASE_VALUE,
CHEAT_TYPE_DECREASE_VALUE,
CHEAT_TYPE_RUN_NEXT_IF_EQ,
CHEAT_TYPE_RUN_NEXT_IF_NEQ,
CHEAT_TYPE_RUN_NEXT_IF_LT,
CHEAT_TYPE_RUN_NEXT_IF_GT
};
enum cheat_search_type
{
CHEAT_SEARCH_TYPE_EXACT = 0,
CHEAT_SEARCH_TYPE_LT,
CHEAT_SEARCH_TYPE_LTE,
CHEAT_SEARCH_TYPE_GT,
CHEAT_SEARCH_TYPE_GTE,
CHEAT_SEARCH_TYPE_EQ,
CHEAT_SEARCH_TYPE_NEQ,
CHEAT_SEARCH_TYPE_EQPLUS,
CHEAT_SEARCH_TYPE_EQMINUS
};
enum cheat_match_action_type
{
CHEAT_MATCH_ACTION_TYPE_VIEW = 0,
CHEAT_MATCH_ACTION_TYPE_DELETE,
CHEAT_MATCH_ACTION_TYPE_COPY,
CHEAT_MATCH_ACTION_TYPE_BROWSE
};
enum cheat_rumble_type
{
RUMBLE_TYPE_DISABLED = 0,
RUMBLE_TYPE_CHANGES,
RUMBLE_TYPE_DOES_NOT_CHANGE,
RUMBLE_TYPE_INCREASE,
RUMBLE_TYPE_DECREASE,
RUMBLE_TYPE_EQ_VALUE,
RUMBLE_TYPE_NEQ_VALUE,
RUMBLE_TYPE_LT_VALUE,
RUMBLE_TYPE_GT_VALUE,
RUMBLE_TYPE_INCREASE_BY_VALUE,
RUMBLE_TYPE_DECREASE_BY_VALUE,
RUMBLE_TYPE_END_LIST
};
/* Some codes are ridiculously large - over 10000 bytes */
#define CHEAT_CODE_SCRATCH_SIZE 16*1024
#define CHEAT_DESC_SCRATCH_SIZE 255
struct item_cheat
{
/* Clock value for when rumbling should stop */
retro_time_t rumble_primary_end_time;
retro_time_t rumble_secondary_end_time;
char *desc;
char *code;
unsigned int idx;
unsigned int handler;
/* Number of bits = 2^memory_search_size
* 0=1, 1=2, 2=4, 3=8, 4=16, 5=32
*/
unsigned int memory_search_size;
unsigned int cheat_type;
unsigned int value;
unsigned int address;
/*
* address_mask used when memory_search_size <8 bits
* if memory_search_size=0, then the number of bits is 1 and this value can be one of the following:
* 0 : 00000001
* 1 : 00000010
* 2 : 00000100
* 3 : 00001000
* 4 : 00010000
* 5 : 00100000
* 6 : 01000000
* 7 : 10000000
* if memory_search_size=1, then the number of bits is 2 and this value can be one of the following:
* 0 : 00000011
* 1 : 00001100
* 2 : 00110000
* 3 : 11000000
* if memory_search_size=2, then the number of bits is 4 and this value can be one of the following:
* 0 : 00001111
* 1 : 11110000
*/
unsigned int address_mask;
unsigned int rumble_type;
unsigned int rumble_value;
unsigned int rumble_prev_value;
unsigned int rumble_initialized;
/* 0-15 for specific port, anything else means "all ports" */
unsigned int rumble_port;
unsigned int rumble_primary_strength; /* 0-65535 */
unsigned int rumble_primary_duration; /* in milliseconds */
unsigned int rumble_secondary_strength; /* 0-65535 */
unsigned int rumble_secondary_duration; /* in milliseconds */
/*
* The repeat_ variables allow for a single cheat code to affect multiple memory addresses.
* repeat_count - the number of times the cheat code should be applied
* repeat_add_to_value - every iteration of repeat_count will have this amount added to item_cheat.value
* repeat_add_to_address - every iteration of repeat_count will have this amount added to item_cheat.address
*
* Note that repeat_add_to_address represents the number of "memory_search_size" blocks to add to
* item_cheat.address. If memory_search_size is 16-bits and repeat_add_to_address is 2, then item_cheat.address
* will be increased by 4 bytes 2*(16-bits) for every iteration.
*
* This is a cheating structure used for codes like unlocking all levels, giving yourself 1 of every item,etc.
*/
unsigned int repeat_count;
unsigned int repeat_add_to_value;
unsigned int repeat_add_to_address;
bool state;
/* Whether to apply the cheat based on big-endian console memory or not */
bool big_endian;
};
struct cheat_manager
{
struct item_cheat working_cheat; /* retro_time_t alignment */
struct item_cheat *cheats;
uint8_t *curr_memory_buf;
uint8_t *prev_memory_buf;
uint8_t *matches;
uint8_t **memory_buf_list;
unsigned *memory_size_list;
unsigned int delete_state;
unsigned int loading_cheat_size;
unsigned int loading_cheat_offset;
unsigned ptr;
unsigned size;
unsigned buf_size;
unsigned total_memory_size;
unsigned num_memory_buffers;
unsigned match_idx;
unsigned match_action;
unsigned search_bit_size;
unsigned dummy;
unsigned search_exact_value;
unsigned search_eqplus_value;
unsigned search_eqminus_value;
unsigned num_matches;
unsigned browse_address;
char working_desc[CHEAT_DESC_SCRATCH_SIZE];
char working_code[CHEAT_CODE_SCRATCH_SIZE];
bool big_endian;
bool memory_initialized;
bool memory_search_initialized;
};
typedef struct cheat_manager cheat_manager_t;
extern cheat_manager_t cheat_manager_state;
unsigned cheat_manager_get_size(void);
bool cheat_manager_load(const char *path, bool append);
/**
* cheat_manager_save:
* @path : Path to cheats file (absolute path).
*
* Saves cheats to file on disk.
*
* Returns: true (1) if successful, otherwise false (0).
**/
bool cheat_manager_save(const char *path,
const char *cheat_database, bool overwrite);
bool cheat_manager_realloc(unsigned new_size, unsigned default_handler);
void cheat_manager_set_code(unsigned index, const char *str);
void cheat_manager_index_next(void);
void cheat_manager_index_prev(void);
void cheat_manager_toggle(void);
void cheat_manager_apply_cheats(void);
void cheat_manager_update(cheat_manager_t *handle, unsigned handle_idx);
void cheat_manager_toggle_index(bool apply_cheats_after_toggle,
unsigned i);
unsigned cheat_manager_get_buf_size(void);
const char *cheat_manager_get_desc(unsigned i);
const char *cheat_manager_get_code(unsigned i);
bool cheat_manager_get_code_state(unsigned i);
void cheat_manager_state_free(void);
void cheat_manager_alloc_if_empty(void);
bool cheat_manager_copy_idx_to_working(unsigned idx);
bool cheat_manager_copy_working_to_idx(unsigned idx);
void cheat_manager_load_game_specific_cheats(const char *path_cheat_database);
void cheat_manager_save_game_specific_cheats(const char *path_cheat_database);
int cheat_manager_initialize_memory(rarch_setting_t *setting, size_t idx, bool wraparound);
int cheat_manager_search_exact(rarch_setting_t *setting, size_t idx, bool wraparound);
int cheat_manager_search_lt(rarch_setting_t *setting, size_t idx, bool wraparound);
int cheat_manager_search_gt(rarch_setting_t *setting, size_t idx, bool wraparound);
int cheat_manager_search_lte(rarch_setting_t *setting, size_t idx, bool wraparound);
int cheat_manager_search_gte(rarch_setting_t *setting, size_t idx, bool wraparound);
int cheat_manager_search_eq(rarch_setting_t *setting, size_t idx, bool wraparound);
int cheat_manager_search_neq(rarch_setting_t *setting, size_t idx, bool wraparound);
int cheat_manager_search_eqplus(rarch_setting_t *setting, size_t idx, bool wraparound);
int cheat_manager_search_eqminus(rarch_setting_t *setting, size_t idx, bool wraparound);
unsigned cheat_manager_get_state_search_size(unsigned search_size);
int cheat_manager_add_matches(const char *path,
const char *label, unsigned type, size_t idx, size_t entry_idx);
void cheat_manager_apply_retro_cheats(void);
void cheat_manager_match_action(
enum cheat_match_action_type match_action,
unsigned int target_match_idx,
unsigned int *address, unsigned int *address_mask,
unsigned int *prev_value, unsigned int *curr_value);
int cheat_manager_copy_match(rarch_setting_t *setting, size_t idx, bool wraparound);
int cheat_manager_delete_match(rarch_setting_t *setting, size_t idx, bool wraparound);
RETRO_END_DECLS
#endif
|