mirror of
https://github.com/libretro/RetroArch
synced 2025-03-01 07:13:35 +00:00
Sync with main repo
This commit is contained in:
commit
c1266c7966
@ -23,6 +23,8 @@
|
||||
|
||||
id<RetroArch_Platform> apple_platform;
|
||||
|
||||
void apple_rarch_exited(void);
|
||||
|
||||
void apple_rarch_exited(void)
|
||||
{
|
||||
[apple_platform unloadingCore];
|
||||
|
@ -284,15 +284,20 @@ static struct rxml_node *rxml_parse_node(const char **ptr_)
|
||||
/* Parse all child nodes. */
|
||||
struct rxml_node *list = NULL;
|
||||
struct rxml_node *tail = NULL;
|
||||
const char *first_start = NULL, *first_closing = NULL;
|
||||
|
||||
const char *ptr = child_start;
|
||||
|
||||
const char *first_start = strchr(ptr, '<');
|
||||
const char *first_closing = strstr(ptr, "</");
|
||||
while (first_start &&
|
||||
first_closing && first_start < first_closing)
|
||||
ptr = child_start;
|
||||
first_start = strchr(ptr, '<');
|
||||
first_closing = strstr(ptr, "</");
|
||||
|
||||
while (
|
||||
first_start &&
|
||||
first_closing &&
|
||||
(first_start < first_closing)
|
||||
)
|
||||
{
|
||||
struct rxml_node *new_node = rxml_parse_node(&ptr);
|
||||
|
||||
if (!new_node)
|
||||
{
|
||||
free(closing_tag);
|
||||
|
3
deps/7zip/7zCrcOpt.c
vendored
3
deps/7zip/7zCrcOpt.c
vendored
@ -7,6 +7,9 @@
|
||||
|
||||
#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
|
||||
|
||||
UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table);
|
||||
UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table);
|
||||
|
||||
UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table)
|
||||
{
|
||||
const Byte *p = (const Byte *)data;
|
||||
|
3
deps/7zip/7zIn.c
vendored
3
deps/7zip/7zIn.c
vendored
@ -14,6 +14,9 @@ Byte k7zSignature[k7zSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C};
|
||||
#define NUM_FOLDER_CODERS_MAX 32
|
||||
#define NUM_CODER_STREAMS_MAX 32
|
||||
|
||||
void SzFolder_Free(CSzFolder *p, ISzAlloc *alloc);
|
||||
int SzFolder_FindBindPairForOutStream(CSzFolder *p, UInt32 outStreamIndex);
|
||||
|
||||
void SzCoderInfo_Init(CSzCoderInfo *p)
|
||||
{
|
||||
Buf_Init(&p->Props);
|
||||
|
4
deps/7zip/CpuArch.c
vendored
4
deps/7zip/CpuArch.c
vendored
@ -1,6 +1,8 @@
|
||||
#include "CpuArch.h"
|
||||
|
||||
Bool CPU_Is_InOrder()
|
||||
Bool CPU_Is_InOrder(void);
|
||||
|
||||
Bool CPU_Is_InOrder(void)
|
||||
{
|
||||
return False;
|
||||
}
|
||||
|
2
deps/7zip/LzmaDec.c
vendored
2
deps/7zip/LzmaDec.c
vendored
@ -682,6 +682,8 @@ static void LzmaDec_InitRc(CLzmaDec *p, const Byte *data)
|
||||
p->needFlush = 0;
|
||||
}
|
||||
|
||||
void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState);
|
||||
|
||||
void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState)
|
||||
{
|
||||
p->needFlush = 1;
|
||||
|
4
deps/rzlib/deflate.c
vendored
4
deps/rzlib/deflate.c
vendored
@ -193,6 +193,10 @@ local const config configuration_table[10] = {
|
||||
s->head[s->hash_size-1] = NIL; \
|
||||
zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head));
|
||||
|
||||
int ZEXPORT deflateResetKeep (z_streamp strm);
|
||||
|
||||
int ZEXPORT deflatePending (z_streamp strm, unsigned *pending, int *bits);
|
||||
|
||||
/* ========================================================================= */
|
||||
int ZEXPORT deflateInit_(z_streamp strm, int level, const char *version, int stream_size)
|
||||
{
|
||||
|
2
deps/rzlib/gzread.c
vendored
2
deps/rzlib/gzread.c
vendored
@ -13,6 +13,8 @@ local int gz_decomp OF((gz_statep));
|
||||
local int gz_fetch OF((gz_statep));
|
||||
local int gz_skip OF((gz_statep, z_off64_t));
|
||||
|
||||
int ZEXPORT gzgetc_(gzFile file);
|
||||
|
||||
/* Use read() to load a buffer -- return -1 on error, otherwise 0. Read from
|
||||
state->fd, and update state->eof, state->err, and state->msg as appropriate.
|
||||
This function needs to loop on read(), since read() is not guaranteed to
|
||||
|
2
deps/rzlib/gzwrite.c
vendored
2
deps/rzlib/gzwrite.c
vendored
@ -10,6 +10,8 @@ local int gz_init OF((gz_statep));
|
||||
local int gz_comp OF((gz_statep, int));
|
||||
local int gz_zero OF((gz_statep, z_off64_t));
|
||||
|
||||
int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va);
|
||||
|
||||
/* Initialize state for writing a gzip file. Mark initialization by setting
|
||||
state->size to non-zero. Return -1 on failure or 0 on success. */
|
||||
local int gz_init(gz_statep state)
|
||||
|
4
deps/rzlib/inflate.c
vendored
4
deps/rzlib/inflate.c
vendored
@ -105,6 +105,10 @@ local int updatewindow OF((z_streamp strm, const unsigned char FAR *end,
|
||||
local unsigned syncsearch OF((unsigned FAR *have, const unsigned char FAR *buf,
|
||||
unsigned len));
|
||||
|
||||
int ZEXPORT inflateResetKeep(z_streamp strm);
|
||||
|
||||
int ZEXPORT inflateGetDictionary(z_streamp strm, Bytef *dictionary, uInt *dictLength);
|
||||
|
||||
int ZEXPORT inflateResetKeep(z_streamp strm)
|
||||
{
|
||||
struct inflate_state FAR *state;
|
||||
|
2
driver.c
2
driver.c
@ -19,7 +19,7 @@
|
||||
#include "general.h"
|
||||
#include "file.h"
|
||||
#include "libretro.h"
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include "compat/posix_string.h"
|
||||
|
14
driver.h
14
driver.h
@ -443,13 +443,13 @@ enum rarch_display_type
|
||||
/* Flags for init_drivers/uninit_drivers */
|
||||
enum
|
||||
{
|
||||
DRIVER_AUDIO = 1 << 0,
|
||||
DRIVER_VIDEO = 1 << 1,
|
||||
DRIVER_INPUT = 1 << 2,
|
||||
DRIVER_OSK = 1 << 3,
|
||||
DRIVER_CAMERA = 1 << 4,
|
||||
DRIVER_LOCATION = 1 << 5,
|
||||
DRIVER_MENU = 1 << 6,
|
||||
DRIVER_AUDIO = 1 << 0,
|
||||
DRIVER_VIDEO = 1 << 1,
|
||||
DRIVER_INPUT = 1 << 2,
|
||||
DRIVER_OSK = 1 << 3,
|
||||
DRIVER_CAMERA = 1 << 4,
|
||||
DRIVER_LOCATION = 1 << 5,
|
||||
DRIVER_MENU = 1 << 6,
|
||||
DRIVERS_VIDEO_INPUT = 1 << 7 /* note multiple drivers */
|
||||
};
|
||||
|
||||
|
@ -692,11 +692,11 @@ bool rarch_environment_cb(unsigned cmd, void *data)
|
||||
{
|
||||
for (id = 0; id < RARCH_FIRST_CUSTOM_BIND; id++)
|
||||
{
|
||||
const char *desc = g_extern.system.input_desc_btn[p][id];
|
||||
if (desc)
|
||||
const char *description = g_extern.system.input_desc_btn[p][id];
|
||||
if (description)
|
||||
{
|
||||
RARCH_LOG("\tRetroPad, Player %u, Button \"%s\" => \"%s\"\n",
|
||||
p + 1, libretro_btn_desc[id], desc);
|
||||
p + 1, libretro_btn_desc[id], description);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -14,15 +14,6 @@
|
||||
*/
|
||||
|
||||
#include "fifo_buffer.h"
|
||||
#include <stdint.h>
|
||||
|
||||
struct fifo_buffer
|
||||
{
|
||||
uint8_t *buffer;
|
||||
size_t bufsize;
|
||||
size_t first;
|
||||
size_t end;
|
||||
};
|
||||
|
||||
fifo_buffer_t *fifo_new(size_t size)
|
||||
{
|
||||
|
@ -17,13 +17,21 @@
|
||||
#define __FIFO_BUFFER_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct fifo_buffer
|
||||
{
|
||||
uint8_t *buffer;
|
||||
size_t bufsize;
|
||||
size_t first;
|
||||
size_t end;
|
||||
};
|
||||
|
||||
typedef struct fifo_buffer fifo_buffer_t;
|
||||
|
||||
fifo_buffer_t *fifo_new(size_t size);
|
||||
|
8
file.c
8
file.c
@ -402,12 +402,12 @@ static bool load_content(const struct retro_subsystem_info *special,
|
||||
}
|
||||
|
||||
char new_path[PATH_MAX];
|
||||
union string_list_elem_attr attr;
|
||||
attr.i = 0;
|
||||
union string_list_elem_attr attributes;
|
||||
attributes.i = 0;
|
||||
fill_pathname_join(new_path,g_settings.extraction_directory,
|
||||
path_basename(path),sizeof(new_path));
|
||||
read_compressed_file(path,NULL,new_path);
|
||||
string_list_append(additional_path_allocs,new_path,attr);
|
||||
string_list_append(additional_path_allocs,new_path, attributes);
|
||||
info[i].path =
|
||||
additional_path_allocs->elems
|
||||
[additional_path_allocs->size -1 ].data;
|
||||
@ -418,7 +418,7 @@ static bool load_content(const struct retro_subsystem_info *special,
|
||||
*/
|
||||
rarch_assert(g_extern.temporary_content != NULL);
|
||||
string_list_append(g_extern.temporary_content,
|
||||
new_path, attr);
|
||||
new_path, attributes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -205,6 +205,11 @@ void *file_list_get_actiondata_at_offset(const file_list_t *list, size_t index)
|
||||
return list->list[index].actiondata;
|
||||
}
|
||||
|
||||
void *file_list_get_last_actiondata(const file_list_t *list)
|
||||
{
|
||||
return list->list[list->size - 1].actiondata;
|
||||
}
|
||||
|
||||
void file_list_get_at_offset(const file_list_t *list, size_t index,
|
||||
const char **path, const char **label, unsigned *file_type)
|
||||
{
|
||||
|
@ -60,6 +60,8 @@ void file_list_get_last(const file_list_t *list,
|
||||
const char **path, const char **label,
|
||||
unsigned *type);
|
||||
|
||||
void *file_list_get_last_actiondata(const file_list_t *list);
|
||||
|
||||
size_t file_list_get_size(const file_list_t *list);
|
||||
size_t file_list_get_directory_ptr(const file_list_t *list);
|
||||
|
||||
|
@ -7,6 +7,8 @@ extern "C" {
|
||||
|
||||
typedef struct menu_file_list_cbs
|
||||
{
|
||||
int (*action_deferred_push)(void *data, void *userdata, const char
|
||||
*path, const char *label, unsigned type);
|
||||
int (*action_ok)(const char *path, const char *label, unsigned type,
|
||||
size_t index);
|
||||
int (*action_start)(unsigned type, const char *label, unsigned action);
|
||||
|
@ -359,27 +359,7 @@ static int menu_lakka_iterate(unsigned action)
|
||||
rarch_setting_t *setting = (rarch_setting_t*)
|
||||
active_subitem->setting;
|
||||
|
||||
switch (action)
|
||||
{
|
||||
case MENU_ACTION_OK:
|
||||
if (setting->cmd_trigger.idx != RARCH_CMD_NONE)
|
||||
setting->cmd_trigger.triggered = true;
|
||||
/* fall-through */
|
||||
case MENU_ACTION_LEFT:
|
||||
case MENU_ACTION_RIGHT:
|
||||
case MENU_ACTION_START:
|
||||
if (setting->type == ST_BOOL)
|
||||
menu_action_setting_boolean(setting, action);
|
||||
else if (setting->type == ST_UINT)
|
||||
menu_action_setting_unsigned_integer(setting, 0, action);
|
||||
else if (setting->type == ST_FLOAT)
|
||||
menu_action_setting_fraction(setting, action);
|
||||
else if (setting->type == ST_STRING)
|
||||
menu_action_setting_driver(setting, action);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
menu_action_handle_setting(setting, 0, action);
|
||||
}
|
||||
|
||||
switch (action)
|
||||
|
@ -89,7 +89,7 @@ static char *str_replace (const char *string,
|
||||
|
||||
static void lakka_draw_text(lakka_handle_t *lakka,
|
||||
const char *str, float x,
|
||||
float y, float scale, float alpha)
|
||||
float y, float scale_factor, float alpha)
|
||||
{
|
||||
if (alpha > lakka->global_alpha)
|
||||
alpha = lakka->global_alpha;
|
||||
@ -116,7 +116,7 @@ static void lakka_draw_text(lakka_handle_t *lakka,
|
||||
params.x = x / gl->win_width;
|
||||
params.y = 1.0f - y / gl->win_height;
|
||||
|
||||
params.scale = scale;
|
||||
params.scale = scale_factor;
|
||||
params.color = FONT_COLOR_RGBA(255, 255, 255, a8);
|
||||
params.full_screen = true;
|
||||
|
||||
@ -196,9 +196,12 @@ static void lakka_draw_background(bool force_transparency)
|
||||
|
||||
static void lakka_draw_icon(lakka_handle_t *lakka,
|
||||
GLuint texture, float x, float y,
|
||||
float alpha, float rotation, float scale)
|
||||
float alpha, float rotation,
|
||||
float scale_factor)
|
||||
{
|
||||
struct gl_coords coords;
|
||||
math_matrix mymat, mrot;
|
||||
|
||||
if (!lakka)
|
||||
return;
|
||||
|
||||
@ -236,14 +239,11 @@ static void lakka_draw_icon(lakka_handle_t *lakka,
|
||||
coords.color = color;
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
|
||||
math_matrix mymat;
|
||||
|
||||
math_matrix mrot;
|
||||
matrix_rotate_z(&mrot, rotation);
|
||||
matrix_multiply(&mymat, &mrot, &gl->mvp_no_rot);
|
||||
|
||||
math_matrix mscal;
|
||||
matrix_scale(&mscal, scale, scale, 1);
|
||||
matrix_scale(&mscal, scale_factor, scale_factor, 1);
|
||||
matrix_multiply(&mymat, &mscal, &mymat);
|
||||
|
||||
gl->shader->set_coords(&coords);
|
||||
|
@ -59,6 +59,9 @@ enum
|
||||
XMB_TEXTURE_LOADSTATE,
|
||||
XMB_TEXTURE_SCREENSHOT,
|
||||
XMB_TEXTURE_RELOAD,
|
||||
XMB_TEXTURE_FILE,
|
||||
XMB_TEXTURE_FOLDER,
|
||||
XMB_TEXTURE_ZIP,
|
||||
XMB_TEXTURE_LAST
|
||||
};
|
||||
|
||||
@ -118,9 +121,10 @@ static const GLfloat rmb_tex_coord[] = {
|
||||
};
|
||||
|
||||
static void xmb_draw_icon(GLuint texture, float x, float y,
|
||||
float alpha, float rotation, float scale)
|
||||
float alpha, float rotation, float scale_factor)
|
||||
{
|
||||
struct gl_coords coords;
|
||||
math_matrix mymat, mrot, mscal;
|
||||
xmb_handle_t *xmb = (xmb_handle_t*)driver.menu->userdata;
|
||||
|
||||
if (!xmb)
|
||||
@ -160,14 +164,10 @@ static void xmb_draw_icon(GLuint texture, float x, float y,
|
||||
coords.color = color;
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
|
||||
math_matrix mymat;
|
||||
|
||||
math_matrix mrot;
|
||||
matrix_rotate_z(&mrot, rotation);
|
||||
matrix_multiply(&mymat, &mrot, &gl->mvp_no_rot);
|
||||
|
||||
math_matrix mscal;
|
||||
matrix_scale(&mscal, scale, scale, 1);
|
||||
matrix_scale(&mscal, scale_factor, scale_factor, 1);
|
||||
matrix_multiply(&mymat, &mscal, &mymat);
|
||||
|
||||
gl->shader->set_coords(&coords);
|
||||
@ -180,7 +180,7 @@ static void xmb_draw_icon(GLuint texture, float x, float y,
|
||||
}
|
||||
|
||||
static void xmb_draw_text(const char *str, float x,
|
||||
float y, float scale, float alpha)
|
||||
float y, float scale_factor, float alpha)
|
||||
{
|
||||
uint8_t a8 = 0;
|
||||
struct font_params params = {0};
|
||||
@ -209,7 +209,7 @@ static void xmb_draw_text(const char *str, float x,
|
||||
params.x = x / gl->win_width;
|
||||
params.y = 1.0f - y / gl->win_height;
|
||||
|
||||
params.scale = scale;
|
||||
params.scale = scale_factor;
|
||||
params.color = FONT_COLOR_RGBA(255, 255, 255, a8);
|
||||
params.full_screen = true;
|
||||
|
||||
@ -472,7 +472,24 @@ static void xmb_frame(void)
|
||||
entry_label, path,
|
||||
path_buf, sizeof(path_buf));
|
||||
|
||||
xmb_draw_icon(xmb->textures[XMB_TEXTURE_SETTING].id,
|
||||
GLuint icon = 0;
|
||||
switch(type)
|
||||
{
|
||||
case MENU_FILE_DIRECTORY:
|
||||
icon = xmb->textures[XMB_TEXTURE_FOLDER].id;
|
||||
break;
|
||||
case MENU_FILE_PLAIN:
|
||||
icon = xmb->textures[XMB_TEXTURE_FILE].id;
|
||||
break;
|
||||
case MENU_FILE_CARCHIVE:
|
||||
icon = xmb->textures[XMB_TEXTURE_ZIP].id;
|
||||
break;
|
||||
default:
|
||||
icon = xmb->textures[XMB_TEXTURE_SETTING].id;
|
||||
break;
|
||||
}
|
||||
|
||||
xmb_draw_icon(icon,
|
||||
xmb->x + xmb->margin_left + xmb->hspacing - xmb->icon_size/2.0,
|
||||
xmb->margin_top + node->y + xmb->icon_size/2.0,
|
||||
node->alpha,
|
||||
@ -766,6 +783,12 @@ static void xmb_context_reset(void *data)
|
||||
"screenshot.png", sizeof(xmb->textures[XMB_TEXTURE_SCREENSHOT].path));
|
||||
fill_pathname_join(xmb->textures[XMB_TEXTURE_RELOAD].path, iconpath,
|
||||
"reload.png", sizeof(xmb->textures[XMB_TEXTURE_RELOAD].path));
|
||||
fill_pathname_join(xmb->textures[XMB_TEXTURE_FILE].path, iconpath,
|
||||
"file.png", sizeof(xmb->textures[XMB_TEXTURE_RELOAD].path));
|
||||
fill_pathname_join(xmb->textures[XMB_TEXTURE_FOLDER].path, iconpath,
|
||||
"folder.png", sizeof(xmb->textures[XMB_TEXTURE_RELOAD].path));
|
||||
fill_pathname_join(xmb->textures[XMB_TEXTURE_ZIP].path, iconpath,
|
||||
"zip.png", sizeof(xmb->textures[XMB_TEXTURE_RELOAD].path));
|
||||
|
||||
for (k = 0; k < XMB_TEXTURE_LAST; k++)
|
||||
xmb->textures[k].id = xmb_png_texture_load(xmb->textures[k].path);
|
||||
|
@ -20,9 +20,12 @@
|
||||
#include "menu_entries.h"
|
||||
#include "menu_shader.h"
|
||||
|
||||
|
||||
int menu_action_setting_apply(rarch_setting_t *setting)
|
||||
int menu_action_setting_boolean(
|
||||
rarch_setting_t *setting, unsigned action)
|
||||
{
|
||||
if (setting->action_ok)
|
||||
setting->action_ok(setting, action);
|
||||
|
||||
if (setting->change_handler)
|
||||
setting->change_handler(setting);
|
||||
|
||||
@ -36,207 +39,42 @@ int menu_action_setting_apply(rarch_setting_t *setting)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int menu_action_setting_boolean(
|
||||
int menu_action_setting_unsigned_integer(
|
||||
rarch_setting_t *setting, unsigned action)
|
||||
{
|
||||
if (
|
||||
!strcmp(setting->name, "savestate") ||
|
||||
!strcmp(setting->name, "loadstate"))
|
||||
{
|
||||
switch (action)
|
||||
{
|
||||
case MENU_ACTION_START:
|
||||
g_settings.state_slot = 0;
|
||||
break;
|
||||
case MENU_ACTION_LEFT:
|
||||
// Slot -1 is (auto) slot.
|
||||
if (g_settings.state_slot >= 0)
|
||||
g_settings.state_slot--;
|
||||
break;
|
||||
case MENU_ACTION_RIGHT:
|
||||
g_settings.state_slot++;
|
||||
break;
|
||||
case MENU_ACTION_OK:
|
||||
*setting->value.boolean = !(*setting->value.boolean);
|
||||
if (setting->action_ok)
|
||||
setting->action_ok(setting, action);
|
||||
|
||||
if (setting->cmd_trigger.idx != RARCH_CMD_NONE)
|
||||
setting->cmd_trigger.triggered = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
if (setting->change_handler)
|
||||
setting->change_handler(setting);
|
||||
|
||||
if (setting->flags & SD_FLAG_EXIT
|
||||
&& setting->cmd_trigger.triggered)
|
||||
{
|
||||
switch (action)
|
||||
{
|
||||
case MENU_ACTION_OK:
|
||||
if (setting->cmd_trigger.idx != RARCH_CMD_NONE)
|
||||
setting->cmd_trigger.triggered = true;
|
||||
/* fall-through */
|
||||
case MENU_ACTION_LEFT:
|
||||
case MENU_ACTION_RIGHT:
|
||||
*setting->value.boolean = !(*setting->value.boolean);
|
||||
break;
|
||||
case MENU_ACTION_START:
|
||||
*setting->value.boolean = setting->default_value.boolean;
|
||||
break;
|
||||
}
|
||||
setting->cmd_trigger.triggered = false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return menu_action_setting_apply(setting);
|
||||
}
|
||||
|
||||
int menu_action_setting_unsigned_integer(
|
||||
rarch_setting_t *setting, unsigned id, unsigned action)
|
||||
{
|
||||
if (id == MENU_FILE_LINEFEED)
|
||||
{
|
||||
if (action == MENU_ACTION_OK)
|
||||
menu_key_start_line(driver.menu, setting->short_description,
|
||||
setting->name, st_uint_callback);
|
||||
else if (action == MENU_ACTION_START)
|
||||
*setting->value.unsigned_integer =
|
||||
setting->default_value.unsigned_integer;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (action)
|
||||
{
|
||||
case MENU_ACTION_LEFT:
|
||||
if (*setting->value.unsigned_integer != setting->min)
|
||||
*setting->value.unsigned_integer =
|
||||
*setting->value.unsigned_integer - setting->step;
|
||||
|
||||
if (setting->enforce_minrange)
|
||||
{
|
||||
if (*setting->value.unsigned_integer < setting->min)
|
||||
*setting->value.unsigned_integer = setting->min;
|
||||
}
|
||||
break;
|
||||
|
||||
case MENU_ACTION_OK:
|
||||
if (setting->cmd_trigger.idx != RARCH_CMD_NONE)
|
||||
setting->cmd_trigger.triggered = true;
|
||||
/* fall-through */
|
||||
case MENU_ACTION_RIGHT:
|
||||
*setting->value.unsigned_integer =
|
||||
*setting->value.unsigned_integer + setting->step;
|
||||
|
||||
if (setting->enforce_maxrange)
|
||||
{
|
||||
if (*setting->value.unsigned_integer > setting->max)
|
||||
*setting->value.unsigned_integer = setting->max;
|
||||
}
|
||||
break;
|
||||
|
||||
case MENU_ACTION_START:
|
||||
*setting->value.unsigned_integer =
|
||||
setting->default_value.unsigned_integer;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return menu_action_setting_apply(setting);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int menu_action_setting_fraction(
|
||||
rarch_setting_t *setting, unsigned action)
|
||||
{
|
||||
if (!strcmp(setting->name, "video_refresh_rate_auto"))
|
||||
if (setting->action_ok)
|
||||
setting->action_ok(setting, action);
|
||||
|
||||
if (setting->change_handler)
|
||||
setting->change_handler(setting);
|
||||
|
||||
if (setting->flags & SD_FLAG_EXIT
|
||||
&& setting->cmd_trigger.triggered)
|
||||
{
|
||||
switch (action)
|
||||
{
|
||||
case MENU_ACTION_START:
|
||||
g_extern.measure_data.frame_time_samples_count = 0;
|
||||
break;
|
||||
case MENU_ACTION_OK:
|
||||
{
|
||||
double refresh_rate, deviation = 0.0;
|
||||
unsigned sample_points = 0;
|
||||
|
||||
if (driver_monitor_fps_statistics(&refresh_rate,
|
||||
&deviation, &sample_points))
|
||||
{
|
||||
driver_set_monitor_refresh_rate(refresh_rate);
|
||||
/* Incase refresh rate update forced non-block video. */
|
||||
rarch_main_command(RARCH_CMD_VIDEO_SET_BLOCKING_STATE);
|
||||
}
|
||||
|
||||
if (setting->cmd_trigger.idx != RARCH_CMD_NONE)
|
||||
setting->cmd_trigger.triggered = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (action)
|
||||
{
|
||||
case MENU_ACTION_LEFT:
|
||||
*setting->value.fraction =
|
||||
*setting->value.fraction - setting->step;
|
||||
|
||||
if (setting->enforce_minrange)
|
||||
{
|
||||
if (*setting->value.fraction < setting->min)
|
||||
*setting->value.fraction = setting->min;
|
||||
}
|
||||
break;
|
||||
|
||||
case MENU_ACTION_OK:
|
||||
if (setting->cmd_trigger.idx != RARCH_CMD_NONE)
|
||||
setting->cmd_trigger.triggered = true;
|
||||
/* fall-through */
|
||||
case MENU_ACTION_RIGHT:
|
||||
*setting->value.fraction =
|
||||
*setting->value.fraction + setting->step;
|
||||
|
||||
if (setting->enforce_maxrange)
|
||||
{
|
||||
if (*setting->value.fraction > setting->max)
|
||||
*setting->value.fraction = setting->max;
|
||||
}
|
||||
break;
|
||||
|
||||
case MENU_ACTION_START:
|
||||
*setting->value.fraction = setting->default_value.fraction;
|
||||
break;
|
||||
}
|
||||
setting->cmd_trigger.triggered = false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return menu_action_setting_apply(setting);
|
||||
}
|
||||
|
||||
void menu_action_setting_driver(
|
||||
rarch_setting_t *setting, unsigned action)
|
||||
{
|
||||
if (!strcmp(setting->name, "audio_resampler_driver"))
|
||||
{
|
||||
switch (action)
|
||||
{
|
||||
case MENU_ACTION_LEFT:
|
||||
find_prev_resampler_driver();
|
||||
break;
|
||||
case MENU_ACTION_RIGHT:
|
||||
find_next_resampler_driver();
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (setting->flags & SD_FLAG_IS_DRIVER)
|
||||
{
|
||||
const char *label = setting->name;
|
||||
char *drv = (char*)setting->value.string;
|
||||
size_t sizeof_driver = setting->size;
|
||||
|
||||
switch (action)
|
||||
{
|
||||
case MENU_ACTION_LEFT:
|
||||
find_prev_driver(label, drv, sizeof_driver);
|
||||
break;
|
||||
case MENU_ACTION_RIGHT:
|
||||
find_next_driver(label, drv, sizeof_driver);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int menu_action_setting_set_current_string(
|
||||
@ -244,7 +82,17 @@ int menu_action_setting_set_current_string(
|
||||
{
|
||||
strlcpy(setting->value.string, str, setting->size);
|
||||
|
||||
return menu_action_setting_apply(setting);
|
||||
if (setting->change_handler)
|
||||
setting->change_handler(setting);
|
||||
|
||||
if (setting->flags & SD_FLAG_EXIT
|
||||
&& setting->cmd_trigger.triggered)
|
||||
{
|
||||
setting->cmd_trigger.triggered = false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int menu_action_set_current_string_based_on_label(
|
||||
@ -261,149 +109,99 @@ int menu_action_setting_set_current_string_path(
|
||||
{
|
||||
fill_pathname_join(setting->value.string, dir, path, setting->size);
|
||||
|
||||
return menu_action_setting_apply(setting);
|
||||
if (setting->change_handler)
|
||||
setting->change_handler(setting);
|
||||
|
||||
if (setting->flags & SD_FLAG_EXIT
|
||||
&& setting->cmd_trigger.triggered)
|
||||
{
|
||||
setting->cmd_trigger.triggered = false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int menu_entries_set_current_path_selection(
|
||||
rarch_setting_t *setting, const char *start_path,
|
||||
const char *label, unsigned type,
|
||||
unsigned action)
|
||||
{
|
||||
switch (action)
|
||||
{
|
||||
case MENU_ACTION_OK:
|
||||
menu_entries_push(driver.menu->menu_stack,
|
||||
start_path, label, type,
|
||||
driver.menu->selection_ptr);
|
||||
|
||||
if (setting->cmd_trigger.idx != RARCH_CMD_NONE)
|
||||
setting->cmd_trigger.triggered = true;
|
||||
break;
|
||||
case MENU_ACTION_START:
|
||||
*setting->value.string = '\0';
|
||||
break;
|
||||
}
|
||||
|
||||
if (setting->change_handler)
|
||||
setting->change_handler(setting);
|
||||
|
||||
if (setting->flags & SD_FLAG_EXIT
|
||||
&& setting->cmd_trigger.triggered)
|
||||
{
|
||||
setting->cmd_trigger.triggered = false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int menu_action_handle_setting(rarch_setting_t *setting,
|
||||
unsigned id, const char *label, unsigned action)
|
||||
unsigned type, unsigned action)
|
||||
{
|
||||
if (!setting)
|
||||
return -1;
|
||||
|
||||
if (setting->type == ST_BOOL)
|
||||
return menu_action_setting_boolean(setting, action);
|
||||
if (setting->type == ST_UINT)
|
||||
return menu_action_setting_unsigned_integer(setting, id, action);
|
||||
return menu_action_setting_unsigned_integer(setting, action);
|
||||
if (setting->type == ST_FLOAT)
|
||||
return menu_action_setting_fraction(setting, action);
|
||||
if (setting->type == ST_PATH)
|
||||
return menu_entries_set_current_path_selection(setting,
|
||||
setting->default_value.string, setting->name, id, action);
|
||||
setting->default_value.string, setting->name, type, action);
|
||||
|
||||
if (setting->type == ST_DIR)
|
||||
{
|
||||
if (action == MENU_ACTION_START)
|
||||
{
|
||||
*setting->value.string = '\0';
|
||||
return menu_action_setting_apply(setting);
|
||||
|
||||
if (setting->change_handler)
|
||||
setting->change_handler(setting);
|
||||
|
||||
if (setting->flags & SD_FLAG_EXIT
|
||||
&& setting->cmd_trigger.triggered)
|
||||
{
|
||||
setting->cmd_trigger.triggered = false;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (setting->type == ST_STRING)
|
||||
{
|
||||
if (
|
||||
(setting->flags & SD_FLAG_ALLOW_INPUT) ||
|
||||
id == MENU_FILE_LINEFEED_SWITCH)
|
||||
{
|
||||
switch (action)
|
||||
{
|
||||
case MENU_ACTION_OK:
|
||||
menu_key_start_line(driver.menu, setting->short_description,
|
||||
setting->name, st_string_callback);
|
||||
break;
|
||||
case MENU_ACTION_START:
|
||||
*setting->value.string = '\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
menu_action_setting_driver(setting, action);
|
||||
if (setting->action_toggle)
|
||||
return setting->action_toggle(setting, action);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef GEKKO
|
||||
enum
|
||||
{
|
||||
GX_RESOLUTIONS_512_192 = 0,
|
||||
GX_RESOLUTIONS_598_200,
|
||||
GX_RESOLUTIONS_640_200,
|
||||
GX_RESOLUTIONS_384_224,
|
||||
GX_RESOLUTIONS_448_224,
|
||||
GX_RESOLUTIONS_480_224,
|
||||
GX_RESOLUTIONS_512_224,
|
||||
GX_RESOLUTIONS_576_224,
|
||||
GX_RESOLUTIONS_608_224,
|
||||
GX_RESOLUTIONS_640_224,
|
||||
GX_RESOLUTIONS_340_232,
|
||||
GX_RESOLUTIONS_512_232,
|
||||
GX_RESOLUTIONS_512_236,
|
||||
GX_RESOLUTIONS_336_240,
|
||||
GX_RESOLUTIONS_352_240,
|
||||
GX_RESOLUTIONS_384_240,
|
||||
GX_RESOLUTIONS_512_240,
|
||||
GX_RESOLUTIONS_530_240,
|
||||
GX_RESOLUTIONS_640_240,
|
||||
GX_RESOLUTIONS_512_384,
|
||||
GX_RESOLUTIONS_598_400,
|
||||
GX_RESOLUTIONS_640_400,
|
||||
GX_RESOLUTIONS_384_448,
|
||||
GX_RESOLUTIONS_448_448,
|
||||
GX_RESOLUTIONS_480_448,
|
||||
GX_RESOLUTIONS_512_448,
|
||||
GX_RESOLUTIONS_576_448,
|
||||
GX_RESOLUTIONS_608_448,
|
||||
GX_RESOLUTIONS_640_448,
|
||||
GX_RESOLUTIONS_340_464,
|
||||
GX_RESOLUTIONS_512_464,
|
||||
GX_RESOLUTIONS_512_472,
|
||||
GX_RESOLUTIONS_352_480,
|
||||
GX_RESOLUTIONS_384_480,
|
||||
GX_RESOLUTIONS_512_480,
|
||||
GX_RESOLUTIONS_530_480,
|
||||
GX_RESOLUTIONS_608_480,
|
||||
GX_RESOLUTIONS_640_480,
|
||||
GX_RESOLUTIONS_LAST,
|
||||
};
|
||||
|
||||
unsigned menu_gx_resolutions[GX_RESOLUTIONS_LAST][2] = {
|
||||
{ 512, 192 },
|
||||
{ 598, 200 },
|
||||
{ 640, 200 },
|
||||
{ 384, 224 },
|
||||
{ 448, 224 },
|
||||
{ 480, 224 },
|
||||
{ 512, 224 },
|
||||
{ 576, 224 },
|
||||
{ 608, 224 },
|
||||
{ 640, 224 },
|
||||
{ 340, 232 },
|
||||
{ 512, 232 },
|
||||
{ 512, 236 },
|
||||
{ 336, 240 },
|
||||
{ 352, 240 },
|
||||
{ 384, 240 },
|
||||
{ 512, 240 },
|
||||
{ 530, 240 },
|
||||
{ 640, 240 },
|
||||
{ 512, 384 },
|
||||
{ 598, 400 },
|
||||
{ 640, 400 },
|
||||
{ 384, 448 },
|
||||
{ 448, 448 },
|
||||
{ 480, 448 },
|
||||
{ 512, 448 },
|
||||
{ 576, 448 },
|
||||
{ 608, 448 },
|
||||
{ 640, 448 },
|
||||
{ 340, 464 },
|
||||
{ 512, 464 },
|
||||
{ 512, 472 },
|
||||
{ 352, 480 },
|
||||
{ 384, 480 },
|
||||
{ 512, 480 },
|
||||
{ 530, 480 },
|
||||
{ 608, 480 },
|
||||
{ 640, 480 },
|
||||
};
|
||||
|
||||
unsigned menu_current_gx_resolution = GX_RESOLUTIONS_640_480;
|
||||
#endif
|
||||
|
||||
int menu_action_setting_set(unsigned id, const char *label,
|
||||
int menu_action_setting_set(unsigned type, const char *label,
|
||||
unsigned action)
|
||||
{
|
||||
unsigned port = driver.menu->current_pad;
|
||||
const file_list_t *list = (const file_list_t*)driver.menu->selection_buf;
|
||||
|
||||
/* Check if setting belongs to settings menu. */
|
||||
@ -412,7 +210,7 @@ int menu_action_setting_set(unsigned id, const char *label,
|
||||
driver.menu->list_settings, list->list[driver.menu->selection_ptr].label);
|
||||
|
||||
if (setting)
|
||||
return menu_action_handle_setting(setting, id, label, action);
|
||||
return menu_action_handle_setting(setting, type, action);
|
||||
|
||||
/* Check if setting belongs to main menu. */
|
||||
|
||||
@ -420,217 +218,7 @@ int menu_action_setting_set(unsigned id, const char *label,
|
||||
driver.menu->list_mainmenu, list->list[driver.menu->selection_ptr].label);
|
||||
|
||||
if (setting)
|
||||
return menu_action_handle_setting(setting, id, label, action);
|
||||
|
||||
/* Fallback. */
|
||||
|
||||
if (!strcmp(label, "input_bind_device_id"))
|
||||
{
|
||||
int *p = (int*)&g_settings.input.joypad_map[port];
|
||||
|
||||
switch (action)
|
||||
{
|
||||
case MENU_ACTION_START:
|
||||
*p = port;
|
||||
break;
|
||||
case MENU_ACTION_LEFT:
|
||||
(*p)--;
|
||||
break;
|
||||
case MENU_ACTION_RIGHT:
|
||||
(*p)++;
|
||||
break;
|
||||
}
|
||||
|
||||
if (*p < -1)
|
||||
*p = -1;
|
||||
else if (*p >= MAX_PLAYERS)
|
||||
*p = MAX_PLAYERS - 1;
|
||||
}
|
||||
else if (!strcmp(label, "input_bind_device_type"))
|
||||
{
|
||||
unsigned current_device, current_index, i, devices[128];
|
||||
const struct retro_controller_info *desc;
|
||||
unsigned types = 0;
|
||||
|
||||
devices[types++] = RETRO_DEVICE_NONE;
|
||||
devices[types++] = RETRO_DEVICE_JOYPAD;
|
||||
|
||||
/* Only push RETRO_DEVICE_ANALOG as default if we use an
|
||||
* older core which doesn't use SET_CONTROLLER_INFO. */
|
||||
if (!g_extern.system.num_ports)
|
||||
devices[types++] = RETRO_DEVICE_ANALOG;
|
||||
|
||||
desc = port < g_extern.system.num_ports ?
|
||||
&g_extern.system.ports[port] : NULL;
|
||||
if (desc)
|
||||
{
|
||||
for (i = 0; i < desc->num_types; i++)
|
||||
{
|
||||
unsigned id = desc->types[i].id;
|
||||
if (types < ARRAY_SIZE(devices) &&
|
||||
id != RETRO_DEVICE_NONE &&
|
||||
id != RETRO_DEVICE_JOYPAD)
|
||||
devices[types++] = id;
|
||||
}
|
||||
}
|
||||
|
||||
current_device = g_settings.input.libretro_device[port];
|
||||
current_index = 0;
|
||||
for (i = 0; i < types; i++)
|
||||
{
|
||||
if (current_device == devices[i])
|
||||
{
|
||||
current_index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (action)
|
||||
{
|
||||
case MENU_ACTION_START:
|
||||
current_device = RETRO_DEVICE_JOYPAD;
|
||||
|
||||
g_settings.input.libretro_device[port] = current_device;
|
||||
pretro_set_controller_port_device(port, current_device);
|
||||
break;
|
||||
|
||||
case MENU_ACTION_LEFT:
|
||||
current_device = devices
|
||||
[(current_index + types - 1) % types];
|
||||
|
||||
g_settings.input.libretro_device[port] = current_device;
|
||||
pretro_set_controller_port_device(port, current_device);
|
||||
break;
|
||||
|
||||
case MENU_ACTION_RIGHT:
|
||||
case MENU_ACTION_OK:
|
||||
current_device = devices
|
||||
[(current_index + 1) % types];
|
||||
|
||||
g_settings.input.libretro_device[port] = current_device;
|
||||
pretro_set_controller_port_device(port, current_device);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (!strcmp(label, "input_bind_player_no"))
|
||||
{
|
||||
switch (action)
|
||||
{
|
||||
case MENU_ACTION_START:
|
||||
driver.menu->current_pad = 0;
|
||||
break;
|
||||
case MENU_ACTION_LEFT:
|
||||
if (driver.menu->current_pad != 0)
|
||||
driver.menu->current_pad--;
|
||||
break;
|
||||
case MENU_ACTION_RIGHT:
|
||||
if (driver.menu->current_pad < MAX_PLAYERS - 1)
|
||||
driver.menu->current_pad++;
|
||||
break;
|
||||
}
|
||||
|
||||
if (port != driver.menu->current_pad)
|
||||
driver.menu->need_refresh = true;
|
||||
port = driver.menu->current_pad;
|
||||
}
|
||||
else if (!strcmp(label, "input_bind_analog_dpad_mode"))
|
||||
{
|
||||
switch (action)
|
||||
{
|
||||
case MENU_ACTION_START:
|
||||
g_settings.input.analog_dpad_mode[port] = 0;
|
||||
break;
|
||||
|
||||
case MENU_ACTION_OK:
|
||||
case MENU_ACTION_RIGHT:
|
||||
g_settings.input.analog_dpad_mode[port] =
|
||||
(g_settings.input.analog_dpad_mode[port] + 1)
|
||||
% ANALOG_DPAD_LAST;
|
||||
break;
|
||||
|
||||
case MENU_ACTION_LEFT:
|
||||
g_settings.input.analog_dpad_mode[port] =
|
||||
(g_settings.input.analog_dpad_mode
|
||||
[port] + ANALOG_DPAD_LAST - 1) % ANALOG_DPAD_LAST;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
#if defined(GEKKO)
|
||||
case MENU_SETTINGS_VIDEO_RESOLUTION:
|
||||
switch (action)
|
||||
{
|
||||
case MENU_ACTION_LEFT:
|
||||
if (menu_current_gx_resolution > 0)
|
||||
menu_current_gx_resolution--;
|
||||
break;
|
||||
case MENU_ACTION_RIGHT:
|
||||
if (menu_current_gx_resolution < GX_RESOLUTIONS_LAST - 1)
|
||||
{
|
||||
#ifdef HW_RVL
|
||||
if ((menu_current_gx_resolution + 1) > GX_RESOLUTIONS_640_480)
|
||||
if (CONF_GetVideo() != CONF_VIDEO_PAL)
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
menu_current_gx_resolution++;
|
||||
}
|
||||
break;
|
||||
case MENU_ACTION_OK:
|
||||
if (driver.video_data)
|
||||
gx_set_video_mode(driver.video_data, menu_gx_resolutions
|
||||
[menu_current_gx_resolution][0],
|
||||
menu_gx_resolutions[menu_current_gx_resolution][1]);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
#elif defined(__CELLOS_LV2__)
|
||||
case MENU_SETTINGS_VIDEO_RESOLUTION:
|
||||
switch (action)
|
||||
{
|
||||
case MENU_ACTION_LEFT:
|
||||
if (g_extern.console.screen.resolutions.current.idx)
|
||||
{
|
||||
g_extern.console.screen.resolutions.current.idx--;
|
||||
g_extern.console.screen.resolutions.current.id =
|
||||
g_extern.console.screen.resolutions.list
|
||||
[g_extern.console.screen.resolutions.current.idx];
|
||||
}
|
||||
break;
|
||||
case MENU_ACTION_RIGHT:
|
||||
if (g_extern.console.screen.resolutions.current.idx + 1 <
|
||||
g_extern.console.screen.resolutions.count)
|
||||
{
|
||||
g_extern.console.screen.resolutions.current.idx++;
|
||||
g_extern.console.screen.resolutions.current.id =
|
||||
g_extern.console.screen.resolutions.list
|
||||
[g_extern.console.screen.resolutions.current.idx];
|
||||
}
|
||||
break;
|
||||
case MENU_ACTION_OK:
|
||||
if (g_extern.console.screen.resolutions.list[
|
||||
g_extern.console.screen.resolutions.current.idx] ==
|
||||
CELL_VIDEO_OUT_RESOLUTION_576)
|
||||
{
|
||||
if (g_extern.console.screen.pal_enable)
|
||||
g_extern.console.screen.pal60_enable = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_extern.console.screen.pal_enable = false;
|
||||
g_extern.console.screen.pal60_enable = false;
|
||||
}
|
||||
|
||||
rarch_main_command(RARCH_CMD_REINIT);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
return menu_action_handle_setting(setting, type, action);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -23,8 +23,6 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int menu_action_setting_apply(rarch_setting_t *setting);
|
||||
|
||||
int menu_action_setting_boolean(
|
||||
rarch_setting_t *setting, unsigned action);
|
||||
|
||||
@ -32,9 +30,6 @@ int menu_action_setting_fraction(
|
||||
rarch_setting_t *setting, unsigned action);
|
||||
|
||||
int menu_action_setting_unsigned_integer(
|
||||
rarch_setting_t *setting, unsigned id, unsigned action);
|
||||
|
||||
void menu_action_setting_driver(
|
||||
rarch_setting_t *setting, unsigned action);
|
||||
|
||||
int menu_action_set_current_string_based_on_label(
|
||||
@ -46,11 +41,11 @@ int menu_action_setting_set_current_string(
|
||||
int menu_action_setting_set_current_string_path(
|
||||
rarch_setting_t *setting, const char *dir, const char *path);
|
||||
|
||||
int menu_action_setting_set(unsigned id, const char *label,
|
||||
int menu_action_setting_set(unsigned type, const char *label,
|
||||
unsigned action);
|
||||
|
||||
int menu_action_handle_setting(rarch_setting_t *setting,
|
||||
unsigned id, const char *label, unsigned action);
|
||||
unsigned type, unsigned action);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -17,10 +17,9 @@
|
||||
#include "menu_entries.h"
|
||||
#include "menu_action.h"
|
||||
#include "../../settings_data.h"
|
||||
#include "../../file_ext.h"
|
||||
#include "../../performance.h"
|
||||
|
||||
static void entries_refresh(file_list_t *list)
|
||||
void entries_refresh(file_list_t *list)
|
||||
{
|
||||
/* Before a refresh, we could have deleted a file on disk, causing
|
||||
* selection_ptr to suddendly be out of range.
|
||||
@ -75,28 +74,28 @@ static inline int menu_list_get_first_char(file_list_t *buf,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void menu_build_scroll_indices(file_list_t *buf)
|
||||
void menu_build_scroll_indices(file_list_t *list)
|
||||
{
|
||||
size_t i;
|
||||
int current;
|
||||
bool current_is_dir;
|
||||
|
||||
if (!driver.menu || !buf)
|
||||
if (!driver.menu || !list)
|
||||
return;
|
||||
|
||||
driver.menu->scroll_indices_size = 0;
|
||||
if (!buf->size)
|
||||
if (!list->size)
|
||||
return;
|
||||
|
||||
driver.menu->scroll_indices[driver.menu->scroll_indices_size++] = 0;
|
||||
|
||||
current = menu_list_get_first_char(buf, 0);
|
||||
current_is_dir = menu_list_elem_is_dir(buf, 0);
|
||||
current = menu_list_get_first_char(list, 0);
|
||||
current_is_dir = menu_list_elem_is_dir(list, 0);
|
||||
|
||||
for (i = 1; i < buf->size; i++)
|
||||
for (i = 1; i < list->size; i++)
|
||||
{
|
||||
int first = menu_list_get_first_char(buf, i);
|
||||
bool is_dir = menu_list_elem_is_dir(buf, i);
|
||||
int first = menu_list_get_first_char(list, i);
|
||||
bool is_dir = menu_list_elem_is_dir(list, i);
|
||||
|
||||
if ((current_is_dir && !is_dir) || (first > current))
|
||||
driver.menu->scroll_indices[driver.menu->scroll_indices_size++] = i;
|
||||
@ -106,7 +105,7 @@ static void menu_build_scroll_indices(file_list_t *buf)
|
||||
}
|
||||
|
||||
driver.menu->scroll_indices[driver.menu->scroll_indices_size++] =
|
||||
buf->size - 1;
|
||||
list->size - 1;
|
||||
}
|
||||
|
||||
static void add_setting_entry(menu_handle_t *menu,
|
||||
@ -180,7 +179,6 @@ static int push_list(menu_handle_t *menu,
|
||||
unsigned i;
|
||||
size_t list_size = 0;
|
||||
bool do_action = false;
|
||||
bool is_history_list = !strcmp(label, "history_list");
|
||||
|
||||
#if 0
|
||||
RARCH_LOG("Label is: %s\n", label);
|
||||
@ -188,36 +186,7 @@ static int push_list(menu_handle_t *menu,
|
||||
RARCH_LOG("Menu type is: %d\n", menu_type);
|
||||
#endif
|
||||
|
||||
if (!strcmp(label, "history_list"))
|
||||
{
|
||||
file_list_clear(list);
|
||||
list_size = content_playlist_size(g_defaults.history);
|
||||
|
||||
for (i = 0; i < list_size; i++)
|
||||
{
|
||||
char fill_buf[PATH_MAX];
|
||||
const char *path = NULL;
|
||||
const char *core_name = NULL;
|
||||
|
||||
content_playlist_get_index(g_defaults.history, i,
|
||||
&path, NULL, &core_name);
|
||||
strlcpy(fill_buf, core_name, sizeof(fill_buf));
|
||||
|
||||
if (path)
|
||||
{
|
||||
char path_short[PATH_MAX];
|
||||
fill_short_pathname_representation(path_short,path,sizeof(path_short));
|
||||
snprintf(fill_buf,sizeof(fill_buf),"%s (%s)",
|
||||
path_short,core_name);
|
||||
}
|
||||
|
||||
file_list_push(list, fill_buf, "",
|
||||
MENU_FILE_PLAYLIST_ENTRY, 0);
|
||||
|
||||
do_action = true;
|
||||
}
|
||||
}
|
||||
else if (!strcmp(label, "Main Menu"))
|
||||
if (!strcmp(label, "Main Menu"))
|
||||
{
|
||||
settings_list_free(menu->list_mainmenu);
|
||||
menu->list_mainmenu = (rarch_setting_t *)setting_data_new(SL_FLAG_MAIN_MENU);
|
||||
@ -532,9 +501,6 @@ static int push_list(menu_handle_t *menu,
|
||||
if (do_action)
|
||||
{
|
||||
driver.menu->scroll_indices_size = 0;
|
||||
if (is_history_list)
|
||||
menu_build_scroll_indices(list);
|
||||
|
||||
entries_refresh(list);
|
||||
}
|
||||
|
||||
@ -544,7 +510,7 @@ static int push_list(menu_handle_t *menu,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int menu_parse_list(file_list_t *list, file_list_t *menu_list,
|
||||
int menu_entries_parse_list(file_list_t *list, file_list_t *menu_list,
|
||||
const char *dir, const char *label, unsigned type,
|
||||
unsigned default_type_plain, const char *exts)
|
||||
{
|
||||
@ -740,7 +706,6 @@ static int menu_parse_list(file_list_t *list, file_list_t *menu_list,
|
||||
{
|
||||
char core_path[PATH_MAX], display_name[PATH_MAX];
|
||||
const char *path = NULL;
|
||||
unsigned type = 0;
|
||||
|
||||
file_list_get_at_offset(list, i, &path, NULL, &type);
|
||||
if (type != MENU_FILE_CORE)
|
||||
@ -780,90 +745,33 @@ static int menu_parse_check(const char *label, unsigned menu_type)
|
||||
!strcmp(label, "disk_image_append"))));
|
||||
if (check)
|
||||
return -1;
|
||||
check = !strcmp(label, "history_list") || !strcmp(label, "deferred_core_list");
|
||||
check = !strcmp(label, "deferred_core_list");
|
||||
if (check)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int menu_entries_deferred_push(file_list_t *list, file_list_t *menu_list)
|
||||
{
|
||||
unsigned type = 0, default_type_plain = MENU_FILE_PLAIN;
|
||||
unsigned type = 0;
|
||||
|
||||
const char *path = NULL;
|
||||
const char *label = NULL;
|
||||
const char *exts = NULL;
|
||||
char ext_buf[PATH_MAX];
|
||||
menu_file_list_cbs_t *cbs = NULL;
|
||||
|
||||
file_list_get_last(menu_list, &path, &label, &type);
|
||||
|
||||
#if 0
|
||||
RARCH_LOG("label: %s\n", label);
|
||||
#endif
|
||||
|
||||
if (((menu_parse_check(label, type)) == -1))
|
||||
return push_list(driver.menu, list, path, label, type);
|
||||
{
|
||||
if (strcmp(label, "history_list") != 0)
|
||||
return push_list(driver.menu, list, path, label, type);
|
||||
}
|
||||
|
||||
//RARCH_LOG("LABEL: %s\n", label);
|
||||
if (!strcmp(label, "core_list"))
|
||||
exts = EXT_EXECUTABLES;
|
||||
else if (!strcmp(label, "configurations"))
|
||||
{
|
||||
exts = "cfg";
|
||||
default_type_plain = MENU_FILE_CONFIG;
|
||||
}
|
||||
else if (!strcmp(label, "video_shader_preset"))
|
||||
{
|
||||
exts = "cgp|glslp";
|
||||
default_type_plain = MENU_FILE_SHADER_PRESET;
|
||||
}
|
||||
else if (!strcmp(label, "video_shader_pass"))
|
||||
{
|
||||
exts = "cg|glsl";
|
||||
default_type_plain = MENU_FILE_SHADER;
|
||||
}
|
||||
else if (!strcmp(label, "video_filter"))
|
||||
{
|
||||
exts = "filt";
|
||||
default_type_plain = MENU_FILE_VIDEOFILTER;
|
||||
}
|
||||
else if (!strcmp(label, "audio_dsp_plugin"))
|
||||
{
|
||||
exts = "dsp";
|
||||
default_type_plain = MENU_FILE_AUDIOFILTER;
|
||||
}
|
||||
else if (!strcmp(label, "input_overlay"))
|
||||
{
|
||||
exts = "cfg";
|
||||
default_type_plain = MENU_FILE_OVERLAY;
|
||||
}
|
||||
else if (!strcmp(label, "video_font_path"))
|
||||
{
|
||||
exts = "ttf";
|
||||
default_type_plain = MENU_FILE_FONT;
|
||||
}
|
||||
else if (!strcmp(label, "game_history_path"))
|
||||
exts = "cfg";
|
||||
else if (menu_common_type_is(label, type) == MENU_FILE_DIRECTORY)
|
||||
exts = ""; /* we ignore files anyway */
|
||||
else if (!strcmp(label, "detect_core_list"))
|
||||
exts = g_extern.core_info ? core_info_list_get_all_extensions(
|
||||
g_extern.core_info) : "";
|
||||
else if (g_extern.menu.info.valid_extensions)
|
||||
{
|
||||
exts = ext_buf;
|
||||
if (*g_extern.menu.info.valid_extensions)
|
||||
snprintf(ext_buf, sizeof(ext_buf), "%s",
|
||||
g_extern.menu.info.valid_extensions);
|
||||
else
|
||||
*ext_buf = '\0';
|
||||
}
|
||||
else
|
||||
exts = g_extern.system.valid_extensions;
|
||||
|
||||
menu_parse_list(list, menu_list, path, label,
|
||||
type, default_type_plain, exts);
|
||||
cbs = (menu_file_list_cbs_t*)
|
||||
file_list_get_last_actiondata(menu_list);
|
||||
|
||||
if (cbs->action_deferred_push)
|
||||
return cbs->action_deferred_push(list, menu_list, path, label, type);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -925,30 +833,6 @@ void menu_flush_stack_label(file_list_t *list,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int menu_entries_set_current_path_selection(
|
||||
rarch_setting_t *setting, const char *start_path,
|
||||
const char *label, unsigned type,
|
||||
unsigned action)
|
||||
{
|
||||
switch (action)
|
||||
{
|
||||
case MENU_ACTION_OK:
|
||||
menu_entries_push(driver.menu->menu_stack,
|
||||
start_path, label, type,
|
||||
driver.menu->selection_ptr);
|
||||
|
||||
if (setting->cmd_trigger.idx != RARCH_CMD_NONE)
|
||||
setting->cmd_trigger.triggered = true;
|
||||
break;
|
||||
case MENU_ACTION_START:
|
||||
*setting->value.string = '\0';
|
||||
break;
|
||||
}
|
||||
|
||||
return menu_action_setting_apply(setting);
|
||||
}
|
||||
|
||||
bool menu_entries_init(menu_handle_t *menu)
|
||||
{
|
||||
if (!menu)
|
||||
|
@ -30,6 +30,10 @@ void menu_entries_push(file_list_t *list,
|
||||
const char *path, const char *label, unsigned type,
|
||||
size_t directory_ptr);
|
||||
|
||||
int menu_entries_parse_list(file_list_t *list, file_list_t *menu_list,
|
||||
const char *dir, const char *label, unsigned type,
|
||||
unsigned default_type_plain, const char *exts);
|
||||
|
||||
void menu_entries_pop_list(file_list_t *list);
|
||||
|
||||
int menu_entries_deferred_push(file_list_t *list, file_list_t *menu_list);
|
||||
@ -39,13 +43,12 @@ void menu_entries_pop_stack(file_list_t *list, const char *needle);
|
||||
void menu_flush_stack_type(file_list_t *list, unsigned final_type);
|
||||
void menu_flush_stack_label(file_list_t *list, const char *needle);
|
||||
|
||||
int menu_entries_set_current_path_selection(
|
||||
rarch_setting_t *setting, const char *start_path,
|
||||
const char *label, unsigned type,
|
||||
unsigned action);
|
||||
|
||||
bool menu_entries_init(menu_handle_t *menu);
|
||||
|
||||
void entries_refresh(file_list_t *list);
|
||||
|
||||
void menu_build_scroll_indices(file_list_t *list);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -21,9 +21,98 @@
|
||||
#include "menu_shader.h"
|
||||
#include "backend/menu_backend.h"
|
||||
|
||||
#include "../../file_ext.h"
|
||||
#include "../../config.def.h"
|
||||
#include "../../performance.h"
|
||||
|
||||
#ifdef GEKKO
|
||||
enum
|
||||
{
|
||||
GX_RESOLUTIONS_512_192 = 0,
|
||||
GX_RESOLUTIONS_598_200,
|
||||
GX_RESOLUTIONS_640_200,
|
||||
GX_RESOLUTIONS_384_224,
|
||||
GX_RESOLUTIONS_448_224,
|
||||
GX_RESOLUTIONS_480_224,
|
||||
GX_RESOLUTIONS_512_224,
|
||||
GX_RESOLUTIONS_576_224,
|
||||
GX_RESOLUTIONS_608_224,
|
||||
GX_RESOLUTIONS_640_224,
|
||||
GX_RESOLUTIONS_340_232,
|
||||
GX_RESOLUTIONS_512_232,
|
||||
GX_RESOLUTIONS_512_236,
|
||||
GX_RESOLUTIONS_336_240,
|
||||
GX_RESOLUTIONS_352_240,
|
||||
GX_RESOLUTIONS_384_240,
|
||||
GX_RESOLUTIONS_512_240,
|
||||
GX_RESOLUTIONS_530_240,
|
||||
GX_RESOLUTIONS_640_240,
|
||||
GX_RESOLUTIONS_512_384,
|
||||
GX_RESOLUTIONS_598_400,
|
||||
GX_RESOLUTIONS_640_400,
|
||||
GX_RESOLUTIONS_384_448,
|
||||
GX_RESOLUTIONS_448_448,
|
||||
GX_RESOLUTIONS_480_448,
|
||||
GX_RESOLUTIONS_512_448,
|
||||
GX_RESOLUTIONS_576_448,
|
||||
GX_RESOLUTIONS_608_448,
|
||||
GX_RESOLUTIONS_640_448,
|
||||
GX_RESOLUTIONS_340_464,
|
||||
GX_RESOLUTIONS_512_464,
|
||||
GX_RESOLUTIONS_512_472,
|
||||
GX_RESOLUTIONS_352_480,
|
||||
GX_RESOLUTIONS_384_480,
|
||||
GX_RESOLUTIONS_512_480,
|
||||
GX_RESOLUTIONS_530_480,
|
||||
GX_RESOLUTIONS_608_480,
|
||||
GX_RESOLUTIONS_640_480,
|
||||
GX_RESOLUTIONS_LAST,
|
||||
};
|
||||
|
||||
unsigned menu_gx_resolutions[GX_RESOLUTIONS_LAST][2] = {
|
||||
{ 512, 192 },
|
||||
{ 598, 200 },
|
||||
{ 640, 200 },
|
||||
{ 384, 224 },
|
||||
{ 448, 224 },
|
||||
{ 480, 224 },
|
||||
{ 512, 224 },
|
||||
{ 576, 224 },
|
||||
{ 608, 224 },
|
||||
{ 640, 224 },
|
||||
{ 340, 232 },
|
||||
{ 512, 232 },
|
||||
{ 512, 236 },
|
||||
{ 336, 240 },
|
||||
{ 352, 240 },
|
||||
{ 384, 240 },
|
||||
{ 512, 240 },
|
||||
{ 530, 240 },
|
||||
{ 640, 240 },
|
||||
{ 512, 384 },
|
||||
{ 598, 400 },
|
||||
{ 640, 400 },
|
||||
{ 384, 448 },
|
||||
{ 448, 448 },
|
||||
{ 480, 448 },
|
||||
{ 512, 448 },
|
||||
{ 576, 448 },
|
||||
{ 608, 448 },
|
||||
{ 640, 448 },
|
||||
{ 340, 464 },
|
||||
{ 512, 464 },
|
||||
{ 512, 472 },
|
||||
{ 352, 480 },
|
||||
{ 384, 480 },
|
||||
{ 512, 480 },
|
||||
{ 530, 480 },
|
||||
{ 608, 480 },
|
||||
{ 640, 480 },
|
||||
};
|
||||
|
||||
unsigned menu_current_gx_resolution = GX_RESOLUTIONS_640_480;
|
||||
#endif
|
||||
|
||||
static void common_load_content(void)
|
||||
{
|
||||
rarch_main_command(RARCH_CMD_LOAD_CONTENT);
|
||||
@ -616,6 +705,484 @@ static int performance_counters_core_toggle(unsigned type, const char *label,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int shader_action_parameter_toggle(unsigned type, const char *label,
|
||||
unsigned action)
|
||||
{
|
||||
#ifdef HAVE_SHADER_MANAGER
|
||||
bool apply_changes = false;
|
||||
struct gfx_shader *shader = NULL;
|
||||
struct gfx_shader_parameter *param = NULL;
|
||||
|
||||
if (!(shader = (struct gfx_shader*)driver.menu->parameter_shader))
|
||||
return 0;
|
||||
|
||||
if (!(param = &shader->parameters[type - MENU_SETTINGS_SHADER_PARAMETER_0]))
|
||||
return 0;
|
||||
|
||||
switch (action)
|
||||
{
|
||||
case MENU_ACTION_START:
|
||||
param->current = param->initial;
|
||||
apply_changes = true;
|
||||
break;
|
||||
|
||||
case MENU_ACTION_LEFT:
|
||||
param->current -= param->step;
|
||||
apply_changes = true;
|
||||
break;
|
||||
|
||||
case MENU_ACTION_RIGHT:
|
||||
param->current += param->step;
|
||||
apply_changes = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
param->current = min(max(param->minimum, param->current), param->maximum);
|
||||
|
||||
if (apply_changes
|
||||
&& !strcmp(label, "video_shader_parameters"))
|
||||
rarch_main_command(RARCH_CMD_SHADERS_APPLY_CHANGES);
|
||||
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef HAVE_SHADER_MANAGER
|
||||
extern size_t hack_shader_pass;
|
||||
#endif
|
||||
|
||||
static int action_toggle_shader_pass(unsigned type, const char *label,
|
||||
unsigned action)
|
||||
{
|
||||
#ifdef HAVE_SHADER_MANAGER
|
||||
hack_shader_pass = type - MENU_SETTINGS_SHADER_PASS_0;
|
||||
struct gfx_shader *shader = (struct gfx_shader*)driver.menu->shader;
|
||||
struct gfx_shader_pass *shader_pass = NULL;
|
||||
|
||||
if (shader)
|
||||
shader_pass = (struct gfx_shader_pass*)&shader->pass[hack_shader_pass];
|
||||
|
||||
switch (action)
|
||||
{
|
||||
case MENU_ACTION_OK:
|
||||
menu_entries_push(driver.menu->menu_stack,
|
||||
g_settings.video.shader_dir,
|
||||
"video_shader_pass",
|
||||
type,
|
||||
driver.menu->selection_ptr);
|
||||
break;
|
||||
case MENU_ACTION_START:
|
||||
if (shader_pass)
|
||||
*shader_pass->source.path = '\0';
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int action_toggle_shader_preset(unsigned type, const char *label,
|
||||
unsigned action)
|
||||
{
|
||||
#ifdef HAVE_SHADER_MANAGER
|
||||
switch (action)
|
||||
{
|
||||
case MENU_ACTION_OK:
|
||||
menu_entries_push(driver.menu->menu_stack,
|
||||
g_settings.video.shader_dir,
|
||||
"video_shader_preset",
|
||||
type,
|
||||
driver.menu->selection_ptr);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int action_toggle_shader_scale_pass(unsigned type, const char *label,
|
||||
unsigned action)
|
||||
{
|
||||
#ifdef HAVE_SHADER_MANAGER
|
||||
unsigned pass = type - MENU_SETTINGS_SHADER_PASS_SCALE_0;
|
||||
struct gfx_shader *shader = (struct gfx_shader*)driver.menu->shader;
|
||||
struct gfx_shader_pass *shader_pass = (struct gfx_shader_pass*)
|
||||
&shader->pass[pass];
|
||||
|
||||
switch (action)
|
||||
{
|
||||
case MENU_ACTION_START:
|
||||
if (shader)
|
||||
{
|
||||
shader_pass->fbo.scale_x = shader_pass->fbo.scale_y = 0;
|
||||
shader_pass->fbo.valid = false;
|
||||
}
|
||||
break;
|
||||
|
||||
case MENU_ACTION_LEFT:
|
||||
case MENU_ACTION_RIGHT:
|
||||
case MENU_ACTION_OK:
|
||||
{
|
||||
unsigned current_scale = shader_pass->fbo.scale_x;
|
||||
unsigned delta = action == MENU_ACTION_LEFT ? 5 : 1;
|
||||
current_scale = (current_scale + delta) % 6;
|
||||
|
||||
if (shader_pass)
|
||||
{
|
||||
shader_pass->fbo.valid = current_scale;
|
||||
shader_pass->fbo.scale_x = shader_pass->fbo.scale_y = current_scale;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int action_toggle_shader_filter_pass(unsigned type, const char *label,
|
||||
unsigned action)
|
||||
{
|
||||
#ifdef HAVE_SHADER_MANAGER
|
||||
unsigned pass = type - MENU_SETTINGS_SHADER_PASS_FILTER_0;
|
||||
struct gfx_shader *shader = (struct gfx_shader*)driver.menu->shader;
|
||||
struct gfx_shader_pass *shader_pass = (struct gfx_shader_pass*)
|
||||
&shader->pass[pass];
|
||||
|
||||
switch (action)
|
||||
{
|
||||
case MENU_ACTION_START:
|
||||
if (shader)
|
||||
shader->pass[pass].filter = RARCH_FILTER_UNSPEC;
|
||||
break;
|
||||
|
||||
case MENU_ACTION_LEFT:
|
||||
case MENU_ACTION_RIGHT:
|
||||
case MENU_ACTION_OK:
|
||||
{
|
||||
unsigned delta = (action == MENU_ACTION_LEFT) ? 2 : 1;
|
||||
if (shader_pass)
|
||||
shader_pass->filter = ((shader_pass->filter + delta) % 3);
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int action_toggle_shader_filter_default(unsigned type, const char *label,
|
||||
unsigned action)
|
||||
{
|
||||
#ifdef HAVE_SHADER_MANAGER
|
||||
rarch_setting_t *current_setting = NULL;
|
||||
if ((current_setting = setting_data_find_setting(
|
||||
driver.menu->list_settings, "video_smooth")))
|
||||
menu_action_setting_boolean(current_setting, action);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int action_toggle_shader_num_passes(unsigned type, const char *label,
|
||||
unsigned action)
|
||||
{
|
||||
#ifdef HAVE_SHADER_MANAGER
|
||||
struct gfx_shader *shader = (struct gfx_shader*)driver.menu->shader;
|
||||
|
||||
if (!shader)
|
||||
return -1;
|
||||
|
||||
switch (action)
|
||||
{
|
||||
case MENU_ACTION_START:
|
||||
if (shader && shader->passes)
|
||||
shader->passes = 0;
|
||||
driver.menu->need_refresh = true;
|
||||
break;
|
||||
|
||||
case MENU_ACTION_LEFT:
|
||||
if (shader && shader->passes)
|
||||
shader->passes--;
|
||||
driver.menu->need_refresh = true;
|
||||
break;
|
||||
|
||||
case MENU_ACTION_RIGHT:
|
||||
case MENU_ACTION_OK:
|
||||
if (shader && (shader->passes < GFX_MAX_SHADERS))
|
||||
shader->passes++;
|
||||
driver.menu->need_refresh = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (driver.menu->need_refresh)
|
||||
gfx_shader_resolve_parameters(NULL, driver.menu->shader);
|
||||
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int action_toggle_shader_parameters(unsigned type, const char *label,
|
||||
unsigned action)
|
||||
{
|
||||
#ifdef HAVE_SHADER_MANAGER
|
||||
switch (action)
|
||||
{
|
||||
case MENU_ACTION_OK:
|
||||
menu_entries_push(driver.menu->menu_stack, "",
|
||||
"video_shader_parameters",
|
||||
MENU_FILE_SWITCH, driver.menu->selection_ptr);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int action_toggle_input_bind_analog_dpad_mode(unsigned type, const char *label,
|
||||
unsigned action)
|
||||
{
|
||||
unsigned port = 0;
|
||||
|
||||
if (!driver.menu)
|
||||
return -1;
|
||||
|
||||
port = driver.menu->current_pad;
|
||||
|
||||
switch (action)
|
||||
{
|
||||
case MENU_ACTION_START:
|
||||
g_settings.input.analog_dpad_mode[port] = 0;
|
||||
break;
|
||||
|
||||
case MENU_ACTION_OK:
|
||||
case MENU_ACTION_RIGHT:
|
||||
g_settings.input.analog_dpad_mode[port] =
|
||||
(g_settings.input.analog_dpad_mode[port] + 1)
|
||||
% ANALOG_DPAD_LAST;
|
||||
break;
|
||||
|
||||
case MENU_ACTION_LEFT:
|
||||
g_settings.input.analog_dpad_mode[port] =
|
||||
(g_settings.input.analog_dpad_mode
|
||||
[port] + ANALOG_DPAD_LAST - 1) % ANALOG_DPAD_LAST;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int action_toggle_input_bind_device_id(unsigned type, const char *label,
|
||||
unsigned action)
|
||||
{
|
||||
int *p = NULL;
|
||||
unsigned port = 0;
|
||||
|
||||
if (!driver.menu)
|
||||
return -1;
|
||||
|
||||
port = driver.menu->current_pad;
|
||||
p = (int*)&g_settings.input.joypad_map[port];
|
||||
|
||||
switch (action)
|
||||
{
|
||||
case MENU_ACTION_START:
|
||||
*p = port;
|
||||
break;
|
||||
case MENU_ACTION_LEFT:
|
||||
(*p)--;
|
||||
break;
|
||||
case MENU_ACTION_RIGHT:
|
||||
(*p)++;
|
||||
break;
|
||||
}
|
||||
|
||||
if (*p < -1)
|
||||
*p = -1;
|
||||
else if (*p >= MAX_PLAYERS)
|
||||
*p = MAX_PLAYERS - 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int action_toggle_input_bind_device_type(unsigned type, const char *label,
|
||||
unsigned action)
|
||||
{
|
||||
unsigned current_device, current_index, i, devices[128];
|
||||
const struct retro_controller_info *desc;
|
||||
unsigned types = 0, port = 0;
|
||||
|
||||
if (!driver.menu)
|
||||
return -1;
|
||||
|
||||
port = driver.menu->current_pad;
|
||||
|
||||
devices[types++] = RETRO_DEVICE_NONE;
|
||||
devices[types++] = RETRO_DEVICE_JOYPAD;
|
||||
|
||||
/* Only push RETRO_DEVICE_ANALOG as default if we use an
|
||||
* older core which doesn't use SET_CONTROLLER_INFO. */
|
||||
if (!g_extern.system.num_ports)
|
||||
devices[types++] = RETRO_DEVICE_ANALOG;
|
||||
|
||||
desc = port < g_extern.system.num_ports ?
|
||||
&g_extern.system.ports[port] : NULL;
|
||||
if (desc)
|
||||
{
|
||||
for (i = 0; i < desc->num_types; i++)
|
||||
{
|
||||
unsigned id = desc->types[i].id;
|
||||
if (types < ARRAY_SIZE(devices) &&
|
||||
id != RETRO_DEVICE_NONE &&
|
||||
id != RETRO_DEVICE_JOYPAD)
|
||||
devices[types++] = id;
|
||||
}
|
||||
}
|
||||
|
||||
current_device = g_settings.input.libretro_device[port];
|
||||
current_index = 0;
|
||||
for (i = 0; i < types; i++)
|
||||
{
|
||||
if (current_device == devices[i])
|
||||
{
|
||||
current_index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (action)
|
||||
{
|
||||
case MENU_ACTION_START:
|
||||
current_device = RETRO_DEVICE_JOYPAD;
|
||||
|
||||
g_settings.input.libretro_device[port] = current_device;
|
||||
pretro_set_controller_port_device(port, current_device);
|
||||
break;
|
||||
|
||||
case MENU_ACTION_LEFT:
|
||||
current_device = devices
|
||||
[(current_index + types - 1) % types];
|
||||
|
||||
g_settings.input.libretro_device[port] = current_device;
|
||||
pretro_set_controller_port_device(port, current_device);
|
||||
break;
|
||||
|
||||
case MENU_ACTION_RIGHT:
|
||||
case MENU_ACTION_OK:
|
||||
current_device = devices
|
||||
[(current_index + 1) % types];
|
||||
|
||||
g_settings.input.libretro_device[port] = current_device;
|
||||
pretro_set_controller_port_device(port, current_device);
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int action_toggle_video_resolution(unsigned type, const char *label,
|
||||
unsigned action)
|
||||
{
|
||||
#ifdef GEKKO
|
||||
switch (action)
|
||||
{
|
||||
case MENU_ACTION_LEFT:
|
||||
if (menu_current_gx_resolution > 0)
|
||||
menu_current_gx_resolution--;
|
||||
break;
|
||||
case MENU_ACTION_RIGHT:
|
||||
if (menu_current_gx_resolution < GX_RESOLUTIONS_LAST - 1)
|
||||
{
|
||||
#ifdef HW_RVL
|
||||
if ((menu_current_gx_resolution + 1) > GX_RESOLUTIONS_640_480)
|
||||
if (CONF_GetVideo() != CONF_VIDEO_PAL)
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
menu_current_gx_resolution++;
|
||||
}
|
||||
break;
|
||||
case MENU_ACTION_OK:
|
||||
if (driver.video_data)
|
||||
gx_set_video_mode(driver.video_data, menu_gx_resolutions
|
||||
[menu_current_gx_resolution][0],
|
||||
menu_gx_resolutions[menu_current_gx_resolution][1]);
|
||||
break;
|
||||
}
|
||||
#elif defined(__CELLOS_LV2__)
|
||||
switch (action)
|
||||
{
|
||||
case MENU_ACTION_LEFT:
|
||||
if (g_extern.console.screen.resolutions.current.idx)
|
||||
{
|
||||
g_extern.console.screen.resolutions.current.idx--;
|
||||
g_extern.console.screen.resolutions.current.id =
|
||||
g_extern.console.screen.resolutions.list
|
||||
[g_extern.console.screen.resolutions.current.idx];
|
||||
}
|
||||
break;
|
||||
case MENU_ACTION_RIGHT:
|
||||
if (g_extern.console.screen.resolutions.current.idx + 1 <
|
||||
g_extern.console.screen.resolutions.count)
|
||||
{
|
||||
g_extern.console.screen.resolutions.current.idx++;
|
||||
g_extern.console.screen.resolutions.current.id =
|
||||
g_extern.console.screen.resolutions.list
|
||||
[g_extern.console.screen.resolutions.current.idx];
|
||||
}
|
||||
break;
|
||||
case MENU_ACTION_OK:
|
||||
if (g_extern.console.screen.resolutions.list[
|
||||
g_extern.console.screen.resolutions.current.idx] ==
|
||||
CELL_VIDEO_OUT_RESOLUTION_576)
|
||||
{
|
||||
if (g_extern.console.screen.pal_enable)
|
||||
g_extern.console.screen.pal60_enable = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_extern.console.screen.pal_enable = false;
|
||||
g_extern.console.screen.pal60_enable = false;
|
||||
}
|
||||
|
||||
rarch_main_command(RARCH_CMD_REINIT);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int action_toggle_input_bind_player_no(unsigned type, const char *label,
|
||||
unsigned action)
|
||||
{
|
||||
unsigned port = 0;
|
||||
|
||||
if (!driver.menu)
|
||||
return -1;
|
||||
|
||||
port = driver.menu->current_pad;
|
||||
|
||||
switch (action)
|
||||
{
|
||||
case MENU_ACTION_START:
|
||||
driver.menu->current_pad = 0;
|
||||
break;
|
||||
case MENU_ACTION_LEFT:
|
||||
if (driver.menu->current_pad != 0)
|
||||
driver.menu->current_pad--;
|
||||
break;
|
||||
case MENU_ACTION_RIGHT:
|
||||
if (driver.menu->current_pad < MAX_PLAYERS - 1)
|
||||
driver.menu->current_pad++;
|
||||
break;
|
||||
}
|
||||
|
||||
if (port != driver.menu->current_pad)
|
||||
driver.menu->need_refresh = true;
|
||||
port = driver.menu->current_pad;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int performance_counters_frontend_toggle(unsigned type, const char *label,
|
||||
unsigned action)
|
||||
{
|
||||
@ -743,6 +1310,236 @@ static int action_start_bind(unsigned type, const char *label,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int deferred_push_core_list(void *data, void *userdata,
|
||||
const char *path, const char *label, unsigned type)
|
||||
{
|
||||
file_list_t *list = (file_list_t*)data;
|
||||
file_list_t *menu_list = (file_list_t*)userdata;
|
||||
|
||||
if (!list || !menu_list)
|
||||
return -1;
|
||||
|
||||
menu_entries_parse_list(list, menu_list, path, label,
|
||||
type, MENU_FILE_PLAIN, EXT_EXECUTABLES);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int deferred_push_history_list(void *data, void *userdata,
|
||||
const char *path, const char *label, unsigned type)
|
||||
{
|
||||
unsigned i;
|
||||
size_t list_size = 0;
|
||||
file_list_t *list = (file_list_t*)data;
|
||||
file_list_t *menu_list = (file_list_t*)userdata;
|
||||
|
||||
if (!list || !menu_list || !driver.menu)
|
||||
return -1;
|
||||
|
||||
file_list_clear(list);
|
||||
list_size = content_playlist_size(g_defaults.history);
|
||||
|
||||
for (i = 0; i < list_size; i++)
|
||||
{
|
||||
char fill_buf[PATH_MAX];
|
||||
const char *core_name = NULL;
|
||||
|
||||
content_playlist_get_index(g_defaults.history, i,
|
||||
&path, NULL, &core_name);
|
||||
strlcpy(fill_buf, core_name, sizeof(fill_buf));
|
||||
|
||||
if (path)
|
||||
{
|
||||
char path_short[PATH_MAX];
|
||||
fill_short_pathname_representation(path_short,path,sizeof(path_short));
|
||||
snprintf(fill_buf,sizeof(fill_buf),"%s (%s)",
|
||||
path_short,core_name);
|
||||
}
|
||||
|
||||
file_list_push(list, fill_buf, "",
|
||||
MENU_FILE_PLAYLIST_ENTRY, 0);
|
||||
}
|
||||
|
||||
driver.menu->scroll_indices_size = 0;
|
||||
menu_build_scroll_indices(list);
|
||||
entries_refresh(list);
|
||||
|
||||
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_configurations(void *data, void *userdata,
|
||||
const char *path, const char *label, unsigned type)
|
||||
{
|
||||
file_list_t *list = (file_list_t*)data;
|
||||
file_list_t *menu_list = (file_list_t*)userdata;
|
||||
|
||||
if (!list || !menu_list)
|
||||
return -1;
|
||||
|
||||
menu_entries_parse_list(list, menu_list, path, label,
|
||||
type, MENU_FILE_CONFIG, "cfg");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int deferred_push_video_shader_preset(void *data, void *userdata,
|
||||
const char *path, const char *label, unsigned type)
|
||||
{
|
||||
file_list_t *list = (file_list_t*)data;
|
||||
file_list_t *menu_list = (file_list_t*)userdata;
|
||||
|
||||
if (!list || !menu_list)
|
||||
return -1;
|
||||
|
||||
menu_entries_parse_list(list, menu_list, path, label,
|
||||
type, MENU_FILE_SHADER_PRESET, "cgp|glslp");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int deferred_push_video_shader_pass(void *data, void *userdata,
|
||||
const char *path, const char *label, unsigned type)
|
||||
{
|
||||
file_list_t *list = (file_list_t*)data;
|
||||
file_list_t *menu_list = (file_list_t*)userdata;
|
||||
|
||||
if (!list || !menu_list)
|
||||
return -1;
|
||||
|
||||
menu_entries_parse_list(list, menu_list, path, label,
|
||||
type, MENU_FILE_SHADER, "cg|glsl");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int deferred_push_video_filter(void *data, void *userdata,
|
||||
const char *path, const char *label, unsigned type)
|
||||
{
|
||||
file_list_t *list = (file_list_t*)data;
|
||||
file_list_t *menu_list = (file_list_t*)userdata;
|
||||
|
||||
if (!list || !menu_list)
|
||||
return -1;
|
||||
|
||||
menu_entries_parse_list(list, menu_list, path, label,
|
||||
type, MENU_FILE_VIDEOFILTER, "filt");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int deferred_push_audio_dsp_plugin(void *data, void *userdata,
|
||||
const char *path, const char *label, unsigned type)
|
||||
{
|
||||
file_list_t *list = (file_list_t*)data;
|
||||
file_list_t *menu_list = (file_list_t*)userdata;
|
||||
|
||||
if (!list || !menu_list)
|
||||
return -1;
|
||||
|
||||
menu_entries_parse_list(list, menu_list, path, label,
|
||||
type, MENU_FILE_AUDIOFILTER, "dsp");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int deferred_push_input_overlay(void *data, void *userdata,
|
||||
const char *path, const char *label, unsigned type)
|
||||
{
|
||||
file_list_t *list = (file_list_t*)data;
|
||||
file_list_t *menu_list = (file_list_t*)userdata;
|
||||
|
||||
if (!list || !menu_list)
|
||||
return -1;
|
||||
|
||||
menu_entries_parse_list(list, menu_list, path, label,
|
||||
type, MENU_FILE_OVERLAY, "cfg");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int deferred_push_video_font_path(void *data, void *userdata,
|
||||
const char *path, const char *label, unsigned type)
|
||||
{
|
||||
file_list_t *list = (file_list_t*)data;
|
||||
file_list_t *menu_list = (file_list_t*)userdata;
|
||||
|
||||
if (!list || !menu_list)
|
||||
return -1;
|
||||
|
||||
menu_entries_parse_list(list, menu_list, path, label,
|
||||
type, MENU_FILE_FONT, "ttf");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int deferred_push_content_history_path(void *data, void *userdata,
|
||||
const char *path, const char *label, unsigned type)
|
||||
{
|
||||
file_list_t *list = (file_list_t*)data;
|
||||
file_list_t *menu_list = (file_list_t*)userdata;
|
||||
|
||||
if (!list || !menu_list)
|
||||
return -1;
|
||||
|
||||
menu_entries_parse_list(list, menu_list, path, label,
|
||||
type, MENU_FILE_PLAIN, "cfg");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int deferred_push_detect_core_list(void *data, void *userdata,
|
||||
const char *path, const char *label, unsigned type)
|
||||
{
|
||||
const char *exts = NULL;
|
||||
file_list_t *list = (file_list_t*)data;
|
||||
file_list_t *menu_list = (file_list_t*)userdata;
|
||||
|
||||
if (!list || !menu_list)
|
||||
return -1;
|
||||
|
||||
exts = g_extern.core_info ? core_info_list_get_all_extensions(
|
||||
g_extern.core_info) : "";
|
||||
|
||||
menu_entries_parse_list(list, menu_list, path, label,
|
||||
type, MENU_FILE_PLAIN, exts);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int deferred_push_default(void *data, void *userdata,
|
||||
const char *path, const char *label, unsigned type)
|
||||
{
|
||||
char ext_buf[PATH_MAX];
|
||||
const char *exts = NULL;
|
||||
file_list_t *list = (file_list_t*)data;
|
||||
file_list_t *menu_list = (file_list_t*)userdata;
|
||||
|
||||
if (!list || !menu_list)
|
||||
return -1;
|
||||
|
||||
if (menu_common_type_is(label, type) == MENU_FILE_DIRECTORY)
|
||||
exts = ""; /* we ignore files anyway */
|
||||
else if (g_extern.menu.info.valid_extensions)
|
||||
{
|
||||
exts = ext_buf;
|
||||
if (*g_extern.menu.info.valid_extensions)
|
||||
snprintf(ext_buf, sizeof(ext_buf), "%s",
|
||||
g_extern.menu.info.valid_extensions);
|
||||
else
|
||||
*ext_buf = '\0';
|
||||
}
|
||||
else
|
||||
exts = g_extern.system.valid_extensions;
|
||||
|
||||
menu_entries_parse_list(list, menu_list, path, label,
|
||||
type, MENU_FILE_PLAIN, exts);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Bind the OK callback function */
|
||||
|
||||
static int menu_entries_cbs_init_bind_ok_first(menu_file_list_cbs_t *cbs,
|
||||
@ -900,11 +1697,36 @@ static void menu_entries_cbs_init_bind_toggle(menu_file_list_cbs_t *cbs,
|
||||
|
||||
cbs->action_toggle = menu_action_setting_set;
|
||||
|
||||
if ((menu_common_type_is(label, type) == MENU_SETTINGS_SHADER_OPTIONS) ||
|
||||
!strcmp(label, "video_shader_parameters") ||
|
||||
!strcmp(label, "video_shader_preset_parameters")
|
||||
)
|
||||
cbs->action_toggle = menu_shader_manager_setting_toggle;
|
||||
if (type >= MENU_SETTINGS_SHADER_PARAMETER_0
|
||||
&& type <= MENU_SETTINGS_SHADER_PARAMETER_LAST)
|
||||
cbs->action_toggle = shader_action_parameter_toggle;
|
||||
else if (!strcmp(label, "video_shader_pass"))
|
||||
cbs->action_toggle = action_toggle_shader_pass;
|
||||
else if (!strcmp(label, "video_shader_preset"))
|
||||
cbs->action_toggle = action_toggle_shader_preset;
|
||||
else if (!strcmp(label, "video_shader_scale_pass"))
|
||||
cbs->action_toggle = action_toggle_shader_scale_pass;
|
||||
else if (!strcmp(label, "video_shader_filter_pass"))
|
||||
cbs->action_toggle = action_toggle_shader_filter_pass;
|
||||
else if (!strcmp(label, "video_shader_default_filter"))
|
||||
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, "video_shader_parameters") ||
|
||||
!strcmp(label, "video_shader_preset_parameters")))
|
||||
cbs->action_toggle = action_toggle_shader_parameters;
|
||||
else if (!strcmp(label, "shader_apply_changes"))
|
||||
cbs->action_toggle = menu_action_setting_set;
|
||||
else if (!strcmp(label, "input_bind_analog_dpad_mode"))
|
||||
cbs->action_toggle = action_toggle_input_bind_analog_dpad_mode;
|
||||
else if (!strcmp(label, "input_bind_player_no"))
|
||||
cbs->action_toggle = action_toggle_input_bind_player_no;
|
||||
else if (!strcmp(label, "input_bind_device_id"))
|
||||
cbs->action_toggle = action_toggle_input_bind_device_id;
|
||||
else if (!strcmp(label, "input_bind_device_type"))
|
||||
cbs->action_toggle = action_toggle_input_bind_device_type;
|
||||
else if (type == MENU_SETTINGS_VIDEO_RESOLUTION)
|
||||
cbs->action_toggle = action_toggle_video_resolution;
|
||||
else if ((type >= MENU_SETTINGS_CORE_OPTION_START))
|
||||
cbs->action_toggle = core_setting_toggle;
|
||||
else if (type >= MENU_SETTINGS_PERF_COUNTERS_BEGIN &&
|
||||
@ -925,6 +1747,41 @@ static void menu_entries_cbs_init_bind_toggle(menu_file_list_cbs_t *cbs,
|
||||
}
|
||||
}
|
||||
|
||||
static void menu_entries_cbs_init_bind_deferred_push(menu_file_list_cbs_t *cbs,
|
||||
const char *path, const char *label, unsigned type, size_t index)
|
||||
{
|
||||
const char *menu_label = NULL;
|
||||
if (!cbs || !driver.menu)
|
||||
return;
|
||||
|
||||
file_list_get_last(driver.menu->menu_stack, NULL, &menu_label, NULL);
|
||||
|
||||
cbs->action_deferred_push = deferred_push_default;
|
||||
|
||||
if (!strcmp(label, "core_list"))
|
||||
cbs->action_deferred_push = deferred_push_core_list;
|
||||
if (!strcmp(label, "history_list"))
|
||||
cbs->action_deferred_push = deferred_push_history_list;
|
||||
else if (!strcmp(label, "configurations"))
|
||||
cbs->action_deferred_push = deferred_push_configurations;
|
||||
else if (!strcmp(label, "video_shader_preset"))
|
||||
cbs->action_deferred_push = deferred_push_video_shader_preset;
|
||||
else if (!strcmp(label, "video_shader_pass"))
|
||||
cbs->action_deferred_push = deferred_push_video_shader_pass;
|
||||
else if (!strcmp(label, "video_filter"))
|
||||
cbs->action_deferred_push = deferred_push_video_filter;
|
||||
else if (!strcmp(label, "audio_dsp_plugin"))
|
||||
cbs->action_deferred_push = deferred_push_audio_dsp_plugin;
|
||||
else if (!strcmp(label, "input_overlay"))
|
||||
cbs->action_deferred_push = deferred_push_input_overlay;
|
||||
else if (!strcmp(label, "video_font_path"))
|
||||
cbs->action_deferred_push = deferred_push_video_font_path;
|
||||
else if (!strcmp(label, "game_history_path"))
|
||||
cbs->action_deferred_push = deferred_push_content_history_path;
|
||||
else if (!strcmp(label, "detect_core_list"))
|
||||
cbs->action_deferred_push = deferred_push_detect_core_list;
|
||||
}
|
||||
|
||||
void menu_entries_cbs_init(void *data,
|
||||
const char *path, const char *label,
|
||||
unsigned type, size_t index)
|
||||
@ -942,5 +1799,6 @@ void menu_entries_cbs_init(void *data,
|
||||
menu_entries_cbs_init_bind_ok(cbs, path, label, type, index);
|
||||
menu_entries_cbs_init_bind_start(cbs, path, label, type, index);
|
||||
menu_entries_cbs_init_bind_toggle(cbs, path, label, type, index);
|
||||
menu_entries_cbs_init_bind_deferred_push(cbs, path, label, type, index);
|
||||
}
|
||||
}
|
||||
|
@ -22,8 +22,6 @@
|
||||
|
||||
#ifdef HAVE_SHADER_MANAGER
|
||||
|
||||
extern size_t hack_shader_pass;
|
||||
|
||||
void menu_shader_manager_init(void *data)
|
||||
{
|
||||
char cgp_path[PATH_MAX];
|
||||
@ -312,229 +310,6 @@ unsigned menu_shader_manager_get_type(const struct gfx_shader *shader)
|
||||
return type;
|
||||
}
|
||||
|
||||
static int handle_shader_pass_setting(struct gfx_shader *shader,
|
||||
unsigned action)
|
||||
{
|
||||
switch (action)
|
||||
{
|
||||
case MENU_ACTION_START:
|
||||
if (shader && shader->passes)
|
||||
shader->passes = 0;
|
||||
driver.menu->need_refresh = true;
|
||||
break;
|
||||
|
||||
case MENU_ACTION_LEFT:
|
||||
if (shader && shader->passes)
|
||||
shader->passes--;
|
||||
driver.menu->need_refresh = true;
|
||||
break;
|
||||
|
||||
case MENU_ACTION_RIGHT:
|
||||
case MENU_ACTION_OK:
|
||||
if (shader && (shader->passes < GFX_MAX_SHADERS))
|
||||
shader->passes++;
|
||||
driver.menu->need_refresh = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (driver.menu->need_refresh)
|
||||
gfx_shader_resolve_parameters(NULL, driver.menu->shader);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int menu_shader_manager_setting_toggle(
|
||||
unsigned type, const char *label, unsigned action)
|
||||
{
|
||||
if (!driver.menu)
|
||||
{
|
||||
RARCH_ERR("Menu handle is not initialized.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
RARCH_LOG("shader label: %s\n", label);
|
||||
#endif
|
||||
|
||||
rarch_setting_t *current_setting = NULL;
|
||||
|
||||
if (!strcmp(label, "video_shader_default_filter"))
|
||||
{
|
||||
if ((current_setting = setting_data_find_setting(
|
||||
driver.menu->list_settings, "video_smooth")))
|
||||
menu_action_setting_boolean(current_setting, action);
|
||||
}
|
||||
else if (type >= MENU_SETTINGS_SHADER_PARAMETER_0
|
||||
&& type <= MENU_SETTINGS_SHADER_PARAMETER_LAST)
|
||||
{
|
||||
bool apply_changes = false;
|
||||
struct gfx_shader *shader = NULL;
|
||||
struct gfx_shader_parameter *param = NULL;
|
||||
|
||||
if (!(shader = (struct gfx_shader*)driver.menu->parameter_shader))
|
||||
return 0;
|
||||
|
||||
if (!(param = &shader->parameters[type - MENU_SETTINGS_SHADER_PARAMETER_0]))
|
||||
return 0;
|
||||
|
||||
switch (action)
|
||||
{
|
||||
case MENU_ACTION_START:
|
||||
param->current = param->initial;
|
||||
apply_changes = true;
|
||||
break;
|
||||
|
||||
case MENU_ACTION_LEFT:
|
||||
param->current -= param->step;
|
||||
apply_changes = true;
|
||||
break;
|
||||
|
||||
case MENU_ACTION_RIGHT:
|
||||
param->current += param->step;
|
||||
apply_changes = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
param->current = min(max(param->minimum, param->current), param->maximum);
|
||||
|
||||
if (apply_changes
|
||||
&& !strcmp(label, "video_shader_parameters"))
|
||||
rarch_main_command(RARCH_CMD_SHADERS_APPLY_CHANGES);
|
||||
}
|
||||
else if ((!strcmp(label, "video_shader_parameters") ||
|
||||
!strcmp(label, "video_shader_preset_parameters"))
|
||||
&& action == MENU_ACTION_OK)
|
||||
menu_entries_push(driver.menu->menu_stack, "",
|
||||
"video_shader_parameters", MENU_FILE_SWITCH, driver.menu->selection_ptr);
|
||||
else if (!strcmp(label, "shader_apply_changes") ||
|
||||
!strcmp(label, "video_shader_num_passes"))
|
||||
{
|
||||
if (!strcmp(label, "video_shader_num_passes"))
|
||||
return handle_shader_pass_setting(driver.menu->shader, action);
|
||||
menu_action_setting_set(type, label, action);
|
||||
}
|
||||
else if (!strcmp(label, "video_shader_preset"))
|
||||
{
|
||||
switch (action)
|
||||
{
|
||||
case MENU_ACTION_OK:
|
||||
menu_entries_push(driver.menu->menu_stack,
|
||||
g_settings.video.shader_dir,
|
||||
"video_shader_preset",
|
||||
type,
|
||||
driver.menu->selection_ptr);
|
||||
break;
|
||||
|
||||
case MENU_ACTION_START:
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (!strcmp(label, "video_shader_pass"))
|
||||
{
|
||||
hack_shader_pass = type - MENU_SETTINGS_SHADER_PASS_0;
|
||||
struct gfx_shader *shader = (struct gfx_shader*)driver.menu->shader;
|
||||
struct gfx_shader_pass *shader_pass = NULL;
|
||||
|
||||
if (shader)
|
||||
shader_pass = (struct gfx_shader_pass*)&shader->pass[hack_shader_pass];
|
||||
|
||||
switch (action)
|
||||
{
|
||||
case MENU_ACTION_OK:
|
||||
menu_entries_push(driver.menu->menu_stack,
|
||||
g_settings.video.shader_dir,
|
||||
"video_shader_pass",
|
||||
type,
|
||||
driver.menu->selection_ptr);
|
||||
break;
|
||||
case MENU_ACTION_START:
|
||||
if (shader_pass)
|
||||
*shader_pass->source.path = '\0';
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (!strcmp(label, "video_shader_filter_pass"))
|
||||
{
|
||||
unsigned pass = type - MENU_SETTINGS_SHADER_PASS_FILTER_0;
|
||||
struct gfx_shader *shader = (struct gfx_shader*)driver.menu->shader;
|
||||
struct gfx_shader_pass *shader_pass = (struct gfx_shader_pass*)
|
||||
&shader->pass[pass];
|
||||
|
||||
switch (action)
|
||||
{
|
||||
case MENU_ACTION_START:
|
||||
if (shader)
|
||||
shader->pass[pass].filter = RARCH_FILTER_UNSPEC;
|
||||
break;
|
||||
|
||||
case MENU_ACTION_LEFT:
|
||||
case MENU_ACTION_RIGHT:
|
||||
case MENU_ACTION_OK:
|
||||
{
|
||||
unsigned delta = (action == MENU_ACTION_LEFT) ? 2 : 1;
|
||||
if (shader_pass)
|
||||
shader_pass->filter = ((shader_pass->filter + delta) % 3);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (!strcmp(label, "video_shader_scale_pass"))
|
||||
{
|
||||
unsigned pass = type - MENU_SETTINGS_SHADER_PASS_SCALE_0;
|
||||
struct gfx_shader *shader = (struct gfx_shader*)driver.menu->shader;
|
||||
struct gfx_shader_pass *shader_pass = (struct gfx_shader_pass*)
|
||||
&shader->pass[pass];
|
||||
|
||||
switch (action)
|
||||
{
|
||||
case MENU_ACTION_START:
|
||||
if (shader)
|
||||
{
|
||||
shader_pass->fbo.scale_x = shader_pass->fbo.scale_y = 0;
|
||||
shader_pass->fbo.valid = false;
|
||||
}
|
||||
break;
|
||||
|
||||
case MENU_ACTION_LEFT:
|
||||
case MENU_ACTION_RIGHT:
|
||||
case MENU_ACTION_OK:
|
||||
{
|
||||
unsigned current_scale = shader_pass->fbo.scale_x;
|
||||
unsigned delta = action == MENU_ACTION_LEFT ? 5 : 1;
|
||||
current_scale = (current_scale + delta) % 6;
|
||||
|
||||
if (shader_pass)
|
||||
{
|
||||
shader_pass->fbo.valid = current_scale;
|
||||
shader_pass->fbo.scale_x = shader_pass->fbo.scale_y = current_scale;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void menu_shader_manager_apply_changes(void)
|
||||
{
|
||||
unsigned shader_type = menu_shader_manager_get_type(driver.menu->shader);
|
||||
@ -568,12 +343,6 @@ void menu_shader_manager_init(void *data) {}
|
||||
void menu_shader_manager_set_preset(struct gfx_shader *shader,
|
||||
unsigned type, const char *cgp_path) { }
|
||||
|
||||
int menu_shader_manager_setting_toggle(
|
||||
unsigned id, const char *label, unsigned action)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void menu_shader_manager_save_preset(
|
||||
const char *basename, bool apply) { }
|
||||
|
||||
|
@ -32,9 +32,6 @@ void menu_shader_manager_init(void *data);
|
||||
void menu_shader_manager_set_preset(struct gfx_shader *shader,
|
||||
unsigned type, const char *cgp_path);
|
||||
|
||||
int menu_shader_manager_setting_toggle(
|
||||
unsigned id, const char *label, unsigned action);
|
||||
|
||||
void menu_shader_manager_save_preset(
|
||||
const char *basename, bool apply);
|
||||
|
||||
|
@ -24,6 +24,10 @@
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
void apple_start_iteration(void);
|
||||
|
||||
void apple_stop_iteration(void);
|
||||
|
||||
static CFRunLoopObserverRef iterate_observer;
|
||||
|
||||
static void do_iteration(void)
|
||||
|
@ -288,7 +288,7 @@ static void thread_loop(void *data)
|
||||
slock_lock(thr->frame.lock);
|
||||
|
||||
thread_update_driver_state(thr);
|
||||
bool ret = false;
|
||||
ret = false;
|
||||
bool alive = false;
|
||||
bool focus = false;
|
||||
bool has_windowed = true;
|
||||
|
@ -85,6 +85,7 @@ static void hidpad_ps4_disconnect(void *data)
|
||||
free(device);
|
||||
}
|
||||
|
||||
#if 0
|
||||
static uint32_t hidpad_ps4_get_buttons(void *data)
|
||||
{
|
||||
uint32_t result = 0;
|
||||
@ -125,7 +126,6 @@ static uint32_t hidpad_ps4_get_buttons(void *data)
|
||||
return result;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static int16_t hidpad_ps4_get_axis(void *data, unsigned axis)
|
||||
{
|
||||
struct hidpad_ps4_data *device = (struct hidpad_ps4_data*)data;
|
||||
|
@ -61,7 +61,7 @@ static void *linuxraw_input_init(void)
|
||||
|
||||
if (driver.stdin_claimed)
|
||||
{
|
||||
RARCH_WARN("stdin is already used for ROM loading. Cannot use stdin for input.\n");
|
||||
RARCH_WARN("stdin is already used for content loading. Cannot use stdin for input.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -98,7 +98,9 @@ static void *linuxraw_input_init(void)
|
||||
sa.sa_handler = linuxraw_exitGracefully;
|
||||
sa.sa_flags = SA_RESTART | SA_RESETHAND;
|
||||
sigemptyset(&sa.sa_mask);
|
||||
// trap some standard termination codes so we can restore the keyboard before we lose control
|
||||
|
||||
/* Trap some standard termination codes so we
|
||||
* can restore the keyboard before we lose control. */
|
||||
sigaction(SIGABRT, &sa, NULL);
|
||||
sigaction(SIGBUS, &sa, NULL);
|
||||
sigaction(SIGFPE, &sa, NULL);
|
||||
@ -111,7 +113,9 @@ static void *linuxraw_input_init(void)
|
||||
linuxraw->joypad = input_joypad_init_driver(g_settings.input.joypad_driver);
|
||||
input_init_keyboard_lut(rarch_key_map_linux);
|
||||
|
||||
driver.stdin_claimed = true; // We need to disable use of stdin command interface if stdin is supposed to be used for input.
|
||||
/* We need to disable use of stdin command interface if
|
||||
* stdin is supposed to be used for input. */
|
||||
driver.stdin_claimed = true;
|
||||
return linuxraw;
|
||||
}
|
||||
|
||||
@ -121,12 +125,14 @@ static bool linuxraw_key_pressed(linuxraw_input_t *linuxraw, int key)
|
||||
return linuxraw->state[sym];
|
||||
}
|
||||
|
||||
static bool linuxraw_is_pressed(linuxraw_input_t *linuxraw, const struct retro_keybind *binds, unsigned id)
|
||||
static bool linuxraw_is_pressed(linuxraw_input_t *linuxraw,
|
||||
const struct retro_keybind *binds, unsigned id)
|
||||
{
|
||||
if (id < RARCH_BIND_LIST_END)
|
||||
{
|
||||
const struct retro_keybind *bind = &binds[id];
|
||||
return bind->valid && linuxraw_key_pressed(linuxraw, binds[id].key);
|
||||
if (bind)
|
||||
return bind->valid && linuxraw_key_pressed(linuxraw, binds[id].key);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -152,7 +158,9 @@ static bool linuxraw_bind_button_pressed(void *data, int key)
|
||||
input_joypad_pressed(linuxraw->joypad, 0, g_settings.input.binds[0], key);
|
||||
}
|
||||
|
||||
static int16_t linuxraw_input_state(void *data, const struct retro_keybind **binds, unsigned port, unsigned device, unsigned index, unsigned id)
|
||||
static int16_t linuxraw_input_state(void *data,
|
||||
const struct retro_keybind **binds, unsigned port,
|
||||
unsigned device, unsigned index, unsigned id)
|
||||
{
|
||||
linuxraw_input_t *linuxraw = (linuxraw_input_t*)data;
|
||||
int16_t ret;
|
||||
@ -188,16 +196,21 @@ static void linuxraw_input_free(void *data)
|
||||
free(data);
|
||||
}
|
||||
|
||||
static bool linuxraw_set_rumble(void *data, unsigned port, enum retro_rumble_effect effect, uint16_t strength)
|
||||
static bool linuxraw_set_rumble(void *data, unsigned port,
|
||||
enum retro_rumble_effect effect, uint16_t strength)
|
||||
{
|
||||
linuxraw_input_t *linuxraw = (linuxraw_input_t*)data;
|
||||
return input_joypad_set_rumble(linuxraw->joypad, port, effect, strength);
|
||||
if (linuxraw)
|
||||
return input_joypad_set_rumble(linuxraw->joypad, port, effect, strength);
|
||||
return false;
|
||||
}
|
||||
|
||||
static const rarch_joypad_driver_t *linuxraw_get_joypad_driver(void *data)
|
||||
{
|
||||
linuxraw_input_t *linuxraw = (linuxraw_input_t*)data;
|
||||
return linuxraw->joypad;
|
||||
if (linuxraw)
|
||||
return linuxraw->joypad;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void linuxraw_input_poll(void *data)
|
||||
|
@ -375,6 +375,7 @@ static bool input_overlay_load_overlay(input_overlay_t *ol,
|
||||
|
||||
snprintf(overlay_path_key, sizeof(overlay_path_key),
|
||||
"overlay%u_overlay", index);
|
||||
|
||||
if (config_get_path(conf, overlay_path_key,
|
||||
overlay_path, sizeof(overlay_path)))
|
||||
{
|
||||
@ -527,22 +528,22 @@ static bool input_overlay_resolve_targets(struct overlay *ol,
|
||||
size_t index, size_t size)
|
||||
{
|
||||
size_t i;
|
||||
struct overlay *current = &ol[index];
|
||||
struct overlay *current = (struct overlay*)&ol[index];
|
||||
|
||||
for (i = 0; i < current->size; i++)
|
||||
{
|
||||
const char *next = current->descs[i].next_index_name;
|
||||
if (*next)
|
||||
{
|
||||
ssize_t index = input_overlay_find_index(ol, next, size);
|
||||
if (index < 0)
|
||||
ssize_t idx = input_overlay_find_index(ol, next, size);
|
||||
if (idx < 0)
|
||||
{
|
||||
RARCH_ERR("[Overlay]: Couldn't find overlay called: \"%s\".\n",
|
||||
next);
|
||||
return false;
|
||||
}
|
||||
|
||||
current->descs[i].next_index = index;
|
||||
current->descs[i].next_index = idx;
|
||||
}
|
||||
else
|
||||
current->descs[i].next_index = (index + 1) % size;
|
||||
|
@ -62,6 +62,8 @@ struct udev_joypad
|
||||
|
||||
char *ident;
|
||||
char *path;
|
||||
int32_t vid;
|
||||
int32_t pid;
|
||||
};
|
||||
|
||||
static struct udev *g_udev;
|
||||
@ -147,7 +149,7 @@ static bool hotplug_available(void)
|
||||
return (poll(&fds, 1, 0) == 1) && (fds.revents & POLLIN);
|
||||
}
|
||||
|
||||
static void check_device(const char *path, bool hotplugged);
|
||||
static void check_device(struct udev_device *dev, const char *path, bool hotplugged);
|
||||
static void remove_device(const char *path);
|
||||
|
||||
static void handle_hotplug(void)
|
||||
@ -166,7 +168,7 @@ static void handle_hotplug(void)
|
||||
if (!strcmp(action, "add"))
|
||||
{
|
||||
RARCH_LOG("[udev]: Hotplug add: %s.\n", devnode);
|
||||
check_device(devnode, true);
|
||||
check_device(dev, devnode, true);
|
||||
}
|
||||
else if (!strcmp(action, "remove"))
|
||||
{
|
||||
@ -308,7 +310,7 @@ static void free_pad(unsigned pad, bool hotplug)
|
||||
NULL);
|
||||
}
|
||||
|
||||
static bool add_pad(unsigned p, int fd, const char *path)
|
||||
static bool add_pad(struct udev_device *dev, unsigned p, int fd, const char *path)
|
||||
{
|
||||
int i;
|
||||
struct udev_joypad *pad = &g_pads[p];
|
||||
@ -318,7 +320,22 @@ static bool add_pad(unsigned p, int fd, const char *path)
|
||||
return false;
|
||||
}
|
||||
|
||||
RARCH_LOG("[udev]: Plugged pad: %s on port #%u.\n", pad->ident, p);
|
||||
const char *buf;
|
||||
|
||||
/* don't worry about unref'ing the parent */
|
||||
struct udev_device *parent =
|
||||
udev_device_get_parent_with_subsystem_devtype(dev, "usb", "usb_device");
|
||||
|
||||
pad->vid = pad->pid = 0;
|
||||
|
||||
if ((buf = udev_device_get_sysattr_value(parent, "idVendor")) != NULL)
|
||||
pad->vid = strtol(buf, NULL, 16);
|
||||
|
||||
if ((buf = udev_device_get_sysattr_value(parent, "idProduct")) != NULL)
|
||||
pad->pid = strtol(buf, NULL, 16);
|
||||
|
||||
RARCH_LOG("[udev]: Plugged pad: %s (%04x:%04x) on port #%u.\n",
|
||||
pad->ident, pad->vid, pad->pid, p);
|
||||
|
||||
struct stat st;
|
||||
if (fstat(fd, &st) < 0)
|
||||
@ -367,10 +384,8 @@ static bool add_pad(unsigned p, int fd, const char *path)
|
||||
pad->fd = fd;
|
||||
pad->path = strdup(path);
|
||||
|
||||
/* TODO - implement VID/PID? */
|
||||
if (*pad->ident)
|
||||
input_config_autoconfigure_joypad(p, pad->ident,
|
||||
0, 0, "udev");
|
||||
input_config_autoconfigure_joypad(p, pad->ident, pad->vid, pad->pid, "udev");
|
||||
|
||||
// Check for rumble features.
|
||||
unsigned long ffbit[NBITS(FF_MAX)] = {0};
|
||||
@ -387,7 +402,7 @@ static bool add_pad(unsigned p, int fd, const char *path)
|
||||
return true;
|
||||
}
|
||||
|
||||
static void check_device(const char *path, bool hotplugged)
|
||||
static void check_device(struct udev_device *dev, const char *path, bool hotplugged)
|
||||
{
|
||||
unsigned i;
|
||||
struct stat st;
|
||||
@ -411,7 +426,7 @@ static void check_device(const char *path, bool hotplugged)
|
||||
if (fd < 0)
|
||||
return;
|
||||
|
||||
if (add_pad(pad, fd, path))
|
||||
if (add_pad(dev, pad, fd, path))
|
||||
{
|
||||
#ifndef IS_JOYCONFIG
|
||||
if (hotplugged)
|
||||
@ -501,7 +516,7 @@ static bool udev_joypad_init(void)
|
||||
struct udev_device *dev = udev_device_new_from_syspath(g_udev, name);
|
||||
const char *devnode = udev_device_get_devnode(dev);
|
||||
if (devnode)
|
||||
check_device(devnode, false);
|
||||
check_device(dev, devnode, false);
|
||||
udev_device_unref(dev);
|
||||
}
|
||||
|
||||
|
@ -18,8 +18,8 @@
|
||||
#include "boolean.h"
|
||||
#include "libretro.h"
|
||||
#include "retro.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
|
474
settings_data.c
474
settings_data.c
File diff suppressed because it is too large
Load Diff
@ -81,6 +81,8 @@ enum setting_list_flags
|
||||
#define SL_FLAG_ALL_SETTINGS (SL_FLAG_ALL - SL_FLAG_MAIN_MENU)
|
||||
|
||||
typedef void (*change_handler_t)(void *data);
|
||||
typedef int (*action_toggle_handler_t)(void *data, unsigned action);
|
||||
typedef int (*action_ok_handler_t)(void *data, unsigned action);
|
||||
|
||||
typedef struct rarch_setting_info
|
||||
{
|
||||
@ -115,7 +117,9 @@ typedef struct rarch_setting
|
||||
change_handler_t change_handler;
|
||||
change_handler_t deferred_handler;
|
||||
change_handler_t read_handler;
|
||||
|
||||
action_toggle_handler_t action_toggle;
|
||||
action_ok_handler_t action_ok;
|
||||
|
||||
union
|
||||
{
|
||||
bool boolean;
|
||||
|
@ -14,7 +14,6 @@
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
Loading…
x
Reference in New Issue
Block a user