From 599fd8abe032fb7e21ced64c451ffdf763345fd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wiktor=20Strz=C4=99ba=C5=82a?= Date: Thu, 9 Aug 2018 14:41:40 +0200 Subject: [PATCH 1/3] =?UTF-8?q?Spec=20file=20for=20building=20under=20MERS?= =?UTF-8?q?DK=20(sailfishos)=20Signed-off-by:=20Wiktor=20Strz=C4=99ba?= =?UTF-8?q?=C5=82a=20?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/sailfishos/retroarch-sailfishos.spec | 87 ++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 pkg/sailfishos/retroarch-sailfishos.spec diff --git a/pkg/sailfishos/retroarch-sailfishos.spec b/pkg/sailfishos/retroarch-sailfishos.spec new file mode 100644 index 0000000000..e5e54448b2 --- /dev/null +++ b/pkg/sailfishos/retroarch-sailfishos.spec @@ -0,0 +1,87 @@ +Name: retroarch +Version: 1.7.3 +Release: v1.2 +Summary: Official reference frontend for libretro + +Group: Applications/Emulators +License: GPLv3+ +URL: http://www.libretro.com/ + +BuildRequires: libxml2-devel +BuildRequires: mesa-llvmpipe-libwayland-egl-devel +BuildRequires: pulseaudio-devel +BuildRequires: OpenAL-devel +BuildRequires: libxkbcommon-devel +BuildRequires: zlib-devel +BuildRequires: freetype-devel +#BuildRequires: ffmpeg-devel +BuildRequires: SDL2-devel +BuildRequires: SDL2_image-devel +#Requires libusb 1.0.16 +#BuildRequires: libusb-devel + +%description +RetroArch is the official reference frontend for the libretro API. +Libretro is a simple but powerful development interface that allows for the +easy creation of emulators, games and multimedia applications that can plug +straight into any libretro-compatible frontend. This development interface +is open to others so that they can run these pluggable emulator and game +cores also in their own programs or devices. + +%build +# No autotools, custom configure script +%ifarch armv7hl +./configure --prefix=%{_prefix} --enable-opengles --enable-neon --enable-egl --enable-wayland +%else +./configure --prefix=%{_prefix} --enable-gles +%endif +make %{?_smp_mflags} + + +%install +make install DESTDIR=%{buildroot} +# Configuration changes +sed -i \ + 's|^# libretro_directory =.*|libretro_directory = "~/.config/retroarch/cores/"|; + s|^# libretro_info_path =.*|libretro_info_path = "~/.config/retroarch/cores/"|; + s|^# joypad_autoconfig_dir =.*|joypad_autoconfig_dir = "/etc/retroarch/joypad"|; + s|^# video_fullscreen =.*|video_fullscreen = "true"|; + s|^# menu_driver =.*|menu_driver = "glui"|; + s|^# menu_pointer_enable =.*|menu_pointer_enable = "true"|; + s|^# input_driver =.*|input_driver = "wayland"|' \ + %{buildroot}/etc/retroarch.cfg + +%ifarch armv7hl +sed -i \ + 's|^# core_updater_buildbot_url =.*|core_updater_buildbot_url = "http://buildbot.libretro.com/nightly/linux/armhf/latest/"|;' \ + %{buildroot}/etc/retroarch.cfg +%endif + +#Disabling audio till it's fixed +sed -i \ + 's|^# audio_enable.*|audio_enable = "false"|' \ + %{buildroot}/etc/retroarch.cfg + +sed -i \ + 's|^Exec=retroarch|Exec=retroarch --menu|' \ + %{buildroot}/usr/share/applications/retroarch.desktop + + # Install icon file in the correct place + mkdir -p %{buildroot}/usr/share/icons/hicolor/86x86/apps + install -m 644 "./media/retroarch-96x96.png" "%{buildroot}/usr/share/icons/hicolor/86x86/apps/retroarch.png" + rm "%{buildroot}/usr/share/pixmaps/retroarch.svg" + rmdir "%{buildroot}/usr/share/pixmaps" + +%files +%doc README.md +%config /etc/retroarch.cfg +%{_prefix}/bin/retroarch +%{_prefix}/bin/retroarch-cg2glsl +%{_prefix}/share/applications/retroarch.desktop +%{_prefix}/share/man/man6/*.6* +%{_prefix}/share/icons/hicolor/86x86/apps/retroarch.* +%{_prefix}/share/doc/retroarch/* +%changelog + + + From ca769b0006fbbdc295cd816835b91e9e6212c640 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wiktor=20Strz=C4=99ba=C5=82a?= Date: Thu, 9 Aug 2018 14:42:19 +0200 Subject: [PATCH 2/3] Wayland have EGL libs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Wiktor Strzębała --- Makefile.common | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Makefile.common b/Makefile.common index 3cd2c39654..5f4106db23 100644 --- a/Makefile.common +++ b/Makefile.common @@ -960,6 +960,9 @@ endif ifeq ($(HAVE_WAYLAND), 1) OBJ += gfx/drivers_context/wayland_ctx.o \ input/drivers/wayland_input.o + ifeq ($(HAVE_EGL), 1) + LIBS += $(EGL_LIBS) + endif DEFINES += $(WAYLAND_CFLAGS) $(WAYLAND_CURSOR_CFLAGS) LIBS += $(WAYLAND_LIBS) $(WAYLAND_CURSOR_LIBS) endif From 45799ee034c18fb62e811093ffa3890d10d82a81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wiktor=20Strz=C4=99ba=C5=82a?= Date: Thu, 9 Aug 2018 20:49:27 +0200 Subject: [PATCH 3/3] Bring up touch support for wayland subsystem for sailfish os devices Touch code cleanup Make variabled static as suggest bparker06 C89 compilation error fix (at least for loops) More C89 fixes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Wiktor Strzębała --- gfx/common/wayland_common.h | 13 +++ gfx/drivers_context/wayland_ctx.c | 187 +++++++++++++++++++++++++++++- input/drivers/wayland_input.c | 91 ++++++++++++++- 3 files changed, 287 insertions(+), 4 deletions(-) diff --git a/gfx/common/wayland_common.h b/gfx/common/wayland_common.h index e48f450907..3cbedb9048 100644 --- a/gfx/common/wayland_common.h +++ b/gfx/common/wayland_common.h @@ -28,6 +28,16 @@ #define UDEV_KEY_MAX 0x2ff #define UDEV_MAX_KEYS (UDEV_KEY_MAX + 7) / 8 +#define MAX_TOUCHES 16 + +typedef struct +{ + bool active; + int16_t x; + int16_t y; +} wayland_touch_data_t; + + typedef struct input_ctx_wayland_data { /* Wayland uses Linux keysyms. */ @@ -49,6 +59,9 @@ typedef struct input_ctx_wayland_data const input_device_driver_t *joypad; bool blocked; + + wayland_touch_data_t touches[MAX_TOUCHES]; + } input_ctx_wayland_data_t; #endif diff --git a/gfx/drivers_context/wayland_ctx.c b/gfx/drivers_context/wayland_ctx.c index 2462fc5ef0..7778e6c280 100644 --- a/gfx/drivers_context/wayland_ctx.c +++ b/gfx/drivers_context/wayland_ctx.c @@ -51,6 +51,19 @@ #include "../../input/input_driver.h" #include "../../input/input_keymaps.h" + +typedef struct touch_pos +{ + bool active; + int32_t id; + unsigned x; + unsigned y; +} touch_pos_t; + +static int num_active_touches; +static touch_pos_t active_touch_positions[MAX_TOUCHES]; + + typedef struct gfx_ctx_wayland_data { #ifdef HAVE_EGL @@ -70,6 +83,7 @@ typedef struct gfx_ctx_wayland_data struct wl_shell *shell; struct wl_keyboard *wl_keyboard; struct wl_pointer *wl_pointer; + struct wl_touch *wl_touch; struct wl_seat *seat; struct wl_shm *shm; unsigned swap_interval; @@ -329,8 +343,136 @@ static const struct wl_pointer_listener pointer_listener = { pointer_handle_axis, }; +static void touch_handle_down(void *data, + struct wl_touch *wl_touch, + uint32_t serial, + uint32_t time, + struct wl_surface *surface, + int32_t id, + wl_fixed_t x, + wl_fixed_t y) +{ + int i; + gfx_ctx_wayland_data_t *wl = (gfx_ctx_wayland_data_t*)data; + if (num_active_touches < MAX_TOUCHES) + { + for (i=0; iwl_pointer); wl->wl_pointer = NULL; } + if ((caps & WL_SEAT_CAPABILITY_TOUCH) && !wl->wl_touch) + { + wl->wl_touch = wl_seat_get_touch(seat); + wl_touch_add_listener(wl->wl_touch, &touch_listener, wl); + } + else if (!(caps & WL_SEAT_CAPABILITY_TOUCH) && wl->wl_touch) + { + wl_touch_destroy(wl->wl_touch); + wl->wl_touch = NULL; + } + } static void seat_handle_name(void *data, struct wl_seat *seat, const char *name) @@ -368,6 +521,22 @@ static const struct wl_seat_listener seat_listener = { seat_handle_name, }; +/* Touch handle functions */ + +bool wayland_context_gettouchpos(void *data, unsigned id, + unsigned* touch_x, unsigned* touch_y) +{ + gfx_ctx_wayland_data_t *wl = (gfx_ctx_wayland_data_t*)data; + + if (id >= MAX_TOUCHES) + return false; + *touch_x = active_touch_positions[id].x; + *touch_y = active_touch_positions[id].y; + return active_touch_positions[id].active; +} + + + /* Shell surface callbacks. */ static void shell_surface_handle_ping(void *data, struct wl_shell_surface *shell_surface, @@ -503,7 +672,7 @@ static void registry_handle_global(void *data, struct wl_registry *reg, wl->shm = (struct wl_shm*)wl_registry_bind(reg, id, &wl_shm_interface, 1); else if (string_is_equal(interface, "wl_seat")) { - wl->seat = (struct wl_seat*)wl_registry_bind(reg, id, &wl_seat_interface, 4); + wl->seat = (struct wl_seat*)wl_registry_bind(reg, id, &wl_seat_interface, 2); wl_seat_add_listener(wl->seat, &seat_listener, wl); } } @@ -568,6 +737,8 @@ static void gfx_ctx_wl_destroy_resources(gfx_ctx_wayland_data_t *wl) wl_keyboard_destroy(wl->wl_keyboard); if (wl->wl_pointer) wl_pointer_destroy(wl->wl_pointer); + if (wl->wl_touch) + wl_touch_destroy(wl->wl_touch); if (wl->cursor.theme) wl_cursor_theme_destroy(wl->cursor.theme); @@ -776,6 +947,7 @@ static bool gfx_ctx_wl_get_metrics(void *data, static void *gfx_ctx_wl_init(video_frame_info_t *video_info, void *video_driver) { + int i; #ifdef HAVE_OPENGL static const EGLint egl_attribs_gl[] = { WL_EGL_ATTRIBS_BASE, @@ -924,12 +1096,23 @@ static void *gfx_ctx_wl_init(video_frame_info_t *video_info, void *video_driver) break; } + wl->input.keyboard_focus = true; wl->input.mouse.focus = true; wl->cursor.surface = wl_compositor_create_surface(wl->compositor); wl->cursor.theme = wl_cursor_theme_load(NULL, 16, wl->shm); wl->cursor.default_cursor = wl_cursor_theme_get_cursor(wl->cursor.theme, "left_ptr"); + + num_active_touches = 0; + for (i=0;iinput); #ifdef HAVE_DBUS diff --git a/input/drivers/wayland_input.c b/input/drivers/wayland_input.c index 0363624320..782311f090 100644 --- a/input/drivers/wayland_input.c +++ b/input/drivers/wayland_input.c @@ -50,6 +50,7 @@ /* TODO/FIXME - * fix game focus toggle */ + /* Forward declaration */ void flush_wayland_fd(void *data); @@ -98,6 +99,32 @@ static int16_t input_wl_lightgun_state(input_ctx_wayland_data_t *wl, unsigned id return 0; } +static void input_wl_touch_pool(void *data) +{ + int id; + input_ctx_wayland_data_t *wl = (input_ctx_wayland_data_t*)data; + + if (!wl) + return; + + unsigned touch_x = 0; + unsigned touch_y = 0; + + for (id=0; idtouches[id].active = true; + } + else + { + wl->touches[id].active = false; + } + wl->touches[id].x = touch_x; + wl->touches[id].y = touch_y; + } +} + static void input_wl_poll(void *data) { input_ctx_wayland_data_t *wl = (input_ctx_wayland_data_t*)data; @@ -119,6 +146,8 @@ static void input_wl_poll(void *data) if (wl->joypad) wl->joypad->poll(); + + input_wl_touch_pool(wl); } static int16_t input_wl_analog_pressed(input_ctx_wayland_data_t *wl, @@ -175,8 +204,9 @@ static int16_t input_wl_pointer_state(input_ctx_wayland_data_t *wl, vp.full_height = 0; if (!(video_driver_translate_coord_viewport_wrap(&vp, - wl->mouse.x, wl->mouse.y, + wl->mouse.x, wl->mouse.y, &res_x, &res_y, &res_screen_x, &res_screen_y))) + return 0; if (screen) @@ -203,6 +233,59 @@ static int16_t input_wl_pointer_state(input_ctx_wayland_data_t *wl, return 0; } +static int16_t input_wl_touch_state(input_ctx_wayland_data_t *wl, + unsigned idx, unsigned id, bool screen) +{ + struct video_viewport vp; + + bool inside = false; + int16_t res_x = 0; + int16_t res_y = 0; + int16_t res_screen_x = 0; + int16_t res_screen_y = 0; + + vp.x = 0; + vp.y = 0; + vp.width = 0; + vp.height = 0; + vp.full_width = 0; + vp.full_height = 0; + + if (idx > MAX_TOUCHES) + return 0; + + if (!(video_driver_translate_coord_viewport_wrap(&vp, + wl->touches[idx].x, wl->touches[idx].y, + &res_x, &res_y, &res_screen_x, &res_screen_y))) + return 0; + + if (screen) + { + res_x = res_screen_x; + res_y = res_screen_y; + } + + inside = (res_x >= -0x7fff) && (res_y >= -0x7fff); + + if (!inside) + return 0; + + switch (id) + { + case RETRO_DEVICE_ID_POINTER_X: + return res_x; + case RETRO_DEVICE_ID_POINTER_Y: + return res_y; + case RETRO_DEVICE_ID_POINTER_PRESSED: + return wl->touches[idx].active; + } + + return 0; +} + + + + static int16_t input_wl_state(void *data, rarch_joypad_info_t joypad_info, const struct retro_keybind **binds, @@ -233,11 +316,15 @@ static int16_t input_wl_state(void *data, return input_wl_mouse_state(wl, id, true); case RETRO_DEVICE_POINTER: - case RARCH_DEVICE_POINTER_SCREEN: if (idx == 0) return input_wl_pointer_state(wl, idx, id, device == RARCH_DEVICE_POINTER_SCREEN); break; + case RARCH_DEVICE_POINTER_SCREEN: + if (idx < MAX_TOUCHES) + return input_wl_touch_state(wl, idx, id, + device == RARCH_DEVICE_POINTER_SCREEN); + break; case RETRO_DEVICE_LIGHTGUN: return input_wl_lightgun_state(wl, id); }