Merge pull request #7438 from RetroSven/master

extend cheat searching to accommodate multiple memory pointers
This commit is contained in:
Twinaphex 2018-10-14 21:24:12 +02:00 committed by GitHub
commit cabb39fc2c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 197 additions and 63 deletions

View File

@ -1290,14 +1290,17 @@ struct retro_hw_render_context_negotiation_interface
* dependence */ * dependence */
#define RETRO_SERIALIZATION_QUIRK_PLATFORM_DEPENDENT (1 << 6) #define RETRO_SERIALIZATION_QUIRK_PLATFORM_DEPENDENT (1 << 6)
#define RETRO_MEMDESC_CONST (1 << 0) /* The frontend will never change this memory area once retro_load_game has returned. */ #define RETRO_MEMDESC_CONST (1 << 0) /* The frontend will never change this memory area once retro_load_game has returned. */
#define RETRO_MEMDESC_BIGENDIAN (1 << 1) /* The memory area contains big endian data. Default is little endian. */ #define RETRO_MEMDESC_BIGENDIAN (1 << 1) /* The memory area contains big endian data. Default is little endian. */
#define RETRO_MEMDESC_ALIGN_2 (1 << 16) /* All memory access in this area is aligned to their own size, or 2, whichever is smaller. */ #define RETRO_MEMDESC_SYSTEM_RAM (1 << 2) /* The memory area is system RAM. This is main RAM of the gaming system. */
#define RETRO_MEMDESC_ALIGN_4 (2 << 16) #define RETRO_MEMDESC_SAVE_RAM (1 << 3) /* The memory area is save RAM. This RAM is usually found on a game cartridge, backed up by a battery. */
#define RETRO_MEMDESC_ALIGN_8 (3 << 16) #define RETRO_MEMDESC_VIDEO_RAM (1 << 4) /* The memory area is video RAM (VRAM) */
#define RETRO_MEMDESC_MINSIZE_2 (1 << 24) /* All memory in this region is accessed at least 2 bytes at the time. */ #define RETRO_MEMDESC_ALIGN_2 (1 << 16) /* All memory access in this area is aligned to their own size, or 2, whichever is smaller. */
#define RETRO_MEMDESC_MINSIZE_4 (2 << 24) #define RETRO_MEMDESC_ALIGN_4 (2 << 16)
#define RETRO_MEMDESC_MINSIZE_8 (3 << 24) #define RETRO_MEMDESC_ALIGN_8 (3 << 16)
#define RETRO_MEMDESC_MINSIZE_2 (1 << 24) /* All memory in this region is accessed at least 2 bytes at the time. */
#define RETRO_MEMDESC_MINSIZE_4 (2 << 24)
#define RETRO_MEMDESC_MINSIZE_8 (3 << 24)
struct retro_memory_descriptor struct retro_memory_descriptor
{ {
uint64_t flags; uint64_t flags;

View File

@ -544,14 +544,22 @@ void cheat_manager_free(void)
if ( cheat_manager_state.matches ) if ( cheat_manager_state.matches )
free(cheat_manager_state.matches); free(cheat_manager_state.matches);
if ( cheat_manager_state.memory_buf_list )
free(cheat_manager_state.memory_buf_list);
if ( cheat_manager_state.memory_size_list )
free(cheat_manager_state.memory_size_list);
cheat_manager_state.cheats = NULL; cheat_manager_state.cheats = NULL;
cheat_manager_state.size = 0; cheat_manager_state.size = 0;
cheat_manager_state.buf_size = 0; cheat_manager_state.buf_size = 0;
cheat_manager_state.prev_memory_buf = NULL; cheat_manager_state.prev_memory_buf = NULL;
cheat_manager_state.curr_memory_buf = NULL; cheat_manager_state.curr_memory_buf = NULL;
cheat_manager_state.memory_buf_list = NULL;
cheat_manager_state.memory_size_list = NULL;
cheat_manager_state.matches = NULL; cheat_manager_state.matches = NULL;
cheat_manager_state.num_memory_buffers = 0;
cheat_manager_state.total_memory_size = 0; cheat_manager_state.total_memory_size = 0;
cheat_manager_state.actual_memory_size = 0;
cheat_manager_state.memory_initialized = false; cheat_manager_state.memory_initialized = false;
cheat_manager_state.memory_search_initialized = false; cheat_manager_state.memory_search_initialized = false;
@ -713,34 +721,105 @@ int cheat_manager_initialize_memory(rarch_setting_t *setting, bool wraparound)
retro_ctx_memory_info_t meminfo; retro_ctx_memory_info_t meminfo;
bool refresh = false; bool refresh = false;
bool is_search_initialization = (setting != NULL); bool is_search_initialization = (setting != NULL);
rarch_system_info_t *system = runloop_get_system_info();
int i ;
unsigned offset = 0;
meminfo.id = RETRO_MEMORY_SYSTEM_RAM; cheat_manager_state.num_memory_buffers = 0 ;
if (!core_get_memory(&meminfo)) cheat_manager_state.total_memory_size = 0 ;
cheat_manager_state.curr_memory_buf = NULL ;
if (cheat_manager_state.memory_buf_list != NULL)
{ {
runloop_msg_queue_push(msg_hash_to_str(MSG_CHEAT_INIT_FAIL), 1, 180, true); free(cheat_manager_state.memory_buf_list) ;
return 0; cheat_manager_state.memory_buf_list = NULL ;
}
if (cheat_manager_state.memory_size_list != NULL)
{
free(cheat_manager_state.memory_size_list) ;
cheat_manager_state.memory_size_list = NULL ;
} }
if ( meminfo.size == 0 ) if (system && system->mmaps.num_descriptors > 0)
return 0; {
for (i = 0; i < system->mmaps.num_descriptors; i++)
{
if ((system->mmaps.descriptors[i].core.flags & RETRO_MEMDESC_SYSTEM_RAM) != 0 &&
system->mmaps.descriptors[i].core.ptr != NULL &&
system->mmaps.descriptors[i].core.len > 0)
{
cheat_manager_state.num_memory_buffers++ ;
if (cheat_manager_state.memory_buf_list == NULL)
cheat_manager_state.memory_buf_list = calloc(1, sizeof(uint8_t *));
else
cheat_manager_state.memory_buf_list = realloc(cheat_manager_state.memory_buf_list, sizeof(uint8_t *)*cheat_manager_state.num_memory_buffers);
if (cheat_manager_state.memory_size_list == NULL)
cheat_manager_state.memory_size_list = calloc(1, sizeof(unsigned));
else
cheat_manager_state.memory_size_list = realloc(cheat_manager_state.memory_size_list, sizeof(unsigned)*cheat_manager_state.num_memory_buffers);
cheat_manager_state.memory_buf_list[cheat_manager_state.num_memory_buffers-1] = system->mmaps.descriptors[i].core.ptr ;
cheat_manager_state.memory_size_list[cheat_manager_state.num_memory_buffers-1] = system->mmaps.descriptors[i].core.len ;
cheat_manager_state.total_memory_size += system->mmaps.descriptors[i].core.len ;
if (cheat_manager_state.curr_memory_buf == NULL)
cheat_manager_state.curr_memory_buf = system->mmaps.descriptors[i].core.ptr;
}
}
}
if (cheat_manager_state.num_memory_buffers == 0)
{
meminfo.id = RETRO_MEMORY_SYSTEM_RAM;
if (!core_get_memory(&meminfo))
{
runloop_msg_queue_push(msg_hash_to_str(MSG_CHEAT_INIT_FAIL), 1, 180, true);
return 0;
}
if (meminfo.size == 0)
return 0;
cheat_manager_state.memory_buf_list = calloc(1, sizeof(uint8_t *));
cheat_manager_state.memory_size_list = calloc(1, sizeof(unsigned));
cheat_manager_state.num_memory_buffers = 1 ;
cheat_manager_state.memory_buf_list[0] = meminfo.data ;
cheat_manager_state.memory_size_list[0] = (unsigned)meminfo.size ;
cheat_manager_state.total_memory_size = (unsigned)meminfo.size;
cheat_manager_state.curr_memory_buf = meminfo.data;
}
cheat_manager_state.actual_memory_size = (unsigned)meminfo.size;
cheat_manager_state.curr_memory_buf = meminfo.data;
cheat_manager_state.total_memory_size = (unsigned)meminfo.size;
cheat_manager_state.num_matches = (cheat_manager_state.total_memory_size*8)/((int)pow(2,cheat_manager_state.search_bit_size)); cheat_manager_state.num_matches = (cheat_manager_state.total_memory_size*8)/((int)pow(2,cheat_manager_state.search_bit_size));
/* Ensure we're aligned on 4-byte boundary */ /* Ensure we're aligned on 4-byte boundary */
#if 0 #if 0
if (meminfo.size % 4 > 0) if (meminfo.size % 4 > 0)
cheat_manager_state.total_memory_size = cheat_manager_state.total_memory_size + (4 - (meminfo.size%4)); cheat_manager_state.total_memory_size = cheat_manager_state.total_memory_size + (4 - (meminfo.size%4));
#endif #endif
if (is_search_initialization) if (is_search_initialization)
{ {
if (cheat_manager_state.prev_memory_buf != NULL)
{
free(cheat_manager_state.prev_memory_buf);
cheat_manager_state.prev_memory_buf = NULL ;
}
cheat_manager_state.prev_memory_buf = (uint8_t*) calloc(cheat_manager_state.total_memory_size, sizeof(uint8_t)); cheat_manager_state.prev_memory_buf = (uint8_t*) calloc(cheat_manager_state.total_memory_size, sizeof(uint8_t));
if (!cheat_manager_state.prev_memory_buf) if (!cheat_manager_state.prev_memory_buf)
{ {
runloop_msg_queue_push(msg_hash_to_str(MSG_CHEAT_INIT_FAIL), 1, 180, true); runloop_msg_queue_push(msg_hash_to_str(MSG_CHEAT_INIT_FAIL), 1, 180, true);
return 0; return 0;
} }
if (cheat_manager_state.matches != NULL)
{
free(cheat_manager_state.matches);
cheat_manager_state.matches = NULL ;
}
cheat_manager_state.matches = (uint8_t*) calloc(cheat_manager_state.total_memory_size, sizeof(uint8_t)); cheat_manager_state.matches = (uint8_t*) calloc(cheat_manager_state.total_memory_size, sizeof(uint8_t));
if (!cheat_manager_state.matches) if (!cheat_manager_state.matches)
{ {
@ -751,7 +830,15 @@ int cheat_manager_initialize_memory(rarch_setting_t *setting, bool wraparound)
} }
memset(cheat_manager_state.matches, 0xFF, cheat_manager_state.total_memory_size); memset(cheat_manager_state.matches, 0xFF, cheat_manager_state.total_memory_size);
memcpy(cheat_manager_state.prev_memory_buf, cheat_manager_state.curr_memory_buf, cheat_manager_state.actual_memory_size);
offset = 0 ;
for ( i = 0 ; i < cheat_manager_state.num_memory_buffers ; i++)
{
memcpy(cheat_manager_state.prev_memory_buf+offset, cheat_manager_state.memory_buf_list[i], cheat_manager_state.memory_size_list[i]);
offset += cheat_manager_state.memory_size_list[i] ;
}
cheat_manager_state.memory_search_initialized = true; cheat_manager_state.memory_search_initialized = true;
} }
@ -771,6 +858,25 @@ int cheat_manager_initialize_memory(rarch_setting_t *setting, bool wraparound)
return 0; return 0;
} }
static unsigned translate_address(unsigned address, unsigned char **curr)
{
unsigned offset = 0 ;
unsigned i = 0 ;
for (i = 0 ; i < cheat_manager_state.num_memory_buffers ; i++ )
{
if ( (address >= offset) && (address < offset+cheat_manager_state.memory_size_list[i]) )
{
*curr = cheat_manager_state.memory_buf_list[i] ;
break ;
}
else
offset += cheat_manager_state.memory_size_list[i] ;
}
return offset ;
}
static void cheat_manager_setup_search_meta(unsigned int bitsize, unsigned int *bytes_per_item, unsigned int *mask, unsigned int *bits) static void cheat_manager_setup_search_meta(unsigned int bitsize, unsigned int *bytes_per_item, unsigned int *mask, unsigned int *bits)
{ {
switch( bitsize) switch( bitsize)
@ -868,9 +974,11 @@ int cheat_manager_search(enum cheat_search_type search_type)
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 offset = 0;
unsigned int i = 0;
bool refresh = false; bool refresh = false;
if (!cheat_manager_state.curr_memory_buf) if (cheat_manager_state.num_memory_buffers == 0)
{ {
runloop_msg_queue_push(msg_hash_to_str(MSG_CHEAT_SEARCH_NOT_INITIALIZED), 1, 180, true); runloop_msg_queue_push(msg_hash_to_str(MSG_CHEAT_SEARCH_NOT_INITIALIZED), 1, 180, true);
return 0; return 0;
@ -884,13 +992,15 @@ int cheat_manager_search(enum cheat_search_type search_type)
{ {
unsigned byte_part; unsigned byte_part;
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)*256) + *(curr+idx+1) : (*(curr+idx-offset)*256) + *(curr+idx+1-offset) :
*(curr+idx) + (*(curr+idx+1)*256); *(curr+idx-offset) + (*(curr+idx+1-offset)*256);
prev_val = cheat_manager_state.big_endian ? prev_val = cheat_manager_state.big_endian ?
(*(prev+idx)*256) + *(prev+idx+1) : (*(prev+idx)*256) + *(prev+idx+1) :
*(prev+idx) + (*(prev+idx+1)*256); *(prev+idx) + (*(prev+idx+1)*256);
@ -899,8 +1009,8 @@ int cheat_manager_search(enum cheat_search_type search_type)
case 4 : case 4 :
{ {
curr_val = cheat_manager_state.big_endian ? curr_val = cheat_manager_state.big_endian ?
(*(curr+idx)*256*256*256) + (*(curr+idx+1)*256*256) + (*(curr+idx+2)*256) + *(curr+idx+3) : (*(curr+idx-offset)*256*256*256) + (*(curr+idx+1-offset)*256*256) + (*(curr+idx+2-offset)*256) + *(curr+idx+3-offset) :
*(curr+idx) + (*(curr+idx+1)*256) + (*(curr+idx+2)*256*256) + (*(curr+idx+3)*256*256*256); *(curr+idx-offset) + (*(curr+idx+1-offset)*256) + (*(curr+idx+2-offset)*256*256) + (*(curr+idx+3-offset)*256*256*256);
prev_val = cheat_manager_state.big_endian ? prev_val = cheat_manager_state.big_endian ?
(*(prev+idx)*256*256*256) + (*(prev+idx+1)*256*256) + (*(prev+idx+2)*256) + *(prev+idx+3) : (*(prev+idx)*256*256*256) + (*(prev+idx+1)*256*256) + (*(prev+idx+2)*256) + *(prev+idx+3) :
*(prev+idx) + (*(prev+idx+1)*256) + (*(prev+idx+2)*256*256) + (*(prev+idx+3)*256*256*256); *(prev+idx) + (*(prev+idx+1)*256) + (*(prev+idx+2)*256*256) + (*(prev+idx+3)*256*256*256);
@ -909,7 +1019,7 @@ int cheat_manager_search(enum cheat_search_type search_type)
case 1 : case 1 :
default : default :
{ {
curr_val = *(curr+idx); curr_val = *(curr-offset+idx);
prev_val = *(prev+idx); prev_val = *(prev+idx);
break; break;
} }
@ -973,7 +1083,13 @@ int cheat_manager_search(enum cheat_search_type search_type)
} }
} }
memcpy(cheat_manager_state.prev_memory_buf, cheat_manager_state.curr_memory_buf, cheat_manager_state.actual_memory_size); offset = 0 ;
for ( i = 0 ; i < cheat_manager_state.num_memory_buffers ; i++)
{
memcpy(cheat_manager_state.prev_memory_buf+offset, cheat_manager_state.memory_buf_list[i], cheat_manager_state.memory_size_list[i]);
offset += cheat_manager_state.memory_size_list[i] ;
}
snprintf(msg, sizeof(msg), msg_hash_to_str(MSG_CHEAT_SEARCH_FOUND_MATCHES), cheat_manager_state.num_matches); snprintf(msg, sizeof(msg), msg_hash_to_str(MSG_CHEAT_SEARCH_FOUND_MATCHES), cheat_manager_state.num_matches);
msg[sizeof(msg) - 1] = 0; msg[sizeof(msg) - 1] = 0;
@ -1015,7 +1131,9 @@ int cheat_manager_add_matches(const char *path,
unsigned int bits = 8; unsigned int bits = 8;
unsigned int curr_val = 0; unsigned int curr_val = 0;
unsigned int num_added = 0; unsigned int num_added = 0;
unsigned char *curr = cheat_manager_state.curr_memory_buf; unsigned int offset = 0;
unsigned int i = 0;
unsigned char *curr = cheat_manager_state.curr_memory_buf;
if ( cheat_manager_state.num_matches + cheat_manager_state.size > 100 ) if ( cheat_manager_state.num_matches + cheat_manager_state.size > 100 )
{ {
@ -1026,21 +1144,23 @@ int cheat_manager_add_matches(const char *path,
for (idx = 0; idx < cheat_manager_state.total_memory_size; idx = idx + bytes_per_item) for (idx = 0; idx < cheat_manager_state.total_memory_size; idx = idx + bytes_per_item)
{ {
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)*256) + *(curr+idx+1) : (*(curr+idx-offset)*256) + *(curr+idx+1-offset) :
*(curr+idx) + (*(curr+idx+1)*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)*256*256*256) + (*(curr+idx+1)*256*256) + (*(curr+idx+2)*256) + *(curr+idx+3) : (*(curr+idx-offset)*256*256*256) + (*(curr+idx+1-offset)*256*256) + (*(curr+idx+2-offset)*256) + *(curr+idx+3-offset) :
*(curr+idx) + (*(curr+idx+1)*256) + (*(curr+idx+2)*256*256) + (*(curr+idx+3)*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); curr_val = *(curr-offset+idx);
break; break;
} }
for (byte_part = 0; byte_part < 8/bits; byte_part++) for (byte_part = 0; byte_part < 8/bits; byte_part++)
@ -1178,6 +1298,7 @@ void cheat_manager_apply_rumble(struct item_cheat *cheat, unsigned int curr_valu
void cheat_manager_apply_retro_cheats(void) void cheat_manager_apply_retro_cheats(void)
{ {
unsigned i; unsigned i;
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;
@ -1216,26 +1337,28 @@ void cheat_manager_apply_retro_cheats(void)
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) ;
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)*256) + *(curr+idx+1) : (*(curr+idx-offset)*256) + *(curr+idx+1-offset) :
*(curr+idx) + (*(curr+idx+1)*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)*256*256*256) + (*(curr+idx+1)*256*256) + (*(curr+idx+2)*256) + *(curr+idx+3) : (*(curr+idx-offset)*256*256*256) + (*(curr+idx+1-offset)*256*256) + (*(curr+idx+2-offset)*256) + *(curr+idx+3-offset) :
*(curr+idx) + (*(curr+idx+1)*256) + (*(curr+idx+2)*256*256) + (*(curr+idx+3)*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); curr_val = *(curr+idx-offset);
break; break;
} }
} }
@ -1283,30 +1406,30 @@ void cheat_manager_apply_retro_cheats(void)
case 2 : case 2 :
if (cheat_manager_state.cheats[i].big_endian) if (cheat_manager_state.cheats[i].big_endian)
{ {
*(curr+idx) = (value_to_set >> 8) & 0xFF; *(curr+idx-offset) = (value_to_set >> 8) & 0xFF;
*(curr+idx+1) = value_to_set & 0xFF; *(curr+idx+1-offset) = value_to_set & 0xFF;
} }
else else
{ {
*(curr+idx) = value_to_set & 0xFF; *(curr+idx-offset) = value_to_set & 0xFF;
*(curr+idx+1) = (value_to_set >> 8) & 0xFF; *(curr+idx+1-offset) = (value_to_set >> 8) & 0xFF;
} }
break; break;
case 4 : case 4 :
if (cheat_manager_state.cheats[i].big_endian) if (cheat_manager_state.cheats[i].big_endian)
{ {
*(curr+idx) = (value_to_set >> 24) & 0xFF; *(curr+idx-offset) = (value_to_set >> 24) & 0xFF;
*(curr+idx+1) = (value_to_set >> 16) & 0xFF; *(curr+idx+1-offset) = (value_to_set >> 16) & 0xFF;
*(curr+idx+2) = (value_to_set >> 8) & 0xFF; *(curr+idx+2-offset) = (value_to_set >> 8) & 0xFF;
*(curr+idx+3) = value_to_set & 0xFF; *(curr+idx+3-offset) = value_to_set & 0xFF;
} }
else else
{ {
*(curr+idx) = value_to_set & 0xFF; *(curr+idx-offset) = value_to_set & 0xFF;
*(curr+idx+1) = (value_to_set >> 8) & 0xFF; *(curr+idx+1-offset) = (value_to_set >> 8) & 0xFF;
*(curr+idx+2) = (value_to_set >> 16) & 0xFF; *(curr+idx+2-offset) = (value_to_set >> 16) & 0xFF;
*(curr+idx+3) = (value_to_set >> 24) & 0xFF; *(curr+idx+3-offset) = (value_to_set >> 24) & 0xFF;
} }
break; break;
@ -1314,7 +1437,7 @@ void cheat_manager_apply_retro_cheats(void)
if (bits < 8) if (bits < 8)
{ {
unsigned bitpos; unsigned bitpos;
unsigned char val = *(curr+idx); unsigned char val = *(curr+idx-offset);
for (bitpos = 0; bitpos < 8; bitpos++) for (bitpos = 0; bitpos < 8; bitpos++)
{ {
@ -1327,13 +1450,13 @@ void cheat_manager_apply_retro_cheats(void)
val = val | (((value_to_set>>bitpos)&0x01)<<bitpos); val = val | (((value_to_set>>bitpos)&0x01)<<bitpos);
} }
} }
*(curr+idx) = val; *(curr+idx-offset) = val;
} }
else else
*(curr+idx) = value_to_set & 0xFF; *(curr+idx-offset) = value_to_set & 0xFF;
break; break;
default : default :
*(curr+idx) = value_to_set & 0xFF; *(curr+idx-offset) = value_to_set & 0xFF;
break; 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;
@ -1358,6 +1481,8 @@ void cheat_manager_apply_retro_cheats(void)
} }
idx = idx%cheat_manager_state.total_memory_size; idx = idx%cheat_manager_state.total_memory_size;
offset = translate_address(idx, &curr) ;
} }
} }
} }
@ -1373,6 +1498,8 @@ void cheat_manager_match_action(enum cheat_match_action_type match_action, unsig
unsigned int bits = 8; unsigned int bits = 8;
unsigned int curr_val = 0; unsigned int curr_val = 0;
unsigned int prev_val = 0; unsigned int prev_val = 0;
unsigned int offset = 0;
unsigned int i = 0;
unsigned char *curr = cheat_manager_state.curr_memory_buf; unsigned char *curr = cheat_manager_state.curr_memory_buf;
unsigned char *prev = cheat_manager_state.prev_memory_buf; unsigned char *prev = cheat_manager_state.prev_memory_buf;
unsigned int curr_match_idx = 0; unsigned int curr_match_idx = 0;
@ -1380,7 +1507,7 @@ void cheat_manager_match_action(enum cheat_match_action_type match_action, unsig
if (target_match_idx > cheat_manager_state.num_matches-1) if (target_match_idx > cheat_manager_state.num_matches-1)
return; return;
if (!curr) if (cheat_manager_state.num_memory_buffers == 0)
return; return;
cheat_manager_setup_search_meta(cheat_manager_state.search_bit_size, &bytes_per_item, &mask, &bits); cheat_manager_setup_search_meta(cheat_manager_state.search_bit_size, &bytes_per_item, &mask, &bits);
@ -1392,12 +1519,14 @@ void cheat_manager_match_action(enum cheat_match_action_type match_action, unsig
for (idx = start_idx; idx < cheat_manager_state.total_memory_size; idx = idx + bytes_per_item) for (idx = start_idx; idx < cheat_manager_state.total_memory_size; idx = idx + bytes_per_item)
{ {
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)*256) + *(curr+idx+1) : (*(curr+idx-offset)*256) + *(curr+idx+1-offset) :
*(curr+idx) + (*(curr+idx+1)*256); *(curr+idx-offset) + (*(curr+idx+1-offset)*256);
if (prev != NULL) if (prev != NULL)
prev_val = cheat_manager_state.big_endian ? prev_val = cheat_manager_state.big_endian ?
(*(prev+idx)*256) + *(prev+idx+1) : (*(prev+idx)*256) + *(prev+idx+1) :
@ -1405,8 +1534,8 @@ void cheat_manager_match_action(enum cheat_match_action_type match_action, unsig
break; break;
case 4 : case 4 :
curr_val = cheat_manager_state.big_endian ? curr_val = cheat_manager_state.big_endian ?
(*(curr+idx)*256*256*256) + (*(curr+idx+1)*256*256) + (*(curr+idx+2)*256) + *(curr+idx+3) : (*(curr+idx-offset)*256*256*256) + (*(curr+idx+1-offset)*256*256) + (*(curr+idx+2-offset)*256) + *(curr+idx+3-offset) :
*(curr+idx) + (*(curr+idx+1)*256) + (*(curr+idx+2)*256*256) + (*(curr+idx+3)*256*256*256); *(curr+idx-offset) + (*(curr+idx+1-offset)*256) + (*(curr+idx+2-offset)*256*256) + (*(curr+idx+3-offset)*256*256*256);
if (prev != NULL) if (prev != NULL)
prev_val = cheat_manager_state.big_endian ? prev_val = cheat_manager_state.big_endian ?
(*(prev+idx)*256*256*256) + (*(prev+idx+1)*256*256) + (*(prev+idx+2)*256) + *(prev+idx+3) : (*(prev+idx)*256*256*256) + (*(prev+idx+1)*256*256) + (*(prev+idx+2)*256) + *(prev+idx+3) :
@ -1414,7 +1543,7 @@ void cheat_manager_match_action(enum cheat_match_action_type match_action, unsig
break; break;
case 1 : case 1 :
default : default :
curr_val = *(curr+idx); curr_val = *(curr+idx-offset);
if (prev != NULL) if (prev != NULL)
prev_val = *(prev+idx); prev_val = *(prev+idx);
break; break;

View File

@ -159,10 +159,12 @@ struct cheat_manager
unsigned size; unsigned size;
unsigned buf_size; unsigned buf_size;
unsigned total_memory_size ; unsigned total_memory_size ;
unsigned actual_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 ;
unsigned *memory_size_list ;
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 ;

View File

@ -5367,7 +5367,7 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data)
setting = menu_setting_find_enum(MENU_ENUM_LABEL_CHEAT_BROWSE_MEMORY); setting = menu_setting_find_enum(MENU_ENUM_LABEL_CHEAT_BROWSE_MEMORY);
if ( setting ) if ( setting )
setting->max = cheat_manager_state.actual_memory_size>0?cheat_manager_state.actual_memory_size-1:0 ; setting->max = cheat_manager_state.total_memory_size>0?cheat_manager_state.total_memory_size-1:0 ;
menu_displaylist_parse_settings_enum(menu, info, menu_displaylist_parse_settings_enum(menu, info,
@ -5571,7 +5571,7 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data)
setting->max = cheat_manager_state.num_matches-1; setting->max = cheat_manager_state.num_matches-1;
setting = menu_setting_find_enum(MENU_ENUM_LABEL_CHEAT_BROWSE_MEMORY); setting = menu_setting_find_enum(MENU_ENUM_LABEL_CHEAT_BROWSE_MEMORY);
if (setting) if (setting)
setting->max = cheat_manager_state.actual_memory_size>0?cheat_manager_state.actual_memory_size-1:0 ; setting->max = cheat_manager_state.total_memory_size>0?cheat_manager_state.total_memory_size-1:0 ;
info->need_refresh = true; info->need_refresh = true;
info->need_push = true; info->need_push = true;

View File

@ -4985,7 +4985,7 @@ static bool setting_append_list(
parent_group, parent_group,
general_write_handler, general_write_handler,
general_read_handler); general_read_handler);
menu_settings_list_current_add_range(list, list_info, 0, cheat_manager_state.actual_memory_size>0?cheat_manager_state.actual_memory_size-1:0, 1, true, true); menu_settings_list_current_add_range(list, list_info, 0, cheat_manager_state.total_memory_size>0?cheat_manager_state.total_memory_size-1:0, 1, true, true);
(*list)[list_info->index - 1].action_left = &setting_uint_action_left_with_refresh; (*list)[list_info->index - 1].action_left = &setting_uint_action_left_with_refresh;
(*list)[list_info->index - 1].action_right = &setting_uint_action_right_with_refresh; (*list)[list_info->index - 1].action_right = &setting_uint_action_right_with_refresh;
(*list)[list_info->index - 1].get_string_representation = &setting_get_string_representation_uint_cheat_browse_address; (*list)[list_info->index - 1].get_string_representation = &setting_get_string_representation_uint_cheat_browse_address;