diff --git a/.gitignore b/.gitignore
index 1751df64bf..d7e042e383 100644
--- a/.gitignore
+++ b/.gitignore
@@ -188,3 +188,6 @@ gfx/common/wayland/xdg-decoration-unstable-v1.h
gfx/common/wayland/xdg-decoration-unstable-v1.c
gfx/common/wayland/xdg-shell.c
gfx/common/wayland/xdg-shell.h
+
+# DINGUX
+*.opk
diff --git a/Makefile.common b/Makefile.common
index d16715567d..df2a896cc2 100644
--- a/Makefile.common
+++ b/Makefile.common
@@ -1183,6 +1183,10 @@ ifeq ($(TARGET), retroarch_orbis)
frontend/drivers/platform_orbis.o
endif
+ifeq ($(DINGUX), 1)
+ OBJ += dingux/dingux_utils.o
+endif
+
ifeq ($(HAVE_WAYLAND), 1)
OBJ += gfx/drivers_context/wayland_ctx.o \
input/common/wayland_common.o \
@@ -2328,7 +2332,7 @@ endif
### Android Play Feature Delivery ###
### (Play Store build core ###
### downloader) ###
-###############WIP###################
+#####################################
ifeq ($(ANDROID), 1)
OBJ += play_feature_delivery/play_feature_delivery.o
endif
diff --git a/Makefile.dingux b/Makefile.dingux
index a15d641193..1043eaa3f0 100644
--- a/Makefile.dingux
+++ b/Makefile.dingux
@@ -4,6 +4,7 @@ PACKAGE_NAME = retroarch
DEBUG ?= 0
+DINGUX = 1
HAVE_SCREENSHOTS = 1
HAVE_REWIND = 1
HAVE_7ZIP = 1
diff --git a/Makefile.rg350 b/Makefile.rg350
new file mode 100644
index 0000000000..518f02ad02
--- /dev/null
+++ b/Makefile.rg350
@@ -0,0 +1,189 @@
+TOOLCHAIN_DIR=/opt/gcw0-toolchain/usr/bin
+CC = $(TOOLCHAIN_DIR)/mipsel-gcw0-linux-uclibc-gcc
+CXX = $(TOOLCHAIN_DIR)/mipsel-gcw0-linux-uclibc-g++
+PACKAGE_NAME = retroarch
+
+DEBUG ?= 0
+
+DINGUX = 1
+HAVE_SCREENSHOTS = 0
+HAVE_REWIND = 1
+HAVE_7ZIP = 1
+HAVE_AL = 1
+# ALSA freezes when switching back from menu
+HAVE_ALSA = 0
+HAVE_DSP_FILTER = 1
+HAVE_VIDEO_FILTER = 1
+HAVE_STATIC_VIDEO_FILTERS = 1
+HAVE_STATIC_AUDIO_FILTERS = 1
+HAVE_FILTERS_BUILTIN = 1
+HAVE_BUILTINMBEDTLS = 1
+HAVE_BUILTINZLIB = 1
+HAVE_C99 = 1
+HAVE_CC = 1
+HAVE_CC_RESAMPLER = 1
+HAVE_CHD = 1
+HAVE_COMMAND = 1
+HAVE_CXX = 1
+HAVE_DR_MP3 = 1
+HAVE_DYNAMIC = 1
+HAVE_EGL = 0
+HAVE_FREETYPE = 0
+HAVE_GDI = 1
+HAVE_GETADDRINFO = 1
+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 = 1
+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 = 1
+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
+
+OS = Linux
+TARGET = retroarch
+OPK_NAME = retroarch_rg350.opk
+
+OBJ :=
+LINK := $(CXX)
+DEF_FLAGS := -march=mips32 -mtune=mips32r2 -mhard-float -ffast-math -fomit-frame-pointer -fdata-sections
+DEF_FLAGS += -I. -Ideps -Ideps/stb -DDINGUX=1 -MMD
+DEF_FLAGS += -Wall -Wno-unused-variable
+DEF_FLAGS += -std=gnu99 -D_GNU_SOURCE
+LIBS := -ldl -lz -lrt -lcrypto -lssl -ludev -pthread
+CFLAGS :=
+CXXFLAGS := -fno-exceptions -fno-rtti -std=c++11 -D__STDC_CONSTANT_MACROS
+ASFLAGS :=
+LDFLAGS := -flto
+INCLUDE_DIRS = -I/opt/gcw0-toolchain/usr/mipsel-gcw0-linux-uclibc/sysroot/usr/include
+LIBRARY_DIRS = -L/opt/gcw0-toolchain/usr/mipsel-gcw0-linux-uclibc/sysroot/usr/lib
+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_AL=1
+DEFINES += -DHAVE_FILTERS_BUILTIN
+DEFINES += -DHAVE_UDEV=1
+
+SDL_DINGUX_CFLAGS := $(shell /opt/gcw0-toolchain/usr/mipsel-gcw0-linux-uclibc/sysroot/usr/bin/sdl-config --cflags)
+SDL_DINGUX_LIBS := $(shell /opt/gcw0-toolchain/usr/mipsel-gcw0-linux-uclibc/sysroot/usr/bin/sdl-config --libs)
+FREETYPE_CFLAGS := $(shell /opt/gcw0-toolchain/usr/mipsel-gcw0-linux-uclibc/sysroot/usr/bin/freetype-config --cflags)
+FREETYPE_LIBS := $(shell /opt/gcw0-toolchain/usr/mipsel-gcw0-linux-uclibc/sysroot/usr/bin/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 += -O2 -DNDEBUG
+endif
+
+include Makefile.common
+
+DEF_FLAGS += $(INCLUDE_DIRS)
+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=Retroarch
+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 $@),)
+ $(LINK) -o $@ $(RARCH_OBJ) $(LIBS) $(LDFLAGS) $(LIBRARY_DIRS)
+
+$(OBJDIR)/%.o: %.c
+ @mkdir -p $(dir $@)
+ @$(if $(Q), $(shell echo echo CC $<),)
+ $(CC) $(CPPFLAGS) $(CFLAGS) $(DEFINES) -c -o $@ $<
+
+$(OBJDIR)/%.o: %.cpp
+ @mkdir -p $(dir $@)
+ @$(if $(Q), $(shell echo echo CXX $<),)
+ $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(DEFINES) -MMD -c -o $@ $<
+
+$(OBJDIR)/%.o: %.m
+ @mkdir -p $(dir $@)
+ @$(if $(Q), $(shell echo echo OBJC $<),)
+ $(CXX) $(OBJCFLAGS) $(DEFINES) -MMD -c -o $@ $<
+
+$(OBJDIR)/%.o: %.S $(HEADERS)
+ @mkdir -p $(dir $@)
+ @$(if $(Q), $(shell echo echo AS $<),)
+ $(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.gcw0.desktop
+ rm -f $(OPK_NAME)
+ cp media/ico_src/icon32.png retroarch.png
+ $(TOOLCHAIN_DIR)/mksquashfs retroarch default.gcw0.desktop retroarch.png $(OPK_NAME) -all-root -no-xattrs -noappend -no-exports
+ rm -f default.gcw0.desktop retroarch.png
+
+.PHONY: all clean opk
+
+print-%:
+ @echo '$*=$($*)'
diff --git a/config.def.h b/config.def.h
index e499f59495..6da2493a3c 100644
--- a/config.def.h
+++ b/config.def.h
@@ -177,8 +177,9 @@
/* To start in Fullscreen, or not. */
-#ifdef HAVE_STEAM
-/* Start in fullscreen mode for Steam build */
+#if defined(HAVE_STEAM) || defined(DINGUX)
+/* Start in fullscreen mode for Steam and
+ * Dingux builds */
#define DEFAULT_FULLSCREEN true
#else
#define DEFAULT_FULLSCREEN false
@@ -199,8 +200,13 @@
/* Fullscreen resolution. A value of 0 uses the desktop
* resolution. */
+#if defined(DINGUX)
+#define DEFAULT_FULLSCREEN_X 320
+#define DEFAULT_FULLSCREEN_Y 240
+#else
#define DEFAULT_FULLSCREEN_X 0
#define DEFAULT_FULLSCREEN_Y 0
+#endif
/* Number of threads to use for video recording */
#define DEFAULT_VIDEO_RECORD_THREADS 2
@@ -355,6 +361,12 @@
#define DEFAULT_ASPECT_RATIO_IDX ASPECT_RATIO_CORE
#endif
+#if defined(DINGUX)
+/* Enables aspect ratio correction (1:1 PAR) when
+ * using the IPU hardware scaler in Dingux devices */
+#define DEFAULT_DINGUX_IPU_KEEP_ASPECT true
+#endif
+
/* Save configuration file on exit. */
#define DEFAULT_CONFIG_SAVE_ON_EXIT true
diff --git a/configuration.c b/configuration.c
index f5f0898b14..ed2ff4137f 100644
--- a/configuration.c
+++ b/configuration.c
@@ -522,10 +522,9 @@ static const enum location_driver_enum LOCATION_DEFAULT_DRIVER = LOCATION_ANDROI
static const enum location_driver_enum LOCATION_DEFAULT_DRIVER = LOCATION_NULL;
#endif
-#if defined(_3DS) && defined(HAVE_RGUI)
+#if (defined(_3DS) || defined(DINGUX)) && defined(HAVE_RGUI)
static const enum menu_driver_enum MENU_DEFAULT_DRIVER = MENU_RGUI;
-#else
-#if defined(HAVE_MATERIALUI) && defined(RARCH_MOBILE)
+#elif defined(HAVE_MATERIALUI) && defined(RARCH_MOBILE)
static const enum menu_driver_enum MENU_DEFAULT_DRIVER = MENU_MATERIALUI;
#elif defined(HAVE_OZONE)
static const enum menu_driver_enum MENU_DEFAULT_DRIVER = MENU_OZONE;
@@ -536,7 +535,6 @@ static const enum menu_driver_enum MENU_DEFAULT_DRIVER = MENU_RGUI;
#else
static const enum menu_driver_enum MENU_DEFAULT_DRIVER = MENU_NULL;
#endif
-#endif
/* All config related settings go here. */
@@ -1458,6 +1456,9 @@ static struct config_bool_setting *populate_settings_bool(
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);
+#if defined(DINGUX)
+ SETTING_BOOL("video_dingux_ipu_keep_aspect", &settings->bools.video_dingux_ipu_keep_aspect, true, DEFAULT_DINGUX_IPU_KEEP_ASPECT, false);
+#endif
SETTING_BOOL("video_threaded", video_driver_get_threaded(), true, DEFAULT_VIDEO_THREADED, false);
SETTING_BOOL("video_shared_context", &settings->bools.video_shared_context, true, DEFAULT_VIDEO_SHARED_CONTEXT, false);
SETTING_BOOL("auto_screenshot_filename", &settings->bools.auto_screenshot_filename, true, DEFAULT_AUTO_SCREENSHOT_FILENAME, false);
diff --git a/configuration.h b/configuration.h
index da6bec10b7..1ef32db9a8 100644
--- a/configuration.h
+++ b/configuration.h
@@ -455,6 +455,7 @@ typedef struct settings
bool video_force_aspect;
bool video_crop_overscan;
bool video_aspect_ratio_auto;
+ bool video_dingux_ipu_keep_aspect;
bool video_scale_integer;
bool video_shader_enable;
bool video_shader_watch_files;
diff --git a/dingux/dingux_utils.c b/dingux/dingux_utils.c
new file mode 100644
index 0000000000..f7c6ce46d6
--- /dev/null
+++ b/dingux/dingux_utils.c
@@ -0,0 +1,97 @@
+/* RetroArch - A frontend for libretro.
+ * Copyright (C) 2010-2014 - Hans-Kristian Arntzen
+ * Copyright (C) 2011-2017 - Daniel De Matteis
+ * Copyright (C) 2019-2020 - 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-
+ * 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 "dingux_utils.h"
+
+#define DINGUX_ALLOW_DOWNSCALING_FILE "/sys/devices/platform/jz-lcd.0/allow_downscaling"
+#define DINGUX_KEEP_ASPECT_RATIO_FILE "/sys/devices/platform/jz-lcd.0/keep_aspect_ratio"
+#define DINGUX_BATTERY_CAPACITY_FILE "/sys/class/power_supply/battery/capacity"
+
+/* Enables/disables downscaling when using
+ * the IPU hardware scaler */
+bool dingux_ipu_set_downscaling_enable(bool enable)
+{
+ const char *path = DINGUX_ALLOW_DOWNSCALING_FILE;
+ const char *enable_str = enable ? "1" : "0";
+
+ /* Check whether file exists */
+ if (!path_is_valid(path))
+ return false;
+
+ /* Write enable state to file */
+ return filestream_write_file(
+ path, enable_str, 1);
+}
+
+/* Enables/disables aspect ratio correction
+ * (1:1 PAR) when using the IPU hardware
+ * scaler (disabling this will stretch the
+ * image to the full screen dimensions) */
+bool dingux_ipu_set_aspect_ratio_enable(bool enable)
+{
+ const char *path = DINGUX_KEEP_ASPECT_RATIO_FILE;
+ const char *enable_str = enable ? "1" : "0";
+
+ /* Check whether file exists */
+ if (!path_is_valid(path))
+ return false;
+
+ /* Write enable state to file */
+ return filestream_write_file(
+ path, enable_str, 1);
+}
+
+/* Fetches internal battery level */
+int dingux_get_battery_level(void)
+{
+ const char *path = DINGUX_BATTERY_CAPACITY_FILE;
+ int64_t file_len = 0;
+ char *file_buf = NULL;
+ int battery_level = 0;
+
+ /* Check whether file exists */
+ if (!path_is_valid(path))
+ goto error;
+
+ /* Read file */
+ if (!filestream_read_file(path, (void**)&file_buf, &file_len) ||
+ (file_len == 0))
+ goto error;
+
+ /* Convert to integer */
+ if (file_buf)
+ {
+ battery_level = atoi(file_buf);
+
+ free(file_buf);
+ file_buf = NULL;
+ }
+
+ return battery_level;
+
+error:
+ if (file_buf)
+ {
+ free(file_buf);
+ file_buf = NULL;
+ }
+
+ return -1;
+}
diff --git a/dingux/dingux_utils.h b/dingux/dingux_utils.h
new file mode 100644
index 0000000000..12bfd18b20
--- /dev/null
+++ b/dingux/dingux_utils.h
@@ -0,0 +1,43 @@
+/* RetroArch - A frontend for libretro.
+ * Copyright (C) 2010-2014 - Hans-Kristian Arntzen
+ * Copyright (C) 2011-2017 - Daniel De Matteis
+ * Copyright (C) 2019-2020 - 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-
+ * 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 .
+ */
+
+#ifndef _DINGUX_UTILS_H
+#define _DINGUX_UTILS_H
+
+#include
+#include
+
+#include
+
+RETRO_BEGIN_DECLS
+
+/* Enables/disables downscaling when using
+ * the IPU hardware scaler */
+bool dingux_ipu_set_downscaling_enable(bool enable);
+
+/* Enables/disables aspect ratio correction
+ * (1:1 PAR) when using the IPU hardware
+ * scaler (disabling this will stretch the
+ * image to the full screen dimensions) */
+bool dingux_ipu_set_aspect_ratio_enable(bool enable);
+
+/* Fetches internal battery level */
+int dingux_get_battery_level(void);
+
+RETRO_END_DECLS
+
+#endif
diff --git a/file_path_special.c b/file_path_special.c
index 76a5ebebd9..2e4fa2a791 100644
--- a/file_path_special.c
+++ b/file_path_special.c
@@ -103,6 +103,14 @@ bool fill_pathname_application_data(char *s, size_t len)
"Library/Application Support/RetroArch", len);
return true;
}
+#elif defined(DINGUX)
+ const char *appdata = getenv("HOME");
+
+ if (appdata)
+ {
+ fill_pathname_join(s, appdata, "/.retroarch", 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 057c87abba..0ea769a5c0 100644
--- a/frontend/drivers/platform_unix.c
+++ b/frontend/drivers/platform_unix.c
@@ -56,6 +56,10 @@
#include
#endif
+#if defined(DINGUX)
+#include "../../dingux/dingux_utils.h"
+#endif
+
#include
#include
#include
@@ -121,6 +125,7 @@ static char unix_cpu_model_name[64] = {0};
/* /proc/meminfo parameters */
#define PROC_MEMINFO_PATH "/proc/meminfo"
+#define PROC_MEMINFO_MEM_TOTAL_TAG "MemTotal:"
#define PROC_MEMINFO_MEM_AVAILABLE_TAG "MemAvailable:"
#define PROC_MEMINFO_MEM_FREE_TAG "MemFree:"
#define PROC_MEMINFO_BUFFERS_TAG "Buffers:"
@@ -1176,7 +1181,7 @@ static enum frontend_powerstate frontend_unix_get_powerstate(
{
enum frontend_powerstate ret = FRONTEND_POWERSTATE_NONE;
-#ifdef ANDROID
+#if defined(ANDROID)
jint powerstate = ret;
jint battery_level = 0;
JNIEnv *env = jni_thread_getenv();
@@ -1195,6 +1200,25 @@ static enum frontend_powerstate frontend_unix_get_powerstate(
*percent = battery_level;
ret = (enum frontend_powerstate)powerstate;
+#elif defined(DINGUX)
+ /* Dingux seems to have limited battery
+ * reporting capability - if we get a valid
+ * integer here, just assume that state is
+ * FRONTEND_POWERSTATE_ON_POWER_SOURCE
+ * (since most dingux devices are not meant
+ * to be used while charging...) */
+ int battery_level = dingux_get_battery_level();
+
+ if (battery_level < 0)
+ *percent = -1;
+ else
+ {
+ *percent = battery_level;
+ ret = FRONTEND_POWERSTATE_ON_POWER_SOURCE;
+ }
+
+ /* 'Time left' reporting is unsupported */
+ *seconds = -1;
#else
if (frontend_unix_powerstate_check_acpi_sysfs(&ret, seconds, percent))
return ret;
@@ -1737,7 +1761,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");
@@ -2030,7 +2058,11 @@ 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
}
if(!string_is_empty(base_path))
@@ -2141,9 +2173,42 @@ static void frontend_unix_exitspawn(char *s, size_t len, char *args)
static uint64_t frontend_unix_get_mem_total(void)
{
+#if defined(DINGUX)
+ char line[256];
+ unsigned long mem_total = 0;
+ FILE* meminfo_file = NULL;
+
+ line[0] = '\0';
+
+ /* Open /proc/meminfo */
+ meminfo_file = fopen(PROC_MEMINFO_PATH, "r");
+
+ if (!meminfo_file)
+ return 0;
+
+ /* Parse lines
+ * (Note: virtual filesystem, so don't have to
+ * worry about buffering file reads) */
+ while (fgets(line, sizeof(line), meminfo_file))
+ {
+ if (string_starts_with_size(line, PROC_MEMINFO_MEM_TOTAL_TAG,
+ STRLEN_CONST(PROC_MEMINFO_MEM_TOTAL_TAG)))
+ {
+ sscanf(line, PROC_MEMINFO_MEM_TOTAL_TAG " %lu kB", &mem_total);
+ break;
+ }
+ }
+
+ /* Close /proc/meminfo */
+ fclose(meminfo_file);
+ meminfo_file = NULL;
+
+ return (uint64_t)mem_total * 1024;
+#else
uint64_t pages = sysconf(_SC_PHYS_PAGES);
uint64_t page_size = sysconf(_SC_PAGE_SIZE);
return pages * page_size;
+#endif
}
static uint64_t frontend_unix_get_mem_free(void)
diff --git a/gfx/drivers/sdl_dingux_gfx.c b/gfx/drivers/sdl_dingux_gfx.c
index aa4fe6d874..10791cc6e2 100644
--- a/gfx/drivers/sdl_dingux_gfx.c
+++ b/gfx/drivers/sdl_dingux_gfx.c
@@ -18,10 +18,14 @@
#include
#include
+#include
+#include
+
#include
#include
#include
-#include "../../verbosity.h"
+#include
+#include
#ifdef HAVE_CONFIG_H
#include "../../config.h"
@@ -31,50 +35,259 @@
#include "../../menu/menu_driver.h"
#endif
-#include
-#include
+#include "../../dingux/dingux_utils.h"
+#include "../../verbosity.h"
+#include "../../gfx/drivers_font_renderer/bitmap.h"
#include "../../configuration.h"
#include "../../retroarch.h"
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
+#define SDL_DINGUX_MENU_WIDTH 320
+#define SDL_DINGUX_MENU_HEIGHT 240
+
+#define SDL_DINGUX_NUM_FONT_GLYPHS 256
+
#define VERBOSE 0
typedef struct sdl_dingux_video
{
- bool rgb;
+ SDL_Surface *screen;
+ uint32_t font_colour32;
+ uint16_t font_colour16;
+ uint16_t menu_texture[SDL_DINGUX_MENU_WIDTH * SDL_DINGUX_MENU_HEIGHT];
+ bool font_lut[SDL_DINGUX_NUM_FONT_GLYPHS][FONT_WIDTH * FONT_HEIGHT];
+ bool rgb32;
+ bool vsync;
bool menu_active;
bool was_in_menu;
bool quitting;
- char menu_frame[320*240*32];
- SDL_Surface *screen;
} sdl_dingux_video_t;
+static void sdl_dingux_init_font_color(sdl_dingux_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_dingux_init_font_lut(sdl_dingux_video_t *vid)
+{
+ size_t symbol_index;
+ size_t i, j;
+
+ /* Loop over all possible characters */
+ for (symbol_index = 0;
+ symbol_index < SDL_DINGUX_NUM_FONT_GLYPHS;
+ symbol_index++)
+ {
+ for (j = 0; j < FONT_HEIGHT; j++)
+ {
+ for (i = 0; i < FONT_WIDTH; i++)
+ {
+ uint8_t rem = 1 << ((i + j * FONT_WIDTH) & 7);
+ unsigned offset = (i + j * FONT_WIDTH) >> 3;
+
+ /* LUT value is 'true' if specified glyph
+ * position contains a pixel */
+ vid->font_lut[symbol_index][i + (j * FONT_WIDTH)] =
+ (bitmap_bin[FONT_OFFSET(symbol_index) + offset] & rem) > 0;
+ }
+ }
+ }
+}
+
+static void sdl_dingux_blit_text16(
+ sdl_dingux_video_t *vid,
+ unsigned x, unsigned y,
+ const char *str)
+{
+ uint16_t *screen_buf = (uint16_t*)vid->screen->pixels;
+ /* 16 bit - divide pitch by 2 */
+ uint16_t screen_stride = (uint16_t)(vid->screen->pitch >> 1);
+ uint16_t screen_width = vid->screen->w;
+ uint16_t screen_height = vid->screen->h;
+ 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 + FONT_HEIGHT + 1 >= screen_height)
+ return;
+
+ while (!string_is_empty(str))
+ {
+ /* Check for out of bounds x coordinates */
+ if (x + FONT_WIDTH_STRIDE + 1 >= screen_width)
+ return;
+
+ /* Deal with spaces first, for efficiency */
+ if (*str == ' ')
+ str++;
+ else
+ {
+ uint16_t i, j;
+ 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_DINGUX_NUM_FONT_GLYPHS)
+ continue;
+
+ for (j = 0; j < FONT_HEIGHT; j++)
+ {
+ uint32_t buff_offset = ((y + j) * screen_stride) + x;
+
+ for (i = 0; i < FONT_WIDTH; i++)
+ {
+ if (vid->font_lut[symbol][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 += FONT_WIDTH_STRIDE;
+ }
+}
+
+static void sdl_dingux_blit_text32(
+ sdl_dingux_video_t *vid,
+ unsigned x, unsigned y,
+ const char *str)
+{
+ uint32_t *screen_buf = (uint32_t*)vid->screen->pixels;
+ /* 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;
+ 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 + FONT_HEIGHT + 1 >= screen_height)
+ return;
+
+ while (!string_is_empty(str))
+ {
+ /* Check for out of bounds x coordinates */
+ if (x + FONT_WIDTH_STRIDE + 1 >= screen_width)
+ return;
+
+ /* Deal with spaces first, for efficiency */
+ if (*str == ' ')
+ str++;
+ else
+ {
+ uint32_t i, j;
+ 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_DINGUX_NUM_FONT_GLYPHS)
+ continue;
+
+ for (j = 0; j < FONT_HEIGHT; j++)
+ {
+ uint32_t buff_offset = ((y + j) * screen_stride) + x;
+
+ for (i = 0; i < FONT_WIDTH; i++)
+ {
+ if (vid->font_lut[symbol][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 += FONT_WIDTH_STRIDE;
+ }
+}
+
static void sdl_dingux_gfx_free(void *data)
{
sdl_dingux_video_t *vid = (sdl_dingux_video_t*)data;
+
if (!vid)
return;
SDL_QuitSubSystem(SDL_INIT_VIDEO);
+ /* It is good manners to leave IPU aspect
+ * ratio scaling enabled when shutting down */
+ dingux_ipu_set_aspect_ratio_enable(true);
+
free(vid);
}
static void *sdl_dingux_gfx_init(const video_info_t *video,
input_driver_t **input, void **input_data)
{
- sdl_dingux_video_t *vid = NULL;
- settings_t *settings = config_get_ptr();
+ sdl_dingux_video_t *vid = NULL;
+ settings_t *settings = config_get_ptr();
+ bool ipu_keep_aspect = settings->bools.video_dingux_ipu_keep_aspect;
+ const char *input_joypad_driver = settings->arrays.input_joypad_driver;
+ uint32_t surface_flags = (video->vsync) ?
+ (SDL_HWSURFACE | SDL_TRIPLEBUF | SDL_FULLSCREEN) :
+ (SDL_HWSURFACE | SDL_FULLSCREEN);
- FILE* f = fopen("/sys/devices/platform/jz-lcd.0/allow_downscaling", "w");
- if (f)
- {
- fprintf(f, "%d", 1);
- fclose(f);
- }
+ dingux_ipu_set_downscaling_enable(true);
+ dingux_ipu_set_aspect_ratio_enable(ipu_keep_aspect);
if (SDL_WasInit(0) == 0)
{
@@ -88,19 +301,34 @@ static void *sdl_dingux_gfx_init(const video_info_t *video,
if (!vid)
return NULL;
-#ifdef VERBOSE
- printf("sdl_dingux_gfx_init video %dx%d rgb32 %d smooth %d input_scale %u force_aspect %d fullscreen %d\n",
- video->width, video->height, video->rgb32, video->smooth, video->input_scale, video->force_aspect, video->fullscreen);
+#if defined(VERBOSE)
+ RARCH_LOG("[sdl_dingux_gfx_init]\n"
+ " video %dx%d\n"
+ " rgb32 %d\n"
+ " smooth %d\n"
+ " input_scale %u\n"
+ " force_aspect %d\n"
+ " fullscreen %d\n"
+ " vsync %d\n"
+ " flags %u\n",
+ video->width, video->height, (int)video->rgb32, (int)video->smooth,
+ video->input_scale, (int)video->force_aspect, (int)video->fullscreen,
+ (int)video->vsync, surface_flags);
#endif
- vid->screen = SDL_SetVideoMode(320, 240, video->rgb32 ? 32 : 16, SDL_HWSURFACE | SDL_TRIPLEBUF | SDL_FULLSCREEN);
+ vid->screen = SDL_SetVideoMode(
+ SDL_DINGUX_MENU_WIDTH, SDL_DINGUX_MENU_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->rgb = video->rgb32;
+ vid->vsync = video->vsync;
+ vid->rgb32 = video->rgb32;
vid->menu_active = false;
vid->was_in_menu = false;
@@ -108,21 +336,24 @@ static void *sdl_dingux_gfx_init(const video_info_t *video,
if (input && input_data)
{
- void *sdl_input = input_driver_init_wrap(&input_sdl,
- settings->arrays.input_joypad_driver);
+ void *sdl_input = input_driver_init_wrap(
+ &input_sdl, input_joypad_driver);
if (sdl_input)
{
- *input = &input_sdl;
+ *input = &input_sdl;
*input_data = sdl_input;
}
else
{
- *input = NULL;
+ *input = NULL;
*input_data = NULL;
}
}
+ sdl_dingux_init_font_color(vid);
+ sdl_dingux_init_font_lut(vid);
+
return vid;
error:
@@ -130,47 +361,75 @@ error:
return NULL;
}
-static void clear_screen(void* data)
-{
- sdl_dingux_video_t* vid = (sdl_dingux_video_t*)data;
- SDL_FillRect(vid->screen, 0, 0);
- SDL_Flip(vid->screen);
- SDL_FillRect(vid->screen, 0, 0);
- SDL_Flip(vid->screen);
- SDL_FillRect(vid->screen, 0, 0);
- SDL_Flip(vid->screen);
-}
-
static void sdl_dingux_set_output(
sdl_dingux_video_t* vid,
- int width, int height, int pitch, bool rgb)
+ int width, int height, int pitch, bool rgb32)
{
-#ifdef VERBOSE
- printf("sdl_dingux_set_output current w %d h %d pitch %d new_w %d new_h %d pitch %d rgb %d\n",
- vid->screen->w, vid->screen->h, vid->screen->pitch, width, height, pitch, (int)vid->rgb);
+ uint32_t surface_flags = (vid->vsync) ?
+ (SDL_HWSURFACE | SDL_TRIPLEBUF | SDL_FULLSCREEN) :
+ (SDL_HWSURFACE | SDL_FULLSCREEN);
+
+#if defined(VERBOSE)
+ RARCH_LOG("[sdl_dingux_set_output]\n"
+ " current w %d h %d pitch %d\n"
+ " new_w %d new_h %d pitch %d\n"
+ " rgb32 %d\n"
+ " vsync %d\n"
+ " flags %u\n",
+ vid->screen->w, vid->screen->h, vid->screen->pitch,
+ width, height, pitch,
+ (int)rgb32, (int)vid->vsync, surface_flags);
#endif
- vid->screen = SDL_SetVideoMode(width, height, rgb ? 32 : 16, SDL_HWSURFACE | SDL_TRIPLEBUF | SDL_FULLSCREEN);
- if (!vid->screen)
- RARCH_ERR("[SDL1]: Failed to init SDL surface: %s\n", SDL_GetError());
+ vid->screen = SDL_SetVideoMode(
+ width, height, rgb32 ? 32 : 16,
+ surface_flags);
+
+ if (!vid->screen)
+ RARCH_ERR("[SDL1]: Failed to init SDL surface: %s\n", SDL_GetError());
}
-static void blit(uint32_t* d, uint32_t* s, int width, int height, int pitch)
+static void sdl_dingux_blit_frame16(uint16_t* dst, uint16_t* src,
+ unsigned width, unsigned height,
+ unsigned dst_pitch, unsigned src_pitch)
{
- unsigned i;
- int skip = pitch/4 - width;
- for (i = 0; i < height; i++)
+ uint16_t *in_ptr = src;
+ uint16_t *out_ptr = dst;
+ /* 16 bit - divide pitch by 2 */
+ uint16_t in_stride = (uint16_t)(src_pitch >> 1);
+ uint16_t out_stride = (uint16_t)(dst_pitch >> 1);
+ size_t y;
+
+ for (y = 0; y < height; y++)
{
- unsigned j;
- for (j = 0; j < width; j++)
- *(d++) = *(s++);
- s += skip;
+ memcpy(out_ptr, in_ptr, width * sizeof(uint16_t));
+ in_ptr += in_stride;
+ out_ptr += out_stride;
}
}
-static bool sdl_dingux_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)
+static void sdl_dingux_blit_frame32(uint32_t* dst, uint32_t* src,
+ unsigned width, unsigned height,
+ unsigned dst_pitch, unsigned src_pitch)
+{
+ uint32_t *in_ptr = src;
+ uint32_t *out_ptr = dst;
+ /* 32 bit - divide pitch by 4 */
+ uint32_t in_stride = (uint32_t)(src_pitch >> 2);
+ uint32_t out_stride = (uint32_t)(dst_pitch >> 2);
+ size_t y;
+
+ for (y = 0; y < height; y++)
+ {
+ memcpy(out_ptr, in_ptr, width * sizeof(uint32_t));
+ in_ptr += in_stride;
+ out_ptr += out_stride;
+ }
+}
+
+static bool sdl_dingux_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_dingux_video_t* vid = (sdl_dingux_video_t*)data;
#ifdef HAVE_MENU
@@ -180,8 +439,13 @@ static bool sdl_dingux_gfx_frame(void *data, const void *frame, unsigned width,
if (unlikely(!frame))
return true;
- if (unlikely((vid->screen->w != width || vid->screen->h != height) && !vid->menu_active))
- sdl_dingux_set_output(vid, width, height, pitch, vid->rgb);
+ /* Update video mode if width/height have changed */
+ if (unlikely(
+ ((vid->screen->w != width) ||
+ (vid->screen->h != height)) &&
+ !vid->menu_active))
+ sdl_dingux_set_output(vid, width, height,
+ pitch, vid->rgb32);
#ifdef HAVE_MENU
menu_driver_frame(menu_is_alive, video_info);
@@ -189,22 +453,66 @@ static bool sdl_dingux_gfx_frame(void *data, const void *frame, unsigned width,
if (likely(!vid->menu_active))
{
- blit((uint32_t*)vid->screen->pixels,
- (uint32_t*)frame,
- vid->rgb ? width : width/2, height, pitch);
- if (unlikely(vid->was_in_menu))
- vid->was_in_menu = false;
+ /* Must always lock SDL surface before
+ * manipulating raw pixel buffer */
+ if (SDL_MUSTLOCK(vid->screen))
+ SDL_LockSurface(vid->screen);
+
+ /* Blit frame to SDL surface */
+ if (vid->rgb32)
+ sdl_dingux_blit_frame32(
+ (uint32_t*)vid->screen->pixels,
+ (uint32_t*)frame,
+ width, height,
+ vid->screen->pitch, pitch);
+ else
+ sdl_dingux_blit_frame16(
+ (uint16_t*)vid->screen->pixels,
+ (uint16_t*)frame,
+ width, height,
+ vid->screen->pitch, pitch);
+
+ 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_dingux_set_output(vid, 320, 240, 320*2, false);
+ sdl_dingux_set_output(vid,
+ SDL_DINGUX_MENU_WIDTH, SDL_DINGUX_MENU_HEIGHT,
+ SDL_DINGUX_MENU_WIDTH * sizeof(uint16_t), false);
+
vid->was_in_menu = true;
}
- memcpy(vid->screen->pixels, vid->menu_frame, 320*240*2);
+
+ if (SDL_MUSTLOCK(vid->screen))
+ SDL_LockSurface(vid->screen);
+
+ /* Fast copy of menu texture to SDL surface */
+ memcpy(vid->screen->pixels, vid->menu_texture,
+ SDL_DINGUX_MENU_WIDTH * SDL_DINGUX_MENU_HEIGHT * sizeof(uint16_t));
}
+ /* Print OSD text, if required */
+ if (msg)
+ {
+ /* If menu is active, colour depth is overriden
+ * to 16 bit */
+ if (vid->rgb32 && !vid->menu_active)
+ sdl_dingux_blit_text32(vid, FONT_WIDTH_STRIDE,
+ vid->screen->h - (FONT_HEIGHT + FONT_WIDTH_STRIDE), msg);
+ else
+ sdl_dingux_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;
@@ -222,14 +530,36 @@ static void sdl_dingux_set_texture_enable(void *data, bool state, bool full_scre
static void sdl_dingux_set_texture_frame(void *data, const void *frame, bool rgb32,
unsigned width, unsigned height, float alpha)
{
- sdl_dingux_video_t *vid = (sdl_dingux_video_t*)data;
+ sdl_dingux_video_t *vid = (sdl_dingux_video_t*)data;
- int len = width * height * 2;
- memcpy(vid->menu_frame, frame, len);
+ if (unlikely(
+ rgb32 ||
+ (width > SDL_DINGUX_MENU_WIDTH) ||
+ (height > SDL_DINGUX_MENU_HEIGHT)))
+ return;
+
+ memcpy(vid->menu_texture, frame, width * height * sizeof(uint16_t));
}
+static void sdl_dingux_gfx_set_nonblock_state(void *data, bool toggle,
+ bool adaptive_vsync_enabled, unsigned swap_interval)
+{
+ sdl_dingux_video_t *vid = (sdl_dingux_video_t*)data;
+ bool vsync = !toggle;
-static void sdl_dingux_gfx_set_nonblock_state(void *a, bool b, bool c, unsigned d) { }
+ if (!vid || !vid->screen)
+ return;
+
+ /* Check whether vsync status has changed */
+ if (vid->vsync != vsync)
+ {
+ vid->vsync = vsync;
+
+ /* Update video mode */
+ sdl_dingux_set_output(vid, vid->screen->w, vid->screen->h,
+ vid->screen->pitch, vid->rgb32);
+ }
+}
static void sdl_dingux_gfx_check_window(sdl_dingux_video_t *vid)
{
@@ -249,26 +579,48 @@ static void sdl_dingux_gfx_check_window(sdl_dingux_video_t *vid)
static bool sdl_dingux_gfx_alive(void *data)
{
sdl_dingux_video_t *vid = (sdl_dingux_video_t*)data;
+
sdl_dingux_gfx_check_window(vid);
return !vid->quitting;
}
-static bool sdl_dingux_gfx_focus(void *data) { return true; }
-static bool sdl_dingux_gfx_suppress_screensaver(void *data, bool enable) { return false; }
-static bool sdl_dingux_gfx_has_windowed(void *data) { return false; }
+static bool sdl_dingux_gfx_focus(void *data)
+{
+ return true;
+}
+
+static bool sdl_dingux_gfx_suppress_screensaver(void *data, bool enable)
+{
+ return false;
+}
+
+static bool sdl_dingux_gfx_has_windowed(void *data)
+{
+ return false;
+}
static void sdl_dingux_gfx_viewport_info(void *data, struct video_viewport *vp)
{
sdl_dingux_video_t *vid = (sdl_dingux_video_t*)data;
+
vp->x = 0;
vp->y = 0;
vp->width = vp->full_width = vid->screen->w;
vp->height = vp->full_height = vid->screen->h;
}
-static void sdl_dingux_set_filtering(void *data, unsigned index, bool smooth, bool ctx_scaling) { }
-static void sdl_dingux_apply_state_changes(void *data) { }
-static uint32_t sdl_dingux_get_flags(void *data) { return 0; }
+static void sdl_dingux_set_filtering(void *data, unsigned index, bool smooth, bool ctx_scaling)
+{
+}
+
+static void sdl_dingux_apply_state_changes(void *data)
+{
+}
+
+static uint32_t sdl_dingux_get_flags(void *data)
+{
+ return 0;
+}
static const video_poke_interface_t sdl_dingux_poke_interface = {
sdl_dingux_get_flags,
@@ -287,16 +639,23 @@ static const video_poke_interface_t sdl_dingux_poke_interface = {
sdl_dingux_set_texture_frame,
sdl_dingux_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 */
+ 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_dingux_get_poke_interface(void *data, const video_poke_interface_t **iface) { *iface = &sdl_dingux_poke_interface; }
+static void sdl_dingux_get_poke_interface(void *data, const video_poke_interface_t **iface)
+{
+ *iface = &sdl_dingux_poke_interface;
+}
+
static bool sdl_dingux_gfx_set_shader(void *data,
- enum rarch_shader_type type, const char *path) { return false; }
+ enum rarch_shader_type type, const char *path)
+{
+ return false;
+}
video_driver_t video_sdl_dingux = {
sdl_dingux_gfx_init,
diff --git a/griffin/griffin.c b/griffin/griffin.c
index a9ca778302..78c2a47e7c 100644
--- a/griffin/griffin.c
+++ b/griffin/griffin.c
@@ -1151,6 +1151,10 @@ FRONTEND
#include "../frontend/drivers/platform_dos.c"
#endif
+#if defined(DINGUX)
+#include "../dingux/dingux_utils.c"
+#endif
+
#include "../core_info.c"
#include "../core_backup.c"
diff --git a/intl/msg_hash_lbl.h b/intl/msg_hash_lbl.h
index bf954e0434..c4dc885a06 100644
--- a/intl/msg_hash_lbl.h
+++ b/intl/msg_hash_lbl.h
@@ -2996,6 +2996,12 @@ MSG_HASH(
MENU_ENUM_LABEL_VIDEO_ASPECT_RATIO_INDEX,
"aspect_ratio_index"
)
+#if defined(DINGUX)
+MSG_HASH(
+ MENU_ENUM_LABEL_VIDEO_DINGUX_IPU_KEEP_ASPECT,
+ "video_dingux_ipu_keep_aspect"
+ )
+#endif
MSG_HASH(
MENU_ENUM_LABEL_VIDEO_BLACK_FRAME_INSERTION,
"video_black_frame_insertion"
@@ -3016,6 +3022,10 @@ MSG_HASH(
MENU_ENUM_LABEL_VIDEO_FILTER,
"video_filter"
)
+MSG_HASH(
+ MENU_ENUM_LABEL_VIDEO_FILTER_REMOVE,
+ "video_filter_remove"
+ )
MSG_HASH(
MENU_ENUM_LABEL_VIDEO_FILTER_DIR,
"video_filter_dir"
diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h
index 26d70206a6..0b6cd3d0cf 100644
--- a/intl/msg_hash_us.h
+++ b/intl/msg_hash_us.h
@@ -1368,6 +1368,14 @@ MSG_HASH(
MENU_ENUM_SUBLABEL_VIDEO_FILTER,
"Apply a CPU-powered video filter.\nNOTE: Might come at a high performance cost. Some video filters might only work for cores that use 32bit or 16bit color."
)
+MSG_HASH(
+ MENU_ENUM_LABEL_VALUE_VIDEO_FILTER_REMOVE,
+ "Remove Video Filter"
+ )
+MSG_HASH(
+ MENU_ENUM_SUBLABEL_VIDEO_FILTER_REMOVE,
+ "Unload any active CPU-powered video filter."
+ )
MSG_HASH(
MENU_ENUM_LABEL_VALUE_VIDEO_NOTCH_WRITE_OVER,
"Enable fullscreen over notch in Android devices"
@@ -1579,6 +1587,16 @@ MSG_HASH(
MENU_ENUM_SUBLABEL_VIDEO_ASPECT_RATIO,
"Floating point value for video aspect ratio (width / height), used if the Aspect Ratio is set to 'Custom Aspect Ratio'."
)
+#if defined(DINGUX)
+MSG_HASH(
+ MENU_ENUM_LABEL_VALUE_VIDEO_DINGUX_IPU_KEEP_ASPECT,
+ "Keep Aspect Ratio"
+ )
+MSG_HASH(
+ MENU_ENUM_SUBLABEL_VIDEO_DINGUX_IPU_KEEP_ASPECT,
+ "Maintain 1:1 pixel aspect ratios when scaling content via the internal IPU. If disabled, images will be stretched to fill the entire display."
+ )
+#endif
MSG_HASH(
MENU_ENUM_LABEL_VALUE_VIDEO_VIEWPORT_CUSTOM_X,
"Custom Aspect Ratio (X Position)"
diff --git a/menu/cbs/menu_cbs_ok.c b/menu/cbs/menu_cbs_ok.c
index 1bc68fb2b5..ed00c4f0ac 100644
--- a/menu/cbs/menu_cbs_ok.c
+++ b/menu/cbs/menu_cbs_ok.c
@@ -1932,8 +1932,8 @@ static int default_action_ok_load_content_from_playlist_from_menu(const char *_p
return 0;
}
-DEFAULT_ACTION_OK_SET(action_ok_set_path_audiofilter, ACTION_OK_SET_PATH_VIDEO_FILTER, MSG_UNKNOWN)
-DEFAULT_ACTION_OK_SET(action_ok_set_path_videofilter, ACTION_OK_SET_PATH_AUDIO_FILTER, MSG_UNKNOWN)
+DEFAULT_ACTION_OK_SET(action_ok_set_path_audiofilter, ACTION_OK_SET_PATH_AUDIO_FILTER, MSG_UNKNOWN)
+DEFAULT_ACTION_OK_SET(action_ok_set_path_videofilter, ACTION_OK_SET_PATH_VIDEO_FILTER, MSG_UNKNOWN)
DEFAULT_ACTION_OK_SET(action_ok_set_path_overlay, ACTION_OK_SET_PATH_OVERLAY, MSG_UNKNOWN)
#ifdef HAVE_VIDEO_LAYOUT
DEFAULT_ACTION_OK_SET(action_ok_set_path_video_layout,ACTION_OK_SET_PATH_VIDEO_LAYOUT, MSG_UNKNOWN)
@@ -2966,6 +2966,30 @@ static int action_ok_shader_preset_remove_game(const char *path,
}
#endif
+static int action_ok_video_filter_remove(const char *path,
+ const char *label, unsigned type, size_t idx, size_t entry_idx)
+{
+ settings_t *settings = config_get_ptr();
+
+ if (!settings)
+ menu_cbs_exit();
+
+ if (!string_is_empty(settings->paths.path_softfilter_plugin))
+ {
+ bool refresh = false;
+
+ /* Unload video filter */
+ settings->paths.path_softfilter_plugin[0] = '\0';
+ command_event(CMD_EVENT_REINIT, NULL);
+
+ /* Refresh menu */
+ menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh);
+ menu_driver_ctl(RARCH_MENU_CTL_SET_PREVENT_POPULATE, NULL);
+ }
+
+ return 0;
+}
+
#ifdef HAVE_CHEATS
static void menu_input_st_string_cb_cheat_file_save_as(
void *userdata, const char *str)
@@ -7987,6 +8011,9 @@ static int menu_cbs_init_bind_ok_compare_type(menu_file_list_cbs_t *cbs,
case MENU_SETTING_ACTION_CORE_LOCK:
BIND_ACTION_OK(cbs, action_ok_core_lock);
break;
+ case MENU_SETTING_ACTION_VIDEO_FILTER_REMOVE:
+ BIND_ACTION_OK(cbs, action_ok_video_filter_remove);
+ break;
default:
return -1;
}
diff --git a/menu/cbs/menu_cbs_start.c b/menu/cbs/menu_cbs_start.c
index 4971bb10cf..c459686fd1 100644
--- a/menu/cbs/menu_cbs_start.c
+++ b/menu/cbs/menu_cbs_start.c
@@ -110,10 +110,21 @@ static int action_start_video_filter_file_load(
settings_t *settings = config_get_ptr();
if (!settings)
- return -1;
+ return menu_cbs_exit();
+
+ if (!string_is_empty(settings->paths.path_softfilter_plugin))
+ {
+ bool refresh = false;
+
+ /* Unload video filter */
+ settings->paths.path_softfilter_plugin[0] = '\0';
+ command_event(CMD_EVENT_REINIT, NULL);
+
+ /* Refresh menu */
+ menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh);
+ menu_driver_ctl(RARCH_MENU_CTL_SET_PREVENT_POPULATE, NULL);
+ }
- settings->paths.path_softfilter_plugin[0] = '\0';
- command_event(CMD_EVENT_REINIT, NULL);
return 0;
}
diff --git a/menu/cbs/menu_cbs_sublabel.c b/menu/cbs/menu_cbs_sublabel.c
index edc4f7249d..ee8ba7b356 100644
--- a/menu/cbs/menu_cbs_sublabel.c
+++ b/menu/cbs/menu_cbs_sublabel.c
@@ -358,6 +358,7 @@ DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_quit_press_twice, MENU_
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_onscreen_notifications_enable, MENU_ENUM_SUBLABEL_VIDEO_FONT_ENABLE)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_video_crop_overscan, MENU_ENUM_SUBLABEL_VIDEO_CROP_OVERSCAN)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_video_filter, MENU_ENUM_SUBLABEL_VIDEO_FILTER)
+DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_video_filter_remove, MENU_ENUM_SUBLABEL_VIDEO_FILTER_REMOVE)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_netplay_nickname, MENU_ENUM_SUBLABEL_NETPLAY_NICKNAME)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_cheevos_username, MENU_ENUM_SUBLABEL_CHEEVOS_USERNAME)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_cheevos_password, MENU_ENUM_SUBLABEL_CHEEVOS_PASSWORD)
@@ -806,6 +807,9 @@ DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_quick_menu,
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_core_information, MENU_ENUM_SUBLABEL_CORE_INFORMATION)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_disc_information, MENU_ENUM_SUBLABEL_DISC_INFORMATION)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_video_aspect_ratio, MENU_ENUM_SUBLABEL_VIDEO_ASPECT_RATIO)
+#if defined(DINGUX)
+DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_video_dingux_ipu_keep_aspect, MENU_ENUM_SUBLABEL_VIDEO_DINGUX_IPU_KEEP_ASPECT)
+#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)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_video_viewport_custom_x, MENU_ENUM_SUBLABEL_VIDEO_VIEWPORT_CUSTOM_X)
@@ -1798,6 +1802,11 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs,
case MENU_ENUM_LABEL_VIDEO_ASPECT_RATIO:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_video_aspect_ratio);
break;
+#if defined(DINGUX)
+ case MENU_ENUM_LABEL_VIDEO_DINGUX_IPU_KEEP_ASPECT:
+ BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_video_dingux_ipu_keep_aspect);
+ break;
+#endif
case MENU_ENUM_LABEL_CORE_INFORMATION:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_core_information);
break;
@@ -3196,6 +3205,9 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs,
case MENU_ENUM_LABEL_VIDEO_FILTER:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_video_filter);
break;
+ case MENU_ENUM_LABEL_VIDEO_FILTER_REMOVE:
+ BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_video_filter_remove);
+ break;
case MENU_ENUM_LABEL_VIDEO_CROP_OVERSCAN:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_video_crop_overscan);
break;
diff --git a/menu/drivers/materialui.c b/menu/drivers/materialui.c
index 37a76ed29b..823a05ee49 100644
--- a/menu/drivers/materialui.c
+++ b/menu/drivers/materialui.c
@@ -9773,6 +9773,7 @@ static void materialui_list_insert(
break;
case MENU_SETTING_ACTION_CORE_DELETE:
case MENU_SETTING_ACTION_CORE_DELETE_BACKUP:
+ case MENU_SETTING_ACTION_VIDEO_FILTER_REMOVE:
node->icon_texture_index = MUI_TEXTURE_REMOVE;
node->icon_type = MUI_ICON_TYPE_INTERNAL;
break;
diff --git a/menu/drivers/ozone/ozone_texture.c b/menu/drivers/ozone/ozone_texture.c
index d7fcdb023c..1b43d6d1cd 100644
--- a/menu/drivers/ozone/ozone_texture.c
+++ b/menu/drivers/ozone/ozone_texture.c
@@ -248,6 +248,7 @@ uintptr_t ozone_entries_icon_get_texture(ozone_handle_t *ozone,
case MENU_ENUM_LABEL_CORE_DELETE:
case MENU_ENUM_LABEL_DELETE_PLAYLIST:
case MENU_ENUM_LABEL_CORE_DELETE_BACKUP_LIST:
+ case MENU_ENUM_LABEL_VIDEO_FILTER_REMOVE:
return ozone->icons_textures[OZONE_ENTRIES_ICONS_TEXTURE_CLOSE];
case MENU_ENUM_LABEL_CORE_LOCK:
return ozone->icons_textures[OZONE_ENTRIES_ICONS_TEXTURE_CORE];
diff --git a/menu/drivers/rgui.c b/menu/drivers/rgui.c
index 3d94265d3b..09484165c1 100644
--- a/menu/drivers/rgui.c
+++ b/menu/drivers/rgui.c
@@ -1054,6 +1054,32 @@ static uint16_t argb32_to_bgra4444(uint32_t col)
return (b << 12) | (g << 8) | (r << 4) | a;
}
+/* DINGUX SDL */
+static uint16_t argb32_to_rgb565(uint32_t col)
+{
+ /* Extract colour components */
+ unsigned a = (col >> 24) & 0xff;
+ unsigned r = (col >> 16) & 0xff;
+ unsigned g = (col >> 8) & 0xff;
+ unsigned b = col & 0xff;
+ if (a < 0xff)
+ {
+ /* RGB565 has no alpha component - as with PS2 colour conversion,
+ * have to darken each RGB value according to the alpha component
+ * of the input colour... */
+ float a_factor = (float)a * (1.0 / 255.0);
+ r = (unsigned)(((float)r * a_factor) + 0.5) & 0xff;
+ g = (unsigned)(((float)g * a_factor) + 0.5) & 0xff;
+ b = (unsigned)(((float)b * a_factor) + 0.5) & 0xff;
+ }
+ /* Convert from 8 bit to 5 bit */
+ r = r >> 3;
+ g = g >> 3;
+ b = b >> 3;
+ /* Return final value */
+ return (r << 11) | (g << 6) | b;
+}
+
/* All other platforms */
static uint16_t argb32_to_rgba4444(uint32_t col)
{
@@ -1077,16 +1103,18 @@ static void rgui_set_pixel_format_function(void)
return;
}
- if ( string_is_equal(driver_ident, "ps2")) /* PS2 */
+ if ( string_is_equal(driver_ident, "ps2")) /* PS2 */
argb32_to_pixel_platform_format = argb32_to_abgr1555;
- 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 */
+ argb32_to_pixel_platform_format = argb32_to_rgb565;
else
argb32_to_pixel_platform_format = argb32_to_rgba4444;
}
@@ -2302,12 +2330,16 @@ static void load_custom_theme(rgui_t *rgui, rgui_theme_t *theme_colors, const ch
unsigned particle_color = 0;
config_file_t *conf = NULL;
const char *wallpaper_key = NULL;
- settings_t *settings = config_get_ptr();
bool success = false;
- unsigned rgui_aspect_ratio = settings->uints.menu_rgui_aspect_ratio;
+#if defined(DINGUX)
+ unsigned aspect_ratio = RGUI_ASPECT_RATIO_4_3;
+#else
+ settings_t *settings = config_get_ptr();
+ unsigned aspect_ratio = settings->uints.menu_rgui_aspect_ratio;
+#endif
/* Determine which type of wallpaper to load */
- switch (rgui_aspect_ratio)
+ switch (aspect_ratio)
{
case RGUI_ASPECT_RATIO_16_9:
case RGUI_ASPECT_RATIO_16_9_CENTRE:
@@ -4250,7 +4282,11 @@ static void rgui_update_menu_viewport(rgui_t *rgui)
#if !defined(GEKKO)
bool do_integer_scaling = false;
settings_t *settings = config_get_ptr();
+#if defined(DINGUX)
+ unsigned aspect_ratio_lock = RGUI_ASPECT_RATIO_LOCK_NONE;
+#else
unsigned aspect_ratio_lock = settings ? settings->uints.menu_rgui_aspect_ratio_lock : 0;
+#endif
if (!settings)
return;
@@ -4373,13 +4409,22 @@ static bool rgui_set_aspect_ratio(rgui_t *rgui, bool delay_update)
* the usual 426, since the last two bits of the
* 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;
#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_lock = RGUI_ASPECT_RATIO_LOCK_NONE;
+#else
settings_t *settings = config_get_ptr();
- unsigned rgui_aspect_ratio = settings->uints.menu_rgui_aspect_ratio;
+ unsigned aspect_ratio = settings->uints.menu_rgui_aspect_ratio;
unsigned aspect_ratio_lock = settings->uints.menu_rgui_aspect_ratio_lock;
+#endif
rgui_framebuffer_free();
rgui_background_free();
@@ -4388,7 +4433,7 @@ static bool rgui_set_aspect_ratio(rgui_t *rgui, bool delay_update)
rgui_thumbnail_free(&mini_left_thumbnail);
/* Cache new aspect ratio */
- rgui->menu_aspect_ratio = rgui_aspect_ratio;
+ rgui->menu_aspect_ratio = aspect_ratio;
/* Set frame buffer dimensions: */
@@ -4399,6 +4444,10 @@ static bool rgui_set_aspect_ratio(rgui_t *rgui, bool delay_update)
* values */
gfx_display_get_fb_size(&fb_width, &fb_height, &fb_pitch);
rgui_frame_buf.height = fb_height;
+#elif defined(DINGUX)
+ /* Dingux devices use a fixed framebuffer size
+ * of 320x240 */
+ rgui_frame_buf.height = 240;
#else
/* If window height is less than RGUI default
* height of 240, allow the frame buffer to
@@ -4494,14 +4543,14 @@ static bool rgui_set_aspect_ratio(rgui_t *rgui, bool delay_update)
* - Must be less than max_frame_buf_width
* (note that this is a redundant safety
* check - it can never actually happen...)
- * - On platforms other than the Wii, must
+ * - On platforms other than Wii and dingux, must
* be less than window width but greater than
* defined minimum width */
rgui_frame_buf.width = (rgui_frame_buf.width > max_frame_buf_width) ?
max_frame_buf_width : rgui_frame_buf.width;
base_term_width = (base_term_width > rgui_frame_buf.width) ?
rgui_frame_buf.width : base_term_width;
-#if !defined(GEKKO)
+#if !(defined(GEKKO) || defined(DINGUX))
if (vp.full_width < rgui_frame_buf.width)
{
rgui_frame_buf.width = (vp.full_width > RGUI_MIN_FB_WIDTH) ?
@@ -4665,7 +4714,11 @@ static void *rgui_init(void **userdata, bool video_is_threaded)
rgui_t *rgui = NULL;
settings_t *settings = config_get_ptr();
gfx_display_t *p_disp = disp_get_ptr();
+#if defined(DINGUX)
+ unsigned aspect_ratio_lock = RGUI_ASPECT_RATIO_LOCK_NONE;
+#else
unsigned aspect_ratio_lock = settings->uints.menu_rgui_aspect_ratio_lock;
+#endif
menu_handle_t *menu = (menu_handle_t*)calloc(1, sizeof(*menu));
if (!menu)
@@ -4822,7 +4875,11 @@ static void rgui_set_texture(void)
unsigned fb_width, fb_height;
settings_t *settings = config_get_ptr();
gfx_display_t *p_disp = disp_get_ptr();
+#if defined(DINGUX)
+ unsigned internal_upscale_level = RGUI_UPSCALE_NONE;
+#else
unsigned internal_upscale_level = settings->uints.menu_rgui_internal_upscale_level;
+#endif
/* Framebuffer is dirty and needs to be updated? */
if (!p_disp->framebuf_dirty)
@@ -5263,8 +5320,12 @@ static void rgui_populate_entries(void *data,
const char *label, unsigned k)
{
rgui_t *rgui = (rgui_t*)data;
+#if defined(DINGUX)
+ unsigned aspect_ratio_lock = RGUI_ASPECT_RATIO_LOCK_NONE;
+#else
settings_t *settings = config_get_ptr();
unsigned aspect_ratio_lock = settings->uints.menu_rgui_aspect_ratio_lock;
+#endif
if (!rgui)
return;
@@ -5423,7 +5484,13 @@ static void rgui_frame(void *data, video_frame_info_t *video_info)
settings_t *settings = config_get_ptr();
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_lock = RGUI_ASPECT_RATIO_LOCK_NONE;
+#else
+ unsigned aspect_ratio = settings->uints.menu_rgui_aspect_ratio;
unsigned aspect_ratio_lock = settings->uints.menu_rgui_aspect_ratio_lock;
+#endif
bool border_filler_enable = settings->bools.menu_rgui_border_filler_enable;
unsigned video_width = video_info->width;
unsigned video_height = video_info->height;
@@ -5500,7 +5567,7 @@ static void rgui_frame(void *data, video_frame_info_t *video_info)
* the next instance of rgui_render() */
/* > Check for changes in aspect ratio */
- if (settings->uints.menu_rgui_aspect_ratio != rgui->menu_aspect_ratio)
+ if (aspect_ratio != rgui->menu_aspect_ratio)
{
/* If user changes aspect ratio directly after opening
* the video scaling settings menu, then all bets are off
@@ -5617,7 +5684,11 @@ static void rgui_toggle(void *userdata, bool menu_on)
{
rgui_t *rgui = (rgui_t*)userdata;
settings_t *settings = config_get_ptr();
+#if defined(DINGUX)
+ unsigned aspect_ratio_lock = RGUI_ASPECT_RATIO_LOCK_NONE;
+#else
unsigned aspect_ratio_lock = settings ? settings->uints.menu_rgui_aspect_ratio_lock : 0;
+#endif
/* TODO/FIXME - when we close RetroArch, this function
* gets called and settings is NULL at this point.
diff --git a/menu/drivers/xmb.c b/menu/drivers/xmb.c
index e491c233f5..c9b7987213 100644
--- a/menu/drivers/xmb.c
+++ b/menu/drivers/xmb.c
@@ -2699,6 +2699,7 @@ static uintptr_t xmb_icon_get_id(xmb_handle_t *xmb,
case MENU_ENUM_LABEL_CORE_DELETE:
case MENU_ENUM_LABEL_DELETE_PLAYLIST:
case MENU_ENUM_LABEL_CORE_DELETE_BACKUP_LIST:
+ case MENU_ENUM_LABEL_VIDEO_FILTER_REMOVE:
return xmb->textures.list[XMB_TEXTURE_CLOSE];
case MENU_ENUM_LABEL_CORE_LOCK:
return xmb->textures.list[XMB_TEXTURE_CORE];
diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c
index afe81c1d57..3b77e09c52 100644
--- a/menu/menu_displaylist.c
+++ b/menu/menu_displaylist.c
@@ -5633,6 +5633,7 @@ unsigned menu_displaylist_build_list(
break;
case DISPLAYLIST_VIDEO_SETTINGS_LIST:
{
+ settings_t *settings = config_get_ptr();
gfx_ctx_flags_t flags;
if (video_display_server_get_flags(&flags))
@@ -5702,6 +5703,14 @@ unsigned menu_displaylist_build_list(
MENU_ENUM_LABEL_VIDEO_FILTER,
PARSE_ONLY_PATH, false) == 0)
count++;
+
+ if (!string_is_empty(settings->paths.path_softfilter_plugin))
+ if (menu_entries_append_enum(list,
+ msg_hash_to_str(MENU_ENUM_LABEL_VALUE_VIDEO_FILTER_REMOVE),
+ msg_hash_to_str(MENU_ENUM_LABEL_VIDEO_FILTER_REMOVE),
+ MENU_ENUM_LABEL_VIDEO_FILTER_REMOVE,
+ MENU_SETTING_ACTION_VIDEO_FILTER_REMOVE, 0, 0))
+ count++;
#endif
if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(list,
MENU_ENUM_LABEL_VIDEO_NOTCH_WRITE_OVER,
@@ -7347,45 +7356,58 @@ unsigned menu_displaylist_build_list(
case DISPLAYLIST_VIDEO_SCALING_SETTINGS_LIST:
{
settings_t *settings = config_get_ptr();
- if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(list,
- MENU_ENUM_LABEL_VIDEO_SCALE_INTEGER,
- 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)
- count++;
- switch (settings->uints.video_aspect_ratio_idx)
+
+#if defined(DINGUX)
+ if (string_is_equal(settings->arrays.video_driver, "sdl_dingux"))
{
- case ASPECT_RATIO_CONFIG:
- if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(list,
- MENU_ENUM_LABEL_VIDEO_ASPECT_RATIO,
- PARSE_ONLY_FLOAT, false) == 0)
- count++;
- break;
- case ASPECT_RATIO_CUSTOM:
- if (!settings->bools.video_scale_integer)
- {
+ if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(list,
+ MENU_ENUM_LABEL_VIDEO_DINGUX_IPU_KEEP_ASPECT,
+ PARSE_ONLY_BOOL, false) == 0)
+ count++;
+ }
+ else
+#endif
+ {
+ if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(list,
+ MENU_ENUM_LABEL_VIDEO_SCALE_INTEGER,
+ 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)
+ count++;
+ switch (settings->uints.video_aspect_ratio_idx)
+ {
+ case ASPECT_RATIO_CONFIG:
if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(list,
- MENU_ENUM_LABEL_VIDEO_VIEWPORT_CUSTOM_X,
- PARSE_ONLY_INT, false) == 0)
+ MENU_ENUM_LABEL_VIDEO_ASPECT_RATIO,
+ PARSE_ONLY_FLOAT, false) == 0)
+ count++;
+ break;
+ case ASPECT_RATIO_CUSTOM:
+ if (!settings->bools.video_scale_integer)
+ {
+ if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(list,
+ MENU_ENUM_LABEL_VIDEO_VIEWPORT_CUSTOM_X,
+ PARSE_ONLY_INT, false) == 0)
+ count++;
+ if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(list,
+ MENU_ENUM_LABEL_VIDEO_VIEWPORT_CUSTOM_Y,
+ PARSE_ONLY_INT, false) == 0)
+ count++;
+ }
+ if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(list,
+ MENU_ENUM_LABEL_VIDEO_VIEWPORT_CUSTOM_WIDTH,
+ PARSE_ONLY_UINT, false) == 0)
count++;
if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(list,
- MENU_ENUM_LABEL_VIDEO_VIEWPORT_CUSTOM_Y,
- PARSE_ONLY_INT, false) == 0)
+ MENU_ENUM_LABEL_VIDEO_VIEWPORT_CUSTOM_HEIGHT,
+ PARSE_ONLY_UINT, false) == 0)
count++;
- }
- if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(list,
- MENU_ENUM_LABEL_VIDEO_VIEWPORT_CUSTOM_WIDTH,
- PARSE_ONLY_UINT, false) == 0)
- count++;
- if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(list,
- MENU_ENUM_LABEL_VIDEO_VIEWPORT_CUSTOM_HEIGHT,
- PARSE_ONLY_UINT, false) == 0)
- count++;
- break;
- default:
- break;
+ break;
+ default:
+ break;
+ }
}
if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(list,
diff --git a/menu/menu_driver.h b/menu/menu_driver.h
index 84566bf6d5..0a31bce6fd 100644
--- a/menu/menu_driver.h
+++ b/menu/menu_driver.h
@@ -220,6 +220,8 @@ enum menu_settings_type
MENU_SETTING_ACTION_CORE_DELETE_BACKUP,
MENU_SETTING_ITEM_CORE_DELETE_BACKUP,
+ MENU_SETTING_ACTION_VIDEO_FILTER_REMOVE,
+
MENU_SETTINGS_LAST
};
diff --git a/menu/menu_setting.c b/menu/menu_setting.c
index ec64fef6cd..ab37f5cc9f 100644
--- a/menu/menu_setting.c
+++ b/menu/menu_setting.c
@@ -118,6 +118,10 @@
#include <3ds/services/cfgu.h>
#endif
+#if defined(DINGUX)
+#include "../dingux/dingux_utils.h"
+#endif
+
#if defined(ANDROID)
#include "../play_feature_delivery/play_feature_delivery.h"
#endif
@@ -7124,6 +7128,11 @@ static void general_write_handler(rarch_setting_t *setting)
case MENU_ENUM_LABEL_VIDEO_CTX_SCALING:
video_driver_set_filtering(1, settings->bools.video_ctx_scaling, settings->bools.video_ctx_scaling);
break;
+#if defined(DINGUX)
+ case MENU_ENUM_LABEL_VIDEO_DINGUX_IPU_KEEP_ASPECT:
+ dingux_ipu_set_aspect_ratio_enable(*setting->value.target.boolean);
+ break;
+#endif
case MENU_ENUM_LABEL_VIDEO_ROTATION:
{
rarch_system_info_t *system = runloop_get_system_info();
@@ -10332,6 +10341,7 @@ static bool setting_append_list(
END_SUB_GROUP(list, list_info, parent_group);
START_SUB_GROUP(list, list_info, "Aspect", &group_info, &subgroup_info, parent_group);
+
CONFIG_UINT(
list, list_info,
&settings->uints.video_aspect_ratio_idx,
@@ -10479,6 +10489,26 @@ static bool setting_append_list(
CMD_EVENT_VIDEO_APPLY_STATE_CHANGES);
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"))
+ {
+ CONFIG_BOOL(
+ list, list_info,
+ &settings->bools.video_dingux_ipu_keep_aspect,
+ MENU_ENUM_LABEL_VIDEO_DINGUX_IPU_KEEP_ASPECT,
+ MENU_ENUM_LABEL_VALUE_VIDEO_DINGUX_IPU_KEEP_ASPECT,
+ DEFAULT_DINGUX_IPU_KEEP_ASPECT,
+ 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);
+ }
+#endif
+
END_SUB_GROUP(list, list_info, parent_group);
START_SUB_GROUP(list, list_info, "Scaling", &group_info, &subgroup_info, parent_group);
@@ -13805,6 +13835,7 @@ static bool setting_append_list(
(*list)[list_info->index - 1].ui_type = ST_UI_TYPE_UINT_COMBOBOX;
}
+#if !defined(DINGUX)
CONFIG_UINT(
list, list_info,
&settings->uints.menu_rgui_aspect_ratio,
@@ -13841,6 +13872,7 @@ static bool setting_append_list(
menu_settings_list_current_add_range(list, list_info, 0, RGUI_ASPECT_RATIO_LOCK_LAST-1, 1, true, true);
#endif
(*list)[list_info->index - 1].ui_type = ST_UI_TYPE_UINT_COMBOBOX;
+#endif
CONFIG_UINT(
list, list_info,
diff --git a/msg_hash.h b/msg_hash.h
index 460c0f66a4..2ff99df6de 100644
--- a/msg_hash.h
+++ b/msg_hash.h
@@ -2169,6 +2169,7 @@ enum msg_hash_enums
MENU_LABEL(RECORDING_OUTPUT_DIRECTORY),
MENU_LABEL(RECORDING_CONFIG_DIRECTORY),
MENU_LABEL(VIDEO_FILTER),
+ MENU_LABEL(VIDEO_FILTER_REMOVE),
MENU_LABEL(PAL60_ENABLE),
MENU_LABEL(CONTENT_HISTORY_PATH),
@@ -2328,6 +2329,9 @@ enum msg_hash_enums
MENU_LABEL(VIDEO_FORCE_ASPECT),
MENU_LABEL(VIDEO_ASPECT_RATIO_AUTO),
MENU_LABEL(VIDEO_ASPECT_RATIO_INDEX),
+#if defined(DINGUX)
+ MENU_LABEL(VIDEO_DINGUX_IPU_KEEP_ASPECT),
+#endif
MENU_LABEL(VIDEO_VFILTER),
MENU_LABEL(VIDEO_GPU_RECORD),
MENU_LABEL(RECORD_USE_OUTPUT_DIRECTORY),