diff --git a/command.c b/command.c index 7b6b682336..928833b882 100644 --- a/command.c +++ b/command.c @@ -1066,6 +1066,7 @@ static void command_event_deinit_core(bool reinit) static void command_event_init_cheats(void) { bool allow_cheats = true; + #ifdef HAVE_NETWORKING allow_cheats &= !netplay_driver_ctl( RARCH_NETPLAY_CTL_IS_DATA_INITED, NULL); @@ -1075,6 +1076,8 @@ static void command_event_init_cheats(void) if (!allow_cheats) return; + cheat_manager_alloc_if_empty() ; + cheat_manager_load_game_specific_cheats() ; /* TODO/FIXME - add some stuff here. */ } diff --git a/gfx/drivers_context/wayland_ctx.c b/gfx/drivers_context/wayland_ctx.c index 1732b21e3c..decbdedadd 100644 --- a/gfx/drivers_context/wayland_ctx.c +++ b/gfx/drivers_context/wayland_ctx.c @@ -206,7 +206,7 @@ static void keyboard_handle_modifiers(void *data, #endif } -static void keyboard_handle_repeat_info(void *data, +void keyboard_handle_repeat_info(void *data, struct wl_keyboard *wl_keyboard, int32_t rate, int32_t delay) @@ -223,8 +223,8 @@ static const struct wl_keyboard_listener keyboard_listener = { keyboard_handle_enter, keyboard_handle_leave, keyboard_handle_key, - keyboard_handle_modifiers, - keyboard_handle_repeat_info, + keyboard_handle_modifiers + //keyboard_handle_repeat_info }; static void gfx_ctx_wl_show_mouse(void *data, bool state); diff --git a/intl/msg_hash_lbl.h b/intl/msg_hash_lbl.h index 779c44441d..e4eb56b8ed 100644 --- a/intl/msg_hash_lbl.h +++ b/intl/msg_hash_lbl.h @@ -126,6 +126,8 @@ MSG_HASH(MENU_ENUM_LABEL_CHEAT_DATABASE_PATH, "cheat_database_path") MSG_HASH(MENU_ENUM_LABEL_CHEAT_FILE_LOAD, "cheat_file_load") +MSG_HASH(MENU_ENUM_LABEL_CHEAT_FILE_LOAD_APPEND, + "cheat_file_load_append") MSG_HASH(MENU_ENUM_LABEL_CHEAT_FILE_SAVE_AS, "cheat_file_save_as") MSG_HASH(MENU_ENUM_LABEL_CHEAT_NUM_PASSES, @@ -343,6 +345,10 @@ MSG_HASH(MENU_ENUM_LABEL_DEFERRED_RETRO_ACHIEVEMENTS_SETTINGS_LIST, "deferred_retro_achievements_settings_list") MSG_HASH(MENU_ENUM_LABEL_DEFERRED_REWIND_SETTINGS_LIST, "deferred_rewind_settings_list") +MSG_HASH(MENU_ENUM_LABEL_DEFERRED_CHEAT_DETAILS_SETTINGS_LIST, + "deferred_cheat_details_settings_list") +MSG_HASH(MENU_ENUM_LABEL_DEFERRED_CHEAT_SEARCH_SETTINGS_LIST, + "deferred_cheat_search_settings_list") MSG_HASH(MENU_ENUM_LABEL_DEFERRED_SAVING_SETTINGS_LIST, "deferred_saving_settings_list") MSG_HASH(MENU_ENUM_LABEL_DEFERRED_THUMBNAILS_UPDATER_LIST, @@ -1539,3 +1545,93 @@ MSG_HASH(MENU_ENUM_LABEL_MIDI_VOLUME, "midi_volume") MSG_HASH(MENU_ENUM_LABEL_SUSTAINED_PERFORMANCE_MODE, "sustained_performance_mode") +MSG_HASH(MENU_ENUM_LABEL_CHEAT_IDX, + "cheat_idx") +MSG_HASH(MENU_ENUM_LABEL_CHEAT_DESC, + "cheat_desc") +MSG_HASH(MENU_ENUM_LABEL_CHEAT_STATE, + "cheat_state") +MSG_HASH(MENU_ENUM_LABEL_CHEAT_CODE, + "cheat_code") +MSG_HASH(MENU_ENUM_LABEL_CHEAT_HANDLER, + "cheat_handler") +MSG_HASH(MENU_ENUM_LABEL_CHEAT_MEMORY_SEARCH_SIZE, + "cheat_memory_search_size") +MSG_HASH(MENU_ENUM_LABEL_CHEAT_TYPE, + "cheat_type") +MSG_HASH(MENU_ENUM_LABEL_CHEAT_VALUE, + "cheat_value") +MSG_HASH(MENU_ENUM_LABEL_CHEAT_ADDRESS, + "cheat_address") +MSG_HASH(MENU_ENUM_LABEL_CHEAT_ADDRESS_BIT_POSITION, + "cheat_address_bit_position") +MSG_HASH(MENU_ENUM_LABEL_CHEAT_RUMBLE_TYPE, + "cheat_rumble_type") +MSG_HASH(MENU_ENUM_LABEL_CHEAT_RUMBLE_VALUE, + "cheat_rumble_value") +MSG_HASH(MENU_ENUM_LABEL_CHEAT_RUMBLE_PORT, + "cheat_rumble_port") +MSG_HASH(MENU_ENUM_LABEL_CHEAT_RUMBLE_PRIMARY_STRENGTH, + "cheat_rumble_primary_strength") +MSG_HASH(MENU_ENUM_LABEL_CHEAT_RUMBLE_PRIMARY_DURATION, + "cheat_rumble_primary_duration") +MSG_HASH(MENU_ENUM_LABEL_CHEAT_RUMBLE_SECONDARY_STRENGTH, + "cheat_rumble_secondary_strength") +MSG_HASH(MENU_ENUM_LABEL_CHEAT_RUMBLE_SECONDARY_DURATION, + "cheat_rumble_secondary_duration") +MSG_HASH(MENU_ENUM_LABEL_CHEAT_ADD_NEW_AFTER, + "cheat_add_new_after") +MSG_HASH(MENU_ENUM_LABEL_CHEAT_ADD_NEW_BEFORE, + "cheat_add_new_before") +MSG_HASH(MENU_ENUM_LABEL_CHEAT_COPY_AFTER, + "cheat_copy_after") +MSG_HASH(MENU_ENUM_LABEL_CHEAT_COPY_BEFORE, + "cheat_copy_before") +MSG_HASH(MENU_ENUM_LABEL_CHEAT_DELETE, + "cheat_delete") +MSG_HASH(MENU_ENUM_LABEL_CHEAT_START_OR_CONT, + "cheat_start_or_cont") +MSG_HASH(MENU_ENUM_LABEL_CHEAT_START_OR_RESTART, + "cheat_start_or_restart") +MSG_HASH(MENU_ENUM_LABEL_CHEAT_SEARCH_EXACT, + "cheat_search_exact") +MSG_HASH(MENU_ENUM_LABEL_CHEAT_SEARCH_LT, + "cheat_search_lt") +MSG_HASH(MENU_ENUM_LABEL_CHEAT_SEARCH_GT, + "cheat_search_gt") +MSG_HASH(MENU_ENUM_LABEL_CHEAT_SEARCH_LTE, + "cheat_search_lte") +MSG_HASH(MENU_ENUM_LABEL_CHEAT_SEARCH_GTE, + "cheat_search_gte") +MSG_HASH(MENU_ENUM_LABEL_CHEAT_SEARCH_EQ, + "cheat_search_eq") +MSG_HASH(MENU_ENUM_LABEL_CHEAT_SEARCH_NEQ, + "cheat_search_neq") +MSG_HASH(MENU_ENUM_LABEL_CHEAT_SEARCH_EQPLUS, + "cheat_search_eqplus") +MSG_HASH(MENU_ENUM_LABEL_CHEAT_SEARCH_EQMINUS, + "cheat_search_eqminus") +MSG_HASH(MENU_ENUM_LABEL_CHEAT_ADD_MATCHES, + "cheat_add_matches") +MSG_HASH(MENU_ENUM_LABEL_CHEAT_VIEW_MATCHES, + "cheat_view_matches") +MSG_HASH(MENU_ENUM_LABEL_CHEAT_CREATE_OPTION, + "cheat_create_option") +MSG_HASH(MENU_ENUM_LABEL_CHEAT_DELETE_OPTION, + "cheat_delete_option") +MSG_HASH(MENU_ENUM_LABEL_CHEAT_ADD_NEW_TOP, + "cheat_add_new_top") +MSG_HASH(MENU_ENUM_LABEL_CHEAT_ADD_NEW_BOTTOM, + "cheat_add_new_bottom") +MSG_HASH(MENU_ENUM_LABEL_CHEAT_DELETE_ALL, + "cheat_delete_all") +MSG_HASH(MENU_ENUM_LABEL_CHEAT_BIG_ENDIAN, + "cheat_big_endian") +MSG_HASH(MENU_ENUM_LABEL_CHEAT_MATCH_IDX, + "cheat_match_idx") +MSG_HASH(MENU_ENUM_LABEL_CHEAT_MATCH, + "cheat_match") +MSG_HASH(MENU_ENUM_LABEL_CHEAT_COPY_MATCH, + "cheat_copy_match") +MSG_HASH(MENU_ENUM_LABEL_CHEAT_DELETE_MATCH, + "cheat_delete_match") diff --git a/intl/msg_hash_us.c b/intl/msg_hash_us.c index a828781ee8..10b9396111 100644 --- a/intl/msg_hash_us.c +++ b/intl/msg_hash_us.c @@ -1945,6 +1945,87 @@ int menu_hash_get_help_us_enum(enum msg_hash_enums msg, char *s, size_t len) snprintf(s, len, "Toggle cheat index.\n"); break; + case MENU_ENUM_LABEL_CHEAT_IDX: + snprintf(s, len, + "Index position in list.\n"); + break; + case MENU_ENUM_LABEL_CHEAT_ADDRESS_BIT_POSITION: + snprintf(s, len, + "Address bitmask when Memory Search Size < 8-bit.\n"); + break; + case MENU_ENUM_LABEL_CHEAT_MATCH_IDX: + snprintf(s, len, + "Select the match to view."); + break; + case MENU_ENUM_LABEL_CHEAT_START_OR_CONT: + snprintf(s, len, + "Scan memory to create new cheats"); + break; + case MENU_ENUM_LABEL_CHEAT_START_OR_RESTART: + snprintf(s, len, + "Left/Right to change bit-size\n"); + break; + case MENU_ENUM_LABEL_CHEAT_SEARCH_EXACT: + snprintf(s, len, + "Left/Right to change value\n"); + break; + case MENU_ENUM_LABEL_CHEAT_SEARCH_LT: + snprintf(s, len, + " "); + break; + case MENU_ENUM_LABEL_CHEAT_SEARCH_GT: + snprintf(s, len, + " "); + break; + case MENU_ENUM_LABEL_CHEAT_SEARCH_EQ: + snprintf(s, len, + " "); + break; + case MENU_ENUM_LABEL_CHEAT_SEARCH_NEQ: + snprintf(s, len, + " "); + break; + case MENU_ENUM_LABEL_CHEAT_SEARCH_EQPLUS: + snprintf(s, len, + "Left/Right to change value\n"); + break; + case MENU_ENUM_LABEL_CHEAT_SEARCH_EQMINUS: + snprintf(s, len, + "Left/Right to change value\n"); + break; + case MENU_ENUM_LABEL_CHEAT_ADD_MATCHES: + snprintf(s, len, + " "); + break; + case MENU_ENUM_LABEL_CHEAT_VIEW_MATCHES: + snprintf(s, len, + " "); + break; + case MENU_ENUM_LABEL_CHEAT_CREATE_OPTION: + snprintf(s, len, + " "); + break; + case MENU_ENUM_LABEL_CHEAT_DELETE_OPTION: + snprintf(s, len, + " "); + break; + case MENU_ENUM_LABEL_CHEAT_ADD_NEW_TOP: + snprintf(s, len, + " "); + break; + case MENU_ENUM_LABEL_CHEAT_ADD_NEW_BOTTOM: + snprintf(s, len, + " "); + break; + case MENU_ENUM_LABEL_CHEAT_DELETE_ALL: + snprintf(s, len, + " "); + break; + case MENU_ENUM_LABEL_CHEAT_BIG_ENDIAN: + snprintf(s, len, + "Big endian : 258 = 0x0102\n" + "Little endian : 258 = 0x0201"); + break; case MENU_ENUM_LABEL_HOLD_FAST_FORWARD: snprintf(s, len, "Hold for fast-forward. Releasing button \n" diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index 506655743d..97dde27334 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -442,6 +442,14 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_CHEAT_APPLY_CHANGES, "Apply Changes" ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_START_SEARCH, + "Start Search For New Cheat Code" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_CONTINUE_SEARCH, + "Continue Search" + ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CHEAT_DATABASE_PATH, "Cheat File" @@ -452,7 +460,11 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CHEAT_FILE_LOAD, - "Load Cheat File" + "Load Cheat File (Replace)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_FILE_LOAD_APPEND, + "Load Cheat File (Append)" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CHEAT_FILE_SAVE_AS, @@ -905,6 +917,10 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_RESET, "Reset game") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_REWIND, "Rewind") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_CHEAT_DETAILS, + "Cheat Details") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_CHEAT_SEARCH, + "Start or Continue Cheat Search") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_SAVE_STATE_KEY, "Save state") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_SCREENSHOT, @@ -1387,6 +1403,10 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_REWIND_BUFFER_SIZE_STEP, "Rewind Buffer Size Step (MB)") MSG_HASH(MENU_ENUM_LABEL_VALUE_REWIND_SETTINGS, "Rewind") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_DETAILS_SETTINGS, + "Cheat Details") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_SETTINGS, + "Start or Continue Cheat Search") MSG_HASH(MENU_ENUM_LABEL_VALUE_RGUI_BROWSER_DIRECTORY, "File Browser") MSG_HASH(MENU_ENUM_LABEL_VALUE_RGUI_CONFIG_DIRECTORY, @@ -2814,6 +2834,94 @@ MSG_HASH( MENU_ENUM_SUBLABEL_REWIND_BUFFER_SIZE_STEP, "Each time you increase or decrease the rewind buffer size value via this UI it will change by this amount" ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEAT_IDX, + "Index position in list." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEAT_ADDRESS_BIT_POSITION, + "Address bitmask when Memory Search Size < 8-bit." +) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEAT_MATCH_IDX, + "Select the match to view." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEAT_START_OR_CONT, + "" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEAT_START_OR_RESTART, + "Left/Right to change bit-size" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEAT_SEARCH_EXACT, + "Left/Right to change value" +) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEAT_SEARCH_LT, + "" +) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEAT_SEARCH_GT, + "" +) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEAT_SEARCH_LTE, + "" +) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEAT_SEARCH_GTE, + "" +) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEAT_SEARCH_EQ, + "" +) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEAT_SEARCH_NEQ, + "" +) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEAT_SEARCH_EQPLUS, + "Left/Right to change value" +) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEAT_SEARCH_EQMINUS, + "Left/Right to change value" +) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEAT_ADD_MATCHES, + "" +) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEAT_VIEW_MATCHES, + "" +) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEAT_CREATE_OPTION, + "" +) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEAT_DELETE_OPTION, + "" +) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEAT_ADD_NEW_TOP, + "" +) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEAT_ADD_NEW_BOTTOM, + "" +) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEAT_DELETE_ALL, + "" +) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEAT_BIG_ENDIAN, + "Big endian : 258 = 0x0102,\nLittle endian : 258 = 0x0201" + ) MSG_HASH( MENU_ENUM_SUBLABEL_LIBRETRO_LOG_LEVEL, "Sets log level for cores. If a log level issued by a core is below this value, it is ignored." @@ -3107,6 +3215,10 @@ MSG_HASH( ) MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_META_REWIND, "Manages rewind settings.") +MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_META_CHEAT_DETAILS, + "Manages cheat details settings.") +MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_META_CHEAT_SEARCH, + "Start or continue a cheat code search.") MSG_HASH(MENU_ENUM_SUBLABEL_RESTART_CONTENT, "Restarts the content from the beginning.") MSG_HASH(MENU_ENUM_SUBLABEL_SAVE_CURRENT_CONFIG_OVERRIDE_CORE, @@ -3282,9 +3394,17 @@ MSG_HASH( ) MSG_HASH(MENU_ENUM_SUBLABEL_CHEAT_APPLY_CHANGES, "Cheat changes will take effect immediately.") +MSG_HASH(MENU_ENUM_SUBLABEL_CHEAT_START_SEARCH, + "Start search for a new cheat. Number of bits can be changed.") +MSG_HASH(MENU_ENUM_SUBLABEL_CHEAT_CONTINUE_SEARCH, + "Continue search for a new cheat.") MSG_HASH( MENU_ENUM_SUBLABEL_CHEAT_FILE_LOAD, - "Load a cheat file." + "Load a cheat file and replace existing cheats." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEAT_FILE_LOAD_APPEND, + "Load a cheat file and append to existing cheats." ) MSG_HASH( MENU_ENUM_SUBLABEL_CHEAT_FILE_SAVE_AS, @@ -3780,3 +3900,235 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_SUSTAINED_PERFORMANCE_MODE, "Sustained Performance Mode") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_MPV_SUPPORT, "mpv support") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_IDX, + "Index") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_MATCH_IDX, + "View Match #") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_MATCH, + "Match Address: %08X Mask: %02X") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_COPY_MATCH, + "Create Code Match #") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_DELETE_MATCH, + "Delete Match #") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_DESC, + "Description") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_STATE, + "Enabled") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_CODE, + "Code") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_HANDLER, + "Handler") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_MEMORY_SEARCH_SIZE, + "Memory Search Size") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_TYPE, + "Type") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_VALUE, + "Value") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_ADDRESS, + "Memory Address") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_ADDRESS_BIT_POSITION, + "Memory Address Mask") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_RUMBLE_TYPE, + "Rumble When Memory") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_RUMBLE_VALUE, + "Rumble Value") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_RUMBLE_PORT, + "Rumble Port") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_RUMBLE_PRIMARY_STRENGTH, + "Rumble Primary Strength") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_RUMBLE_PRIMARY_DURATION, + "Rumble Primary Duration (ms)") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_RUMBLE_SECONDARY_STRENGTH, + "Rumble Secondary Strength") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_RUMBLE_SECONDARY_DURATION, + "Rumble Secondary Duration (ms)") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_ADD_NEW_AFTER, + "Add New Cheat After This One") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_ADD_NEW_BEFORE, + "Add New Cheat Before This One") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_COPY_AFTER, + "Copy This Cheat After") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_COPY_BEFORE, + "Copy This Cheat Before") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_DELETE, + "Delete This Cheat") +MSG_HASH(MENU_ENUM_LABEL_CHEAT_HANDLER_TYPE_EMU, + "Emulator") +MSG_HASH(MENU_ENUM_LABEL_CHEAT_HANDLER_TYPE_RETRO, + "RetroArch") +MSG_HASH(MENU_ENUM_LABEL_CHEAT_TYPE_DISABLED, + "") +MSG_HASH(MENU_ENUM_LABEL_CHEAT_TYPE_SET_TO_VALUE, + "Set To Value") +MSG_HASH(MENU_ENUM_LABEL_CHEAT_TYPE_INCREASE_VALUE, + "Increase By Value") +MSG_HASH(MENU_ENUM_LABEL_CHEAT_TYPE_DECREASE_VALUE, + "Decrease By Value") +MSG_HASH(MENU_ENUM_LABEL_CHEAT_TYPE_RUN_NEXT_IF_EQ, + "Run next cheat if value = memory") +MSG_HASH(MENU_ENUM_LABEL_CHEAT_TYPE_RUN_NEXT_IF_NEQ, + "Run next cheat if value != memory") +MSG_HASH(MENU_ENUM_LABEL_CHEAT_TYPE_RUN_NEXT_IF_LT, + "Run next cheat if value < memory") +MSG_HASH(MENU_ENUM_LABEL_CHEAT_TYPE_RUN_NEXT_IF_GT, + "Run next cheat if value > memory") +MSG_HASH(MENU_ENUM_LABEL_RUMBLE_TYPE_DISABLED, + "") +MSG_HASH(MENU_ENUM_LABEL_RUMBLE_TYPE_CHANGES, + "Changes") +MSG_HASH(MENU_ENUM_LABEL_RUMBLE_TYPE_DOES_NOT_CHANGE, + "Does Not Change") +MSG_HASH(MENU_ENUM_LABEL_RUMBLE_TYPE_INCREASE, + "Increases") +MSG_HASH(MENU_ENUM_LABEL_RUMBLE_TYPE_DECREASE, + "Decreases") +MSG_HASH(MENU_ENUM_LABEL_RUMBLE_TYPE_EQ_VALUE, + "= Rumble Value") +MSG_HASH(MENU_ENUM_LABEL_RUMBLE_TYPE_NEQ_VALUE, + "!= Rumble Value") +MSG_HASH(MENU_ENUM_LABEL_RUMBLE_TYPE_LT_VALUE, + "< Rumble Value") +MSG_HASH(MENU_ENUM_LABEL_RUMBLE_TYPE_GT_VALUE, + "> Rumble Value") +MSG_HASH(MENU_ENUM_LABEL_CHEAT_MEMORY_SIZE_1, + "1-bit, max value = 0x01") +MSG_HASH(MENU_ENUM_LABEL_CHEAT_MEMORY_SIZE_2, + "2-bit, max value = 0x03") +MSG_HASH(MENU_ENUM_LABEL_CHEAT_MEMORY_SIZE_4, + "4-bit, max value = 0x0F") +MSG_HASH(MENU_ENUM_LABEL_CHEAT_MEMORY_SIZE_8, + "8-bit, max value = 0xFF") +MSG_HASH(MENU_ENUM_LABEL_CHEAT_MEMORY_SIZE_16, + "16-bit, max value = 0xFFFF") +MSG_HASH(MENU_ENUM_LABEL_CHEAT_MEMORY_SIZE_32, + "32-bit, max value = 0xFFFFFFFF") +MSG_HASH(MENU_ENUM_LABEL_RUMBLE_PORT_0, + "1") +MSG_HASH(MENU_ENUM_LABEL_RUMBLE_PORT_1, + "2") +MSG_HASH(MENU_ENUM_LABEL_RUMBLE_PORT_2, + "3") +MSG_HASH(MENU_ENUM_LABEL_RUMBLE_PORT_3, + "4") +MSG_HASH(MENU_ENUM_LABEL_RUMBLE_PORT_4, + "5") +MSG_HASH(MENU_ENUM_LABEL_RUMBLE_PORT_5, + "6") +MSG_HASH(MENU_ENUM_LABEL_RUMBLE_PORT_6, + "7") +MSG_HASH(MENU_ENUM_LABEL_RUMBLE_PORT_7, + "8") +MSG_HASH(MENU_ENUM_LABEL_RUMBLE_PORT_8, + "9") +MSG_HASH(MENU_ENUM_LABEL_RUMBLE_PORT_9, + "10") +MSG_HASH(MENU_ENUM_LABEL_RUMBLE_PORT_10, + "11") +MSG_HASH(MENU_ENUM_LABEL_RUMBLE_PORT_11, + "12") +MSG_HASH(MENU_ENUM_LABEL_RUMBLE_PORT_12, + "13") +MSG_HASH(MENU_ENUM_LABEL_RUMBLE_PORT_13, + "14") +MSG_HASH(MENU_ENUM_LABEL_RUMBLE_PORT_14, + "15") +MSG_HASH(MENU_ENUM_LABEL_RUMBLE_PORT_15, + "16") +MSG_HASH(MENU_ENUM_LABEL_RUMBLE_PORT_16, + "All") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_START_OR_CONT, + "Start or Continue Cheat Search") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_START_OR_RESTART, + "Start or Restart Cheat Search") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_EXACT, + "Search Memory For Values") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_LT, + "Search Memory For Values") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_GT, + "Search Memory For Values") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_EQ, + "Search Memory For Values") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_GTE, + "Search Memory For Values") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_LTE, + "Search Memory For Values") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_NEQ, + "Search Memory For Values") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_EQPLUS, + "Search Memory For Values") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_EQMINUS, + "Search Memory For Values") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_ADD_MATCHES, + "Add the %u Matches to Your List") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_VIEW_MATCHES, + "View the List of %u Matches") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_CREATE_OPTION, + "Create Code From This Match") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_DELETE_OPTION, + "Delete This Match") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_ADD_NEW_TOP, + "Add New Code to Top") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_ADD_NEW_BOTTOM, + "Add New Code to Bottom") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_DELETE_ALL, + "Delete All Codes") +MSG_HASH(MENU_ENUM_LABEL_CHEAT_SEARCH_EXACT_VAL, + "Equal to %u (%X)") +MSG_HASH(MENU_ENUM_LABEL_CHEAT_SEARCH_LT_VAL, + "Less Than Before") +MSG_HASH(MENU_ENUM_LABEL_CHEAT_SEARCH_GT_VAL, + "Greater Than Before") +MSG_HASH(MENU_ENUM_LABEL_CHEAT_SEARCH_LTE_VAL, + "Less Than or Equal To Before") +MSG_HASH(MENU_ENUM_LABEL_CHEAT_SEARCH_GTE_VAL, + "Greater Than or Equal To Before") +MSG_HASH(MENU_ENUM_LABEL_CHEAT_SEARCH_EQ_VAL, + "Equal to Before") +MSG_HASH(MENU_ENUM_LABEL_CHEAT_SEARCH_NEQ_VAL, + "Not Equal to Before") +MSG_HASH(MENU_ENUM_LABEL_CHEAT_SEARCH_EQPLUS_VAL, + "Equal to Before+%u (%X)") +MSG_HASH(MENU_ENUM_LABEL_CHEAT_SEARCH_EQMINUS_VAL, + "Equal to Before-%u (%X)") +MSG_HASH(MENU_ENUM_LABEL_CHEAT_SEARCH_SETTINGS, + "Start or Continue Cheat Search") +MSG_HASH(MSG_CHEAT_INIT_SUCCESS, + "Successfully started cheat search") +MSG_HASH(MSG_CHEAT_INIT_FAIL, + "Failed to start cheat search") +MSG_HASH(MSG_CHEAT_SEARCH_NOT_INITIALIZED, + "Searching has not been initialized/started") +MSG_HASH(MSG_CHEAT_SEARCH_FOUND_MATCHES, + "New match count = %u") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_BIG_ENDIAN, + "Big Endian") +MSG_HASH(MSG_CHEAT_SEARCH_ADDED_MATCHES_SUCCESS, + "Added %u matches") +MSG_HASH(MSG_CHEAT_SEARCH_ADDED_MATCHES_FAIL, + "Failed to add matches") +MSG_HASH(MSG_CHEAT_SEARCH_ADD_MATCH_SUCCESS, + "Created code from match") +MSG_HASH(MSG_CHEAT_SEARCH_ADD_MATCH_FAIL, + "Failed to create code") +MSG_HASH(MSG_CHEAT_SEARCH_DELETE_MATCH_SUCCESS, + "Deleted match") +MSG_HASH(MSG_CHEAT_SEARCH_ADDED_MATCHES_TOO_MANY, + "Not enough room. The total number of cheats you can have is 100.") +MSG_HASH(MSG_CHEAT_ADD_TOP_SUCCESS, + "New cheat added to top of list.") +MSG_HASH(MSG_CHEAT_ADD_BOTTOM_SUCCESS, + "New cheat added to bottom of list.") +MSG_HASH(MSG_CHEAT_DELETE_ALL_INSTRUCTIONS, + "Press right five times to delete all cheats.") +MSG_HASH(MSG_CHEAT_DELETE_ALL_SUCCESS, + "All cheats deleted.") +MSG_HASH(MSG_CHEAT_ADD_BEFORE_SUCCESS, + "New cheat added before this one.") +MSG_HASH(MSG_CHEAT_ADD_AFTER_SUCCESS, + "New cheat added after this one.") +MSG_HASH(MSG_CHEAT_COPY_BEFORE_SUCCESS, + "Cheat copied before this one.") +MSG_HASH(MSG_CHEAT_COPY_AFTER_SUCCESS, + "Cheat copied after this one.") +MSG_HASH(MSG_CHEAT_DELETE_SUCCESS, + "Cheat deleted.") diff --git a/libretro-common/file/config_file.c b/libretro-common/file/config_file.c index 942de7da65..15ce4336d1 100644 --- a/libretro-common/file/config_file.c +++ b/libretro-common/file/config_file.c @@ -843,6 +843,15 @@ void config_set_int(config_file_t *conf, const char *key, int val) config_set_string(conf, key, buf); } +void config_set_uint(config_file_t *conf, const char *key, unsigned int val) +{ + char buf[128]; + + buf[0] = '\0'; + snprintf(buf, sizeof(buf), "%u", val); + config_set_string(conf, key, buf); +} + void config_set_hex(config_file_t *conf, const char *key, unsigned val) { char buf[128]; diff --git a/libretro-common/include/file/config_file.h b/libretro-common/include/file/config_file.h index 3ee7f51333..97fca031a3 100644 --- a/libretro-common/include/file/config_file.h +++ b/libretro-common/include/file/config_file.h @@ -164,6 +164,7 @@ void config_set_string(config_file_t *conf, const char *entry, const char *val); void config_unset(config_file_t *conf, const char *key); void config_set_path(config_file_t *conf, const char *entry, const char *val); void config_set_bool(config_file_t *conf, const char *entry, bool val); +void config_set_uint(config_file_t *conf, const char *key, unsigned int val); /* Write the current config to a file. */ bool config_file_write(config_file_t *conf, const char *path); diff --git a/managers/cheat_manager.c b/managers/cheat_manager.c index 888175171a..de7128bf48 100644 --- a/managers/cheat_manager.c +++ b/managers/cheat_manager.c @@ -24,11 +24,18 @@ #include #include #include +#include #ifdef HAVE_CONFIG_H #include "../config.h" #endif +#ifdef HAVE_MENU +#include "menu/menu_driver.h" +#include "menu/widgets/menu_input_dialog.h" +#include "menu/widgets/menu_input_bind_dialog.h" +#endif + #ifdef HAVE_CHEEVOS #include "../cheevos/cheevos.h" #endif @@ -40,38 +47,17 @@ #include "../dynamic.h" #include "../core.h" #include "../verbosity.h" +#include "../input/input_driver.h" -struct item_cheat -{ - char *desc; - bool state; - char *code; -}; - -struct cheat_manager -{ - struct item_cheat *cheats; - unsigned ptr; - unsigned size; - unsigned buf_size; -}; - -static cheat_manager_t *cheat_manager_state; unsigned cheat_manager_get_buf_size(void) { - cheat_manager_t *handle = cheat_manager_state; - if (!handle) - return 0; - return handle->buf_size; + return cheat_manager_state.buf_size; } unsigned cheat_manager_get_size(void) { - cheat_manager_t *handle = cheat_manager_state; - if (!handle) - return 0; - return handle->size; + return cheat_manager_state.size; } void cheat_manager_apply_cheats(void) @@ -80,22 +66,21 @@ void cheat_manager_apply_cheats(void) bool data_bool = false; #endif unsigned i, idx = 0; - cheat_manager_t *handle = cheat_manager_state; - if (!handle) + if (!cheat_manager_state.cheats) return; core_reset_cheat(); - for (i = 0; i < handle->size; i++) + for (i = 0; i < cheat_manager_state.size; i++) { - if (handle->cheats[i].state) + if (cheat_manager_state.cheats[i].state && cheat_manager_state.cheats[i].handler == CHEAT_HANDLER_TYPE_EMU) { retro_ctx_cheat_info_t cheat_info; cheat_info.index = idx++; cheat_info.enabled = true; - cheat_info.code = handle->cheats[i].code; + cheat_info.code = cheat_manager_state.cheats[i].code; if (!string_is_empty(cheat_info.code)) core_set_cheat(&cheat_info); @@ -112,14 +97,13 @@ void cheat_manager_apply_cheats(void) void cheat_manager_set_code(unsigned i, const char *str) { - cheat_manager_t *handle = cheat_manager_state; - if (!handle) + if (!cheat_manager_state.cheats) return; if (!string_is_empty(str)) - handle->cheats[i].code = strdup(str); + strcpy(cheat_manager_state.cheats[i].code,str) ; - handle->cheats[i].state = true; + cheat_manager_state.cheats[i].state = true; } /** @@ -130,22 +114,34 @@ void cheat_manager_set_code(unsigned i, const char *str) * * Returns: true (1) if successful, otherwise false (0). **/ -bool cheat_manager_save(const char *path, const char *cheat_database) +bool cheat_manager_save(const char *path, const char *cheat_database, bool overwrite) { bool ret; unsigned i; char buf[PATH_MAX_LENGTH]; char cheats_file[PATH_MAX_LENGTH]; config_file_t *conf = NULL; - cheat_manager_t *handle = cheat_manager_state; buf[0] = cheats_file[0] = '\0'; - fill_pathname_join(buf, cheat_database, path, sizeof(buf)); + if ( cheat_database == NULL ) + { + strncpy(cheats_file, path, PATH_MAX_LENGTH) ; + } + else + { + fill_pathname_join(buf, cheat_database, path, sizeof(buf)); - fill_pathname_noext(cheats_file, buf, ".cht", sizeof(cheats_file)); - - conf = config_file_new(cheats_file); + fill_pathname_noext(cheats_file, buf, ".cht", sizeof(cheats_file)); + } + if ( !overwrite ) + { + conf = config_file_new(cheats_file); + } + else + { + conf = config_file_new(NULL); + } if (!conf) conf = config_file_new(NULL); @@ -153,34 +149,75 @@ bool cheat_manager_save(const char *path, const char *cheat_database) if (!conf) return false; - if (!handle) + if (!cheat_manager_state.cheats) { config_file_free(conf); return false; } - config_set_int(conf, "cheats", handle->size); + config_set_int(conf, "cheats", cheat_manager_state.size); - for (i = 0; i < handle->size; i++) + for (i = 0; i < cheat_manager_state.size; i++) { - char key[64]; + char endian_key[100]; + char key[256]; char desc_key[256]; char code_key[256]; char enable_key[256]; - key[0] = desc_key[0] = code_key[0] = enable_key[0] = '\0'; + key[0] = endian_key[0] = desc_key[0] = code_key[0] = enable_key[0] = '\0'; - snprintf(key, sizeof(key), "cheat%u", i); + snprintf(endian_key, sizeof(endian_key), "cheat%u_big_endian", i); snprintf(desc_key, sizeof(desc_key), "cheat%u_desc", i); snprintf(code_key, sizeof(code_key), "cheat%u_code", i); snprintf(enable_key, sizeof(enable_key), "cheat%u_enable", i); - if (handle->cheats[i].desc) - config_set_string(conf, desc_key, handle->cheats[i].desc); + if (!string_is_empty(cheat_manager_state.cheats[i].desc)) + config_set_string(conf, desc_key, cheat_manager_state.cheats[i].desc); else - config_set_string(conf, desc_key, handle->cheats[i].code); - config_set_string(conf, code_key, handle->cheats[i].code); - config_set_bool(conf, enable_key, handle->cheats[i].state); + 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); + + 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", + }; + + for ( int j = 0 ; j < 13 ; j++ ) + { + unsigned int* data_ptrs[13] = { + &cheat_manager_state.cheats[i].handler, + &cheat_manager_state.cheats[i].memory_search_size, + &cheat_manager_state.cheats[i].cheat_type, + &cheat_manager_state.cheats[i].value, + &cheat_manager_state.cheats[i].address, + &cheat_manager_state.cheats[i].address_mask, + &cheat_manager_state.cheats[i].rumble_type, + &cheat_manager_state.cheats[i].rumble_value , + &cheat_manager_state.cheats[i].rumble_port, + &cheat_manager_state.cheats[i].rumble_primary_strength, + &cheat_manager_state.cheats[i].rumble_primary_duration, + &cheat_manager_state.cheats[i].rumble_secondary_strength, + &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])); + } + } ret = config_file_write(conf, cheats_file); @@ -189,43 +226,62 @@ bool cheat_manager_save(const char *path, const char *cheat_database) return ret; } -static cheat_manager_t *cheat_manager_new(unsigned size) +bool cheat_manager_copy_idx_to_working(unsigned idx) +{ + if ( (!cheat_manager_state.cheats) || (cheat_manager_state.size < idx+1)) + { + return false; + } + + memcpy(&(cheat_manager_state.working_cheat), &(cheat_manager_state.cheats[idx]), sizeof(struct item_cheat)) ; + return true ; +} +bool cheat_manager_copy_working_to_idx(unsigned idx) +{ + if ( (!cheat_manager_state.cheats) || (cheat_manager_state.size < idx+1)) + { + return false; + } + + memcpy(&(cheat_manager_state.cheats[idx]), &(cheat_manager_state.working_cheat), sizeof(struct item_cheat)) ; + return true ; +} +static void cheat_manager_new(unsigned size) { unsigned i; - cheat_manager_t *handle = (cheat_manager_t*) - calloc(1, sizeof(struct cheat_manager)); - if (!handle) - return NULL; - handle->buf_size = size; - handle->size = size; - handle->cheats = (struct item_cheat*) - calloc(handle->buf_size, sizeof(struct item_cheat)); + cheat_manager_free() ; - if (!handle->cheats) + cheat_manager_state.buf_size = size; + cheat_manager_state.size = size; + cheat_manager_state.search_bit_size = 3; + cheat_manager_state.cheats = (struct item_cheat*) + calloc(cheat_manager_state.buf_size, sizeof(struct item_cheat)); + + if (!cheat_manager_state.cheats) { - handle->buf_size = 0; - handle->size = 0; - handle->cheats = NULL; - return handle; + cheat_manager_state.buf_size = 0; + cheat_manager_state.size = 0; + cheat_manager_state.cheats = NULL; + return ; } - for (i = 0; i < handle->size; i++) + for (i = 0; i < cheat_manager_state.size; i++) { - handle->cheats[i].desc = NULL; - handle->cheats[i].code = NULL; - handle->cheats[i].state = false; + cheat_manager_state.cheats[i].desc[0] = 0 ; + cheat_manager_state.cheats[i].code[0] = 0 ; + cheat_manager_state.cheats[i].state = false; } - return handle; + return ; } -bool cheat_manager_load(const char *path) +bool cheat_manager_load(const char *path, bool append) { unsigned cheats = 0, i; - cheat_manager_t *cheat; config_file_t *conf = config_file_new(path); + unsigned orig_size ; if (!conf) return false; @@ -235,44 +291,111 @@ bool cheat_manager_load(const char *path) if (cheats == 0) goto error; - cheat = cheat_manager_new(cheats); + cheat_manager_alloc_if_empty() ; - if (!cheat) - goto error; - - for (i = 0; i < cheats; i++) + if ( append ) { - char key[64]; + orig_size = cheat_manager_get_size() ; + if ( orig_size == 0) + { + cheat_manager_new(cheats); + } + else + { + cheats = cheats + orig_size ; + if (cheat_manager_realloc(cheats, CHEAT_HANDLER_TYPE_EMU)) + { + } + } + } + else + { + orig_size = 0 ; + cheat_manager_new(cheats); + } + + for (i = orig_size; i < cheats; i++) + { + unsigned int* data_ptrs[13] = { + &cheat_manager_state.cheats[i].handler, + &cheat_manager_state.cheats[i].memory_search_size, + &cheat_manager_state.cheats[i].cheat_type, + &cheat_manager_state.cheats[i].value, + &cheat_manager_state.cheats[i].address, + &cheat_manager_state.cheats[i].address_mask, + &cheat_manager_state.cheats[i].rumble_type, + &cheat_manager_state.cheats[i].rumble_value , + &cheat_manager_state.cheats[i].rumble_port, + &cheat_manager_state.cheats[i].rumble_primary_strength, + &cheat_manager_state.cheats[i].rumble_primary_duration, + &cheat_manager_state.cheats[i].rumble_secondary_strength, + &cheat_manager_state.cheats[i].rumble_secondary_duration + } ; + 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", + }; char desc_key[256]; char code_key[256]; char enable_key[256]; + char endian_key[256]; char *tmp = NULL; bool tmp_bool = false; - key[0] = desc_key[0] = code_key[0] = enable_key[0] = '\0'; + endian_key[0] = desc_key[0] = code_key[0] = enable_key[0] = '\0'; - snprintf(key, sizeof(key), "cheat%u", i); - snprintf(desc_key, sizeof(desc_key), "cheat%u_desc", i); - snprintf(code_key, sizeof(code_key), "cheat%u_code", i); - snprintf(enable_key, sizeof(enable_key), "cheat%u_enable", i); + snprintf(desc_key, sizeof(desc_key), "cheat%u_desc", i-orig_size); + snprintf(code_key, sizeof(code_key), "cheat%u_code", i-orig_size); + snprintf(enable_key, sizeof(enable_key), "cheat%u_enable", i-orig_size); + snprintf(endian_key, sizeof(endian_key), "cheat%u_endian", i-orig_size); + + cheat_manager_state.cheats[i].idx = i ; + + cheat_manager_state.cheats[i].desc[0] = 0 ; + cheat_manager_state.cheats[i].code[0] = 0 ; + cheat_manager_state.cheats[i].state = false ; + cheat_manager_state.cheats[i].big_endian = false ; if (config_get_string(conf, desc_key, &tmp) && !string_is_empty(tmp)) - cheat->cheats[i].desc = strdup(tmp); + strcpy(cheat_manager_state.cheats[i].desc,tmp) ; if (config_get_string(conf, code_key, &tmp) && !string_is_empty(tmp)) - cheat->cheats[i].code = strdup(tmp); + strcpy(cheat_manager_state.cheats[i].code,tmp) ; if (config_get_bool(conf, enable_key, &tmp_bool)) - cheat->cheats[i].state = tmp_bool; + cheat_manager_state.cheats[i].state = tmp_bool; + + if (config_get_bool(conf, endian_key, &tmp_bool)) + cheat_manager_state.cheats[i].big_endian = tmp_bool; if (tmp) free(tmp); + + cheat_manager_state.cheats[i].cheat_type = CHEAT_TYPE_SET_TO_VALUE ; + cheat_manager_state.cheats[i].memory_search_size = 3; + for ( int j = 0 ; j < 13 ; j++ ) { + char key[50] ; + unsigned val = 0; + snprintf(key, sizeof(key), keys[j], i-orig_size); + + if ( config_get_uint(conf, key, &val)) + *(data_ptrs[j]) = val ; + } } config_file_free(conf); - cheat_manager_state = cheat; - return true; error: @@ -281,36 +404,43 @@ error: } -bool cheat_manager_realloc(unsigned new_size) +bool cheat_manager_realloc(unsigned new_size, unsigned default_handler) { unsigned i; - cheat_manager_t *handle = cheat_manager_state; + unsigned orig_size ; - if (!handle) - return false; - if (!handle->cheats) - handle->cheats = (struct item_cheat*) - calloc(new_size, sizeof(struct item_cheat)); - else - handle->cheats = (struct item_cheat*) - realloc(handle->cheats, new_size * sizeof(struct item_cheat)); - - if (!handle->cheats) + if (!cheat_manager_state.cheats) { - handle->buf_size = handle->size = 0; - handle->cheats = NULL; + cheat_manager_state.cheats = (struct item_cheat*) + calloc(new_size, sizeof(struct item_cheat)); + orig_size = 0 ; + } + else + { + orig_size = cheat_manager_state.size ; + cheat_manager_state.cheats = (struct item_cheat*) + realloc(cheat_manager_state.cheats, new_size * sizeof(struct item_cheat)); + } + + if (!cheat_manager_state.cheats) + { + cheat_manager_state.buf_size = cheat_manager_state.size = 0; + cheat_manager_state.cheats = NULL; return false; } - handle->buf_size = new_size; - handle->size = new_size; + cheat_manager_state.buf_size = new_size; + cheat_manager_state.size = new_size; - for (i = 0; i < handle->size; i++) + for (i = orig_size; i < cheat_manager_state.size; i++) { - handle->cheats[i].desc = NULL; - handle->cheats[i].code = NULL; - handle->cheats[i].state = false; + memset(&(cheat_manager_state.cheats[i]), 0, sizeof(cheat_manager_state.cheats[i])) ; + cheat_manager_state.cheats[i].state = false; + cheat_manager_state.cheats[i].handler = 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; } return true; @@ -318,36 +448,33 @@ bool cheat_manager_realloc(unsigned new_size) void cheat_manager_free(void) { - cheat_manager_t *handle = cheat_manager_state; - if (!handle) - return; + if (cheat_manager_state.cheats) + free(cheat_manager_state.cheats); - if (handle->cheats) - { - unsigned i; + if ( cheat_manager_state.prev_memory_buf ) + free(cheat_manager_state.prev_memory_buf) ; - for (i = 0; i < handle->size; i++) - { - free(handle->cheats[i].desc); - free(handle->cheats[i].code); - } + cheat_manager_state.cheats = NULL ; + cheat_manager_state.size = 0 ; + cheat_manager_state.buf_size = 0 ; + cheat_manager_state.prev_memory_buf = NULL ; + cheat_manager_state.curr_memory_buf = NULL ; + cheat_manager_state.total_memory_size = 0 ; + cheat_manager_state.actual_memory_size = 0 ; + cheat_manager_state.memory_initialized = false ; - free(handle->cheats); - } - - free(handle); } void cheat_manager_update(cheat_manager_t *handle, unsigned handle_idx) { char msg[256]; - if (!handle) + if (!handle || !handle->cheats) return; snprintf(msg, sizeof(msg), "Cheat: #%u [%s]: %s", handle_idx, handle->cheats[handle_idx].state ? "ON" : "OFF", - (handle->cheats[handle_idx].desc) ? + (handle->cheats[handle_idx].desc[0]) ? (handle->cheats[handle_idx].desc) : (handle->cheats[handle_idx].code) ); runloop_msg_queue_push(msg, 1, 180, true); @@ -356,95 +483,965 @@ void cheat_manager_update(cheat_manager_t *handle, unsigned handle_idx) void cheat_manager_toggle_index(unsigned i) { - cheat_manager_t *handle = cheat_manager_state; - if (!handle) + if (!cheat_manager_state.cheats) return; - handle->cheats[i].state = !handle->cheats[i].state; - cheat_manager_update(handle, i); + cheat_manager_state.cheats[i].state = !cheat_manager_state.cheats[i].state; + cheat_manager_update(&cheat_manager_state, i); } void cheat_manager_toggle(void) { - cheat_manager_t *handle = cheat_manager_state; - if (!handle) + if (!cheat_manager_state.cheats) return; - handle->cheats[handle->ptr].state ^= true; + cheat_manager_state.cheats[cheat_manager_state.ptr].state ^= true; cheat_manager_apply_cheats(); - cheat_manager_update(handle, handle->ptr); + cheat_manager_update(&cheat_manager_state, cheat_manager_state.ptr); } void cheat_manager_index_next(void) { - cheat_manager_t *handle = cheat_manager_state; - - if (!handle) + if (!cheat_manager_state.cheats) return; - handle->ptr = (handle->ptr + 1) % handle->size; - cheat_manager_update(handle, handle->ptr); + cheat_manager_state.ptr = (cheat_manager_state.ptr + 1) % cheat_manager_state.size; + cheat_manager_update(&cheat_manager_state, cheat_manager_state.ptr); } void cheat_manager_index_prev(void) { - cheat_manager_t *handle = cheat_manager_state; - - if (!handle) + if (!cheat_manager_state.cheats) return; - if (handle->ptr == 0) - handle->ptr = handle->size - 1; + if (cheat_manager_state.ptr == 0) + cheat_manager_state.ptr = cheat_manager_state.size - 1; else - handle->ptr--; + cheat_manager_state.ptr--; - cheat_manager_update(handle, handle->ptr); + cheat_manager_update(&cheat_manager_state, cheat_manager_state.ptr); } const char *cheat_manager_get_code(unsigned i) { - cheat_manager_t *handle = cheat_manager_state; - if (!handle) + if (!cheat_manager_state.cheats) return NULL; - return handle->cheats[i].code; + return cheat_manager_state.cheats[i].code; } const char *cheat_manager_get_desc(unsigned i) { - cheat_manager_t *handle = cheat_manager_state; - if (!handle) + if (!cheat_manager_state.cheats) return NULL; - return handle->cheats[i].desc; + return cheat_manager_state.cheats[i].desc; } bool cheat_manager_get_code_state(unsigned i) { - cheat_manager_t *handle = cheat_manager_state; - if (!handle) + if (!cheat_manager_state.cheats) return false; - return handle->cheats[i].state; + return cheat_manager_state.cheats[i].state; +} + +void cheat_manager_load_game_specific_cheats() +{ + global_t *global = global_get_ptr(); + + if (global ) + { + cheat_manager_load(global->name.cheatfile,true) ; + } + +} +void cheat_manager_save_game_specific_cheats() +{ + global_t *global = global_get_ptr(); + + if (global ) + { + cheat_manager_save(global->name.cheatfile, NULL, true) ; + } + } void cheat_manager_state_free(void) { cheat_manager_free(); - - cheat_manager_state = NULL; } bool cheat_manager_alloc_if_empty(void) { - cheat_manager_t *handle = cheat_manager_state; - if (!handle) + if (!cheat_manager_state.cheats) { - cheat_manager_t *tmp = cheat_manager_new(0); - - if (!tmp) - return false; - cheat_manager_state = tmp; + cheat_manager_new(0); } return true; } + +int cheat_manager_initialize_search(void *data, bool wraparound) +{ + retro_ctx_memory_info_t meminfo ; + bool refresh = false; + + 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 ; + } + + cheat_manager_state.actual_memory_size = meminfo.size ; + cheat_manager_state.curr_memory_buf = meminfo.data ; + cheat_manager_state.total_memory_size = meminfo.size ; + cheat_manager_state.num_matches = 0 ; + //ensure we're aligned on 4-byte boundary + //if ( meminfo.size % 4 > 0 ) { + //cheat_manager_state.total_memory_size = cheat_manager_state.total_memory_size + (4 - (meminfo.size%4)) ; + //} + 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 ) + { + runloop_msg_queue_push(msg_hash_to_str(MSG_CHEAT_INIT_FAIL), 1, 180, true); + return 0 ; + } + cheat_manager_state.matches = (uint8_t*) calloc(cheat_manager_state.total_memory_size, sizeof(uint8_t)); + if (!cheat_manager_state.matches ) + { + free(cheat_manager_state.prev_memory_buf) ; + cheat_manager_state.prev_memory_buf = NULL ; + runloop_msg_queue_push(msg_hash_to_str(MSG_CHEAT_INIT_FAIL), 1, 180, true); + return 0 ; + } + + 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); + cheat_manager_state.num_matches = (cheat_manager_state.total_memory_size*8)/((int)pow(2,cheat_manager_state.search_bit_size)) ; + + cheat_manager_state.memory_initialized = true ; + + runloop_msg_queue_push(msg_hash_to_str(MSG_CHEAT_INIT_SUCCESS), 1, 180, true); + menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh); + menu_driver_ctl(RARCH_MENU_CTL_SET_PREVENT_POPULATE, NULL); + + return 0 ; +} + +static void cheat_manager_setup_search_meta(unsigned int bitsize, unsigned int *bytes_per_item, unsigned int *mask, unsigned int *bits) +{ + switch( bitsize) + { + case 0 : + { + *bytes_per_item = 1 ; + *bits = 1 ; + *mask = 0x01 ; + break ; + } + case 1 : + { + *bytes_per_item = 1 ; + *bits = 2 ; + *mask = 0x03 ; + break ; + } + case 2 : + { + *bytes_per_item = 1 ; + *bits = 4 ; + *mask = 0x0F ; + break ; + } + case 3 : + { + *bytes_per_item = 1 ; + *bits = 8 ; + *mask = 0xFF ; + break ; + } + case 4 : + { + *bytes_per_item = 2 ; + *bits = 8 ; + *mask = 0xFFFF ; + break ; + } + case 5 : + { + *bytes_per_item = 4 ; + *bits = 8 ; + *mask = 0xFFFFFFFF ; + break ; + } + } +} + +int cheat_manager_search_exact(void *data, bool wraparound) +{ + return cheat_manager_search(CHEAT_SEARCH_TYPE_EXACT) ; +} +int cheat_manager_search_lt(void *data, bool wraparound) +{ + return cheat_manager_search(CHEAT_SEARCH_TYPE_LT) ; +} +int cheat_manager_search_gt(void *data, bool wraparound) +{ + return cheat_manager_search(CHEAT_SEARCH_TYPE_GT) ; +} +int cheat_manager_search_lte(void *data, bool wraparound) +{ + return cheat_manager_search(CHEAT_SEARCH_TYPE_LTE) ; +} +int cheat_manager_search_gte(void *data, bool wraparound) +{ + return cheat_manager_search(CHEAT_SEARCH_TYPE_GTE) ; +} +int cheat_manager_search_eq(void *data, bool wraparound) +{ + return cheat_manager_search(CHEAT_SEARCH_TYPE_EQ) ; +} +int cheat_manager_search_neq(void *data, bool wraparound) +{ + return cheat_manager_search(CHEAT_SEARCH_TYPE_NEQ) ; +} +int cheat_manager_search_eqplus(void *data, bool wraparound) +{ + return cheat_manager_search(CHEAT_SEARCH_TYPE_EQPLUS) ; +} +int cheat_manager_search_eqminus(void *data, bool wraparound) +{ + return cheat_manager_search(CHEAT_SEARCH_TYPE_EQMINUS) ; +} + +int cheat_manager_search(enum cheat_search_type search_type) +{ + char msg[100]; + unsigned char *curr = cheat_manager_state.curr_memory_buf ; + unsigned char *prev = cheat_manager_state.prev_memory_buf ; + unsigned int idx = 0 ; + unsigned int num_matches = 0 ; + unsigned int curr_val ; + unsigned int prev_val ; + unsigned int mask = 0 ; + unsigned int bytes_per_item = 1 ; + unsigned int bits = 8 ; + bool refresh = false; + + if ( cheat_manager_state.curr_memory_buf == NULL ) + { + runloop_msg_queue_push(msg_hash_to_str(MSG_CHEAT_SEARCH_NOT_INITIALIZED), 1, 180, true); + return 0 ; + } + + + cheat_manager_setup_search_meta(cheat_manager_state.search_bit_size, &bytes_per_item, &mask, &bits) ; + + //little endian FF000000 = 256 + for ( idx = 0 ; idx < cheat_manager_state.total_memory_size ; idx = idx + bytes_per_item) + { + switch ( bytes_per_item ) + { + case 2 : + { + curr_val = cheat_manager_state.big_endian ? + (*(curr+idx)*256) + *(curr+idx+1) : + *(curr+idx) + (*(curr+idx+1)*256) ; + prev_val = cheat_manager_state.big_endian ? + (*(prev+idx)*256) + *(prev+idx+1) : + *(prev+idx) + (*(prev+idx+1)*256) ; + break ; + } + case 4 : + { + 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) + (*(curr+idx+1)*256) + (*(curr+idx+2)*256*256) + (*(curr+idx+3)*256*256*256) ; + 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) + (*(prev+idx+1)*256) + (*(prev+idx+2)*256*256) + (*(prev+idx+3)*256*256*256) ; + break ; + } + case 1 : + default : + { + curr_val = *(curr+idx) ; + prev_val = *(prev+idx) ; + break ; + } + } + for ( int byte_part = 0 ; byte_part < 8/bits ; byte_part++) + { + unsigned int curr_subval = (curr_val >> (byte_part*bits) ) & mask ; + unsigned int prev_subval = (prev_val >> (byte_part*bits) ) & mask ; + unsigned int prev_match ; + + if ( bits < 8 ) + { + prev_match = *(cheat_manager_state.matches+idx) & (mask << (byte_part*bits)) ; + } + else + { + prev_match = *(cheat_manager_state.matches+idx) ; + } + + if ( prev_match > 0 ) + { + bool match = false ; + switch ( search_type ) + { + case CHEAT_SEARCH_TYPE_EXACT : + { + match = ( curr_subval == cheat_manager_state.search_exact_value) ; + break; + } + case CHEAT_SEARCH_TYPE_LT : + { + match = ( curr_subval < prev_subval) ; + break; + } + case CHEAT_SEARCH_TYPE_GT : + { + match = ( curr_subval > prev_subval) ; + break; + } + case CHEAT_SEARCH_TYPE_LTE : + { + match = ( curr_subval <= prev_subval) ; + break; + } + case CHEAT_SEARCH_TYPE_GTE : + { + match = ( curr_subval >= prev_subval) ; + break; + } + case CHEAT_SEARCH_TYPE_EQ : + { + match = ( curr_subval == prev_subval) ; + break; + } + case CHEAT_SEARCH_TYPE_NEQ : + { + match = ( curr_subval != prev_subval) ; + break; + } + case CHEAT_SEARCH_TYPE_EQPLUS : + { + match = ( curr_subval == prev_subval+cheat_manager_state.search_eqplus_value) ; + break; + } + case CHEAT_SEARCH_TYPE_EQMINUS : + { + match = ( curr_subval == prev_subval-cheat_manager_state.search_eqminus_value) ; + break; + } + } + if (!match ) + { + if ( bits < 8 ) + { + *(cheat_manager_state.matches+idx) = *(cheat_manager_state.matches+idx) & + (( ~(mask << (byte_part*bits))) & 0xFF ); + } + else + { + memset(cheat_manager_state.matches+idx,0,bytes_per_item) ; + } + if ( cheat_manager_state.num_matches > 0 ) + { + cheat_manager_state.num_matches-- ; + } + } + } + } + } + + memcpy(cheat_manager_state.prev_memory_buf, cheat_manager_state.curr_memory_buf, cheat_manager_state.actual_memory_size); + + snprintf(msg, sizeof(msg), msg_hash_to_str(MSG_CHEAT_SEARCH_FOUND_MATCHES), cheat_manager_state.num_matches) ; + msg[sizeof(msg) - 1] = 0; + + runloop_msg_queue_push(msg, 1, 180, true); + + menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh); + menu_driver_ctl(RARCH_MENU_CTL_SET_PREVENT_POPULATE, NULL); + return 0 ; +} + +bool cheat_manager_add_new_code(unsigned int memory_search_size, unsigned int address, unsigned int address_mask, + bool big_endian, unsigned int value) +{ + int new_size = cheat_manager_get_size() + 1; + + if ( !cheat_manager_realloc(new_size, CHEAT_HANDLER_TYPE_RETRO) ) + return false ; + + cheat_manager_state.cheats[cheat_manager_state.size-1].address = address ; + cheat_manager_state.cheats[cheat_manager_state.size-1].address_mask = address_mask ; + cheat_manager_state.cheats[cheat_manager_state.size-1].memory_search_size = memory_search_size ; + cheat_manager_state.cheats[cheat_manager_state.size-1].value = value ; + cheat_manager_state.cheats[cheat_manager_state.size-1].big_endian = big_endian ; + + return true ; +} +int cheat_manager_add_matches(const char *path, + const char *label, unsigned type, size_t menuidx, size_t entry_idx) +{ + char msg[100]; + bool refresh = false; + unsigned int mask = 0 ; + unsigned int bytes_per_item = 1 ; + unsigned int bits = 8 ; + unsigned int curr_val = 0 ; + unsigned int num_added = 0 ; + unsigned char *curr = cheat_manager_state.curr_memory_buf ; + + if ( cheat_manager_state.num_matches + cheat_manager_state.size > 100 ) + { + runloop_msg_queue_push(msg_hash_to_str(MSG_CHEAT_SEARCH_ADDED_MATCHES_TOO_MANY), 1, 180, true); + return 0 ; + } + cheat_manager_setup_search_meta(cheat_manager_state.search_bit_size, &bytes_per_item, &mask, &bits) ; + + for ( unsigned int idx = 0 ; idx < cheat_manager_state.total_memory_size ; idx = idx + bytes_per_item) + { + switch ( bytes_per_item ) + { + case 2 : + { + curr_val = cheat_manager_state.big_endian ? + (*(curr+idx)*256) + *(curr+idx+1) : + *(curr+idx) + (*(curr+idx+1)*256) ; + break ; + } + case 4 : + { + 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) + (*(curr+idx+1)*256) + (*(curr+idx+2)*256*256) + (*(curr+idx+3)*256*256*256) ; + break ; + } + case 1 : + default : + { + curr_val = *(curr+idx) ; + break ; + } + } + for ( int byte_part = 0 ; byte_part < 8/bits ; byte_part++) + { + unsigned int prev_match ; + + if ( bits < 8 ) + { + prev_match = *(cheat_manager_state.matches+idx) & (mask << (byte_part*bits)) ; + if ( prev_match ) + { + if ( !cheat_manager_add_new_code(cheat_manager_state.search_bit_size, idx, (mask << (byte_part*bits)), + cheat_manager_state.big_endian, curr_val) ) + { + runloop_msg_queue_push(msg_hash_to_str(MSG_CHEAT_SEARCH_ADDED_MATCHES_FAIL), 1, 180, true); + return 0 ; + } + num_added++ ; + } + } + else + { + prev_match = *(cheat_manager_state.matches+idx) ; + if ( prev_match ) + { + if ( !cheat_manager_add_new_code(cheat_manager_state.search_bit_size, idx, 0xFF, + cheat_manager_state.big_endian, curr_val) ) + { + runloop_msg_queue_push(msg_hash_to_str(MSG_CHEAT_SEARCH_ADDED_MATCHES_FAIL), 1, 180, true); + return 0 ; + } + num_added++ ; + } + } + + } + } + + snprintf(msg, sizeof(msg), msg_hash_to_str(MSG_CHEAT_SEARCH_ADDED_MATCHES_SUCCESS), cheat_manager_state.num_matches) ; + msg[sizeof(msg) - 1] = 0; + + runloop_msg_queue_push(msg, 1, 180, true); + + menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh); + menu_driver_ctl(RARCH_MENU_CTL_SET_PREVENT_POPULATE, NULL); + + return 0 ; +} + +void cheat_manager_apply_rumble(struct item_cheat *cheat, unsigned int curr_value) +{ + bool rumble = false ; + + switch ( cheat->rumble_type ) + { + case RUMBLE_TYPE_DISABLED : + { + return ; + } + case RUMBLE_TYPE_CHANGES: + { + rumble = (curr_value != cheat->rumble_prev_value) ; + break ; + } + case RUMBLE_TYPE_DOES_NOT_CHANGE: + { + rumble = (curr_value == cheat->rumble_prev_value) ; + break ; + } + case RUMBLE_TYPE_INCREASE: + { + rumble = (curr_value > cheat->rumble_prev_value) ; + break ; + } + case RUMBLE_TYPE_DECREASE: + { + rumble = (curr_value < cheat->rumble_prev_value) ; + break ; + } + case RUMBLE_TYPE_EQ_VALUE: + { + rumble = (curr_value == cheat->rumble_value) ; + break ; + } + case RUMBLE_TYPE_NEQ_VALUE: + { + rumble = (curr_value != cheat->rumble_value) ; + break ; + } + case RUMBLE_TYPE_LT_VALUE: + { + rumble = (curr_value < cheat->rumble_value) ; + break ; + } + case RUMBLE_TYPE_GT_VALUE: + { + rumble = (curr_value > cheat->rumble_value) ; + break ; + } + + } + + cheat->rumble_prev_value = curr_value ; + + //Give the emulator enough time to initialize, load state, etc + if ( cheat->rumble_initialized > 300) + { + if ( rumble ) + { + cheat->rumble_primary_end_time = cpu_features_get_time_usec() + (cheat->rumble_primary_duration*1000) ; + cheat->rumble_secondary_end_time = cpu_features_get_time_usec() + (cheat->rumble_secondary_duration*1000) ; + input_driver_set_rumble_state(cheat->rumble_port, RETRO_RUMBLE_STRONG, cheat->rumble_primary_strength); + input_driver_set_rumble_state(cheat->rumble_port, RETRO_RUMBLE_WEAK, cheat->rumble_secondary_strength); + } + } + else + { + cheat->rumble_initialized++ ; + return ; + } + + if ( cheat->rumble_primary_end_time <= cpu_features_get_time_usec() ) + { + if ( cheat->rumble_primary_end_time != 0 ) + input_driver_set_rumble_state(cheat->rumble_port, RETRO_RUMBLE_STRONG, 0); + cheat->rumble_primary_end_time = 0; + } + else + { + input_driver_set_rumble_state(cheat->rumble_port, RETRO_RUMBLE_STRONG, cheat->rumble_primary_strength); + } + + if ( cheat->rumble_secondary_end_time <= cpu_features_get_time_usec() ) + { + if ( cheat->rumble_secondary_end_time != 0 ) + input_driver_set_rumble_state(cheat->rumble_port, RETRO_RUMBLE_WEAK, 0); + cheat->rumble_secondary_end_time = 0 ; + } + else + { + input_driver_set_rumble_state(cheat->rumble_port, RETRO_RUMBLE_WEAK, cheat->rumble_secondary_strength); + } +} + +void cheat_manager_apply_retro_cheats() +{ + unsigned int mask = 0 ; + unsigned int bytes_per_item = 1 ; + unsigned int bits = 8 ; + unsigned int curr_val = 0 ; + unsigned int num_added = 0 ; + bool run_cheat = true ; + + if ( (!cheat_manager_state.cheats) ) + { + return ; + } + + + for ( int i = 0 ; i < cheat_manager_state.size ; i++ ) + { + if (cheat_manager_state.cheats[i].handler != CHEAT_HANDLER_TYPE_RETRO || !cheat_manager_state.cheats[i].state) + { + continue ; + } + if ( !cheat_manager_state.memory_initialized ) + { + cheat_manager_initialize_search(NULL, false) ; + } + //If we're still not initialized, something must have gone wrong - just bail + if ( !cheat_manager_state.memory_initialized ) + { + return ; + } + if ( !run_cheat ) + { + run_cheat = true ; + continue ; + } + cheat_manager_setup_search_meta(cheat_manager_state.cheats[i].memory_search_size, &bytes_per_item, &mask, &bits) ; + unsigned char *curr = cheat_manager_state.curr_memory_buf ; + unsigned int idx = cheat_manager_state.cheats[i].address ; + + switch ( bytes_per_item ) + { + case 2 : + { + curr_val = cheat_manager_state.big_endian ? + (*(curr+idx)*256) + *(curr+idx+1) : + *(curr+idx) + (*(curr+idx+1)*256) ; + break ; + } + case 4 : + { + 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) + (*(curr+idx+1)*256) + (*(curr+idx+2)*256*256) + (*(curr+idx+3)*256*256*256) ; + break ; + } + case 1 : + default : + { + curr_val = *(curr+idx) ; + break ; + } + } + + cheat_manager_apply_rumble(&cheat_manager_state.cheats[i], curr_val) ; + + bool set_value = false ; + unsigned int value_to_set = 0 ; + + switch ( cheat_manager_state.cheats[i].cheat_type ) + { + case CHEAT_TYPE_SET_TO_VALUE : + { + set_value = true ; + value_to_set = cheat_manager_state.cheats[i].value ; + break ; + } + case CHEAT_TYPE_INCREASE_VALUE: + { + set_value = true ; + value_to_set = curr_val + cheat_manager_state.cheats[i].value ; + break; + } + case CHEAT_TYPE_DECREASE_VALUE: + { + set_value = true ; + value_to_set = curr_val - cheat_manager_state.cheats[i].value ; + break; + } + case CHEAT_TYPE_RUN_NEXT_IF_EQ: + { + if (!( curr_val == cheat_manager_state.cheats[i].value )) + { + run_cheat = false ; + } + break; + } + case CHEAT_TYPE_RUN_NEXT_IF_NEQ: + { + if (!( curr_val != cheat_manager_state.cheats[i].value )) + { + run_cheat = false ; + } + break; + } + case CHEAT_TYPE_RUN_NEXT_IF_LT: + { + if (!( cheat_manager_state.cheats[i].value < curr_val)) + { + run_cheat = false ; + } + break; + } + case CHEAT_TYPE_RUN_NEXT_IF_GT: + { + if (!( cheat_manager_state.cheats[i].value > curr_val)) + { + run_cheat = false ; + } + break; + } + + } + if ( set_value ) + { + switch ( bytes_per_item ) + { + 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 char val = *(curr+idx) ; + for ( int bitpos = 0 ; bitpos < 8 ; bitpos++) + { + if ( (cheat_manager_state.cheats[i].address_mask>>bitpos)&0x01 ) + { + mask = (~(1<>bitpos)&0x01)< cheat_manager_state.num_matches-1) + { + return ; + } + + char msg[100]; + bool refresh = false; + unsigned int mask = 0 ; + unsigned int bytes_per_item = 1 ; + unsigned int bits = 8 ; + unsigned int curr_val = 0 ; + unsigned int prev_val = 0 ; + unsigned char *curr = cheat_manager_state.curr_memory_buf ; + unsigned char *prev = cheat_manager_state.prev_memory_buf ; + unsigned int curr_match_idx = 0; + + cheat_manager_setup_search_meta(cheat_manager_state.search_bit_size, &bytes_per_item, &mask, &bits) ; + for ( unsigned int idx = 0 ; idx < cheat_manager_state.total_memory_size ; idx = idx + bytes_per_item) + { + switch ( bytes_per_item ) + { + case 2 : + { + curr_val = cheat_manager_state.big_endian ? + (*(curr+idx)*256) + *(curr+idx+1) : + *(curr+idx) + (*(curr+idx+1)*256) ; + prev_val = cheat_manager_state.big_endian ? + (*(prev+idx)*256) + *(prev+idx+1) : + *(prev+idx) + (*(prev+idx+1)*256) ; + break ; + } + case 4 : + { + 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) + (*(curr+idx+1)*256) + (*(curr+idx+2)*256*256) + (*(curr+idx+3)*256*256*256) ; + 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) + (*(prev+idx+1)*256) + (*(prev+idx+2)*256*256) + (*(prev+idx+3)*256*256*256) ; + break ; + } + case 1 : + default : + { + curr_val = *(curr+idx) ; + prev_val = *(prev+idx) ; + break ; + } + } + for ( int byte_part = 0 ; byte_part < 8/bits ; byte_part++) + { + unsigned int prev_match ; + + if ( bits < 8 ) + { + prev_match = *(cheat_manager_state.matches+idx) & (mask << (byte_part*bits)) ; + if ( prev_match ) + { + if ( target_match_idx == curr_match_idx ) + { + switch ( match_action ) + { + case CHEAT_MATCH_ACTION_TYPE_VIEW : + { + *address = idx ; + *address_mask = (mask << (byte_part*bits)) ; + *curr_value = curr_val ; + *prev_value = prev_val ; + return ; + } + case CHEAT_MATCH_ACTION_TYPE_COPY : + { + if ( !cheat_manager_add_new_code(cheat_manager_state.search_bit_size, idx, (mask << (byte_part*bits)), + cheat_manager_state.big_endian, curr_val) ) + { + runloop_msg_queue_push(msg_hash_to_str(MSG_CHEAT_SEARCH_ADD_MATCH_FAIL), 1, 180, true); + } + else + { + runloop_msg_queue_push(msg_hash_to_str(MSG_CHEAT_SEARCH_ADD_MATCH_SUCCESS), 1, 180, true); + } + return ; + } + case CHEAT_MATCH_ACTION_TYPE_DELETE : + { + if ( bits < 8 ) + { + *(cheat_manager_state.matches+idx) = *(cheat_manager_state.matches+idx) & + (( ~(mask << (byte_part*bits))) & 0xFF ); + } + else + { + memset(cheat_manager_state.matches+idx,0,bytes_per_item) ; + } + if ( cheat_manager_state.num_matches > 0 ) + { + cheat_manager_state.num_matches-- ; + } + runloop_msg_queue_push(msg_hash_to_str(MSG_CHEAT_SEARCH_DELETE_MATCH_SUCCESS), 1, 180, true); + return ; + } + } + return ; + } + curr_match_idx++ ; + } + } + else + { + prev_match = *(cheat_manager_state.matches+idx) ; + if ( prev_match ) + { + if ( target_match_idx == curr_match_idx ) + { + switch ( match_action ) + { + case CHEAT_MATCH_ACTION_TYPE_VIEW : + { + *address = idx ; + *address_mask = 0xFF ; + *curr_value = curr_val ; + *prev_value = prev_val ; + return ; + } + case CHEAT_MATCH_ACTION_TYPE_COPY : + { + if ( !cheat_manager_add_new_code(cheat_manager_state.search_bit_size, idx, 0xFF, + cheat_manager_state.big_endian, curr_val) ) + { + runloop_msg_queue_push(msg_hash_to_str(MSG_CHEAT_SEARCH_ADD_MATCH_FAIL), 1, 180, true); + } + else + { + runloop_msg_queue_push(msg_hash_to_str(MSG_CHEAT_SEARCH_ADD_MATCH_SUCCESS), 1, 180, true); + } + return ; + } + case CHEAT_MATCH_ACTION_TYPE_DELETE : + { + if ( bits < 8 ) + { + *(cheat_manager_state.matches+idx) = *(cheat_manager_state.matches+idx) & + (( ~(mask << (byte_part*bits))) & 0xFF ); + } + else + { + memset(cheat_manager_state.matches+idx,0,bytes_per_item) ; + } + if ( cheat_manager_state.num_matches > 0 ) + { + cheat_manager_state.num_matches-- ; + } + runloop_msg_queue_push(msg_hash_to_str(MSG_CHEAT_SEARCH_DELETE_MATCH_SUCCESS), 1, 180, true); + return ; + } + } + } + curr_match_idx++ ; + } + } + + } + } +} +int cheat_manager_copy_match(void *data, bool wraparound) +{ + cheat_manager_match_action(CHEAT_MATCH_ACTION_TYPE_COPY, cheat_manager_state.match_idx, NULL, NULL, NULL, NULL) ; + return 0 ; +} + +int cheat_manager_delete_match(void *data, bool wraparound) +{ + bool refresh = false ; + cheat_manager_match_action(CHEAT_MATCH_ACTION_TYPE_DELETE, cheat_manager_state.match_idx, NULL, NULL, NULL, NULL) ; + menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh); + menu_driver_ctl(RARCH_MENU_CTL_SET_PREVENT_POPULATE, NULL); + return 0 ; +} diff --git a/managers/cheat_manager.h b/managers/cheat_manager.h index db623101d0..2b84df40d2 100644 --- a/managers/cheat_manager.h +++ b/managers/cheat_manager.h @@ -22,11 +22,144 @@ 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 +}; + +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 +}; + +#define CHEAT_CODE_SIZE 100 +#define CHEAT_DESC_SIZE 100 + +struct item_cheat +{ + unsigned int idx; + char desc[CHEAT_DESC_SIZE]; + bool state; + char code[CHEAT_CODE_SIZE]; + 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 ; + //Whether to apply the cheat based on big-endian console memory or not + bool big_endian ; + unsigned int rumble_type ; + unsigned int rumble_value ; + unsigned int rumble_prev_value ; + unsigned int rumble_initialized ; + 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_duration ; //in milliseconds + 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_duration ; //in milliseconds + retro_time_t rumble_secondary_end_time ; //clock value for when rumbling should stop +}; + +struct cheat_manager +{ + struct item_cheat *cheats; + unsigned ptr; + unsigned size; + unsigned buf_size; + unsigned total_memory_size ; + unsigned actual_memory_size ; + uint8_t *curr_memory_buf ; + uint8_t *prev_memory_buf ; + uint8_t *matches ; + struct item_cheat working_cheat; + 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 ; + bool big_endian ; + bool memory_initialized ; + unsigned int delete_state ; +}; + typedef struct cheat_manager cheat_manager_t; +cheat_manager_t cheat_manager_state; + unsigned cheat_manager_get_size(void); -bool cheat_manager_load(const char *path); +bool cheat_manager_load(const char *path, bool append); /** * cheat_manager_save: @@ -36,9 +169,9 @@ bool cheat_manager_load(const char *path); * * Returns: true (1) if successful, otherwise false (0). **/ -bool cheat_manager_save(const char *path, const char *cheat_database); +bool cheat_manager_save(const char *path, const char *cheat_database, bool overwrite); -bool cheat_manager_realloc(unsigned new_size); +bool cheat_manager_realloc(unsigned new_size, unsigned default_handler); void cheat_manager_set_code(unsigned index, const char *str); @@ -68,6 +201,32 @@ void cheat_manager_state_free(void); bool 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(); + +void cheat_manager_save_game_specific_cheats(); + +int cheat_manager_initialize_search(void *data, bool wraparound); +int cheat_manager_search_exact(void *data, bool wraparound); +int cheat_manager_search_lt(void *data, bool wraparound); +int cheat_manager_search_gt(void *data, bool wraparound); +int cheat_manager_search_lte(void *data, bool wraparound); +int cheat_manager_search_gte(void *data, bool wraparound); +int cheat_manager_search_eq(void *data, bool wraparound); +int cheat_manager_search_neq(void *data, bool wraparound); +int cheat_manager_search_eqplus(void *data, bool wraparound); +int cheat_manager_search_eqminus(void *data, bool wraparound); +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() ; +int cheat_manager_search(enum cheat_search_type search_type); +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(void *data, bool wraparound); +int cheat_manager_delete_match(void *data, bool wraparound); RETRO_END_DECLS #endif diff --git a/menu/cbs/menu_cbs_cancel.c b/menu/cbs/menu_cbs_cancel.c index 830cfb6e6d..ddd6d09f1d 100644 --- a/menu/cbs/menu_cbs_cancel.c +++ b/menu/cbs/menu_cbs_cancel.c @@ -19,6 +19,7 @@ #include "../menu_driver.h" #include "../menu_cbs.h" #include "../../msg_hash.h" +#include "../../managers/cheat_manager.h" #include "../widgets/menu_filebrowser.h" @@ -34,8 +35,9 @@ static int action_cancel_pop_default(const char *path, { size_t new_selection_ptr; const char *menu_label = NULL; + enum msg_hash_enums enum_idx = 0 ; - menu_entries_get_last_stack(NULL, &menu_label, NULL, NULL, NULL); + menu_entries_get_last_stack(NULL, &menu_label, NULL, &enum_idx, NULL); if (!string_is_empty(menu_label)) { @@ -60,6 +62,13 @@ static int action_cancel_pop_default(const char *path, return 0; } +static int action_cancel_cheat_details(const char *path, + const char *label, unsigned type, size_t idx) +{ + cheat_manager_copy_working_to_idx(cheat_manager_state.working_cheat.idx) ; + return action_cancel_pop_default(path, label, type, idx) ; +} + static int action_cancel_core_content(const char *path, const char *label, unsigned type, size_t idx) { @@ -98,6 +107,41 @@ static int menu_cbs_init_bind_cancel_compare_type( BIND_ACTION_CANCEL(cbs, action_cancel_core_content); return 0; } + + switch ( cbs->enum_idx ) + { + + case MENU_ENUM_LABEL_CHEAT_IDX: + case MENU_ENUM_LABEL_CHEAT_STATE: + case MENU_ENUM_LABEL_CHEAT_DESC: + case MENU_ENUM_LABEL_CHEAT_HANDLER: + case MENU_ENUM_LABEL_CHEAT_CODE: + case MENU_ENUM_LABEL_CHEAT_MEMORY_SEARCH_SIZE: + case MENU_ENUM_LABEL_CHEAT_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_RUMBLE_TYPE: + case MENU_ENUM_LABEL_CHEAT_RUMBLE_VALUE: + case MENU_ENUM_LABEL_CHEAT_RUMBLE_PORT: + case MENU_ENUM_LABEL_CHEAT_RUMBLE_PRIMARY_STRENGTH: + case MENU_ENUM_LABEL_CHEAT_RUMBLE_PRIMARY_DURATION: + case MENU_ENUM_LABEL_CHEAT_RUMBLE_SECONDARY_STRENGTH: + case MENU_ENUM_LABEL_CHEAT_RUMBLE_SECONDARY_DURATION: + case MENU_ENUM_LABEL_CHEAT_ADD_NEW_AFTER: + case MENU_ENUM_LABEL_CHEAT_ADD_NEW_BEFORE: + case MENU_ENUM_LABEL_CHEAT_COPY_AFTER: + case MENU_ENUM_LABEL_CHEAT_COPY_BEFORE: + case MENU_ENUM_LABEL_CHEAT_DELETE: + { + BIND_ACTION_CANCEL(cbs, action_cancel_cheat_details); + break ; + } + default : + { + break ; + } + } return -1; } diff --git a/menu/cbs/menu_cbs_deferred_push.c b/menu/cbs/menu_cbs_deferred_push.c index 947ff0937a..5312f3f507 100644 --- a/menu/cbs/menu_cbs_deferred_push.c +++ b/menu/cbs/menu_cbs_deferred_push.c @@ -115,6 +115,7 @@ generic_deferred_push(deferred_push_video_filter, DISPLAYLIST_ generic_deferred_push(deferred_push_images, DISPLAYLIST_IMAGES) generic_deferred_push(deferred_push_audio_dsp_plugin, DISPLAYLIST_AUDIO_FILTERS) generic_deferred_push(deferred_push_cheat_file_load, DISPLAYLIST_CHEAT_FILES) +generic_deferred_push(deferred_push_cheat_file_load_append, DISPLAYLIST_CHEAT_FILES) generic_deferred_push(deferred_push_remap_file_load, DISPLAYLIST_REMAP_FILES) generic_deferred_push(deferred_push_record_configfile, DISPLAYLIST_RECORD_CONFIG_FILES) generic_deferred_push(deferred_push_input_overlay, DISPLAYLIST_OVERLAYS) @@ -139,6 +140,8 @@ generic_deferred_push(deferred_push_mixer_stream_settings_list, DISPLAYLIST_ generic_deferred_push(deferred_push_logging_settings_list, DISPLAYLIST_LOGGING_SETTINGS_LIST) generic_deferred_push(deferred_push_frame_throttle_settings_list, DISPLAYLIST_FRAME_THROTTLE_SETTINGS_LIST) generic_deferred_push(deferred_push_rewind_settings_list, DISPLAYLIST_REWIND_SETTINGS_LIST) +generic_deferred_push(deferred_push_cheat_details_settings_list, DISPLAYLIST_CHEAT_DETAILS_SETTINGS_LIST) +generic_deferred_push(deferred_push_cheat_search_settings_list, DISPLAYLIST_CHEAT_SEARCH_SETTINGS_LIST) generic_deferred_push(deferred_push_onscreen_display_settings_list, DISPLAYLIST_ONSCREEN_DISPLAY_SETTINGS_LIST) generic_deferred_push(deferred_push_onscreen_notifications_settings_list, DISPLAYLIST_ONSCREEN_NOTIFICATIONS_SETTINGS_LIST) generic_deferred_push(deferred_push_onscreen_overlay_settings_list, DISPLAYLIST_ONSCREEN_OVERLAY_SETTINGS_LIST) @@ -653,6 +656,16 @@ static int menu_cbs_init_bind_deferred_push_compare_label( BIND_ACTION_DEFERRED_PUSH(cbs, deferred_push_rewind_settings_list); return 0; } + else if (string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_CHEAT_DETAILS_SETTINGS_LIST))) + { + BIND_ACTION_DEFERRED_PUSH(cbs, deferred_push_cheat_details_settings_list); + return 0; + } + else if (string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_CHEAT_SEARCH_SETTINGS_LIST))) + { + BIND_ACTION_DEFERRED_PUSH(cbs, deferred_push_cheat_search_settings_list); + return 0; + } else if (string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_ONSCREEN_DISPLAY_SETTINGS_LIST))) { BIND_ACTION_DEFERRED_PUSH(cbs, deferred_push_onscreen_display_settings_list); @@ -1002,6 +1015,9 @@ static int menu_cbs_init_bind_deferred_push_compare_label( case MENU_ENUM_LABEL_CHEAT_FILE_LOAD: BIND_ACTION_DEFERRED_PUSH(cbs, deferred_push_cheat_file_load); break; + case MENU_ENUM_LABEL_CHEAT_FILE_LOAD_APPEND: + BIND_ACTION_DEFERRED_PUSH(cbs, deferred_push_cheat_file_load_append); + break; case MENU_ENUM_LABEL_REMAP_FILE_LOAD: BIND_ACTION_DEFERRED_PUSH(cbs, deferred_push_remap_file_load); break; @@ -1258,6 +1274,9 @@ static int menu_cbs_init_bind_deferred_push_compare_label( case MENU_LABEL_CHEAT_FILE_LOAD: BIND_ACTION_DEFERRED_PUSH(cbs, deferred_push_cheat_file_load); break; + case MENU_LABEL_CHEAT_FILE_LOAD_APPEND: + BIND_ACTION_DEFERRED_PUSH(cbs, deferred_push_cheat_file_load_append); + break; case MENU_LABEL_REMAP_FILE_LOAD: BIND_ACTION_DEFERRED_PUSH(cbs, deferred_push_remap_file_load); break; diff --git a/menu/cbs/menu_cbs_get_value.c b/menu/cbs/menu_cbs_get_value.c index 556e137606..5c35f18158 100644 --- a/menu/cbs/menu_cbs_get_value.c +++ b/menu/cbs/menu_cbs_get_value.c @@ -687,14 +687,47 @@ static void menu_action_setting_disp_set_label_cheat( unsigned cheat_index = type - MENU_SETTINGS_CHEAT_BEGIN; if (cheat_index < cheat_manager_get_buf_size()) - snprintf(s, len, "%s : (%s)", - (cheat_manager_get_code(cheat_index) != NULL) - ? cheat_manager_get_code(cheat_index) : - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NOT_AVAILABLE), - cheat_manager_get_code_state(cheat_index) ? - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_ON) : - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF) - ); + { + if ( cheat_manager_state.cheats[cheat_index].handler == CHEAT_HANDLER_TYPE_EMU) + { + snprintf(s, len, "%s : (%s)", + (cheat_manager_get_code(cheat_index) != NULL) + ? cheat_manager_get_code(cheat_index) : + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NOT_AVAILABLE), + cheat_manager_get_code_state(cheat_index) ? + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_ON) : + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF) + ); + } + else + { + snprintf(s, len, "%08X : (%s)", cheat_manager_state.cheats[cheat_index].address, + cheat_manager_get_code_state(cheat_index) ? + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_ON) : + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF) + ); + } + } + *w = 19; + strlcpy(s2, path, len2); +} + +static void menu_action_setting_disp_set_label_cheat_match( + file_list_t* list, + unsigned *w, unsigned type, unsigned i, + const char *label, + char *s, size_t len, + const char *entry_label, + const char *path, + char *s2, size_t len2) +{ + unsigned int address = 0; + unsigned int address_mask = 0; + unsigned int prev_val = 0; + unsigned int curr_val = 0 ; + cheat_manager_match_action(CHEAT_MATCH_ACTION_TYPE_VIEW, cheat_manager_state.match_idx, &address, &address_mask, &prev_val, &curr_val) ; + + snprintf(s, len, "Prev: %u Curr: %u", prev_val, curr_val) ; *w = 19; strlcpy(s2, path, len2); } @@ -2268,6 +2301,10 @@ static int menu_cbs_init_bind_get_string_representation_compare_type( BIND_ACTION_GET_VALUE(cbs, menu_action_setting_disp_set_label_menu_file_cheat); break; + case MENU_SETTINGS_CHEAT_MATCH: + BIND_ACTION_GET_VALUE(cbs, + menu_action_setting_disp_set_label_cheat_match); + break; case MENU_SETTING_SUBGROUP: case MENU_SETTINGS_CUSTOM_BIND_ALL: case MENU_SETTINGS_CUSTOM_BIND_DEFAULT_ALL: diff --git a/menu/cbs/menu_cbs_left.c b/menu/cbs/menu_cbs_left.c index 529feaa923..28613bcf81 100644 --- a/menu/cbs/menu_cbs_left.c +++ b/menu/cbs/menu_cbs_left.c @@ -571,7 +571,7 @@ static int action_left_cheat_num_passes(unsigned type, const char *label, new_size = cheat_manager_get_size() - 1; menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh); menu_driver_ctl(RARCH_MENU_CTL_SET_PREVENT_POPULATE, NULL); - cheat_manager_realloc(new_size); + cheat_manager_realloc(new_size, CHEAT_HANDLER_TYPE_RETRO); return 0; } diff --git a/menu/cbs/menu_cbs_ok.c b/menu/cbs/menu_cbs_ok.c index 6440e237a3..6320c7e89b 100644 --- a/menu/cbs/menu_cbs_ok.c +++ b/menu/cbs/menu_cbs_ok.c @@ -87,7 +87,8 @@ enum ACTION_OK_SET_PATH_AUDIO_FILTER, ACTION_OK_SET_PATH_VIDEO_FILTER, ACTION_OK_SET_PATH_OVERLAY, - ACTION_OK_SET_DIRECTORY + ACTION_OK_SET_DIRECTORY, + ACTION_OK_LOAD_CHEAT_FILE_APPEND, }; enum @@ -278,6 +279,10 @@ static enum msg_hash_enums action_ok_dl_to_enum(unsigned lbl) return MENU_ENUM_LABEL_DEFERRED_FRAME_THROTTLE_SETTINGS_LIST; case ACTION_OK_DL_REWIND_SETTINGS_LIST: return MENU_ENUM_LABEL_DEFERRED_REWIND_SETTINGS_LIST; + case ACTION_OK_DL_CHEAT_DETAILS_SETTINGS_LIST: + return MENU_ENUM_LABEL_DEFERRED_CHEAT_DETAILS_SETTINGS_LIST; + case ACTION_OK_DL_CHEAT_SEARCH_SETTINGS_LIST: + return MENU_ENUM_LABEL_DEFERRED_CHEAT_SEARCH_SETTINGS_LIST; case ACTION_OK_DL_ONSCREEN_DISPLAY_SETTINGS_LIST: return MENU_ENUM_LABEL_DEFERRED_ONSCREEN_DISPLAY_SETTINGS_LIST; case ACTION_OK_DL_ONSCREEN_NOTIFICATIONS_SETTINGS_LIST: @@ -611,6 +616,14 @@ int generic_action_ok_displaylist_push(const char *path, info_label = label; dl_type = DISPLAYLIST_FILE_BROWSER_SELECT_FILE; break; + case ACTION_OK_DL_CHEAT_FILE_APPEND: + filebrowser_clear_type(); + info.type = type; + info.directory_ptr = idx; + info_path = settings->paths.path_cheat_database; + info_label = label; + dl_type = DISPLAYLIST_FILE_BROWSER_SELECT_FILE; + break; case ACTION_OK_DL_CORE_LIST: filebrowser_clear_type(); info.type = type; @@ -815,6 +828,49 @@ int generic_action_ok_displaylist_push(const char *path, MENU_ENUM_LABEL_DEFERRED_CORE_LIST_SET; dl_type = DISPLAYLIST_GENERIC; break; + case ACTION_OK_DL_CHEAT_DETAILS_SETTINGS_LIST: + { + cheat_manager_copy_idx_to_working(type-MENU_SETTINGS_CHEAT_BEGIN) ; + rarch_setting_t *setting = menu_setting_find(msg_hash_to_str(MENU_ENUM_LABEL_CHEAT_IDX)); + if ( setting ) { + setting->max = cheat_manager_get_size()-1 ; + } + setting = menu_setting_find(msg_hash_to_str(MENU_ENUM_LABEL_CHEAT_VALUE)); + if ( setting ) { + setting->max = (int) pow(2,pow((double) 2,cheat_manager_state.working_cheat.memory_search_size))-1; + } + setting = menu_setting_find(msg_hash_to_str(MENU_ENUM_LABEL_CHEAT_RUMBLE_VALUE)); + if ( setting ) { + setting->max = (int) pow(2,pow((double) 2,cheat_manager_state.working_cheat.memory_search_size))-1; + } + setting = menu_setting_find(msg_hash_to_str(MENU_ENUM_LABEL_CHEAT_ADDRESS_BIT_POSITION)); + if ( setting ) { + int max_bit_position = cheat_manager_state.working_cheat.memory_search_size<3 ? 7 : 0 ; + setting->max = max_bit_position ; + } + action_ok_dl_lbl(action_ok_dl_to_enum(action_type), DISPLAYLIST_GENERIC); + break ; + } + case ACTION_OK_DL_CHEAT_SEARCH_SETTINGS_LIST: + { + rarch_setting_t *setting = menu_setting_find(msg_hash_to_str(MENU_ENUM_LABEL_CHEAT_SEARCH_EXACT)); + if ( setting ) { + //*setting->value.target.unsigned_integer = 0 ; + setting->max = (int) pow(2,pow((double) 2,cheat_manager_state.search_bit_size))-1; + } + setting = menu_setting_find(msg_hash_to_str(MENU_ENUM_LABEL_CHEAT_SEARCH_EQPLUS)); + if ( setting ) { + //*setting->value.target.unsigned_integer = 0 ; + setting->max = (int) pow(2,pow((double) 2,cheat_manager_state.search_bit_size))-1; + } + setting = menu_setting_find(msg_hash_to_str(MENU_ENUM_LABEL_CHEAT_SEARCH_EQMINUS)); + if ( setting ) { + //*setting->value.target.unsigned_integer = 0 ; + setting->max = (int) pow(2,pow((double) 2,cheat_manager_state.search_bit_size))-1; + } + action_ok_dl_lbl(action_ok_dl_to_enum(action_type), DISPLAYLIST_GENERIC); + break ; + } case ACTION_OK_DL_MIXER_STREAM_SETTINGS_LIST: case ACTION_OK_DL_ACCOUNTS_LIST: case ACTION_OK_DL_INPUT_SETTINGS_LIST: @@ -1349,7 +1405,14 @@ static int generic_action_ok(const char *path, flush_char = msg_hash_to_str(flush_id); cheat_manager_free(); - if (!cheat_manager_load(action_path)) + if (!cheat_manager_load(action_path,false)) + goto error; + break; + case ACTION_OK_LOAD_CHEAT_FILE_APPEND: + flush_char = msg_hash_to_str(flush_id); + //cheat_manager_free(); + + if (!cheat_manager_load(action_path,true)) goto error; break; case ACTION_OK_APPEND_DISK_IMAGE: @@ -1441,6 +1504,7 @@ default_action_ok_set(action_ok_config_load, ACTION_OK_LOAD_CONFIG_FILE default_action_ok_set(action_ok_disk_image_append, ACTION_OK_APPEND_DISK_IMAGE, MSG_UNKNOWN) default_action_ok_set(action_ok_subsystem_add, ACTION_OK_SUBSYSTEM_ADD, MSG_UNKNOWN) default_action_ok_set(action_ok_cheat_file_load, ACTION_OK_LOAD_CHEAT_FILE, MENU_ENUM_LABEL_CORE_CHEAT_OPTIONS) +default_action_ok_set(action_ok_cheat_file_load_append, ACTION_OK_LOAD_CHEAT_FILE_APPEND, MENU_ENUM_LABEL_CORE_CHEAT_OPTIONS) default_action_ok_set(action_ok_record_configfile_load, ACTION_OK_LOAD_RECORD_CONFIGFILE, MENU_ENUM_LABEL_RECORDING_SETTINGS) default_action_ok_set(action_ok_remap_file_load, ACTION_OK_LOAD_REMAPPING_FILE, MENU_ENUM_LABEL_CORE_INPUT_REMAPPING_OPTIONS ) default_action_ok_set(action_ok_shader_preset_load, ACTION_OK_LOAD_PRESET , MENU_ENUM_LABEL_SHADER_OPTIONS) @@ -2018,21 +2082,6 @@ int generic_action_ok_help(const char *path, entry_idx, ACTION_OK_DL_HELP); } - -static void menu_input_st_cheat_cb(void *userdata, const char *str) -{ - (void)userdata; - - if (str && *str) - { - unsigned cheat_index = menu_input_dialog_get_kb_type() - - MENU_SETTINGS_CHEAT_BEGIN; - cheat_manager_set_code(cheat_index, str); - } - - menu_input_dialog_end(); -} - static void menu_input_wifi_cb(void *userdata, const char *passphrase) { unsigned idx = menu_input_dialog_get_kb_idx(); @@ -2170,7 +2219,7 @@ static void menu_input_st_string_cb_cheat_file_save_as( menu_setting_generic(setting, false); } else if (!string_is_empty(label)) - cheat_manager_save(str, settings->paths.path_cheat_database); + cheat_manager_save(str, settings->paths.path_cheat_database,false); } menu_input_dialog_end(); @@ -2206,10 +2255,6 @@ default_action_dialog_start(action_ok_cheat_file_save_as, msg_hash_to_str(MSG_INPUT_CHEAT_FILENAME), (unsigned)idx, menu_input_st_string_cb_cheat_file_save_as) -default_action_dialog_start(action_ok_cheat, - msg_hash_to_str(MSG_INPUT_CHEAT), - (unsigned)idx, - menu_input_st_cheat_cb) default_action_dialog_start(action_ok_disable_kiosk_mode, msg_hash_to_str(MSG_INPUT_KIOSK_MODE_PASSWORD), (unsigned)entry_idx, @@ -2617,6 +2662,233 @@ static int action_ok_audio_run(const char *path, #endif } +static int action_ok_cheat_add_top(const char *path, + const char *label, unsigned type, size_t idx, size_t entry_idx) +{ + char msg[256] ; + bool refresh = false ; + unsigned int new_size = cheat_manager_get_size() + 1; + menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh); + menu_driver_ctl(RARCH_MENU_CTL_SET_PREVENT_POPULATE, NULL); + cheat_manager_realloc(new_size, CHEAT_HANDLER_TYPE_RETRO); + + struct item_cheat tmp ; + + memcpy(&tmp, &cheat_manager_state.cheats[cheat_manager_state.size-1], sizeof(struct item_cheat )) ; + tmp.idx = 0 ; + + for ( int i = cheat_manager_state.size-2 ; i >=0 ; i--) + { + memcpy(&cheat_manager_state.cheats[i+1], &cheat_manager_state.cheats[i], sizeof(struct item_cheat )) ; + cheat_manager_state.cheats[i+1].idx++ ; + } + + memcpy(&cheat_manager_state.cheats[0], &tmp, sizeof(struct item_cheat )) ; + + snprintf(msg, sizeof(msg), msg_hash_to_str(MSG_CHEAT_ADD_TOP_SUCCESS)) ; + msg[sizeof(msg) - 1] = 0; + + runloop_msg_queue_push(msg, 1, 180, true); + + return 0 ; +} + +static int action_ok_cheat_add_bottom(const char *path, + const char *label, unsigned type, size_t idx, size_t entry_idx) +{ + char msg[256] ; + bool refresh = false ; + + unsigned int new_size = cheat_manager_get_size() + 1; + menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh); + menu_driver_ctl(RARCH_MENU_CTL_SET_PREVENT_POPULATE, NULL); + cheat_manager_realloc(new_size, CHEAT_HANDLER_TYPE_RETRO); + + snprintf(msg, sizeof(msg), msg_hash_to_str(MSG_CHEAT_ADD_BOTTOM_SUCCESS)) ; + msg[sizeof(msg) - 1] = 0; + + runloop_msg_queue_push(msg, 1, 180, true); + + return 0 ; +} + +static int action_ok_cheat_delete_all(const char *path, + const char *label, unsigned type, size_t idx, size_t entry_idx) +{ + char msg[256] ; + snprintf(msg, sizeof(msg), msg_hash_to_str(MSG_CHEAT_DELETE_ALL_INSTRUCTIONS)) ; + msg[sizeof(msg) - 1] = 0; + + runloop_msg_queue_push(msg, 1, 240, true); + return 0 ; +} + +static int action_ok_cheat_add_new_after(const char *path, + const char *label, unsigned type, size_t idx, size_t entry_idx) +{ + char msg[256] ; + bool refresh = false ; + unsigned int new_size = cheat_manager_get_size() + 1; + cheat_manager_realloc(new_size, CHEAT_HANDLER_TYPE_RETRO); + + struct item_cheat tmp ; + + memcpy(&tmp, &cheat_manager_state.cheats[cheat_manager_state.size-1], sizeof(struct item_cheat )) ; + tmp.idx = cheat_manager_state.working_cheat.idx+1 ; + + for ( int i = cheat_manager_state.size-2 ; i >=cheat_manager_state.working_cheat.idx+1 ; i--) + { + memcpy(&cheat_manager_state.cheats[i+1], &cheat_manager_state.cheats[i], sizeof(struct item_cheat )) ; + cheat_manager_state.cheats[i+1].idx++ ; + } + + memcpy(&cheat_manager_state.cheats[cheat_manager_state.working_cheat.idx+1], &tmp, sizeof(struct item_cheat )) ; + + menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh); + menu_driver_ctl(RARCH_MENU_CTL_SET_PREVENT_POPULATE, NULL); + + snprintf(msg, sizeof(msg), msg_hash_to_str(MSG_CHEAT_ADD_AFTER_SUCCESS)) ; + msg[sizeof(msg) - 1] = 0; + + runloop_msg_queue_push(msg, 1, 180, true); + + return 0 ; +} + +static int action_ok_cheat_add_new_before(const char *path, + const char *label, unsigned type, size_t idx, size_t entry_idx) +{ + char msg[256] ; + bool refresh = false ; + unsigned int new_size = cheat_manager_get_size() + 1; + cheat_manager_realloc(new_size, CHEAT_HANDLER_TYPE_RETRO); + + struct item_cheat tmp ; + + memcpy(&tmp, &cheat_manager_state.cheats[cheat_manager_state.size-1], sizeof(struct item_cheat )) ; + tmp.idx = cheat_manager_state.working_cheat.idx ; + + for ( int i = cheat_manager_state.size-2 ; i >=(int)tmp.idx ; i--) + { + memcpy(&cheat_manager_state.cheats[i+1], &cheat_manager_state.cheats[i], sizeof(struct item_cheat )) ; + cheat_manager_state.cheats[i+1].idx++ ; + } + + memcpy(&cheat_manager_state.cheats[tmp.idx], &tmp, sizeof(struct item_cheat )) ; + memcpy(&cheat_manager_state.working_cheat, &tmp, sizeof(struct item_cheat )) ; + + menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh); + menu_driver_ctl(RARCH_MENU_CTL_SET_PREVENT_POPULATE, NULL); + + snprintf(msg, sizeof(msg), msg_hash_to_str(MSG_CHEAT_ADD_BEFORE_SUCCESS)) ; + msg[sizeof(msg) - 1] = 0; + + runloop_msg_queue_push(msg, 1, 180, true); + + return 0 ; +} + +static int action_ok_cheat_copy_before(const char *path, + const char *label, unsigned type, size_t idx, size_t entry_idx) +{ + char msg[256] ; + bool refresh = false ; + unsigned int new_size = cheat_manager_get_size() + 1; + cheat_manager_realloc(new_size, CHEAT_HANDLER_TYPE_RETRO); + + struct item_cheat tmp ; + + memcpy(&tmp, &cheat_manager_state.cheats[cheat_manager_state.working_cheat.idx], sizeof(struct item_cheat )) ; + tmp.idx = cheat_manager_state.working_cheat.idx ; + + for ( int i = cheat_manager_state.size-2 ; i >=(int)tmp.idx ; i--) + { + memcpy(&cheat_manager_state.cheats[i+1], &cheat_manager_state.cheats[i], sizeof(struct item_cheat )) ; + cheat_manager_state.cheats[i+1].idx++ ; + } + + memcpy(&cheat_manager_state.cheats[tmp.idx], &tmp, sizeof(struct item_cheat )) ; + memcpy(&cheat_manager_state.working_cheat, &tmp, sizeof(struct item_cheat )) ; + + menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh); + menu_driver_ctl(RARCH_MENU_CTL_SET_PREVENT_POPULATE, NULL); + + snprintf(msg, sizeof(msg), msg_hash_to_str(MSG_CHEAT_COPY_BEFORE_SUCCESS)) ; + msg[sizeof(msg) - 1] = 0; + + runloop_msg_queue_push(msg, 1, 180, true); + + + return 0 ; +} + +static int action_ok_cheat_copy_after(const char *path, + const char *label, unsigned type, size_t idx, size_t entry_idx) +{ + char msg[256] ; + bool refresh = false ; + unsigned int new_size = cheat_manager_get_size() + 1; + cheat_manager_realloc(new_size, CHEAT_HANDLER_TYPE_RETRO); + + struct item_cheat tmp ; + + memcpy(&tmp, &cheat_manager_state.cheats[cheat_manager_state.working_cheat.idx], sizeof(struct item_cheat )) ; + tmp.idx = cheat_manager_state.working_cheat.idx+1 ; + + for ( int i = cheat_manager_state.size-2 ; i >=cheat_manager_state.working_cheat.idx+1 ; i--) + { + memcpy(&cheat_manager_state.cheats[i+1], &cheat_manager_state.cheats[i], sizeof(struct item_cheat )) ; + cheat_manager_state.cheats[i+1].idx++ ; + } + + memcpy(&cheat_manager_state.cheats[cheat_manager_state.working_cheat.idx+1], &tmp, sizeof(struct item_cheat )) ; + + menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh); + menu_driver_ctl(RARCH_MENU_CTL_SET_PREVENT_POPULATE, NULL); + + snprintf(msg, sizeof(msg), msg_hash_to_str(MSG_CHEAT_COPY_AFTER_SUCCESS)) ; + msg[sizeof(msg) - 1] = 0; + + runloop_msg_queue_push(msg, 1, 180, true); + + return 0 ; +} + +static int action_ok_cheat_delete(const char *path, + const char *label, unsigned type, size_t idx, size_t entry_idx) +{ + char msg[256] ; + bool refresh = false ; + unsigned int new_size = cheat_manager_get_size() - 1; + + if( new_size >0 ) + { + for ( int i = cheat_manager_state.working_cheat.idx ; i enum_idx) { + case MENU_ENUM_LABEL_CHEAT_START_OR_CONT: + BIND_ACTION_OK(cbs, action_ok_cheat_start_or_cont); + break; + case MENU_ENUM_LABEL_CHEAT_ADD_NEW_TOP: + BIND_ACTION_OK(cbs, action_ok_cheat_add_top); + break; + case MENU_ENUM_LABEL_CHEAT_ADD_NEW_BOTTOM: + BIND_ACTION_OK(cbs, action_ok_cheat_add_bottom); + break; + case MENU_ENUM_LABEL_CHEAT_DELETE_ALL: + BIND_ACTION_OK(cbs, action_ok_cheat_delete_all); + break; + case MENU_ENUM_LABEL_CHEAT_ADD_NEW_AFTER: + BIND_ACTION_OK(cbs, action_ok_cheat_add_new_after); + break; + case MENU_ENUM_LABEL_CHEAT_ADD_NEW_BEFORE: + BIND_ACTION_OK(cbs, action_ok_cheat_add_new_before); + break; + case MENU_ENUM_LABEL_CHEAT_COPY_AFTER: + BIND_ACTION_OK(cbs, action_ok_cheat_copy_after); + break; + case MENU_ENUM_LABEL_CHEAT_COPY_BEFORE: + BIND_ACTION_OK(cbs, action_ok_cheat_copy_before); + break; + case MENU_ENUM_LABEL_CHEAT_DELETE: + BIND_ACTION_OK(cbs, action_ok_cheat_delete); + break; case MENU_ENUM_LABEL_RUN_MUSIC: BIND_ACTION_OK(cbs, action_ok_audio_run); break; @@ -4433,6 +4735,9 @@ static int menu_cbs_init_bind_ok_compare_label(menu_file_list_cbs_t *cbs, case MENU_ENUM_LABEL_CHEAT_FILE_LOAD: BIND_ACTION_OK(cbs, action_ok_cheat_file); break; + case MENU_ENUM_LABEL_CHEAT_FILE_LOAD_APPEND: + BIND_ACTION_OK(cbs, action_ok_cheat_file_append); + break; case MENU_ENUM_LABEL_AUDIO_DSP_PLUGIN: BIND_ACTION_OK(cbs, action_ok_audio_dsp_plugin); break; @@ -4722,6 +5027,9 @@ static int menu_cbs_init_bind_ok_compare_label(menu_file_list_cbs_t *cbs, case MENU_ENUM_LABEL_UPDATE_CHEATS: BIND_ACTION_OK(cbs, action_ok_update_cheats); break; + case MENU_ENUM_LABEL_CHEAT_ADD_MATCHES: + BIND_ACTION_OK(cbs, cheat_manager_add_matches); + break; case MENU_ENUM_LABEL_UPDATE_AUTOCONFIG_PROFILES: BIND_ACTION_OK(cbs, action_ok_update_autoconfig_profiles); break; @@ -4770,6 +5078,9 @@ static int menu_cbs_init_bind_ok_compare_label(menu_file_list_cbs_t *cbs, case MENU_LABEL_CHEAT_FILE_LOAD: BIND_ACTION_OK(cbs, action_ok_cheat_file); break; + case MENU_LABEL_CHEAT_FILE_LOAD_APPEND: + BIND_ACTION_OK(cbs, action_ok_cheat_file_append); + break; case MENU_LABEL_AUDIO_DSP_PLUGIN: BIND_ACTION_OK(cbs, action_ok_audio_dsp_plugin); break; @@ -4925,7 +5236,14 @@ static int menu_cbs_init_bind_ok_compare_type(menu_file_list_cbs_t *cbs, BIND_ACTION_OK(cbs, action_ok_push_generic_list); break; case FILE_TYPE_CHEAT: - BIND_ACTION_OK(cbs, action_ok_cheat_file_load); + if ( menu_label_hash == MENU_LABEL_CHEAT_FILE_LOAD_APPEND ) + { + BIND_ACTION_OK(cbs, action_ok_cheat_file_load_append); + } + else + { + BIND_ACTION_OK(cbs, action_ok_cheat_file_load); + } break; case FILE_TYPE_RECORD_CONFIG: BIND_ACTION_OK(cbs, action_ok_record_configfile_load); diff --git a/menu/cbs/menu_cbs_right.c b/menu/cbs/menu_cbs_right.c index aec568435b..2bf06e79b3 100644 --- a/menu/cbs/menu_cbs_right.c +++ b/menu/cbs/menu_cbs_right.c @@ -272,6 +272,28 @@ static int action_right_mainmenu(unsigned type, const char *label, return 0; } +static int action_right_cheat_delete_all(unsigned type, const char *label, + bool wraparound) +{ + bool refresh = false ; + char msg[256] ; + + if ( ++cheat_manager_state.delete_state >= 5 ) + { + cheat_manager_state.delete_state = 0 ; + cheat_manager_realloc(0, CHEAT_HANDLER_TYPE_EMU) ; + menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh); + menu_driver_ctl(RARCH_MENU_CTL_SET_PREVENT_POPULATE, NULL); + + snprintf(msg, sizeof(msg), msg_hash_to_str(MSG_CHEAT_DELETE_ALL_SUCCESS)) ; + msg[sizeof(msg) - 1] = 0; + + runloop_msg_queue_push(msg, 1, 180, true); + } + + return 0; +} + static int action_right_shader_scale_pass(unsigned type, const char *label, bool wraparound) { @@ -328,7 +350,7 @@ static int action_right_cheat_num_passes(unsigned type, const char *label, new_size = cheat_manager_get_size() + 1; menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh); menu_driver_ctl(RARCH_MENU_CTL_SET_PREVENT_POPULATE, NULL); - cheat_manager_realloc(new_size); + cheat_manager_realloc(new_size, CHEAT_HANDLER_TYPE_RETRO); return 0; } @@ -656,6 +678,9 @@ static int menu_cbs_init_bind_right_compare_label(menu_file_list_cbs_t *cbs, case MENU_ENUM_LABEL_CONNECT_NETPLAY_ROOM: BIND_ACTION_RIGHT(cbs, action_right_mainmenu); break; + case MENU_ENUM_LABEL_CHEAT_DELETE_ALL: + BIND_ACTION_RIGHT(cbs, action_right_cheat_delete_all); + break; case MENU_ENUM_LABEL_VIDEO_SHADER_SCALE_PASS: BIND_ACTION_RIGHT(cbs, action_right_shader_scale_pass); break; diff --git a/menu/cbs/menu_cbs_start.c b/menu/cbs/menu_cbs_start.c index 7917cc9b0d..129a017be6 100644 --- a/menu/cbs/menu_cbs_start.c +++ b/menu/cbs/menu_cbs_start.c @@ -205,7 +205,7 @@ static int action_start_cheat_num_passes(unsigned type, const char *label) { bool refresh = false; menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh); - cheat_manager_realloc(0); + cheat_manager_realloc(0, CHEAT_HANDLER_TYPE_EMU); } return 0; diff --git a/menu/cbs/menu_cbs_sublabel.c b/menu/cbs/menu_cbs_sublabel.c index 8f0102625b..592ccea299 100644 --- a/menu/cbs/menu_cbs_sublabel.c +++ b/menu/cbs/menu_cbs_sublabel.c @@ -41,6 +41,7 @@ #include "../../retroarch.h" #include "../../content.h" #include "../../configuration.h" +#include "../../managers/cheat_manager.h" #define default_sublabel_macro(func_name, lbl) \ static int (func_name)(file_list_t *list, unsigned type, unsigned i, const char *label, const char *path, char *s, size_t len) \ @@ -208,6 +209,26 @@ default_sublabel_macro(action_bind_sublabel_rewind, MENU_ default_sublabel_macro(action_bind_sublabel_rewind_granularity, MENU_ENUM_SUBLABEL_REWIND_GRANULARITY) default_sublabel_macro(action_bind_sublabel_rewind_buffer_size, MENU_ENUM_SUBLABEL_REWIND_BUFFER_SIZE) default_sublabel_macro(action_bind_sublabel_rewind_buffer_size_step, MENU_ENUM_SUBLABEL_REWIND_BUFFER_SIZE_STEP) +default_sublabel_macro(action_bind_sublabel_cheat_idx, MENU_ENUM_SUBLABEL_CHEAT_IDX) +default_sublabel_macro(action_bind_sublabel_cheat_match_idx, MENU_ENUM_SUBLABEL_CHEAT_MATCH_IDX) +default_sublabel_macro(action_bind_sublabel_cheat_big_endian, MENU_ENUM_SUBLABEL_CHEAT_BIG_ENDIAN) +default_sublabel_macro(action_bind_sublabel_cheat_start_or_cont, MENU_ENUM_SUBLABEL_CHEAT_START_OR_CONT) +default_sublabel_macro(action_bind_sublabel_cheat_start_or_restart, MENU_ENUM_SUBLABEL_CHEAT_START_OR_RESTART) +default_sublabel_macro(action_bind_sublabel_cheat_search_exact, MENU_ENUM_SUBLABEL_CHEAT_SEARCH_EXACT) +default_sublabel_macro(action_bind_sublabel_cheat_search_lt, MENU_ENUM_SUBLABEL_CHEAT_SEARCH_LT) +default_sublabel_macro(action_bind_sublabel_cheat_search_gt, MENU_ENUM_SUBLABEL_CHEAT_SEARCH_GT) +default_sublabel_macro(action_bind_sublabel_cheat_search_eq, MENU_ENUM_SUBLABEL_CHEAT_SEARCH_EQ) +default_sublabel_macro(action_bind_sublabel_cheat_search_neq, MENU_ENUM_SUBLABEL_CHEAT_SEARCH_NEQ) +default_sublabel_macro(action_bind_sublabel_cheat_search_eqplus, MENU_ENUM_SUBLABEL_CHEAT_SEARCH_EQPLUS) +default_sublabel_macro(action_bind_sublabel_cheat_search_eqminus, MENU_ENUM_SUBLABEL_CHEAT_SEARCH_EQMINUS) +default_sublabel_macro(action_bind_sublabel_cheat_add_matches, MENU_ENUM_SUBLABEL_CHEAT_ADD_MATCHES) +default_sublabel_macro(action_bind_sublabel_cheat_view_matches, MENU_ENUM_SUBLABEL_CHEAT_VIEW_MATCHES) +default_sublabel_macro(action_bind_sublabel_cheat_create_option, MENU_ENUM_SUBLABEL_CHEAT_CREATE_OPTION) +default_sublabel_macro(action_bind_sublabel_cheat_delete_option, MENU_ENUM_SUBLABEL_CHEAT_DELETE_OPTION) +default_sublabel_macro(action_bind_sublabel_cheat_add_new_top, MENU_ENUM_SUBLABEL_CHEAT_ADD_NEW_TOP) +default_sublabel_macro(action_bind_sublabel_cheat_add_new_bottom, MENU_ENUM_SUBLABEL_CHEAT_ADD_NEW_BOTTOM) +default_sublabel_macro(action_bind_sublabel_cheat_address_bit_position, MENU_ENUM_SUBLABEL_CHEAT_ADDRESS_BIT_POSITION) +default_sublabel_macro(action_bind_sublabel_cheat_delete_all, MENU_ENUM_SUBLABEL_CHEAT_DELETE_ALL) default_sublabel_macro(action_bind_sublabel_libretro_log_level, MENU_ENUM_SUBLABEL_LIBRETRO_LOG_LEVEL) default_sublabel_macro(action_bind_sublabel_perfcnt_enable, MENU_ENUM_SUBLABEL_PERFCNT_ENABLE) default_sublabel_macro(action_bind_sublabel_savestate_auto_save, MENU_ENUM_SUBLABEL_SAVESTATE_AUTO_SAVE) @@ -303,6 +324,8 @@ default_sublabel_macro(action_bind_sublabel_undo_save_state, default_sublabel_macro(action_bind_sublabel_accounts_retro_achievements, MENU_ENUM_SUBLABEL_ACCOUNTS_RETRO_ACHIEVEMENTS) default_sublabel_macro(action_bind_sublabel_accounts_list, MENU_ENUM_SUBLABEL_ACCOUNTS_LIST) default_sublabel_macro(action_bind_sublabel_input_meta_rewind, MENU_ENUM_SUBLABEL_INPUT_META_REWIND) +default_sublabel_macro(action_bind_sublabel_input_meta_cheat_details, MENU_ENUM_SUBLABEL_INPUT_META_CHEAT_DETAILS) +default_sublabel_macro(action_bind_sublabel_input_meta_cheat_search, MENU_ENUM_SUBLABEL_INPUT_META_CHEAT_SEARCH) default_sublabel_macro(action_bind_sublabel_restart_content, MENU_ENUM_SUBLABEL_RESTART_CONTENT) default_sublabel_macro(action_bind_sublabel_save_current_config_override_core, MENU_ENUM_SUBLABEL_SAVE_CURRENT_CONFIG_OVERRIDE_CORE) default_sublabel_macro(action_bind_sublabel_save_current_config_override_content_dir, @@ -415,6 +438,7 @@ default_sublabel_macro(action_bind_sublabel_shader_preset_parameters, default_sublabel_macro(action_bind_sublabel_cheat_apply_changes, MENU_ENUM_SUBLABEL_CHEAT_APPLY_CHANGES) default_sublabel_macro(action_bind_sublabel_cheat_num_passes, MENU_ENUM_SUBLABEL_CHEAT_NUM_PASSES) default_sublabel_macro(action_bind_sublabel_cheat_file_load, MENU_ENUM_SUBLABEL_CHEAT_FILE_LOAD) +default_sublabel_macro(action_bind_sublabel_cheat_file_load_append, MENU_ENUM_SUBLABEL_CHEAT_FILE_LOAD_APPEND) default_sublabel_macro(action_bind_sublabel_cheat_file_save_as, MENU_ENUM_SUBLABEL_CHEAT_FILE_SAVE_AS) default_sublabel_macro(action_bind_sublabel_quick_menu, MENU_ENUM_SUBLABEL_CONTENT_SETTINGS) default_sublabel_macro(action_bind_sublabel_core_information, MENU_ENUM_SUBLABEL_CORE_INFORMATION) @@ -540,6 +564,29 @@ static int action_bind_sublabel_remap_sublabel( return 0; } +static int action_bind_sublabel_cheat_desc( + file_list_t *list, + unsigned type, unsigned i, + const char *label, const char *path, + char *s, size_t len) +{ + unsigned offset = (type - MENU_SETTINGS_CHEAT_BEGIN); + + if ( cheat_manager_state.cheats ) + { + if ( cheat_manager_state.cheats[offset].handler == CHEAT_HANDLER_TYPE_EMU) + { + snprintf(s, len, "Emulator-Handled") ; + } + else + { + snprintf(s, len, "RetroArch-Handled") ; + } + } + + return 0; +} + #ifdef HAVE_NETWORKING static int action_bind_sublabel_netplay_room( file_list_t *list, @@ -652,6 +699,12 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs, BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_remap_sublabel); } + if (type >= MENU_SETTINGS_CHEAT_BEGIN + && type <= MENU_SETTINGS_CHEAT_END) + { + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_cheat_desc); + } + if (type >= MENU_SETTINGS_AUDIO_MIXER_STREAM_BEGIN && type <= MENU_SETTINGS_AUDIO_MIXER_STREAM_END) { @@ -713,6 +766,9 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs, case MENU_ENUM_LABEL_CHEAT_FILE_LOAD: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_cheat_file_load); break; + case MENU_ENUM_LABEL_CHEAT_FILE_LOAD_APPEND: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_cheat_file_load_append); + break; case MENU_ENUM_LABEL_CHEAT_APPLY_CHANGES: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_cheat_apply_changes); break; @@ -1062,6 +1118,12 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs, case MENU_ENUM_LABEL_REWIND_SETTINGS: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_input_meta_rewind); break; + case MENU_ENUM_LABEL_CHEAT_DETAILS_SETTINGS: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_input_meta_cheat_details); + break; + case MENU_ENUM_LABEL_CHEAT_SEARCH_SETTINGS: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_input_meta_cheat_search); + break; case MENU_ENUM_LABEL_ACCOUNTS_LIST: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_accounts_list); break; @@ -1338,6 +1400,66 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs, case MENU_ENUM_LABEL_REWIND_BUFFER_SIZE_STEP: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_rewind_buffer_size_step); break; + case MENU_ENUM_LABEL_CHEAT_IDX: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_cheat_idx); + break; + case MENU_ENUM_LABEL_CHEAT_MATCH_IDX: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_cheat_match_idx); + break; + case MENU_ENUM_LABEL_CHEAT_BIG_ENDIAN: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_cheat_big_endian); + break; + case MENU_ENUM_LABEL_CHEAT_START_OR_CONT: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_cheat_start_or_cont); + break; + case MENU_ENUM_LABEL_CHEAT_START_OR_RESTART: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_cheat_start_or_restart); + break; + case MENU_ENUM_LABEL_CHEAT_SEARCH_EXACT: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_cheat_search_exact); + break; + case MENU_ENUM_LABEL_CHEAT_SEARCH_LT: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_cheat_search_lt); + break; + case MENU_ENUM_LABEL_CHEAT_SEARCH_GT: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_cheat_search_gt); + break; + case MENU_ENUM_LABEL_CHEAT_SEARCH_EQ: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_cheat_search_eq); + break; + case MENU_ENUM_LABEL_CHEAT_SEARCH_NEQ: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_cheat_search_neq); + break; + case MENU_ENUM_LABEL_CHEAT_SEARCH_EQPLUS: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_cheat_search_eqplus); + break; + case MENU_ENUM_LABEL_CHEAT_SEARCH_EQMINUS: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_cheat_search_eqminus); + break; + case MENU_ENUM_LABEL_CHEAT_ADD_MATCHES: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_cheat_add_matches); + break; + case MENU_ENUM_LABEL_CHEAT_VIEW_MATCHES: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_cheat_view_matches); + break; + case MENU_ENUM_LABEL_CHEAT_CREATE_OPTION: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_cheat_create_option); + break; + case MENU_ENUM_LABEL_CHEAT_DELETE_OPTION: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_cheat_delete_option); + break; + case MENU_ENUM_LABEL_CHEAT_ADD_NEW_TOP: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_cheat_add_new_top); + break; + case MENU_ENUM_LABEL_CHEAT_ADD_NEW_BOTTOM: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_cheat_add_new_bottom); + break; + case MENU_ENUM_LABEL_CHEAT_ADDRESS_BIT_POSITION: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_cheat_address_bit_position); + break; + case MENU_ENUM_LABEL_CHEAT_DELETE_ALL: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_cheat_delete_all); + break; case MENU_ENUM_LABEL_SLOWMOTION_RATIO: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_slowmotion_ratio); break; diff --git a/menu/cbs/menu_cbs_title.c b/menu/cbs/menu_cbs_title.c index d14554e972..99f0f72c81 100644 --- a/menu/cbs/menu_cbs_title.c +++ b/menu/cbs/menu_cbs_title.c @@ -117,6 +117,8 @@ default_title_macro(action_get_saving_settings_list, MENU_ENUM_LABEL_ default_title_macro(action_get_logging_settings_list, MENU_ENUM_LABEL_VALUE_LOGGING_SETTINGS) default_title_macro(action_get_frame_throttle_settings_list, MENU_ENUM_LABEL_VALUE_FRAME_THROTTLE_SETTINGS) default_title_macro(action_get_rewind_settings_list, MENU_ENUM_LABEL_VALUE_REWIND_SETTINGS) +default_title_macro(action_get_cheat_details_settings_list, MENU_ENUM_LABEL_VALUE_CHEAT_DETAILS_SETTINGS) +default_title_macro(action_get_cheat_search_settings_list, MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_SETTINGS) default_title_macro(action_get_onscreen_display_settings_list, MENU_ENUM_LABEL_VALUE_ONSCREEN_DISPLAY_SETTINGS) default_title_macro(action_get_onscreen_notifications_settings_list, MENU_ENUM_LABEL_VALUE_ONSCREEN_NOTIFICATIONS_SETTINGS) default_title_macro(action_get_onscreen_overlay_settings_list, MENU_ENUM_LABEL_VALUE_ONSCREEN_OVERLAY_SETTINGS) @@ -156,6 +158,7 @@ default_title_macro(action_get_title_goto_video, MENU_ENUM_LABEL_ default_fill_title_macro(action_get_title_disk_image_append, MENU_ENUM_LABEL_VALUE_DISK_IMAGE_APPEND) default_fill_title_macro(action_get_title_cheat_file_load, MENU_ENUM_LABEL_VALUE_CHEAT_FILE) +default_fill_title_macro(action_get_title_cheat_file_load_append, MENU_ENUM_LABEL_VALUE_CHEAT_FILE_APPEND) default_fill_title_macro(action_get_title_remap_file_load, MENU_ENUM_LABEL_VALUE_REMAP_FILE) default_fill_title_macro(action_get_title_overlay, MENU_ENUM_LABEL_VALUE_OVERLAY) default_fill_title_macro(action_get_title_video_filter, MENU_ENUM_LABEL_VALUE_VIDEO_FILTER) @@ -365,6 +368,16 @@ static int menu_cbs_init_bind_title_compare_label(menu_file_list_cbs_t *cbs, BIND_ACTION_GET_TITLE(cbs, action_get_rewind_settings_list); return 0; } + else if (string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_CHEAT_DETAILS_SETTINGS_LIST))) + { + BIND_ACTION_GET_TITLE(cbs, action_get_cheat_details_settings_list); + return 0; + } + else if (string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_CHEAT_SEARCH_SETTINGS_LIST))) + { + BIND_ACTION_GET_TITLE(cbs, action_get_cheat_search_settings_list); + return 0; + } else if (string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_ONSCREEN_DISPLAY_SETTINGS_LIST))) { BIND_ACTION_GET_TITLE(cbs, action_get_onscreen_display_settings_list); @@ -748,6 +761,12 @@ static int menu_cbs_init_bind_title_compare_label(menu_file_list_cbs_t *cbs, case MENU_ENUM_LABEL_DEFERRED_REWIND_SETTINGS_LIST: BIND_ACTION_GET_TITLE(cbs, action_get_rewind_settings_list); break; + case MENU_ENUM_LABEL_DEFERRED_CHEAT_DETAILS_SETTINGS_LIST: + BIND_ACTION_GET_TITLE(cbs, action_get_cheat_details_settings_list); + break; + case MENU_ENUM_LABEL_DEFERRED_CHEAT_SEARCH_SETTINGS_LIST: + BIND_ACTION_GET_TITLE(cbs, action_get_cheat_search_settings_list); + break; case MENU_ENUM_LABEL_DEFERRED_ONSCREEN_DISPLAY_SETTINGS_LIST: BIND_ACTION_GET_TITLE(cbs, action_get_onscreen_display_settings_list); break; @@ -783,6 +802,9 @@ static int menu_cbs_init_bind_title_compare_label(menu_file_list_cbs_t *cbs, case MENU_ENUM_LABEL_CHEAT_FILE_LOAD: BIND_ACTION_GET_TITLE(cbs, action_get_title_cheat_file_load); break; + case MENU_ENUM_LABEL_CHEAT_FILE_LOAD_APPEND: + BIND_ACTION_GET_TITLE(cbs, action_get_title_cheat_file_load_append); + break; case MENU_ENUM_LABEL_REMAP_FILE_LOAD: BIND_ACTION_GET_TITLE(cbs, action_get_title_remap_file_load); break; @@ -1067,6 +1089,9 @@ static int menu_cbs_init_bind_title_compare_label(menu_file_list_cbs_t *cbs, case MENU_LABEL_CHEAT_FILE_LOAD: BIND_ACTION_GET_TITLE(cbs, action_get_title_cheat_file_load); break; + case MENU_LABEL_CHEAT_FILE_LOAD_APPEND: + BIND_ACTION_GET_TITLE(cbs, action_get_title_cheat_file_load_append); + break; case MENU_LABEL_REMAP_FILE_LOAD: BIND_ACTION_GET_TITLE(cbs, action_get_title_remap_file_load); break; diff --git a/menu/menu_cbs.h b/menu/menu_cbs.h index b33299df59..7f0ca78c34 100644 --- a/menu/menu_cbs.h +++ b/menu/menu_cbs.h @@ -75,6 +75,8 @@ enum ACTION_OK_DL_LOGGING_SETTINGS_LIST, ACTION_OK_DL_FRAME_THROTTLE_SETTINGS_LIST, ACTION_OK_DL_REWIND_SETTINGS_LIST, + ACTION_OK_DL_CHEAT_DETAILS_SETTINGS_LIST, + ACTION_OK_DL_CHEAT_SEARCH_SETTINGS_LIST, ACTION_OK_DL_CORE_SETTINGS_LIST, ACTION_OK_DL_INPUT_HOTKEY_BINDS_LIST, ACTION_OK_DL_RECORDING_SETTINGS_LIST, @@ -91,6 +93,7 @@ enum ACTION_OK_DL_PLAYLIST_COLLECTION, ACTION_OK_DL_CONTENT_COLLECTION_LIST, ACTION_OK_DL_CHEAT_FILE, + ACTION_OK_DL_CHEAT_FILE_APPEND, ACTION_OK_DL_CORE_LIST, ACTION_OK_DL_LAKKA_LIST, ACTION_OK_DL_CONFIGURATIONS_LIST, diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index e942861a46..23fe951e62 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -3165,26 +3165,45 @@ static int menu_displaylist_parse_options_cheats( return -1; menu_entries_append_enum(info->list, - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CHEAT_APPLY_CHANGES), - msg_hash_to_str(MENU_ENUM_LABEL_CHEAT_APPLY_CHANGES), - MENU_ENUM_LABEL_CHEAT_APPLY_CHANGES, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CHEAT_START_OR_CONT), + msg_hash_to_str(MENU_ENUM_LABEL_CHEAT_START_OR_CONT), + MENU_ENUM_LABEL_CHEAT_START_OR_CONT, MENU_SETTING_ACTION, 0, 0); menu_entries_append_enum(info->list, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CHEAT_FILE_LOAD), msg_hash_to_str(MENU_ENUM_LABEL_CHEAT_FILE_LOAD), MENU_ENUM_LABEL_CHEAT_FILE_LOAD, MENU_SETTING_ACTION, 0, 0); + menu_entries_append_enum(info->list, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CHEAT_FILE_LOAD_APPEND), + msg_hash_to_str(MENU_ENUM_LABEL_CHEAT_FILE_LOAD_APPEND), + MENU_ENUM_LABEL_CHEAT_FILE_LOAD_APPEND, + MENU_SETTING_ACTION, 0, 0); menu_entries_append_enum(info->list, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CHEAT_FILE_SAVE_AS), msg_hash_to_str(MENU_ENUM_LABEL_CHEAT_FILE_SAVE_AS), MENU_ENUM_LABEL_CHEAT_FILE_SAVE_AS, MENU_SETTING_ACTION, 0, 0); menu_entries_append_enum(info->list, - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CHEAT_NUM_PASSES), - msg_hash_to_str(MENU_ENUM_LABEL_CHEAT_NUM_PASSES), - MENU_ENUM_LABEL_CHEAT_NUM_PASSES, - 0, 0, 0); - + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CHEAT_ADD_NEW_TOP), + msg_hash_to_str(MENU_ENUM_LABEL_CHEAT_ADD_NEW_TOP), + MENU_ENUM_LABEL_CHEAT_ADD_NEW_TOP, + MENU_SETTING_ACTION, 0, 0); + menu_entries_append_enum(info->list, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CHEAT_ADD_NEW_BOTTOM), + msg_hash_to_str(MENU_ENUM_LABEL_CHEAT_ADD_NEW_BOTTOM), + MENU_ENUM_LABEL_CHEAT_ADD_NEW_BOTTOM, + MENU_SETTING_ACTION, 0, 0); + menu_entries_append_enum(info->list, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CHEAT_DELETE_ALL), + msg_hash_to_str(MENU_ENUM_LABEL_CHEAT_DELETE_ALL), + MENU_ENUM_LABEL_CHEAT_DELETE_ALL, + MENU_SETTING_ACTION, 0, 0); + menu_entries_append_enum(info->list, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CHEAT_APPLY_CHANGES), + msg_hash_to_str(MENU_ENUM_LABEL_CHEAT_APPLY_CHANGES), + MENU_ENUM_LABEL_CHEAT_APPLY_CHANGES, + MENU_SETTING_ACTION, 0, 0); for (i = 0; i < cheat_manager_get_size(); i++) { char cheat_label[64]; @@ -3780,6 +3799,11 @@ static bool menu_displaylist_push_internal( if (menu_displaylist_ctl(DISPLAYLIST_SETTINGS_ALL, info)) return true; } + else if (string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_CHEAT_SEARCH_SETTINGS))) + { + if (menu_displaylist_ctl(DISPLAYLIST_CHEAT_SEARCH_SETTINGS_LIST, info)) + return true; + } else if (string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_MUSIC_TAB))) { filebrowser_clear_type(); @@ -5129,6 +5153,196 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) MENU_ENUM_LABEL_REWIND_BUFFER_SIZE_STEP, PARSE_ONLY_UINT, false); + info->need_refresh = true; + info->need_push = true; + break; + case DISPLAYLIST_CHEAT_DETAILS_SETTINGS_LIST: + menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); + + + menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_CHEAT_IDX, + PARSE_ONLY_UINT, false); + + menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_CHEAT_STATE, + PARSE_ONLY_BOOL, false); + menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_CHEAT_DESC, + PARSE_ONLY_STRING, false); + menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_CHEAT_HANDLER, + PARSE_ONLY_UINT, false); + if ( cheat_manager_state.working_cheat.handler == CHEAT_HANDLER_TYPE_EMU) + { + menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_CHEAT_CODE, + PARSE_ONLY_STRING, false); + } + else + { + menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_CHEAT_MEMORY_SEARCH_SIZE, + PARSE_ONLY_UINT, false); + menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_CHEAT_TYPE, + PARSE_ONLY_UINT, false); + menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_CHEAT_VALUE, + PARSE_ONLY_UINT, false); + menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_CHEAT_ADDRESS, + PARSE_ONLY_UINT, false); + 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_RUMBLE_TYPE, + PARSE_ONLY_UINT, false); + menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_CHEAT_RUMBLE_VALUE, + PARSE_ONLY_UINT, false); + menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_CHEAT_RUMBLE_PORT, + PARSE_ONLY_UINT, false); + menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_CHEAT_RUMBLE_PRIMARY_STRENGTH, + PARSE_ONLY_UINT, false); + menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_CHEAT_RUMBLE_PRIMARY_DURATION, + PARSE_ONLY_UINT, false); + menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_CHEAT_RUMBLE_SECONDARY_STRENGTH, + PARSE_ONLY_UINT, false); + menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_CHEAT_RUMBLE_SECONDARY_DURATION, + PARSE_ONLY_UINT, false); + } + + // + + menu_entries_append_enum(info->list, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CHEAT_ADD_NEW_AFTER), + msg_hash_to_str(MENU_ENUM_LABEL_CHEAT_ADD_NEW_AFTER), + MENU_ENUM_LABEL_CHEAT_ADD_NEW_AFTER, + MENU_SETTING_ACTION, 0, 0); + menu_entries_append_enum(info->list, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CHEAT_ADD_NEW_BEFORE), + msg_hash_to_str(MENU_ENUM_LABEL_CHEAT_ADD_NEW_BEFORE), + MENU_ENUM_LABEL_CHEAT_ADD_NEW_BEFORE, + MENU_SETTING_ACTION, 0, 0); + menu_entries_append_enum(info->list, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CHEAT_COPY_AFTER), + msg_hash_to_str(MENU_ENUM_LABEL_CHEAT_COPY_AFTER), + MENU_ENUM_LABEL_CHEAT_COPY_AFTER, + MENU_SETTING_ACTION, 0, 0); + menu_entries_append_enum(info->list, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CHEAT_COPY_BEFORE), + msg_hash_to_str(MENU_ENUM_LABEL_CHEAT_COPY_BEFORE), + MENU_ENUM_LABEL_CHEAT_COPY_BEFORE, + MENU_SETTING_ACTION, 0, 0); + menu_entries_append_enum(info->list, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CHEAT_DELETE), + msg_hash_to_str(MENU_ENUM_LABEL_CHEAT_DELETE), + MENU_ENUM_LABEL_CHEAT_DELETE, + MENU_SETTING_ACTION, 0, 0); + + info->need_refresh = true; + info->need_push = true; + break; + case DISPLAYLIST_CHEAT_SEARCH_SETTINGS_LIST: + menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); + + + menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_CHEAT_START_OR_RESTART, + PARSE_ONLY_UINT, false); + + menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_CHEAT_BIG_ENDIAN, + PARSE_ONLY_BOOL, false); + + menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_CHEAT_SEARCH_EXACT, + PARSE_ONLY_UINT, false); + + menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_CHEAT_SEARCH_LT, + PARSE_ONLY_UINT, false); + + menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_CHEAT_SEARCH_LTE, + PARSE_ONLY_UINT, false); + + menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_CHEAT_SEARCH_GT, + PARSE_ONLY_UINT, false); + + menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_CHEAT_SEARCH_GTE, + PARSE_ONLY_UINT, false); + + menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_CHEAT_SEARCH_EQ, + PARSE_ONLY_UINT, false); + + menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_CHEAT_SEARCH_NEQ, + PARSE_ONLY_UINT, false); + + menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_CHEAT_SEARCH_EQPLUS, + PARSE_ONLY_UINT, false); + + menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_CHEAT_SEARCH_EQMINUS, + PARSE_ONLY_UINT, false); + + char cheat_label[64]; + + cheat_label[0] = '\0'; + snprintf(cheat_label, sizeof(cheat_label), + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CHEAT_ADD_MATCHES), cheat_manager_state.num_matches); + + menu_entries_append_enum(info->list, + cheat_label, + msg_hash_to_str(MENU_ENUM_LABEL_CHEAT_ADD_MATCHES), + MENU_ENUM_LABEL_CHEAT_ADD_MATCHES, + MENU_SETTING_ACTION, 0, 0); + + menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_CHEAT_DELETE_MATCH, + PARSE_ONLY_UINT, false); + + menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_CHEAT_COPY_MATCH, + PARSE_ONLY_UINT, false); + + cheat_label[0] = '\0'; + unsigned int address = 0; + unsigned int address_mask = 0; + unsigned int prev_val = 0; + unsigned int curr_val = 0 ; + cheat_manager_match_action(CHEAT_MATCH_ACTION_TYPE_VIEW, cheat_manager_state.match_idx, &address, &address_mask, &prev_val, &curr_val) ; + snprintf(cheat_label, sizeof(cheat_label), + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CHEAT_MATCH), address, address_mask); + + menu_entries_append_enum(info->list, + cheat_label, + "", + MSG_UNKNOWN, + MENU_SETTINGS_CHEAT_MATCH, 0, 0); + + + rarch_setting_t *setting = menu_setting_find(msg_hash_to_str(MENU_ENUM_LABEL_CHEAT_DELETE_MATCH)); + if ( setting ) { + setting->max = cheat_manager_state.num_matches-1; + } + setting = menu_setting_find(msg_hash_to_str(MENU_ENUM_LABEL_CHEAT_COPY_MATCH)); + if ( setting ) { + setting->max = cheat_manager_state.num_matches-1; + } + info->need_refresh = true; info->need_push = true; break; diff --git a/menu/menu_displaylist.h b/menu/menu_displaylist.h index 4924a465da..8fe0bea1a7 100644 --- a/menu/menu_displaylist.h +++ b/menu/menu_displaylist.h @@ -119,6 +119,8 @@ enum menu_displaylist_ctl_state DISPLAYLIST_LOGGING_SETTINGS_LIST, DISPLAYLIST_FRAME_THROTTLE_SETTINGS_LIST, DISPLAYLIST_REWIND_SETTINGS_LIST, + DISPLAYLIST_CHEAT_DETAILS_SETTINGS_LIST, + DISPLAYLIST_CHEAT_SEARCH_SETTINGS_LIST, DISPLAYLIST_AUDIO_SETTINGS_LIST, DISPLAYLIST_AUDIO_MIXER_SETTINGS_LIST, DISPLAYLIST_CORE_SETTINGS_LIST, diff --git a/menu/menu_driver.h b/menu/menu_driver.h index b919f290e6..b4b28059b1 100644 --- a/menu/menu_driver.h +++ b/menu/menu_driver.h @@ -233,7 +233,7 @@ enum menu_settings_type MENU_SETTINGS_SUBSYSTEM_ADD, MENU_SETTINGS_SUBSYSTEM_LAST = MENU_SETTINGS_SUBSYSTEM_ADD + RARCH_MAX_SUBSYSTEMS, - + MENU_SETTINGS_CHEAT_MATCH, MENU_SETTINGS_LAST }; diff --git a/menu/menu_setting.c b/menu/menu_setting.c index e273fbe65d..7c95ed5f4b 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -85,6 +85,7 @@ #include "../lakka.h" #include "../retroarch.h" #include "../gfx/video_display_server.h" +#include "../managers/cheat_manager.h" #include "../tasks/tasks_internal.h" @@ -102,6 +103,9 @@ enum settings_list_type SETTINGS_LIST_LOGGING, SETTINGS_LIST_SAVING, SETTINGS_LIST_REWIND, + SETTINGS_LIST_CHEAT_DETAILS, + SETTINGS_LIST_CHEAT_SEARCH, + SETTINGS_LIST_CHEAT_MATCHES, SETTINGS_LIST_VIDEO, SETTINGS_LIST_AUDIO, SETTINGS_LIST_INPUT, @@ -434,6 +438,99 @@ int setting_string_action_right_midi_output(void *data, bool wraparound) return -1; } +static void setting_get_string_representation_uint_cheat_exact(void *data, + char *s, size_t len) +{ + rarch_setting_t *setting = (rarch_setting_t*)data; + if (setting) + { + snprintf(s, len, msg_hash_to_str(MENU_ENUM_LABEL_CHEAT_SEARCH_EXACT_VAL), + *setting->value.target.unsigned_integer, *setting->value.target.unsigned_integer); + } +} + +static void setting_get_string_representation_uint_cheat_lt(void *data, + char *s, size_t len) +{ + rarch_setting_t *setting = (rarch_setting_t*)data; + if (setting) + { + snprintf(s, len, msg_hash_to_str(MENU_ENUM_LABEL_CHEAT_SEARCH_LT_VAL)); + } +} + +static void setting_get_string_representation_uint_cheat_gt(void *data, + char *s, size_t len) +{ + rarch_setting_t *setting = (rarch_setting_t*)data; + if (setting) + { + snprintf(s, len, msg_hash_to_str(MENU_ENUM_LABEL_CHEAT_SEARCH_GT_VAL)); + } +} + +static void setting_get_string_representation_uint_cheat_lte(void *data, + char *s, size_t len) +{ + rarch_setting_t *setting = (rarch_setting_t*)data; + if (setting) + { + snprintf(s, len, msg_hash_to_str(MENU_ENUM_LABEL_CHEAT_SEARCH_LTE_VAL)); + } +} + +static void setting_get_string_representation_uint_cheat_gte(void *data, + char *s, size_t len) +{ + rarch_setting_t *setting = (rarch_setting_t*)data; + if (setting) + { + snprintf(s, len, msg_hash_to_str(MENU_ENUM_LABEL_CHEAT_SEARCH_GTE_VAL)); + } +} + +static void setting_get_string_representation_uint_cheat_eq(void *data, + char *s, size_t len) +{ + rarch_setting_t *setting = (rarch_setting_t*)data; + if (setting) + { + snprintf(s, len, msg_hash_to_str(MENU_ENUM_LABEL_CHEAT_SEARCH_EQ_VAL)); + } +} + +static void setting_get_string_representation_uint_cheat_neq(void *data, + char *s, size_t len) +{ + rarch_setting_t *setting = (rarch_setting_t*)data; + if (setting) + { + snprintf(s, len, msg_hash_to_str(MENU_ENUM_LABEL_CHEAT_SEARCH_NEQ_VAL)); + } +} + +static void setting_get_string_representation_uint_cheat_eqplus(void *data, + char *s, size_t len) +{ + rarch_setting_t *setting = (rarch_setting_t*)data; + if (setting) + { + snprintf(s, len, msg_hash_to_str(MENU_ENUM_LABEL_CHEAT_SEARCH_EQPLUS_VAL), + *setting->value.target.unsigned_integer, *setting->value.target.unsigned_integer); + } +} + +static void setting_get_string_representation_uint_cheat_eqminus(void *data, + char *s, size_t len) +{ + rarch_setting_t *setting = (rarch_setting_t*)data; + if (setting) + { + snprintf(s, len, msg_hash_to_str(MENU_ENUM_LABEL_CHEAT_SEARCH_EQMINUS_VAL), + *setting->value.target.unsigned_integer, *setting->value.target.unsigned_integer); + } +} + static void setting_get_string_representation_uint_video_rotation(void *data, char *s, size_t len) { @@ -1647,6 +1744,47 @@ void general_write_handler(void *data) } } break; + case MENU_ENUM_LABEL_CHEAT_MEMORY_SEARCH_SIZE: + { + rarch_setting_t *setting = menu_setting_find(msg_hash_to_str(MENU_ENUM_LABEL_CHEAT_VALUE)); + if ( setting ) { + *(setting->value.target.unsigned_integer) = 0 ; + setting->max = (int) pow(2,pow((double) 2,cheat_manager_state.working_cheat.memory_search_size))-1; + } + setting = menu_setting_find(msg_hash_to_str(MENU_ENUM_LABEL_CHEAT_RUMBLE_VALUE)); + if ( setting ) { + *setting->value.target.unsigned_integer = 0 ; + setting->max = (int) pow(2,pow((double) 2,cheat_manager_state.working_cheat.memory_search_size))-1; + } + setting = menu_setting_find(msg_hash_to_str(MENU_ENUM_LABEL_CHEAT_ADDRESS_BIT_POSITION)); + if ( setting ) { + *setting->value.target.unsigned_integer = 0 ; + int max_bit_position = cheat_manager_state.working_cheat.memory_search_size<3 ? 255 : 0 ; + setting->max = max_bit_position ; + } + + } + break; + case MENU_ENUM_LABEL_CHEAT_START_OR_RESTART: + { + rarch_setting_t *setting = menu_setting_find(msg_hash_to_str(MENU_ENUM_LABEL_CHEAT_SEARCH_EXACT)); + if ( setting ) { + *setting->value.target.unsigned_integer = 0 ; + setting->max = (int) pow(2,pow((double) 2,cheat_manager_state.search_bit_size))-1; + } + setting = menu_setting_find(msg_hash_to_str(MENU_ENUM_LABEL_CHEAT_SEARCH_EQPLUS)); + if ( setting ) { + *setting->value.target.unsigned_integer = 0 ; + setting->max = (int) pow(2,pow((double) 2,cheat_manager_state.search_bit_size))-1; + } + setting = menu_setting_find(msg_hash_to_str(MENU_ENUM_LABEL_CHEAT_SEARCH_EQMINUS)); + if ( setting ) { + *setting->value.target.unsigned_integer = 0 ; + setting->max = (int) pow(2,pow((double) 2,cheat_manager_state.search_bit_size))-1; + } + + } + break; default: break; } @@ -2042,6 +2180,24 @@ static int directory_action_start_generic(void *data) return 0; } +#define config_uint_cbs(var, label, left, right, msg_enum_base, string_rep, min, max, step) \ + CONFIG_UINT( \ + list, list_info, \ + &(var), \ + MENU_ENUM_LABEL_##label, \ + MENU_ENUM_LABEL_VALUE_##label, \ + var, \ + &group_info, \ + &subgroup_info, \ + parent_group, \ + general_write_handler, \ + general_read_handler); \ + (*list)[list_info->index - 1].action_left = left; \ + (*list)[list_info->index - 1].action_right = right; \ + (*list)[list_info->index - 1].get_string_representation = string_rep; \ + (*list)[list_info->index - 1].index_offset = msg_enum_base; \ + menu_settings_list_current_add_range(list, list_info, min, max, step, true, true); + static bool setting_append_list( enum settings_list_type type, rarch_setting_t **list, @@ -2443,6 +2599,22 @@ static bool setting_append_list( parent_group); settings_data_list_current_add_flags(list, list_info, SD_FLAG_LAKKA_ADVANCED); + CONFIG_ACTION( + list, list_info, + MENU_ENUM_LABEL_CHEAT_DETAILS_SETTINGS, + MENU_ENUM_LABEL_VALUE_CHEAT_DETAILS_SETTINGS, + &group_info, + &subgroup_info, + parent_group); + + CONFIG_ACTION( + list, list_info, + MENU_ENUM_LABEL_CHEAT_SEARCH_SETTINGS, + MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_SETTINGS, + &group_info, + &subgroup_info, + parent_group); + CONFIG_ACTION( list, list_info, MENU_ENUM_LABEL_RECORDING_SETTINGS, @@ -3077,7 +3249,6 @@ static bool setting_append_list( START_SUB_GROUP(list, list_info, "State", &group_info, &subgroup_info, parent_group); - CONFIG_BOOL( list, list_info, &settings->bools.rewind_enable, @@ -3124,7 +3295,7 @@ static bool setting_append_list( &settings->uints.rewind_buffer_size_step, MENU_ENUM_LABEL_REWIND_BUFFER_SIZE_STEP, MENU_ENUM_LABEL_VALUE_REWIND_BUFFER_SIZE_STEP, - rewind_buffer_size_step, + rewind_buffer_size_step, &group_info, &subgroup_info, parent_group, @@ -3132,6 +3303,342 @@ static bool setting_append_list( general_read_handler); menu_settings_list_current_add_range(list, list_info, 1, 100, 1, true, true); + END_SUB_GROUP(list, list_info, parent_group); + END_GROUP(list, list_info, parent_group); + break; + case SETTINGS_LIST_CHEAT_DETAILS: + if ( ! cheat_manager_state.cheats ) + { + break ; + } + START_GROUP(list, list_info, &group_info, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CHEAT_DETAILS_SETTINGS), parent_group); + + parent_group = msg_hash_to_str(MENU_ENUM_LABEL_CHEAT_DETAILS_SETTINGS); + + START_SUB_GROUP(list, list_info, "State", &group_info, &subgroup_info, parent_group); + + + + config_uint_cbs(cheat_manager_state.working_cheat.idx, CHEAT_IDX, + NULL,NULL, + 0,&setting_get_string_representation_uint,0,cheat_manager_get_size()-1,1) ; + + CONFIG_BOOL( + list, list_info, + &cheat_manager_state.working_cheat.state, + MENU_ENUM_LABEL_CHEAT_STATE, + MENU_ENUM_LABEL_VALUE_CHEAT_STATE, + cheat_manager_state.working_cheat.state, + MENU_ENUM_LABEL_VALUE_OFF, + MENU_ENUM_LABEL_VALUE_ON, + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler, + SD_FLAG_NONE); + + CONFIG_STRING( + list, list_info, + cheat_manager_state.working_cheat.desc, + sizeof(cheat_manager_state.working_cheat.desc), + MENU_ENUM_LABEL_CHEAT_DESC, + MENU_ENUM_LABEL_VALUE_CHEAT_DESC, + "", + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler); + settings_data_list_current_add_flags(list, list_info, SD_FLAG_ALLOW_INPUT); + + config_uint_cbs(cheat_manager_state.working_cheat.handler, CHEAT_HANDLER, + setting_uint_action_left_with_refresh,setting_uint_action_right_with_refresh, + MENU_ENUM_LABEL_CHEAT_HANDLER_TYPE_EMU,&setting_get_string_representation_uint_as_enum, + CHEAT_HANDLER_TYPE_EMU,CHEAT_HANDLER_TYPE_RETRO,1) ; + + CONFIG_STRING( + list, list_info, + cheat_manager_state.working_cheat.code, + sizeof(cheat_manager_state.working_cheat.code), + MENU_ENUM_LABEL_CHEAT_CODE, + MENU_ENUM_LABEL_VALUE_CHEAT_CODE, + "", + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler); + settings_data_list_current_add_flags(list, list_info, SD_FLAG_ALLOW_INPUT); + + config_uint_cbs(cheat_manager_state.working_cheat.memory_search_size, CHEAT_MEMORY_SEARCH_SIZE, + setting_uint_action_left_with_refresh,setting_uint_action_right_with_refresh, + MENU_ENUM_LABEL_CHEAT_MEMORY_SIZE_1,&setting_get_string_representation_uint_as_enum, + 0,5,1) ; + + config_uint_cbs(cheat_manager_state.working_cheat.cheat_type, CHEAT_TYPE, + setting_uint_action_left_default,setting_uint_action_right_default, + MENU_ENUM_LABEL_CHEAT_TYPE_DISABLED,&setting_get_string_representation_uint_as_enum, + CHEAT_TYPE_DISABLED,CHEAT_TYPE_RUN_NEXT_IF_GT,1) ; + + config_uint_cbs(cheat_manager_state.working_cheat.value, CHEAT_VALUE, + setting_uint_action_left_default,setting_uint_action_right_default, + 0,&setting_get_string_representation_hex_and_uint,0,(int) pow(2,pow((double) 2,cheat_manager_state.working_cheat.memory_search_size))-1,1) ; + + config_uint_cbs(cheat_manager_state.working_cheat.address, CHEAT_ADDRESS, + setting_uint_action_left_default,setting_uint_action_right_default, + 0,&setting_get_string_representation_hex_and_uint,0,cheat_manager_state.total_memory_size==0?0:cheat_manager_state.total_memory_size-1,1) ; + + int max_bit_position = cheat_manager_state.working_cheat.memory_search_size<3 ? 255 : 0 ; + config_uint_cbs(cheat_manager_state.working_cheat.address_mask, CHEAT_ADDRESS_BIT_POSITION, + setting_uint_action_left_default,setting_uint_action_right_default, + 0,&setting_get_string_representation_hex_and_uint,0,max_bit_position,1) ; + + CONFIG_BOOL( + list, list_info, + &cheat_manager_state.working_cheat.big_endian, + MENU_ENUM_LABEL_CHEAT_BIG_ENDIAN, + MENU_ENUM_LABEL_VALUE_CHEAT_BIG_ENDIAN, + cheat_manager_state.working_cheat.big_endian, + MENU_ENUM_LABEL_VALUE_OFF, + MENU_ENUM_LABEL_VALUE_ON, + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler, + SD_FLAG_NONE); + + 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, + RUMBLE_TYPE_DISABLED,RUMBLE_TYPE_GT_VALUE,1) ; + + config_uint_cbs(cheat_manager_state.working_cheat.rumble_value, CHEAT_RUMBLE_VALUE, + setting_uint_action_left_default,setting_uint_action_right_default, + 0,&setting_get_string_representation_hex_and_uint,0,(int) pow(2,pow((double) 2,cheat_manager_state.working_cheat.memory_search_size))-1,1) ; + + config_uint_cbs(cheat_manager_state.working_cheat.rumble_port, CHEAT_RUMBLE_PORT, + setting_uint_action_left_default,setting_uint_action_right_default, + MENU_ENUM_LABEL_RUMBLE_PORT_0,&setting_get_string_representation_uint_as_enum, + 0,16,1) ; + + config_uint_cbs(cheat_manager_state.working_cheat.rumble_primary_strength, CHEAT_RUMBLE_PRIMARY_STRENGTH, + setting_uint_action_left_default,setting_uint_action_right_default, + 0,&setting_get_string_representation_hex_and_uint,0,65535,1) ; + + config_uint_cbs(cheat_manager_state.working_cheat.rumble_primary_duration, CHEAT_RUMBLE_PRIMARY_DURATION, + setting_uint_action_left_default,setting_uint_action_right_default, + 0,&setting_get_string_representation_uint,0,5000,1) ; + + config_uint_cbs(cheat_manager_state.working_cheat.rumble_secondary_strength, CHEAT_RUMBLE_SECONDARY_STRENGTH, + setting_uint_action_left_default,setting_uint_action_right_default, + 0,&setting_get_string_representation_hex_and_uint,0,65535,1) ; + + config_uint_cbs(cheat_manager_state.working_cheat.rumble_secondary_duration, CHEAT_RUMBLE_SECONDARY_DURATION, + setting_uint_action_left_default,setting_uint_action_right_default, + 0,&setting_get_string_representation_uint,0,5000,1) ; + + + + END_SUB_GROUP(list, list_info, parent_group); + END_GROUP(list, list_info, parent_group); + break; + case SETTINGS_LIST_CHEAT_SEARCH: + if ( ! cheat_manager_state.cheats ) + { + break ; + } + START_GROUP(list, list_info, &group_info, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_SETTINGS), parent_group); + + parent_group = msg_hash_to_str(MENU_ENUM_LABEL_CHEAT_SEARCH_SETTINGS); + + START_SUB_GROUP(list, list_info, "State", &group_info, &subgroup_info, parent_group); + + config_uint_cbs(cheat_manager_state.search_bit_size, CHEAT_START_OR_RESTART, + setting_uint_action_left_with_refresh,setting_uint_action_right_with_refresh, + MENU_ENUM_LABEL_CHEAT_MEMORY_SIZE_1,&setting_get_string_representation_uint_as_enum, + 0,5,1) ; + (*list)[list_info->index - 1].action_ok = &cheat_manager_initialize_search; + + CONFIG_BOOL( + list, list_info, + &cheat_manager_state.big_endian, + MENU_ENUM_LABEL_CHEAT_BIG_ENDIAN, + MENU_ENUM_LABEL_VALUE_CHEAT_BIG_ENDIAN, + cheat_manager_state.big_endian, + MENU_ENUM_LABEL_VALUE_OFF, + MENU_ENUM_LABEL_VALUE_ON, + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler, + SD_FLAG_NONE); + + CONFIG_UINT( + list, list_info, + &cheat_manager_state.search_exact_value, + MENU_ENUM_LABEL_CHEAT_SEARCH_EXACT, + MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_EXACT, + cheat_manager_state.search_exact_value, + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler); + menu_settings_list_current_add_range(list, list_info, 0, (int) pow(2,pow((double) 2,cheat_manager_state.search_bit_size))-1, 1, true, true); + (*list)[list_info->index - 1].get_string_representation = &setting_get_string_representation_uint_cheat_exact; + (*list)[list_info->index - 1].action_ok = &cheat_manager_search_exact; + + + CONFIG_UINT( + list, list_info, + &cheat_manager_state.dummy, + MENU_ENUM_LABEL_CHEAT_SEARCH_LT, + MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_LT, + cheat_manager_state.dummy, + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler); + (*list)[list_info->index - 1].get_string_representation = &setting_get_string_representation_uint_cheat_lt; + (*list)[list_info->index - 1].action_ok = &cheat_manager_search_lt; + + CONFIG_UINT( + list, list_info, + &cheat_manager_state.dummy, + MENU_ENUM_LABEL_CHEAT_SEARCH_LTE, + MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_LTE, + cheat_manager_state.dummy, + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler); + (*list)[list_info->index - 1].get_string_representation = &setting_get_string_representation_uint_cheat_lte; + (*list)[list_info->index - 1].action_ok = &cheat_manager_search_lte; + + CONFIG_UINT( + list, list_info, + &cheat_manager_state.dummy, + MENU_ENUM_LABEL_CHEAT_SEARCH_GT, + MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_GT, + cheat_manager_state.dummy, + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler); + (*list)[list_info->index - 1].get_string_representation = &setting_get_string_representation_uint_cheat_gt; + (*list)[list_info->index - 1].action_ok = &cheat_manager_search_gt; + + CONFIG_UINT( + list, list_info, + &cheat_manager_state.dummy, + MENU_ENUM_LABEL_CHEAT_SEARCH_GTE, + MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_GTE, + cheat_manager_state.dummy, + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler); + (*list)[list_info->index - 1].get_string_representation = &setting_get_string_representation_uint_cheat_gte; + (*list)[list_info->index - 1].action_ok = &cheat_manager_search_gte; + + CONFIG_UINT( + list, list_info, + &cheat_manager_state.dummy, + MENU_ENUM_LABEL_CHEAT_SEARCH_EQ, + MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_EQ, + cheat_manager_state.dummy, + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler); + (*list)[list_info->index - 1].get_string_representation = &setting_get_string_representation_uint_cheat_eq; + (*list)[list_info->index - 1].action_ok = &cheat_manager_search_eq; + + CONFIG_UINT( + list, list_info, + &cheat_manager_state.dummy, + MENU_ENUM_LABEL_CHEAT_SEARCH_NEQ, + MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_NEQ, + cheat_manager_state.dummy, + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler); + (*list)[list_info->index - 1].get_string_representation = &setting_get_string_representation_uint_cheat_neq; + (*list)[list_info->index - 1].action_ok = &cheat_manager_search_neq; + + CONFIG_UINT( + list, list_info, + &cheat_manager_state.search_eqplus_value, + MENU_ENUM_LABEL_CHEAT_SEARCH_EQPLUS, + MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_EQPLUS, + cheat_manager_state.search_eqplus_value, + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler); + menu_settings_list_current_add_range(list, list_info, 0, (int) pow(2,pow((double) 2,cheat_manager_state.search_bit_size))-1, 1, true, true); + (*list)[list_info->index - 1].get_string_representation = &setting_get_string_representation_uint_cheat_eqplus; + (*list)[list_info->index - 1].action_ok = &cheat_manager_search_eqplus; + + CONFIG_UINT( + list, list_info, + &cheat_manager_state.search_eqminus_value, + MENU_ENUM_LABEL_CHEAT_SEARCH_EQMINUS, + MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_EQMINUS, + cheat_manager_state.search_eqminus_value, + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler); + menu_settings_list_current_add_range(list, list_info, 0, (int) pow(2,pow((double) 2,cheat_manager_state.search_bit_size))-1, 1, true, true); + (*list)[list_info->index - 1].get_string_representation = &setting_get_string_representation_uint_cheat_eqminus; + (*list)[list_info->index - 1].action_ok = &cheat_manager_search_eqminus; + + CONFIG_UINT( + list, list_info, + &cheat_manager_state.match_idx, + MENU_ENUM_LABEL_CHEAT_DELETE_MATCH, + MENU_ENUM_LABEL_VALUE_CHEAT_DELETE_MATCH, + cheat_manager_state.match_idx, + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler); + menu_settings_list_current_add_range(list, list_info, 0, cheat_manager_state.num_matches-1, 1, true, true); + (*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_ok = &cheat_manager_delete_match; + + CONFIG_UINT( + list, list_info, + &cheat_manager_state.match_idx, + MENU_ENUM_LABEL_CHEAT_COPY_MATCH, + MENU_ENUM_LABEL_VALUE_CHEAT_COPY_MATCH, + cheat_manager_state.match_idx, + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler); + menu_settings_list_current_add_range(list, list_info, 0, cheat_manager_state.num_matches-1, 1, true, true); + (*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_ok = &cheat_manager_copy_match; + + END_SUB_GROUP(list, list_info, parent_group); END_GROUP(list, list_info, parent_group); break; @@ -8271,6 +8778,9 @@ static rarch_setting_t *menu_setting_new_internal(rarch_setting_info_t *list_inf SETTINGS_LIST_LOGGING, SETTINGS_LIST_SAVING, SETTINGS_LIST_REWIND, + SETTINGS_LIST_CHEAT_DETAILS, + SETTINGS_LIST_CHEAT_SEARCH, + SETTINGS_LIST_CHEAT_MATCHES, SETTINGS_LIST_VIDEO, SETTINGS_LIST_AUDIO, SETTINGS_LIST_INPUT, diff --git a/menu/widgets/menu_input_bind_dialog.c b/menu/widgets/menu_input_bind_dialog.c index e7e242448b..67e864d976 100644 --- a/menu/widgets/menu_input_bind_dialog.c +++ b/menu/widgets/menu_input_bind_dialog.c @@ -477,7 +477,7 @@ static bool menu_input_key_bind_poll_find_hold_pad( return false; } -static bool menu_input_key_bind_poll_find_hold( +bool menu_input_key_bind_poll_find_hold( struct menu_bind_state *new_state, struct retro_keybind * output ) diff --git a/msg_hash.h b/msg_hash.h index 41dfbb57dc..1497033365 100644 --- a/msg_hash.h +++ b/msg_hash.h @@ -436,6 +436,7 @@ enum msg_hash_enums MENU_ENUM_LABEL_VALUE_REMAP_FILE, MENU_ENUM_LABEL_VALUE_CHEAT_FILE, + MENU_ENUM_LABEL_VALUE_CHEAT_FILE_APPEND, MENU_ENUM_LABEL_INPUT_HOTKEY_BIND_BEGIN, MENU_ENUM_LABEL_INPUT_HOTKEY_BIND_END = MENU_ENUM_LABEL_INPUT_HOTKEY_BIND_BEGIN + RARCH_BIND_LIST_END, @@ -1016,6 +1017,8 @@ enum msg_hash_enums MENU_ENUM_LABEL_DEFERRED_SAVING_SETTINGS_LIST, MENU_ENUM_LABEL_DEFERRED_FRAME_THROTTLE_SETTINGS_LIST, MENU_ENUM_LABEL_DEFERRED_REWIND_SETTINGS_LIST, + MENU_ENUM_LABEL_DEFERRED_CHEAT_DETAILS_SETTINGS_LIST, + MENU_ENUM_LABEL_DEFERRED_CHEAT_SEARCH_SETTINGS_LIST, MENU_ENUM_LABEL_DEFERRED_ONSCREEN_DISPLAY_SETTINGS_LIST, MENU_ENUM_LABEL_DEFERRED_ONSCREEN_OVERLAY_SETTINGS_LIST, MENU_ENUM_LABEL_DEFERRED_ONSCREEN_NOTIFICATIONS_SETTINGS_LIST, @@ -1196,7 +1199,54 @@ enum msg_hash_enums MENU_LABEL(REWIND_BUFFER_SIZE), MENU_LABEL(REWIND_BUFFER_SIZE_STEP), MENU_LABEL(INPUT_META_REWIND), + MENU_LABEL(INPUT_META_CHEAT_DETAILS), + MENU_LABEL(INPUT_META_CHEAT_SEARCH), + MENU_LABEL(CHEAT_IDX), + MENU_LABEL(CHEAT_DESC), + MENU_LABEL(CHEAT_STATE), + MENU_LABEL(CHEAT_CODE), + MENU_LABEL(CHEAT_HANDLER), + MENU_LABEL(CHEAT_MEMORY_SEARCH_SIZE), + MENU_LABEL(CHEAT_TYPE), + MENU_LABEL(CHEAT_VALUE), + MENU_LABEL(CHEAT_ADDRESS), + MENU_LABEL(CHEAT_ADDRESS_BIT_POSITION), + MENU_LABEL(CHEAT_RUMBLE_TYPE), + MENU_LABEL(CHEAT_RUMBLE_VALUE), + MENU_LABEL(CHEAT_RUMBLE_PORT), + MENU_LABEL(CHEAT_RUMBLE_PRIMARY_STRENGTH), + MENU_LABEL(CHEAT_RUMBLE_PRIMARY_DURATION), + MENU_LABEL(CHEAT_RUMBLE_SECONDARY_STRENGTH), + MENU_LABEL(CHEAT_RUMBLE_SECONDARY_DURATION), + MENU_LABEL(CHEAT_ADD_NEW_AFTER), + MENU_LABEL(CHEAT_ADD_NEW_BEFORE), + MENU_LABEL(CHEAT_COPY_AFTER), + MENU_LABEL(CHEAT_COPY_BEFORE), + MENU_LABEL(CHEAT_DELETE), + + MENU_LABEL(CHEAT_START_OR_CONT), + MENU_LABEL(CHEAT_START_OR_RESTART), + MENU_LABEL(CHEAT_SEARCH_EXACT), + MENU_LABEL(CHEAT_SEARCH_LT), + MENU_LABEL(CHEAT_SEARCH_GT), + MENU_LABEL(CHEAT_SEARCH_LTE), + MENU_LABEL(CHEAT_SEARCH_GTE), + MENU_LABEL(CHEAT_SEARCH_EQ), + MENU_LABEL(CHEAT_SEARCH_NEQ), + MENU_LABEL(CHEAT_SEARCH_EQPLUS), + MENU_LABEL(CHEAT_SEARCH_EQMINUS), + MENU_LABEL(CHEAT_ADD_MATCHES), + MENU_LABEL(CHEAT_CREATE_OPTION), + MENU_LABEL(CHEAT_DELETE_OPTION), + MENU_LABEL(CHEAT_ADD_NEW_TOP), + MENU_LABEL(CHEAT_ADD_NEW_BOTTOM), + MENU_LABEL(CHEAT_DELETE_ALL), + MENU_LABEL(CHEAT_BIG_ENDIAN), + MENU_LABEL(CHEAT_MATCH_IDX), + MENU_LABEL(CHEAT_MATCH), + MENU_LABEL(CHEAT_COPY_MATCH), + MENU_LABEL(CHEAT_DELETE_MATCH), MENU_LABEL(SCREEN_RESOLUTION), MENU_LABEL(TITLE_COLOR), MENU_LABEL(SAVESTATE_AUTO_INDEX), @@ -1484,6 +1534,7 @@ enum msg_hash_enums MENU_LABEL(VIDEO_SHADER_PRESET), MENU_LABEL(CHEAT_FILE_LOAD), + MENU_LABEL(CHEAT_FILE_LOAD_APPEND), MENU_LABEL(REMAP_FILE_LOAD), MENU_ENUM_LABEL_MESSAGE, @@ -1532,6 +1583,8 @@ enum msg_hash_enums MENU_LABEL(RECORDING_SETTINGS), MENU_LABEL(OVERLAY_SETTINGS), MENU_LABEL(REWIND_SETTINGS), + MENU_LABEL(CHEAT_DETAILS_SETTINGS), + MENU_LABEL(CHEAT_SEARCH_SETTINGS), MENU_ENUM_LABEL_ONSCREEN_KEYBOARD_OVERLAY_SETTINGS, @@ -1546,6 +1599,9 @@ enum msg_hash_enums MENU_LABEL(ONSCREEN_OVERLAY_SETTINGS), MENU_LABEL(ONSCREEN_NOTIFICATIONS_SETTINGS), MENU_LABEL(CHEAT_APPLY_CHANGES), + MENU_LABEL(CHEAT_START_SEARCH), + MENU_LABEL(CHEAT_CONTINUE_SEARCH), + MENU_LABEL(CHEAT_VIEW_MATCHES), MENU_ENUM_LABEL_COLLECTION, MENU_LABEL(CONFIGURATIONS), @@ -1878,6 +1934,76 @@ enum msg_hash_enums MENU_LABEL(SUSTAINED_PERFORMANCE_MODE), + MENU_ENUM_LABEL_CHEAT_HANDLER_TYPE_EMU, + MENU_ENUM_LABEL_CHEAT_HANDLER_TYPE_RETRO, + MENU_ENUM_LABEL_CHEAT_TYPE_DISABLED, + MENU_ENUM_LABEL_CHEAT_TYPE_SET_TO_VALUE, + MENU_ENUM_LABEL_CHEAT_TYPE_INCREASE_VALUE, + MENU_ENUM_LABEL_CHEAT_TYPE_DECREASE_VALUE, + MENU_ENUM_LABEL_CHEAT_TYPE_RUN_NEXT_IF_EQ, + MENU_ENUM_LABEL_CHEAT_TYPE_RUN_NEXT_IF_NEQ, + MENU_ENUM_LABEL_CHEAT_TYPE_RUN_NEXT_IF_LT, + MENU_ENUM_LABEL_CHEAT_TYPE_RUN_NEXT_IF_GT, + MENU_ENUM_LABEL_RUMBLE_TYPE_DISABLED, + MENU_ENUM_LABEL_RUMBLE_TYPE_CHANGES, + MENU_ENUM_LABEL_RUMBLE_TYPE_DOES_NOT_CHANGE, + MENU_ENUM_LABEL_RUMBLE_TYPE_INCREASE, + MENU_ENUM_LABEL_RUMBLE_TYPE_DECREASE, + MENU_ENUM_LABEL_RUMBLE_TYPE_EQ_VALUE, + MENU_ENUM_LABEL_RUMBLE_TYPE_NEQ_VALUE, + MENU_ENUM_LABEL_RUMBLE_TYPE_LT_VALUE, + MENU_ENUM_LABEL_RUMBLE_TYPE_GT_VALUE, + MENU_ENUM_LABEL_CHEAT_MEMORY_SIZE_1, + MENU_ENUM_LABEL_CHEAT_MEMORY_SIZE_2, + MENU_ENUM_LABEL_CHEAT_MEMORY_SIZE_4, + MENU_ENUM_LABEL_CHEAT_MEMORY_SIZE_8, + MENU_ENUM_LABEL_CHEAT_MEMORY_SIZE_16, + MENU_ENUM_LABEL_CHEAT_MEMORY_SIZE_32, + MENU_ENUM_LABEL_RUMBLE_PORT_0, + MENU_ENUM_LABEL_RUMBLE_PORT_1, + MENU_ENUM_LABEL_RUMBLE_PORT_2, + MENU_ENUM_LABEL_RUMBLE_PORT_3, + MENU_ENUM_LABEL_RUMBLE_PORT_4, + MENU_ENUM_LABEL_RUMBLE_PORT_5, + MENU_ENUM_LABEL_RUMBLE_PORT_6, + MENU_ENUM_LABEL_RUMBLE_PORT_7, + MENU_ENUM_LABEL_RUMBLE_PORT_8, + MENU_ENUM_LABEL_RUMBLE_PORT_9, + MENU_ENUM_LABEL_RUMBLE_PORT_10, + MENU_ENUM_LABEL_RUMBLE_PORT_11, + MENU_ENUM_LABEL_RUMBLE_PORT_12, + MENU_ENUM_LABEL_RUMBLE_PORT_13, + MENU_ENUM_LABEL_RUMBLE_PORT_14, + MENU_ENUM_LABEL_RUMBLE_PORT_15, + MENU_ENUM_LABEL_RUMBLE_PORT_16, + MENU_ENUM_LABEL_CHEAT_SEARCH_EXACT_VAL, + MENU_ENUM_LABEL_CHEAT_SEARCH_LT_VAL, + MENU_ENUM_LABEL_CHEAT_SEARCH_LTE_VAL, + MENU_ENUM_LABEL_CHEAT_SEARCH_GT_VAL, + MENU_ENUM_LABEL_CHEAT_SEARCH_GTE_VAL, + MENU_ENUM_LABEL_CHEAT_SEARCH_EQ_VAL, + MENU_ENUM_LABEL_CHEAT_SEARCH_NEQ_VAL, + MENU_ENUM_LABEL_CHEAT_SEARCH_EQPLUS_VAL, + MENU_ENUM_LABEL_CHEAT_SEARCH_EQMINUS_VAL, + MSG_CHEAT_INIT_SUCCESS, + MSG_CHEAT_INIT_FAIL, + MSG_CHEAT_SEARCH_NOT_INITIALIZED, + MSG_CHEAT_SEARCH_FOUND_MATCHES, + MSG_CHEAT_SEARCH_ADDED_MATCHES_SUCCESS, + MSG_CHEAT_SEARCH_ADDED_MATCHES_FAIL, + MSG_CHEAT_SEARCH_ADDED_MATCHES_TOO_MANY, + MSG_CHEAT_DELETE_ALL_INSTRUCTIONS, + MSG_CHEAT_ADD_TOP_SUCCESS, + MSG_CHEAT_ADD_BOTTOM_SUCCESS, + MSG_CHEAT_DELETE_ALL_SUCCESS, + MSG_CHEAT_ADD_AFTER_SUCCESS, + MSG_CHEAT_ADD_BEFORE_SUCCESS, + MSG_CHEAT_COPY_AFTER_SUCCESS, + MSG_CHEAT_COPY_BEFORE_SUCCESS, + MSG_CHEAT_DELETE_SUCCESS, + MSG_CHEAT_SEARCH_ADD_MATCH_SUCCESS, + MSG_CHEAT_SEARCH_ADD_MATCH_FAIL, + MSG_CHEAT_SEARCH_DELETE_MATCH_SUCCESS, MSG_LAST }; @@ -1983,6 +2109,7 @@ enum msg_hash_enums #define MENU_LABEL_CHEAT_DATABASE_PATH 0x01388b8aU #define MENU_LABEL_CHEAT_FILE_LOAD 0x57336148U +#define MENU_LABEL_CHEAT_FILE_LOAD_APPEND 0xbf4aefffU #define MENU_LABEL_CHEAT_FILE_SAVE_AS 0x1f58dccaU #define MENU_LABEL_CHEAT_APPLY_CHANGES 0xde88aa27U diff --git a/retroarch.c b/retroarch.c index 69836ee943..4d03731be6 100644 --- a/retroarch.c +++ b/retroarch.c @@ -1370,6 +1370,7 @@ bool retroarch_main_init(int argc, char *argv[]) } } + command_event(CMD_EVENT_CHEATS_INIT, NULL); drivers_init(DRIVERS_CMD_ALL); command_event(CMD_EVENT_COMMAND_INIT, NULL); command_event(CMD_EVENT_REMOTE_INIT, NULL); @@ -1377,7 +1378,6 @@ bool retroarch_main_init(int argc, char *argv[]) command_event(CMD_EVENT_REWIND_INIT, NULL); command_event(CMD_EVENT_CONTROLLERS_INIT, NULL); command_event(CMD_EVENT_RECORD_INIT, NULL); - command_event(CMD_EVENT_CHEATS_INIT, NULL); path_init_savefile(); @@ -2669,6 +2669,8 @@ static enum runloop_state runloop_check_state( if (menu_is_alive) { static input_bits_t old_input = {{0}}; + static enum menu_action old_action = MENU_ACTION_CANCEL; + menu_ctx_iterate_t iter; retro_ctx.poll_cb(); @@ -2689,6 +2691,52 @@ static enum runloop_state runloop_check_state( iter.action = action; + global_t *global = global_get_ptr(); + if ( global ) + { + if ( action == old_action ) + { + if ( action == MENU_ACTION_NOOP ) + { + global->menu.noop_press_time = cpu_features_get_time_usec() - global->menu.noop_start_time ; + } + else + { + global->menu.action_press_time = cpu_features_get_time_usec() - global->menu.action_start_time ; + } + } + else + { + if ( action == MENU_ACTION_NOOP ) + { + global->menu.noop_start_time = cpu_features_get_time_usec() ; + global->menu.noop_press_time = 0 ; + if ( global->menu.prev_action == old_action ) + { + global->menu.action_start_time = global->menu.prev_start_time; + } + else + { + global->menu.action_start_time = cpu_features_get_time_usec() ; + } + } + else + { + if ( global->menu.prev_action == action && global->menu.noop_press_time < 200000) //250ms + { + global->menu.action_start_time = global->menu.prev_start_time ; + global->menu.action_press_time = cpu_features_get_time_usec() - global->menu.action_start_time; + } + else + { + global->menu.prev_start_time = cpu_features_get_time_usec() ; + global->menu.prev_action = action ; + global->menu.action_press_time = 0 ; + } + } + } + } + if (!menu_driver_iterate(&iter)) rarch_menu_running_finished(); @@ -2708,6 +2756,7 @@ static enum runloop_state runloop_check_state( } old_input = current_input; + old_action = action; if (!focused) return RUNLOOP_STATE_POLLED_AND_SLEEP; @@ -3367,6 +3416,8 @@ int runloop_iterate(unsigned *sleep_ms) cheevos_test(); #endif + cheat_manager_apply_retro_cheats() ; + #ifdef HAVE_DISCORD if (discord_is_inited) { diff --git a/retroarch.h b/retroarch.h index 1635c83de8..7dd318bcd7 100644 --- a/retroarch.h +++ b/retroarch.h @@ -27,6 +27,10 @@ #include "core_type.h" #include "core.h" +#ifdef HAVE_MENU +#include "menu/menu_input.h" +#endif + RETRO_BEGIN_DECLS enum rarch_ctl_state @@ -271,6 +275,18 @@ typedef struct global } resolutions; } screen; } console; + /* Settings and/or global states specific to menus */ + struct + { +#ifdef HAVE_MENU + retro_time_t prev_start_time ; + retro_time_t noop_press_time ; + retro_time_t noop_start_time ; + retro_time_t action_start_time ; + retro_time_t action_press_time ; + enum menu_action prev_action ; +#endif + } menu; } global_t; bool rarch_ctl(enum rarch_ctl_state state, void *data); diff --git a/setting_list.c b/setting_list.c index 3199179060..8448c53f9d 100644 --- a/setting_list.c +++ b/setting_list.c @@ -35,6 +35,7 @@ #include "configuration.h" #include "config.def.h" #include "setting_list.h" +#include "retroarch.h" bool settings_list_append(rarch_setting_t **list, rarch_setting_info_t *list_info) @@ -146,7 +147,16 @@ static void setting_get_string_representation_hex(void *data, *setting->value.target.unsigned_integer); } -static void setting_get_string_representation_uint(void *data, +void setting_get_string_representation_hex_and_uint(void *data, + char *s, size_t len) +{ + rarch_setting_t *setting = (rarch_setting_t*)data; + if (setting) + snprintf(s, len, "%u (%08X)", + *setting->value.target.unsigned_integer, *setting->value.target.unsigned_integer); +} + +void setting_get_string_representation_uint(void *data, char *s, size_t len) { rarch_setting_t *setting = (rarch_setting_t*)data; @@ -155,7 +165,7 @@ static void setting_get_string_representation_uint(void *data, *setting->value.target.unsigned_integer); } -static void setting_get_string_representation_size(void *data, +void setting_get_string_representation_size(void *data, char *s, size_t len) { rarch_setting_t *setting = (rarch_setting_t*)data; @@ -173,11 +183,85 @@ void setting_get_string_representation_size_in_mb(void *data, (*setting->value.target.sizet)/(1024*1024)); } -static int setting_uint_action_left_default(void *data, bool wraparound) +void setting_get_string_representation_uint_as_enum(void *data, + char *s, size_t len) +{ + rarch_setting_t *setting = (rarch_setting_t*)data; + if (setting) + snprintf(s, len, "%s", + msg_hash_to_str(setting->index_offset+(*setting->value.target.unsigned_integer))); +} + +static float recalc_step_based_on_length_of_action(rarch_setting_t *setting) +{ + float step = setting->step; +#ifdef HAVE_MENU + global_t *global = global_get_ptr(); + if ( global ) + { +#if 0 + if (setting->enforce_minrange) + { + float numsteps = (setting->max-setting->min)/setting->step ; + float multiplier = 1.0f ; + if ( global->menu.action_press_time > 12000000) + { + multiplier = (numsteps/60.0f); + } else if ( global->menu.action_press_time > 9000000) + { + multiplier = (numsteps/300.0f) ; + } else if ( global->menu.action_press_time > 6000000) + { + multiplier = (numsteps/750.0f); + } else if ( global->menu.action_press_time > 3000000) + { + multiplier = (numsteps/3000.0f) ; + } else + { + multiplier = 1.0f ; + } + step = setting->step*multiplier; + } + else +#endif + { + if ( global->menu.action_press_time > 21000000) + { + step = setting->step*1000000.0f ; + } else if ( global->menu.action_press_time > 18000000) + { + step = setting->step*10000.0f ; + } else if ( global->menu.action_press_time > 15000000) + { + step = setting->step*1000.0f ; + } else if ( global->menu.action_press_time > 12000000) + { + step = setting->step*100.0f ; + } else if ( global->menu.action_press_time > 9000000) + { + step = setting->step*100.0f ; + } else if ( global->menu.action_press_time > 6000000) + { + step = setting->step*10.0f ; + } else if ( global->menu.action_press_time > 3000000) + { + step = setting->step*5.0f ; + } else + { + step = setting->step ; + } + } + } +#endif + return step < setting->step ? setting->step : step ; +} + +int setting_uint_action_left_default(void *data, bool wraparound) { rarch_setting_t *setting = (rarch_setting_t*)data; double min = 0.0f; bool overflowed = false; + float step = 0.0f ; if (!setting) return -1; @@ -186,10 +270,12 @@ static int setting_uint_action_left_default(void *data, bool wraparound) (void)wraparound; /* TODO/FIXME - handle this */ - overflowed = setting->step > *setting->value.target.unsigned_integer; + step = recalc_step_based_on_length_of_action(setting) ; + + overflowed = step > *setting->value.target.unsigned_integer; if (!overflowed) - *setting->value.target.unsigned_integer = *setting->value.target.unsigned_integer - setting->step; + *setting->value.target.unsigned_integer = *setting->value.target.unsigned_integer - step; if (setting->enforce_minrange) { @@ -211,10 +297,11 @@ static int setting_uint_action_left_default(void *data, bool wraparound) return 0; } -static int setting_uint_action_right_default(void *data, bool wraparound) +int setting_uint_action_right_default(void *data, bool wraparound) { rarch_setting_t *setting = (rarch_setting_t*)data; double max = 0.0f; + float step = 0.0f ; if (!setting) return -1; @@ -223,8 +310,10 @@ static int setting_uint_action_right_default(void *data, bool wraparound) (void)wraparound; /* TODO/FIXME - handle this */ + step = recalc_step_based_on_length_of_action(setting) ; + *setting->value.target.unsigned_integer = - *setting->value.target.unsigned_integer + setting->step; + *setting->value.target.unsigned_integer + step; if (setting->enforce_maxrange) { @@ -246,11 +335,36 @@ static int setting_uint_action_right_default(void *data, bool wraparound) return 0; } +int setting_uint_action_right_with_refresh(void *data, bool wraparound) +{ + int retval = setting_uint_action_right_default(data, wraparound) ; + bool refresh = false; + + menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh); + menu_driver_ctl(RARCH_MENU_CTL_SET_PREVENT_POPULATE, NULL); + + return retval ; +} + +int setting_uint_action_left_with_refresh(void *data, bool wraparound) +{ + int retval = setting_uint_action_left_default(data, wraparound) ; + bool refresh = false; + + menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh); + menu_driver_ctl(RARCH_MENU_CTL_SET_PREVENT_POPULATE, NULL); + + return retval ; + +} + + static int setting_size_action_left_default(void *data, bool wraparound) { rarch_setting_t *setting = (rarch_setting_t*)data; double min = 0.0f; bool overflowed = false; + float step = 0.0f ; if (!setting) return -1; @@ -259,10 +373,12 @@ static int setting_size_action_left_default(void *data, bool wraparound) (void)wraparound; /* TODO/FIXME - handle this */ - overflowed = setting->step > *setting->value.target.sizet; + step = recalc_step_based_on_length_of_action(setting) ; + + overflowed = step > *setting->value.target.sizet; if (!overflowed) - *setting->value.target.sizet = *setting->value.target.sizet - setting->step; + *setting->value.target.sizet = *setting->value.target.sizet - step; if (setting->enforce_minrange) { @@ -288,6 +404,7 @@ static int setting_size_action_right_default(void *data, bool wraparound) { rarch_setting_t *setting = (rarch_setting_t*)data; double max = 0.0f; + float step = 0.0f ; if (!setting) return -1; @@ -296,8 +413,10 @@ static int setting_size_action_right_default(void *data, bool wraparound) (void)wraparound; /* TODO/FIXME - handle this */ + step = recalc_step_based_on_length_of_action(setting) ; + *setting->value.target.sizet = - *setting->value.target.sizet + setting->step; + *setting->value.target.sizet + step; if (setting->enforce_maxrange) { @@ -1044,7 +1163,6 @@ static rarch_setting_t setting_size_setting(const char* name, result.action_cancel = NULL; result.action_ok = setting_generic_action_ok_default; result.action_select = setting_generic_action_ok_default; - result.get_string_representation = &setting_get_string_representation_size; result.get_string_representation = string_representation_handler; result.bind_type = 0; diff --git a/setting_list.h b/setting_list.h index 01bf89d37b..13e4ca451e 100644 --- a/setting_list.h +++ b/setting_list.h @@ -101,7 +101,7 @@ struct rarch_setting bool enforce_maxrange; uint8_t index; - uint8_t index_offset; + uint32_t index_offset; unsigned bind_type; uint32_t size; @@ -434,6 +434,17 @@ void settings_data_list_current_add_free_flags( void setting_get_string_representation_size_in_mb(void *data, char *s, size_t len); +int setting_uint_action_right_with_refresh(void *data, bool wraparound) ; + +int setting_uint_action_left_with_refresh(void *data, bool wraparound) ; + +void setting_get_string_representation_uint_as_enum(void *data, + char *s, size_t len); + +int setting_uint_action_left_default(void *data, bool wraparound); +int setting_uint_action_right_default(void *data, bool wraparound); +void setting_get_string_representation_uint(void *data,char *s, size_t len); +void setting_get_string_representation_hex_and_uint(void *data, char *s, size_t len); #define setting_get_type(setting) ((setting) ? setting->type : ST_NONE) RETRO_END_DECLS diff --git a/tasks/task_save.c b/tasks/task_save.c index 08bfbf947e..556da1fde0 100644 --- a/tasks/task_save.c +++ b/tasks/task_save.c @@ -52,6 +52,7 @@ #include "../retroarch.h" #include "../verbosity.h" #include "tasks_internal.h" +#include "../managers/cheat_manager.h" #define SAVE_STATE_CHUNK 4096 @@ -1482,6 +1483,7 @@ bool event_save_files(void) { unsigned i; + cheat_manager_save_game_specific_cheats() ; if (!task_save_files || !rarch_ctl(RARCH_CTL_IS_SRAM_USED, NULL)) return false;