[Scummvm-git-logs] scummvm master -> 1dbb8cf96af3b4b14535f0a86e6904cea8857e67

spleen1981 noreply at scummvm.org
Fri Sep 8 22:38:06 UTC 2023


This automated email contains information about 24 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
4cb49b3682 LIBRETRO: add retro settings export functions
b320082bd2 LIBRETRO: refactor log_cb
76d177cec6 LIBRETRO: expose input_cb and refactor
96710cd093 LIBRETRO: refactor retro_input_device and add get function
c92f3dba01 LIBRETRO: extended retro_set_controller_port_device to additional devices
ca0eb94933 LIBRETRO: remove processMouse arguments
ba58463669 LIBRETRO: add OSystem_libretro::refreshRetroSettings()
9617f010b5 LIBRETRO: add OSystem_libretro::getMouseXYFromAnalog()
260bd5b918 LIBRETRO: add OSystem_libretro::getMouseXYFromButton()
e7a8d1dea4 LIBRETRO: simplify OSystem_libretro::getMouseXYFromButton()
eb1aa4037b LIBRETRO: fix cursor speed reduction
88e97990f6 LIBRETRO: clean up retropad input
5c13a41324 LIBRETRO: add libretro-mapper.h
84ebccb5af LIBRETRO: add dynamically displayed options
90adba467e LIBRETRO: use retro_get_system_av_info in retro_run
6cc96ef4ac LIBRETRO: fix frame rate in inverse_acceleration_time
3d4475da76 LIBRETRO: fix sample rate setting default value
ad2e4d1512 LIBRETRO: add retropad mapping settings
524c270ded LIBRETRO: fix settings descriptions w/o categories
da563c7bf4 LIBRETRO: cover settings update following reset to defaults
b486ca6881 LIBRETRO: use cpu_features_get_time_usec to get current time
8431d59abd LIBRETRO: BUILD: add debug flag
f634443ea6 LIBRETRO: move log_scummvm_exit_code call
1dbb8cf96a LIBREETRO: add mouse fine control speed reduction setting


Commit: 4cb49b368231eb6995f73579f6fd8dae1efb6e8b
    https://github.com/scummvm/scummvm/commit/4cb49b368231eb6995f73579f6fd8dae1efb6e8b
Author: Giovanni Cascione (ing.cascione at gmail.com)
Date: 2023-09-09T00:35:59+02:00

Commit Message:
LIBRETRO: add retro settings export functions

Changed paths:
    backends/platform/libretro/include/libretro-os.h
    backends/platform/libretro/src/libretro-os-base.cpp
    backends/platform/libretro/src/libretro-os-events.cpp
    backends/platform/libretro/src/libretro-os-graphics.cpp
    backends/platform/libretro/src/libretro.cpp


diff --git a/backends/platform/libretro/include/libretro-os.h b/backends/platform/libretro/include/libretro-os.h
index 773caa1370e..f8183dc9b19 100644
--- a/backends/platform/libretro/include/libretro-os.h
+++ b/backends/platform/libretro/include/libretro-os.h
@@ -33,11 +33,16 @@
 #define LIBRETRO_G_SYSTEM dynamic_cast<OSystem_libretro *>(g_system)
 
 extern retro_log_printf_t log_cb;
-extern bool timing_inaccuracies_is_enabled(void);
+extern bool retro_setting_get_timing_inaccuracies_enabled(void);
+extern float retro_setting_get_frame_rate(void);
+extern uint16 retro_setting_get_sample_rate(void);
+extern int retro_setting_get_analog_deadzone(void);
+extern bool retro_setting_get_analog_response_is_quadratic(void);
+extern float retro_setting_get_mouse_speed(void);
+extern float retro_setting_get_gamepad_cursor_speed(void);
+extern float retro_setting_get_gamepad_acceleration_time(void);
 extern void reset_performance_tuner(void);
 extern void retro_osd_notification(const char* msg);
-extern float frame_rate;
-extern uint16 sample_rate;
 extern const char * retro_get_system_dir(void);
 extern const char * retro_get_save_dir(void);
 
