加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
setting_list.c 67.06 KB
一键复制 编辑 原始数据 按行查看 历史
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122
/* RetroArch - A frontend for libretro.
* Copyright (C) 2011-2017 - Daniel De Matteis
*
* RetroArch is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with RetroArch.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include <boolean.h>
#include <file/file_path.h>
#include <string/stdstring.h>
#include <compat/strl.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "input/input_driver.h"
#include "config.def.keybinds.h"
#ifdef HAVE_MENU
#include "menu/menu_driver.h"
#include "menu/widgets/menu_input_dialog.h"
#include "menu/widgets/menu_input_bind_dialog.h"
#endif
#include "configuration.h"
#include "config.def.h"
#include "setting_list.h"
bool settings_list_append(rarch_setting_t **list,
rarch_setting_info_t *list_info)
{
if (!list || !*list || !list_info)
return false;
if (list_info->index == list_info->size)
{
list_info->size *= 2;
*list = (rarch_setting_t*)
realloc(*list, sizeof(rarch_setting_t) * list_info->size);
if (!*list)
return false;
}
return true;
}
unsigned setting_get_bind_type(rarch_setting_t *setting)
{
if (!setting)
return 0;
return setting->bind_type;
}
static int setting_bind_action_ok(void *data, bool wraparound)
{
(void)wraparound; /* TODO/FIXME - handle this */
#ifdef HAVE_MENU
/* TODO - get rid of menu dependency */
if (!menu_input_key_bind_set_mode(MENU_INPUT_BINDS_CTL_BIND_SINGLE, data))
return -1;
#endif
return 0;
}
static int setting_int_action_right_default(void *data, bool wraparound)
{
rarch_setting_t *setting = (rarch_setting_t*)data;
double max = 0.0f;
if (!setting)
return -1;
max = setting->max;
(void)wraparound; /* TODO/FIXME - handle this */
*setting->value.target.integer =
*setting->value.target.integer + setting->step;
if (setting->enforce_maxrange)
{
if (*setting->value.target.integer > max)
{
settings_t *settings = config_get_ptr();
#ifdef HAVE_MENU
double min = setting->min;
if (settings && settings->bools.menu_navigation_wraparound_enable)
*setting->value.target.integer = min;
else
#endif
*setting->value.target.integer = max;
}
}
return 0;
}
#ifdef HAVE_MENU
static int setting_bind_action_start(void *data)
{
unsigned bind_type;
struct retro_keybind *keybind = NULL;
rarch_setting_t *setting = (rarch_setting_t*)data;
struct retro_keybind *def_binds = (struct retro_keybind *)retro_keybinds_1;
if (!setting)
return -1;
keybind = (struct retro_keybind*)setting->value.target.keybind;
if (!keybind)
return -1;
keybind->joykey = NO_BTN;
keybind->joyaxis = AXIS_NONE;
if (setting->index_offset)
def_binds = (struct retro_keybind*)retro_keybinds_rest;
bind_type = setting_get_bind_type(setting);
keybind->key = def_binds[bind_type - MENU_SETTINGS_BIND_BEGIN].key;
return 0;
}
#endif
static void setting_get_string_representation_hex(void *data,
char *s, size_t len)
{
rarch_setting_t *setting = (rarch_setting_t*)data;
if (setting)
snprintf(s, len, "%08x",
*setting->value.target.unsigned_integer);
}
static void setting_get_string_representation_uint(void *data,
char *s, size_t len)
{
rarch_setting_t *setting = (rarch_setting_t*)data;
if (setting)
snprintf(s, len, "%u",
*setting->value.target.unsigned_integer);
}
static 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;
if (!setting)
return -1;
min = setting->min;
(void)wraparound; /* TODO/FIXME - handle this */
overflowed = setting->step > *setting->value.target.unsigned_integer;
if (!overflowed)
*setting->value.target.unsigned_integer = *setting->value.target.unsigned_integer - setting->step;
if (setting->enforce_minrange)
{
if (overflowed || *setting->value.target.unsigned_integer < min)
{
settings_t *settings = config_get_ptr();
#ifdef HAVE_MENU
double max = setting->max;
if (settings && settings->bools.menu_navigation_wraparound_enable)
*setting->value.target.unsigned_integer = max;
else
#endif
*setting->value.target.unsigned_integer = min;
}
}
return 0;
}
static int setting_uint_action_right_default(void *data, bool wraparound)
{
rarch_setting_t *setting = (rarch_setting_t*)data;
double max = 0.0f;
if (!setting)
return -1;
max = setting->max;
(void)wraparound; /* TODO/FIXME - handle this */
*setting->value.target.unsigned_integer =
*setting->value.target.unsigned_integer + setting->step;
if (setting->enforce_maxrange)
{
if (*setting->value.target.unsigned_integer > max)
{
settings_t *settings = config_get_ptr();
#ifdef HAVE_MENU
double min = setting->min;
if (settings && settings->bools.menu_navigation_wraparound_enable)
*setting->value.target.unsigned_integer = min;
else
#endif
*setting->value.target.unsigned_integer = max;
}
}
return 0;
}
int setting_generic_action_ok_default(void *data, bool wraparound)
{
rarch_setting_t *setting = (rarch_setting_t*)data;
if (!setting)
return -1;
(void)wraparound; /* TODO/FIXME - handle this */
if (setting->cmd_trigger.idx != CMD_EVENT_NONE)
setting->cmd_trigger.triggered = true;
return 0;
}
static void setting_get_string_representation_int(void *data,
char *s, size_t len)
{
rarch_setting_t *setting = (rarch_setting_t*)data;
if (setting)
snprintf(s, len, "%d", *setting->value.target.integer);
}
/**
* setting_set_with_string_representation:
* @setting : pointer to setting
* @value : value for the setting (string)
*
* Set a settings' value with a string. It is assumed
* that the string has been properly formatted.
**/
int setting_set_with_string_representation(rarch_setting_t* setting,
const char* value)
{
double min, max;
uint64_t flags;
if (!setting || !value)
return -1;
min = setting->min;
max = setting->max;
flags = setting->flags;
switch (setting_get_type(setting))
{
case ST_INT:
sscanf(value, "%d", setting->value.target.integer);
if (flags & SD_FLAG_HAS_RANGE)
{
if (setting->enforce_minrange && *setting->value.target.integer < min)
*setting->value.target.integer = min;
if (setting->enforce_maxrange && *setting->value.target.integer > max)
{
#ifdef HAVE_MENU
settings_t *settings = config_get_ptr();
if (settings && settings->bools.menu_navigation_wraparound_enable)
*setting->value.target.integer = min;
else
#endif
*setting->value.target.integer = max;
}
}
break;
case ST_UINT:
sscanf(value, "%u", setting->value.target.unsigned_integer);
if (flags & SD_FLAG_HAS_RANGE)
{
if (setting->enforce_minrange && *setting->value.target.unsigned_integer < min)
*setting->value.target.unsigned_integer = min;
if (setting->enforce_maxrange && *setting->value.target.unsigned_integer > max)
{
#ifdef HAVE_MENU
settings_t *settings = config_get_ptr();
if (settings && settings->bools.menu_navigation_wraparound_enable)
*setting->value.target.unsigned_integer = min;
else
#endif
*setting->value.target.unsigned_integer = max;
}
}
break;
case ST_FLOAT:
sscanf(value, "%f", setting->value.target.fraction);
if (flags & SD_FLAG_HAS_RANGE)
{
if (setting->enforce_minrange && *setting->value.target.fraction < min)
*setting->value.target.fraction = min;
if (setting->enforce_maxrange && *setting->value.target.fraction > max)
{
#ifdef HAVE_MENU
settings_t *settings = config_get_ptr();
if (settings && settings->bools.menu_navigation_wraparound_enable)
*setting->value.target.fraction = min;
else
#endif
*setting->value.target.fraction = max;
}
}
break;
case ST_PATH:
case ST_DIR:
case ST_STRING:
case ST_STRING_OPTIONS:
case ST_ACTION:
strlcpy(setting->value.target.string, value, setting->size);
break;
case ST_BOOL:
if (string_is_equal_fast(value, "true", 4))
*setting->value.target.boolean = true;
else if (string_is_equal_fast(value, "false", 5))
*setting->value.target.boolean = false;
break;
default:
break;
}
if (setting->change_handler)
setting->change_handler(setting);
return 0;
}
static int setting_fraction_action_left_default(
void *data, bool wraparound)
{
rarch_setting_t *setting = (rarch_setting_t*)data;
if (!setting)
return -1;
(void)wraparound; /* TODO/FIXME - handle this */
*setting->value.target.fraction =
*setting->value.target.fraction - setting->step;
if (setting->enforce_minrange)
{
double min = setting->min;
if (*setting->value.target.fraction < min)
*setting->value.target.fraction = min;
}
return 0;
}
static int setting_fraction_action_right_default(
void *data, bool wraparound)
{
rarch_setting_t *setting = (rarch_setting_t*)data;
double max = 0.0f;
if (!setting)
return -1;
max = setting->max;
(void)wraparound; /* TODO/FIXME - handle this */
*setting->value.target.fraction =
*setting->value.target.fraction + setting->step;
if (setting->enforce_maxrange)
{
if (*setting->value.target.fraction > max)
{
#ifdef HAVE_MENU
settings_t *settings = config_get_ptr();
double min = setting->min;
if (settings && settings->bools.menu_navigation_wraparound_enable)
*setting->value.target.fraction = min;
else
#endif
*setting->value.target.fraction = max;
}
}
return 0;
}
/**
* setting_reset_setting:
* @setting : pointer to setting
*
* Reset a setting's value to its defaults.
**/
static void setting_reset_setting(rarch_setting_t* setting)
{
if (!setting)
return;
switch (setting_get_type(setting))
{
case ST_BOOL:
*setting->value.target.boolean = setting->default_value.boolean;
break;
case ST_INT:
*setting->value.target.integer = setting->default_value.integer;
break;
case ST_UINT:
*setting->value.target.unsigned_integer = setting->default_value.unsigned_integer;
break;
case ST_FLOAT:
*setting->value.target.fraction = setting->default_value.fraction;
break;
case ST_BIND:
*setting->value.target.keybind = *setting->default_value.keybind;
break;
case ST_STRING:
case ST_STRING_OPTIONS:
case ST_PATH:
case ST_DIR:
if (setting->default_value.string)
{
if (setting_get_type(setting) == ST_STRING)
setting_set_with_string_representation(setting, setting->default_value.string);
else
fill_pathname_expand_special(setting->value.target.string,
setting->default_value.string, setting->size);
}
break;
default:
break;
}
if (setting->change_handler)
setting->change_handler(setting);
}
int setting_generic_action_start_default(void *data)
{
rarch_setting_t *setting = (rarch_setting_t*)data;
if (!setting)
return -1;
setting_reset_setting(setting);
return 0;
}
static void setting_get_string_representation_default(void *data,
char *s, size_t len)
{
(void)data;
strlcpy(s, "...", len);
}
/**
* setting_get_string_representation_st_bool:
* @setting : pointer to setting
* @s : string for the type to be represented on-screen as
* a label.
* @len : size of @s
*
* Set a settings' label value. The setting is of type ST_BOOL.
**/
static void setting_get_string_representation_st_bool(void *data,
char *s, size_t len)
{
rarch_setting_t *setting = (rarch_setting_t*)data;
if (setting)
strlcpy(s, *setting->value.target.boolean ? setting->boolean.on_label :
setting->boolean.off_label, len);
}
/**
* setting_get_string_representation_st_float:
* @setting : pointer to setting
* @s : string for the type to be represented on-screen as
* a label.
* @len : size of @s
*
* Set a settings' label value. The setting is of type ST_FLOAT.
**/
static void setting_get_string_representation_st_float(void *data,
char *s, size_t len)
{
rarch_setting_t *setting = (rarch_setting_t*)data;
if (setting)
snprintf(s, len, setting->rounding_fraction,
*setting->value.target.fraction);
}
static void setting_get_string_representation_st_dir(void *data,
char *s, size_t len)
{
rarch_setting_t *setting = (rarch_setting_t*)data;
if (setting)
strlcpy(s,
*setting->value.target.string ?
setting->value.target.string : setting->dir.empty_path,
len);
}
static void setting_get_string_representation_st_path(void *data,
char *s, size_t len)
{
rarch_setting_t *setting = (rarch_setting_t*)data;
if (setting)
fill_short_pathname_representation(s, setting->value.target.string, len);
}
static void setting_get_string_representation_st_string(void *data,
char *s, size_t len)
{
rarch_setting_t *setting = (rarch_setting_t*)data;
if (setting)
strlcpy(s, setting->value.target.string, len);
}
static void setting_get_string_representation_st_bind(void *data,
char *s, size_t len)
{
unsigned index_offset;
rarch_setting_t *setting = (rarch_setting_t*)data;
const struct retro_keybind* keybind = NULL;
const struct retro_keybind* auto_bind = NULL;
if (!setting)
return;
index_offset = setting->index_offset;
keybind = (const struct retro_keybind*)setting->value.target.keybind;
auto_bind = (const struct retro_keybind*)
input_config_get_bind_auto(index_offset, keybind->id);
input_config_get_bind_string(s, keybind, auto_bind, len);
}
static int setting_action_action_ok(void *data, bool wraparound)
{
rarch_setting_t *setting = (rarch_setting_t*)data;
if (!setting)
return -1;
(void)wraparound; /* TODO/FIXME - handle this */
if (setting->cmd_trigger.idx != CMD_EVENT_NONE)
command_event(setting->cmd_trigger.idx, NULL);
return 0;
}
/**
* setting_action_setting:
* @name : Name of setting.
* @short_description : Short description of setting.
* @group : Group that the setting belongs to.
* @subgroup : Subgroup that the setting belongs to.
*
* Initializes a setting of type ST_ACTION.
*
* Returns: setting of type ST_ACTION.
**/
static rarch_setting_t setting_action_setting(const char* name,
const char* short_description,
const char *group, const char *subgroup,
const char *parent_group,
bool dont_use_enum_idx)
{
rarch_setting_t result;
result.enum_idx = MSG_UNKNOWN;
result.type = ST_ACTION;
result.size = 0;
result.name = name;
result.name_hash = 0;
result.short_description = short_description;
result.group = group;
result.subgroup = subgroup;
result.parent_group = parent_group;
result.values = NULL;
result.index = 0;
result.index_offset = 0;
result.min = 0.0;
result.max = 0.0;
result.flags = 0;
result.free_flags = 0;
result.change_handler = NULL;
result.read_handler = NULL;
result.action_start = NULL;
result.action_left = NULL;
result.action_right = NULL;
result.action_up = NULL;
result.action_down = NULL;
result.action_cancel = NULL;
result.action_ok = setting_action_action_ok;
result.action_select = setting_action_action_ok;
result.get_string_representation = &setting_get_string_representation_default;
result.bind_type = 0;
result.browser_selection_type = ST_NONE;
result.step = 0.0f;
result.rounding_fraction = NULL;
result.enforce_minrange = false;
result.enforce_maxrange = false;
result.cmd_trigger.idx = CMD_EVENT_NONE;
result.cmd_trigger.triggered = false;
result.dont_use_enum_idx_representation = dont_use_enum_idx;
return result;
}
/**
* setting_group_setting:
* @type : type of settting.
* @name : name of setting.
*
* Initializes a setting of type ST_GROUP.
*
* Returns: setting of type ST_GROUP.
**/
static rarch_setting_t setting_group_setting(enum setting_type type, const char* name,
const char *parent_group)
{
rarch_setting_t result;
result.enum_idx = MSG_UNKNOWN;
result.type = type;
result.size = 0;
result.name = name;
result.name_hash = 0;
result.short_description = name;
result.group = NULL;
result.subgroup = NULL;
result.parent_group = parent_group;
result.values = NULL;
result.index = 0;
result.index_offset = 0;
result.min = 0.0;
result.max = 0.0;
result.flags = 0;
result.free_flags = 0;
result.change_handler = NULL;
result.read_handler = NULL;
result.action_start = NULL;
result.action_left = NULL;
result.action_right = NULL;
result.action_up = NULL;
result.action_down = NULL;
result.action_cancel = NULL;
result.action_ok = NULL;
result.action_select = NULL;
result.get_string_representation = &setting_get_string_representation_default;
result.bind_type = 0;
result.browser_selection_type = ST_NONE;
result.step = 0.0f;
result.rounding_fraction = NULL;
result.enforce_minrange = false;
result.enforce_maxrange = false;
result.cmd_trigger.idx = CMD_EVENT_NONE;
result.cmd_trigger.triggered = false;
result.dont_use_enum_idx_representation = false;
return result;
}
/**
* setting_float_setting:
* @name : name of setting.
* @short_description : Short description of setting.
* @target : Target of float setting.
* @default_value : Default value (in float).
* @rounding : Rounding (for float-to-string representation).
* @group : Group that the setting belongs to.
* @subgroup : Subgroup that the setting belongs to.
* @change_handler : Function callback for change handler function pointer.
* @read_handler : Function callback for read handler function pointer.
*
* Initializes a setting of type ST_FLOAT.
*
* Returns: setting of type ST_FLOAT.
**/
static rarch_setting_t setting_float_setting(const char* name,
const char* short_description, float* target, float default_value,
const char *rounding, const char *group, const char *subgroup,
const char *parent_group,
change_handler_t change_handler, change_handler_t read_handler,
bool dont_use_enum_idx)
{
rarch_setting_t result;
result.enum_idx = MSG_UNKNOWN;
result.type = ST_FLOAT;
result.size = sizeof(float);
result.name = name;
result.name_hash = 0;
result.short_description = short_description;
result.group = group;
result.subgroup = subgroup;
result.parent_group = parent_group;
result.values = NULL;
result.index = 0;
result.index_offset = 0;
result.min = 0.0;
result.max = 0.0;
result.flags = 0;
result.free_flags = 0;
result.change_handler = change_handler;
result.read_handler = read_handler;
result.action_start = setting_generic_action_start_default;
result.action_left = setting_fraction_action_left_default;
result.action_right = setting_fraction_action_right_default;
result.action_up = NULL;
result.action_down = NULL;
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_st_float;
result.bind_type = 0;
result.browser_selection_type = ST_NONE;
result.step = 0.0f;
result.rounding_fraction = rounding;
result.enforce_minrange = false;
result.enforce_maxrange = false;
result.value.target.fraction = target;
result.original_value.fraction = *target;
result.default_value.fraction = default_value;
result.cmd_trigger.idx = CMD_EVENT_NONE;
result.cmd_trigger.triggered = false;
result.dont_use_enum_idx_representation = dont_use_enum_idx;
return result;
}
/**
* setting_uint_setting:
* @name : name of setting.
* @short_description : Short description of setting.
* @target : Target of unsigned integer setting.
* @default_value : Default value (in unsigned integer format).
* @group : Group that the setting belongs to.
* @subgroup : Subgroup that the setting belongs to.
* @change_handler : Function callback for change handler function pointer.
* @read_handler : Function callback for read handler function pointer.
*
* Initializes a setting of type ST_UINT.
*
* Returns: setting of type ST_UINT.
**/
static rarch_setting_t setting_uint_setting(const char* name,
const char* short_description, unsigned int* target,
unsigned int default_value,
const char *group, const char *subgroup, const char *parent_group,
change_handler_t change_handler, change_handler_t read_handler,
bool dont_use_enum_idx)
{
rarch_setting_t result;
result.enum_idx = MSG_UNKNOWN;
result.type = ST_UINT;
result.size = sizeof(unsigned int);
result.name = name;
result.name_hash = 0;
result.short_description = short_description;
result.group = group;
result.subgroup = subgroup;
result.parent_group = parent_group;
result.values = NULL;
result.index = 0;
result.index_offset = 0;
result.min = 0.0;
result.max = 0.0;
result.flags = 0;
result.free_flags = 0;
result.change_handler = change_handler;
result.read_handler = read_handler;
result.action_start = setting_generic_action_start_default;
result.action_left = setting_uint_action_left_default;
result.action_right = setting_uint_action_right_default;
result.action_up = NULL;
result.action_down = NULL;
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_uint;
result.bind_type = 0;
result.browser_selection_type = ST_NONE;
result.step = 0.0f;
result.rounding_fraction = NULL;
result.enforce_minrange = false;
result.enforce_maxrange = false;
result.value.target.unsigned_integer = target;
result.original_value.unsigned_integer = *target;
result.default_value.unsigned_integer = default_value;
result.cmd_trigger.idx = CMD_EVENT_NONE;
result.cmd_trigger.triggered = false;
result.dont_use_enum_idx_representation = dont_use_enum_idx;
return result;
}
/**
* setting_hex_setting:
* @name : name of setting.
* @short_description : Short description of setting.
* @target : Target of unsigned integer setting.
* @default_value : Default value (in unsigned integer format).
* @group : Group that the setting belongs to.
* @subgroup : Subgroup that the setting belongs to.
* @change_handler : Function callback for change handler function pointer.
* @read_handler : Function callback for read handler function pointer.
*
* Initializes a setting of type ST_HEX.
*
* Returns: setting of type ST_HEX.
**/
static rarch_setting_t setting_hex_setting(const char* name,
const char* short_description, unsigned int* target,
unsigned int default_value,
const char *group, const char *subgroup, const char *parent_group,
change_handler_t change_handler, change_handler_t read_handler,
bool dont_use_enum_idx)
{
rarch_setting_t result;
result.enum_idx = MSG_UNKNOWN;
result.type = ST_HEX;
result.size = sizeof(unsigned int);
result.name = name;
result.name_hash = 0;
result.short_description = short_description;
result.group = group;
result.subgroup = subgroup;
result.parent_group = parent_group;
result.values = NULL;
result.index = 0;
result.index_offset = 0;
result.min = 0.0;
result.max = 0.0;
result.flags = 0;
result.free_flags = 0;
result.change_handler = change_handler;
result.read_handler = read_handler;
result.action_start = setting_generic_action_start_default;
result.action_left = NULL;
result.action_right = NULL;
result.action_up = NULL;
result.action_down = NULL;
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_hex;
result.bind_type = 0;
result.browser_selection_type = ST_NONE;
result.step = 0.0f;
result.rounding_fraction = NULL;
result.enforce_minrange = false;
result.enforce_maxrange = false;
result.value.target.unsigned_integer = target;
result.original_value.unsigned_integer = *target;
result.default_value.unsigned_integer = default_value;
result.cmd_trigger.idx = CMD_EVENT_NONE;
result.cmd_trigger.triggered = false;
result.dont_use_enum_idx_representation = dont_use_enum_idx;
return result;
}
/**
* setting_bind_setting:
* @name : name of setting.
* @short_description : Short description of setting.
* @target : Target of bind setting.
* @idx : Index of bind setting.
* @idx_offset : Index offset of bind setting.
* @default_value : Default value (in bind format).
* @group : Group that the setting belongs to.
* @subgroup : Subgroup that the setting belongs to.
*
* Initializes a setting of type ST_BIND.
*
* Returns: setting of type ST_BIND.
**/
static rarch_setting_t setting_bind_setting(const char* name,
const char* short_description, struct retro_keybind* target,
uint32_t idx, uint32_t idx_offset,
const struct retro_keybind* default_value,
const char *group, const char *subgroup,
const char *parent_group,
bool dont_use_enum_idx)
{
rarch_setting_t result;
result.enum_idx = MSG_UNKNOWN;
result.type = ST_BIND;
result.size = 0;
result.name = name;
result.name_hash = 0;
result.short_description = short_description;
result.group = group;
result.subgroup = subgroup;
result.parent_group = parent_group;
result.values = NULL;
result.index = idx;
result.index_offset = idx_offset;
result.min = 0.0;
result.max = 0.0;
result.flags = 0;
result.free_flags = 0;
result.change_handler = NULL;
result.read_handler = NULL;
#ifdef HAVE_MENU
result.action_start = setting_bind_action_start;
#else
result.action_start = NULL;
#endif
result.action_left = NULL;
result.action_right = NULL;
result.action_up = NULL;
result.action_down = NULL;
result.action_cancel = NULL;
result.action_ok = setting_bind_action_ok;
result.action_select = setting_bind_action_ok;
result.get_string_representation = &setting_get_string_representation_st_bind;
result.bind_type = 0;
result.browser_selection_type = ST_NONE;
result.step = 0.0f;
result.rounding_fraction = NULL;
result.enforce_minrange = false;
result.enforce_maxrange = false;
result.value.target.keybind = target;
result.default_value.keybind = default_value;
result.cmd_trigger.idx = CMD_EVENT_NONE;
result.cmd_trigger.triggered = false;
result.dont_use_enum_idx_representation = dont_use_enum_idx;
return result;
}
static int setting_int_action_left_default(void *data, bool wraparound)
{
double min = 0.0f;
rarch_setting_t *setting = (rarch_setting_t*)data;
if (!setting)
return -1;
min = setting->min;
(void)wraparound; /* TODO/FIXME - handle this */
if (*setting->value.target.integer != min)
*setting->value.target.integer =
*setting->value.target.integer - setting->step;
if (setting->enforce_minrange)
{
if (*setting->value.target.integer < min)
*setting->value.target.integer = min;
}
return 0;
}
static int setting_bool_action_ok_default(void *data, bool wraparound)
{
rarch_setting_t *setting = (rarch_setting_t*)data;
if (!setting)
return -1;
(void)wraparound; /* TODO/FIXME - handle this */
setting_set_with_string_representation(setting,
*setting->value.target.boolean ? "false" : "true");
return 0;
}
static int setting_bool_action_toggle_default(void *data, bool wraparound)
{
rarch_setting_t *setting = (rarch_setting_t*)data;
if (!setting)
return -1;
(void)wraparound; /* TODO/FIXME - handle this */
setting_set_with_string_representation(setting,
*setting->value.target.boolean ? "false" : "true");
return 0;
}
int setting_string_action_start_generic(void *data)
{
rarch_setting_t *setting = (rarch_setting_t*)data;
if (!setting)
return -1;
setting->value.target.string[0] = '\0';
return 0;
}
/**
* setting_string_setting:
* @type : type of setting.
* @name : name of setting.
* @short_description : Short description of setting.
* @target : Target of string setting.
* @size : Size of string setting.
* @default_value : Default value (in string format).
* @empty : TODO/FIXME: ???
* @group : Group that the setting belongs to.
* @subgroup : Subgroup that the setting belongs to.
* @change_handler : Function callback for change handler function pointer.
* @read_handler : Function callback for read handler function pointer.
*
* Initializes a string setting (of type @type).
*
* Returns: String setting of type @type.
**/
static rarch_setting_t setting_string_setting(enum setting_type type,
const char* name, const char* short_description, char* target,
unsigned size, const char* default_value, const char *empty,
const char *group, const char *subgroup, const char *parent_group,
change_handler_t change_handler,
change_handler_t read_handler,
bool dont_use_enum_idx)
{
rarch_setting_t result;
result.enum_idx = MSG_UNKNOWN;
result.type = type;
result.size = size;
result.name = name;
result.name_hash = 0;
result.short_description = short_description;
result.group = group;
result.subgroup = subgroup;
result.parent_group = parent_group;
result.values = NULL;
result.index = 0;
result.index_offset = 0;
result.min = 0.0;
result.max = 0.0;
result.flags = 0;
result.free_flags = 0;
result.change_handler = change_handler;
result.read_handler = read_handler;
result.action_start = NULL;
result.action_left = NULL;
result.action_right = NULL;
result.action_up = NULL;
result.action_down = NULL;
result.action_cancel = NULL;
result.action_ok = NULL;
result.action_select = NULL;
result.get_string_representation = &setting_get_string_representation_st_string;
result.bind_type = 0;
result.browser_selection_type = ST_NONE;
result.step = 0.0f;
result.rounding_fraction = NULL;
result.enforce_minrange = false;
result.enforce_maxrange = false;
result.dir.empty_path = empty;
result.value.target.string = target;
result.default_value.string = default_value;
result.cmd_trigger.idx = CMD_EVENT_NONE;
result.cmd_trigger.triggered = false;
switch (type)
{
case ST_DIR:
result.action_start = setting_string_action_start_generic;
result.browser_selection_type = ST_DIR;
result.get_string_representation = &setting_get_string_representation_st_dir;
break;
case ST_PATH:
result.action_start = setting_string_action_start_generic;
result.browser_selection_type = ST_PATH;
result.get_string_representation = &setting_get_string_representation_st_path;
break;
default:
break;
}
result.dont_use_enum_idx_representation = dont_use_enum_idx;
return result;
}
/**
* setting_string_setting_options:
* @type : type of settting.
* @name : name of setting.
* @short_description : Short description of setting.
* @target : Target of bind setting.
* @size : Size of string setting.
* @default_value : Default value.
* @empty : N/A.
* @values : Values, separated by a delimiter.
* @group : Group that the setting belongs to.
* @subgroup : Subgroup that the setting belongs to.
* @change_handler : Function callback for change handler function pointer.
* @read_handler : Function callback for read handler function pointer.
*
* Initializes a string options list setting.
*
* Returns: string option list setting.
**/
static rarch_setting_t setting_string_setting_options(enum setting_type type,
const char* name, const char* short_description, char* target,
unsigned size, const char* default_value,
const char *empty, const char *values,
const char *group, const char *subgroup, const char *parent_group,
change_handler_t change_handler, change_handler_t read_handler,
bool dont_use_enum_idx)
{
rarch_setting_t result = setting_string_setting(type, name,
short_description, target, size, default_value, empty, group,
subgroup, parent_group, change_handler, read_handler,
dont_use_enum_idx);
result.parent_group = parent_group;
result.values = values;
return result;
}
/**
* setting_subgroup_setting:
* @type : type of settting.
* @name : name of setting.
* @parent_name : group that the subgroup setting belongs to.
*
* Initializes a setting of type ST_SUBGROUP.
*
* Returns: setting of type ST_SUBGROUP.
**/
static rarch_setting_t setting_subgroup_setting(enum setting_type type,
const char* name, const char *parent_name, const char *parent_group,
bool dont_use_enum_idx)
{
rarch_setting_t result;
result.enum_idx = MSG_UNKNOWN;
result.type = type;
result.size = 0;
result.name = name;
result.name_hash = 0;
result.short_description = name;
result.group = parent_name;
result.parent_group = parent_group;
result.values = NULL;
result.subgroup = NULL;
result.index = 0;
result.index_offset = 0;
result.min = 0.0;
result.max = 0.0;
result.flags = 0;
result.free_flags = 0;
result.change_handler = NULL;
result.read_handler = NULL;
result.action_start = NULL;
result.action_left = NULL;
result.action_right = NULL;
result.action_up = NULL;
result.action_down = NULL;
result.action_cancel = NULL;
result.action_ok = NULL;
result.action_select = NULL;
result.get_string_representation = &setting_get_string_representation_default;
result.bind_type = 0;
result.browser_selection_type = ST_NONE;
result.step = 0.0f;
result.rounding_fraction = NULL;
result.enforce_minrange = false;
result.enforce_maxrange = false;
result.cmd_trigger.idx = CMD_EVENT_NONE;
result.cmd_trigger.triggered = false;
result.dont_use_enum_idx_representation = dont_use_enum_idx;
return result;
}
/**
* setting_bool_setting:
* @name : name of setting.
* @short_description : Short description of setting.
* @target : Target of bool setting.
* @default_value : Default value (in bool format).
* @off : String value for "Off" label.
* @on : String value for "On" label.
* @group : Group that the setting belongs to.
* @subgroup : Subgroup that the setting belongs to.
* @change_handler : Function callback for change handler function pointer.
* @read_handler : Function callback for read handler function pointer.
*
* Initializes a setting of type ST_BOOL.
*
* Returns: setting of type ST_BOOL.
**/
static rarch_setting_t setting_bool_setting(const char* name,
const char* short_description, bool* target, bool default_value,
const char *off, const char *on,
const char *group, const char *subgroup, const char *parent_group,
change_handler_t change_handler, change_handler_t read_handler,
bool dont_use_enum_idx)
{
rarch_setting_t result;
result.enum_idx = MSG_UNKNOWN;
result.type = ST_BOOL;
result.size = sizeof(bool);
result.name = name;
result.name_hash = name ? msg_hash_calculate(name) : 0;
result.short_description = short_description;
result.group = group;
result.subgroup = subgroup;
result.parent_group = parent_group;
result.values = NULL;
result.index = 0;
result.index_offset = 0;
result.min = 0.0;
result.max = 0.0;
result.flags = 0;
result.free_flags = 0;
result.change_handler = change_handler;
result.read_handler = read_handler;
result.action_start = setting_generic_action_start_default;
result.action_left = setting_bool_action_toggle_default;
result.action_right = setting_bool_action_toggle_default;
result.action_up = NULL;
result.action_down = NULL;
result.action_cancel = NULL;
result.action_ok = setting_bool_action_ok_default;
result.action_select = setting_generic_action_ok_default;
result.get_string_representation = &setting_get_string_representation_st_bool;
result.bind_type = 0;
result.browser_selection_type = ST_NONE;
result.step = 0.0f;
result.rounding_fraction = NULL;
result.enforce_minrange = false;
result.enforce_maxrange = false;
result.value.target.boolean = target;
result.original_value.boolean = *target;
result.default_value.boolean = default_value;
result.boolean.off_label = off;
result.boolean.on_label = on;
result.cmd_trigger.idx = CMD_EVENT_NONE;
result.cmd_trigger.triggered = false;
result.dont_use_enum_idx_representation = dont_use_enum_idx;
return result;
}
/**
* setting_int_setting:
* @name : name of setting.
* @short_description : Short description of setting.
* @target : Target of signed integer setting.
* @default_value : Default value (in signed integer format).
* @group : Group that the setting belongs to.
* @subgroup : Subgroup that the setting belongs to.
* @change_handler : Function callback for change handler function pointer.
* @read_handler : Function callback for read handler function pointer.
*
* Initializes a setting of type ST_INT.
*
* Returns: setting of type ST_INT.
**/
static rarch_setting_t setting_int_setting(const char* name,
const char* short_description, int* target,
int default_value,
const char *group, const char *subgroup, const char *parent_group,
change_handler_t change_handler, change_handler_t read_handler,
bool dont_use_enum_idx)
{
rarch_setting_t result;
result.enum_idx = MSG_UNKNOWN;
result.type = ST_INT;
result.size = sizeof(int);
result.name = name;
result.name_hash = name ? msg_hash_calculate(name) : 0;
result.short_description = short_description;
result.group = group;
result.subgroup = subgroup;
result.parent_group = parent_group;
result.values = NULL;
result.index = 0;
result.index_offset = 0;
result.min = 0.0;
result.max = 0.0;
result.flags = 0;
result.free_flags = 0;
result.change_handler = change_handler;
result.read_handler = read_handler;
result.action_start = setting_generic_action_start_default;
result.action_left = setting_int_action_left_default;
result.action_right = setting_int_action_right_default;
result.action_up = NULL;
result.action_down = NULL;
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_int;
result.bind_type = 0;
result.browser_selection_type = ST_NONE;
result.step = 0.0f;
result.rounding_fraction = NULL;
result.enforce_minrange = false;
result.enforce_maxrange = false;
result.value.target.integer = target;
result.original_value.integer = *target;
result.default_value.integer = default_value;
result.cmd_trigger.idx = CMD_EVENT_NONE;
result.cmd_trigger.triggered = false;
result.dont_use_enum_idx_representation = dont_use_enum_idx;
return result;
}
bool CONFIG_BOOL_ALT(
rarch_setting_t **list,
rarch_setting_info_t *list_info,
bool *target,
const char *name, const char *SHORT,
bool default_value,
enum msg_hash_enums off_enum_idx,
enum msg_hash_enums on_enum_idx,
rarch_setting_group_info_t *group_info,
rarch_setting_group_info_t *subgroup_info,
const char *parent_group,
change_handler_t change_handler,
change_handler_t read_handler,
uint32_t flags)
{
rarch_setting_t value = setting_bool_setting(name, SHORT, target,
default_value,
msg_hash_to_str(off_enum_idx), msg_hash_to_str(on_enum_idx),
group_info->name, subgroup_info->name, parent_group,
change_handler, read_handler, true);
if (!settings_list_append(list, list_info))
return false;
if (value.name)
value.name_hash = msg_hash_calculate(value.name);
(*list)[list_info->index++] = value;
if (flags != SD_FLAG_NONE)
settings_data_list_current_add_flags(list, list_info, flags);
return true;
}
bool CONFIG_BOOL(
rarch_setting_t **list,
rarch_setting_info_t *list_info,
bool *target,
enum msg_hash_enums name_enum_idx,
enum msg_hash_enums SHORT_enum_idx,
bool default_value,
enum msg_hash_enums off_enum_idx,
enum msg_hash_enums on_enum_idx,
rarch_setting_group_info_t *group_info,
rarch_setting_group_info_t *subgroup_info,
const char *parent_group,
change_handler_t change_handler,
change_handler_t read_handler,
uint32_t flags)
{
rarch_setting_t value = setting_bool_setting(
msg_hash_to_str(name_enum_idx),
msg_hash_to_str(SHORT_enum_idx),
target,
default_value,
msg_hash_to_str(off_enum_idx),
msg_hash_to_str(on_enum_idx),
group_info->name, subgroup_info->name, parent_group,
change_handler, read_handler, false);
if (!settings_list_append(list, list_info))
return false;
if (value.name)
value.name_hash = msg_hash_calculate(value.name);
(*list)[list_info->index++] = value;
if (flags != SD_FLAG_NONE)
settings_data_list_current_add_flags(list, list_info, flags);
#ifdef HAVE_MENU
menu_settings_list_current_add_enum_idx(list, list_info, name_enum_idx);
menu_settings_list_current_add_enum_value_idx(list, list_info, SHORT_enum_idx);
#endif
return true;
}
bool CONFIG_INT(
rarch_setting_t **list,
rarch_setting_info_t *list_info,
int *target,
enum msg_hash_enums name_enum_idx,
enum msg_hash_enums SHORT_enum_idx,
int default_value,
rarch_setting_group_info_t *group_info,
rarch_setting_group_info_t *subgroup_info,
const char *parent_group,
change_handler_t change_handler, change_handler_t read_handler)
{
rarch_setting_t value = setting_int_setting(
msg_hash_to_str(name_enum_idx),
msg_hash_to_str(SHORT_enum_idx),
target, default_value,
group_info->name, subgroup_info->name, parent_group,
change_handler, read_handler,
false);
if (!(settings_list_append(list, list_info)))
return false;
if (value.name)
value.name_hash = msg_hash_calculate(value.name);
(*list)[list_info->index++] = value;
#ifdef HAVE_MENU
menu_settings_list_current_add_enum_idx(list, list_info, name_enum_idx);
menu_settings_list_current_add_enum_value_idx(list, list_info, SHORT_enum_idx);
#endif
return true;
}
bool CONFIG_UINT_ALT(
rarch_setting_t **list,
rarch_setting_info_t *list_info,
unsigned int *target,
const char *name, const char *SHORT,
unsigned int default_value,
rarch_setting_group_info_t *group_info,
rarch_setting_group_info_t *subgroup_info,
const char *parent_group,
change_handler_t change_handler, change_handler_t read_handler)
{
rarch_setting_t value = setting_uint_setting(name, SHORT, target, default_value,
group_info->name,
subgroup_info->name, parent_group, change_handler, read_handler,
true);
if (!(settings_list_append(list, list_info)))
return false;
if (value.name)
value.name_hash = msg_hash_calculate(value.name);
(*list)[list_info->index++] = value;
return true;
}
bool CONFIG_UINT(
rarch_setting_t **list,
rarch_setting_info_t *list_info,
unsigned int *target,
enum msg_hash_enums name_enum_idx,
enum msg_hash_enums SHORT_enum_idx,
unsigned int default_value,
rarch_setting_group_info_t *group_info,
rarch_setting_group_info_t *subgroup_info,
const char *parent_group,
change_handler_t change_handler, change_handler_t read_handler)
{
rarch_setting_t value = setting_uint_setting (
msg_hash_to_str(name_enum_idx),
msg_hash_to_str(SHORT_enum_idx),
target, default_value,
group_info->name,
subgroup_info->name, parent_group,
change_handler, read_handler,
false);
if (!(settings_list_append(list, list_info)))
return false;
if (value.name)
value.name_hash = msg_hash_calculate(value.name);
(*list)[list_info->index++] = value;
#ifdef HAVE_MENU
menu_settings_list_current_add_enum_idx(list, list_info, name_enum_idx);
menu_settings_list_current_add_enum_value_idx(list, list_info, SHORT_enum_idx);
#endif
return true;
}
bool CONFIG_FLOAT(
rarch_setting_t **list,
rarch_setting_info_t *list_info,
float *target,
enum msg_hash_enums name_enum_idx,
enum msg_hash_enums SHORT_enum_idx,
float default_value, const char *rounding,
rarch_setting_group_info_t *group_info,
rarch_setting_group_info_t *subgroup_info,
const char *parent_group,
change_handler_t change_handler, change_handler_t read_handler)
{
rarch_setting_t value = setting_float_setting(msg_hash_to_str(name_enum_idx),
msg_hash_to_str(SHORT_enum_idx), target, default_value, rounding,
group_info->name, subgroup_info->name, parent_group, change_handler, read_handler,
false);
if (!(settings_list_append(list, list_info)))
return false;
if (value.name)
value.name_hash = msg_hash_calculate(value.name);
(*list)[list_info->index++] = value;
#ifdef HAVE_MENU
menu_settings_list_current_add_enum_idx(list, list_info, name_enum_idx);
menu_settings_list_current_add_enum_value_idx(list, list_info, SHORT_enum_idx);
#endif
return true;
}
bool CONFIG_PATH(
rarch_setting_t **list,
rarch_setting_info_t *list_info,
char *target, size_t len,
enum msg_hash_enums name_enum_idx,
enum msg_hash_enums SHORT_enum_idx,
const char *default_value,
rarch_setting_group_info_t *group_info,
rarch_setting_group_info_t *subgroup_info,
const char *parent_group,
change_handler_t change_handler, change_handler_t read_handler)
{
rarch_setting_t value = setting_string_setting(ST_PATH,
msg_hash_to_str(name_enum_idx),
msg_hash_to_str(SHORT_enum_idx),
target, (unsigned)len, default_value, "",
group_info->name, subgroup_info->name, parent_group,
change_handler, read_handler,
false);
if (!(settings_list_append(list, list_info)))
return false;
if (value.name)
value.name_hash = msg_hash_calculate(value.name);
(*list)[list_info->index++] = value;
settings_data_list_current_add_flags(list, list_info, SD_FLAG_ALLOW_EMPTY);
#ifdef HAVE_MENU
menu_settings_list_current_add_enum_idx(list, list_info, name_enum_idx);
menu_settings_list_current_add_enum_value_idx(list, list_info, SHORT_enum_idx);
#endif
return true;
}
bool CONFIG_DIR(
rarch_setting_t **list,
rarch_setting_info_t *list_info,
char *target, size_t len,
enum msg_hash_enums name_enum_idx,
enum msg_hash_enums SHORT_enum_idx,
const char *default_value,
enum msg_hash_enums empty_enum_idx,
rarch_setting_group_info_t *group_info,
rarch_setting_group_info_t *subgroup_info,
const char *parent_group,
change_handler_t change_handler, change_handler_t read_handler)
{
rarch_setting_t value = setting_string_setting(ST_DIR,
msg_hash_to_str(name_enum_idx),
msg_hash_to_str(SHORT_enum_idx),
target, (unsigned)len, default_value,
msg_hash_to_str(empty_enum_idx),
group_info->name, subgroup_info->name, parent_group,
change_handler, read_handler,
false);
if (!(settings_list_append(list, list_info)))
return false;
if (value.name)
value.name_hash = msg_hash_calculate(value.name);
(*list)[list_info->index++] = value;
settings_data_list_current_add_flags(
list,
list_info,
SD_FLAG_ALLOW_EMPTY | SD_FLAG_PATH_DIR | SD_FLAG_BROWSER_ACTION);
#ifdef HAVE_MENU
menu_settings_list_current_add_enum_idx(list, list_info, name_enum_idx);
menu_settings_list_current_add_enum_value_idx(list, list_info, SHORT_enum_idx);
#endif
return true;
}
bool CONFIG_STRING(
rarch_setting_t **list,
rarch_setting_info_t *list_info,
char *target, size_t len,
enum msg_hash_enums name_enum_idx,
enum msg_hash_enums SHORT_enum_idx,
const char *default_value,
rarch_setting_group_info_t *group_info,
rarch_setting_group_info_t *subgroup_info,
const char *parent_group,
change_handler_t change_handler, change_handler_t read_handler)
{
rarch_setting_t value = setting_string_setting(ST_STRING,
msg_hash_to_str(name_enum_idx),
msg_hash_to_str(SHORT_enum_idx),
target, (unsigned)len, default_value, "",
group_info->name, subgroup_info->name, parent_group,
change_handler, read_handler, false);
if (!(settings_list_append(list, list_info)))
return false;
if (value.name)
value.name_hash = msg_hash_calculate(value.name);
(*list)[list_info->index++] = value;
#ifdef HAVE_MENU
menu_settings_list_current_add_enum_idx(list, list_info, name_enum_idx);
menu_settings_list_current_add_enum_value_idx(list, list_info, SHORT_enum_idx);
#endif
return true;
}
bool CONFIG_STRING_OPTIONS(
rarch_setting_t **list,
rarch_setting_info_t *list_info,
char *target, size_t len,
enum msg_hash_enums name_enum_idx,
enum msg_hash_enums SHORT_enum_idx,
const char *default_value, const char *values,
rarch_setting_group_info_t *group_info,
rarch_setting_group_info_t *subgroup_info,
const char *parent_group,
change_handler_t change_handler, change_handler_t read_handler)
{
rarch_setting_t value = setting_string_setting_options(ST_STRING_OPTIONS,
msg_hash_to_str(name_enum_idx),
msg_hash_to_str(SHORT_enum_idx),
target, (unsigned)len, default_value, "", values,
group_info->name, subgroup_info->name, parent_group,
change_handler, read_handler, false);
if (!(settings_list_append(list, list_info)))
return false;
if (value.name)
value.name_hash = msg_hash_calculate(value.name);
(*list)[list_info->index++] = value;
#ifdef HAVE_MENU
menu_settings_list_current_add_enum_idx(list, list_info, name_enum_idx);
menu_settings_list_current_add_enum_value_idx(list, list_info, SHORT_enum_idx);
#endif
/* Request values to be freed later */
settings_data_list_current_add_free_flags(list, list_info, SD_FREE_FLAG_VALUES);
return true;
}
bool CONFIG_HEX(
rarch_setting_t **list,
rarch_setting_info_t *list_info,
unsigned int *target,
enum msg_hash_enums name_enum_idx,
enum msg_hash_enums SHORT_enum_idx,
unsigned int default_value,
rarch_setting_group_info_t *group_info,
rarch_setting_group_info_t *subgroup_info,
const char *parent_group,
change_handler_t change_handler, change_handler_t read_handler)
{
rarch_setting_t value = setting_hex_setting(
msg_hash_to_str(name_enum_idx),
msg_hash_to_str(SHORT_enum_idx),
target, default_value,
group_info->name, subgroup_info->name, parent_group,
change_handler, read_handler, false);
if (!(settings_list_append(list, list_info)))
return false;
if (value.name)
value.name_hash = msg_hash_calculate(value.name);
(*list)[list_info->index++] = value;
#ifdef HAVE_MENU
menu_settings_list_current_add_enum_idx(list, list_info, name_enum_idx);
menu_settings_list_current_add_enum_value_idx(list, list_info, SHORT_enum_idx);
#endif
return true;
}
/* Please strdup() NAME and SHORT */
bool CONFIG_BIND(
rarch_setting_t **list,
rarch_setting_info_t *list_info,
struct retro_keybind *target,
uint32_t player, uint32_t player_offset,
const char *name, const char *SHORT,
const struct retro_keybind *default_value,
rarch_setting_group_info_t *group_info,
rarch_setting_group_info_t *subgroup_info,
const char *parent_group)
{
rarch_setting_t value = setting_bind_setting(name, SHORT, target,
player, player_offset, default_value,
group_info->name, subgroup_info->name, parent_group,
false);
if (!(settings_list_append(list, list_info)))
return false;
if (value.name)
value.name_hash = msg_hash_calculate(value.name);
(*list)[list_info->index++] = value;
/* Request name and short description to be freed later */
settings_data_list_current_add_free_flags(list, list_info, SD_FREE_FLAG_NAME | SD_FREE_FLAG_SHORT);
return true;
}
bool CONFIG_BIND_ALT(
rarch_setting_t **list,
rarch_setting_info_t *list_info,
struct retro_keybind *target,
uint32_t player, uint32_t player_offset,
const char *name, const char *SHORT,
const struct retro_keybind *default_value,
rarch_setting_group_info_t *group_info,
rarch_setting_group_info_t *subgroup_info,
const char *parent_group)
{
rarch_setting_t value = setting_bind_setting(name, SHORT, target,
player, player_offset, default_value,
group_info->name, subgroup_info->name, parent_group,
true);
if (!(settings_list_append(list, list_info)))
return false;
if (value.name)
value.name_hash = msg_hash_calculate(value.name);
(*list)[list_info->index++] = value;
/* Request name and short description to be freed later */
settings_data_list_current_add_free_flags(list, list_info, SD_FREE_FLAG_NAME | SD_FREE_FLAG_SHORT);
return true;
}
bool CONFIG_ACTION_ALT(
rarch_setting_t **list,
rarch_setting_info_t *list_info,
const char *name, const char *SHORT,
rarch_setting_group_info_t *group_info,
rarch_setting_group_info_t *subgroup_info,
const char *parent_group)
{
rarch_setting_t value = setting_action_setting(name, SHORT,
group_info->name, subgroup_info->name, parent_group,
true);
if (!settings_list_append(list, list_info))
return false;
if (value.name)
value.name_hash = msg_hash_calculate(value.name);
(*list)[list_info->index++] = value;
return true;
}
bool CONFIG_ACTION(
rarch_setting_t **list,
rarch_setting_info_t *list_info,
enum msg_hash_enums name_enum_idx,
enum msg_hash_enums SHORT_enum_idx,
rarch_setting_group_info_t *group_info,
rarch_setting_group_info_t *subgroup_info,
const char *parent_group)
{
rarch_setting_t value = setting_action_setting(
msg_hash_to_str(name_enum_idx),
msg_hash_to_str(SHORT_enum_idx),
group_info->name,
subgroup_info->name, parent_group,
false);
if (!settings_list_append(list, list_info))
return false;
if (value.name)
value.name_hash = msg_hash_calculate(value.name);
(*list)[list_info->index++] = value;
#ifdef HAVE_MENU
menu_settings_list_current_add_enum_idx(list, list_info, name_enum_idx);
menu_settings_list_current_add_enum_value_idx(list, list_info, SHORT_enum_idx);
#endif
return true;
}
bool START_GROUP(rarch_setting_t **list, rarch_setting_info_t *list_info,
rarch_setting_group_info_t *group_info,
const char *name, const char *parent_group)
{
rarch_setting_t value = setting_group_setting (ST_GROUP, name, parent_group);
group_info->name = name;
if (!(settings_list_append(list, list_info)))
return false;
if (value.name)
value.name_hash = msg_hash_calculate(value.name);
(*list)[list_info->index++] = value;
return true;
}
bool END_GROUP(rarch_setting_t **list, rarch_setting_info_t *list_info,
const char *parent_group)
{
rarch_setting_t value = setting_group_setting (ST_END_GROUP, 0, parent_group);
if (!(settings_list_append(list, list_info)))
return false;
if (value.name)
value.name_hash = msg_hash_calculate(value.name);
(*list)[list_info->index++] = value;
return true;
}
bool START_SUB_GROUP(rarch_setting_t **list,
rarch_setting_info_t *list_info, const char *name,
rarch_setting_group_info_t *group_info,
rarch_setting_group_info_t *subgroup_info,
const char *parent_group)
{
rarch_setting_t value = setting_subgroup_setting (ST_SUB_GROUP,
name, group_info->name, parent_group, false);
subgroup_info->name = name;
if (!(settings_list_append(list, list_info)))
return false;
if (value.name)
value.name_hash = msg_hash_calculate(value.name);
(*list)[list_info->index++] = value;
return true;
}
bool END_SUB_GROUP(
rarch_setting_t **list,
rarch_setting_info_t *list_info,
const char *parent_group)
{
rarch_setting_t value = setting_group_setting (ST_END_SUB_GROUP, 0, parent_group);
if (!(settings_list_append(list, list_info)))
return false;
if (value.name)
value.name_hash = msg_hash_calculate(value.name);
(*list)[list_info->index++] = value;
return true;
}
#ifdef HAVE_MENU
static void menu_input_st_string_cb(void *userdata, const char *str)
{
if (str && *str)
{
rarch_setting_t *setting = NULL;
const char *label = menu_input_dialog_get_label_setting_buffer();
if (!string_is_empty(label))
setting = menu_setting_find(label);
if (setting)
{
setting_set_with_string_representation(setting, str);
menu_setting_generic(setting, false);
}
}
menu_input_dialog_end();
}
static void menu_input_st_uint_cb(void *userdata, const char *str)
{
if (str && *str)
{
const char *label = menu_input_dialog_get_label_setting_buffer();
rarch_setting_t *setting = menu_setting_find(label);
setting_set_with_string_representation(setting, str);
}
menu_input_dialog_end();
}
static void menu_input_st_hex_cb(void *userdata, const char *str)
{
if (str && *str)
{
const char *label = menu_input_dialog_get_label_setting_buffer();
rarch_setting_t *setting = menu_setting_find(label);
if (setting)
{
unsigned *ptr = (unsigned*)setting_get_ptr(setting);
if (str[0] == '#')
str++;
if (ptr)
*ptr = (unsigned)strtoul(str, NULL, 16);
}
}
menu_input_dialog_end();
}
static int setting_generic_action_ok_linefeed(void *data, bool wraparound)
{
menu_input_ctx_line_t line;
input_keyboard_line_complete_t cb = NULL;
rarch_setting_t *setting = (rarch_setting_t*)data;
if (!setting)
return -1;
(void)wraparound;
switch (setting_get_type(setting))
{
case ST_UINT:
cb = menu_input_st_uint_cb;
break;
case ST_HEX:
cb = menu_input_st_hex_cb;
break;
case ST_STRING:
case ST_STRING_OPTIONS:
cb = menu_input_st_string_cb;
break;
default:
break;
}
line.label = setting->short_description;
line.label_setting = setting->name;
line.type = 0;
line.idx = 0;
line.cb = cb;
if (!menu_input_dialog_start(&line))
return -1;
return 0;
}
#endif
static void setting_add_special_callbacks(
rarch_setting_t **list,
rarch_setting_info_t *list_info,
unsigned values)
{
unsigned idx = list_info->index - 1;
if (values & SD_FLAG_ALLOW_INPUT)
{
#ifdef HAVE_MENU
(*list)[idx].action_ok = setting_generic_action_ok_linefeed;
(*list)[idx].action_select = setting_generic_action_ok_linefeed;
#else
(*list)[idx].action_ok = NULL;
(*list)[idx].action_select = NULL;
#endif
switch ((*list)[idx].type)
{
case ST_UINT:
(*list)[idx].action_cancel = NULL;
break;
case ST_HEX:
(*list)[idx].action_cancel = NULL;
break;
case ST_STRING:
(*list)[idx].action_start = setting_string_action_start_generic;
(*list)[idx].action_cancel = NULL;
break;
default:
break;
}
}
}
void settings_data_list_current_add_flags(
rarch_setting_t **list,
rarch_setting_info_t *list_info,
unsigned values)
{
(*list)[list_info->index - 1].flags |= values;
setting_add_special_callbacks(list, list_info, values);
}
void settings_data_list_current_add_free_flags(
rarch_setting_t **list,
rarch_setting_info_t *list_info,
unsigned values)
{
(*list)[list_info->index - 1].free_flags |= values;
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化