Add preliminary Core Cheat Options support - should work with

cores like SNES9x/bSNES right now
This commit is contained in:
twinaphex 2014-12-06 15:47:25 +01:00
parent 2808fbcd52
commit fe0ece3124
11 changed files with 279 additions and 42 deletions

View File

@ -35,21 +35,6 @@
#include "compat/rxml/rxml.h"
#endif
struct cheat
{
char *desc;
bool state;
char *code;
};
struct cheat_manager
{
struct cheat *cheats;
unsigned ptr;
unsigned size;
unsigned buf_size;
};
static char *strcat_alloc(char *dest, const char *input)
{
size_t dest_len = dest ? strlen(dest) : 0;
@ -68,13 +53,13 @@ static char *strcat_alloc(char *dest, const char *input)
return output;
}
static bool xml_grab_cheat(struct cheat *cht, xmlNodePtr ptr)
static bool xml_grab_cheat(struct item_cheat *cht, xmlNodePtr ptr)
{
bool first;
if (!ptr)
return false;
memset(cht, 0, sizeof(struct cheat));
memset(cht, 0, sizeof(struct item_cheat));
first = true;
for (; ptr; ptr = ptr->next)
@ -124,10 +109,7 @@ static bool xml_grab_cheats(cheat_manager_t *handle, xmlNodePtr ptr)
{
if (handle->size == handle->buf_size)
{
handle->buf_size *= 2;
handle->cheats = (struct cheat*)
realloc(handle->cheats, handle->buf_size * sizeof(struct cheat));
if (!handle->cheats)
if (!cheat_manager_realloc(handle, handle->buf_size * 2))
return false;
}
@ -139,7 +121,7 @@ static bool xml_grab_cheats(cheat_manager_t *handle, xmlNodePtr ptr)
return true;
}
static void cheat_manager_apply_cheats(cheat_manager_t *handle)
void cheat_manager_apply_cheats(cheat_manager_t *handle)
{
unsigned i;
unsigned idx = 0;
@ -231,7 +213,68 @@ static void cheat_manager_save_config(cheat_manager_t *handle,
config_file_free(conf);
}
cheat_manager_t *cheat_manager_new(const char *path)
cheat_manager_t *cheat_manager_new(void)
{
unsigned i;
cheat_manager_t *handle = NULL;
handle = (cheat_manager_t*)calloc(1, sizeof(struct cheat_manager));
if (!handle)
return NULL;
handle->buf_size = handle->size = 0;
handle->cheats = (struct item_cheat*)
calloc(handle->buf_size, sizeof(struct item_cheat));
if (!handle->cheats)
{
handle->buf_size = 0;
handle->size = 0;
handle->cheats = NULL;
return handle;
}
for (i = 0; i < handle->size; i++)
{
handle->cheats[i].desc = NULL;
handle->cheats[i].code = NULL;
handle->cheats[i].state = false;
}
return handle;
}
bool cheat_manager_realloc(cheat_manager_t *handle, unsigned new_size)
{
unsigned i;
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)
{
handle->buf_size = handle->size = 0;
handle->cheats = NULL;
return false;
}
handle->buf_size = new_size;
handle->size = new_size;
for (i = 0; i < handle->size; i++)
{
handle->cheats[i].desc = NULL;
handle->cheats[i].code = NULL;
handle->cheats[i].state = false;
}
return true;
}
cheat_manager_t *cheat_manager_new_from_xml(const char *path)
{
xmlParserCtxtPtr ctx;
xmlNodePtr head, cur;
@ -252,8 +295,8 @@ cheat_manager_t *cheat_manager_new(const char *path)
cur = NULL;
handle->buf_size = 1;
handle->cheats = (struct cheat*)
calloc(handle->buf_size, sizeof(struct cheat));
handle->cheats = (struct item_cheat*)
calloc(handle->buf_size, sizeof(struct item_cheat));
if (!handle->cheats)
{
handle->buf_size = 0;

View File

@ -16,13 +16,34 @@
#ifndef __RARCH_CHEATS_H
#define __RARCH_CHEATS_H
#include <boolean.h>
#ifdef __cplusplus
extern "C" {
#endif
struct item_cheat
{
char *desc;
bool state;
char *code;
};
struct cheat_manager
{
struct item_cheat *cheats;
unsigned ptr;
unsigned size;
unsigned buf_size;
};
typedef struct cheat_manager cheat_manager_t;
cheat_manager_t* cheat_manager_new(const char *path);
cheat_manager_t *cheat_manager_new(void);
cheat_manager_t* cheat_manager_new_from_xml(const char *path);
bool cheat_manager_realloc(cheat_manager_t *handle, unsigned new_size);
void cheat_manager_free(cheat_manager_t *handle);
@ -32,6 +53,8 @@ void cheat_manager_index_prev(cheat_manager_t *handle);
void cheat_manager_toggle(cheat_manager_t *handle);
void cheat_manager_apply_cheats(cheat_manager_t *handle);
#ifdef __cplusplus
}
#endif

View File

@ -58,6 +58,8 @@ static void get_title(const char *label, const char *dir,
strlcpy(title, "DISK OPTIONS", sizeof_title);
else if (!strcmp(label, "core_options"))
strlcpy(title, "CORE OPTIONS", sizeof_title);
else if (!strcmp(label, "core_cheat_options"))
strlcpy(title, "CORE CHEAT OPTIONS", sizeof_title);
else if (!strcmp(label, "core_information"))
strlcpy(title, "CORE INFO", sizeof_title);
else if (!strcmp(label, "Privacy Options"))

View File

@ -166,6 +166,7 @@ void *menu_init(const void *data)
#ifdef HAVE_SHADER_MANAGER
menu->shader = (struct gfx_shader*)calloc(1, sizeof(struct gfx_shader));
#endif
menu->cheats = cheat_manager_new();
menu->push_start_screen = g_settings.menu_show_start_screen;
g_settings.menu_show_start_screen = false;
@ -218,6 +219,10 @@ void menu_free(void *data)
menu->shader = NULL;
#endif
if (menu->cheats)
cheat_manager_free(menu->cheats);
menu->cheats = NULL;
if (driver.menu_ctx && driver.menu_ctx->free)
driver.menu_ctx->free(menu);

View File

@ -45,6 +45,10 @@
#define MAX_COUNTERS 64
#endif
#ifndef MAX_CHEAT_COUNTERS
#define MAX_CHEAT_COUNTERS 100
#endif
#define MENU_SETTINGS_CORE_INFO_NONE 0xffff
#define MENU_SETTINGS_CORE_OPTION_NONE 0xffff
#define MENU_SETTINGS_CORE_OPTION_START 0x10000
@ -141,7 +145,9 @@ typedef enum
MENU_SETTINGS_LIBRETRO_PERF_COUNTERS_BEGIN,
MENU_SETTINGS_LIBRETRO_PERF_COUNTERS_END = MENU_SETTINGS_LIBRETRO_PERF_COUNTERS_BEGIN + (MAX_COUNTERS - 1),
MENU_SETTINGS_PERF_COUNTERS_BEGIN,
MENU_SETTINGS_PERF_COUNTERS_END = MENU_SETTINGS_PERF_COUNTERS_BEGIN + (MAX_COUNTERS - 1)
MENU_SETTINGS_PERF_COUNTERS_END = MENU_SETTINGS_PERF_COUNTERS_BEGIN + (MAX_COUNTERS - 1),
MENU_SETTINGS_CHEAT_BEGIN,
MENU_SETTINGS_CHEAT_END = MENU_SETTINGS_CHEAT_BEGIN + (MAX_CHEAT_COUNTERS - 1),
} menu_settings_t;
void *menu_init(const void *data);

View File

@ -21,6 +21,7 @@
#include <stdint.h>
#include <boolean.h>
#include "menu_list.h"
#include "../cheats.h"
#include "../settings_list.h"
#ifdef __cplusplus
@ -108,6 +109,7 @@ typedef struct
bool load_no_content;
struct gfx_shader *shader;
cheat_manager_t *cheats;
struct menu_bind_state binds;
@ -133,6 +135,8 @@ typedef struct
const char *label;
const char *label_setting;
bool display;
unsigned type;
unsigned idx;
} keyboard;
rarch_setting_t *list_mainmenu;

View File

@ -24,6 +24,7 @@
#include "../file_ext.h"
#include "../config.def.h"
#include "../cheats.h"
#include <file/dir_list.h>
@ -164,6 +165,14 @@ static int action_ok_load_state(const char *path,
return 0;
}
static int action_ok_cheat(const char *path,
const char *label, unsigned type, size_t idx)
{
menu_key_start_line(driver.menu, "Input Cheat",
label, type, idx, st_cheat_callback);
return 0;
}
static int action_ok_save_state(const char *path,
const char *label, unsigned type, size_t idx)
{
@ -261,6 +270,19 @@ static int action_ok_shader_apply_changes(const char *path,
return 0;
}
static int action_ok_cheat_apply_changes(const char *path,
const char *label, unsigned type, size_t idx)
{
cheat_manager_t *cheat = (cheat_manager_t*)driver.menu->cheats;
if (!cheat)
return -1;
cheat_manager_apply_cheats(cheat);
return 0;
}
/* FIXME: Ugly hack, need to be refactored badly. */
size_t hack_shader_pass = 0;
@ -321,7 +343,7 @@ static int action_ok_shader_preset_save_as(const char *path,
return -1;
menu_key_start_line(driver.menu, "Preset Filename",
label, st_string_callback);
label, type, idx, st_string_callback);
return 0;
}
@ -1130,7 +1152,7 @@ static int action_start_shader_num_passes(unsigned type, const char *label,
if (!shader)
return -1;
if (shader && shader->passes)
if (shader->passes)
shader->passes = 0;
driver.menu->need_refresh = true;
@ -1139,6 +1161,52 @@ static int action_start_shader_num_passes(unsigned type, const char *label,
return 0;
}
static int action_start_cheat_num_passes(unsigned type, const char *label,
unsigned action)
{
cheat_manager_t *cheat = (cheat_manager_t*)driver.menu->cheats;
if (!cheat)
return -1;
if (cheat->size)
{
cheat_manager_realloc(cheat, 0);
driver.menu->need_refresh = true;
}
return 0;
}
static int action_toggle_cheat_num_passes(unsigned type, const char *label,
unsigned action)
{
unsigned new_size = 0;
cheat_manager_t *cheat = (cheat_manager_t*)driver.menu->cheats;
if (!cheat)
return -1;
switch (action)
{
case MENU_ACTION_LEFT:
if (cheat->size)
new_size = cheat->size - 1;
driver.menu->need_refresh = true;
break;
case MENU_ACTION_RIGHT:
new_size = cheat->size + 1;
driver.menu->need_refresh = true;
break;
}
if (driver.menu->need_refresh)
cheat_manager_realloc(cheat, new_size);
return 0;
}
static int action_toggle_shader_num_passes(unsigned type, const char *label,
unsigned action)
{
@ -1151,13 +1219,13 @@ static int action_toggle_shader_num_passes(unsigned type, const char *label,
switch (action)
{
case MENU_ACTION_LEFT:
if (shader && shader->passes)
if (shader->passes)
shader->passes--;
driver.menu->need_refresh = true;
break;
case MENU_ACTION_RIGHT:
if (shader && (shader->passes < GFX_MAX_SHADERS))
if ((shader->passes < GFX_MAX_SHADERS))
shader->passes++;
driver.menu->need_refresh = true;
break;
@ -1761,6 +1829,36 @@ static int deferred_push_frontend_counters(void *data, void *userdata,
return 0;
}
static int deferred_push_core_cheat_options(void *data, void *userdata,
const char *path, const char *label, unsigned type)
{
unsigned i;
size_t opts = 100;
file_list_t *list = (file_list_t*)data;
cheat_manager_t *cheat = (cheat_manager_t*)driver.menu->cheats;
if (!list || !cheat)
return -1;
menu_list_clear(list);
menu_list_push(list, "Cheat Passes", "cheat_num_passes",
0, 0);
menu_list_push(list, "Apply Cheat Changes", "cheat_apply_changes",
MENU_SETTING_ACTION, 0);
for (i = 0; i < cheat->size; i++)
{
char label[64];
snprintf(label, sizeof(label), "Cheat #%d: ", i);
menu_list_push(list, label, "", MENU_SETTINGS_CHEAT_BEGIN + i, 0);
}
if (driver.menu_ctx && driver.menu_ctx->populate_entries)
driver.menu_ctx->populate_entries(driver.menu, path, label, type);
return 0;
}
static int deferred_push_core_options(void *data, void *userdata,
const char *path, const char *label, unsigned type)
{
@ -2106,6 +2204,9 @@ static int menu_entries_cbs_init_bind_ok_first(menu_file_list_cbs_t *cbs,
else if (type >= MENU_SETTINGS_SHADER_PRESET_PARAMETER_0
&& type <= MENU_SETTINGS_SHADER_PRESET_PARAMETER_LAST)
cbs->action_ok = NULL;
else if (type >= MENU_SETTINGS_CHEAT_BEGIN
&& type <= MENU_SETTINGS_CHEAT_END)
cbs->action_ok = action_ok_cheat;
else if (!strcmp(label, "savestate"))
cbs->action_ok = action_ok_save_state;
else if (!strcmp(label, "loadstate"))
@ -2210,6 +2311,8 @@ static void menu_entries_cbs_init_bind_start(menu_file_list_cbs_t *cbs,
cbs->action_start = action_start_shader_filter_pass;
else if (!strcmp(label, "video_shader_num_passes"))
cbs->action_start = action_start_shader_num_passes;
else if (!strcmp(label, "cheat_num_passes"))
cbs->action_start = action_start_cheat_num_passes;
else if (type >= MENU_SETTINGS_SHADER_PARAMETER_0
&& type <= MENU_SETTINGS_SHADER_PARAMETER_LAST)
cbs->action_start = action_start_shader_action_parameter;
@ -2263,6 +2366,7 @@ static void menu_entries_cbs_init_bind_ok(menu_file_list_cbs_t *cbs,
!strcmp(label, "Shader Options") ||
!strcmp(label, "Input Options") ||
!strcmp(label, "core_options") ||
!strcmp(label, "core_cheat_options") ||
!strcmp(label, "core_information") ||
!strcmp(label, "disk_options") ||
!strcmp(label, "settings") ||
@ -2282,6 +2386,8 @@ static void menu_entries_cbs_init_bind_ok(menu_file_list_cbs_t *cbs,
cbs->action_ok = action_ok_push_path_list;
else if (!strcmp(label, "shader_apply_changes"))
cbs->action_ok = action_ok_shader_apply_changes;
else if (!strcmp(label, "cheat_apply_changes"))
cbs->action_ok = action_ok_cheat_apply_changes;
else if (!strcmp(label, "video_shader_preset_save_as"))
cbs->action_ok = action_ok_shader_preset_save_as;
else if (!strcmp(label, "core_list"))
@ -2334,6 +2440,8 @@ static void menu_entries_cbs_init_bind_toggle(menu_file_list_cbs_t *cbs,
cbs->action_toggle = action_toggle_shader_filter_default;
else if (!strcmp(label, "video_shader_num_passes"))
cbs->action_toggle = action_toggle_shader_num_passes;
else if (!strcmp(label, "cheat_num_passes"))
cbs->action_toggle = action_toggle_cheat_num_passes;
else if (type == MENU_SETTINGS_VIDEO_RESOLUTION)
cbs->action_toggle = action_toggle_video_resolution;
else if ((type >= MENU_SETTINGS_CORE_OPTION_START))
@ -2401,6 +2509,8 @@ static void menu_entries_cbs_init_bind_deferred_push(menu_file_list_cbs_t *cbs,
cbs->action_deferred_push = deferred_push_frontend_counters;
else if (!strcmp(label, "core_options"))
cbs->action_deferred_push = deferred_push_core_options;
else if (!strcmp(label, "core_cheat_options"))
cbs->action_deferred_push = deferred_push_core_cheat_options;
else if (!strcmp(label, "disk_options"))
cbs->action_deferred_push = deferred_push_disk_options;
else if (!strcmp(label, "core_list"))

View File

@ -33,7 +33,8 @@
#include "../settings_data.h"
void menu_key_start_line(void *data, const char *label,
const char *label_setting, input_keyboard_line_complete_t cb)
const char *label_setting, unsigned type, unsigned idx,
input_keyboard_line_complete_t cb)
{
menu_handle_t *menu = (menu_handle_t*)data;
@ -43,6 +44,8 @@ void menu_key_start_line(void *data, const char *label,
menu->keyboard.display = true;
menu->keyboard.label = label;
menu->keyboard.label_setting = label_setting;
menu->keyboard.type = type;
menu->keyboard.idx = idx;
menu->keyboard.buffer = input_keyboard_start_line(menu, cb);
}
@ -107,6 +110,22 @@ void st_string_callback(void *userdata, const char *str)
menu_key_end_line(menu);
}
void st_cheat_callback(void *userdata, const char *str)
{
menu_handle_t *menu = (menu_handle_t*)userdata;
cheat_manager_t *cheat = (cheat_manager_t*)menu->cheats;
if (cheat && str && *str)
{
unsigned cheat_index = menu->keyboard.type - MENU_SETTINGS_CHEAT_BEGIN;
RARCH_LOG("cheat_index is: %d\n", cheat_index);
cheat->cheats[cheat_index].code = strdup(str);
cheat->cheats[cheat_index].state = true;
}
menu_key_end_line(menu);
}
void menu_key_event(bool down, unsigned keycode,
uint32_t character, uint16_t mod)
{

View File

@ -27,12 +27,15 @@ void menu_key_event(bool down, unsigned keycode, uint32_t character,
uint16_t key_modifiers);
void menu_key_start_line(void *data, const char *label,
const char *label_setting, input_keyboard_line_complete_t cb);
const char *label_setting, unsigned type, unsigned idx,
input_keyboard_line_complete_t cb);
void st_uint_callback(void *userdata, const char *str);
void st_string_callback(void *userdata, const char *str);
void st_cheat_callback(void *userdata, const char *str);
void menu_poll_bind_get_rested_axes(struct menu_bind_state *state);
void menu_poll_bind_state(struct menu_bind_state *state);

View File

@ -1118,7 +1118,7 @@ static void init_cheats(void)
return;
if (*g_settings.cheat_database)
g_extern.cheat = cheat_manager_new(g_settings.cheat_database);
g_extern.cheat = cheat_manager_new_from_xml(g_settings.cheat_database);
}
static void init_rewind(void)

View File

@ -989,7 +989,7 @@ static int setting_data_uint_action_ok_linefeed(void *data, unsigned action)
return -1;
menu_key_start_line(driver.menu, setting->short_description,
setting->name, st_uint_callback);
setting->name, 0, 0, st_uint_callback);
return 0;
}
@ -2400,7 +2400,19 @@ void setting_data_get_label(char *type_str,
}
else
#endif
if (type >= MENU_SETTINGS_PERF_COUNTERS_BEGIN
if (!strcmp(label, "cheat_num_passes"))
snprintf(type_str, type_str_size, "%u", driver.menu->cheats->buf_size);
else if (type >= MENU_SETTINGS_CHEAT_BEGIN
&& type <= MENU_SETTINGS_CHEAT_END)
{
unsigned cheat_index = type - MENU_SETTINGS_CHEAT_BEGIN;
if (cheat_index < driver.menu->cheats->buf_size)
snprintf(type_str, type_str_size, "%s",
(
(driver.menu->cheats->cheats[cheat_index].code != NULL)
) ? driver.menu->cheats->cheats[cheat_index].code : "N/A");
}
else if (type >= MENU_SETTINGS_PERF_COUNTERS_BEGIN
&& type <= MENU_SETTINGS_PERF_COUNTERS_END)
menu_common_setting_set_label_perf(type_str, type_str_size, w, type,
perf_counters_rarch,
@ -2747,7 +2759,7 @@ static int setting_data_string_action_ok_allow_input(void *data,
return -1;
menu_key_start_line(driver.menu, setting->short_description,
setting->name, st_string_callback);
setting->name, 0, 0, st_string_callback);
return 0;
}
@ -2859,22 +2871,32 @@ static bool setting_data_append_list_main_menu_options(
group_info.name,
subgroup_info.name);
CONFIG_ACTION(
"core_information",
"Core Information",
group_info.name,
subgroup_info.name);
if (g_extern.main_is_init
&& !g_extern.libretro_dummy
&& g_extern.system.disk_control.get_num_images)
if (g_extern.main_is_init)
{
CONFIG_ACTION(
"disk_options",
"Core Disk Options",
"core_cheat_options",
"Core Cheat Options",
group_info.name,
subgroup_info.name);
if ( !g_extern.libretro_dummy
&& g_extern.system.disk_control.get_num_images)
{
CONFIG_ACTION(
"disk_options",
"Core Disk Options",
group_info.name,
subgroup_info.name);
}
}
CONFIG_ACTION(
"settings",
"Settings",