Skip to content

Commit

Permalink
3D, Dual screen, Motion Controls, and Sunshine fix (#18)
Browse files Browse the repository at this point in the history
* Update moonlight-common-c with RTSP encryption

* Fix __builtin_cpu_supports(aes) on GCC 9 and earlier

* Update SDL_GameControllerDB

* Add missing CMake include

* Replace FindLibUUID.cmake with modified version from CMake project

* Update moonlight-common-c

* Replace ioctl() retry loops with drmIoctl()

* Add rotation support for Rockchip

Fixes moonlight-stream#878

* Treat devices as gamepads if they have a hat instead of an analog stick

Fixes moonlight-stream#880

* Ignore CRCs in SDL mappings

* Move CPU detection code into a separate file

* Link util.c into the platform libraries

* Replace SDL key handling with Moonlight Qt code

The existing code had a bunch of incorrectly mapped keys and was using
keysym instead of scancode which causes issues with non-US keyboards.

* Remove a bunch of useless asserts

* Provide better errors when RK renderer fails

* Version 2.7.0

* Fix build warnings

* Adds the ability to display side-by-side stereoscopic 3D images in 3D mode.
Adds offset buffers for 3D images.

* Add config option for displaying the stream across both displays.
Adds video logic for stretching stream images across top and bottom displays.
Simplifies 3D/Wide mode switching.

* Adds touch handler for dual screen mode
formats modified files

* Fix build dependency error
Add dual screen status to the loading print
Move all wide mode setting to ensure_3d functions

* Bump moonlight-common-c
This seems to fix connection issues with sunshine v0.22

* Fix graphics glitch on exit

* Add gyroscope/accelerometer output
Add config option for enabling/disabling motion controls

* Smooth out motion control behavior
Fix gyroscope coefficient use
Fix gyroscope directions (tested with cemu)

---------

Co-authored-by: Cameron Gutman <[email protected]>
  • Loading branch information
zoeyjodon and cgutman authored Mar 20, 2024
1 parent d77c4b1 commit 1ab2ce4
Show file tree
Hide file tree
Showing 26 changed files with 2,004 additions and 1,399 deletions.
21 changes: 14 additions & 7 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
cmake_minimum_required(VERSION 3.1)
project(moonlight-embedded VERSION 2.6.2 LANGUAGES C)
cmake_minimum_required(VERSION 3.6)
project(moonlight-embedded VERSION 2.7.0 LANGUAGES C)
SET(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake")
SET(CMAKE_C_STANDARD 99)
include(${CMAKE_ROOT}/Modules/GNUInstallDirs.cmake)
include(${CMAKE_SOURCE_DIR}/cmake/generate_version_header.cmake)

include(CheckCSourceCompiles)

add_compile_options(-Wall -Wextra -Wno-unused-parameter -Wno-pointer-sign -Wno-sign-compare -Wno-switch)

aux_source_directory(./src SRC_LIST)
Expand Down Expand Up @@ -98,6 +100,11 @@ if (HAVE_GETAUXVAL)
list(APPEND MOONLIGHT_DEFINITIONS HAVE_GETAUXVAL)
endif()

check_c_source_compiles("int main(void) { return __builtin_cpu_supports(\"aes\"); }" HAVE_BICS_AES)
if (HAVE_BICS_AES)
list(APPEND MOONLIGHT_DEFINITIONS HAVE_BICS_AES)
endif()

if (CEC_FOUND)
list(APPEND MOONLIGHT_DEFINITIONS HAVE_LIBCEC)
list(APPEND MOONLIGHT_OPTIONS CEC)
Expand All @@ -109,7 +116,7 @@ endif()
if(AMLOGIC_FOUND)
list(APPEND MOONLIGHT_DEFINITIONS HAVE_AML)
list(APPEND MOONLIGHT_OPTIONS AML)
add_library(moonlight-aml SHARED ./src/video/aml.c ${ILCLIENT_SRC_LIST})
add_library(moonlight-aml SHARED ./src/video/aml.c ./src/util.c ${ILCLIENT_SRC_LIST})
target_include_directories(moonlight-aml PRIVATE ${AMLOGIC_INCLUDE_DIRS} ${GAMESTREAM_INCLUDE_DIR} ${MOONLIGHT_COMMON_INCLUDE_DIR})
target_link_libraries(moonlight-aml gamestream ${AMLOGIC_LIBRARIES})
set_property(TARGET moonlight-aml PROPERTY COMPILE_DEFINITIONS ${AMLOGIC_DEFINITIONS})
Expand All @@ -120,7 +127,7 @@ if(BROADCOM-OMX_FOUND)
list(APPEND MOONLIGHT_DEFINITIONS HAVE_PI)
list(APPEND MOONLIGHT_OPTIONS PI)
aux_source_directory(./third_party/ilclient ILCLIENT_SRC_LIST)
add_library(moonlight-pi SHARED ./src/video/pi.c ./src/audio/omx.c ${ILCLIENT_SRC_LIST})
add_library(moonlight-pi SHARED ./src/video/pi.c ./src/audio/omx.c ./src/util.c ${ILCLIENT_SRC_LIST})
target_include_directories(moonlight-pi PRIVATE ./third_party/ilclient ${BROADCOM_INCLUDE_DIRS} ${GAMESTREAM_INCLUDE_DIR} ${MOONLIGHT_COMMON_INCLUDE_DIR} ${OPUS_INCLUDE_DIRS})
target_link_libraries(moonlight-pi gamestream ${BROADCOM_OMX_LIBRARIES} ${OPUS_LIBRARY})
set_property(TARGET moonlight-pi PROPERTY COMPILE_DEFINITIONS ${BROADCOM_OMX_DEFINITIONS})
Expand All @@ -130,7 +137,7 @@ endif()
if(MMAL_FOUND)
list(APPEND MOONLIGHT_DEFINITIONS HAVE_MMAL)
list(APPEND MOONLIGHT_OPTIONS MMAL)
add_library(moonlight-mmal SHARED ./src/video/mmal.c)
add_library(moonlight-mmal SHARED ./src/video/mmal.c ./src/util.c)
target_include_directories(moonlight-mmal PRIVATE ${MMAL_INCLUDE_DIRS} ${GAMESTREAM_INCLUDE_DIR} ${MOONLIGHT_COMMON_INCLUDE_DIR})
target_link_libraries(moonlight-mmal gamestream ${MMAL_LINK_LIBRARIES})
install(TARGETS moonlight-mmal DESTINATION ${CMAKE_INSTALL_LIBDIR})
Expand All @@ -139,7 +146,7 @@ endif()
if(FREESCALE_FOUND)
list(APPEND MOONLIGHT_DEFINITIONS HAVE_IMX)
list(APPEND MOONLIGHT_OPTIONS IMX)
add_library(moonlight-imx SHARED ./src/video/imx.c ./src/video/imx_vpu.c)
add_library(moonlight-imx SHARED ./src/video/imx.c ./src/video/imx_vpu.c ./src/util.c)
target_include_directories(moonlight-imx PRIVATE ${FREESCALE_INCLUDE_DIRS} ${GAMESTREAM_INCLUDE_DIR} ${MOONLIGHT_COMMON_INCLUDE_DIR})
target_link_libraries(moonlight-imx gamestream ${FREESCALE_LIBRARIES})
install(TARGETS moonlight-imx DESTINATION ${CMAKE_INSTALL_LIBDIR})
Expand All @@ -148,7 +155,7 @@ endif()
if(ROCKCHIP_FOUND)
list(APPEND MOONLIGHT_DEFINITIONS HAVE_ROCKCHIP)
list(APPEND MOONLIGHT_OPTIONS ROCKCHIP)
add_library(moonlight-rk SHARED ./src/video/rk.c)
add_library(moonlight-rk SHARED ./src/video/rk.c ./src/util.c)
target_include_directories(moonlight-rk PRIVATE ${ROCKCHIP_INCLUDE_DIRS} ${GAMESTREAM_INCLUDE_DIR} ${MOONLIGHT_COMMON_INCLUDE_DIR})
target_link_libraries(moonlight-rk gamestream ${ROCKCHIP_LIBRARIES})
set_property(TARGET moonlight-rk PROPERTY COMPILE_DEFINITIONS ${ROCKCHIP_DEFINITIONS})
Expand Down
122 changes: 74 additions & 48 deletions cmake/FindLibUUID.cmake
Original file line number Diff line number Diff line change
@@ -1,51 +1,77 @@
# - Try to find LIBUUID
# Find LIBUUID headers, libraries and the answer to all questions.
# CMake - Cross Platform Makefile Generator
# Copyright 2000-2024 Kitware, Inc. and Contributors
# All rights reserved.
#
# LIBUUID_FOUND True if libuuid got found
# LIBUUID_INCLUDE_DIRS Location of libuuid headers
# LIBUUID_LIBRARIES List of libraries to use libuuid
#
# Copyright (c) 2008 Bjoern Ricks <[email protected]>
#
# Redistribution and use is allowed according to the terms of the New
# BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
# Distributed under the OSI-approved BSD 3-Clause License. See
# https://cmake.org/licensing for details.
#
#[=======================================================================[.rst:
FindLibUUID
------------
Find LibUUID include directory and library.
Imported Targets
^^^^^^^^^^^^^^^^
An :ref:`imported target <Imported targets>` named
``LibUUID::LibUUID`` is provided if LibUUID has been found.
Result Variables
^^^^^^^^^^^^^^^^
This module defines the following variables:
``LibUUID_FOUND``
True if LibUUID was found, false otherwise.
``LibUUID_INCLUDE_DIRS``
Include directories needed to include LibUUID headers.
``LibUUID_LIBRARIES``
Libraries needed to link to LibUUID.
Cache Variables
^^^^^^^^^^^^^^^
This module uses the following cache variables:
``LibUUID_LIBRARY``
The location of the LibUUID library file.
``LibUUID_INCLUDE_DIR``
The location of the LibUUID include directory containing ``uuid/uuid.h``.
The cache variables should not be used by project code.
They may be set by end users to point at LibUUID components.
#]=======================================================================]

#-----------------------------------------------------------------------------
find_library(LibUUID_LIBRARY
NAMES uuid
)
mark_as_advanced(LibUUID_LIBRARY)

find_path(LibUUID_INCLUDE_DIR
NAMES uuid/uuid.h
)
mark_as_advanced(LibUUID_INCLUDE_DIR)

#-----------------------------------------------------------------------------
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibUUID
FOUND_VAR LibUUID_FOUND
REQUIRED_VARS LibUUID_LIBRARY LibUUID_INCLUDE_DIR
)
set(LIBUUID_FOUND ${LibUUID_FOUND})

INCLUDE( FindPkgConfig )

IF ( LibUuid_FIND_REQUIRED )
SET( _pkgconfig_REQUIRED "REQUIRED" )
ELSE( LibUuid_FIND_REQUIRED )
SET( _pkgconfig_REQUIRED "" )
ENDIF ( LibUuid_FIND_REQUIRED )

IF ( LIBUUID_MIN_VERSION )
PKG_SEARCH_MODULE( LIBUUID ${_pkgconfig_REQUIRED} uuid>=${LIBUUID_MIN_VERSION} )
ELSE ( LIBUUID_MIN_VERSION )
PKG_SEARCH_MODULE( LIBUUID ${_pkgconfig_REQUIRED} uuid )
ENDIF ( LIBUUID_MIN_VERSION )


IF( NOT LIBUUID_FOUND AND NOT PKG_CONFIG_FOUND )
FIND_PATH( LIBUUID_INCLUDE_DIRS uuid/uuid.h )
FIND_LIBRARY( LIBUUID_LIBRARIES uuid)

# Report results
IF ( LIBUUID_LIBRARIES AND LIBUUID_INCLUDE_DIRS )
SET( LIBUUID_FOUND 1 )
IF ( NOT LIBUUID_FIND_QUIETLY )
MESSAGE( STATUS "Found libuuid: ${LIBUUID_LIBRARIES}" )
ENDIF ( NOT LIBUUID_FIND_QUIETLY )
ELSE ( LIBUUID_LIBRARIES AND LIBUUID_INCLUDE_DIRS )
IF ( LIBUUID_FIND_REQUIRED )
MESSAGE( SEND_ERROR "Could NOT find libuuid" )
ELSE ( LIBUUID_FIND_REQUIRED )
IF ( NOT LIBUUID_FIND_QUIETLY )
MESSAGE( STATUS "Could NOT find libuuid" )
ENDIF ( NOT LIBUUID_FIND_QUIETLY )
ENDIF ( LIBUUID_FIND_REQUIRED )
ENDIF ( LIBUUID_LIBRARIES AND LIBUUID_INCLUDE_DIRS )
ENDIF( NOT LIBUUID_FOUND AND NOT PKG_CONFIG_FOUND )

MARK_AS_ADVANCED( LIBUUID_LIBRARIES LIBUUID_INCLUDE_DIRS )
#-----------------------------------------------------------------------------
# Provide documented result variables and targets.
if(LibUUID_FOUND)
set(LibUUID_INCLUDE_DIRS ${LibUUID_INCLUDE_DIR})
set(LibUUID_LIBRARIES ${LibUUID_LIBRARY})
if(NOT TARGET LibUUID::LibUUID)
add_library(LibUUID::LibUUID UNKNOWN IMPORTED)
set_target_properties(LibUUID::LibUUID PROPERTIES
IMPORTED_LOCATION "${LibUUID_LIBRARY}"
INTERFACE_INCLUDE_DIRECTORIES "${LibUUID_INCLUDE_DIRS}"
)
endif()
endif()
4 changes: 2 additions & 2 deletions libgamestream/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ target_link_libraries(gamestream moonlight-common)
set_target_properties(gamestream PROPERTIES SOVERSION ${SO_VERSION} VERSION ${PROJECT_VERSION})
set_target_properties(moonlight-common PROPERTIES SOVERSION ${SO_VERSION} VERSION ${PROJECT_VERSION})

target_include_directories(gamestream PRIVATE ../third_party/moonlight-common-c/src ../third_party/h264bitstream ${AVAHI_INCLUDE_DIRS} ${LIBUUID_INCLUDE_DIRS})
target_include_directories(gamestream PRIVATE ../third_party/moonlight-common-c/src ../third_party/h264bitstream ${AVAHI_INCLUDE_DIRS} ${LibUUID_INCLUDE_DIRS})
target_include_directories(moonlight-common PRIVATE ../third_party/moonlight-common-c/reedsolomon ../third_party/moonlight-common-c/enet/include)
target_link_libraries(gamestream ${CURL_LIBRARIES} ${OPENSSL_LIBRARIES} ${EXPAT_LIBRARIES} ${AVAHI_LIBRARIES} ${LIBUUID_LIBRARIES})
target_link_libraries(gamestream ${CURL_LIBRARIES} ${OPENSSL_LIBRARIES} ${EXPAT_LIBRARIES} ${AVAHI_LIBRARIES} ${LibUUID_LIBRARIES})

target_link_libraries(gamestream ${CMAKE_THREAD_LIBS_INIT} ${CMAKE_DL_LIBS})

Expand Down
3 changes: 2 additions & 1 deletion libgamestream/client.c
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,7 @@ int gs_pair(PSERVER_DATA server, char* pin) {
char* pairing_secret = NULL;
char* client_pairing_secret = NULL;
char* client_pairing_secret_hex = NULL;
PHTTP_DATA data = NULL;

if (server->paired) {
gs_error = "Already paired";
Expand All @@ -454,7 +455,7 @@ int gs_pair(PSERVER_DATA server, char* pin) {
uuid_generate_random(uuid);
uuid_unparse(uuid, uuid_str);
snprintf(url, url_max_len, "http://%s:%u/pair?uniqueid=%s&uuid=%s&devicename=roth&updateState=1&phrase=getservercert&salt=%s&clientcert=%s", server->serverInfo.address, server->httpPort, unique_id, uuid_str, salt_hex, cert_hex);
PHTTP_DATA data = http_create_data();
data = http_create_data();
if (data == NULL)
return GS_OUT_OF_MEMORY;
else if ((ret = http_request(url, data)) != GS_OK)
Expand Down
40 changes: 27 additions & 13 deletions src/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "platform_main.h"
#include "config.h"
#include "util.h"
#include "cpu.h"

#include "input/evdev.h"
#include "audio/audio.h"
Expand Down Expand Up @@ -84,6 +85,8 @@ static struct option long_options[] = {
{"port", required_argument, NULL, '6'},
{"hdr", no_argument, NULL, '7'},
{"hwdecode", required_argument, NULL, '8'},
{"dual_screen", required_argument, NULL, '9'},
{"motion_controls", required_argument, NULL, 'e'},
{"swapfacebuttons", required_argument, NULL, 'A'},
{"swaptriggersandshoulders", required_argument, NULL, 'B'},
{0, 0, 0, 0},
Expand Down Expand Up @@ -162,6 +165,14 @@ void parse_argument(int c, char* value, PCONFIGURATION config) {
case 'd':
config->stream.height = atoi(value);
break;
case 'e':
if ((value != NULL) && (strcmp(value, "true") == 0)) {
config->motion_controls = true;
}
else {
config->motion_controls = false;
}
break;
case 'g':
config->stream.bitrate = atoi(value);
break;
Expand Down Expand Up @@ -306,6 +317,13 @@ void parse_argument(int c, char* value, PCONFIGURATION config) {
config->hwdecode = false;
}
break;
case '9':
if ((value != NULL) && (strcmp(value, "true") == 0)) {
config->dual_screen = true;
}
else {
config->dual_screen = false;
}
case 'A':
if ((value != NULL) && (strcmp(value, "true") == 0)) {
config->swap_face_buttons = true;
Expand Down Expand Up @@ -387,6 +405,8 @@ void config_save(char* filename, PCONFIGURATION config) {
write_config_bool(fd, "swapfacebuttons", config->swap_face_buttons);
write_config_bool(fd, "swaptriggersandshoulders", config->swap_triggers_and_shoulders);
write_config_bool(fd, "debug", config->debug_level);
write_config_bool(fd, "dual_screen", config->dual_screen);
write_config_bool(fd, "motion_controls", config->motion_controls);

if (strcmp(config->app, "Steam") != 0)
write_config_string(fd, "app", config->app);
Expand All @@ -410,23 +430,15 @@ void config_parse(int argc, char* argv[], PCONFIGURATION config) {
if (has_fast_aes()) {
config->stream.encryptionFlags = ENCFLG_ALL;
}
else if (has_slow_aes()) {
// For extremely slow CPUs, opt out of audio encryption
config->stream.encryptionFlags = ENCFLG_NONE;
printf("Disabling encryption on low performance CPU\n");
}
else {
config->stream.encryptionFlags = ENCFLG_AUDIO;
}

#ifdef __arm__
char cpuinfo[4096] = {};
if (read_file("/proc/cpuinfo", cpuinfo, sizeof(cpuinfo) - 1) > 0) {
// If this is a ARMv6 CPU (like the Pi 1), we'll assume it's not
// powerful enough to handle audio encryption. The Pi 1 could
// barely handle Opus decoding alone.
if (strstr(cpuinfo, "ARMv6")) {
config->stream.encryptionFlags = ENCFLG_NONE;
printf("Disabling encryption on low performance CPU\n");
}
}
#endif

config->debug_level = 0;
config->platform = "auto";
config->app = "Steam";
Expand Down Expand Up @@ -457,6 +469,8 @@ void config_parse(int argc, char* argv[], PCONFIGURATION config) {
config->stream.fps = 30;
config->stream.encryptionFlags = ENCFLG_NONE;
config->hwdecode = true;
config->dual_screen = false;
config->motion_controls = false;
config->swap_face_buttons = false;
config->swap_triggers_and_shoulders = false;

Expand Down
3 changes: 3 additions & 0 deletions src/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include <Limelight.h>

#include <stdbool.h>
#include "platform_main.h"

#define MAX_INPUTS 6

Expand Down Expand Up @@ -49,6 +50,8 @@ typedef struct _CONFIGURATION {
int pin;
unsigned short port;
bool hwdecode;
bool dual_screen;
bool motion_controls;
bool swap_face_buttons;
bool swap_triggers_and_shoulders;
} CONFIGURATION, *PCONFIGURATION;
Expand Down
Loading

0 comments on commit 1ab2ce4

Please sign in to comment.