add cheat variables to allow for updating large portions of memory - e.g. unlock all levels

This commit is contained in:
Sven 2018-09-29 14:52:10 -04:00
parent 67347205d4
commit 25b5a7e3b8
8 changed files with 214 additions and 101 deletions

View File

@ -1605,6 +1605,12 @@ MSG_HASH(MENU_ENUM_LABEL_CHEAT_TYPE,
"cheat_type")
MSG_HASH(MENU_ENUM_LABEL_CHEAT_VALUE,
"cheat_value")
MSG_HASH(MENU_ENUM_LABEL_CHEAT_REPEAT_COUNT,
"cheat_repeat_count")
MSG_HASH(MENU_ENUM_LABEL_CHEAT_REPEAT_ADD_TO_VALUE,
"cheat_repeat_add_to_value")
MSG_HASH(MENU_ENUM_LABEL_CHEAT_REPEAT_ADD_TO_ADDRESS,
"cheat_repeat_add_to_address")
MSG_HASH(MENU_ENUM_LABEL_CHEAT_ADDRESS,
"cheat_address")
MSG_HASH(MENU_ENUM_LABEL_CHEAT_ADDRESS_BIT_POSITION,

View File

@ -6822,6 +6822,18 @@ MSG_HASH(
MENU_ENUM_LABEL_VALUE_CHEAT_RUMBLE_SECONDARY_DURATION,
"Rumble Secondary Duration (ms)"
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_CHEAT_REPEAT_COUNT,
"Number of Iterations"
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_CHEAT_REPEAT_ADD_TO_VALUE,
"Value Increase Each Iteration"
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_CHEAT_REPEAT_ADD_TO_ADDRESS,
"Address Increase Each Iteration"
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_CHEAT_ADD_NEW_AFTER,
"Add New Cheat After This One"
@ -7589,4 +7601,4 @@ MSG_HASH(
MSG_HASH(
MENU_ENUM_LABEL_VALUE_STREAMING_TITLE,
"Title of Stream"
)
)

View File

@ -123,6 +123,25 @@ bool cheat_manager_save(const char *path, const char *cheat_database, bool overw
char buf[PATH_MAX_LENGTH];
char cheats_file[PATH_MAX_LENGTH];
config_file_t *conf = NULL;
unsigned int* data_ptrs[16] = { NULL};
char* keys[16] = {
"cheat%u_handler",
"cheat%u_memory_search_size",
"cheat%u_cheat_type",
"cheat%u_value",
"cheat%u_address",
"cheat%u_address_bit_position",
"cheat%u_rumble_type",
"cheat%u_rumble_value",
"cheat%u_rumble_port",
"cheat%u_rumble_primary_strength",
"cheat%u_rumble_primary_duration",
"cheat%u_rumble_secondary_strength",
"cheat%u_rumble_secondary_duration",
"cheat%u_repeat_count",
"cheat%u_repeat_add_to_value",
"cheat%u_repeat_add_to_address",
};
buf[0] = cheats_file[0] = '\0';
@ -158,21 +177,6 @@ bool cheat_manager_save(const char *path, const char *cheat_database, bool overw
char desc_key[256];
char code_key[256];
char enable_key[256];
char* keys[13] = {
"cheat%u_handler",
"cheat%u_memory_search_size",
"cheat%u_cheat_type",
"cheat%u_value",
"cheat%u_address",
"cheat%u_address_bit_position",
"cheat%u_rumble_type",
"cheat%u_rumble_value",
"cheat%u_rumble_port",
"cheat%u_rumble_primary_strength",
"cheat%u_rumble_primary_duration",
"cheat%u_rumble_secondary_strength",
"cheat%u_rumble_secondary_duration",
};
key[0] = endian_key[0] = desc_key[0] = code_key[0] = enable_key[0] = '\0';
@ -185,26 +189,30 @@ bool cheat_manager_save(const char *path, const char *cheat_database, bool overw
config_set_string(conf, desc_key, cheat_manager_state.cheats[i].desc);
else
config_set_string(conf, desc_key, cheat_manager_state.cheats[i].code);
config_set_string(conf, code_key, cheat_manager_state.cheats[i].code);
config_set_bool(conf, enable_key, cheat_manager_state.cheats[i].state);
config_set_bool(conf, endian_key, cheat_manager_state.cheats[i].big_endian);
for (j = 0; j < 13; j++)
data_ptrs[0] = &cheat_manager_state.cheats[i].handler;
data_ptrs[1] = &cheat_manager_state.cheats[i].memory_search_size;
data_ptrs[2] = &cheat_manager_state.cheats[i].cheat_type;
data_ptrs[3] = &cheat_manager_state.cheats[i].value;
data_ptrs[4] = &cheat_manager_state.cheats[i].address;
data_ptrs[5] = &cheat_manager_state.cheats[i].address_mask;
data_ptrs[6] = &cheat_manager_state.cheats[i].rumble_type;
data_ptrs[7] = &cheat_manager_state.cheats[i].rumble_value;
data_ptrs[8] = &cheat_manager_state.cheats[i].rumble_port;
data_ptrs[9] = &cheat_manager_state.cheats[i].rumble_primary_strength;
data_ptrs[10] = &cheat_manager_state.cheats[i].rumble_primary_duration;
data_ptrs[11] = &cheat_manager_state.cheats[i].rumble_secondary_strength;
data_ptrs[12] = &cheat_manager_state.cheats[i].rumble_secondary_duration;
data_ptrs[13] = &cheat_manager_state.cheats[i].repeat_count;
data_ptrs[14] = &cheat_manager_state.cheats[i].repeat_add_to_value;
data_ptrs[15] = &cheat_manager_state.cheats[i].repeat_add_to_address;
for (j = 0; j < 16; j++)
{
unsigned int* data_ptrs[13] = { NULL};
data_ptrs[0] = &cheat_manager_state.cheats[i].handler;
data_ptrs[1] = &cheat_manager_state.cheats[i].memory_search_size;
data_ptrs[2] = &cheat_manager_state.cheats[i].cheat_type;
data_ptrs[3] = &cheat_manager_state.cheats[i].value;
data_ptrs[4] = &cheat_manager_state.cheats[i].address;
data_ptrs[5] = &cheat_manager_state.cheats[i].address_mask;
data_ptrs[6] = &cheat_manager_state.cheats[i].rumble_type;
data_ptrs[7] = &cheat_manager_state.cheats[i].rumble_value;
data_ptrs[8] = &cheat_manager_state.cheats[i].rumble_port;
data_ptrs[9] = &cheat_manager_state.cheats[i].rumble_primary_strength;
data_ptrs[10] = &cheat_manager_state.cheats[i].rumble_primary_duration;
data_ptrs[11] = &cheat_manager_state.cheats[i].rumble_secondary_strength;
data_ptrs[12] = &cheat_manager_state.cheats[i].rumble_secondary_duration;
key[0] = '\0';
snprintf(key, sizeof(key), keys[j], i);
config_set_uint(conf, key, *(data_ptrs[j]));
@ -283,6 +291,9 @@ static void cheat_manager_new(unsigned size)
cheat_manager_state.cheats[i].desc = NULL ;
cheat_manager_state.cheats[i].code = NULL ;
cheat_manager_state.cheats[i].state = false;
cheat_manager_state.cheats[i].repeat_count = 1;
cheat_manager_state.cheats[i].repeat_add_to_value = 0;
cheat_manager_state.cheats[i].repeat_add_to_address = 1;
}
return ;
@ -293,6 +304,25 @@ bool cheat_manager_load(const char *path, bool append)
unsigned cheats = 0, i;
config_file_t *conf = config_file_new(path);
unsigned orig_size ;
unsigned int* data_ptrs[16] = { NULL};
char* keys[16] = {
"cheat%u_handler",
"cheat%u_memory_search_size",
"cheat%u_cheat_type",
"cheat%u_value",
"cheat%u_address",
"cheat%u_address_bit_position",
"cheat%u_rumble_type",
"cheat%u_rumble_value",
"cheat%u_rumble_port",
"cheat%u_rumble_primary_strength",
"cheat%u_rumble_primary_duration",
"cheat%u_rumble_secondary_strength",
"cheat%u_rumble_secondary_duration",
"cheat%u_repeat_count",
"cheat%u_repeat_add_to_value",
"cheat%u_repeat_add_to_address",
};
if (!conf)
return false;
@ -334,22 +364,7 @@ bool cheat_manager_load(const char *path, bool append)
char endian_key[256];
char *tmp = NULL;
bool tmp_bool = false;
unsigned int* data_ptrs[13] = { NULL};
char* keys[13] = {
"cheat%u_handler",
"cheat%u_memory_search_size",
"cheat%u_cheat_type",
"cheat%u_value",
"cheat%u_address",
"cheat%u_address_bit_position",
"cheat%u_rumble_type",
"cheat%u_rumble_value",
"cheat%u_rumble_port",
"cheat%u_rumble_primary_strength",
"cheat%u_rumble_primary_duration",
"cheat%u_rumble_secondary_strength",
"cheat%u_rumble_secondary_duration",
};
data_ptrs[0] = &cheat_manager_state.cheats[i].handler;
data_ptrs[1] = &cheat_manager_state.cheats[i].memory_search_size;
data_ptrs[2] = &cheat_manager_state.cheats[i].cheat_type;
@ -363,6 +378,9 @@ bool cheat_manager_load(const char *path, bool append)
data_ptrs[10] = &cheat_manager_state.cheats[i].rumble_primary_duration;
data_ptrs[11] = &cheat_manager_state.cheats[i].rumble_secondary_strength;
data_ptrs[12] = &cheat_manager_state.cheats[i].rumble_secondary_duration;
data_ptrs[13] = &cheat_manager_state.cheats[i].repeat_count;
data_ptrs[14] = &cheat_manager_state.cheats[i].repeat_add_to_value;
data_ptrs[15] = &cheat_manager_state.cheats[i].repeat_add_to_address;
endian_key[0] = desc_key[0] = code_key[0] = enable_key[0] = '\0';
@ -395,7 +413,7 @@ bool cheat_manager_load(const char *path, bool append)
cheat_manager_state.cheats[i].cheat_type = CHEAT_TYPE_SET_TO_VALUE ;
cheat_manager_state.cheats[i].memory_search_size = 3;
for (j = 0 ; j < 13 ; j++ )
for (j = 0 ; j < 16 ; j++ )
{
char key[50] ;
unsigned val = 0;
@ -463,6 +481,9 @@ bool cheat_manager_realloc(unsigned new_size, unsigned default_handler)
cheat_manager_state.cheats[i].cheat_type = CHEAT_TYPE_SET_TO_VALUE ;
cheat_manager_state.cheats[i].memory_search_size = 3;
cheat_manager_state.cheats[i].idx = i;
cheat_manager_state.cheats[i].repeat_count = 1;
cheat_manager_state.cheats[i].repeat_add_to_value = 0;
cheat_manager_state.cheats[i].repeat_add_to_address = 1;
}
return true;
@ -1141,6 +1162,8 @@ void cheat_manager_apply_retro_cheats(void)
unsigned int idx;
bool set_value = false;
unsigned int value_to_set = 0;
unsigned int repeat_iter = 0 ;
unsigned int address_mask = cheat_manager_state.cheats[i].address_mask ;
if (cheat_manager_state.cheats[i].handler != CHEAT_HANDLER_TYPE_RETRO || !cheat_manager_state.cheats[i].state)
continue ;
@ -1222,63 +1245,88 @@ void cheat_manager_apply_retro_cheats(void)
}
if (set_value)
{
switch (bytes_per_item)
for ( repeat_iter = 1 ; repeat_iter <= cheat_manager_state.cheats[i].repeat_count ; repeat_iter++)
{
case 2 :
if (cheat_manager_state.cheats[i].big_endian)
{
*(curr+idx) = (value_to_set >> 8) & 0xFF ;
*(curr+idx+1) = value_to_set & 0xFF ;
}
else
{
*(curr+idx) = value_to_set & 0xFF ;
*(curr+idx+1) = (value_to_set >> 8) & 0xFF ;
}
break ;
case 4 :
if (cheat_manager_state.cheats[i].big_endian)
{
*(curr+idx) = (value_to_set >> 24) & 0xFF ;
*(curr+idx+1) = (value_to_set >> 16) & 0xFF ;
*(curr+idx+2) = (value_to_set >> 8) & 0xFF ;
*(curr+idx+3) = value_to_set & 0xFF ;
}
else
{
*(curr+idx) = value_to_set & 0xFF ;
*(curr+idx+1) = (value_to_set >> 8) & 0xFF ;
*(curr+idx+2) = (value_to_set >> 16) & 0xFF ;
*(curr+idx+3) = (value_to_set >> 24) & 0xFF ;
}
break ;
case 1 :
if (bits < 8)
{
unsigned bitpos;
unsigned char val = *(curr+idx);
for (bitpos = 0 ; bitpos < 8 ; bitpos++)
switch (bytes_per_item)
{
case 2 :
if (cheat_manager_state.cheats[i].big_endian)
{
if ((cheat_manager_state.cheats[i].address_mask>>bitpos)&0x01 )
{
mask = (~(1<<bitpos)&0xFF) ;
/* Clear current bit value */
val = val & mask ;
/* Inject cheat bit value */
val = val | (((value_to_set>>bitpos)&0x01)<<bitpos) ;
}
*(curr+idx) = (value_to_set >> 8) & 0xFF ;
*(curr+idx+1) = value_to_set & 0xFF ;
}
else
{
*(curr+idx) = value_to_set & 0xFF ;
*(curr+idx+1) = (value_to_set >> 8) & 0xFF ;
}
break ;
case 4 :
if (cheat_manager_state.cheats[i].big_endian)
{
*(curr+idx) = (value_to_set >> 24) & 0xFF ;
*(curr+idx+1) = (value_to_set >> 16) & 0xFF ;
*(curr+idx+2) = (value_to_set >> 8) & 0xFF ;
*(curr+idx+3) = value_to_set & 0xFF ;
}
else
{
*(curr+idx) = value_to_set & 0xFF ;
*(curr+idx+1) = (value_to_set >> 8) & 0xFF ;
*(curr+idx+2) = (value_to_set >> 16) & 0xFF ;
*(curr+idx+3) = (value_to_set >> 24) & 0xFF ;
}
break ;
case 1 :
if (bits < 8)
{
unsigned bitpos;
unsigned char val = *(curr+idx);
for (bitpos = 0 ; bitpos < 8 ; bitpos++)
{
if ((address_mask>>bitpos)&0x01 )
{
mask = (~(1<<bitpos)&0xFF) ;
/* Clear current bit value */
val = val & mask ;
/* Inject cheat bit value */
val = val | (((value_to_set>>bitpos)&0x01)<<bitpos) ;
}
}
*(curr+idx) = val ;
}
else
*(curr+idx) = value_to_set & 0xFF;
break ;
default :
*(curr+idx) = value_to_set & 0xFF ;
break ;
}
value_to_set += cheat_manager_state.cheats[i].repeat_add_to_value ;
value_to_set = value_to_set%mask ;
if ( bits < 8 )
{
unsigned int bit_iter ;
for ( bit_iter = 0 ; bit_iter < cheat_manager_state.cheats[i].repeat_add_to_address ; bit_iter++)
{
address_mask = (address_mask<<mask)&0xFF ;
if ( address_mask == 0 )
{
address_mask = mask ;
idx++ ;
}
*(curr+idx) = val ;
}
else
*(curr+idx) = value_to_set & 0xFF;
break ;
default :
*(curr+idx) = value_to_set & 0xFF ;
break ;
}
else
{
idx += (cheat_manager_state.cheats[i].repeat_add_to_address*bytes_per_item) ;
}
idx = idx%cheat_manager_state.total_memory_size ;
}
}
}

View File

@ -132,6 +132,23 @@ struct item_cheat
unsigned int rumble_secondary_strength ; /* 0-65535 */
unsigned int rumble_secondary_duration ; /* in milliseconds */
retro_time_t rumble_secondary_end_time ; /* clock value for when rumbling should stop */
/*
* 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_seach_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 ;
};
struct cheat_manager

View File

@ -126,6 +126,9 @@ static int menu_cbs_init_bind_cancel_compare_type(
case MENU_ENUM_LABEL_CHEAT_VALUE:
case MENU_ENUM_LABEL_CHEAT_ADDRESS:
case MENU_ENUM_LABEL_CHEAT_ADDRESS_BIT_POSITION:
case MENU_ENUM_LABEL_CHEAT_REPEAT_COUNT:
case MENU_ENUM_LABEL_CHEAT_REPEAT_ADD_TO_ADDRESS:
case MENU_ENUM_LABEL_CHEAT_REPEAT_ADD_TO_VALUE:
case MENU_ENUM_LABEL_CHEAT_RUMBLE_TYPE:
case MENU_ENUM_LABEL_CHEAT_RUMBLE_VALUE:
case MENU_ENUM_LABEL_CHEAT_RUMBLE_PORT:

View File

@ -5259,6 +5259,15 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data)
menu_displaylist_parse_settings_enum(menu, info,
MENU_ENUM_LABEL_CHEAT_ADDRESS_BIT_POSITION,
PARSE_ONLY_UINT, false);
menu_displaylist_parse_settings_enum(menu, info,
MENU_ENUM_LABEL_CHEAT_REPEAT_COUNT,
PARSE_ONLY_UINT, false);
menu_displaylist_parse_settings_enum(menu, info,
MENU_ENUM_LABEL_CHEAT_REPEAT_ADD_TO_ADDRESS,
PARSE_ONLY_UINT, false);
menu_displaylist_parse_settings_enum(menu, info,
MENU_ENUM_LABEL_CHEAT_REPEAT_ADD_TO_VALUE,
PARSE_ONLY_UINT, false);
menu_displaylist_parse_settings_enum(menu, info,
MENU_ENUM_LABEL_CHEAT_RUMBLE_TYPE,
PARSE_ONLY_UINT, false);

View File

@ -4585,6 +4585,21 @@ static bool setting_append_list(
general_read_handler,
SD_FLAG_NONE);
config_uint_cbs(cheat_manager_state.working_cheat.repeat_count, CHEAT_REPEAT_COUNT,
setting_uint_action_left_default,setting_uint_action_right_default,
0,&setting_get_string_representation_hex_and_uint,1,2048,1) ;
(*list)[list_info->index - 1].action_ok = &setting_action_ok_uint;
config_uint_cbs(cheat_manager_state.working_cheat.repeat_add_to_address, CHEAT_REPEAT_ADD_TO_ADDRESS,
setting_uint_action_left_default,setting_uint_action_right_default,
0,&setting_get_string_representation_hex_and_uint,1,2048,1) ;
(*list)[list_info->index - 1].action_ok = &setting_action_ok_uint;
config_uint_cbs(cheat_manager_state.working_cheat.repeat_add_to_value, CHEAT_REPEAT_ADD_TO_VALUE,
setting_uint_action_left_default,setting_uint_action_right_default,
0,&setting_get_string_representation_hex_and_uint,0,0xFFFF,1) ;
(*list)[list_info->index - 1].action_ok = &setting_action_ok_uint;
config_uint_cbs(cheat_manager_state.working_cheat.rumble_type, CHEAT_RUMBLE_TYPE,
setting_uint_action_left_default,setting_uint_action_right_default,
MENU_ENUM_LABEL_RUMBLE_TYPE_DISABLED,&setting_get_string_representation_uint_as_enum,

View File

@ -1247,6 +1247,9 @@ enum msg_hash_enums
MENU_LABEL(CHEAT_VALUE),
MENU_LABEL(CHEAT_ADDRESS),
MENU_LABEL(CHEAT_ADDRESS_BIT_POSITION),
MENU_LABEL(CHEAT_REPEAT_COUNT),
MENU_LABEL(CHEAT_REPEAT_ADD_TO_VALUE),
MENU_LABEL(CHEAT_REPEAT_ADD_TO_ADDRESS),
MENU_LABEL(CHEAT_RUMBLE_TYPE),
MENU_LABEL(CHEAT_RUMBLE_VALUE),
MENU_LABEL(CHEAT_RUMBLE_PORT),