diff --git a/backends/platform/libretro/src/libretro-os-base.cpp b/backends/platform/libretro/src/libretro-os-base.cpp
index 35978080f10..1b9d51835f6 100644
--- a/backends/platform/libretro/src/libretro-os-base.cpp
+++ b/backends/platform/libretro/src/libretro-os-base.cpp
@@ -83,10 +83,10 @@ void OSystem_libretro::initBackend() {
 #else
 	_overlay.create(RES_W_OVERLAY, RES_H_OVERLAY, Graphics::PixelFormat(2, 5, 5, 5, 1, 10, 5, 0, 15));
 #endif
-	_mixer = new Audio::MixerImpl(sample_rate);
-	log_cb(RETRO_LOG_DEBUG,"Mixer set up at %dHz\n", sample_rate);
+	_mixer = new Audio::MixerImpl(retro_setting_get_sample_rate());
+	log_cb(RETRO_LOG_DEBUG,"Mixer set up at %dHz\n", retro_setting_get_sample_rate());
 
-	_timerManager = new LibretroTimerManager(frame_rate);
+	_timerManager = new LibretroTimerManager(retro_setting_get_frame_rate());
 
 	_mixer->setReady(true);
 
diff --git a/backends/platform/libretro/src/libretro-os-events.cpp b/backends/platform/libretro/src/libretro-os-events.cpp
index 576fc0a7665..170f14d9236 100644
--- a/backends/platform/libretro/src/libretro-os-events.cpp
+++ b/backends/platform/libretro/src/libretro-os-events.cpp
@@ -72,7 +72,7 @@ void OSystem_libretro::delayMillis(uint msecs) {
 
 	_threadSwitchCaller = THREAD_SWITCH_DELAY;
 
-	if (timing_inaccuracies_is_enabled()) {
+	if (retro_setting_get_timing_inaccuracies_enabled()) {
 		while (elapsed_time < msecs) {
 			/* When remaining delay would take us past the next thread switch time, we switch immediately
 			in order to burn as much as possible delay time in the main RetroArch thread as soon as possible. */
diff --git a/backends/platform/libretro/src/libretro-os-graphics.cpp b/backends/platform/libretro/src/libretro-os-graphics.cpp
index 8064cbaf239..af9dc35dd0f 100644
--- a/backends/platform/libretro/src/libretro-os-graphics.cpp
+++ b/backends/platform/libretro/src/libretro-os-graphics.cpp
@@ -301,7 +301,7 @@ void OSystem_libretro::updateScreen() {
 		}
 	}
 
-	if (! timing_inaccuracies_is_enabled() && !_overlayInGUI) {
+	if (! retro_setting_get_timing_inaccuracies_enabled() && !_overlayInGUI) {
 		_threadSwitchCaller = THREAD_SWITCH_UPDATE;
 		((LibretroTimerManager *)_timerManager)->checkThread();
 	}
diff --git a/backends/platform/libretro/src/libretro.cpp b/backends/platform/libretro/src/libretro.cpp
index 5ae51c753f7..f0ed8a41377 100644
--- a/backends/platform/libretro/src/libretro.cpp
+++ b/backends/platform/libretro/src/libretro.cpp
@@ -71,7 +71,7 @@ static int retro_device = RETRO_DEVICE_JOYPAD;
 // Default deadzone: 15%
 static int analog_deadzone = (int)(0.15f * ANALOG_RANGE);
 
-static float gampad_cursor_speed = 1.0f;
+static float gamepad_cursor_speed = 1.0f;
 static bool analog_response_is_quadratic = false;
 
 static float mouse_speed = 1.0f;
@@ -101,8 +101,8 @@ static uint8 performance_switch = 0;
 static uint32 perf_ref_frame = 0;
 static uint32 perf_ref_audio_buff_occupancy = 0;
 
-float frame_rate = 0;
-uint16 sample_rate = 0;
+static float frame_rate = 0;
+static uint16 sample_rate = 0;
 static uint16 samples_per_frame = 0;               // length in samples per frame
 static size_t samples_per_frame_buffer_size = 0;
 
@@ -194,9 +194,9 @@ static void update_variables(void) {
 
 	var.key = "scummvm_gamepad_cursor_speed";
 	var.value = NULL;
-	gampad_cursor_speed = 1.0f;
+	gamepad_cursor_speed = 1.0f;
 	if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) {
-		gampad_cursor_speed = (float)atof(var.value);
+		gamepad_cursor_speed = (float)atof(var.value);
 	}
 
 	var.key = "scummvm_gamepad_cursor_acceleration_time";
@@ -320,13 +320,42 @@ static void update_variables(void) {
 	}
 }
 
-bool timing_inaccuracies_is_enabled(){
+bool retro_setting_get_timing_inaccuracies_enabled(){
 	if (performance_switch & PERF_SWITCH_ON)
 		return (performance_switch & PERF_SWITCH_ENABLE_TIMING_INACCURACIES);
 	else
 		return timing_inaccuracies_enabled;
 }
 
+
+int retro_setting_get_analog_deadzone(void) {
+	return analog_deadzone;
+}
+
+float retro_setting_get_gamepad_cursor_speed(void) {
+	return gamepad_cursor_speed;
+}
+
+bool retro_setting_get_analog_response_is_quadratic(void) {
+	return analog_response_is_quadratic;
+}
+
+float retro_setting_get_mouse_speed(void) {
+	return mouse_speed;
+}
+
+float retro_setting_get_gamepad_acceleration_time(void) {
+	return gamepad_acceleration_time;
+}
+
+float retro_setting_get_frame_rate(void) {
+	return frame_rate;
+}
+
+uint16 retro_setting_get_sample_rate(void) {
+	return sample_rate;
+}
+
 void init_command_params(void) {
 	memset(cmd_params, 0, sizeof(cmd_params));
 	cmd_params_num = 1;
@@ -851,7 +880,7 @@ void retro_run(void) {
 		} while (LIBRETRO_G_SYSTEM->getThreadSwitchCaller() & THREAD_SWITCH_UPDATE);
 
 		poll_cb();
-		LIBRETRO_G_SYSTEM->processMouse(input_cb, retro_device, gampad_cursor_speed, gamepad_acceleration_time, analog_response_is_quadratic, analog_deadzone, mouse_speed);
+		LIBRETRO_G_SYSTEM->processMouse(input_cb, retro_device, gamepad_cursor_speed, gamepad_acceleration_time, analog_response_is_quadratic, analog_deadzone, mouse_speed);
 	}
 }
 


Commit: b320082bd2b02bb23910ea6619c865022d263b5c
    https://github.com/scummvm/scummvm/commit/b320082bd2b02bb23910ea6619c865022d263b5c
Author: Giovanni Cascione (ing.cascione at gmail.com)
Date: 2023-09-09T00:35:59+02:00

Commit Message:
LIBRETRO: refactor log_cb

Changed paths:
    backends/platform/libretro/include/libretro-os.h
    backends/platform/libretro/src/libretro-os-base.cpp
    backends/platform/libretro/src/libretro-os-utils.cpp
    backends/platform/libretro/src/libretro.cpp


diff --git a/backends/platform/libretro/include/libretro-os.h b/backends/platform/libretro/include/libretro-os.h
index f8183dc9b19..4f43cce9ec3 100644
--- a/backends/platform/libretro/include/libretro-os.h
+++ b/backends/platform/libretro/include/libretro-os.h
@@ -32,7 +32,7 @@
 
 #define LIBRETRO_G_SYSTEM dynamic_cast<OSystem_libretro *>(g_system)
 
-extern retro_log_printf_t log_cb;
+extern retro_log_printf_t retro_log_cb;
 extern bool retro_setting_get_timing_inaccuracies_enabled(void);
 extern float retro_setting_get_frame_rate(void);
 extern uint16 retro_setting_get_sample_rate(void);
diff --git a/backends/platform/libretro/src/libretro-os-base.cpp b/backends/platform/libretro/src/libretro-os-base.cpp
index 1b9d51835f6..a24ff8e6a4d 100644
--- a/backends/platform/libretro/src/libretro-os-base.cpp
+++ b/backends/platform/libretro/src/libretro-os-base.cpp
@@ -84,7 +84,7 @@ void OSystem_libretro::initBackend() {
 	_overlay.create(RES_W_OVERLAY, RES_H_OVERLAY, Graphics::PixelFormat(2, 5, 5, 5, 1, 10, 5, 0, 15));
 #endif
 	_mixer = new Audio::MixerImpl(retro_setting_get_sample_rate());
-	log_cb(RETRO_LOG_DEBUG,"Mixer set up at %dHz\n", retro_setting_get_sample_rate());
+	retro_log_cb(RETRO_LOG_DEBUG,"Mixer set up at %dHz\n", retro_setting_get_sample_rate());
 
 	_timerManager = new LibretroTimerManager(retro_setting_get_frame_rate());
 
@@ -97,7 +97,7 @@ void OSystem_libretro::engineInit() {
 	Common::String engineId = ConfMan.get("engineid");
 	if (engineId.equalsIgnoreCase("scumm") && ConfMan.getBool("original_gui")) {
 		ConfMan.setBool("original_gui", false);
-		log_cb(RETRO_LOG_INFO, "\"original_gui\" setting forced to false\n");
+		retro_log_cb(RETRO_LOG_INFO, "\"original_gui\" setting forced to false\n");
 	}
 }
 
diff --git a/backends/platform/libretro/src/libretro-os-utils.cpp b/backends/platform/libretro/src/libretro-os-utils.cpp
index 9a98b2d2648..ec9e945cc91 100644
--- a/backends/platform/libretro/src/libretro-os-utils.cpp
+++ b/backends/platform/libretro/src/libretro-os-utils.cpp
@@ -78,8 +78,8 @@ void OSystem_libretro::logMessage(LogMessageType::Type type, const char *message
 			break;
 	}
 
-	if (log_cb)
-		log_cb(loglevel, "%s\n", message);
+	if (retro_log_cb)
+		retro_log_cb(loglevel, "%s\n", message);
 }
 
 
diff --git a/backends/platform/libretro/src/libretro.cpp b/backends/platform/libretro/src/libretro.cpp
index f0ed8a41377..8ea060d8f70 100644
--- a/backends/platform/libretro/src/libretro.cpp
+++ b/backends/platform/libretro/src/libretro.cpp
@@ -58,7 +58,7 @@
 static struct retro_game_info game_buf;
 static struct retro_game_info * game_buf_ptr;
 
-retro_log_printf_t log_cb = NULL;
+retro_log_printf_t retro_log_cb = NULL;
 static retro_video_refresh_t video_cb = NULL;
 static retro_audio_sample_batch_t audio_batch_cb = NULL;
 static retro_environment_t environ_cb = NULL;
@@ -111,11 +111,11 @@ static int16_t *sound_buffer_empty = NULL;         // pointer to zeroed output b
 
 static void log_scummvm_exit_code(void) {
 	if (retro_get_scummvm_res() == Common::kNoError)
-		log_cb(RETRO_LOG_INFO, "ScummVM exited successfully.\n");
+		retro_log_cb(RETRO_LOG_INFO, "ScummVM exited successfully.\n");
 	else if (retro_get_scummvm_res() < Common::kNoError)
-		log_cb(RETRO_LOG_WARN, "Unknown ScummVM exit code.\n");
+		retro_log_cb(RETRO_LOG_WARN, "Unknown ScummVM exit code.\n");
 	else
-		log_cb(RETRO_LOG_ERROR, "ScummVM exited with error %d.\n", retro_get_scummvm_res());
+		retro_log_cb(RETRO_LOG_ERROR, "ScummVM exited with error %d.\n", retro_get_scummvm_res());
 }
 
 static void audio_buffer_init(uint16 sample_rate, uint16 frame_rate) {
@@ -130,7 +130,7 @@ static void audio_buffer_init(uint16 sample_rate, uint16 frame_rate) {
 		memset(sound_buffer, 0, samples_per_frame_buffer_size);
 		memset(sound_buffer_empty, 0, samples_per_frame_buffer_size);
 	} else
-		log_cb(RETRO_LOG_ERROR, "audio_buffer_init error.\n");
+		retro_log_cb(RETRO_LOG_ERROR, "audio_buffer_init error.\n");
 
 	audio_status |= AUDIO_STATUS_UPDATE_LATENCY;
 }
@@ -152,7 +152,7 @@ static void retro_audio_buff_status_cb(bool active, unsigned occupancy, bool und
 static void increase_performance() {
 	if (!(performance_switch & PERF_SWITCH_ENABLE_TIMING_INACCURACIES)) {
 		performance_switch |= PERF_SWITCH_ENABLE_TIMING_INACCURACIES;
-		log_cb(RETRO_LOG_DEBUG, "Auto performance tuner: 'Allow Timing Inaccuracies' enabled.\n");
+		retro_log_cb(RETRO_LOG_DEBUG, "Auto performance tuner: 'Allow Timing Inaccuracies' enabled.\n");
 		return;
 	}
 
@@ -164,7 +164,7 @@ static void increase_accuracy() {
 
 	if (performance_switch & PERF_SWITCH_ENABLE_TIMING_INACCURACIES) {
 		performance_switch &= ~PERF_SWITCH_ENABLE_TIMING_INACCURACIES;
-		log_cb(RETRO_LOG_DEBUG, "Auto performance tuner: 'Allow Timing Inaccuracies' disabled.\n");
+		retro_log_cb(RETRO_LOG_DEBUG, "Auto performance tuner: 'Allow Timing Inaccuracies' disabled.\n");
 		return;
 	}
 }
@@ -172,7 +172,7 @@ static void increase_accuracy() {
 void reset_performance_tuner() {
 	if (performance_switch & PERF_SWITCH_ON) {
 		performance_switch = PERF_SWITCH_ON;
-		log_cb(RETRO_LOG_DEBUG, "Auto performance tuner: reset.\n");
+		retro_log_cb(RETRO_LOG_DEBUG, "Auto performance tuner: reset.\n");
 	}
 }
 
@@ -298,13 +298,13 @@ static void update_variables(void) {
 
 	if (!(audio_status & AUDIO_STATUS_BUFFER_SUPPORT)) {
 		if (frameskip_type > 1) {
-			log_cb(RETRO_LOG_WARN, "Selected frameskip mode not available.\n");
+			retro_log_cb(RETRO_LOG_WARN, "Selected frameskip mode not available.\n");
 			retro_osd_notification("Selected frameskip mode not available");
 			frameskip_type = 0;
 		}
 
 		if (performance_switch) {
-			log_cb(RETRO_LOG_WARN, "Auto performance tuner not available.\n");
+			retro_log_cb(RETRO_LOG_WARN, "Auto performance tuner not available.\n");
 			retro_osd_notification("Auto performance tuner not available");
 			performance_switch = 0;
 		}
@@ -527,8 +527,8 @@ const char * retro_get_system_dir(void){
 	if (environ_cb(RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY, &sysdir))
 		return sysdir;
 	else {
-		if (log_cb)
-			log_cb(RETRO_LOG_WARN, "No System directory specified, using current directory.\n");
+		if (retro_log_cb)
+			retro_log_cb(RETRO_LOG_WARN, "No System directory specified, using current directory.\n");
 		if (! environ_cb(RETRO_ENVIRONMENT_GET_LIBRETRO_PATH, &coredir))
 			coredir = ".";
 		return coredir;
@@ -543,8 +543,8 @@ const char * retro_get_save_dir(void){
 	if (environ_cb(RETRO_ENVIRONMENT_GET_SAVE_DIRECTORY, &savedir))
 		return savedir;
 	else {
-		if (log_cb)
-			log_cb(RETRO_LOG_WARN, "No Save directory specified, using current directory.\n");
+		if (retro_log_cb)
+			retro_log_cb(RETRO_LOG_WARN, "No Save directory specified, using current directory.\n");
 		if (! environ_cb(RETRO_ENVIRONMENT_GET_LIBRETRO_PATH, &coredir))
 			coredir = ".";
 		return coredir;
@@ -554,11 +554,11 @@ const char * retro_get_save_dir(void){
 void retro_init(void) {
 	struct retro_log_callback log;
 	if (environ_cb(RETRO_ENVIRONMENT_GET_LOG_INTERFACE, &log))
-		log_cb = log.log;
+		retro_log_cb = log.log;
 	else
-		log_cb = NULL;
+		retro_log_cb = NULL;
 
-	log_cb(RETRO_LOG_DEBUG, "ScummVM core version: %s\n",__GIT_VERSION);
+	retro_log_cb(RETRO_LOG_DEBUG, "ScummVM core version: %s\n",__GIT_VERSION);
 
 	struct retro_audio_buffer_status_callback buf_status_cb;
 	buf_status_cb.callback = retro_audio_buff_status_cb;
@@ -608,8 +608,8 @@ void retro_init(void) {
 
 #ifdef FRONTEND_SUPPORTS_RGB565
 	enum retro_pixel_format rgb565 = RETRO_PIXEL_FORMAT_RGB565;
-	if (!environ_cb(RETRO_ENVIRONMENT_SET_PIXEL_FORMAT, &rgb565) && log_cb)
-		log_cb(RETRO_LOG_INFO, "Frontend supports RGB565 -will use that instead of XRGB1555.\n");
+	if (!environ_cb(RETRO_ENVIRONMENT_SET_PIXEL_FORMAT, &rgb565) && retro_log_cb)
+		retro_log_cb(RETRO_LOG_INFO, "Frontend supports RGB565 -will use that instead of XRGB1555.\n");
 #endif
 
 	retro_keyboard_callback cb = {LIBRETRO_G_SYSTEM->processKeyEvent};
@@ -625,8 +625,8 @@ void retro_deinit(void) {
 
 void retro_set_controller_port_device(unsigned port, unsigned device) {
 	if (port != 0) {
-		if (log_cb)
-			log_cb(RETRO_LOG_WARN, "Invalid controller port %d.\n", port);
+		if (retro_log_cb)
+			retro_log_cb(RETRO_LOG_WARN, "Invalid controller port %d.\n", port);
 		return;
 	}
 
@@ -636,16 +636,16 @@ void retro_set_controller_port_device(unsigned port, unsigned device) {
 		retro_device = device;
 		break;
 	default:
-		if (log_cb)
-			log_cb(RETRO_LOG_WARN, "Invalid controller device class %d.\n", device);
+		if (retro_log_cb)
+			retro_log_cb(RETRO_LOG_WARN, "Invalid controller device class %d.\n", device);
 		break;
 	}
 }
 
 bool retro_load_game(const struct retro_game_info *game) {
 	if (!g_system) {
-		if (log_cb)
-			log_cb(RETRO_LOG_ERROR, "[scummvm] Failed to initialize platform driver.\n");
+		if (retro_log_cb)
+			retro_log_cb(RETRO_LOG_ERROR, "[scummvm] Failed to initialize platform driver.\n");
 		return false;
 	}
 
@@ -673,14 +673,14 @@ bool retro_load_game(const struct retro_game_info *game) {
 			// Open the file.
 			RFILE *gamefile = filestream_open(game->path, RETRO_VFS_FILE_ACCESS_READ, RETRO_VFS_FILE_ACCESS_HINT_NONE);
 			if (!gamefile) {
-				log_cb(RETRO_LOG_ERROR, "[scummvm] Failed to load given game file '%s'.\n", game->path);
+				retro_log_cb(RETRO_LOG_ERROR, "[scummvm] Failed to load given game file '%s'.\n", game->path);
 				return false;
 			}
 
 			// Load the file data.
 			if (filestream_gets(gamefile, target_id, sizeof(target_id)) == NULL) {
 				filestream_close(gamefile);
-				log_cb(RETRO_LOG_ERROR, "[scummvm] Failed to load contents of game file '%s'.\n", game->path);
+				retro_log_cb(RETRO_LOG_ERROR, "[scummvm] Failed to load contents of game file '%s'.\n", game->path);
 				return false;
 			}
 			filestream_close(gamefile);
@@ -690,7 +690,7 @@ bool retro_load_game(const struct retro_game_info *game) {
 			strcpy(target_id, tmp.c_str());
 
 			if (strlen(target_id) == 0) {
-				log_cb(RETRO_LOG_ERROR, "[scummvm] Game file '%s' does not contain any target id.\n", game->path);
+				retro_log_cb(RETRO_LOG_ERROR, "[scummvm] Game file '%s' does not contain any target id.\n", game->path);
 				return false;
 			}
 
@@ -701,7 +701,7 @@ bool retro_load_game(const struct retro_game_info *game) {
 			} else {
 				// If this node has no parent node, then it returns a duplicate of this node.
 				if (detect_target.getPath().equals(parent_dir.getPath())) {
-					log_cb(RETRO_LOG_ERROR, "[scummvm] Autodetect not possible. No parent directory detected in '%s'.\n", game->path);
+					retro_log_cb(RETRO_LOG_ERROR, "[scummvm] Autodetect not possible. No parent directory detected in '%s'.\n", game->path);
 					return false;
 				}
 			}
@@ -713,23 +713,23 @@ bool retro_load_game(const struct retro_game_info *game) {
 		switch (test_game_status) {
 		case TEST_GAME_OK_ID_FOUND:
 			sprintf(buffer, "-p \"%s\" %s", parent_dir.getPath().c_str(), target_id);
-			log_cb(RETRO_LOG_DEBUG, "[scummvm] launch via target id and game dir\n");
+			retro_log_cb(RETRO_LOG_DEBUG, "[scummvm] launch via target id and game dir\n");
 			break;
 		case TEST_GAME_OK_TARGET_FOUND:
 			sprintf(buffer, "%s", target_id);
-			log_cb(RETRO_LOG_DEBUG, "[scummvm] launch via target id and scummvm.ini\n");
+			retro_log_cb(RETRO_LOG_DEBUG, "[scummvm] launch via target id and scummvm.ini\n");
 			break;
 		case TEST_GAME_OK_ID_AUTODETECTED:
 			sprintf(buffer, "-p \"%s\" --auto-detect", parent_dir.getPath().c_str());
-			log_cb(RETRO_LOG_DEBUG, "[scummvm] launch via autodetect\n");
+			retro_log_cb(RETRO_LOG_DEBUG, "[scummvm] launch via autodetect\n");
 			break;
 		case TEST_GAME_KO_MULTIPLE_RESULTS:
-			log_cb(RETRO_LOG_WARN, "[scummvm] Multiple targets found for '%s' in scummvm.ini\n", target_id);
+			retro_log_cb(RETRO_LOG_WARN, "[scummvm] Multiple targets found for '%s' in scummvm.ini\n", target_id);
 			retro_osd_notification("Multiple targets found");
 			break;
 		case TEST_GAME_KO_NOT_FOUND:
 		default:
-			log_cb(RETRO_LOG_WARN, "[scummvm] Game not found. Check path and content of '%s'\n", game->path);
+			retro_log_cb(RETRO_LOG_WARN, "[scummvm] Game not found. Check path and content of '%s'\n", game->path);
 			retro_osd_notification("Game not found");
 		}
 
@@ -739,8 +739,8 @@ bool retro_load_game(const struct retro_game_info *game) {
 	}
 
 	if (!retro_init_emu_thread()) {
-		if (log_cb)
-			log_cb(RETRO_LOG_ERROR, "[scummvm] Failed to initialize emulation thread!\n");
+		if (retro_log_cb)
+			retro_log_cb(RETRO_LOG_ERROR, "[scummvm] Failed to initialize emulation thread!\n");
 		return false;
 	}
 	return true;
@@ -818,7 +818,7 @@ void retro_run(void) {
 
 			/* Reset frameskip counter if not flagged */
 			if ((!skip_frame && frameskip_counter) || frameskip_counter >= FRAMESKIP_MAX) {
-				log_cb(RETRO_LOG_DEBUG, "%d frame(s) skipped (%ld)\n", frameskip_counter, current_frame);
+				retro_log_cb(RETRO_LOG_DEBUG, "%d frame(s) skipped (%ld)\n", frameskip_counter, current_frame);
 				skip_frame = false;
 				frameskip_counter = 0;
 			/* Keep on skipping frames if flagged */


Commit: 76d177cec6f61ac38b32acb5f99fd843160eb701
    https://github.com/scummvm/scummvm/commit/76d177cec6f61ac38b32acb5f99fd843160eb701
Author: Giovanni Cascione (ing.cascione at gmail.com)
Date: 2023-09-09T00:36:00+02:00

Commit Message:
LIBRETRO: expose input_cb and refactor

Changed paths:
    backends/platform/libretro/include/libretro-os.h
    backends/platform/libretro/src/libretro-os-inputs.cpp
    backends/platform/libretro/src/libretro.cpp


diff --git a/backends/platform/libretro/include/libretro-os.h b/backends/platform/libretro/include/libretro-os.h
index 4f43cce9ec3..ce81f3d5f0d 100644
--- a/backends/platform/libretro/include/libretro-os.h
+++ b/backends/platform/libretro/include/libretro-os.h
@@ -32,7 +32,9 @@
 
 #define LIBRETRO_G_SYSTEM dynamic_cast<OSystem_libretro *>(g_system)
 
+/* libretro.cpp functions */
 extern retro_log_printf_t retro_log_cb;
+extern retro_input_state_t retro_input_cb;
 extern bool retro_setting_get_timing_inaccuracies_enabled(void);
 extern float retro_setting_get_frame_rate(void);
 extern uint16 retro_setting_get_sample_rate(void);
diff --git a/backends/platform/libretro/src/libretro-os-inputs.cpp b/backends/platform/libretro/src/libretro-os-inputs.cpp
index 9e838570e9a..04ebc4876d1 100644
--- a/backends/platform/libretro/src/libretro-os-inputs.cpp
+++ b/backends/platform/libretro/src/libretro-os-inputs.cpp
@@ -49,7 +49,7 @@ void OSystem_libretro::updateMouseXY(float deltaAcc, float * cumulativeXYAcc, in
 	*relMouseXY = (int)deltaAcc;
 }
 
-void OSystem_libretro::processMouse(retro_input_state_t aCallback, int device, float gampad_cursor_speed, float gamepad_acceleration_time, bool analog_response_is_quadratic, int analog_deadzone, float mouse_speed) {
+void OSystem_libretro::processMouse(retro_input_state_t retro_input_cb, int device, float gampad_cursor_speed, float gamepad_acceleration_time, bool analog_response_is_quadratic, int analog_deadzone, float mouse_speed) {
 	enum processMouse_status {
 		STATUS_DOING_JOYSTICK  = (1 << 0),
 		STATUS_DOING_MOUSE     = (1 << 1),
@@ -95,15 +95,15 @@ void OSystem_libretro::processMouse(retro_input_state_t aCallback, int device, f
 	};
 
 	// Reduce gamepad cursor speed, if required
-	if (device == RETRO_DEVICE_JOYPAD && aCallback(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2)) {
+	if (device == RETRO_DEVICE_JOYPAD && retro_input_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2)) {
 		adjusted_cursor_speed = adjusted_cursor_speed * (1.0f / 5.0f);
 	}
 
 	status = 0;
-	x = aCallback(0, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_X);
-	y = aCallback(0, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_Y);
-	joy_x = aCallback(0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_X);
-	joy_y = aCallback(0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_Y);
+	x = retro_input_cb(0, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_X);
+	y = retro_input_cb(0, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_Y);
+	joy_x = retro_input_cb(0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_X);
+	joy_y = retro_input_cb(0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_Y);
 
 	// Left Analog X Axis
 	if (joy_x > analog_deadzone || joy_x < -analog_deadzone) {
@@ -158,10 +158,10 @@ void OSystem_libretro::processMouse(retro_input_state_t aCallback, int device, f
 	}
 
 	if (device == RETRO_DEVICE_JOYPAD) {
-		bool dpadLeft = aCallback(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT);
-		bool dpadRight = aCallback(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT);
-		bool dpadUp = aCallback(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP);
-		bool dpadDown = aCallback(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN);
+		bool dpadLeft = retro_input_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT);
+		bool dpadRight = retro_input_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT);
+		bool dpadUp = retro_input_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP);
+		bool dpadDown = retro_input_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN);
 
 		if (dpadLeft || dpadRight) {
 			status |= (STATUS_DOING_JOYSTICK | STATUS_DOING_X);
@@ -200,7 +200,7 @@ void OSystem_libretro::processMouse(retro_input_state_t aCallback, int device, f
 			_dpadYVel = 0.0f;
 		}
 
-		if (aCallback(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START)) {
+		if (retro_input_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START)) {
 			Common::Event ev;
 			ev.type = Common::EVENT_MAINMENU;
 			_events.push_back(ev);
@@ -208,9 +208,9 @@ void OSystem_libretro::processMouse(retro_input_state_t aCallback, int device, f
 	}
 
 #if defined(WIIU) || defined(__SWITCH__)
-	int p_x = aCallback(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_X);
-	int p_y = aCallback(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_Y);
-	int p_press = aCallback(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_PRESSED);
+	int p_x = retro_input_cb(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_X);
+	int p_y = retro_input_cb(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_Y);
+	int p_press = retro_input_cb(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_PRESSED);
 	int px = (int)((p_x + 0x7fff) * _screen.w / 0xffff);
 	int py = (int)((p_y + 0x7fff) * _screen.h / 0xffff);
 	// printf("(%d,%d) p:%d\n",px,py,pp);
@@ -262,7 +262,7 @@ void OSystem_libretro::processMouse(retro_input_state_t aCallback, int device, f
 	}
 
 	// Gampad mouse buttons
-	down = aCallback(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A);
+	down = retro_input_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A);
 	if (down != _joypadmouseButtons[0]) {
 		_joypadmouseButtons[0] = down;
 
@@ -273,7 +273,7 @@ void OSystem_libretro::processMouse(retro_input_state_t aCallback, int device, f
 		_events.push_back(ev);
 	}
 
-	down = aCallback(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B);
+	down = retro_input_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B);
 	if (down != _joypadmouseButtons[1]) {
 		_joypadmouseButtons[1] = down;
 
@@ -286,7 +286,7 @@ void OSystem_libretro::processMouse(retro_input_state_t aCallback, int device, f
 
 	// Gamepad keyboard buttons
 	for (int i = 0; i < 8; i++) {
-		down = aCallback(0, RETRO_DEVICE_JOYPAD, 0, gampad_key_map[i][0]);
+		down = retro_input_cb(0, RETRO_DEVICE_JOYPAD, 0, gampad_key_map[i][0]);
 		if (down != _joypadkeyboardButtons[i]) {
 			_joypadkeyboardButtons[i] = down;
 			bool state = down ? true : false;
@@ -295,8 +295,8 @@ void OSystem_libretro::processMouse(retro_input_state_t aCallback, int device, f
 	}
 
 	// Gamepad right stick numpad emulation
-	joy_rx = aCallback(0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_X);
-	joy_ry = aCallback(0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_Y);
+	joy_rx = retro_input_cb(0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_X);
+	joy_ry = retro_input_cb(0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_Y);
 
 	if (joy_rx > analog_deadzone)
 		joy_rx = joy_rx - analog_deadzone;
@@ -401,7 +401,7 @@ void OSystem_libretro::processMouse(retro_input_state_t aCallback, int device, f
 
 	for (int i = 0; i < 2; i++) {
 		Common::Event ev;
-		bool down = aCallback(0, RETRO_DEVICE_MOUSE, 0, retroButtons[i]);
+		bool down = retro_input_cb(0, RETRO_DEVICE_MOUSE, 0, retroButtons[i]);
 		if (down != _mouseButtons[i]) {
 			_mouseButtons[i] = down;
 
diff --git a/backends/platform/libretro/src/libretro.cpp b/backends/platform/libretro/src/libretro.cpp
index 8ea060d8f70..4d17c4b3512 100644
--- a/backends/platform/libretro/src/libretro.cpp
+++ b/backends/platform/libretro/src/libretro.cpp
@@ -59,11 +59,11 @@ static struct retro_game_info game_buf;
 static struct retro_game_info * game_buf_ptr;
 
 retro_log_printf_t retro_log_cb = NULL;
+retro_input_state_t retro_input_cb = NULL;
 static retro_video_refresh_t video_cb = NULL;
 static retro_audio_sample_batch_t audio_batch_cb = NULL;
 static retro_environment_t environ_cb = NULL;
 static retro_input_poll_t poll_cb = NULL;
-static retro_input_state_t input_cb = NULL;
 static int retro_device = RETRO_DEVICE_JOYPAD;
 
 // System analog stick range is -0x8000 to 0x8000
@@ -479,7 +479,7 @@ void retro_set_input_poll(retro_input_poll_t cb) {
 }
 
 void retro_set_input_state(retro_input_state_t cb) {
-	input_cb = cb;
+	retro_input_cb = cb;
 }
 
 void retro_set_environment(retro_environment_t cb) {
@@ -880,7 +880,7 @@ void retro_run(void) {
 		} while (LIBRETRO_G_SYSTEM->getThreadSwitchCaller() & THREAD_SWITCH_UPDATE);
 
 		poll_cb();
-		LIBRETRO_G_SYSTEM->processMouse(input_cb, retro_device, gamepad_cursor_speed, gamepad_acceleration_time, analog_response_is_quadratic, analog_deadzone, mouse_speed);
+		LIBRETRO_G_SYSTEM->processMouse(retro_input_cb, retro_device, gamepad_cursor_speed, gamepad_acceleration_time, analog_response_is_quadratic, analog_deadzone, mouse_speed);
 	}
 }
 


Commit: 96710cd093998ef7cb4ede77a21843f905296b3e
    https://github.com/scummvm/scummvm/commit/96710cd093998ef7cb4ede77a21843f905296b3e
Author: Giovanni Cascione (ing.cascione at gmail.com)
Date: 2023-09-09T00:36:01+02:00

Commit Message:
LIBRETRO: refactor retro_input_device and add get function

Changed paths:
    backends/platform/libretro/include/libretro-os.h
    backends/platform/libretro/src/libretro.cpp


diff --git a/backends/platform/libretro/include/libretro-os.h b/backends/platform/libretro/include/libretro-os.h
index ce81f3d5f0d..a1bf26d4539 100644
--- a/backends/platform/libretro/include/libretro-os.h
+++ b/backends/platform/libretro/include/libretro-os.h
@@ -45,6 +45,7 @@ extern float retro_setting_get_gamepad_cursor_speed(void);
 extern float retro_setting_get_gamepad_acceleration_time(void);
 extern void reset_performance_tuner(void);
 extern void retro_osd_notification(const char* msg);
+extern int retro_get_input_device(void);
 extern const char * retro_get_system_dir(void);
 extern const char * retro_get_save_dir(void);
 
diff --git a/backends/platform/libretro/src/libretro.cpp b/backends/platform/libretro/src/libretro.cpp
index 4d17c4b3512..4e0350ab410 100644
--- a/backends/platform/libretro/src/libretro.cpp
+++ b/backends/platform/libretro/src/libretro.cpp
@@ -64,7 +64,7 @@ static retro_video_refresh_t video_cb = NULL;
 static retro_audio_sample_batch_t audio_batch_cb = NULL;
 static retro_environment_t environ_cb = NULL;
 static retro_input_poll_t poll_cb = NULL;
-static int retro_device = RETRO_DEVICE_JOYPAD;
+static int retro_input_device = RETRO_DEVICE_JOYPAD;
 
 // System analog stick range is -0x8000 to 0x8000
 #define ANALOG_RANGE 0x8000
@@ -362,6 +362,10 @@ void init_command_params(void) {
 	strcpy(cmd_params[0], "scummvm\0");
 }
 
+int retro_get_input_device(void) {
+	return retro_input_device;
+}
+
 void parse_command_params(char *cmdline) {
 	int j = 0;
 	int cmdlen = strlen(cmdline);
@@ -633,7 +637,7 @@ void retro_set_controller_port_device(unsigned port, unsigned device) {
 	switch (device) {
 	case RETRO_DEVICE_JOYPAD:
 	case RETRO_DEVICE_MOUSE:
-		retro_device = device;
+		retro_input_device = device;
 		break;
 	default:
 		if (retro_log_cb)
@@ -880,7 +884,7 @@ void retro_run(void) {
 		} while (LIBRETRO_G_SYSTEM->getThreadSwitchCaller() & THREAD_SWITCH_UPDATE);
 
 		poll_cb();
-		LIBRETRO_G_SYSTEM->processMouse(retro_input_cb, retro_device, gamepad_cursor_speed, gamepad_acceleration_time, analog_response_is_quadratic, analog_deadzone, mouse_speed);
+		LIBRETRO_G_SYSTEM->processMouse(retro_input_cb, retro_input_device, gamepad_cursor_speed, gamepad_acceleration_time, analog_response_is_quadratic, analog_deadzone, mouse_speed);
 	}
 }
 


Commit: c92f3dba012ea91aecb572ed33c07b2446c496c9
    https://github.com/scummvm/scummvm/commit/c92f3dba012ea91aecb572ed33c07b2446c496c9
Author: Giovanni Cascione (ing.cascione at gmail.com)
Date: 2023-09-09T00:36:02+02:00

Commit Message:
LIBRETRO: extended retro_set_controller_port_device to additional devices

Changed paths:
    backends/platform/libretro/src/libretro.cpp


diff --git a/backends/platform/libretro/src/libretro.cpp b/backends/platform/libretro/src/libretro.cpp
index 4e0350ab410..26944575591 100644
--- a/backends/platform/libretro/src/libretro.cpp
+++ b/backends/platform/libretro/src/libretro.cpp
@@ -630,13 +630,16 @@ void retro_deinit(void) {
 void retro_set_controller_port_device(unsigned port, unsigned device) {
 	if (port != 0) {
 		if (retro_log_cb)
-			retro_log_cb(RETRO_LOG_WARN, "Invalid controller port %d.\n", port);
+			retro_log_cb(RETRO_LOG_WARN, "Invalid controller port %d, expected port 0 (#1)\n", port);
 		return;
 	}
 
 	switch (device) {
 	case RETRO_DEVICE_JOYPAD:
 	case RETRO_DEVICE_MOUSE:
+	case RETRO_DEVICE_KEYBOARD:
+	case RETRO_DEVICE_ANALOG:
+	case RETRO_DEVICE_POINTER:
 		retro_input_device = device;
 		break;
 	default:


Commit: ca0eb9493350b87f6918867d55ec0dce1c5bf71d
    https://github.com/scummvm/scummvm/commit/ca0eb9493350b87f6918867d55ec0dce1c5bf71d
Author: Giovanni Cascione (ing.cascione at gmail.com)
Date: 2023-09-09T00:36:02+02:00

Commit Message:
LIBRETRO: remove processMouse arguments

Changed paths:
    backends/platform/libretro/include/libretro-os.h
    backends/platform/libretro/src/libretro-os-inputs.cpp
    backends/platform/libretro/src/libretro.cpp


diff --git a/backends/platform/libretro/include/libretro-os.h b/backends/platform/libretro/include/libretro-os.h
index a1bf26d4539..9f2884ef337 100644
--- a/backends/platform/libretro/include/libretro-os.h
+++ b/backends/platform/libretro/include/libretro-os.h
@@ -181,7 +181,7 @@ private:
 
 	/* Inputs */
 public:
-	void processMouse(retro_input_state_t aCallback, int device, float gampad_cursor_speed, float gamepad_acceleration_time, bool analog_response_is_quadratic, int analog_deadzone, float mouse_speed);
+	void processMouse(void);
 	static void processKeyEvent(bool down, unsigned keycode, uint32_t character, uint16_t key_modifiers);
 	void setShakePos(int shakeXOffset, int shakeYOffset) override {}
 private:
diff --git a/backends/platform/libretro/src/libretro-os-inputs.cpp b/backends/platform/libretro/src/libretro-os-inputs.cpp
index 04ebc4876d1..ba3e4b9446c 100644
--- a/backends/platform/libretro/src/libretro-os-inputs.cpp
+++ b/backends/platform/libretro/src/libretro-os-inputs.cpp
@@ -49,7 +49,7 @@ void OSystem_libretro::updateMouseXY(float deltaAcc, float * cumulativeXYAcc, in
 	*relMouseXY = (int)deltaAcc;
 }
 
-void OSystem_libretro::processMouse(retro_input_state_t retro_input_cb, int device, float gampad_cursor_speed, float gamepad_acceleration_time, bool analog_response_is_quadratic, int analog_deadzone, float mouse_speed) {
+void OSystem_libretro::processMouse(void) {
 	enum processMouse_status {
 		STATUS_DOING_JOYSTICK  = (1 << 0),
 		STATUS_DOING_MOUSE     = (1 << 1),
@@ -62,8 +62,8 @@ void OSystem_libretro::processMouse(retro_input_state_t retro_input_cb, int devi
 	float deltaAcc;
 	bool  down;
 	float screen_adjusted_cursor_speed = (float)_screen.w / 320.0f; // Dpad cursor speed should always be based off a 320 wide screen, to keep speeds consistent
-	float adjusted_cursor_speed = (float)BASE_CURSOR_SPEED * gampad_cursor_speed * screen_adjusted_cursor_speed;
-	float inverse_acceleration_time = (gamepad_acceleration_time > 0.0) ? (1.0 / 60.0) * (1.0 / gamepad_acceleration_time) : 1.0;
+	float adjusted_cursor_speed = (float)BASE_CURSOR_SPEED * retro_setting_get_gamepad_cursor_speed() * screen_adjusted_cursor_speed;
+	float inverse_acceleration_time = (retro_setting_get_gamepad_acceleration_time() > 0.0) ? (1.0 / 60.0) * (1.0 / retro_setting_get_gamepad_acceleration_time()) : 1.0;
 	int dpad_cursor_offset;
 	double rs_radius, rs_angle;
 	unsigned numpad_index;
@@ -95,7 +95,7 @@ void OSystem_libretro::processMouse(retro_input_state_t retro_input_cb, int devi
 	};
 
 	// Reduce gamepad cursor speed, if required
-	if (device == RETRO_DEVICE_JOYPAD && retro_input_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2)) {
+	if (retro_get_input_device() == RETRO_DEVICE_JOYPAD && retro_input_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2)) {
 		adjusted_cursor_speed = adjusted_cursor_speed * (1.0f / 5.0f);
 	}
 
@@ -106,21 +106,21 @@ void OSystem_libretro::processMouse(retro_input_state_t retro_input_cb, int devi
 	joy_y = retro_input_cb(0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_Y);
 
 	// Left Analog X Axis
-	if (joy_x > analog_deadzone || joy_x < -analog_deadzone) {
+	if (joy_x > retro_setting_get_analog_deadzone() || joy_x < -retro_setting_get_analog_deadzone()) {
 		status |= (STATUS_DOING_JOYSTICK | STATUS_DOING_X);
-		if (joy_x > analog_deadzone) {
+		if (joy_x > retro_setting_get_analog_deadzone()) {
 			// Reset accumulator when changing direction
 			_mouseXAcc = (_mouseXAcc < 0.0) ? 0.0 : _mouseXAcc;
-			joy_x = joy_x - analog_deadzone;
+			joy_x = joy_x - retro_setting_get_analog_deadzone();
 		}
-		if (joy_x < -analog_deadzone) {
+		if (joy_x < -retro_setting_get_analog_deadzone()) {
 			// Reset accumulator when changing direction
 			_mouseXAcc = (_mouseXAcc > 0.0) ? 0.0 : _mouseXAcc;
-			joy_x = joy_x + analog_deadzone;
+			joy_x = joy_x + retro_setting_get_analog_deadzone();
 		}
 		// Update accumulator
-		analog_amplitude_x = (float)joy_x / (float)(ANALOG_RANGE - analog_deadzone);
-		if (analog_response_is_quadratic) {
+		analog_amplitude_x = (float)joy_x / (float)(ANALOG_RANGE - retro_setting_get_analog_deadzone());
+		if (retro_setting_get_analog_response_is_quadratic()) {
 			if (analog_amplitude_x < 0.0)
 				analog_amplitude_x = -(analog_amplitude_x * analog_amplitude_x);
 			else
@@ -132,21 +132,21 @@ void OSystem_libretro::processMouse(retro_input_state_t retro_input_cb, int devi
 	}
 
 	// Left Analog Y Axis
-	if (joy_y > analog_deadzone || joy_y < -analog_deadzone) {
+	if (joy_y > retro_setting_get_analog_deadzone() || joy_y < -retro_setting_get_analog_deadzone()) {
 		status |= (STATUS_DOING_JOYSTICK | STATUS_DOING_Y);
-		if (joy_y > analog_deadzone) {
+		if (joy_y > retro_setting_get_analog_deadzone()) {
 			// Reset accumulator when changing direction
 			_mouseYAcc = (_mouseYAcc < 0.0) ? 0.0 : _mouseYAcc;
-			joy_y = joy_y - analog_deadzone;
+			joy_y = joy_y - retro_setting_get_analog_deadzone();
 		}
-		if (joy_y < -analog_deadzone) {
+		if (joy_y < -retro_setting_get_analog_deadzone()) {
 			// Reset accumulator when changing direction
 			_mouseYAcc = (_mouseYAcc > 0.0) ? 0.0 : _mouseYAcc;
-			joy_y = joy_y + analog_deadzone;
+			joy_y = joy_y + retro_setting_get_analog_deadzone();
 		}
 		// Update accumulator
-		analog_amplitude_y = (float)joy_y / (float)(ANALOG_RANGE - analog_deadzone);
-		if (analog_response_is_quadratic) {
+		analog_amplitude_y = (float)joy_y / (float)(ANALOG_RANGE - retro_setting_get_analog_deadzone());
+		if (retro_setting_get_analog_response_is_quadratic()) {
 			if (analog_amplitude_y < 0.0)
 				analog_amplitude_y = -(analog_amplitude_y * analog_amplitude_y);
 			else
@@ -157,7 +157,7 @@ void OSystem_libretro::processMouse(retro_input_state_t retro_input_cb, int devi
 		updateMouseXY(deltaAcc, &_mouseYAcc, 0);
 	}
 
-	if (device == RETRO_DEVICE_JOYPAD) {
+	if (retro_get_input_device() == RETRO_DEVICE_JOYPAD) {
 		bool dpadLeft = retro_input_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT);
 		bool dpadRight = retro_input_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT);
 		bool dpadUp = retro_input_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP);
@@ -298,24 +298,24 @@ void OSystem_libretro::processMouse(retro_input_state_t retro_input_cb, int devi
 	joy_rx = retro_input_cb(0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_X);
 	joy_ry = retro_input_cb(0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_Y);
 
-	if (joy_rx > analog_deadzone)
-		joy_rx = joy_rx - analog_deadzone;
-	else if (joy_rx < -analog_deadzone)
-		joy_rx = joy_rx + analog_deadzone;
+	if (joy_rx > retro_setting_get_analog_deadzone())
+		joy_rx = joy_rx - retro_setting_get_analog_deadzone();
+	else if (joy_rx < -retro_setting_get_analog_deadzone())
+		joy_rx = joy_rx + retro_setting_get_analog_deadzone();
 	else
 		joy_rx = 0;
 
-	if (joy_ry > analog_deadzone)
-		joy_ry = joy_ry - analog_deadzone;
-	else if (joy_ry < -analog_deadzone)
-		joy_ry = joy_ry + analog_deadzone;
+	if (joy_ry > retro_setting_get_analog_deadzone())
+		joy_ry = joy_ry - retro_setting_get_analog_deadzone();
+	else if (joy_ry < -retro_setting_get_analog_deadzone())
+		joy_ry = joy_ry + retro_setting_get_analog_deadzone();
 	else
 		joy_ry = 0;
 
 	// This is very ugly, but I don't have time to make it nicer...
 	if (joy_rx != 0 || joy_ry != 0) {
-		analog_amplitude_x = (float)joy_rx / (float)(ANALOG_RANGE - analog_deadzone);
-		analog_amplitude_y = (float)joy_ry / (float)(ANALOG_RANGE - analog_deadzone);
+		analog_amplitude_x = (float)joy_rx / (float)(ANALOG_RANGE - retro_setting_get_analog_deadzone());
+		analog_amplitude_y = (float)joy_ry / (float)(ANALOG_RANGE - retro_setting_get_analog_deadzone());
 
 		// Convert to polar coordinates: part 1
 		rs_radius = sqrt((double)(analog_amplitude_x * analog_amplitude_x) + (double)(analog_amplitude_y * analog_amplitude_y));
@@ -371,7 +371,7 @@ void OSystem_libretro::processMouse(retro_input_state_t retro_input_cb, int devi
 			// Reset accumulator when changing direction
 			_mouseXAcc = (_mouseXAcc > 0.0) ? 0.0 : _mouseXAcc;
 		}
-		deltaAcc = (float)x * mouse_speed;
+		deltaAcc = (float)x * retro_setting_get_mouse_speed();
 		updateMouseXY(deltaAcc, &_mouseXAcc, 1);
 	}
 	// > Y Axis
@@ -385,7 +385,7 @@ void OSystem_libretro::processMouse(retro_input_state_t retro_input_cb, int devi
 			// Reset accumulator when changing direction
 			_mouseYAcc = (_mouseYAcc > 0.0) ? 0.0 : _mouseYAcc;
 		}
-		deltaAcc = (float)y * mouse_speed;
+		deltaAcc = (float)y * retro_setting_get_mouse_speed();
 		updateMouseXY(deltaAcc, &_mouseYAcc, 0);
 	}
 
diff --git a/backends/platform/libretro/src/libretro.cpp b/backends/platform/libretro/src/libretro.cpp
index 26944575591..d1d65d5ee35 100644
--- a/backends/platform/libretro/src/libretro.cpp
+++ b/backends/platform/libretro/src/libretro.cpp
@@ -887,7 +887,7 @@ void retro_run(void) {
 		} while (LIBRETRO_G_SYSTEM->getThreadSwitchCaller() & THREAD_SWITCH_UPDATE);
 
 		poll_cb();
-		LIBRETRO_G_SYSTEM->processMouse(retro_input_cb, retro_input_device, gamepad_cursor_speed, gamepad_acceleration_time, analog_response_is_quadratic, analog_deadzone, mouse_speed);
+		LIBRETRO_G_SYSTEM->processMouse();
 	}
 }
 


Commit: ba58463669990b03d94cf66997d2d634c0d57c5c
    https://github.com/scummvm/scummvm/commit/ba58463669990b03d94cf66997d2d634c0d57c5c
Author: Giovanni Cascione (ing.cascione at gmail.com)
Date: 2023-09-09T00:36:03+02:00

Commit Message:
LIBRETRO: add OSystem_libretro::refreshRetroSettings()

Changed paths:
    backends/platform/libretro/include/libretro-os.h
    backends/platform/libretro/src/libretro-os-base.cpp
    backends/platform/libretro/src/libretro-os-graphics.cpp
    backends/platform/libretro/src/libretro-os-inputs.cpp
    backends/platform/libretro/src/libretro.cpp


diff --git a/backends/platform/libretro/include/libretro-os.h b/backends/platform/libretro/include/libretro-os.h
index 9f2884ef337..6f5ac479d3f 100644
--- a/backends/platform/libretro/include/libretro-os.h
+++ b/backends/platform/libretro/include/libretro-os.h
@@ -30,6 +30,8 @@
 #include "graphics/palette.h"
 #include "graphics/surface.h"
 
+#define BASE_CURSOR_SPEED 4
+
 #define LIBRETRO_G_SYSTEM dynamic_cast<OSystem_libretro *>(g_system)
 
 /* libretro.cpp functions */
@@ -86,6 +88,8 @@ private:
 	float _dpadXVel;
 	float _dpadYVel;
 	unsigned _joypadnumpadLast;
+	float _adjusted_cursor_speed;
+	float _inverse_acceleration_time;
 	uint32 _startTime;
 	uint8 _threadSwitchCaller;
 	Common::String s_systemDir;
@@ -123,6 +127,7 @@ public:
 	bool hasFeature(Feature f) override;
 	void setFeatureState(Feature f, bool enable) override;
 	bool getFeatureState(Feature f) override;
+	void refreshRetroSettings(void);
 	void destroy(void);
 	void quit() override {}
 
diff --git a/backends/platform/libretro/src/libretro-os-base.cpp b/backends/platform/libretro/src/libretro-os-base.cpp
index a24ff8e6a4d..982d32d78b7 100644
--- a/backends/platform/libretro/src/libretro-os-base.cpp
+++ b/backends/platform/libretro/src/libretro-os-base.cpp
@@ -91,6 +91,8 @@ void OSystem_libretro::initBackend() {
 	_mixer->setReady(true);
 
 	EventsBaseBackend::initBackend();
+
+	refreshRetroSettings();
 }
 
 void OSystem_libretro::engineInit() {
@@ -122,6 +124,11 @@ Audio::Mixer *OSystem_libretro::getMixer() {
         return _mixer;
 }
 
+void OSystem_libretro::refreshRetroSettings() {
+        _adjusted_cursor_speed = (float)BASE_CURSOR_SPEED * retro_setting_get_gamepad_cursor_speed() * (float)(_overlayInGUI ? _overlay.w : _gameScreen.w) / 320.0f; // Dpad cursor speed should always be based off a 320 wide screen, to keep speeds consistent;
+        _inverse_acceleration_time = (retro_setting_get_gamepad_acceleration_time() > 0.0) ? (1.0 / 60.0) * (1.0 / retro_setting_get_gamepad_acceleration_time()) : 1.0;
+}
+
 void OSystem_libretro::destroy() {
 	delete this;
 }
diff --git a/backends/platform/libretro/src/libretro-os-graphics.cpp b/backends/platform/libretro/src/libretro-os-graphics.cpp
index af9dc35dd0f..16e76513bf1 100644
--- a/backends/platform/libretro/src/libretro-os-graphics.cpp
+++ b/backends/platform/libretro/src/libretro-os-graphics.cpp
@@ -245,6 +245,7 @@ const OSystem_libretro::GraphicsMode *OSystem_libretro::getSupportedGraphicsMode
 
 void OSystem_libretro::initSize(uint width, uint height, const Graphics::PixelFormat *format) {
 	_gameScreen.create(width, height, format ? *format : Graphics::PixelFormat::createFormatCLUT8());
+	refreshRetroSettings();
 }
 
 int16 OSystem_libretro::getHeight() {
diff --git a/backends/platform/libretro/src/libretro-os-inputs.cpp b/backends/platform/libretro/src/libretro-os-inputs.cpp
index ba3e4b9446c..5b5574d3441 100644
--- a/backends/platform/libretro/src/libretro-os-inputs.cpp
+++ b/backends/platform/libretro/src/libretro-os-inputs.cpp
@@ -19,7 +19,6 @@
 #include "backends/platform/libretro/include/libretro-os.h"
 
 #define ANALOG_RANGE 0x8000
-#define BASE_CURSOR_SPEED 4
 #define PI 3.141592653589793238
 
 void OSystem_libretro::updateMouseXY(float deltaAcc, float * cumulativeXYAcc, int doing_x){
@@ -61,9 +60,6 @@ void OSystem_libretro::processMouse(void) {
 	float analog_amplitude_x, analog_amplitude_y;
 	float deltaAcc;
 	bool  down;
-	float screen_adjusted_cursor_speed = (float)_screen.w / 320.0f; // Dpad cursor speed should always be based off a 320 wide screen, to keep speeds consistent
-	float adjusted_cursor_speed = (float)BASE_CURSOR_SPEED * retro_setting_get_gamepad_cursor_speed() * screen_adjusted_cursor_speed;
-	float inverse_acceleration_time = (retro_setting_get_gamepad_acceleration_time() > 0.0) ? (1.0 / 60.0) * (1.0 / retro_setting_get_gamepad_acceleration_time()) : 1.0;
 	int dpad_cursor_offset;
 	double rs_radius, rs_angle;
 	unsigned numpad_index;
@@ -96,7 +92,7 @@ void OSystem_libretro::processMouse(void) {
 
 	// Reduce gamepad cursor speed, if required
 	if (retro_get_input_device() == RETRO_DEVICE_JOYPAD && retro_input_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2)) {
-		adjusted_cursor_speed = adjusted_cursor_speed * (1.0f / 5.0f);
+		_adjusted_cursor_speed = _adjusted_cursor_speed * (1.0f / 5.0f);
 	}
 
 	status = 0;
@@ -127,7 +123,7 @@ void OSystem_libretro::processMouse(void) {
 				analog_amplitude_x = analog_amplitude_x * analog_amplitude_x;
 		}
 		// printf("analog_amplitude_x: %f\n", analog_amplitude_x);
-		deltaAcc = analog_amplitude_x * adjusted_cursor_speed;
+		deltaAcc = analog_amplitude_x * _adjusted_cursor_speed;
 		updateMouseXY(deltaAcc, &_mouseXAcc, 1);
 	}
 
@@ -153,7 +149,7 @@ void OSystem_libretro::processMouse(void) {
 				analog_amplitude_y = analog_amplitude_y * analog_amplitude_y;
 		}
 		// printf("analog_amplitude_y: %f\n", analog_amplitude_y);
-		deltaAcc = analog_amplitude_y * adjusted_cursor_speed;
+		deltaAcc = analog_amplitude_y * _adjusted_cursor_speed;
 		updateMouseXY(deltaAcc, &_mouseYAcc, 0);
 	}
 
@@ -165,13 +161,13 @@ void OSystem_libretro::processMouse(void) {
 
 		if (dpadLeft || dpadRight) {
 			status |= (STATUS_DOING_JOYSTICK | STATUS_DOING_X);
-			_dpadXVel = MIN(_dpadXVel + inverse_acceleration_time, 1.0f);
+			_dpadXVel = MIN(_dpadXVel + _inverse_acceleration_time, 1.0f);
 
 			if (dpadLeft) {
-				deltaAcc = -(_dpadXVel * adjusted_cursor_speed);
+				deltaAcc = -(_dpadXVel * _adjusted_cursor_speed);
 				_dpadXAcc = _dpadXAcc < deltaAcc ? _dpadXAcc : 0.0f;
 			} else { //dpadRight
-				deltaAcc = _dpadXVel * adjusted_cursor_speed;
+				deltaAcc = _dpadXVel * _adjusted_cursor_speed;
 				_dpadXAcc = _dpadXAcc > deltaAcc ? _dpadXAcc : 0.0f;
 			}
 
@@ -183,13 +179,13 @@ void OSystem_libretro::processMouse(void) {
 
 		if (dpadUp || dpadDown) {
 			status |= (STATUS_DOING_JOYSTICK | STATUS_DOING_Y);
-			_dpadYVel = MIN(_dpadYVel + inverse_acceleration_time, 1.0f);
+			_dpadYVel = MIN(_dpadYVel + _inverse_acceleration_time, 1.0f);
 
 			if (dpadUp) {
-				deltaAcc = -(_dpadYVel * adjusted_cursor_speed);
+				deltaAcc = -(_dpadYVel * _adjusted_cursor_speed);
 				_dpadYAcc = _dpadYAcc < deltaAcc ? _dpadYAcc : 0.0f;
 			} else { //dpadDown
-				deltaAcc = _dpadYVel * adjusted_cursor_speed;
+				deltaAcc = _dpadYVel * _adjusted_cursor_speed;
 				_dpadYAcc = _dpadYAcc > deltaAcc ? _dpadYAcc : 0.0f;
 			}
 
diff --git a/backends/platform/libretro/src/libretro.cpp b/backends/platform/libretro/src/libretro.cpp
index d1d65d5ee35..b80544a4edd 100644
--- a/backends/platform/libretro/src/libretro.cpp
+++ b/backends/platform/libretro/src/libretro.cpp
@@ -761,6 +761,7 @@ void retro_run(void) {
 	bool updated = false;
 	if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE, &updated) && updated){
 		update_variables();
+		LIBRETRO_G_SYSTEM->refreshRetroSettings();
 	}
 
 	if (audio_status & AUDIO_STATUS_UPDATE_AV_INFO){


Commit: 9617f010b59624244df545154decb162a06d8764
    https://github.com/scummvm/scummvm/commit/9617f010b59624244df545154decb162a06d8764
Author: Giovanni Cascione (ing.cascione at gmail.com)
Date: 2023-09-09T00:36:04+02:00

Commit Message:
LIBRETRO: add OSystem_libretro::getMouseXYFromAnalog()

Changed paths:
    backends/platform/libretro/include/libretro-os.h
    backends/platform/libretro/src/libretro-os-inputs.cpp


diff --git a/backends/platform/libretro/include/libretro-os.h b/backends/platform/libretro/include/libretro-os.h
index 6f5ac479d3f..fa8011c2518 100644
--- a/backends/platform/libretro/include/libretro-os.h
+++ b/backends/platform/libretro/include/libretro-os.h
@@ -191,7 +191,7 @@ public:
 	void setShakePos(int shakeXOffset, int shakeYOffset) override {}
 private:
 	void updateMouseXY(float deltaAcc, float * cumulativeXYAcc, int doing_x);
-
+	void getMouseXYFromAnalog(bool is_x, int16_t coor);
 };
 
 #endif
diff --git a/backends/platform/libretro/src/libretro-os-inputs.cpp b/backends/platform/libretro/src/libretro-os-inputs.cpp
index 5b5574d3441..7909971533e 100644
--- a/backends/platform/libretro/src/libretro-os-inputs.cpp
+++ b/backends/platform/libretro/src/libretro-os-inputs.cpp
@@ -21,6 +21,14 @@
 #define ANALOG_RANGE 0x8000
 #define PI 3.141592653589793238
 
+uint8_t status = 0;
+enum processMouse_status {
+	STATUS_DOING_JOYSTICK  = (1 << 0),
+	STATUS_DOING_MOUSE     = (1 << 1),
+	STATUS_DOING_X         = (1 << 2),
+	STATUS_DOING_Y         = (1 << 3)
+};
+
 void OSystem_libretro::updateMouseXY(float deltaAcc, float * cumulativeXYAcc, int doing_x){
 	int * mouseXY;
 	int16 * screen_wh;
@@ -48,15 +56,38 @@ void OSystem_libretro::updateMouseXY(float deltaAcc, float * cumulativeXYAcc, in
 	*relMouseXY = (int)deltaAcc;
 }
 
+void OSystem_libretro::getMouseXYFromAnalog(bool is_x, int16_t coor) {
+
+	int16_t sign = (coor > 0) - (coor < 0);
+	uint16_t abs_coor = abs(coor);
+	float * mouseAcc;
+
+	if (abs_coor < retro_setting_get_analog_deadzone()) return;
+
+	status |= STATUS_DOING_JOYSTICK;
+
+	if (is_x) {
+		status |= STATUS_DOING_X;
+		mouseAcc = &_mouseXAcc;
+	} else {
+		status |= STATUS_DOING_Y;
+		mouseAcc = &_mouseYAcc;
+	}
+
+	*mouseAcc = ((*mouseAcc > 0) - (*mouseAcc < 0)) == sign ? *mouseAcc : 0;
+	float analog_amplitude = (float)(abs_coor - retro_setting_get_analog_deadzone()) / (float)(ANALOG_RANGE - retro_setting_get_analog_deadzone());
+
+	if (retro_setting_get_analog_response_is_quadratic())
+		analog_amplitude *= analog_amplitude;
+
+	if (sign < 0)
+		analog_amplitude = -analog_amplitude;
+
+	updateMouseXY(analog_amplitude * _adjusted_cursor_speed, mouseAcc, is_x);
+}
+
 void OSystem_libretro::processMouse(void) {
-	enum processMouse_status {
-		STATUS_DOING_JOYSTICK  = (1 << 0),
-		STATUS_DOING_MOUSE     = (1 << 1),
-		STATUS_DOING_X         = (1 << 2),
-		STATUS_DOING_Y         = (1 << 3)
-	};
-	uint8_t status = 0;
-	int16_t joy_x, joy_y, joy_rx, joy_ry, x, y;
+	int16_t joy_rx, joy_ry, x, y;
 	float analog_amplitude_x, analog_amplitude_y;
 	float deltaAcc;
 	bool  down;
@@ -98,60 +129,9 @@ void OSystem_libretro::processMouse(void) {
 	status = 0;
 	x = retro_input_cb(0, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_X);
 	y = retro_input_cb(0, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_Y);
-	joy_x = retro_input_cb(0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_X);
-	joy_y = retro_input_cb(0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_Y);
 
-	// Left Analog X Axis
-	if (joy_x > retro_setting_get_analog_deadzone() || joy_x < -retro_setting_get_analog_deadzone()) {
-		status |= (STATUS_DOING_JOYSTICK | STATUS_DOING_X);
-		if (joy_x > retro_setting_get_analog_deadzone()) {
-			// Reset accumulator when changing direction
-			_mouseXAcc = (_mouseXAcc < 0.0) ? 0.0 : _mouseXAcc;
-			joy_x = joy_x - retro_setting_get_analog_deadzone();
-		}
-		if (joy_x < -retro_setting_get_analog_deadzone()) {
-			// Reset accumulator when changing direction
-			_mouseXAcc = (_mouseXAcc > 0.0) ? 0.0 : _mouseXAcc;
-			joy_x = joy_x + retro_setting_get_analog_deadzone();
-		}
-		// Update accumulator
-		analog_amplitude_x = (float)joy_x / (float)(ANALOG_RANGE - retro_setting_get_analog_deadzone());
-		if (retro_setting_get_analog_response_is_quadratic()) {
-			if (analog_amplitude_x < 0.0)
-				analog_amplitude_x = -(analog_amplitude_x * analog_amplitude_x);
-			else
-				analog_amplitude_x = analog_amplitude_x * analog_amplitude_x;
-		}
-		// printf("analog_amplitude_x: %f\n", analog_amplitude_x);
-		deltaAcc = analog_amplitude_x * _adjusted_cursor_speed;
-		updateMouseXY(deltaAcc, &_mouseXAcc, 1);
-	}
-
-	// Left Analog Y Axis
-	if (joy_y > retro_setting_get_analog_deadzone() || joy_y < -retro_setting_get_analog_deadzone()) {
-		status |= (STATUS_DOING_JOYSTICK | STATUS_DOING_Y);
-		if (joy_y > retro_setting_get_analog_deadzone()) {
-			// Reset accumulator when changing direction
-			_mouseYAcc = (_mouseYAcc < 0.0) ? 0.0 : _mouseYAcc;
-			joy_y = joy_y - retro_setting_get_analog_deadzone();
-		}
-		if (joy_y < -retro_setting_get_analog_deadzone()) {
-			// Reset accumulator when changing direction
-			_mouseYAcc = (_mouseYAcc > 0.0) ? 0.0 : _mouseYAcc;
-			joy_y = joy_y + retro_setting_get_analog_deadzone();
-		}
-		// Update accumulator
-		analog_amplitude_y = (float)joy_y / (float)(ANALOG_RANGE - retro_setting_get_analog_deadzone());
-		if (retro_setting_get_analog_response_is_quadratic()) {
-			if (analog_amplitude_y < 0.0)
-				analog_amplitude_y = -(analog_amplitude_y * analog_amplitude_y);
-			else
-				analog_amplitude_y = analog_amplitude_y * analog_amplitude_y;
-		}
-		// printf("analog_amplitude_y: %f\n", analog_amplitude_y);
-		deltaAcc = analog_amplitude_y * _adjusted_cursor_speed;
-		updateMouseXY(deltaAcc, &_mouseYAcc, 0);
-	}
+	getMouseXYFromAnalog(true, retro_input_cb(0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_X));
+	getMouseXYFromAnalog(false, retro_input_cb(0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_Y));
 
 	if (retro_get_input_device() == RETRO_DEVICE_JOYPAD) {
 		bool dpadLeft = retro_input_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT);


Commit: 260bd5b918fc6f4d529b3e5a48f50d492f3560ec
    https://github.com/scummvm/scummvm/commit/260bd5b918fc6f4d529b3e5a48f50d492f3560ec
Author: Giovanni Cascione (ing.cascione at gmail.com)
Date: 2023-09-09T00:36:05+02:00

Commit Message:
LIBRETRO: add OSystem_libretro::getMouseXYFromButton()

Changed paths:
    backends/platform/libretro/include/libretro-os.h
    backends/platform/libretro/src/libretro-os-inputs.cpp


diff --git a/backends/platform/libretro/include/libretro-os.h b/backends/platform/libretro/include/libretro-os.h
index fa8011c2518..ea070088c19 100644
--- a/backends/platform/libretro/include/libretro-os.h
+++ b/backends/platform/libretro/include/libretro-os.h
@@ -192,6 +192,8 @@ public:
 private:
 	void updateMouseXY(float deltaAcc, float * cumulativeXYAcc, int doing_x);
 	void getMouseXYFromAnalog(bool is_x, int16_t coor);
+	void getMouseXYFromButton(int16_t coor_x, int16_t coor_y);
+	void updateMouseXYFromButton(bool is_x, int16_t coor);
 };
 
 #endif
diff --git a/backends/platform/libretro/src/libretro-os-inputs.cpp b/backends/platform/libretro/src/libretro-os-inputs.cpp
index 7909971533e..ec4fc748e67 100644
--- a/backends/platform/libretro/src/libretro-os-inputs.cpp
+++ b/backends/platform/libretro/src/libretro-os-inputs.cpp
@@ -80,10 +80,50 @@ void OSystem_libretro::getMouseXYFromAnalog(bool is_x, int16_t coor) {
 	if (retro_setting_get_analog_response_is_quadratic())
 		analog_amplitude *= analog_amplitude;
 
-	if (sign < 0)
-		analog_amplitude = -analog_amplitude;
+	updateMouseXY(sign * analog_amplitude * _adjusted_cursor_speed, mouseAcc, is_x);
+}
+
+void OSystem_libretro::updateMouseXYFromButton(bool is_x, int16_t sign) {
+	float * dpadVel;
+	float * dpadAcc;
+
+	if (is_x) {
+		dpadVel = &_dpadXVel;
+		dpadAcc = &_dpadXAcc;
+	} else {
+		dpadVel = &_dpadYVel;
+		dpadAcc = &_dpadYAcc;
+	}
+
+	if (*dpadAcc && ((*dpadAcc > 0) - (*dpadAcc < 0)) != sign) {
+		*dpadVel = 0.0f;
+		*dpadAcc = 0.0f;
+	}
 
-	updateMouseXY(analog_amplitude * _adjusted_cursor_speed, mouseAcc, is_x);
+	*dpadVel = MIN(*dpadVel + _inverse_acceleration_time, 1.0f);
+
+	updateMouseXY(sign * *dpadVel * _adjusted_cursor_speed, dpadAcc, is_x);
+}
+
+
+void OSystem_libretro::getMouseXYFromButton(int16_t coor_x, int16_t coor_y) {
+
+	if (! coor_x && ! coor_y)
+		return;
+
+	status |= STATUS_DOING_JOYSTICK;
+
+	if (coor_x) {
+		status |= STATUS_DOING_X;
+		updateMouseXYFromButton(1, coor_x);
+	} else
+		_dpadXVel = 0.0f;
+
+	if (coor_y) {
+		status |= STATUS_DOING_Y;
+		updateMouseXYFromButton(0, coor_y);
+	} else
+		_dpadYVel = 0.0f;
 }
 
 void OSystem_libretro::processMouse(void) {
@@ -134,47 +174,9 @@ void OSystem_libretro::processMouse(void) {
 	getMouseXYFromAnalog(false, retro_input_cb(0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_Y));
 
 	if (retro_get_input_device() == RETRO_DEVICE_JOYPAD) {
-		bool dpadLeft = retro_input_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT);
-		bool dpadRight = retro_input_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT);
-		bool dpadUp = retro_input_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP);
-		bool dpadDown = retro_input_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN);
-
-		if (dpadLeft || dpadRight) {
-			status |= (STATUS_DOING_JOYSTICK | STATUS_DOING_X);
-			_dpadXVel = MIN(_dpadXVel + _inverse_acceleration_time, 1.0f);
-
-			if (dpadLeft) {
-				deltaAcc = -(_dpadXVel * _adjusted_cursor_speed);
-				_dpadXAcc = _dpadXAcc < deltaAcc ? _dpadXAcc : 0.0f;
-			} else { //dpadRight
-				deltaAcc = _dpadXVel * _adjusted_cursor_speed;
-				_dpadXAcc = _dpadXAcc > deltaAcc ? _dpadXAcc : 0.0f;
-			}
-
-			updateMouseXY(deltaAcc, &_dpadXAcc, 1);
-		} else {
-			_dpadXVel = 0.0f;
-		}
 
-
-		if (dpadUp || dpadDown) {
-			status |= (STATUS_DOING_JOYSTICK | STATUS_DOING_Y);
-			_dpadYVel = MIN(_dpadYVel + _inverse_acceleration_time, 1.0f);
-
-			if (dpadUp) {
-				deltaAcc = -(_dpadYVel * _adjusted_cursor_speed);
-				_dpadYAcc = _dpadYAcc < deltaAcc ? _dpadYAcc : 0.0f;
-			} else { //dpadDown
-				deltaAcc = _dpadYVel * _adjusted_cursor_speed;
-				_dpadYAcc = _dpadYAcc > deltaAcc ? _dpadYAcc : 0.0f;
-			}
-
-			updateMouseXY(deltaAcc, &_dpadYAcc, 0);
-
-
-		} else {
-			_dpadYVel = 0.0f;
-		}
+		getMouseXYFromButton(retro_input_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT) - retro_input_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT),
+					retro_input_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN) - retro_input_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP));
 
 		if (retro_input_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START)) {
 			Common::Event ev;


Commit: e7a8d1dea4ea9858edcb58b4dc8a2cbb9ffd426a
    https://github.com/scummvm/scummvm/commit/e7a8d1dea4ea9858edcb58b4dc8a2cbb9ffd426a
Author: Giovanni Cascione (ing.cascione at gmail.com)
Date: 2023-09-09T00:36:06+02:00

Commit Message:
LIBRETRO: simplify OSystem_libretro::getMouseXYFromButton()

Changed paths:
    backends/platform/libretro/include/libretro-os.h
    backends/platform/libretro/src/libretro-os-inputs.cpp


diff --git a/backends/platform/libretro/include/libretro-os.h b/backends/platform/libretro/include/libretro-os.h
index ea070088c19..637c8d3b8b1 100644
--- a/backends/platform/libretro/include/libretro-os.h
+++ b/backends/platform/libretro/include/libretro-os.h
@@ -192,8 +192,7 @@ public:
 private:
 	void updateMouseXY(float deltaAcc, float * cumulativeXYAcc, int doing_x);
 	void getMouseXYFromAnalog(bool is_x, int16_t coor);
-	void getMouseXYFromButton(int16_t coor_x, int16_t coor_y);
-	void updateMouseXYFromButton(bool is_x, int16_t coor);
+	void getMouseXYFromButton(bool is_x, int16_t sign);
 };
 
 #endif
diff --git a/backends/platform/libretro/src/libretro-os-inputs.cpp b/backends/platform/libretro/src/libretro-os-inputs.cpp
index ec4fc748e67..b9cd68d7c44 100644
--- a/backends/platform/libretro/src/libretro-os-inputs.cpp
+++ b/backends/platform/libretro/src/libretro-os-inputs.cpp
@@ -34,11 +34,17 @@ void OSystem_libretro::updateMouseXY(float deltaAcc, float * cumulativeXYAcc, in
 	int16 * screen_wh;
 	int * relMouseXY;
 	int cumulativeXYAcc_int;
+
+	if (! deltaAcc)
+		return;
+
 	if (doing_x) {
+		status |= STATUS_DOING_X;
 		mouseXY = &_mouseX;
 		screen_wh = &_screen.w;
 		relMouseXY = &_relMouseX;
 	} else {
+		status |= STATUS_DOING_Y;
 		mouseXY = &_mouseY;
 		screen_wh = &_screen.h;
 		relMouseXY = &_relMouseY;
@@ -67,10 +73,8 @@ void OSystem_libretro::getMouseXYFromAnalog(bool is_x, int16_t coor) {
 	status |= STATUS_DOING_JOYSTICK;
 
 	if (is_x) {
-		status |= STATUS_DOING_X;
 		mouseAcc = &_mouseXAcc;
 	} else {
-		status |= STATUS_DOING_Y;
 		mouseAcc = &_mouseYAcc;
 	}
 
@@ -83,7 +87,7 @@ void OSystem_libretro::getMouseXYFromAnalog(bool is_x, int16_t coor) {
 	updateMouseXY(sign * analog_amplitude * _adjusted_cursor_speed, mouseAcc, is_x);
 }
 
-void OSystem_libretro::updateMouseXYFromButton(bool is_x, int16_t sign) {
+void OSystem_libretro::getMouseXYFromButton(bool is_x, int16_t sign) {
 	float * dpadVel;
 	float * dpadAcc;
 
@@ -95,35 +99,19 @@ void OSystem_libretro::updateMouseXYFromButton(bool is_x, int16_t sign) {
 		dpadAcc = &_dpadYAcc;
 	}
 
-	if (*dpadAcc && ((*dpadAcc > 0) - (*dpadAcc < 0)) != sign) {
+	if ((*dpadAcc && ((*dpadAcc > 0) - (*dpadAcc < 0)) != sign) || ! sign) {
 		*dpadVel = 0.0f;
 		*dpadAcc = 0.0f;
 	}
 
-	*dpadVel = MIN(*dpadVel + _inverse_acceleration_time, 1.0f);
-
-	updateMouseXY(sign * *dpadVel * _adjusted_cursor_speed, dpadAcc, is_x);
-}
-
-
-void OSystem_libretro::getMouseXYFromButton(int16_t coor_x, int16_t coor_y) {
-
-	if (! coor_x && ! coor_y)
+	if (! sign)
 		return;
 
 	status |= STATUS_DOING_JOYSTICK;
 
-	if (coor_x) {
-		status |= STATUS_DOING_X;
-		updateMouseXYFromButton(1, coor_x);
-	} else
-		_dpadXVel = 0.0f;
+	*dpadVel = MIN(*dpadVel + _inverse_acceleration_time, 1.0f);
 
-	if (coor_y) {
-		status |= STATUS_DOING_Y;
-		updateMouseXYFromButton(0, coor_y);
-	} else
-		_dpadYVel = 0.0f;
+	updateMouseXY(sign * *dpadVel * _adjusted_cursor_speed, dpadAcc, is_x);
 }
 
 void OSystem_libretro::processMouse(void) {
@@ -175,8 +163,8 @@ void OSystem_libretro::processMouse(void) {
 
 	if (retro_get_input_device() == RETRO_DEVICE_JOYPAD) {
 
-		getMouseXYFromButton(retro_input_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT) - retro_input_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT),
-					retro_input_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN) - retro_input_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP));
+		getMouseXYFromButton(true, retro_input_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT) - retro_input_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT));
+		getMouseXYFromButton(false, retro_input_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN) - retro_input_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP));
 
 		if (retro_input_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START)) {
 			Common::Event ev;


Commit: eb1aa4037bab181fec8d8402cc499b712c1dcb40
    https://github.com/scummvm/scummvm/commit/eb1aa4037bab181fec8d8402cc499b712c1dcb40
Author: Giovanni Cascione (ing.cascione at gmail.com)
Date: 2023-09-09T00:36:06+02:00

Commit Message:
LIBRETRO: fix cursor speed reduction

Changed paths:
    backends/platform/libretro/src/libretro-os-inputs.cpp


diff --git a/backends/platform/libretro/src/libretro-os-inputs.cpp b/backends/platform/libretro/src/libretro-os-inputs.cpp
index b9cd68d7c44..8fc05480dc4 100644
--- a/backends/platform/libretro/src/libretro-os-inputs.cpp
+++ b/backends/platform/libretro/src/libretro-os-inputs.cpp
@@ -26,7 +26,8 @@ enum processMouse_status {
 	STATUS_DOING_JOYSTICK  = (1 << 0),
 	STATUS_DOING_MOUSE     = (1 << 1),
 	STATUS_DOING_X         = (1 << 2),
-	STATUS_DOING_Y         = (1 << 3)
+	STATUS_DOING_Y         = (1 << 3),
+	STATUS_DOING_SLOWER    = (1 << 4)
 };
 
 void OSystem_libretro::updateMouseXY(float deltaAcc, float * cumulativeXYAcc, int doing_x){
@@ -38,6 +39,9 @@ void OSystem_libretro::updateMouseXY(float deltaAcc, float * cumulativeXYAcc, in
 	if (! deltaAcc)
 		return;
 
+	if (status & STATUS_DOING_SLOWER)
+		deltaAcc *= 0.2f;
+
 	if (doing_x) {
 		status |= STATUS_DOING_X;
 		mouseXY = &_mouseX;
@@ -149,12 +153,15 @@ void OSystem_libretro::processMouse(void) {
 		{(unsigned)Common::KEYCODE_KP4, 52},
 	};
 
-	// Reduce gamepad cursor speed, if required
+	status = 0;
+
+	// Reduce cursor speed, if required
 	if (retro_get_input_device() == RETRO_DEVICE_JOYPAD && retro_input_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2)) {
-		_adjusted_cursor_speed = _adjusted_cursor_speed * (1.0f / 5.0f);
+		status |= STATUS_DOING_SLOWER;
+	} else {
+		status &= ~STATUS_DOING_SLOWER;
 	}
 
-	status = 0;
 	x = retro_input_cb(0, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_X);
 	y = retro_input_cb(0, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_Y);
 


Commit: 88e97990f6130b662e4176a9493703557c618d3b
    https://github.com/scummvm/scummvm/commit/88e97990f6130b662e4176a9493703557c618d3b
Author: Giovanni Cascione (ing.cascione at gmail.com)
Date: 2023-09-09T00:36:07+02:00

Commit Message:
LIBRETRO: clean up retropad input

Changed paths:
    backends/platform/libretro/src/libretro-os-inputs.cpp


diff --git a/backends/platform/libretro/src/libretro-os-inputs.cpp b/backends/platform/libretro/src/libretro-os-inputs.cpp
index 8fc05480dc4..febdfd1e6b7 100644
--- a/backends/platform/libretro/src/libretro-os-inputs.cpp
+++ b/backends/platform/libretro/src/libretro-os-inputs.cpp
@@ -155,6 +155,9 @@ void OSystem_libretro::processMouse(void) {
 
 	status = 0;
 
+
+	// Process input from RetroPad
+
 	// Reduce cursor speed, if required
 	if (retro_get_input_device() == RETRO_DEVICE_JOYPAD && retro_input_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2)) {
 		status |= STATUS_DOING_SLOWER;
@@ -162,24 +165,63 @@ void OSystem_libretro::processMouse(void) {
 		status &= ~STATUS_DOING_SLOWER;
 	}
 
-	x = retro_input_cb(0, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_X);
-	y = retro_input_cb(0, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_Y);
-
 	getMouseXYFromAnalog(true, retro_input_cb(0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_X));
 	getMouseXYFromAnalog(false, retro_input_cb(0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_Y));
 
-	if (retro_get_input_device() == RETRO_DEVICE_JOYPAD) {
 
-		getMouseXYFromButton(true, retro_input_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT) - retro_input_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT));
-		getMouseXYFromButton(false, retro_input_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN) - retro_input_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP));
+	getMouseXYFromButton(true, retro_input_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT) - retro_input_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT));
+	getMouseXYFromButton(false, retro_input_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN) - retro_input_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP));
 
-		if (retro_input_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START)) {
-			Common::Event ev;
-			ev.type = Common::EVENT_MAINMENU;
-			_events.push_back(ev);
+	if (retro_input_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START)) {
+		Common::Event ev;
+		ev.type = Common::EVENT_MAINMENU;
+		_events.push_back(ev);
+	}
+
+	if (status & STATUS_DOING_JOYSTICK) {
+		Common::Event ev;
+		ev.type = Common::EVENT_MOUSEMOVE;
+		ev.mouse.x = _mouseX;
+		ev.mouse.y = _mouseY;
+		ev.relMouse.x = status & STATUS_DOING_X ? _relMouseX : 0;
+		ev.relMouse.y = status & STATUS_DOING_Y ? _relMouseY : 0;
+		_events.push_back(ev);
+	}
+
+	// Gamepad mouse buttons
+	down = retro_input_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A);
+	if (down != _joypadmouseButtons[0]) {
+		_joypadmouseButtons[0] = down;
+
+		Common::Event ev;
+		ev.type = eventID[0][down ? 0 : 1];
+		ev.mouse.x = _mouseX;
+		ev.mouse.y = _mouseY;
+		_events.push_back(ev);
+	}
+
+	down = retro_input_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B);
+	if (down != _joypadmouseButtons[1]) {
+		_joypadmouseButtons[1] = down;
+
+		Common::Event ev;
+		ev.type = eventID[1][down ? 0 : 1];
+		ev.mouse.x = _mouseX;
+		ev.mouse.y = _mouseY;
+		_events.push_back(ev);
+	}
+
+	// Gamepad keyboard buttons
+	for (int i = 0; i < 8; i++) {
+		down = retro_input_cb(0, RETRO_DEVICE_JOYPAD, 0, gampad_key_map[i][0]);
+		if (down != _joypadkeyboardButtons[i]) {
+			_joypadkeyboardButtons[i] = down;
+			bool state = down ? true : false;
+			processKeyEvent(state, gampad_key_map[i][1], (uint32_t)gampad_key_map[i][2], (uint32_t)gampad_key_map[i][3]);
 		}
 	}
 
+
 #if defined(WIIU) || defined(__SWITCH__)
 	int p_x = retro_input_cb(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_X);
 	int p_y = retro_input_cb(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_Y);
@@ -224,49 +266,6 @@ void OSystem_libretro::processMouse(void) {
 
 #endif
 
-	if (status & STATUS_DOING_JOYSTICK) {
-		Common::Event ev;
-		ev.type = Common::EVENT_MOUSEMOVE;
-		ev.mouse.x = _mouseX;
-		ev.mouse.y = _mouseY;
-		ev.relMouse.x = status & STATUS_DOING_X ? _relMouseX : 0;
-		ev.relMouse.y = status & STATUS_DOING_Y ? _relMouseY : 0;
-		_events.push_back(ev);
-	}
-
-	// Gampad mouse buttons
-	down = retro_input_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A);
-	if (down != _joypadmouseButtons[0]) {
-		_joypadmouseButtons[0] = down;
-
-		Common::Event ev;
-		ev.type = eventID[0][down ? 0 : 1];
-		ev.mouse.x = _mouseX;
-		ev.mouse.y = _mouseY;
-		_events.push_back(ev);
-	}
-
-	down = retro_input_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B);
-	if (down != _joypadmouseButtons[1]) {
-		_joypadmouseButtons[1] = down;
-
-		Common::Event ev;
-		ev.type = eventID[1][down ? 0 : 1];
-		ev.mouse.x = _mouseX;
-		ev.mouse.y = _mouseY;
-		_events.push_back(ev);
-	}
-
-	// Gamepad keyboard buttons
-	for (int i = 0; i < 8; i++) {
-		down = retro_input_cb(0, RETRO_DEVICE_JOYPAD, 0, gampad_key_map[i][0]);
-		if (down != _joypadkeyboardButtons[i]) {
-			_joypadkeyboardButtons[i] = down;
-			bool state = down ? true : false;
-			processKeyEvent(state, gampad_key_map[i][1], (uint32_t)gampad_key_map[i][2], (uint32_t)gampad_key_map[i][3]);
-		}
-	}
-
 	// Gamepad right stick numpad emulation
 	joy_rx = retro_input_cb(0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_X);
 	joy_ry = retro_input_cb(0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_Y);
@@ -333,6 +332,9 @@ void OSystem_libretro::processMouse(void) {
 	}
 
 	// Process input from physical mouse
+	x = retro_input_cb(0, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_X);
+	y = retro_input_cb(0, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_Y);
+
 	// > X Axis
 	if (x != 0) {
 		status |= (STATUS_DOING_MOUSE | STATUS_DOING_X);


Commit: 5c13a413243226856052f27b4305a2fb6df8bd70
    https://github.com/scummvm/scummvm/commit/5c13a413243226856052f27b4305a2fb6df8bd70
Author: Giovanni Cascione (ing.cascione at gmail.com)
Date: 2023-09-09T00:36:08+02:00

Commit Message:
LIBRETRO: add libretro-mapper.h

Changed paths:
  A backends/platform/libretro/include/libretro-mapper.h
    backends/platform/libretro/src/libretro.cpp


diff --git a/backends/platform/libretro/include/libretro-mapper.h b/backends/platform/libretro/include/libretro-mapper.h
new file mode 100644
index 00000000000..5836d0ce955
--- /dev/null
+++ b/backends/platform/libretro/include/libretro-mapper.h
@@ -0,0 +1,57 @@
+/* Copyright (C) 2023 Giovanni Cascione <ing.cascione at gmail.com>
+ *
+ * This program 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 Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef LIBRETRO_MAPPER_H
+#define LIBRETRO_MAPPER_H
+
+#include <libretro.h>
+
+const struct retro_controller_description retro_controller_list[] = {
+	{"None", RETRO_DEVICE_NONE},
+	{"Automatic", RETRO_DEVICE_JOYPAD},
+	{NULL, 0}
+};
+
+const struct retro_controller_info retro_controller_lists[] = {
+	{retro_controller_list, sizeof(retro_controller_list) / sizeof(retro_controller_list[0])},
+	{NULL, 0}
+};
+
+struct retro_input_descriptor retro_input_desc[] = {
+	{0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP, "Up"},
+	{0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN, "Down"},
+	{0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT, "Left"},
+	{0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT, "Right"},
+	{0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B, "B / Fire / Red"},
+	{0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A, "A / 2nd fire / Blue"},
+	{0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y, "Y / Green"},
+	{0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X, "X / Yellow"},
+	{0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT, "Select"},
+	{0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "Start / Play"},
+	{0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L, "L / Rewind"},
+	{0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R, "R / Forward"},
+	{0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L2, "L2"},
+	{0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2, "R2"},
+	{0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L3, "L3"},
+	{0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R3, "R3"},
+	{0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_X, "Left Analog X"},
+	{0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_Y, "Left Analog Y"},
+	{0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_X, "Right Analog X"},
+	{0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_Y, "Right Analog Y"}
+};
+
+#endif // LIBRETRO_MAPPER_H
diff --git a/backends/platform/libretro/src/libretro.cpp b/backends/platform/libretro/src/libretro.cpp
index b80544a4edd..802a4c9216c 100644
--- a/backends/platform/libretro/src/libretro.cpp
+++ b/backends/platform/libretro/src/libretro.cpp
@@ -54,6 +54,7 @@
 #include "backends/platform/libretro/include/libretro-core-options.h"
 #include "backends/platform/libretro/include/libretro-os.h"
 #include "backends/platform/libretro/include/libretro-defs.h"
+#include "backends/platform/libretro/include/libretro-mapper.h"
 
 static struct retro_game_info game_buf;
 static struct retro_game_info * game_buf_ptr;
@@ -572,33 +573,9 @@ void retro_init(void) {
 
 	init_command_params();
 
-	struct retro_input_descriptor desc[] = {
-		{0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT, "Mouse Cursor Left"},
-		{0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP, "Mouse Cursor Up"},
-		{0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN, "Mouse Cursor Down"},
-		{0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT, "Mouse Cursor Right"},
-		{0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B, "Right Mouse Button"},
-		{0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A, "Left Mouse Button"},
-		{0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X, "Esc"},
-		{0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y, "."},
-		{0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L, "Enter"},
-		{0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R, "Numpad 5"},
-		{0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L2, "Backspace"},
-		{0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2, "Cursor Fine Control"},
-		{0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L3, "F10"},
-		{0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R3, "Numpad 0"},
-		{0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "ScummVM GUI"},
-		{0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT, "Virtual Keyboard"},
-		{0, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_LEFT, "Left click"},
-		{0, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_RIGHT, "Right click"},
-		{0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_X, "Left Analog X"},
-		{0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_Y, "Left Analog Y"},
-		{0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_X, "Right Analog X"},
-		{0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_Y, "Right Analog Y"},
-		{0},
-	};
-
-	environ_cb(RETRO_ENVIRONMENT_SET_INPUT_DESCRIPTORS, desc);
+	environ_cb(RETRO_ENVIRONMENT_SET_INPUT_DESCRIPTORS, retro_input_desc);
+
+	environ_cb(RETRO_ENVIRONMENT_SET_CONTROLLER_INFO, (void*)retro_controller_lists);
 
 	/* Get color mode: 32 first as VGA has 6 bits per pixel */
 #if 0


Commit: 84ebccb5af90d327ea1826915cdcecb8af10f1e5
    https://github.com/scummvm/scummvm/commit/84ebccb5af90d327ea1826915cdcecb8af10f1e5
Author: Giovanni Cascione (ing.cascione at gmail.com)
Date: 2023-09-09T00:36:09+02:00

Commit Message:
LIBRETRO: add dynamically displayed options

Changed paths:
    backends/platform/libretro/src/libretro.cpp


diff --git a/backends/platform/libretro/src/libretro.cpp b/backends/platform/libretro/src/libretro.cpp
index 802a4c9216c..26f16c2e32e 100644
--- a/backends/platform/libretro/src/libretro.cpp
+++ b/backends/platform/libretro/src/libretro.cpp
@@ -110,6 +110,10 @@ static size_t samples_per_frame_buffer_size = 0;
 static int16_t *sound_buffer = NULL;               // pointer to output buffer
 static int16_t *sound_buffer_empty = NULL;         // pointer to zeroed output buffer, to regulate GUI FPS
 
+static bool updating_variables = false;
+static int opt_frameskip_threshold_display = 0;
+static int opt_frameskip_no_display = 0;
+
 static void log_scummvm_exit_code(void) {
 	if (retro_get_scummvm_res() == Common::kNoError)
 		retro_log_cb(RETRO_LOG_INFO, "ScummVM exited successfully.\n");
@@ -190,7 +194,7 @@ void retro_osd_notification(const char* msg) {
 
 static void update_variables(void) {
 	struct retro_variable var;
-
+	updating_variables = true;
 	const char* osd_msg = "";
 
 	var.key = "scummvm_gamepad_cursor_speed";
@@ -275,14 +279,20 @@ static void update_variables(void) {
 	var.value = NULL;
 	uint8 old_frameskip_type = frameskip_type;
 	if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) {
+		opt_frameskip_threshold_display = 0;
+		opt_frameskip_no_display = 0;
+
 		if (strcmp(var.value, "disabled") == 0)
 			frameskip_type = 0;
-		else if (strcmp(var.value, "fixed") == 0)
+		else if (strcmp(var.value, "fixed") == 0) {
 			frameskip_type = 1;
-		else if (strcmp(var.value, "auto") == 0)
+			opt_frameskip_no_display = 1;
+		} else if (strcmp(var.value, "auto") == 0)
 			frameskip_type = 2;
-		else if (strcmp(var.value, "manual") == 0)
+		else if (strcmp(var.value, "manual") == 0) {
 			frameskip_type = 3;
+			opt_frameskip_threshold_display = 1;
+		}
 	}
 
 	var.key = "scummvm_auto_performance_tuner";
@@ -319,6 +329,35 @@ static void update_variables(void) {
 				audio_status |= AUDIO_STATUS_UPDATE_AV_INFO;
 		}
 	}
+	updating_variables = false;
+}
+
+static void retro_set_options_display(void) {
+	struct retro_core_option_display option_display;
+
+	option_display.visible = opt_frameskip_threshold_display;
+	option_display.key = "scummvm_frameskip_threshold";
+	environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS_DISPLAY, &option_display);
+
+
+	option_display.visible = opt_frameskip_no_display;
+	option_display.key = "scummvm_frameskip_no";
+	environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS_DISPLAY, &option_display);
+}
+
+static bool retro_update_display(void) {
+	if (updating_variables)
+	return false;
+
+	/* Core options */
+	bool updated = false;
+	if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE, &updated) && updated)
+	{
+		update_variables();
+		LIBRETRO_G_SYSTEM->refreshRetroSettings();
+		retro_set_options_display();
+	}
+	return updated;
 }
 
 bool retro_setting_get_timing_inaccuracies_enabled(){
@@ -328,7 +367,6 @@ bool retro_setting_get_timing_inaccuracies_enabled(){
 		return timing_inaccuracies_enabled;
 }
 
-
 int retro_setting_get_analog_deadzone(void) {
 	return analog_deadzone;
 }
@@ -494,6 +532,10 @@ void retro_set_environment(retro_environment_t cb) {
 
 	environ_cb(RETRO_ENVIRONMENT_SET_SUPPORT_NO_GAME, &tmp);
 	libretro_set_core_options(environ_cb, &has_categories);
+
+	/* Core option display callback */
+	struct retro_core_options_update_display_callback update_display_callback = {retro_update_display};
+	environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS_UPDATE_DISPLAY_CALLBACK, &update_display_callback);
 }
 
 unsigned retro_api_version(void) {
@@ -571,6 +613,8 @@ void retro_init(void) {
 
 	update_variables();
 
+	retro_set_options_display();
+
 	init_command_params();
 
 	environ_cb(RETRO_ENVIRONMENT_SET_INPUT_DESCRIPTORS, retro_input_desc);
@@ -735,12 +779,6 @@ bool retro_load_game_special(unsigned game_type, const struct retro_game_info *i
 }
 
 void retro_run(void) {
-	bool updated = false;
-	if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE, &updated) && updated){
-		update_variables();
-		LIBRETRO_G_SYSTEM->refreshRetroSettings();
-	}
-
 	if (audio_status & AUDIO_STATUS_UPDATE_AV_INFO){
 		struct retro_system_av_info info;
 		info.geometry.base_width = RES_W;


Commit: 90adba467e8d5021874f1a252e1a4d588a0c6371
    https://github.com/scummvm/scummvm/commit/90adba467e8d5021874f1a252e1a4d588a0c6371
Author: Giovanni Cascione (ing.cascione at gmail.com)
Date: 2023-09-09T00:36:09+02:00

Commit Message:
LIBRETRO: use retro_get_system_av_info in retro_run

Changed paths:
    backends/platform/libretro/src/libretro.cpp


diff --git a/backends/platform/libretro/src/libretro.cpp b/backends/platform/libretro/src/libretro.cpp
index 26f16c2e32e..395c97fc984 100644
--- a/backends/platform/libretro/src/libretro.cpp
+++ b/backends/platform/libretro/src/libretro.cpp
@@ -781,13 +781,7 @@ bool retro_load_game_special(unsigned game_type, const struct retro_game_info *i
 void retro_run(void) {
 	if (audio_status & AUDIO_STATUS_UPDATE_AV_INFO){
 		struct retro_system_av_info info;
-		info.geometry.base_width = RES_W;
-		info.geometry.base_height = RES_H;
-		info.geometry.max_width = RES_W;
-		info.geometry.max_height = RES_H;
-		info.geometry.aspect_ratio = 4.0f / 3.0f;
-		info.timing.fps = frame_rate;
-		info.timing.sample_rate = sample_rate;
+		retro_get_system_av_info(&info);
 		environ_cb(RETRO_ENVIRONMENT_SET_SYSTEM_AV_INFO , &info);
 	}
 


Commit: 6cc96ef4ac4b634b7a2603e333c0bfd6ef6d7cc1
    https://github.com/scummvm/scummvm/commit/6cc96ef4ac4b634b7a2603e333c0bfd6ef6d7cc1
Author: Giovanni Cascione (ing.cascione at gmail.com)
Date: 2023-09-09T00:36:10+02:00

Commit Message:
LIBRETRO: fix frame rate in inverse_acceleration_time

Changed paths:
    backends/platform/libretro/src/libretro-os-base.cpp


diff --git a/backends/platform/libretro/src/libretro-os-base.cpp b/backends/platform/libretro/src/libretro-os-base.cpp
index 982d32d78b7..0b98ba4cb96 100644
--- a/backends/platform/libretro/src/libretro-os-base.cpp
+++ b/backends/platform/libretro/src/libretro-os-base.cpp
@@ -14,7 +14,7 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  *
  */
-
+#define FORBIDDEN_SYMBOL_ALLOW_ALL
 #if defined(_WIN32)
 #include "backends/fs/windows/windows-fs-factory.h"
 #define FS_SYSTEM_FACTORY WindowsFilesystemFactory
@@ -126,7 +126,7 @@ Audio::Mixer *OSystem_libretro::getMixer() {
 
 void OSystem_libretro::refreshRetroSettings() {
         _adjusted_cursor_speed = (float)BASE_CURSOR_SPEED * retro_setting_get_gamepad_cursor_speed() * (float)(_overlayInGUI ? _overlay.w : _gameScreen.w) / 320.0f; // Dpad cursor speed should always be based off a 320 wide screen, to keep speeds consistent;
-        _inverse_acceleration_time = (retro_setting_get_gamepad_acceleration_time() > 0.0) ? (1.0 / 60.0) * (1.0 / retro_setting_get_gamepad_acceleration_time()) : 1.0;
+        _inverse_acceleration_time = (retro_setting_get_gamepad_acceleration_time() > 0.0) ? (1.0f / (float)retro_setting_get_frame_rate()) * (1.0f / retro_setting_get_gamepad_acceleration_time()) : 1.0f;
 }
 
 void OSystem_libretro::destroy() {


Commit: 3d4475da76c13f84a8b754508ad35d355ae19248
    https://github.com/scummvm/scummvm/commit/3d4475da76c13f84a8b754508ad35d355ae19248
Author: Giovanni Cascione (ing.cascione at gmail.com)
Date: 2023-09-09T00:36:11+02:00

Commit Message:
LIBRETRO: fix sample rate setting default value

Changed paths:
    backends/platform/libretro/include/libretro-core-options.h


diff --git a/backends/platform/libretro/include/libretro-core-options.h b/backends/platform/libretro/include/libretro-core-options.h
index 930ca1bc9bb..0d53cc40aba 100644
--- a/backends/platform/libretro/include/libretro-core-options.h
+++ b/backends/platform/libretro/include/libretro-core-options.h
@@ -305,7 +305,7 @@ struct retro_core_option_v2_definition option_defs_us[] = {
 			{ "44100 Hz", NULL },
 			{ NULL, NULL },
 		},
-		"48000"
+		"48000 Hz"
 	},
 	{
 		"scummvm_auto_performance_tuner",


Commit: ad2e4d151234843d2ebf20a54e9ad177ab6ad0d5
    https://github.com/scummvm/scummvm/commit/ad2e4d151234843d2ebf20a54e9ad177ab6ad0d5
Author: Giovanni Cascione (ing.cascione at gmail.com)
Date: 2023-09-09T00:36:12+02:00

Commit Message:
LIBRETRO: add retropad mapping settings
* Major libretro-os-inputs rework

Changed paths:
  A backends/platform/libretro/src/libretro-mapper.cpp
    backends/platform/libretro/Makefile.common
    backends/platform/libretro/include/libretro-core-options-intl.h
    backends/platform/libretro/include/libretro-core-options.h
    backends/platform/libretro/include/libretro-defs.h
    backends/platform/libretro/include/libretro-mapper.h
    backends/platform/libretro/include/libretro-os.h
    backends/platform/libretro/src/libretro-os-base.cpp
    backends/platform/libretro/src/libretro-os-inputs.cpp
    backends/platform/libretro/src/libretro.cpp


diff --git a/backends/platform/libretro/Makefile.common b/backends/platform/libretro/Makefile.common
index 06999793082..d8d34b67fc2 100644
--- a/backends/platform/libretro/Makefile.common
+++ b/backends/platform/libretro/Makefile.common
@@ -127,7 +127,8 @@ LIBRETRO_OBJS := $(CORE_PATH)/libretro.o \
 	$(CORE_PATH)/libretro-os-inputs.o \
 	$(CORE_PATH)/libretro-os-utils.o \
 	$(CORE_PATH)/libretro-threads.o \
-	$(CORE_PATH)/libretro-timer.o
+	$(CORE_PATH)/libretro-timer.o \
+	$(CORE_PATH)/libretro-mapper.o
 
 OBJS += $(LIBRETRO_OBJS)
 
diff --git a/backends/platform/libretro/include/libretro-core-options-intl.h b/backends/platform/libretro/include/libretro-core-options-intl.h
index 59850076fa4..9b11d5b34b1 100644
--- a/backends/platform/libretro/include/libretro-core-options-intl.h
+++ b/backends/platform/libretro/include/libretro-core-options-intl.h
@@ -85,6 +85,11 @@ struct retro_core_option_v2_category option_cats_it[] = {
 		NULL,
 		"Impostazioni relative al timing"
 	},
+	{
+                "retropad",
+                "Mappatura RetroPad",
+                "Configura la mappatura del RetroPad"
+        },
 	{ NULL, NULL, NULL },
 };
 
@@ -234,6 +239,297 @@ struct retro_core_option_v2_definition option_defs_it[] = {
 		},
 		NULL
 	},
+	/* Button mappings */
+	{
+		"scummvm_mapper_up",
+		"RetroPad > Su",
+		"Su",
+		NULL,
+		NULL,
+		"retropad",
+		{
+			{ NULL, NULL }
+		},
+		NULL,
+	},
+	{
+		"scummvm_mapper_down",
+		"RetroPad > Giù",
+		"Giù",
+		NULL,
+		NULL,
+		"retropad",
+		{
+			{ NULL, NULL }
+		},
+		NULL,
+	},
+	{
+		"scummvm_mapper_left",
+		"RetroPad > Sinistra",
+		"Sinistra",
+		NULL,
+		NULL,
+		"retropad",
+		{
+			{ NULL, NULL }
+		},
+		NULL,
+	},
+	{
+		"scummvm_mapper_right",
+		"RetroPad > Destra",
+		"Destra",
+		NULL,
+		NULL,
+		"retropad",
+		{
+			{ NULL, NULL }
+		},
+		NULL,
+	},
+	{
+		"scummvm_mapper_a",
+		"RetroPad > A",
+		"A",
+		NULL,
+		NULL,
+		"retropad",
+		{
+			{ NULL, NULL }
+		},
+		NULL,
+	},
+	{
+		"scummvm_mapper_b",
+		"RetroPad > B",
+		"B",
+		NULL,
+		NULL,
+		"retropad",
+		{
+			{ NULL, NULL }
+		},
+		NULL,
+	},
+	{
+		"scummvm_mapper_x",
+		"RetroPad > X",
+		"X",
+		NULL,
+		NULL,
+		"retropad",
+		{
+			{ NULL, NULL }
+		},
+		NULL,
+	},
+	{
+		"scummvm_mapper_y",
+		"RetroPad > Y",
+		"Y",
+		NULL,
+		NULL,
+		"retropad",
+		{
+			{ NULL, NULL }
+		},
+		NULL,
+	},
+	{
+		"scummvm_mapper_select",
+		"RetroPad > Select",
+		"Select",
+		NULL,
+		NULL,
+		"retropad",
+		{
+			{ NULL, NULL }
+		},
+		NULL,
+	},
+	{
+		"scummvm_mapper_start",
+		"RetroPad > Start",
+		"Start",
+		NULL,
+		NULL,
+		"retropad",
+		{
+			{ NULL, NULL }
+		},
+		NULL,
+	},
+	{
+		"scummvm_mapper_l",
+		"RetroPad > L",
+		"L",
+		NULL,
+		NULL,
+		"retropad",
+		{
+			{ NULL, NULL }
+		},
+		NULL,
+	},
+	{
+		"scummvm_mapper_r",
+		"RetroPad > R",
+		"R",
+		NULL,
+		NULL,
+		"retropad",
+		{
+			{ NULL, NULL }
+		},
+		NULL,
+	},
+	{
+		"scummvm_mapper_l2",
+		"RetroPad > L2",
+		"L2",
+		NULL,
+		NULL,
+		"retropad",
+		{
+			{ NULL, NULL }
+		},
+		NULL,
+	},
+	{
+		"scummvm_mapper_r2",
+		"RetroPad > R2",
+		"R2",
+		NULL,
+		NULL,
+		"retropad",
+		{
+			{ NULL, NULL }
+		},
+		NULL,
+	},
+	{
+		"scummvm_mapper_l3",
+		"RetroPad > L3",
+		"L3",
+		NULL,
+		NULL,
+		"retropad",
+		{
+			{ NULL, NULL }
+		},
+		NULL,
+	},
+	{
+		"scummvm_mapper_r3",
+		"RetroPad > R3",
+		"R3",
+		NULL,
+		NULL,
+		"retropad",
+		{
+			{ NULL, NULL }
+		},
+		NULL,
+	},
+	/* Left Stick */
+	{
+		"scummvm_mapper_lu",
+		"RetroPad > Leva Analogica Sinistra > Su",
+		"Leva Analogica Sinistra > Su",
+		NULL,
+		NULL,
+		"retropad",
+		{
+			{ NULL, NULL }
+		},
+		NULL,
+	},
+	{
+		"scummvm_mapper_ld",
+		"RetroPad > Leva Analogica Sinistra > Giù",
+		"Leva Analogica Sinistra > Giù",
+		NULL,
+		NULL,
+		"retropad",
+		{
+			{ NULL, NULL }
+		},
+		NULL,
+	},
+	{
+		"scummvm_mapper_ll",
+		"RetroPad > Leva Analogica Sinistra > Sinistra",
+		"Leva Analogica Sinistra > Sinistra",
+		NULL,
+		NULL,
+		"retropad",
+		{
+			{ NULL, NULL }
+		},
+		NULL,
+	},
+	{
+		"scummvm_mapper_lr",
+		"RetroPad > Leva Analogica Sinistra > Destra",
+		"Leva Analogica Sinistra > Destra",
+		NULL,
+		NULL,
+		"retropad",
+		{
+			{ NULL, NULL }
+		},
+		NULL,
+	},
+	/* Right Stick */
+	{
+		"scummvm_mapper_ru",
+		"RetroPad > Leva Analogica Destra > Su",
+		"Leva Analogica Destra > Su",
+		NULL,
+		NULL,
+		"retropad",
+		{
+			{ NULL, NULL }
+		},
+		NULL,
+	},
+	{
+		"scummvm_mapper_rd",
+		"RetroPad > Leva Analogica Destra > Giù",
+		"Leva Analogica Destra > Giù",
+		NULL,
+		NULL,
+		"retropad",
+		{
+			{ NULL, NULL }
+		},
+		NULL,
+	},
+	{
+		"scummvm_mapper_rl",
+		"RetroPad > Leva Analogica Destra > Sinistra",
+		"Leva Analogica Destra > Sinistra",
+		NULL,
+		NULL,
+		"retropad",
+		{
+			{ NULL, NULL }
+		},
+		NULL,
+	},
+	{
+		"scummvm_mapper_rr",
+		"RetroPad > Leva Analogica Destra > Leva Analogica Destra",
+		"Leva Analogica Destra > Destra",
+		NULL,
+		NULL,
+		"retropad",
+		{
+			{ NULL, NULL }
+		},
+		NULL,
+	},
 	{
 		"scummvm_auto_performance_tuner",
 		"Regolazione automatica performance",
@@ -252,6 +548,165 @@ struct retro_core_options_v2 options_it = {
 	option_cats_it,
 	option_defs_it
 };
+
+
+/* List has been reduced to fit RETRO_NUM_CORE_OPTION_VALUES_MAX.
+ * Latest element {NULL, NULL} has been omitted in this case as the array is exactly sized
+ * RETRO_NUM_CORE_OPTION_VALUES_MAX; in case the array size will be reduced, {NULL, NULL}
+ * element to be uncommented.
+ */
+
+struct retro_core_option_value retro_keys_label_it [] = {
+	{"---", "---"},
+	{"RETROKE_VKBD", "Attiva/disattiva Tastiera Virtuale"},
+	{"RETROKE_LEFT", "Cursore Mouse Sinistra"},
+	{"RETROKE_UP", "Cursore Mouse Su"},
+	{"RETROKE_DOWN", "Cursore Mouse Giù"},
+	{"RETROKE_RIGHT", "Cursore Mouse Destra"},
+	{"RETROKE_LEFT_BUTTON", "Tasto Mouse Sinistra"},
+	{"RETROKE_RIGHT_BUTTON", "Tasto Mouse Destra"},
+	{"RETROKE_FINE_CONTROL", "Controllo Fine Cursore Mouse"},
+	{"RETROKE_SCUMMVM_GUI", "ScummVM GUI"},
+	{"RETROKE_SHIFT_MOD", "Tastiera Shift (Modificatore)"},
+	{"RETROKE_CTRL_MOD", "Tastiera Control (Modificatore)"},
+	{"RETROKE_ALT_MOD", "Tastiera Alt (Modificatore)"},
+	{"RETROK_BACKSPACE", "Tastiera Backspace"},
+	{"RETROK_TAB", "Tastiera Tab"},
+	{"RETROK_CLEAR", "Tastiera Clear"},
+	{"RETROK_RETURN", "Tastiera Return"},
+	{"RETROK_PAUSE", "Tastiera Pause"},
+	{"RETROK_ESCAPE", "Tastiera Escape"},
+	{"RETROK_SPACE", "Tastiera Space"},
+	{"RETROK_EXCLAIM", "Tastiera !"},
+	{"RETROK_QUOTEDBL", "Tastiera \""},
+	{"RETROK_HASH", "Tastiera #"},
+	{"RETROK_DOLLAR", "Tastiera $"},
+	{"RETROK_AMPERSAND", "Tastiera &"},
+	{"RETROK_QUOTE", "Tastiera \'"},
+	{"RETROK_LEFTPAREN", "Tastiera ("},
+	{"RETROK_RIGHTPAREN", "Tastiera )"},
+	{"RETROK_ASTERISK", "Tastiera *"},
+	{"RETROK_PLUS", "Tastiera +"},
+	{"RETROK_COMMA", "Tastiera ,"},
+	{"RETROK_MINUS", "Tastiera -"},
+	{"RETROK_PERIOD", "Tastiera ."},
+	{"RETROK_SLASH", "Tastiera /"},
+	{"RETROK_0", "Tastiera 0"},
+	{"RETROK_1", "Tastiera 1"},
+	{"RETROK_2", "Tastiera 2"},
+	{"RETROK_3", "Tastiera 3"},
+	{"RETROK_4", "Tastiera 4"},
+	{"RETROK_5", "Tastiera 5"},
+	{"RETROK_6", "Tastiera 6"},
+	{"RETROK_7", "Tastiera 7"},
+	{"RETROK_8", "Tastiera 8"},
+	{"RETROK_9", "Tastiera 9"},
+	{"RETROK_COLON", "Tastiera :"},
+	{"RETROK_SEMICOLON", "Tastiera ;"},
+	{"RETROK_LESS", "Tastiera <"},
+	{"RETROK_EQUALS", "Tastiera ="},
+	{"RETROK_GREATER", "Tastiera >"},
+	{"RETROK_QUESTION", "Tastiera ?"},
+	{"RETROK_AT", "Tastiera @"},
+	{"RETROK_LEFTBRACKET", "Tastiera ["},
+	{"RETROK_BACKSLASH", "Tastiera \\"},
+	{"RETROK_RIGHTBRACKET", "Tastiera ]"},
+	{"RETROK_CARET", "Tastiera ^"},
+	{"RETROK_UNDERSCORE", "Tastiera _"},
+	{"RETROK_BACKQUOTE", "Tastiera `"},
+	{"RETROK_a", "Tastiera a"},
+	{"RETROK_b", "Tastiera b"},
+	{"RETROK_c", "Tastiera c"},
+	{"RETROK_d", "Tastiera d"},
+	{"RETROK_e", "Tastiera e"},
+	{"RETROK_f", "Tastiera f"},
+	{"RETROK_g", "Tastiera g"},
+	{"RETROK_h", "Tastiera h"},
+	{"RETROK_i", "Tastiera i"},
+	{"RETROK_j", "Tastiera j"},
+	{"RETROK_k", "Tastiera k"},
+	{"RETROK_l", "Tastiera l"},
+	{"RETROK_m", "Tastiera m"},
+	{"RETROK_n", "Tastiera n"},
+	{"RETROK_o", "Tastiera o"},
+	{"RETROK_p", "Tastiera p"},
+	{"RETROK_q", "Tastiera q"},
+	{"RETROK_r", "Tastiera r"},
+	{"RETROK_s", "Tastiera s"},
+	{"RETROK_t", "Tastiera t"},
+	{"RETROK_u", "Tastiera u"},
+	{"RETROK_v", "Tastiera v"},
+	{"RETROK_w", "Tastiera w"},
+	{"RETROK_x", "Tastiera x"},
+	{"RETROK_y", "Tastiera y"},
+	{"RETROK_z", "Tastiera z"},
+	{"RETROK_KP0", "Tastiera Numpad 0"},
+	{"RETROK_KP1", "Tastiera Numpad 1"},
+	{"RETROK_KP2", "Tastiera Numpad 2"},
+	{"RETROK_KP3", "Tastiera Numpad 3"},
+	{"RETROK_KP4", "Tastiera Numpad 4"},
+	{"RETROK_KP5", "Tastiera Numpad 5"},
+	{"RETROK_KP6", "Tastiera Numpad 6"},
+	{"RETROK_KP7", "Tastiera Numpad 7"},
+	{"RETROK_KP8", "Tastiera Numpad 8"},
+	{"RETROK_KP9", "Tastiera Numpad 9"},
+	{"RETROK_KP_PERIOD", "Tastiera Numpad ."},
+	{"RETROK_KP_DIVIDE", "Tastiera Numpad /"},
+	{"RETROK_KP_MULTIPLY", "Tastiera Numpad *"},
+	{"RETROK_KP_MINUS", "Tastiera Numpad -"},
+	{"RETROK_KP_PLUS", "Tastiera Numpad +"},
+	{"RETROK_KP_ENTER", "Tastiera Numpad Enter"},
+	{"RETROK_KP_EQUALS", "Tastiera Numpad ="},
+	{"RETROK_UP", "Tastiera Su"},
+	{"RETROK_DOWN", "Tastiera Giù"},
+	{"RETROK_LEFT", "Tastiera Sinistra"},
+	{"RETROK_RIGHT", "Tastiera Destra"},
+	{"RETROK_INSERT", "Tastiera Insert"},
+	{"RETROK_DELETE", "Tastiera Delete"},
+	{"RETROK_HOME", "Tastiera Home"},
+	{"RETROK_END", "Tastiera End"},
+	{"RETROK_PAGEUP", "Tastiera PageUp"},
+	{"RETROK_PAGEDOWN", "Tastiera PageDown"},
+	{"RETROK_F1", "Tastiera F1"},
+	{"RETROK_F2", "Tastiera F2"},
+	{"RETROK_F3", "Tastiera F3"},
+	{"RETROK_F4", "Tastiera F4"},
+	{"RETROK_F5", "Tastiera F5"},
+	{"RETROK_F6", "Tastiera F6"},
+	{"RETROK_F7", "Tastiera F7"},
+	{"RETROK_F8", "Tastiera F8"},
+	{"RETROK_F9", "Tastiera F9"},
+	{"RETROK_F10", "Tastiera F10"},
+	{"RETROK_F11", "Tastiera F11"},
+	{"RETROK_F12", "Tastiera F12"},
+//{"RETROK_F13","Tastiera F13"},
+//{"RETROK_F14","Tastiera F14"},
+//{"RETROK_F15","Tastiera F15"},
+//{"RETROK_NUMLOCK","Tastiera NumLock"},
+//{"RETROK_CAPSLOCK","Tastiera Caps Lock"},
+//{"RETROK_SCROLLOCK","Tastiera Scroll Lock"},
+	{"RETROK_LSHIFT", "Tastiera Shift Sinistra"},
+	{"RETROK_RSHIFT", "Tastiera Shift Destra"},
+	{"RETROK_LCTRL", "Tastiera Control Sinistra"},
+	{"RETROK_RCTRL", "Tastiera Control Destra"},
+	{"RETROK_LALT", "Tastiera Alt Sinistra"},
+	{"RETROK_RALT", "Tastiera Alt Destra"},
+//{"RETROK_LMETA","Tastiera Left Meta"},
+//{"RETROK_RMETA","Tastiera Right Meta"},
+//{"RETROK_LSUPER","Tastiera Left Super"},
+//{"RETROK_RSUPER","Tastiera Right Super"},
+//{"RETROK_MODE","Tastiera Mode"},
+//{"RETROK_COMPOSE","Tastiera Compose"},
+//{"RETROK_HELP","Tastiera Help"},
+//{"RETROK_PRINT","Tastiera Print"},
+//{"RETROK_SYSREQ","Tastiera SysReq"},
+//{"RETROK_BREAK","Tastiera Break"},
+//{"RETROK_MENU","Tastiera Menu"},
+//{"RETROK_POWER","Tastiera Power"},
+//{"RETROK_EURO","Tastiera Euro"},
+//{"RETROK_UNDO","Tastiera Undo"},
+};
+
 /* RETRO_LANGUAGE_DUTCH */
 
 /* RETRO_LANGUAGE_PORTUGUESE_BRAZIL */
diff --git a/backends/platform/libretro/include/libretro-core-options.h b/backends/platform/libretro/include/libretro-core-options.h
index 0d53cc40aba..86e95a5f631 100644
--- a/backends/platform/libretro/include/libretro-core-options.h
+++ b/backends/platform/libretro/include/libretro-core-options.h
@@ -87,6 +87,11 @@ struct retro_core_option_v2_category option_cats_us[] = {
 		"Timing",
 		"Configure timing settings"
 	},
+	{
+		"retropad",
+		"RetroPad mapping",
+		"Configure RetroPad mapping"
+	},
 	{ NULL, NULL, NULL },
 };
 
@@ -307,6 +312,297 @@ struct retro_core_option_v2_definition option_defs_us[] = {
 		},
 		"48000 Hz"
 	},
+	/* Button mappings */
+	{
+		"scummvm_mapper_up",
+		"RetroPad > Up",
+		"Up",
+		NULL,
+		NULL,
+		"retropad",
+		{
+			{ NULL, NULL }
+		},
+		"RETROKE_UP"
+	},
+	{
+		"scummvm_mapper_down",
+		"RetroPad > Down",
+		"Down",
+		NULL,
+		NULL,
+		"retropad",
+		{
+			{ NULL, NULL }
+		},
+		"RETROKE_DOWN"
+	},
+	{
+		"scummvm_mapper_left",
+		"RetroPad > Left",
+		"Left",
+		NULL,
+		NULL,
+		"retropad",
+		{
+			{ NULL, NULL }
+		},
+		"RETROKE_LEFT"
+	},
+	{
+		"scummvm_mapper_right",
+		"RetroPad > Right",
+		"Right",
+		NULL,
+		NULL,
+		"retropad",
+		{
+			{ NULL, NULL }
+		},
+		"RETROKE_RIGHT"
+	},
+	{
+		"scummvm_mapper_a",
+		"RetroPad > A",
+		"A",
+		NULL,
+		NULL,
+		"retropad",
+		{
+			{ NULL, NULL }
+		},
+		"RETROK_ESCAPE"
+	},
+	{
+		"scummvm_mapper_b",
+		"RetroPad > B",
+		"B",
+		NULL,
+		NULL,
+		"retropad",
+		{
+			{ NULL, NULL }
+		},
+		"RETROK_RETURN"
+	},
+	{
+		"scummvm_mapper_x",
+		"RetroPad > X",
+		"X",
+		NULL,
+		NULL,
+		"retropad",
+		{
+			{ NULL, NULL }
+		},
+		"RETROK_F5"
+	},
+	{
+		"scummvm_mapper_y",
+		"RetroPad > Y",
+		"Y",
+		NULL,
+		NULL,
+		"retropad",
+		{
+			{ NULL, NULL }
+		},
+		"RETROK_SPACE"
+	},
+	{
+		"scummvm_mapper_select",
+		"RetroPad > Select",
+		"Select",
+		NULL,
+		NULL,
+		"retropad",
+		{
+			{ NULL, NULL }
+		},
+		"RETROKE_VKBD"
+	},
+	{
+		"scummvm_mapper_start",
+		"RetroPad > Start",
+		"Start",
+		NULL,
+		NULL,
+		"retropad",
+		{
+			{ NULL, NULL }
+		},
+		"RETROKE_SCUMMVM_GUI"
+	},
+	{
+		"scummvm_mapper_l",
+		"RetroPad > L",
+		"L",
+		NULL,
+		NULL,
+		"retropad",
+		{
+			{ NULL, NULL }
+		},
+		"RETROKE_LEFT_BUTTON"
+	},
+	{
+		"scummvm_mapper_r",
+		"RetroPad > R",
+		"R",
+		NULL,
+		NULL,
+		"retropad",
+		{
+			{ NULL, NULL }
+		},
+		"RETROKE_RIGHT_BUTTON"
+	},
+	{
+		"scummvm_mapper_l2",
+		"RetroPad > L2",
+		"L2",
+		NULL,
+		NULL,
+		"retropad",
+		{
+			{ NULL, NULL }
+		},
+		"---"
+	},
+	{
+		"scummvm_mapper_r2",
+		"RetroPad > R2",
+		"R2",
+		NULL,
+		NULL,
+		"retropad",
+		{
+			{ NULL, NULL }
+		},
+		"RETROKE_FINE_CONTROL"
+	},
+	{
+		"scummvm_mapper_l3",
+		"RetroPad > L3",
+		"L3",
+		NULL,
+		NULL,
+		"retropad",
+		{
+			{ NULL, NULL }
+		},
+		"---"
+	},
+	{
+		"scummvm_mapper_r3",
+		"RetroPad > R3",
+		"R3",
+		NULL,
+		NULL,
+		"retropad",
+		{
+			{ NULL, NULL }
+		},
+		"---"
+	},
+	/* Left Stick */
+	{
+		"scummvm_mapper_lu",
+		"RetroPad > Left Analog > Up",
+		"Left Analog > Up",
+		NULL,
+		NULL,
+		"retropad",
+		{
+			{ NULL, NULL }
+		},
+		"RETROKE_UP"
+	},
+	{
+		"scummvm_mapper_ld",
+		"RetroPad > Left Analog > Down",
+		"Left Analog > Down",
+		NULL,
+		NULL,
+		"retropad",
+		{
+			{ NULL, NULL }
+		},
+		"RETROKE_DOWN"
+	},
+	{
+		"scummvm_mapper_ll",
+		"RetroPad > Left Analog > Left",
+		"Left Analog > Left",
+		NULL,
+		NULL,
+		"retropad",
+		{
+			{ NULL, NULL }
+		},
+		"RETROKE_LEFT"
+	},
+	{
+		"scummvm_mapper_lr",
+		"RetroPad > Left Analog > Right",
+		"Left Analog > Right",
+		NULL,
+		NULL,
+		"retropad",
+		{
+			{ NULL, NULL }
+		},
+		"RETROKE_RIGHT"
+	},
+	/* Right Stick */
+	{
+		"scummvm_mapper_ru",
+		"RetroPad > Right Analog > Up",
+		"Right Analog > Up",
+		NULL,
+		NULL,
+		"retropad",
+		{
+			{ NULL, NULL }
+		},
+		"RETROK_UP"
+	},
+	{
+		"scummvm_mapper_rd",
+		"RetroPad > Right Analog > Down",
+		"Right Analog > Down",
+		NULL,
+		NULL,
+		"retropad",
+		{
+			{ NULL, NULL }
+		},
+		"RETROK_DOWN"
+	},
+	{
+		"scummvm_mapper_rl",
+		"RetroPad > Right Analog > Left",
+		"Right Analog > Left",
+		NULL,
+		NULL,
+		"retropad",
+		{
+			{ NULL, NULL }
+		},
+		"RETROK_LEFT"
+	},
+	{
+		"scummvm_mapper_rr",
+		"RetroPad > Right Analog > Right",
+		"Right Analog > Right",
+		NULL,
+		NULL,
+		"retropad",
+		{
+			{ NULL, NULL }
+		},
+		"RETROK_RIGHT"
+	},
 	{
 		"scummvm_auto_performance_tuner",
 		"Auto performance tuner",
@@ -333,6 +629,164 @@ struct retro_core_options_v2 options_us = {
 	option_defs_us
 };
 
+/* List has been reduced to fit RETRO_NUM_CORE_OPTION_VALUES_MAX.
+ * Latest element {NULL, NULL} has been omitted in this case as the array is exactly sized
+ * RETRO_NUM_CORE_OPTION_VALUES_MAX; in case the array size will be reduced, {NULL, NULL}
+ * element to be uncommented.
+ */
+
+struct retro_core_option_value retro_keys_label_us [] = {
+	{"---", "---"},
+	{"RETROKE_VKBD", "Toggle Virtual Keyboard"},
+	{"RETROKE_LEFT", "Mouse Cursor Left"},
+	{"RETROKE_UP", "Mouse Cursor Up"},
+	{"RETROKE_DOWN", "Mouse Cursor Down"},
+	{"RETROKE_RIGHT", "Mouse Cursor Right"},
+	{"RETROKE_LEFT_BUTTON", "Mouse Left Button"},
+	{"RETROKE_RIGHT_BUTTON", "Mouse Right Button"},
+	{"RETROKE_FINE_CONTROL", "Mouse Cursor Fine Control"},
+	{"RETROKE_SCUMMVM_GUI", "ScummVM GUI"},
+	{"RETROKE_SHIFT_MOD", "Keyboard Shift (Modifier)"},
+	{"RETROKE_CTRL_MOD", "Keyboard Control (Modifier)"},
+	{"RETROKE_ALT_MOD", "Keyboard Alt (Modifier)"},
+	{"RETROK_BACKSPACE", "Keyboard Backspace"},
+	{"RETROK_TAB", "Keyboard Tab"},
+	{"RETROK_CLEAR", "Keyboard Clear"},
+	{"RETROK_RETURN", "Keyboard Return"},
+	{"RETROK_PAUSE", "Keyboard Pause"},
+	{"RETROK_ESCAPE", "Keyboard Escape"},
+	{"RETROK_SPACE", "Keyboard Space"},
+	{"RETROK_EXCLAIM", "Keyboard !"},
+	{"RETROK_QUOTEDBL", "Keyboard \""},
+	{"RETROK_HASH", "Keyboard #"},
+	{"RETROK_DOLLAR", "Keyboard $"},
+	{"RETROK_AMPERSAND", "Keyboard &"},
+	{"RETROK_QUOTE", "Keyboard \'"},
+	{"RETROK_LEFTPAREN", "Keyboard ("},
+	{"RETROK_RIGHTPAREN", "Keyboard )"},
+	{"RETROK_ASTERISK", "Keyboard *"},
+	{"RETROK_PLUS", "Keyboard +"},
+	{"RETROK_COMMA", "Keyboard ,"},
+	{"RETROK_MINUS", "Keyboard -"},
+	{"RETROK_PERIOD", "Keyboard ."},
+	{"RETROK_SLASH", "Keyboard /"},
+	{"RETROK_0", "Keyboard 0"},
+	{"RETROK_1", "Keyboard 1"},
+	{"RETROK_2", "Keyboard 2"},
+	{"RETROK_3", "Keyboard 3"},
+	{"RETROK_4", "Keyboard 4"},
+	{"RETROK_5", "Keyboard 5"},
+	{"RETROK_6", "Keyboard 6"},
+	{"RETROK_7", "Keyboard 7"},
+	{"RETROK_8", "Keyboard 8"},
+	{"RETROK_9", "Keyboard 9"},
+	{"RETROK_COLON", "Keyboard :"},
+	{"RETROK_SEMICOLON", "Keyboard ;"},
+	{"RETROK_LESS", "Keyboard <"},
+	{"RETROK_EQUALS", "Keyboard ="},
+	{"RETROK_GREATER", "Keyboard >"},
+	{"RETROK_QUESTION", "Keyboard ?"},
+	{"RETROK_AT", "Keyboard @"},
+	{"RETROK_LEFTBRACKET", "Keyboard ["},
+	{"RETROK_BACKSLASH", "Keyboard \\"},
+	{"RETROK_RIGHTBRACKET", "Keyboard ]"},
+	{"RETROK_CARET", "Keyboard ^"},
+	{"RETROK_UNDERSCORE", "Keyboard _"},
+	{"RETROK_BACKQUOTE", "Keyboard `"},
+	{"RETROK_a", "Keyboard a"},
+	{"RETROK_b", "Keyboard b"},
+	{"RETROK_c", "Keyboard c"},
+	{"RETROK_d", "Keyboard d"},
+	{"RETROK_e", "Keyboard e"},
+	{"RETROK_f", "Keyboard f"},
+	{"RETROK_g", "Keyboard g"},
+	{"RETROK_h", "Keyboard h"},
+	{"RETROK_i", "Keyboard i"},
+	{"RETROK_j", "Keyboard j"},
+	{"RETROK_k", "Keyboard k"},
+	{"RETROK_l", "Keyboard l"},
+	{"RETROK_m", "Keyboard m"},
+	{"RETROK_n", "Keyboard n"},
+	{"RETROK_o", "Keyboard o"},
+	{"RETROK_p", "Keyboard p"},
+	{"RETROK_q", "Keyboard q"},
+	{"RETROK_r", "Keyboard r"},
+	{"RETROK_s", "Keyboard s"},
+	{"RETROK_t", "Keyboard t"},
+	{"RETROK_u", "Keyboard u"},
+	{"RETROK_v", "Keyboard v"},
+	{"RETROK_w", "Keyboard w"},
+	{"RETROK_x", "Keyboard x"},
+	{"RETROK_y", "Keyboard y"},
+	{"RETROK_z", "Keyboard z"},
+	{"RETROK_KP0", "Keyboard Numpad 0"},
+	{"RETROK_KP1", "Keyboard Numpad 1"},
+	{"RETROK_KP2", "Keyboard Numpad 2"},
+	{"RETROK_KP3", "Keyboard Numpad 3"},
+	{"RETROK_KP4", "Keyboard Numpad 4"},
+	{"RETROK_KP5", "Keyboard Numpad 5"},
+	{"RETROK_KP6", "Keyboard Numpad 6"},
+	{"RETROK_KP7", "Keyboard Numpad 7"},
+	{"RETROK_KP8", "Keyboard Numpad 8"},
+	{"RETROK_KP9", "Keyboard Numpad 9"},
+	{"RETROK_KP_PERIOD", "Keyboard Numpad ."},
+	{"RETROK_KP_DIVIDE", "Keyboard Numpad /"},
+	{"RETROK_KP_MULTIPLY", "Keyboard Numpad *"},
+	{"RETROK_KP_MINUS", "Keyboard Numpad -"},
+	{"RETROK_KP_PLUS", "Keyboard Numpad +"},
+	{"RETROK_KP_ENTER", "Keyboard Numpad Enter"},
+	{"RETROK_KP_EQUALS", "Keyboard Numpad ="},
+	{"RETROK_UP", "Keyboard Up"},
+	{"RETROK_DOWN", "Keyboard Down"},
+	{"RETROK_LEFT", "Keyboard Left"},
+	{"RETROK_RIGHT", "Keyboard Right"},
+	{"RETROK_INSERT", "Keyboard Insert"},
+	{"RETROK_DELETE", "Keyboard Delete"},
+	{"RETROK_HOME", "Keyboard Home"},
+	{"RETROK_END", "Keyboard End"},
+	{"RETROK_PAGEUP", "Keyboard PageUp"},
+	{"RETROK_PAGEDOWN", "Keyboard PageDown"},
+	{"RETROK_F1", "Keyboard F1"},
+	{"RETROK_F2", "Keyboard F2"},
+	{"RETROK_F3", "Keyboard F3"},
+	{"RETROK_F4", "Keyboard F4"},
+	{"RETROK_F5", "Keyboard F5"},
+	{"RETROK_F6", "Keyboard F6"},
+	{"RETROK_F7", "Keyboard F7"},
+	{"RETROK_F8", "Keyboard F8"},
+	{"RETROK_F9", "Keyboard F9"},
+	{"RETROK_F10", "Keyboard F10"},
+	{"RETROK_F11", "Keyboard F11"},
+	{"RETROK_F12", "Keyboard F12"},
+//{"RETROK_F13","Keyboard F13"},
+//{"RETROK_F14","Keyboard F14"},
+//{"RETROK_F15","Keyboard F15"},
+//{"RETROK_NUMLOCK","Keyboard NumLock"},
+//{"RETROK_CAPSLOCK","Keyboard Caps Lock"},
+//{"RETROK_SCROLLOCK","Keyboard Scroll Lock"},
+	{"RETROK_LSHIFT", "Keyboard Left Shift"},
+	{"RETROK_RSHIFT", "Keyboard Right Shift"},
+	{"RETROK_LCTRL", "Keyboard Left Control"},
+	{"RETROK_RCTRL", "Keyboard Right Control"},
+	{"RETROK_LALT", "Keyboard Left Alt"},
+	{"RETROK_RALT", "Keyboard Right Alt"},
+//{"RETROK_LMETA","Keyboard Left Meta"},
+//{"RETROK_RMETA","Keyboard Right Meta"},
+//{"RETROK_LSUPER","Keyboard Left Super"},
+//{"RETROK_RSUPER","Keyboard Right Super"},
+//{"RETROK_MODE","Keyboard Mode"},
+//{"RETROK_COMPOSE","Keyboard Compose"},
+//{"RETROK_HELP","Keyboard Help"},
+//{"RETROK_PRINT","Keyboard Print"},
+//{"RETROK_SYSREQ","Keyboard SysReq"},
+//{"RETROK_BREAK","Keyboard Break"},
+//{"RETROK_MENU","Keyboard Menu"},
+//{"RETROK_POWER","Keyboard Power"},
+//{"RETROK_EURO","Keyboard Euro"},
+//{"RETROK_UNDO","Keyboard Undo"},
+//{NULL, NULL}
+};
+
 /*
  ********************************
  * Language Mapping
@@ -361,6 +815,28 @@ struct retro_core_options_v2 *options_intl[RETRO_LANGUAGE_LAST] = {
 	NULL,           /* RETRO_LANGUAGE_GREEK */
 	NULL,           /* RETRO_LANGUAGE_TURKISH */
 };
+
+struct retro_core_option_value *retro_keys_labels_intl[RETRO_LANGUAGE_LAST] = {
+	retro_keys_label_us, /* RETRO_LANGUAGE_ENGLISH */
+	NULL,           /* RETRO_LANGUAGE_JAPANESE */
+	NULL,           /* RETRO_LANGUAGE_FRENCH */
+	NULL,           /* RETRO_LANGUAGE_SPANISH */
+	NULL,           /* RETRO_LANGUAGE_GERMAN */
+	retro_keys_label_it, /* RETRO_LANGUAGE_ITALIAN */
+	NULL,           /* RETRO_LANGUAGE_DUTCH */
+	NULL,           /* RETRO_LANGUAGE_PORTUGUESE_BRAZIL */
+	NULL,           /* RETRO_LANGUAGE_PORTUGUESE_PORTUGAL */
+	NULL,           /* RETRO_LANGUAGE_RUSSIAN */
+	NULL,           /* RETRO_LANGUAGE_KOREAN */
+	NULL,           /* RETRO_LANGUAGE_CHINESE_TRADITIONAL */
+	NULL,           /* RETRO_LANGUAGE_CHINESE_SIMPLIFIED */
+	NULL,           /* RETRO_LANGUAGE_ESPERANTO */
+	NULL,           /* RETRO_LANGUAGE_POLISH */
+	NULL,           /* RETRO_LANGUAGE_VIETNAMESE */
+	NULL,           /* RETRO_LANGUAGE_ARABIC */
+	NULL,           /* RETRO_LANGUAGE_GREEK */
+	NULL,           /* RETRO_LANGUAGE_TURKISH */
+};
 #endif
 
 /*
@@ -369,6 +845,52 @@ struct retro_core_options_v2 *options_intl[RETRO_LANGUAGE_LAST] = {
  ********************************
  */
 
+static INLINE void libretro_fill_options_mapper_data(retro_environment_t environ_cb) {
+	/* Fill in the values for all the mappers */
+	int m = 0;
+	int n = 0;
+	while (option_defs_us[m].key) {
+		if (strstr(option_defs_us[m].key, "scummvm_mapper_")) {
+			n = 0;
+			while (retro_keys_label_us[n].label && n < RETRO_NUM_CORE_OPTION_VALUES_MAX - 1) {
+				option_defs_us[m].values[n].value = retro_keys_label_us[n].value;
+				option_defs_us[m].values[n].label = retro_keys_label_us[n].label;
+				++n;
+			}
+			option_defs_us[m].values[n].value = NULL;
+			option_defs_us[m].values[n].label = NULL;
+		}
+		++m;
+	}
+#ifndef HAVE_NO_LANGEXTRA
+	struct retro_core_option_value *retro_keys_label_intl = NULL;
+	unsigned language = 0;
+
+	if (environ_cb(RETRO_ENVIRONMENT_GET_LANGUAGE, &language) &&
+	        (language < RETRO_LANGUAGE_LAST) && (language != RETRO_LANGUAGE_ENGLISH))
+		retro_keys_label_intl = retro_keys_labels_intl[language];
+
+	if (! options_intl[language] || ! retro_keys_label_intl)
+		return;
+
+	m = 0;
+	n = 0;
+	while (options_intl[language]->definitions[m].key) {
+		if (strstr(options_intl[language]->definitions[m].key, "scummvm_mapper_")) {
+			n = 0;
+			while ((retro_keys_label_intl + n)->label && n < RETRO_NUM_CORE_OPTION_VALUES_MAX - 1) {
+				options_intl[language]->definitions[m].values[n].value = (retro_keys_label_intl + n)->value;
+				options_intl[language]->definitions[m].values[n].label = (retro_keys_label_intl + n)->label;
+				++n;
+			}
+			options_intl[language]->definitions[m].values[n].value = NULL;
+			options_intl[language]->definitions[m].values[n].label = NULL;
+		}
+		++m;
+	}
+#endif
+}
+
 /* Handles configuration/setting of core options.
  * Should be called as early as possible - ideally inside
  * retro_set_environment(), and no later than retro_load_game()
diff --git a/backends/platform/libretro/include/libretro-defs.h b/backends/platform/libretro/include/libretro-defs.h
index 89b284035ea..bdbfdcd1868 100644
--- a/backends/platform/libretro/include/libretro-defs.h
+++ b/backends/platform/libretro/include/libretro-defs.h
@@ -18,6 +18,9 @@
 #ifndef LIBRETRO_DEFS_H
 #define LIBRETRO_DEFS_H
 
+// System analog stick range is -0x8000 to 0x8000
+#define ANALOG_RANGE 0x8000
+
 #define DEFAULT_SAMPLE_RATE     48000
 #define DEFAULT_REFRESH_RATE    60
 #define FRAMESKIP_MAX           DEFAULT_REFRESH_RATE / 2
diff --git a/backends/platform/libretro/include/libretro-mapper.h b/backends/platform/libretro/include/libretro-mapper.h
index 5836d0ce955..65231eb798b 100644
--- a/backends/platform/libretro/include/libretro-mapper.h
+++ b/backends/platform/libretro/include/libretro-mapper.h
@@ -19,6 +19,200 @@
 #define LIBRETRO_MAPPER_H
 
 #include <libretro.h>
+#include "common/keyboard.h"
+
+#define RETRO_DEVICE_KEY_STATUS         0
+#define RETRO_DEVICE_KEY_PREV_STATUS    1
+#define RETRO_DEVICE_KEY_CHANGED        2
+
+#define RETRO_DEVICE_ID_JOYPAD_ANALOG   16
+
+#define RETRO_DEVICE_ID_JOYPAD_LR       16
+#define RETRO_DEVICE_ID_JOYPAD_LL       17
+#define RETRO_DEVICE_ID_JOYPAD_LD       18
+#define RETRO_DEVICE_ID_JOYPAD_LU       19
+#define RETRO_DEVICE_ID_JOYPAD_RR       20
+#define RETRO_DEVICE_ID_JOYPAD_RL       21
+#define RETRO_DEVICE_ID_JOYPAD_RD       22
+#define RETRO_DEVICE_ID_JOYPAD_RU       23
+
+#define RETRO_DEVICE_ID_JOYPAD_LAST     24
+
+#define RETROKE_VKBD -1
+#define RETROKE_LEFT -2
+#define RETROKE_UP -3
+#define RETROKE_DOWN -4
+#define RETROKE_RIGHT -5
+#define RETROKE_LEFT_BUTTON -6
+#define RETROKE_RIGHT_BUTTON -7
+#define RETROKE_FINE_CONTROL -8
+#define RETROKE_SCUMMVM_GUI -9
+#define RETROKE_SHIFT_MOD -10
+#define RETROKE_CTRL_MOD -11
+#define RETROKE_ALT_MOD -12
+
+/* libretro.cpp functions */
+extern retro_input_state_t retro_input_cb;
+extern int retro_setting_get_analog_deadzone(void);
+extern bool retro_get_input_bitmask_supported(void);
+
+struct retro_keymap {
+	int retro_id;
+	int scummvm_id;
+	const char *value;
+};
+
+static const struct retro_keymap retro_keys[] = {
+	{0, 0, "---"},
+	{RETROKE_VKBD, 0, "RETROKE_VKBD"},
+	{RETROKE_LEFT, 0, "RETROKE_LEFT"},
+	{RETROKE_UP, 0, "RETROKE_UP"},
+	{RETROKE_DOWN, 0, "RETROKE_DOWN"},
+	{RETROKE_RIGHT, 0, "RETROKE_RIGHT"},
+	{RETROKE_LEFT_BUTTON, 0, "RETROKE_LEFT_BUTTON"},
+	{RETROKE_RIGHT_BUTTON, 0, "RETROKERIGHT_BUTTON"},
+	{RETROKE_FINE_CONTROL, 0, "RETROKE_FINE_CONTROL"},
+	{RETROKE_SCUMMVM_GUI, 0, "RETROKE_SCUMMVM_GUI"},
+	{RETROKE_SHIFT_MOD, 0, "RETROKE_SHIFT_MOD"},
+	{RETROKE_CTRL_MOD, 0, "RETROKE_CTRL_MOD"},
+	{RETROKE_ALT_MOD, 0, "RETROKE_ALT_MOD"},
+	{RETROK_BACKSPACE, Common::KEYCODE_BACKSPACE, "RETROK_BACKSPACE"},
+	{RETROK_TAB, Common::KEYCODE_TAB, "RETROK_TAB"},
+	{RETROK_CLEAR, Common::KEYCODE_CLEAR, "RETROK_CLEAR"},
+	{RETROK_RETURN, Common::KEYCODE_RETURN, "RETROK_RETURN"},
+	{RETROK_PAUSE, Common::KEYCODE_PAUSE, "RETROK_PAUSE"},
+	{RETROK_ESCAPE, Common::KEYCODE_ESCAPE, "RETROK_ESCAPE"},
+	{RETROK_SPACE, Common::KEYCODE_SPACE, "RETROK_SPACE"},
+	{RETROK_EXCLAIM, Common::KEYCODE_EXCLAIM, "RETROK_EXCLAIM"},
+	{RETROK_QUOTEDBL, Common::KEYCODE_QUOTEDBL, "RETROK_QUOTEDBL"},
+	{RETROK_HASH, Common::KEYCODE_HASH, "RETROK_HASH"},
+	{RETROK_DOLLAR, Common::KEYCODE_DOLLAR, "RETROK_DOLLAR"},
+	{RETROK_AMPERSAND, Common::KEYCODE_AMPERSAND, "RETROK_AMPERSAND"},
+	{RETROK_QUOTE, Common::KEYCODE_QUOTE, "RETROK_QUOTE"},
+	{RETROK_LEFTPAREN, Common::KEYCODE_LEFTPAREN, "RETROK_LEFTPAREN"},
+	{RETROK_RIGHTPAREN, Common::KEYCODE_RIGHTPAREN, "RETROK_RIGHTPAREN"},
+	{RETROK_ASTERISK, Common::KEYCODE_ASTERISK, "RETROK_ASTERISK"},
+	{RETROK_PLUS, Common::KEYCODE_PLUS, "RETROK_PLUS"},
+	{RETROK_COMMA, Common::KEYCODE_COMMA, "RETROK_COMMA"},
+	{RETROK_MINUS, Common::KEYCODE_MINUS, "RETROK_MINUS"},
+	{RETROK_PERIOD, Common::KEYCODE_PERIOD, "RETROK_PERIOD"},
+	{RETROK_SLASH, Common::KEYCODE_SLASH, "RETROK_SLASH"},
+	{RETROK_0, Common::KEYCODE_0, "RETROK_0"},
+	{RETROK_1, Common::KEYCODE_1, "RETROK_1"},
+	{RETROK_2, Common::KEYCODE_2, "RETROK_2"},
+	{RETROK_3, Common::KEYCODE_3, "RETROK_3"},
+	{RETROK_4, Common::KEYCODE_4, "RETROK_4"},
+	{RETROK_5, Common::KEYCODE_5, "RETROK_5"},
+	{RETROK_6, Common::KEYCODE_6, "RETROK_6"},
+	{RETROK_7, Common::KEYCODE_7, "RETROK_7"},
+	{RETROK_8, Common::KEYCODE_8, "RETROK_8"},
+	{RETROK_9, Common::KEYCODE_9, "RETROK_9"},
+	{RETROK_COLON, Common::KEYCODE_COLON, "RETROK_COLON"},
+	{RETROK_SEMICOLON, Common::KEYCODE_SEMICOLON, "RETROK_SEMICOLON"},
+	{RETROK_LESS, Common::KEYCODE_LESS, "RETROK_LESS"},
+	{RETROK_EQUALS, Common::KEYCODE_EQUALS, "RETROK_EQUALS"},
+	{RETROK_GREATER, Common::KEYCODE_GREATER, "RETROK_GREATER"},
+	{RETROK_QUESTION, Common::KEYCODE_QUESTION, "RETROK_QUESTION"},
+	{RETROK_AT, Common::KEYCODE_AT, "RETROK_AT"},
+	{RETROK_LEFTBRACKET, Common::KEYCODE_LEFTBRACKET, "RETROK_LEFTBRACKET"},
+	{RETROK_BACKSLASH, Common::KEYCODE_BACKSLASH, "RETROK_BACKSLASH"},
+	{RETROK_RIGHTBRACKET, Common::KEYCODE_RIGHTBRACKET, "RETROK_RIGHTBRACKET"},
+	{RETROK_CARET, Common::KEYCODE_CARET, "RETROK_CARET"},
+	{RETROK_UNDERSCORE, Common::KEYCODE_UNDERSCORE, "RETROK_UNDERSCORE"},
+	{RETROK_BACKQUOTE, Common::KEYCODE_BACKQUOTE, "RETROK_BACKQUOTE"},
+	{RETROK_a, Common::KEYCODE_a, "RETROK_a"},
+	{RETROK_b, Common::KEYCODE_b, "RETROK_b"},
+	{RETROK_c, Common::KEYCODE_c, "RETROK_c"},
+	{RETROK_d, Common::KEYCODE_d, "RETROK_d"},
+	{RETROK_e, Common::KEYCODE_e, "RETROK_e"},
+	{RETROK_f, Common::KEYCODE_f, "RETROK_f"},
+	{RETROK_g, Common::KEYCODE_g, "RETROK_g"},
+	{RETROK_h, Common::KEYCODE_h, "RETROK_h"},
+	{RETROK_i, Common::KEYCODE_i, "RETROK_i"},
+	{RETROK_j, Common::KEYCODE_j, "RETROK_j"},
+	{RETROK_k, Common::KEYCODE_k, "RETROK_k"},
+	{RETROK_l, Common::KEYCODE_l, "RETROK_l"},
+	{RETROK_m, Common::KEYCODE_m, "RETROK_m"},
+	{RETROK_n, Common::KEYCODE_n, "RETROK_n"},
+	{RETROK_o, Common::KEYCODE_o, "RETROK_o"},
+	{RETROK_p, Common::KEYCODE_p, "RETROK_p"},
+	{RETROK_q, Common::KEYCODE_q, "RETROK_q"},
+	{RETROK_r, Common::KEYCODE_r, "RETROK_r"},
+	{RETROK_s, Common::KEYCODE_s, "RETROK_s"},
+	{RETROK_t, Common::KEYCODE_t, "RETROK_t"},
+	{RETROK_u, Common::KEYCODE_u, "RETROK_u"},
+	{RETROK_v, Common::KEYCODE_v, "RETROK_v"},
+	{RETROK_w, Common::KEYCODE_w, "RETROK_w"},
+	{RETROK_x, Common::KEYCODE_x, "RETROK_x"},
+	{RETROK_y, Common::KEYCODE_y, "RETROK_y"},
+	{RETROK_z, Common::KEYCODE_z, "RETROK_z"},
+	{RETROK_KP0, Common::KEYCODE_KP0, "RETROK_KP0"},
+	{RETROK_KP1, Common::KEYCODE_KP1, "RETROK_KP1"},
+	{RETROK_KP2, Common::KEYCODE_KP2, "RETROK_KP2"},
+	{RETROK_KP3, Common::KEYCODE_KP3, "RETROK_KP3"},
+	{RETROK_KP4, Common::KEYCODE_KP4, "RETROK_KP4"},
+	{RETROK_KP5, Common::KEYCODE_KP5, "RETROK_KP5"},
+	{RETROK_KP6, Common::KEYCODE_KP6, "RETROK_KP6"},
+	{RETROK_KP7, Common::KEYCODE_KP7, "RETROK_KP7"},
+	{RETROK_KP8, Common::KEYCODE_KP8, "RETROK_KP8"},
+	{RETROK_KP9, Common::KEYCODE_KP9, "RETROK_KP9"},
+	{RETROK_KP_PERIOD, Common::KEYCODE_KP_PERIOD, "RETROK_KP_PERIOD"},
+	{RETROK_KP_DIVIDE, Common::KEYCODE_KP_DIVIDE, "RETROK_KP_DIVIDE"},
+	{RETROK_KP_MULTIPLY, Common::KEYCODE_KP_MULTIPLY, "RETROK_KP_MULTIPLY"},
+	{RETROK_KP_MINUS, Common::KEYCODE_KP_MINUS, "RETROK_KP_MINUS"},
+	{RETROK_KP_PLUS, Common::KEYCODE_KP_PLUS, "RETROK_KP_PLUS"},
+	{RETROK_KP_ENTER, Common::KEYCODE_KP_ENTER, "RETROK_KP_ENTER"},
+	{RETROK_KP_EQUALS, Common::KEYCODE_KP_EQUALS, "RETROK_KP_EQUALS"},
+	{RETROK_UP, Common::KEYCODE_UP, "RETROK_UP"},
+	{RETROK_DOWN, Common::KEYCODE_DOWN, "RETROK_DOWN"},
+	{RETROK_LEFT, Common::KEYCODE_LEFT, "RETROK_LEFT"},
+	{RETROK_RIGHT, Common::KEYCODE_RIGHT, "RETROK_RIGHT"},
+	{RETROK_INSERT, Common::KEYCODE_INSERT, "RETROK_INSERT"},
+	{RETROK_DELETE, Common::KEYCODE_DELETE, "RETROK_DELETE"},
+	{RETROK_HOME, Common::KEYCODE_HOME, "RETROK_HOME"},
+	{RETROK_END, Common::KEYCODE_END, "RETROK_END"},
+	{RETROK_PAGEUP, Common::KEYCODE_PAGEUP, "RETROK_PAGEUP"},
+	{RETROK_PAGEDOWN, Common::KEYCODE_PAGEDOWN, "RETROK_PAGEDOWN"},
+	{RETROK_F1, Common::KEYCODE_F1, "RETROK_F1"},
+	{RETROK_F2, Common::KEYCODE_F2, "RETROK_F2"},
+	{RETROK_F3, Common::KEYCODE_F3, "RETROK_F3"},
+	{RETROK_F4, Common::KEYCODE_F4, "RETROK_F4"},
+	{RETROK_F5, Common::KEYCODE_F5, "RETROK_F5"},
+	{RETROK_F6, Common::KEYCODE_F6, "RETROK_F6"},
+	{RETROK_F7, Common::KEYCODE_F7, "RETROK_F7"},
+	{RETROK_F8, Common::KEYCODE_F8, "RETROK_F8"},
+	{RETROK_F9, Common::KEYCODE_F9, "RETROK_F9"},
+	{RETROK_F10, Common::KEYCODE_F10, "RETROK_F10"},
+	{RETROK_F11, Common::KEYCODE_F11, "RETROK_F11"},
+	{RETROK_F12, Common::KEYCODE_F12, "RETROK_F12"},
+	{RETROK_F13, Common::KEYCODE_F13, "RETROK_F13"},
+	{RETROK_F14, Common::KEYCODE_F14, "RETROK_F14"},
+	{RETROK_F15, Common::KEYCODE_F15, "RETROK_F15"},
+	{RETROK_NUMLOCK, Common::KEYCODE_NUMLOCK, "RETROK_NUMLOCK"},
+	{RETROK_CAPSLOCK, Common::KEYCODE_CAPSLOCK, "RETROK_CAPSLOCK"},
+	{RETROK_SCROLLOCK, Common::KEYCODE_SCROLLOCK, "RETROK_SCROLLOCK"},
+	{RETROK_LSHIFT, Common::KEYCODE_LSHIFT, "RETROK_LSHIFT"},
+	{RETROK_RSHIFT, Common::KEYCODE_RSHIFT, "RETROK_RSHIFT"},
+	{RETROK_LCTRL, Common::KEYCODE_LCTRL, "RETROK_LCTRL"},
+	{RETROK_RCTRL, Common::KEYCODE_RCTRL, "RETROK_RCTRL"},
+	{RETROK_LALT, Common::KEYCODE_LALT, "RETROK_LALT"},
+	{RETROK_RALT, Common::KEYCODE_RALT, "RETROK_RALT"},
+	{RETROK_LMETA, Common::KEYCODE_LMETA, "RETROK_LMETA"},
+	{RETROK_RMETA, Common::KEYCODE_RMETA, "RETROK_RMETA"},
+	{RETROK_LSUPER, Common::KEYCODE_LSUPER, "RETROK_LSUPER"},
+	{RETROK_RSUPER, Common::KEYCODE_RSUPER, "RETROK_RSUPER"},
+	{RETROK_MODE, Common::KEYCODE_MODE, "RETROK_MODE"},
+	{RETROK_COMPOSE, Common::KEYCODE_COMPOSE, "RETROK_COMPOSE"},
+	{RETROK_HELP, Common::KEYCODE_HELP, "RETROK_HELP"},
+	{RETROK_PRINT, Common::KEYCODE_PRINT, "RETROK_PRINT"},
+	{RETROK_SYSREQ, Common::KEYCODE_SYSREQ, "RETROK_SYSREQ"},
+	{RETROK_BREAK, Common::KEYCODE_BREAK, "RETROK_BREAK"},
+	{RETROK_MENU, Common::KEYCODE_MENU, "RETROK_MENU"},
+	{RETROK_POWER, Common::KEYCODE_POWER, "RETROK_POWER"},
+	{RETROK_EURO, Common::KEYCODE_EURO, "RETROK_EURO"},
+	{RETROK_UNDO, Common::KEYCODE_UNDO, "RETROK_UNDO"},
+	{RETROK_LAST, 0, ""}
+};
 
 const struct retro_controller_description retro_controller_list[] = {
 	{"None", RETRO_DEVICE_NONE},
@@ -31,7 +225,7 @@ const struct retro_controller_info retro_controller_lists[] = {
 	{NULL, 0}
 };
 
-struct retro_input_descriptor retro_input_desc[] = {
+static struct retro_input_descriptor retro_input_desc[] = {
 	{0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP, "Up"},
 	{0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN, "Down"},
 	{0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT, "Left"},
@@ -54,4 +248,14 @@ struct retro_input_descriptor retro_input_desc[] = {
 	{0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_Y, "Right Analog Y"}
 };
 
+void mapper_poll_device(void);
+bool mapper_set_device_keys(unsigned int retro_device_id, const char *retro_key_value);
+uint8_t mapper_get_device_key_status(unsigned int retro_device_id);
+int16_t mapper_get_device_key_value(unsigned int retro_device_id);
+int16_t mapper_get_device_key_retro_id(unsigned int retro_device_id);
+int16_t mapper_get_device_key_scummvm_id(unsigned int retro_device_id);
+int8_t mapper_get_mapper_key_index(int16_t key_retro_id, uint8_t start_index = 0);
+uint8_t mapper_get_mapper_key_status(int16_t key_retro_id);
+int16_t mapper_get_mapper_key_value(int16_t key_retro_id);
+
 #endif // LIBRETRO_MAPPER_H
diff --git a/backends/platform/libretro/include/libretro-os.h b/backends/platform/libretro/include/libretro-os.h
index 637c8d3b8b1..7bca55718f8 100644
--- a/backends/platform/libretro/include/libretro-os.h
+++ b/backends/platform/libretro/include/libretro-os.h
@@ -31,6 +31,11 @@
 #include "graphics/surface.h"
 
 #define BASE_CURSOR_SPEED 4
+#define CURSOR_STATUS_DOING_JOYSTICK  (1 << 0)
+#define CURSOR_STATUS_DOING_MOUSE     (1 << 1)
+#define CURSOR_STATUS_DOING_X         (1 << 2)
+#define CURSOR_STATUS_DOING_Y         (1 << 3)
+#define CURSOR_STATUS_DOING_SLOWER    (1 << 4)
 
 #define LIBRETRO_G_SYSTEM dynamic_cast<OSystem_libretro *>(g_system)
 
@@ -87,11 +92,11 @@ private:
 	float _dpadYAcc;
 	float _dpadXVel;
 	float _dpadYVel;
-	unsigned _joypadnumpadLast;
 	float _adjusted_cursor_speed;
 	float _inverse_acceleration_time;
 	uint32 _startTime;
 	uint8 _threadSwitchCaller;
+	uint8_t _cursorStatus;
 	Common::String s_systemDir;
 	Common::String s_saveDir;
 	Common::String s_extraDir;
@@ -111,9 +116,6 @@ public:
 	bool _overlayInGUI;
 	bool _mouseDontScale;
 	bool _mouseButtons[2];
-	bool _joypadmouseButtons[2];
-	bool _joypadkeyboardButtons[8];
-	bool _joypadnumpadActive;
 	bool _ptrmouseButton;
 	bool _mousePaletteEnabled;
 	bool _mouseVisible;
@@ -186,7 +188,7 @@ private:
 
 	/* Inputs */
 public:
-	void processMouse(void);
+	void processInputs(void);
 	static void processKeyEvent(bool down, unsigned keycode, uint32_t character, uint16_t key_modifiers);
 	void setShakePos(int shakeXOffset, int shakeYOffset) override {}
 private:
diff --git a/backends/platform/libretro/src/libretro-mapper.cpp b/backends/platform/libretro/src/libretro-mapper.cpp
new file mode 100644
index 00000000000..89dcaba8b28
--- /dev/null
+++ b/backends/platform/libretro/src/libretro-mapper.cpp
@@ -0,0 +1,167 @@
+/* Copyright (C) 2023 Giovanni Cascione <ing.cascione at gmail.com>
+ *
+ * This program 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 Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+#define FORBIDDEN_SYMBOL_EXCEPTION_strcpy
+#define FORBIDDEN_SYMBOL_EXCEPTION_strcat
+
+#include "backends/platform/libretro/include/libretro-mapper.h"
+
+struct retro_keymap mapper_keys[RETRO_DEVICE_ID_JOYPAD_LAST] = {0};
+
+static int16_t mapper_digital_buttons_status = 0;
+static uint32_t mapper_digital_buttons_prev_status = 0;
+static int16_t mapper_analog_stick_status [2][2] = {0};
+
+void mapper_poll_device(void) {
+	//Store previous on/off status
+	mapper_digital_buttons_prev_status = mapper_digital_buttons_status;
+	for (int8_t i = RETRO_DEVICE_ID_JOYPAD_ANALOG; i < RETRO_DEVICE_ID_JOYPAD_LAST; i++)
+		mapper_digital_buttons_prev_status |= mapper_get_device_key_value(i) ? 1 << i : 0;
+
+	//Get current status
+	mapper_digital_buttons_status = 0;
+	bool bitmasks = false;
+	// Store real digital buttons status
+	if (retro_get_input_bitmask_supported())
+		mapper_digital_buttons_status = retro_input_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_MASK);
+	else
+		for (int8_t i = 0; i < RETRO_DEVICE_ID_JOYPAD_ANALOG; i++)
+			mapper_digital_buttons_status |= (retro_input_cb(0, RETRO_DEVICE_JOYPAD, 0, i) << i);
+
+	//Store analog sticks (analog) status
+	for (int8_t i = 0; i < 2; i++)
+		for (int8_t j = 0; j < 2; j++)
+			mapper_analog_stick_status[i][j] = retro_input_cb(0, RETRO_DEVICE_ANALOG, i, j);
+}
+
+static int16_t mapper_get_retro_key_index(const char *retro_key_value) {
+	uint16_t i = 0;
+	while (retro_keys[i].retro_id != RETROK_LAST) {
+		if (strcmp(retro_keys[i].value, retro_key_value) == 0)
+			return i;
+		++i;
+	}
+	return -1;
+}
+
+int8_t mapper_get_mapper_key_index(int16_t key_retro_id, uint8_t start_index) {
+	uint8_t i = start_index;
+	while (i < RETRO_DEVICE_ID_JOYPAD_LAST - 1) {
+		if (mapper_keys[i].retro_id == key_retro_id)
+			return i;
+		++i;
+	}
+	return -1;
+}
+
+bool mapper_set_device_keys(unsigned int retro_device_id, const char *retro_key_value) {
+	int16_t retro_key_index = mapper_get_retro_key_index(retro_key_value);
+	if (retro_key_index > -1 && retro_device_id < RETRO_DEVICE_ID_JOYPAD_LAST) {
+		mapper_keys[retro_device_id] = retro_keys[retro_key_index];
+		return true;
+	}
+	return false;
+}
+
+int16_t mapper_get_device_key_value(unsigned int retro_device_id) {
+	if (retro_device_id < RETRO_DEVICE_ID_JOYPAD_ANALOG) {
+		return (mapper_digital_buttons_status & (1 << retro_device_id)) > 0;
+	} else if (retro_device_id < RETRO_DEVICE_ID_JOYPAD_LAST) {
+		int16_t res;
+		int16_t sign;
+		switch (retro_device_id) {
+		case RETRO_DEVICE_ID_JOYPAD_LU:
+			res =    mapper_analog_stick_status[RETRO_DEVICE_INDEX_ANALOG_LEFT][RETRO_DEVICE_ID_ANALOG_Y];
+			sign = -1;
+			break;
+		case RETRO_DEVICE_ID_JOYPAD_LD:
+			res =    mapper_analog_stick_status[RETRO_DEVICE_INDEX_ANALOG_LEFT][RETRO_DEVICE_ID_ANALOG_Y];
+			sign = 1;
+			break;
+		case RETRO_DEVICE_ID_JOYPAD_LL:
+			res =    mapper_analog_stick_status[RETRO_DEVICE_INDEX_ANALOG_LEFT][RETRO_DEVICE_ID_ANALOG_X];
+			sign = -1;
+			break;
+		case RETRO_DEVICE_ID_JOYPAD_LR:
+			res =    mapper_analog_stick_status[RETRO_DEVICE_INDEX_ANALOG_LEFT][RETRO_DEVICE_ID_ANALOG_X];
+			sign = 1;
+			break;
+		case RETRO_DEVICE_ID_JOYPAD_RU:
+			res =    mapper_analog_stick_status[RETRO_DEVICE_INDEX_ANALOG_RIGHT][RETRO_DEVICE_ID_ANALOG_Y];
+			sign = -1;
+			break;
+		case RETRO_DEVICE_ID_JOYPAD_RD:
+			res =    mapper_analog_stick_status[RETRO_DEVICE_INDEX_ANALOG_RIGHT][RETRO_DEVICE_ID_ANALOG_Y];
+			sign = 1;
+			break;
+		case RETRO_DEVICE_ID_JOYPAD_RL:
+			res =    mapper_analog_stick_status[RETRO_DEVICE_INDEX_ANALOG_RIGHT][RETRO_DEVICE_ID_ANALOG_X];
+			sign = -1;
+			break;
+		case RETRO_DEVICE_ID_JOYPAD_RR:
+			res =    mapper_analog_stick_status[RETRO_DEVICE_INDEX_ANALOG_RIGHT][RETRO_DEVICE_ID_ANALOG_X];
+			sign = 1;
+		}
+
+		bool check_sign = (res > 0) - (res < 0) == sign;
+		res = abs(res);
+		/* discard analog values of 1 to discriminate from digital inputs */
+		return check_sign && res > 1 && res > retro_setting_get_analog_deadzone() ? res : 0;
+	}
+	return 0;
+}
+
+uint8_t mapper_get_device_key_status(unsigned int retro_device_id) {
+	uint8_t status = mapper_get_device_key_value(retro_device_id) ? 1 << RETRO_DEVICE_KEY_STATUS : 0;
+	status |= (mapper_digital_buttons_prev_status & (1 << retro_device_id)) ? 1 << RETRO_DEVICE_KEY_PREV_STATUS : 0;
+	status |= ((status & (1 << RETRO_DEVICE_KEY_STATUS)) > 0) == ((status & (1 << RETRO_DEVICE_KEY_PREV_STATUS)) > 0) ? 0 : 1 << RETRO_DEVICE_KEY_CHANGED;
+	return status;
+}
+
+int16_t mapper_get_mapper_key_value(int16_t retro_key_retro_id) {
+	int16_t result = 0;
+	int8_t retro_key_index = 0;
+	while (retro_key_index > -1) {
+		retro_key_index = mapper_get_mapper_key_index(retro_key_retro_id, retro_key_index);
+		if (retro_key_index > -1) {
+			if (mapper_get_device_key_value(retro_key_index) > result)
+				result = mapper_get_device_key_value(retro_key_index);
+			retro_key_index++;
+		}
+	}
+	return result;
+}
+
+uint8_t mapper_get_mapper_key_status(int16_t retro_key_retro_id) {
+	uint8_t status = 0;
+	int8_t retro_key_index = 0;
+	while (retro_key_index > -1) {
+		retro_key_index = mapper_get_mapper_key_index(retro_key_retro_id, retro_key_index);
+		if (retro_key_index > -1) {
+			status |= mapper_get_device_key_status(retro_key_index);
+			retro_key_index++;
+		}
+	}
+	return status;
+}
+
+int16_t mapper_get_device_key_retro_id(unsigned int retro_device_id) {
+	return mapper_keys[retro_device_id].retro_id;
+}
+
+int16_t mapper_get_device_key_scummvm_id(unsigned int retro_device_id) {
+	return mapper_keys[retro_device_id].scummvm_id;
+}
diff --git a/backends/platform/libretro/src/libretro-os-base.cpp b/backends/platform/libretro/src/libretro-os-base.cpp
index 0b98ba4cb96..cf59cdbb352 100644
--- a/backends/platform/libretro/src/libretro-os-base.cpp
+++ b/backends/platform/libretro/src/libretro-os-base.cpp
@@ -33,11 +33,9 @@
 #include "backends/platform/libretro/include/libretro-os.h"
 #include "backends/platform/libretro/include/libretro-defs.h"
 
-OSystem_libretro::OSystem_libretro() : _mousePaletteEnabled(false), _mouseVisible(false), _mouseX(0), _mouseY(0), _mouseXAcc(0.0), _mouseYAcc(0.0), _mouseHotspotX(0), _mouseHotspotY(0), _dpadXAcc(0.0), _dpadYAcc(0.0), _dpadXVel(0.0f), _dpadYVel(0.0f), _mouseKeyColor(0), _mouseDontScale(false), _joypadnumpadLast(8), _joypadnumpadActive(false), _mixer(0), _startTime(0), _threadSwitchCaller(0) {
+OSystem_libretro::OSystem_libretro() : _mousePaletteEnabled(false), _mouseVisible(false), _mouseX(0), _mouseY(0), _mouseXAcc(0.0), _mouseYAcc(0.0), _mouseHotspotX(0), _mouseHotspotY(0), _dpadXAcc(0.0), _dpadYAcc(0.0), _dpadXVel(0.0f), _dpadYVel(0.0f), _mouseKeyColor(0), _mouseDontScale(false), _mixer(0), _startTime(0), _threadSwitchCaller(0), _cursorStatus(0) {
 	_fsFactory = new FS_SYSTEM_FACTORY();
 	memset(_mouseButtons, 0, sizeof(_mouseButtons));
-	memset(_joypadmouseButtons, 0, sizeof(_joypadmouseButtons));
-	memset(_joypadkeyboardButtons, 0, sizeof(_joypadkeyboardButtons));
 
 	s_systemDir = Common::String(retro_get_system_dir());
 	s_saveDir = Common::String(retro_get_save_dir());
diff --git a/backends/platform/libretro/src/libretro-os-inputs.cpp b/backends/platform/libretro/src/libretro-os-inputs.cpp
index febdfd1e6b7..eb70f5c91f7 100644
--- a/backends/platform/libretro/src/libretro-os-inputs.cpp
+++ b/backends/platform/libretro/src/libretro-os-inputs.cpp
@@ -14,47 +14,39 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  *
  */
+#define FORBIDDEN_SYMBOL_EXCEPTION_strcpy
+#define FORBIDDEN_SYMBOL_EXCEPTION_strcat
 
 #include <libretro.h>
 #include "backends/platform/libretro/include/libretro-os.h"
+#include "backends/platform/libretro/include/libretro-mapper.h"
+#include "backends/platform/libretro/include/libretro-defs.h"
 
-#define ANALOG_RANGE 0x8000
-#define PI 3.141592653589793238
-
-uint8_t status = 0;
-enum processMouse_status {
-	STATUS_DOING_JOYSTICK  = (1 << 0),
-	STATUS_DOING_MOUSE     = (1 << 1),
-	STATUS_DOING_X         = (1 << 2),
-	STATUS_DOING_Y         = (1 << 3),
-	STATUS_DOING_SLOWER    = (1 << 4)
-};
-
-void OSystem_libretro::updateMouseXY(float deltaAcc, float * cumulativeXYAcc, int doing_x){
-	int * mouseXY;
-	int16 * screen_wh;
-	int * relMouseXY;
+void OSystem_libretro::updateMouseXY(float deltaAcc, float *cumulativeXYAcc, int doing_x) {
+	int *mouseXY;
+	int16 *screen_wh;
+	int *relMouseXY;
 	int cumulativeXYAcc_int;
 
 	if (! deltaAcc)
 		return;
 
-	if (status & STATUS_DOING_SLOWER)
+	if (_cursorStatus & CURSOR_STATUS_DOING_SLOWER)
 		deltaAcc *= 0.2f;
 
 	if (doing_x) {
-		status |= STATUS_DOING_X;
+		_cursorStatus |= CURSOR_STATUS_DOING_X;
 		mouseXY = &_mouseX;
 		screen_wh = &_screen.w;
 		relMouseXY = &_relMouseX;
 	} else {
-		status |= STATUS_DOING_Y;
+		_cursorStatus |= CURSOR_STATUS_DOING_Y;
 		mouseXY = &_mouseY;
 		screen_wh = &_screen.h;
 		relMouseXY = &_relMouseY;
 	}
 	*cumulativeXYAcc += deltaAcc;
-	cumulativeXYAcc_int = (int)*cumulativeXYAcc;
+	cumulativeXYAcc_int = (int) * cumulativeXYAcc;
 	if (cumulativeXYAcc_int != 0) {
 		// Set mouse position
 		*mouseXY += cumulativeXYAcc_int;
@@ -70,11 +62,11 @@ void OSystem_libretro::getMouseXYFromAnalog(bool is_x, int16_t coor) {
 
 	int16_t sign = (coor > 0) - (coor < 0);
 	uint16_t abs_coor = abs(coor);
-	float * mouseAcc;
+	float *mouseAcc;
 
 	if (abs_coor < retro_setting_get_analog_deadzone()) return;
 
-	status |= STATUS_DOING_JOYSTICK;
+	_cursorStatus |= CURSOR_STATUS_DOING_JOYSTICK;
 
 	if (is_x) {
 		mouseAcc = &_mouseXAcc;
@@ -92,8 +84,8 @@ void OSystem_libretro::getMouseXYFromAnalog(bool is_x, int16_t coor) {
 }
 
 void OSystem_libretro::getMouseXYFromButton(bool is_x, int16_t sign) {
-	float * dpadVel;
-	float * dpadAcc;
+	float *dpadVel;
+	float *dpadAcc;
 
 	if (is_x) {
 		dpadVel = &_dpadXVel;
@@ -111,116 +103,109 @@ void OSystem_libretro::getMouseXYFromButton(bool is_x, int16_t sign) {
 	if (! sign)
 		return;
 
-	status |= STATUS_DOING_JOYSTICK;
+	_cursorStatus |= CURSOR_STATUS_DOING_JOYSTICK;
 
 	*dpadVel = MIN(*dpadVel + _inverse_acceleration_time, 1.0f);
 
 	updateMouseXY(sign * *dpadVel * _adjusted_cursor_speed, dpadAcc, is_x);
 }
 
-void OSystem_libretro::processMouse(void) {
-	int16_t joy_rx, joy_ry, x, y;
+void OSystem_libretro::processInputs(void) {
+	int16_t x, y;
 	float analog_amplitude_x, analog_amplitude_y;
 	float deltaAcc;
-	bool  down;
-	int dpad_cursor_offset;
-	double rs_radius, rs_angle;
-	unsigned numpad_index;
+	bool down;
+	int key_modifiers [3][2] = {{RETROKE_SHIFT_MOD, RETROKMOD_SHIFT}, {RETROKE_CTRL_MOD, RETROKMOD_CTRL}, {RETROKE_ALT_MOD, RETROKMOD_ALT}};
+	int key_flags = 0;
+	int retropad_value = 0;
 
 	static const uint32_t retroButtons[2] = {RETRO_DEVICE_ID_MOUSE_LEFT, RETRO_DEVICE_ID_MOUSE_RIGHT};
 	static const Common::EventType eventID[2][2] = {{Common::EVENT_LBUTTONDOWN, Common::EVENT_LBUTTONUP}, {Common::EVENT_RBUTTONDOWN, Common::EVENT_RBUTTONUP}};
 
-	static const unsigned gampad_key_map[8][4] = {
-		{RETRO_DEVICE_ID_JOYPAD_X, (unsigned)Common::KEYCODE_ESCAPE, (unsigned)Common::ASCII_ESCAPE, 0},           // Esc
-		{RETRO_DEVICE_ID_JOYPAD_Y, (unsigned)Common::KEYCODE_PERIOD, 46, 0},                                       // .
-		{RETRO_DEVICE_ID_JOYPAD_L, (unsigned)Common::KEYCODE_RETURN, (unsigned)Common::ASCII_RETURN, 0},           // Enter
-		{RETRO_DEVICE_ID_JOYPAD_R, (unsigned)Common::KEYCODE_KP5, 53, 0},                                          // Numpad 5
-		{RETRO_DEVICE_ID_JOYPAD_L2, (unsigned)Common::KEYCODE_BACKSPACE, (unsigned)Common::ASCII_BACKSPACE, 0},    // Backspace
-		{RETRO_DEVICE_ID_JOYPAD_L3, (unsigned)Common::KEYCODE_F10, (unsigned)Common::ASCII_F10, 0},                // F10
-		{RETRO_DEVICE_ID_JOYPAD_R3, (unsigned)Common::KEYCODE_KP0, 48, 0},                                         // Numpad 0
-		{RETRO_DEVICE_ID_JOYPAD_SELECT, (unsigned)Common::KEYCODE_F7, (unsigned)Common::ASCII_F7, RETROKMOD_CTRL}, // CTRL+F7 (virtual keyboard)
-	};
-
-	// Right stick circular wrap around: 1 -> 2 -> 3 -> 6 -> 9 -> 8 -> 7 -> 4
-	static const unsigned gampad_numpad_map[8][2] = {
-		{(unsigned)Common::KEYCODE_KP1, 49},
-		{(unsigned)Common::KEYCODE_KP2, 50},
-		{(unsigned)Common::KEYCODE_KP3, 51},
-		{(unsigned)Common::KEYCODE_KP6, 54},
-		{(unsigned)Common::KEYCODE_KP9, 57},
-		{(unsigned)Common::KEYCODE_KP8, 56},
-		{(unsigned)Common::KEYCODE_KP7, 55},
-		{(unsigned)Common::KEYCODE_KP4, 52},
-	};
-
-	status = 0;
-
+	_cursorStatus = 0;
 
 	// Process input from RetroPad
+	mapper_poll_device();
 
 	// Reduce cursor speed, if required
-	if (retro_get_input_device() == RETRO_DEVICE_JOYPAD && retro_input_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2)) {
-		status |= STATUS_DOING_SLOWER;
+	if (retro_get_input_device() == RETRO_DEVICE_JOYPAD && mapper_get_mapper_key_status(RETROKE_FINE_CONTROL)) {
+		_cursorStatus |= CURSOR_STATUS_DOING_SLOWER;
 	} else {
-		status &= ~STATUS_DOING_SLOWER;
+		_cursorStatus &= ~CURSOR_STATUS_DOING_SLOWER;
 	}
 
-	getMouseXYFromAnalog(true, retro_input_cb(0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_X));
-	getMouseXYFromAnalog(false, retro_input_cb(0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_Y));
+	// Handle x,y
+	int x_coor_cursor = mapper_get_mapper_key_value(RETROKE_RIGHT) - mapper_get_mapper_key_value(RETROKE_LEFT);
+	int y_coor_cursor = mapper_get_mapper_key_value(RETROKE_DOWN) - mapper_get_mapper_key_value(RETROKE_UP);
+
+	if (abs(x_coor_cursor) > 1) {
+		getMouseXYFromAnalog(true, x_coor_cursor);
+	} else
+		getMouseXYFromButton(true, x_coor_cursor);
 
+	if (abs(y_coor_cursor) > 1)
+		getMouseXYFromAnalog(false, y_coor_cursor);
+	else
+		getMouseXYFromButton(false, y_coor_cursor);
 
-	getMouseXYFromButton(true, retro_input_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT) - retro_input_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT));
-	getMouseXYFromButton(false, retro_input_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN) - retro_input_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP));
+	if (_cursorStatus & CURSOR_STATUS_DOING_JOYSTICK) {
+		Common::Event ev;
+		ev.type = Common::EVENT_MOUSEMOVE;
+		ev.mouse.x = _mouseX;
+		ev.mouse.y = _mouseY;
+		ev.relMouse.x = _cursorStatus & CURSOR_STATUS_DOING_X ? _relMouseX : 0;
+		ev.relMouse.y = _cursorStatus & CURSOR_STATUS_DOING_Y ? _relMouseY : 0;
+		_events.push_back(ev);
+	}
 
-	if (retro_input_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START)) {
+	// Handle special functions
+	if (mapper_get_mapper_key_value(RETROKE_SCUMMVM_GUI)) {
 		Common::Event ev;
 		ev.type = Common::EVENT_MAINMENU;
 		_events.push_back(ev);
 	}
 
-	if (status & STATUS_DOING_JOYSTICK) {
+	if ((mapper_get_mapper_key_status(RETROKE_VKBD) & ((1 << RETRO_DEVICE_KEY_STATUS) | (1 << RETRO_DEVICE_KEY_CHANGED))) == ((1 << RETRO_DEVICE_KEY_STATUS) | (1 << RETRO_DEVICE_KEY_CHANGED))) {
 		Common::Event ev;
-		ev.type = Common::EVENT_MOUSEMOVE;
-		ev.mouse.x = _mouseX;
-		ev.mouse.y = _mouseY;
-		ev.relMouse.x = status & STATUS_DOING_X ? _relMouseX : 0;
-		ev.relMouse.y = status & STATUS_DOING_Y ? _relMouseY : 0;
+		ev.type = Common::EVENT_VIRTUAL_KEYBOARD;
 		_events.push_back(ev);
 	}
 
-	// Gamepad mouse buttons
-	down = retro_input_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A);
-	if (down != _joypadmouseButtons[0]) {
-		_joypadmouseButtons[0] = down;
 
+	// Handle mouse buttons
+	retropad_value = mapper_get_mapper_key_status(RETROKE_LEFT_BUTTON);
+	if (retropad_value & (1 << RETRO_DEVICE_KEY_CHANGED)) {
 		Common::Event ev;
-		ev.type = eventID[0][down ? 0 : 1];
+		ev.type = eventID[0][(retropad_value & (1 << RETRO_DEVICE_KEY_STATUS)) ? 0 : 1];
 		ev.mouse.x = _mouseX;
 		ev.mouse.y = _mouseY;
 		_events.push_back(ev);
 	}
 
-	down = retro_input_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B);
-	if (down != _joypadmouseButtons[1]) {
-		_joypadmouseButtons[1] = down;
-
+	retropad_value = mapper_get_mapper_key_status(RETROKE_RIGHT_BUTTON);
+	if (retropad_value & (1 << RETRO_DEVICE_KEY_CHANGED)) {
 		Common::Event ev;
-		ev.type = eventID[1][down ? 0 : 1];
+		ev.type = eventID[0][(retropad_value & (1 << RETRO_DEVICE_KEY_STATUS)) ? 0 : 1];
 		ev.mouse.x = _mouseX;
 		ev.mouse.y = _mouseY;
 		_events.push_back(ev);
 	}
 
-	// Gamepad keyboard buttons
-	for (int i = 0; i < 8; i++) {
-		down = retro_input_cb(0, RETRO_DEVICE_JOYPAD, 0, gampad_key_map[i][0]);
-		if (down != _joypadkeyboardButtons[i]) {
-			_joypadkeyboardButtons[i] = down;
-			bool state = down ? true : false;
-			processKeyEvent(state, gampad_key_map[i][1], (uint32_t)gampad_key_map[i][2], (uint32_t)gampad_key_map[i][3]);
-		}
+	// Handle keyboard buttons
+	for (uint8_t i = 0; i < sizeof(key_modifiers) / sizeof(key_modifiers[0]); i++) {
+		if (mapper_get_mapper_key_value(key_modifiers[i][0]))
+			key_flags |= key_modifiers[i][1];
 	}
 
+	for (uint8_t i = 0; i < RETRO_DEVICE_ID_JOYPAD_LAST; i++) {
+		if (mapper_get_device_key_retro_id(i) <= 0)
+			continue;
+		retropad_value = mapper_get_device_key_status(i);
+
+		if (retropad_value & (1 << RETRO_DEVICE_KEY_CHANGED)) {
+			processKeyEvent((retropad_value & (1 << RETRO_DEVICE_KEY_STATUS)), mapper_get_device_key_scummvm_id(i), 0, key_flags);
+		}
+	}
 
 #if defined(WIIU) || defined(__SWITCH__)
 	int p_x = retro_input_cb(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_X);
@@ -266,78 +251,13 @@ void OSystem_libretro::processMouse(void) {
 
 #endif
 
-	// Gamepad right stick numpad emulation
-	joy_rx = retro_input_cb(0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_X);
-	joy_ry = retro_input_cb(0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_Y);
-
-	if (joy_rx > retro_setting_get_analog_deadzone())
-		joy_rx = joy_rx - retro_setting_get_analog_deadzone();
-	else if (joy_rx < -retro_setting_get_analog_deadzone())
-		joy_rx = joy_rx + retro_setting_get_analog_deadzone();
-	else
-		joy_rx = 0;
-
-	if (joy_ry > retro_setting_get_analog_deadzone())
-		joy_ry = joy_ry - retro_setting_get_analog_deadzone();
-	else if (joy_ry < -retro_setting_get_analog_deadzone())
-		joy_ry = joy_ry + retro_setting_get_analog_deadzone();
-	else
-		joy_ry = 0;
-
-	// This is very ugly, but I don't have time to make it nicer...
-	if (joy_rx != 0 || joy_ry != 0) {
-		analog_amplitude_x = (float)joy_rx / (float)(ANALOG_RANGE - retro_setting_get_analog_deadzone());
-		analog_amplitude_y = (float)joy_ry / (float)(ANALOG_RANGE - retro_setting_get_analog_deadzone());
-
-		// Convert to polar coordinates: part 1
-		rs_radius = sqrt((double)(analog_amplitude_x * analog_amplitude_x) + (double)(analog_amplitude_y * analog_amplitude_y));
-
-		// Check if radius is above threshold
-		if (rs_radius > 0.5) {
-			// Convert to polar coordinates: part 2
-			rs_angle = atan2((double)analog_amplitude_y, (double)analog_amplitude_x);
-
-			// Adjust rotation offset...
-			rs_angle = (2.0 * PI) - (rs_angle + PI);
-			rs_angle = fmod(rs_angle - (0.125 * PI), 2.0 * PI);
-			if (rs_angle < 0)
-				rs_angle += 2.0 * PI;
-
-			// Convert angle into numpad key index
-			numpad_index = (unsigned)((rs_angle / (2.0 * PI)) * 8.0);
-			// Unnecessary safety check...
-			numpad_index = (numpad_index > 7) ? 7 : numpad_index;
-			// printf("numpad_index: %u\n", numpad_index);
-
-			if (numpad_index != _joypadnumpadLast) {
-				// Unset last key, if required
-				if (_joypadnumpadActive)
-					processKeyEvent(false, gampad_numpad_map[_joypadnumpadLast][0], (uint32_t)gampad_numpad_map[_joypadnumpadLast][1], 0);
-
-				// Set new key
-				processKeyEvent(true, gampad_numpad_map[numpad_index][0], (uint32_t)gampad_numpad_map[numpad_index][1], 0);
-
-				_joypadnumpadLast = numpad_index;
-				_joypadnumpadActive = true;
-			}
-		} else if (_joypadnumpadActive) {
-			processKeyEvent(false, gampad_numpad_map[_joypadnumpadLast][0], (uint32_t)gampad_numpad_map[_joypadnumpadLast][1], 0);
-			_joypadnumpadActive = false;
-			_joypadnumpadLast = 8;
-		}
-	} else if (_joypadnumpadActive) {
-		processKeyEvent(false, gampad_numpad_map[_joypadnumpadLast][0], (uint32_t)gampad_numpad_map[_joypadnumpadLast][1], 0);
-		_joypadnumpadActive = false;
-		_joypadnumpadLast = 8;
-	}
-
 	// Process input from physical mouse
 	x = retro_input_cb(0, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_X);
 	y = retro_input_cb(0, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_Y);
 
 	// > X Axis
 	if (x != 0) {
-		status |= (STATUS_DOING_MOUSE | STATUS_DOING_X);
+		_cursorStatus |= (CURSOR_STATUS_DOING_MOUSE | CURSOR_STATUS_DOING_X);
 		if (x > 0) {
 			// Reset accumulator when changing direction
 			_mouseXAcc = (_mouseXAcc < 0.0) ? 0.0 : _mouseXAcc;
@@ -351,7 +271,7 @@ void OSystem_libretro::processMouse(void) {
 	}
 	// > Y Axis
 	if (y != 0) {
-		status |= (STATUS_DOING_MOUSE | STATUS_DOING_Y);
+		_cursorStatus |= (CURSOR_STATUS_DOING_MOUSE | CURSOR_STATUS_DOING_Y);
 		if (y > 0) {
 			// Reset accumulator when changing direction
 			_mouseYAcc = (_mouseYAcc < 0.0) ? 0.0 : _mouseYAcc;
@@ -364,13 +284,13 @@ void OSystem_libretro::processMouse(void) {
 		updateMouseXY(deltaAcc, &_mouseYAcc, 0);
 	}
 
-	if (status & STATUS_DOING_MOUSE) {
+	if (_cursorStatus & CURSOR_STATUS_DOING_MOUSE) {
 		Common::Event ev;
 		ev.type = Common::EVENT_MOUSEMOVE;
 		ev.mouse.x = _mouseX;
 		ev.mouse.y = _mouseY;
-		ev.relMouse.x = status & STATUS_DOING_X ? _relMouseX : 0;
-		ev.relMouse.y = status & STATUS_DOING_Y ? _relMouseY : 0;
+		ev.relMouse.x = _cursorStatus & CURSOR_STATUS_DOING_X ? _relMouseX : 0;
+		ev.relMouse.y = _cursorStatus & CURSOR_STATUS_DOING_Y ? _relMouseY : 0;
 		_events.push_back(ev);
 	}
 
diff --git a/backends/platform/libretro/src/libretro.cpp b/backends/platform/libretro/src/libretro.cpp
index 395c97fc984..e246f9e3be0 100644
--- a/backends/platform/libretro/src/libretro.cpp
+++ b/backends/platform/libretro/src/libretro.cpp
@@ -57,7 +57,7 @@
 #include "backends/platform/libretro/include/libretro-mapper.h"
 
 static struct retro_game_info game_buf;
-static struct retro_game_info * game_buf_ptr;
+static struct retro_game_info *game_buf_ptr;
 
 retro_log_printf_t retro_log_cb = NULL;
 retro_input_state_t retro_input_cb = NULL;
@@ -67,8 +67,6 @@ static retro_environment_t environ_cb = NULL;
 static retro_input_poll_t poll_cb = NULL;
 static int retro_input_device = RETRO_DEVICE_JOYPAD;
 
-// System analog stick range is -0x8000 to 0x8000
-#define ANALOG_RANGE 0x8000
 // Default deadzone: 15%
 static int analog_deadzone = (int)(0.15f * ANALOG_RANGE);
 
@@ -110,6 +108,7 @@ static size_t samples_per_frame_buffer_size = 0;
 static int16_t *sound_buffer = NULL;               // pointer to output buffer
 static int16_t *sound_buffer_empty = NULL;         // pointer to zeroed output buffer, to regulate GUI FPS
 
+static bool input_bitmask_supported = false;
 static bool updating_variables = false;
 static int opt_frameskip_threshold_display = 0;
 static int opt_frameskip_no_display = 0;
@@ -181,7 +180,7 @@ void reset_performance_tuner() {
 	}
 }
 
-void retro_osd_notification(const char* msg) {
+void retro_osd_notification(const char *msg) {
 	if (!msg || *msg == '\0')
 		return;
 	struct retro_message_ext retro_msg;
@@ -195,7 +194,7 @@ void retro_osd_notification(const char* msg) {
 static void update_variables(void) {
 	struct retro_variable var;
 	updating_variables = true;
-	const char* osd_msg = "";
+	const char *osd_msg = "";
 
 	var.key = "scummvm_gamepad_cursor_speed";
 	var.value = NULL;
@@ -307,6 +306,150 @@ static void update_variables(void) {
 			performance_switch = 0;
 	}
 
+	var.key = "scummvm_mapper_up";
+	var.value = NULL;
+	if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) {
+		mapper_set_device_keys(RETRO_DEVICE_ID_JOYPAD_UP, var.value);
+	}
+
+	var.key = "scummvm_mapper_down";
+	var.value = NULL;
+	if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) {
+		mapper_set_device_keys(RETRO_DEVICE_ID_JOYPAD_DOWN, var.value);
+	}
+
+	var.key = "scummvm_mapper_left";
+	var.value = NULL;
+	if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) {
+		mapper_set_device_keys(RETRO_DEVICE_ID_JOYPAD_LEFT, var.value);
+	}
+
+	var.key = "scummvm_mapper_right";
+	var.value = NULL;
+	if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) {
+		mapper_set_device_keys(RETRO_DEVICE_ID_JOYPAD_RIGHT, var.value);
+	}
+
+	var.key = "scummvm_mapper_a";
+	var.value = NULL;
+	if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) {
+		mapper_set_device_keys(RETRO_DEVICE_ID_JOYPAD_A, var.value);
+	}
+
+	var.key = "scummvm_mapper_b";
+	var.value = NULL;
+	if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) {
+		mapper_set_device_keys(RETRO_DEVICE_ID_JOYPAD_B, var.value);
+	}
+
+	var.key = "scummvm_mapper_x";
+	var.value = NULL;
+	if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) {
+		mapper_set_device_keys(RETRO_DEVICE_ID_JOYPAD_X, var.value);
+	}
+
+	var.key = "scummvm_mapper_y";
+	var.value = NULL;
+	if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) {
+		mapper_set_device_keys(RETRO_DEVICE_ID_JOYPAD_Y, var.value);
+	}
+
+	var.key = "scummvm_mapper_select";
+	var.value = NULL;
+	if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) {
+		mapper_set_device_keys(RETRO_DEVICE_ID_JOYPAD_SELECT, var.value);
+	}
+
+	var.key = "scummvm_mapper_start";
+	var.value = NULL;
+	if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) {
+		mapper_set_device_keys(RETRO_DEVICE_ID_JOYPAD_START, var.value);
+	}
+
+	var.key = "scummvm_mapper_l";
+	var.value = NULL;
+	if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) {
+		mapper_set_device_keys(RETRO_DEVICE_ID_JOYPAD_L, var.value);
+	}
+
+	var.key = "scummvm_mapper_r";
+	var.value = NULL;
+	if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) {
+		mapper_set_device_keys(RETRO_DEVICE_ID_JOYPAD_R, var.value);
+	}
+
+	var.key = "scummvm_mapper_l2";
+	var.value = NULL;
+	if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) {
+		mapper_set_device_keys(RETRO_DEVICE_ID_JOYPAD_L2, var.value);
+	}
+
+	var.key = "scummvm_mapper_r2";
+	var.value = NULL;
+	if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) {
+		mapper_set_device_keys(RETRO_DEVICE_ID_JOYPAD_R2, var.value);
+	}
+
+	var.key = "scummvm_mapper_l3";
+	var.value = NULL;
+	if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) {
+		mapper_set_device_keys(RETRO_DEVICE_ID_JOYPAD_L3, var.value);
+	}
+
+	var.key = "scummvm_mapper_r3";
+	var.value = NULL;
+	if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) {
+		mapper_set_device_keys(RETRO_DEVICE_ID_JOYPAD_R3, var.value);
+	}
+
+	var.key = "scummvm_mapper_lu";
+	var.value = NULL;
+	if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) {
+		mapper_set_device_keys(RETRO_DEVICE_ID_JOYPAD_LU, var.value);
+	}
+
+	var.key = "scummvm_mapper_ld";
+	var.value = NULL;
+	if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) {
+		mapper_set_device_keys(RETRO_DEVICE_ID_JOYPAD_LD, var.value);
+	}
+
+	var.key = "scummvm_mapper_ll";
+	var.value = NULL;
+	if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) {
+		mapper_set_device_keys(RETRO_DEVICE_ID_JOYPAD_LL, var.value);
+	}
+
+	var.key = "scummvm_mapper_lr";
+	var.value = NULL;
+	if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) {
+		mapper_set_device_keys(RETRO_DEVICE_ID_JOYPAD_LR, var.value);
+	}
+
+	var.key = "scummvm_mapper_ru";
+	var.value = NULL;
+	if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) {
+		mapper_set_device_keys(RETRO_DEVICE_ID_JOYPAD_RU, var.value);
+	}
+
+	var.key = "scummvm_mapper_rd";
+	var.value = NULL;
+	if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) {
+		mapper_set_device_keys(RETRO_DEVICE_ID_JOYPAD_RD, var.value);
+	}
+
+	var.key = "scummvm_mapper_rl";
+	var.value = NULL;
+	if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) {
+		mapper_set_device_keys(RETRO_DEVICE_ID_JOYPAD_RL, var.value);
+	}
+
+	var.key = "scummvm_mapper_rr";
+	var.value = NULL;
+	if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) {
+		mapper_set_device_keys(RETRO_DEVICE_ID_JOYPAD_RR, var.value);
+	}
+
 	if (!(audio_status & AUDIO_STATUS_BUFFER_SUPPORT)) {
 		if (frameskip_type > 1) {
 			retro_log_cb(RETRO_LOG_WARN, "Selected frameskip mode not available.\n");
@@ -347,12 +490,11 @@ static void retro_set_options_display(void) {
 
 static bool retro_update_display(void) {
 	if (updating_variables)
-	return false;
+		return false;
 
 	/* Core options */
 	bool updated = false;
-	if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE, &updated) && updated)
-	{
+	if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE, &updated) && updated) {
 		update_variables();
 		LIBRETRO_G_SYSTEM->refreshRetroSettings();
 		retro_set_options_display();
@@ -360,7 +502,7 @@ static bool retro_update_display(void) {
 	return updated;
 }
 
-bool retro_setting_get_timing_inaccuracies_enabled(){
+bool retro_setting_get_timing_inaccuracies_enabled() {
 	if (performance_switch & PERF_SWITCH_ON)
 		return (performance_switch & PERF_SWITCH_ENABLE_TIMING_INACCURACIES);
 	else
@@ -391,6 +533,10 @@ float retro_setting_get_frame_rate(void) {
 	return frame_rate;
 }
 
+bool retro_get_input_bitmask_supported(void) {
+	return input_bitmask_supported;
+}
+
 uint16 retro_setting_get_sample_rate(void) {
 	return sample_rate;
 }
@@ -529,8 +675,8 @@ void retro_set_environment(retro_environment_t cb) {
 	environ_cb = cb;
 	bool tmp = true;
 	bool has_categories;
-
 	environ_cb(RETRO_ENVIRONMENT_SET_SUPPORT_NO_GAME, &tmp);
+	libretro_fill_options_mapper_data(environ_cb);
 	libretro_set_core_options(environ_cb, &has_categories);
 
 	/* Core option display callback */
@@ -567,7 +713,7 @@ void retro_get_system_av_info(struct retro_system_av_info *info) {
 	info->timing.sample_rate = sample_rate;
 }
 
-const char * retro_get_system_dir(void){
+const char *retro_get_system_dir(void) {
 	const char *sysdir;
 	const char *coredir;
 
@@ -582,7 +728,7 @@ const char * retro_get_system_dir(void){
 	}
 }
 
-const char * retro_get_save_dir(void){
+const char *retro_get_save_dir(void) {
 	const char *savedir;
 	const char *coredir;
 
@@ -605,7 +751,7 @@ void retro_init(void) {
 	else
 		retro_log_cb = NULL;
 
-	retro_log_cb(RETRO_LOG_DEBUG, "ScummVM core version: %s\n",__GIT_VERSION);
+	retro_log_cb(RETRO_LOG_DEBUG, "ScummVM core version: %s\n", __GIT_VERSION);
 
 	struct retro_audio_buffer_status_callback buf_status_cb;
 	buf_status_cb.callback = retro_audio_buff_status_cb;
@@ -619,7 +765,7 @@ void retro_init(void) {
 
 	environ_cb(RETRO_ENVIRONMENT_SET_INPUT_DESCRIPTORS, retro_input_desc);
 
-	environ_cb(RETRO_ENVIRONMENT_SET_CONTROLLER_INFO, (void*)retro_controller_lists);
+	environ_cb(RETRO_ENVIRONMENT_SET_CONTROLLER_INFO, (void *)retro_controller_lists);
 
 	/* Get color mode: 32 first as VGA has 6 bits per pixel */
 #if 0
@@ -640,6 +786,9 @@ void retro_init(void) {
 	retro_keyboard_callback cb = {LIBRETRO_G_SYSTEM->processKeyEvent};
 	environ_cb(RETRO_ENVIRONMENT_SET_KEYBOARD_CALLBACK, &cb);
 
+	if (environ_cb(RETRO_ENVIRONMENT_GET_INPUT_BITMASKS, NULL))
+		input_bitmask_supported = true;
+
 	g_system = new OSystem_libretro();
 }
 
@@ -779,13 +928,13 @@ bool retro_load_game_special(unsigned game_type, const struct retro_game_info *i
 }
 
 void retro_run(void) {
-	if (audio_status & AUDIO_STATUS_UPDATE_AV_INFO){
+	if (audio_status & AUDIO_STATUS_UPDATE_AV_INFO) {
 		struct retro_system_av_info info;
 		retro_get_system_av_info(&info);
-		environ_cb(RETRO_ENVIRONMENT_SET_SYSTEM_AV_INFO , &info);
+		environ_cb(RETRO_ENVIRONMENT_SET_SYSTEM_AV_INFO, &info);
 	}
 
-	if (audio_status & AUDIO_STATUS_UPDATE_LATENCY){
+	if (audio_status & AUDIO_STATUS_UPDATE_LATENCY) {
 		uint32 audio_latency;
 		float frame_time_msec = 1000.0f / frame_rate;
 
@@ -799,7 +948,7 @@ void retro_run(void) {
 		audio_status &= ~AUDIO_STATUS_UPDATE_LATENCY;
 	}
 
-	if (audio_status & AUDIO_STATUS_UPDATE_AV_INFO){
+	if (audio_status & AUDIO_STATUS_UPDATE_AV_INFO) {
 		audio_status &= ~AUDIO_STATUS_UPDATE_AV_INFO;
 		retro_reset();
 		return;
@@ -897,7 +1046,7 @@ void retro_run(void) {
 		} while (LIBRETRO_G_SYSTEM->getThreadSwitchCaller() & THREAD_SWITCH_UPDATE);
 
 		poll_cb();
-		LIBRETRO_G_SYSTEM->processMouse();
+		LIBRETRO_G_SYSTEM->processInputs();
 	}
 }
 


Commit: 524c270ded9e05be6b012d688ab156588dce2f32
    https://github.com/scummvm/scummvm/commit/524c270ded9e05be6b012d688ab156588dce2f32
Author: Giovanni Cascione (ing.cascione at gmail.com)
Date: 2023-09-09T00:36:12+02:00

Commit Message:
LIBRETRO: fix settings descriptions w/o categories

Changed paths:
    backends/platform/libretro/include/libretro-core-options-intl.h
    backends/platform/libretro/include/libretro-core-options.h


diff --git a/backends/platform/libretro/include/libretro-core-options-intl.h b/backends/platform/libretro/include/libretro-core-options-intl.h
index 9b11d5b34b1..7edb9653fb8 100644
--- a/backends/platform/libretro/include/libretro-core-options-intl.h
+++ b/backends/platform/libretro/include/libretro-core-options-intl.h
@@ -96,8 +96,8 @@ struct retro_core_option_v2_category option_cats_it[] = {
 struct retro_core_option_v2_definition option_defs_it[] = {
 	{
 		"scummvm_gamepad_cursor_speed",
+		"Cursore > Velocità del cursore",
 		"Velocità del cursore",
-		NULL,
 		"Moltiplicatore della velocità del cursore del mouse quando si usa la leva analogica sinistra o il D-Pad del RetroPad. Il valore di default di '1.0' è ottimizzato per i giochi con risoluzione nativa di '320x200' o '320x240'. Per i giochi ad 'alta definizione' con risoluzione di '640x400' or '640x480', si raccomanda il valore di '2.0'",
 		NULL,
 		NULL,
@@ -108,8 +108,8 @@ struct retro_core_option_v2_definition option_defs_it[] = {
 	},
 	{
 		"scummvm_gamepad_cursor_acceleration_time",
+		"Cursore > Accelerazione del cursore",
 		"Accelerazione del cursore",
-		NULL,
 		"Il tempo (in secondi) necessario al cursore del mouse per raggiungere la piena velocità quando si usa la leva analogica sinistra o il D-Pad del RetroPad.",
 		NULL,
 		NULL,
@@ -120,8 +120,8 @@ struct retro_core_option_v2_definition option_defs_it[] = {
 	},
 	{
 		"scummvm_analog_response",
+		"Cursore > Risposta analogica del cursore",
 		"Risposta analogica del cursore",
-		NULL,
 		"Modalità di risposta della velocità del cursore del mouse allo spostamento della leva analogica sinistra del RetroPad. 'Lineare': La velocità è direttamente proporzionale allo spostamento della leva. Questa è l'impostazione di default adatta alla maggior parte degli utenti. 'Quadratica': La velocità aumenta con il quadrato dello spostamento della leva. Questo permette maggior precisione nei piccoli movimenti senza sacrificare il raggiungimento della velocità massima a spostamento completo. Questa modalità può richiedere pratica per un uso efficace.",
 		NULL,
 		NULL,
@@ -134,8 +134,8 @@ struct retro_core_option_v2_definition option_defs_it[] = {
 	},
 	{
 		"scummvm_analog_deadzone",
+		"Cursore > Zona morta analogica (percentuale)",
 		"Zona morta analogica (percentuale)",
-		NULL,
 		"Zona morta della leva analogica sinistra del RetroPad. Può essere usata per eliminare scorrimenti indesiderati del cursore.",
 		NULL,
 		NULL,
@@ -146,8 +146,8 @@ struct retro_core_option_v2_definition option_defs_it[] = {
 	},
 	{
 		"scummvm_mouse_speed",
+		"Cursore > Velocità del mouse",
 		"Velocità del mouse",
-		NULL,
 		"Moltiplicatore della velocità del cursore del mouse quando si usa RetroMouse.",
 		NULL,
 		NULL,
@@ -158,11 +158,11 @@ struct retro_core_option_v2_definition option_defs_it[] = {
 	},
 	{
 		"scummvm_frameskip_type",
+		"Frameskip > Salto dei fotogrammi",
 		"Salto dei fotogrammi",
-		NULL,
 		"Salto dei fotogrammi per evitare buffer under-run audio (crackling). Migliora le prestazioni a discapito della fluidità video. 'Auto' salta i fotogrammi su indicazione del frontend, 'Soglia' usa l'impostazione di 'Soglia minima buffer audio (%)', 'Fisso' usa l'impostazione 'Salto dei fotogrammi fisso'.",
 		NULL,
-		"frameskip",
+		NULL,
 		{
 			{ "disabled", NULL },
 			{ "fixed", "Fisso" },
@@ -174,11 +174,11 @@ struct retro_core_option_v2_definition option_defs_it[] = {
 	},
 	{
 		"scummvm_frameskip_threshold",
+		"Frameskip > Soglia minima buffer audio (%)",
 		"Soglia minima buffer audio (%)",
-		NULL,
 		"Quando 'Salto dei fotogrammi' è impostato su 'Soglia', specifica la soglia minima del buffer audio al di sotto della quale il fotogramma viene saltato. Valori più alti riducono il rischio di crackling al costo di un salto di fotogrammi più frequente.",
 		NULL,
-		"frameskip",
+		NULL,
 		{
 			{ NULL, NULL },
 		},
@@ -186,11 +186,11 @@ struct retro_core_option_v2_definition option_defs_it[] = {
 	},
 	{
 		"scummvm_frameskip_no",
+		"Frameskip > Salto dei fotogrammi fisso",
 		"Salto dei fotogrammi fisso",
-		NULL,
 		"Quando la modalità di 'Salto dei fotogrammi' è 'Fisso', o il frontend non supporta una delle altre modalità selezionate, salta costantemente X fotogrammi ogni X+1.",
 		NULL,
-		"frameskip",
+		NULL,
 		{
 			{ "0", "Nessun fotogramma saltato" },
 			{ "1", "Salto di 1 fotogramma su 2" },
@@ -204,8 +204,8 @@ struct retro_core_option_v2_definition option_defs_it[] = {
 	},
 	{
 		"scummvm_allow_timing_inaccuracies",
+		"Timing > Consenti inaccuratezze di timing",
 		"Consenti inaccuratezze di timing",
-		NULL,
 		"Consente inaccuratezze di timing che riducono significativamente le richeste di CPU. Anche se la maggior parte delle inaccuratezze sono impercettibili, in alcuni casi potrebbe introdurre problemi di sincronizzazione audio, quindi questa opzione andrebbe abilitata solo se il raggiungimento della piena velocità non è possibile in altro modo.",
 		NULL,
 		NULL,
@@ -217,11 +217,11 @@ struct retro_core_option_v2_definition option_defs_it[] = {
 
 	{
 		"scummvm_framerate",
+		"Timing > Tetto frequenza dei fotogrammi",
 		"Tetto frequenza dei fotogrammi",
-		NULL,
 		"Imposta il limite superiore della frequenza dei fotogrammi. Il cambio di questa impostazione causerà il reset del core.",
 		NULL,
-		"timing",
+		NULL,
 		{
 			{ NULL, NULL },
 		},
@@ -229,11 +229,11 @@ struct retro_core_option_v2_definition option_defs_it[] = {
 	},
 	{
 		"scummvm_samplerate",
+		"Timing > Frequenza di campionamento",
 		"Frequenza di campionamento",
-		NULL,
 		"Imposta la frequenza di campionamento. Il cambio di questa impostazione causerà il reset del core.",
 		NULL,
-		"timing",
+		NULL,
 		{
 			{ NULL, NULL },
 		},
@@ -246,7 +246,7 @@ struct retro_core_option_v2_definition option_defs_it[] = {
 		"Su",
 		NULL,
 		NULL,
-		"retropad",
+		NULL,
 		{
 			{ NULL, NULL }
 		},
@@ -258,7 +258,7 @@ struct retro_core_option_v2_definition option_defs_it[] = {
 		"Giù",
 		NULL,
 		NULL,
-		"retropad",
+		NULL,
 		{
 			{ NULL, NULL }
 		},
@@ -270,7 +270,7 @@ struct retro_core_option_v2_definition option_defs_it[] = {
 		"Sinistra",
 		NULL,
 		NULL,
-		"retropad",
+		NULL,
 		{
 			{ NULL, NULL }
 		},
@@ -282,7 +282,7 @@ struct retro_core_option_v2_definition option_defs_it[] = {
 		"Destra",
 		NULL,
 		NULL,
-		"retropad",
+		NULL,
 		{
 			{ NULL, NULL }
 		},
@@ -294,7 +294,7 @@ struct retro_core_option_v2_definition option_defs_it[] = {
 		"A",
 		NULL,
 		NULL,
-		"retropad",
+		NULL,
 		{
 			{ NULL, NULL }
 		},
@@ -306,7 +306,7 @@ struct retro_core_option_v2_definition option_defs_it[] = {
 		"B",
 		NULL,
 		NULL,
-		"retropad",
+		NULL,
 		{
 			{ NULL, NULL }
 		},
@@ -318,7 +318,7 @@ struct retro_core_option_v2_definition option_defs_it[] = {
 		"X",
 		NULL,
 		NULL,
-		"retropad",
+		NULL,
 		{
 			{ NULL, NULL }
 		},
@@ -330,7 +330,7 @@ struct retro_core_option_v2_definition option_defs_it[] = {
 		"Y",
 		NULL,
 		NULL,
-		"retropad",
+		NULL,
 		{
 			{ NULL, NULL }
 		},
@@ -342,7 +342,7 @@ struct retro_core_option_v2_definition option_defs_it[] = {
 		"Select",
 		NULL,
 		NULL,
-		"retropad",
+		NULL,
 		{
 			{ NULL, NULL }
 		},
@@ -354,7 +354,7 @@ struct retro_core_option_v2_definition option_defs_it[] = {
 		"Start",
 		NULL,
 		NULL,
-		"retropad",
+		NULL,
 		{
 			{ NULL, NULL }
 		},
@@ -366,7 +366,7 @@ struct retro_core_option_v2_definition option_defs_it[] = {
 		"L",
 		NULL,
 		NULL,
-		"retropad",
+		NULL,
 		{
 			{ NULL, NULL }
 		},
@@ -378,7 +378,7 @@ struct retro_core_option_v2_definition option_defs_it[] = {
 		"R",
 		NULL,
 		NULL,
-		"retropad",
+		NULL,
 		{
 			{ NULL, NULL }
 		},
@@ -390,7 +390,7 @@ struct retro_core_option_v2_definition option_defs_it[] = {
 		"L2",
 		NULL,
 		NULL,
-		"retropad",
+		NULL,
 		{
 			{ NULL, NULL }
 		},
@@ -402,7 +402,7 @@ struct retro_core_option_v2_definition option_defs_it[] = {
 		"R2",
 		NULL,
 		NULL,
-		"retropad",
+		NULL,
 		{
 			{ NULL, NULL }
 		},
@@ -414,7 +414,7 @@ struct retro_core_option_v2_definition option_defs_it[] = {
 		"L3",
 		NULL,
 		NULL,
-		"retropad",
+		NULL,
 		{
 			{ NULL, NULL }
 		},
@@ -426,7 +426,7 @@ struct retro_core_option_v2_definition option_defs_it[] = {
 		"R3",
 		NULL,
 		NULL,
-		"retropad",
+		NULL,
 		{
 			{ NULL, NULL }
 		},
@@ -439,7 +439,7 @@ struct retro_core_option_v2_definition option_defs_it[] = {
 		"Leva Analogica Sinistra > Su",
 		NULL,
 		NULL,
-		"retropad",
+		NULL,
 		{
 			{ NULL, NULL }
 		},
@@ -451,7 +451,7 @@ struct retro_core_option_v2_definition option_defs_it[] = {
 		"Leva Analogica Sinistra > Giù",
 		NULL,
 		NULL,
-		"retropad",
+		NULL,
 		{
 			{ NULL, NULL }
 		},
@@ -463,7 +463,7 @@ struct retro_core_option_v2_definition option_defs_it[] = {
 		"Leva Analogica Sinistra > Sinistra",
 		NULL,
 		NULL,
-		"retropad",
+		NULL,
 		{
 			{ NULL, NULL }
 		},
@@ -475,7 +475,7 @@ struct retro_core_option_v2_definition option_defs_it[] = {
 		"Leva Analogica Sinistra > Destra",
 		NULL,
 		NULL,
-		"retropad",
+		NULL,
 		{
 			{ NULL, NULL }
 		},
@@ -488,7 +488,7 @@ struct retro_core_option_v2_definition option_defs_it[] = {
 		"Leva Analogica Destra > Su",
 		NULL,
 		NULL,
-		"retropad",
+		NULL,
 		{
 			{ NULL, NULL }
 		},
@@ -500,7 +500,7 @@ struct retro_core_option_v2_definition option_defs_it[] = {
 		"Leva Analogica Destra > Giù",
 		NULL,
 		NULL,
-		"retropad",
+		NULL,
 		{
 			{ NULL, NULL }
 		},
@@ -512,7 +512,7 @@ struct retro_core_option_v2_definition option_defs_it[] = {
 		"Leva Analogica Destra > Sinistra",
 		NULL,
 		NULL,
-		"retropad",
+		NULL,
 		{
 			{ NULL, NULL }
 		},
@@ -524,7 +524,7 @@ struct retro_core_option_v2_definition option_defs_it[] = {
 		"Leva Analogica Destra > Destra",
 		NULL,
 		NULL,
-		"retropad",
+		NULL,
 		{
 			{ NULL, NULL }
 		},
diff --git a/backends/platform/libretro/include/libretro-core-options.h b/backends/platform/libretro/include/libretro-core-options.h
index 86e95a5f631..d4b5134c6cd 100644
--- a/backends/platform/libretro/include/libretro-core-options.h
+++ b/backends/platform/libretro/include/libretro-core-options.h
@@ -98,8 +98,8 @@ struct retro_core_option_v2_category option_cats_us[] = {
 struct retro_core_option_v2_definition option_defs_us[] = {
 	{
 		"scummvm_gamepad_cursor_speed",
+		"Cursor > Gamepad Cursor Speed",
 		"Gamepad Cursor Speed",
-		NULL,
 		"Sets the mouse cursor speed multiplier when moving the cursor with the RetroPad left analog stick or D-Pad. The default value of '1.0' is optimised for games that have a native resolution of '320x200' or '320x240'. When running 'high definition' games with a resolution of '640x400' or '640x480', a Gamepad Cursor Speed of '2.0' is recommended.",
 		NULL,
 		"cursor",
@@ -118,8 +118,8 @@ struct retro_core_option_v2_definition option_defs_us[] = {
 	},
 	{
 		"scummvm_gamepad_cursor_acceleration_time",
+		"Cursor > Gamepad Cursor Acceleration",
 		"Gamepad Cursor Acceleration",
-		NULL,
 		"The amount of time (In seconds) it takes for the cursor to reach full speed",
 		NULL,
 		"cursor",
@@ -141,8 +141,8 @@ struct retro_core_option_v2_definition option_defs_us[] = {
 	},
 	{
 		"scummvm_analog_response",
+		"Cursor > Analog Cursor Response",
 		"Analog Cursor Response",
-		NULL,
 		"Determines how the speed of the cursor varies when tilting the RetroPad left analog stick. 'Linear': Speed is directly proportional to analog stick displacement. This is standard behaviour with which most users will be familiar. 'Quadratic': Speed increases quadratically with analog stick displacement. This allows for greater precision when making small movements without sacrificing maximum speed at full analog range. This mode may require practice for effective use.",
 		NULL,
 		"cursor",
@@ -155,8 +155,8 @@ struct retro_core_option_v2_definition option_defs_us[] = {
 	},
 	{
 		"scummvm_analog_deadzone",
+		"Cursor > Analog Deadzone (Percent)",
 		"Analog Deadzone (Percent)",
-		NULL,
 		"Sets the deadzone of the RetroPad analog sticks. Used to eliminate cursor drift/unwanted input.",
 		NULL,
 		"cursor",
@@ -174,8 +174,8 @@ struct retro_core_option_v2_definition option_defs_us[] = {
 	},
 	{
 		"scummvm_mouse_speed",
+		"Cursor > Mouse Speed",
 		"Mouse Speed",
-		NULL,
 		"Sets the mouse cursor speed multiplier when moving the cursor with the RetroMouse.",
 		NULL,
 		"cursor",
@@ -207,8 +207,8 @@ struct retro_core_option_v2_definition option_defs_us[] = {
 	},
 	{
 		"scummvm_frameskip_type",
+		"Frameskip > Frameskip Mode",
 		"Frameskip Mode",
-		NULL,
 		"Skip frames to avoid audio buffer under-run (crackling). Improves performance at the expense of visual smoothness. 'Auto' skips frames when advised by the frontend. 'Threshold' uses the 'Frameskip Threshold (%)' setting. 'Fixed' uses the 'Fixed Frameskip' setting.",
 		NULL,
 		"frameskip",
@@ -223,8 +223,8 @@ struct retro_core_option_v2_definition option_defs_us[] = {
 	},
 	{
 		"scummvm_frameskip_threshold",
+		"Frameskip > Frameskip Threshold (%)",
 		"Frameskip Threshold (%)",
-		NULL,
 		"When 'Frameskip' is set to 'Threshold', specifies the audio buffer occupancy threshold (percentage) below which frames will be skipped. Higher values reduce the risk of crackling by causing frames to be dropped more frequently.",
 		NULL,
 		"frameskip",
@@ -251,8 +251,8 @@ struct retro_core_option_v2_definition option_defs_us[] = {
 	},
 	{
 		"scummvm_frameskip_no",
+		"Frameskip > Fixed Frameskip",
 		"Fixed Frameskip",
-		NULL,
 		"When 'Frameskip' is set to 'Fixed', or if the frontend doesn't support the alternative 'Frameskip' mode, skip rendering at a fixed rate of X frames out of X+1",
 		NULL,
 		"frameskip",
@@ -269,8 +269,8 @@ struct retro_core_option_v2_definition option_defs_us[] = {
 	},
 	{
 		"scummvm_allow_timing_inaccuracies",
+		"Timing > Allow Timing Inaccuracies",
 		"Allow Timing Inaccuracies",
-		NULL,
 		"Allow timing inaccuracies that reduces CPU requirements. Though most timing deviations are imperceptible, in some cases it may introduce audio sync/timing issues, hence this option should be enabled only if full speed cannot be reached otherwise.",
 		NULL,
 		"timing",
@@ -283,8 +283,8 @@ struct retro_core_option_v2_definition option_defs_us[] = {
 	},
 	{
 		"scummvm_framerate",
+		"Timing > Frame rate cap",
 		"Frame rate cap",
-		NULL,
 		"Set core frame rate upper limit. Changing this setting will reset the core.",
 		NULL,
 		"timing",
@@ -300,8 +300,8 @@ struct retro_core_option_v2_definition option_defs_us[] = {
 	},
 	{
 		"scummvm_samplerate",
+		"Timing > Sample rate",
 		"Sample rate",
-		NULL,
 		"Set core sample rate. Changing this setting will reset the core.",
 		NULL,
 		"timing",


Commit: da563c7bf4623f68297acfa39e4925ff03374874
    https://github.com/scummvm/scummvm/commit/da563c7bf4623f68297acfa39e4925ff03374874
Author: Giovanni Cascione (ing.cascione at gmail.com)
Date: 2023-09-09T00:36:13+02:00

Commit Message:
LIBRETRO: cover settings update following reset to defaults

Changed paths:
    backends/platform/libretro/src/libretro.cpp


diff --git a/backends/platform/libretro/src/libretro.cpp b/backends/platform/libretro/src/libretro.cpp
index e246f9e3be0..cf3ddf4d270 100644
--- a/backends/platform/libretro/src/libretro.cpp
+++ b/backends/platform/libretro/src/libretro.cpp
@@ -482,13 +482,12 @@ static void retro_set_options_display(void) {
 	option_display.key = "scummvm_frameskip_threshold";
 	environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS_DISPLAY, &option_display);
 
-
 	option_display.visible = opt_frameskip_no_display;
 	option_display.key = "scummvm_frameskip_no";
 	environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS_DISPLAY, &option_display);
 }
 
-static bool retro_update_display(void) {
+static bool retro_update_options_display(void) {
 	if (updating_variables)
 		return false;
 
@@ -680,7 +679,7 @@ void retro_set_environment(retro_environment_t cb) {
 	libretro_set_core_options(environ_cb, &has_categories);
 
 	/* Core option display callback */
-	struct retro_core_options_update_display_callback update_display_callback = {retro_update_display};
+	struct retro_core_options_update_display_callback update_display_callback = {retro_update_options_display};
 	environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS_UPDATE_DISPLAY_CALLBACK, &update_display_callback);
 }
 
@@ -928,6 +927,10 @@ bool retro_load_game_special(unsigned game_type, const struct retro_game_info *i
 }
 
 void retro_run(void) {
+	/* Settings change is covered by RETRO_ENVIRONMENT_SET_CORE_OPTIONS_UPDATE_DISPLAY_CALLBACK
+	except in case of core options reset to defaults, for which the following call is needed*/
+	retro_update_options_display();
+
 	if (audio_status & AUDIO_STATUS_UPDATE_AV_INFO) {
 		struct retro_system_av_info info;
 		retro_get_system_av_info(&info);


Commit: b486ca68814bb5a9baddc5f74accb74b313a7742
    https://github.com/scummvm/scummvm/commit/b486ca68814bb5a9baddc5f74accb74b313a7742
Author: Giovanni Cascione (ing.cascione at gmail.com)
Date: 2023-09-09T00:36:14+02:00

Commit Message:
LIBRETRO: use cpu_features_get_time_usec to get current time

Changed paths:
  A backends/platform/libretro/include/wiiu/os/thread.h
  A backends/platform/libretro/include/wiiu/os/time.h
  A backends/platform/libretro/include/wiiu/types.h
    backends/platform/libretro/Makefile
    backends/platform/libretro/dependencies.mk
    backends/platform/libretro/include/libretro-os.h
    backends/platform/libretro/src/libretro-os-base.cpp
    backends/platform/libretro/src/libretro-os-events.cpp
    backends/platform/libretro/src/libretro-os-utils.cpp


diff --git a/backends/platform/libretro/Makefile b/backends/platform/libretro/Makefile
index 34e0c4bd967..3693e27c208 100644
--- a/backends/platform/libretro/Makefile
+++ b/backends/platform/libretro/Makefile
@@ -156,7 +156,7 @@ else ifeq ($(platform), wiiu)
    CXX = $(DEVKITPPC)/bin/powerpc-eabi-g++$(EXE_EXT)
    AR = $(DEVKITPPC)/bin/powerpc-eabi-ar$(EXE_EXT) rcs
    AR_ALONE = $(DEVKITPPC)/bin/powerpc-eabi-ar$(EXE_EXT)
-   DEFINES += -DGEKKO -mwup -mcpu=750 -meabi -mhard-float -D__POWERPC__ -D__ppc__ -DRETRO_IS_BIG_ENDIAN=1 -DRETRO_IS_LITTLE_ENDIAN=0 -DWORDS_BIGENDIAN=1
+   DEFINES += -mwup -mcpu=750 -meabi -mhard-float -D__POWERPC__ -D__ppc__ -DRETRO_IS_BIG_ENDIAN=1 -DRETRO_IS_LITTLE_ENDIAN=0 -DWORDS_BIGENDIAN=1
    DEFINES += -U__INT32_TYPE__ -U __UINT32_TYPE__ -D__INT32_TYPE__=int
    DEFINES += -DHAVE_STRTOUL -DWIIU
    CXXFLAGS := -fpermissive
diff --git a/backends/platform/libretro/dependencies.mk b/backends/platform/libretro/dependencies.mk
index 9951009aec2..f28ea005ddc 100644
--- a/backends/platform/libretro/dependencies.mk
+++ b/backends/platform/libretro/dependencies.mk
@@ -43,7 +43,9 @@ OBJS_DEPS += $(DEPS_PATH)/$(DEPS_FOLDER_libretro-common)/file/file_path_io.o \
 	$(DEPS_PATH)/$(DEPS_FOLDER_libretro-common)/vfs/vfs_implementation.o \
 	$(DEPS_PATH)/$(DEPS_FOLDER_libretro-common)/string/stdstring.o \
 	$(DEPS_PATH)/$(DEPS_FOLDER_libretro-common)/time/rtime.o \
-	$(DEPS_PATH)/$(DEPS_FOLDER_libretro-common)/streams/file_stream.o
+	$(DEPS_PATH)/$(DEPS_FOLDER_libretro-common)/streams/file_stream.o \
+	$(DEPS_PATH)/$(DEPS_FOLDER_libretro-common)/features/features_cpu.o
+
 
 ifeq ($(USE_LIBCO), 1)
 OBJS_DEPS += $(DEPS_PATH)/$(DEPS_FOLDER_libretro-common)/libco/libco.o
diff --git a/backends/platform/libretro/include/libretro-os.h b/backends/platform/libretro/include/libretro-os.h
index 7bca55718f8..5406221472f 100644
--- a/backends/platform/libretro/include/libretro-os.h
+++ b/backends/platform/libretro/include/libretro-os.h
@@ -18,6 +18,7 @@
 #define BACKENDS_LIBRETRO_OS_H
 
 #include <libretro.h>
+#include <features/features_cpu.h>
 #include <retro_miscellaneous.h>
 
 #include "audio/mixer_intern.h"
diff --git a/backends/platform/libretro/include/wiiu/os/thread.h b/backends/platform/libretro/include/wiiu/os/thread.h
new file mode 100644
index 00000000000..a545185c60a
--- /dev/null
+++ b/backends/platform/libretro/include/wiiu/os/thread.h
@@ -0,0 +1,277 @@
+#pragma once
+#include <wiiu/types.h>
+#include "time.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct OSThread OSThread;
+
+typedef int (*OSThreadEntryPointFn)(int argc, const char **argv);
+typedef void (*OSThreadCleanupCallbackFn)(OSThread *thread, void *stack);
+typedef void (*OSThreadDeallocatorFn)(OSThread *thread, void *stack);
+
+enum OS_THREAD_STATE
+{
+   OS_THREAD_STATE_NONE             = 0,
+
+   /*! Thread is ready to run */
+   OS_THREAD_STATE_READY            = 1 << 0,
+
+   /*! Thread is running */
+   OS_THREAD_STATE_RUNNING          = 1 << 1,
+
+   /*! Thread is waiting, i.e. on a mutex */
+   OS_THREAD_STATE_WAITING          = 1 << 2,
+
+   /*! Thread is about to terminate */
+   OS_THREAD_STATE_MORIBUND         = 1 << 3,
+};
+typedef uint8_t OSThreadState;
+
+enum OS_THREAD_REQUEST
+{
+   OS_THREAD_REQUEST_NONE           = 0,
+   OS_THREAD_REQUEST_SUSPEND        = 1,
+   OS_THREAD_REQUEST_CANCEL         = 2,
+};
+typedef uint32_t OSThreadRequest;
+
+enum OS_THREAD_ATTRIB
+{
+   /*! Allow the thread to run on CPU0. */
+   OS_THREAD_ATTRIB_AFFINITY_CPU0   = 1 << 0,
+
+   /*! Allow the thread to run on CPU1. */
+   OS_THREAD_ATTRIB_AFFINITY_CPU1   = 1 << 1,
+
+   /*! Allow the thread to run on CPU2. */
+   OS_THREAD_ATTRIB_AFFINITY_CPU2   = 1 << 2,
+
+   /*! Allow the thread to run any CPU. */
+   OS_THREAD_ATTRIB_AFFINITY_ANY    = ((1 << 0) | (1 << 1) | (1 << 2)),
+
+   /*! Start the thread detached. */
+   OS_THREAD_ATTRIB_DETACHED        = 1 << 3,
+
+   /*! Enables tracking of stack usage. */
+   OS_THREAD_ATTRIB_STACK_USAGE     = 1 << 5
+};
+typedef uint8_t OSThreadAttributes;
+
+#define OS_CONTEXT_TAG 0x4F53436F6E747874ull
+
+typedef struct OSContext
+{
+   /*! Should always be set to the value OS_CONTEXT_TAG. */
+   uint64_t tag;
+
+   uint32_t gpr[32];
+   uint32_t cr;
+   uint32_t lr;
+   uint32_t ctr;
+   uint32_t xer;
+   uint32_t srr0;
+   uint32_t srr1;
+   uint32_t __unknown[0x5];
+   uint32_t fpscr;
+   double fpr[32];
+   uint16_t spinLockCount;
+   uint16_t state;
+   uint32_t gqr[8];
+   uint32_t __unknown0;
+   double psf[32];
+   uint64_t coretime[3];
+   uint64_t starttime;
+   uint32_t error;
+   uint32_t __unknown1;
+   uint32_t pmc1;
+   uint32_t pmc2;
+   uint32_t pmc3;
+   uint32_t pmc4;
+   uint32_t mmcr0;
+   uint32_t mmcr1;
+} OSContext;
+
+typedef struct OSMutex OSMutex;
+typedef struct OSFastMutex OSFastMutex;
+
+typedef struct OSMutexQueue
+{
+   OSMutex *head;
+   OSMutex *tail;
+   void *parent;
+   uint32_t __unknown;
+} OSMutexQueue;
+
+typedef struct OSFastMutexQueue
+{
+   OSFastMutex *head;
+   OSFastMutex *tail;
+} OSFastMutexQueue;
+
+typedef struct
+{
+   OSThread *prev;
+   OSThread *next;
+} OSThreadLink;
+
+typedef struct
+{
+   OSThread *head;
+   OSThread *tail;
+   void *parent;
+   uint32_t __unknown;
+} OSThreadQueue;
+
+typedef struct
+{
+   OSThread *head;
+   OSThread *tail;
+} OSThreadSimpleQueue;
+
+#define OS_THREAD_TAG 0x74487244u
+#pragma pack(push, 1)
+typedef struct __attribute__ ((aligned (8))) OSThread
+{
+   OSContext context;
+
+   /*! Should always be set to the value OS_THREAD_TAG. */
+   uint32_t tag;
+
+   /*! Bitfield of OS_THREAD_STATE */
+   OSThreadState state;
+
+   /*! Bitfield of OS_THREAD_ATTRIB */
+   OSThreadAttributes attr;
+
+   /*! Unique thread ID */
+   uint16_t id;
+
+   /*! Suspend count (increased by OSSuspendThread). */
+   int32_t suspendCounter;
+
+   /*! Actual priority of thread. */
+   int32_t priority;
+
+   /*! Base priority of thread, 0 is highest priority, 31 is lowest priority. */
+   int32_t basePriority;
+
+   /*! Exit value */
+   int32_t exitValue;
+
+   uint32_t unknown0[0x9];
+
+   /*! Queue the thread is currently waiting on */
+   OSThreadQueue *queue;
+
+   /*! Link used for thread queue */
+   OSThreadLink link;
+
+   /*! Queue of threads waiting to join this thread */
+   OSThreadQueue joinQueue;
+
+   /*! Mutex this thread is waiting to lock */
+   OSMutex *mutex;
+
+   /*! Queue of mutexes this thread owns */
+   OSMutexQueue mutexQueue;
+
+   /*! Link for global active thread queue */
+   OSThreadLink activeLink;
+
+   /*! Stack start (top, highest address) */
+   void *stackStart;
+
+   /*! Stack end (bottom, lowest address) */
+   void *stackEnd;
+
+   /*! Thread entry point */
+   OSThreadEntryPointFn entryPoint;
+
+   uint32_t unknown1[0x77];
+
+   /*! Thread specific values, accessed with OSSetThreadSpecific and OSGetThreadSpecific. */
+   uint32_t specific[0x10];
+
+   uint32_t unknown2;
+
+   /*! Thread name, accessed with OSSetThreadName and OSGetThreadName. */
+   const char *name;
+
+   uint32_t unknown3;
+
+   /*! The stack pointer passed in OSCreateThread. */
+   void *userStackPointer;
+
+   /*! Called just before thread is terminated, set with OSSetThreadCleanupCallback */
+   OSThreadCleanupCallbackFn cleanupCallback;
+
+   /*! Called just after a thread is terminated, set with OSSetThreadDeallocator */
+   OSThreadDeallocatorFn deallocator;
+
+   /*! If TRUE then a thread can be cancelled or suspended, set with OSSetThreadCancelState */
+   BOOL cancelState;
+
+   /*! Current thread request, used for cancelleing and suspending the thread. */
+   OSThreadRequest requestFlag;
+
+   /*! Pending suspend request count */
+   int32_t needSuspend;
+
+   /*! Result of thread suspend */
+   int32_t suspendResult;
+
+   /*! Queue of threads waiting for a thread to be suspended. */
+   OSThreadQueue suspendQueue;
+
+   uint32_t unknown4[0x2B];
+} OSThread;
+#pragma pack(pop)
+
+void
+OSCancelThread(OSThread *thread);
+int32_t OSCheckActiveThreads();
+int32_t OSCheckThreadStackUsage(OSThread *thread);
+void OSClearThreadStackUsage(OSThread *thread);
+void OSContinueThread(OSThread *thread);
+BOOL OSCreateThread(OSThread *thread, OSThreadEntryPointFn entry, int32_t argc, char *argv,
+                    void *stack, uint32_t stackSize, int32_t priority, OSThreadAttributes attributes);
+void OSDetachThread(OSThread *thread);
+void OSExitThread(int32_t result);
+void OSGetActiveThreadLink(OSThread *thread, OSThreadLink *link);
+OSThread *OSGetCurrentThread();
+OSThread *OSGetDefaultThread(uint32_t coreID);
+uint32_t OSGetStackPointer();
+uint32_t OSGetThreadAffinity(OSThread *thread);
+const char *OSGetThreadName(OSThread *thread);
+int32_t OSGetThreadPriority(OSThread *thread);
+uint32_t OSGetThreadSpecific(uint32_t id);
+BOOL OSIsThreadSuspended(OSThread *thread);
+BOOL OSIsThreadTerminated(OSThread *thread);
+BOOL OSJoinThread(OSThread *thread, int *threadResult);
+int32_t OSResumeThread(OSThread *thread);
+BOOL OSRunThread(OSThread *thread, OSThreadEntryPointFn entry, int argc, const char **argv);
+BOOL OSSetThreadAffinity(OSThread *thread, uint32_t affinity);
+BOOL OSSetThreadCancelState(BOOL state);
+OSThreadCleanupCallbackFn OSSetThreadCleanupCallback(OSThread *thread,
+      OSThreadCleanupCallbackFn callback);
+OSThreadDeallocatorFn OSSetThreadDeallocator(OSThread *thread, OSThreadDeallocatorFn deallocator);
+void OSSetThreadName(OSThread *thread, const char *name);
+BOOL OSSetThreadPriority(OSThread *thread, int32_t priority);
+BOOL OSSetThreadRunQuantum(OSThread *thread, uint32_t quantum);
+void OSSetThreadSpecific(uint32_t id, uint32_t value);
+BOOL OSSetThreadStackUsage(OSThread *thread);
+void OSSleepThread(OSThreadQueue *queue);
+void OSSleepTicks(OSTime ticks);
+uint32_t OSSuspendThread(OSThread *thread);
+void OSTestThreadCancel();
+void OSWakeupThread(OSThreadQueue *queue);
+void OSYieldThread();
+void OSInitThreadQueue(OSThreadQueue *queue);
+void OSInitThreadQueueEx(OSThreadQueue *queue, void *parent);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/backends/platform/libretro/include/wiiu/os/time.h b/backends/platform/libretro/include/wiiu/os/time.h
new file mode 100644
index 00000000000..e8ff34254a0
--- /dev/null
+++ b/backends/platform/libretro/include/wiiu/os/time.h
@@ -0,0 +1,49 @@
+#pragma once
+#include <wiiu/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define OSOneSecond ((OSGetSystemInfo()->clockSpeed) / 4)
+#define OSMilliseconds(val) ((((uint64_t)(val)) * (uint64_t)(OSOneSecond)) / 1000ull)
+#define OSMicroseconds(val) ((((uint64_t)(val)) * (uint64_t)(OSOneSecond)) / 1000000ull)
+#define OSNanoseconds(val) ((((uint64_t)(val)) * (uint64_t)(OSOneSecond)) / 1000000000ull)
+
+#define wiiu_bus_clock             (17 * 13 * 5*5*5 * 5*5*5     * 3*3 * 2*2*2) /*   248.625000 Mhz */
+#define wiiu_cpu_clock             (17 * 13 * 5*5*5 * 5*5*5 * 5 * 3*3 * 2*2*2) /*  1243.125000 Mhz */
+#define wiiu_timer_clock           (17 * 13 * 5*5*5 * 5*5*5     * 3*3 * 2)     /*    62.156250 Mhz */
+
+#define sec_to_ticks(s)          (((17 * 13 * 5*5*5 * 5*5*5 * 3*3 * 2) * (uint64_t)(s)))
+#define ms_to_ticks(ms)          (((17 * 13 * 5*5*5 * 3*3) * (uint64_t)(ms)) / (2*2))
+#define us_to_ticks(us)          (((17 * 13 * 3*3) * (uint64_t)(us)) / (2*2* 2*2*2))
+#define ns_to_ticks(ns)          (((17 * 13 * 3*3) * (uint64_t)(ns)) / (2*2* 2*2*2* 2*2*2 *5*5*5))
+
+#define ticks_to_sec(ticks)      (((uint64_t)(ticks)) / (17 * 13 * 5*5*5 * 5*5*5 * 3*3 * 2))
+#define ticks_to_ms(ticks)       (((uint64_t)(ticks) * (2*2)) / (17 * 13 * 5*5*5 * 3*3))
+#define ticks_to_us(ticks)       (((uint64_t)(ticks) * (2*2 * 2*2*2)) / (17 * 13 * 3*3))
+#define ticks_to_ns(ticks)       (((uint64_t)(ticks) * (2*2 * 2*2*2 * 2*2*2 * 5*5*5)) / (17 * 13 * 3*3))
+
+typedef int32_t OSTick;
+typedef int64_t OSTime;
+
+typedef struct
+{
+   int32_t tm_sec;
+   int32_t tm_min;
+   int32_t tm_hour;
+   int32_t tm_mday;
+   int32_t tm_mon;
+   int32_t tm_year;
+}OSCalendarTime;
+
+OSTime OSGetTime();
+OSTime OSGetSystemTime();
+OSTick OSGetTick();
+OSTick OSGetSystemTick();
+OSTime OSCalendarTimeToTicks(OSCalendarTime *calendarTime);
+void OSTicksToCalendarTime(OSTime time, OSCalendarTime *calendarTime);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/backends/platform/libretro/include/wiiu/types.h b/backends/platform/libretro/include/wiiu/types.h
new file mode 100644
index 00000000000..3927c5bb52c
--- /dev/null
+++ b/backends/platform/libretro/include/wiiu/types.h
@@ -0,0 +1,41 @@
+#pragma once
+#include <stdint.h>
+#include <stdbool.h>
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+typedef int BOOL;
+
+typedef uint8_t u8;
+typedef uint16_t u16;
+typedef uint32_t u32;
+typedef uint64_t u64;
+
+typedef int8_t s8;
+typedef int16_t s16;
+typedef int32_t s32;
+typedef int64_t s64;
+
+typedef volatile u8 vu8;
+typedef volatile u16 vu16;
+typedef volatile u32 vu32;
+typedef volatile u64 vu64;
+
+typedef volatile s8 vs8;
+typedef volatile s16 vs16;
+typedef volatile s32 vs32;
+typedef volatile s64 vs64;
+
+typedef float f32;
+typedef double f64;
+
+typedef volatile float vf32;
+typedef volatile double vf64;
+
+#define countof(array)  (sizeof(array) / sizeof(*array))
diff --git a/backends/platform/libretro/src/libretro-os-base.cpp b/backends/platform/libretro/src/libretro-os-base.cpp
index cf59cdbb352..66072898f49 100644
--- a/backends/platform/libretro/src/libretro-os-base.cpp
+++ b/backends/platform/libretro/src/libretro-os-base.cpp
@@ -43,7 +43,7 @@ OSystem_libretro::OSystem_libretro() : _mousePaletteEnabled(false), _mouseVisibl
 	s_extraDir = s_systemDir + "/" + SCUMMVM_SYSTEM_SUBDIR + "/" + SCUMMVM_EXTRA_SUBDIR;
 	s_lastDir = s_systemDir;
 
-	_startTime = getMillis();
+	_startTime = (uint32)(cpu_features_get_time_usec() / 1000);
 }
 
 OSystem_libretro::~OSystem_libretro() {
diff --git a/backends/platform/libretro/src/libretro-os-events.cpp b/backends/platform/libretro/src/libretro-os-events.cpp
index 170f14d9236..84950cfa862 100644
--- a/backends/platform/libretro/src/libretro-os-events.cpp
+++ b/backends/platform/libretro/src/libretro-os-events.cpp
@@ -18,15 +18,6 @@
 #include <unistd.h>
 #include <features/features_cpu.h>
 
-#include <sys/time.h>
-#if defined(__CELLOS_LV2__)
-#include <sys/sys_time.h>
-#elif (defined(GEKKO) && !defined(WIIU))
-#include <ogc/lwp_watchdog.h>
-#else
-#include <time.h>
-#endif
-
 #include "common/list.h"
 #include "common/events.h"
 #include "backends/platform/libretro/include/libretro-os.h"
@@ -52,18 +43,7 @@ uint8 OSystem_libretro::getThreadSwitchCaller(){
 }
 
 uint32 OSystem_libretro::getMillis(bool skipRecord) {
-#if (defined(GEKKO) && !defined(WIIU))
-	return (ticks_to_microsecs(gettime()) / 1000.0) - _startTime;
-#elif defined(WIIU)
-	return ((cpu_features_get_time_usec()) / 1000) - _startTime;
-#elif defined(__CELLOS_LV2__)
-	return (sys_time_get_system_time() / 1000.0) - _startTime;
-#else
-	struct timeval t;
-	gettimeofday(&t, 0);
-
-	return ((t.tv_sec * 1000) + (t.tv_usec / 1000)) - _startTime;
-#endif
+	return (uint32)(cpu_features_get_time_usec() / 1000) - _startTime;
 }
 
 void OSystem_libretro::delayMillis(uint msecs) {
diff --git a/backends/platform/libretro/src/libretro-os-utils.cpp b/backends/platform/libretro/src/libretro-os-utils.cpp
index ec9e945cc91..0bb44b02464 100644
--- a/backends/platform/libretro/src/libretro-os-utils.cpp
+++ b/backends/platform/libretro/src/libretro-os-utils.cpp
@@ -16,15 +16,7 @@
  */
 #define FORBIDDEN_SYMBOL_EXCEPTION_time
 
-#include <sys/time.h>
-#if defined(__CELLOS_LV2__)
-#include <sys/sys_time.h>
-#elif (defined(GEKKO) && !defined(WIIU))
-#include <ogc/lwp_watchdog.h>
-#else
-#include <time.h>
-#endif
-
+#include <features/features_cpu.h>
 #include "common/tokenizer.h"
 #include "common/config-manager.h"
 #include "base/commandLine.h"
@@ -32,7 +24,7 @@
 #include "backends/platform/libretro/include/libretro-defs.h"
 
 void OSystem_libretro::getTimeAndDate(TimeDate &t, bool skipRecord) const {
-	time_t curTime = time(NULL);
+	uint32 curTime = (uint32) (cpu_features_get_time_usec() / 1000000);
 
 #define YEAR0 1900
 #define EPOCH_YR 1970


Commit: 8431d59abde71b4ee1ad232c0fc5d94f143a847b
    https://github.com/scummvm/scummvm/commit/8431d59abde71b4ee1ad232c0fc5d94f143a847b
Author: Giovanni Cascione (ing.cascione at gmail.com)
Date: 2023-09-09T00:36:15+02:00

Commit Message:
LIBRETRO: BUILD: add debug flag

Changed paths:
    backends/platform/libretro/Makefile.common


diff --git a/backends/platform/libretro/Makefile.common b/backends/platform/libretro/Makefile.common
index d8d34b67fc2..ff8d6d0df13 100644
--- a/backends/platform/libretro/Makefile.common
+++ b/backends/platform/libretro/Makefile.common
@@ -106,7 +106,7 @@ else
 endif
 
 ifeq ($(DEBUG), 1)
-   DEFINES += -O0 -g -DLIBRETRO_DEBUG
+   DEFINES += -O0 -g -DLIBRETRO_DEBUG -DDEBUG_BUILD
 else
    DEFINES += -DDISABLE_TEXT_CONSOLE -DRELEASE_BUILD
 endif


Commit: f634443ea65b5e397ab54d350f9718ee653501ff
    https://github.com/scummvm/scummvm/commit/f634443ea65b5e397ab54d350f9718ee653501ff
Author: Giovanni Cascione (ing.cascione at gmail.com)
Date: 2023-09-09T00:36:16+02:00

Commit Message:
LIBRETRO: move log_scummvm_exit_code call

Changed paths:
    backends/platform/libretro/src/libretro.cpp


diff --git a/backends/platform/libretro/src/libretro.cpp b/backends/platform/libretro/src/libretro.cpp
index cf3ddf4d270..00dac712808 100644
--- a/backends/platform/libretro/src/libretro.cpp
+++ b/backends/platform/libretro/src/libretro.cpp
@@ -590,7 +590,6 @@ void parse_command_params(char *cmdline) {
 }
 
 static void exit_to_frontend(void) {
-	log_scummvm_exit_code();
 	environ_cb(RETRO_ENVIRONMENT_SHUTDOWN, NULL);
 }
 
@@ -794,6 +793,7 @@ void retro_init(void) {
 void retro_deinit(void) {
 	LIBRETRO_G_SYSTEM->destroy();
 	free(sound_buffer);
+	log_scummvm_exit_code();
 }
 
 void retro_set_controller_port_device(unsigned port, unsigned device) {


Commit: 1dbb8cf96af3b4b14535f0a86e6904cea8857e67
    https://github.com/scummvm/scummvm/commit/1dbb8cf96af3b4b14535f0a86e6904cea8857e67
Author: Giovanni Cascione (ing.cascione at gmail.com)
Date: 2023-09-09T00:36:17+02:00

Commit Message:
LIBREETRO: add mouse fine control speed reduction setting

Changed paths:
    backends/platform/libretro/include/libretro-core-options-intl.h
    backends/platform/libretro/include/libretro-core-options.h
    backends/platform/libretro/include/libretro-os.h
    backends/platform/libretro/src/libretro-os-inputs.cpp
    backends/platform/libretro/src/libretro.cpp


diff --git a/backends/platform/libretro/include/libretro-core-options-intl.h b/backends/platform/libretro/include/libretro-core-options-intl.h
index 7edb9653fb8..ef0c6d02d70 100644
--- a/backends/platform/libretro/include/libretro-core-options-intl.h
+++ b/backends/platform/libretro/include/libretro-core-options-intl.h
@@ -86,10 +86,10 @@ struct retro_core_option_v2_category option_cats_it[] = {
 		"Impostazioni relative al timing"
 	},
 	{
-                "retropad",
-                "Mappatura RetroPad",
-                "Configura la mappatura del RetroPad"
-        },
+		"retropad",
+		"Mappatura RetroPad",
+		"Configura la mappatura del RetroPad"
+	},
 	{ NULL, NULL, NULL },
 };
 
@@ -134,9 +134,9 @@ struct retro_core_option_v2_definition option_defs_it[] = {
 	},
 	{
 		"scummvm_analog_deadzone",
-		"Cursore > Zona morta analogica (percentuale)",
-		"Zona morta analogica (percentuale)",
-		"Zona morta della leva analogica sinistra del RetroPad. Può essere usata per eliminare scorrimenti indesiderati del cursore.",
+		"Cursore > Zona morta analogica",
+		"Zona morta analogica",
+		"Zona morta percentuale delle leve analogiche del RetroPad. Può essere usata per eliminare scorrimenti indesiderati del cursore.",
 		NULL,
 		NULL,
 		{
@@ -156,6 +156,18 @@ struct retro_core_option_v2_definition option_defs_it[] = {
 		},
 		NULL
 	},
+	{
+		"scummvm_mouse_fine_control_speed_reduction",
+		"Cursore > Riduzione velocità con controllo fine del mouse",
+		"Riduzione velocità con controllo fine del mouse",
+		"Riduzione della velocità del cursore del mouse come percentuale della velocità normale quando il controllo fine è attivato.",
+		NULL,
+		NULL,
+		{
+			{NULL, NULL},
+		},
+		NULL
+	},
 	{
 		"scummvm_frameskip_type",
 		"Frameskip > Salto dei fotogrammi",
diff --git a/backends/platform/libretro/include/libretro-core-options.h b/backends/platform/libretro/include/libretro-core-options.h
index d4b5134c6cd..6321fdc37f9 100644
--- a/backends/platform/libretro/include/libretro-core-options.h
+++ b/backends/platform/libretro/include/libretro-core-options.h
@@ -155,19 +155,19 @@ struct retro_core_option_v2_definition option_defs_us[] = {
 	},
 	{
 		"scummvm_analog_deadzone",
-		"Cursor > Analog Deadzone (Percent)",
-		"Analog Deadzone (Percent)",
-		"Sets the deadzone of the RetroPad analog sticks. Used to eliminate cursor drift/unwanted input.",
+		"Cursor > Analog Deadzone",
+		"Analog Deadzone",
+		"Sets the deadzone in percentage of the RetroPad analog sticks. Used to eliminate cursor drift/unwanted input.",
 		NULL,
 		"cursor",
 		{
-			{"0", NULL},
-			{"5", NULL},
-			{"10", NULL},
-			{"15", NULL},
-			{"20", NULL},
-			{"25", NULL},
-			{"30", NULL},
+			{"0", "0 %"},
+			{"5", "5 %"},
+			{"10", "10 %"},
+			{"15", "15 %"},
+			{"20", "20 %"},
+			{"25", "25 %"},
+			{"30", "30 %"},
 			{NULL, NULL},
 		},
 		"15"
@@ -205,6 +205,21 @@ struct retro_core_option_v2_definition option_defs_us[] = {
 		},
 		"1.0"
 	},
+	{
+		"scummvm_mouse_fine_control_speed_reduction",
+		"Cursor > Mouse Fine Control Speed Reduction",
+		"Mouse Fine Control Speed Reduction",
+		"Sets the mouse cursor speed reduction as percentage of normal speed when fine control is activated.",
+		NULL,
+		"cursor",
+		{
+			{"2", "50 %"},
+			{"4", "20 %"},
+			{"10", "10 %"},
+			{NULL, NULL},
+		},
+		"4"
+	},
 	{
 		"scummvm_frameskip_type",
 		"Frameskip > Frameskip Mode",
diff --git a/backends/platform/libretro/include/libretro-os.h b/backends/platform/libretro/include/libretro-os.h
index 5406221472f..c2e486aeb3f 100644
--- a/backends/platform/libretro/include/libretro-os.h
+++ b/backends/platform/libretro/include/libretro-os.h
@@ -49,6 +49,7 @@ extern uint16 retro_setting_get_sample_rate(void);
 extern int retro_setting_get_analog_deadzone(void);
 extern bool retro_setting_get_analog_response_is_quadratic(void);
 extern float retro_setting_get_mouse_speed(void);
+extern int retro_setting_get_mouse_fine_control_speed_reduction(void);
 extern float retro_setting_get_gamepad_cursor_speed(void);
 extern float retro_setting_get_gamepad_acceleration_time(void);
 extern void reset_performance_tuner(void);
diff --git a/backends/platform/libretro/src/libretro-os-inputs.cpp b/backends/platform/libretro/src/libretro-os-inputs.cpp
index eb70f5c91f7..34538a7f850 100644
--- a/backends/platform/libretro/src/libretro-os-inputs.cpp
+++ b/backends/platform/libretro/src/libretro-os-inputs.cpp
@@ -32,7 +32,7 @@ void OSystem_libretro::updateMouseXY(float deltaAcc, float *cumulativeXYAcc, int
 		return;
 
 	if (_cursorStatus & CURSOR_STATUS_DOING_SLOWER)
-		deltaAcc *= 0.2f;
+		deltaAcc /= retro_setting_get_mouse_fine_control_speed_reduction();
 
 	if (doing_x) {
 		_cursorStatus |= CURSOR_STATUS_DOING_X;
diff --git a/backends/platform/libretro/src/libretro.cpp b/backends/platform/libretro/src/libretro.cpp
index 00dac712808..e0542c16aa6 100644
--- a/backends/platform/libretro/src/libretro.cpp
+++ b/backends/platform/libretro/src/libretro.cpp
@@ -75,6 +75,7 @@ static bool analog_response_is_quadratic = false;
 
 static float mouse_speed = 1.0f;
 static float gamepad_acceleration_time = 0.2f;
+static int mouse_fine_control_speed_reduction = 4;
 
 static bool timing_inaccuracies_enabled = false;
 
@@ -232,6 +233,12 @@ static void update_variables(void) {
 		mouse_speed = (float)atof(var.value);
 	}
 
+	var.key = "scummvm_mouse_fine_control_speed_reduction";
+	var.value = NULL;
+	if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) {
+		mouse_fine_control_speed_reduction = (int)atoi(var.value);
+	}
+
 	var.key = "scummvm_allow_timing_inaccuracies";
 	var.value = NULL;
 	timing_inaccuracies_enabled = false;
@@ -524,6 +531,10 @@ float retro_setting_get_mouse_speed(void) {
 	return mouse_speed;
 }
 
+int retro_setting_get_mouse_fine_control_speed_reduction(void) {
+	return mouse_fine_control_speed_reduction;
+}
+
 float retro_setting_get_gamepad_acceleration_time(void) {
 	return gamepad_acceleration_time;
 }




More information about the Scummvm-git-logs mailing list