Skip to content

Commit 2b10ee4

Browse files
f4mrfauxclaude
andcommitted
feat: Implement per-game cheat list auto-population preferences
Add comprehensive per-game cheat auto-population system following RetroArch's development patterns and configuration standards. ## Key Features: - **Clear Terminology**: Renamed from 'auto-load' to 'auto-populate' to clarify that this discovers cheat files, not activates cheats - **Per-Game Preferences**: Users can enable/disable auto-population per-game, stored in game-specific config files - **RetroArch-Style Priority**: per-game → global → default hierarchy - **Backward Compatibility**: Legacy 'cheats_enable_auto_load' still works ## Configuration System: - cheats_auto_populate_lists: Global auto-population setting - cheats_auto_populate_per_game: Enable per-game preference system - Per-game configs saved to config/GAMENAME.cfg files ## API Functions: - cheat_manager_should_auto_populate_for_current_content() - cheat_manager_set_per_game_auto_populate(bool enabled) - cheat_manager_get_per_game_auto_populate() This allows users to have auto-population ON for RPGs like Pokemon but OFF for arcade games, with settings remembered across sessions. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
1 parent 020a673 commit 2b10ee4

File tree

6 files changed

+171
-13
lines changed

6 files changed

+171
-13
lines changed

cheat_manager.c

