This commit is contained in:
twinaphex 2019-08-10 14:23:00 +02:00
parent 41c6345381
commit baf8c71545
3 changed files with 158 additions and 156 deletions

View File

@ -277,27 +277,27 @@ static void cheat_manager_new(unsigned size)
cheat_manager_free(); cheat_manager_free();
cheat_manager_state.buf_size = size; cheat_manager_state.buf_size = size;
cheat_manager_state.size = size; cheat_manager_state.size = size;
cheat_manager_state.search_bit_size = 3; cheat_manager_state.search_bit_size = 3;
cheat_manager_state.cheats = (struct item_cheat*) cheat_manager_state.cheats = (struct item_cheat*)
calloc(cheat_manager_state.buf_size, sizeof(struct item_cheat)); calloc(cheat_manager_state.buf_size, sizeof(struct item_cheat));
if (!cheat_manager_state.cheats) if (!cheat_manager_state.cheats)
{ {
cheat_manager_state.buf_size = 0; cheat_manager_state.buf_size = 0;
cheat_manager_state.size = 0; cheat_manager_state.size = 0;
cheat_manager_state.cheats = NULL; cheat_manager_state.cheats = NULL;
return; return;
} }
for (i = 0; i < cheat_manager_state.size; i++) for (i = 0; i < cheat_manager_state.size; i++)
{ {
cheat_manager_state.cheats[i].desc = NULL; cheat_manager_state.cheats[i].desc = NULL;
cheat_manager_state.cheats[i].code = NULL; cheat_manager_state.cheats[i].code = NULL;
cheat_manager_state.cheats[i].state = false; cheat_manager_state.cheats[i].state = false;
cheat_manager_state.cheats[i].repeat_count = 1; 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_value = 0;
cheat_manager_state.cheats[i].repeat_add_to_address = 1; cheat_manager_state.cheats[i].repeat_add_to_address = 1;
} }
} }
@ -390,9 +390,10 @@ static void cheat_manager_load_cb_second_pass(char *key, char *value)
bool cheat_manager_load(const char *path, bool append) bool cheat_manager_load(const char *path, bool append)
{ {
unsigned orig_size;
unsigned cheats = 0, i;
config_file_cb_t cb; config_file_cb_t cb;
unsigned orig_size = 0;
unsigned cheats = 0;
unsigned i = 0;
config_file_t *conf = NULL; config_file_t *conf = NULL;
cb.config_file_new_entry_cb = cheat_manager_load_cb_first_pass; cb.config_file_new_entry_cb = cheat_manager_load_cb_first_pass;
@ -1285,22 +1286,22 @@ void cheat_manager_apply_retro_cheats(void)
{ {
unsigned i; unsigned i;
unsigned int offset; unsigned int offset;
unsigned int mask = 0; unsigned int mask = 0;
unsigned int bytes_per_item = 1; unsigned int bytes_per_item = 1;
unsigned int bits = 8; unsigned int bits = 8;
unsigned int curr_val = 0; unsigned int curr_val = 0;
bool run_cheat = true; bool run_cheat = true;
if ((!cheat_manager_state.cheats)) if ((!cheat_manager_state.cheats))
return; return;
for (i = 0; i < cheat_manager_state.size; i++) for (i = 0; i < cheat_manager_state.size; i++)
{ {
unsigned char *curr; unsigned char *curr = NULL;
unsigned int idx; bool set_value = false;
bool set_value = false; unsigned int idx = 0;
unsigned int value_to_set = 0; unsigned int value_to_set = 0;
unsigned int repeat_iter = 0; unsigned int repeat_iter = 0;
unsigned int address_mask = cheat_manager_state.cheats[i].address_mask; 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) if (cheat_manager_state.cheats[i].handler != CHEAT_HANDLER_TYPE_RETRO || !cheat_manager_state.cheats[i].state)
@ -1320,61 +1321,61 @@ void cheat_manager_apply_retro_cheats(void)
} }
cheat_manager_setup_search_meta(cheat_manager_state.cheats[i].memory_search_size, &bytes_per_item, &mask, &bits); cheat_manager_setup_search_meta(cheat_manager_state.cheats[i].memory_search_size, &bytes_per_item, &mask, &bits);
curr = cheat_manager_state.curr_memory_buf; curr = cheat_manager_state.curr_memory_buf;
idx = cheat_manager_state.cheats[i].address; idx = cheat_manager_state.cheats[i].address;
offset = translate_address(idx, &curr); offset = translate_address(idx, &curr);
switch (bytes_per_item) switch (bytes_per_item)
{ {
case 2: case 2:
curr_val = cheat_manager_state.big_endian ? curr_val = cheat_manager_state.big_endian ?
(*(curr + idx - offset) * 256) + *(curr + idx + 1 - offset) : (*(curr + idx - offset) * 256) + *(curr + idx + 1 - offset) :
*(curr + idx - offset) + (*(curr + idx + 1 - offset) * 256); *(curr + idx - offset) + (*(curr + idx + 1 - offset) * 256);
break; break;
case 4: case 4:
curr_val = cheat_manager_state.big_endian ? curr_val = cheat_manager_state.big_endian ?
(*(curr + idx - offset) * 256 * 256 * 256) + (*(curr + idx + 1 - offset) * 256 * 256) + (*(curr + idx + 2 - offset) * 256) + *(curr + idx + 3 - offset) : (*(curr + idx - offset) * 256 * 256 * 256) + (*(curr + idx + 1 - offset) * 256 * 256) + (*(curr + idx + 2 - offset) * 256) + *(curr + idx + 3 - offset) :
*(curr + idx - offset) + (*(curr + idx + 1 - offset) * 256) + (*(curr + idx + 2 - offset) * 256 * 256) + (*(curr + idx + 3 - offset) * 256 * 256 * 256); *(curr + idx - offset) + (*(curr + idx + 1 - offset) * 256) + (*(curr + idx + 2 - offset) * 256 * 256) + (*(curr + idx + 3 - offset) * 256 * 256 * 256);
break; break;
case 1: case 1:
default: default:
curr_val = *(curr + idx - offset); curr_val = *(curr + idx - offset);
break; break;
} }
cheat_manager_apply_rumble(&cheat_manager_state.cheats[i], curr_val); cheat_manager_apply_rumble(&cheat_manager_state.cheats[i], curr_val);
switch (cheat_manager_state.cheats[i].cheat_type) switch (cheat_manager_state.cheats[i].cheat_type)
{ {
case CHEAT_TYPE_SET_TO_VALUE: case CHEAT_TYPE_SET_TO_VALUE:
set_value = true; set_value = true;
value_to_set = cheat_manager_state.cheats[i].value; value_to_set = cheat_manager_state.cheats[i].value;
break; break;
case CHEAT_TYPE_INCREASE_VALUE: case CHEAT_TYPE_INCREASE_VALUE:
set_value = true; set_value = true;
value_to_set = curr_val + cheat_manager_state.cheats[i].value; value_to_set = curr_val + cheat_manager_state.cheats[i].value;
break; break;
case CHEAT_TYPE_DECREASE_VALUE: case CHEAT_TYPE_DECREASE_VALUE:
set_value = true; set_value = true;
value_to_set = curr_val - cheat_manager_state.cheats[i].value; value_to_set = curr_val - cheat_manager_state.cheats[i].value;
break; break;
case CHEAT_TYPE_RUN_NEXT_IF_EQ: case CHEAT_TYPE_RUN_NEXT_IF_EQ:
if (!(curr_val == cheat_manager_state.cheats[i].value)) if (!(curr_val == cheat_manager_state.cheats[i].value))
run_cheat = false; run_cheat = false;
break; break;
case CHEAT_TYPE_RUN_NEXT_IF_NEQ: case CHEAT_TYPE_RUN_NEXT_IF_NEQ:
if (!(curr_val != cheat_manager_state.cheats[i].value)) if (!(curr_val != cheat_manager_state.cheats[i].value))
run_cheat = false; run_cheat = false;
break; break;
case CHEAT_TYPE_RUN_NEXT_IF_LT: case CHEAT_TYPE_RUN_NEXT_IF_LT:
if (!(cheat_manager_state.cheats[i].value < curr_val)) if (!(cheat_manager_state.cheats[i].value < curr_val))
run_cheat = false; run_cheat = false;
break; break;
case CHEAT_TYPE_RUN_NEXT_IF_GT: case CHEAT_TYPE_RUN_NEXT_IF_GT:
if (!(cheat_manager_state.cheats[i].value > curr_val)) if (!(cheat_manager_state.cheats[i].value > curr_val))
run_cheat = false; run_cheat = false;
break; break;
} }
if (set_value) if (set_value)
@ -1383,60 +1384,60 @@ void cheat_manager_apply_retro_cheats(void)
{ {
switch (bytes_per_item) switch (bytes_per_item)
{ {
case 2: case 2:
if (cheat_manager_state.cheats[i].big_endian) if (cheat_manager_state.cheats[i].big_endian)
{
*(curr + idx - offset) = (value_to_set >> 8) & 0xFF;
*(curr + idx + 1 - offset) = value_to_set & 0xFF;
}
else
{
*(curr + idx - offset) = value_to_set & 0xFF;
*(curr + idx + 1 - offset) = (value_to_set >> 8) & 0xFF;
}
break;
case 4:
if (cheat_manager_state.cheats[i].big_endian)
{
*(curr + idx - offset) = (value_to_set >> 24) & 0xFF;
*(curr + idx + 1 - offset) = (value_to_set >> 16) & 0xFF;
*(curr + idx + 2 - offset) = (value_to_set >> 8) & 0xFF;
*(curr + idx + 3 - offset) = value_to_set & 0xFF;
}
else
{
*(curr + idx - offset) = value_to_set & 0xFF;
*(curr + idx + 1 - offset) = (value_to_set >> 8) & 0xFF;
*(curr + idx + 2 - offset) = (value_to_set >> 16) & 0xFF;
*(curr + idx + 3 - offset) = (value_to_set >> 24) & 0xFF;
}
break;
case 1:
if (bits < 8)
{
unsigned bitpos;
unsigned char val = *(curr + idx - offset);
for (bitpos = 0; bitpos < 8; bitpos++)
{ {
if ((address_mask >> bitpos) & 0x01) *(curr + idx - offset) = (value_to_set >> 8) & 0xFF;
{ *(curr + idx + 1 - offset) = value_to_set & 0xFF;
mask = (~(1 << bitpos) & 0xFF);
/* Clear current bit value */
val = val & mask;
/* Inject cheat bit value */
val = val | (((value_to_set >> bitpos) & 0x01) << bitpos);
}
} }
else
{
*(curr + idx - offset) = value_to_set & 0xFF;
*(curr + idx + 1 - offset) = (value_to_set >> 8) & 0xFF;
}
break;
case 4:
if (cheat_manager_state.cheats[i].big_endian)
{
*(curr + idx - offset) = (value_to_set >> 24) & 0xFF;
*(curr + idx + 1 - offset) = (value_to_set >> 16) & 0xFF;
*(curr + idx + 2 - offset) = (value_to_set >> 8) & 0xFF;
*(curr + idx + 3 - offset) = value_to_set & 0xFF;
}
else
{
*(curr + idx - offset) = value_to_set & 0xFF;
*(curr + idx + 1 - offset) = (value_to_set >> 8) & 0xFF;
*(curr + idx + 2 - offset) = (value_to_set >> 16) & 0xFF;
*(curr + idx + 3 - offset) = (value_to_set >> 24) & 0xFF;
}
break;
case 1:
if (bits < 8)
{
unsigned bitpos;
unsigned char val = *(curr + idx - offset);
*(curr + idx - offset) = val; for (bitpos = 0; bitpos < 8; bitpos++)
} {
else 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 - offset) = val;
}
else
*(curr + idx - offset) = value_to_set & 0xFF;
break;
default:
*(curr + idx - offset) = value_to_set & 0xFF; *(curr + idx - offset) = value_to_set & 0xFF;
break; break;
default:
*(curr + idx - offset) = value_to_set & 0xFF;
break;
} }
value_to_set += cheat_manager_state.cheats[i].repeat_add_to_value; value_to_set += cheat_manager_state.cheats[i].repeat_add_to_value;
@ -1468,6 +1469,7 @@ 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, 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) unsigned int *prev_value, unsigned int *curr_value)
{ {

View File

@ -90,14 +90,14 @@ struct item_cheat
char *desc; char *desc;
bool state; bool state;
char *code; char *code;
unsigned int handler ; unsigned int handler;
/* Number of bits = 2^memory_search_size /* Number of bits = 2^memory_search_size
* 0=1, 1=2, 2=4, 3=8, 4=16, 5=32 * 0=1, 1=2, 2=4, 3=8, 4=16, 5=32
*/ */
unsigned int memory_search_size ; unsigned int memory_search_size;
unsigned int cheat_type ; unsigned int cheat_type;
unsigned int value ; unsigned int value;
unsigned int address ; unsigned int address;
/* /*
* address_mask used when memory_search_size <8 bits * 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: * if memory_search_size=0, then the number of bits is 1 and this value can be one of the following:
@ -118,20 +118,20 @@ struct item_cheat
* 0 : 00001111 * 0 : 00001111
* 1 : 11110000 * 1 : 11110000
*/ */
unsigned int address_mask ; unsigned int address_mask;
/* Whether to apply the cheat based on big-endian console memory or not */ /* Whether to apply the cheat based on big-endian console memory or not */
bool big_endian ; bool big_endian;
unsigned int rumble_type ; unsigned int rumble_type;
unsigned int rumble_value ; unsigned int rumble_value;
unsigned int rumble_prev_value ; unsigned int rumble_prev_value;
unsigned int rumble_initialized ; unsigned int rumble_initialized;
unsigned int rumble_port ; /* 0-15 for specific port, anything else means "all ports" */ unsigned int rumble_port; /* 0-15 for specific port, anything else means "all ports" */
unsigned int rumble_primary_strength ; /* 0-65535 */ unsigned int rumble_primary_strength; /* 0-65535 */
unsigned int rumble_primary_duration ; /* in milliseconds */ unsigned int rumble_primary_duration; /* in milliseconds */
retro_time_t rumble_primary_end_time ; /* clock value for when rumbling should stop */ retro_time_t rumble_primary_end_time; /* clock value for when rumbling should stop */
unsigned int rumble_secondary_strength ; /* 0-65535 */ unsigned int rumble_secondary_strength; /* 0-65535 */
unsigned int rumble_secondary_duration ; /* in milliseconds */ unsigned int rumble_secondary_duration; /* in milliseconds */
retro_time_t rumble_secondary_end_time ; /* clock value for when rumbling should stop */ 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. * The repeat_ variables allow for a single cheat code to affect multiple memory addresses.
@ -145,9 +145,9 @@ struct item_cheat
* *
* This is a cheating structure used for codes like unlocking all levels, giving yourself 1 of every item,etc. * 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_count;
unsigned int repeat_add_to_value ; unsigned int repeat_add_to_value;
unsigned int repeat_add_to_address ; unsigned int repeat_add_to_address;
}; };
@ -157,29 +157,29 @@ struct cheat_manager
unsigned ptr; unsigned ptr;
unsigned size; unsigned size;
unsigned buf_size; unsigned buf_size;
unsigned total_memory_size ; unsigned total_memory_size;
uint8_t *curr_memory_buf ; uint8_t *curr_memory_buf;
uint8_t *prev_memory_buf ; uint8_t *prev_memory_buf;
uint8_t *matches ; uint8_t *matches;
uint8_t **memory_buf_list ; uint8_t **memory_buf_list;
unsigned *memory_size_list ; unsigned *memory_size_list;
unsigned num_memory_buffers ; unsigned num_memory_buffers;
struct item_cheat working_cheat; struct item_cheat working_cheat;
unsigned match_idx ; unsigned match_idx;
unsigned match_action ; unsigned match_action;
unsigned search_bit_size ; unsigned search_bit_size;
unsigned dummy ; unsigned dummy;
unsigned search_exact_value ; unsigned search_exact_value;
unsigned search_eqplus_value ; unsigned search_eqplus_value;
unsigned search_eqminus_value ; unsigned search_eqminus_value;
unsigned num_matches ; unsigned num_matches;
bool big_endian ; bool big_endian;
bool memory_initialized ; bool memory_initialized;
bool memory_search_initialized ; bool memory_search_initialized;
unsigned int delete_state ; unsigned int delete_state;
unsigned browse_address; unsigned browse_address;
char working_desc[CHEAT_DESC_SCRATCH_SIZE] ; char working_desc[CHEAT_DESC_SCRATCH_SIZE];
char working_code[CHEAT_CODE_SCRATCH_SIZE] ; char working_code[CHEAT_CODE_SCRATCH_SIZE];
unsigned int loading_cheat_size; unsigned int loading_cheat_size;
unsigned int loading_cheat_offset; unsigned int loading_cheat_offset;
}; };

View File

@ -2841,7 +2841,7 @@ static void command_event_init_cheats(void)
cheat_manager_alloc_if_empty(); cheat_manager_alloc_if_empty();
cheat_manager_load_game_specific_cheats(); cheat_manager_load_game_specific_cheats();
if (settings != NULL && settings->bools.apply_cheats_after_load) if (settings && settings->bools.apply_cheats_after_load)
cheat_manager_apply_cheats(); cheat_manager_apply_cheats();
} }
@ -3827,7 +3827,7 @@ bool command_event(enum event_command cmd, void *data)
case CMD_EVENT_LOAD_STATE: case CMD_EVENT_LOAD_STATE:
/* Immutable - disallow savestate load when /* Immutable - disallow savestate load when
* we absolutely cannot change game state. */ * we absolutely cannot change game state. */
if (bsv_movie_state_handle != NULL) if (bsv_movie_state_handle)
return false; return false;
#ifdef HAVE_CHEEVOS #ifdef HAVE_CHEEVOS
@ -17308,7 +17308,7 @@ void video_driver_set_stub_frame(void)
void video_driver_unset_stub_frame(void) void video_driver_unset_stub_frame(void)
{ {
if (frame_bak != NULL) if (frame_bak)
current_video->frame = frame_bak; current_video->frame = frame_bak;
frame_bak = NULL; frame_bak = NULL;