From 935c7d0e2c7936a11d9e84fbb6fb1094778d0108 Mon Sep 17 00:00:00 2001 From: toshixm Date: Sun, 30 May 2021 09:17:06 +0900 Subject: [PATCH 01/58] use _wfullpath() instead of _fullpath() --- libretro-common/file/file_path.c | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/libretro-common/file/file_path.c b/libretro-common/file/file_path.c index d8cbd5e5c0..127c71ebea 100644 --- a/libretro-common/file/file_path.c +++ b/libretro-common/file/file_path.c @@ -638,16 +638,31 @@ bool path_is_absolute(const char *path) char *path_resolve_realpath(char *buf, size_t size, bool resolve_symlinks) { #if !defined(RARCH_CONSOLE) && defined(RARCH_INTERNAL) - char tmp[PATH_MAX_LENGTH]; #ifdef _WIN32 - strlcpy(tmp, buf, sizeof(tmp)); - if (!_fullpath(buf, tmp, size)) + char *ret = NULL; + wchar_t *abs_path = (wchar_t *)malloc(PATH_MAX_LENGTH * sizeof(wchar_t)); + wchar_t *rel_path = utf8_to_utf16_string_alloc(buf); + + if (abs_path && rel_path && _wfullpath(abs_path, rel_path, PATH_MAX_LENGTH)) { - strlcpy(buf, tmp, size); - return NULL; + char *tmp = utf16_to_utf8_string_alloc(abs_path); + + if (tmp) + { + strlcpy(buf, tmp, size); + free(tmp); + ret = buf; + } } - return buf; + + if (rel_path) + free(rel_path); + if (abs_path) + free(abs_path); + + return ret; #else + char tmp[PATH_MAX_LENGTH]; size_t t; char *p; const char *next; From 1218aebfbfdab955230cdfe576cd7d87cf5cc050 Mon Sep 17 00:00:00 2001 From: toshixm Date: Thu, 3 Jun 2021 15:26:33 +0900 Subject: [PATCH 02/58] static allocation instead of malloc() --- libretro-common/file/file_path.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/libretro-common/file/file_path.c b/libretro-common/file/file_path.c index 127c71ebea..d582e9bd48 100644 --- a/libretro-common/file/file_path.c +++ b/libretro-common/file/file_path.c @@ -640,25 +640,25 @@ char *path_resolve_realpath(char *buf, size_t size, bool resolve_symlinks) #if !defined(RARCH_CONSOLE) && defined(RARCH_INTERNAL) #ifdef _WIN32 char *ret = NULL; - wchar_t *abs_path = (wchar_t *)malloc(PATH_MAX_LENGTH * sizeof(wchar_t)); + wchar_t abs_path[PATH_MAX_LENGTH]; wchar_t *rel_path = utf8_to_utf16_string_alloc(buf); - if (abs_path && rel_path && _wfullpath(abs_path, rel_path, PATH_MAX_LENGTH)) - { - char *tmp = utf16_to_utf8_string_alloc(abs_path); - - if (tmp) - { - strlcpy(buf, tmp, size); - free(tmp); - ret = buf; - } - } - if (rel_path) + { + if (_wfullpath(abs_path, rel_path, PATH_MAX_LENGTH)) + { + char *tmp = utf16_to_utf8_string_alloc(abs_path); + + if (tmp) + { + strlcpy(buf, tmp, size); + free(tmp); + ret = buf; + } + } + free(rel_path); - if (abs_path) - free(abs_path); + } return ret; #else From 98be8f0c22693a1e947b8a6b12108d14c877ff90 Mon Sep 17 00:00:00 2001 From: CTCaer Date: Wed, 9 Jun 2021 13:16:37 +0300 Subject: [PATCH 03/58] plat: unix: correct backlight max_brightness path We are assuming that device has its backlight device symlinked to /sys/class/backlight/backlight so this should be stated. Additionally any hardcoding should be disallowed and the symlink should be always used. --- frontend/drivers/platform_unix.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/frontend/drivers/platform_unix.c b/frontend/drivers/platform_unix.c index 8cc3231c2c..b50bce688c 100644 --- a/frontend/drivers/platform_unix.c +++ b/frontend/drivers/platform_unix.c @@ -1349,15 +1349,15 @@ static void frontend_unix_set_screen_brightness(int value) char *buffer = NULL; char svalue[16] = {0}; unsigned int max_brightness = 100; - #if !defined(HAVE_LAKKA_SWITCH) - filestream_read_file("/sys/devices/platform/backlight/backlight/backlight/max_brightness", + + /* Device tree should have 'label = "backlight";' if control is desirable */ + filestream_read_file("/sys/class/backlight/backlight/max_brightness", &buffer, NULL); if (buffer) { sscanf(buffer, "%u", &max_brightness); free(buffer); } - #endif /* Calculate the brightness */ value = (value * max_brightness) / 100; @@ -2827,7 +2827,7 @@ frontend_ctx_driver_t frontend_ctx_unix = { #endif #if defined(HAVE_LAKKA_SWITCH) || (defined(HAVE_LAKKA) && defined(HAVE_ODROIDGO2)) frontend_unix_set_screen_brightness,/* set_screen_brightness */ -#else +#else NULL, /* set_screen_brightness */ #endif frontend_unix_watch_path_for_changes, From b483f233d297495aa4ee89a3a0030d8a0ae6c024 Mon Sep 17 00:00:00 2001 From: sonninnos Date: Thu, 24 Jun 2021 00:56:52 +0300 Subject: [PATCH 04/58] Integer overscale option --- config.def.h | 2 ++ configuration.c | 1 + configuration.h | 1 + intl/msg_hash_lbl.h | 4 ++++ intl/msg_hash_us.c | 7 ++++++- intl/msg_hash_us.h | 8 ++++++++ menu/cbs/menu_cbs_sublabel.c | 4 ++++ menu/menu_displaylist.c | 5 +++++ menu/menu_setting.c | 22 ++++++++++++++++++++++ msg_hash.h | 1 + retroarch.c | 12 ++++++++++-- 11 files changed, 64 insertions(+), 3 deletions(-) diff --git a/config.def.h b/config.def.h index d2f2846bf9..c8bcff6917 100644 --- a/config.def.h +++ b/config.def.h @@ -380,8 +380,10 @@ /* Only scale in integer steps. * The base size depends on system-reported geometry and aspect ratio. * If video_force_aspect is not set, X/Y will be integer scaled independently. + * Overscale rounds up instead of down, default is downscale. */ #define DEFAULT_SCALE_INTEGER false +#define DEFAULT_SCALE_INTEGER_OVERSCALE false /* Controls aspect ratio handling. */ diff --git a/configuration.c b/configuration.c index 174894e41b..752151ecd1 100644 --- a/configuration.c +++ b/configuration.c @@ -1530,6 +1530,7 @@ static struct config_bool_setting *populate_settings_bool( SETTING_BOOL("video_windowed_fullscreen", &settings->bools.video_windowed_fullscreen, true, DEFAULT_WINDOWED_FULLSCREEN, false); SETTING_BOOL("video_crop_overscan", &settings->bools.video_crop_overscan, true, DEFAULT_CROP_OVERSCAN, false); SETTING_BOOL("video_scale_integer", &settings->bools.video_scale_integer, true, DEFAULT_SCALE_INTEGER, false); + SETTING_BOOL("video_scale_integer_overscale", &settings->bools.video_scale_integer_overscale, true, DEFAULT_SCALE_INTEGER_OVERSCALE, false); SETTING_BOOL("video_smooth", &settings->bools.video_smooth, true, DEFAULT_VIDEO_SMOOTH, false); SETTING_BOOL("video_ctx_scaling", &settings->bools.video_ctx_scaling, true, DEFAULT_VIDEO_CTX_SCALING, false); SETTING_BOOL("video_force_aspect", &settings->bools.video_force_aspect, true, DEFAULT_FORCE_ASPECT, false); diff --git a/configuration.h b/configuration.h index 29f52bfd2e..773d03d3ae 100644 --- a/configuration.h +++ b/configuration.h @@ -497,6 +497,7 @@ typedef struct settings bool video_aspect_ratio_auto; bool video_dingux_ipu_keep_aspect; bool video_scale_integer; + bool video_scale_integer_overscale; bool video_shader_enable; bool video_shader_watch_files; bool video_shader_remember_last_dir; diff --git a/intl/msg_hash_lbl.h b/intl/msg_hash_lbl.h index aebd44e3ef..8c7aba31ed 100644 --- a/intl/msg_hash_lbl.h +++ b/intl/msg_hash_lbl.h @@ -3314,6 +3314,10 @@ MSG_HASH( MENU_ENUM_LABEL_VIDEO_SCALE_INTEGER, "video_scale_integer" ) +MSG_HASH( + MENU_ENUM_LABEL_VIDEO_SCALE_INTEGER_OVERSCALE, + "video_scale_integer_overscale" + ) MSG_HASH( MENU_ENUM_LABEL_VIDEO_SETTINGS, "video_settings" diff --git a/intl/msg_hash_us.c b/intl/msg_hash_us.c index 39418993bf..9eda1c4ad6 100644 --- a/intl/msg_hash_us.c +++ b/intl/msg_hash_us.c @@ -1365,9 +1365,14 @@ int msg_hash_get_help_us_enum(enum msg_hash_enums msg, char *s, size_t len) "The base size depends on system-reported \n" "geometry and aspect ratio.\n" " \n" - "If Force Aspect is not set, X/Y will be \n" + "If 'Force Aspect Ratio' is not set, X/Y will be \n" "integer scaled independently."); break; + case MENU_ENUM_LABEL_VIDEO_SCALE_INTEGER_OVERSCALE: + snprintf(s, len, + "Force integer scaling to round up \n" + " to the next larger integer instead of rounding down."); + break; case MENU_ENUM_LABEL_AUDIO_VOLUME: snprintf(s, len, "Audio volume, expressed in dB.\n" diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index 43e5b65d3a..d2c50ed246 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -1631,6 +1631,14 @@ MSG_HASH( MENU_ENUM_SUBLABEL_VIDEO_SCALE_INTEGER, "Scale video in integer steps only. The base size depends on system-reported geometry and aspect ratio. If 'Force Aspect Ratio' is not set, X/Y will be integer scaled independently." ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_SCALE_INTEGER_OVERSCALE, + "Integer Scale Overscale" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_SCALE_INTEGER_OVERSCALE, + "Force integer scaling to round up to the next larger integer instead of rounding down." + ) MSG_HASH( MENU_ENUM_LABEL_VALUE_VIDEO_ASPECT_RATIO_INDEX, "Aspect Ratio" diff --git a/menu/cbs/menu_cbs_sublabel.c b/menu/cbs/menu_cbs_sublabel.c index 6ed665bbbe..cabf2763ac 100644 --- a/menu/cbs/menu_cbs_sublabel.c +++ b/menu/cbs/menu_cbs_sublabel.c @@ -451,6 +451,7 @@ DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_overlay_auto_rotate, MENU_ DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_overlay_auto_scale, MENU_ENUM_SUBLABEL_INPUT_OVERLAY_AUTO_SCALE) DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_content_collection_list, MENU_ENUM_SUBLABEL_PLAYLISTS_TAB) DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_video_scale_integer, MENU_ENUM_SUBLABEL_VIDEO_SCALE_INTEGER) +DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_video_scale_integer_overscale, MENU_ENUM_SUBLABEL_VIDEO_SCALE_INTEGER_OVERSCALE) DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_video_gpu_screenshot, MENU_ENUM_SUBLABEL_VIDEO_GPU_SCREENSHOT) DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_video_rotation, MENU_ENUM_SUBLABEL_VIDEO_ROTATION) DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_screen_orientation, MENU_ENUM_SUBLABEL_SCREEN_ORIENTATION) @@ -3278,6 +3279,9 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs, case MENU_ENUM_LABEL_VIDEO_SCALE_INTEGER: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_video_scale_integer); break; + case MENU_ENUM_LABEL_VIDEO_SCALE_INTEGER_OVERSCALE: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_video_scale_integer_overscale); + break; case MENU_ENUM_LABEL_PLAYLISTS_TAB: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_content_collection_list); break; diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index 352006a09b..12259241c0 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -7765,6 +7765,11 @@ unsigned menu_displaylist_build_list( MENU_ENUM_LABEL_VIDEO_SCALE_INTEGER, PARSE_ONLY_BOOL, false) == 0) count++; + if (settings->bools.video_scale_integer) + if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(list, + MENU_ENUM_LABEL_VIDEO_SCALE_INTEGER_OVERSCALE, + PARSE_ONLY_BOOL, false) == 0) + count++; if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(list, MENU_ENUM_LABEL_VIDEO_ASPECT_RATIO_INDEX, PARSE_ONLY_UINT, false) == 0) diff --git a/menu/menu_setting.c b/menu/menu_setting.c index 4ea8deb769..19631ad7a3 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -11366,6 +11366,28 @@ static bool setting_append_list( list_info, CMD_EVENT_VIDEO_APPLY_STATE_CHANGES); + CONFIG_BOOL( + list, list_info, + &settings->bools.video_scale_integer_overscale, + MENU_ENUM_LABEL_VIDEO_SCALE_INTEGER_OVERSCALE, + MENU_ENUM_LABEL_VALUE_VIDEO_SCALE_INTEGER_OVERSCALE, + DEFAULT_SCALE_INTEGER_OVERSCALE, + MENU_ENUM_LABEL_VALUE_OFF, + MENU_ENUM_LABEL_VALUE_ON, + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler, + SD_FLAG_NONE); + (*list)[list_info->index - 1].action_ok = setting_bool_action_left_with_refresh; + (*list)[list_info->index - 1].action_left = setting_bool_action_left_with_refresh; + (*list)[list_info->index - 1].action_right = setting_bool_action_right_with_refresh; + MENU_SETTINGS_LIST_CURRENT_ADD_CMD( + list, + list_info, + CMD_EVENT_VIDEO_APPLY_STATE_CHANGES); + #ifdef GEKKO CONFIG_UINT( list, list_info, diff --git a/msg_hash.h b/msg_hash.h index cc67621fd7..7ae1857157 100644 --- a/msg_hash.h +++ b/msg_hash.h @@ -1072,6 +1072,7 @@ enum msg_hash_enums MENU_LABEL(VIDEO_NOTCH_WRITE_OVER), MENU_LABEL(VIDEO_SCALE_INTEGER), + MENU_LABEL(VIDEO_SCALE_INTEGER_OVERSCALE), MENU_LABEL(VIDEO_VIEWPORT_CUSTOM_X), MENU_LABEL(VIDEO_VIEWPORT_CUSTOM_Y), MENU_LABEL(VIDEO_VIEWPORT_CUSTOM_WIDTH), diff --git a/retroarch.c b/retroarch.c index d5fab68864..b9b4bcaa8b 100644 --- a/retroarch.c +++ b/retroarch.c @@ -31819,6 +31819,7 @@ void video_viewport_get_scaled_integer(struct video_viewport *vp, struct rarch_state *p_rarch = &rarch_st; settings_t *settings = p_rarch->configuration_settings; unsigned video_aspect_ratio_idx = settings->uints.video_aspect_ratio_idx; + bool overscale = settings->bools.video_scale_integer_overscale; if (video_aspect_ratio_idx == ASPECT_RATIO_CUSTOM) { @@ -31861,8 +31862,15 @@ void video_viewport_get_scaled_integer(struct video_viewport *vp, if (keep_aspect) { /* X/Y scale must be same. */ - unsigned max_scale = MIN(width / base_width, - height / base_height); + unsigned max_scale = 1; + + if (overscale) + max_scale = MIN((width / base_width) + !!(width % base_width), + (height / base_height) + !!(height % base_height)); + else + max_scale = MIN(width / base_width, + height / base_height); + padding_x = width - base_width * max_scale; padding_y = height - base_height * max_scale; } From b1b5148090c7596bdb06da240435c8489b9eb66f Mon Sep 17 00:00:00 2001 From: John Parton Date: Sat, 26 Jun 2021 14:54:42 -0500 Subject: [PATCH 05/58] Enable Alsa/Alsa_thread on OpenDingux, but not alsa midi driver, keeping openal the default audio driver --- Makefile.common | 4 +++- Makefile.rg350_odbeta | 5 +++-- configuration.c | 4 +++- retroarch_data.h | 2 +- 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/Makefile.common b/Makefile.common index da5bf14f9e..34576dd4b0 100644 --- a/Makefile.common +++ b/Makefile.common @@ -829,7 +829,9 @@ ifeq ($(HAVE_ALSA), 1) ifneq ($(HAVE_HAKCHI), 1) ifneq ($(HAVE_SEGAM), 1) - OBJ += midi/drivers/alsa_midi.o + ifneq ($(DINGUX), 1) + OBJ += midi/drivers/alsa_midi.o + endif endif endif diff --git a/Makefile.rg350_odbeta b/Makefile.rg350_odbeta index d33a487eec..078d3c7ed8 100644 --- a/Makefile.rg350_odbeta +++ b/Makefile.rg350_odbeta @@ -45,8 +45,7 @@ HAVE_SCREENSHOTS = 0 HAVE_REWIND = 1 HAVE_7ZIP = 1 HAVE_AL = 1 -# ALSA freezes when switching back from menu -HAVE_ALSA = 0 +HAVE_ALSA = 1 HAVE_DSP_FILTER = 1 HAVE_VIDEO_FILTER = 1 HAVE_STATIC_VIDEO_FILTERS = 1 @@ -121,6 +120,7 @@ DEF_FLAGS += -ffunction-sections -fdata-sections DEF_FLAGS += -I. -Ideps -Ideps/stb -DDINGUX=1 -DDINGUX_BETA=1 -MMD DEF_FLAGS += -Wall -Wno-unused-variable DEF_FLAGS += -std=gnu99 -D_GNU_SOURCE -flto +DEF_FLAGS += -lasound LIBS := -ldl -lz -lrt -ludev -pthread CFLAGS := CXXFLAGS := -fno-exceptions -fno-rtti -std=c++11 -D__STDC_CONSTANT_MACROS @@ -134,6 +134,7 @@ DEFINES += -DHAVE_GETOPT_LONG=1 -DHAVE_STRCASESTR=1 -DHAVE_DYNAMIC=1 DEFINES += -DHAVE_AL=1 DEFINES += -DHAVE_FILTERS_BUILTIN DEFINES += -DHAVE_UDEV=1 +DEFINES += -DHAVE_ALSA SDL_DINGUX_CFLAGS := $(shell $(GCW0_SDL_CONFIG) --cflags) SDL_DINGUX_LIBS := $(shell $(GCW0_SDL_CONFIG) --libs) diff --git a/configuration.c b/configuration.c index 174894e41b..652c435dca 100644 --- a/configuration.c +++ b/configuration.c @@ -339,6 +339,8 @@ static const enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_PS3; static const enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_CTR; #elif defined(SWITCH) static const enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_SWITCH; +#elif defined(DINGUX) && defined(HAVE_AL) +static const enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_AL; #elif defined(HAVE_PULSE) static const enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_PULSE; #elif defined(HAVE_ALSA) && defined(HAVE_THREADS) @@ -397,7 +399,7 @@ static const enum record_driver_enum RECORD_DEFAULT_DRIVER = RECORD_NULL; #ifdef HAVE_WINMM static const enum midi_driver_enum MIDI_DEFAULT_DRIVER = MIDI_WINMM; -#elif defined(HAVE_ALSA) && !defined(HAVE_HAKCHI) && !defined(HAVE_SEGAM) +#elif defined(HAVE_ALSA) && !defined(HAVE_HAKCHI) && !defined(HAVE_SEGAM) && !defined(DINGUX) static const enum midi_driver_enum MIDI_DEFAULT_DRIVER = MIDI_ALSA; #else static const enum midi_driver_enum MIDI_DEFAULT_DRIVER = MIDI_NULL; diff --git a/retroarch_data.h b/retroarch_data.h index e9713cf831..31aa49a5ac 100644 --- a/retroarch_data.h +++ b/retroarch_data.h @@ -1190,7 +1190,7 @@ static midi_driver_t midi_null = { }; static midi_driver_t *midi_drivers[] = { -#if defined(HAVE_ALSA) && !defined(HAVE_HAKCHI) && !defined(HAVE_SEGAM) +#if defined(HAVE_ALSA) && !defined(HAVE_HAKCHI) && !defined(HAVE_SEGAM) && !defined(DINGUX) &midi_alsa, #endif #ifdef HAVE_WINMM From d6a1c21fe1decbbd5bb23300e6a3e1e822c2ff36 Mon Sep 17 00:00:00 2001 From: Grant Date: Sat, 26 Jun 2021 23:09:47 +0100 Subject: [PATCH 06/58] udev fixes] --- input/drivers/udev_input.c | 76 ++++++++++++++++++++++---------------- 1 file changed, 44 insertions(+), 32 deletions(-) diff --git a/input/drivers/udev_input.c b/input/drivers/udev_input.c index ad65ddd125..979425f69c 100644 --- a/input/drivers/udev_input.c +++ b/input/drivers/udev_input.c @@ -112,6 +112,7 @@ typedef struct int32_t x_rel, y_rel; bool l, r, m, b4, b5; bool wu, wd, whu, whd; + bool pp; } udev_input_mouse_t; struct udev_input_device @@ -252,7 +253,7 @@ static udev_input_mouse_t *udev_get_mouse( static void udev_mouse_set_x(udev_input_mouse_t *mouse, int32_t x, bool abs) { - video_viewport_t vp; + video_viewport_t vp; if (abs) { @@ -427,7 +428,9 @@ static void udev_handle_mouse(void *data, case BTN_MIDDLE: mouse->m = event->value; break; - + case BTN_TOUCH: + mouse->pp = event->value; + break; /*case BTN_??: mouse->b4 = event->value; break;*/ @@ -478,11 +481,14 @@ static void udev_handle_mouse(void *data, break; } } +#define test_bit(array, bit) (array[bit/8] & (1<<(bit%8))) static int udev_input_add_device(udev_input_t *udev, enum udev_input_dev_type type, const char *devnode, device_handle_cb cb) { unsigned char keycaps[(KEY_MAX / 8) + 1]; + unsigned char abscaps[(ABS_MAX / 8) + 1]; + int has_absolutes = 0; int fd; struct stat st; #if defined(HAVE_EPOLL) @@ -494,6 +500,9 @@ static int udev_input_add_device(udev_input_t *udev, udev_input_device_t **tmp; udev_input_device_t *device = NULL; + memset(keycaps, '\0', sizeof (keycaps)); + memset(keycaps, '\0', sizeof (abscaps)); + st.st_dev = 0; if (stat(devnode, &st) < 0) @@ -520,33 +529,36 @@ static int udev_input_add_device(udev_input_t *udev, if (ioctl(fd, EVIOCGBIT(EV_KEY, sizeof (keycaps)), keycaps) == -1) return -1; /* gotta have some buttons! return -1 to skip error logging for this:) */ - if (ioctl(fd, EVIOCGABS(ABS_X), &absinfo) >= 0) - { - if (absinfo.minimum >= absinfo.maximum ) - { - device->mouse.x_min = -1; - device->mouse.x_max = -1; - } - else - { - device->mouse.x_min = absinfo.minimum; - device->mouse.x_max = absinfo.maximum; - } - } - if (ioctl(fd, EVIOCGABS(ABS_Y), &absinfo) >= 0) + + if (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof (abscaps)), abscaps) != -1) { - if (absinfo.minimum >= absinfo.maximum ) - { - device->mouse.y_min = -1; - device->mouse.y_max = -1; - } - else - { - device->mouse.y_min = absinfo.minimum; - device->mouse.y_max = absinfo.maximum; - } - } + if ( (test_bit(abscaps, ABS_X)) && (test_bit(abscaps, ABS_Y)) ) + { + /* might be a touchpad... */ + if (test_bit(keycaps, BTN_TOUCH)) + { + /* touchpad, touchscreen, or tablet. */ + has_absolutes = 1; + } + } + } + device->mouse.x_min = device->mouse.y_min = device->mouse.x_max = device->mouse.y_max = 0; + + if (has_absolutes) + { + struct input_absinfo absinfo; + if (ioctl(fd, EVIOCGABS(ABS_X), &absinfo) == -1) + return 0; + device->mouse.x_min = absinfo.minimum; + device->mouse.x_max = absinfo.maximum; + + if (ioctl(fd, EVIOCGABS(ABS_Y), &absinfo) == -1) + return 0; + device->mouse.y_min = absinfo.minimum; + device->mouse.y_max = absinfo.maximum; + } + } tmp = ( udev_input_device_t**)realloc(udev->devices, @@ -944,7 +956,7 @@ static int16_t udev_pointer_state(udev_input_t *udev, case RETRO_DEVICE_ID_POINTER_Y: return udev_mouse_get_pointer_y(mouse, screen); case RETRO_DEVICE_ID_POINTER_PRESSED: - return mouse->l; + return mouse->pp; } return 0; @@ -1241,10 +1253,10 @@ static bool open_devices(udev_input_t *udev, if (fd != -1) { int check = udev_input_add_device(udev, type, devnode, cb); - if (!check && check != -1 ) - RARCH_DBG("[udev] udev_input_add_device error : %s (%s).\n", + if (check == 0) + RARCH_LOG("[udev] udev_input_add_device error : %s (%s).\n", devnode, strerror(errno)); - else if (check != -1 && check != 0) + else if (check == 1 ) { char ident[255]; if (ioctl(fd, EVIOCGNAME(sizeof(ident)), ident) < 0) @@ -1257,7 +1269,7 @@ static bool open_devices(udev_input_t *udev, devnode); device_keyboard++; } - else + else if (type == UDEV_INPUT_MOUSE || type== UDEV_INPUT_TOUCHPAD) { RARCH_LOG("[udev]: Added Device mouse#%d %s (%s) .\n", device_mouse, From c31e0ba9b9375e9d94f82e1a8b5be4648807f21c Mon Sep 17 00:00:00 2001 From: confusedguy9 <38110536+confusedguy9@users.noreply.github.com> Date: Sun, 4 Jul 2021 14:46:41 +0800 Subject: [PATCH 07/58] Enable 7z support for Switch --- Makefile.libnx | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile.libnx b/Makefile.libnx index f75703b060..efe1f309ef 100644 --- a/Makefile.libnx +++ b/Makefile.libnx @@ -32,6 +32,7 @@ HAVE_RTGA = 1 HAVE_RPNG = 1 HAVE_RJPEG = 1 HAVE_RBMP = 1 +HAVE_7ZIP = 1 HAVE_ZLIB = 1 HAVE_BUILTINZLIB = 1 HAVE_LIBRETRODB = 1 From 7b46cca917a0db0ab5d87b7423234abe175e949a Mon Sep 17 00:00:00 2001 From: Guo Yunhe Date: Sun, 4 Jul 2021 21:43:39 +0800 Subject: [PATCH 08/58] Fetch translations from Crowdin --- intl/msg_hash_es.h | 2 +- intl/msg_hash_ko.h | 12 +++++++++++ intl/progress.h | 52 +++++++++++++++++++++++----------------------- 3 files changed, 39 insertions(+), 27 deletions(-) diff --git a/intl/msg_hash_es.h b/intl/msg_hash_es.h index 191347af56..2e1775cc9e 100644 --- a/intl/msg_hash_es.h +++ b/intl/msg_hash_es.h @@ -4035,7 +4035,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_LABEL_VALUE_MENU_SCROLL_DELAY, - "Retraso al desplazar el menú" + "Retraso para desplazar el menú" ) MSG_HASH( MENU_ENUM_SUBLABEL_MENU_SCROLL_DELAY, diff --git a/intl/msg_hash_ko.h b/intl/msg_hash_ko.h index 795b11a898..0c6ad7ca3a 100644 --- a/intl/msg_hash_ko.h +++ b/intl/msg_hash_ko.h @@ -2640,6 +2640,10 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_INPUT_ADC_TYPE, "아날로그로 디지털 입력" ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_ADC_TYPE, + "지정한 아날로그 스틱을 방향 패드 대신으로 사용합니다. 코어가 아날로그 입력을 지원하는 경우, 방향 패드 매핑은 (강제) 옵션을 선택하지 않은 한 비활성화됩니다. 방향 패드 매핑을 강제하면 코어는 지정한 스틱의 아날로그 입력을 받을 수 없게 됩니다." + ) MSG_HASH( MENU_ENUM_LABEL_VALUE_INPUT_DEVICE_INDEX, "장치 인덱스" @@ -7615,6 +7619,14 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_RIGHT_ANALOG, "우 아날로그" ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_LEFT_ANALOG_FORCED, + "좌 아날로그 (강제)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RIGHT_ANALOG_FORCED, + "우 아날로그 (강제)" + ) MSG_HASH( MENU_ENUM_LABEL_VALUE_INPUT_KEY, "(키: %s)" diff --git a/intl/progress.h b/intl/progress.h index 7783ab1160..c034f3e6cb 100644 --- a/intl/progress.h +++ b/intl/progress.h @@ -1,14 +1,14 @@ /* Arabic */ -#define LANGUAGE_PROGRESS_ARABIC_TRANSLATED 60 +#define LANGUAGE_PROGRESS_ARABIC_TRANSLATED 67 #define LANGUAGE_PROGRESS_ARABIC_APPROVED 0 /* Asturian */ -#define LANGUAGE_PROGRESS_ASTURIAN_TRANSLATED 16 -#define LANGUAGE_PROGRESS_ASTURIAN_APPROVED 16 +#define LANGUAGE_PROGRESS_ASTURIAN_TRANSLATED 15 +#define LANGUAGE_PROGRESS_ASTURIAN_APPROVED 15 /* Chinese Simplified */ -#define LANGUAGE_PROGRESS_CHINESE_SIMPLIFIED_TRANSLATED 88 -#define LANGUAGE_PROGRESS_CHINESE_SIMPLIFIED_APPROVED 65 +#define LANGUAGE_PROGRESS_CHINESE_SIMPLIFIED_TRANSLATED 100 +#define LANGUAGE_PROGRESS_CHINESE_SIMPLIFIED_APPROVED 64 /* Chinese Traditional */ #define LANGUAGE_PROGRESS_CHINESE_TRADITIONAL_TRANSLATED 25 @@ -32,22 +32,22 @@ /* Finnish */ #define LANGUAGE_PROGRESS_FINNISH_TRANSLATED 99 -#define LANGUAGE_PROGRESS_FINNISH_APPROVED 7 +#define LANGUAGE_PROGRESS_FINNISH_APPROVED 69 /* French */ -#define LANGUAGE_PROGRESS_FRENCH_TRANSLATED 99 -#define LANGUAGE_PROGRESS_FRENCH_APPROVED 99 +#define LANGUAGE_PROGRESS_FRENCH_TRANSLATED 100 +#define LANGUAGE_PROGRESS_FRENCH_APPROVED 100 /* Galician */ #define LANGUAGE_PROGRESS_GALICIAN_TRANSLATED 8 #define LANGUAGE_PROGRESS_GALICIAN_APPROVED 0 /* German */ -#define LANGUAGE_PROGRESS_GERMAN_TRANSLATED 96 -#define LANGUAGE_PROGRESS_GERMAN_APPROVED 0 +#define LANGUAGE_PROGRESS_GERMAN_TRANSLATED 99 +#define LANGUAGE_PROGRESS_GERMAN_APPROVED 15 /* Greek */ -#define LANGUAGE_PROGRESS_GREEK_TRANSLATED 29 +#define LANGUAGE_PROGRESS_GREEK_TRANSLATED 28 #define LANGUAGE_PROGRESS_GREEK_APPROVED 0 /* Hebrew */ @@ -59,19 +59,19 @@ #define LANGUAGE_PROGRESS_HUNGARIAN_APPROVED 0 /* Indonesian */ -#define LANGUAGE_PROGRESS_INDONESIAN_TRANSLATED 5 +#define LANGUAGE_PROGRESS_INDONESIAN_TRANSLATED 16 #define LANGUAGE_PROGRESS_INDONESIAN_APPROVED 0 /* Italian */ -#define LANGUAGE_PROGRESS_ITALIAN_TRANSLATED 99 +#define LANGUAGE_PROGRESS_ITALIAN_TRANSLATED 100 #define LANGUAGE_PROGRESS_ITALIAN_APPROVED 0 /* Japanese */ -#define LANGUAGE_PROGRESS_JAPANESE_TRANSLATED 82 +#define LANGUAGE_PROGRESS_JAPANESE_TRANSLATED 92 #define LANGUAGE_PROGRESS_JAPANESE_APPROVED 0 /* Korean */ -#define LANGUAGE_PROGRESS_KOREAN_TRANSLATED 99 +#define LANGUAGE_PROGRESS_KOREAN_TRANSLATED 100 #define LANGUAGE_PROGRESS_KOREAN_APPROVED 0 /* Persian */ @@ -80,39 +80,39 @@ /* Polish */ #define LANGUAGE_PROGRESS_POLISH_TRANSLATED 99 -#define LANGUAGE_PROGRESS_POLISH_APPROVED 36 +#define LANGUAGE_PROGRESS_POLISH_APPROVED 38 /* Portuguese */ #define LANGUAGE_PROGRESS_PORTUGUESE_TRANSLATED 27 #define LANGUAGE_PROGRESS_PORTUGUESE_APPROVED 0 /* Portuguese, Brazilian */ -#define LANGUAGE_PROGRESS_PORTUGUESE_BRAZILIAN_TRANSLATED 99 +#define LANGUAGE_PROGRESS_PORTUGUESE_BRAZILIAN_TRANSLATED 100 #define LANGUAGE_PROGRESS_PORTUGUESE_BRAZILIAN_APPROVED 5 /* Russian */ -#define LANGUAGE_PROGRESS_RUSSIAN_TRANSLATED 99 -#define LANGUAGE_PROGRESS_RUSSIAN_APPROVED 10 +#define LANGUAGE_PROGRESS_RUSSIAN_TRANSLATED 100 +#define LANGUAGE_PROGRESS_RUSSIAN_APPROVED 13 /* Slovak */ -#define LANGUAGE_PROGRESS_SLOVAK_TRANSLATED 9 +#define LANGUAGE_PROGRESS_SLOVAK_TRANSLATED 15 #define LANGUAGE_PROGRESS_SLOVAK_APPROVED 0 /* Spanish */ -#define LANGUAGE_PROGRESS_SPANISH_TRANSLATED 99 -#define LANGUAGE_PROGRESS_SPANISH_APPROVED 96 +#define LANGUAGE_PROGRESS_SPANISH_TRANSLATED 100 +#define LANGUAGE_PROGRESS_SPANISH_APPROVED 99 /* Swedish */ #define LANGUAGE_PROGRESS_SWEDISH_TRANSLATED 17 #define LANGUAGE_PROGRESS_SWEDISH_APPROVED 0 /* Turkish */ -#define LANGUAGE_PROGRESS_TURKISH_TRANSLATED 99 -#define LANGUAGE_PROGRESS_TURKISH_APPROVED 99 +#define LANGUAGE_PROGRESS_TURKISH_TRANSLATED 100 +#define LANGUAGE_PROGRESS_TURKISH_APPROVED 100 /* Ukrainian */ -#define LANGUAGE_PROGRESS_UKRAINIAN_TRANSLATED 42 -#define LANGUAGE_PROGRESS_UKRAINIAN_APPROVED 8 +#define LANGUAGE_PROGRESS_UKRAINIAN_TRANSLATED 43 +#define LANGUAGE_PROGRESS_UKRAINIAN_APPROVED 9 /* Vietnamese */ #define LANGUAGE_PROGRESS_VIETNAMESE_TRANSLATED 5 From 523d7d6ee8d0157d2da5986aa7515af563f060b2 Mon Sep 17 00:00:00 2001 From: "Mark W. Kidd" Date: Mon, 5 Jul 2021 15:18:17 -0400 Subject: [PATCH 09/58] consolidate input defines --- input/input_defines.h | 46 +++++++++++++++++++++++++++++++++++++++++++ input/input_driver.h | 46 ------------------------------------------- 2 files changed, 46 insertions(+), 46 deletions(-) diff --git a/input/input_defines.h b/input/input_defines.h index 036af0716a..07a0caac0d 100644 --- a/input/input_defines.h +++ b/input/input_defines.h @@ -135,6 +135,52 @@ enum analog_dpad_mode ANALOG_DPAD_LAST }; +enum input_toggle_type +{ + INPUT_TOGGLE_NONE = 0, + INPUT_TOGGLE_DOWN_Y_L_R, + INPUT_TOGGLE_L3_R3, + INPUT_TOGGLE_L1_R1_START_SELECT, + INPUT_TOGGLE_START_SELECT, + INPUT_TOGGLE_L3_R, + INPUT_TOGGLE_L_R, + INPUT_TOGGLE_HOLD_START, + INPUT_TOGGLE_HOLD_SELECT, + INPUT_TOGGLE_DOWN_SELECT, + INPUT_TOGGLE_L2_R2, + INPUT_TOGGLE_LAST +}; + +enum input_turbo_mode +{ + INPUT_TURBO_MODE_CLASSIC = 0, + INPUT_TURBO_MODE_SINGLEBUTTON, + INPUT_TURBO_MODE_SINGLEBUTTON_HOLD, + INPUT_TURBO_MODE_LAST +}; + +enum input_turbo_default_button +{ + INPUT_TURBO_DEFAULT_BUTTON_B = 0, + INPUT_TURBO_DEFAULT_BUTTON_Y, + INPUT_TURBO_DEFAULT_BUTTON_A, + INPUT_TURBO_DEFAULT_BUTTON_X, + INPUT_TURBO_DEFAULT_BUTTON_L, + INPUT_TURBO_DEFAULT_BUTTON_R, + INPUT_TURBO_DEFAULT_BUTTON_L2, + INPUT_TURBO_DEFAULT_BUTTON_R2, + INPUT_TURBO_DEFAULT_BUTTON_L3, + INPUT_TURBO_DEFAULT_BUTTON_R3, + INPUT_TURBO_DEFAULT_BUTTON_LAST +}; + +enum input_action +{ + INPUT_ACTION_NONE = 0, + INPUT_ACTION_AXIS_THRESHOLD, + INPUT_ACTION_MAX_USERS +}; + /* Specialized _MOUSE that targets the full screen regardless of viewport. */ #define RARCH_DEVICE_MOUSE_SCREEN (RETRO_DEVICE_MOUSE | 0x10000) diff --git a/input/input_driver.h b/input/input_driver.h index 10e32b1a30..3fd2f3dcc2 100644 --- a/input/input_driver.h +++ b/input/input_driver.h @@ -43,52 +43,6 @@ RETRO_BEGIN_DECLS -enum input_toggle_type -{ - INPUT_TOGGLE_NONE = 0, - INPUT_TOGGLE_DOWN_Y_L_R, - INPUT_TOGGLE_L3_R3, - INPUT_TOGGLE_L1_R1_START_SELECT, - INPUT_TOGGLE_START_SELECT, - INPUT_TOGGLE_L3_R, - INPUT_TOGGLE_L_R, - INPUT_TOGGLE_HOLD_START, - INPUT_TOGGLE_HOLD_SELECT, - INPUT_TOGGLE_DOWN_SELECT, - INPUT_TOGGLE_L2_R2, - INPUT_TOGGLE_LAST -}; - -enum input_turbo_mode -{ - INPUT_TURBO_MODE_CLASSIC = 0, - INPUT_TURBO_MODE_SINGLEBUTTON, - INPUT_TURBO_MODE_SINGLEBUTTON_HOLD, - INPUT_TURBO_MODE_LAST -}; - -enum input_turbo_default_button -{ - INPUT_TURBO_DEFAULT_BUTTON_B = 0, - INPUT_TURBO_DEFAULT_BUTTON_Y, - INPUT_TURBO_DEFAULT_BUTTON_A, - INPUT_TURBO_DEFAULT_BUTTON_X, - INPUT_TURBO_DEFAULT_BUTTON_L, - INPUT_TURBO_DEFAULT_BUTTON_R, - INPUT_TURBO_DEFAULT_BUTTON_L2, - INPUT_TURBO_DEFAULT_BUTTON_R2, - INPUT_TURBO_DEFAULT_BUTTON_L3, - INPUT_TURBO_DEFAULT_BUTTON_R3, - INPUT_TURBO_DEFAULT_BUTTON_LAST -}; - -enum input_action -{ - INPUT_ACTION_NONE = 0, - INPUT_ACTION_AXIS_THRESHOLD, - INPUT_ACTION_MAX_USERS -}; - struct retro_keybind { char *joykey_label; From d0212ec5aa2a9ed468ac1bf0f897dd0a5b0d2b69 Mon Sep 17 00:00:00 2001 From: xenomorph-us Date: Tue, 6 Jul 2021 13:55:43 +0900 Subject: [PATCH 10/58] HTTPS link to EditorConfig.org --- .editorconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.editorconfig b/.editorconfig index 2ee2ca19f1..9d13991864 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,4 +1,4 @@ -# EditorConfig: http://EditorConfig.org +# EditorConfig: https://EditorConfig.org # Top-most EditorConfig file root = true From 6e61eb084aac026a67e9ab2ae38752ecc3f165ac Mon Sep 17 00:00:00 2001 From: JustMeDaFaq Date: Tue, 6 Jul 2021 19:51:42 +0200 Subject: [PATCH 11/58] Default to d3d11 on UWP builds Even if compiled with ANGLE, lets default to d3d11 since ANGLE is calling D3D anyway. That makes cores like PCSX2 and Duckstation boot proper with default settings, ANGLE cores still switching automatically. --- configuration.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/configuration.c b/configuration.c index e8dc20a76e..aed70f7988 100644 --- a/configuration.c +++ b/configuration.c @@ -260,6 +260,9 @@ static const enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_GL; #else static const enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_METAL; #endif +#elif defined(__WINRT__) || defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP +/* Lets default to D3D11 in UWP, even when its compiled with ANGLE, since ANGLE is just calling D3D anyway.*/ +static const enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_D3D11; #elif defined(HAVE_OPENGL1) && defined(_MSC_VER) && (_MSC_VER <= 1600) /* On Windows XP and earlier, use gl1 by default * (regular opengl has compatibility issues with From b17dd28ff2daf0751362e367050453551bcc2d78 Mon Sep 17 00:00:00 2001 From: "Mark W. Kidd" Date: Mon, 5 Jul 2021 22:04:39 -0400 Subject: [PATCH 12/58] consolidate and comment input_remapping.h --- input/input_driver.h | 40 --------- input/input_remapping.h | 162 +++++++++++++++++++++++++++++------ menu/cbs/menu_cbs_scan.c | 1 + menu/cbs/menu_cbs_sublabel.c | 1 + menu/menu_displaylist.c | 1 + retroarch.c | 20 ++--- tasks/task_autodetect.c | 1 + tasks/task_overlay.c | 1 + ui/drivers/qt/qt_options.cpp | 1 + 9 files changed, 150 insertions(+), 78 deletions(-) diff --git a/input/input_driver.h b/input/input_driver.h index 10e32b1a30..dd56a19a86 100644 --- a/input/input_driver.h +++ b/input/input_driver.h @@ -524,46 +524,6 @@ struct input_keyboard_ctx_wait void input_keyboard_event(bool down, unsigned code, uint32_t character, uint16_t mod, unsigned device); -const char *input_config_bind_map_get_base(unsigned i); - -unsigned input_config_bind_map_get_meta(unsigned i); - -const char *input_config_bind_map_get_desc(unsigned i); - -uint8_t input_config_bind_map_get_retro_key(unsigned i); - -/* auto_bind can be NULL. */ -void input_config_get_bind_string(char *buf, - const struct retro_keybind *bind, - const struct retro_keybind *auto_bind, size_t size); - -/** - * input_config_translate_str_to_rk: - * @str : String to translate to key ID. - * - * Translates string representation to key identifier. - * - * Returns: key identifier. - **/ -enum retro_key input_config_translate_str_to_rk(const char *str); - -/** - * input_config_translate_str_to_bind_id: - * @str : String to translate to bind ID. - * - * Translate string representation to bind ID. - * - * Returns: Bind ID value on success, otherwise - * RARCH_BIND_LIST_END on not found. - **/ -unsigned input_config_translate_str_to_bind_id(const char *str); - -void config_read_keybinds_conf(void *data); - -/* Note: 'data' is an object of type config_file_t - * > We assume it was done like this to avoid including - * config_file.h... */ -void input_config_set_autoconfig_binds(unsigned port, void *data); /* Set input_device_info */ void input_config_set_device_name(unsigned port, const char *name); diff --git a/input/input_remapping.h b/input/input_remapping.h index 2925a66ac5..ab06073037 100644 --- a/input/input_remapping.h +++ b/input/input_remapping.h @@ -26,56 +26,162 @@ RETRO_BEGIN_DECLS /** - * input_remapping_load_file: - * @data : Path to config file. - * * Loads a remap file from disk to memory. + * + * @param data Path to config file. * - * Returns: true (1) if successful, otherwise false (0). + * @return true (1) if successful, otherwise false (0). **/ bool input_remapping_load_file(void *data, const char *path); /** - * input_remapping_save_file: - * @path : Path to remapping file (relative path). - * * Saves remapping values to file. * - * Returns: true (1) if successful, otherwise false (0). + * @param path Relative path to remapping file. + * + * @return true (1) if successful, otherwise false (0). **/ bool input_remapping_save_file(const char *path); -bool input_remapping_remove_file(const char *path, - const char *dir_input_remapping); +bool input_remapping_remove_file(const char *path, + const char *dir_input_remapping); -/* Caches any global configuration settings that - * should not be overwritten by input remap - * changes made while content is running. - * Must be called on each core init. */ +/** + * Caches any global configuration settings that should not be overwritten by + * input remap changes made while content is running. Must be called on each + * core init. + */ void input_remapping_cache_global_config(void); -/* Sets flags to enable the restoration of - * global configuration settings from the - * internal cache. Should be called independently - * from 'input_remapping_cache_global_config()'. + +/** + * Sets flags to enable the restoration of global configuration settings from + * the internal cache. Should be called independently from + * `input_remapping_cache_global_config()`. * Must be called: - * - Whenever content is loaded - * - Whenever a remap file is loaded */ + * - Whenever content is loaded + * - Whenever a remap file is loaded + */ void input_remapping_enable_global_config_restore(void); -/* Restores any cached global configuration settings - * *if* 'input_remapping_enable_global_config_restore()' - * has been called. - * Must be called on core deint. - * If 'clear_cache' is true, function becomes a NOOP - * until the next time input_remapping_cache_global_config() - * and input_remapping_enable_global_config_restore() - * are called. */ + +/** + * Restores any global configuration settings that were cached on the last core + * init if `input_remapping_enable_global_config_restore()` has been called. + * Must be called on core deinitialization. + * + * @param clear_cache If true, function becomes a NOOP until the next time + * `input_remapping_cache_global_config()` and + * `input_remapping_enable_global_config_restore()` are + * called. + */ void input_remapping_restore_global_config(bool clear_cache); +/** + * Must be called whenever `settings->uints.input_remap_ports` is modified. + */ void input_remapping_update_port_map(void); +/** + * Frees global->name.remapfile and sets these runloop_state flags to false: + * remaps_core_active, remaps_content_dir_active, and remaps_game_active. + */ void input_remapping_deinit(void); + +/** + * Used to set the default mapping values within the `settings` struct + * @param clear_cache This value is passed to + * `input_remapping_restore_global_config()`. Please see + * the documentation for that function for details. + */ void input_remapping_set_defaults(bool clear_cache); +/** + * Checks `input_config_bind_map` for the requested `input_bind_map`, and if + * the bind has been registered, returns its base. + * + * @param index + * + * @return the contents of the meta field, or NULL if there is no matching bind + */ +const char *input_config_bind_map_get_base(unsigned bind_index); + +/** + * Checks `input_config_bind_map` for the requested `input_bind_map`, and if + * the bind has been registered, returns the value of its meta binds field. + * + * @param index + * + * @return the contents of the meta field, or 0 if there is no matching bind + */ +unsigned input_config_bind_map_get_meta(unsigned bind_index); + +/** + * Checks `input_config_bind_map` for the requested `input_bind_map`, and if + * the bind has been registered, returns a pointer to its description field. + * + * @param index + * + * @return the contents of the description field, or NULL if there is no + * matching bind + */ +const char *input_config_bind_map_get_desc(unsigned index); + +/** + * Checks `input_config_bind_map` for the requested `input_bind_map`, and if + * the bind has been registered, returns the value of its retro_key field. + * + * @param index + * + * @return the value of the retro_key field, or 0 if there is no matching bind + */ +uint8_t input_config_bind_map_get_retro_key(unsigned index); + +/** + * Converts a retro_keybind to a human-readable string, optionally allowing a + * fallback auto_bind to be used as the source for the string. + * + * @param buf A string which will be overwritten with the returned value + * @param bind A binding to convert to a string + * @param auto_bind A default binding which will be used after `bind`. Can be NULL. + * @param size The maximum length that will be written to `buf` + */ +void input_config_get_bind_string(char *buf, const struct retro_keybind *bind, + const struct retro_keybind *auto_bind, size_t size); + +/** + * Parses the string representation of a retro_key struct + * + * @param str String to parse. + * + * @return Key identifier. + **/ +enum retro_key input_config_translate_str_to_rk(const char *str); + +/** + * Searches for a string among the "base" fields of the list of binds. + * + * @param str String to search for among the binds + * + * @return Bind index value on success or RARCH_BIND_LIST_END if not found. + **/ +unsigned input_config_translate_str_to_bind_id(const char *str); + +/** + * Parse the bind data of an object of config_file_t. + * + * @param data An object of type config_file_t. We assume it is passed as a + * void pointer like this to avoid including config_file.h. + **/ +void config_read_keybinds_conf(void *data); + +/** + * Apply autoconfig binds to the indicated control port. + * + * @param port + * @param data An object of type config_file_t. We assume it is passed as a + * void pointer like this to avoid including config_file.h. + */ +void input_config_set_autoconfig_binds(unsigned port, void *data); + RETRO_END_DECLS #endif diff --git a/menu/cbs/menu_cbs_scan.c b/menu/cbs/menu_cbs_scan.c index 68eb28bb10..6e155035cb 100644 --- a/menu/cbs/menu_cbs_scan.c +++ b/menu/cbs/menu_cbs_scan.c @@ -24,6 +24,7 @@ #include "../menu_driver.h" #include "../menu_cbs.h" #include "../menu_setting.h" +#include "../../input/input_remapping.h" #include "../../input/input_driver.h" diff --git a/menu/cbs/menu_cbs_sublabel.c b/menu/cbs/menu_cbs_sublabel.c index 6ed665bbbe..ea41beb9d2 100644 --- a/menu/cbs/menu_cbs_sublabel.c +++ b/menu/cbs/menu_cbs_sublabel.c @@ -21,6 +21,7 @@ #include "../menu_driver.h" #include "../menu_cbs.h" +#include "../../input/input_remapping.h" #include "../../retroarch.h" #include "../../core_option_manager.h" diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index ba2dd8ef88..6e826d1c9a 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -112,6 +112,7 @@ #include "../manual_content_scan.h" #include "../core_backup.h" #include "../misc/cpufreq/cpufreq.h" +#include "../input/input_remapping.h" /* Spacers used for ' - ' labels * in playlists */ diff --git a/retroarch.c b/retroarch.c index fd9d55ec53..3e4c9ce433 100644 --- a/retroarch.c +++ b/retroarch.c @@ -26510,46 +26510,46 @@ void input_keyboard_event(bool down, unsigned code, } } -static bool input_config_bind_map_get_valid(unsigned i) +static bool input_config_bind_map_get_valid(unsigned bind_index) { const struct input_bind_map *keybind = - (const struct input_bind_map*)INPUT_CONFIG_BIND_MAP_GET(i); + (const struct input_bind_map*)INPUT_CONFIG_BIND_MAP_GET(bind_index); if (!keybind) return false; return keybind->valid; } -unsigned input_config_bind_map_get_meta(unsigned i) +unsigned input_config_bind_map_get_meta(unsigned bind_index) { const struct input_bind_map *keybind = - (const struct input_bind_map*)INPUT_CONFIG_BIND_MAP_GET(i); + (const struct input_bind_map*)INPUT_CONFIG_BIND_MAP_GET(bind_index); if (!keybind) return 0; return keybind->meta; } -const char *input_config_bind_map_get_base(unsigned i) +const char *input_config_bind_map_get_base(unsigned bind_index) { const struct input_bind_map *keybind = - (const struct input_bind_map*)INPUT_CONFIG_BIND_MAP_GET(i); + (const struct input_bind_map*)INPUT_CONFIG_BIND_MAP_GET(bind_index); if (!keybind) return NULL; return keybind->base; } -const char *input_config_bind_map_get_desc(unsigned i) +const char *input_config_bind_map_get_desc(unsigned bind_index) { const struct input_bind_map *keybind = - (const struct input_bind_map*)INPUT_CONFIG_BIND_MAP_GET(i); + (const struct input_bind_map*)INPUT_CONFIG_BIND_MAP_GET(bind_index); if (!keybind) return NULL; return msg_hash_to_str(keybind->desc); } -uint8_t input_config_bind_map_get_retro_key(unsigned i) +uint8_t input_config_bind_map_get_retro_key(unsigned bind_index) { const struct input_bind_map *keybind = - (const struct input_bind_map*)INPUT_CONFIG_BIND_MAP_GET(i); + (const struct input_bind_map*)INPUT_CONFIG_BIND_MAP_GET(bind_index); if (!keybind) return 0; return keybind->retro_key; diff --git a/tasks/task_autodetect.c b/tasks/task_autodetect.c index 6048fcaf91..69d8f94166 100644 --- a/tasks/task_autodetect.c +++ b/tasks/task_autodetect.c @@ -30,6 +30,7 @@ #include "../list_special.h" #include "../retroarch.h" #include "../input/input_driver.h" +#include "../input/input_remapping.h" #include "tasks_internal.h" #ifdef HAVE_BLISSBOX diff --git a/tasks/task_overlay.c b/tasks/task_overlay.c index 8d4410b689..3877a7931d 100644 --- a/tasks/task_overlay.c +++ b/tasks/task_overlay.c @@ -28,6 +28,7 @@ #include "tasks_internal.h" #include "../input/input_overlay.h" +#include "../input/input_remapping.h" #include "../retroarch.h" #include "../verbosity.h" diff --git a/ui/drivers/qt/qt_options.cpp b/ui/drivers/qt/qt_options.cpp index 6fbf3326d9..993366c77c 100644 --- a/ui/drivers/qt/qt_options.cpp +++ b/ui/drivers/qt/qt_options.cpp @@ -14,6 +14,7 @@ extern "C" { #include "../../../gfx/video_display_server.h" #include "../../../input/input_driver.h" +#include "../../../input/input_remapping.h" #include "../../../network/netplay/netplay.h" #include "../../../retroarch.h" From d14c4d288361bfc05541187fdf9321f08bcb75ab Mon Sep 17 00:00:00 2001 From: HyperspaceMadness Date: Wed, 7 Jul 2021 09:37:36 -0400 Subject: [PATCH 13/58] Added Aspect Ratio Full Fixes Fixes Moved ASPECT_RATIO_FULL to end of list, added TODO Fixed Full Order Fixed UI Visibility --- gfx/video_defines.h | 3 ++- retroarch.c | 47 ++++++++++++++++++++++++++++++++++++ retroarch.h | 2 ++ retroarch_data.h | 3 ++- ui/drivers/qt/qt_options.cpp | 4 +++ 5 files changed, 57 insertions(+), 2 deletions(-) diff --git a/gfx/video_defines.h b/gfx/video_defines.h index 2a1dd62a39..33f94d584b 100644 --- a/gfx/video_defines.h +++ b/gfx/video_defines.h @@ -55,6 +55,7 @@ enum aspect_ratio ASPECT_RATIO_SQUARE, ASPECT_RATIO_CORE, ASPECT_RATIO_CUSTOM, + ASPECT_RATIO_FULL, ASPECT_RATIO_END }; @@ -116,7 +117,7 @@ enum text_alignment #define COLOR_ABGR(r, g, b, a) (((unsigned)(a) << 24) | ((b) << 16) | ((g) << 8) | ((r) << 0)) #endif -#define LAST_ASPECT_RATIO ASPECT_RATIO_CUSTOM +#define LAST_ASPECT_RATIO ASPECT_RATIO_FULL /* ABGR color format defines */ diff --git a/retroarch.c b/retroarch.c index fd9d55ec53..15ed1f993c 100644 --- a/retroarch.c +++ b/retroarch.c @@ -31379,6 +31379,21 @@ void video_driver_set_viewport_core(void) (float)geom->base_width / geom->base_height; } +void video_driver_set_viewport_full() +{ + unsigned width = 0; + unsigned height = 0; + + video_driver_get_size(&width, &height); + + if (width == 0 || height == 0) + { + return; + } + + aspectratio_lut[ASPECT_RATIO_FULL].value = (float)width / (float)height; +} + void video_driver_reset_custom_viewport(void) { struct rarch_state *p_rarch = &rarch_st; @@ -31473,6 +31488,10 @@ void video_driver_set_aspect_ratio(void) settings->bools.video_aspect_ratio_auto); break; + case ASPECT_RATIO_FULL: + video_driver_set_viewport_full(); + break; + default: break; } @@ -38007,6 +38026,34 @@ static enum runloop_state runloop_check_state( } #endif + /* + * If the Aspect Ratio is FULL then update the aspect ratio to the + * current video driver aspect ratio (The full window) + * + * TODO/FIXME + * Should possibly be refactored to have last width & driver width & height + * only be done once when we are using an overlay OR using aspect ratio + * full + */ + if (settings->uints.video_aspect_ratio_idx == ASPECT_RATIO_FULL) + { + static unsigned last_width = 0; + static unsigned last_height = 0; + unsigned video_driver_width = p_rarch->video_driver_width; + unsigned video_driver_height = p_rarch->video_driver_height; + + /* Check whether video aspect has changed */ + if ((video_driver_width != last_width) || + (video_driver_height != last_height)) + { + /* Update set aspect ratio so the full matches the current video width & height */ + command_event(CMD_EVENT_VIDEO_SET_ASPECT_RATIO, NULL); + + last_width = video_driver_width; + last_height = video_driver_height; + } + } + /* Check quit key */ { bool trig_quit_key, quit_press_twice; diff --git a/retroarch.h b/retroarch.h index f76cb34182..53575b7ab4 100644 --- a/retroarch.h +++ b/retroarch.h @@ -1567,6 +1567,8 @@ bool video_driver_supports_read_frame_raw(void); void video_driver_set_viewport_core(void); +void video_driver_set_viewport_full(void); + void video_driver_reset_custom_viewport(void); void video_driver_set_rgba(void); diff --git a/retroarch_data.h b/retroarch_data.h index e9713cf831..802f21e0d0 100644 --- a/retroarch_data.h +++ b/retroarch_data.h @@ -2373,7 +2373,8 @@ struct aspect_ratio_elem aspectratio_lut[ASPECT_RATIO_END] = { { 0.0f, "Config" }, { 1.0f, "Square pixel" }, { 1.0f, "Core provided" }, - { 0.0f, "Custom" } + { 0.0f, "Custom" }, + { 1.3333f, "Full" } }; static gfx_api_gpu_map gpu_map[] = { diff --git a/ui/drivers/qt/qt_options.cpp b/ui/drivers/qt/qt_options.cpp index 6fbf3326d9..5da7a0fdec 100644 --- a/ui/drivers/qt/qt_options.cpp +++ b/ui/drivers/qt/qt_options.cpp @@ -1352,6 +1352,7 @@ AspectRatioGroup::AspectRatioGroup(const QString &title, QWidget *parent) : QHBoxLayout *custom = new QHBoxLayout; QVBoxLayout *customRadio = new QVBoxLayout; QHBoxLayout *config = new QHBoxLayout; + QHBoxLayout *full = new QHBoxLayout; QHBoxLayout *aspectL = new QHBoxLayout; FormLayout *leftAspectForm = new FormLayout; FormLayout *rightAspectForm = new FormLayout; @@ -1382,6 +1383,8 @@ AspectRatioGroup::AspectRatioGroup(const QString &title, QWidget *parent) : config->setStretch(1, 1); config->setSizeConstraint(QLayout::SetMinimumSize); + full->addWidget(new UIntRadioButton(MENU_ENUM_LABEL_VIDEO_ASPECT_RATIO_INDEX, ASPECT_RATIO_FULL)); + leftAspect->addRow(new UIntRadioButton(MENU_ENUM_LABEL_VIDEO_ASPECT_RATIO_INDEX, ASPECT_RATIO_CORE)); leftAspect->addRow(preset); @@ -1394,6 +1397,7 @@ AspectRatioGroup::AspectRatioGroup(const QString &title, QWidget *parent) : aspectL->addLayout(rightAspect); addRow(aspectL); + addRow(full); addRow(custom); connect(m_radioButton, SIGNAL(clicked(bool)), this, SLOT(onAspectRadioClicked(bool))); From 197203d09b5b20aef1c7cdbe6b2ed1f420c2ab05 Mon Sep 17 00:00:00 2001 From: Ben Templeman Date: Fri, 25 Jun 2021 13:47:23 +0100 Subject: [PATCH 14/58] Fixed monitor index corruption on Windows and added correct fractal scalling. only used when required. Updated log defines to match SR upstream. Added new SR_CONFIG_PATHS for non Winddows and Linux systems. Not that SR works on them but to fix RA compile issues Updated SR2 code base to latest. Added supprt for windows monitor indexing. Fixed monitor index bug where index 1 was not being used corretly and "auto" was not being sent. Updated swithres for x86 windows fix fixed SR2 auto issue Fixed auto monitor bug Fixed monitor index corruption on Windows Fixxed buffer size bug Added correct fractal scalling. only used when required. --- deps/switchres/display_windows.cpp | 55 ++++++++++++++++++++++++++++-- deps/switchres/log.cpp | 22 ++++++------ deps/switchres/switchres.cpp | 4 ++- gfx/video_crt_switch.c | 55 ++++++++++++++++-------------- 4 files changed, 97 insertions(+), 39 deletions(-) diff --git a/deps/switchres/display_windows.cpp b/deps/switchres/display_windows.cpp index 0372ccc916..f8186a972a 100644 --- a/deps/switchres/display_windows.cpp +++ b/deps/switchres/display_windows.cpp @@ -16,6 +16,11 @@ #include "display_windows.h" #include "log.h" +typedef struct ENUM_INFO +{ + int index; + HMONITOR h_monitor; +} ENUM_INFO; //============================================================ // windows_display::windows_display @@ -41,8 +46,54 @@ windows_display::~windows_display() // windows_display::init //============================================================ +int CALLBACK monitor_by_index(HMONITOR h_monitor, HDC, LPRECT, LPARAM data) +{ + ENUM_INFO *mon_info = (ENUM_INFO*) data; + if (--mon_info->index < 0) + { + mon_info->h_monitor = h_monitor; + return false; + } + return true; +} + bool windows_display::init() { + char display[32] = {}; + + // If monitor is passed by index, find the matching device + if (strlen(m_ds.screen) == 1) + { + int monitor_index = m_ds.screen[0] - '0'; + if (monitor_index < 0 || monitor_index > 9) + { + log_error("Switchres: bad monitor index %d\n", monitor_index); + return false; + } + + ENUM_INFO mon_info; + mon_info.index = monitor_index; + mon_info.h_monitor = NULL; + + EnumDisplayMonitors(NULL, NULL, monitor_by_index, (LPARAM)&mon_info); + if (mon_info.h_monitor != NULL) + { + MONITORINFOEXA info = {}; + info.cbSize = sizeof(info); + GetMonitorInfoA(mon_info.h_monitor, &info); + snprintf(display, sizeof(display) -1, "%s", info.szDevice); + log_info("display %s\n", display); + } + else + { + log_error("Swichres: couldn't find handle for monitor index %d\n", monitor_index); + return false; + } + } + else + strncpy(display, m_ds.screen, sizeof(display)-1); + + // Find the display by device name, or "auto" for primary display DISPLAY_DEVICEA lpDisplayDevice[DISPLAY_MAX]; int idev = 0; int found = -1; @@ -55,8 +106,8 @@ bool windows_display::init() if (EnumDisplayDevicesA(NULL, idev, &lpDisplayDevice[idev], 0) == FALSE) break; - if ((!strcmp(m_ds.screen, "auto") && (lpDisplayDevice[idev].StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE)) - || !strcmp(m_ds.screen, lpDisplayDevice[idev].DeviceName) || m_ds.screen[0] - '0' == idev) + if ((!strcmp(display, "auto") && (lpDisplayDevice[idev].StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE)) + || !strcmp(display, lpDisplayDevice[idev].DeviceName)) found = idev; idev++; diff --git a/deps/switchres/log.cpp b/deps/switchres/log.cpp index fd990422f2..3749af33d9 100644 --- a/deps/switchres/log.cpp +++ b/deps/switchres/log.cpp @@ -14,8 +14,8 @@ #include "log.h" -enum log_verbosity { NONE, ERROR, INFO, DBG }; -static log_verbosity log_level = INFO; +enum log_verbosity { NONE, SR_ERROR, SR_INFO, SR_DEBUG }; +static log_verbosity log_level = SR_INFO; void log_dummy(const char *, ...) {} @@ -36,21 +36,21 @@ LOG_ERROR log_error_bak = &log_dummy; void set_log_verbose(void *func_ptr) { - if (log_level >= DBG) + if (log_level >= SR_DEBUG) log_verbose = (LOG_VERBOSE)func_ptr; log_verbose_bak = (LOG_VERBOSE)func_ptr; } void set_log_info(void *func_ptr) { - if (log_level >= INFO) + if (log_level >= SR_INFO) log_info = (LOG_INFO)func_ptr; log_info_bak = (LOG_INFO)func_ptr; } void set_log_error(void *func_ptr) { - if (log_level >= ERROR) + if (log_level >= SR_ERROR) log_error = (LOG_ERROR)func_ptr; log_error_bak = (LOG_ERROR)func_ptr; } @@ -60,19 +60,19 @@ void set_log_verbosity(int level) // Keep the log in the enum bounds if (level < NONE) level = NONE; - if(level > DBG) - level = DBG; + if(level > SR_DEBUG) + level = SR_DEBUG; log_error = &log_dummy; log_info = &log_dummy; log_verbose = &log_dummy; - if (level >= ERROR) + if (level >= SR_ERROR) log_error = log_error_bak; - if (level >= INFO) + if (level >= SR_INFO) log_info = log_info_bak; - if (level >= DBG) + if (level >= SR_DEBUG) log_verbose = log_verbose_bak; -} +} \ No newline at end of file diff --git a/deps/switchres/switchres.cpp b/deps/switchres/switchres.cpp index b5721d9b39..527aa35aea 100644 --- a/deps/switchres/switchres.cpp +++ b/deps/switchres/switchres.cpp @@ -23,8 +23,10 @@ const string WHITESPACE = " \n\r\t\f\v"; #if defined(_WIN32) #define SR_CONFIG_PATHS ";.\\;.\\ini\\;" -#else +#elif defined(__linux__) #define SR_CONFIG_PATHS ";./;./ini/;/etc/;" +#else + #define SR_CONFIG_PATHS ";./" #endif //============================================================ diff --git a/gfx/video_crt_switch.c b/gfx/video_crt_switch.c index 9d7cd0ffba..bf6c403941 100644 --- a/gfx/video_crt_switch.c +++ b/gfx/video_crt_switch.c @@ -87,36 +87,45 @@ static void crt_aspect_ratio_switch( videocrt_switch_t *p_switch, unsigned width, unsigned height, unsigned srm_width, unsigned srm_height) { - /* send aspect float to video_driver */ - RARCH_LOG("[CRT]: Setting Video Screen Size to: %dx%d \n", width, height); - video_driver_set_size(srm_width , srm_height); - video_driver_set_viewport(srm_width , srm_height,1,1); - p_switch->fly_aspect = (float)width / (float)height; video_driver_set_aspect_ratio_value((float)p_switch->fly_aspect); RARCH_LOG("[CRT]: Setting Aspect Ratio: %f \n", (float)p_switch->fly_aspect); + RARCH_LOG("[CRT]: Setting Video Screen Size to: %dx%d \n", width, height); + video_driver_set_size(width , height); + video_driver_set_viewport(width , height,1,1); + video_driver_apply_state_changes(); } static void set_aspect(videocrt_switch_t *p_switch, unsigned int width, unsigned int height, unsigned int srm_width, unsigned srm_height, - unsigned int srm_xscale, unsigned srm_yscale) + unsigned int srm_xscale, unsigned srm_yscale, bool srm_isstretched ) { unsigned int patched_width = 0; unsigned int patched_height = 0; int scaled_width = 0; int scaled_height = 0; - /* used to fix aspect shoule SR not find a resolution */ + + /* used to fix aspect should SR not find a resolution */ if (srm_width == 0) { video_driver_get_size(&patched_width, &patched_height); + srm_xscale = 1; + srm_yscale = 1; }else{ + /* use native values as we will be multiplying by srm scale later. */ patched_width = width; patched_height = height; } + if (srm_isstretched && srm_width > 0) + { + srm_xscale = srm_width/width; + srm_yscale = srm_height/height; + } + scaled_width = roundf(patched_width*srm_xscale); scaled_height = roundf(patched_height*srm_yscale); @@ -127,22 +136,19 @@ static bool crt_sr2_init(videocrt_switch_t *p_switch, int monitor_index, unsigne { const char* err_msg; char* mode; - char index = 0; - char mindex[1]; + char index[10]; + if (monitor_index+1 >= 0 && monitor_index+1 < 10) - index = monitor_index+48; + sprintf(index, "%d", monitor_index); else - index = '0'; - - mindex[0] = index; + sprintf(index, "%s", "0"); if (!p_switch->sr2_active) { RARCH_LOG("[CRT]: SR init \n"); - sr_init(); #if (__STDC_VERSION__ >= 199409L) /* no logs for C98 or less */ sr_set_log_callback_info(RARCH_LOG); @@ -167,23 +173,22 @@ static bool crt_sr2_init(videocrt_switch_t *p_switch, int monitor_index, unsigne RARCH_LOG("[CRT]: CRT Mode: %d - Selected from ini \n", crt_mode) ; } - if (super_width >2 ) sr_set_user_mode(super_width, 0, 0); RARCH_LOG("[CRT]: SR init_disp \n"); if (monitor_index+1 > 0) { - RARCH_LOG("SRobj: RA Monitor Index: %s\n",mindex); - p_switch->rtn = sr_init_disp(mindex); - RARCH_LOG("[CRT]: SR Disp Monitor Index: %s \n", mindex); + RARCH_LOG("[CRT]: RA Monitor Index Manual: %s\n", &index[0]); + p_switch->rtn = sr_init_disp(index); + RARCH_LOG("[CRT]: SR Disp Monitor Index Manual: %s \n", &index[0]); } if (monitor_index == -1) { - RARCH_LOG("SRobj: RA Monitor Index: %s\n",NULL); - p_switch->rtn = sr_init_disp(NULL); - RARCH_LOG("[CRT]: SR Disp Monitor Index: Auto \n"); + RARCH_LOG("[CRT]: RA Monitor Index Auto: %s\n","auto"); + p_switch->rtn = sr_init_disp("auto"); + RARCH_LOG("[CRT]: SR Disp Monitor Index Auto: Auto \n"); } RARCH_LOG("[CRT]: SR rtn %d \n", p_switch->rtn); @@ -247,12 +252,12 @@ static void switch_res_crt( } p_switch->sr_core_hz = srm.refresh; - set_aspect(p_switch, w , h, srm.width, srm.height, srm.x_scale, srm.y_scale); + set_aspect(p_switch, w , h, srm.width, srm.height, srm.x_scale, srm.y_scale, srm.is_stretched); RARCH_LOG("[CRT]: SR scaled X:%d Y:%d \n",srm.x_scale, srm.y_scale); }else { - set_aspect(p_switch, width , height, width, height ,1,1); + set_aspect(p_switch, width , height, width, height ,1,1, false); video_driver_set_size(width , height); video_driver_apply_state_changes(); @@ -305,7 +310,7 @@ static void crt_fix_hh_res(videocrt_switch_t *p_switch, int native_width, int wi int corrected_height = 240; switch_res_crt(p_switch, corrected_width, corrected_height , crt_mode, corrected_width, monitor_index-1, super_width); - set_aspect(p_switch, native_width , height, native_width, height ,1,1); + set_aspect(p_switch, native_width , height, native_width, height ,1,1, false); video_driver_set_size(native_width , height); @@ -484,7 +489,7 @@ static void crt_rpi_switch(videocrt_switch_t *p_switch, int width, int height, f set_aspect(p_switch, width, height, width, height, - 1, 1); + 1, 1, false); int w = width; while (w < 1920) { From 4803100dc40aa4fe2ff65759a4370ab6ca511241 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Thu, 8 Jul 2021 20:50:54 +0200 Subject: [PATCH 15/58] (UWP/Xbox) Should fix display issues with Dolphin/PCSX2 on Xbox --- config.def.h | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/config.def.h b/config.def.h index c8bcff6917..0d6d7a8983 100644 --- a/config.def.h +++ b/config.def.h @@ -201,16 +201,21 @@ /* To start in Fullscreen, or not. */ -#if defined(HAVE_STEAM) || defined(DINGUX) -/* Start in fullscreen mode for Steam and - * Dingux builds */ +#if defined(HAVE_STEAM) || defined(DINGUX) || defined(__WINRT__) || defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP +/* Start in fullscreen mode for Steam and Dingux + * WinRT and Winapi Family builds */ #define DEFAULT_FULLSCREEN true #else #define DEFAULT_FULLSCREEN false #endif /* To use windowed mode or not when going fullscreen. */ -#define DEFAULT_WINDOWED_FULLSCREEN true +#if defined(__WINRT__) || defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP +/* Do not use windowed mode for WinRT and Winapi Family builds on the Xbox UWP with fixed resolution shrinks the image into the left top corner of the screen with some libretro cores */ +#define DEFAULT_WINDOWED_FULLSCREEN false +#else +#define DEFAULT_WINDOWED_FULLSCREEN true +#endif /* Which monitor to prefer. 0 is any monitor, 1 and up selects * specific monitors, 1 being the first monitor. */ @@ -227,6 +232,9 @@ #if defined(DINGUX) #define DEFAULT_FULLSCREEN_X 320 #define DEFAULT_FULLSCREEN_Y 240 +#elif defined(__WINRT__) || defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP +#define DEFAULT_FULLSCREEN_X 1920 +#define DEFAULT_FULLSCREEN_Y 1080 #else #define DEFAULT_FULLSCREEN_X 0 #define DEFAULT_FULLSCREEN_Y 0 From d4fb27a7a9219ed745af911899f63a18f77a69ae Mon Sep 17 00:00:00 2001 From: "Mark W. Kidd" Date: Thu, 8 Jul 2021 22:52:19 -0400 Subject: [PATCH 16/58] implement natt fix from void() --- libretro-common/include/net/net_natt.h | 3 +- libretro-common/net/net_natt.c | 41 ++++++++++++++++---------- tasks/task_netplay_nat_traversal.c | 5 +--- 3 files changed, 28 insertions(+), 21 deletions(-) diff --git a/libretro-common/include/net/net_natt.h b/libretro-common/include/net/net_natt.h index 74ca3164ac..8634dc3e73 100644 --- a/libretro-common/include/net/net_natt.h +++ b/libretro-common/include/net/net_natt.h @@ -62,7 +62,8 @@ struct natt_status /** * Initialize global NAT traversal structures (must be called once to use other * functions) */ -void natt_init(void); +void natt_init(struct natt_status *status, + uint16_t port, enum socket_protocol proto); /** Initialize a NAT traversal status object */ bool natt_new(struct natt_status *status); diff --git a/libretro-common/net/net_natt.c b/libretro-common/net/net_natt.c index c8ce68761f..a345af98dc 100644 --- a/libretro-common/net/net_natt.c +++ b/libretro-common/net/net_natt.c @@ -47,7 +47,13 @@ static struct UPNPUrls urls; static struct IGDdatas data; #endif -void natt_init(void) +/* + natt_open_port_any(ntsd->nat_traversal_state, + ntsd->port, SOCKET_PROTOCOL_TCP); +*/ + +void natt_init(struct natt_status *status, + uint16_t port, enum socket_protocol proto) { #ifndef HAVE_SOCKET_LEGACY #if HAVE_MINIUPNPC @@ -56,8 +62,6 @@ void natt_init(void) char * descXML; int descXMLsize = 0; int upnperror = 0; - memset(&urls, 0, sizeof(struct UPNPUrls)); - memset(&data, 0, sizeof(struct IGDdatas)); devlist = upnpDiscover(2000, NULL, NULL, 0, 0, 2, &upnperror); if (devlist) { @@ -65,22 +69,27 @@ void natt_init(void) while (dev) { if (strstr (dev->st, "InternetGatewayDevice")) - break; + { + memset(&urls, 0, sizeof(struct UPNPUrls)); + memset(&data, 0, sizeof(struct IGDdatas)); + descXML = (char *) miniwget(dev->descURL, &descXMLsize, 0, NULL); + if (descXML) + { + parserootdesc(descXML, descXMLsize, &data); + free (descXML); + descXML = 0; + + GetUPNPUrls (&urls, &data, dev->descURL, 0); + } + if(natt_open_port_any(status, port, proto)) + goto end; + + } dev = dev->pNext; } - if (!dev) - dev = devlist; - - descXML = (char *) miniwget(dev->descURL, &descXMLsize, 0, NULL); - if (descXML) - { - parserootdesc(descXML, descXMLsize, &data); - free (descXML); - descXML = 0; - GetUPNPUrls (&urls, &data, dev->descURL, 0); - } - freeUPNPDevlist(devlist); } +end: + freeUPNPDevlist(devlist); #endif #endif } diff --git a/tasks/task_netplay_nat_traversal.c b/tasks/task_netplay_nat_traversal.c index b645ef93d0..4068072df5 100644 --- a/tasks/task_netplay_nat_traversal.c +++ b/tasks/task_netplay_nat_traversal.c @@ -51,11 +51,8 @@ static void task_netplay_nat_traversal_handler(retro_task_t *task) struct nat_traversal_state_data *ntsd = (struct nat_traversal_state_data *) task->task_data; - natt_init(); - if (natt_new(ntsd->nat_traversal_state)) - natt_open_port_any(ntsd->nat_traversal_state, - ntsd->port, SOCKET_PROTOCOL_TCP); + natt_init(ntsd->nat_traversal_state, ntsd->port, SOCKET_PROTOCOL_TCP); task_set_progress(task, 100); task_set_finished(task, true); From c10bac65588666e7cbe6387f4d8b593d3b7393ef Mon Sep 17 00:00:00 2001 From: sonninnos Date: Fri, 9 Jul 2021 16:06:56 +0300 Subject: [PATCH 17/58] AV_INFO logging details --- retroarch.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/retroarch.c b/retroarch.c index ba459f266b..1d22d09157 100644 --- a/retroarch.c +++ b/retroarch.c @@ -18137,7 +18137,11 @@ static bool rarch_environment_cb(unsigned cmd, void *data) DRIVERS_CMD_ALL & ~(DRIVER_VIDEO_MASK | DRIVER_INPUT_MASK | DRIVER_MENU_MASK) : DRIVERS_CMD_ALL; - RARCH_LOG("[Environ]: SET_SYSTEM_AV_INFO.\n"); + RARCH_LOG("[Environ]: SET_SYSTEM_AV_INFO: %ux%u, aspect: %.3f, fps: %.3f, sample rate: %.2f Hz.\n", + (*info)->geometry.base_width, (*info)->geometry.base_height, + (*info)->geometry.aspect_ratio, + (*info)->timing.fps, + (*info)->timing.sample_rate); memcpy(av_info, *info, sizeof(*av_info)); command_event(CMD_EVENT_REINIT, &reinit_flags); From b3c929499ec294ea51a54c79e3d6175664676007 Mon Sep 17 00:00:00 2001 From: Nicolas Roehm Date: Sat, 10 Jul 2021 14:10:12 +0200 Subject: [PATCH 18/58] [Upd] error message --- input/drivers/rwebinput_input.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/input/drivers/rwebinput_input.c b/input/drivers/rwebinput_input.c index be4b631bde..58ae91b6ab 100644 --- a/input/drivers/rwebinput_input.c +++ b/input/drivers/rwebinput_input.c @@ -315,7 +315,7 @@ static void *rwebinput_input_init(const char *joypad_driver) if (r != EMSCRIPTEN_RESULT_SUCCESS) { RARCH_ERR( - "[EMSCRIPTEN/INPUT] failed to create keydown callback: %d\n", r); + "[EMSCRIPTEN/INPUT] failed to create keyup callback: %d\n", r); } r = emscripten_set_keypress_callback( From 902949ea941823d0c17ffea1610bafbdd866da4d Mon Sep 17 00:00:00 2001 From: MrHuu Date: Sun, 11 Jul 2021 13:04:22 +0200 Subject: [PATCH 19/58] (3DS) Add ID for genesis_plus_gx_wide core --- pkg/ctr/Makefile.cores | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/pkg/ctr/Makefile.cores b/pkg/ctr/Makefile.cores index c3645f0502..aad59746d0 100644 --- a/pkg/ctr/Makefile.cores +++ b/pkg/ctr/Makefile.cores @@ -197,6 +197,13 @@ else ifeq ($(LIBRETRO), genesis_plus_gx) APP_ICON = pkg/ctr/assets/genesis_plus_gx.png APP_BANNER = pkg/ctr/assets/genesis_plus_gx_banner.png +else ifeq ($(LIBRETRO), genesis_plus_gx_wide) + APP_TITLE = Genesis Plus GX Libretro Wide + APP_PRODUCT_CODE = RARCH-GENPLUSGXWIDE + APP_UNIQUE_ID = 0xBACE0 + APP_ICON = pkg/ctr/assets/genesis_plus_gx.png + APP_BANNER = pkg/ctr/assets/genesis_plus_gx_banner.png + else ifeq ($(LIBRETRO), gme) APP_TITLE = GME APP_PRODUCT_CODE = RARCH-GME @@ -631,6 +638,7 @@ else ifeq ($(LIBRETRO), x1) APP_UNIQUE_ID = 0xBAC99 APP_ICON = pkg/ctr/assets/default.png APP_BANNER = pkg/ctr/assets/libretro_banner.png + else ifeq ($(LIBRETRO), xrick) APP_TITLE = XRick APP_PRODUCT_CODE = RARCH-XRICK From 57c52e4fc722e626df50e2c36e19180a5d187e93 Mon Sep 17 00:00:00 2001 From: MrHuu Date: Sun, 11 Jul 2021 15:03:10 +0200 Subject: [PATCH 20/58] (3DS) Add unique ID's add lowresnx add vice_xcbm5x0 add vice_xscpu64 --- pkg/ctr/Makefile.cores | 84 ++++++++++++++++++++++++++---------------- 1 file changed, 52 insertions(+), 32 deletions(-) diff --git a/pkg/ctr/Makefile.cores b/pkg/ctr/Makefile.cores index aad59746d0..be73907225 100644 --- a/pkg/ctr/Makefile.cores +++ b/pkg/ctr/Makefile.cores @@ -34,13 +34,6 @@ else ifeq ($(LIBRETRO), bluemsx) APP_ICON = pkg/ctr/assets/bluemsx.png APP_BANNER = pkg/ctr/assets/bluemsx_banner.png -else ifeq ($(LIBRETRO), chailove) - APP_TITLE = ChaiLove - APP_PRODUCT_CODE = RARCH-CHAILOVE - APP_UNIQUE_ID = 0xBACB2 - APP_ICON = pkg/ctr/assets/default.png - APP_BANNER = pkg/ctr/assets/libretro_banner.png - else ifeq ($(LIBRETRO), cap32) APP_TITLE = Caprice32 APP_AUTHOR = various @@ -49,6 +42,13 @@ else ifeq ($(LIBRETRO), cap32) APP_ICON = pkg/ctr/assets/Caprice32.png APP_BANNER = pkg/ctr/assets/Caprice32_banner.png +else ifeq ($(LIBRETRO), chailove) + APP_TITLE = ChaiLove + APP_PRODUCT_CODE = RARCH-CHAILOVE + APP_UNIQUE_ID = 0xBACB2 + APP_ICON = pkg/ctr/assets/default.png + APP_BANNER = pkg/ctr/assets/libretro_banner.png + else ifeq ($(LIBRETRO), crocods) APP_TITLE = CROCODS APP_PRODUCT_CODE = RARCH-CROCODS @@ -88,15 +88,6 @@ else ifeq ($(LIBRETRO), fbalpha2012) APP_ICON = pkg/ctr/assets/fbalpha2012.png APP_BANNER = pkg/ctr/assets/fbalpha2012_banner.png -else ifeq ($(LIBRETRO), fbalpha2012_neogeo) - APP_TITLE = Final Burn Alpha 2012 - NeoGeo - APP_AUTHOR = Team FB Alpha - APP_PRODUCT_CODE = RARCH-FBANEOGEO - APP_UNIQUE_ID = 0xBAC10 - APP_ICON = pkg/ctr/assets/fbalpha2012_neogeo.png - APP_BANNER = pkg/ctr/assets/fbalpha2012_neogeo_banner.png - APP_SYSTEM_MODE = 80MB - else ifeq ($(LIBRETRO), fbalpha2012_cps1) APP_TITLE = Final Burn Alpha 2012 - CPS-1 APP_AUTHOR = Team FB Alpha @@ -123,6 +114,15 @@ else ifeq ($(LIBRETRO), fbalpha2012_cps3) APP_BANNER = pkg/ctr/assets/fbalpha2012_cps3_banner.png APP_SYSTEM_MODE = 80MB +else ifeq ($(LIBRETRO), fbalpha2012_neogeo) + APP_TITLE = Final Burn Alpha 2012 - NeoGeo + APP_AUTHOR = Team FB Alpha + APP_PRODUCT_CODE = RARCH-FBANEOGEO + APP_UNIQUE_ID = 0xBAC10 + APP_ICON = pkg/ctr/assets/fbalpha2012_neogeo.png + APP_BANNER = pkg/ctr/assets/fbalpha2012_neogeo_banner.png + APP_SYSTEM_MODE = 80MB + else ifeq ($(LIBRETRO), fbneo) APP_TITLE = FinalBurn Neo APP_AUTHOR = Team FBNeo @@ -160,13 +160,6 @@ else ifeq ($(LIBRETRO), freechaf) APP_ICON = pkg/ctr/assets/default.png APP_BANNER = pkg/ctr/assets/libretro_banner.png -else ifeq ($(LIBRETRO), frodo) - APP_TITLE = Frodo - APP_PRODUCT_CODE = RARCH-FRODO - APP_UNIQUE_ID = 0xBACB9 - APP_ICON = pkg/ctr/assets/default.png - APP_BANNER = pkg/ctr/assets/libretro_banner.png - else ifeq ($(LIBRETRO), freeintv) APP_TITLE = FreeIntv APP_AUTHOR = various @@ -175,6 +168,13 @@ else ifeq ($(LIBRETRO), freeintv) APP_ICON = pkg/ctr/assets/freeintv.png APP_BANNER = pkg/ctr/assets/freeintv_banner.png +else ifeq ($(LIBRETRO), frodo) + APP_TITLE = Frodo + APP_PRODUCT_CODE = RARCH-FRODO + APP_UNIQUE_ID = 0xBACB9 + APP_ICON = pkg/ctr/assets/default.png + APP_BANNER = pkg/ctr/assets/libretro_banner.png + else ifeq ($(LIBRETRO), fuse) APP_TITLE = Fuse APP_AUTHOR = various @@ -233,6 +233,13 @@ else ifeq ($(LIBRETRO), handy) APP_ICON = pkg/ctr/assets/handy.png APP_BANNER = pkg/ctr/assets/handy_banner.png +else ifeq ($(LIBRETRO), lowresnx) + APP_TITLE = LowRes NX + APP_PRODUCT_CODE = RARCH-LOWRESNX + APP_UNIQUE_ID = 0xBACD1 + APP_ICON = pkg/ctr/assets/default.png + APP_BANNER = pkg/ctr/assets/libretro_banner.png + else ifeq ($(LIBRETRO), hatari) APP_TITLE = Hatari APP_PRODUCT_CODE = RARCH-HATARI @@ -308,14 +315,6 @@ else ifeq ($(LIBRETRO), mgba) APP_ICON = pkg/ctr/assets/mgba.png APP_BANNER = pkg/ctr/assets/mgba_banner.png -else ifeq ($(LIBRETRO), nekop2) - APP_TITLE = Neko Project 2 - APP_AUTHOR = various - APP_PRODUCT_CODE = RARCH-NP2 - APP_UNIQUE_ID = 0xBAC1C - APP_ICON = pkg/ctr/assets/nekop2.png - APP_BANNER = pkg/ctr/assets/nekop2_banner.png - else ifeq ($(LIBRETRO), mrboom) APP_TITLE = MrBoom APP_PRODUCT_CODE = RARCH-MRBOOM @@ -330,6 +329,14 @@ else ifeq ($(LIBRETRO), mu) APP_ICON = pkg/ctr/assets/MU.png APP_BANNER = pkg/ctr/assets/MU_banner.png +else ifeq ($(LIBRETRO), nekop2) + APP_TITLE = Neko Project 2 + APP_AUTHOR = various + APP_PRODUCT_CODE = RARCH-NP2 + APP_UNIQUE_ID = 0xBAC1C + APP_ICON = pkg/ctr/assets/nekop2.png + APP_BANNER = pkg/ctr/assets/nekop2_banner.png + else ifeq ($(LIBRETRO), neocd) APP_TITLE = NeoCD APP_PRODUCT_CODE = RARCH-NEOCD @@ -399,7 +406,6 @@ else ifeq ($(LIBRETRO), pocketcdg) APP_ICON = pkg/ctr/assets/default.png APP_BANNER = pkg/ctr/assets/libretro_banner.png - else ifeq ($(LIBRETRO), pokemini) APP_TITLE = PokeMini APP_AUTHOR = justburn @@ -604,6 +610,13 @@ else ifeq ($(LIBRETRO), vice_xcbm2) APP_ICON = pkg/ctr/assets/default.png APP_BANNER = pkg/ctr/assets/libretro_banner.png +else ifeq ($(LIBRETRO), vice_xcbm5x0) + APP_TITLE = VICE xcbm5x0 + APP_PRODUCT_CODE = RARCH-VICE-XCBM5X0 + APP_UNIQUE_ID = 0xBACD2 + APP_ICON = pkg/ctr/assets/default.png + APP_BANNER = pkg/ctr/assets/libretro_banner.png + else ifeq ($(LIBRETRO), vice_xpet) APP_TITLE = VICE xpet APP_PRODUCT_CODE = RARCH-VICE-XPET @@ -618,6 +631,13 @@ else ifeq ($(LIBRETRO), vice_xplus4) APP_ICON = pkg/ctr/assets/default.png APP_BANNER = pkg/ctr/assets/libretro_banner.png +else ifeq ($(LIBRETRO), vice_xscpu64) + APP_TITLE = VICE xscpu64 + APP_PRODUCT_CODE = RARCH-VICE-XSCPU64 + APP_UNIQUE_ID = 0xBACD3 + APP_ICON = pkg/ctr/assets/default.png + APP_BANNER = pkg/ctr/assets/libretro_banner.png + else ifeq ($(LIBRETRO), vice_xvic) APP_TITLE = VICE xvic APP_PRODUCT_CODE = RARCH-VICE-XVIC From 89b46bc24695da8431f869967e3cb2b30664dc26 Mon Sep 17 00:00:00 2001 From: CrystalCT Date: Mon, 12 Jul 2021 09:35:44 +0200 Subject: [PATCH 21/58] First basic RSX driver for PSL1GHT --- Makefile.psl1ght | 2 +- gfx/drivers/rsx_gfx.c | 246 +++++++----- gfx/drivers_context/psl1ght_ctx.c | 351 ++++++++++++++++++ griffin/griffin.c | 4 +- libretro-common/include/defines/ps3_defines.h | 3 + retroarch.c | 1 + retroarch.h | 3 +- 7 files changed, 510 insertions(+), 100 deletions(-) create mode 100755 gfx/drivers_context/psl1ght_ctx.c diff --git a/Makefile.psl1ght b/Makefile.psl1ght index 892406cf44..6ce56f09ca 100644 --- a/Makefile.psl1ght +++ b/Makefile.psl1ght @@ -66,7 +66,7 @@ endif SHARED_FLAGS := SHARED_FLAGS += -DHAVE_VIDEO_LAYOUT -SHARED_FLAGS += -DHAVE_MENU -DHAVE_CONFIGFILE -DHAVE_PATCH -DHAVE_CHEATS -DRARCH_CONSOLE -DHAVE_OVERLAY -DHAVE_HEADSET -DHAVE_CG -DHAVE_CG_RUNTIME_COMPILER -DHAVE_GCMGL -DHAVE_SYSMODULES -DHAVE_SYSUTILS -DHAVE_RARCH_EXEC -DHAVE_MOUSE -DHAVE_ZLIB -DHAVE_RPNG -DHAVE_GRIFFIN=1 -DHAVE_NETWORKING=1 -DHAVE_SOCKET_LEGACY=1 -DPC_DEVELOPMENT_IP_ADDRESS=\"$(PC_DEVELOPMENT_IP_ADDRESS)\" -DPC_DEVELOPMENT_UDP_PORT=$(PC_DEVELOPMENT_UDP_PORT) -Wno-char-subscripts -DHAVE_CC_RESAMPLER -DRARCH_INTERNAL -DHAVE_SCREENSHOTS -DHAVE_REWIND -DHAVE_MULTIMAN -DHAVE_RGUI +SHARED_FLAGS += -DHAVE_MENU -DHAVE_CONFIGFILE -DHAVE_PATCH -DHAVE_CHEATS -DRARCH_CONSOLE -DHAVE_OVERLAY -DHAVE_HEADSET -DHAVE_CG -DHAVE_CG_RUNTIME_COMPILER -DHAVE_SYSMODULES -DHAVE_SYSUTILS -DHAVE_RARCH_EXEC -DHAVE_MOUSE -DHAVE_ZLIB -DHAVE_RPNG -DHAVE_GRIFFIN=1 -DHAVE_NETWORKING=1 -DHAVE_SOCKET_LEGACY=1 -DPC_DEVELOPMENT_IP_ADDRESS=\"$(PC_DEVELOPMENT_IP_ADDRESS)\" -DPC_DEVELOPMENT_UDP_PORT=$(PC_DEVELOPMENT_UDP_PORT) -Wno-char-subscripts -DHAVE_CC_RESAMPLER -DRARCH_INTERNAL -DHAVE_SCREENSHOTS -DHAVE_REWIND -DHAVE_MULTIMAN -DHAVE_RGUI CFLAGS += -std=gnu99 $(SHARED_FLAGS) CXXFLAGS += $(SHARED_FLAGS) diff --git a/gfx/drivers/rsx_gfx.c b/gfx/drivers/rsx_gfx.c index 1fa86f06a1..01ea8183e7 100644 --- a/gfx/drivers/rsx_gfx.c +++ b/gfx/drivers/rsx_gfx.c @@ -65,6 +65,10 @@ #define MAX_BUFFERS 2 +#define rsx_context_bind_hw_render(rsx, enable) \ + if (rsx->shared_context_use) \ + rsx->ctx_driver->bind_hw_render(rsx->ctx_data, enable) + typedef struct { int height; @@ -81,21 +85,20 @@ typedef struct float u; float y; float x; -} gcm_scale_vector_t; +} rsx_scale_vector_t; typedef struct { s16 x0, y0, x1, y1; s16 u0, v0, u1, v1; -} gcm_vertex_t; +} rsx_vertex_t; -typedef struct gcm_video -{ +typedef struct { video_viewport_t vp; rsxBuffer buffers[MAX_BUFFERS]; rsxBuffer menuBuffers[MAX_BUFFERS]; int currentBuffer, menuBuffer; - gcmContextData *context; + gcmContextData* context; u16 width; u16 height; bool menu_frame_enable; @@ -103,24 +106,62 @@ typedef struct gcm_video bool vsync; u32 depth_pitch; u32 depth_offset; - u32 *depth_buffer; + u32* depth_buffer; bool smooth; unsigned rotation; bool keep_aspect; bool should_resize; bool msg_rendering_enabled; -} gcm_video_t; + + const shader_backend_t* shader; + void* shader_data; + void* renderchain_data; + void* ctx_data; + const gfx_ctx_driver_t* ctx_driver; + bool shared_context_use; + + video_info_t video_info; + struct video_tex_info tex_info; /* unsigned int alignment */ + struct video_tex_info prev_info[GFX_MAX_TEXTURES]; /* unsigned alignment */ + struct video_fbo_rect fbo_rect[GFX_MAX_SHADERS]; /* unsigned alignment */ +} rsx_t; + +static const gfx_ctx_driver_t* rsx_get_context(rsx_t* rsx) +{ + const gfx_ctx_driver_t* gfx_ctx = NULL; + void* ctx_data = NULL; + settings_t* settings = config_get_ptr(); + struct retro_hw_render_callback* hwr = video_driver_get_hw_context(); + + bool video_shared_context = settings->bools.video_shared_context; + enum gfx_ctx_api api = GFX_CTX_RSX_API; + + rsx->shared_context_use = video_shared_context && hwr->context_type != RETRO_HW_CONTEXT_NONE; + + if ((libretro_get_shared_context()) + && (hwr->context_type != RETRO_HW_CONTEXT_NONE)) + rsx->shared_context_use = true; + + gfx_ctx = video_context_driver_init_first(rsx, + settings->arrays.video_context_driver, + api, 1, 0, rsx->shared_context_use, &ctx_data); + + if (ctx_data) + rsx->ctx_data = ctx_data; + + return gfx_ctx; +} #ifndef HAVE_THREADS -static bool gcm_tasks_finder(retro_task_t *task,void *userdata) +static bool rsx_tasks_finder(retro_task_t *task,void *userdata) { return task; } -task_finder_data_t gcm_tasks_finder_data = {gcm_tasks_finder, NULL}; +task_finder_data_t rsx_tasks_finder_data = {rsx_tasks_finder, NULL}; #endif -static int gcm_make_buffer(rsxBuffer * buffer, u16 width, u16 height, int id) +static int rsx_make_buffer(rsxBuffer * buffer, u16 width, u16 height, int id) { int depth = sizeof(u32); int pitch = depth * width; @@ -150,7 +191,7 @@ error: return FALSE; } -static int gcm_flip(gcmContextData *context, s32 buffer) +static int rsx_flip(gcmContextData *context, s32 buffer) { if (gcmSetFlip(context, buffer) == 0) { @@ -165,16 +206,16 @@ static int gcm_flip(gcmContextData *context, s32 buffer) #define GCM_LABEL_INDEX 255 -static void gcm_wait_rsx_idle(gcmContextData *context); +static void rsx_wait_rsx_idle(gcmContextData *context); -static void gcm_wait_flip(void) +static void rsx_wait_flip(void) { while (gcmGetFlipStatus() != 0) usleep (200); /* Sleep, to not stress the cpu. */ gcmResetFlipStatus(); } -static gcmContextData *gcm_init_screen(gcm_video_t* gcm) +static gcmContextData *rsx_init_screen(rsx_t* gcm) { /* Context to keep track of the RSX buffer. */ gcmContextData *context = NULL; @@ -230,7 +271,7 @@ static gcmContextData *gcm_init_screen(gcm_video_t* gcm) gcm->width = res.width; gcm->height = res.height; - gcm_wait_rsx_idle(context); + rsx_wait_rsx_idle(context); if (videoConfigure (0, &vconfig, NULL, 0) != 0) goto error; @@ -241,7 +282,8 @@ static gcmContextData *gcm_init_screen(gcm_video_t* gcm) gcmSetFlipMode (GCM_FLIP_VSYNC); /* Wait for VSYNC to flip */ gcm->depth_pitch = res.width * sizeof(u32); - gcm->depth_buffer = (u32 *) rsxMemalign (64, (res.height * gcm->depth_pitch)* 2); + gcm->depth_buffer = (u32 *) rsxMemalign (64, (res.height * gcm->depth_pitch)); //Beware, if was (res.height * gcm->depth_pitch)*2 + rsxAddressToOffset (gcm->depth_buffer, &gcm->depth_offset); gcmResetFlipStatus(); @@ -273,7 +315,7 @@ static void waitFinish(gcmContextData *context, u32 sLabelVal) sLabelVal++; } -static void gcm_wait_rsx_idle(gcmContextData *context) +static void rsx_wait_rsx_idle(gcmContextData *context) { u32 sLabelVal = 1; @@ -285,35 +327,43 @@ static void gcm_wait_rsx_idle(gcmContextData *context) waitFinish(context, sLabelVal); } -static void* gcm_init(const video_info_t* video, +static void* rsx_init(const video_info_t* video, input_driver_t** input, void** input_data) { int i; - gcm_video_t* gcm = malloc(sizeof(gcm_video_t)); + rsx_t* rsx = malloc(sizeof(rsx_t)); - if (!gcm) + if (!rsx) return NULL; - memset(gcm, 0, sizeof(gcm_video_t)); + memset(rsx, 0, sizeof(rsx_t)); - gcm->context = gcm_init_screen(gcm); + rsx->context = rsx_init_screen(rsx); + const gfx_ctx_driver_t* ctx_driver = rsx_get_context(rsx); + + if (!ctx_driver) + return NULL; + + video_context_driver_set((const gfx_ctx_driver_t*)ctx_driver); + rsx->ctx_driver = ctx_driver; + rsx->video_info = *video; for (i = 0; i < MAX_BUFFERS; i++) - gcm_make_buffer(&gcm->buffers[i], gcm->width, gcm->height, i); + rsx_make_buffer(&rsx->buffers[i], rsx->width, rsx->height, i); for (i = 0; i < MAX_BUFFERS; i++) - gcm_make_buffer(&gcm->menuBuffers[i], gcm->width, gcm->height, i + MAX_BUFFERS); + rsx_make_buffer(&rsx->menuBuffers[i], rsx->width, rsx->height, i + MAX_BUFFERS); - gcm_flip(gcm->context, MAX_BUFFERS - 1); + rsx_flip(rsx->context, MAX_BUFFERS - 1); - gcm->vp.x = 0; - gcm->vp.y = 0; - gcm->vp.width = gcm->width; - gcm->vp.height = gcm->height; - gcm->vp.full_width = gcm->width; - gcm->vp.full_height = gcm->height; - gcm->rgb32 = video->rgb32; - video_driver_set_size(gcm->vp.width, gcm->vp.height); + rsx->vp.x = 0; + rsx->vp.y = 0; + rsx->vp.width = rsx->width; + rsx->vp.height = rsx->height; + rsx->vp.full_width = rsx->width; + rsx->vp.full_height = rsx->height; + rsx->rgb32 = video->rgb32; + video_driver_set_size(rsx->vp.width, rsx->vp.height); if (input && input_data) { @@ -322,17 +372,19 @@ static void* gcm_init(const video_info_t* video, *input_data = ps3input; } - return gcm; + rsx_context_bind_hw_render(rsx, true); + + return rsx; } -static void gcm_fill_black(uint32_t *dst, uint32_t *dst_end, size_t sz) +static void rsx_fill_black(uint32_t *dst, uint32_t *dst_end, size_t sz) { if (sz > dst_end - dst) sz = dst_end - dst; memset (dst, 0, sz * 4); } -static void gcm_blit_buffer( +static void rsx_blit_buffer( rsxBuffer *buffer, const void *frame, unsigned width, unsigned height, unsigned pitch, int rgb32, bool do_scaling) { @@ -379,7 +431,7 @@ static void gcm_blit_buffer( for (i = 0; i < height; i++) { memcpy(dst, src, width * 4); - gcm_fill_black(dst + width, dst_end, buffer->width - width); + rsx_fill_black(dst + width, dst_end, buffer->width - width); dst += buffer->width; src += pitch; } @@ -397,7 +449,7 @@ static void gcm_blit_buffer( u8 b = ((rgb565 << 3) & 0xfc); *dst = (r<<16) | (g<<8) | b; } - gcm_fill_black(dst, dst_end, buffer->width - width); + rsx_fill_black(dst, dst_end, buffer->width - width); dst += buffer->width - width; src += pitch / 2 - width; @@ -419,7 +471,7 @@ static void gcm_blit_buffer( dst[l * buffer->width] = c; } for (int l = 0; l < scale; l++) - gcm_fill_black(dst + l * buffer->width, dst_end, buffer->width - width * scale); + rsx_fill_black(dst + l * buffer->width, dst_end, buffer->width - width * scale); dst += buffer->width * scale - width * scale; src += pitch / 4 - width; @@ -440,7 +492,7 @@ static void gcm_blit_buffer( dst[l * buffer->width] = c; } for (int l = 0; l < scale; l++) - gcm_fill_black(dst + l * buffer->width, dst_end, buffer->width - width * scale); + rsx_fill_black(dst + l * buffer->width, dst_end, buffer->width - width * scale); dst += buffer->width * scale - width * scale; src += pitch / 2 - width; @@ -452,25 +504,25 @@ static void gcm_blit_buffer( memset(dst, 0, 4 * (dst_end - dst)); } -static void gcm_update_screen(gcm_video_t *gcm) +static void rsx_update_screen(rsx_t* gcm) { rsxBuffer *buffer = gcm->menu_frame_enable ? &gcm->menuBuffers[gcm->menuBuffer] : &gcm->buffers[gcm->currentBuffer]; - gcm_flip(gcm->context, buffer->id); + rsx_flip(gcm->context, buffer->id); if (gcm->vsync) - gcm_wait_flip(); + rsx_wait_flip(); #ifdef HAVE_SYSUTILS cellSysutilCheckCallback(); #endif } -static bool gcm_frame(void* data, const void* frame, +static bool rsx_frame(void* data, const void* frame, unsigned width, unsigned height, uint64_t frame_count, unsigned pitch, const char* msg, video_frame_info_t *video_info) { - gcm_video_t *gcm = (gcm_video_t*)data; + rsx_t* gcm = (rsx_t*)data; #ifdef HAVE_MENU bool statistics_show = video_info->statistics_show; struct font_params *osd_params = (struct font_params*) @@ -482,13 +534,13 @@ static bool gcm_frame(void* data, const void* frame, gcm->currentBuffer++; if (gcm->currentBuffer >= MAX_BUFFERS) gcm->currentBuffer = 0; - gcm_blit_buffer( + rsx_blit_buffer( &gcm->buffers[gcm->currentBuffer], frame, width, height, pitch, gcm->rgb32, true); } /* TODO: translucid menu */ - gcm_update_screen(gcm); + rsx_update_screen(gcm); return true; @@ -505,38 +557,38 @@ static bool gcm_frame(void* data, const void* frame, return true; } -static void gcm_set_nonblock_state(void* data, bool toggle, +static void rsx_set_nonblock_state(void* data, bool toggle, bool a, unsigned b) { - gcm_video_t* gcm = (gcm_video_t*)data; + rsx_t* gcm = (rsx_t*)data; if (gcm) gcm->vsync = !toggle; } -static bool gcm_alive(void* data) +static bool rsx_alive(void* data) { (void)data; return true; } -static bool gcm_focus(void* data) +static bool rsx_focus(void* data) { (void)data; return true; } -static bool gcm_suppress_screensaver(void* data, bool enable) +static bool rsx_suppress_screensaver(void* data, bool enable) { (void)data; (void)enable; return false; } -static void gcm_free(void* data) +static void rsx_free(void* data) { int i; - gcm_video_t* gcm = (gcm_video_t*)data; + rsx_t* gcm = (rsx_t*)data; if (!gcm) return; @@ -554,38 +606,38 @@ static void gcm_free(void* data) free (gcm); } -static void gcm_set_texture_frame(void* data, const void* frame, bool rgb32, +static void rsx_set_texture_frame(void* data, const void* frame, bool rgb32, unsigned width, unsigned height, float alpha) { - gcm_video_t* gcm = (gcm_video_t*)data; + rsx_t* gcm = (rsx_t*)data; int newBuffer = gcm->menuBuffer + 1; if (newBuffer >= MAX_BUFFERS) newBuffer = 0; /* TODO: respect alpha */ - gcm_blit_buffer(&gcm->menuBuffers[newBuffer], frame, width, height, + rsx_blit_buffer(&gcm->menuBuffers[newBuffer], frame, width, height, width * (rgb32 ? 4 : 2), rgb32, true); gcm->menuBuffer = newBuffer; - gcm_update_screen(gcm); + rsx_update_screen(gcm); } -static void gcm_set_texture_enable(void* data, bool state, bool full_screen) +static void rsx_set_texture_enable(void* data, bool state, bool full_screen) { - gcm_video_t* gcm = (gcm_video_t*)data; + rsx_t* gcm = (rsx_t*)data; if (!gcm) return; gcm->menu_frame_enable = state; - gcm_update_screen(gcm); + rsx_update_screen(gcm); } -static void gcm_set_rotation(void* data, unsigned rotation) +static void rsx_set_rotation(void* data, unsigned rotation) { - gcm_video_t* gcm = (gcm_video_t*)data; + rsx_t* gcm = (rsx_t*)data; if (!gcm) return; @@ -593,17 +645,17 @@ static void gcm_set_rotation(void* data, unsigned rotation) gcm->rotation = rotation; gcm->should_resize = true; } -static void gcm_set_filtering(void* data, unsigned index, bool smooth) +static void rsx_set_filtering(void* data, unsigned index, bool smooth) { - gcm_video_t* gcm = (gcm_video_t*)data; + rsx_t* gcm = (rsx_t*)data; if (gcm) gcm->smooth = smooth; } -static void gcm_set_aspect_ratio(void* data, unsigned aspect_ratio_idx) +static void rsx_set_aspect_ratio(void* data, unsigned aspect_ratio_idx) { - gcm_video_t *gcm = (gcm_video_t*)data; + rsx_t* gcm = (rsx_t*)data; if(!gcm) return; @@ -612,58 +664,58 @@ static void gcm_set_aspect_ratio(void* data, unsigned aspect_ratio_idx) gcm->should_resize = true; } -static void gcm_apply_state_changes(void* data) +static void rsx_apply_state_changes(void* data) { - gcm_video_t* gcm = (gcm_video_t*)data; + rsx_t* gcm = (rsx_t*)data; if (gcm) gcm->should_resize = true; } -static void gcm_viewport_info(void* data, struct video_viewport* vp) +static void rsx_viewport_info(void* data, struct video_viewport* vp) { - gcm_video_t* gcm = (gcm_video_t*)data; + rsx_t* gcm = (rsx_t*)data; if (gcm) *vp = gcm->vp; } -static void gcm_set_osd_msg(void *data, +static void rsx_set_osd_msg(void *data, video_frame_info_t *video_info, const char *msg, const void *params, void *font) { - gcm_video_t* gcm = (gcm_video_t*)data; + rsx_t* gcm = (rsx_t*)data; if (gcm && gcm->msg_rendering_enabled) font_driver_render_msg(data, msg, params, font); } -static uint32_t gcm_get_flags(void *data) +static uint32_t rsx_get_flags(void *data) { uint32_t flags = 0; return flags; } -static const video_poke_interface_t gcm_poke_interface = { - gcm_get_flags, +static const video_poke_interface_t rsx_poke_interface = { + rsx_get_flags, NULL, /* load_texture */ NULL, /* unload_texture */ NULL, NULL, - gcm_set_filtering, + rsx_set_filtering, NULL, /* get_video_output_size */ NULL, /* get_video_output_prev */ NULL, /* get_video_output_next */ NULL, /* get_current_framebuffer */ NULL, - gcm_set_aspect_ratio, - gcm_apply_state_changes, - gcm_set_texture_frame, - gcm_set_texture_enable, - gcm_set_osd_msg, + rsx_set_aspect_ratio, + rsx_apply_state_changes, + rsx_set_texture_frame, + rsx_set_texture_enable, + rsx_set_osd_msg, NULL, /* show_mouse */ NULL, /* grab_mouse_toggle */ NULL, /* get_current_shader */ @@ -671,14 +723,14 @@ static const video_poke_interface_t gcm_poke_interface = { NULL /* get_hw_render_interface */ }; -static void gcm_get_poke_interface(void* data, +static void rsx_get_poke_interface(void* data, const video_poke_interface_t** iface) { (void)data; - *iface = &gcm_poke_interface; + *iface = &rsx_poke_interface; } -static bool gcm_set_shader(void* data, +static bool rsx_set_shader(void* data, enum rarch_shader_type type, const char* path) { (void)data; @@ -690,19 +742,19 @@ static bool gcm_set_shader(void* data, video_driver_t video_gcm = { - gcm_init, - gcm_frame, - gcm_set_nonblock_state, - gcm_alive, - gcm_focus, - gcm_suppress_screensaver, + rsx_init, + rsx_frame, + rsx_set_nonblock_state, + rsx_alive, + rsx_focus, + rsx_suppress_screensaver, NULL, /* has_windowed */ - gcm_set_shader, - gcm_free, - "gcm", + rsx_set_shader, + rsx_free, + "rsx", NULL, /* set_viewport */ - gcm_set_rotation, - gcm_viewport_info, + rsx_set_rotation, + rsx_viewport_info, NULL, /* read_viewport */ NULL, /* read_frame_raw */ #ifdef HAVE_OVERLAY @@ -711,5 +763,5 @@ video_driver_t video_gcm = #ifdef HAVE_VIDEO_LAYOUT NULL, #endif - gcm_get_poke_interface + rsx_get_poke_interface }; diff --git a/gfx/drivers_context/psl1ght_ctx.c b/gfx/drivers_context/psl1ght_ctx.c new file mode 100755 index 0000000000..bb56e4ade3 --- /dev/null +++ b/gfx/drivers_context/psl1ght_ctx.c @@ -0,0 +1,351 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2014 - Hans-Kristian Arntzen + * Copyright (C) 2011-2017 - Daniel De Matteis + * + * RetroArch is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with RetroArch. + * If not, see . + */ + +#include + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include "../../configuration.h" +#include "../../retroarch.h" +#include "../../verbosity.h" +#include +#include "../../frontend/frontend_driver.h" +#include + +typedef struct gfx_ctx_psl1ght_data +{ +#if defined(HAVE_PSGL) + PSGLdevice* gl_device; + PSGLcontext* gl_context; +#else + gcmContextData *rx_context; +#endif +} gfx_ctx_psl1ght_data_t; + +/* TODO/FIXME - static global */ +static enum gfx_ctx_api ps3_api = GFX_CTX_RSX_API; + +static void gfx_ctx_psl1ght_get_resolution(unsigned idx, + unsigned *width, unsigned *height) +{ + CellVideoOutResolution resolution; + cellVideoOutGetResolution(idx, &resolution); + + *width = resolution.width; + *height = resolution.height; +} + +static float gfx_ctx_psl1ght_get_aspect_ratio(void *data) +{ + CellVideoOutState videoState; + + cellVideoOutGetState(CELL_VIDEO_OUT_PRIMARY, 0, &videoState); + + switch (videoState.displayMode.aspect) + { + case CELL_VIDEO_OUT_ASPECT_4_3: + return 4.0f/3.0f; + case CELL_VIDEO_OUT_ASPECT_16_9: + break; + } + + return 16.0f/9.0f; +} + +static void gfx_ctx_psl1ght_get_available_resolutions(void) +{ + unsigned i; + uint32_t videomode[] = { + CELL_VIDEO_OUT_RESOLUTION_480, + CELL_VIDEO_OUT_RESOLUTION_576, + CELL_VIDEO_OUT_RESOLUTION_960x1080, + CELL_VIDEO_OUT_RESOLUTION_720, + CELL_VIDEO_OUT_RESOLUTION_1280x1080, + CELL_VIDEO_OUT_RESOLUTION_1440x1080, + CELL_VIDEO_OUT_RESOLUTION_1600x1080, + CELL_VIDEO_OUT_RESOLUTION_1080 + }; + uint32_t resolution_count = 0; + bool defaultresolution = true; + uint16_t num_videomodes = sizeof(videomode) / sizeof(uint32_t); + global_t *global = global_get_ptr(); + + if (global->console.screen.resolutions.check) + return; + + for (i = 0; i < num_videomodes; i++) + { + if (cellVideoOutGetResolutionAvailability( + CELL_VIDEO_OUT_PRIMARY, videomode[i], + CELL_VIDEO_OUT_ASPECT_AUTO, 0)) + resolution_count++; + } + + global->console.screen.resolutions.count = 0; + global->console.screen.resolutions.list = + malloc(resolution_count * sizeof(uint32_t)); + + for (i = 0; i < num_videomodes; i++) + { + if (cellVideoOutGetResolutionAvailability( + CELL_VIDEO_OUT_PRIMARY, + videomode[i], + CELL_VIDEO_OUT_ASPECT_AUTO, 0)) + { + global->console.screen.resolutions.list[ + global->console.screen.resolutions.count++] = videomode[i]; + global->console.screen.resolutions.initial.id = videomode[i]; + + if (global->console.screen.resolutions.current.id == videomode[i]) + { + defaultresolution = false; + global->console.screen.resolutions.current.idx = + global->console.screen.resolutions.count-1; + } + } + } + + /* In case we didn't specify a resolution - + * make the last resolution + that was added to the list (the highest resolution) + the default resolution */ + if (global->console.screen.resolutions.current.id > num_videomodes || defaultresolution) + { + global->console.screen.resolutions.current.idx = resolution_count - 1; + global->console.screen.resolutions.current.id = global->console.screen.resolutions.list[global->console.screen.resolutions.current.idx]; + } + + global->console.screen.resolutions.check = true; +} + +static void gfx_ctx_psl1ght_set_swap_interval(void *data, int interval) +{ +#if defined(HAVE_PSGL) + if (interval == 1) + glEnable(GL_VSYNC_SCE); + else + glDisable(GL_VSYNC_SCE); +#endif +} + +static void gfx_ctx_psl1ght_check_window(void *data, bool *quit, + bool *resize, unsigned *width, unsigned *height) +{ + +} + +static bool gfx_ctx_psl1ght_has_focus(void *data) { return true; } +static bool gfx_ctx_psl1ght_suppress_screensaver(void *data, bool enable) { return false; } + +static void gfx_ctx_psl1ght_swap_buffers(void *data) +{ +#ifdef HAVE_PSGL + psglSwap(); +#endif +#ifdef HAVE_SYSUTILS + cellSysutilCheckCallback(); +#endif +} + +static void gfx_ctx_psl1ght_get_video_size(void *data, + unsigned *width, unsigned *height) +{ + gfx_ctx_psl1ght_data_t *psl1ght = (gfx_ctx_psl1ght_data_t*)data; + +#if defined(HAVE_PSGL) + if (psl1ght) + psglGetDeviceDimensions(ps3->gl_device, width, height); +#endif +} + +static void *gfx_ctx_psl1ght_init(void *video_driver) +{ + printf("gfx_ctx_psl1ght_init: %p\n", video_driver); + global_t *global = global_get_ptr(); + gfx_ctx_psl1ght_data_t *psl1ght = (gfx_ctx_psl1ght_data_t*) + calloc(1, sizeof(gfx_ctx_psl1ght_data_t)); + + if (!psl1ght) + return NULL; + + + + global->console.screen.pal_enable = + cellVideoOutGetResolutionAvailability( + CELL_VIDEO_OUT_PRIMARY, CELL_VIDEO_OUT_RESOLUTION_576, + CELL_VIDEO_OUT_ASPECT_AUTO, 0); + + gfx_ctx_psl1ght_get_available_resolutions(); + + return psl1ght; +} + +static bool gfx_ctx_psl1ght_set_video_mode(void *data, + unsigned width, unsigned height, + bool fullscreen) { return true; } + +static void gfx_ctx_psl1ght_destroy_resources(gfx_ctx_psl1ght_data_t *ps3) +{ + if (!ps3) + return; + +#if defined(HAVE_PSGL) + psglDestroyContext(ps3->gl_context); + psglDestroyDevice(ps3->gl_device); + + psglExit(); +#endif +} + +static void gfx_ctx_psl1ght_destroy(void *data) +{ + gfx_ctx_psl1ght_data_t *ps3 = (gfx_ctx_psl1ght_data_t*)data; + + if (!ps3) + return; + + gfx_ctx_psl1ght_destroy_resources(ps3); + free(data); +} + +static void gfx_ctx_psl1ght_input_driver(void *data, + const char *joypad_name, + input_driver_t **input, void **input_data) +{ + void *ps3input = input_driver_init_wrap(&input_ps3, joypad_name); + + *input = ps3input ? &input_ps3 : NULL; + *input_data = ps3input; +} + +static enum gfx_ctx_api gfx_ctx_psl1ght_get_api(void *data) { return ps3_api; } + +static bool gfx_ctx_psl1ght_bind_api(void *data, + enum gfx_ctx_api api, unsigned major, unsigned minor) +{ + ps3_api = api; + + if (api == GFX_CTX_RSX_API) + return true; + + return false; +} + +static void gfx_ctx_psl1ght_get_video_output_size(void *data, + unsigned *width, unsigned *height) +{ + global_t *global = global_get_ptr(); + + if (!global) + return; + + gfx_ctx_psl1ght_get_resolution(global->console.screen.resolutions.current.id, + width, height); + + if (*width == 720 && *height == 576) + { + if (global->console.screen.pal_enable) + global->console.screen.pal60_enable = true; + } + else + { + global->console.screen.pal_enable = false; + global->console.screen.pal60_enable = false; + } +} + +static void gfx_ctx_psl1ght_get_video_output_prev(void *data) +{ + global_t *global = global_get_ptr(); + + if (!global) + return; + + if (global->console.screen.resolutions.current.idx) + { + global->console.screen.resolutions.current.idx--; + global->console.screen.resolutions.current.id = + global->console.screen.resolutions.list + [global->console.screen.resolutions.current.idx]; + } +} + +static void gfx_ctx_psl1ght_get_video_output_next(void *data) +{ + global_t *global = global_get_ptr(); + + if (!global) + return; + + if (global->console.screen.resolutions.current.idx + 1 < + global->console.screen.resolutions.count) + { + global->console.screen.resolutions.current.idx++; + global->console.screen.resolutions.current.id = + global->console.screen.resolutions.list + [global->console.screen.resolutions.current.idx]; + } +} + +static uint32_t gfx_ctx_psl1ght_get_flags(void *data) +{ + uint32_t flags = 0; + +#ifdef HAVE_CG + BIT32_SET(flags, GFX_CTX_FLAGS_SHADERS_CG); +#endif + + return flags; +} + +static void gfx_ctx_psl1ght_set_flags(void *data, uint32_t flags) { } + +const gfx_ctx_driver_t gfx_ctx_psl1ght = { + gfx_ctx_psl1ght_init, + gfx_ctx_psl1ght_destroy, + gfx_ctx_psl1ght_get_api, + gfx_ctx_psl1ght_bind_api, + gfx_ctx_psl1ght_set_swap_interval, + gfx_ctx_psl1ght_set_video_mode, + gfx_ctx_psl1ght_get_video_size, + NULL, /* get_refresh_rate */ + gfx_ctx_psl1ght_get_video_output_size, + gfx_ctx_psl1ght_get_video_output_prev, + gfx_ctx_psl1ght_get_video_output_next, + NULL, /* get_metrics */ + NULL, + NULL, /* update_title */ + gfx_ctx_psl1ght_check_window, + NULL, /* set_resize */ + gfx_ctx_psl1ght_has_focus, + gfx_ctx_psl1ght_suppress_screensaver, + false, /* has_windowed */ + gfx_ctx_psl1ght_swap_buffers, + gfx_ctx_psl1ght_input_driver, + NULL, + NULL, + NULL, + NULL, + "psl1ght", + gfx_ctx_psl1ght_get_flags, + gfx_ctx_psl1ght_set_flags, + NULL, + NULL +}; diff --git a/griffin/griffin.c b/griffin/griffin.c index a04933717f..e60461a0ca 100644 --- a/griffin/griffin.c +++ b/griffin/griffin.c @@ -268,7 +268,9 @@ VIDEO CONTEXT #include "../gfx/drivers_context/qnx_ctx.c" #elif defined(EMSCRIPTEN) #include "../gfx/drivers_context/emscriptenegl_ctx.c" -#elif defined(__PS3__) && !defined(__PSL1GHT__) +#elif defined(__PSL1GHT__) +#include "../gfx/drivers_context/psl1ght_ctx.c" +#elif defined(__PS3__) #include "../gfx/drivers_context/ps3_ctx.c" #endif diff --git a/libretro-common/include/defines/ps3_defines.h b/libretro-common/include/defines/ps3_defines.h index 8114628327..6724691e43 100644 --- a/libretro-common/include/defines/ps3_defines.h +++ b/libretro-common/include/defines/ps3_defines.h @@ -660,6 +660,9 @@ extern int audioAddData(uint32_t portNum, float *data, #define CELL_SYSMODULE_SYSUTIL_NP SYSMODULE_SYSUTIL_NP #define CELL_SYSMODULE_JPGDEC SYSMODULE_JPGDEC #define CELL_SYSMODULE_PNGDEC SYSMODULE_PNGDEC +#define CELL_SYSMODULE_FONT SYSMODULE_FONT +#define CELL_SYSMODULE_FREETYPE SYSMODULE_FREETYPE +#define CELL_SYSMODULE_FONTFT SYSMODULE_FONTFT #define cellSysmoduleLoadModule sysModuleLoad #define cellSysmoduleUnloadModule sysModuleUnload diff --git a/retroarch.c b/retroarch.c index 1d22d09157..417fc84930 100644 --- a/retroarch.c +++ b/retroarch.c @@ -32861,6 +32861,7 @@ const gfx_ctx_driver_t *video_context_driver_init_first(void *data, case GFX_CTX_OPENGL_ES_API: case GFX_CTX_OPENVG_API: case GFX_CTX_METAL_API: + case GFX_CTX_RSX_API: return gl_context_driver_init_first( p_rarch, settings, data, ident, api, major, minor, diff --git a/retroarch.h b/retroarch.h index 53575b7ab4..8dde537f69 100644 --- a/retroarch.h +++ b/retroarch.h @@ -839,7 +839,8 @@ enum gfx_ctx_api GFX_CTX_DIRECT3D12_API, GFX_CTX_OPENVG_API, GFX_CTX_VULKAN_API, - GFX_CTX_METAL_API + GFX_CTX_METAL_API, + GFX_CTX_RSX_API }; enum display_metric_types From 7a3d78b1c0e8fc8673ec9dd0a2989ede221c0e5f Mon Sep 17 00:00:00 2001 From: jdgleaver Date: Mon, 12 Jul 2021 12:14:55 +0100 Subject: [PATCH 22/58] (Menu+Widgets) Add workaround for FPU bug that breaks scale factor comparisons on certain platforms (fixes XMB thumbnails on 32bit Linux/Windows) --- gfx/gfx_widgets.c | 14 +++++++++++--- menu/drivers/materialui.c | 10 +++++++++- menu/drivers/ozone/ozone.c | 10 +++++++++- menu/drivers/xmb.c | 10 +++++++++- 4 files changed, 38 insertions(+), 6 deletions(-) diff --git a/gfx/gfx_widgets.c b/gfx/gfx_widgets.c index f3a650f9e3..bdcbe2a08a 100644 --- a/gfx/gfx_widgets.c +++ b/gfx/gfx_widgets.c @@ -1037,9 +1037,15 @@ void gfx_widgets_iterate( { size_t i; dispgfx_widget_t *p_dispwidget = (dispgfx_widget_t*)data; - /* Check whether screen dimensions or menu scale - * factor have changed */ - float scale_factor = 0.0f; + /* c.f. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=323 + * On some platforms (e.g. 32-bit x86 without SSE), + * gcc can produce inconsistent floating point results + * depending upon optimisation level. This can break + * floating point variable comparisons. A workaround is + * to declare the affected variable as 'volatile', which + * disables optimisations and removes excess precision + * (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=323#c87) */ + volatile float scale_factor = 0.0f; gfx_display_t *p_disp = (gfx_display_t*)data_disp; settings_t *settings = (settings_t*)settings_data; #ifdef HAVE_XMB @@ -1051,6 +1057,8 @@ void gfx_widgets_iterate( scale_factor = gfx_display_get_widget_dpi_scale(p_disp, settings, width, height, fullscreen); + /* Check whether screen dimensions or menu scale + * factor have changed */ if ((scale_factor != p_dispwidget->last_scale_factor) || (width != p_dispwidget->last_video_width) || (height != p_dispwidget->last_video_height)) diff --git a/menu/drivers/materialui.c b/menu/drivers/materialui.c index 476de4729b..3f063370b4 100644 --- a/menu/drivers/materialui.c +++ b/menu/drivers/materialui.c @@ -3512,7 +3512,15 @@ static void materialui_render(void *data, { size_t i; float bottom; - float scale_factor; + /* c.f. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=323 + * On some platforms (e.g. 32-bit x86 without SSE), + * gcc can produce inconsistent floating point results + * depending upon optimisation level. This can break + * floating point variable comparisons. A workaround is + * to declare the affected variable as 'volatile', which + * disables optimisations and removes excess precision + * (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=323#c87) */ + volatile float scale_factor; settings_t *settings = config_get_ptr(); materialui_handle_t *mui = (materialui_handle_t*)data; gfx_display_t *p_disp = disp_get_ptr(); diff --git a/menu/drivers/ozone/ozone.c b/menu/drivers/ozone/ozone.c index e9d10aba8a..1dd415bdb0 100644 --- a/menu/drivers/ozone/ozone.c +++ b/menu/drivers/ozone/ozone.c @@ -1750,7 +1750,15 @@ static void ozone_render(void *data, bool is_idle) { size_t i; - float scale_factor; + /* c.f. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=323 + * On some platforms (e.g. 32-bit x86 without SSE), + * gcc can produce inconsistent floating point results + * depending upon optimisation level. This can break + * floating point variable comparisons. A workaround is + * to declare the affected variable as 'volatile', which + * disables optimisations and removes excess precision + * (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=323#c87) */ + volatile float scale_factor; unsigned entries_end = (unsigned)menu_entries_get_size(); bool pointer_enabled = false; unsigned language = *msg_hash_get_uint(MSG_HASH_USER_LANGUAGE); diff --git a/menu/drivers/xmb.c b/menu/drivers/xmb.c index 8a288b1817..058909173b 100644 --- a/menu/drivers/xmb.c +++ b/menu/drivers/xmb.c @@ -3971,7 +3971,15 @@ static void xmb_render(void *data, /* 'i' must be of 'size_t', since it is passed * by reference to menu_entries_ctl() */ size_t i; - float scale_factor; + /* c.f. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=323 + * On some platforms (e.g. 32-bit x86 without SSE), + * gcc can produce inconsistent floating point results + * depending upon optimisation level. This can break + * floating point variable comparisons. A workaround is + * to declare the affected variable as 'volatile', which + * disables optimisations and removes excess precision + * (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=323#c87) */ + volatile float scale_factor; xmb_handle_t *xmb = (xmb_handle_t*)data; settings_t *settings = config_get_ptr(); size_t end = menu_entries_get_size(); From eb259174b820c74f65a4703f9c21f54837f6bf43 Mon Sep 17 00:00:00 2001 From: jdgleaver Date: Tue, 13 Jul 2021 13:11:19 +0100 Subject: [PATCH 23/58] (Dingux) Fix display when cores 'drop' frames --- gfx/drivers/sdl_dingux_gfx.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/gfx/drivers/sdl_dingux_gfx.c b/gfx/drivers/sdl_dingux_gfx.c index 865c16f478..faf1511124 100644 --- a/gfx/drivers/sdl_dingux_gfx.c +++ b/gfx/drivers/sdl_dingux_gfx.c @@ -761,7 +761,13 @@ static bool sdl_dingux_gfx_frame(void *data, const void *frame, { sdl_dingux_video_t* vid = (sdl_dingux_video_t*)data; - if (unlikely(!vid)) + /* Return early if: + * - Input sdl_dingux_video_t struct is NULL + * (cannot realistically happen) + * - Menu is inactive and input 'content' frame + * data is NULL (may happen when e.g. a running + * core skips a frame) */ + if (unlikely(!vid || (!frame && !vid->menu_active))) return true; /* If fast forward is currently active, we may @@ -805,16 +811,13 @@ static bool sdl_dingux_gfx_frame(void *data, const void *frame, if (likely(vid->mode_valid)) { - if (likely(frame)) - { - /* Blit frame to SDL surface */ - if (vid->rgb32) - sdl_dingux_blit_frame32(vid, (uint32_t*)frame, - width, height, pitch); - else - sdl_dingux_blit_frame16(vid, (uint16_t*)frame, - width, height, pitch); - } + /* Blit frame to SDL surface */ + if (vid->rgb32) + sdl_dingux_blit_frame32(vid, (uint32_t*)frame, + width, height, pitch); + else + sdl_dingux_blit_frame16(vid, (uint16_t*)frame, + width, height, pitch); } /* If current display mode is invalid, * just display an error message */ From 54706bec8a71e8f3e8e5113c15b7fcbe2a7f086e Mon Sep 17 00:00:00 2001 From: jdgleaver Date: Tue, 13 Jul 2021 14:18:11 +0100 Subject: [PATCH 24/58] (Dingux Beta) Use ALSA audio driver by default --- configuration.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/configuration.c b/configuration.c index de23095dbc..aba6c74e1b 100644 --- a/configuration.c +++ b/configuration.c @@ -342,6 +342,8 @@ static const enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_PS3; static const enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_CTR; #elif defined(SWITCH) static const enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_SWITCH; +#elif defined(DINGUX_BETA) && defined(HAVE_ALSA) +static const enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_ALSA; #elif defined(DINGUX) && defined(HAVE_AL) static const enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_AL; #elif defined(HAVE_PULSE) From f6aeb717ba37d273f60045958fbea1e215830a06 Mon Sep 17 00:00:00 2001 From: John Parton Date: Tue, 13 Jul 2021 11:36:48 -0500 Subject: [PATCH 25/58] Basic rs90 build DINGUX_BETA has clock_gettime libogc Add tinyalsa support to rs90 --- Makefile.common | 21 +- Makefile.rs90 | 236 +++++ config.def.h | 4 +- configuration.c | 11 +- gfx/drivers/sdl_dingux_gfx.c | 1 + gfx/drivers/sdl_rs90_gfx.c | 1187 ++++++++++++++++++++++ griffin/griffin.c | 8 + input/drivers_joypad/sdl_dingux_joypad.c | 41 +- libretro-common/rthreads/rthreads.c | 2 +- menu/drivers/rgui.c | 46 +- menu/menu_displaylist.c | 3 +- menu/menu_setting.c | 13 +- retroarch.h | 1 + retroarch_data.h | 18 +- 14 files changed, 1549 insertions(+), 43 deletions(-) create mode 100644 Makefile.rs90 create mode 100644 gfx/drivers/sdl_rs90_gfx.c diff --git a/Makefile.common b/Makefile.common index 34576dd4b0..5394c2c1a9 100644 --- a/Makefile.common +++ b/Makefile.common @@ -668,7 +668,7 @@ else ifeq ($(HAVE_BUILTINMBEDTLS), 1) DEFINES += -DMBEDTLS_SSL_DEBUG_ALL endif - # MinGW requires this for some reason, + # MinGW requires this for some reason, # even though the include paths are relative to the source INCLUDE_DIRS += -Ideps/mbedtls @@ -1576,8 +1576,14 @@ else ifeq ($(HAVE_SDL), 1) else ifeq ($(HAVE_SDL_DINGUX), 1) HAVE_SDL_COMMON = 1 DEF_FLAGS += -DHAVE_SDL -DHAVE_SDL_DINGUX - OBJ += gfx/drivers/sdl_dingux_gfx.o \ - input/drivers/sdl_dingux_input.o \ + + ifeq ($(RS90), 1) + OBJ += gfx/drivers/sdl_rs90_gfx.o + else + OBJ += gfx/drivers/sdl_dingux_gfx.o + endif + + OBJ += input/drivers/sdl_dingux_input.o \ input/drivers_joypad/sdl_dingux_joypad.o DEF_FLAGS += $(SDL_DINGUX_CFLAGS) LIBS += $(SDL_DINGUX_LIBS) @@ -2296,9 +2302,9 @@ ifeq ($(HAVE_CRTSWITCHRES), 1) $(DEPS_DIR)/switchres/resync_windows.o endif ifneq ($(findstring Linux,$(OS)),) - OBJ += $(DEPS_DIR)/switchres/display_linux.o + OBJ += $(DEPS_DIR)/switchres/display_linux.o ifeq ($(HAVE_X11)$(HAVE_XRANDR), 11) - OBJ += $(DEPS_DIR)/switchres/custom_video_xrandr.o + OBJ += $(DEPS_DIR)/switchres/custom_video_xrandr.o DEFINES += -DSR_WITH_XRANDR endif endif @@ -2325,9 +2331,9 @@ ifeq ($(HAVE_COCOA_COMMON),1) OBJ += input/drivers/cocoa_input.o \ ui/drivers/ui_cocoa.o \ ui/drivers/cocoa/cocoa_common.o - + ifeq ($(HAVE_OPENGL), 1) - DEFINES += -DGL_SILENCE_DEPRECATION + DEFINES += -DGL_SILENCE_DEPRECATION OBJ += gfx/drivers_context/cocoa_gl_ctx.o endif ifeq ($(HAVE_VULKAN), 1) @@ -2482,4 +2488,3 @@ ifeq ($(HAVE_ODROIDGO2), 1) endif ################################## - diff --git a/Makefile.rs90 b/Makefile.rs90 new file mode 100644 index 0000000000..cfb26c41d1 --- /dev/null +++ b/Makefile.rs90 @@ -0,0 +1,236 @@ +######################### +## Toolchain variables ## +######################### + +# Alpha toolchain +TOOLCHAIN_DIR=/opt/rs90-toolchain + +# All toolchain-related variables may be +# overridden via the command line +ifdef GCW0_CC +CC = $(GCW0_CC) +else +CC = $(TOOLCHAIN_DIR)/usr/bin/mipsel-rs90-linux-musl-gcc +endif + +ifdef GCW0_CXX +CXX = $(GCW0_CXX) +else +CXX = $(TOOLCHAIN_DIR)/usr/bin/mipsel-rs90-linux-musl-g++ +endif + +ifdef GCW0_STRIP +STRIP = $(GCW0_STRIP) +else +STRIP = $(TOOLCHAIN_DIR)/usr/bin/mipsel-rs90-linux-musl-strip +endif + +GCW0_SDL_CONFIG ?= $(TOOLCHAIN_DIR)/usr/mipsel-rs90-linux-musl/sysroot/usr/bin/sdl-config +GCW0_FREETYPE_CONFIG ?= $(TOOLCHAIN_DIR)/usr/mipsel-rs90-linux-musl/sysroot/usr/bin/freetype-config +GCW0_MK_SQUASH_FS ?= $(TOOLCHAIN_DIR)/usr/bin/mksquashfs + +GCW0_INC_DIR ?= $(TOOLCHAIN_DIR)/usr/mipsel-rs90-linux-musl/sysroot/usr/include +GCW0_LIB_DIR ?= $(TOOLCHAIN_DIR)/usr/mipsel-rs90-linux-musl/sysroot/usr/lib + +######################### +######################### + +PACKAGE_NAME = retroarch + +DEBUG ?= 0 + +RS90 = 1 +DINGUX = 1 +DINGUX_BETA = 1 +HAVE_SCREENSHOTS = 0 +HAVE_REWIND = 1 +HAVE_7ZIP = 1 +HAVE_AL = 0 +# ALSA freezes when switching back from menu +HAVE_ALSA = 1 +HAVE_DSP_FILTER = 1 +HAVE_VIDEO_FILTER = 1 +HAVE_STATIC_VIDEO_FILTERS = 1 +HAVE_STATIC_AUDIO_FILTERS = 1 +HAVE_FILTERS_BUILTIN = 1 +HAVE_BUILTINMBEDTLS = 0 +HAVE_BUILTINZLIB = 1 +HAVE_C99 = 1 +HAVE_CC = 1 +HAVE_CC_RESAMPLER = 1 + +HAVE_CHD = 1 +HAVE_COMMAND = 0 +HAVE_CXX = 1 +HAVE_DR_MP3 = 1 +HAVE_DYNAMIC = 1 +HAVE_EGL = 0 +HAVE_FREETYPE = 0 +HAVE_GDI = 1 +HAVE_GETADDRINFO = 0 +HAVE_GETOPT_LONG = 1 +HAVE_GLSL = 0 +HAVE_HID = 1 +HAVE_IBXM = 1 +HAVE_IMAGEVIEWER = 1 +HAVE_LANGEXTRA = 0 +HAVE_LIBRETRODB = 1 +HAVE_MENU = 1 +HAVE_MENU_COMMON = 1 +HAVE_GFX_WIDGETS = 0 +HAVE_MMAP = 1 +HAVE_OPENDINGUX_FBDEV = 0 +HAVE_OPENGL = 0 +HAVE_OPENGL1 = 0 +HAVE_OPENGLES = 0 +HAVE_OPENGLES3 = 0 +HAVE_OPENGL_CORE = 0 +HAVE_OPENSSL = 1 +HAVE_OVERLAY = 0 +HAVE_RBMP = 1 +HAVE_RJPEG = 1 +HAVE_RPILED = 0 +HAVE_RPNG = 1 +HAVE_RUNAHEAD = 1 +HAVE_SDL_DINGUX = 1 +HAVE_SHADERPIPELINE = 0 +HAVE_STB_FONT = 0 +HAVE_STB_IMAGE = 1 +HAVE_STB_VORBIS = 1 +HAVE_STDIN_CMD = 0 +HAVE_STRCASESTR = 1 +HAVE_THREADS = 1 +HAVE_UDEV = 1 +HAVE_RGUI = 1 +HAVE_MATERIALUI = 0 +HAVE_XMB = 0 +HAVE_OZONE = 0 +HAVE_ZLIB = 1 +HAVE_CONFIGFILE = 1 +HAVE_PATCH = 1 +HAVE_CHEATS = 1 +HAVE_CHEEVOS = 0 +HAVE_LIBSHAKE = 0 +HAVE_TINYALSA = 1 +HAVE_NEAREST_RESAMPLER = 1 + +OS = Linux +TARGET = retroarch +OPK_NAME = retroarch_rs90_odbeta.opk + +OBJ := +LINK := $(CXX) +DEF_FLAGS := -mplt -mno-shared +DEF_FLAGS += -ffunction-sections -fdata-sections +DEF_FLAGS += -I. -Ideps -Ideps/stb -DRS90=1 -DDINGUX=1 -DDINGUX_BETA=1 -MMD +DEF_FLAGS += -Wall -Wno-unused-variable +DEF_FLAGS += -std=gnu99 -D_GNU_SOURopendinguxCE -flto -lasound +LIBS := -ldl -lz -lrt -ludev -pthread +CFLAGS := +CXXFLAGS := -fno-exceptions -fno-rtti -std=c++11 -D__STDC_CONSTANT_MACROS +ASFLAGS := +LDFLAGS := -Wl,--gc-sections +INCLUDE_DIRS = -I$(GCW0_INC_DIR) +LIBRARY_DIRS = -L$(GCW0_LIB_DIR) +DEFINES := -DRARCH_INTERNAL -D_FILE_OFFSET_BITS=64 -UHAVE_STATIC_DUMMY +DEFINES += -DHAVE_C99=1 -DHAVE_CXX=1 +DEFINES += -DHAVE_GETOPT_LONG=1 -DHAVE_STRCASESTR=1 -DHAVE_DYNAMIC=1 +DEFINES += -DHAVE_FILTERS_BUILTIN +DEFINES += -DHAVE_UDEV=1 +DEFINES += -DHAVE_ALSA +DEFINES += -DCC_RESAMPLER_PRECISION=0 + +SDL_DINGUX_CFLAGS := $(shell $(GCW0_SDL_CONFIG) --cflags) +SDL_DINGUX_LIBS := $(shell $(GCW0_SDL_CONFIG) --libs) +FREETYPE_CFLAGS := $(shell $(GCW0_FREETYPE_CONFIG) --cflags) +FREETYPE_LIBS := $(shell $(GCW0_FREETYPE_CONFIG) --libs) +# AL_LIBS := -lopenal +MMAP_LIBS = -lc + +OBJDIR_BASE := obj-unix + +ifeq ($(DEBUG), 1) + OBJDIR := $(OBJDIR_BASE)/debug + DEF_FLAGS += -O0 -g -DDEBUG -D_DEBUG +else + OBJDIR := $(OBJDIR_BASE)/release + DEF_FLAGS += -Ofast -DNDEBUG +endif + +include Makefile.common + +DEF_FLAGS += $(INCLUDE_DIRS) +LDFLAGS += $(CFLAGS) $(CXXFLAGS) $(DEF_FLAGS) +CFLAGS += $(DEF_FLAGS) +CXXFLAGS += $(DEF_FLAGS) + +HEADERS = $(wildcard */*/*.h) $(wildcard */*.h) $(wildcard *.h) + +Q := @ + +RARCH_OBJ := $(addprefix $(OBJDIR)/,$(OBJ)) + +define DESKTOP_ENTRY +[Desktop Entry] +Name=RetroArch +Comment=Frontend for emulators, game engines +Exec=retroarch +Terminal=false +Type=Application +StartupNotify=true +Icon=retroarch +Categories=emulators; +X-OD-NeedsDownscaling=true +endef +export DESKTOP_ENTRY + +all: $(TARGET) opk + +-include $(RARCH_OBJ:.o=.d) + +SYMBOL_MAP := -Wl,-Map=output.map + +$(TARGET): $(RARCH_OBJ) + @$(if $(Q), $(shell echo echo LD $@),) + $(Q)$(LINK) -o $@ $(RARCH_OBJ) $(LIBS) $(LDFLAGS) $(LIBRARY_DIRS) + +$(OBJDIR)/%.o: %.c + @mkdir -p $(dir $@) + @$(if $(Q), $(shell echo echo CC $<),) + $(Q)$(CC) $(CPPFLAGS) $(CFLAGS) $(DEFINES) -c -o $@ $< + +$(OBJDIR)/%.o: %.cpp + @mkdir -p $(dir $@) + @$(if $(Q), $(shell echo echo CXX $<),) + $(Q)$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(DEFINES) -MMD -c -o $@ $< + +$(OBJDIR)/%.o: %.m + @mkdir -p $(dir $@) + @$(if $(Q), $(shell echo echo OBJC $<),) + $(Q)$(CXX) $(OBJCFLAGS) $(DEFINES) -MMD -c -o $@ $< + +$(OBJDIR)/%.o: %.S $(HEADERS) + @mkdir -p $(dir $@) + @$(if $(Q), $(shell echo echo AS $<),) + $(Q)$(CC) $(CFLAGS) $(ASFLAGS) $(DEFINES) -c -o $@ $< + +clean: + rm -rf $(OBJDIR_BASE) + rm -f $(TARGET) + rm -f *.d + rm -rf $(OPK_NAME) + +opk: $(TARGET) + echo "$$DESKTOP_ENTRY" > default.rs90.desktop + rm -f $(OPK_NAME) + cp media/ico_src/icon32.png retroarch.png +ifeq ($STRIP_BIN, 1) + $(STRIP) --strip-unneeded retroarch +endif + $(GCW0_MK_SQUASH_FS) retroarch default.rs90.desktop retroarch.png $(OPK_NAME) -all-root -no-xattrs -noappend -no-exports + rm -f default.rs90.desktop retroarch.png + +.PHONY: all clean opk + +print-%: + @echo '$*=$($*)' diff --git a/config.def.h b/config.def.h index 0d6d7a8983..45c99427d1 100644 --- a/config.def.h +++ b/config.def.h @@ -739,7 +739,9 @@ static const bool default_savefiles_in_content_dir = false; static const bool default_systemfiles_in_content_dir = false; static const bool default_screenshots_in_content_dir = false; -#if defined(_XBOX1) || defined(__PS3__) || defined(_XBOX360) || defined(DINGUX) +#if defined(RS90) +#define DEFAULT_MENU_TOGGLE_GAMEPAD_COMBO INPUT_TOGGLE_START_SELECT +#elif defined(_XBOX1) || defined(__PS3__) || defined(_XBOX360) || defined(DINGUX) #define DEFAULT_MENU_TOGGLE_GAMEPAD_COMBO INPUT_TOGGLE_L3_R3 #elif defined(PS2) || defined(PSP) #define DEFAULT_MENU_TOGGLE_GAMEPAD_COMBO INPUT_TOGGLE_HOLD_START diff --git a/configuration.c b/configuration.c index de23095dbc..f7f99b7b9f 100644 --- a/configuration.c +++ b/configuration.c @@ -70,6 +70,7 @@ enum video_driver_enum VIDEO_SDL, VIDEO_SDL2, VIDEO_SDL_DINGUX, + VIDEO_SDL_RS90, VIDEO_EXT, VIDEO_WII, VIDEO_WIIU, @@ -311,7 +312,11 @@ static const enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_SDL; #elif defined(HAVE_SDL2) static const enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_SDL2; #elif defined(HAVE_SDL_DINGUX) +#if defined(RS90) +static const enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_SDL_RS90; +#else static const enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_SDL_DINGUX; +#endif #elif defined(_WIN32) && !defined(_XBOX) static const enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_GDI; #elif defined(DJGPP) @@ -388,7 +393,9 @@ static const enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_EXT; static const enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_NULL; #endif -#if defined(PSP) || defined(EMSCRIPTEN) +#if defined(RS90) +static const enum audio_resampler_driver_enum AUDIO_DEFAULT_RESAMPLER_DRIVER = AUDIO_RESAMPLER_NEAREST; +#elif defined(PSP) || defined(EMSCRIPTEN) static const enum audio_resampler_driver_enum AUDIO_DEFAULT_RESAMPLER_DRIVER = AUDIO_RESAMPLER_CC; #else static const enum audio_resampler_driver_enum AUDIO_DEFAULT_RESAMPLER_DRIVER = AUDIO_RESAMPLER_SINC; @@ -852,6 +859,8 @@ const char *config_get_default_video(void) return "xvideo"; case VIDEO_SDL_DINGUX: return "sdl_dingux"; + case VIDEO_SDL_RS90: + return "sdl_rs90"; case VIDEO_SDL: return "sdl"; case VIDEO_SDL2: diff --git a/gfx/drivers/sdl_dingux_gfx.c b/gfx/drivers/sdl_dingux_gfx.c index 865c16f478..ae49b0d347 100644 --- a/gfx/drivers/sdl_dingux_gfx.c +++ b/gfx/drivers/sdl_dingux_gfx.c @@ -2,6 +2,7 @@ * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - Daniel De Matteis * Copyright (C) 2011-2017 - Higor Euripedes + * Copyright (C) 2019-2021 - James Leaver * * RetroArch is free software: you can redistribute it and/or modify it under the terms * of the GNU General Public License as published by the Free Software Found- diff --git a/gfx/drivers/sdl_rs90_gfx.c b/gfx/drivers/sdl_rs90_gfx.c new file mode 100644 index 0000000000..77246a7e5f --- /dev/null +++ b/gfx/drivers/sdl_rs90_gfx.c @@ -0,0 +1,1187 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2014 - Hans-Kristian Arntzen + * Copyright (C) 2011-2017 - Daniel De Matteis + * Copyright (C) 2011-2017 - Higor Euripedes + * Copyright (C) 2019-2021 - James Leaver + * Copyright (C) 2021 - John Parton + * + * RetroArch is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with RetroArch. + * If not, see . + */ + +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_CONFIG_H +#include "../../config.h" +#endif + +#ifdef HAVE_MENU +#include "../../menu/menu_driver.h" +#endif + +#include "../../dingux/dingux_utils.h" + +#include "../../verbosity.h" +#include "../../gfx/drivers_font_renderer/bitmap.h" +#include "../../configuration.h" +#include "../../retroarch.h" +#if defined(DINGUX_BETA) +#include "../../driver.h" +#endif + +#define likely(x) __builtin_expect(!!(x), 1) +#define unlikely(x) __builtin_expect(!!(x), 0) + +#define SDL_RS90_WIDTH 240 +#define SDL_RS90_HEIGHT 160 + +#define SDL_RS90_NUM_FONT_GLYPHS 256 + +typedef struct sdl_rs90_video +{ + retro_time_t last_frame_time; + retro_time_t ff_frame_time_min; + SDL_Surface *screen; + bitmapfont_lut_t *osd_font; + /* Scaling/padding/cropping parameters */ + unsigned content_width; + unsigned content_height; + unsigned frame_width; + unsigned frame_height; + unsigned frame_padding_x; + unsigned frame_padding_y; + unsigned frame_crop_x; + unsigned frame_crop_y; +#if defined(DINGUX_BETA) + enum dingux_refresh_rate refresh_rate; +#endif + uint32_t font_colour32; + uint16_t font_colour16; + uint16_t menu_texture[SDL_RS90_WIDTH * SDL_RS90_HEIGHT]; + bool rgb32; + bool vsync; + bool keep_aspect; + bool scale_integer; + bool menu_active; + bool was_in_menu; + bool quitting; + bool mode_valid; +} sdl_rs90_video_t; + +static void sdl_rs90_init_font_color(sdl_rs90_video_t *vid) +{ + settings_t *settings = config_get_ptr(); + uint32_t red = 0xFF; + uint32_t green = 0xFF; + uint32_t blue = 0xFF; + + if (settings) + { + red = (uint32_t)((settings->floats.video_msg_color_r * 255.0f) + 0.5f) & 0xFF; + green = (uint32_t)((settings->floats.video_msg_color_g * 255.0f) + 0.5f) & 0xFF; + blue = (uint32_t)((settings->floats.video_msg_color_b * 255.0f) + 0.5f) & 0xFF; + } + + /* Convert to XRGB8888 */ + vid->font_colour32 = (red << 16) | (green << 8) | blue; + + /* Convert to RGB565 */ + red = red >> 3; + green = green >> 3; + blue = blue >> 3; + + vid->font_colour16 = (red << 11) | (green << 6) | blue; +} + +static void sdl_rs90_blit_text16( + sdl_rs90_video_t *vid, + unsigned x, unsigned y, + const char *str) +{ + /* Note: Cannot draw text in padding region + * (padding region is never cleared, so + * any text pixels would remain as garbage) */ + uint16_t *screen_buf = (uint16_t*)vid->screen->pixels; + bool **font_lut = vid->osd_font->lut; + /* 16 bit - divide pitch by 2 */ + uint16_t screen_stride = (uint16_t)(vid->screen->pitch >> 1); + uint16_t screen_width = vid->frame_width; + uint16_t screen_height = vid->frame_height; + unsigned x_pos = x + vid->frame_padding_x; + unsigned y_pos = (y > (screen_height >> 1)) ? + (y - vid->frame_padding_y) : (y + vid->frame_padding_y); + uint16_t shadow_color_buf[2] = {0}; + uint16_t color_buf[2]; + + color_buf[0] = vid->font_colour16; + color_buf[1] = 0; + + /* Check for out of bounds y coordinates */ + if (y_pos + FONT_HEIGHT + 1 >= + screen_height - vid->frame_padding_y) + return; + + while (!string_is_empty(str)) + { + /* Check for out of bounds x coordinates */ + if (x_pos + FONT_WIDTH_STRIDE + 1 >= + screen_width - vid->frame_padding_x) + return; + + /* Deal with spaces first, for efficiency */ + if (*str == ' ') + str++; + else + { + uint16_t i, j; + bool *symbol_lut; + uint32_t symbol = utf8_walk(&str); + + /* Stupid hack: 'oe' ligatures are not really + * standard extended ASCII, so we have to waste + * CPU cycles performing a conversion from the + * unicode values... */ + if (symbol == 339) /* Latin small ligature oe */ + symbol = 156; + if (symbol == 338) /* Latin capital ligature oe */ + symbol = 140; + + if (symbol >= SDL_RS90_NUM_FONT_GLYPHS) + continue; + + symbol_lut = font_lut[symbol]; + + for (j = 0; j < FONT_HEIGHT; j++) + { + uint32_t buff_offset = ((y_pos + j) * screen_stride) + x_pos; + + for (i = 0; i < FONT_WIDTH; i++) + { + if (*(symbol_lut + i + (j * FONT_WIDTH))) + { + uint16_t *screen_buf_ptr = screen_buf + buff_offset + i; + + /* Text pixel + right shadow */ + memcpy(screen_buf_ptr, color_buf, sizeof(uint16_t)); + + /* Bottom shadow */ + screen_buf_ptr += screen_stride; + memcpy(screen_buf_ptr, shadow_color_buf, sizeof(uint16_t)); + } + } + } + } + + x_pos += FONT_WIDTH_STRIDE; + } +} + +static void sdl_rs90_blit_text32( + sdl_rs90_video_t *vid, + unsigned x, unsigned y, + const char *str) +{ + /* Note: Cannot draw text in padding region + * (padding region is never cleared, so + * any text pixels would remain as garbage) */ + uint32_t *screen_buf = (uint32_t*)vid->screen->pixels; + bool **font_lut = vid->osd_font->lut; + /* 32 bit - divide pitch by 4 */ + uint32_t screen_stride = (uint32_t)(vid->screen->pitch >> 2); + uint32_t screen_width = vid->screen->w; + uint32_t screen_height = vid->screen->h; + unsigned x_pos = x + vid->frame_padding_x; + unsigned y_pos = (y > (screen_height >> 1)) ? + (y - vid->frame_padding_y) : (y + vid->frame_padding_y); + uint32_t shadow_color_buf[2] = {0}; + uint32_t color_buf[2]; + + color_buf[0] = vid->font_colour32; + color_buf[1] = 0; + + /* Check for out of bounds y coordinates */ + if (y_pos + FONT_HEIGHT + 1 >= + screen_height - vid->frame_padding_y) + return; + + while (!string_is_empty(str)) + { + /* Check for out of bounds x coordinates */ + if (x_pos + FONT_WIDTH_STRIDE + 1 >= + screen_width - vid->frame_padding_x) + return; + + /* Deal with spaces first, for efficiency */ + if (*str == ' ') + str++; + else + { + uint32_t i, j; + bool *symbol_lut; + uint32_t symbol = utf8_walk(&str); + + /* Stupid hack: 'oe' ligatures are not really + * standard extended ASCII, so we have to waste + * CPU cycles performing a conversion from the + * unicode values... */ + if (symbol == 339) /* Latin small ligature oe */ + symbol = 156; + if (symbol == 338) /* Latin capital ligature oe */ + symbol = 140; + + if (symbol >= SDL_RS90_NUM_FONT_GLYPHS) + continue; + + symbol_lut = font_lut[symbol]; + + for (j = 0; j < FONT_HEIGHT; j++) + { + uint32_t buff_offset = ((y_pos + j) * screen_stride) + x_pos; + + for (i = 0; i < FONT_WIDTH; i++) + { + if (*(symbol_lut + i + (j * FONT_WIDTH))) + { + uint32_t *screen_buf_ptr = screen_buf + buff_offset + i; + + /* Text pixel + right shadow */ + memcpy(screen_buf_ptr, color_buf, sizeof(uint32_t)); + + /* Bottom shadow */ + screen_buf_ptr += screen_stride; + memcpy(screen_buf_ptr, shadow_color_buf, sizeof(uint32_t)); + } + } + } + } + + x_pos += FONT_WIDTH_STRIDE; + } +} + +static void sdl_rs90_blit_video_mode_error_msg(sdl_rs90_video_t *vid) +{ + const char *error_msg = msg_hash_to_str(MSG_UNSUPPORTED_VIDEO_MODE); + char display_mode[64]; + + display_mode[0] = '\0'; + + /* Zero out pixel buffer */ + memset(vid->screen->pixels, 0, + vid->screen->pitch * vid->screen->h); + + /* Generate display mode string */ + snprintf(display_mode, sizeof(display_mode), "> %ux%u, %s", + vid->frame_width, vid->frame_height, + vid->rgb32 ? "XRGB8888" : "RGB565"); + + /* Print error message */ + if (vid->rgb32) + { + sdl_rs90_blit_text32(vid, + FONT_WIDTH_STRIDE, FONT_WIDTH_STRIDE, + error_msg); + + sdl_rs90_blit_text32(vid, + FONT_WIDTH_STRIDE, FONT_WIDTH_STRIDE + FONT_HEIGHT_STRIDE, + display_mode); + } + else + { + sdl_rs90_blit_text16(vid, + FONT_WIDTH_STRIDE, FONT_WIDTH_STRIDE, + error_msg); + + sdl_rs90_blit_text16(vid, + FONT_WIDTH_STRIDE, FONT_WIDTH_STRIDE + FONT_HEIGHT_STRIDE, + display_mode); + } +} + +static void sdl_rs90_gfx_free(void *data) +{ + sdl_rs90_video_t *vid = (sdl_rs90_video_t*)data; + + if (!vid) + return; + + if (vid->osd_font) + bitmapfont_free_lut(vid->osd_font); + + free(vid); +} + +static void sdl_rs90_input_driver_init( + const char *input_driver_name, const char *joypad_driver_name, + input_driver_t **input, void **input_data) +{ + /* Sanity check */ + if (!input || !input_data) + return; + + *input = NULL; + *input_data = NULL; + + /* If input driver name is empty, cannot + * initialise anything... */ + if (string_is_empty(input_driver_name)) + return; + + if (string_is_equal(input_driver_name, "sdl_dingux")) + { + *input_data = input_driver_init_wrap(&input_sdl_dingux, + joypad_driver_name); + + if (*input_data) + *input = &input_sdl_dingux; + + return; + } + +#if defined(HAVE_SDL) || defined(HAVE_SDL2) + if (string_is_equal(input_driver_name, "sdl")) + { + *input_data = input_driver_init_wrap(&input_sdl, + joypad_driver_name); + + if (*input_data) + *input = &input_sdl; + + return; + } +#endif + +#if defined(HAVE_UDEV) + if (string_is_equal(input_driver_name, "udev")) + { + *input_data = input_driver_init_wrap(&input_udev, + joypad_driver_name); + + if (*input_data) + *input = &input_udev; + + return; + } +#endif + +#if defined(__linux__) + if (string_is_equal(input_driver_name, "linuxraw")) + { + *input_data = input_driver_init_wrap(&input_linuxraw, + joypad_driver_name); + + if (*input_data) + *input = &input_linuxraw; + + return; + } +#endif +} + +static void *sdl_rs90_gfx_init(const video_info_t *video, + input_driver_t **input, void **input_data) +{ + sdl_rs90_video_t *vid = NULL; + uint32_t sdl_subsystem_flags = SDL_WasInit(0); + settings_t *settings = config_get_ptr(); +#if defined(DINGUX_BETA) + enum dingux_refresh_rate current_refresh_rate = DINGUX_REFRESH_RATE_60HZ; + enum dingux_refresh_rate target_refresh_rate = (enum dingux_refresh_rate) + settings->uints.video_dingux_refresh_rate; + bool refresh_rate_valid = false; + float hw_refresh_rate = 0.0f; +#endif + const char *input_driver_name = settings->arrays.input_driver; + const char *joypad_driver_name = settings->arrays.input_joypad_driver; + uint32_t surface_flags = (video->vsync) ? + (SDL_HWSURFACE | SDL_TRIPLEBUF | SDL_FULLSCREEN) : + (SDL_HWSURFACE | SDL_FULLSCREEN); + + /* Initialise graphics subsystem, if required */ + if (sdl_subsystem_flags == 0) + { + if (SDL_Init(SDL_INIT_VIDEO) < 0) + return NULL; + } + else if ((sdl_subsystem_flags & SDL_INIT_VIDEO) == 0) + { + if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) + return NULL; + } + + vid = (sdl_rs90_video_t*)calloc(1, sizeof(*vid)); + if (!vid) + return NULL; + +#if defined(DINGUX_BETA) + /* Get current refresh rate */ + refresh_rate_valid = dingux_get_video_refresh_rate(¤t_refresh_rate); + + /* Check if refresh rate needs to be updated */ + if (!refresh_rate_valid || + (current_refresh_rate != target_refresh_rate)) + hw_refresh_rate = dingux_set_video_refresh_rate(target_refresh_rate); + else + { + /* Correct refresh rate is already set, + * just convert to float */ + switch (current_refresh_rate) + { + case DINGUX_REFRESH_RATE_50HZ: + hw_refresh_rate = 50.0f; + break; + default: + hw_refresh_rate = 60.0f; + break; + } + } + + if (hw_refresh_rate == 0.0f) + { + RARCH_ERR("[SDL1]: Failed to set video refresh rate\n"); + goto error; + } + + vid->refresh_rate = target_refresh_rate; + switch (target_refresh_rate) + { + case DINGUX_REFRESH_RATE_50HZ: + vid->ff_frame_time_min = 20000; + break; + default: + vid->ff_frame_time_min = 16667; + break; + } + + driver_ctl(RARCH_DRIVER_CTL_SET_REFRESH_RATE, &hw_refresh_rate); +#else + vid->ff_frame_time_min = 16667; +#endif + + vid->screen = SDL_SetVideoMode( + SDL_RS90_WIDTH, SDL_RS90_HEIGHT, + video->rgb32 ? 32 : 16, + surface_flags); + + if (!vid->screen) + { + RARCH_ERR("[SDL1]: Failed to init SDL surface: %s\n", SDL_GetError()); + goto error; + } + + vid->content_width = SDL_RS90_WIDTH; + vid->content_height = SDL_RS90_HEIGHT; + vid->frame_width = SDL_RS90_WIDTH; + vid->frame_height = SDL_RS90_HEIGHT; + vid->rgb32 = video->rgb32; + vid->vsync = video->vsync; + vid->keep_aspect = settings->bools.video_dingux_ipu_keep_aspect; + vid->scale_integer = settings->bools.video_scale_integer; + vid->menu_active = false; + vid->was_in_menu = false; + vid->quitting = false; + vid->mode_valid = true; + vid->last_frame_time = 0; + + SDL_ShowCursor(SDL_DISABLE); + + sdl_rs90_input_driver_init(input_driver_name, + joypad_driver_name, input, input_data); + + /* Initialise OSD font */ + sdl_rs90_init_font_color(vid); + + vid->osd_font = bitmapfont_get_lut(); + + if (!vid->osd_font || + vid->osd_font->glyph_max < + (SDL_RS90_NUM_FONT_GLYPHS - 1)) + { + RARCH_ERR("[SDL1]: Failed to init OSD font\n"); + goto error; + } + + return vid; + +error: + sdl_rs90_gfx_free(vid); + return NULL; +} + +static void sdl_rs90_set_output( + sdl_rs90_video_t* vid, + unsigned width, unsigned height, bool rgb32) +{ + uint32_t surface_flags = (vid->vsync) ? + (SDL_HWSURFACE | SDL_TRIPLEBUF | SDL_FULLSCREEN) : + (SDL_HWSURFACE | SDL_FULLSCREEN); + + vid->content_width = width; + vid->content_height = height; + + /* Technically, "scale_integer" here just means "do not scale" + * If the content is larger, we crop, otherwise we just centre + * it in the frame. + * If we want to support a core with an absolutely tiny screen + * (i.e. less than 120x80), we should do actual integer scaling + * (PokeMini @ 96x64 and VeMUlator @ 48x32 are probably the + * only cores where this is an issue, but PokeMini at least + * offers internal upscaling...) */ + if (vid->scale_integer) + { + if (width > SDL_RS90_WIDTH) + { + vid->frame_width = SDL_RS90_WIDTH; + vid->frame_crop_x = (width - SDL_RS90_WIDTH) >> 1; + vid->frame_padding_x = 0; + } + else + { + vid->frame_width = width; + vid->frame_crop_x = 0; + vid->frame_padding_x = (SDL_RS90_WIDTH - width) >> 1; + } + + if (height > SDL_RS90_HEIGHT) + { + vid->frame_height = SDL_RS90_HEIGHT; + vid->frame_crop_y = (height - SDL_RS90_HEIGHT) >> 1; + vid->frame_padding_y = 0; + } + else + { + vid->frame_height = height; + vid->frame_crop_y = 0; + vid->frame_padding_y = (SDL_RS90_HEIGHT - height) >> 1; + } + } + else + { + /* Normal scaling */ + if (vid->keep_aspect) + { + if (height * SDL_RS90_WIDTH > width * SDL_RS90_HEIGHT) + { + /* Integer math is fine */ + vid->frame_width = (width * SDL_RS90_HEIGHT) / height; + vid->frame_height = SDL_RS90_HEIGHT; + } + else + { + /* Integer math is fine */ + vid->frame_width = SDL_RS90_WIDTH; + vid->frame_height = (height * SDL_RS90_WIDTH) / width; + } + } + else + { + vid->frame_width = SDL_RS90_WIDTH; + vid->frame_height = SDL_RS90_HEIGHT; + } + + vid->frame_crop_x = 0; + vid->frame_padding_x = (SDL_RS90_WIDTH - vid->frame_width) >> 1; + vid->frame_crop_y = 0; + vid->frame_padding_y = (SDL_RS90_HEIGHT - vid->frame_height) >> 1; + } + + /* Attempt to change video mode */ + vid->screen = SDL_SetVideoMode( + SDL_RS90_WIDTH, SDL_RS90_HEIGHT, + rgb32 ? 32 : 16, + surface_flags); + + /* Check whether selected display mode is valid */ + if (unlikely(!vid->screen)) + { + RARCH_ERR("[SDL1]: Failed to init SDL surface: %s\n", SDL_GetError()); + vid->mode_valid = false; + } + else + { + /* Determine whether frame padding is required */ + if ((vid->frame_padding_x > 0) || + (vid->frame_padding_y > 0)) + { + /* To prevent garbage pixels in the padding + * region, must zero out pixel buffer */ + if (SDL_MUSTLOCK(vid->screen)) + SDL_LockSurface(vid->screen); + + memset(vid->screen->pixels, 0, + vid->screen->pitch * vid->screen->h); + + if (SDL_MUSTLOCK(vid->screen)) + SDL_UnlockSurface(vid->screen); + } + + vid->mode_valid = true; + } +} + +/* Approximate nearest-neighbour scaling using + * bitshifts and integer math */ +static void sdl_rs90_blit_frame16_scale(sdl_rs90_video_t *vid, + uint16_t* src, unsigned width, unsigned height, + unsigned src_pitch) +{ + uint32_t x_step = (((uint32_t)(width) << 16) + 1) / vid->frame_width; + uint32_t y_step = (((uint32_t)(height) << 16) + 1) / vid->frame_height; + + /* 16 bit - divide pitch by 2 */ + size_t in_stride = (size_t)(src_pitch >> 1); + size_t out_stride = (size_t)(vid->screen->pitch >> 1); + + /* Apply x/y padding offset */ + uint16_t *top_corner = (uint16_t*)(vid->screen->pixels) + vid->frame_padding_x + + out_stride * vid->frame_padding_y; + + /* Temporary pointers */ + uint16_t *in_ptr = NULL; + uint16_t *out_ptr = NULL; + + uint32_t y = 0; + size_t row; + + /* TODO/FIXME: Optimize these loops further. + * Consider saving these computations in an array + * and indexing over them. + * Would likely be slower due to cache (non-)locality, + * but it's worth a shot. + * Tons of -> operations. */ + for (row = 0; row < vid->frame_height; row++) + { + size_t col = vid->frame_width; + uint32_t x = 0; + + out_ptr = top_corner + out_stride * row; + in_ptr = src + (y >> 16) * in_stride; + + do + { + *out_ptr = in_ptr[x >> 16]; + x += x_step; + out_ptr++; + } + while (--col); + + y += y_step; + } +} + +static void sdl_rs90_blit_frame16_no_scale(sdl_rs90_video_t *vid, + uint16_t* src, unsigned width, unsigned height, + unsigned src_pitch) +{ + /* 16 bit - divide pitch by 2 */ + size_t in_stride = (size_t)(src_pitch >> 1); + size_t out_stride = (size_t)(vid->screen->pitch >> 1); + + /* Manipulate offsets so that padding/crop + * are applied correctly */ + uint16_t *in_ptr = src + vid->frame_crop_x + vid->frame_crop_y * in_stride; + uint16_t *out_ptr = (uint16_t*)(vid->screen->pixels) + vid->frame_padding_x + + out_stride * vid->frame_padding_y; + + size_t y = vid->frame_height; + + /* TODO/FIXME: Optimize this loop */ + do + { + memcpy(out_ptr, in_ptr, vid->frame_width * sizeof(uint16_t)); + in_ptr += in_stride; + out_ptr += out_stride; + } + while (--y); +} + +static void sdl_rs90_blit_frame16(sdl_rs90_video_t *vid, + uint16_t* src, unsigned width, unsigned height, + unsigned src_pitch) +{ + /* If source and destination buffers have the + * same pitch, perform fast copy of raw pixel data */ + /* TODO/FIXME: Make sure this code path is used for + * GBA content */ + if (src_pitch == vid->screen->pitch && + height == SDL_RS90_HEIGHT) + memcpy(vid->screen->pixels, src, src_pitch * SDL_RS90_HEIGHT); + else + { + if (vid->scale_integer) + sdl_rs90_blit_frame16_no_scale( + vid, src, width, height, src_pitch); + else + sdl_rs90_blit_frame16_scale( + vid, src, width, height, src_pitch); + } +} + +static void sdl_rs90_blit_frame32_scale(sdl_rs90_video_t *vid, + uint32_t* src, unsigned width, unsigned height, + unsigned src_pitch) +{ + uint32_t x_step = (((uint32_t)(width) << 16) + 1) / vid->frame_width; + uint32_t y_step = (((uint32_t)(height) << 16) + 1) / vid->frame_height; + + /* 32 bit - divide pitch by 4 */ + size_t in_stride = (size_t)(src_pitch >> 2); + size_t out_stride = (size_t)(vid->screen->pitch >> 2); + + /* Apply x/y padding offset */ + uint32_t *top_corner = (uint32_t*)(vid->screen->pixels) + vid->frame_padding_x + + out_stride * vid->frame_padding_y; + + /* Temporary pointers */ + uint32_t *in_ptr = NULL; + uint32_t *out_ptr = NULL; + + uint32_t y = 0; + size_t row; + + /* TODO/FIXME: Optimize these loops further. + * Consider saving these computations in an array + * and indexing over them. + * Would likely be slower due to cache (non-)locality, + * but it's worth a shot. + * Tons of -> operations. */ + for (row = 0; row < vid->frame_height; row++) + { + size_t col = vid->frame_width; + uint32_t x = 0; + + out_ptr = top_corner + out_stride * row; + in_ptr = src + (y >> 16) * in_stride; + + do + { + *out_ptr = in_ptr[x >> 16]; + x += x_step; + out_ptr++; + } + while (--col); + + y += y_step; + } +} + +static void sdl_rs90_blit_frame32_no_scale(sdl_rs90_video_t *vid, + uint32_t* src, unsigned width, unsigned height, + unsigned src_pitch) +{ + /* 32 bit - divide pitch by 4 */ + size_t in_stride = (size_t)(src_pitch >> 2); + size_t out_stride = (size_t)(vid->screen->pitch >> 2); + + /* Manipulate offsets so that padding/crop + * are applied correctly */ + uint32_t *in_ptr = src + vid->frame_crop_x + vid->frame_crop_y * in_stride; + uint32_t *out_ptr = (uint32_t*)(vid->screen->pixels) + vid->frame_padding_x + + out_stride * vid->frame_padding_y; + + size_t y = vid->frame_height; + + /* TODO/FIXME: Optimize this loop */ + do + { + memcpy(out_ptr, in_ptr, vid->frame_width * sizeof(uint32_t)); + in_ptr += in_stride; + out_ptr += out_stride; + } + while (--y); +} + +static void sdl_rs90_blit_frame32(sdl_rs90_video_t *vid, + uint32_t* src, unsigned width, unsigned height, + unsigned src_pitch) +{ + /* If source and destination buffers have the + * same pitch, perform fast copy of raw pixel data */ + /* TODO/FIXME: Make sure this code path is used for + * GBA content */ + if ((src_pitch == vid->screen->pitch) && + (height == SDL_RS90_HEIGHT)) + memcpy(vid->screen->pixels, src, src_pitch * SDL_RS90_HEIGHT); + else + { + if (vid->scale_integer) + sdl_rs90_blit_frame32_no_scale( + vid, src, width, height, src_pitch); + else + sdl_rs90_blit_frame32_scale( + vid, src, width, height, src_pitch); + } +} + +static bool sdl_rs90_gfx_frame(void *data, const void *frame, + unsigned width, unsigned height, uint64_t frame_count, + unsigned pitch, const char *msg, video_frame_info_t *video_info) +{ + sdl_rs90_video_t* vid = (sdl_rs90_video_t*)data; + + /* Return early if: + * - Input sdl_rs90_video_t struct is NULL + * (cannot realistically happen) + * - Menu is inactive and input 'content' frame + * data is NULL (may happen when e.g. a running + * core skips a frame) */ + if (unlikely(!vid || (!frame && !vid->menu_active))) + return true; + + /* If fast forward is currently active, we may + * push frames at an 'unlimited' rate. Since the + * display has a fixed refresh rate of 60 Hz (or + * potentially 50 Hz on OpenDingux Beta), this + * represents wasted effort. We therefore drop any + * 'excess' frames in this case. + * (Note that we *only* do this when fast forwarding. + * Attempting this trick while running content normally + * will cause bad frame pacing) */ + if (unlikely(video_info->input_driver_nonblock_state)) + { + retro_time_t current_time = cpu_features_get_time_usec(); + + if ((current_time - vid->last_frame_time) < + vid->ff_frame_time_min) + return true; + + vid->last_frame_time = current_time; + } + +#ifdef HAVE_MENU + menu_driver_frame(video_info->menu_is_alive, video_info); +#endif + + if (likely(!vid->menu_active)) + { + /* Update video mode if we were in the menu on + * the previous frame, or width/height have changed */ + if (unlikely( + vid->was_in_menu || + (vid->content_width != width) || + (vid->content_height != height))) + sdl_rs90_set_output(vid, width, height, vid->rgb32); + + /* Must always lock SDL surface before + * manipulating raw pixel buffer */ + if (SDL_MUSTLOCK(vid->screen)) + SDL_LockSurface(vid->screen); + + if (likely(vid->mode_valid)) + { + /* Blit frame to SDL surface */ + if (vid->rgb32) + sdl_rs90_blit_frame32(vid, (uint32_t*)frame, + width, height, pitch); + else + sdl_rs90_blit_frame16(vid, (uint16_t*)frame, + width, height, pitch); + } + /* If current display mode is invalid, + * just display an error message */ + else + sdl_rs90_blit_video_mode_error_msg(vid); + + vid->was_in_menu = false; + } + else + { + /* If this is the first frame that the menu + * is active, update video mode */ + if (!vid->was_in_menu) + { + sdl_rs90_set_output(vid, + SDL_RS90_WIDTH, SDL_RS90_HEIGHT, false); + + vid->was_in_menu = true; + } + + if (SDL_MUSTLOCK(vid->screen)) + SDL_LockSurface(vid->screen); + + /* Blit menu texture to SDL surface */ + sdl_rs90_blit_frame16(vid, vid->menu_texture, + SDL_RS90_WIDTH, SDL_RS90_HEIGHT, + SDL_RS90_WIDTH * sizeof(uint16_t)); + } + + /* Print OSD text, if required */ + if (msg) + { + /* If menu is active, colour depth is overridden + * to 16 bit */ + if (vid->rgb32 && !vid->menu_active) + sdl_rs90_blit_text32(vid, FONT_WIDTH_STRIDE, + vid->screen->h - (FONT_HEIGHT + FONT_WIDTH_STRIDE), msg); + else + sdl_rs90_blit_text16(vid, FONT_WIDTH_STRIDE, + vid->screen->h - (FONT_HEIGHT + FONT_WIDTH_STRIDE), msg); + } + + /* Pixel manipulation complete - unlock + * SDL surface */ + if (SDL_MUSTLOCK(vid->screen)) + SDL_UnlockSurface(vid->screen); + + SDL_Flip(vid->screen); + + return true; +} + +static void sdl_rs90_set_texture_enable(void *data, bool state, bool full_screen) +{ + sdl_rs90_video_t *vid = (sdl_rs90_video_t*)data; + + if (unlikely(!vid)) + return; + + vid->menu_active = state; +} + +static void sdl_rs90_set_texture_frame(void *data, const void *frame, bool rgb32, + unsigned width, unsigned height, float alpha) +{ + sdl_rs90_video_t *vid = (sdl_rs90_video_t*)data; + + if (unlikely( + !vid || + rgb32 || + (width > SDL_RS90_WIDTH) || + (height > SDL_RS90_HEIGHT))) + return; + + memcpy(vid->menu_texture, frame, width * height * sizeof(uint16_t)); +} + +static void sdl_rs90_gfx_set_nonblock_state(void *data, bool toggle, + bool adaptive_vsync_enabled, unsigned swap_interval) +{ + sdl_rs90_video_t *vid = (sdl_rs90_video_t*)data; + bool vsync = !toggle; + + if (unlikely(!vid)) + return; + + /* Check whether vsync status has changed */ + if (vid->vsync != vsync) + { + unsigned current_width = vid->content_width; + unsigned current_height = vid->content_height; + vid->vsync = vsync; + + /* Update video mode */ + + /* TODO/FIXME: The following workaround is required + * on GCW0 devices; check whether it is required on + * the RS-90, and remove if not */ + + /* Note that a tedious workaround is required... + * - Calling SDL_SetVideoMode() with the currently + * set width, height and pixel format can randomly + * become a noop even if the surface flags change. + * - Since all we are doing here is changing the VSYNC + * parameter (which just modifies surface flags), this + * means the VSYNC toggle may not be registered... + * - This is a huge problem when enabling fast forward, + * because VSYNC ON effectively limits maximum frame + * rate - if we push frames too rapidly, the OS chokes + * and the display freezes. + * We have to ensure that the VSYNC state change is + * applied in all cases. We can only do this by forcing + * a 'real' video mode update, which means adjusting the + * video resolution. We therefore end up calling + * sdl_rs90_set_output() *twice*, setting the dimensions + * to an arbitrary value before restoring the actual + * desired width/height */ + sdl_rs90_set_output(vid, + current_width, + (current_height > 4) ? (current_height - 2) : 16, + vid->rgb32); + + sdl_rs90_set_output(vid, + current_width, current_height, vid->rgb32); + } +} + +static void sdl_rs90_gfx_check_window(sdl_rs90_video_t *vid) +{ + SDL_Event event; + + SDL_PumpEvents(); + while (SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_QUITMASK)) + { + if (event.type != SDL_QUIT) + continue; + + vid->quitting = true; + break; + } +} + +static bool sdl_rs90_gfx_alive(void *data) +{ + sdl_rs90_video_t *vid = (sdl_rs90_video_t*)data; + + if (unlikely(!vid)) + return false; + + sdl_rs90_gfx_check_window(vid); + return !vid->quitting; +} + +static bool sdl_rs90_gfx_focus(void *data) +{ + return true; +} + +static bool sdl_rs90_gfx_suppress_screensaver(void *data, bool enable) +{ + return false; +} + +static bool sdl_rs90_gfx_has_windowed(void *data) +{ + return false; +} + +static void sdl_rs90_gfx_viewport_info(void *data, struct video_viewport *vp) +{ + sdl_rs90_video_t *vid = (sdl_rs90_video_t*)data; + + if (unlikely(!vid)) + return; + + vp->x = 0; + vp->y = 0; + vp->width = vp->full_width = vid->frame_width; + vp->height = vp->full_height = vid->frame_height; +} + +static float sdl_rs90_get_refresh_rate(void *data) +{ +#if defined(DINGUX_BETA) + sdl_rs90_video_t *vid = (sdl_rs90_video_t*)data; + + if (!vid) + return 0.0f; + + switch (vid->refresh_rate) + { + case DINGUX_REFRESH_RATE_50HZ: + return 50.0f; + default: + break; + } +#endif + + return 60.0f; +} + +static void sdl_rs90_apply_state_changes(void *data) +{ + sdl_rs90_video_t *vid = (sdl_rs90_video_t*)data; + settings_t *settings = config_get_ptr(); + bool keep_aspect = (settings) ? settings->bools.video_dingux_ipu_keep_aspect : true; + bool integer_scaling = (settings) ? settings->bools.video_scale_integer : false; + + if (!vid || !settings) + return; + + if ((vid->keep_aspect != keep_aspect) || + (vid->scale_integer != integer_scaling)) + { + vid->keep_aspect = keep_aspect; + vid->scale_integer = integer_scaling; + + /* Aspect/scaling changes require all frame + * dimension/padding/cropping parameters to + * be recalculated. Easiest method is to just + * (re-)set the current output video mode */ + sdl_rs90_set_output(vid, vid->content_width, + vid->content_height, vid->rgb32); + } +} + +static uint32_t sdl_rs90_get_flags(void *data) +{ + return 0; +} + +static const video_poke_interface_t sdl_rs90_poke_interface = { + sdl_rs90_get_flags, + NULL, + NULL, + NULL, + sdl_rs90_get_refresh_rate, + NULL, /* set_filtering */ + NULL, /* get_video_output_size */ + NULL, /* get_video_output_prev */ + NULL, /* get_video_output_next */ + NULL, /* get_current_framebuffer */ + NULL, /* get_proc_address */ + NULL, + sdl_rs90_apply_state_changes, + sdl_rs90_set_texture_frame, + sdl_rs90_set_texture_enable, + NULL, + NULL, /* sdl_show_mouse */ + NULL, /* sdl_grab_mouse_toggle */ + NULL, /* get_current_shader */ + NULL, /* get_current_software_framebuffer */ + NULL /* get_hw_render_interface */ +}; + +static void sdl_rs90_get_poke_interface(void *data, const video_poke_interface_t **iface) +{ + *iface = &sdl_rs90_poke_interface; +} + +static bool sdl_rs90_gfx_set_shader(void *data, + enum rarch_shader_type type, const char *path) +{ + return false; +} + +video_driver_t video_sdl_rs90 = { + sdl_rs90_gfx_init, + sdl_rs90_gfx_frame, + sdl_rs90_gfx_set_nonblock_state, + sdl_rs90_gfx_alive, + sdl_rs90_gfx_focus, + sdl_rs90_gfx_suppress_screensaver, + sdl_rs90_gfx_has_windowed, + sdl_rs90_gfx_set_shader, + sdl_rs90_gfx_free, + "sdl_rs90", + NULL, + NULL, /* set_rotation */ + sdl_rs90_gfx_viewport_info, + NULL, /* read_viewport */ + NULL, /* read_frame_raw */ +#ifdef HAVE_OVERLAY + NULL, +#endif +#ifdef HAVE_VIDEO_LAYOUT + NULL, +#endif + sdl_rs90_get_poke_interface +}; diff --git a/griffin/griffin.c b/griffin/griffin.c index e60461a0ca..a187296e3b 100644 --- a/griffin/griffin.c +++ b/griffin/griffin.c @@ -467,6 +467,14 @@ VIDEO DRIVER #include "../gfx/common/sdl2_common.c" #endif +#if defined(DINGUX) && defined(HAVE_SDL_DINGUX) +#if defined(RS90) +#include "../gfx/drivers/sdl_rs90_gfx.c" +#else +#include "../gfx/drivers/sdl_dingux_gfx.c" +#endif +#endif + #ifdef HAVE_VG #include "../gfx/drivers/vg.c" #endif diff --git a/input/drivers_joypad/sdl_dingux_joypad.c b/input/drivers_joypad/sdl_dingux_joypad.c index 4b74166a40..8406390660 100644 --- a/input/drivers_joypad/sdl_dingux_joypad.c +++ b/input/drivers_joypad/sdl_dingux_joypad.c @@ -31,6 +31,11 @@ #include "../../configuration.h" #endif +#if !defined(RS90) +#define SDL_DINGUX_HAS_ANALOG 1 +#define SDL_DINGUX_HAS_MENU_TOGGLE 1 +#endif + /* Simple joypad driver designed to rationalise * the bizarre keyboard/gamepad hybrid setup * of OpenDingux devices */ @@ -66,7 +71,9 @@ typedef struct typedef struct { +#if defined(SDL_DINGUX_HAS_ANALOG) SDL_Joystick *device; +#endif #if defined(HAVE_LIBSHAKE) dingux_joypad_rumble_t rumble; #endif @@ -74,11 +81,15 @@ typedef struct uint16_t pad_state; int16_t analog_state[2][2]; bool connected; +#if defined(SDL_DINGUX_HAS_MENU_TOGGLE) bool menu_toggle; +#endif } dingux_joypad_t; +#if defined(SDL_DINGUX_HAS_MENU_TOGGLE) /* TODO/FIXME - global referenced outside */ extern uint64_t lifecycle_state; +#endif static dingux_joypad_t dingux_joypad; @@ -259,6 +270,7 @@ static void sdl_dingux_joypad_connect(void) { dingux_joypad_t *joypad = (dingux_joypad_t*)&dingux_joypad; +#if defined(SDL_DINGUX_HAS_ANALOG) /* Open joypad device */ if (SDL_NumJoysticks() > 0) joypad->device = SDL_JoystickOpen(0); @@ -266,6 +278,7 @@ static void sdl_dingux_joypad_connect(void) /* If joypad exists, get number of axes */ if (joypad->device) joypad->num_axes = SDL_JoystickNumAxes(joypad->device); +#endif #if defined(HAVE_LIBSHAKE) /* Configure rumble interface */ @@ -289,8 +302,10 @@ static void sdl_dingux_joypad_disconnect(void) { dingux_joypad_t *joypad = (dingux_joypad_t*)&dingux_joypad; +#if defined(SDL_DINGUX_HAS_ANALOG) if (joypad->device) SDL_JoystickClose(joypad->device); +#endif if (joypad->connected) input_autoconfigure_disconnect(0, sdl_dingux_joypad.ident); @@ -329,7 +344,9 @@ static void sdl_dingux_joypad_destroy(void) Shake_Quit(); #endif +#if defined(SDL_DINGUX_HAS_MENU_TOGGLE) BIT64_CLEAR(lifecycle_state, RARCH_MENU_TOGGLE); +#endif } static void *sdl_dingux_joypad_init(void *data) @@ -338,8 +355,11 @@ static void *sdl_dingux_joypad_init(void *data) uint32_t sdl_subsystem_flags = SDL_WasInit(0); memset(joypad, 0, sizeof(dingux_joypad_t)); +#if defined(SDL_DINGUX_HAS_MENU_TOGGLE) BIT64_CLEAR(lifecycle_state, RARCH_MENU_TOGGLE); +#endif +#if defined(SDL_DINGUX_HAS_ANALOG) /* Initialise joystick subsystem, if required */ if (sdl_subsystem_flags == 0) { @@ -351,6 +371,7 @@ static void *sdl_dingux_joypad_init(void *data) if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) < 0) return NULL; } +#endif #if defined(HAVE_LIBSHAKE) /* Initialise rumble interface */ @@ -397,6 +418,7 @@ static void sdl_dingux_joypad_get_buttons(unsigned port, input_bits_t *state) static int16_t sdl_dingux_joypad_axis_state(unsigned port, uint32_t joyaxis) { +#if defined(SDL_DINGUX_HAS_ANALOG) dingux_joypad_t *joypad = (dingux_joypad_t*)&dingux_joypad; int val = 0; int axis = -1; @@ -437,6 +459,9 @@ static int16_t sdl_dingux_joypad_axis_state(unsigned port, uint32_t joyaxis) return 0; return val; +#else + return 0; +#endif } static int16_t sdl_dingux_joypad_axis(unsigned port, uint32_t joyaxis) @@ -465,16 +490,20 @@ static int16_t sdl_dingux_joypad_state( /* Auto-binds are per joypad, not per user. */ const uint64_t joykey = (binds[i].joykey != NO_BTN) ? binds[i].joykey : joypad_info->auto_binds[i].joykey; +#if defined(SDL_DINGUX_HAS_ANALOG) const uint32_t joyaxis = (binds[i].joyaxis != AXIS_NONE) ? binds[i].joyaxis : joypad_info->auto_binds[i].joyaxis; - - if ((uint16_t)joykey != NO_BTN && +#endif + + if ((uint16_t)joykey != NO_BTN && (joypad->pad_state & (1 << (uint16_t)joykey))) ret |= (1 << i); +#if defined(SDL_DINGUX_HAS_ANALOG) else if (joyaxis != AXIS_NONE && - ((float)abs(sdl_dingux_joypad_axis_state(port_idx, joyaxis)) + ((float)abs(sdl_dingux_joypad_axis_state(port_idx, joyaxis)) / 0x8000) > joypad_info->axis_threshold) ret |= (1 << i); +#endif } return ret; @@ -485,6 +514,7 @@ static void sdl_dingux_joypad_poll(void) dingux_joypad_t *joypad = (dingux_joypad_t*)&dingux_joypad; SDL_Event event; +#if defined(SDL_DINGUX_HAS_MENU_TOGGLE) /* Note: The menu toggle key is an awkward special * case - the press/release events happen almost * instantaneously, and since we only sample once @@ -496,6 +526,7 @@ static void sdl_dingux_joypad_poll(void) BIT64_CLEAR(lifecycle_state, RARCH_MENU_TOGGLE); joypad->menu_toggle = false; } +#endif /* All digital inputs map to keyboard keys * - X: SDLK_SPACE @@ -571,10 +602,12 @@ static void sdl_dingux_joypad_poll(void) case SDLK_LEFT: BIT16_SET(joypad->pad_state, RETRO_DEVICE_ID_JOYPAD_LEFT); break; +#if defined(SDL_DINGUX_HAS_MENU_TOGGLE) case SDLK_HOME: BIT64_SET(lifecycle_state, RARCH_MENU_TOGGLE); joypad->menu_toggle = true; break; +#endif default: break; } @@ -639,6 +672,7 @@ static void sdl_dingux_joypad_poll(void) } } +#if defined(SDL_DINGUX_HAS_ANALOG) /* Analog inputs come from the joypad device, * if connected */ if (joypad->device) @@ -676,6 +710,7 @@ static void sdl_dingux_joypad_poll(void) (axis_value < -0x7FFF) ? -0x7FFF : axis_value; } } +#endif } input_device_driver_t sdl_dingux_joypad = { diff --git a/libretro-common/rthreads/rthreads.c b/libretro-common/rthreads/rthreads.c index bb5b38b037..3942651532 100644 --- a/libretro-common/rthreads/rthreads.c +++ b/libretro-common/rthreads/rthreads.c @@ -872,7 +872,7 @@ bool scond_wait_timeout(scond_t *cond, slock_t *lock, int64_t timeout_us) int tickms = ps2_clock(); now.tv_sec = tickms/1000; now.tv_nsec = tickms * 1000; -#elif defined(__mips__) || defined(VITA) || defined(_3DS) +#elif !defined(DINGUX_BETA) && (defined(__mips__) || defined(VITA) || defined(_3DS)) struct timeval tm; gettimeofday(&tm, NULL); diff --git a/menu/drivers/rgui.c b/menu/drivers/rgui.c index ff8631edeb..522c03b778 100644 --- a/menu/drivers/rgui.c +++ b/menu/drivers/rgui.c @@ -80,6 +80,22 @@ #define RGUI_MIN_FB_WIDTH 256 #define RGUI_MAX_FB_WIDTH 426 +#if defined(DINGUX) +#if defined(RS90) +/* The RS-90 uses a fixed framebuffer size + * of 240x160 */ +#define RGUI_DINGUX_ASPECT_RATIO RGUI_ASPECT_RATIO_3_2 +#define RGUI_DINGUX_FB_WIDTH 240 +#define RGUI_DINGUX_FB_HEIGHT 160 +#else +/* Other Dingux devices (RG350 etc.) use a + * fixed framebuffer size of 320x240 */ +#define RGUI_DINGUX_ASPECT_RATIO RGUI_ASPECT_RATIO_4_3 +#define RGUI_DINGUX_FB_WIDTH 320 +#define RGUI_DINGUX_FB_HEIGHT 240 +#endif +#endif + /* Maximum entry value length in characters * when using fixed with layouts * (i.e. Maximum possible 'spacing' as @@ -1502,20 +1518,21 @@ static bool rgui_set_pixel_format_function(void) return transparency_supported; } - if ( string_is_equal(driver_ident, "ps2")) /* PS2 */ + if ( string_is_equal(driver_ident, "ps2")) /* PS2 */ { argb32_to_pixel_platform_format = argb32_to_abgr1555; transparency_supported = false; } - else if (string_is_equal(driver_ident, "gx")) /* GEKKO */ + else if (string_is_equal(driver_ident, "gx")) /* GEKKO */ argb32_to_pixel_platform_format = argb32_to_rgb5a3; - else if (string_is_equal(driver_ident, "psp1")) /* PSP */ + else if (string_is_equal(driver_ident, "psp1")) /* PSP */ argb32_to_pixel_platform_format = argb32_to_abgr4444; - else if (string_is_equal(driver_ident, "d3d10") || /* D3D10/11/12 */ + else if (string_is_equal(driver_ident, "d3d10") || /* D3D10/11/12 */ string_is_equal(driver_ident, "d3d11") || string_is_equal(driver_ident, "d3d12")) argb32_to_pixel_platform_format = argb32_to_bgra4444; - else if (string_is_equal(driver_ident, "sdl_dingux")) /* DINGUX SDL */ + else if (string_is_equal(driver_ident, "sdl_dingux") || /* DINGUX SDL */ + string_is_equal(driver_ident, "sdl_rs90")) { argb32_to_pixel_platform_format = argb32_to_rgb565; transparency_supported = false; @@ -3006,7 +3023,7 @@ static void load_custom_theme(rgui_t *rgui, rgui_theme_t *theme_colors, const ch const char *wallpaper_key = NULL; bool success = false; #if defined(DINGUX) - unsigned aspect_ratio = RGUI_ASPECT_RATIO_4_3; + unsigned aspect_ratio = RGUI_DINGUX_ASPECT_RATIO; #else settings_t *settings = config_get_ptr(); unsigned aspect_ratio = settings->uints.menu_rgui_aspect_ratio; @@ -5435,15 +5452,14 @@ static bool rgui_set_aspect_ratio(rgui_t *rgui, * width value must be zero... */ unsigned max_frame_buf_width = 424; #elif defined(DINGUX) - /* Dingux devices use a fixed framebuffer size - * of 320x240 */ - unsigned max_frame_buf_width = 320; + /* Dingux devices use a fixed framebuffer size */ + unsigned max_frame_buf_width = RGUI_DINGUX_FB_WIDTH; #else struct video_viewport vp; unsigned max_frame_buf_width = RGUI_MAX_FB_WIDTH; #endif #if defined(DINGUX) - unsigned aspect_ratio = RGUI_ASPECT_RATIO_4_3; + unsigned aspect_ratio = RGUI_DINGUX_ASPECT_RATIO; unsigned aspect_ratio_lock = RGUI_ASPECT_RATIO_LOCK_NONE; #else settings_t *settings = config_get_ptr(); @@ -5469,9 +5485,8 @@ static bool rgui_set_aspect_ratio(rgui_t *rgui, * values */ rgui->frame_buf.height = p_disp->framebuf_height; #elif defined(DINGUX) - /* Dingux devices use a fixed framebuffer size - * of 320x240 */ - rgui->frame_buf.height = 240; + /* Dingux devices use a fixed framebuffer size */ + rgui->frame_buf.height = RGUI_DINGUX_FB_HEIGHT; #else /* If window height is less than RGUI default * height of 240, allow the frame buffer to @@ -6587,7 +6602,7 @@ static void rgui_frame(void *data, video_frame_info_t *video_info) bool bg_filler_thickness_enable = settings->bools.menu_rgui_background_filler_thickness_enable; bool border_filler_thickness_enable = settings->bools.menu_rgui_border_filler_thickness_enable; #if defined(DINGUX) - unsigned aspect_ratio = RGUI_ASPECT_RATIO_4_3; + unsigned aspect_ratio = RGUI_DINGUX_ASPECT_RATIO; unsigned aspect_ratio_lock = RGUI_ASPECT_RATIO_LOCK_NONE; #else unsigned aspect_ratio = settings->uints.menu_rgui_aspect_ratio; @@ -6714,7 +6729,7 @@ static void rgui_frame(void *data, video_frame_info_t *video_info) if ((rgui->window_width != video_width) || (rgui->window_height != video_height)) { -#if !defined(GEKKO) +#if !defined(GEKKO) && !defined(DINGUX) /* If window width or height are less than the * RGUI default size of (320-426)x240, must enable * dynamic menu 'downscaling'. @@ -6744,7 +6759,6 @@ static void rgui_frame(void *data, video_frame_info_t *video_info) case RGUI_ASPECT_RATIO_5_3_CENTRE: default_fb_width = 400; break; - default: /* 4:3 */ default_fb_width = 320; diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index 00805b4f5c..c972e8696b 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -7768,7 +7768,8 @@ unsigned menu_displaylist_build_list( case DISPLAYLIST_VIDEO_SCALING_SETTINGS_LIST: { #if defined(DINGUX) - if (string_is_equal(settings->arrays.video_driver, "sdl_dingux")) + if (string_is_equal(settings->arrays.video_driver, "sdl_dingux") || + string_is_equal(settings->arrays.video_driver, "sdl_rs90")) { if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(list, MENU_ENUM_LABEL_VIDEO_SCALE_INTEGER, diff --git a/menu/menu_setting.c b/menu/menu_setting.c index 19631ad7a3..ca7aad473e 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -10954,7 +10954,8 @@ static bool setting_append_list( } #if defined(DINGUX) && defined(DINGUX_BETA) - if (string_is_equal(settings->arrays.video_driver, "sdl_dingux")) + if (string_is_equal(settings->arrays.video_driver, "sdl_dingux") || + string_is_equal(settings->arrays.video_driver, "sdl_rs90")) { CONFIG_UINT( list, list_info, @@ -11209,7 +11210,8 @@ static bool setting_append_list( SETTINGS_DATA_LIST_CURRENT_ADD_FLAGS(list, list_info, SD_FLAG_LAKKA_ADVANCED); #if defined(DINGUX) - if (string_is_equal(settings->arrays.video_driver, "sdl_dingux")) + if (string_is_equal(settings->arrays.video_driver, "sdl_dingux") || + string_is_equal(settings->arrays.video_driver, "sdl_rs90")) { CONFIG_BOOL( list, list_info, @@ -14935,10 +14937,11 @@ static bool setting_append_list( general_read_handler); MENU_SETTINGS_LIST_CURRENT_ADD_VALUES(list, list_info, "cfg"); - /* ps2 and sdl_dingux gfx drivers do not support - * menu framebuffer transparency */ + /* ps2 and sdl_dingux/sdl_rs90 gfx drivers do + * not support menu framebuffer transparency */ if (!string_is_equal(settings->arrays.video_driver, "ps2") && - !string_is_equal(settings->arrays.video_driver, "sdl_dingux")) + !string_is_equal(settings->arrays.video_driver, "sdl_dingux") && + !string_is_equal(settings->arrays.video_driver, "sdl_rs90")) { CONFIG_BOOL( list, list_info, diff --git a/retroarch.h b/retroarch.h index 8dde537f69..d49dca46cd 100644 --- a/retroarch.h +++ b/retroarch.h @@ -1874,6 +1874,7 @@ extern video_driver_t video_xvideo; extern video_driver_t video_sdl; extern video_driver_t video_sdl2; extern video_driver_t video_sdl_dingux; +extern video_driver_t video_sdl_rs90; extern video_driver_t video_vg; extern video_driver_t video_omap; extern video_driver_t video_exynos; diff --git a/retroarch_data.h b/retroarch_data.h index 22d74a3406..b48ace713d 100644 --- a/retroarch_data.h +++ b/retroarch_data.h @@ -645,8 +645,12 @@ static const video_driver_t *video_drivers[] = { &video_sdl2, #endif #ifdef HAVE_SDL_DINGUX +#if defined(RS90) + &video_sdl_rs90, +#else &video_sdl_dingux, #endif +#endif #ifdef HAVE_XVIDEO &video_xvideo, #endif @@ -995,7 +999,7 @@ static input_device_driver_t *joypad_drivers[] = { }; #ifdef HAVE_HID -static bool null_hid_joypad_query(void *data, unsigned pad) { +static bool null_hid_joypad_query(void *data, unsigned pad) { return pad < MAX_USERS; } static const char *null_hid_joypad_name( void *data, unsigned pad) { return NULL; } @@ -1665,7 +1669,7 @@ typedef struct discord_state discord_state_t; #endif struct runloop -{ +{ retro_usec_t frame_time_last; /* int64_t alignment */ msg_queue_t msg_queue; /* ptr alignment */ @@ -1733,7 +1737,7 @@ struct rarch_state menu_input_t menu_input_state; /* retro_time_t alignment */ #endif - + #if defined(HAVE_CG) || defined(HAVE_GLSL) || defined(HAVE_SLANG) || defined(HAVE_HLSL) rarch_timer_t shader_delay_timer; /* int64_t alignment */ @@ -1911,7 +1915,7 @@ struct rarch_state struct retro_subsystem_rom_info subsystem_data_roms[SUBSYSTEM_MAX_SUBSYSTEMS] [SUBSYSTEM_MAX_SUBSYSTEM_ROMS]; /* ptr alignment */ - + gfx_ctx_driver_t current_video_context; /* ptr alignment */ content_state_t content_st; /* ptr alignment */ midi_event_t midi_drv_input_event; /* ptr alignment */ @@ -1989,7 +1993,7 @@ struct rarch_state size_t runahead_save_state_size; #endif - jmp_buf error_sjlj_context; /* 4-byte alignment, + jmp_buf error_sjlj_context; /* 4-byte alignment, put it right before long */ turbo_buttons_t input_driver_turbo_btns; /* int32_t alignment */ @@ -2017,7 +2021,7 @@ struct rarch_state int reannounce; #endif - input_device_info_t input_device_info[MAX_INPUT_DEVICES]; + input_device_info_t input_device_info[MAX_INPUT_DEVICES]; /* unsigned alignment */ #ifdef HAVE_MENU menu_dialog_t dialog_st; /* unsigned alignment */ @@ -2093,7 +2097,7 @@ struct rarch_state #endif #ifdef HAVE_MENU - menu_input_pointer_hw_state_t menu_input_pointer_hw_state; + menu_input_pointer_hw_state_t menu_input_pointer_hw_state; /* int16_t alignment */ #endif From 7af4f6e84d1d9bba75079903149d315d1dafe4b3 Mon Sep 17 00:00:00 2001 From: jdgleaver Date: Thu, 8 Jul 2021 16:43:02 +0100 Subject: [PATCH 26/58] (.gitlab-ci.yml) Add RS-90 target --- .gitlab-ci.yml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 2cd195ef29..88c203ba46 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -426,6 +426,28 @@ build-retroarch-dingux-odbeta-mips32: - "cp -f libretro-common/audio/dsp_filters/*.dsp ${MEDIA_PATH}/${CI_PROJECT_NAME}/filters/audio" - "cp -f gfx/video_filters/*.filt ${MEDIA_PATH}/${CI_PROJECT_NAME}/filters/video" +build-retroarch-rs90-odbeta-mips32: + image: $CI_SERVER_HOST:5050/libretro-infrastructure/libretro-build-dingux:odbeta + stage: build + variables: + MEDIA_PATH: .media + STRIP_BIN: 1 + before_script: + - export NUMPROC=$(($(nproc)/3)) + artifacts: + paths: + - retroarch + - retroarch_rs90_odbeta.opk + - ${MEDIA_PATH} + expire_in: 10 min + dependencies: [] + script: + - "make -j$NUMPROC -f Makefile.rs90" + - "mkdir -p ${MEDIA_PATH}/${CI_PROJECT_NAME}/filters/audio" + - "mkdir -p ${MEDIA_PATH}/${CI_PROJECT_NAME}/filters/video" + - "cp -f libretro-common/audio/dsp_filters/*.dsp ${MEDIA_PATH}/${CI_PROJECT_NAME}/filters/audio" + - "cp -f gfx/video_filters/*.filt ${MEDIA_PATH}/${CI_PROJECT_NAME}/filters/video" + build-retroarch-android-normal: image: $CI_SERVER_HOST:5050/libretro-infrastructure/libretro-build-android:latest stage: build From 137f18bed11c625539563a954ad0cb90ff084bfa Mon Sep 17 00:00:00 2001 From: jdgleaver Date: Wed, 14 Jul 2021 15:03:29 +0100 Subject: [PATCH 27/58] (RGUI) Fix sublabel length when menu clock is disabled --- menu/drivers/rgui.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/menu/drivers/rgui.c b/menu/drivers/rgui.c index 522c03b778..fe76981ac2 100644 --- a/menu/drivers/rgui.c +++ b/menu/drivers/rgui.c @@ -4736,7 +4736,9 @@ static void rgui_render(void *data, unsigned title_y = rgui->term_layout.start_y - rgui->font_height_stride; unsigned term_end_x = rgui->term_layout.start_x + (rgui->term_layout.width * rgui->font_width_stride); unsigned timedate_x = term_end_x - (5 * rgui->font_width_stride); - unsigned core_name_len = ((timedate_x - rgui->term_layout.start_x) / rgui->font_width_stride) - 3; + unsigned core_name_len = menu_timedate_enable ? + ((timedate_x - rgui->term_layout.start_x) / rgui->font_width_stride) - 3 : + rgui->term_layout.width - 1; bool show_mini_thumbnails = rgui->is_playlist && rgui_inline_thumbnails; bool show_thumbnail = false; bool show_left_thumbnail = false; From 7439f4d6d00735451566ded702bd7a547307fb94 Mon Sep 17 00:00:00 2001 From: jdgleaver Date: Wed, 14 Jul 2021 15:27:07 +0100 Subject: [PATCH 28/58] (RS-90) Disable menu clock by default --- config.def.h | 8 ++++++++ configuration.c | 2 +- menu/menu_setting.c | 2 +- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/config.def.h b/config.def.h index 45c99427d1..14e403c221 100644 --- a/config.def.h +++ b/config.def.h @@ -1324,6 +1324,14 @@ static const unsigned menu_left_thumbnails_default = 0; static const unsigned gfx_thumbnail_upscale_threshold = 0; #ifdef HAVE_MENU +#if defined(RS90) +/* The RS-90 has a hardware clock that is neither + * configurable nor persistent, rendering it useless. + * We therefore hide it in the menu by default. */ +#define DEFAULT_MENU_TIMEDATE_ENABLE false +#else +#define DEFAULT_MENU_TIMEDATE_ENABLE true +#endif #define DEFAULT_MENU_TIMEDATE_STYLE MENU_TIMEDATE_STYLE_DDMM_HM #define DEFAULT_MENU_TIMEDATE_DATE_SEPARATOR MENU_TIMEDATE_DATE_SEPARATOR_HYPHEN #endif diff --git a/configuration.c b/configuration.c index fc75a820a1..ae5d26b483 100644 --- a/configuration.c +++ b/configuration.c @@ -1627,7 +1627,7 @@ static struct config_bool_setting *populate_settings_bool( SETTING_BOOL("menu_insert_disk_resume", &settings->bools.menu_insert_disk_resume, true, DEFAULT_MENU_INSERT_DISK_RESUME, false); SETTING_BOOL("menu_mouse_enable", &settings->bools.menu_mouse_enable, true, DEFAULT_MOUSE_ENABLE, false); SETTING_BOOL("menu_pointer_enable", &settings->bools.menu_pointer_enable, true, DEFAULT_POINTER_ENABLE, false); - SETTING_BOOL("menu_timedate_enable", &settings->bools.menu_timedate_enable, true, true, false); + SETTING_BOOL("menu_timedate_enable", &settings->bools.menu_timedate_enable, true, DEFAULT_MENU_TIMEDATE_ENABLE, false); SETTING_BOOL("menu_battery_level_enable", &settings->bools.menu_battery_level_enable, true, true, false); SETTING_BOOL("menu_core_enable", &settings->bools.menu_core_enable, true, true, false); SETTING_BOOL("menu_show_sublabels", &settings->bools.menu_show_sublabels, true, menu_show_sublabels, false); diff --git a/menu/menu_setting.c b/menu/menu_setting.c index ca7aad473e..6bd2ec6286 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -16430,7 +16430,7 @@ static bool setting_append_list( &settings->bools.menu_timedate_enable, MENU_ENUM_LABEL_TIMEDATE_ENABLE, MENU_ENUM_LABEL_VALUE_TIMEDATE_ENABLE, - true, + DEFAULT_MENU_TIMEDATE_ENABLE, MENU_ENUM_LABEL_VALUE_OFF, MENU_ENUM_LABEL_VALUE_ON, &group_info, From 14580e5f6f16ff1a82f8199d8af75b19d9991369 Mon Sep 17 00:00:00 2001 From: jdgleaver Date: Wed, 14 Jul 2021 16:44:30 +0100 Subject: [PATCH 29/58] (RS-90) Fix offset of OSD text --- gfx/drivers/sdl_rs90_gfx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gfx/drivers/sdl_rs90_gfx.c b/gfx/drivers/sdl_rs90_gfx.c index 77246a7e5f..db599eacf8 100644 --- a/gfx/drivers/sdl_rs90_gfx.c +++ b/gfx/drivers/sdl_rs90_gfx.c @@ -124,8 +124,8 @@ static void sdl_rs90_blit_text16( bool **font_lut = vid->osd_font->lut; /* 16 bit - divide pitch by 2 */ uint16_t screen_stride = (uint16_t)(vid->screen->pitch >> 1); - uint16_t screen_width = vid->frame_width; - uint16_t screen_height = vid->frame_height; + uint16_t screen_width = vid->screen->w; + uint16_t screen_height = vid->screen->h; unsigned x_pos = x + vid->frame_padding_x; unsigned y_pos = (y > (screen_height >> 1)) ? (y - vid->frame_padding_y) : (y + vid->frame_padding_y); From 043765949073e1a4d68e88cd5d4f6a7d07b000f7 Mon Sep 17 00:00:00 2001 From: jdgleaver Date: Thu, 15 Jul 2021 11:15:55 +0100 Subject: [PATCH 30/58] (RS-90) Disable unnecessary/inappropriate build flags --- Makefile.rs90 | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/Makefile.rs90 b/Makefile.rs90 index cfb26c41d1..7b5f2b1d18 100644 --- a/Makefile.rs90 +++ b/Makefile.rs90 @@ -43,10 +43,9 @@ RS90 = 1 DINGUX = 1 DINGUX_BETA = 1 HAVE_SCREENSHOTS = 0 -HAVE_REWIND = 1 +HAVE_REWIND = 0 HAVE_7ZIP = 1 HAVE_AL = 0 -# ALSA freezes when switching back from menu HAVE_ALSA = 1 HAVE_DSP_FILTER = 1 HAVE_VIDEO_FILTER = 1 @@ -59,20 +58,20 @@ HAVE_C99 = 1 HAVE_CC = 1 HAVE_CC_RESAMPLER = 1 -HAVE_CHD = 1 +HAVE_CHD = 0 HAVE_COMMAND = 0 HAVE_CXX = 1 -HAVE_DR_MP3 = 1 +HAVE_DR_MP3 = 0 HAVE_DYNAMIC = 1 HAVE_EGL = 0 HAVE_FREETYPE = 0 -HAVE_GDI = 1 +HAVE_GDI = 0 HAVE_GETADDRINFO = 0 HAVE_GETOPT_LONG = 1 HAVE_GLSL = 0 -HAVE_HID = 1 -HAVE_IBXM = 1 -HAVE_IMAGEVIEWER = 1 +HAVE_HID = 0 +HAVE_IBXM = 0 +HAVE_IMAGEVIEWER = 0 HAVE_LANGEXTRA = 0 HAVE_LIBRETRODB = 1 HAVE_MENU = 1 @@ -85,18 +84,18 @@ HAVE_OPENGL1 = 0 HAVE_OPENGLES = 0 HAVE_OPENGLES3 = 0 HAVE_OPENGL_CORE = 0 -HAVE_OPENSSL = 1 +HAVE_OPENSSL = 0 HAVE_OVERLAY = 0 HAVE_RBMP = 1 HAVE_RJPEG = 1 HAVE_RPILED = 0 HAVE_RPNG = 1 -HAVE_RUNAHEAD = 1 +HAVE_RUNAHEAD = 0 HAVE_SDL_DINGUX = 1 HAVE_SHADERPIPELINE = 0 HAVE_STB_FONT = 0 -HAVE_STB_IMAGE = 1 -HAVE_STB_VORBIS = 1 +HAVE_STB_IMAGE = 0 +HAVE_STB_VORBIS = 0 HAVE_STDIN_CMD = 0 HAVE_STRCASESTR = 1 HAVE_THREADS = 1 @@ -144,7 +143,6 @@ SDL_DINGUX_CFLAGS := $(shell $(GCW0_SDL_CONFIG) --cflags) SDL_DINGUX_LIBS := $(shell $(GCW0_SDL_CONFIG) --libs) FREETYPE_CFLAGS := $(shell $(GCW0_FREETYPE_CONFIG) --cflags) FREETYPE_LIBS := $(shell $(GCW0_FREETYPE_CONFIG) --libs) -# AL_LIBS := -lopenal MMAP_LIBS = -lc OBJDIR_BASE := obj-unix From 21228cfbd4b5affad4ee37137dadb7a6bf8c6e82 Mon Sep 17 00:00:00 2001 From: jdgleaver Date: Thu, 15 Jul 2021 11:50:08 +0100 Subject: [PATCH 31/58] (RS-90) Hide 'Bilinear Filtering' video option --- menu/menu_setting.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/menu/menu_setting.c b/menu/menu_setting.c index 6bd2ec6286..d65711c726 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -11466,7 +11466,7 @@ static bool setting_append_list( menu_settings_list_current_add_range(list, list_info, 0, DINGUX_IPU_FILTER_LAST - 1, 1, true, true); (*list)[list_info->index - 1].ui_type = ST_UI_TYPE_UINT_COMBOBOX; } - else + else if (!string_is_equal(settings->arrays.video_driver, "sdl_rs90")) #endif { CONFIG_BOOL( From 7900ba604fb85a6dc2c829860d9d5cb8303d2e09 Mon Sep 17 00:00:00 2001 From: IlDucci Date: Thu, 15 Jul 2021 15:21:27 +0200 Subject: [PATCH 32/58] Fetch translations from Crowdin 15-Jul-2021 --- intl/msg_hash_de.h | 18 +++++++-------- intl/msg_hash_es.h | 8 +++++++ intl/msg_hash_fr.h | 8 +++++++ intl/msg_hash_it.h | 8 +++++++ intl/msg_hash_ko.h | 8 +++++++ intl/msg_hash_pt_br.h | 8 +++++++ intl/msg_hash_ru.h | 8 +++++++ intl/msg_hash_tr.h | 8 +++++++ intl/msg_hash_uk.h | 8 +++++++ intl/progress.h | 52 +++++++++++++++++++++---------------------- 10 files changed, 99 insertions(+), 35 deletions(-) diff --git a/intl/msg_hash_de.h b/intl/msg_hash_de.h index 7972b9f828..5ab496b162 100644 --- a/intl/msg_hash_de.h +++ b/intl/msg_hash_de.h @@ -922,18 +922,10 @@ MSG_HASH( MENU_ENUM_SUBLABEL_DRIVER_SETTINGS, "Die von diesem System verwendeten Treiber ändern." ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_VIDEO_SETTINGS, - "Videotreiber" - ) MSG_HASH( MENU_ENUM_SUBLABEL_VIDEO_SETTINGS, "Videoausgabe-Einstellungen ändern." ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_SETTINGS, - "Audiotreiber" - ) MSG_HASH( MENU_ENUM_SUBLABEL_AUDIO_SETTINGS, "Audioausgabe-Einstellungen ändern." @@ -1535,6 +1527,14 @@ MSG_HASH( MENU_ENUM_SUBLABEL_VIDEO_SCALE_INTEGER, "Das Bild in ganzzahligen Schritten skalieren. Die Basisgröße hängt von der vom System gemeldeten Geometrie und dem Seitenverhältnis ab. Wenn \"Seitenverhältnis erzwingen\" nicht gewählt ist, werden Höhe u. Breite unabhängig skaliert." ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_SCALE_INTEGER_OVERSCALE, + "Aufgerundete ganzzahlige Skalierung" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_SCALE_INTEGER_OVERSCALE, + "Bei ganzzahliger Skalierung den Skalierungsfaktor aufrunden, statt ihn abzurunden." + ) MSG_HASH( MENU_ENUM_LABEL_VALUE_VIDEO_ASPECT_RATIO_INDEX, "Bildseitenverhältnis" @@ -7715,7 +7715,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_LABEL_VALUE_RGUI_ASPECT_RATIO_LOCK_INTEGER, - "Pixelgenaue Bildskalierung" + "Ganzzahlige Skalierung" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_RGUI_ASPECT_RATIO_LOCK_FILL_SCREEN, diff --git a/intl/msg_hash_es.h b/intl/msg_hash_es.h index 2e1775cc9e..719732afed 100644 --- a/intl/msg_hash_es.h +++ b/intl/msg_hash_es.h @@ -1587,6 +1587,14 @@ MSG_HASH( MENU_ENUM_SUBLABEL_VIDEO_SCALE_INTEGER, "Limita el escalado de vídeo a múltiplos enteros. El tamaño base dependerá de la geometría indicada por el sistema y la relación de aspecto. Si la opción «Forzar relación de aspecto» está desactivada, los valores X e Y serán escalados individualmente." ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_SCALE_INTEGER_OVERSCALE, + "Sobreescalar imagen al usar números enteros" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_SCALE_INTEGER_OVERSCALE, + "Hace que el escalado por números enteros redondee siempre a un valor superior en vez de a uno inferior." + ) MSG_HASH( MENU_ENUM_LABEL_VALUE_VIDEO_ASPECT_RATIO_INDEX, "Relación de aspecto" diff --git a/intl/msg_hash_fr.h b/intl/msg_hash_fr.h index 92d7fe1cc0..96a8327838 100644 --- a/intl/msg_hash_fr.h +++ b/intl/msg_hash_fr.h @@ -1579,6 +1579,14 @@ MSG_HASH( MENU_ENUM_SUBLABEL_VIDEO_SCALE_INTEGER, "Mettre la vidéo à l'échelle sur un nombre entier uniquement. La taille de base dépend de la géométrie et du rapport d'aspect détectés par le système. Si 'Forcer le rapport d'aspect' est désactivé, X/Y seront mis à l'échelle à l'entier indépendamment." ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_SCALE_INTEGER_OVERSCALE, + "Échelle à l'entier surdimensionnée" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_SCALE_INTEGER_OVERSCALE, + "Force la mise à l'échelle sur l'entier à arrondir au prochain entier supérieur plutôt qu'inférieur." + ) MSG_HASH( MENU_ENUM_LABEL_VALUE_VIDEO_ASPECT_RATIO_INDEX, "Rapport d'aspect" diff --git a/intl/msg_hash_it.h b/intl/msg_hash_it.h index 9b989081dc..362f3b95f8 100644 --- a/intl/msg_hash_it.h +++ b/intl/msg_hash_it.h @@ -1567,6 +1567,14 @@ MSG_HASH( MENU_ENUM_SUBLABEL_VIDEO_SCALE_INTEGER, "Scala video solo con passaggi interi. La dimensione di base dipende dalla geometria e dal rapporto di aspetto riportati dal sistema. Se 'Force Aspect Ratio' non è impostato, X/Y sarà scalato in modo indipendente." ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_SCALE_INTEGER_OVERSCALE, + "Overscale A Scala Intera" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_SCALE_INTEGER_OVERSCALE, + "Forza il ridimensionamento degli interi per arrotondare al prossimo numero intero maggiore invece di arrotondare." + ) MSG_HASH( MENU_ENUM_LABEL_VALUE_VIDEO_ASPECT_RATIO_INDEX, "Rapporto d'aspetto" diff --git a/intl/msg_hash_ko.h b/intl/msg_hash_ko.h index 0c6ad7ca3a..afffd7a9da 100644 --- a/intl/msg_hash_ko.h +++ b/intl/msg_hash_ko.h @@ -1607,6 +1607,14 @@ MSG_HASH( MENU_ENUM_SUBLABEL_VIDEO_SCALE_INTEGER, "비디오의 크기를 정수 단위로만 조정합니다. 기본 크기는 각 시스템이 보고한 크기와 종횡비에 따라 결정되며 '강제 화면비'를 설정하지 않았을 경우 X/Y 크기를 각각 정수 단위로 조절합니다." ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_SCALE_INTEGER_OVERSCALE, + "정수 단위 오버스케일링" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_SCALE_INTEGER_OVERSCALE, + "화면 크기를 조정할 정수 단위 배율을 버림 대신 올림으로 계산합니다." + ) MSG_HASH( MENU_ENUM_LABEL_VALUE_VIDEO_ASPECT_RATIO_INDEX, "화면비" diff --git a/intl/msg_hash_pt_br.h b/intl/msg_hash_pt_br.h index 6d0c4bdee6..37ad4ad859 100644 --- a/intl/msg_hash_pt_br.h +++ b/intl/msg_hash_pt_br.h @@ -1575,6 +1575,14 @@ MSG_HASH( MENU_ENUM_SUBLABEL_VIDEO_SCALE_INTEGER, "Apenas redimensione o vídeo com valores inteiros. O tamanho principal depende da geometria informada pelo sistema e da proporção da tela. Caso a opção 'Forçar proporção' não esteja definida, X / Y serão dimensionados independentemente com valores inteiros." ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_SCALE_INTEGER_OVERSCALE, + "Dimensionar imagem em números inteiros" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_SCALE_INTEGER_OVERSCALE, + "Faz com que o dimensionamento inteiro seja sempre arredondado para um valor mais alto em vez de um valor mais baixo." + ) MSG_HASH( MENU_ENUM_LABEL_VALUE_VIDEO_ASPECT_RATIO_INDEX, "Proporção de tela" diff --git a/intl/msg_hash_ru.h b/intl/msg_hash_ru.h index 717a3f1347..96bd009357 100644 --- a/intl/msg_hash_ru.h +++ b/intl/msg_hash_ru.h @@ -1599,6 +1599,14 @@ MSG_HASH( MENU_ENUM_SUBLABEL_VIDEO_SCALE_INTEGER, "Масштабировать изображение с целочисленным интервалом. Базовый размер зависит от геометрии и соотношения сторон системы. Если не включена 'Принудительная установка' для соотношения сторон, значения X/Y будут меняться независимо друг от друга." ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_SCALE_INTEGER_OVERSCALE, + "Повышать целочисленное масштабирование" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_SCALE_INTEGER_OVERSCALE, + "При целочисленном масштабировании делать округление в сторону ближайшего большего целого числа." + ) MSG_HASH( MENU_ENUM_LABEL_VALUE_VIDEO_ASPECT_RATIO_INDEX, "Соотношение сторон" diff --git a/intl/msg_hash_tr.h b/intl/msg_hash_tr.h index d6cbddc89c..16f39db720 100644 --- a/intl/msg_hash_tr.h +++ b/intl/msg_hash_tr.h @@ -1579,6 +1579,14 @@ MSG_HASH( MENU_ENUM_SUBLABEL_VIDEO_SCALE_INTEGER, "Videoyu yalnızca tamsayı adımlarla ölçeklendirir. Temel boyut, sistem tarafından bildirilen geometriye ve en/boy oranına bağlıdır. 'En/Boy Oranını Zorla' ayarlanmazsa, X/Y birbirlerinden bağımsız, tamsayı katlarıyla ölçeklendirilirler." ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_SCALE_INTEGER_OVERSCALE, + "Tamsayı Ölçeği Aşırı Ölçek" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_SCALE_INTEGER_OVERSCALE, + "Aşağı yuvarlamak yerine bir sonraki daha büyük tam sayıya yuvarlamak için tamsayı ölçeklendirmeyi zorlayın." + ) MSG_HASH( MENU_ENUM_LABEL_VALUE_VIDEO_ASPECT_RATIO_INDEX, "En Boy Oranı" diff --git a/intl/msg_hash_uk.h b/intl/msg_hash_uk.h index 5c7775c891..4ef6008c84 100644 --- a/intl/msg_hash_uk.h +++ b/intl/msg_hash_uk.h @@ -1603,6 +1603,14 @@ MSG_HASH( MENU_ENUM_SUBLABEL_VIDEO_SCALE_INTEGER, "Масштабуйте відео лише цілими кроками. Базовий розмір залежить від геометрії та співвідношення сторін, про які повідомляє система. Якщо не встановлено \"Примусове співвідношення сторін\", X / Y буде цілочисельним масштабом незалежно." ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_SCALE_INTEGER_OVERSCALE, + "Масштаб Цілочисельной Шкали" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_SCALE_INTEGER_OVERSCALE, + "Примусово масштабувати ціле число для округлення до наступного більшого цілого числа замість округлення вниз." + ) MSG_HASH( MENU_ENUM_LABEL_VALUE_VIDEO_ASPECT_RATIO_INDEX, "Співвідношення сторін" diff --git a/intl/progress.h b/intl/progress.h index c034f3e6cb..7783ab1160 100644 --- a/intl/progress.h +++ b/intl/progress.h @@ -1,14 +1,14 @@ /* Arabic */ -#define LANGUAGE_PROGRESS_ARABIC_TRANSLATED 67 +#define LANGUAGE_PROGRESS_ARABIC_TRANSLATED 60 #define LANGUAGE_PROGRESS_ARABIC_APPROVED 0 /* Asturian */ -#define LANGUAGE_PROGRESS_ASTURIAN_TRANSLATED 15 -#define LANGUAGE_PROGRESS_ASTURIAN_APPROVED 15 +#define LANGUAGE_PROGRESS_ASTURIAN_TRANSLATED 16 +#define LANGUAGE_PROGRESS_ASTURIAN_APPROVED 16 /* Chinese Simplified */ -#define LANGUAGE_PROGRESS_CHINESE_SIMPLIFIED_TRANSLATED 100 -#define LANGUAGE_PROGRESS_CHINESE_SIMPLIFIED_APPROVED 64 +#define LANGUAGE_PROGRESS_CHINESE_SIMPLIFIED_TRANSLATED 88 +#define LANGUAGE_PROGRESS_CHINESE_SIMPLIFIED_APPROVED 65 /* Chinese Traditional */ #define LANGUAGE_PROGRESS_CHINESE_TRADITIONAL_TRANSLATED 25 @@ -32,22 +32,22 @@ /* Finnish */ #define LANGUAGE_PROGRESS_FINNISH_TRANSLATED 99 -#define LANGUAGE_PROGRESS_FINNISH_APPROVED 69 +#define LANGUAGE_PROGRESS_FINNISH_APPROVED 7 /* French */ -#define LANGUAGE_PROGRESS_FRENCH_TRANSLATED 100 -#define LANGUAGE_PROGRESS_FRENCH_APPROVED 100 +#define LANGUAGE_PROGRESS_FRENCH_TRANSLATED 99 +#define LANGUAGE_PROGRESS_FRENCH_APPROVED 99 /* Galician */ #define LANGUAGE_PROGRESS_GALICIAN_TRANSLATED 8 #define LANGUAGE_PROGRESS_GALICIAN_APPROVED 0 /* German */ -#define LANGUAGE_PROGRESS_GERMAN_TRANSLATED 99 -#define LANGUAGE_PROGRESS_GERMAN_APPROVED 15 +#define LANGUAGE_PROGRESS_GERMAN_TRANSLATED 96 +#define LANGUAGE_PROGRESS_GERMAN_APPROVED 0 /* Greek */ -#define LANGUAGE_PROGRESS_GREEK_TRANSLATED 28 +#define LANGUAGE_PROGRESS_GREEK_TRANSLATED 29 #define LANGUAGE_PROGRESS_GREEK_APPROVED 0 /* Hebrew */ @@ -59,19 +59,19 @@ #define LANGUAGE_PROGRESS_HUNGARIAN_APPROVED 0 /* Indonesian */ -#define LANGUAGE_PROGRESS_INDONESIAN_TRANSLATED 16 +#define LANGUAGE_PROGRESS_INDONESIAN_TRANSLATED 5 #define LANGUAGE_PROGRESS_INDONESIAN_APPROVED 0 /* Italian */ -#define LANGUAGE_PROGRESS_ITALIAN_TRANSLATED 100 +#define LANGUAGE_PROGRESS_ITALIAN_TRANSLATED 99 #define LANGUAGE_PROGRESS_ITALIAN_APPROVED 0 /* Japanese */ -#define LANGUAGE_PROGRESS_JAPANESE_TRANSLATED 92 +#define LANGUAGE_PROGRESS_JAPANESE_TRANSLATED 82 #define LANGUAGE_PROGRESS_JAPANESE_APPROVED 0 /* Korean */ -#define LANGUAGE_PROGRESS_KOREAN_TRANSLATED 100 +#define LANGUAGE_PROGRESS_KOREAN_TRANSLATED 99 #define LANGUAGE_PROGRESS_KOREAN_APPROVED 0 /* Persian */ @@ -80,39 +80,39 @@ /* Polish */ #define LANGUAGE_PROGRESS_POLISH_TRANSLATED 99 -#define LANGUAGE_PROGRESS_POLISH_APPROVED 38 +#define LANGUAGE_PROGRESS_POLISH_APPROVED 36 /* Portuguese */ #define LANGUAGE_PROGRESS_PORTUGUESE_TRANSLATED 27 #define LANGUAGE_PROGRESS_PORTUGUESE_APPROVED 0 /* Portuguese, Brazilian */ -#define LANGUAGE_PROGRESS_PORTUGUESE_BRAZILIAN_TRANSLATED 100 +#define LANGUAGE_PROGRESS_PORTUGUESE_BRAZILIAN_TRANSLATED 99 #define LANGUAGE_PROGRESS_PORTUGUESE_BRAZILIAN_APPROVED 5 /* Russian */ -#define LANGUAGE_PROGRESS_RUSSIAN_TRANSLATED 100 -#define LANGUAGE_PROGRESS_RUSSIAN_APPROVED 13 +#define LANGUAGE_PROGRESS_RUSSIAN_TRANSLATED 99 +#define LANGUAGE_PROGRESS_RUSSIAN_APPROVED 10 /* Slovak */ -#define LANGUAGE_PROGRESS_SLOVAK_TRANSLATED 15 +#define LANGUAGE_PROGRESS_SLOVAK_TRANSLATED 9 #define LANGUAGE_PROGRESS_SLOVAK_APPROVED 0 /* Spanish */ -#define LANGUAGE_PROGRESS_SPANISH_TRANSLATED 100 -#define LANGUAGE_PROGRESS_SPANISH_APPROVED 99 +#define LANGUAGE_PROGRESS_SPANISH_TRANSLATED 99 +#define LANGUAGE_PROGRESS_SPANISH_APPROVED 96 /* Swedish */ #define LANGUAGE_PROGRESS_SWEDISH_TRANSLATED 17 #define LANGUAGE_PROGRESS_SWEDISH_APPROVED 0 /* Turkish */ -#define LANGUAGE_PROGRESS_TURKISH_TRANSLATED 100 -#define LANGUAGE_PROGRESS_TURKISH_APPROVED 100 +#define LANGUAGE_PROGRESS_TURKISH_TRANSLATED 99 +#define LANGUAGE_PROGRESS_TURKISH_APPROVED 99 /* Ukrainian */ -#define LANGUAGE_PROGRESS_UKRAINIAN_TRANSLATED 43 -#define LANGUAGE_PROGRESS_UKRAINIAN_APPROVED 9 +#define LANGUAGE_PROGRESS_UKRAINIAN_TRANSLATED 42 +#define LANGUAGE_PROGRESS_UKRAINIAN_APPROVED 8 /* Vietnamese */ #define LANGUAGE_PROGRESS_VIETNAMESE_TRANSLATED 5 From 9e100b752e00a3b328f1e9ead6950160280506a1 Mon Sep 17 00:00:00 2001 From: jdgleaver Date: Thu, 15 Jul 2021 16:53:47 +0100 Subject: [PATCH 33/58] (RS-90) Move appdata (retroarch) base directory to external microsd card --- dingux/dingux_utils.c | 92 ++++++++++++++++++++++++++++++-- dingux/dingux_utils.h | 4 ++ file_path_special.c | 13 +++-- frontend/drivers/platform_unix.c | 19 +++---- 4 files changed, 109 insertions(+), 19 deletions(-) diff --git a/dingux/dingux_utils.c b/dingux/dingux_utils.c index c13649d1b5..ec4eca19f1 100644 --- a/dingux/dingux_utils.c +++ b/dingux/dingux_utils.c @@ -17,12 +17,13 @@ #include #include - -#if defined(DINGUX_BETA) #include -#include +#if defined(RS90) +#include #endif +#include + #include "dingux_utils.h" #define DINGUX_ALLOW_DOWNSCALING_FILE "/sys/devices/platform/jz-lcd.0/allow_downscaling" @@ -32,6 +33,14 @@ #define DINGUX_SHARPNESS_DOWNSCALING_FILE "/sys/devices/platform/jz-lcd.0/sharpness_downscaling" #define DINGUX_BATTERY_CAPACITY_FILE "/sys/class/power_supply/battery/capacity" +/* Base path defines */ +#define DINGUX_HOME_ENVAR "HOME" +#define DINGUX_BASE_DIR "retroarch" +#define DINGUX_BASE_DIR_HIDDEN ".retroarch" +#define DINGUX_RS90_MEDIA_PATH "/media" +#define DINGUX_RS90_DEFAULT_SD_PATH "/media/mmcblk0p1" +#define DINGUX_RS90_DATA_PATH "/media/data" + /* OpenDingux Beta defines */ #define DINGUX_BATTERY_VOLTAGE_MIN "/sys/class/power_supply/jz-battery/voltage_min_design" #define DINGUX_BATTERY_VOLTAGE_MAX "/sys/class/power_supply/jz-battery/voltage_max_design" @@ -302,3 +311,80 @@ int dingux_get_battery_level(void) return dingux_read_battery_sys_file(DINGUX_BATTERY_CAPACITY_FILE); #endif } + +/* Fetches the path of the base 'retroarch' + * directory */ +void dingux_get_base_path(char *path, size_t len) +{ + const char *home = NULL; +#if defined(RS90) + struct string_list *dir_list = NULL; +#endif + + if (!path || (len < 1)) + return; + +#if defined(RS90) + /* The RS-90 home directory is located on the + * device's internal storage. This has limited + * space (a total of only 256MB), such that it + * is impractical to store cores and user files + * here. We therefore attempt to use a base + * path on the external microsd card */ + + /* Get list of directories in /media */ + dir_list = dir_list_new(DINGUX_RS90_MEDIA_PATH, + NULL, true, true, false, false); + + if (dir_list) + { + size_t i; + bool path_found = false; + + for (i = 0; i < dir_list->size; i++) + { + const char *dir_path = dir_list->elems[i].data; + int dir_type = dir_list->elems[i].attr.i; + + /* Skip files and invalid entries */ + if ((dir_type != RARCH_DIRECTORY) || + string_is_empty(dir_path) || + string_is_equal(dir_path, DINGUX_RS90_DATA_PATH)) + continue; + + /* Build 'retroarch' subdirectory path */ + snprintf(path, len, "%s%c%s", dir_path, + PATH_DEFAULT_SLASH_C(), DINGUX_BASE_DIR); + + /* We can use this subdirectory path if: + * - Directory corresponds to an unlabelled + * microsd card + * - Subdirectory already exists */ + if (string_is_equal(dir_path, DINGUX_RS90_DEFAULT_SD_PATH) || + path_is_directory(path)) + { + path_found = true; + break; + } + } + + dir_list_free(dir_list); + + if (path_found) + return; + } +#endif + /* Get home directory */ + home = getenv(DINGUX_HOME_ENVAR); + + /* If a home directory is found (which should + * always be the case), base path is "$HOME/.retroarch" + * > If home path is unset, use existing UNIX frontend + * driver default of "retroarch" (this will ultimately + * fail, but there is nothing else we can do...) */ + if (home) + snprintf(path, len, "%s%c%s", home, + PATH_DEFAULT_SLASH_C(), DINGUX_BASE_DIR_HIDDEN); + else + strlcpy(path, DINGUX_BASE_DIR, len); +} diff --git a/dingux/dingux_utils.h b/dingux/dingux_utils.h index bf13140fca..4aa71b578a 100644 --- a/dingux/dingux_utils.h +++ b/dingux/dingux_utils.h @@ -101,6 +101,10 @@ bool dingux_ipu_reset(void); /* Fetches internal battery level */ int dingux_get_battery_level(void); +/* Fetches the path of the base 'retroarch' + * directory */ +void dingux_get_base_path(char *path, size_t len); + RETRO_END_DECLS #endif diff --git a/file_path_special.c b/file_path_special.c index 9b5b7d567b..153bde3018 100644 --- a/file_path_special.c +++ b/file_path_special.c @@ -37,6 +37,10 @@ #include #endif +#if defined(DINGUX) +#include "dingux/dingux_utils.h" +#endif + #include #include #include @@ -104,13 +108,8 @@ bool fill_pathname_application_data(char *s, size_t len) return true; } #elif defined(DINGUX) - const char *appdata = getenv("HOME"); - - if (appdata) - { - fill_pathname_join(s, appdata, "/.retroarch", len); - return true; - } + dingux_get_base_path(s, len); + return true; #elif !defined(RARCH_CONSOLE) const char *xdg = getenv("XDG_CONFIG_HOME"); const char *appdata = getenv("HOME"); diff --git a/frontend/drivers/platform_unix.c b/frontend/drivers/platform_unix.c index b50bce688c..44946f9c93 100644 --- a/frontend/drivers/platform_unix.c +++ b/frontend/drivers/platform_unix.c @@ -1792,6 +1792,9 @@ static void frontend_unix_get_env(int *argc, } #else char base_path[PATH_MAX] = {0}; +#if defined(DINGUX) + dingux_get_base_path(base_path, sizeof(base_path)); +#else const char *xdg = getenv("XDG_CONFIG_HOME"); const char *home = getenv("HOME"); @@ -1803,14 +1806,11 @@ static void frontend_unix_get_env(int *argc, else if (home) { strlcpy(base_path, home, sizeof(base_path)); -#if defined(DINGUX) - strlcat(base_path, "/.retroarch", sizeof(base_path)); -#else strlcat(base_path, "/.config/retroarch", sizeof(base_path)); -#endif } else strcpy_literal(base_path, "retroarch"); +#endif fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CORE], base_path, "cores", sizeof(g_defaults.dirs[DEFAULT_DIR_CORE])); @@ -2154,10 +2154,14 @@ static int frontend_unix_parse_drive_list(void *data, bool load_content) #else char base_path[PATH_MAX] = {0}; char udisks_media_path[PATH_MAX] = {0}; - const char *xdg = getenv("XDG_CONFIG_HOME"); const char *home = getenv("HOME"); const char *user = getenv("USER"); +#if defined(DINGUX) + dingux_get_base_path(base_path, sizeof(base_path)); +#else + const char *xdg = getenv("XDG_CONFIG_HOME"); + if (xdg) { strlcpy(base_path, xdg, sizeof(base_path)); @@ -2166,12 +2170,9 @@ static int frontend_unix_parse_drive_list(void *data, bool load_content) else if (home) { strlcpy(base_path, home, sizeof(base_path)); -#if defined(DINGUX) - strlcat(base_path, "/.retroarch", sizeof(base_path)); -#else strlcat(base_path, "/.config/retroarch", sizeof(base_path)); -#endif } +#endif strlcpy(udisks_media_path, "/run/media", sizeof(udisks_media_path)); if (user) From 260352aa9e17eafe56b287adb1313b294d1d0bfc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francisco=20Jos=C3=A9=20Garc=C3=ADa=20Garc=C3=ADa?= Date: Thu, 15 Jul 2021 19:21:24 +0200 Subject: [PATCH 34/58] Vita: wrong flags for not piglet version --- Makefile.vita | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Makefile.vita b/Makefile.vita index 74766e1283..c42b7a8ea3 100644 --- a/Makefile.vita +++ b/Makefile.vita @@ -112,7 +112,11 @@ LD := $(CXX) LIBDIRS := -L. -ARCHFLAGS := -march=armv7-a -mfpu=neon -mfloat-abi=hard -DVITA -DSCE_LIBC_SIZE=$(SCE_LIBC_SIZE) +ARCHFLAGS := -march=armv7-a -mfpu=neon -mfloat-abi=hard -DVITA +ifeq ($(HAVE_VITAGLES), 1) + ARCHFLAGS += -DSCE_LIBC_SIZE=$(SCE_LIBC_SIZE) +endif + CFLAGS += $(ARCHFLAGS) -mword-relocations -fno-optimize-sibling-calls ifeq ($(DEBUG), 1) From 214a80b3382dd40fe371a2948e16dd90b0a16bf1 Mon Sep 17 00:00:00 2001 From: Ember Cold Date: Fri, 16 Jul 2021 17:21:11 +0300 Subject: [PATCH 35/58] Prevent xdg-screensaver's "Protocol error" messages --- gfx/common/x11_common.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/gfx/common/x11_common.c b/gfx/common/x11_common.c index 9c804be1f8..25f6133e46 100644 --- a/gfx/common/x11_common.c +++ b/gfx/common/x11_common.c @@ -199,11 +199,24 @@ static void xdg_screensaver_inhibit(Window wnd) { int ret; char cmd[64]; + char title[128]; cmd[0] = '\0'; + title[0] = '\0'; RARCH_LOG("[X11]: Suspending screensaver (X11, xdg-screensaver).\n"); + /* Make sure the window has a title, even if it's a bogus one, otherwise + * xdg-screensaver will fail and report to stderr, framing RA for its bug. + * A single space character is used so that the title bar stays visibly + * the same, as if there's no title at all. */ + video_driver_get_window_title(title, sizeof(title)); + if (strlen(title) == 0) + snprintf(title, sizeof(title), " "); + XChangeProperty(g_x11_dpy, g_x11_win, XA_WM_NAME, XA_STRING, + 8, PropModeReplace, (const unsigned char*) title, + strlen(title)); + snprintf(cmd, sizeof(cmd), "xdg-screensaver suspend 0x%x", (int)wnd); ret = system(cmd); From 03f2d2376edd520a73ff3bb6a35d47104356a340 Mon Sep 17 00:00:00 2001 From: "Mark W. Kidd" Date: Fri, 16 Jul 2021 11:13:52 -0400 Subject: [PATCH 36/58] clarify netplay upnp port mapping messages --- intl/msg_hash_us.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index d2c50ed246..c36435fc05 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -10536,11 +10536,11 @@ MSG_HASH( ) MSG_HASH( MSG_PUBLIC_ADDRESS, - "Port Mapping Successful" + "Netplay Port Mapping Successful" ) MSG_HASH( MSG_UPNP_FAILED, - "Port Mapping Failed" + "Netplay UPNP Port Mapping Failed" ) MSG_HASH( MSG_NO_ARGUMENTS_SUPPLIED_AND_NO_MENU_BUILTIN, From 6b65daf07d45c255bf6d26f146127f3f5fa878bb Mon Sep 17 00:00:00 2001 From: jdgleaver Date: Fri, 16 Jul 2021 17:48:03 +0100 Subject: [PATCH 37/58] (OpenDingux Beta) Fix IPU scaling when running 256x224 (SNES/Genesis) content --- gfx/drivers/sdl_dingux_gfx.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/gfx/drivers/sdl_dingux_gfx.c b/gfx/drivers/sdl_dingux_gfx.c index 4c5abfb272..607e3de340 100644 --- a/gfx/drivers/sdl_dingux_gfx.c +++ b/gfx/drivers/sdl_dingux_gfx.c @@ -581,6 +581,12 @@ static void sdl_dingux_sanitize_frame_dimensions( /* GB/GBC/GG (x3) @ 480x432 */ else if ((width == 480) && (height == 432)) *sanitized_width = 496; + /* SNES/Genesis @ 256x224 */ + else if ((width == 256) && (height == 224)) + *sanitized_width = 288; + /* SNES/Genesis (x2) @ 512x448 */ + else if ((width == 512) && (height == 448)) + *sanitized_width = 560; } #endif From 6521bfcdc1e2069c3f5a6f275db67e9f664bf041 Mon Sep 17 00:00:00 2001 From: Ash Logan Date: Sat, 17 Jul 2021 12:16:00 +1000 Subject: [PATCH 38/58] gitignore: Don't ignore some of the Wii U sources --- .gitignore | 2 -- 1 file changed, 2 deletions(-) diff --git a/.gitignore b/.gitignore index cec9e0c4fd..485e7b46fe 100644 --- a/.gitignore +++ b/.gitignore @@ -94,7 +94,6 @@ database overlays playlists states -system shaders/shaders_cg shaders/shaders_glsl shaders/shaders_slang @@ -220,7 +219,6 @@ libretro-common/samples/streams/rzip/rzip #VITA param.sfo -*.S *.wo *.elf *.self From a35323ace9971042c81f084d37aa7f21d0886431 Mon Sep 17 00:00:00 2001 From: Ash Logan Date: Sun, 18 Jul 2021 14:47:25 +1000 Subject: [PATCH 39/58] (task_http.c) Use 100% as maximum, not minimum With previous logic, any normal percentage would get MAX'd to 100% (max(70, 100) == 100). Correct math to use here is min --- tasks/task_http.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/task_http.c b/tasks/task_http.c index 28ba001d26..eac88020ed 100644 --- a/tasks/task_http.c +++ b/tasks/task_http.c @@ -133,7 +133,7 @@ static int task_http_iterate_transfer(retro_task_t *task) task_set_progress(task, (signed)(pos * 100 / tot)); else /* but invert the logic if it would cause an overflow */ - task_set_progress(task, MAX((signed)pos / (tot / 100), 100)); + task_set_progress(task, MIN((signed)pos / (tot / 100), 100)); return -1; } From e5553bde4e35f0f7986843d214452e273ea7a7c8 Mon Sep 17 00:00:00 2001 From: Ash Logan Date: Sun, 18 Jul 2021 13:56:22 +1000 Subject: [PATCH 40/58] wiiu: Network optimisations - WINSCALE, TCP sACK, large buffers See code sample in https://github.com/devkitPro/wut/issues/169 and https://github.com/Laf111/WiiUFtpServer/blob/243078940681175ef2901415a5498f0d759d4c0e/src/net.c#L88 --- libretro-common/include/net/net_compat.h | 5 ++++ libretro-common/net/net_compat.c | 31 ++++++++++++++++++++++++ libretro-common/net/net_socket.c | 14 +++++++++++ wiiu/include/sys/socket.h | 5 ++++ wiiu/include/wiiu/os/thread.h | 2 +- wiiu/system/imports.h | 8 ++++++ 6 files changed, 64 insertions(+), 1 deletion(-) diff --git a/libretro-common/include/net/net_compat.h b/libretro-common/include/net/net_compat.h index 7f9f452e64..7387596eb8 100644 --- a/libretro-common/include/net/net_compat.h +++ b/libretro-common/include/net/net_compat.h @@ -158,6 +158,11 @@ static INLINE bool isagain(int bytes) #endif } +#ifdef WIIU +#define WIIU_RCVBUF (128 * 2 * 1024) +#define WIIU_SNDBUF (128 * 2 * 1024) +#endif + #ifdef _XBOX #define socklen_t int diff --git a/libretro-common/net/net_compat.c b/libretro-common/net/net_compat.c index aacbb4dd3e..8b9e183e46 100644 --- a/libretro-common/net/net_compat.c +++ b/libretro-common/net/net_compat.c @@ -264,6 +264,25 @@ void freeaddrinfo_retro(struct addrinfo *res) #endif } +#if defined(WIIU) +#include + +static OSThread wiiu_net_cmpt_thread; +static void wiiu_net_cmpt_thread_cleanup(OSThread *thread, void *stack) { + free(stack); +} +static int wiiu_net_cmpt_thread_entry(int argc, const char** argv) { + const int buf_size = WIIU_RCVBUF + WIIU_SNDBUF; + void* buf = memalign(128, buf_size); + if (!buf) return -1; + + somemopt(1, buf, buf_size, 0); + + free(buf); + return 0; +} +#endif + /** * network_init: * @@ -332,6 +351,18 @@ bool network_init(void) return false; #elif defined(WIIU) socket_lib_init(); + + const int stack_size = 4096; + void* stack = malloc(stack_size); + if (stack && OSCreateThread(&wiiu_net_cmpt_thread, + wiiu_net_cmpt_thread_entry, 0, NULL, stack+stack_size, stack_size, + 3, OS_THREAD_ATTRIB_AFFINITY_ANY)) { + + OSSetThreadName(&wiiu_net_cmpt_thread, "Network compat thread"); + OSSetThreadDeallocator(&wiiu_net_cmpt_thread, + wiiu_net_cmpt_thread_cleanup); + OSResumeThread(&wiiu_net_cmpt_thread); + } #elif defined(_3DS) _net_compat_net_memory = (u32*)memalign(SOC_ALIGN, SOC_BUFFERSIZE); if (!_net_compat_net_memory) diff --git a/libretro-common/net/net_socket.c b/libretro-common/net/net_socket.c index f33d284075..04b01ade4c 100644 --- a/libretro-common/net/net_socket.c +++ b/libretro-common/net/net_socket.c @@ -256,6 +256,20 @@ int socket_connect(int fd, void *data, bool timeout_enable) setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, (char*)&timeout, sizeof timeout); } +#endif +#if defined(WIIU) + int op = 1; + setsockopt(fd, SOL_SOCKET, SO_WINSCALE, &op, sizeof(op)); + if (addr->ai_socktype == SOCK_STREAM) { + setsockopt(fd, SOL_SOCKET, SO_TCPSACK, &op, sizeof(op)); + + setsockopt(fd, SOL_SOCKET, 0x10000, &op, sizeof(op)); + int recvsz = WIIU_RCVBUF; + setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &recvsz, sizeof(recvsz)); + int sendsz = WIIU_SNDBUF; + setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &sendsz, sizeof(sendsz)); + } + #endif return connect(fd, addr->ai_addr, addr->ai_addrlen); diff --git a/wiiu/include/sys/socket.h b/wiiu/include/sys/socket.h index 24eabff7f1..45b2ea9bdc 100644 --- a/wiiu/include/sys/socket.h +++ b/wiiu/include/sys/socket.h @@ -21,6 +21,10 @@ extern "C" { /* #define MSG_DONTWAIT 0x0004 */ #define SO_REUSEADDR 0x0004 +#define SO_WINSCALE 0x0400 +#define SO_TCPSACK 0x0200 +#define SO_SNDBUF 0x1001 +#define SO_RCVBUF 0x1002 #define SO_NBIO 0x1014 #define SO_NONBLOCK 0x1016 @@ -70,6 +74,7 @@ int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t int shutdown(int sockfd, int how); int socket(int domain, int type, int protocol); int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); +int somemopt (int req_type, char* mem, unsigned int memlen, int flags); int socketlasterr(void); diff --git a/wiiu/include/wiiu/os/thread.h b/wiiu/include/wiiu/os/thread.h index b962b1acc5..a545185c60 100644 --- a/wiiu/include/wiiu/os/thread.h +++ b/wiiu/include/wiiu/os/thread.h @@ -133,7 +133,7 @@ typedef struct #define OS_THREAD_TAG 0x74487244u #pragma pack(push, 1) -typedef struct OSThread +typedef struct __attribute__ ((aligned (8))) OSThread { OSContext context; diff --git a/wiiu/system/imports.h b/wiiu/system/imports.h index e3685aaa1a..bfff0e860c 100644 --- a/wiiu/system/imports.h +++ b/wiiu/system/imports.h @@ -32,6 +32,7 @@ IMPORT(OSIsThreadTerminated); IMPORT(OSSetThreadPriority); IMPORT(OSCreateThread); IMPORT(OSSetThreadCleanupCallback); +IMPORT(OSSetThreadDeallocator); IMPORT(OSResumeThread); IMPORT(OSIsThreadSuspended); IMPORT(OSSuspendThread); @@ -39,6 +40,7 @@ IMPORT(OSGetCurrentThread); IMPORT(OSExitThread); IMPORT(OSJoinThread); IMPORT(OSYieldThread); +IMPORT(OSSetThreadName); IMPORT(OSGetCoreId); IMPORT(OSIsMainCore); IMPORT(OSGetSystemTime); @@ -153,6 +155,12 @@ IMPORT(socketlasterr); IMPORT_END(); +IMPORT_BEGIN(nn_nets2); + +IMPORT(somemopt); + +IMPORT_END(); + /* gx2 */ IMPORT_BEGIN(gx2); From 5887016db377872765f4a0b84cbad8cbdc7fb370 Mon Sep 17 00:00:00 2001 From: Ash Logan Date: Sun, 18 Jul 2021 21:34:08 +1000 Subject: [PATCH 41/58] deps/libiosuhax: Update to wiiu-env/libiosuhax@69532cf --- Makefile.common | 8 +- Makefile.wiiu | 2 +- .../.github/workflows/push_image.yml | 25 + deps/libiosuhax/.gitignore | 5 + deps/libiosuhax/.travis.yml | 29 + deps/libiosuhax/Dockerfile | 9 + deps/libiosuhax/Makefile | 157 ++ deps/libiosuhax/README.md | 10 + deps/libiosuhax/{ => include}/iosuhax.h | 221 +- .../{ => include}/iosuhax_devoptab.h | 84 +- .../{ => include}/iosuhax_disc_interface.h | 146 +- deps/libiosuhax/os_functions.h | 51 - deps/libiosuhax/{ => source}/iosuhax.c | 1985 ++++++++------- .../{ => source}/iosuhax_devoptab.c | 2127 ++++++++--------- .../{ => source}/iosuhax_disc_interface.c | 524 ++-- deps/libiosuhax/source/os_functions.h | 28 + griffin/griffin.c | 6 +- 17 files changed, 2709 insertions(+), 2708 deletions(-) create mode 100644 deps/libiosuhax/.github/workflows/push_image.yml create mode 100644 deps/libiosuhax/.gitignore create mode 100644 deps/libiosuhax/.travis.yml create mode 100644 deps/libiosuhax/Dockerfile create mode 100644 deps/libiosuhax/Makefile create mode 100644 deps/libiosuhax/README.md rename deps/libiosuhax/{ => include}/iosuhax.h (96%) rename deps/libiosuhax/{ => include}/iosuhax_devoptab.h (97%) rename deps/libiosuhax/{ => include}/iosuhax_disc_interface.h (97%) delete mode 100644 deps/libiosuhax/os_functions.h rename deps/libiosuhax/{ => source}/iosuhax.c (78%) rename deps/libiosuhax/{ => source}/iosuhax_devoptab.c (84%) rename deps/libiosuhax/{ => source}/iosuhax_disc_interface.c (92%) create mode 100644 deps/libiosuhax/source/os_functions.h diff --git a/Makefile.common b/Makefile.common index 5394c2c1a9..bd1188034b 100644 --- a/Makefile.common +++ b/Makefile.common @@ -2377,10 +2377,10 @@ endif ifeq ($(WANT_IOSUHAX), 1) DEFINES += -DHAVE_IOSUHAX - INCLUDE_DIRS += -I$(DEPS_DIR)/libiosuhax - OBJ += $(DEPS_DIR)/libiosuhax/iosuhax.o \ - $(DEPS_DIR)/libiosuhax/iosuhax_devoptab.o \ - $(DEPS_DIR)/libiosuhax/iosuhax_disc_interface.o + INCLUDE_DIRS += -I$(DEPS_DIR)/libiosuhax/include + OBJ += $(DEPS_DIR)/libiosuhax/source/iosuhax.o \ + $(DEPS_DIR)/libiosuhax/source/iosuhax_devoptab.o \ + $(DEPS_DIR)/libiosuhax/source/iosuhax_disc_interface.o endif ifeq ($(WANT_LIBFAT), 1) diff --git a/Makefile.wiiu b/Makefile.wiiu index 55a0dd93cc..c565db262c 100644 --- a/Makefile.wiiu +++ b/Makefile.wiiu @@ -102,7 +102,7 @@ endif INCDIRS += -Ilibretro-common/include/compat/zlib # for stb, libfat, iosuhax - INCDIRS += -Ideps -Ideps/libfat/include -Ideps/libiosuhax + INCDIRS += -Ideps -Ideps/libfat/include -Ideps/libiosuhax/include # pad_functions uses wiiu/input.h INCDIRS += -Iinput/include INCDIRS += -Ideps/SPIRV-Cross diff --git a/deps/libiosuhax/.github/workflows/push_image.yml b/deps/libiosuhax/.github/workflows/push_image.yml new file mode 100644 index 0000000000..9cd7bbdb42 --- /dev/null +++ b/deps/libiosuhax/.github/workflows/push_image.yml @@ -0,0 +1,25 @@ +name: Publish Docker Image +on: + push: + branches: + - master +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@master + - name: Get release version + id: get_release_tag + run: | + echo RELEASE_VERSION=$(echo $(date '+%Y%m%d')) >> $GITHUB_ENV + echo REPOSITORY_NAME=$(echo "$GITHUB_REPOSITORY" | awk -F / '{print $2}' | sed -e "s/:refs//" | tr '[:upper:]' '[:lower:]') >> $GITHUB_ENV + echo REPOSITORY_OWNER=$(echo "$GITHUB_REPOSITORY" | awk -F / '{print $1}' | sed 's/[^a-zA-Z0-9]//g' | tr '[:upper:]' '[:lower:]') >> $GITHUB_ENV + - name: Publish to Registry + uses: elgohr/Publish-Docker-Github-Action@master + with: + name: ${{ env.REPOSITORY_OWNER }}/${{ env.REPOSITORY_NAME }} + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + snapshot: true + cache: true + tags: "latest, ${{ env.RELEASE_VERSION }}" \ No newline at end of file diff --git a/deps/libiosuhax/.gitignore b/deps/libiosuhax/.gitignore new file mode 100644 index 0000000000..0955c90e6e --- /dev/null +++ b/deps/libiosuhax/.gitignore @@ -0,0 +1,5 @@ +/*.a +/build +*.bz2 +release/ +lib/ diff --git a/deps/libiosuhax/.travis.yml b/deps/libiosuhax/.travis.yml new file mode 100644 index 0000000000..ff1f980eaa --- /dev/null +++ b/deps/libiosuhax/.travis.yml @@ -0,0 +1,29 @@ +language: cpp + +os: linux +sudo: false +dist: trusty + +env: + global: + - DEVKITPRO=/opt/devkitpro + - DEVKITPPC=/opt/devkitpro/devkitPPC + +cache: + directories: + - "$HOME/.local" + - "$DEVKITPRO" + +addons: + apt: + packages: + - p7zip-full + +before_install: + - mkdir -p "${DEVKITPRO}" + - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then wget https://github.com/devkitPro/pacman/releases/download/devkitpro-pacman-1.0.1/devkitpro-pacman.deb -O /tmp/devkitpro-pacman.deb; fi + - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo dpkg -i /tmp/devkitpro-pacman.deb; fi + - yes | sudo dkp-pacman -Syu devkitPPC --needed + +script: + - make && make install \ No newline at end of file diff --git a/deps/libiosuhax/Dockerfile b/deps/libiosuhax/Dockerfile new file mode 100644 index 0000000000..27aa8936e8 --- /dev/null +++ b/deps/libiosuhax/Dockerfile @@ -0,0 +1,9 @@ +FROM wiiuenv/devkitppc:20210101 + +WORKDIR tmp_build +COPY . . +RUN make clean && make && mkdir -p /artifacts/wut/usr && cp -r lib /artifacts/wut/usr && cp -r include /artifacts/wut/usr +WORKDIR /artifacts + +FROM scratch +COPY --from=0 /artifacts /artifacts \ No newline at end of file diff --git a/deps/libiosuhax/Makefile b/deps/libiosuhax/Makefile new file mode 100644 index 0000000000..03af789f3d --- /dev/null +++ b/deps/libiosuhax/Makefile @@ -0,0 +1,157 @@ +#------------------------------------------------------------------------------- +.SUFFIXES: +#------------------------------------------------------------------------------- + +ifeq ($(strip $(DEVKITPRO)),) +$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=/devkitpro") +endif + +TOPDIR ?= $(CURDIR) + +include $(DEVKITPRO)/wut/share/wut_rules + +export VER_MAJOR := 1 +export VER_MINOR := 0 +export VER_PATCH := 0 + +VERSION := $(VER_MAJOR).$(VER_MINOR).$(VER_PATCH) + +#------------------------------------------------------------------------------- +# TARGET is the name of the output +# BUILD is the directory where object files & intermediate files will be placed +# SOURCES is a list of directories containing source code +# DATA is a list of directories containing data files +# INCLUDES is a list of directories containing header files +#------------------------------------------------------------------------------- +TARGET := $(notdir $(CURDIR)) +BUILD := build +SOURCES := source +DATA := data +INCLUDES := source \ + include \ + +#--------------------------------------------------------------------------------- +# options for code generation +#--------------------------------------------------------------------------------- +CFLAGS := -Wall -Werror -save-temps \ + -ffunction-sections -fdata-sections \ + $(MACHDEP) \ + $(BUILD_CFLAGS) + +CFLAGS += $(INCLUDE) -D__WIIU__ -D__WUT__ + +CXXFLAGS := $(CFLAGS) -std=gnu++17 + +ASFLAGS := $(MACHDEP) + +LDFLAGS = $(ARCH) -Wl,--gc-sections + + +LIBS := + +#--------------------------------------------------------------------------------- +# list of directories containing libraries, this must be the top level containing +# include and lib +#--------------------------------------------------------------------------------- +LIBDIRS := $(PORTLIBS) $(WUT_ROOT) + +#--------------------------------------------------------------------------------- +# no real need to edit anything past this point unless you need to add additional +# rules for different file extensions +#--------------------------------------------------------------------------------- +ifneq ($(BUILD),$(notdir $(CURDIR))) +#--------------------------------------------------------------------------------- + +export TOPDIR := $(CURDIR) + +export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ + $(foreach dir,$(DATA),$(CURDIR)/$(dir)) + +CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) +CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) +SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) +DEFFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.def))) +BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) + +#--------------------------------------------------------------------------------- +# use CXX for linking C++ projects, CC for standard C +#--------------------------------------------------------------------------------- +ifeq ($(strip $(CPPFILES)),) +#--------------------------------------------------------------------------------- + export LD := $(CC) +#--------------------------------------------------------------------------------- +else +#--------------------------------------------------------------------------------- + export LD := $(CXX) +#--------------------------------------------------------------------------------- +endif +#--------------------------------------------------------------------------------- + +export OFILES_BIN := $(addsuffix .o,$(BINFILES)) +export OFILES_SRC := $(DEFFILES:.def=.o) $(SFILES:.s=.o) $(CFILES:.c=.o) $(CPPFILES:.cpp=.o) +export OFILES := $(OFILES_BIN) $(OFILES_SRC) +export HFILES := $(addsuffix .h,$(subst .,_,$(BINFILES))) + +export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ + $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ + -I. + +.PHONY: all dist-bin dist-src dist install clean + +#--------------------------------------------------------------------------------- +all: lib/libiosuhax.a + +dist-bin: all + @tar --exclude=*~ -cjf libiosuhax-$(VERSION).tar.bz2 include lib + +dist-src: + @tar --exclude=*~ -cjf libiosuhax-src-$(VERSION).tar.bz2 include source Makefile + +dist: dist-src dist-bin + +install: dist-bin + mkdir -p $(DESTDIR)$(DEVKITPRO)/wut/usr + bzip2 -cd libiosuhax-$(VERSION).tar.bz2 | tar -xf - -C $(DESTDIR)$(DEVKITPRO)/wut/usr + +lib: + @[ -d $@ ] || mkdir -p $@ + +release: + @[ -d $@ ] || mkdir -p $@ + +lib/libiosuhax.a :$(SOURCES) $(INCLUDES) | lib release + @$(MAKE) BUILD=release OUTPUT=$(CURDIR)/$@ \ + BUILD_CFLAGS="-DNDEBUG=1 -O2 -s" \ + DEPSDIR=$(CURDIR)/release \ + --no-print-directory -C release \ + -f $(CURDIR)/Makefile + +#--------------------------------------------------------------------------------- +clean: + @echo clean ... + @rm -rf release lib + +#--------------------------------------------------------------------------------- +else + +DEPENDS := $(OFILES:.o=.d) + +#--------------------------------------------------------------------------------- +# main targets +#--------------------------------------------------------------------------------- +$(OUTPUT) : $(OFILES) + +$(OFILES_SRC) : $(HFILES) + +#--------------------------------------------------------------------------------- +%_bin.h %.bin.o : %.bin +#--------------------------------------------------------------------------------- + @echo $(notdir $<) + @$(bin2o) + + +-include $(DEPENDS) + +#--------------------------------------------------------------------------------------- +endif +#--------------------------------------------------------------------------------------- diff --git a/deps/libiosuhax/README.md b/deps/libiosuhax/README.md new file mode 100644 index 0000000000..1fc1235092 --- /dev/null +++ b/deps/libiosuhax/README.md @@ -0,0 +1,10 @@ +[![Build Status](https://travis-ci.org/dimok789/libiosuhax.svg)](https://travis-ci.org/dimok789/libiosuhax) +# libiosuhax +A PPC library to access IOSUHAX from PPC and a devoptab for any device or path. +It's only compatible to RPX-Files. + +## Building +Make you to have [wut](https://github.com/devkitPro/wut/) installed and use the following command for build: +``` +make install +``` diff --git a/deps/libiosuhax/iosuhax.h b/deps/libiosuhax/include/iosuhax.h similarity index 96% rename from deps/libiosuhax/iosuhax.h rename to deps/libiosuhax/include/iosuhax.h index 25b7367cad..9b2350b7fd 100644 --- a/deps/libiosuhax/iosuhax.h +++ b/deps/libiosuhax/include/iosuhax.h @@ -1,109 +1,112 @@ -/*************************************************************************** - * Copyright (C) 2016 - * by Dimok - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any - * damages arising from the use of this software. - * - * Permission is granted to anyone to use this software for any - * purpose, including commercial applications, and to alter it and - * redistribute it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you - * must not claim that you wrote the original software. If you use - * this software in a product, an acknowledgment in the product - * documentation would be appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and - * must not be misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source - * distribution. - ***************************************************************************/ -#ifndef _LIB_IOSUHAX_H_ -#define _LIB_IOSUHAX_H_ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define IOS_ERROR_UNKNOWN_VALUE 0xFFFFFFD6 -#define IOS_ERROR_INVALID_ARG 0xFFFFFFE3 -#define IOS_ERROR_INVALID_SIZE 0xFFFFFFE9 -#define IOS_ERROR_UNKNOWN 0xFFFFFFF7 -#define IOS_ERROR_NOEXISTS 0xFFFFFFFA - -typedef struct -{ - uint32_t flag; - uint32_t permission; - uint32_t owner_id; - uint32_t group_id; - uint32_t size; // size in bytes - uint32_t physsize; // physical size on disk in bytes - uint32_t unk[3]; - uint32_t id; - uint32_t ctime; - uint32_t mtime; - uint32_t unk2[0x0D]; -}fileStat_s; - -typedef struct -{ - fileStat_s stat; - char name[0x100]; -}directoryEntry_s; - -#define DIR_ENTRY_IS_DIRECTORY 0x80000000 - -#define FSA_MOUNTFLAGS_BINDMOUNT (1 << 0) -#define FSA_MOUNTFLAGS_GLOBAL (1 << 1) - -int IOSUHAX_Open(const char *dev); // if dev == NULL the default path /dev/iosuhax will be used -int IOSUHAX_Close(void); - -int IOSUHAX_memwrite(uint32_t address, const uint8_t * buffer, uint32_t size); // IOSU external input -int IOSUHAX_memread(uint32_t address, uint8_t * out_buffer, uint32_t size); // IOSU external output -int IOSUHAX_memcpy(uint32_t dst, uint32_t src, uint32_t size); // IOSU internal memcpy only - -int IOSUHAX_SVC(uint32_t svc_id, uint32_t * args, uint32_t arg_cnt); - -int IOSUHAX_FSA_Open(); -int IOSUHAX_FSA_Close(int fsaFd); - -int IOSUHAX_FSA_Mount(int fsaFd, const char* device_path, const char* volume_path, uint32_t flags, const char* arg_string, int arg_string_len); -int IOSUHAX_FSA_Unmount(int fsaFd, const char* path, uint32_t flags); -int IOSUHAX_FSA_FlushVolume(int fsaFd, const char* volume_path); - -int IOSUHAX_FSA_GetDeviceInfo(int fsaFd, const char* device_path, int type, uint32_t* out_data); - -int IOSUHAX_FSA_MakeDir(int fsaFd, const char* path, uint32_t flags); -int IOSUHAX_FSA_OpenDir(int fsaFd, const char* path, int* outHandle); -int IOSUHAX_FSA_ReadDir(int fsaFd, int handle, directoryEntry_s* out_data); -int IOSUHAX_FSA_RewindDir(int fsaFd, int dirHandle); -int IOSUHAX_FSA_CloseDir(int fsaFd, int handle); -int IOSUHAX_FSA_ChangeDir(int fsaFd, const char *path); - -int IOSUHAX_FSA_OpenFile(int fsaFd, const char* path, const char* mode, int* outHandle); -int IOSUHAX_FSA_ReadFile(int fsaFd, void* data, uint32_t size, uint32_t cnt, int fileHandle, uint32_t flags); -int IOSUHAX_FSA_WriteFile(int fsaFd, const void* data, uint32_t size, uint32_t cnt, int fileHandle, uint32_t flags); -int IOSUHAX_FSA_StatFile(int fsaFd, int fileHandle, fileStat_s* out_data); -int IOSUHAX_FSA_CloseFile(int fsaFd, int fileHandle); -int IOSUHAX_FSA_SetFilePos(int fsaFd, int fileHandle, uint32_t position); -int IOSUHAX_FSA_GetStat(int fsaFd, const char *path, fileStat_s* out_data); -int IOSUHAX_FSA_Remove(int fsaFd, const char *path); -int IOSUHAX_FSA_ChangeMode(int fsaFd, const char* path, int mode); - -int IOSUHAX_FSA_RawOpen(int fsaFd, const char* device_path, int* outHandle); -int IOSUHAX_FSA_RawRead(int fsaFd, void* data, uint32_t block_size, uint32_t block_cnt, uint64_t sector_offset, int device_handle); -int IOSUHAX_FSA_RawWrite(int fsaFd, const void* data, uint32_t block_size, uint32_t block_cnt, uint64_t sector_offset, int device_handle); -int IOSUHAX_FSA_RawClose(int fsaFd, int device_handle); - -#ifdef __cplusplus -} -#endif - -#endif +/*************************************************************************** + * Copyright (C) 2016 + * by Dimok + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any + * damages arising from the use of this software. + * + * Permission is granted to anyone to use this software for any + * purpose, including commercial applications, and to alter it and + * redistribute it freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you + * must not claim that you wrote the original software. If you use + * this software in a product, an acknowledgment in the product + * documentation would be appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and + * must not be misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. + ***************************************************************************/ +#ifndef _LIB_IOSUHAX_H_ +#define _LIB_IOSUHAX_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define IOS_ERROR_UNKNOWN_VALUE 0xFFFFFFD6 +#define IOS_ERROR_INVALID_ARG 0xFFFFFFE3 +#define IOS_ERROR_INVALID_SIZE 0xFFFFFFE9 +#define IOS_ERROR_UNKNOWN 0xFFFFFFF7 +#define IOS_ERROR_NOEXISTS 0xFFFFFFFA + +typedef struct +{ + uint32_t flag; + uint32_t permission; + uint32_t owner_id; + uint32_t group_id; + uint32_t size; // size in bytes + uint32_t physsize; // physical size on disk in bytes + uint32_t unk[3]; + uint32_t id; + uint32_t ctime; + uint32_t mtime; + uint32_t unk2[0x0D]; +}fileStat_s; + +typedef struct +{ + fileStat_s stat; + char name[0x100]; +}directoryEntry_s; + +#define DIR_ENTRY_IS_DIRECTORY 0x80000000 + +#define FSA_MOUNTFLAGS_BINDMOUNT (1 << 0) +#define FSA_MOUNTFLAGS_GLOBAL (1 << 1) + +int IOSUHAX_Open(const char *dev); // if dev == NULL the default path /dev/iosuhax will be used +int IOSUHAX_Close(void); + +int IOSUHAX_memwrite(uint32_t address, const uint8_t * buffer, uint32_t size); // IOSU external input +int IOSUHAX_memread(uint32_t address, uint8_t * out_buffer, uint32_t size); // IOSU external output +int IOSUHAX_memcpy(uint32_t dst, uint32_t src, uint32_t size); // IOSU internal memcpy only + +int IOSUHAX_kern_write32(uint32_t address, uint32_t value); +int IOSUHAX_kern_read32(uint32_t address, uint32_t* out_buffer, uint32_t count); + +int IOSUHAX_SVC(uint32_t svc_id, uint32_t * args, uint32_t arg_cnt); + +int IOSUHAX_FSA_Open(); +int IOSUHAX_FSA_Close(int fsaFd); + +int IOSUHAX_FSA_Mount(int fsaFd, const char* device_path, const char* volume_path, uint32_t flags, const char* arg_string, int arg_string_len); +int IOSUHAX_FSA_Unmount(int fsaFd, const char* path, uint32_t flags); +int IOSUHAX_FSA_FlushVolume(int fsaFd, const char* volume_path); + +int IOSUHAX_FSA_GetDeviceInfo(int fsaFd, const char* device_path, int type, uint32_t* out_data); + +int IOSUHAX_FSA_MakeDir(int fsaFd, const char* path, uint32_t flags); +int IOSUHAX_FSA_OpenDir(int fsaFd, const char* path, int* outHandle); +int IOSUHAX_FSA_ReadDir(int fsaFd, int handle, directoryEntry_s* out_data); +int IOSUHAX_FSA_RewindDir(int fsaFd, int dirHandle); +int IOSUHAX_FSA_CloseDir(int fsaFd, int handle); +int IOSUHAX_FSA_ChangeDir(int fsaFd, const char *path); + +int IOSUHAX_FSA_OpenFile(int fsaFd, const char* path, const char* mode, int* outHandle); +int IOSUHAX_FSA_ReadFile(int fsaFd, void* data, uint32_t size, uint32_t cnt, int fileHandle, uint32_t flags); +int IOSUHAX_FSA_WriteFile(int fsaFd, const void* data, uint32_t size, uint32_t cnt, int fileHandle, uint32_t flags); +int IOSUHAX_FSA_StatFile(int fsaFd, int fileHandle, fileStat_s* out_data); +int IOSUHAX_FSA_CloseFile(int fsaFd, int fileHandle); +int IOSUHAX_FSA_SetFilePos(int fsaFd, int fileHandle, uint32_t position); +int IOSUHAX_FSA_GetStat(int fsaFd, const char *path, fileStat_s* out_data); +int IOSUHAX_FSA_Remove(int fsaFd, const char *path); +int IOSUHAX_FSA_ChangeMode(int fsaFd, const char* path, int mode); + +int IOSUHAX_FSA_RawOpen(int fsaFd, const char* device_path, int* outHandle); +int IOSUHAX_FSA_RawRead(int fsaFd, void* data, uint32_t block_size, uint32_t block_cnt, uint64_t sector_offset, int device_handle); +int IOSUHAX_FSA_RawWrite(int fsaFd, const void* data, uint32_t block_size, uint32_t block_cnt, uint64_t sector_offset, int device_handle); +int IOSUHAX_FSA_RawClose(int fsaFd, int device_handle); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/deps/libiosuhax/iosuhax_devoptab.h b/deps/libiosuhax/include/iosuhax_devoptab.h similarity index 97% rename from deps/libiosuhax/iosuhax_devoptab.h rename to deps/libiosuhax/include/iosuhax_devoptab.h index 2c7d5d227c..18847a683c 100644 --- a/deps/libiosuhax/iosuhax_devoptab.h +++ b/deps/libiosuhax/include/iosuhax_devoptab.h @@ -1,42 +1,42 @@ -/*************************************************************************** - * Copyright (C) 2015 - * by Dimok - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any - * damages arising from the use of this software. - * - * Permission is granted to anyone to use this software for any - * purpose, including commercial applications, and to alter it and - * redistribute it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you - * must not claim that you wrote the original software. If you use - * this software in a product, an acknowledgment in the product - * documentation would be appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and - * must not be misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source - * distribution. - ***************************************************************************/ -#ifndef __IOSUHAX_DEVOPTAB_H_ -#define __IOSUHAX_DEVOPTAB_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -//! virtual name example: sd or odd (for sd:/ or odd:/ access) -//! fsaFd: fd received by IOSUHAX_FSA_Open(); -//! dev_path: (optional) if a device should be mounted to the mount_path. If NULL no IOSUHAX_FSA_Mount is not executed. -//! mount_path: path to map to virtual device name -int mount_fs(const char *virt_name, int fsaFd, const char *dev_path, const char *mount_path); -int unmount_fs(const char *virt_name); - -#ifdef __cplusplus -} -#endif - -#endif // __IOSUHAX_DEVOPTAB_H_ +/*************************************************************************** + * Copyright (C) 2015 + * by Dimok + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any + * damages arising from the use of this software. + * + * Permission is granted to anyone to use this software for any + * purpose, including commercial applications, and to alter it and + * redistribute it freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you + * must not claim that you wrote the original software. If you use + * this software in a product, an acknowledgment in the product + * documentation would be appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and + * must not be misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. + ***************************************************************************/ +#ifndef __IOSUHAX_DEVOPTAB_H_ +#define __IOSUHAX_DEVOPTAB_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +//! virtual name example: sd or odd (for sd:/ or odd:/ access) +//! fsaFd: fd received by IOSUHAX_FSA_Open(); +//! dev_path: (optional) if a device should be mounted to the mount_path. If NULL no IOSUHAX_FSA_Mount is not executed. +//! mount_path: path to map to virtual device name +int mount_fs(const char *virt_name, int fsaFd, const char *dev_path, const char *mount_path); +int unmount_fs(const char *virt_name); + +#ifdef __cplusplus +} +#endif + +#endif // __IOSUHAX_DEVOPTAB_H_ diff --git a/deps/libiosuhax/iosuhax_disc_interface.h b/deps/libiosuhax/include/iosuhax_disc_interface.h similarity index 97% rename from deps/libiosuhax/iosuhax_disc_interface.h rename to deps/libiosuhax/include/iosuhax_disc_interface.h index 0ce479547b..c5b703b7bc 100644 --- a/deps/libiosuhax/iosuhax_disc_interface.h +++ b/deps/libiosuhax/include/iosuhax_disc_interface.h @@ -1,73 +1,73 @@ -/*************************************************************************** - * Copyright (C) 2016 - * by Dimok - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any - * damages arising from the use of this software. - * - * Permission is granted to anyone to use this software for any - * purpose, including commercial applications, and to alter it and - * redistribute it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you - * must not claim that you wrote the original software. If you use - * this software in a product, an acknowledgment in the product - * documentation would be appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and - * must not be misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source - * distribution. - ***************************************************************************/ -#ifndef _IOSUHAX_DISC_INTERFACE_H_ -#define _IOSUHAX_DISC_INTERFACE_H_ - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define DEVICE_TYPE_WII_U_SD (('W'<<24)|('U'<<16)|('S'<<8)|'D') -#define DEVICE_TYPE_WII_U_USB (('W'<<24)|('U'<<16)|('S'<<8)|'B') -#define FEATURE_WII_U_SD 0x00001000 -#define FEATURE_WII_U_USB 0x00002000 - -#ifndef OGC_DISC_IO_INCLUDE -typedef uint32_t sec_t; - -#define FEATURE_MEDIUM_CANREAD 0x00000001 -#define FEATURE_MEDIUM_CANWRITE 0x00000002 - -typedef bool (* FN_MEDIUM_STARTUP)(void) ; -typedef bool (* FN_MEDIUM_ISINSERTED)(void) ; -typedef bool (* FN_MEDIUM_READSECTORS)(uint32_t sector, uint32_t numSectors, void* buffer) ; -typedef bool (* FN_MEDIUM_WRITESECTORS)(uint32_t sector, uint32_t numSectors, const void* buffer) ; -typedef bool (* FN_MEDIUM_CLEARSTATUS)(void) ; -typedef bool (* FN_MEDIUM_SHUTDOWN)(void) ; - -struct DISC_INTERFACE_STRUCT { - unsigned long ioType ; - unsigned long features ; - FN_MEDIUM_STARTUP startup ; - FN_MEDIUM_ISINSERTED isInserted ; - FN_MEDIUM_READSECTORS readSectors ; - FN_MEDIUM_WRITESECTORS writeSectors ; - FN_MEDIUM_CLEARSTATUS clearStatus ; - FN_MEDIUM_SHUTDOWN shutdown ; -} ; - -typedef struct DISC_INTERFACE_STRUCT DISC_INTERFACE ; -#endif - -extern const DISC_INTERFACE IOSUHAX_sdio_disc_interface; -extern const DISC_INTERFACE IOSUHAX_usb_disc_interface; - -#ifdef __cplusplus -} -#endif - -#endif +/*************************************************************************** + * Copyright (C) 2016 + * by Dimok + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any + * damages arising from the use of this software. + * + * Permission is granted to anyone to use this software for any + * purpose, including commercial applications, and to alter it and + * redistribute it freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you + * must not claim that you wrote the original software. If you use + * this software in a product, an acknowledgment in the product + * documentation would be appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and + * must not be misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. + ***************************************************************************/ +#ifndef _IOSUHAX_DISC_INTERFACE_H_ +#define _IOSUHAX_DISC_INTERFACE_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define DEVICE_TYPE_WII_U_SD (('W'<<24)|('U'<<16)|('S'<<8)|'D') +#define DEVICE_TYPE_WII_U_USB (('W'<<24)|('U'<<16)|('S'<<8)|'B') +#define FEATURE_WII_U_SD 0x00001000 +#define FEATURE_WII_U_USB 0x00002000 + +#ifndef OGC_DISC_IO_INCLUDE +typedef uint32_t sec_t; + +#define FEATURE_MEDIUM_CANREAD 0x00000001 +#define FEATURE_MEDIUM_CANWRITE 0x00000002 + +typedef bool (* FN_MEDIUM_STARTUP)(void) ; +typedef bool (* FN_MEDIUM_ISINSERTED)(void) ; +typedef bool (* FN_MEDIUM_READSECTORS)(uint32_t sector, uint32_t numSectors, void* buffer) ; +typedef bool (* FN_MEDIUM_WRITESECTORS)(uint32_t sector, uint32_t numSectors, const void* buffer) ; +typedef bool (* FN_MEDIUM_CLEARSTATUS)(void) ; +typedef bool (* FN_MEDIUM_SHUTDOWN)(void) ; + +struct DISC_INTERFACE_STRUCT { + unsigned long ioType ; + unsigned long features ; + FN_MEDIUM_STARTUP startup ; + FN_MEDIUM_ISINSERTED isInserted ; + FN_MEDIUM_READSECTORS readSectors ; + FN_MEDIUM_WRITESECTORS writeSectors ; + FN_MEDIUM_CLEARSTATUS clearStatus ; + FN_MEDIUM_SHUTDOWN shutdown ; +} ; + +typedef struct DISC_INTERFACE_STRUCT DISC_INTERFACE ; +#endif + +extern const DISC_INTERFACE IOSUHAX_sdio_disc_interface; +extern const DISC_INTERFACE IOSUHAX_usb_disc_interface; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/deps/libiosuhax/os_functions.h b/deps/libiosuhax/os_functions.h deleted file mode 100644 index 6135236344..0000000000 --- a/deps/libiosuhax/os_functions.h +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef __OS_FUNCTIONS_H_ -#define __OS_FUNCTIONS_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#define OS_MUTEX_SIZE 44 - -// RetroArch mod: use existing headers; prevents conflicts in griffin -#include -#include -#if 0 - -#ifndef __WUT__ -//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -//! Mutex functions -//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -extern void (* OSInitMutex)(void* mutex); -extern void (* OSLockMutex)(void* mutex); -extern void (* OSUnlockMutex)(void* mutex); - -//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -//! IOS function -//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -extern int (*IOS_Ioctl)(int fd, unsigned int request, void *input_buffer,unsigned int input_buffer_len, void *output_buffer, unsigned int output_buffer_len); -extern int (*IOS_Open)(char *path, unsigned int mode); -extern int (*IOS_Close)(int fd); -#else -//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -//! Mutex functions -//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -extern void OSInitMutex(void* mutex); -extern void OSLockMutex(void* mutex); -extern void OSUnlockMutex(void* mutex); - -//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -//! IOS function -//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -extern int IOS_Ioctl(int fd, unsigned int request, void *input_buffer,unsigned int input_buffer_len, void *output_buffer, unsigned int output_buffer_len); -extern int IOS_Open(char *path, unsigned int mode); -extern int IOS_Close(int fd); -#endif // __WUT__ - -#ifdef __cplusplus -} -#endif - -#endif // 0 - -#endif // __OS_FUNCTIONS_H_ diff --git a/deps/libiosuhax/iosuhax.c b/deps/libiosuhax/source/iosuhax.c similarity index 78% rename from deps/libiosuhax/iosuhax.c rename to deps/libiosuhax/source/iosuhax.c index 34a842ce73..bf6032850d 100644 --- a/deps/libiosuhax/iosuhax.c +++ b/deps/libiosuhax/source/iosuhax.c @@ -1,1029 +1,956 @@ -/*************************************************************************** - * Copyright (C) 2016 - * by Dimok - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any - * damages arising from the use of this software. - * - * Permission is granted to anyone to use this software for any - * purpose, including commercial applications, and to alter it and - * redistribute it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you - * must not claim that you wrote the original software. If you use - * this software in a product, an acknowledgment in the product - * documentation would be appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and - * must not be misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source - * distribution. - ***************************************************************************/ -#include -#include -#include "os_functions.h" -#include "iosuhax.h" - -#define IOSUHAX_MAGIC_WORD 0x4E696365 - -#define IOCTL_MEM_WRITE 0x00 -#define IOCTL_MEM_READ 0x01 -#define IOCTL_SVC 0x02 -#define IOCTL_MEMCPY 0x04 -#define IOCTL_REPEATED_WRITE 0x05 -#define IOCTL_KERN_READ32 0x06 -#define IOCTL_KERN_WRITE32 0x07 - -#define IOCTL_FSA_OPEN 0x40 -#define IOCTL_FSA_CLOSE 0x41 -#define IOCTL_FSA_MOUNT 0x42 -#define IOCTL_FSA_UNMOUNT 0x43 -#define IOCTL_FSA_GETDEVICEINFO 0x44 -#define IOCTL_FSA_OPENDIR 0x45 -#define IOCTL_FSA_READDIR 0x46 -#define IOCTL_FSA_CLOSEDIR 0x47 -#define IOCTL_FSA_MAKEDIR 0x48 -#define IOCTL_FSA_OPENFILE 0x49 -#define IOCTL_FSA_READFILE 0x4A -#define IOCTL_FSA_WRITEFILE 0x4B -#define IOCTL_FSA_STATFILE 0x4C -#define IOCTL_FSA_CLOSEFILE 0x4D -#define IOCTL_FSA_SETFILEPOS 0x4E -#define IOCTL_FSA_GETSTAT 0x4F -#define IOCTL_FSA_REMOVE 0x50 -#define IOCTL_FSA_REWINDDIR 0x51 -#define IOCTL_FSA_CHDIR 0x52 -#define IOCTL_FSA_RENAME 0x53 -#define IOCTL_FSA_RAW_OPEN 0x54 -#define IOCTL_FSA_RAW_READ 0x55 -#define IOCTL_FSA_RAW_WRITE 0x56 -#define IOCTL_FSA_RAW_CLOSE 0x57 -#define IOCTL_FSA_CHANGEMODE 0x58 -#define IOCTL_FSA_FLUSHVOLUME 0x59 -#define IOCTL_CHECK_IF_IOSUHAX 0x5B - -static int iosuhaxHandle = -1; - -int IOSUHAX_Open(const char *dev) -{ - if(iosuhaxHandle >= 0) - return iosuhaxHandle; - - iosuhaxHandle = IOS_Open((char*)(dev ? dev : "/dev/iosuhax"), 0); - if(iosuhaxHandle >= 0 && dev) /* make sure device is actually iosuhax */ - { - unsigned int res = 0; - IOS_Ioctl(iosuhaxHandle, IOCTL_CHECK_IF_IOSUHAX, (void*)0, 0, &res, 4); - if(res != IOSUHAX_MAGIC_WORD) - { - IOS_Close(iosuhaxHandle); - iosuhaxHandle = -1; - } - } - - return iosuhaxHandle; -} - -int IOSUHAX_Close(void) -{ - if(iosuhaxHandle < 0) - return 0; - - int res = IOS_Close(iosuhaxHandle); - iosuhaxHandle = -1; - return res; -} - -int IOSUHAX_memwrite(uint32_t address, const uint8_t * buffer, uint32_t size) -{ - if(iosuhaxHandle < 0) - return iosuhaxHandle; - - if(!buffer) - return -1; - - uint32_t *io_buf = (uint32_t*)memalign(0x20, size + 4); - if(!io_buf) - return -2; - - io_buf[0] = address; - memcpy(io_buf + 1, buffer, size); - - int res = IOS_Ioctl(iosuhaxHandle, IOCTL_MEM_WRITE, io_buf, size + 4, 0, 0); - - free(io_buf); - return res; -} - -int IOSUHAX_memread(uint32_t address, uint8_t * out_buffer, uint32_t size) -{ - if(iosuhaxHandle < 0) - return iosuhaxHandle; - - if(!out_buffer || !size) - return -1; - - return IOS_Ioctl(iosuhaxHandle, IOCTL_MEM_READ, &address, sizeof(address), out_buffer, size); -} - -int IOSUHAX_memcpy(uint32_t dst, uint32_t src, uint32_t size) -{ - if(iosuhaxHandle < 0) - return iosuhaxHandle; - - if(!dst || !src || !size) - return -1; - - uint32_t io_buf[3]; - io_buf[0] = dst; - io_buf[1] = src; - io_buf[2] = size; - - return IOS_Ioctl(iosuhaxHandle, IOCTL_MEMCPY, io_buf, sizeof(io_buf), 0, 0); -} - -int IOSUHAX_SVC(uint32_t svc_id, uint32_t * args, uint32_t arg_cnt) -{ - if(iosuhaxHandle < 0) - return iosuhaxHandle; - - uint32_t arguments[9]; - arguments[0] = svc_id; - - if(args && arg_cnt) - { - if(arg_cnt > 8) - arg_cnt = 8; - - memcpy(arguments + 1, args, arg_cnt * 4); - } - - int result; - int ret = IOS_Ioctl(iosuhaxHandle, IOCTL_SVC, arguments, (1 + arg_cnt) * 4, &result, sizeof(result)); - if(ret < 0) - return ret; - - return result; -} - -int IOSUHAX_FSA_Open(void) -{ - if(iosuhaxHandle < 0) - return iosuhaxHandle; - - int fsaFd; - - int res = IOS_Ioctl(iosuhaxHandle, IOCTL_FSA_OPEN, 0, 0, &fsaFd, sizeof(fsaFd)); - if(res < 0) - return res; - - return fsaFd; -} - -int IOSUHAX_FSA_Close(int fsaFd) -{ - if(iosuhaxHandle < 0) - return iosuhaxHandle; - - int res = IOS_Ioctl(iosuhaxHandle, IOCTL_FSA_CLOSE, &fsaFd, sizeof(fsaFd), &fsaFd, sizeof(fsaFd)); - if(res < 0) - return res; - - return fsaFd; -} - -int IOSUHAX_FSA_Mount(int fsaFd, const char* device_path, const char* volume_path, uint32_t flags, const char* arg_string, int arg_string_len) -{ - if(iosuhaxHandle < 0) - return iosuhaxHandle; - - if(!device_path || !volume_path || !arg_string) - return -1; - - const int input_cnt = 6; - - int io_buf_size = (sizeof(uint32_t) * input_cnt) + strlen(device_path) + strlen(volume_path) + arg_string_len + 3; - - uint32_t *io_buf = (uint32_t*)memalign(0x20, io_buf_size); - if(!io_buf) - return -2; - - memset(io_buf, 0, io_buf_size); - io_buf[0] = fsaFd; - io_buf[1] = sizeof(uint32_t) * input_cnt; - io_buf[2] = io_buf[1] + strlen(device_path) + 1; - io_buf[3] = flags; - io_buf[4] = arg_string_len ? ( io_buf[2] + strlen(volume_path) + 1) : 0; - io_buf[5] = arg_string_len; - - strcpy(((char*)io_buf) + io_buf[1], device_path); - strcpy(((char*)io_buf) + io_buf[2], volume_path); - - if(arg_string_len) - memcpy(((char*)io_buf) + io_buf[4], arg_string, arg_string_len); - - int mountRes; - - int res = IOS_Ioctl(iosuhaxHandle, IOCTL_FSA_MOUNT, io_buf, io_buf_size, &mountRes, sizeof(mountRes)); - if(res < 0) - { - free(io_buf); - return res; - } - - free(io_buf); - return mountRes; -} - -int IOSUHAX_FSA_Unmount(int fsaFd, const char* path, uint32_t flags) -{ - if(iosuhaxHandle < 0) - return iosuhaxHandle; - - if(!path) - return -1; - - const int input_cnt = 3; - - int io_buf_size = sizeof(uint32_t) * input_cnt + strlen(path) + 1; - - uint32_t *io_buf = (uint32_t*)memalign(0x20, io_buf_size); - if(!io_buf) - return -2; - - io_buf[0] = fsaFd; - io_buf[1] = sizeof(uint32_t) * input_cnt; - io_buf[2] = flags; - strcpy(((char*)io_buf) + io_buf[1], path); - - int result; - - int res = IOS_Ioctl(iosuhaxHandle, IOCTL_FSA_UNMOUNT, io_buf, io_buf_size, &result, sizeof(result)); - if(res < 0) - { - free(io_buf); - return res; - } - - free(io_buf); - return result; -} - -int IOSUHAX_FSA_FlushVolume(int fsaFd, const char *volume_path) -{ - if(iosuhaxHandle < 0) - return iosuhaxHandle; - - if(!volume_path) - return -1; - - const int input_cnt = 2; - - int io_buf_size = sizeof(uint32_t) * input_cnt + strlen(volume_path) + 1; - - uint32_t *io_buf = (uint32_t*)memalign(0x20, io_buf_size); - if(!io_buf) - return -2; - - io_buf[0] = fsaFd; - io_buf[1] = sizeof(uint32_t) * input_cnt; - strcpy(((char*)io_buf) + io_buf[1], volume_path); - - int result; - - int res = IOS_Ioctl(iosuhaxHandle, IOCTL_FSA_FLUSHVOLUME, io_buf, io_buf_size, &result, sizeof(result)); - if(res < 0) - { - free(io_buf); - return res; - } - - free(io_buf); - return result; -} - -int IOSUHAX_FSA_GetDeviceInfo(int fsaFd, const char* device_path, int type, uint32_t* out_data) -{ - if(iosuhaxHandle < 0) - return iosuhaxHandle; - - if(!device_path || !out_data) - return -1; - - const int input_cnt = 3; - - int io_buf_size = sizeof(uint32_t) * input_cnt + strlen(device_path) + 1; - - uint32_t *io_buf = (uint32_t*)memalign(0x20, io_buf_size); - if(!io_buf) - return -2; - - io_buf[0] = fsaFd; - io_buf[1] = sizeof(uint32_t) * input_cnt; - io_buf[2] = type; - strcpy(((char*)io_buf) + io_buf[1], device_path); - - uint32_t out_buf[1 + 0x64 / 4]; - - int res = IOS_Ioctl(iosuhaxHandle, IOCTL_FSA_GETDEVICEINFO, io_buf, io_buf_size, out_buf, sizeof(out_buf)); - if(res < 0) - { - free(io_buf); - return res; - } - - memcpy(out_data, out_buf + 1, 0x64); - free(io_buf); - return out_buf[0]; -} - -int IOSUHAX_FSA_MakeDir(int fsaFd, const char* path, uint32_t flags) -{ - if(iosuhaxHandle < 0) - return iosuhaxHandle; - - if(!path) - return -1; - - const int input_cnt = 3; - - int io_buf_size = sizeof(uint32_t) * input_cnt + strlen(path) + 1; - - uint32_t *io_buf = (uint32_t*)memalign(0x20, io_buf_size); - if(!io_buf) - return -2; - - io_buf[0] = fsaFd; - io_buf[1] = sizeof(uint32_t) * input_cnt; - io_buf[2] = flags; - strcpy(((char*)io_buf) + io_buf[1], path); - - int result; - int res = IOS_Ioctl(iosuhaxHandle, IOCTL_FSA_MAKEDIR, io_buf, io_buf_size, &result, sizeof(result)); - if(res < 0) - { - free(io_buf); - return res; - } - - free(io_buf); - return result; -} - -int IOSUHAX_FSA_OpenDir(int fsaFd, const char* path, int* outHandle) -{ - if(iosuhaxHandle < 0) - return iosuhaxHandle; - - if(!path) - return -1; - - const int input_cnt = 2; - - int io_buf_size = sizeof(uint32_t) * input_cnt + strlen(path) + 1; - - uint32_t *io_buf = (uint32_t*)memalign(0x20, io_buf_size); - if(!io_buf) - return -2; - - io_buf[0] = fsaFd; - io_buf[1] = sizeof(uint32_t) * input_cnt; - strcpy(((char*)io_buf) + io_buf[1], path); - - int result_vec[2]; - - int res = IOS_Ioctl(iosuhaxHandle, IOCTL_FSA_OPENDIR, io_buf, io_buf_size, result_vec, sizeof(result_vec)); - if(res < 0) - { - free(io_buf); - return res; - } - - *outHandle = result_vec[1]; - free(io_buf); - return result_vec[0]; -} - -int IOSUHAX_FSA_ReadDir(int fsaFd, int handle, directoryEntry_s* out_data) -{ - if(iosuhaxHandle < 0) - return iosuhaxHandle; - - if(!out_data) - return -1; - - const int input_cnt = 2; - - int io_buf_size = sizeof(uint32_t) * input_cnt; - - uint32_t *io_buf = (uint32_t*)memalign(0x20, io_buf_size); - if(!io_buf) - return -2; - - io_buf[0] = fsaFd; - io_buf[1] = handle; - - int result_vec_size = 4 + sizeof(directoryEntry_s); - uint8_t *result_vec = (uint8_t*) memalign(0x20, result_vec_size); - if(!result_vec) - { - free(io_buf); - return -2; - } - - int res = IOS_Ioctl(iosuhaxHandle, IOCTL_FSA_READDIR, io_buf, io_buf_size, result_vec, result_vec_size); - if(res < 0) - { - free(result_vec); - free(io_buf); - return res; - } - - int result = *(int*)result_vec; - memcpy(out_data, result_vec + 4, sizeof(directoryEntry_s)); - free(io_buf); - free(result_vec); - return result; -} - -int IOSUHAX_FSA_RewindDir(int fsaFd, int dirHandle) -{ - if(iosuhaxHandle < 0) - return iosuhaxHandle; - - const int input_cnt = 2; - - int io_buf_size = sizeof(uint32_t) * input_cnt; - - uint32_t *io_buf = (uint32_t*)memalign(0x20, io_buf_size); - if(!io_buf) - return -2; - - io_buf[0] = fsaFd; - io_buf[1] = dirHandle; - - int result; - - int res = IOS_Ioctl(iosuhaxHandle, IOCTL_FSA_REWINDDIR, io_buf, io_buf_size, &result, sizeof(result)); - if(res < 0) - { - free(io_buf); - return res; - } - - free(io_buf); - return result; -} - -int IOSUHAX_FSA_CloseDir(int fsaFd, int handle) -{ - if(iosuhaxHandle < 0) - return iosuhaxHandle; - - const int input_cnt = 2; - - int io_buf_size = sizeof(uint32_t) * input_cnt; - - uint32_t *io_buf = (uint32_t*)memalign(0x20, io_buf_size); - if(!io_buf) - return -2; - - io_buf[0] = fsaFd; - io_buf[1] = handle; - - int result; - - int res = IOS_Ioctl(iosuhaxHandle, IOCTL_FSA_CLOSEDIR, io_buf, io_buf_size, &result, sizeof(result)); - if(res < 0) - { - free(io_buf); - return res; - } - - free(io_buf); - return result; -} - -int IOSUHAX_FSA_ChangeDir(int fsaFd, const char *path) -{ - if(iosuhaxHandle < 0) - return iosuhaxHandle; - - if(!path) - return -1; - - const int input_cnt = 2; - - int io_buf_size = sizeof(uint32_t) * input_cnt + strlen(path) + 1; - - uint32_t *io_buf = (uint32_t*)memalign(0x20, io_buf_size); - if(!io_buf) - return -2; - - io_buf[0] = fsaFd; - io_buf[1] = sizeof(uint32_t) * input_cnt; - strcpy(((char*)io_buf) + io_buf[1], path); - - int result; - - int res = IOS_Ioctl(iosuhaxHandle, IOCTL_FSA_CHDIR, io_buf, io_buf_size, &result, sizeof(result)); - if(res < 0) - { - free(io_buf); - return res; - } - - free(io_buf); - return result; -} - -int IOSUHAX_FSA_OpenFile(int fsaFd, const char* path, const char* mode, int* outHandle) -{ - if(iosuhaxHandle < 0) - return iosuhaxHandle; - - if(!path || !mode || !outHandle) - return -1; - - const int input_cnt = 3; - - int io_buf_size = sizeof(uint32_t) * input_cnt + strlen(path) + strlen(mode) + 2; - - uint32_t *io_buf = (uint32_t*)memalign(0x20, io_buf_size); - if(!io_buf) - return -2; - - io_buf[0] = fsaFd; - io_buf[1] = sizeof(uint32_t) * input_cnt; - io_buf[2] = io_buf[1] + strlen(path) + 1; - strcpy(((char*)io_buf) + io_buf[1], path); - strcpy(((char*)io_buf) + io_buf[2], mode); - - int result_vec[2]; - - int res = IOS_Ioctl(iosuhaxHandle, IOCTL_FSA_OPENFILE, io_buf, io_buf_size, result_vec, sizeof(result_vec)); - if(res < 0) - { - free(io_buf); - return res; - } - - *outHandle = result_vec[1]; - free(io_buf); - return result_vec[0]; -} - -int IOSUHAX_FSA_ReadFile(int fsaFd, void* data, uint32_t size, uint32_t cnt, int fileHandle, uint32_t flags) -{ - if(iosuhaxHandle < 0) - return iosuhaxHandle; - - if(!data) - return -1; - - const int input_cnt = 5; - - int io_buf_size = sizeof(uint32_t) * input_cnt; - - uint32_t *io_buf = (uint32_t*)memalign(0x20, io_buf_size); - if(!io_buf) - return -2; - - io_buf[0] = fsaFd; - io_buf[1] = size; - io_buf[2] = cnt; - io_buf[3] = fileHandle; - io_buf[4] = flags; - - int out_buf_size = ((size * cnt + 0x40) + 0x3F) & ~0x3F; - - uint32_t *out_buffer = (uint32_t*)memalign(0x40, out_buf_size); - if(!out_buffer) - { - free(io_buf); - return -2; - } - - int res = IOS_Ioctl(iosuhaxHandle, IOCTL_FSA_READFILE, io_buf, io_buf_size, out_buffer, out_buf_size); - if(res < 0) - { - free(out_buffer); - free(io_buf); - return res; - } - - /* ! data is put to offset 0x40 to align the buffer output */ - memcpy(data, ((uint8_t*)out_buffer) + 0x40, size * cnt); - - int result = out_buffer[0]; - - free(out_buffer); - free(io_buf); - return result; -} - -int IOSUHAX_FSA_WriteFile(int fsaFd, const void* data, uint32_t size, uint32_t cnt, int fileHandle, uint32_t flags) -{ - if(iosuhaxHandle < 0) - return iosuhaxHandle; - - if(!data) - return -1; - - const int input_cnt = 5; - - int io_buf_size = ((sizeof(uint32_t) * input_cnt + size * cnt + 0x40) + 0x3F) & ~0x3F; - - uint32_t *io_buf = (uint32_t*)memalign(0x20, io_buf_size); - if(!io_buf) - return -2; - - io_buf[0] = fsaFd; - io_buf[1] = size; - io_buf[2] = cnt; - io_buf[3] = fileHandle; - io_buf[4] = flags; - - /* ! data is put to offset 0x40 to align the buffer input */ - memcpy(((uint8_t*)io_buf) + 0x40, data, size * cnt); - - int result; - int res = IOS_Ioctl(iosuhaxHandle, IOCTL_FSA_WRITEFILE, io_buf, io_buf_size, &result, sizeof(result)); - if(res < 0) - { - free(io_buf); - return res; - } - free(io_buf); - return result; -} - -int IOSUHAX_FSA_StatFile(int fsaFd, int fileHandle, fileStat_s* out_data) -{ - if(iosuhaxHandle < 0) - return iosuhaxHandle; - - if(!out_data) - return -1; - - const int input_cnt = 2; - - int io_buf_size = sizeof(uint32_t) * input_cnt; - - uint32_t *io_buf = (uint32_t*)memalign(0x20, io_buf_size); - if(!io_buf) - return -2; - - io_buf[0] = fsaFd; - io_buf[1] = fileHandle; - - int out_buf_size = 4 + sizeof(fileStat_s); - uint32_t *out_buffer = (uint32_t*)memalign(0x20, out_buf_size); - if(!out_buffer) - { - free(io_buf); - return -2; - } - - int res = IOS_Ioctl(iosuhaxHandle, IOCTL_FSA_STATFILE, io_buf, io_buf_size, out_buffer, out_buf_size); - if(res < 0) - { - free(io_buf); - free(out_buffer); - return res; - } - - int result = out_buffer[0]; - memcpy(out_data, out_buffer + 1, sizeof(fileStat_s)); - - free(io_buf); - free(out_buffer); - return result; -} - -int IOSUHAX_FSA_CloseFile(int fsaFd, int fileHandle) -{ - if(iosuhaxHandle < 0) - return iosuhaxHandle; - - const int input_cnt = 2; - - int io_buf_size = sizeof(uint32_t) * input_cnt; - - uint32_t *io_buf = (uint32_t*)memalign(0x20, io_buf_size); - if(!io_buf) - return -2; - - io_buf[0] = fsaFd; - io_buf[1] = fileHandle; - - int result; - - int res = IOS_Ioctl(iosuhaxHandle, IOCTL_FSA_CLOSEFILE, io_buf, io_buf_size, &result, sizeof(result)); - if(res < 0) - { - free(io_buf); - return res; - } - - free(io_buf); - return result; -} - -int IOSUHAX_FSA_SetFilePos(int fsaFd, int fileHandle, uint32_t position) -{ - if(iosuhaxHandle < 0) - return iosuhaxHandle; - - const int input_cnt = 3; - - int io_buf_size = sizeof(uint32_t) * input_cnt; - - uint32_t *io_buf = (uint32_t*)memalign(0x20, io_buf_size); - if(!io_buf) - return -2; - - io_buf[0] = fsaFd; - io_buf[1] = fileHandle; - io_buf[2] = position; - - int result; - - int res = IOS_Ioctl(iosuhaxHandle, IOCTL_FSA_SETFILEPOS, io_buf, io_buf_size, &result, sizeof(result)); - if(res < 0) - { - free(io_buf); - return res; - } - - free(io_buf); - return result; -} - -int IOSUHAX_FSA_GetStat(int fsaFd, const char *path, fileStat_s* out_data) -{ - if(iosuhaxHandle < 0) - return iosuhaxHandle; - - if(!path || !out_data) - return -1; - - const int input_cnt = 2; - - int io_buf_size = sizeof(uint32_t) * input_cnt + strlen(path) + 1; - - uint32_t *io_buf = (uint32_t*)memalign(0x20, io_buf_size); - if(!io_buf) - return -2; - - io_buf[0] = fsaFd; - io_buf[1] = sizeof(uint32_t) * input_cnt; - strcpy(((char*)io_buf) + io_buf[1], path); - - int out_buf_size = 4 + sizeof(fileStat_s); - uint32_t *out_buffer = (uint32_t*)memalign(0x20, out_buf_size); - if(!out_buffer) - { - free(io_buf); - return -2; - } - - int res = IOS_Ioctl(iosuhaxHandle, IOCTL_FSA_GETSTAT, io_buf, io_buf_size, out_buffer, out_buf_size); - if(res < 0) - { - free(io_buf); - free(out_buffer); - return res; - } - - int result = out_buffer[0]; - memcpy(out_data, out_buffer + 1, sizeof(fileStat_s)); - - free(io_buf); - free(out_buffer); - return result; -} - -int IOSUHAX_FSA_Remove(int fsaFd, const char *path) -{ - if(iosuhaxHandle < 0) - return iosuhaxHandle; - - if(!path) - return -1; - - const int input_cnt = 2; - - int io_buf_size = sizeof(uint32_t) * input_cnt + strlen(path) + 1; - - uint32_t *io_buf = (uint32_t*)memalign(0x20, io_buf_size); - if(!io_buf) - return -2; - - io_buf[0] = fsaFd; - io_buf[1] = sizeof(uint32_t) * input_cnt; - strcpy(((char*)io_buf) + io_buf[1], path); - - int result; - - int res = IOS_Ioctl(iosuhaxHandle, IOCTL_FSA_REMOVE, io_buf, io_buf_size, &result, sizeof(result)); - if(res < 0) - { - free(io_buf); - return res; - } - - free(io_buf); - return result; -} - -int IOSUHAX_FSA_ChangeMode(int fsaFd, const char* path, int mode) -{ - if(iosuhaxHandle < 0) - return iosuhaxHandle; - - if(!path) - return -1; - - const int input_cnt = 3; - - int io_buf_size = sizeof(uint32_t) * input_cnt + strlen(path) + 1; - - uint32_t *io_buf = (uint32_t*)memalign(0x20, io_buf_size); - if(!io_buf) - return -2; - - io_buf[0] = fsaFd; - io_buf[1] = sizeof(uint32_t) * input_cnt; - io_buf[2] = mode; - strcpy(((char*)io_buf) + io_buf[1], path); - - int result; - - int res = IOS_Ioctl(iosuhaxHandle, IOCTL_FSA_CHANGEMODE, io_buf, io_buf_size, &result, sizeof(result)); - if(res < 0) - { - free(io_buf); - return res; - } - - free(io_buf); - return result; -} - -int IOSUHAX_FSA_RawOpen(int fsaFd, const char* device_path, int* outHandle) -{ - if(iosuhaxHandle < 0) - return iosuhaxHandle; - - if(!device_path && !outHandle) - return -1; - - const int input_cnt = 2; - - int io_buf_size = sizeof(uint32_t) * input_cnt + strlen(device_path) + 1; - - uint32_t *io_buf = (uint32_t*)memalign(0x20, io_buf_size); - if(!io_buf) - return -2; - - io_buf[0] = fsaFd; - io_buf[1] = sizeof(uint32_t) * input_cnt; - strcpy(((char*)io_buf) + io_buf[1], device_path); - - int result_vec[2]; - - int res = IOS_Ioctl(iosuhaxHandle, IOCTL_FSA_RAW_OPEN, io_buf, io_buf_size, result_vec, sizeof(result_vec)); - if(res < 0) - { - free(io_buf); - return res; - } - - if(outHandle) - *outHandle = result_vec[1]; - - free(io_buf); - return result_vec[0]; -} - -int IOSUHAX_FSA_RawRead(int fsaFd, void* data, uint32_t block_size, uint32_t block_cnt, uint64_t sector_offset, int device_handle) -{ - if(iosuhaxHandle < 0) - return iosuhaxHandle; - - if(!data) - return -1; - - const int input_cnt = 6; - - int io_buf_size = sizeof(uint32_t) * input_cnt; - - uint32_t *io_buf = (uint32_t*)memalign(0x20, io_buf_size); - if(!io_buf) - return -2; - - io_buf[0] = fsaFd; - io_buf[1] = block_size; - io_buf[2] = block_cnt; - io_buf[3] = (sector_offset >> 32) & 0xFFFFFFFF; - io_buf[4] = sector_offset & 0xFFFFFFFF; - io_buf[5] = device_handle; - - int out_buf_size = ((block_size * block_cnt + 0x40) + 0x3F) & ~0x3F; - - uint32_t *out_buffer = (uint32_t*)memalign(0x40, out_buf_size); - if(!out_buffer) - { - free(io_buf); - return -2; - } - - int res = IOS_Ioctl(iosuhaxHandle, IOCTL_FSA_RAW_READ, io_buf, io_buf_size, out_buffer, out_buf_size); - if(res < 0) - { - free(out_buffer); - free(io_buf); - return res; - } - - /* ! data is put to offset 0x40 to align the buffer output */ - memcpy(data, ((uint8_t*)out_buffer) + 0x40, block_size * block_cnt); - - int result = out_buffer[0]; - - free(out_buffer); - free(io_buf); - return result; -} - -int IOSUHAX_FSA_RawWrite(int fsaFd, const void* data, uint32_t block_size, uint32_t block_cnt, uint64_t sector_offset, int device_handle) -{ - if(iosuhaxHandle < 0) - return iosuhaxHandle; - - if(!data) - return -1; - - const int input_cnt = 6; - - int io_buf_size = ((sizeof(uint32_t) * input_cnt + block_size * block_cnt + 0x40) + 0x3F) & ~0x3F; - - uint32_t *io_buf = (uint32_t*)memalign(0x20, io_buf_size); - if(!io_buf) - return -2; - - io_buf[0] = fsaFd; - io_buf[1] = block_size; - io_buf[2] = block_cnt; - io_buf[3] = (sector_offset >> 32) & 0xFFFFFFFF; - io_buf[4] = sector_offset & 0xFFFFFFFF; - io_buf[5] = device_handle; - - /* ! data is put to offset 0x40 to align the buffer input */ - memcpy(((uint8_t*)io_buf) + 0x40, data, block_size * block_cnt); - - int result; - - int res = IOS_Ioctl(iosuhaxHandle, IOCTL_FSA_RAW_WRITE, io_buf, io_buf_size, &result, sizeof(result)); - if(res < 0) - { - free(io_buf); - return res; - } - - free(io_buf); - return result; -} - - -int IOSUHAX_FSA_RawClose(int fsaFd, int device_handle) -{ - if(iosuhaxHandle < 0) - return iosuhaxHandle; - - const int input_cnt = 2; - - int io_buf_size = sizeof(uint32_t) * input_cnt; - - uint32_t *io_buf = (uint32_t*)memalign(0x20, io_buf_size); - if(!io_buf) - return -2; - - io_buf[0] = fsaFd; - io_buf[1] = device_handle; - - int result; - - int res = IOS_Ioctl(iosuhaxHandle, IOCTL_FSA_RAW_CLOSE, io_buf, io_buf_size, &result, sizeof(result)); - if(res < 0) - { - free(io_buf); - return res; - } - - free(io_buf); - return result; -} +/*************************************************************************** + * Copyright (C) 2016 + * by Dimok + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any + * damages arising from the use of this software. + * + * Permission is granted to anyone to use this software for any + * purpose, including commercial applications, and to alter it and + * redistribute it freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you + * must not claim that you wrote the original software. If you use + * this software in a product, an acknowledgment in the product + * documentation would be appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and + * must not be misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. + ***************************************************************************/ +#include +#include +#include "os_functions.h" +#include "iosuhax.h" + +#define IOSUHAX_MAGIC_WORD 0x4E696365 + +#define IOCTL_MEM_WRITE 0x00 +#define IOCTL_MEM_READ 0x01 +#define IOCTL_SVC 0x02 +#define IOCTL_MEMCPY 0x04 +#define IOCTL_REPEATED_WRITE 0x05 +#define IOCTL_KERN_READ32 0x06 +#define IOCTL_KERN_WRITE32 0x07 + +#define IOCTL_FSA_OPEN 0x40 +#define IOCTL_FSA_CLOSE 0x41 +#define IOCTL_FSA_MOUNT 0x42 +#define IOCTL_FSA_UNMOUNT 0x43 +#define IOCTL_FSA_GETDEVICEINFO 0x44 +#define IOCTL_FSA_OPENDIR 0x45 +#define IOCTL_FSA_READDIR 0x46 +#define IOCTL_FSA_CLOSEDIR 0x47 +#define IOCTL_FSA_MAKEDIR 0x48 +#define IOCTL_FSA_OPENFILE 0x49 +#define IOCTL_FSA_READFILE 0x4A +#define IOCTL_FSA_WRITEFILE 0x4B +#define IOCTL_FSA_STATFILE 0x4C +#define IOCTL_FSA_CLOSEFILE 0x4D +#define IOCTL_FSA_SETFILEPOS 0x4E +#define IOCTL_FSA_GETSTAT 0x4F +#define IOCTL_FSA_REMOVE 0x50 +#define IOCTL_FSA_REWINDDIR 0x51 +#define IOCTL_FSA_CHDIR 0x52 +#define IOCTL_FSA_RENAME 0x53 +#define IOCTL_FSA_RAW_OPEN 0x54 +#define IOCTL_FSA_RAW_READ 0x55 +#define IOCTL_FSA_RAW_WRITE 0x56 +#define IOCTL_FSA_RAW_CLOSE 0x57 +#define IOCTL_FSA_CHANGEMODE 0x58 +#define IOCTL_FSA_FLUSHVOLUME 0x59 +#define IOCTL_CHECK_IF_IOSUHAX 0x5B + +static int iosuhaxHandle = -1; + +#define ALIGN(align) __attribute__((aligned(align))) +#define ROUNDUP(x, align) (((x) + ((align) - 1)) & ~((align) - 1)) + +int IOSUHAX_Open(const char *dev) +{ + if(iosuhaxHandle >= 0) + return iosuhaxHandle; + + iosuhaxHandle = IOS_Open((char*)(dev ? dev : "/dev/iosuhax"), 0); + if(iosuhaxHandle >= 0 && dev) //make sure device is actually iosuhax + { + ALIGN(0x20) int res[0x20 >> 2]; + *res = 0; + + IOS_Ioctl(iosuhaxHandle, IOCTL_CHECK_IF_IOSUHAX, (void*)0, 0, res, 4); + if(*res != IOSUHAX_MAGIC_WORD) + { + IOS_Close(iosuhaxHandle); + iosuhaxHandle = -1; + } + } + + return iosuhaxHandle; +} + +int IOSUHAX_Close(void) +{ + if(iosuhaxHandle < 0) + return 0; + + int res = IOS_Close(iosuhaxHandle); + iosuhaxHandle = -1; + return res; +} + +int IOSUHAX_memwrite(uint32_t address, const uint8_t * buffer, uint32_t size) +{ + if(iosuhaxHandle < 0) + return iosuhaxHandle; + + uint32_t *io_buf = (uint32_t*)memalign(0x20, ROUNDUP(size + 4, 0x20)); + if(!io_buf) + return -2; + + io_buf[0] = address; + memcpy(io_buf + 1, buffer, size); + + int res = IOS_Ioctl(iosuhaxHandle, IOCTL_MEM_WRITE, io_buf, size + 4, 0, 0); + + free(io_buf); + return res; +} + +int IOSUHAX_memread(uint32_t address, uint8_t * out_buffer, uint32_t size) +{ + if(iosuhaxHandle < 0) + return iosuhaxHandle; + + ALIGN(0x20) int io_buf[0x20 >> 2]; + io_buf[0] = address; + + void* tmp_buf = NULL; + + if(((uintptr_t)out_buffer & 0x1F) || (size & 0x1F)) + { + tmp_buf = (uint32_t*)memalign(0x20, ROUNDUP(size, 0x20)); + if(!tmp_buf) + return -2; + } + + int res = IOS_Ioctl(iosuhaxHandle, IOCTL_MEM_READ, io_buf, sizeof(address), tmp_buf ? tmp_buf : out_buffer, size); + + if(res >= 0 && tmp_buf) + memcpy(out_buffer, tmp_buf, size); + + free(tmp_buf); + return res; +} + +int IOSUHAX_memcpy(uint32_t dst, uint32_t src, uint32_t size) +{ + if(iosuhaxHandle < 0) + return iosuhaxHandle; + + ALIGN(0x20) uint32_t io_buf[0x20 >> 2]; + io_buf[0] = dst; + io_buf[1] = src; + io_buf[2] = size; + + return IOS_Ioctl(iosuhaxHandle, IOCTL_MEMCPY, io_buf, 3 * sizeof(uint32_t), 0, 0); +} + +int IOSUHAX_kern_write32(uint32_t address, uint32_t value) +{ + if(iosuhaxHandle < 0) + return iosuhaxHandle; + + ALIGN(0x20) uint32_t io_buf[0x20 >> 2]; + io_buf[0] = address; + io_buf[1] = value; + + return IOS_Ioctl(iosuhaxHandle, IOCTL_KERN_WRITE32, io_buf, 2 * sizeof(uint32_t), 0, 0); +} + +int IOSUHAX_kern_read32(uint32_t address, uint32_t* out_buffer, uint32_t count) +{ + if(iosuhaxHandle < 0) + return iosuhaxHandle; + + ALIGN(0x20) uint32_t io_buf[0x20 >> 2]; + io_buf[0] = address; + + void* tmp_buf = NULL; + + if(((uintptr_t)out_buffer & 0x1F) || ((count * 4) & 0x1F)) + { + tmp_buf = (uint32_t*)memalign(0x20, ROUNDUP((count * 4), 0x20)); + if(!tmp_buf) + return -2; + } + + int res = IOS_Ioctl(iosuhaxHandle, IOCTL_KERN_READ32, io_buf, sizeof(address), tmp_buf ? tmp_buf : out_buffer, count * 4); + + if(res >= 0 && tmp_buf) + memcpy(out_buffer, tmp_buf, count * 4); + + free(tmp_buf); + return res; +} + +int IOSUHAX_SVC(uint32_t svc_id, uint32_t * args, uint32_t arg_cnt) +{ + if(iosuhaxHandle < 0) + return iosuhaxHandle; + + ALIGN(0x20) uint32_t arguments[0x40 >> 2]; + arguments[0] = svc_id; + + if(args && arg_cnt) + { + if(arg_cnt > 8) + arg_cnt = 8; + + memcpy(arguments + 1, args, arg_cnt * 4); + } + + ALIGN(0x20) int result[0x20 >> 2]; + int ret = IOS_Ioctl(iosuhaxHandle, IOCTL_SVC, arguments, (1 + arg_cnt) * 4, result, 4); + if(ret < 0) + return ret; + + return *result; +} + +int IOSUHAX_FSA_Open(void) +{ + if(iosuhaxHandle < 0) + return iosuhaxHandle; + + ALIGN(0x20) int io_buf[0x20 >> 2]; + + int res = IOS_Ioctl(iosuhaxHandle, IOCTL_FSA_OPEN, 0, 0, io_buf, sizeof(int)); + if(res < 0) + return res; + + return io_buf[0]; +} + +int IOSUHAX_FSA_Close(int fsaFd) +{ + if(iosuhaxHandle < 0) + return iosuhaxHandle; + + ALIGN(0x20) int io_buf[0x20 >> 2]; + io_buf[0] = fsaFd; + + int res = IOS_Ioctl(iosuhaxHandle, IOCTL_FSA_CLOSE, io_buf, sizeof(fsaFd), io_buf, sizeof(fsaFd)); + if(res < 0) + return res; + + return io_buf[0]; +} + +int IOSUHAX_FSA_Mount(int fsaFd, const char* device_path, const char* volume_path, uint32_t flags, const char* arg_string, int arg_string_len) +{ + if(iosuhaxHandle < 0) + return iosuhaxHandle; + + const int input_cnt = 6; + + int io_buf_size = (sizeof(uint32_t) * input_cnt) + strlen(device_path) + strlen(volume_path) + arg_string_len + 3; + + ALIGN(0x20) int io_buf[ROUNDUP(io_buf_size, 0x20) >> 2]; + memset(io_buf, 0, io_buf_size); + + io_buf[0] = fsaFd; + io_buf[1] = sizeof(uint32_t) * input_cnt; + io_buf[2] = io_buf[1] + strlen(device_path) + 1; + io_buf[3] = flags; + io_buf[4] = arg_string_len ? ( io_buf[2] + strlen(volume_path) + 1) : 0; + io_buf[5] = arg_string_len; + + strcpy(((char*)io_buf) + io_buf[1], device_path); + strcpy(((char*)io_buf) + io_buf[2], volume_path); + + if(arg_string_len) + memcpy(((char*)io_buf) + io_buf[4], arg_string, arg_string_len); + + int res = IOS_Ioctl(iosuhaxHandle, IOCTL_FSA_MOUNT, io_buf, io_buf_size, io_buf, 4); + if(res < 0) + return res; + + return io_buf[0]; +} + +int IOSUHAX_FSA_Unmount(int fsaFd, const char* path, uint32_t flags) +{ + if(iosuhaxHandle < 0) + return iosuhaxHandle; + + const int input_cnt = 3; + + int io_buf_size = sizeof(uint32_t) * input_cnt + strlen(path) + 1; + + ALIGN(0x20) int io_buf[ROUNDUP(io_buf_size, 0x20) >> 2]; + + io_buf[0] = fsaFd; + io_buf[1] = sizeof(uint32_t) * input_cnt; + io_buf[2] = flags; + strcpy(((char*)io_buf) + io_buf[1], path); + + int res = IOS_Ioctl(iosuhaxHandle, IOCTL_FSA_UNMOUNT, io_buf, io_buf_size, io_buf, 4); + if(res < 0) + return res; + + return io_buf[0]; +} + +int IOSUHAX_FSA_FlushVolume(int fsaFd, const char *volume_path) +{ + if(iosuhaxHandle < 0) + return iosuhaxHandle; + + const int input_cnt = 2; + + int io_buf_size = sizeof(uint32_t) * input_cnt + strlen(volume_path) + 1; + + ALIGN(0x20) int io_buf[ROUNDUP(io_buf_size, 0x20) >> 2]; + + io_buf[0] = fsaFd; + io_buf[1] = sizeof(uint32_t) * input_cnt; + strcpy(((char*)io_buf) + io_buf[1], volume_path); + + int res = IOS_Ioctl(iosuhaxHandle, IOCTL_FSA_FLUSHVOLUME, io_buf, io_buf_size, io_buf, 4); + if(res < 0) + return res; + + return io_buf[0]; +} + +int IOSUHAX_FSA_GetDeviceInfo(int fsaFd, const char* device_path, int type, uint32_t* out_data) +{ + if(iosuhaxHandle < 0) + return iosuhaxHandle; + + const int input_cnt = 3; + + int io_buf_size = sizeof(uint32_t) * input_cnt + strlen(device_path) + 1; + + uint32_t *io_buf = (uint32_t*)memalign(0x20, io_buf_size); + if(!io_buf) + return -2; + + io_buf[0] = fsaFd; + io_buf[1] = sizeof(uint32_t) * input_cnt; + io_buf[2] = type; + strcpy(((char*)io_buf) + io_buf[1], device_path); + + uint32_t out_buf[1 + 0x64 / 4]; + + int res = IOS_Ioctl(iosuhaxHandle, IOCTL_FSA_GETDEVICEINFO, io_buf, io_buf_size, out_buf, sizeof(out_buf)); + if(res < 0) + { + free(io_buf); + return res; + } + + memcpy(out_data, out_buf + 1, 0x64); + free(io_buf); + return out_buf[0]; +} + +int IOSUHAX_FSA_MakeDir(int fsaFd, const char* path, uint32_t flags) +{ + if(iosuhaxHandle < 0) + return iosuhaxHandle; + + const int input_cnt = 3; + + int io_buf_size = sizeof(uint32_t) * input_cnt + strlen(path) + 1; + + uint32_t *io_buf = (uint32_t*)memalign(0x20, io_buf_size); + if(!io_buf) + return -2; + + io_buf[0] = fsaFd; + io_buf[1] = sizeof(uint32_t) * input_cnt; + io_buf[2] = flags; + strcpy(((char*)io_buf) + io_buf[1], path); + + int result; + int res = IOS_Ioctl(iosuhaxHandle, IOCTL_FSA_MAKEDIR, io_buf, io_buf_size, &result, sizeof(result)); + if(res < 0) + { + free(io_buf); + return res; + } + + free(io_buf); + return result; +} + +int IOSUHAX_FSA_OpenDir(int fsaFd, const char* path, int* outHandle) +{ + if(iosuhaxHandle < 0) + return iosuhaxHandle; + + const int input_cnt = 2; + + int io_buf_size = sizeof(uint32_t) * input_cnt + strlen(path) + 1; + + uint32_t *io_buf = (uint32_t*)memalign(0x20, io_buf_size); + if(!io_buf) + return -2; + + io_buf[0] = fsaFd; + io_buf[1] = sizeof(uint32_t) * input_cnt; + strcpy(((char*)io_buf) + io_buf[1], path); + + int result_vec[2]; + + int res = IOS_Ioctl(iosuhaxHandle, IOCTL_FSA_OPENDIR, io_buf, io_buf_size, result_vec, sizeof(result_vec)); + if(res < 0) + { + free(io_buf); + return res; + } + + *outHandle = result_vec[1]; + free(io_buf); + return result_vec[0]; +} + +int IOSUHAX_FSA_ReadDir(int fsaFd, int handle, directoryEntry_s* out_data) +{ + if(iosuhaxHandle < 0) + return iosuhaxHandle; + + const int input_cnt = 2; + + int io_buf_size = sizeof(uint32_t) * input_cnt; + + uint32_t *io_buf = (uint32_t*)memalign(0x20, io_buf_size); + if(!io_buf) + return -2; + + io_buf[0] = fsaFd; + io_buf[1] = handle; + + int result_vec_size = 4 + sizeof(directoryEntry_s); + uint8_t *result_vec = (uint8_t*) memalign(0x20, result_vec_size); + if(!result_vec) + { + free(io_buf); + return -2; + } + + int res = IOS_Ioctl(iosuhaxHandle, IOCTL_FSA_READDIR, io_buf, io_buf_size, result_vec, result_vec_size); + if(res < 0) + { + free(result_vec); + free(io_buf); + return res; + } + + int result = *(int*)result_vec; + memcpy(out_data, result_vec + 4, sizeof(directoryEntry_s)); + free(io_buf); + free(result_vec); + return result; +} + +int IOSUHAX_FSA_RewindDir(int fsaFd, int dirHandle) +{ + if(iosuhaxHandle < 0) + return iosuhaxHandle; + + const int input_cnt = 2; + + int io_buf_size = sizeof(uint32_t) * input_cnt; + + uint32_t *io_buf = (uint32_t*)memalign(0x20, io_buf_size); + if(!io_buf) + return -2; + + io_buf[0] = fsaFd; + io_buf[1] = dirHandle; + + int result; + + int res = IOS_Ioctl(iosuhaxHandle, IOCTL_FSA_REWINDDIR, io_buf, io_buf_size, &result, sizeof(result)); + if(res < 0) + { + free(io_buf); + return res; + } + + free(io_buf); + return result; +} + +int IOSUHAX_FSA_CloseDir(int fsaFd, int handle) +{ + if(iosuhaxHandle < 0) + return iosuhaxHandle; + + const int input_cnt = 2; + + int io_buf_size = sizeof(uint32_t) * input_cnt; + + uint32_t *io_buf = (uint32_t*)memalign(0x20, io_buf_size); + if(!io_buf) + return -2; + + io_buf[0] = fsaFd; + io_buf[1] = handle; + + int result; + + int res = IOS_Ioctl(iosuhaxHandle, IOCTL_FSA_CLOSEDIR, io_buf, io_buf_size, &result, sizeof(result)); + if(res < 0) + { + free(io_buf); + return res; + } + + free(io_buf); + return result; +} + +int IOSUHAX_FSA_ChangeDir(int fsaFd, const char *path) +{ + if(iosuhaxHandle < 0) + return iosuhaxHandle; + + const int input_cnt = 2; + + int io_buf_size = sizeof(uint32_t) * input_cnt + strlen(path) + 1; + + uint32_t *io_buf = (uint32_t*)memalign(0x20, io_buf_size); + if(!io_buf) + return -2; + + io_buf[0] = fsaFd; + io_buf[1] = sizeof(uint32_t) * input_cnt; + strcpy(((char*)io_buf) + io_buf[1], path); + + int result; + + int res = IOS_Ioctl(iosuhaxHandle, IOCTL_FSA_CHDIR, io_buf, io_buf_size, &result, sizeof(result)); + if(res < 0) + { + free(io_buf); + return res; + } + + free(io_buf); + return result; +} + +int IOSUHAX_FSA_OpenFile(int fsaFd, const char* path, const char* mode, int* outHandle) +{ + if(iosuhaxHandle < 0) + return iosuhaxHandle; + + const int input_cnt = 3; + + int io_buf_size = sizeof(uint32_t) * input_cnt + strlen(path) + strlen(mode) + 2; + + uint32_t *io_buf = (uint32_t*)memalign(0x20, io_buf_size); + if(!io_buf) + return -2; + + io_buf[0] = fsaFd; + io_buf[1] = sizeof(uint32_t) * input_cnt; + io_buf[2] = io_buf[1] + strlen(path) + 1; + strcpy(((char*)io_buf) + io_buf[1], path); + strcpy(((char*)io_buf) + io_buf[2], mode); + + int result_vec[2]; + + int res = IOS_Ioctl(iosuhaxHandle, IOCTL_FSA_OPENFILE, io_buf, io_buf_size, result_vec, sizeof(result_vec)); + if(res < 0) + { + free(io_buf); + return res; + } + + *outHandle = result_vec[1]; + free(io_buf); + return result_vec[0]; +} + +int IOSUHAX_FSA_ReadFile(int fsaFd, void* data, uint32_t size, uint32_t cnt, int fileHandle, uint32_t flags) +{ + if(iosuhaxHandle < 0) + return iosuhaxHandle; + + const int input_cnt = 5; + + int io_buf_size = sizeof(uint32_t) * input_cnt; + + uint32_t *io_buf = (uint32_t*)memalign(0x20, io_buf_size); + if(!io_buf) + return -2; + + io_buf[0] = fsaFd; + io_buf[1] = size; + io_buf[2] = cnt; + io_buf[3] = fileHandle; + io_buf[4] = flags; + + int out_buf_size = ((size * cnt + 0x40) + 0x3F) & ~0x3F; + + uint32_t *out_buffer = (uint32_t*)memalign(0x40, out_buf_size); + if(!out_buffer) + { + free(io_buf); + return -2; + } + + int res = IOS_Ioctl(iosuhaxHandle, IOCTL_FSA_READFILE, io_buf, io_buf_size, out_buffer, out_buf_size); + if(res < 0) + { + free(out_buffer); + free(io_buf); + return res; + } + + //! data is put to offset 0x40 to align the buffer output + memcpy(data, ((uint8_t*)out_buffer) + 0x40, size * cnt); + + int result = out_buffer[0]; + + free(out_buffer); + free(io_buf); + return result; +} + +int IOSUHAX_FSA_WriteFile(int fsaFd, const void* data, uint32_t size, uint32_t cnt, int fileHandle, uint32_t flags) +{ + if(iosuhaxHandle < 0) + return iosuhaxHandle; + + const int input_cnt = 5; + + int io_buf_size = ((sizeof(uint32_t) * input_cnt + size * cnt + 0x40) + 0x3F) & ~0x3F; + + uint32_t *io_buf = (uint32_t*)memalign(0x20, io_buf_size); + if(!io_buf) + return -2; + + io_buf[0] = fsaFd; + io_buf[1] = size; + io_buf[2] = cnt; + io_buf[3] = fileHandle; + io_buf[4] = flags; + + //! data is put to offset 0x40 to align the buffer input + memcpy(((uint8_t*)io_buf) + 0x40, data, size * cnt); + + int result; + int res = IOS_Ioctl(iosuhaxHandle, IOCTL_FSA_WRITEFILE, io_buf, io_buf_size, &result, sizeof(result)); + if(res < 0) + { + free(io_buf); + return res; + } + free(io_buf); + return result; +} + +int IOSUHAX_FSA_StatFile(int fsaFd, int fileHandle, fileStat_s* out_data) +{ + if(iosuhaxHandle < 0) + return iosuhaxHandle; + + const int input_cnt = 2; + + int io_buf_size = sizeof(uint32_t) * input_cnt; + + uint32_t *io_buf = (uint32_t*)memalign(0x20, io_buf_size); + if(!io_buf) + return -2; + + io_buf[0] = fsaFd; + io_buf[1] = fileHandle; + + int out_buf_size = 4 + sizeof(fileStat_s); + uint32_t *out_buffer = (uint32_t*)memalign(0x20, out_buf_size); + if(!out_buffer) + { + free(io_buf); + return -2; + } + + int res = IOS_Ioctl(iosuhaxHandle, IOCTL_FSA_STATFILE, io_buf, io_buf_size, out_buffer, out_buf_size); + if(res < 0) + { + free(io_buf); + free(out_buffer); + return res; + } + + int result = out_buffer[0]; + memcpy(out_data, out_buffer + 1, sizeof(fileStat_s)); + + free(io_buf); + free(out_buffer); + return result; +} + +int IOSUHAX_FSA_CloseFile(int fsaFd, int fileHandle) +{ + if(iosuhaxHandle < 0) + return iosuhaxHandle; + + const int input_cnt = 2; + + int io_buf_size = sizeof(uint32_t) * input_cnt; + + uint32_t *io_buf = (uint32_t*)memalign(0x20, io_buf_size); + if(!io_buf) + return -2; + + io_buf[0] = fsaFd; + io_buf[1] = fileHandle; + + int result; + + int res = IOS_Ioctl(iosuhaxHandle, IOCTL_FSA_CLOSEFILE, io_buf, io_buf_size, &result, sizeof(result)); + if(res < 0) + { + free(io_buf); + return res; + } + + free(io_buf); + return result; +} + +int IOSUHAX_FSA_SetFilePos(int fsaFd, int fileHandle, uint32_t position) +{ + if(iosuhaxHandle < 0) + return iosuhaxHandle; + + const int input_cnt = 3; + + int io_buf_size = sizeof(uint32_t) * input_cnt; + + uint32_t *io_buf = (uint32_t*)memalign(0x20, io_buf_size); + if(!io_buf) + return -2; + + io_buf[0] = fsaFd; + io_buf[1] = fileHandle; + io_buf[2] = position; + + int result; + + int res = IOS_Ioctl(iosuhaxHandle, IOCTL_FSA_SETFILEPOS, io_buf, io_buf_size, &result, sizeof(result)); + if(res < 0) + { + free(io_buf); + return res; + } + + free(io_buf); + return result; +} + +int IOSUHAX_FSA_GetStat(int fsaFd, const char *path, fileStat_s* out_data) +{ + if(iosuhaxHandle < 0) + return iosuhaxHandle; + + const int input_cnt = 2; + + int io_buf_size = sizeof(uint32_t) * input_cnt + strlen(path) + 1; + + uint32_t *io_buf = (uint32_t*)memalign(0x20, io_buf_size); + if(!io_buf) + return -2; + + io_buf[0] = fsaFd; + io_buf[1] = sizeof(uint32_t) * input_cnt; + strcpy(((char*)io_buf) + io_buf[1], path); + + int out_buf_size = 4 + sizeof(fileStat_s); + uint32_t *out_buffer = (uint32_t*)memalign(0x20, out_buf_size); + if(!out_buffer) + { + free(io_buf); + return -2; + } + + int res = IOS_Ioctl(iosuhaxHandle, IOCTL_FSA_GETSTAT, io_buf, io_buf_size, out_buffer, out_buf_size); + if(res < 0) + { + free(io_buf); + free(out_buffer); + return res; + } + + int result = out_buffer[0]; + memcpy(out_data, out_buffer + 1, sizeof(fileStat_s)); + + free(io_buf); + free(out_buffer); + return result; +} + +int IOSUHAX_FSA_Remove(int fsaFd, const char *path) +{ + if(iosuhaxHandle < 0) + return iosuhaxHandle; + + const int input_cnt = 2; + + int io_buf_size = sizeof(uint32_t) * input_cnt + strlen(path) + 1; + + uint32_t *io_buf = (uint32_t*)memalign(0x20, ROUNDUP(io_buf_size, 0x20)); + if(!io_buf) + return -2; + + io_buf[0] = fsaFd; + io_buf[1] = sizeof(uint32_t) * input_cnt; + strcpy(((char*)io_buf) + io_buf[1], path); + + int res = IOS_Ioctl(iosuhaxHandle, IOCTL_FSA_REMOVE, io_buf, io_buf_size, io_buf, 4); + if(res >= 0) + res = io_buf[0]; + + free(io_buf); + return res; +} + +int IOSUHAX_FSA_ChangeMode(int fsaFd, const char* path, int mode) +{ + if(iosuhaxHandle < 0) + return iosuhaxHandle; + + const int input_cnt = 3; + + int io_buf_size = sizeof(uint32_t) * input_cnt + strlen(path) + 1; + + ALIGN(0x20) uint32_t io_buf[ROUNDUP(io_buf_size, 0x20) >> 2]; + + io_buf[0] = fsaFd; + io_buf[1] = sizeof(uint32_t) * input_cnt; + io_buf[2] = mode; + strcpy(((char*)io_buf) + io_buf[1], path); + + int res = IOS_Ioctl(iosuhaxHandle, IOCTL_FSA_CHANGEMODE, io_buf, io_buf_size, io_buf, 4); + if(res < 0) + return res; + + return io_buf[0]; +} + +int IOSUHAX_FSA_RawOpen(int fsaFd, const char* device_path, int* outHandle) +{ + if(iosuhaxHandle < 0) + return iosuhaxHandle; + + const int input_cnt = 2; + + int io_buf_size = sizeof(uint32_t) * input_cnt + strlen(device_path) + 1; + + ALIGN(0x20) uint32_t io_buf[ROUNDUP(io_buf_size, 0x20) >> 2]; + + io_buf[0] = fsaFd; + io_buf[1] = sizeof(uint32_t) * input_cnt; + strcpy(((char*)io_buf) + io_buf[1], device_path); + + int res = IOS_Ioctl(iosuhaxHandle, IOCTL_FSA_RAW_OPEN, io_buf, io_buf_size, io_buf, 2 * sizeof(int)); + if(res < 0) + return res; + + if(outHandle) + *outHandle = io_buf[1]; + + return io_buf[0]; +} + +int IOSUHAX_FSA_RawRead(int fsaFd, void* data, uint32_t block_size, uint32_t block_cnt, uint64_t sector_offset, int device_handle) +{ + if(iosuhaxHandle < 0) + return iosuhaxHandle; + + const int input_cnt = 6; + + int io_buf_size = 0x40 + block_size * block_cnt; + uint32_t *io_buf = (uint32_t*)memalign(0x40, ROUNDUP(io_buf_size, 0x40)); + + if(!io_buf) + return -2; + + io_buf[0] = fsaFd; + io_buf[1] = block_size; + io_buf[2] = block_cnt; + io_buf[3] = (sector_offset >> 32) & 0xFFFFFFFF; + io_buf[4] = sector_offset & 0xFFFFFFFF; + io_buf[5] = device_handle; + + int res = IOS_Ioctl(iosuhaxHandle, IOCTL_FSA_RAW_READ, io_buf, sizeof(uint32_t) * input_cnt, io_buf, io_buf_size); + if(res >= 0) + { + //! data is put to offset 0x40 to align the buffer output + memcpy(data, ((uint8_t*)io_buf) + 0x40, block_size * block_cnt); + + res = io_buf[0]; + } + + free(io_buf); + return res; +} + +int IOSUHAX_FSA_RawWrite(int fsaFd, const void* data, uint32_t block_size, uint32_t block_cnt, uint64_t sector_offset, int device_handle) +{ + if(iosuhaxHandle < 0) + return iosuhaxHandle; + + int io_buf_size = ROUNDUP(0x40 + block_size * block_cnt, 0x40); + + uint32_t *io_buf = (uint32_t*)memalign(0x40, io_buf_size); + if(!io_buf) + return -2; + + io_buf[0] = fsaFd; + io_buf[1] = block_size; + io_buf[2] = block_cnt; + io_buf[3] = (sector_offset >> 32) & 0xFFFFFFFF; + io_buf[4] = sector_offset & 0xFFFFFFFF; + io_buf[5] = device_handle; + + //! data is put to offset 0x40 to align the buffer input + memcpy(((uint8_t*)io_buf) + 0x40, data, block_size * block_cnt); + + int res = IOS_Ioctl(iosuhaxHandle, IOCTL_FSA_RAW_WRITE, io_buf, io_buf_size, io_buf, 4); + if(res >= 0) + res = io_buf[0]; + + free(io_buf); + return res; +} + + +int IOSUHAX_FSA_RawClose(int fsaFd, int device_handle) +{ + if(iosuhaxHandle < 0) + return iosuhaxHandle; + + const int input_cnt = 2; + + int io_buf_size = sizeof(uint32_t) * input_cnt; + + ALIGN(0x20) uint32_t io_buf[ROUNDUP(io_buf_size, 0x20) >> 2]; + + io_buf[0] = fsaFd; + io_buf[1] = device_handle; + + int res = IOS_Ioctl(iosuhaxHandle, IOCTL_FSA_RAW_CLOSE, io_buf, io_buf_size, io_buf, 4); + if(res < 0) + return res; + + return io_buf[0]; +} diff --git a/deps/libiosuhax/iosuhax_devoptab.c b/deps/libiosuhax/source/iosuhax_devoptab.c similarity index 84% rename from deps/libiosuhax/iosuhax_devoptab.c rename to deps/libiosuhax/source/iosuhax_devoptab.c index 4d59d6ae73..5e945f8ad4 100644 --- a/deps/libiosuhax/iosuhax_devoptab.c +++ b/deps/libiosuhax/source/iosuhax_devoptab.c @@ -1,1134 +1,993 @@ -/*************************************************************************** - * Copyright (C) 2015 - * by Dimok - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any - * damages arising from the use of this software. - * - * Permission is granted to anyone to use this software for any - * purpose, including commercial applications, and to alter it and - * redistribute it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you - * must not claim that you wrote the original software. If you use - * this software in a product, an acknowledgment in the product - * documentation would be appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and - * must not be misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source - * distribution. - ***************************************************************************/ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "os_functions.h" -#include "iosuhax.h" - -typedef struct _fs_dev_private_t { - char *mount_path; - int fsaFd; - int mounted; - void *pMutex; -} fs_dev_private_t; - -typedef struct _fs_dev_file_state_t { - fs_dev_private_t *dev; - int fd; /* File descriptor */ - int flags; /* Opening flags */ - int read; /* True if allowed to read from file */ - int write; /* True if allowed to write to file */ - int append; /* True if allowed to append to file */ - uint32_t pos; /* Current position within the file (in bytes) */ - uint32_t len; /* Total length of the file (in bytes) */ - struct _fs_dev_file_state_t *prevOpenFile; /* The previous entry in a double-linked FILO list of open files */ - struct _fs_dev_file_state_t *nextOpenFile; /* The next entry in a double-linked FILO list of open files */ -} fs_dev_file_state_t; - -typedef struct _fs_dev_dir_entry_t { - fs_dev_private_t *dev; - int dirHandle; -} fs_dev_dir_entry_t; - -static fs_dev_private_t *fs_dev_get_device_data(const char *path) -{ - const devoptab_t *devoptab = NULL; - char name[128] = {0}; - int i; - - if(!path) - return NULL; - - /* Get the device name from the path */ - strncpy(name, path, 127); - strtok(name, ":/"); - - // Search the devoptab table for the specified device name - // NOTE: We do this manually due to a 'bug' in GetDeviceOpTab - // which ignores names with suffixes and causes names - // like "ntfs" and "ntfs1" to be seen as equals - for (i = 3; i < STD_MAX; i++) { - devoptab = devoptab_list[i]; - if (devoptab && devoptab->name) { - if (strcmp(name, devoptab->name) == 0) { - return (fs_dev_private_t *)devoptab->deviceData; - } - } - } - - return NULL; -} - -static char *fs_dev_real_path (const char *path, fs_dev_private_t *dev) -{ - /* Sanity check */ - if (!path || !dev) - return NULL; - - /* Move the path pointer to the start of the actual path */ - if (strchr(path, ':') != NULL) { - path = strchr(path, ':') + 1; - } - - int mount_len = strlen(dev->mount_path); - - char *new_name = (char*)malloc(mount_len + strlen(path) + 1); - if(new_name) { - strcpy(new_name, dev->mount_path); - strcpy(new_name + mount_len, path); - return new_name; - } - return new_name; -} - -static int fs_dev_open_r (struct _reent *r, void *fileStruct, const char *path, int flags, int mode) -{ - fs_dev_private_t *dev = fs_dev_get_device_data(path); - - if(!r) - return -1; - - if(!dev) { - r->_errno = ENODEV; - return -1; - } - - fs_dev_file_state_t *file = (fs_dev_file_state_t *)fileStruct; - if(!file) { - r->_errno = EINVAL; - return -1; - } - - file->dev = dev; - /* Determine which mode the file is opened for */ - file->flags = flags; - - const char *mode_str; - - if ((flags & 0x03) == O_RDONLY) { - file->read = 1; - file->write = 0; - file->append = 0; - mode_str = "r"; - } else if ((flags & 0x03) == O_WRONLY) { - file->read = 0; - file->write = 1; - file->append = (flags & O_APPEND); - mode_str = file->append ? "a" : "w"; - } else if ((flags & 0x03) == O_RDWR) { - file->read = 1; - file->write = 1; - file->append = (flags & O_APPEND); - mode_str = file->append ? "a+" : "r+"; - } else { - r->_errno = EACCES; - return -1; - } - - int fd = -1; - - OSLockMutex(dev->pMutex); - - char *real_path = fs_dev_real_path(path, dev); - if(!path) { - r->_errno = ENOMEM; - OSUnlockMutex(dev->pMutex); - return -1; - } - - int result = IOSUHAX_FSA_OpenFile(dev->fsaFd, real_path, mode_str, &fd); - - free(real_path); - - if(result == 0) - { - fileStat_s stats; - result = IOSUHAX_FSA_StatFile(dev->fsaFd, fd, &stats); - if(result != 0) { - IOSUHAX_FSA_CloseFile(dev->fsaFd, fd); - r->_errno = result; - OSUnlockMutex(dev->pMutex); - return -1; - } - file->fd = fd; - file->pos = 0; - file->len = stats.size; - OSUnlockMutex(dev->pMutex); - return (int)file; - } - - r->_errno = result; - OSUnlockMutex(dev->pMutex); - return -1; -} - -static int fs_dev_close_r (struct _reent *r, void *fd) -{ - fs_dev_file_state_t *file = (fs_dev_file_state_t *)fd; - - if(!r) - return -1; - - if(!file) { - r->_errno = EINVAL; - return -1; - } - - if(!file->dev) { - r->_errno = ENODEV; - return -1; - } - - OSLockMutex(file->dev->pMutex); - - int result = IOSUHAX_FSA_CloseFile(file->dev->fsaFd, file->fd); - - OSUnlockMutex(file->dev->pMutex); - - if(result < 0) - { - r->_errno = result; - return -1; - } - return 0; -} - -static off_t fs_dev_seek_r (struct _reent *r, void* fd, off_t pos, int dir) -{ - fs_dev_file_state_t *file = (fs_dev_file_state_t *)fd; - - if(!r) - return 0; - - if(!file) { - r->_errno = EINVAL; - return 0; - } - - if(!file->dev) { - r->_errno = ENODEV; - return 0; - } - - OSLockMutex(file->dev->pMutex); - - switch(dir) - { - case SEEK_SET: - file->pos = pos; - break; - case SEEK_CUR: - file->pos += pos; - break; - case SEEK_END: - file->pos = file->len + pos; - break; - default: - r->_errno = EINVAL; - return -1; - } - - int result = IOSUHAX_FSA_SetFilePos(file->dev->fsaFd, file->fd, file->pos); - - OSUnlockMutex(file->dev->pMutex); - - if(result == 0) - { - return file->pos; - } - - return result; -} - -static ssize_t fs_dev_write_r (struct _reent *r, void *fd, const char *ptr, size_t len) -{ - fs_dev_file_state_t *file = (fs_dev_file_state_t *)fd; - - if(!r) - return 0; - - if(!file) { - r->_errno = EINVAL; - return 0; - } - - if(!file->dev) { - r->_errno = ENODEV; - return 0; - } - - if(!file->write) - { - r->_errno = EACCES; - return 0; - } - - OSLockMutex(file->dev->pMutex); - - size_t done = 0; - - while(done < len) - { - size_t write_size = len - done; - - int result = IOSUHAX_FSA_WriteFile(file->dev->fsaFd, ptr + done, 0x01, write_size, file->fd, 0); - if(result < 0) - { - r->_errno = result; - break; - } - else if(result == 0) - { - if(write_size > 0) - done = 0; - break; - } - else - { - done += result; - file->pos += result; - } - } - - OSUnlockMutex(file->dev->pMutex); - return done; -} - -static ssize_t fs_dev_read_r (struct _reent *r, void *fd, char *ptr, size_t len) -{ - if(!r) - return 0; - - fs_dev_file_state_t *file = (fs_dev_file_state_t *)fd; - - if(!file) { - r->_errno = EINVAL; - return 0; - } - - if(!file->dev) { - r->_errno = ENODEV; - return 0; - } - - if(!file->read) - { - r->_errno = EACCES; - return 0; - } - - OSLockMutex(file->dev->pMutex); - - size_t done = 0; - - while(done < len) - { - size_t read_size = len - done; - - int result = IOSUHAX_FSA_ReadFile(file->dev->fsaFd, ptr + done, 0x01, read_size, file->fd, 0); - if(result < 0) - { - r->_errno = result; - done = 0; - break; - } - else if(result == 0) - { - /*! TODO: error on read_size > 0 */ - break; - } - else - { - done += result; - file->pos += result; - } - } - - OSUnlockMutex(file->dev->pMutex); - return done; -} - - -static int fs_dev_fstat_r (struct _reent *r, void *fd, struct stat *st) -{ - fs_dev_file_state_t *file = (fs_dev_file_state_t *)fd; - - if(!r) - return -1; - - if(!file) { - r->_errno = EINVAL; - return -1; - } - - if(!file->dev) { - r->_errno = ENODEV; - return -1; - } - - OSLockMutex(file->dev->pMutex); - - /* Zero out the stat buffer */ - memset(st, 0, sizeof(struct stat)); - - fileStat_s stats; - int result = IOSUHAX_FSA_StatFile(file->dev->fsaFd, (int)fd, &stats); - if(result != 0) { - r->_errno = result; - OSUnlockMutex(file->dev->pMutex); - return -1; - } - - st->st_mode = S_IFREG; - st->st_size = stats.size; - st->st_blocks = (stats.size + 511) >> 9; - st->st_nlink = 1; - - /* Fill in the generic entry stats */ - st->st_dev = stats.id; - st->st_uid = stats.owner_id; - st->st_gid = stats.group_id; - st->st_ino = stats.id; - st->st_atime = stats.mtime; - st->st_ctime = stats.ctime; - st->st_mtime = stats.mtime; - OSUnlockMutex(file->dev->pMutex); - return 0; -} - -static int fs_dev_ftruncate_r (struct _reent *r, void *fd, off_t len) -{ - fs_dev_file_state_t *file = (fs_dev_file_state_t *)fd; - - if(!r) - return -1; - - if(!file) { - r->_errno = EINVAL; - return -1; - } - - if(!file->dev) { - r->_errno = ENODEV; - return -1; - } - - r->_errno = ENOTSUP; - /* TODO */ - return -1; -} - -static int fs_dev_fsync_r (struct _reent *r, void *fd) -{ - fs_dev_file_state_t *file = (fs_dev_file_state_t *)fd; - - if(!r) - return -1; - - if(!file) { - r->_errno = EINVAL; - return -1; - } - - if(!file->dev) { - r->_errno = ENODEV; - return -1; - } - - r->_errno = ENOTSUP; - /* TODO */ - return -1; -} - -static int fs_dev_stat_r (struct _reent *r, const char *path, struct stat *st) -{ - fs_dev_private_t *dev = fs_dev_get_device_data(path); - - if(!r) - return -1; - - if(!dev) { - r->_errno = ENODEV; - return -1; - } - - OSLockMutex(dev->pMutex); - - // Zero out the stat buffer - memset(st, 0, sizeof(struct stat)); - - char *real_path = fs_dev_real_path(path, dev); - if(!real_path) { - r->_errno = ENOMEM; - OSUnlockMutex(dev->pMutex); - return -1; - } - - fileStat_s stats; - - int result = IOSUHAX_FSA_GetStat(dev->fsaFd, real_path, &stats); - - free(real_path); - - if(result < 0) { - r->_errno = result; - OSUnlockMutex(dev->pMutex); - return -1; - } - - // mark root also as directory - st->st_mode = ((stats.flag & 0x80000000) || (strlen(dev->mount_path) + 1 == strlen(real_path)))? S_IFDIR : S_IFREG; - st->st_nlink = 1; - st->st_size = stats.size; - st->st_blocks = (stats.size + 511) >> 9; - // Fill in the generic entry stats - st->st_dev = stats.id; - st->st_uid = stats.owner_id; - st->st_gid = stats.group_id; - st->st_ino = stats.id; - st->st_atime = stats.mtime; - st->st_ctime = stats.ctime; - st->st_mtime = stats.mtime; - - OSUnlockMutex(dev->pMutex); - - return 0; -} - -static int fs_dev_link_r (struct _reent *r, const char *existing, const char *newLink) -{ - if(!r) - return -1; - - r->_errno = ENOTSUP; - return -1; -} - -static int fs_dev_unlink_r (struct _reent *r, const char *name) -{ - fs_dev_private_t *dev = fs_dev_get_device_data(name); - - if(!r) - return -1; - - if(!dev) { - r->_errno = ENODEV; - return -1; - } - - OSLockMutex(dev->pMutex); - - char *real_path = fs_dev_real_path(name, dev); - if(!real_path) { - r->_errno = ENOMEM; - OSUnlockMutex(dev->pMutex); - return -1; - } - - int result = IOSUHAX_FSA_Remove(dev->fsaFd, real_path); - - free(real_path); - - OSUnlockMutex(dev->pMutex); - - if(result < 0) { - r->_errno = result; - return -1; - } - - return result; -} - -static int fs_dev_chdir_r (struct _reent *r, const char *name) -{ - fs_dev_private_t *dev = fs_dev_get_device_data(name); - - if(!r) - return -1; - - if(!dev) { - r->_errno = ENODEV; - return -1; - } - - OSLockMutex(dev->pMutex); - - char *real_path = fs_dev_real_path(name, dev); - if(!real_path) { - r->_errno = ENOMEM; - OSUnlockMutex(dev->pMutex); - return -1; - } - - int result = IOSUHAX_FSA_ChangeDir(dev->fsaFd, real_path); - - free(real_path); - - OSUnlockMutex(dev->pMutex); - - if(result < 0) { - r->_errno = result; - return -1; - } - - return 0; -} - -static int fs_dev_rename_r (struct _reent *r, const char *oldName, const char *newName) -{ - fs_dev_private_t *dev = fs_dev_get_device_data(oldName); - - if(!r) - return -1; - - if(!dev) { - r->_errno = ENODEV; - return -1; - } - - if(!newName) { - r->_errno = EINVAL; - return -1; - } - - OSLockMutex(dev->pMutex); - - char *real_oldpath = fs_dev_real_path(oldName, dev); - if(!real_oldpath) { - r->_errno = ENOMEM; - OSUnlockMutex(dev->pMutex); - return -1; - } - char *real_newpath = fs_dev_real_path(newName, dev); - if(!real_newpath) { - r->_errno = ENOMEM; - free(real_oldpath); - OSUnlockMutex(dev->pMutex); - return -1; - } - - //! TODO - int result = -ENOTSUP; - - free(real_oldpath); - free(real_newpath); - - OSUnlockMutex(dev->pMutex); - - if(result < 0) { - r->_errno = result; - return -1; - } - - return 0; - -} - -static int fs_dev_mkdir_r (struct _reent *r, const char *path, int mode) -{ - fs_dev_private_t *dev = fs_dev_get_device_data(path); - - if(!r) - return -1; - - if(!dev) { - r->_errno = ENODEV; - return -1; - } - - OSLockMutex(dev->pMutex); - - char *real_path = fs_dev_real_path(path, dev); - if(!real_path) { - r->_errno = ENOMEM; - OSUnlockMutex(dev->pMutex); - return -1; - } - - int result = IOSUHAX_FSA_MakeDir(dev->fsaFd, real_path, mode); - - free(real_path); - - OSUnlockMutex(dev->pMutex); - - if(result < 0) { - r->_errno = result; - return -1; - } - - return 0; -} - -static int fs_dev_chmod_r (struct _reent *r, const char *path, int mode) -{ - fs_dev_private_t *dev = fs_dev_get_device_data(path); - - if(!r) - return -1; - - if(!dev) { - r->_errno = ENODEV; - return -1; - } - - OSLockMutex(dev->pMutex); - - char *real_path = fs_dev_real_path(path, dev); - if(!real_path) { - r->_errno = ENOMEM; - OSUnlockMutex(dev->pMutex); - return -1; - } - - int result = IOSUHAX_FSA_ChangeMode(dev->fsaFd, real_path, mode); - - free(real_path); - - OSUnlockMutex(dev->pMutex); - - if(result < 0) { - r->_errno = result; - return -1; - } - - return 0; -} - -static int fs_dev_statvfs_r (struct _reent *r, const char *path, struct statvfs *buf) -{ - fs_dev_private_t *dev = fs_dev_get_device_data(path); - - if(!r) - return -1; - - if(!dev) { - r->_errno = ENODEV; - return -1; - } - - if(!buf) { - r->_errno = EINVAL; - return -1; - } - - OSLockMutex(dev->pMutex); - - // Zero out the stat buffer - memset(buf, 0, sizeof(struct statvfs)); - - char *real_path = fs_dev_real_path(path, dev); - if(!real_path) { - r->_errno = ENOMEM; - OSUnlockMutex(dev->pMutex); - return -1; - } - - uint64_t size; - - int result = IOSUHAX_FSA_GetDeviceInfo(dev->fsaFd, real_path, 0x00, (uint32_t*)&size); - - free(real_path); - - if(result < 0) { - r->_errno = result; - OSUnlockMutex(dev->pMutex); - return -1; - } - - // File system block size - buf->f_bsize = 512; - - // Fundamental file system block size - buf->f_frsize = 512; - - // Total number of blocks on file system in units of f_frsize - buf->f_blocks = size >> 9; // this is unknown - - // Free blocks available for all and for non-privileged processes - buf->f_bfree = buf->f_bavail = size >> 9; - - // Number of inodes at this point in time - buf->f_files = 0xffffffff; - - // Free inodes available for all and for non-privileged processes - buf->f_ffree = 0xffffffff; - - // File system id - buf->f_fsid = (int)dev; - - // Bit mask of f_flag values. - buf->f_flag = 0; - - // Maximum length of filenames - buf->f_namemax = 255; - - OSUnlockMutex(dev->pMutex); - - return 0; -} - -static DIR_ITER *fs_dev_diropen_r (struct _reent *r, DIR_ITER *dirState, const char *path) -{ - fs_dev_private_t *dev = fs_dev_get_device_data(path); - - if(!r) - return NULL; - - if(!dev) { - r->_errno = ENODEV; - return NULL; - } - - if(!dirState) { - r->_errno = EINVAL; - return NULL; - } - - fs_dev_dir_entry_t *dirIter = (fs_dev_dir_entry_t *)dirState->dirStruct; - - OSLockMutex(dev->pMutex); - - char *real_path = fs_dev_real_path(path, dev); - if(!real_path) { - r->_errno = ENOMEM; - OSUnlockMutex(dev->pMutex); - return NULL; - } - - int dirHandle; - - int result = IOSUHAX_FSA_OpenDir(dev->fsaFd, real_path, &dirHandle); - - free(real_path); - - OSUnlockMutex(dev->pMutex); - - if(result < 0) - { - r->_errno = result; - return NULL; - } - - dirIter->dev = dev; - dirIter->dirHandle = dirHandle; - - return dirState; -} - -static int fs_dev_dirclose_r (struct _reent *r, DIR_ITER *dirState) -{ - fs_dev_dir_entry_t *dirIter; - - if(!r) - return -1; - - if(!dirState) { - r->_errno = EINVAL; - return -1; - } - - dirIter = (fs_dev_dir_entry_t *)dirState->dirStruct; - - if(!dirIter->dev) { - r->_errno = ENODEV; - return -1; - } - - OSLockMutex(dirIter->dev->pMutex); - - int result = IOSUHAX_FSA_CloseDir(dirIter->dev->fsaFd, dirIter->dirHandle); - - OSUnlockMutex(dirIter->dev->pMutex); - - if(result < 0) - { - r->_errno = result; - return -1; - } - return 0; -} - -static int fs_dev_dirreset_r (struct _reent *r, DIR_ITER *dirState) -{ - fs_dev_dir_entry_t *dirIter; - - if(!r) - return -1; - - if(!dirState) { - r->_errno = EINVAL; - return -1; - } - - dirIter = (fs_dev_dir_entry_t *)dirState->dirStruct; - - if(!dirIter->dev) { - r->_errno = ENODEV; - return -1; - } - - OSLockMutex(dirIter->dev->pMutex); - - int result = IOSUHAX_FSA_RewindDir(dirIter->dev->fsaFd, dirIter->dirHandle); - - OSUnlockMutex(dirIter->dev->pMutex); - - if(result < 0) - { - r->_errno = result; - return -1; - } - return 0; -} - -static int fs_dev_dirnext_r (struct _reent *r, DIR_ITER *dirState, char *filename, struct stat *st) -{ - fs_dev_dir_entry_t *dirIter; - - if(!r) - return -1; - - if(!dirState) { - r->_errno = EINVAL; - return -1; - } - - dirIter = (fs_dev_dir_entry_t *)dirState->dirStruct; - - if(!dirIter->dev) { - r->_errno = ENODEV; - return -1; - } - - OSLockMutex(dirIter->dev->pMutex); - - directoryEntry_s * dir_entry = malloc(sizeof(directoryEntry_s)); - - int result = IOSUHAX_FSA_ReadDir(dirIter->dev->fsaFd, dirIter->dirHandle, dir_entry); - if(result < 0) - { - free(dir_entry); - r->_errno = result; - OSUnlockMutex(dirIter->dev->pMutex); - return -1; - } - - // Fetch the current entry - strcpy(filename, dir_entry->name); - - if(st) - { - memset(st, 0, sizeof(struct stat)); - st->st_mode = (dir_entry->stat.flag & 0x80000000) ? S_IFDIR : S_IFREG; - st->st_nlink = 1; - st->st_size = dir_entry->stat.size; - st->st_blocks = (dir_entry->stat.size + 511) >> 9; - st->st_dev = dir_entry->stat.id; - st->st_uid = dir_entry->stat.owner_id; - st->st_gid = dir_entry->stat.group_id; - st->st_ino = dir_entry->stat.id; - st->st_atime = dir_entry->stat.mtime; - st->st_ctime = dir_entry->stat.ctime; - st->st_mtime = dir_entry->stat.mtime; - } - - free(dir_entry); - OSUnlockMutex(dirIter->dev->pMutex); - return 0; -} - -// NTFS device driver devoptab -static const devoptab_t devops_fs = { - NULL, /* Device name */ - sizeof (fs_dev_file_state_t), - fs_dev_open_r, - fs_dev_close_r, - fs_dev_write_r, - fs_dev_read_r, - fs_dev_seek_r, - fs_dev_fstat_r, - fs_dev_stat_r, - fs_dev_link_r, - fs_dev_unlink_r, - fs_dev_chdir_r, - fs_dev_rename_r, - fs_dev_mkdir_r, - sizeof (fs_dev_dir_entry_t), - fs_dev_diropen_r, - fs_dev_dirreset_r, - fs_dev_dirnext_r, - fs_dev_dirclose_r, - fs_dev_statvfs_r, - fs_dev_ftruncate_r, - fs_dev_fsync_r, - fs_dev_chmod_r, - NULL, /* fs_dev_fchmod_r */ - NULL /* Device data */ -}; - -static int fs_dev_add_device (const char *name, const char *mount_path, int fsaFd, int isMounted) -{ - devoptab_t *dev = NULL; - char *devname = NULL; - char *devpath = NULL; - int i; - - // Sanity check - if (!name || !mount_path) { - errno = EINVAL; - return -1; - } - - // Allocate a devoptab for this device - dev = (devoptab_t *) malloc(sizeof(devoptab_t) + strlen(name) + 1); - if (!dev) { - errno = ENOMEM; - return -1; - } - - // Use the space allocated at the end of the devoptab for storing the device name - devname = (char*)(dev + 1); - strcpy(devname, name); - - // create private data - fs_dev_private_t *priv = (fs_dev_private_t *)malloc(sizeof(fs_dev_private_t) + strlen(mount_path) + 1); - if(!priv) { - free(dev); - errno = ENOMEM; - return -1; - } - - devpath = (char*)(priv+1); - strcpy(devpath, mount_path); - - // setup private data - priv->mount_path = devpath; - priv->fsaFd = fsaFd; - priv->mounted = isMounted; - priv->pMutex = malloc(OS_MUTEX_SIZE); - - if(!priv->pMutex) { - free(dev); - free(priv); - errno = ENOMEM; - return -1; - } - - OSInitMutex(priv->pMutex); - - // Setup the devoptab - memcpy(dev, &devops_fs, sizeof(devoptab_t)); - dev->name = devname; - dev->deviceData = priv; - - // Add the device to the devoptab table (if there is a free slot) - for (i = 3; i < STD_MAX; i++) { - if (devoptab_list[i] == devoptab_list[0]) { - devoptab_list[i] = dev; - return 0; - } - } - - // failure, free all memory - free(priv); - free(dev); - - // If we reach here then there are no free slots in the devoptab table for this device - errno = EADDRNOTAVAIL; - return -1; -} - -static int fs_dev_remove_device (const char *path) -{ - const devoptab_t *devoptab = NULL; - char name[128] = {0}; - int i; - - if(!path) - return -1; - - // Get the device name from the path - strncpy(name, path, 127); - strtok(name, ":/"); - - // Find and remove the specified device from the devoptab table - // NOTE: We do this manually due to a 'bug' in RemoveDevice - // which ignores names with suffixes and causes names - // like "ntfs" and "ntfs1" to be seen as equals - for (i = 3; i < STD_MAX; i++) { - devoptab = devoptab_list[i]; - if (devoptab && devoptab->name) { - if (strcmp(name, devoptab->name) == 0) { - devoptab_list[i] = devoptab_list[0]; - - if(devoptab->deviceData) - { - fs_dev_private_t *priv = (fs_dev_private_t *)devoptab->deviceData; - - if(priv->mounted) - IOSUHAX_FSA_Unmount(priv->fsaFd, priv->mount_path, 2); - - if(priv->pMutex) - free(priv->pMutex); - free(devoptab->deviceData); - } - - free((devoptab_t*)devoptab); - return 0; - } - } - } - - return -1; -} - -int mount_fs(const char *virt_name, int fsaFd, const char *dev_path, const char *mount_path) -{ - int isMounted = 0; - - if(dev_path) - { - isMounted = 1; - - int res = IOSUHAX_FSA_Mount(fsaFd, dev_path, mount_path, 2, 0, 0); - if(res != 0) - { - return res; - } - } - - return fs_dev_add_device(virt_name, mount_path, fsaFd, isMounted); -} - -int unmount_fs(const char *virt_name) -{ - return fs_dev_remove_device(virt_name); -} +/*************************************************************************** + * Copyright (C) 2015 + * by Dimok + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any + * damages arising from the use of this software. + * + * Permission is granted to anyone to use this software for any + * purpose, including commercial applications, and to alter it and + * redistribute it freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you + * must not claim that you wrote the original software. If you use + * this software in a product, an acknowledgment in the product + * documentation would be appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and + * must not be misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. + ***************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "os_functions.h" +#include "iosuhax.h" + +typedef struct _fs_dev_private_t { + char *mount_path; + int fsaFd; + int mounted; + void *pMutex; +} fs_dev_private_t; + +typedef struct _fs_dev_file_state_t { + fs_dev_private_t *dev; + int fd; /* File descriptor */ + int flags; /* Opening flags */ + int read; /* True if allowed to read from file */ + int write; /* True if allowed to write to file */ + int append; /* True if allowed to append to file */ + uint32_t pos; /* Current position within the file (in bytes) */ + uint32_t len; /* Total length of the file (in bytes) */ + struct _fs_dev_file_state_t *prevOpenFile; /* The previous entry in a double-linked FILO list of open files */ + struct _fs_dev_file_state_t *nextOpenFile; /* The next entry in a double-linked FILO list of open files */ +} fs_dev_file_state_t; + +typedef struct _fs_dev_dir_entry_t { + fs_dev_private_t *dev; + int dirHandle; +} fs_dev_dir_entry_t; + +static fs_dev_private_t *fs_dev_get_device_data(const char *path) +{ + const devoptab_t *devoptab = NULL; + char name[128] = {0}; + int i; + + // Get the device name from the path + strncpy(name, path, 127); + strtok(name, ":/"); + + // Search the devoptab table for the specified device name + // NOTE: We do this manually due to a 'bug' in GetDeviceOpTab + // which ignores names with suffixes and causes names + // like "ntfs" and "ntfs1" to be seen as equals + for (i = 3; i < STD_MAX; i++) { + devoptab = devoptab_list[i]; + if (devoptab && devoptab->name) { + if (strcmp(name, devoptab->name) == 0) { + return (fs_dev_private_t *)devoptab->deviceData; + } + } + } + + return NULL; +} + +static char *fs_dev_real_path (const char *path, fs_dev_private_t *dev) +{ + // Sanity check + if (!path) + return NULL; + + // Move the path pointer to the start of the actual path + if (strchr(path, ':') != NULL) { + path = strchr(path, ':') + 1; + } + + int mount_len = strlen(dev->mount_path); + + char *new_name = (char*)malloc(mount_len + strlen(path) + 1); + if(new_name) { + strcpy(new_name, dev->mount_path); + strcpy(new_name + mount_len, path); + return new_name; + } + return new_name; +} + +static int fs_dev_open_r (struct _reent *r, void *fileStruct, const char *path, int flags, int mode) +{ + fs_dev_private_t *dev = fs_dev_get_device_data(path); + if(!dev) { + r->_errno = ENODEV; + return -1; + } + + fs_dev_file_state_t *file = (fs_dev_file_state_t *)fileStruct; + + file->dev = dev; + // Determine which mode the file is opened for + file->flags = flags; + + const char *fsMode; + + // Map flags to open modes + if (flags == 0) { + file->read = 1; + file->write = 0; + file->append = 0; + fsMode = "r"; + } else if (flags == 2) { + file->read = 1; + file->write = 1; + file->append = 0; + fsMode = "r+"; + } else if (flags == 0x601) { + file->read = 0; + file->write = 1; + file->append = 0; + fsMode = "w"; + } else if(flags == 0x602) { + file->read = 1; + file->write = 1; + file->append = 0; + fsMode = "w+"; + } else if(flags == 0x209) { + file->read = 0; + file->write = 1; + file->append = 1; + fsMode = "a"; + } else if(flags == 0x20A) { + file->read = 1; + file->write = 1; + file->append = 1; + fsMode = "a+"; + } else { + r->_errno = EINVAL; + return -1; + } + + + int fd = -1; + + OSLockMutex(dev->pMutex); + + char *real_path = fs_dev_real_path(path, dev); + if(!path) { + r->_errno = ENOMEM; + OSUnlockMutex(dev->pMutex); + return -1; + } + + int result = IOSUHAX_FSA_OpenFile(dev->fsaFd, real_path, fsMode, &fd); + + free(real_path); + + if(result == 0) + { + fileStat_s stats; + result = IOSUHAX_FSA_StatFile(dev->fsaFd, fd, &stats); + if(result != 0) { + IOSUHAX_FSA_CloseFile(dev->fsaFd, fd); + r->_errno = result; + OSUnlockMutex(dev->pMutex); + return -1; + } + file->fd = fd; + file->pos = 0; + file->len = stats.size; + OSUnlockMutex(dev->pMutex); + return (int)file; + } + + r->_errno = result; + OSUnlockMutex(dev->pMutex); + return -1; +} + + +static int fs_dev_close_r (struct _reent *r, void *fd) +{ + fs_dev_file_state_t *file = (fs_dev_file_state_t *)fd; + if(!file->dev) { + r->_errno = ENODEV; + return -1; + } + + OSLockMutex(file->dev->pMutex); + + int result = IOSUHAX_FSA_CloseFile(file->dev->fsaFd, file->fd); + + OSUnlockMutex(file->dev->pMutex); + + if(result < 0) + { + r->_errno = result; + return -1; + } + return 0; +} + +static off_t fs_dev_seek_r (struct _reent *r, void *fd, off_t pos, int dir) +{ + fs_dev_file_state_t *file = (fs_dev_file_state_t *)fd; + if(!file->dev) { + r->_errno = ENODEV; + return 0; + } + + OSLockMutex(file->dev->pMutex); + + switch(dir) + { + case SEEK_SET: + file->pos = pos; + break; + case SEEK_CUR: + file->pos += pos; + break; + case SEEK_END: + file->pos = file->len + pos; + break; + default: + r->_errno = EINVAL; + return -1; + } + + int result = IOSUHAX_FSA_SetFilePos(file->dev->fsaFd, file->fd, file->pos); + + OSUnlockMutex(file->dev->pMutex); + + if(result == 0) + { + return file->pos; + } + + return result; +} + +static ssize_t fs_dev_write_r (struct _reent *r, void *fd, const char *ptr, size_t len) +{ + fs_dev_file_state_t *file = (fs_dev_file_state_t *)fd; + if(!file->dev) { + r->_errno = ENODEV; + return 0; + } + + if(!file->write) + { + r->_errno = EACCES; + return 0; + } + + OSLockMutex(file->dev->pMutex); + + size_t done = 0; + + while(done < len) + { + size_t write_size = len - done; + + int result = IOSUHAX_FSA_WriteFile(file->dev->fsaFd, ptr + done, 0x01, write_size, file->fd, 0); + if(result < 0) + { + r->_errno = result; + break; + } + else if(result == 0) + { + if(write_size > 0) + done = 0; + break; + } + else + { + done += result; + file->pos += result; + } + } + + OSUnlockMutex(file->dev->pMutex); + return done; +} + +static ssize_t fs_dev_read_r (struct _reent *r, void *fd, char *ptr, size_t len) +{ + fs_dev_file_state_t *file = (fs_dev_file_state_t *)fd; + if(!file->dev) { + r->_errno = ENODEV; + return 0; + } + + if(!file->read) + { + r->_errno = EACCES; + return 0; + } + + OSLockMutex(file->dev->pMutex); + + size_t done = 0; + + while(done < len) + { + size_t read_size = len - done; + + int result = IOSUHAX_FSA_ReadFile(file->dev->fsaFd, ptr + done, 0x01, read_size, file->fd, 0); + if(result < 0) + { + r->_errno = result; + done = 0; + break; + } + else if(result == 0) + { + //! TODO: error on read_size > 0 + break; + } + else + { + done += result; + file->pos += result; + } + } + + OSUnlockMutex(file->dev->pMutex); + return done; +} + + +static int fs_dev_fstat_r (struct _reent *r, void *fd, struct stat *st) +{ + fs_dev_file_state_t *file = (fs_dev_file_state_t *)fd; + if(!file->dev) { + r->_errno = ENODEV; + return -1; + } + + OSLockMutex(file->dev->pMutex); + + // Zero out the stat buffer + memset(st, 0, sizeof(struct stat)); + + fileStat_s stats; + int result = IOSUHAX_FSA_StatFile(file->dev->fsaFd, (int)fd, &stats); + if(result != 0) { + r->_errno = result; + OSUnlockMutex(file->dev->pMutex); + return -1; + } + + st->st_mode = S_IFREG; + st->st_size = stats.size; + st->st_blocks = (stats.size + 511) >> 9; + st->st_nlink = 1; + + // Fill in the generic entry stats + st->st_dev = stats.id; + st->st_uid = stats.owner_id; + st->st_gid = stats.group_id; + st->st_ino = stats.id; + st->st_atime = stats.mtime; + st->st_ctime = stats.ctime; + st->st_mtime = stats.mtime; + OSUnlockMutex(file->dev->pMutex); + return 0; +} + +static int fs_dev_ftruncate_r (struct _reent *r, void *fd, off_t len) +{ + fs_dev_file_state_t *file = (fs_dev_file_state_t *)fd; + if(!file->dev) { + r->_errno = ENODEV; + return -1; + } + + r->_errno = ENOTSUP; + // TODO + return -1; +} + +static int fs_dev_fsync_r (struct _reent *r, void *fd) +{ + fs_dev_file_state_t *file = (fs_dev_file_state_t *)fd; + if(!file->dev) { + r->_errno = ENODEV; + return -1; + } + + r->_errno = ENOTSUP; + // TODO + return -1; +} + +static int fs_dev_stat_r (struct _reent *r, const char *path, struct stat *st) +{ + fs_dev_private_t *dev = fs_dev_get_device_data(path); + if(!dev) { + r->_errno = ENODEV; + return -1; + } + + OSLockMutex(dev->pMutex); + + // Zero out the stat buffer + memset(st, 0, sizeof(struct stat)); + + char *real_path = fs_dev_real_path(path, dev); + if(!real_path) { + r->_errno = ENOMEM; + OSUnlockMutex(dev->pMutex); + return -1; + } + + fileStat_s stats; + + int result = IOSUHAX_FSA_GetStat(dev->fsaFd, real_path, &stats); + + free(real_path); + + if(result < 0) { + r->_errno = result; + OSUnlockMutex(dev->pMutex); + return -1; + } + + // mark root also as directory + st->st_mode = ((stats.flag & 0x80000000) || (strlen(dev->mount_path) + 1 == strlen(real_path)))? S_IFDIR : S_IFREG; + st->st_nlink = 1; + st->st_size = stats.size; + st->st_blocks = (stats.size + 511) >> 9; + // Fill in the generic entry stats + st->st_dev = stats.id; + st->st_uid = stats.owner_id; + st->st_gid = stats.group_id; + st->st_ino = stats.id; + st->st_atime = stats.mtime; + st->st_ctime = stats.ctime; + st->st_mtime = stats.mtime; + + OSUnlockMutex(dev->pMutex); + + return 0; +} + +static int fs_dev_link_r (struct _reent *r, const char *existing, const char *newLink) +{ + r->_errno = ENOTSUP; + return -1; +} + +static int fs_dev_unlink_r (struct _reent *r, const char *name) +{ + fs_dev_private_t *dev = fs_dev_get_device_data(name); + if(!dev) { + r->_errno = ENODEV; + return -1; + } + + OSLockMutex(dev->pMutex); + + char *real_path = fs_dev_real_path(name, dev); + if(!real_path) { + r->_errno = ENOMEM; + OSUnlockMutex(dev->pMutex); + return -1; + } + + int result = IOSUHAX_FSA_Remove(dev->fsaFd, real_path); + + free(real_path); + + OSUnlockMutex(dev->pMutex); + + if(result < 0) { + r->_errno = result; + return -1; + } + + return result; +} + +static int fs_dev_chdir_r (struct _reent *r, const char *name) +{ + fs_dev_private_t *dev = fs_dev_get_device_data(name); + if(!dev) { + r->_errno = ENODEV; + return -1; + } + + OSLockMutex(dev->pMutex); + + char *real_path = fs_dev_real_path(name, dev); + if(!real_path) { + r->_errno = ENOMEM; + OSUnlockMutex(dev->pMutex); + return -1; + } + + int result = IOSUHAX_FSA_ChangeDir(dev->fsaFd, real_path); + + free(real_path); + + OSUnlockMutex(dev->pMutex); + + if(result < 0) { + r->_errno = result; + return -1; + } + + return 0; +} + +static int fs_dev_rename_r (struct _reent *r, const char *oldName, const char *newName) +{ + fs_dev_private_t *dev = fs_dev_get_device_data(oldName); + if(!dev) { + r->_errno = ENODEV; + return -1; + } + + OSLockMutex(dev->pMutex); + + char *real_oldpath = fs_dev_real_path(oldName, dev); + if(!real_oldpath) { + r->_errno = ENOMEM; + OSUnlockMutex(dev->pMutex); + return -1; + } + char *real_newpath = fs_dev_real_path(newName, dev); + if(!real_newpath) { + r->_errno = ENOMEM; + free(real_oldpath); + OSUnlockMutex(dev->pMutex); + return -1; + } + + //! TODO + int result = -ENOTSUP; + + free(real_oldpath); + free(real_newpath); + + OSUnlockMutex(dev->pMutex); + + if(result < 0) { + r->_errno = result; + return -1; + } + + return 0; + +} + +static int fs_dev_mkdir_r (struct _reent *r, const char *path, int mode) +{ + fs_dev_private_t *dev = fs_dev_get_device_data(path); + if(!dev) { + r->_errno = ENODEV; + return -1; + } + + OSLockMutex(dev->pMutex); + + char *real_path = fs_dev_real_path(path, dev); + if(!real_path) { + r->_errno = ENOMEM; + OSUnlockMutex(dev->pMutex); + return -1; + } + + int result = IOSUHAX_FSA_MakeDir(dev->fsaFd, real_path, mode); + + free(real_path); + + OSUnlockMutex(dev->pMutex); + + if(result < 0) { + r->_errno = result; + return -1; + } + + return 0; +} + +static int fs_dev_chmod_r (struct _reent *r, const char *path, int mode) +{ + fs_dev_private_t *dev = fs_dev_get_device_data(path); + if(!dev) { + r->_errno = ENODEV; + return -1; + } + + OSLockMutex(dev->pMutex); + + char *real_path = fs_dev_real_path(path, dev); + if(!real_path) { + r->_errno = ENOMEM; + OSUnlockMutex(dev->pMutex); + return -1; + } + + int result = IOSUHAX_FSA_ChangeMode(dev->fsaFd, real_path, mode); + + free(real_path); + + OSUnlockMutex(dev->pMutex); + + if(result < 0) { + r->_errno = result; + return -1; + } + + return 0; +} + +static int fs_dev_statvfs_r (struct _reent *r, const char *path, struct statvfs *buf) +{ + fs_dev_private_t *dev = fs_dev_get_device_data(path); + if(!dev) { + r->_errno = ENODEV; + return -1; + } + + OSLockMutex(dev->pMutex); + + // Zero out the stat buffer + memset(buf, 0, sizeof(struct statvfs)); + + char *real_path = fs_dev_real_path(path, dev); + if(!real_path) { + r->_errno = ENOMEM; + OSUnlockMutex(dev->pMutex); + return -1; + } + + uint64_t size; + + int result = IOSUHAX_FSA_GetDeviceInfo(dev->fsaFd, real_path, 0x00, (uint32_t*)&size); + + free(real_path); + + if(result < 0) { + r->_errno = result; + OSUnlockMutex(dev->pMutex); + return -1; + } + + // File system block size + buf->f_bsize = 512; + + // Fundamental file system block size + buf->f_frsize = 512; + + // Total number of blocks on file system in units of f_frsize + buf->f_blocks = size >> 9; // this is unknown + + // Free blocks available for all and for non-privileged processes + buf->f_bfree = buf->f_bavail = size >> 9; + + // Number of inodes at this point in time + buf->f_files = 0xffffffff; + + // Free inodes available for all and for non-privileged processes + buf->f_ffree = 0xffffffff; + + // File system id + buf->f_fsid = (int)dev; + + // Bit mask of f_flag values. + buf->f_flag = 0; + + // Maximum length of filenames + buf->f_namemax = 255; + + OSUnlockMutex(dev->pMutex); + + return 0; +} + +static DIR_ITER *fs_dev_diropen_r (struct _reent *r, DIR_ITER *dirState, const char *path) +{ + fs_dev_private_t *dev = fs_dev_get_device_data(path); + if(!dev) { + r->_errno = ENODEV; + return NULL; + } + + fs_dev_dir_entry_t *dirIter = (fs_dev_dir_entry_t *)dirState->dirStruct; + + OSLockMutex(dev->pMutex); + + char *real_path = fs_dev_real_path(path, dev); + if(!real_path) { + r->_errno = ENOMEM; + OSUnlockMutex(dev->pMutex); + return NULL; + } + + int dirHandle; + + int result = IOSUHAX_FSA_OpenDir(dev->fsaFd, real_path, &dirHandle); + + free(real_path); + + OSUnlockMutex(dev->pMutex); + + if(result < 0) + { + r->_errno = result; + return NULL; + } + + dirIter->dev = dev; + dirIter->dirHandle = dirHandle; + + return dirState; +} + +static int fs_dev_dirclose_r (struct _reent *r, DIR_ITER *dirState) +{ + fs_dev_dir_entry_t *dirIter = (fs_dev_dir_entry_t *)dirState->dirStruct; + if(!dirIter->dev) { + r->_errno = ENODEV; + return -1; + } + + OSLockMutex(dirIter->dev->pMutex); + + int result = IOSUHAX_FSA_CloseDir(dirIter->dev->fsaFd, dirIter->dirHandle); + + OSUnlockMutex(dirIter->dev->pMutex); + + if(result < 0) + { + r->_errno = result; + return -1; + } + return 0; +} + +static int fs_dev_dirreset_r (struct _reent *r, DIR_ITER *dirState) +{ + fs_dev_dir_entry_t *dirIter = (fs_dev_dir_entry_t *)dirState->dirStruct; + if(!dirIter->dev) { + r->_errno = ENODEV; + return -1; + } + + OSLockMutex(dirIter->dev->pMutex); + + int result = IOSUHAX_FSA_RewindDir(dirIter->dev->fsaFd, dirIter->dirHandle); + + OSUnlockMutex(dirIter->dev->pMutex); + + if(result < 0) + { + r->_errno = result; + return -1; + } + return 0; +} + +static int fs_dev_dirnext_r (struct _reent *r, DIR_ITER *dirState, char *filename, struct stat *st) +{ + fs_dev_dir_entry_t *dirIter = (fs_dev_dir_entry_t *)dirState->dirStruct; + if(!dirIter->dev) { + r->_errno = ENODEV; + return -1; + } + + OSLockMutex(dirIter->dev->pMutex); + + directoryEntry_s * dir_entry = malloc(sizeof(directoryEntry_s)); + + int result = IOSUHAX_FSA_ReadDir(dirIter->dev->fsaFd, dirIter->dirHandle, dir_entry); + if(result < 0) + { + free(dir_entry); + r->_errno = result; + OSUnlockMutex(dirIter->dev->pMutex); + return -1; + } + + // Fetch the current entry + strcpy(filename, dir_entry->name); + + if(st) + { + memset(st, 0, sizeof(struct stat)); + st->st_mode = (dir_entry->stat.flag & 0x80000000) ? S_IFDIR : S_IFREG; + st->st_nlink = 1; + st->st_size = dir_entry->stat.size; + st->st_blocks = (dir_entry->stat.size + 511) >> 9; + st->st_dev = dir_entry->stat.id; + st->st_uid = dir_entry->stat.owner_id; + st->st_gid = dir_entry->stat.group_id; + st->st_ino = dir_entry->stat.id; + st->st_atime = dir_entry->stat.mtime; + st->st_ctime = dir_entry->stat.ctime; + st->st_mtime = dir_entry->stat.mtime; + } + + free(dir_entry); + OSUnlockMutex(dirIter->dev->pMutex); + return 0; +} + +// NTFS device driver devoptab +static const devoptab_t devops_fs = { + NULL, /* Device name */ + sizeof (fs_dev_file_state_t), + fs_dev_open_r, + fs_dev_close_r, + fs_dev_write_r, + fs_dev_read_r, + fs_dev_seek_r, + fs_dev_fstat_r, + fs_dev_stat_r, + fs_dev_link_r, + fs_dev_unlink_r, + fs_dev_chdir_r, + fs_dev_rename_r, + fs_dev_mkdir_r, + sizeof (fs_dev_dir_entry_t), + fs_dev_diropen_r, + fs_dev_dirreset_r, + fs_dev_dirnext_r, + fs_dev_dirclose_r, + fs_dev_statvfs_r, + fs_dev_ftruncate_r, + fs_dev_fsync_r, + fs_dev_chmod_r, + NULL, /* fs_dev_fchmod_r */ + NULL /* Device data */ +}; + +static int fs_dev_add_device (const char *name, const char *mount_path, int fsaFd, int isMounted) +{ + devoptab_t *dev = NULL; + char *devname = NULL; + char *devpath = NULL; + int i; + + // Sanity check + if (!name) { + errno = EINVAL; + return -1; + } + + // Allocate a devoptab for this device + dev = (devoptab_t *) malloc(sizeof(devoptab_t) + strlen(name) + 1); + if (!dev) { + errno = ENOMEM; + return -1; + } + + // Use the space allocated at the end of the devoptab for storing the device name + devname = (char*)(dev + 1); + strcpy(devname, name); + + // create private data + fs_dev_private_t *priv = (fs_dev_private_t *)malloc(sizeof(fs_dev_private_t) + strlen(mount_path) + 1); + if(!priv) { + free(dev); + errno = ENOMEM; + return -1; + } + + devpath = (char*)(priv+1); + strcpy(devpath, mount_path); + + // setup private data + priv->mount_path = devpath; + priv->fsaFd = fsaFd; + priv->mounted = isMounted; + priv->pMutex = malloc(OS_MUTEX_SIZE); + + if(!priv->pMutex) { + free(dev); + free(priv); + errno = ENOMEM; + return -1; + } + + OSInitMutex(priv->pMutex); + + // Setup the devoptab + memcpy(dev, &devops_fs, sizeof(devoptab_t)); + dev->name = devname; + dev->deviceData = priv; + + // Add the device to the devoptab table (if there is a free slot) + for (i = 3; i < STD_MAX; i++) { + if (devoptab_list[i] == devoptab_list[0]) { + devoptab_list[i] = dev; + return 0; + } + } + + // failure, free all memory + free(priv); + free(dev); + + // If we reach here then there are no free slots in the devoptab table for this device + errno = EADDRNOTAVAIL; + return -1; +} + +static int fs_dev_remove_device (const char *path) +{ + const devoptab_t *devoptab = NULL; + char name[128] = {0}; + int i; + + // Get the device name from the path + strncpy(name, path, 127); + strtok(name, ":/"); + + // Find and remove the specified device from the devoptab table + // NOTE: We do this manually due to a 'bug' in RemoveDevice + // which ignores names with suffixes and causes names + // like "ntfs" and "ntfs1" to be seen as equals + for (i = 3; i < STD_MAX; i++) { + devoptab = devoptab_list[i]; + if (devoptab && devoptab->name) { + if (strcmp(name, devoptab->name) == 0) { + devoptab_list[i] = devoptab_list[0]; + + if(devoptab->deviceData) + { + fs_dev_private_t *priv = (fs_dev_private_t *)devoptab->deviceData; + + if(priv->mounted) + IOSUHAX_FSA_Unmount(priv->fsaFd, priv->mount_path, 2); + + if(priv->pMutex) + free(priv->pMutex); + free(devoptab->deviceData); + } + + free((devoptab_t*)devoptab); + return 0; + } + } + } + + return -1; +} + +int mount_fs(const char *virt_name, int fsaFd, const char *dev_path, const char *mount_path) +{ + int isMounted = 0; + + if(dev_path) + { + isMounted = 1; + + int res = IOSUHAX_FSA_Mount(fsaFd, dev_path, mount_path, 2, 0, 0); + if(res != 0) + { + return res; + } + } + + return fs_dev_add_device(virt_name, mount_path, fsaFd, isMounted); +} + +int unmount_fs(const char *virt_name) +{ + return fs_dev_remove_device(virt_name); +} diff --git a/deps/libiosuhax/iosuhax_disc_interface.c b/deps/libiosuhax/source/iosuhax_disc_interface.c similarity index 92% rename from deps/libiosuhax/iosuhax_disc_interface.c rename to deps/libiosuhax/source/iosuhax_disc_interface.c index dd1291ec27..1160fc1924 100644 --- a/deps/libiosuhax/iosuhax_disc_interface.c +++ b/deps/libiosuhax/source/iosuhax_disc_interface.c @@ -1,262 +1,262 @@ -/*************************************************************************** - * Copyright (C) 2016 - * by Dimok - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any - * damages arising from the use of this software. - * - * Permission is granted to anyone to use this software for any - * purpose, including commercial applications, and to alter it and - * redistribute it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you - * must not claim that you wrote the original software. If you use - * this software in a product, an acknowledgment in the product - * documentation would be appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and - * must not be misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source - * distribution. - ***************************************************************************/ -#include -#include -#include "iosuhax.h" -#include "iosuhax_disc_interface.h" - -#define FSA_REF_SD 0x01 -#define FSA_REF_USB 0x02 - -static int initialized = 0; - -static int fsaFdSd = 0; -static int fsaFdUsb = 0; -static int sdioFd = 0; -static int usbFd = 0; - -static void IOSUHAX_disc_io_initialize(void) -{ - if(initialized == 0) - { - initialized = 1; - fsaFdSd = -1; - fsaFdUsb = -1; - sdioFd = -1; - usbFd = -1; - } -} - -static bool IOSUHAX_disc_io_fsa_open(int fsaFd) -{ - IOSUHAX_disc_io_initialize(); - - if(IOSUHAX_Open(NULL) < 0) - return false; - - if(fsaFd == FSA_REF_SD) - { - if(fsaFdSd < 0) - { - fsaFdSd = IOSUHAX_FSA_Open(); - } - - if(fsaFdSd >= 0) - return true; - } - else if(fsaFd == FSA_REF_USB) - { - if(fsaFdUsb < 0) - { - fsaFdUsb = IOSUHAX_FSA_Open(); - } - - if(fsaFdUsb >= 0) - return true; - } - - return false; -} - -static void IOSUHAX_disc_io_fsa_close(int fsaFd) -{ - if(fsaFd == FSA_REF_SD) - { - if(fsaFdSd >= 0) - { - IOSUHAX_FSA_Close(fsaFdSd); - fsaFdSd = -1; - } - } - else if(fsaFd == FSA_REF_USB) - { - if(fsaFdUsb >= 0) - { - IOSUHAX_FSA_Close(fsaFdUsb); - fsaFdUsb = -1; - } - } -} - -static bool IOSUHAX_sdio_startup(void) -{ - if(!IOSUHAX_disc_io_fsa_open(FSA_REF_SD)) - return false; - - if(sdioFd < 0) - { - int res = IOSUHAX_FSA_RawOpen(fsaFdSd, "/dev/sdcard01", &sdioFd); - if(res < 0) - { - IOSUHAX_disc_io_fsa_close(FSA_REF_SD); - sdioFd = -1; - } - } - - return (sdioFd >= 0); -} - -static bool IOSUHAX_sdio_isInserted(void) -{ - //! TODO: check for SD card inserted with IOSUHAX_FSA_GetDeviceInfo() - return initialized && (fsaFdSd >= 0) && (sdioFd >= 0); -} - -static bool IOSUHAX_sdio_clearStatus(void) -{ - return true; -} - -static bool IOSUHAX_sdio_shutdown(void) -{ - if(!IOSUHAX_sdio_isInserted()) - return false; - - IOSUHAX_FSA_RawClose(fsaFdSd, sdioFd); - IOSUHAX_disc_io_fsa_close(FSA_REF_SD); - sdioFd = -1; - return true; -} - -static bool IOSUHAX_sdio_readSectors(uint32_t sector, uint32_t numSectors, void* buffer) -{ - if(!IOSUHAX_sdio_isInserted() || !buffer) - return false; - - int res = IOSUHAX_FSA_RawRead(fsaFdSd, buffer, 512, numSectors, sector, sdioFd); - if(res < 0) - { - return false; - } - - return true; -} - -static bool IOSUHAX_sdio_writeSectors(uint32_t sector, uint32_t numSectors, const void* buffer) -{ - if(!IOSUHAX_sdio_isInserted() || !buffer) - return false; - - int res = IOSUHAX_FSA_RawWrite(fsaFdSd, buffer, 512, numSectors, sector, sdioFd); - if(res < 0) - { - return false; - } - - return true; -} - -const DISC_INTERFACE IOSUHAX_sdio_disc_interface = -{ - DEVICE_TYPE_WII_U_SD, - FEATURE_MEDIUM_CANREAD | FEATURE_MEDIUM_CANWRITE | FEATURE_WII_U_SD, - IOSUHAX_sdio_startup, - IOSUHAX_sdio_isInserted, - IOSUHAX_sdio_readSectors, - IOSUHAX_sdio_writeSectors, - IOSUHAX_sdio_clearStatus, - IOSUHAX_sdio_shutdown -}; - -static bool IOSUHAX_usb_startup(void) -{ - if(!IOSUHAX_disc_io_fsa_open(FSA_REF_USB)) - return false; - - if(usbFd < 0) - { - int res = IOSUHAX_FSA_RawOpen(fsaFdUsb, "/dev/usb01", &usbFd); - if(res < 0) - { - res = IOSUHAX_FSA_RawOpen(fsaFdUsb, "/dev/usb02", &usbFd); - if(res < 0) - { - IOSUHAX_disc_io_fsa_close(FSA_REF_USB); - usbFd = -1; - } - } - } - return (usbFd >= 0); -} - -static bool IOSUHAX_usb_isInserted(void) -{ - return initialized && (fsaFdUsb >= 0) && (usbFd >= 0); -} - -static bool IOSUHAX_usb_clearStatus(void) -{ - return true; -} - -static bool IOSUHAX_usb_shutdown(void) -{ - if(!IOSUHAX_usb_isInserted()) - return false; - - IOSUHAX_FSA_RawClose(fsaFdUsb, usbFd); - IOSUHAX_disc_io_fsa_close(FSA_REF_USB); - usbFd = -1; - return true; -} - -static bool IOSUHAX_usb_readSectors(uint32_t sector, uint32_t numSectors, void* buffer) -{ - if(!IOSUHAX_usb_isInserted() || !buffer) - return false; - - int res = IOSUHAX_FSA_RawRead(fsaFdUsb, buffer, 512, numSectors, sector, usbFd); - if(res < 0) - { - return false; - } - - return true; -} - -static bool IOSUHAX_usb_writeSectors(uint32_t sector, uint32_t numSectors, const void* buffer) -{ - if(!IOSUHAX_usb_isInserted() || !buffer) - return false; - - int res = IOSUHAX_FSA_RawWrite(fsaFdUsb, buffer, 512, numSectors, sector, usbFd); - if(res < 0) - { - return false; - } - - return true; -} - -const DISC_INTERFACE IOSUHAX_usb_disc_interface = -{ - DEVICE_TYPE_WII_U_USB, - FEATURE_MEDIUM_CANREAD | FEATURE_MEDIUM_CANWRITE | FEATURE_WII_U_USB, - IOSUHAX_usb_startup, - IOSUHAX_usb_isInserted, - IOSUHAX_usb_readSectors, - IOSUHAX_usb_writeSectors, - IOSUHAX_usb_clearStatus, - IOSUHAX_usb_shutdown -}; +/*************************************************************************** + * Copyright (C) 2016 + * by Dimok + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any + * damages arising from the use of this software. + * + * Permission is granted to anyone to use this software for any + * purpose, including commercial applications, and to alter it and + * redistribute it freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you + * must not claim that you wrote the original software. If you use + * this software in a product, an acknowledgment in the product + * documentation would be appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and + * must not be misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. + ***************************************************************************/ +#include +#include +#include "iosuhax.h" +#include "iosuhax_disc_interface.h" + +#define FSA_REF_SD 0x01 +#define FSA_REF_USB 0x02 + +static int initialized = 0; + +static int fsaFdSd = 0; +static int fsaFdUsb = 0; +static int sdioFd = 0; +static int usbFd = 0; + +static void IOSUHAX_disc_io_initialize(void) +{ + if(initialized == 0) + { + initialized = 1; + fsaFdSd = -1; + fsaFdUsb = -1; + sdioFd = -1; + usbFd = -1; + } +} + +static bool IOSUHAX_disc_io_fsa_open(int fsaFd) +{ + IOSUHAX_disc_io_initialize(); + + if(IOSUHAX_Open(NULL) < 0) + return false; + + if(fsaFd == FSA_REF_SD) + { + if(fsaFdSd < 0) + { + fsaFdSd = IOSUHAX_FSA_Open(); + } + + if(fsaFdSd >= 0) + return true; + } + else if(fsaFd == FSA_REF_USB) + { + if(fsaFdUsb < 0) + { + fsaFdUsb = IOSUHAX_FSA_Open(); + } + + if(fsaFdUsb >= 0) + return true; + } + + return false; +} + +static void IOSUHAX_disc_io_fsa_close(int fsaFd) +{ + if(fsaFd == FSA_REF_SD) + { + if(fsaFdSd >= 0) + { + IOSUHAX_FSA_Close(fsaFdSd); + fsaFdSd = -1; + } + } + else if(fsaFd == FSA_REF_USB) + { + if(fsaFdUsb >= 0) + { + IOSUHAX_FSA_Close(fsaFdUsb); + fsaFdUsb = -1; + } + } +} + +static bool IOSUHAX_sdio_startup(void) +{ + if(!IOSUHAX_disc_io_fsa_open(FSA_REF_SD)) + return false; + + if(sdioFd < 0) + { + int res = IOSUHAX_FSA_RawOpen(fsaFdSd, "/dev/sdcard01", &sdioFd); + if(res < 0) + { + IOSUHAX_disc_io_fsa_close(FSA_REF_SD); + sdioFd = -1; + } + } + + return (sdioFd >= 0); +} + +static bool IOSUHAX_sdio_isInserted(void) +{ + //! TODO: check for SD card inserted with IOSUHAX_FSA_GetDeviceInfo() + return initialized && (fsaFdSd >= 0) && (sdioFd >= 0); +} + +static bool IOSUHAX_sdio_clearStatus(void) +{ + return true; +} + +static bool IOSUHAX_sdio_shutdown(void) +{ + if(!IOSUHAX_sdio_isInserted()) + return false; + + IOSUHAX_FSA_RawClose(fsaFdSd, sdioFd); + IOSUHAX_disc_io_fsa_close(FSA_REF_SD); + sdioFd = -1; + return true; +} + +static bool IOSUHAX_sdio_readSectors(uint32_t sector, uint32_t numSectors, void* buffer) +{ + if(!IOSUHAX_sdio_isInserted()) + return false; + + int res = IOSUHAX_FSA_RawRead(fsaFdSd, buffer, 512, numSectors, sector, sdioFd); + if(res < 0) + { + return false; + } + + return true; +} + +static bool IOSUHAX_sdio_writeSectors(uint32_t sector, uint32_t numSectors, const void* buffer) +{ + if(!IOSUHAX_sdio_isInserted()) + return false; + + int res = IOSUHAX_FSA_RawWrite(fsaFdSd, buffer, 512, numSectors, sector, sdioFd); + if(res < 0) + { + return false; + } + + return true; +} + +const DISC_INTERFACE IOSUHAX_sdio_disc_interface = +{ + DEVICE_TYPE_WII_U_SD, + FEATURE_MEDIUM_CANREAD | FEATURE_MEDIUM_CANWRITE | FEATURE_WII_U_SD, + IOSUHAX_sdio_startup, + IOSUHAX_sdio_isInserted, + IOSUHAX_sdio_readSectors, + IOSUHAX_sdio_writeSectors, + IOSUHAX_sdio_clearStatus, + IOSUHAX_sdio_shutdown +}; + +static bool IOSUHAX_usb_startup(void) +{ + if(!IOSUHAX_disc_io_fsa_open(FSA_REF_USB)) + return false; + + if(usbFd < 0) + { + int res = IOSUHAX_FSA_RawOpen(fsaFdUsb, "/dev/usb01", &usbFd); + if(res < 0) + { + res = IOSUHAX_FSA_RawOpen(fsaFdUsb, "/dev/usb02", &usbFd); + if(res < 0) + { + IOSUHAX_disc_io_fsa_close(FSA_REF_USB); + usbFd = -1; + } + } + } + return (usbFd >= 0); +} + +static bool IOSUHAX_usb_isInserted(void) +{ + return initialized && (fsaFdUsb >= 0) && (usbFd >= 0); +} + +static bool IOSUHAX_usb_clearStatus(void) +{ + return true; +} + +static bool IOSUHAX_usb_shutdown(void) +{ + if(!IOSUHAX_usb_isInserted()) + return false; + + IOSUHAX_FSA_RawClose(fsaFdUsb, usbFd); + IOSUHAX_disc_io_fsa_close(FSA_REF_USB); + usbFd = -1; + return true; +} + +static bool IOSUHAX_usb_readSectors(uint32_t sector, uint32_t numSectors, void* buffer) +{ + if(!IOSUHAX_usb_isInserted()) + return false; + + int res = IOSUHAX_FSA_RawRead(fsaFdUsb, buffer, 512, numSectors, sector, usbFd); + if(res < 0) + { + return false; + } + + return true; +} + +static bool IOSUHAX_usb_writeSectors(uint32_t sector, uint32_t numSectors, const void* buffer) +{ + if(!IOSUHAX_usb_isInserted()) + return false; + + int res = IOSUHAX_FSA_RawWrite(fsaFdUsb, buffer, 512, numSectors, sector, usbFd); + if(res < 0) + { + return false; + } + + return true; +} + +const DISC_INTERFACE IOSUHAX_usb_disc_interface = +{ + DEVICE_TYPE_WII_U_USB, + FEATURE_MEDIUM_CANREAD | FEATURE_MEDIUM_CANWRITE | FEATURE_WII_U_USB, + IOSUHAX_usb_startup, + IOSUHAX_usb_isInserted, + IOSUHAX_usb_readSectors, + IOSUHAX_usb_writeSectors, + IOSUHAX_usb_clearStatus, + IOSUHAX_usb_shutdown +}; diff --git a/deps/libiosuhax/source/os_functions.h b/deps/libiosuhax/source/os_functions.h new file mode 100644 index 0000000000..a9d9d00317 --- /dev/null +++ b/deps/libiosuhax/source/os_functions.h @@ -0,0 +1,28 @@ +#ifndef __OS_FUNCTIONS_H_ +#define __OS_FUNCTIONS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#define OS_MUTEX_SIZE 44 + +//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//! Mutex functions +//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +extern void OSInitMutex(void* mutex); +extern void OSLockMutex(void* mutex); +extern void OSUnlockMutex(void* mutex); + +//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//! IOS function +//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +extern int IOS_Ioctl(int fd, unsigned int request, void *input_buffer,unsigned int input_buffer_len, void *output_buffer, unsigned int output_buffer_len); +extern int IOS_Open(char *path, unsigned int mode); +extern int IOS_Close(int fd); + +#ifdef __cplusplus +} +#endif + +#endif // __OS_FUNCTIONS_H_ diff --git a/griffin/griffin.c b/griffin/griffin.c index a187296e3b..0b880cba5c 100644 --- a/griffin/griffin.c +++ b/griffin/griffin.c @@ -1515,9 +1515,9 @@ DEPENDENCIES #endif #ifdef WANT_IOSUHAX -#include "../deps/libiosuhax/iosuhax.c" -#include "../deps/libiosuhax/iosuhax_devoptab.c" -#include "../deps/libiosuhax/iosuhax_disc_interface.c" +#include "../deps/libiosuhax/source/iosuhax.c" +#include "../deps/libiosuhax/source/iosuhax_devoptab.c" +#include "../deps/libiosuhax/source/iosuhax_disc_interface.c" #endif /*============================================================ From 90040117afadf0d9fb69d4f68e09c175c6e374d4 Mon Sep 17 00:00:00 2001 From: Ash Logan Date: Sun, 18 Jul 2021 21:39:49 +1000 Subject: [PATCH 42/58] deps/libfat: Increase cache size on Wii U We got lotsa RAM! See https://github.com/aliaspider/wiiu/blob/5be1be8e66c60a6c7ffd3bb47bbd2a72077b3f12/libfat/common.h#L62-L66 --- deps/libfat/common.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deps/libfat/common.h b/deps/libfat/common.h index b38889ee5f..66ca7bf77e 100644 --- a/deps/libfat/common.h +++ b/deps/libfat/common.h @@ -63,8 +63,8 @@ /* Platform specific options */ #if defined (__wiiu__) - #define DEFAULT_CACHE_PAGES 4 - #define DEFAULT_SECTORS_PAGE 64 + #define DEFAULT_CACHE_PAGES 512 + #define DEFAULT_SECTORS_PAGE 128 #if 0 #define USE_LWP_LOCK #define USE_RTC_TIME From a3be19214ee7ab8faf95aba148518c1d2aa13bb1 Mon Sep 17 00:00:00 2001 From: Ash Logan Date: Sun, 18 Jul 2021 21:54:11 +1000 Subject: [PATCH 43/58] vfs: Use 128k vbufs for Wii U We have loads of RAM and large vbufs are *very* beneficial --- libretro-common/vfs/vfs_implementation.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/libretro-common/vfs/vfs_implementation.c b/libretro-common/vfs/vfs_implementation.c index 4ad9dbd200..dd7e466b5e 100644 --- a/libretro-common/vfs/vfs_implementation.c +++ b/libretro-common/vfs/vfs_implementation.c @@ -62,6 +62,9 @@ # include # include # endif +# if defined(WIIU) +# include +# endif #endif #include @@ -447,6 +450,14 @@ libretro_vfs_implementation_file *retro_vfs_file_open_impl( if (stream->fp) setvbuf(stream->fp, stream->buf, _IOFBF, 0x10000); } +#elif defined(WIIU) + if (stream->scheme != VFS_SCHEME_CDROM) + { + const int bufsize = 128*1024; + stream->buf = (char*)memalign(0x40, bufsize); + if (stream->fp) + setvbuf(stream->fp, stream->buf, _IOFBF, bufsize); + } #elif !defined(PSP) if (stream->scheme != VFS_SCHEME_CDROM) { From e43f07b85b6017df5b38363c3743ffdd48808083 Mon Sep 17 00:00:00 2001 From: Ash Logan Date: Sun, 18 Jul 2021 22:31:43 +1000 Subject: [PATCH 44/58] wiiu: Add fastpath for already aligned buffers --- libretro-common/file/nbio/nbio_stdio.c | 9 ++ wiiu/fs/sd_fat_devoptab.c | 151 ++++++++++++++----------- 2 files changed, 95 insertions(+), 65 deletions(-) diff --git a/libretro-common/file/nbio/nbio_stdio.c b/libretro-common/file/nbio/nbio_stdio.c index 328e32aedb..e05968b6fa 100644 --- a/libretro-common/file/nbio/nbio_stdio.c +++ b/libretro-common/file/nbio/nbio_stdio.c @@ -22,6 +22,9 @@ #include #include +#if defined(WIIU) +#include +#endif #include #include @@ -130,8 +133,14 @@ static void *nbio_stdio_open(const char * filename, unsigned mode) handle->mode = mode; +#if defined(WIIU) + /* hit the aligned-buffer fast path on Wii U */ + if (len) + buf = memalign(0x40, (size_t)len); +#else if (len) buf = malloc((size_t)len); +#endif if (len && !buf) goto error; diff --git a/wiiu/fs/sd_fat_devoptab.c b/wiiu/fs/sd_fat_devoptab.c index a179d10134..f9b6608bac 100644 --- a/wiiu/fs/sd_fat_devoptab.c +++ b/wiiu/fs/sd_fat_devoptab.c @@ -279,47 +279,56 @@ static ssize_t sd_fat_write_r (struct _reent *r, void* fd, const char *ptr, size OSLockMutex(file->dev->pMutex); - size_t len_aligned = FS_ALIGN(len); - if(len_aligned > 0x4000) - len_aligned = 0x4000; - - unsigned char *tmpBuf = (unsigned char *)memalign(FS_ALIGNMENT, len_aligned); - if(!tmpBuf) { - r->_errno = ENOMEM; - OSUnlockMutex(file->dev->pMutex); - return 0; - } - size_t done = 0; - while(done < len) - { - size_t write_size = (len_aligned < (len - done)) ? len_aligned : (len - done); - memcpy(tmpBuf, ptr + done, write_size); - - int result = FSWriteFile(file->dev->pClient, file->dev->pCmd, tmpBuf, 0x01, write_size, file->fd, 0, -1); -#if 0 - FSFlushFile(file->dev->pClient, file->dev->pCmd, file->fd, -1); -#endif - if(result < 0) - { + /* fast path: buffer is already correctly aligned */ + if (!((uintptr_t)ptr & (FS_ALIGNMENT-1))) { + int result = FSWriteFile(file->dev->pClient, file->dev->pCmd, (uint8_t*)ptr, 1, len, file->fd, 0, -1); + if(result < 0) { r->_errno = result; - break; - } - else if(result == 0) - { - if(write_size > 0) - done = 0; - break; - } - else - { - done += result; + } else { + done = result; file->pos += result; } + } else { + size_t len_aligned = FS_ALIGN(len); + if(len_aligned > 0x4000) + len_aligned = 0x4000; + + unsigned char *tmpBuf = (unsigned char *)memalign(FS_ALIGNMENT, len_aligned); + if(!tmpBuf) { + r->_errno = ENOMEM; + OSUnlockMutex(file->dev->pMutex); + return 0; + } + + while(done < len) + { + size_t write_size = (len_aligned < (len - done)) ? len_aligned : (len - done); + memcpy(tmpBuf, ptr + done, write_size); + + int result = FSWriteFile(file->dev->pClient, file->dev->pCmd, tmpBuf, 0x01, write_size, file->fd, 0, -1); + if(result < 0) + { + r->_errno = result; + break; + } + else if(result == 0) + { + if(write_size > 0) + done = 0; + break; + } + else + { + done += result; + file->pos += result; + } + } + + free(tmpBuf); } - free(tmpBuf); OSUnlockMutex(file->dev->pMutex); return done; } @@ -340,44 +349,56 @@ static ssize_t sd_fat_read_r (struct _reent *r, void* fd, char *ptr, size_t len) OSLockMutex(file->dev->pMutex); - size_t len_aligned = FS_ALIGN(len); - if(len_aligned > 0x4000) - len_aligned = 0x4000; - - unsigned char *tmpBuf = (unsigned char *)memalign(FS_ALIGNMENT, len_aligned); - if(!tmpBuf) { - r->_errno = ENOMEM; - OSUnlockMutex(file->dev->pMutex); - return 0; - } - size_t done = 0; - while(done < len) - { - size_t read_size = (len_aligned < (len - done)) ? len_aligned : (len - done); - - int result = FSReadFile(file->dev->pClient, file->dev->pCmd, tmpBuf, 0x01, read_size, file->fd, 0, -1); - if(result < 0) - { + /* fast path: buffer is already correctly aligned */ + if (!((uintptr_t)ptr & (FS_ALIGNMENT-1))) { + int result = FSReadFile(file->dev->pClient, file->dev->pCmd, (uint8_t*)ptr, 1, len, file->fd, 0, -1); + if(result < 0) { r->_errno = result; - done = 0; - break; - } - else if(result == 0) - { - /*! TODO: error on read_size > 0 */ - break; - } - else - { - memcpy(ptr + done, tmpBuf, read_size); - done += result; + } else { + done = result; file->pos += result; } + } else { + size_t len_aligned = FS_ALIGN(len); + if(len_aligned > 0x4000) + len_aligned = 0x4000; + + unsigned char *tmpBuf = (unsigned char *)memalign(FS_ALIGNMENT, len_aligned); + if(!tmpBuf) { + r->_errno = ENOMEM; + OSUnlockMutex(file->dev->pMutex); + return 0; + } + + while(done < len) + { + size_t read_size = (len_aligned < (len - done)) ? len_aligned : (len - done); + + int result = FSReadFile(file->dev->pClient, file->dev->pCmd, tmpBuf, 0x01, read_size, file->fd, 0, -1); + if(result < 0) + { + r->_errno = result; + done = 0; + break; + } + else if(result == 0) + { + /*! TODO: error on read_size > 0 */ + break; + } + else + { + memcpy(ptr + done, tmpBuf, read_size); + done += result; + file->pos += result; + } + } + + free(tmpBuf); } - free(tmpBuf); OSUnlockMutex(file->dev->pMutex); return done; } From fcefefaeab74ff8ff89dfc5ca37f698281242438 Mon Sep 17 00:00:00 2001 From: gouchi Date: Sun, 18 Jul 2021 22:40:01 +0200 Subject: [PATCH 45/58] intl: Add missing languages for the first startup --- retroarch.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/retroarch.c b/retroarch.c index 417fc84930..14b126adef 100644 --- a/retroarch.c +++ b/retroarch.c @@ -39375,6 +39375,12 @@ enum retro_language rarch_get_language_from_iso(const char *iso639) {"vi", RETRO_LANGUAGE_VIETNAMESE}, {"ar", RETRO_LANGUAGE_ARABIC}, {"el", RETRO_LANGUAGE_GREEK}, + {"tr", RETRO_LANGUAGE_TURKISH}, + {"sk", RETRO_LANGUAGE_SLOVAK}, + {"fa", RETRO_LANGUAGE_PERSIAN}, + {"he", RETRO_LANGUAGE_HEBREW}, + {"ast", RETRO_LANGUAGE_ASTURIAN}, + {"fi", RETRO_LANGUAGE_FINNISH}, }; if (string_is_empty(iso639)) From 27b02d66aa875b7a0d9f37450fed4d3dea35b8bf Mon Sep 17 00:00:00 2001 From: Ash Logan Date: Mon, 19 Jul 2021 16:59:41 +1000 Subject: [PATCH 46/58] (Wii U) Ignore some bogus KPAD results This API is completely bonkers, seems to have no idea what the error conditions are --- input/drivers_joypad/wiiu/kpad_driver.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/input/drivers_joypad/wiiu/kpad_driver.c b/input/drivers_joypad/wiiu/kpad_driver.c index 2d7a36a4f4..0466975b5f 100644 --- a/input/drivers_joypad/wiiu/kpad_driver.c +++ b/input/drivers_joypad/wiiu/kpad_driver.c @@ -251,6 +251,12 @@ static void kpad_poll(void) } poll_failures[channel] = 0; + /* Several reads when a device is connected or an attachment added give */ + /* bogus results, try to weed them out */ + if (kpad.wpad_error || kpad.device_type == 255) { + continue; + } + kpad_poll_one_channel(channel, &kpad); } } From af88aaee778deb3afa4e489a8f8602e0a670c375 Mon Sep 17 00:00:00 2001 From: jdgleaver Date: Mon, 19 Jul 2021 14:15:28 +0100 Subject: [PATCH 47/58] (RGUI) Enable fullscreen thumbnail toggle using RetroPad 'start' button --- menu/drivers/rgui.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/menu/drivers/rgui.c b/menu/drivers/rgui.c index fe76981ac2..519f17eed4 100644 --- a/menu/drivers/rgui.c +++ b/menu/drivers/rgui.c @@ -6242,7 +6242,7 @@ static void rgui_toggle_fs_thumbnail(void *userdata) } /* Note that we always load thumbnails immediately - * when toggling via the 'scan' button (scheduling a + * when toggling via a RetroPad button (scheduling a * delayed load here would make for a poor user * experience...) */ rgui_scan_selected_entry_thumbnail(rgui, true); @@ -6944,8 +6944,22 @@ static enum menu_action rgui_parse_menu_entry_action( } break; case MENU_ACTION_SCAN: - /* If this is a playlist, 'scan' command is - * used to toggle fullscreen thumbnail view */ + case MENU_ACTION_START: + /* If this is a playlist, both the 'scan' + * command and 'start' action are used to + * toggle the fullscreen thumbnail view + * > 'scan' is more ergonomic, which is a + * benefit for RGUI because its low + * resolution framebuffer means fullscreen + * thumbnails are likely to be viewed far + * more often than with other menu drivers + * > 'start' is the regular toggle button + * for all other menu drivers, and is + * included as a fallback here for users + * with gamepads with limited numbers of + * face buttons (e.g. a NES-style pad + * does not possess a RetroPad Y/'scan' + * button) */ if (rgui->is_playlist) { rgui_toggle_fs_thumbnail(rgui); From e306dd8eeb97707f334ce3206d01dd5b02dde76a Mon Sep 17 00:00:00 2001 From: jdgleaver Date: Mon, 19 Jul 2021 16:37:07 +0100 Subject: [PATCH 48/58] Automatically disable core info cache when core info directory is read-only --- core_info.c | 22 +++++++++++++++------- core_info.h | 3 ++- intl/msg_hash_us.h | 4 ++++ menu/menu_setting.c | 20 ++++++++++++++++++-- msg_hash.h | 1 + retroarch.c | 17 +++++++++++++++-- 6 files changed, 55 insertions(+), 12 deletions(-) diff --git a/core_info.c b/core_info.c index 69075fe98f..ea2ab05201 100644 --- a/core_info.c +++ b/core_info.c @@ -732,17 +732,18 @@ end: return core_info_cache_list; } -static void core_info_cache_write(core_info_cache_list_t *list, const char *info_dir) +static bool core_info_cache_write(core_info_cache_list_t *list, const char *info_dir) { intfstream_t *file = NULL; rjsonwriter_t *writer = NULL; + bool success = false; char file_path[PATH_MAX_LENGTH]; size_t i, j; file_path[0] = '\0'; if (!list) - return; + return false; /* Open info cache file */ if (string_is_empty(info_dir)) @@ -763,7 +764,7 @@ static void core_info_cache_write(core_info_cache_list_t *list, const char *info if (!file) { RARCH_ERR("[Core Info] Failed to write to core info cache file: %s\n", file_path); - return; + return false; } /* Write info cache */ @@ -1068,6 +1069,7 @@ static void core_info_cache_write(core_info_cache_list_t *list, const char *info rjsonwriter_free(writer); RARCH_LOG("[Core Info] Wrote to cache file: %s\n", file_path); + success = true; /* Remove 'force refresh' file, if required */ file_path[0] = '\0'; @@ -1086,6 +1088,7 @@ end: free(file); list->refresh = false; + return success; } static void core_info_check_uninstalled(core_info_cache_list_t *list) @@ -1774,7 +1777,8 @@ static core_info_list_t *core_info_list_new(const char *path, const char *libretro_info_dir, const char *exts, bool dir_show_hidden_files, - bool enable_cache) + bool enable_cache, + bool *cache_supported) { size_t i; core_path_list_t *path_list = NULL; @@ -1906,12 +1910,14 @@ static core_info_list_t *core_info_list_new(const char *path, * a refresh) * > Write new cache to disk if updates are * required */ + *cache_supported = true; if (core_info_cache_list) { core_info_check_uninstalled(core_info_cache_list); if (core_info_cache_list->refresh) - core_info_cache_write(core_info_cache_list, info_dir); + *cache_supported = core_info_cache_write( + core_info_cache_list, info_dir); core_info_cache_list_free(core_info_cache_list); } @@ -2104,14 +2110,16 @@ void core_info_deinit_list(void) } bool core_info_init_list(const char *path_info, const char *dir_cores, - const char *exts, bool dir_show_hidden_files, bool enable_cache) + const char *exts, bool dir_show_hidden_files, + bool enable_cache, bool *cache_supported) { core_info_state_t *p_coreinfo = coreinfo_get_ptr(); if (!(p_coreinfo->curr_list = core_info_list_new(dir_cores, !string_is_empty(path_info) ? path_info : dir_cores, exts, dir_show_hidden_files, - enable_cache))) + enable_cache, + cache_supported))) return false; return true; } diff --git a/core_info.h b/core_info.h index 7cb286abff..ae9a7f28ab 100644 --- a/core_info.h +++ b/core_info.h @@ -157,7 +157,8 @@ bool core_info_get_current_core(core_info_t **core); void core_info_deinit_list(void); bool core_info_init_list(const char *path_info, const char *dir_cores, - const char *exts, bool show_hidden_files, bool enable_cache); + const char *exts, bool show_hidden_files, + bool enable_cache, bool *cache_supported); bool core_info_get_list(core_info_list_t **core); diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index c36435fc05..dc77aff722 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -12034,6 +12034,10 @@ MSG_HASH( MSG_UNSUPPORTED_VIDEO_MODE, "Unsupported video mode" ) +MSG_HASH( + MSG_CORE_INFO_CACHE_UNSUPPORTED, + "Cannot write to core info directory - core info cache will be disabled" + ) /* Lakka */ diff --git a/menu/menu_setting.c b/menu/menu_setting.c index d65711c726..bc50449ed5 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -7959,8 +7959,24 @@ static void general_write_handler(rarch_setting_t *setting) * force a cache refresh on the next * core info initialisation */ if (*setting->value.target.boolean) - core_info_cache_force_refresh(!string_is_empty(path_libretro_info) ? - path_libretro_info : dir_libretro); + if (!core_info_cache_force_refresh(!string_is_empty(path_libretro_info) ? + path_libretro_info : dir_libretro)) + { + /* core_info_cache_force_refresh() will fail + * if we cannot write to the the core_info + * directory. This will typically only happen + * on platforms where the core_info directory + * is explicitly (and intentionally) placed on + * read-only storage. In this case, core info + * caching cannot function correctly anyway, + * so we simply force-disable the feature */ + configuration_set_bool(settings, + settings->bools.core_info_cache_enable, false); + runloop_msg_queue_push( + msg_hash_to_str(MSG_CORE_INFO_CACHE_UNSUPPORTED), + 1, 100, true, + NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); + } } break; default: diff --git a/msg_hash.h b/msg_hash.h index 7ae1857157..0f9f8c35df 100644 --- a/msg_hash.h +++ b/msg_hash.h @@ -491,6 +491,7 @@ enum msg_hash_enums MSG_LOCALAP_ERROR_CONFIG_PARSE, #endif MSG_UNSUPPORTED_VIDEO_MODE, + MSG_CORE_INFO_CACHE_UNSUPPORTED, MENU_LABEL(MENU_XMB_ANIMATION_HORIZONTAL_HIGHLIGHT), MENU_LABEL(MENU_XMB_ANIMATION_MOVE_UP_DOWN), diff --git a/retroarch.c b/retroarch.c index 14b126adef..15c67eeb77 100644 --- a/retroarch.c +++ b/retroarch.c @@ -14296,12 +14296,25 @@ bool command_event(enum event_command cmd, void *data) return false; if (!string_is_empty(dir_libretro)) + { + bool cache_supported = false; + core_info_init_list(path_libretro_info, dir_libretro, ext_name, show_hidden_files, - core_info_cache_enable - ); + core_info_cache_enable, + &cache_supported); + + /* If core info cache is enabled but cache + * functionality is unsupported (i.e. because + * the core info directory is on read-only + * storage), force-disable the setting to + * avoid repeated failures */ + if (core_info_cache_enable && !cache_supported) + configuration_set_bool(settings, + settings->bools.core_info_cache_enable, false); + } } break; case CMD_EVENT_CORE_DEINIT: From 8038d899d6b7786a0e6f5ef1894cd5fa2ea1e9e8 Mon Sep 17 00:00:00 2001 From: "Mark W. Kidd" Date: Sat, 17 Jul 2021 13:32:03 -0400 Subject: [PATCH 49/58] add documentation to input_driver.h --- input/input_driver.h | 824 ++++++++++++++++++++++++++----------------- 1 file changed, 504 insertions(+), 320 deletions(-) diff --git a/input/input_driver.h b/input/input_driver.h index bf14c4629e..180dfffa69 100644 --- a/input/input_driver.h +++ b/input/input_driver.h @@ -26,7 +26,7 @@ #ifdef HAVE_CONFIG_H #include "config.h" -#endif +#endif /* HAVE_CONFIG_H */ #include #include @@ -45,35 +45,55 @@ RETRO_BEGIN_DECLS struct retro_keybind { + /** + * Human-readable label for the control. + */ char *joykey_label; + + /** + * Human-readable label for an analog axis. + */ char *joyaxis_label; - /* Joypad axis. Negative and positive axes - * are embedded into this variable. */ + /** + * Joypad axis. Negative and positive axes are both represented by this variable. + */ uint32_t joyaxis; - /* Default joy axis binding value - - * for resetting bind to default */ + /** + * Default joy axis binding value for resetting bind to default. + */ uint32_t def_joyaxis; - /* Used by input_{push,pop}_analog_dpad(). */ + /** + * Used by input_{push,pop}_analog_dpad(). + */ uint32_t orig_joyaxis; enum msg_hash_enums enum_idx; + enum retro_key key; uint16_t id; - uint16_t mbutton; /* mouse button ID */ + /** + * What mouse button ID has been mapped to this control. + */ + uint16_t mbutton; - /* Joypad key. Joypad POV (hats) - * are embedded into this key as well. */ + /** + * Joypad key. Joypad POV (hats) are embedded into this key as well. + **/ uint16_t joykey; - /* Default key binding value - - * for resetting bind to default */ + /** + * Default key binding value (for resetting bind). + */ uint16_t def_joykey; + /** + * Determines whether or not the binding is valid. + */ bool valid; }; @@ -101,10 +121,10 @@ typedef struct } input_device_info_t; /** - * input_driver: * Organizes the functions and data structures of each driver that are accessed * by other parts of the input code. The input_driver structs are the "interface" * between RetroArch and the input driver. + * * Every driver must establish an input_driver struct with pointers to its own * implementations of these functions, and each of those input_driver structs is * declared below. @@ -112,53 +132,50 @@ typedef struct struct input_driver { /** - * init: Initializes input driver. + * Initializes input driver. * - * PARAMETERS - * @joypad_driver: Name of the joypad driver associated with the input driver + * @param joypad_driver Name of the joypad driver associated with the + * input driver */ void *(*init)(const char *joypad_driver); /** - * poll: Called once every frame to poll input. This function pointer can be set - * to NULL if not supported by the input driver, for example if a joypad driver - * is responsible for polling on a particular driver/platform. + * Called once every frame to poll input. This function pointer can be set + * to NULL if not supported by the input driver, for example if a joypad + * driver is responsible for polling on a particular driver/platform. * - * PARAMETERS - * @data: the input state struct + * @param data the input state struct */ void (*poll)(void *data); /** - * input_state: Queries state for a specified control on a specified input port. - * This function pointer can be set to NULL if not supported by the input driver, - * for example if a joypad driver is responsible for quering state for a particular - * driver/platform. + * Queries state for a specified control on a specified input port. This + * function pointer can be set to NULL if not supported by the input driver, + * for example if a joypad driver is responsible for quering state for a + * particular driver/platform. * - * PARAMETERS - * @joypad_data: The input state struct, defined by the input driver - * @sec_joypad_data: The input state struct of any secondary input device - * (e.g. MFi controllers), defined by a secondary input driver. - * May be NULL. Queried state to be returned is the logical - * OR of 'joypad_data' and 'sec_joypad_data' - * @joypad_info: Info struct for the controller to be queried, containing - * physical (hardware) device index and autoconfig input mapping. - * @retro_keybinds: Data structure for control mappings for all libretro - * input device abstractions - * @keyboard_mapping_blocked: - * If true, disregard custom keyboard mapping - * @port: Which RetroArch port is being polled - * @device: Which libretro abstraction is being polled - (RETRO_DEVICE_ID_RETROPAD, RETRO_DEVICE_ID_MOUSE, etc) - * @index: For controls that support more than one axis or can return - * multiple simultaneous inputs, such as an analog joystick - * or touchpad. - * @id: Which control is being polled (eg RETRO_DEVICE_ID_JOYPAD_START) + * @param joypad_data Input state struct, defined by the input driver + * @param sec_joypad_data Input state struct for secondary input devices (eg + * MFi controllers), defined by a secondary driver. + * Queried state to be returned is the logical OR of + * joypad_data and sec_joypad_data. May be NULL. + * @param joypad_info Info struct for the controller to be queried, + * with hardware device ID and autoconfig mapping. + * @param retro_keybinds Structure for control mappings for all libretro + * input device abstractions + * @param keyboard_mapping_blocked + * If true, disregard custom keyboard mapping + * @param port Which RetroArch port is being polled + * @param device Which libretro abstraction is being polled + * (RETRO_DEVICE_ID_RETROPAD, RETRO_DEVICE_ID_MOUSE) + * @param index For controls with more than one axis or multiple + * simultaneous inputs, such as an analog joystick + * or touchpad. + * @param id Which control is being polled + * (eg RETRO_DEVICE_ID_JOYPAD_START) * - * RETURNS - * Digital controls: Returns 1 for a pressed control and 0 otherwise. - * Analog controls: Retruns values in the range of a signed 16-bit integer, - * [-0x8000, 0x7fff] + * @return 1 for pressed digital control, 0 for non-pressed digital control. + * Values in the range of a signed 16-bit integer,[-0x8000, 0x7fff] */ int16_t (*input_state)(void *data, const input_device_driver_t *joypad_data, @@ -169,83 +186,73 @@ struct input_driver unsigned port, unsigned device, unsigned index, unsigned id); /** - * free: Frees the input struct. + * Frees the input struct. * - * PARAMETERS - * @data: The input state struct + * @param data The input state struct. */ void (*free)(void *data); /** - * set_sensor_state: Sets the state related for sensors, such - * as polling rate or enabling/disable the sensor entirely, etc. - * This function pointer may be set to NULL if setting sensor - * values is not supported. + * Sets the state related for sensors, such as polling rate or to deactivate + * the sensor entirely, etc. This function pointer may be set to NULL if + * setting sensor values is not supported. * - * PARAMETERS - * @data: The input state struct - * @port: Input port - * @effect: Sensor action - * @rate: Sensor rate update + * @param data The input state struct + * @param port + * @param effect Sensor action + * @param rate Sensor rate update * - * RETURNS - * Boolean true if the operation is successful. + * @return true if the operation is successful. **/ bool (*set_sensor_state)(void *data, unsigned port, enum retro_sensor_action action, unsigned rate); /** - * get_sensor_input: Retrieves the sensor state associated with - * the provided port and ID. This function pointer may be set to - * NULL if retreiving sensor state is not supported. + * Retrieves the sensor state associated with the provided port and ID. This + * function pointer may be set to NULL if retreiving sensor state is not + * supported. * - * PARAMETERS - * @data: The input state struct - * @port: Input port - * @id: Sensor ID + * @param data The input state struct + * @param port + * @param id Sensor ID * - * RETURNS - * The current state associated with the port and ID as a float. - **/ + * @return The current state associated with the port and ID as a float + **/ float (*get_sensor_input)(void *data, unsigned port, unsigned id); /** - * get_capabilities: The means for an input driver to indicate to RetroArch - * which libretro input abstractions the driver supports - * PARAMETERS - * @data: The input state struct + * The means for an input driver to indicate to RetroArch which libretro + * input abstractions the driver supports. * - * RETURNS - * a unit64_t composed via bitwise operators + * @param data The input state struct. + * + * @return A unit64_t composed via bitwise operators. */ uint64_t (*get_capabilities)(void *data); /** - * ident: The human-readable name of the input driver + * The human-readable name of the input driver. */ const char *ident; /** - * grab_mouse: Grab or ungrab the mouse according to the value of `state`. - * This function pointer can be set to NULL if the driver does not support - * grabbing the mouse. + * Grab or ungrab the mouse according to the value of `state`. This function + * pointer can be set to NULL if the driver does not support grabbing the + * mouse. * - * PARAMETERS - * @data: The input state struct - * @state: True to grab the mouse, false to ungrab + * @param data The input state struct + * @param state True to grab the mouse, false to ungrab */ void (*grab_mouse)(void *data, bool state); /** - * grab_stdin: Check to see if the input driver has claimed stdin, and - * therefore it is not available for other input. This function pointer - * can be set to NULL if the driver does not support claiming stdin. + * Check to see if the input driver has claimed stdin, and therefore it is + * not available for other input. This function pointercan be set to NULL if + * the driver does not support claiming stdin. * - * PARAMETERS - * @data: The input state struct + * @param data The input state struct * - * RETURNS - * True if the input driver has claimed stdin. This function pointer + * @return True if the input driver has claimed stdin. */ bool (*grab_stdin)(void *data); }; @@ -267,6 +274,408 @@ struct rarch_joypad_driver const char *ident; }; +/** + * Get an enumerated list of all input driver names + * + * @return string listing of all input driver names, separated by '|'. + **/ +const char* config_get_input_driver_options(void); + +/** + * Sets the rumble state. Used by RETRO_ENVIRONMENT_GET_RUMBLE_INTERFACE. + * + * @param port User number. + * @param effect Rumble effect. + * @param strength Strength of rumble effect. + * + * @return true if the rumble state has been successfully set + **/ +bool input_driver_set_rumble_state(unsigned port, + enum retro_rumble_effect effect, uint16_t strength); + +/** + * Sets the sensor state. Used by RETRO_ENVIRONMENT_GET_SENSOR_INTERFACE. + * + * @param port + * @param effect Sensor action + * @param rate Sensor rate update + * + * @return true if the sensor state has been successfully set + **/ +bool input_sensor_set_state(unsigned port, + enum retro_sensor_action action, unsigned rate); + +/** + * Retrieves the sensor state associated with the provided port and ID. + * + * @param port + * @param id Sensor ID + * + * @return The current state associated with the port and ID as a float + **/ +float input_sensor_get_input(unsigned port, unsigned id); + +/** + * Retrieves the input driver state struct + * + * @return The input state struct + **/ +void *input_driver_get_data(void); + +/** + * Sets the input_driver_nonblock_state flag to true + **/ +void input_driver_set_nonblock_state(void); + +/** + * Sets the input_driver_nonblock_state flag to false + **/ +void input_driver_unset_nonblock_state(void); + +/** + * If the action is INPUT_ACTION_AXIS_THRESHOLD, return the current + * input_driver_axis_threshold. + * + * @return value of input_driver_axis_threshold or NULL for actions other than + * INPUT_ACTION_AXIS_THRESHOLD +**/ +float *input_driver_get_float(enum input_action action); + +/** + * If the action is INPUT_ACTION_MAX_USERS, return the current + * input_driver_max_users. + * + * @return value of input_driver_axis_threshold or NULL for actions other than + * INPUT_ACTION_AXIS_THRESHOLD +**/ +unsigned *input_driver_get_uint(enum input_action action); + +/** + * Get an enumerated list of all joypad driver names + * + * @return String listing of all joypad driver names, separated by '|'. + **/ +const char* config_get_joypad_driver_options(void); + +/** + * Initialize a joypad driver of name ident. If ident points to NULL or a + * zero-length string, equivalent to calling input_joypad_init_first(). + * + * @param ident identifier of driver to initialize. + * + * @return The joypad driver if found, otherwise NULL. + **/ +const input_device_driver_t *input_joypad_init_driver( + const char *ident, void *data); + +/** + * Takes as input analog key identifiers and converts them to corresponding + * bind IDs ident_minus and ident_plus. + * + * @param idx Analog key index (eg RETRO_DEVICE_INDEX_ANALOG_LEFT) + * @param ident Analog key identifier (eg RETRO_DEVICE_ID_ANALOG_X) + * @param ident_minus Bind ID minus, will be set by function. + * @param ident_plus Bind ID plus, will be set by function. + */ +#define input_conv_analog_id_to_bind_id(idx, ident, ident_minus, ident_plus) \ + switch ((idx << 1) | ident) \ + { \ + case (RETRO_DEVICE_INDEX_ANALOG_LEFT << 1) | RETRO_DEVICE_ID_ANALOG_X: \ + ident_minus = RARCH_ANALOG_LEFT_X_MINUS; \ + ident_plus = RARCH_ANALOG_LEFT_X_PLUS; \ + break; \ + case (RETRO_DEVICE_INDEX_ANALOG_LEFT << 1) | RETRO_DEVICE_ID_ANALOG_Y: \ + ident_minus = RARCH_ANALOG_LEFT_Y_MINUS; \ + ident_plus = RARCH_ANALOG_LEFT_Y_PLUS; \ + break; \ + case (RETRO_DEVICE_INDEX_ANALOG_RIGHT << 1) | RETRO_DEVICE_ID_ANALOG_X: \ + ident_minus = RARCH_ANALOG_RIGHT_X_MINUS; \ + ident_plus = RARCH_ANALOG_RIGHT_X_PLUS; \ + break; \ + case (RETRO_DEVICE_INDEX_ANALOG_RIGHT << 1) | RETRO_DEVICE_ID_ANALOG_Y: \ + ident_minus = RARCH_ANALOG_RIGHT_Y_MINUS; \ + ident_plus = RARCH_ANALOG_RIGHT_Y_PLUS; \ + break; \ + } + +/** + * Registers a newly connected pad with RetroArch. + * + * @param port Joystick number + * @param driver Handle for joypad driver handling joystick's input + **/ +void input_pad_connect(unsigned port, input_device_driver_t *driver); + + +/*****************************************************************************/ +#ifdef HAVE_HID +#include "include/hid_driver.h" + +/** + * Get an enumerated list of all HID driver names + * + * @return String listing of all HID driver names, separated by '|'. + **/ +const char* config_get_hid_driver_options(void); + +/** + * Finds first suitable HID driver and initializes. + * + * @return HID driver if found, otherwise NULL. + **/ +const hid_driver_t *input_hid_init_first(void); + +/** + * Get a pointer to the HID driver data structure + * + * @return Pointer to hid_data struct + **/ +const void *hid_driver_get_data(void); + +/** + * This should be called after we've invoked free() on the HID driver; the + * memory will have already been freed so we need to reset the pointer. + */ +void hid_driver_reset_data(void); + +#endif /* HAVE_HID */ +/*****************************************************************************/ + + +/** + * line_complete callback (when carriage return is pressed) + * + * @param userdata User data which will be passed to subsequent callbacks. + * @param line the line of input, which can be NULL. + **/ +typedef void (*input_keyboard_line_complete_t)(void *userdata, + const char *line); + +/** + * Callback for keypress events + * + * @param userdata The user data that was passed through from the keyboard press callback. + * @param code keycode + **/ +typedef bool (*input_keyboard_press_t)(void *userdata, unsigned code); + +struct input_keyboard_ctx_wait +{ + void *userdata; + input_keyboard_press_t cb; +}; + +/** + * Called by drivers when keyboard events are fired. Interfaces with the global + * driver struct and libretro callbacks. + * + * @param down Was Keycode pressed down? + * @param code Keycode. + * @param character Character inputted. + * @param mod TODO/FIXME/??? + **/ +void input_keyboard_event(bool down, unsigned code, uint32_t character, + uint16_t mod, unsigned device); + +/** + * Set the name of the device in the specified port + * + * @param port + */ +void input_config_set_device_name(unsigned port, const char *name); + +/** + * Set the formatted "display name" of the device in the specified port + * + * @param port + */ +void input_config_set_device_display_name(unsigned port, const char *name); + +/** + * Set the configuration path for the device in the specified port + * + * @param port + * @param path The path of the device config. + */ +void input_config_set_device_config_path(unsigned port, const char *path); + +/** + * Set the configuration name for the device in the specified port + * + * @param port + * @param name The name of the config to set. + */ +void input_config_set_device_config_name(unsigned port, const char *name); + +/** + * Set the joypad driver for the device in the specified port + * + * @param port + * @param driver The driver to set the given port to. + */ +void input_config_set_device_joypad_driver(unsigned port, const char *driver); + +/** + * Set the vendor ID (vid) for the device in the specified port + * + * @param port + * @param vid The VID to set the given device port to. + */ +void input_config_set_device_vid(unsigned port, uint16_t vid); + +/** + * Set the pad ID (pid) for the device in the specified port + * + * @param port + * @param pid The PID to set the given device port to. + */ +void input_config_set_device_pid(unsigned port, uint16_t pid); + +/** + * Sets the autoconfigured flag for the device in the specified port + * + * @param port + * @param autoconfigured Whether or nor the device is configured automatically. + */ +void input_config_set_device_autoconfigured(unsigned port, bool autoconfigured); + +/** + * Sets the name index number for the device in the specified port + * + * @param port + * @param name_index The name index to set the device to use. + */ +void input_config_set_device_name_index(unsigned port, unsigned name_index); + +/** + * Sets the device type of the specified port + * + * @param port + * @param id The device type (RETRO_DEVICE_JOYPAD, RETRO_DEVICE_MOUSE, etc) + */ +void input_config_set_device(unsigned port, unsigned id); + +/** + * Registers a pad_connection_listener_interface with a function pointer that + * is called when a joypad is connected. Only used by the wiiu_joypad driver. + * + * @param listener a struct that implements pad_connection_listener_interface + */ +void set_connection_listener(pad_connection_listener_t *listener); + +/* Clear input_device_info */ +void input_config_clear_device_name(unsigned port); +void input_config_clear_device_display_name(unsigned port); +void input_config_clear_device_config_path(unsigned port); +void input_config_clear_device_config_name(unsigned port); +void input_config_clear_device_joypad_driver(unsigned port); + +unsigned input_config_get_device_count(void); + +unsigned *input_config_get_device_ptr(unsigned port); + +unsigned input_config_get_device(unsigned port); + +/* Get input_device_info */ +const char *input_config_get_device_name(unsigned port); +const char *input_config_get_device_display_name(unsigned port); +const char *input_config_get_device_config_path(unsigned port); +const char *input_config_get_device_config_name(unsigned port); +const char *input_config_get_device_joypad_driver(unsigned port); + +/** + * Retrieves the vendor id (vid) of a connected controller + * + * @param port + * + * @return the vendor id VID of the device + */ +uint16_t input_config_get_device_vid(unsigned port); + +/** + * Retrieves the pad id (pad) of a connected controller + * + * @param port + * + * @return the port id PID of the device + */ +uint16_t input_config_get_device_pid(unsigned port); + +/** + * Returns the value of the autoconfigured flag for the specified device + * + * @param port + * + * @return the autoconfigured flag + */ +bool input_config_get_device_autoconfigured(unsigned port); + +/** + * Get the name index number for the device in this port + * + * @param port + * + * @return the name index for this device + */ +unsigned input_config_get_device_name_index(unsigned port); + + +/*****************************************************************************/ + +/** + * Retrieve the device name char pointer. + * + * @deprecated input_config_get_device_name_ptr is required by linuxraw_joypad + * and parport_joypad. These drivers should be refactored such that this + * low-level access is not required. + * + * @param port + * + * @return a pointer to the device name on the specified port + */ +char *input_config_get_device_name_ptr(unsigned port); + +/** + * Get the size of the device name. + * + * @deprecated input_config_get_device_name_size is required by linuxraw_joypad + * and parport_joypad. These drivers should be refactored such that this + * low-level access is not required. + * + * @param port + * + * @return the size of the device name on the specified port + */ +size_t input_config_get_device_name_size(unsigned port); + +/*****************************************************************************/ + +/** + * Save the current keybinds on a port to the config file. + * + * @param conf pointer to config file object + * @param user user number (ie port - TODO: change to port nomenclature) + */ +void input_config_save_keybinds_user(void *data, unsigned user); + +const struct retro_keybind *input_config_get_bind_auto(unsigned port, unsigned id); + +/** + * Save a key binding to the config file. + * + * @param conf pointer to config file object + * @param prefix prefix name of keybind + * @param base base name of keybind + * @param bind pointer to key binding object + * @param kb save keyboard binds + */ +void input_config_save_keybind(void *data, const char *prefix, + const char *base, const struct retro_keybind *bind, + bool save_empty); + +void input_config_reset_autoconfig_binds(unsigned port); +void input_config_reset(void); + #if defined(ANDROID) #define DEFAULT_MAX_PADS 8 #define ANDROID_KEYBOARD_PORT DEFAULT_MAX_PADS @@ -279,7 +688,7 @@ struct rarch_joypad_driver #define DEFAULT_MAX_PADS 16 #else #define DEFAULT_MAX_PADS 5 -#endif +#endif /* WIIU_HID */ #elif defined(DJGPP) #define DEFAULT_MAX_PADS 1 #define DOS_KEYBOARD_PORT DEFAULT_MAX_PADS @@ -309,232 +718,7 @@ struct rarch_joypad_driver #define DEFAULT_MAX_PADS 2 #else #define DEFAULT_MAX_PADS 16 -#endif - -/** - * config_get_input_driver_options: - * - * Get an enumerated list of all input driver names, separated by '|'. - * - * Returns: string listing of all input driver names, separated by '|'. - **/ -const char* config_get_input_driver_options(void); - -/** - * input_driver_set_rumble_state: - * @port : User number. - * @effect : Rumble effect. - * @strength : Strength of rumble effect. - * - * Sets the rumble state. - * Used by RETRO_ENVIRONMENT_GET_RUMBLE_INTERFACE. - **/ -bool input_driver_set_rumble_state(unsigned port, - enum retro_rumble_effect effect, uint16_t strength); - -/** - * input_sensor_set_state: - * @port : User number. - * @effect : Sensor action. - * @rate : Sensor rate update. - * - * Sets the sensor state. - * Used by RETRO_ENVIRONMENT_GET_SENSOR_INTERFACE. - **/ -bool input_sensor_set_state(unsigned port, - enum retro_sensor_action action, unsigned rate); - -float input_sensor_get_input(unsigned port, unsigned id); - -void *input_driver_get_data(void); - -void input_driver_set_nonblock_state(void); - -void input_driver_unset_nonblock_state(void); - -float *input_driver_get_float(enum input_action action); - -unsigned *input_driver_get_uint(enum input_action action); - -/** - * config_get_joypad_driver_options: - * - * Get an enumerated list of all joypad driver names, separated by '|'. - * - * Returns: string listing of all joypad driver names, separated by '|'. - **/ -const char* config_get_joypad_driver_options(void); - -/** - * input_joypad_init_driver: - * @ident : identifier of driver to initialize. - * - * Initialize a joypad driver of name @ident. - * - * If ident points to NULL or a zero-length string, - * equivalent to calling input_joypad_init_first(). - * - * Returns: joypad driver if found, otherwise NULL. - **/ -const input_device_driver_t *input_joypad_init_driver( - const char *ident, void *data); - -/** - * input_conv_analog_id_to_bind_id: - * @idx : Analog key index. - * E.g.: - * - RETRO_DEVICE_INDEX_ANALOG_LEFT - * - RETRO_DEVICE_INDEX_ANALOG_RIGHT - * @ident : Analog key identifier. - * E.g.: - * - RETRO_DEVICE_ID_ANALOG_X - * - RETRO_DEVICE_ID_ANALOG_Y - * @ident_minus : Bind ID minus, will be set by function. - * @ident_plus : Bind ID plus, will be set by function. - * - * Takes as input analog key identifiers and converts - * them to corresponding bind IDs @ident_minus and @ident_plus. - **/ -#define input_conv_analog_id_to_bind_id(idx, ident, ident_minus, ident_plus) \ - switch ((idx << 1) | ident) \ - { \ - case (RETRO_DEVICE_INDEX_ANALOG_LEFT << 1) | RETRO_DEVICE_ID_ANALOG_X: \ - ident_minus = RARCH_ANALOG_LEFT_X_MINUS; \ - ident_plus = RARCH_ANALOG_LEFT_X_PLUS; \ - break; \ - case (RETRO_DEVICE_INDEX_ANALOG_LEFT << 1) | RETRO_DEVICE_ID_ANALOG_Y: \ - ident_minus = RARCH_ANALOG_LEFT_Y_MINUS; \ - ident_plus = RARCH_ANALOG_LEFT_Y_PLUS; \ - break; \ - case (RETRO_DEVICE_INDEX_ANALOG_RIGHT << 1) | RETRO_DEVICE_ID_ANALOG_X: \ - ident_minus = RARCH_ANALOG_RIGHT_X_MINUS; \ - ident_plus = RARCH_ANALOG_RIGHT_X_PLUS; \ - break; \ - case (RETRO_DEVICE_INDEX_ANALOG_RIGHT << 1) | RETRO_DEVICE_ID_ANALOG_Y: \ - ident_minus = RARCH_ANALOG_RIGHT_Y_MINUS; \ - ident_plus = RARCH_ANALOG_RIGHT_Y_PLUS; \ - break; \ - } - -/** - * input_pad_connect: - * @port : Joystick number. - * @driver : handle for joypad driver handling joystick's input - * - * Registers a newly connected pad with RetroArch. - **/ -void input_pad_connect(unsigned port, input_device_driver_t *driver); - -#ifdef HAVE_HID -#include "include/hid_driver.h" - -/** - * config_get_hid_driver_options: - * - * Get an enumerated list of all HID driver names, separated by '|'. - * - * Returns: string listing of all HID driver names, separated by '|'. - **/ -const char* config_get_hid_driver_options(void); - -/** - * input_hid_init_first: - * - * Finds first suitable HID driver and initializes. - * - * Returns: HID driver if found, otherwise NULL. - **/ -const hid_driver_t *input_hid_init_first(void); - -const void *hid_driver_get_data(void); -void hid_driver_reset_data(void); -#endif - -/** Line complete callback. - * Calls back after return is pressed with the completed line. - * Line can be NULL. - **/ -typedef void (*input_keyboard_line_complete_t)(void *userdata, - const char *line); - -typedef bool (*input_keyboard_press_t)(void *userdata, unsigned code); - -struct input_keyboard_ctx_wait -{ - void *userdata; - input_keyboard_press_t cb; -}; - -/** - * input_keyboard_event: - * @down : Keycode was pressed down? - * @code : Keycode. - * @character : Character inputted. - * @mod : TODO/FIXME: ??? - * - * Keyboard event utils. Called by drivers when keyboard events are fired. - * This interfaces with the global driver struct and libretro callbacks. - **/ -void input_keyboard_event(bool down, unsigned code, uint32_t character, - uint16_t mod, unsigned device); - - -/* Set input_device_info */ -void input_config_set_device_name(unsigned port, const char *name); -void input_config_set_device_display_name(unsigned port, const char *name); -void input_config_set_device_config_path(unsigned port, const char *path); -void input_config_set_device_config_name(unsigned port, const char *name); -void input_config_set_device_joypad_driver(unsigned port, const char *driver); -void input_config_set_device_vid(unsigned port, uint16_t vid); -void input_config_set_device_pid(unsigned port, uint16_t pid); -void input_config_set_device_autoconfigured(unsigned port, bool autoconfigured); -void input_config_set_device_name_index(unsigned port, unsigned name_index); - -/* Clear input_device_info */ -void input_config_clear_device_name(unsigned port); -void input_config_clear_device_display_name(unsigned port); -void input_config_clear_device_config_path(unsigned port); -void input_config_clear_device_config_name(unsigned port); -void input_config_clear_device_joypad_driver(unsigned port); - -unsigned input_config_get_device_count(void); - -unsigned *input_config_get_device_ptr(unsigned port); - -unsigned input_config_get_device(unsigned port); - -void input_config_set_device(unsigned port, unsigned id); - -/* Get input_device_info */ -const char *input_config_get_device_name(unsigned port); -const char *input_config_get_device_display_name(unsigned port); -const char *input_config_get_device_config_path(unsigned port); -const char *input_config_get_device_config_name(unsigned port); -const char *input_config_get_device_joypad_driver(unsigned port); -uint16_t input_config_get_device_vid(unsigned port); -uint16_t input_config_get_device_pid(unsigned port); -bool input_config_get_device_autoconfigured(unsigned port); -unsigned input_config_get_device_name_index(unsigned port); - -/* TODO/FIXME: This is required by linuxraw_joypad.c - * and parport_joypad.c. These input drivers should - * be refactored such that this dubious low-level - * access is not required */ -char *input_config_get_device_name_ptr(unsigned port); -size_t input_config_get_device_name_size(unsigned port); - -const struct retro_keybind *input_config_get_bind_auto(unsigned port, unsigned id); - -void input_config_save_keybinds_user(void *data, unsigned user); - -void input_config_save_keybind(void *data, const char *prefix, - const char *base, const struct retro_keybind *bind, - bool save_empty); - -void input_config_reset_autoconfig_binds(unsigned port); -void input_config_reset(void); - -void set_connection_listener(pad_connection_listener_t *listener); +#endif /* defined(ANDROID) */ extern input_device_driver_t dinput_joypad; extern input_device_driver_t linuxraw_joypad; @@ -589,7 +773,7 @@ extern hid_driver_t iohidmanager_hid; extern hid_driver_t btstack_hid; extern hid_driver_t libusb_hid; extern hid_driver_t wiiusb_hid; -#endif +#endif /* HAVE_HID */ typedef struct menu_input_ctx_line { @@ -618,4 +802,4 @@ void menu_input_dialog_end(void); RETRO_END_DECLS -#endif +#endif /* __INPUT_DRIVER__H */ From e9a5625445e5c1903f439c111b852d9f3190ecb9 Mon Sep 17 00:00:00 2001 From: Ash Logan Date: Tue, 20 Jul 2021 08:59:16 +1000 Subject: [PATCH 50/58] (Wii U/Vita) Use Ozone icons instead of XMB Monochrome The Ozone icons are small pngs, 46x46, while the XMB Monochrome icons are 256x256, which do not look good on low-dpi screens when downscaled so extremely. --- file_path_special.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/file_path_special.c b/file_path_special.c index 153bde3018..e23ae4287e 100644 --- a/file_path_special.c +++ b/file_path_special.c @@ -304,6 +304,21 @@ void fill_pathname_application_special(char *s, strlcpy(s, dir_assets, len); fill_pathname_slash(s, len); +#if defined(WIIU) || defined(VITA) + /* Smaller 46x46 icons look better on low-dpi devices */ + /* ozone */ + strlcat(s, "ozone", len); + fill_pathname_slash(s, len); + + /* png */ + strlcat(s, "png", len); + fill_pathname_slash(s, len); + + /* Icons path */ + strlcat(s, "icons", len); + fill_pathname_slash(s, len); +#else + /* Otherwise, use large 256x256 icons */ /* xmb */ strlcat(s, "xmb", len); fill_pathname_slash(s, len); @@ -315,6 +330,7 @@ void fill_pathname_application_special(char *s, /* Icons path */ strlcat(s, "png", len); fill_pathname_slash(s, len); +#endif } #endif break; From edd9ed3619646a3a577a12c20a07c9b01abfc277 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Tue, 20 Jul 2021 05:13:52 +0200 Subject: [PATCH 51/58] Fix some style nits --- retroarch.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/retroarch.c b/retroarch.c index 15c67eeb77..0642c8c779 100644 --- a/retroarch.c +++ b/retroarch.c @@ -31396,7 +31396,7 @@ void video_driver_set_viewport_core(void) (float)geom->base_width / geom->base_height; } -void video_driver_set_viewport_full() +void video_driver_set_viewport_full(void) { unsigned width = 0; unsigned height = 0; @@ -31404,9 +31404,7 @@ void video_driver_set_viewport_full() video_driver_get_size(&width, &height); if (width == 0 || height == 0) - { return; - } aspectratio_lut[ASPECT_RATIO_FULL].value = (float)width / (float)height; } From 646cadba8cd833fa64200c3414788a7869113677 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Tue, 20 Jul 2021 05:23:12 +0200 Subject: [PATCH 52/58] Another style nit --- disk_index_file.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/disk_index_file.c b/disk_index_file.c index 236bbf5ae6..0ebd122db2 100644 --- a/disk_index_file.c +++ b/disk_index_file.c @@ -47,11 +47,9 @@ static bool DCifJSONObjectMemberHandler(void* context, const char *pValue, size_ { DCifJSONContext *pCtx = (DCifJSONContext*)context; + /* something went wrong */ if (pCtx->current_entry_str_val) - { - /* something went wrong */ return false; - } if (length) { From 4621ed7dcc9d9f5cc0781a51e4464f2af89cf8cb Mon Sep 17 00:00:00 2001 From: Ash Logan Date: Tue, 20 Jul 2021 18:51:53 +1000 Subject: [PATCH 53/58] (Wii U) Display scissor doesn't use inverted coordinates Unlike the draw callback, seems the scissor callback does *not* have an inverted y-coordinate. Yay! --- gfx/drivers_display/gfx_display_wiiu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gfx/drivers_display/gfx_display_wiiu.c b/gfx/drivers_display/gfx_display_wiiu.c index b11870c322..0abcd6b75e 100644 --- a/gfx/drivers_display/gfx_display_wiiu.c +++ b/gfx/drivers_display/gfx_display_wiiu.c @@ -283,7 +283,7 @@ static void gfx_display_wiiu_scissor_begin( int x, int y, unsigned width, unsigned height) { - GX2SetScissor(MAX(x, 0), MAX(video_height - y - height, 0), MIN(width, video_width), MIN(height, video_height)); + GX2SetScissor(MAX(x, 0), MAX(y, 0), MIN(width, video_width), MIN(height, video_height)); } static void gfx_display_wiiu_scissor_end( From 20e70f9caa7cb032cf5dd8c803f22c80aeeecf35 Mon Sep 17 00:00:00 2001 From: Ash Logan Date: Tue, 20 Jul 2021 19:57:35 +1000 Subject: [PATCH 54/58] (Wii U) Only sample alpha channel when rendering fonts The font backend provides only the alpha channel for a given glyph, but we were sampling that channel for the r, g, b and a. Fix by hard-coding the sampled colour to white - the actually desired colour is multiplied in later. --- gfx/drivers_font/wiiu_font.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gfx/drivers_font/wiiu_font.c b/gfx/drivers_font/wiiu_font.c index b9ba5369bc..0adb22f382 100644 --- a/gfx/drivers_font/wiiu_font.c +++ b/gfx/drivers_font/wiiu_font.c @@ -65,7 +65,7 @@ static void* wiiu_font_init_font(void* data, const char* font_path, font->texture.viewNumSlices = 1; font->texture.surface.format = GX2_SURFACE_FORMAT_UNORM_R8; - font->texture.compMap = GX2_COMP_SEL(_R, _R, _R, _R); + font->texture.compMap = GX2_COMP_SEL(_1, _1, _1, _R); GX2CalcSurfaceSizeAndAlignment(&font->texture.surface); GX2InitTextureRegs(&font->texture); From 60c32fe4945ee5f7434655e85abd8aed8723ec72 Mon Sep 17 00:00:00 2001 From: Ash Logan Date: Tue, 20 Jul 2021 20:05:44 +1000 Subject: [PATCH 55/58] (Wii U) Render font lines with correct spacing No idea about this one, borrowed code from the Vita and it makes multi-line rendering look correct again --- gfx/drivers_font/wiiu_font.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gfx/drivers_font/wiiu_font.c b/gfx/drivers_font/wiiu_font.c index 0adb22f382..3bbd111b01 100644 --- a/gfx/drivers_font/wiiu_font.c +++ b/gfx/drivers_font/wiiu_font.c @@ -258,7 +258,7 @@ static void wiiu_font_render_message( return; } - line_height = scale / line_metrics->height; + line_height = line_metrics->height * scale / wiiu->vp.height; for (;;) { From 218286aa99b39a766e83d41f119f03df67bcf367 Mon Sep 17 00:00:00 2001 From: jdgleaver Date: Wed, 21 Jul 2021 14:11:42 +0100 Subject: [PATCH 56/58] (RS90) Add optional approximate 'semi-linear' scaling filter --- config.def.h | 5 + configuration.c | 3 + configuration.h | 1 + gfx/common/x11_common.c | 23 +- gfx/drivers/sdl_rs90_gfx.c | 588 +++++++++++++++++++++++++---------- intl/msg_hash_lbl.h | 6 + intl/msg_hash_us.h | 18 ++ menu/cbs/menu_cbs_sublabel.c | 8 + menu/menu_defines.h | 9 + menu/menu_displaylist.c | 6 + menu/menu_setting.c | 55 +++- msg_hash.h | 6 + 12 files changed, 545 insertions(+), 183 deletions(-) diff --git a/config.def.h b/config.def.h index 14e403c221..2b1fc5824a 100644 --- a/config.def.h +++ b/config.def.h @@ -420,6 +420,11 @@ * in Dingux devices */ #define DEFAULT_DINGUX_REFRESH_RATE DINGUX_REFRESH_RATE_60HZ #endif +#if defined(RS90) +/* Sets image filtering method on the RS90 + * when integer scaling is disabled */ +#define DEFAULT_DINGUX_RS90_SOFTFILTER_TYPE DINGUX_RS90_SOFTFILTER_POINT +#endif #endif /* Save configuration file on exit. */ diff --git a/configuration.c b/configuration.c index ae5d26b483..f16b9fb541 100644 --- a/configuration.c +++ b/configuration.c @@ -2137,6 +2137,9 @@ static struct config_uint_setting *populate_settings_uint( #if defined(DINGUX_BETA) SETTING_UINT("video_dingux_refresh_rate", &settings->uints.video_dingux_refresh_rate, true, DEFAULT_DINGUX_REFRESH_RATE, false); #endif +#if defined(RS90) + SETTING_UINT("video_dingux_rs90_softfilter_type", &settings->uints.video_dingux_rs90_softfilter_type, true, DEFAULT_DINGUX_RS90_SOFTFILTER_TYPE, false); +#endif #endif #ifdef HAVE_MENU diff --git a/configuration.h b/configuration.h index 773d03d3ae..b5b326cc9e 100644 --- a/configuration.h +++ b/configuration.h @@ -209,6 +209,7 @@ typedef struct settings unsigned video_3ds_display_mode; unsigned video_dingux_ipu_filter_type; unsigned video_dingux_refresh_rate; + unsigned video_dingux_rs90_softfilter_type; #ifdef HAVE_VIDEO_LAYOUT unsigned video_layout_selected_view; #endif diff --git a/gfx/common/x11_common.c b/gfx/common/x11_common.c index 25f6133e46..f9aebf5040 100644 --- a/gfx/common/x11_common.c +++ b/gfx/common/x11_common.c @@ -206,16 +206,19 @@ static void xdg_screensaver_inhibit(Window wnd) RARCH_LOG("[X11]: Suspending screensaver (X11, xdg-screensaver).\n"); - /* Make sure the window has a title, even if it's a bogus one, otherwise - * xdg-screensaver will fail and report to stderr, framing RA for its bug. - * A single space character is used so that the title bar stays visibly - * the same, as if there's no title at all. */ - video_driver_get_window_title(title, sizeof(title)); - if (strlen(title) == 0) - snprintf(title, sizeof(title), " "); - XChangeProperty(g_x11_dpy, g_x11_win, XA_WM_NAME, XA_STRING, - 8, PropModeReplace, (const unsigned char*) title, - strlen(title)); + if (g_x11_dpy && g_x11_win) + { + /* Make sure the window has a title, even if it's a bogus one, otherwise + * xdg-screensaver will fail and report to stderr, framing RA for its bug. + * A single space character is used so that the title bar stays visibly + * the same, as if there's no title at all. */ + video_driver_get_window_title(title, sizeof(title)); + if (strlen(title) == 0) + snprintf(title, sizeof(title), " "); + XChangeProperty(g_x11_dpy, g_x11_win, XA_WM_NAME, XA_STRING, + 8, PropModeReplace, (const unsigned char*) title, + strlen(title)); + } snprintf(cmd, sizeof(cmd), "xdg-screensaver suspend 0x%x", (int)wnd); diff --git a/gfx/drivers/sdl_rs90_gfx.c b/gfx/drivers/sdl_rs90_gfx.c index db599eacf8..0da790ebd0 100644 --- a/gfx/drivers/sdl_rs90_gfx.c +++ b/gfx/drivers/sdl_rs90_gfx.c @@ -56,11 +56,18 @@ #define SDL_RS90_NUM_FONT_GLYPHS 256 -typedef struct sdl_rs90_video +typedef struct sdl_rs90_video sdl_rs90_video_t; +struct sdl_rs90_video { retro_time_t last_frame_time; retro_time_t ff_frame_time_min; SDL_Surface *screen; + void (*scale_frame16)(sdl_rs90_video_t *vid, + uint16_t *src, unsigned width, unsigned height, + unsigned src_pitch); + void (*scale_frame32)(sdl_rs90_video_t *vid, + uint32_t *src, unsigned width, unsigned height, + unsigned src_pitch); bitmapfont_lut_t *osd_font; /* Scaling/padding/cropping parameters */ unsigned content_width; @@ -71,6 +78,7 @@ typedef struct sdl_rs90_video unsigned frame_padding_y; unsigned frame_crop_x; unsigned frame_crop_y; + enum dingux_rs90_softfilter_type softfilter_type; #if defined(DINGUX_BETA) enum dingux_refresh_rate refresh_rate; #endif @@ -85,7 +93,380 @@ typedef struct sdl_rs90_video bool was_in_menu; bool quitting; bool mode_valid; -} sdl_rs90_video_t; +}; + +/* Image interpolation START */ + +static void sdl_rs90_scale_frame16_integer(sdl_rs90_video_t *vid, + uint16_t *src, unsigned width, unsigned height, + unsigned src_pitch) +{ + /* 16 bit - divide pitch by 2 */ + size_t in_stride = (size_t)(src_pitch >> 1); + size_t out_stride = (size_t)(vid->screen->pitch >> 1); + + /* Manipulate offsets so that padding/crop + * are applied correctly */ + uint16_t *in_ptr = src + vid->frame_crop_x + vid->frame_crop_y * in_stride; + uint16_t *out_ptr = (uint16_t*)(vid->screen->pixels) + vid->frame_padding_x + + out_stride * vid->frame_padding_y; + + size_t y = vid->frame_height; + + /* TODO/FIXME: Optimize this loop */ + do + { + memcpy(out_ptr, in_ptr, vid->frame_width * sizeof(uint16_t)); + in_ptr += in_stride; + out_ptr += out_stride; + } + while (--y); +} + +static void sdl_rs90_scale_frame32_integer(sdl_rs90_video_t *vid, + uint32_t *src, unsigned width, unsigned height, + unsigned src_pitch) +{ + /* 32 bit - divide pitch by 4 */ + size_t in_stride = (size_t)(src_pitch >> 2); + size_t out_stride = (size_t)(vid->screen->pitch >> 2); + + /* Manipulate offsets so that padding/crop + * are applied correctly */ + uint32_t *in_ptr = src + vid->frame_crop_x + vid->frame_crop_y * in_stride; + uint32_t *out_ptr = (uint32_t*)(vid->screen->pixels) + vid->frame_padding_x + + out_stride * vid->frame_padding_y; + + size_t y = vid->frame_height; + + /* TODO/FIXME: Optimize this loop */ + do + { + memcpy(out_ptr, in_ptr, vid->frame_width * sizeof(uint32_t)); + in_ptr += in_stride; + out_ptr += out_stride; + } + while (--y); +} + +/* Approximate nearest-neighbour scaling using + * bitshifts and integer math */ +static void sdl_rs90_scale_frame16_point(sdl_rs90_video_t *vid, + uint16_t *src, unsigned width, unsigned height, + unsigned src_pitch) +{ + uint32_t x_step = (((uint32_t)(width) << 16) + 1) / vid->frame_width; + uint32_t y_step = (((uint32_t)(height) << 16) + 1) / vid->frame_height; + + /* 16 bit - divide pitch by 2 */ + size_t in_stride = (size_t)(src_pitch >> 1); + size_t out_stride = (size_t)(vid->screen->pitch >> 1); + + /* Apply x/y padding offset */ + uint16_t *top_corner = (uint16_t*)(vid->screen->pixels) + vid->frame_padding_x + + out_stride * vid->frame_padding_y; + + /* Temporary pointers */ + uint16_t *in_ptr = NULL; + uint16_t *out_ptr = NULL; + + uint32_t y = 0; + size_t row; + + /* TODO/FIXME: Optimize these loops further. + * Consider saving these computations in an array + * and indexing over them. + * Would likely be slower due to cache (non-)locality, + * but it's worth a shot. + * Tons of -> operations. */ + for (row = 0; row < vid->frame_height; row++) + { + size_t col = vid->frame_width; + uint32_t x = 0; + + out_ptr = top_corner + out_stride * row; + in_ptr = src + (y >> 16) * in_stride; + + do + { + *(out_ptr++) = in_ptr[x >> 16]; + x += x_step; + } + while (--col); + + y += y_step; + } +} + +static void sdl_rs90_scale_frame32_point(sdl_rs90_video_t *vid, + uint32_t *src, unsigned width, unsigned height, + unsigned src_pitch) +{ + uint32_t x_step = (((uint32_t)(width) << 16) + 1) / vid->frame_width; + uint32_t y_step = (((uint32_t)(height) << 16) + 1) / vid->frame_height; + + /* 32 bit - divide pitch by 4 */ + size_t in_stride = (size_t)(src_pitch >> 2); + size_t out_stride = (size_t)(vid->screen->pitch >> 2); + + /* Apply x/y padding offset */ + uint32_t *top_corner = (uint32_t*)(vid->screen->pixels) + vid->frame_padding_x + + out_stride * vid->frame_padding_y; + + /* Temporary pointers */ + uint32_t *in_ptr = NULL; + uint32_t *out_ptr = NULL; + + uint32_t y = 0; + size_t row; + + /* TODO/FIXME: Optimize these loops further. + * Consider saving these computations in an array + * and indexing over them. + * Would likely be slower due to cache (non-)locality, + * but it's worth a shot. + * Tons of -> operations. */ + for (row = 0; row < vid->frame_height; row++) + { + size_t col = vid->frame_width; + uint32_t x = 0; + + out_ptr = top_corner + out_stride * row; + in_ptr = src + (y >> 16) * in_stride; + + do + { + *(out_ptr++) = in_ptr[x >> 16]; + x += x_step; + } + while (--col); + + y += y_step; + } +} + +/* Produces a 50:50 mix of pixels a and b + * > c.f. "Mixing Packed RGB Pixels Efficiently" + * http://blargg.8bitalley.com/info/rgb_mixing.html */ +#define SDL_RS90_PIXEL_AVERAGE_16(a, b) (((a) + (b) + (((a) ^ (b)) & 0x821)) >> 1) +#define SDL_RS90_PIXEL_AVERAGE_32(a, b) (((a) + (b) + (((a) ^ (b)) & 0x10101)) >> 1) + +/* Scales a single horizontal line using approximate + * linear scaling + * > c.f. "Image Scaling with Bresenham" + * https://www.drdobbs.com/image-scaling-with-bresenham/184405045 */ +static void sdl_rs90_scale_line_bresenham16(uint16_t *target, uint16_t *src, + unsigned src_width, unsigned target_width, + unsigned int_part, unsigned fract_part, unsigned midpoint) +{ + unsigned num_pixels = target_width; + unsigned E = 0; /* TODO/FIXME: Determine better variable name - 'error'? */ + + /* If source and target have the same width, + * can perform a fast copy of raw pixel data */ + if (src_width == target_width) + { + memcpy(target, src, target_width * sizeof(uint16_t)); + return; + } + else if (target_width > src_width) + num_pixels--; + + do + { + *(target++) = (E >= midpoint) ? + SDL_RS90_PIXEL_AVERAGE_16(*src, *(src + 1)) : *src; + + src += int_part; + E += fract_part; + + if (E >= target_width) + { + E -= target_width; + src++; + } + } + while (--num_pixels); + + if (target_width > src_width) + *target = *src; +} + +static void sdl_rs90_scale_frame16_bresenham_horz(sdl_rs90_video_t *vid, + uint16_t *src, unsigned width, unsigned height, + unsigned src_pitch) +{ + /* 16 bit - divide pitch by 2 */ + size_t in_stride = (size_t)(src_pitch >> 1); + size_t out_stride = (size_t)(vid->screen->pitch >> 1); + + uint16_t *prev_src = NULL; + + /* Account for x/y padding */ + uint16_t *target = (uint16_t*)(vid->screen->pixels) + vid->frame_padding_x + + (out_stride * vid->frame_padding_y); + unsigned target_width = vid->frame_width; + unsigned target_height = vid->frame_height; + + unsigned num_lines = target_height; + unsigned int_part = (height / target_height) * in_stride; + unsigned fract_part = height % target_height; + unsigned E = 0; /* TODO/FIXME: Determine better variable name - 'error'? */ + + unsigned col_int_part = width / target_width; + unsigned col_fract_part = width % target_width; + /* Enhance midpoint selection as described in + * https://www.compuphase.com/graphic/scale1errata.htm */ + int col_midpoint = (target_width > width) ? + ((int)target_width - 3 * ((int)target_width - (int)width)) >> 1 : + (int)(target_width << 1) - (int)width; + /* Clamp lower bound to (target_width / 2) */ + if (col_midpoint < (int)(target_width >> 1)) + col_midpoint = (int)(target_width >> 1); + + while (num_lines--) + { + /* If line is supposed to be identical to + * previous line, just copy it */ + if (src == prev_src) + memcpy(target, target - out_stride, target_width * sizeof(uint16_t)); + else + { + sdl_rs90_scale_line_bresenham16(target, src, width, target_width, + col_int_part, col_fract_part, (unsigned)col_midpoint); + prev_src = src; + } + + target += out_stride; + src += int_part; + E += fract_part; + + if (E >= target_height) + { + E -= target_height; + src += in_stride; + } + } +} + +static void sdl_rs90_scale_line_bresenham32(uint32_t *target, uint32_t *src, + unsigned src_width, unsigned target_width, + unsigned int_part, unsigned fract_part, unsigned midpoint) +{ + unsigned num_pixels = target_width; + unsigned E = 0; /* TODO/FIXME: Determine better variable name - 'error'? */ + + /* If source and target have the same width, + * can perform a fast copy of raw pixel data */ + if (src_width == target_width) + { + memcpy(target, src, target_width * sizeof(uint32_t)); + return; + } + else if (target_width > src_width) + num_pixels--; + + do + { + *(target++) = (E >= midpoint) ? + SDL_RS90_PIXEL_AVERAGE_32(*src, *(src + 1)) : *src; + + src += int_part; + E += fract_part; + + if (E >= target_width) + { + E -= target_width; + src++; + } + } + while (--num_pixels); + + if (target_width > src_width) + *target = *src; +} + +static void sdl_rs90_scale_frame32_bresenham_horz(sdl_rs90_video_t *vid, + uint32_t *src, unsigned width, unsigned height, + unsigned src_pitch) +{ + /* 32 bit - divide pitch by 4 */ + size_t in_stride = (size_t)(src_pitch >> 2); + size_t out_stride = (size_t)(vid->screen->pitch >> 2); + + uint32_t *prev_src = NULL; + + /* Account for x/y padding */ + uint32_t *target = (uint32_t*)(vid->screen->pixels) + vid->frame_padding_x + + (out_stride * vid->frame_padding_y); + unsigned target_width = vid->frame_width; + unsigned target_height = vid->frame_height; + + unsigned num_lines = target_height; + unsigned int_part = (height / target_height) * in_stride; + unsigned fract_part = height % target_height; + unsigned E = 0; /* TODO/FIXME: Determine better variable name - 'error'? */ + + unsigned col_int_part = width / target_width; + unsigned col_fract_part = width % target_width; + /* Enhance midpoint selection as described in + * https://www.compuphase.com/graphic/scale1errata.htm */ + int col_midpoint = (target_width > width) ? + ((int)target_width - 3 * ((int)target_width - (int)width)) >> 1 : + (int)(target_width << 1) - (int)width; + /* Clamp lower bound to (target_width / 2) */ + if (col_midpoint < (int)(target_width >> 1)) + col_midpoint = (int)(target_width >> 1); + + while (num_lines--) + { + /* If line is supposed to be identical to + * previous line, just copy it */ + if (src == prev_src) + memcpy(target, target - out_stride, target_width * sizeof(uint32_t)); + else + { + sdl_rs90_scale_line_bresenham32(target, src, width, target_width, + col_int_part, col_fract_part, (unsigned)col_midpoint); + prev_src = src; + } + + target += out_stride; + src += int_part; + E += fract_part; + + if (E >= target_height) + { + E -= target_height; + src += in_stride; + } + } +} + +static void sdl_rs90_set_scale_frame_functions(sdl_rs90_video_t *vid) +{ + /* Set integer scaling by default */ + vid->scale_frame16 = sdl_rs90_scale_frame16_integer; + vid->scale_frame32 = sdl_rs90_scale_frame32_integer; + + if (!vid->scale_integer) + { + switch (vid->softfilter_type) + { + case DINGUX_RS90_SOFTFILTER_BRESENHAM_HORZ: + vid->scale_frame16 = sdl_rs90_scale_frame16_bresenham_horz; + vid->scale_frame32 = sdl_rs90_scale_frame32_bresenham_horz; + break; + case DINGUX_RS90_SOFTFILTER_POINT: + default: + vid->scale_frame16 = sdl_rs90_scale_frame16_point; + vid->scale_frame32 = sdl_rs90_scale_frame32_point; + break; + } + } +} + +/* Image interpolation END */ static void sdl_rs90_init_font_color(sdl_rs90_video_t *vid) { @@ -496,6 +877,8 @@ static void *sdl_rs90_gfx_init(const video_info_t *video, vid->vsync = video->vsync; vid->keep_aspect = settings->bools.video_dingux_ipu_keep_aspect; vid->scale_integer = settings->bools.video_scale_integer; + vid->softfilter_type = (enum dingux_rs90_softfilter_type) + settings->uints.video_dingux_rs90_softfilter_type; vid->menu_active = false; vid->was_in_menu = false; vid->quitting = false; @@ -520,6 +903,9 @@ static void *sdl_rs90_gfx_init(const video_info_t *video, goto error; } + /* Assign frame scaling function pointers */ + sdl_rs90_set_scale_frame_functions(vid); + return vid; error: @@ -638,82 +1024,6 @@ static void sdl_rs90_set_output( } } -/* Approximate nearest-neighbour scaling using - * bitshifts and integer math */ -static void sdl_rs90_blit_frame16_scale(sdl_rs90_video_t *vid, - uint16_t* src, unsigned width, unsigned height, - unsigned src_pitch) -{ - uint32_t x_step = (((uint32_t)(width) << 16) + 1) / vid->frame_width; - uint32_t y_step = (((uint32_t)(height) << 16) + 1) / vid->frame_height; - - /* 16 bit - divide pitch by 2 */ - size_t in_stride = (size_t)(src_pitch >> 1); - size_t out_stride = (size_t)(vid->screen->pitch >> 1); - - /* Apply x/y padding offset */ - uint16_t *top_corner = (uint16_t*)(vid->screen->pixels) + vid->frame_padding_x + - out_stride * vid->frame_padding_y; - - /* Temporary pointers */ - uint16_t *in_ptr = NULL; - uint16_t *out_ptr = NULL; - - uint32_t y = 0; - size_t row; - - /* TODO/FIXME: Optimize these loops further. - * Consider saving these computations in an array - * and indexing over them. - * Would likely be slower due to cache (non-)locality, - * but it's worth a shot. - * Tons of -> operations. */ - for (row = 0; row < vid->frame_height; row++) - { - size_t col = vid->frame_width; - uint32_t x = 0; - - out_ptr = top_corner + out_stride * row; - in_ptr = src + (y >> 16) * in_stride; - - do - { - *out_ptr = in_ptr[x >> 16]; - x += x_step; - out_ptr++; - } - while (--col); - - y += y_step; - } -} - -static void sdl_rs90_blit_frame16_no_scale(sdl_rs90_video_t *vid, - uint16_t* src, unsigned width, unsigned height, - unsigned src_pitch) -{ - /* 16 bit - divide pitch by 2 */ - size_t in_stride = (size_t)(src_pitch >> 1); - size_t out_stride = (size_t)(vid->screen->pitch >> 1); - - /* Manipulate offsets so that padding/crop - * are applied correctly */ - uint16_t *in_ptr = src + vid->frame_crop_x + vid->frame_crop_y * in_stride; - uint16_t *out_ptr = (uint16_t*)(vid->screen->pixels) + vid->frame_padding_x + - out_stride * vid->frame_padding_y; - - size_t y = vid->frame_height; - - /* TODO/FIXME: Optimize this loop */ - do - { - memcpy(out_ptr, in_ptr, vid->frame_width * sizeof(uint16_t)); - in_ptr += in_stride; - out_ptr += out_stride; - } - while (--y); -} - static void sdl_rs90_blit_frame16(sdl_rs90_video_t *vid, uint16_t* src, unsigned width, unsigned height, unsigned src_pitch) @@ -726,88 +1036,7 @@ static void sdl_rs90_blit_frame16(sdl_rs90_video_t *vid, height == SDL_RS90_HEIGHT) memcpy(vid->screen->pixels, src, src_pitch * SDL_RS90_HEIGHT); else - { - if (vid->scale_integer) - sdl_rs90_blit_frame16_no_scale( - vid, src, width, height, src_pitch); - else - sdl_rs90_blit_frame16_scale( - vid, src, width, height, src_pitch); - } -} - -static void sdl_rs90_blit_frame32_scale(sdl_rs90_video_t *vid, - uint32_t* src, unsigned width, unsigned height, - unsigned src_pitch) -{ - uint32_t x_step = (((uint32_t)(width) << 16) + 1) / vid->frame_width; - uint32_t y_step = (((uint32_t)(height) << 16) + 1) / vid->frame_height; - - /* 32 bit - divide pitch by 4 */ - size_t in_stride = (size_t)(src_pitch >> 2); - size_t out_stride = (size_t)(vid->screen->pitch >> 2); - - /* Apply x/y padding offset */ - uint32_t *top_corner = (uint32_t*)(vid->screen->pixels) + vid->frame_padding_x + - out_stride * vid->frame_padding_y; - - /* Temporary pointers */ - uint32_t *in_ptr = NULL; - uint32_t *out_ptr = NULL; - - uint32_t y = 0; - size_t row; - - /* TODO/FIXME: Optimize these loops further. - * Consider saving these computations in an array - * and indexing over them. - * Would likely be slower due to cache (non-)locality, - * but it's worth a shot. - * Tons of -> operations. */ - for (row = 0; row < vid->frame_height; row++) - { - size_t col = vid->frame_width; - uint32_t x = 0; - - out_ptr = top_corner + out_stride * row; - in_ptr = src + (y >> 16) * in_stride; - - do - { - *out_ptr = in_ptr[x >> 16]; - x += x_step; - out_ptr++; - } - while (--col); - - y += y_step; - } -} - -static void sdl_rs90_blit_frame32_no_scale(sdl_rs90_video_t *vid, - uint32_t* src, unsigned width, unsigned height, - unsigned src_pitch) -{ - /* 32 bit - divide pitch by 4 */ - size_t in_stride = (size_t)(src_pitch >> 2); - size_t out_stride = (size_t)(vid->screen->pitch >> 2); - - /* Manipulate offsets so that padding/crop - * are applied correctly */ - uint32_t *in_ptr = src + vid->frame_crop_x + vid->frame_crop_y * in_stride; - uint32_t *out_ptr = (uint32_t*)(vid->screen->pixels) + vid->frame_padding_x + - out_stride * vid->frame_padding_y; - - size_t y = vid->frame_height; - - /* TODO/FIXME: Optimize this loop */ - do - { - memcpy(out_ptr, in_ptr, vid->frame_width * sizeof(uint32_t)); - in_ptr += in_stride; - out_ptr += out_stride; - } - while (--y); + vid->scale_frame16(vid, src, width, height, src_pitch); } static void sdl_rs90_blit_frame32(sdl_rs90_video_t *vid, @@ -822,14 +1051,7 @@ static void sdl_rs90_blit_frame32(sdl_rs90_video_t *vid, (height == SDL_RS90_HEIGHT)) memcpy(vid->screen->pixels, src, src_pitch * SDL_RS90_HEIGHT); else - { - if (vid->scale_integer) - sdl_rs90_blit_frame32_no_scale( - vid, src, width, height, src_pitch); - else - sdl_rs90_blit_frame32_scale( - vid, src, width, height, src_pitch); - } + vid->scale_frame32(vid, src, width, height, src_pitch); } static bool sdl_rs90_gfx_frame(void *data, const void *frame, @@ -1096,6 +1318,25 @@ static float sdl_rs90_get_refresh_rate(void *data) return 60.0f; } +static void sdl_rs90_set_filtering(void *data, unsigned index, bool smooth, bool ctx_scaling) +{ + sdl_rs90_video_t *vid = (sdl_rs90_video_t*)data; + settings_t *settings = config_get_ptr(); + enum dingux_rs90_softfilter_type softfilter_type = (settings) ? + (enum dingux_rs90_softfilter_type)settings->uints.video_dingux_rs90_softfilter_type : + DINGUX_RS90_SOFTFILTER_POINT; + + if (!vid || !settings) + return; + + /* Update software filter setting, if required */ + if (vid->softfilter_type != softfilter_type) + { + vid->softfilter_type = softfilter_type; + sdl_rs90_set_scale_frame_functions(vid); + } +} + static void sdl_rs90_apply_state_changes(void *data) { sdl_rs90_video_t *vid = (sdl_rs90_video_t*)data; @@ -1112,12 +1353,17 @@ static void sdl_rs90_apply_state_changes(void *data) vid->keep_aspect = keep_aspect; vid->scale_integer = integer_scaling; + /* Reassign frame scaling function pointers */ + sdl_rs90_set_scale_frame_functions(vid); + /* Aspect/scaling changes require all frame * dimension/padding/cropping parameters to * be recalculated. Easiest method is to just - * (re-)set the current output video mode */ + * (re-)set the current output video mode + * Note: If menu is active, colour depth is + * overridden to 16 bit */ sdl_rs90_set_output(vid, vid->content_width, - vid->content_height, vid->rgb32); + vid->content_height, vid->menu_active ? false : vid->rgb32); } } @@ -1132,7 +1378,7 @@ static const video_poke_interface_t sdl_rs90_poke_interface = { NULL, NULL, sdl_rs90_get_refresh_rate, - NULL, /* set_filtering */ + sdl_rs90_set_filtering, NULL, /* get_video_output_size */ NULL, /* get_video_output_prev */ NULL, /* get_video_output_next */ diff --git a/intl/msg_hash_lbl.h b/intl/msg_hash_lbl.h index 8c7aba31ed..fe048346b5 100644 --- a/intl/msg_hash_lbl.h +++ b/intl/msg_hash_lbl.h @@ -3181,6 +3181,12 @@ MSG_HASH( "video_dingux_refresh_rate" ) #endif +#if defined(RS90) +MSG_HASH( + MENU_ENUM_LABEL_VIDEO_DINGUX_RS90_SOFTFILTER_TYPE, + "video_dingux_rs90_softfilter_type" + ) +#endif #endif MSG_HASH( MENU_ENUM_LABEL_VIDEO_BLACK_FRAME_INSERTION, diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index dc77aff722..6cd7527e9c 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -1373,6 +1373,24 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_VIDEO_DINGUX_IPU_FILTER_NEAREST, "Nearest Neighbor" ) +#if defined(RS90) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_DINGUX_RS90_SOFTFILTER_TYPE, + "Image Interpolation" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_DINGUX_RS90_SOFTFILTER_TYPE, + "Specify image interpolation method when 'Integer Scale' is disabled. 'Nearest Neighbor' has the least performance impact." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_DINGUX_RS90_SOFTFILTER_POINT, + "Nearest Neighbor" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_DINGUX_RS90_SOFTFILTER_BRESENHAM_HORZ, + "Semi-Linear" + ) +#endif #endif MSG_HASH( MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_DELAY, diff --git a/menu/cbs/menu_cbs_sublabel.c b/menu/cbs/menu_cbs_sublabel.c index 8195a9da9c..44dc396dcd 100644 --- a/menu/cbs/menu_cbs_sublabel.c +++ b/menu/cbs/menu_cbs_sublabel.c @@ -872,6 +872,9 @@ DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_video_dingux_ipu_filter_type, #if defined(DINGUX_BETA) DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_video_dingux_refresh_rate, MENU_ENUM_SUBLABEL_VIDEO_DINGUX_REFRESH_RATE) #endif +#if defined(RS90) +DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_video_dingux_rs90_softfilter_type, MENU_ENUM_SUBLABEL_VIDEO_DINGUX_RS90_SOFTFILTER_TYPE) +#endif #endif DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_video_viewport_custom_height, MENU_ENUM_SUBLABEL_VIDEO_VIEWPORT_CUSTOM_HEIGHT) DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_video_viewport_custom_width, MENU_ENUM_SUBLABEL_VIDEO_VIEWPORT_CUSTOM_WIDTH) @@ -1968,6 +1971,11 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs, BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_video_dingux_refresh_rate); break; #endif +#if defined(RS90) + case MENU_ENUM_LABEL_VIDEO_DINGUX_RS90_SOFTFILTER_TYPE: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_video_dingux_rs90_softfilter_type); + break; +#endif #endif case MENU_ENUM_LABEL_CORE_INFORMATION: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_core_information); diff --git a/menu/menu_defines.h b/menu/menu_defines.h index 939ead32d1..e9698558c2 100644 --- a/menu/menu_defines.h +++ b/menu/menu_defines.h @@ -416,6 +416,15 @@ enum quit_on_close_content_type QUIT_ON_CLOSE_CONTENT_LAST }; +#if defined(DINGUX) && defined(RS90) +enum dingux_rs90_softfilter_type +{ + DINGUX_RS90_SOFTFILTER_POINT = 0, + DINGUX_RS90_SOFTFILTER_BRESENHAM_HORZ, + DINGUX_RS90_SOFTFILTER_LAST +}; +#endif + RETRO_END_DECLS #endif diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index c972e8696b..7aded472b3 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -6028,6 +6028,12 @@ unsigned menu_displaylist_build_list( MENU_ENUM_LABEL_VIDEO_DINGUX_IPU_FILTER_TYPE, PARSE_ONLY_UINT, false) == 0) count++; +#if defined(RS90) + if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(list, + MENU_ENUM_LABEL_VIDEO_DINGUX_RS90_SOFTFILTER_TYPE, + PARSE_ONLY_UINT, false) == 0) + count++; +#endif #endif if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(list, MENU_ENUM_LABEL_VIDEO_SHADER_DELAY, diff --git a/menu/menu_setting.c b/menu/menu_setting.c index bc50449ed5..2cc00060de 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -5200,6 +5200,32 @@ static void setting_get_string_representation_uint_video_dingux_refresh_rate( } } #endif + +#if defined(RS90) +static void setting_get_string_representation_uint_video_dingux_rs90_softfilter_type( + rarch_setting_t *setting, + char *s, size_t len) +{ + if (!setting) + return; + + switch (*setting->value.target.unsigned_integer) + { + case DINGUX_RS90_SOFTFILTER_POINT: + strlcpy(s, + msg_hash_to_str( + MENU_ENUM_LABEL_VALUE_VIDEO_DINGUX_RS90_SOFTFILTER_POINT), + len); + break; + case DINGUX_RS90_SOFTFILTER_BRESENHAM_HORZ: + strlcpy(s, + msg_hash_to_str( + MENU_ENUM_LABEL_VALUE_VIDEO_DINGUX_RS90_SOFTFILTER_BRESENHAM_HORZ), + len); + break; + } +} +#endif #endif static void setting_get_string_representation_uint_input_auto_game_focus( @@ -7615,10 +7641,14 @@ static void general_write_handler(rarch_setting_t *setting) case MENU_ENUM_LABEL_VIDEO_CTX_SCALING: #if defined(DINGUX) case MENU_ENUM_LABEL_VIDEO_DINGUX_IPU_FILTER_TYPE: +#if defined(RS90) + case MENU_ENUM_LABEL_VIDEO_DINGUX_RS90_SOFTFILTER_TYPE: +#endif #endif { settings_t *settings = config_get_ptr(); - video_driver_set_filtering(1, settings->bools.video_ctx_scaling, settings->bools.video_ctx_scaling); + video_driver_set_filtering(1, settings->bools.video_smooth, + settings->bools.video_ctx_scaling); } break; case MENU_ENUM_LABEL_VIDEO_ROTATION: @@ -11482,7 +11512,28 @@ static bool setting_append_list( menu_settings_list_current_add_range(list, list_info, 0, DINGUX_IPU_FILTER_LAST - 1, 1, true, true); (*list)[list_info->index - 1].ui_type = ST_UI_TYPE_UINT_COMBOBOX; } - else if (!string_is_equal(settings->arrays.video_driver, "sdl_rs90")) +#if defined(RS90) + else if (string_is_equal(settings->arrays.video_driver, "sdl_rs90")) + { + CONFIG_UINT( + list, list_info, + &settings->uints.video_dingux_rs90_softfilter_type, + MENU_ENUM_LABEL_VIDEO_DINGUX_RS90_SOFTFILTER_TYPE, + MENU_ENUM_LABEL_VALUE_VIDEO_DINGUX_RS90_SOFTFILTER_TYPE, + DEFAULT_DINGUX_RS90_SOFTFILTER_TYPE, + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler); + (*list)[list_info->index - 1].action_ok = &setting_action_ok_uint; + (*list)[list_info->index - 1].get_string_representation = + &setting_get_string_representation_uint_video_dingux_rs90_softfilter_type; + menu_settings_list_current_add_range(list, list_info, 0, DINGUX_RS90_SOFTFILTER_LAST - 1, 1, true, true); + (*list)[list_info->index - 1].ui_type = ST_UI_TYPE_UINT_COMBOBOX; + } +#endif + else #endif { CONFIG_BOOL( diff --git a/msg_hash.h b/msg_hash.h index 0f9f8c35df..ea724912dd 100644 --- a/msg_hash.h +++ b/msg_hash.h @@ -2474,6 +2474,12 @@ enum msg_hash_enums MENU_ENUM_LABEL_VALUE_VIDEO_DINGUX_REFRESH_RATE_60HZ, MENU_ENUM_LABEL_VALUE_VIDEO_DINGUX_REFRESH_RATE_50HZ, #endif +#if defined(RS90) + MENU_LABEL(VIDEO_DINGUX_RS90_SOFTFILTER_TYPE), + + MENU_ENUM_LABEL_VALUE_VIDEO_DINGUX_RS90_SOFTFILTER_POINT, + MENU_ENUM_LABEL_VALUE_VIDEO_DINGUX_RS90_SOFTFILTER_BRESENHAM_HORZ, +#endif #endif MENU_LABEL(VIDEO_VFILTER), MENU_LABEL(VIDEO_GPU_RECORD), From 7f411db808a686ac5e201e398a75dbdc79ea048f Mon Sep 17 00:00:00 2001 From: Francisco Javier Trujillo Mata Date: Thu, 22 Jul 2021 00:03:18 +0200 Subject: [PATCH 57/58] Use BDM for increasing up USB speed --- Makefile.ps2 | 2 +- Makefile.ps2.salamander | 3 ++- frontend/drivers/platform_ps2.c | 4 +++- ps2/include/ps2_irx_variables.h | 10 ++++++++-- ps2/irx/Makefile | 3 ++- 5 files changed, 16 insertions(+), 6 deletions(-) diff --git a/Makefile.ps2 b/Makefile.ps2 index 2877840d3c..7e4f58b2bd 100644 --- a/Makefile.ps2 +++ b/Makefile.ps2 @@ -50,7 +50,7 @@ CFLAGS += $(RARCH_DEFINES) # All the IRX objects EE_OBJS += $(IRX_DIR)/sio2man_irx.o $ $(IRX_DIR)/iomanX_irx.o $(IRX_DIR)/fileXio_irx.o EE_OBJS += $(IRX_DIR)/mcman_irx.o $(IRX_DIR)/mcserv_irx.o -EE_OBJS += $(IRX_DIR)/usbd_irx.o $(IRX_DIR)/usbhdfsd_irx.o +EE_OBJS += $(IRX_DIR)/usbd_irx.o $(IRX_DIR)/bdm_irx.o $(IRX_DIR)/bdmfs_vfat_irx.o $(IRX_DIR)/usbmass_bd_irx.o EE_OBJS += $(IRX_DIR)/libsd_irx.o $(IRX_DIR)/audsrv_irx.o EE_OBJS += $(IRX_DIR)/cdfs_irx.o EE_OBJS += $(IRX_DIR)/mtapman_irx.o $(IRX_DIR)/padman_irx.o diff --git a/Makefile.ps2.salamander b/Makefile.ps2.salamander index 85cdb10895..80ea5b55d0 100644 --- a/Makefile.ps2.salamander +++ b/Makefile.ps2.salamander @@ -61,7 +61,8 @@ EE_OBJS = frontend/frontend_salamander.o \ # Needed IRX objects EE_OBJS += $(IRX_DIR)/sio2man_irx.o $ $(IRX_DIR)/iomanX_irx.o $(IRX_DIR)/fileXio_irx.o -EE_OBJS += $(IRX_DIR)/mcman_irx.o $(IRX_DIR)/mcserv_irx.o $(IRX_DIR)/usbd_irx.o $(IRX_DIR)/usbhdfsd_irx.o +EE_OBJS += $(IRX_DIR)/mcman_irx.o $(IRX_DIR)/mcserv_irx.o +EE_OBJS += $(IRX_DIR)/usbd_irx.o $(IRX_DIR)/bdm_irx.o $(IRX_DIR)/bdmfs_vfat_irx.o $(IRX_DIR)/usbmass_bd_irx.o EE_OBJS += $(IRX_DIR)/cdfs_irx.o EE_CFLAGS = $(CFLAGS) diff --git a/frontend/drivers/platform_ps2.c b/frontend/drivers/platform_ps2.c index 9014416bf3..40059c6687 100644 --- a/frontend/drivers/platform_ps2.c +++ b/frontend/drivers/platform_ps2.c @@ -127,7 +127,9 @@ static void load_modules() /* USB */ SifExecModuleBuffer(&usbd_irx, size_usbd_irx, 0, NULL, NULL); - SifExecModuleBuffer(&usbhdfsd_irx, size_usbhdfsd_irx, 0, NULL, NULL); + SifExecModuleBuffer(&bdm_irx, size_bdm_irx, 0, NULL, NULL); + SifExecModuleBuffer(&bdmfs_vfat_irx, size_bdmfs_vfat_irx, 0, NULL, NULL); + SifExecModuleBuffer(&usbmass_bd_irx, size_usbmass_bd_irx, 0, NULL, NULL); #if !defined(DEBUG) /* CDFS */ diff --git a/ps2/include/ps2_irx_variables.h b/ps2/include/ps2_irx_variables.h index 5696213422..51455e0ea9 100644 --- a/ps2/include/ps2_irx_variables.h +++ b/ps2/include/ps2_irx_variables.h @@ -51,8 +51,14 @@ extern unsigned int size_ps2fs_irx; extern unsigned char usbd_irx; extern unsigned int size_usbd_irx; -extern unsigned char usbhdfsd_irx; -extern unsigned int size_usbhdfsd_irx; +extern unsigned char bdm_irx; +extern unsigned int size_bdm_irx; + +extern unsigned char bdmfs_vfat_irx; +extern unsigned int size_bdmfs_vfat_irx; + +extern unsigned char usbmass_bd_irx; +extern unsigned int size_usbmass_bd_irx; extern unsigned char cdfs_irx; extern unsigned int size_cdfs_irx; diff --git a/ps2/irx/Makefile b/ps2/irx/Makefile index 26997ee593..916ee60f95 100644 --- a/ps2/irx/Makefile +++ b/ps2/irx/Makefile @@ -4,7 +4,8 @@ IRX_DIR = $(PS2SDK)/iop/irx #IRX modules # IRX modules - modules have to be in IRX_DIR -IRX_FILES += iomanX.irx fileXio.irx sio2man.irx mtapman.irx padman.irx mcman.irx mcserv.irx usbd.irx usbhdfsd.irx +IRX_FILES += iomanX.irx fileXio.irx sio2man.irx mtapman.irx padman.irx mcman.irx mcserv.irx +IRX_FILES += usbd.irx bdm.irx bdmfs_vfat.irx usbmass_bd.irx IRX_FILES += libsd.irx audsrv.irx cdfs.irx IRX_C_FILES = $(IRX_FILES:.irx=_irx.c) From fdee0f4e7e2fd2394fc6aace807fe294eb6dc5b0 Mon Sep 17 00:00:00 2001 From: Remi McGill Date: Thu, 22 Jul 2021 10:20:50 -0400 Subject: [PATCH 58/58] Max_Shader_Parameters_Increased_to_1024 --- gfx/video_shader_parse.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gfx/video_shader_parse.h b/gfx/video_shader_parse.h index 5399f35f7a..4e41c35e08 100644 --- a/gfx/video_shader_parse.h +++ b/gfx/video_shader_parse.h @@ -34,7 +34,7 @@ RETRO_BEGIN_DECLS #endif #ifndef GFX_MAX_PARAMETERS -#define GFX_MAX_PARAMETERS 512 +#define GFX_MAX_PARAMETERS 1024 #endif #ifndef GFX_MAX_FRAME_HISTORY