Lines changed: 110 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -778,7 +778,7 @@ unsigned cheat_manager_auto_resolve_and_load_for_current_content(
778778
unsigned candidates_found = 0;
779779
settings_t *settings = config_get_ptr();
780780

781-
RARCH_LOG("[Cheats][auto] CHEAT AUTO-LOAD TRIGGERED - Starting auto-resolution...\n");
781+
RARCH_LOG("[Cheats][auto] CHEAT AUTO-POPULATION TRIGGERED - Discovering available cheat files...\n");
782782

783783
*loaded_exact_match = false;
784784
*has_multiple_candidates = false;
@@ -2420,3 +2420,112 @@ int cheat_manager_delete_match(rarch_setting_t *setting, size_t idx, bool wrapar
24202420
#endif
24212421
return 0;
24222422
}
2423+
2424+
/* Per-game cheat auto-population functionality */
2425+
2426+
static char per_game_cheat_config_path[PATH_MAX_LENGTH] = {0};
2427+
2428+
/**
2429+
* @brief Get the per-game configuration file path for current content
2430+
*/
2431+
static const char* cheat_manager_get_per_game_config_path(void)
2432+
{
2433+
static char game_name_sanitized[PATH_MAX_LENGTH];
2434+
const char *content_path = path_get(RARCH_PATH_BASENAME);
2435+
settings_t *settings = config_get_ptr();
2436+
2437+
if (!content_path || !settings)
2438+
return NULL;
2439+
2440+
/* Get sanitized game name */
2441+
strlcpy(game_name_sanitized, path_basename_nocompression(content_path), sizeof(game_name_sanitized));
2442+
path_remove_extension(game_name_sanitized);
2443+
2444+
/* Build per-game config path: config/GAMENAME.cfg */
2445+
fill_pathname_join_special(per_game_cheat_config_path,
2446+
settings->paths.directory_menu_config,
2447+
game_name_sanitized, sizeof(per_game_cheat_config_path));
2448+
strlcat(per_game_cheat_config_path, ".cfg", sizeof(per_game_cheat_config_path));
2449+
2450+
return per_game_cheat_config_path;
2451+
}
2452+
2453+
bool cheat_manager_should_auto_populate_for_current_content(void)
2454+
{
2455+
settings_t *settings = config_get_ptr();
2456+
int per_game_setting;
2457+
2458+
if (!settings)
2459+
return false;
2460+
2461+
/* Check if per-game settings are enabled globally */
2462+
if (!settings->bools.cheats_auto_populate_per_game)
2463+
return settings->bools.cheats_auto_populate_lists;
2464+
2465+
/* Check per-game preference first */
2466+
per_game_setting = cheat_manager_get_per_game_auto_populate();
2467+
if (per_game_setting >= 0)
2468+
return (per_game_setting == 1);
2469+
2470+
/* Fall back to global setting */
2471+
return settings->bools.cheats_auto_populate_lists;
2472+
}
2473+
2474+
int cheat_manager_get_per_game_auto_populate(void)
2475+
{
2476+
const char *config_path = cheat_manager_get_per_game_config_path();
2477+
config_file_t *config_file;
2478+
bool config_value;
2479+
2480+
if (!config_path || !path_is_valid(config_path))
2481+
return -1; /* No per-game config exists */
2482+
2483+
config_file = config_file_new(config_path);
2484+
if (!config_file)
2485+
return -1; /* Failed to load config */
2486+
2487+
/* Look for the per-game cheat auto-population setting */
2488+
if (config_get_bool(config_file, "cheats_auto_populate_lists", &config_value))
2489+
{
2490+
config_file_free(config_file);
2491+
return config_value ? 1 : 0;
2492+
}
2493+
2494+
config_file_free(config_file);
2495+
return -1; /* Setting not found in per-game config */
2496+
}
2497+
2498+
void cheat_manager_set_per_game_auto_populate(bool enabled)
2499+
{
2500+
const char *config_path = cheat_manager_get_per_game_config_path();
2501+
config_file_t *config_file;
2502+
2503+
if (!config_path)
2504+
{
2505+
RARCH_ERR("[Cheats][per-game] Failed to determine per-game config path\n");
2506+
return;
2507+
}
2508+
2509+
/* Create or load existing per-game config */
2510+
config_file = config_file_new(config_path);
2511+
if (!config_file)
2512+
config_file = config_file_new_alloc();
2513+
2514+
if (!config_file)
2515+
{
2516+
RARCH_ERR("[Cheats][per-game] Failed to create per-game config file\n");
2517+
return;
2518+
}
2519+
2520+
/* Set the per-game cheat auto-population preference */
2521+
config_set_bool(config_file, "cheats_auto_populate_lists", enabled);
2522+
2523+
/* Save the updated config */
2524+
if (!config_file_write(config_file, config_path))
2525+
RARCH_ERR("[Cheats][per-game] Failed to save per-game config: %s\n", config_path);
2526+
else
2527+
RARCH_LOG("[Cheats][per-game] Saved per-game auto-populate setting: %s = %s\n",
2528+
config_path, enabled ? "true" : "false");
2529+
2530+
config_file_free(config_file);
2531+
}

cheat_manager.h

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,42 @@ const char *cheat_manager_get_current_game_override(void);
371371
*/
372372
void cheat_manager_clear_current_game_override(void);
373373

374+
/**
375+
* @brief Check if cheat auto-population should be enabled for current content
376+
*
377+
* Checks per-game configuration first, then falls back to global setting.
378+
* Follows RetroArch's override hierarchy: per-game → global → default.
379+
*
380+
* @return true if cheat lists should be auto-populated for current content
381+
*
382+
* @note Respects both global and per-game settings
383+
* @note Per-game settings stored in game-specific config files
384+
*/
385+
bool cheat_manager_should_auto_populate_for_current_content(void);
386+
387+
/**
388+
* @brief Set per-game cheat auto-population preference
389+
*
390+
* Saves the per-game cheat auto-population setting to the current game's
391+
* configuration file, following RetroArch's per-game override pattern.
392+
*
393+
* @param[in] enabled true to enable auto-population for this game, false to disable
394+
*
395+
* @note Setting is persistent across sessions for this specific game
396+
* @note Creates/updates per-game config file as needed
397+
*/
398+
void cheat_manager_set_per_game_auto_populate(bool enabled);
399+
400+
/**
401+
* @brief Get per-game cheat auto-population preference
402+
*
403+
* Returns the current per-game setting, or -1 if no per-game preference is set
404+
* (indicating the global setting should be used).
405+
*
406+
* @return 1 if enabled for this game, 0 if disabled for this game, -1 if not set
407+
*/
408+
int cheat_manager_get_per_game_auto_populate(void);
409+
374410
bool cheat_manager_copy_idx_to_working(unsigned idx);
375411

376412
bool cheat_manager_copy_working_to_idx(unsigned idx);

command.c

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1362,9 +1362,11 @@ void command_event_init_cheats(
13621362

13631363
/* Try auto-resolution if enabled */
13641364
settings_t *settings = config_get_ptr();
1365-
RARCH_LOG("[Cheats][auto] Cheat init called - auto_load setting: %s\n",
1366-
(settings && settings->bools.cheats_enable_auto_load) ? "ENABLED" : "DISABLED");
1367-
if (settings && settings->bools.cheats_enable_auto_load)
1365+
/* Use per-game cheat auto-population logic */
1366+
bool should_auto_populate = cheat_manager_should_auto_populate_for_current_content();
1367+
RARCH_LOG("[Cheats][auto] Cheat init called - auto_populate for this content: %s\n",
1368+
should_auto_populate ? "ENABLED" : "DISABLED");
1369+
if (should_auto_populate)
13681370
{
13691371
bool loaded_exact_match = false;
13701372
bool has_multiple_candidates = false;
@@ -1373,23 +1375,23 @@ void command_event_init_cheats(
13731375

13741376
if (loaded_exact_match)
13751377
{
1376-
/* Auto-resolution succeeded - skip manual loading */
1377-
RARCH_LOG("[Cheats][auto] Auto-resolved and loaded cheats successfully\n");
1378+
/* Auto-population succeeded - cheat list populated, cheats ready for manual activation */
1379+
RARCH_LOG("[Cheats][auto] Auto-populated cheat list successfully - cheats ready for manual activation\n");
13781380
}
13791381
else if (has_multiple_candidates)
13801382
{
13811383
/* Multiple candidates found - user can select from menu */
1382-
RARCH_LOG("[Cheats][auto] Multiple cheat files found - check Quick Menu > Cheats\n");
1384+
RARCH_LOG("[Cheats][auto] Multiple cheat files found - check Quick Menu > Cheats for selection\n");
13831385
}
13841386
else
13851387
{
1386-
/* No auto-resolution - fall back to normal manual loading */
1388+
/* No auto-population - fall back to normal manual loading */
13871389
cheat_manager_load_game_specific_cheats(path_cheat_db);
13881390
}
13891391
}
13901392
else
13911393
{
1392-
/* Auto-loading disabled - use normal manual loading */
1394+
/* Auto-population disabled - use normal manual loading */
13931395
cheat_manager_load_game_specific_cheats(path_cheat_db);
13941396
}
13951397

config.def.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1287,8 +1287,12 @@
12871287
/* When set, all enabled cheats are auto-applied when a game is loaded. */
12881288
#define DEFAULT_APPLY_CHEATS_AFTER_LOAD false
12891289

1290-
/* When set, cheats are automatically loaded for matching content. */
1291-
#define DEFAULT_CHEATS_ENABLE_AUTO_LOAD false
1290+
/* When set, cheat files are automatically discovered and populated in cheat lists for matching content.
1291+
* Cheats are NOT automatically activated - user must manually enable individual cheats. */
1292+
#define DEFAULT_CHEATS_AUTO_POPULATE_LISTS false
1293+
1294+
/* DEPRECATED: Legacy name for backward compatibility */
1295+
#define DEFAULT_CHEATS_ENABLE_AUTO_LOAD DEFAULT_CHEATS_AUTO_POPULATE_LISTS
12921296

12931297

12941298
#if defined(RETROFW) || defined(MIYOO)

configuration.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1770,7 +1770,13 @@ static struct config_bool_setting *populate_settings_bool(
17701770
SETTING_BOOL("suspend_screensaver_enable", &settings->bools.ui_suspend_screensaver_enable, true, true, false);
17711771
SETTING_BOOL("apply_cheats_after_toggle", &settings->bools.apply_cheats_after_toggle, true, DEFAULT_APPLY_CHEATS_AFTER_TOGGLE, false);
17721772
SETTING_BOOL("apply_cheats_after_load", &settings->bools.apply_cheats_after_load, true, DEFAULT_APPLY_CHEATS_AFTER_LOAD, false);
1773-
SETTING_BOOL("cheats_enable_auto_load", &settings->bools.cheats_enable_auto_load, true, DEFAULT_CHEATS_ENABLE_AUTO_LOAD, false);
1773+
1774+
/* Cheat list auto-population settings */
1775+
SETTING_BOOL("cheats_auto_populate_lists", &settings->bools.cheats_auto_populate_lists, true, DEFAULT_CHEATS_AUTO_POPULATE_LISTS, false);
1776+
SETTING_BOOL("cheats_auto_populate_per_game", &settings->bools.cheats_auto_populate_per_game, true, false, false);
1777+
1778+
/* DEPRECATED: Legacy setting for backward compatibility */
1779+
SETTING_BOOL("cheats_enable_auto_load", &settings->bools.cheats_auto_populate_lists, true, DEFAULT_CHEATS_ENABLE_AUTO_LOAD, false);
17741780
SETTING_BOOL("rewind_enable", &settings->bools.rewind_enable, true, DEFAULT_REWIND_ENABLE, false);
17751781
SETTING_BOOL("fastforward_frameskip", &settings->bools.fastforward_frameskip, true, DEFAULT_FASTFORWARD_FRAMESKIP, false);
17761782
SETTING_BOOL("vrr_runloop_enable", &settings->bools.vrr_runloop_enable, true, DEFAULT_VRR_RUNLOOP_ENABLE, false);

configuration.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1015,7 +1015,8 @@ typedef struct settings
10151015
bool menu_throttle_framerate;
10161016
bool apply_cheats_after_toggle;
10171017
bool apply_cheats_after_load;
1018-
bool cheats_enable_auto_load;
1018+
bool cheats_auto_populate_lists; /* Auto-discover and populate cheat lists */
1019+
bool cheats_auto_populate_per_game; /* Enable per-game cheat list auto-population preferences */
10191020
bool run_ahead_enabled;
10201021
bool run_ahead_secondary_instance;
10211022
bool run_ahead_hide_warnings;

0 commit comments

Comments
 (0)