mirror of
https://git.sr.ht/~thestr4ng3r/chiaki
synced 2025-07-06 13:02:11 -07:00
Compare commits
43 commits
Author | SHA1 | Date | |
---|---|---|---|
|
a1fd418685 | ||
|
bb5a79f234 | ||
|
4eb90a7a65 | ||
|
94fcdc3c61 | ||
|
8911a44766 | ||
|
89368f63c9 | ||
|
d4a0603bf2 | ||
|
666238ba9f | ||
|
bcdd0dd7fd | ||
|
6096de8c13 | ||
|
582ec7aa54 | ||
|
e14083c87c | ||
|
c2f0932670 | ||
|
7a490b5aae | ||
|
4c8209762c | ||
|
76690a319c | ||
|
36816db7ac | ||
|
801f902bea | ||
|
74d39e6314 | ||
|
40a9dee4ed | ||
|
6bfbcfc456 | ||
|
e00f5fae9d | ||
|
4164255ef9 | ||
|
b790fb3fb5 | ||
|
b4f051395f | ||
|
420809b24e | ||
|
7d820bd4ab | ||
|
aa3a3b8bbc | ||
|
ccecc67d74 | ||
|
dcd2e6af4a | ||
|
7a01ac0d41 | ||
|
796a128456 | ||
|
695da18473 | ||
|
7870a28cdd | ||
|
a44000ea2b | ||
|
2b4a7426ff | ||
|
f50b060795 | ||
|
a049ed43ec | ||
|
ae3ca1ac7a | ||
|
2257030ade | ||
|
6df937a57c | ||
|
078e83ec70 | ||
|
ac8a3a3a3c |
90 changed files with 1795 additions and 379 deletions
|
@ -5,6 +5,7 @@ image:
|
|||
branches:
|
||||
only:
|
||||
- master
|
||||
- develop
|
||||
- /^v\d.*$/
|
||||
- /^deploy-test(-.*)?$/
|
||||
|
||||
|
@ -36,14 +37,14 @@ for:
|
|||
install:
|
||||
- git submodule update --init --recursive
|
||||
- sudo pip3 install protobuf
|
||||
- brew install qt opus openssl@1.1 nasm sdl2 protobuf
|
||||
- HOMEBREW_NO_AUTO_UPDATE=1 brew install qt@5 opus openssl@1.1 nasm sdl2 protobuf
|
||||
- scripts/build-ffmpeg.sh
|
||||
|
||||
build_script:
|
||||
- export CMAKE_PREFIX_PATH="`pwd`/ffmpeg-prefix;/usr/local/opt/openssl@1.1;/usr/local/opt/qt"
|
||||
- export CMAKE_PREFIX_PATH="`pwd`/ffmpeg-prefix;/usr/local/opt/openssl@1.1;/usr/local/opt/qt@5"
|
||||
- scripts/build-common.sh
|
||||
- cp -a build/gui/chiaki.app Chiaki.app
|
||||
- /usr/local/opt/qt/bin/macdeployqt Chiaki.app -dmg
|
||||
- /usr/local/opt/qt@5/bin/macdeployqt Chiaki.app -dmg
|
||||
|
||||
artifacts:
|
||||
- path: Chiaki.dmg
|
||||
|
|
|
@ -22,7 +22,7 @@ tasks:
|
|||
sudo docker run \
|
||||
-v /home/build:/home/build \
|
||||
-u $(id -u):$(id -g) \
|
||||
thestr4ng3r/android:f064ea6 \
|
||||
thestr4ng3r/android:90d826e \
|
||||
/bin/bash -c "cd /home/build/chiaki/android && ./gradlew assembleRelease bundleRelease"
|
||||
cp chiaki/android/app/build/outputs/apk/release/app-release*.apk Chiaki.apk
|
||||
cp chiaki/android/app/build/outputs/bundle/release/app-release*.aab Chiaki.aab
|
||||
|
|
|
@ -9,38 +9,47 @@ packages:
|
|||
- ninja
|
||||
- protoc
|
||||
- py3-protobuf
|
||||
- py3-setuptools
|
||||
- opus-dev
|
||||
- qt5-qtbase-dev
|
||||
- qt5-qtsvg-dev
|
||||
- qt5-qtmultimedia-dev
|
||||
- ffmpeg-dev
|
||||
- sdl2-dev
|
||||
- sdl2-static # this is gone on alpine edge so might be necessary to remove later
|
||||
- docker
|
||||
- podman
|
||||
- fuse
|
||||
- udev
|
||||
- argp-standalone
|
||||
|
||||
artifacts:
|
||||
- chiaki.nro
|
||||
- Chiaki.AppImage
|
||||
|
||||
tasks:
|
||||
- start_docker: |
|
||||
sudo service docker start
|
||||
sudo chmod +s /usr/bin/docker # Yes, I know what I am doing
|
||||
sudo service fuse start # Fuse for AppImages
|
||||
- setup_podman: |
|
||||
sudo rc-service udev start
|
||||
sudo rc-service cgroups start
|
||||
sudo rc-service fuse start # Fuse for AppImages
|
||||
echo build:100000:65536 | sudo tee /etc/subuid
|
||||
echo build:100000:65536 | sudo tee /etc/subgid
|
||||
# https://www.kernel.org/doc/Documentation/networking/tuntap.txt
|
||||
# for slirp4netns
|
||||
sudo mkdir -p /dev/net
|
||||
sudo mknod /dev/net/tun c 10 200
|
||||
sudo chmod 0666 /dev/net/tun
|
||||
- local_build_and_test: |
|
||||
cd chiaki
|
||||
cmake -Bbuild -GNinja
|
||||
cmake -Bbuild -GNinja -DCHIAKI_ENABLE_CLI=ON -DCHIAKI_ENABLE_GUI=ON -DCHIAKI_CLI_ARGP_STANDALONE=ON
|
||||
ninja -C build
|
||||
build/test/chiaki-unit
|
||||
- appimage: |
|
||||
cd chiaki
|
||||
scripts/run-docker-build-appimage.sh
|
||||
scripts/run-podman-build-appimage.sh
|
||||
cp appimage/Chiaki.AppImage ../Chiaki.AppImage
|
||||
- switch: |
|
||||
cd chiaki
|
||||
scripts/switch/run-docker-build-chiaki.sh
|
||||
scripts/switch/run-podman-build-chiaki.sh
|
||||
cp build_switch/switch/chiaki.nro ../chiaki.nro
|
||||
- bullseye: |
|
||||
cd chiaki
|
||||
scripts/run-docker-build-bullseye.sh
|
||||
scripts/run-podman-build-bullseye.sh
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
image: freebsd/latest
|
||||
image: freebsd/14.x
|
||||
|
||||
sources:
|
||||
- https://git.sr.ht/~thestr4ng3r/chiaki
|
||||
|
@ -7,7 +7,8 @@ sources:
|
|||
packages:
|
||||
- cmake
|
||||
- protobuf
|
||||
- py37-protobuf
|
||||
- py311-setuptools # should not be needed with nanopb >= 0.4.9
|
||||
- py311-protobuf
|
||||
- opus
|
||||
- qt5-core
|
||||
- qt5-qmake
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
image: openbsd/6.7
|
||||
image: openbsd/latest
|
||||
|
||||
sources:
|
||||
- https://git.sr.ht/~thestr4ng3r/chiaki
|
||||
|
@ -7,6 +7,7 @@ sources:
|
|||
packages:
|
||||
- cmake
|
||||
- protobuf
|
||||
- py3-setuptools # should not be needed with nanopb >= 0.4.9
|
||||
- py3-protobuf
|
||||
- opus
|
||||
- qtbase
|
||||
|
|
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -29,3 +29,5 @@ compile_commands.json
|
|||
chiaki.conf
|
||||
/appimage
|
||||
.cache/
|
||||
/*.app
|
||||
/*.dmg
|
||||
|
|
2
.gitmodules
vendored
2
.gitmodules
vendored
|
@ -15,4 +15,4 @@
|
|||
url = https://github.com/google/oboe
|
||||
[submodule "switch/borealis"]
|
||||
path = switch/borealis
|
||||
url = https://github.com/natinusala/borealis.git
|
||||
url = https://git.sr.ht/~thestr4ng3r/borealis
|
||||
|
|
|
@ -24,6 +24,7 @@ endif()
|
|||
tri_option(CHIAKI_ENABLE_FFMPEG_DECODER "Enable FFMPEG video decoder" ${CHIAKI_FFMPEG_DEFAULT})
|
||||
tri_option(CHIAKI_ENABLE_PI_DECODER "Enable Raspberry Pi-specific video decoder (requires libraspberrypi0 and libraspberrypi-doc)" AUTO)
|
||||
option(CHIAKI_LIB_ENABLE_MBEDTLS "Use mbedtls instead of OpenSSL as part of Chiaki Lib" OFF)
|
||||
option(CHIAKI_LIB_MBEDTLS_EXTERNAL_PROJECT "Fetch Mbed TLS instead of using system-provided libs" OFF)
|
||||
option(CHIAKI_LIB_OPENSSL_EXTERNAL_PROJECT "Use OpenSSL as CMake external project" OFF)
|
||||
option(CHIAKI_GUI_ENABLE_SDL_GAMECONTROLLER "Use SDL Gamecontroller for Input" ON)
|
||||
option(CHIAKI_CLI_ARGP_STANDALONE "Search for standalone argp lib for CLI" OFF)
|
||||
|
@ -31,7 +32,7 @@ tri_option(CHIAKI_USE_SYSTEM_JERASURE "Use system-provided jerasure instead of s
|
|||
tri_option(CHIAKI_USE_SYSTEM_NANOPB "Use system-provided nanopb instead of submodule" AUTO)
|
||||
|
||||
set(CHIAKI_VERSION_MAJOR 2)
|
||||
set(CHIAKI_VERSION_MINOR 1)
|
||||
set(CHIAKI_VERSION_MINOR 2)
|
||||
set(CHIAKI_VERSION_PATCH 0)
|
||||
set(CHIAKI_VERSION ${CHIAKI_VERSION_MAJOR}.${CHIAKI_VERSION_MINOR}.${CHIAKI_VERSION_PATCH})
|
||||
|
||||
|
@ -89,6 +90,20 @@ endif()
|
|||
|
||||
if(CHIAKI_LIB_ENABLE_MBEDTLS)
|
||||
add_definitions(-DCHIAKI_LIB_ENABLE_MBEDTLS)
|
||||
if(CHIAKI_LIB_MBEDTLS_EXTERNAL_PROJECT)
|
||||
set(FETCHCONTENT_QUIET CACHE BOOL FALSE)
|
||||
include(FetchContent)
|
||||
set(ENABLE_TESTING CACHE INTERNAL OFF)
|
||||
set(ENABLE_PROGRAMS CACHE INTERNAL OFF)
|
||||
set(USE_SHARED_MBEDTLS_LIBRARY CACHE INTERNAL OFF)
|
||||
FetchContent_Declare(
|
||||
mbedtls
|
||||
GIT_REPOSITORY https://github.com/Mbed-TLS/mbedtls.git
|
||||
GIT_TAG 8b3f26a5ac38d4fdccbc5c5366229f3e01dafcc0 # v2.28.0
|
||||
GIT_PROGRESS TRUE
|
||||
)
|
||||
FetchContent_MakeAvailable(mbedtls)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(CHIAKI_ENABLE_FFMPEG_DECODER)
|
||||
|
@ -135,21 +150,30 @@ if(CHIAKI_ENABLE_CLI)
|
|||
add_subdirectory(cli)
|
||||
endif()
|
||||
|
||||
if(CHIAKI_ENABLE_GUI AND CHIAKI_GUI_ENABLE_SDL_GAMECONTROLLER)
|
||||
find_package(SDL2 MODULE REQUIRED)
|
||||
endif()
|
||||
|
||||
if(CHIAKI_ENABLE_SETSU)
|
||||
find_package(Udev QUIET)
|
||||
find_package(Evdev QUIET)
|
||||
if(Udev_FOUND AND Evdev_FOUND)
|
||||
set(CHIAKI_ENABLE_SETSU ON)
|
||||
else()
|
||||
if(NOT CHIAKI_ENABLE_SETSU STREQUAL AUTO)
|
||||
message(FATAL_ERROR "
|
||||
CHIAKI_ENABLE_SETSU is set to ON, but its dependencies (udev and evdev) could not be resolved.
|
||||
Keep in mind that setsu is only supported on Linux!")
|
||||
endif()
|
||||
if(CHIAKI_ENABLE_SETSU STREQUAL AUTO AND SDL2_FOUND AND (SDL2_VERSION_MINOR GREATER 0 OR SDL2_VERSION_PATCH GREATER_EQUAL 14))
|
||||
message(STATUS "SDL version ${SDL2_VERSION} is >= 2.0.14, disabling Setsu")
|
||||
set(CHIAKI_ENABLE_SETSU OFF)
|
||||
endif()
|
||||
if(CHIAKI_ENABLE_SETSU)
|
||||
add_subdirectory(setsu)
|
||||
else()
|
||||
find_package(Udev QUIET)
|
||||
find_package(Evdev QUIET)
|
||||
if(Udev_FOUND AND Evdev_FOUND)
|
||||
set(CHIAKI_ENABLE_SETSU ON)
|
||||
else()
|
||||
if(NOT CHIAKI_ENABLE_SETSU STREQUAL AUTO)
|
||||
message(FATAL_ERROR "
|
||||
CHIAKI_ENABLE_SETSU is set to ON, but its dependencies (udev and evdev) could not be resolved.
|
||||
Keep in mind that setsu is only supported on Linux!")
|
||||
endif()
|
||||
set(CHIAKI_ENABLE_SETSU OFF)
|
||||
endif()
|
||||
if(CHIAKI_ENABLE_SETSU)
|
||||
add_subdirectory(setsu)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
@ -160,7 +184,6 @@ else()
|
|||
endif()
|
||||
|
||||
if(CHIAKI_ENABLE_GUI)
|
||||
#add_subdirectory(setsu)
|
||||
add_subdirectory(gui)
|
||||
endif()
|
||||
|
||||
|
|
17
README.md
17
README.md
|
@ -8,14 +8,19 @@
|
|||
[](https://ci.appveyor.com/project/thestr4ng3r/chiaki) [](https://builds.sr.ht/~thestr4ng3r/chiaki?)
|
||||
|
||||
Chiaki is a Free and Open Source Software Client for PlayStation 4 and PlayStation 5 Remote Play
|
||||
for Linux, FreeBSD, OpenBSD, Android, macOS, Windows, Nintendo Switch and potentially even more platforms.
|
||||
for Linux, FreeBSD, OpenBSD, NetBSD, Android, macOS, Windows, Nintendo Switch and potentially even more platforms.
|
||||
|
||||

|
||||
|
||||
## Project Status
|
||||
## Project Status and Contributing
|
||||
|
||||
As all relevant features are implemented, this project is considered to be finished and in maintenance mode only.
|
||||
No major updates are planned and contributions are only accepted in special cases.
|
||||
No major updates are planned and contributions are only accepted in special cases such as security issues.
|
||||
The objective is to keep a stable base and not break existing support for less mainstream platforms such as BSDs.
|
||||
|
||||
**For a more active, fast moving and community-oriented project, refer
|
||||
to [chiaki-ng](https://streetpea.github.io/chiaki-ng/) ("next generation").
|
||||
If you would like to contribute, this will likely also be the best place to do so.**
|
||||
|
||||

|
||||
|
||||
## Installing
|
||||
|
||||
|
@ -28,7 +33,7 @@ Builds are provided for Linux, Android, macOS, Nintendo Switch and Windows.
|
|||
You can download them [here](https://git.sr.ht/~thestr4ng3r/chiaki/refs).
|
||||
|
||||
* **Linux**: The provided file is an [AppImage](https://appimage.org/). Simply make it executable (`chmod +x <file>.AppImage`) and run it.
|
||||
* **Android**: Install from [Google Play](https://play.google.com/store/apps/details?id=com.metallic.chiaki), [F-Droid](https://f-droid.org/packages/com.metallic.chiaki/) or download the APK from Sourcehut.
|
||||
* **Android**: Install from [F-Droid](https://f-droid.org/packages/com.metallic.chiaki/) or download the APK from Sourcehut.
|
||||
* **macOS**: Drag the application from the `.dmg` into your Applications folder.
|
||||
* **Windows**: Extract the `.zip` file and execute `chiaki.exe`.
|
||||
* **Switch**: Download the `.nro` file and copy it into the `switch/` directory on your SD card.
|
||||
|
|
|
@ -18,13 +18,12 @@ def chiakiVersion = "$chiakiVersionMajor.$chiakiVersionMinor.$chiakiVersionPatch
|
|||
println("Determined Chiaki Version: $chiakiVersion")
|
||||
|
||||
android {
|
||||
compileSdkVersion 30
|
||||
buildToolsVersion "30.0.2"
|
||||
compileSdkVersion 33
|
||||
defaultConfig {
|
||||
applicationId "com.metallic.chiaki"
|
||||
minSdkVersion 21
|
||||
targetSdkVersion 30
|
||||
versionCode 10
|
||||
targetSdkVersion 33
|
||||
versionCode 12
|
||||
versionName chiakiVersion
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
|
@ -33,6 +32,8 @@ android {
|
|||
"-DCHIAKI_ENABLE_GUI=OFF",
|
||||
"-DCHIAKI_ENABLE_SETSU=OFF",
|
||||
"-DCHIAKI_ENABLE_ANDROID=ON",
|
||||
"-DCHIAKI_ENABLE_FFMPEG_DECODER=OFF",
|
||||
"-DCHIAKI_ENABLE_PI_DECODER=OFF",
|
||||
"-DCHIAKI_LIB_ENABLE_OPUS=OFF",
|
||||
"-DCHIAKI_LIB_OPENSSL_EXTERNAL_PROJECT=ON"
|
||||
}
|
||||
|
@ -50,7 +51,7 @@ android {
|
|||
}
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
version "3.10.2+"
|
||||
version "3.22.1"
|
||||
path rootCMakeLists
|
||||
}
|
||||
}
|
||||
|
@ -93,23 +94,23 @@ tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all {
|
|||
dependencies {
|
||||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||
implementation 'androidx.appcompat:appcompat:1.2.0'
|
||||
implementation 'androidx.core:core-ktx:1.3.2'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
|
||||
implementation 'androidx.recyclerview:recyclerview:1.1.0'
|
||||
implementation 'androidx.preference:preference:1.1.1'
|
||||
implementation 'com.google.android.material:material:1.2.1'
|
||||
implementation 'androidx.appcompat:appcompat:1.6.0'
|
||||
implementation 'androidx.core:core-ktx:1.9.0'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
|
||||
implementation 'androidx.recyclerview:recyclerview:1.2.1'
|
||||
implementation 'androidx.preference:preference:1.2.0'
|
||||
implementation 'com.google.android.material:material:1.8.0'
|
||||
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
|
||||
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0'
|
||||
implementation 'androidx.lifecycle:lifecycle-reactivestreams:2.2.0'
|
||||
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1'
|
||||
implementation 'androidx.lifecycle:lifecycle-reactivestreams:2.5.1'
|
||||
implementation "io.reactivex.rxjava2:rxjava:2.2.20"
|
||||
implementation "io.reactivex.rxjava2:rxkotlin:2.4.0"
|
||||
implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
|
||||
def room_version = "2.2.6"
|
||||
def room_version = "2.5.0"
|
||||
implementation "androidx.room:room-runtime:$room_version"
|
||||
kapt "androidx.room:room-compiler:$room_version"
|
||||
implementation "androidx.room:room-ktx:$room_version"
|
||||
implementation "androidx.room:room-rxjava2:$room_version"
|
||||
implementation "com.squareup.moshi:moshi:1.9.2"
|
||||
kapt "com.squareup.moshi:moshi-kotlin-codegen:1.9.2"
|
||||
implementation "com.squareup.moshi:moshi:1.14.0"
|
||||
kapt "com.squareup.moshi:moshi-kotlin-codegen:1.14.0"
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.VIBRATE" />
|
||||
<uses-permission android:name="android.permission.HIGH_SAMPLING_RATE_SENSORS" />
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
|
@ -28,7 +29,8 @@
|
|||
</provider>
|
||||
|
||||
<activity android:name=".main.MainActivity"
|
||||
android:configChanges="keyboard|keyboardHidden|orientation|screenSize">
|
||||
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
|
|
|
@ -110,9 +110,9 @@ JNIEXPORT jstring JNICALL JNI_FCN(quitReasonToString)(JNIEnv *env, jobject obj,
|
|||
return E->NewStringUTF(env, chiaki_quit_reason_string((ChiakiQuitReason)value));
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL JNI_FCN(quitReasonIsStopped)(JNIEnv *env, jobject obj, jint value)
|
||||
JNIEXPORT jboolean JNICALL JNI_FCN(quitReasonIsError)(JNIEnv *env, jobject obj, jint value)
|
||||
{
|
||||
return value == CHIAKI_QUIT_REASON_STOPPED;
|
||||
return chiaki_quit_reason_is_error(value);
|
||||
}
|
||||
|
||||
JNIEXPORT jobject JNICALL JNI_FCN(videoProfilePreset)(JNIEnv *env, jobject obj, jint resolution_preset, jint fps_preset, jobject codec)
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 0ab5b12a5bc3630a3d6c83b20eed2a669ebf7a24
|
||||
Subproject commit 8740d0fc321a55489dbbf6067298201b7d2e106d
|
|
@ -3,7 +3,7 @@
|
|||
package com.metallic.chiaki.common
|
||||
|
||||
import androidx.room.*
|
||||
import androidx.room.ForeignKey.SET_NULL
|
||||
import androidx.room.ForeignKey.Companion.SET_NULL
|
||||
import io.reactivex.Completable
|
||||
import io.reactivex.Flowable
|
||||
import io.reactivex.Single
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
package com.metallic.chiaki.common
|
||||
|
||||
import androidx.room.*
|
||||
import androidx.room.ColumnInfo.BLOB
|
||||
import androidx.room.ColumnInfo.Companion.BLOB
|
||||
import com.metallic.chiaki.lib.RegistHost
|
||||
import com.metallic.chiaki.lib.Target
|
||||
import io.reactivex.Completable
|
||||
|
|
|
@ -25,6 +25,8 @@ import io.reactivex.rxkotlin.addTo
|
|||
import io.reactivex.schedulers.Schedulers
|
||||
import okio.Buffer
|
||||
import okio.Okio
|
||||
import okio.buffer
|
||||
import okio.source
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
|
||||
|
@ -164,7 +166,7 @@ fun importSettingsFromUri(activity: Activity, uri: Uri, disposable: CompositeDis
|
|||
try
|
||||
{
|
||||
val inputStream = activity.contentResolver.openInputStream(uri) ?: throw IOException()
|
||||
val buffer = Okio.buffer(Okio.source(inputStream))
|
||||
val buffer = inputStream.source().buffer()
|
||||
val reader = JsonReader.of(buffer)
|
||||
val adapter = moshi().serializedSettingsAdapter()
|
||||
|
||||
|
|
|
@ -83,7 +83,7 @@ private class ChiakiNative
|
|||
}
|
||||
@JvmStatic external fun errorCodeToString(value: Int): String
|
||||
@JvmStatic external fun quitReasonToString(value: Int): String
|
||||
@JvmStatic external fun quitReasonIsStopped(value: Int): Boolean
|
||||
@JvmStatic external fun quitReasonIsError(value: Int): Boolean
|
||||
@JvmStatic external fun videoProfilePreset(resolutionPreset: Int, fpsPreset: Int, codec: Codec): ConnectVideoProfile
|
||||
@JvmStatic external fun sessionCreate(result: CreateResult, connectInfo: ConnectInfo, logFile: String?, logVerbose: Boolean, javaSession: Session)
|
||||
@JvmStatic external fun sessionFree(ptr: Long)
|
||||
|
@ -309,10 +309,7 @@ class QuitReason(val value: Int)
|
|||
{
|
||||
override fun toString() = ChiakiNative.quitReasonToString(value)
|
||||
|
||||
/**
|
||||
* whether the reason is CHIAKI_QUIT_REASON_STOPPED
|
||||
*/
|
||||
val isStopped = ChiakiNative.quitReasonIsStopped(value)
|
||||
val isError = ChiakiNative.quitReasonIsError(value)
|
||||
}
|
||||
|
||||
sealed class Event
|
||||
|
|
|
@ -174,7 +174,7 @@ class StreamActivity : AppCompatActivity(), View.OnSystemUiVisibilityChangeListe
|
|||
.alpha(1.0f)
|
||||
.setListener(object: AnimatorListenerAdapter()
|
||||
{
|
||||
override fun onAnimationEnd(animation: Animator?)
|
||||
override fun onAnimationEnd(animation: Animator)
|
||||
{
|
||||
binding.overlay.alpha = 1.0f
|
||||
}
|
||||
|
@ -189,7 +189,7 @@ class StreamActivity : AppCompatActivity(), View.OnSystemUiVisibilityChangeListe
|
|||
.alpha(0.0f)
|
||||
.setListener(object: AnimatorListenerAdapter()
|
||||
{
|
||||
override fun onAnimationEnd(animation: Animator?)
|
||||
override fun onAnimationEnd(animation: Animator)
|
||||
{
|
||||
binding.overlay.isGone = true
|
||||
}
|
||||
|
@ -230,28 +230,33 @@ class StreamActivity : AppCompatActivity(), View.OnSystemUiVisibilityChangeListe
|
|||
{
|
||||
is StreamStateQuit ->
|
||||
{
|
||||
if(!state.reason.isStopped && dialogContents != StreamQuitDialog)
|
||||
if(dialogContents != StreamQuitDialog)
|
||||
{
|
||||
dialog?.dismiss()
|
||||
val reasonStr = state.reasonString
|
||||
val dialog = MaterialAlertDialogBuilder(this)
|
||||
.setMessage(getString(R.string.alert_message_session_quit, state.reason.toString())
|
||||
+ (if(reasonStr != null) "\n$reasonStr" else ""))
|
||||
.setPositiveButton(R.string.action_reconnect) { _, _ ->
|
||||
dialog = null
|
||||
reconnect()
|
||||
}
|
||||
.setOnCancelListener {
|
||||
dialog = null
|
||||
finish()
|
||||
}
|
||||
.setNegativeButton(R.string.action_quit_session) { _, _ ->
|
||||
dialog = null
|
||||
finish()
|
||||
}
|
||||
.create()
|
||||
dialogContents = StreamQuitDialog
|
||||
dialog.show()
|
||||
if(state.reason.isError)
|
||||
{
|
||||
dialog?.dismiss()
|
||||
val reasonStr = state.reasonString
|
||||
val dialog = MaterialAlertDialogBuilder(this)
|
||||
.setMessage(getString(R.string.alert_message_session_quit, state.reason.toString())
|
||||
+ (if(reasonStr != null) "\n$reasonStr" else ""))
|
||||
.setPositiveButton(R.string.action_reconnect) { _, _ ->
|
||||
dialog = null
|
||||
reconnect()
|
||||
}
|
||||
.setOnCancelListener {
|
||||
dialog = null
|
||||
finish()
|
||||
}
|
||||
.setNegativeButton(R.string.action_quit_session) { _, _ ->
|
||||
dialog = null
|
||||
finish()
|
||||
}
|
||||
.create()
|
||||
dialogContents = StreamQuitDialog
|
||||
dialog.show()
|
||||
}
|
||||
else
|
||||
finish()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -306,6 +311,8 @@ class StreamActivity : AppCompatActivity(), View.OnSystemUiVisibilityChangeListe
|
|||
dialog.show()
|
||||
}
|
||||
}
|
||||
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||
|
||||
buildscript {
|
||||
ext.kotlin_version = '1.4.21'
|
||||
ext.kotlin_version = '1.8.0'
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:4.1.1'
|
||||
classpath 'com.android.tools.build:gradle:7.4.1'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#Fri Jan 15 11:37:05 CET 2021
|
||||
#Sun Feb 05 16:25:19 CET 2023
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
|
266
assets/chiaki_macos.svg
Normal file
266
assets/chiaki_macos.svg
Normal file
|
@ -0,0 +1,266 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="1024"
|
||||
height="1024"
|
||||
viewBox="0 0 270.93332 270.93334"
|
||||
version="1.1"
|
||||
id="svg5"
|
||||
inkscape:version="1.2.1 (9c6d41e, 2022-07-14)"
|
||||
sodipodi:docname="chiaki_macos.svg"
|
||||
xml:space="preserve"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"><sodipodi:namedview
|
||||
id="namedview7"
|
||||
pagecolor="#505050"
|
||||
bordercolor="#eeeeee"
|
||||
borderopacity="1"
|
||||
inkscape:showpageshadow="0"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pagecheckerboard="true"
|
||||
inkscape:deskcolor="#505050"
|
||||
inkscape:document-units="mm"
|
||||
showgrid="false"
|
||||
inkscape:zoom="0.5946522"
|
||||
inkscape:cx="616.32665"
|
||||
inkscape:cy="519.63148"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="978"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="25"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="layer1"
|
||||
showguides="true"><sodipodi:guide
|
||||
position="26.458333,219.96511"
|
||||
orientation="-1,0"
|
||||
id="guide1357"
|
||||
inkscape:locked="false"
|
||||
inkscape:label=""
|
||||
inkscape:color="rgb(0,134,229)" /><sodipodi:guide
|
||||
position="50.653599,244.475"
|
||||
orientation="0,1"
|
||||
id="guide1359"
|
||||
inkscape:locked="false"
|
||||
inkscape:label=""
|
||||
inkscape:color="rgb(0,134,229)" /><sodipodi:guide
|
||||
position="244.475,210.52655"
|
||||
orientation="-1,0"
|
||||
id="guide1361"
|
||||
inkscape:locked="false"
|
||||
inkscape:label=""
|
||||
inkscape:color="rgb(0,134,229)" /><sodipodi:guide
|
||||
position="67.733332,26.458333"
|
||||
orientation="0,1"
|
||||
id="guide1363"
|
||||
inkscape:locked="false"
|
||||
inkscape:label=""
|
||||
inkscape:color="rgb(0,134,229)" /><sodipodi:guide
|
||||
position="135.46666,253.78662"
|
||||
orientation="-1,0"
|
||||
id="guide4345"
|
||||
inkscape:locked="false"
|
||||
inkscape:label=""
|
||||
inkscape:color="rgb(0,134,229)" /></sodipodi:namedview><defs
|
||||
id="defs2"><linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient4465"><stop
|
||||
style="stop-color:#f1ff7f;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop4461" /><stop
|
||||
style="stop-color:#b2d400;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop4463" /></linearGradient><filter
|
||||
x="-0.014563107"
|
||||
y="-0.014563107"
|
||||
width="1.0291262"
|
||||
height="1.0412621"
|
||||
filterUnits="objectBoundingBox"
|
||||
id="filter-80aygx4sbj-3"><feOffset
|
||||
dx="0"
|
||||
dy="5"
|
||||
in="SourceAlpha"
|
||||
result="shadowOffsetOuter1"
|
||||
id="feOffset424" /><feGaussianBlur
|
||||
stdDeviation="2.5"
|
||||
in="shadowOffsetOuter1"
|
||||
result="shadowBlurOuter1"
|
||||
id="feGaussianBlur426" /><feColorMatrix
|
||||
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.3 0"
|
||||
type="matrix"
|
||||
in="shadowBlurOuter1"
|
||||
id="feColorMatrix428" /></filter><clipPath
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath869"><path
|
||||
d="m -143.73827,56.831818 a 79.375,79.375 0 0 1 102.042535,2e-6 l -51.021268,60.80478 z"
|
||||
sodipodi:end="5.4105207"
|
||||
sodipodi:start="4.0142573"
|
||||
sodipodi:ry="79.375"
|
||||
sodipodi:rx="79.375"
|
||||
sodipodi:cy="117.6366"
|
||||
sodipodi:cx="-92.717003"
|
||||
sodipodi:type="arc"
|
||||
id="path871"
|
||||
style="fill:#008080;fill-opacity:1;stroke:none;stroke-width:11.1206;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
sodipodi:arc-type="slice" /></clipPath><clipPath
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath964"><circle
|
||||
style="display:inline;fill:#ff9955;fill-opacity:1;stroke:none;stroke-width:8.46667;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="circle966"
|
||||
cx="-135.46669"
|
||||
cy="161.49431"
|
||||
r="135.46667"
|
||||
inkscape:label="circle"
|
||||
transform="scale(-1,1)" /></clipPath><clipPath
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath4387"><path
|
||||
d="m 270.31599,96.939968 c 0,-3.20165 0,-6.403627 -0.0173,-9.605605 -0.0174,-2.697285 -0.0473,-5.393909 -0.12049,-8.089885 -0.15834,-5.876017 -0.50503,-11.802446 -1.55009,-17.613009 -1.05975,-5.894353 -2.79053,-11.380228 -5.51791,-16.735846 -2.68122,-5.26397 -6.18365,-10.080848 -10.3626,-14.256872 -4.17798,-4.176024 -8.99614,-7.676173 -14.26207,-10.355782 -5.36116,-2.728048 -10.85292,-4.458156 -16.75377,-5.517628 -5.81122,-1.043433 -11.73926,-1.38939 -17.61526,-1.54813 -2.69792,-0.07299 -5.39585,-0.103764 -8.09443,-0.120439 -3.2036,-0.01955 -6.40721,-0.01806 -9.61081,-0.01806 L 149.2133,12.945506 h -27.8204 l -36.538684,0.133205 c -3.209827,0 -6.419646,-0.0016 -9.629466,0.01806 -2.704145,0.01657 -5.406981,0.04745 -8.110144,0.120439 -5.889745,0.158737 -11.831203,0.505024 -17.656149,1.549765 -5.908728,1.059145 -11.408663,2.788599 -16.777022,5.514685 -5.277041,2.679934 -10.105685,6.18041 -14.292493,10.35709 -4.186156,4.175697 -7.695131,8.991593 -10.3812753,14.254581 -2.734911,5.35823 -4.4689412,10.84739 -5.5313527,16.74501 -1.0460477,5.808273 -1.3926574,11.732737 -1.55205319,17.606136 -0.0726642,2.696304 -0.10408515,5.392927 -0.12043909,8.089885 -0.0195464,3.202305 -0.18427009,7.179987 -0.18427009,10.381964 v 36.032494 28.11836 l 0.16625869,36.79805 c 0,3.20624 -0.001309,6.41247 0.0180605,9.6187 0.0163323,2.70089 0.0477729,5.40111 0.12078473,8.10101 0.15905935,5.88356 0.50633015,11.81849 1.55336045,17.63691 1.0620848,5.90221 2.7957884,11.39593 5.5284083,16.75842 2.6864707,5.27149 6.1960987,10.09461 10.3825837,14.27651 4.186482,4.18193 9.013815,7.68665 14.289876,10.3702 5.37163,2.73164 10.874184,4.46402 16.786519,5.52481 5.82232,1.04508 11.761815,1.39168 17.649275,1.55042 2.703163,0.073 5.406326,0.10416 8.110465,0.12049 3.20982,0.0198 6.419318,0.0198 9.629138,0.0198 h 36.868929 27.88948 36.79758 c 3.2036,0 6.40721,0 9.61081,-0.0198 2.69858,-0.0174 5.39651,-0.0475 8.09444,-0.12049 5.87828,-0.15908 11.8083,-0.506 17.62211,-1.55173 5.89727,-1.06076 11.38641,-2.79253 16.74462,-5.52253 5.26689,-2.68321 10.08605,-6.18859 14.26436,-10.37117 4.17829,-4.18126 7.68039,-9.00371 10.36162,-14.27421 2.72902,-5.36511 4.45979,-10.86145 5.52024,-16.7676 1.04409,-5.81612 1.39036,-11.74877 1.5491,-17.63003 0.073,-2.70023 0.10416,-5.40045 0.11999,-8.10101 0.0173,-3.20623 0.0173,-6.41246 0.0173,-9.6187 0,0 0,-36.14835 0,-36.79805 v -28.14782 c 0,-0.47982 0,-36.779393 0,-36.779393"
|
||||
id="path4389"
|
||||
style="fill:#cfff0d;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.654602"
|
||||
inkscape:label="clip" /></clipPath><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4465"
|
||||
id="linearGradient4467"
|
||||
x1="67.73333"
|
||||
y1="13.229165"
|
||||
x2="67.73333"
|
||||
y2="122.2375"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(2.0000001,0,0,2.0000001,5.0529028e-6,-2.9497097e-5)" /><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4465"
|
||||
id="linearGradient1573"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="67.73333"
|
||||
y1="13.229165"
|
||||
x2="67.73333"
|
||||
y2="122.2375"
|
||||
gradientTransform="matrix(1.9999999,0,0,1.9999999,-8.9032287e-4,7.677083e-6)" /></defs><g
|
||||
inkscape:label="Ebene 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"><path
|
||||
d="m 417,128.31353 c 0,-4.89098 0,-9.78246 -0.0281,-14.67394 -0.0245,-4.12049 -0.072,-8.23997 -0.184,-12.35846 -0.242,-8.976466 -0.77149,-18.029933 -2.36798,-26.906401 C 412.80098,65.370262 410.157,56.989792 405.99053,48.808322 401.89456,40.766852 396.5441,33.408378 390.16015,27.028902 383.7777,20.649425 376.41725,15.302444 368.37281,11.208959 360.18287,7.0414744 351.79343,4.398484 342.779,2.7799899 333.90156,1.1859957 324.84563,0.65749761 315.8692,0.41499849 311.74773,0.3034989 307.62626,0.25649907 303.50379,0.23099916 298.60983,0.20099927 293.71586,0.20349926 288.8219,0.20349926 L 231.99832,0 h -42.49969 l -55.81808,0.20349926 c -4.90347,0 -9.80693,-0.0025 -14.71039,0.0274999 -4.13097,0.0254999 -8.25994,0.0724997 -12.38941,0.18399933 C 97.583315,0.65749761 88.506882,1.1864957 79.608448,2.7824899 70.582015,4.400484 62.180077,7.0424744 53.979137,11.206959 45.917697,15.300944 38.541252,20.648425 32.145299,27.028902 25.750346,33.407878 20.389886,40.764852 16.286417,48.804822 12.108447,56.990293 9.459467,65.375762 7.836479,74.385229 6.2384908,83.258197 5.7089948,92.308664 5.4654965,101.28113 5.3544974,105.40012 5.3064977,109.5196 5.2814979,113.63959 5.2514981,118.53157 5,124.60805 5,129.49953 v 55.0448 42.95484 l 0.2539981,56.2143 c 0,4.89798 -0.002,9.79596 0.0275,14.69394 0.025,4.12599 0.072999,8.25097 0.1844986,12.37546 0.2429983,8.98797 0.7734943,18.05443 2.3729825,26.9429 1.622488,9.01647 4.2709678,17.40894 8.4454378,25.60091 4.103969,8.05297 9.465429,15.42094 15.860882,21.80942 6.395453,6.38848 13.769898,11.74245 21.829839,15.84194 8.205939,4.17298 16.611876,6.81947 25.64381,8.43997 8.894434,1.59649 17.967867,2.12599 26.961802,2.36849 4.12947,0.1115 8.25894,0.159 12.38991,0.184 C 123.87412,412 128.77708,412 133.68055,412 h 56.32258 42.60518 56.21359 c 4.89396,0 9.78793,0 14.68189,-0.0295 4.12247,-0.025 8.24394,-0.0725 12.36541,-0.184 8.97993,-0.243 18.03887,-0.773 26.9203,-2.37049 9.00893,-1.62049 17.39437,-4.26598 25.57981,-8.43647 8.04594,-4.09898 15.40789,-9.45397 21.79084,-15.84344 6.38295,-6.38748 11.73291,-13.75445 15.82888,-21.80592 4.16897,-8.19597 6.81295,-16.59244 8.43294,-25.61491 1.59499,-8.88497 2.12398,-17.94793 2.36648,-26.9324 0.1115,-4.12499 0.159,-8.24997 0.1835,-12.37546 C 417,293.50943 417,288.61145 417,283.71347 c 0,0 0,-55.2218 0,-56.2143 v -42.99984 c 0,-0.733 0,-56.1858 0,-56.1858"
|
||||
id="use436"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;filter:url(#filter-80aygx4sbj-3)"
|
||||
transform="matrix(0.52916669,0,0,0.52916669,23.8125,26.458334)" /><path
|
||||
d="m 244.475,94.357609 c 0,-2.588144 0,-5.176552 -0.014,-7.76496 -0.014,-2.180426 -0.0382,-4.360318 -0.0974,-6.539686 -0.128,-4.750046 -0.40826,-9.540837 -1.25306,-14.237969 -0.85668,-4.764864 -2.2558,-9.199528 -4.46056,-13.52889 -2.16744,-4.255278 -4.99872,-8.149136 -8.3769,-11.524941 -3.37738,-3.375806 -7.27228,-6.20525 -11.52914,-8.371386 -4.33384,-2.205294 -8.77326,-3.603876 -13.54338,-4.46033 -4.69766,-0.843488 -9.48976,-1.123152 -14.23978,-1.251474 -2.18094,-0.059 -4.3619,-0.08388 -6.54336,-0.09736 -2.58972,-0.0158 -5.17946,-0.0146 -7.76918,-0.0146 l -30.06997,-0.10768 h -22.48942 l -29.537067,0.10768 c -2.594752,0 -5.1895,-0.0013 -7.784248,0.0146 -2.185972,0.0134 -4.370884,0.03836 -6.556062,0.09736 -4.761142,0.12832 -9.564087,0.40825 -14.272841,1.252796 -4.776488,0.85619 -9.222514,2.254242 -13.562178,4.45795 -4.265844,2.1664 -8.169214,4.996108 -11.553737,8.372444 -3.383996,3.375541 -6.220574,7.268605 -8.391994,11.523089 -2.210842,4.331478 -3.612594,8.76879 -4.471424,13.536298 -0.845602,4.69528 -1.125794,9.484485 -1.254646,14.232413 -0.05874,2.179634 -0.08414,4.359524 -0.09736,6.539686 -0.0158,2.588674 -0.14896,5.804144 -0.14896,8.392552 v 29.127869 22.73027 l 0.1344,29.74674 c 0,2.59184 -0.0011,5.18368 0.0146,7.77554 0.0132,2.18334 0.03862,4.36614 0.09764,6.54868 0.12858,4.75614 0.409306,9.5538 1.255702,14.25728 0.858566,4.77122 2.260054,9.21222 4.469044,13.54714 2.171684,4.26136 5.00879,8.16026 8.393052,11.54082 3.384259,3.38058 7.286569,6.21372 11.551621,8.38304 4.34231,2.2082 8.790452,3.60862 13.56985,4.46614 4.706638,0.84482 9.507995,1.125 14.267285,1.25332 2.185178,0.059 4.370356,0.0842 6.556326,0.0974 2.594748,0.016 5.189232,0.016 7.783984,0.016 h 29.804033 22.54524 29.74635 c 2.58972,0 5.17944,0 7.76916,-0.016 2.18148,-0.014 4.36242,-0.0384 6.54338,-0.0974 4.75188,-0.1286 9.54556,-0.40904 14.24532,-1.25438 4.76722,-0.8575 9.20452,-2.25742 13.53598,-4.4643 4.25764,-2.16904 8.15334,-5.00272 11.531,-8.38382 3.37764,-3.38004 6.20866,-7.2784 8.3761,-11.53896 2.20608,-4.33704 3.6052,-8.78016 4.46244,-13.55456 0.84402,-4.70162 1.12394,-9.49744 1.25226,-14.25172 0.059,-2.18282 0.0842,-4.36562 0.097,-6.54868 0.014,-2.59186 0.014,-5.1837 0.014,-7.77554 0,0 0,-29.22154 0,-29.74674 v -22.75408 c 0,-0.38788 0,-29.731651 0,-29.731651"
|
||||
id="use438"
|
||||
style="display:inline;fill:url(#linearGradient1573);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.529166" /><path
|
||||
id="path1446"
|
||||
style="display:none;fill:url(#linearGradient4467);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.529166"
|
||||
inkscape:label="bg_cut"
|
||||
d="m 124.0896,26.458306 -29.537222,0.10748 c -2.59475,0 -5.188758,-0.0015 -7.783504,0.0144 -2.18597,0.0134 -4.37153,0.03918 -6.556706,0.09818 -4.761139,0.12832 -9.564283,0.408092 -14.273031,1.252638 -4.776484,0.856188 -9.222305,2.253902 -13.561965,4.457609 -4.26584,2.166398 -8.169296,4.996284 -11.553817,8.372616 -3.383992,3.375538 -6.219802,7.268332 -8.39122,11.522813 -2.210838,4.331472 -3.613248,8.76862 -4.472078,13.536124 -0.8456,4.695277 -1.125852,9.484801 -1.254704,14.232723 -0.05874,2.179632 -0.08394,4.358977 -0.09716,6.539137 -0.0158,2.588672 -0.14882,5.804882 -0.14882,8.393286 V 108.73021 H 244.47502 V 94.35796 h 0.001 c 0,-2.58814 -4.8e-4,-5.177528 -0.014,-7.765934 -0.014,-2.180424 -0.038,-4.359771 -0.0972,-6.539137 -0.128,-4.75004 -0.40784,-9.540762 -1.25264,-14.237891 -0.85668,-4.76486 -2.25596,-9.199532 -4.46072,-13.52889 -2.16744,-4.255275 -4.99856,-8.149077 -8.37674,-11.524879 -3.37738,-3.375802 -7.27216,-6.205448 -11.52902,-8.371582 -4.33384,-2.205293 -8.77324,-3.604257 -13.54336,-4.460711 -4.69766,-0.843486 -9.48993,-1.122248 -14.23996,-1.25057 -2.18094,-0.059 -4.36179,-0.0847 -6.54327,-0.09818 -2.58971,-0.0158 -5.18035,-0.0144 -7.77006,-0.0144 l -30.06949,-0.10748 z m -97.498969,149.491654 0.0032,0.63976 c 0,2.59184 -0.0012,5.18442 0.0144,7.77627 0.0132,2.18333 0.03916,4.36589 0.09818,6.54843 0.12858,4.75613 0.408308,9.55406 1.254704,14.25754 0.858566,4.7712 2.261024,9.21154 4.470012,13.54646 2.171682,4.26134 5.007994,8.16086 8.392252,11.5414 3.384257,3.38058 7.286703,6.21364 11.551751,8.38296 4.342306,2.2082 8.790839,3.60836 13.570231,4.46588 4.706634,0.84482 9.507544,1.12534 14.266831,1.25366 2.185176,0.059 4.370738,0.084 6.556706,0.0972 2.594746,0.016 5.188754,0.016 7.783504,0.016 h 29.804898 22.54437 29.74702 c 2.58972,0 5.17932,5e-4 7.76903,-0.016 2.18148,-0.014 4.36233,-0.0382 6.54327,-0.0972 4.75188,-0.1286 9.54537,-0.40936 14.24513,-1.2547 4.76722,-0.8575 9.20466,-2.25694 13.53612,-4.4638 4.25764,-2.16904 8.15342,-5.0029 11.53108,-8.384 3.37764,-3.38002 6.20828,-7.27878 8.37572,-11.53934 2.20608,-4.33704 3.60554,-8.78034 4.46278,-13.55472 0.84402,-4.70162 1.12432,-9.49706 1.25264,-14.25134 0.059,-2.1828 0.0834,-4.36536 0.0962,-6.54843 0.014,-2.59185 0.014,-5.18443 0.014,-7.77627 v -0.63976 z" /><g
|
||||
id="g1005"
|
||||
inkscape:label="main icon"
|
||||
clip-path="url(#clipPath4387)"
|
||||
style="display:inline"
|
||||
transform="matrix(0.80837807,0,0,0.80837807,25.958398,15.993434)"><rect
|
||||
inkscape:label="bg"
|
||||
ry="1.0565645"
|
||||
y="20.8298"
|
||||
x="-4.0937502e-07"
|
||||
height="270.93335"
|
||||
width="270.93335"
|
||||
id="rect873"
|
||||
style="display:none;fill:#cfff0d;fill-opacity:1;stroke:none;stroke-width:8.46431;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /><g
|
||||
id="g1033"
|
||||
inkscape:label="right (original)"
|
||||
transform="matrix(-1,0,0,1,262.28035,14.266743)"
|
||||
style="display:none;stroke:none"><path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path1019"
|
||||
d="M -8.6529992,183.6071 H 107.72321 l 19.09046,28.9079 V 100.45235 H -8.6529992 Z"
|
||||
style="display:inline;fill:#162d50;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
sodipodi:nodetypes="cccccc"
|
||||
inkscape:label="face" /><rect
|
||||
style="fill:#ffaaee;fill-opacity:1;stroke:none;stroke-width:0.185662;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
id="rect1021"
|
||||
width="15.497028"
|
||||
height="31.75"
|
||||
x="92.382744"
|
||||
y="131.06844"
|
||||
inkscape:label="eye" /><path
|
||||
sodipodi:type="star"
|
||||
style="fill:#162d50;fill-opacity:1;stroke:none;stroke-width:0.5;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
id="path1023"
|
||||
sodipodi:sides="3"
|
||||
sodipodi:cx="75.635689"
|
||||
sodipodi:cy="87.601158"
|
||||
sodipodi:r1="33.042126"
|
||||
sodipodi:r2="16.521063"
|
||||
sodipodi:arg1="0.52359878"
|
||||
sodipodi:arg2="1.5707963"
|
||||
inkscape:flatsided="false"
|
||||
inkscape:rounded="0"
|
||||
inkscape:randomized="0"
|
||||
d="m 104.25101,104.12222 -28.615321,0 -28.615321,0 14.30766,-24.781593 14.307661,-24.781595 14.30766,24.781594 z"
|
||||
inkscape:transform-center-y="-7.0654063"
|
||||
transform="matrix(0.70280031,0,0,0.85532099,32.495272,20.355967)"
|
||||
inkscape:label="ear" /><flowRoot
|
||||
xml:space="preserve"
|
||||
id="flowRoot1031"
|
||||
style="font-style:normal;font-weight:normal;font-size:40px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;display:inline;fill:#000000;fill-opacity:1;stroke:none"
|
||||
transform="matrix(0.26458333,0,0,0.26458333,-8.6529992,15.861276)"
|
||||
inkscape:label="flowRoot4545"><flowRegion
|
||||
id="flowRegion1027"
|
||||
style="stroke:none"><rect
|
||||
id="rect1025"
|
||||
width="104.28571"
|
||||
height="78.571426"
|
||||
x="-374.28571"
|
||||
y="54"
|
||||
style="stroke:none" /></flowRegion><flowPara
|
||||
id="flowPara1029" /></flowRoot></g><use
|
||||
style="display:none"
|
||||
inkscape:label="left"
|
||||
transform="matrix(-1,0,0,1,270.93336,-5.3256301e-6)"
|
||||
height="100%"
|
||||
width="100%"
|
||||
id="use4535"
|
||||
xlink:href="#g4527"
|
||||
y="0"
|
||||
x="0" /><g
|
||||
style="display:inline;stroke:none"
|
||||
transform="matrix(-1,0,0,1,262.28035,14.266743)"
|
||||
inkscape:label="face"
|
||||
id="g4527"><path
|
||||
style="display:inline;fill:#162d50;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 356.42773,228.50391 -38.0039,80.11132 -21.9375,46.24219 H -619.27414 V 669.14258 H 439.84766 L 512,778.40039 584.15234,669.14258 H 1613.2487 V 354.85742 H 727.51367 l -21.9375,-46.24219 -38.0039,-80.11132 -38.00586,80.11132 -21.9375,46.24219 H 512 416.37109 l -21.9375,-46.24219 z"
|
||||
id="path4518"
|
||||
inkscape:connector-curvature="0"
|
||||
inkscape:label="shape"
|
||||
transform="matrix(-0.26458333,0,0,0.26458333,262.28035,6.563066)"
|
||||
sodipodi:nodetypes="ccccccccccccccccccc" /><rect
|
||||
inkscape:label="eye right"
|
||||
y="131.18182"
|
||||
x="92.153267"
|
||||
height="31.75"
|
||||
width="15.875"
|
||||
id="rect1043"
|
||||
style="display:inline;fill:#ffaaee;fill-opacity:1;stroke:none;stroke-width:0.187912;stroke-miterlimit:4;stroke-dasharray:none" /><rect
|
||||
style="display:inline;fill:#ffaaee;fill-opacity:1;stroke:none;stroke-width:0.187912;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
id="rect1047"
|
||||
width="15.875"
|
||||
height="31.75"
|
||||
x="145.59911"
|
||||
y="131.18182"
|
||||
inkscape:label="eye left" /></g><g
|
||||
inkscape:label="dangerous_microwaves"
|
||||
clip-path="url(#clipPath869)"
|
||||
style="fill:none"
|
||||
transform="translate(187.02207,-8.675551)"
|
||||
id="g844"><circle
|
||||
inkscape:label="path830"
|
||||
r="58.208332"
|
||||
style="fill:none;fill-opacity:1;stroke:#162d50;stroke-width:8.46667;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path830"
|
||||
cx="-92.71701"
|
||||
cy="117.6366" /><circle
|
||||
r="41.241978"
|
||||
cy="117.6366"
|
||||
cx="-92.71701"
|
||||
id="circle840"
|
||||
style="fill:none;fill-opacity:1;stroke:#162d50;stroke-width:8.46667;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /></g></g></g></svg>
|
After Width: | Height: | Size: 20 KiB |
102
assets/chiaki_macos_simple.svg
Normal file
102
assets/chiaki_macos_simple.svg
Normal file
|
@ -0,0 +1,102 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="1024"
|
||||
height="1024"
|
||||
viewBox="0 0 270.93332 270.93334"
|
||||
version="1.1"
|
||||
id="svg5"
|
||||
xml:space="preserve"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"><defs
|
||||
id="defs2"><linearGradient
|
||||
id="linearGradient4465"><stop
|
||||
style="stop-color:#f6ffbc;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop4461" /><stop
|
||||
style="stop-color:#b4d700;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop4463" /></linearGradient><filter
|
||||
x="-0.014563107"
|
||||
y="-0.014563107"
|
||||
width="1.0291262"
|
||||
height="1.0412621"
|
||||
filterUnits="objectBoundingBox"
|
||||
id="filter-80aygx4sbj-3"><feOffset
|
||||
dx="0"
|
||||
dy="5"
|
||||
in="SourceAlpha"
|
||||
result="shadowOffsetOuter1"
|
||||
id="feOffset424" /><feGaussianBlur
|
||||
stdDeviation="2.5"
|
||||
in="shadowOffsetOuter1"
|
||||
result="shadowBlurOuter1"
|
||||
id="feGaussianBlur426" /><feColorMatrix
|
||||
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.3 0"
|
||||
type="matrix"
|
||||
in="shadowBlurOuter1"
|
||||
id="feColorMatrix428" /></filter><clipPath
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath964"><circle
|
||||
style="display:inline;fill:#ff9955;fill-opacity:1;stroke:none;stroke-width:8.46667;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="circle966"
|
||||
cx="-135.46669"
|
||||
cy="161.49431"
|
||||
r="135.46667"
|
||||
transform="scale(-1,1)" /></clipPath><linearGradient
|
||||
xlink:href="#linearGradient4465"
|
||||
id="linearGradient4467"
|
||||
x1="67.73333"
|
||||
y1="13.229165"
|
||||
x2="67.73333"
|
||||
y2="122.2375"
|
||||
gradientUnits="userSpaceOnUse" /><linearGradient
|
||||
xlink:href="#linearGradient4465-9"
|
||||
id="linearGradient4467-7"
|
||||
x1="67.73333"
|
||||
y1="13.229165"
|
||||
x2="67.73333"
|
||||
y2="122.2375"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(-7.288516e-4,6.5027792e-5)" /><linearGradient
|
||||
id="linearGradient4465-9"><stop
|
||||
style="stop-color:#f1ff7f;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop4461-3" /><stop
|
||||
style="stop-color:#b2d400;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop4463-8" /></linearGradient></defs><g
|
||||
id="layer1"
|
||||
transform="matrix(2.0000001,0,0,2.0000001,4.2905177e-6,-3.0059484e-5)"><path
|
||||
d="m 417,128.31353 c 0,-4.89098 0,-9.78246 -0.0281,-14.67394 -0.0245,-4.12049 -0.072,-8.23997 -0.184,-12.35846 -0.242,-8.976466 -0.77149,-18.029933 -2.36798,-26.906401 C 412.80098,65.370262 410.157,56.989792 405.99053,48.808322 401.89456,40.766852 396.5441,33.408378 390.16015,27.028902 383.7777,20.649425 376.41725,15.302444 368.37281,11.208959 360.18287,7.0414744 351.79343,4.398484 342.779,2.7799899 333.90156,1.1859957 324.84563,0.65749761 315.8692,0.41499849 311.74773,0.3034989 307.62626,0.25649907 303.50379,0.23099916 298.60983,0.20099927 293.71586,0.20349926 288.8219,0.20349926 L 231.99832,0 h -42.49969 l -55.81808,0.20349926 c -4.90347,0 -9.80693,-0.0025 -14.71039,0.0274999 -4.13097,0.0254999 -8.25994,0.0724997 -12.38941,0.18399933 C 97.583315,0.65749761 88.506882,1.1864957 79.608448,2.7824899 70.582015,4.400484 62.180077,7.0424744 53.979137,11.206959 45.917697,15.300944 38.541252,20.648425 32.145299,27.028902 25.750346,33.407878 20.389886,40.764852 16.286417,48.804822 12.108447,56.990293 9.459467,65.375762 7.836479,74.385229 6.2384908,83.258197 5.7089948,92.308664 5.4654965,101.28113 5.3544974,105.40012 5.3064977,109.5196 5.2814979,113.63959 5.2514981,118.53157 5,124.60805 5,129.49953 v 55.0448 42.95484 l 0.2539981,56.2143 c 0,4.89798 -0.002,9.79596 0.0275,14.69394 0.025,4.12599 0.072999,8.25097 0.1844986,12.37546 0.2429983,8.98797 0.7734943,18.05443 2.3729825,26.9429 1.622488,9.01647 4.2709678,17.40894 8.4454378,25.60091 4.103969,8.05297 9.465429,15.42094 15.860882,21.80942 6.395453,6.38848 13.769898,11.74245 21.829839,15.84194 8.205939,4.17298 16.611876,6.81947 25.64381,8.43997 8.894434,1.59649 17.967867,2.12599 26.961802,2.36849 4.12947,0.1115 8.25894,0.159 12.38991,0.184 C 123.87412,412 128.77708,412 133.68055,412 h 56.32258 42.60518 56.21359 c 4.89396,0 9.78793,0 14.68189,-0.0295 4.12247,-0.025 8.24394,-0.0725 12.36541,-0.184 8.97993,-0.243 18.03887,-0.773 26.9203,-2.37049 9.00893,-1.62049 17.39437,-4.26598 25.57981,-8.43647 8.04594,-4.09898 15.40789,-9.45397 21.79084,-15.84344 6.38295,-6.38748 11.73291,-13.75445 15.82888,-21.80592 4.16897,-8.19597 6.81295,-16.59244 8.43294,-25.61491 1.59499,-8.88497 2.12398,-17.94793 2.36648,-26.9324 0.1115,-4.12499 0.159,-8.24997 0.1835,-12.37546 C 417,293.50943 417,288.61145 417,283.71347 c 0,0 0,-55.2218 0,-56.2143 v -42.99984 c 0,-0.733 0,-56.1858 0,-56.1858"
|
||||
id="use436"
|
||||
style="display:inline;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;filter:url(#filter-80aygx4sbj-3)"
|
||||
transform="matrix(0.26458333,0,0,0.26458333,11.906247,13.229181)" /><path
|
||||
id="path1446-0"
|
||||
style="display:inline;fill:url(#linearGradient4467-7);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.264583"
|
||||
d="m 62.044061,13.229232 -14.7686,0.05374 c -1.29738,0 -2.59438,-7.27e-4 -3.89175,0.0072 -1.09299,0.0067 -2.18577,0.01959 -3.27836,0.04909 -2.38057,0.06416 -4.78214,0.204046 -7.13651,0.626319 -2.38824,0.428094 -4.61115,1.126951 -6.78098,2.228804 -2.13292,1.083199 -4.08465,2.498142 -5.77691,4.186308 -1.692,1.687769 -3.1099,3.634166 -4.19561,5.761406 -1.10542,2.165736 -1.80663,4.38431 -2.23604,6.768062 -0.4228,2.347638 -0.56293,4.7424 -0.62735,7.116361 -0.0294,1.089816 -0.042,2.179488 -0.0486,3.269568 -0.008,1.294336 -0.0744,2.902441 -0.0744,4.196643 v 6.872449 H 122.23676 v -7.186125 h 5.2e-4 c 0,-1.29407 -2.4e-4,-2.588764 -0.007,-3.882967 -0.007,-1.090212 -0.019,-2.179885 -0.0486,-3.269568 -0.064,-2.37502 -0.20392,-4.770381 -0.62632,-7.118945 -0.42834,-2.38243 -1.12798,-4.599766 -2.23036,-6.764445 -1.08372,-2.127637 -2.49928,-4.074538 -4.18837,-5.762439 -1.68869,-1.687901 -3.63608,-3.102724 -5.76451,-4.185791 -2.16692,-1.102646 -4.38662,-1.802128 -6.77168,-2.230355 -2.34883,-0.421743 -4.744969,-0.561124 -7.119979,-0.625285 -1.09047,-0.0295 -2.1809,-0.04235 -3.27163,-0.04909 -1.29486,-0.0079 -2.59018,-0.0072 -3.88504,-0.0072 l -15.03474,-0.05374 z m -48.74947,74.745825 0.002,0.319877 c 0,1.295923 -6e-4,2.592212 0.007,3.888135 0.007,1.091667 0.0196,2.182948 0.0491,3.274218 0.0643,2.378065 0.20415,4.777033 0.62735,7.128773 0.42928,2.3856 1.13051,4.60577 2.235,6.77323 1.08584,2.13067 2.504,4.08043 4.19613,5.7707 1.69213,1.69029 3.64335,3.10682 5.77587,4.19148 2.17116,1.1041 4.39542,1.80418 6.78512,2.23294 2.35332,0.42241 4.75377,0.56267 7.13341,0.62683 1.09259,0.0295 2.18537,0.042 3.27836,0.0486 1.29737,0.008 2.59437,0.008 3.89175,0.008 h 14.90244 11.27219 14.87351 c 1.29485,0 2.58965,2.5e-4 3.88451,-0.008 1.09074,-0.007 2.18117,-0.0191 3.27164,-0.0486 2.37594,-0.0643 4.772679,-0.20468 7.122559,-0.62735 2.38361,-0.42875 4.60233,-1.12847 6.76806,-2.2319 2.12882,-1.08452 4.07671,-2.50145 5.76554,-4.192 1.68882,-1.69001 3.10414,-3.63939 4.18786,-5.76967 1.10304,-2.16852 1.80277,-4.39017 2.23139,-6.77736 0.42201,-2.35081 0.56216,-4.748534 0.62632,-7.125673 0.0295,-1.091402 0.0417,-2.182683 0.0481,-3.274218 0.007,-1.295923 0.007,-2.592212 0.007,-3.888135 v -0.319877 z" /><path
|
||||
id="path4518"
|
||||
style="display:inline;fill:#162d50;stroke:none;stroke-width:0.106942px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 51.096105,40.852287 -4.064351,8.567436 -2.345593,4.945434 H 13.229682 v 7.69152 11.365198 l 0.06563,14.553117 H 60.017007 L 67.733332,99.65955 75.449657,87.974992 H 122.2375 V 73.421875 62.044791 54.365157 H 90.780505 l -2.345594,-4.945434 -4.064351,-8.567436 -4.064351,8.567436 -2.346111,4.945434 H 67.733332 57.506567 l -2.34611,-4.945434 z" /><rect
|
||||
y="66.785446"
|
||||
x="-81.742691"
|
||||
height="12.833001"
|
||||
width="6.4165006"
|
||||
id="rect1043"
|
||||
style="display:inline;fill:#ffaaee;fill-opacity:1;stroke:none;stroke-width:0.075952;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
transform="scale(-1,1)" /><rect
|
||||
style="display:inline;fill:#ffaaee;fill-opacity:1;stroke:none;stroke-width:0.075952;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
id="rect1047"
|
||||
width="6.4165006"
|
||||
height="12.833001"
|
||||
x="-60.140472"
|
||||
y="66.785446"
|
||||
transform="scale(-1,1)" /><path
|
||||
id="path830"
|
||||
style="color:#000000;fill:#162d50;-inkscape-stroke:none"
|
||||
d="m 51.095589,26.798881 c -6.169023,0 -11.826367,2.225125 -16.215031,5.913334 l 2.185913,2.605009 c 3.790164,-3.181711 8.681211,-5.09633 14.029118,-5.09633 5.348221,0 10.239895,1.9148 14.030152,5.096847 l 2.185913,-2.605009 C 62.922884,29.024147 57.264963,26.798881 51.095589,26.798881 Z" /><path
|
||||
id="circle840"
|
||||
style="color:#000000;fill:#162d50;-inkscape-stroke:none"
|
||||
d="m 51.095589,33.656344 c -4.49058,0 -8.610793,1.621713 -11.807548,4.308781 l 2.18643,2.605525 c 2.597877,-2.180752 5.951484,-3.492293 9.621118,-3.492293 3.669777,0 7.024322,1.311388 9.622669,3.492293 l 2.185913,-2.605009 C 59.707311,35.278198 55.58652,33.656344 51.095589,33.656344 Z" /></g></svg>
|
After Width: | Height: | Size: 9.2 KiB |
|
@ -15,3 +15,4 @@ endif()
|
|||
|
||||
add_executable(chiaki-cli src/main.c)
|
||||
target_link_libraries(chiaki-cli chiaki-cli-lib)
|
||||
install(TARGETS chiaki-cli)
|
||||
|
|
|
@ -142,13 +142,19 @@ CHIAKI_EXPORT int chiaki_cli_cmd_discover(ChiakiLog *log, int argc, char *argv[]
|
|||
return 1;
|
||||
}
|
||||
|
||||
((struct sockaddr_in *)host_addr)->sin_port = htons(CHIAKI_DISCOVERY_PORT_PS4); // TODO: IPv6, PS5, should probably use the service
|
||||
|
||||
ChiakiDiscoveryPacket packet;
|
||||
memset(&packet, 0, sizeof(packet));
|
||||
packet.cmd = CHIAKI_DISCOVERY_CMD_SRCH;
|
||||
|
||||
chiaki_discovery_send(&discovery, &packet, host_addr, host_addr_len);
|
||||
packet.protocol_version = CHIAKI_DISCOVERY_PROTOCOL_VERSION_PS4;
|
||||
((struct sockaddr_in *)host_addr)->sin_port = htons(CHIAKI_DISCOVERY_PORT_PS4);
|
||||
err = chiaki_discovery_send(&discovery, &packet, host_addr, host_addr_len);
|
||||
if(err != CHIAKI_ERR_SUCCESS)
|
||||
CHIAKI_LOGE(log, "Failed to send discovery packet for PS4: %s", chiaki_error_string(err));
|
||||
packet.protocol_version = CHIAKI_DISCOVERY_PROTOCOL_VERSION_PS5;
|
||||
((struct sockaddr_in *)host_addr)->sin_port = htons(CHIAKI_DISCOVERY_PORT_PS5);
|
||||
err = chiaki_discovery_send(&discovery, &packet, host_addr, host_addr_len);
|
||||
if(err != CHIAKI_ERR_SUCCESS)
|
||||
CHIAKI_LOGE(log, "Failed to send discovery packet for PS5: %s", chiaki_error_string(err));
|
||||
|
||||
while(1)
|
||||
sleep(1); // TODO: wtf
|
||||
|
|
|
@ -11,10 +11,14 @@ static char doc[] = "Send a PS4 wakeup packet.";
|
|||
|
||||
#define ARG_KEY_HOST 'h'
|
||||
#define ARG_KEY_REGISTKEY 'r'
|
||||
#define ARG_KEY_PS4 '4'
|
||||
#define ARG_KEY_PS5 '5'
|
||||
|
||||
static struct argp_option options[] = {
|
||||
{ "host", ARG_KEY_HOST, "Host", 0, "Host to send wakeup packet to", 0 },
|
||||
{ "registkey", ARG_KEY_REGISTKEY, "RegistKey", 0, "PS4 registration key", 0 },
|
||||
{ "registkey", ARG_KEY_REGISTKEY, "RegistKey", 0, "Remote Play registration key (plaintext)", 0 },
|
||||
{ "ps4", ARG_KEY_PS4, NULL, 0, "PlayStation 4", 0 },
|
||||
{ "ps5", ARG_KEY_PS5, NULL, 0, "PlayStation 5 (default)", 0 },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
|
@ -22,6 +26,7 @@ typedef struct arguments
|
|||
{
|
||||
const char *host;
|
||||
const char *registkey;
|
||||
bool ps5;
|
||||
} Arguments;
|
||||
|
||||
static int parse_opt(int key, char *arg, struct argp_state *state)
|
||||
|
@ -39,6 +44,12 @@ static int parse_opt(int key, char *arg, struct argp_state *state)
|
|||
case ARGP_KEY_ARG:
|
||||
argp_usage(state);
|
||||
break;
|
||||
case ARG_KEY_PS4:
|
||||
arguments->ps5 = false;
|
||||
break;
|
||||
case ARG_KEY_PS5:
|
||||
arguments->ps5 = true;
|
||||
break;
|
||||
default:
|
||||
return ARGP_ERR_UNKNOWN;
|
||||
}
|
||||
|
@ -51,6 +62,7 @@ static struct argp argp = { options, parse_opt, 0, doc, 0, 0, 0 };
|
|||
CHIAKI_EXPORT int chiaki_cli_cmd_wakeup(ChiakiLog *log, int argc, char *argv[])
|
||||
{
|
||||
Arguments arguments = { 0 };
|
||||
arguments.ps5 = true;
|
||||
error_t argp_r = argp_parse(&argp, argc, argv, ARGP_IN_ORDER, NULL, &arguments);
|
||||
if(argp_r != 0)
|
||||
return 1;
|
||||
|
@ -73,5 +85,5 @@ CHIAKI_EXPORT int chiaki_cli_cmd_wakeup(ChiakiLog *log, int argc, char *argv[])
|
|||
|
||||
uint64_t credential = (uint64_t)strtoull(arguments.registkey, NULL, 16);
|
||||
|
||||
return chiaki_discovery_wakeup(log, NULL, arguments.host, credential, false);
|
||||
return chiaki_discovery_wakeup(log, NULL, arguments.host, credential, arguments.ps5);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,26 @@
|
|||
|
||||
find_package(SDL2 NO_MODULE QUIET)
|
||||
|
||||
# Adapted from libsdl-org/SDL_ttf: https://github.com/libsdl-org/SDL_ttf/blob/main/cmake/FindPrivateSDL2.cmake#L19-L31
|
||||
# Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
# Licensed under the zlib license (https://github.com/libsdl-org/SDL_ttf/blob/main/LICENSE.txt)
|
||||
set(SDL2_VERSION_MAJOR)
|
||||
set(SDL2_VERSION_MINOR)
|
||||
set(SDL2_VERSION_PATCH)
|
||||
set(SDL2_VERSION)
|
||||
if(SDL2_INCLUDE_DIR)
|
||||
file(READ "${SDL2_INCLUDE_DIR}/SDL_version.h" _sdl_version_h)
|
||||
string(REGEX MATCH "#define[ \t]+SDL_MAJOR_VERSION[ \t]+([0-9]+)" _sdl2_major_re "${_sdl_version_h}")
|
||||
set(SDL2_VERSION_MAJOR "${CMAKE_MATCH_1}")
|
||||
string(REGEX MATCH "#define[ \t]+SDL_MINOR_VERSION[ \t]+([0-9]+)" _sdl2_minor_re "${_sdl_version_h}")
|
||||
set(SDL2_VERSION_MINOR "${CMAKE_MATCH_1}")
|
||||
string(REGEX MATCH "#define[ \t]+SDL_PATCHLEVEL[ \t]+([0-9]+)" _sdl2_patch_re "${_sdl_version_h}")
|
||||
set(SDL2_VERSION_PATCH "${CMAKE_MATCH_1}")
|
||||
if(_sdl2_major_re AND _sdl2_minor_re AND _sdl2_patch_re)
|
||||
set(SDL2_VERSION "${SDL2_VERSION_MAJOR}.${SDL2_VERSION_MINOR}.${SDL2_VERSION_PATCH}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(SDL2_FOUND AND (NOT TARGET SDL2::SDL2))
|
||||
add_library(SDL2::SDL2 UNKNOWN IMPORTED GLOBAL)
|
||||
if(NOT SDL2_LIBDIR)
|
||||
|
|
|
@ -33,8 +33,8 @@ endif()
|
|||
|
||||
find_program(MAKE_EXE NAMES gmake make)
|
||||
ExternalProject_Add(OpenSSL-ExternalProject
|
||||
URL https://www.openssl.org/source/openssl-1.1.1d.tar.gz
|
||||
URL_HASH SHA256=1e3a91bc1f9dfce01af26026f856e064eab4c8ee0a8f457b5ae30b40b8b711f2
|
||||
URL https://www.openssl.org/source/openssl-1.1.1s.tar.gz
|
||||
URL_HASH SHA256=c5ac01e760ee6ff0dab61d6b2bbd30146724d063eb322180c6f18a6f74e4b6aa
|
||||
INSTALL_DIR "${OPENSSL_INSTALL_DIR}"
|
||||
CONFIGURE_COMMAND ${CMAKE_COMMAND} -E env ${OPENSSL_BUILD_ENV}
|
||||
"<SOURCE_DIR>/Configure" "--prefix=<INSTALL_DIR>" no-shared ${OPENSSL_CONFIG_EXTRA_ARGS} "${OPENSSL_OS_COMPILER}"
|
||||
|
|
|
@ -1,34 +1,15 @@
|
|||
|
||||
# Find DEVKITPRO
|
||||
set(DEVKITPRO "$ENV{DEVKITPRO}" CACHE PATH "Path to DevKitPro")
|
||||
set(PORTLIBS_PREFIX "$ENV{PORTLIBS_PREFIX}" CACHE PATH "Path to portlibs inside DevKitPro")
|
||||
if(NOT DEVKITPRO OR NOT PORTLIBS_PREFIX)
|
||||
message(FATAL_ERROR "Please set DEVKITPRO & PORTLIBS_PREFIX env before calling cmake. https://devkitpro.org/wiki/Getting_Started")
|
||||
if(NOT DEVKITPRO)
|
||||
message(FATAL_ERROR "Please set DEVKITPRO env before calling cmake. https://devkitpro.org/wiki/Getting_Started")
|
||||
endif()
|
||||
|
||||
# include devkitpro toolchain
|
||||
include("${DEVKITPRO}/switch.cmake")
|
||||
include("${DEVKITPRO}/cmake/Switch.cmake")
|
||||
|
||||
set(NSWITCH TRUE)
|
||||
|
||||
# Enable gcc -g, to use
|
||||
# /opt/devkitpro/devkitA64/bin/aarch64-none-elf-addr2line -e build_switch/switch/chiaki -f -p -C -a 0xCCB5C
|
||||
# set(CMAKE_BUILD_TYPE Debug)
|
||||
# set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
# set(BUILD_SHARED_LIBS OFF CACHE INTERNAL "Shared libs not available" )
|
||||
|
||||
# FIXME rework this file to use the toolchain only
|
||||
# https://github.com/diasurgical/devilutionX/pull/764
|
||||
set(ARCH "-march=armv8-a+crc+crypto -mtune=cortex-a57 -mtp=soft -ftls-model=local-exec")
|
||||
# set(CMAKE_C_FLAGS "-O2 -ffunction-sections ${ARCH}")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS}")
|
||||
# workaroud force -fPIE to avoid
|
||||
# aarch64-none-elf/bin/ld: read-only segment has dynamic relocations
|
||||
set(CMAKE_EXE_LINKER_FLAGS "-specs=${DEVKITPRO}/libnx/switch.specs ${ARCH} -fPIE -Wl,-Map,Output.map")
|
||||
|
||||
# add portlibs to the list of include dir
|
||||
include_directories("${PORTLIBS_PREFIX}/include")
|
||||
|
||||
# troubleshoot
|
||||
message(STATUS "CMAKE_FIND_ROOT_PATH = ${CMAKE_FIND_ROOT_PATH}")
|
||||
message(STATUS "PKG_CONFIG_EXECUTABLE = ${PKG_CONFIG_EXECUTABLE}")
|
||||
|
@ -79,4 +60,3 @@ function(add_nro_target output_name target title author version icon romfs)
|
|||
endfunction()
|
||||
|
||||
set(CMAKE_USE_SYSTEM_ENVIRONMENT_PATH OFF)
|
||||
set(CMAKE_PREFIX_PATH "/")
|
||||
|
|
|
@ -6,9 +6,6 @@ find_package(Qt5 REQUIRED COMPONENTS Core Widgets Gui Concurrent Multimedia Open
|
|||
if(APPLE)
|
||||
find_package(Qt5 REQUIRED COMPONENTS MacExtras)
|
||||
endif()
|
||||
if(CHIAKI_GUI_ENABLE_SDL_GAMECONTROLLER)
|
||||
find_package(SDL2 MODULE REQUIRED)
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
add_definitions(-DWIN32_LEAN_AND_MEAN)
|
||||
|
@ -70,12 +67,12 @@ if(CHIAKI_ENABLE_CLI)
|
|||
endif()
|
||||
|
||||
target_link_libraries(chiaki Qt5::Core Qt5::Widgets Qt5::Gui Qt5::Concurrent Qt5::Multimedia Qt5::OpenGL Qt5::Svg)
|
||||
target_link_libraries(chiaki SDL2::SDL2)
|
||||
if(APPLE)
|
||||
target_link_libraries(chiaki Qt5::MacExtras)
|
||||
target_compile_definitions(chiaki PRIVATE CHIAKI_GUI_ENABLE_QT_MACEXTRAS)
|
||||
endif()
|
||||
if(CHIAKI_GUI_ENABLE_SDL_GAMECONTROLLER)
|
||||
target_link_libraries(chiaki SDL2::SDL2)
|
||||
target_compile_definitions(chiaki PRIVATE CHIAKI_GUI_ENABLE_SDL_GAMECONTROLLER)
|
||||
endif()
|
||||
if(CHIAKI_ENABLE_SETSU)
|
||||
|
|
BIN
gui/chiaki.icns
BIN
gui/chiaki.icns
Binary file not shown.
|
@ -3,6 +3,8 @@
|
|||
#ifndef CHIAKI_AVOPENGLWIDGET_H
|
||||
#define CHIAKI_AVOPENGLWIDGET_H
|
||||
|
||||
#include "transformmode.h"
|
||||
|
||||
#include <chiaki/log.h>
|
||||
|
||||
#include <QOpenGLWidget>
|
||||
|
@ -74,21 +76,24 @@ class AVOpenGLWidget: public QOpenGLWidget
|
|||
public:
|
||||
static QSurfaceFormat CreateSurfaceFormat();
|
||||
|
||||
explicit AVOpenGLWidget(StreamSession *session, QWidget *parent = nullptr);
|
||||
explicit AVOpenGLWidget(StreamSession *session, QWidget *parent = nullptr, TransformMode transform_mode = TransformMode::Fit);
|
||||
~AVOpenGLWidget() override;
|
||||
|
||||
void SwapFrames();
|
||||
AVOpenGLFrame *GetBackgroundFrame() { return &frames[1 - frame_fg]; }
|
||||
|
||||
void SetTransformMode(TransformMode mode) { transform_mode = mode; }
|
||||
TransformMode GetTransformMode() const { return transform_mode; }
|
||||
|
||||
protected:
|
||||
TransformMode transform_mode;
|
||||
void mouseMoveEvent(QMouseEvent *event) override;
|
||||
|
||||
void initializeGL() override;
|
||||
void paintGL() override;
|
||||
|
||||
private slots:
|
||||
void ResetMouseTimeout();
|
||||
public slots:
|
||||
void ResetMouseTimeout();
|
||||
void HideMouse();
|
||||
};
|
||||
|
||||
|
|
|
@ -12,8 +12,12 @@
|
|||
|
||||
#ifdef CHIAKI_GUI_ENABLE_SDL_GAMECONTROLLER
|
||||
#include <SDL.h>
|
||||
#include <chiaki/orientation.h>
|
||||
#endif
|
||||
|
||||
#define PS_TOUCHPAD_MAX_X 1920
|
||||
#define PS_TOUCHPAD_MAX_Y 1079
|
||||
|
||||
class Controller;
|
||||
|
||||
class ControllerManager : public QObject
|
||||
|
@ -33,7 +37,9 @@ class ControllerManager : public QObject
|
|||
private slots:
|
||||
void UpdateAvailableControllers();
|
||||
void HandleEvents();
|
||||
void ControllerEvent(int device_id);
|
||||
#ifdef CHIAKI_GUI_ENABLE_SDL_GAMECONTROLLER
|
||||
void ControllerEvent(SDL_Event evt);
|
||||
#endif
|
||||
|
||||
public:
|
||||
static ControllerManager *GetInstance();
|
||||
|
@ -57,12 +63,24 @@ class Controller : public QObject
|
|||
private:
|
||||
Controller(int device_id, ControllerManager *manager);
|
||||
|
||||
void UpdateState();
|
||||
#ifdef CHIAKI_GUI_ENABLE_SDL_GAMECONTROLLER
|
||||
void UpdateState(SDL_Event event);
|
||||
bool HandleButtonEvent(SDL_ControllerButtonEvent event);
|
||||
bool HandleAxisEvent(SDL_ControllerAxisEvent event);
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 14)
|
||||
bool HandleSensorEvent(SDL_ControllerSensorEvent event);
|
||||
bool HandleTouchpadEvent(SDL_ControllerTouchpadEvent event);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
ControllerManager *manager;
|
||||
int id;
|
||||
ChiakiOrientationTracker orientation_tracker;
|
||||
ChiakiControllerState state;
|
||||
bool is_dualsense;
|
||||
|
||||
#ifdef CHIAKI_GUI_ENABLE_SDL_GAMECONTROLLER
|
||||
QMap<QPair<Sint64, Sint64>, uint8_t> touch_ids;
|
||||
SDL_GameController *controller;
|
||||
#endif
|
||||
|
||||
|
@ -74,9 +92,43 @@ class Controller : public QObject
|
|||
QString GetName();
|
||||
ChiakiControllerState GetState();
|
||||
void SetRumble(uint8_t left, uint8_t right);
|
||||
void SetTriggerEffects(uint8_t type_left, const uint8_t *data_left, uint8_t type_right, const uint8_t *data_right);
|
||||
bool IsDualSense();
|
||||
|
||||
signals:
|
||||
void StateChanged();
|
||||
};
|
||||
|
||||
/* PS5 trigger effect documentation:
|
||||
https://controllers.fandom.com/wiki/Sony_DualSense#FFB_Trigger_Modes
|
||||
|
||||
Taken from SDL2, licensed under the zlib license,
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
https://github.com/libsdl-org/SDL/blob/release-2.24.1/test/testgamecontroller.c#L263-L289
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
Uint8 ucEnableBits1; /* 0 */
|
||||
Uint8 ucEnableBits2; /* 1 */
|
||||
Uint8 ucRumbleRight; /* 2 */
|
||||
Uint8 ucRumbleLeft; /* 3 */
|
||||
Uint8 ucHeadphoneVolume; /* 4 */
|
||||
Uint8 ucSpeakerVolume; /* 5 */
|
||||
Uint8 ucMicrophoneVolume; /* 6 */
|
||||
Uint8 ucAudioEnableBits; /* 7 */
|
||||
Uint8 ucMicLightMode; /* 8 */
|
||||
Uint8 ucAudioMuteBits; /* 9 */
|
||||
Uint8 rgucRightTriggerEffect[11]; /* 10 */
|
||||
Uint8 rgucLeftTriggerEffect[11]; /* 21 */
|
||||
Uint8 rgucUnknown1[6]; /* 32 */
|
||||
Uint8 ucLedFlags; /* 38 */
|
||||
Uint8 rgucUnknown2[2]; /* 39 */
|
||||
Uint8 ucLedAnim; /* 41 */
|
||||
Uint8 ucLedBrightness; /* 42 */
|
||||
Uint8 ucPadLights; /* 43 */
|
||||
Uint8 ucLedRed; /* 44 */
|
||||
Uint8 ucLedGreen; /* 45 */
|
||||
Uint8 ucLedBlue; /* 46 */
|
||||
} DS5EffectsState_t;
|
||||
|
||||
#endif // CHIAKI_CONTROLLERMANAGER_H
|
||||
|
|
|
@ -55,6 +55,7 @@ class MainWindow : public QMainWindow
|
|||
|
||||
void UpdateDiscoveryEnabled();
|
||||
void ShowSettings();
|
||||
void Quit();
|
||||
|
||||
void UpdateDisplayServers();
|
||||
void UpdateServerWidgets();
|
||||
|
|
|
@ -63,6 +63,9 @@ class Settings : public QObject
|
|||
void SetLogVerbose(bool enabled) { settings.setValue("settings/log_verbose", enabled); }
|
||||
uint32_t GetLogLevelMask();
|
||||
|
||||
bool GetDualSenseEnabled() const { return settings.value("settings/dualsense_enabled", false).toBool(); }
|
||||
void SetDualSenseEnabled(bool enabled) { settings.setValue("settings/dualsense_enabled", enabled); }
|
||||
|
||||
ChiakiVideoResolutionPreset GetResolution() const;
|
||||
void SetResolution(ChiakiVideoResolutionPreset resolution);
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ class SettingsDialog : public QDialog
|
|||
|
||||
QCheckBox *log_verbose_check_box;
|
||||
QComboBox *disconnect_action_combo_box;
|
||||
QCheckBox *dualsense_check_box;
|
||||
|
||||
QComboBox *resolution_combo_box;
|
||||
QComboBox *fps_combo_box;
|
||||
|
@ -37,6 +38,7 @@ class SettingsDialog : public QDialog
|
|||
|
||||
private slots:
|
||||
void LogVerboseChanged();
|
||||
void DualSenseChanged();
|
||||
void DisconnectActionSelected();
|
||||
|
||||
void ResolutionSelected();
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "sessionlog.h"
|
||||
#include "controllermanager.h"
|
||||
#include "settings.h"
|
||||
#include "transformmode.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QImage>
|
||||
|
@ -53,9 +54,18 @@ struct StreamSessionConnectInfo
|
|||
ChiakiConnectVideoProfile video_profile;
|
||||
unsigned int audio_buffer_size;
|
||||
bool fullscreen;
|
||||
TransformMode transform_mode;
|
||||
bool enable_keyboard;
|
||||
bool enable_dualsense;
|
||||
|
||||
StreamSessionConnectInfo(Settings *settings, ChiakiTarget target, QString host, QByteArray regist_key, QByteArray morning, bool fullscreen);
|
||||
StreamSessionConnectInfo(
|
||||
Settings *settings,
|
||||
ChiakiTarget target,
|
||||
QString host,
|
||||
QByteArray regist_key,
|
||||
QByteArray morning,
|
||||
bool fullscreen,
|
||||
TransformMode transform_mode);
|
||||
};
|
||||
|
||||
class StreamSession : public QObject
|
||||
|
@ -92,17 +102,23 @@ class StreamSession : public QObject
|
|||
unsigned int audio_buffer_size;
|
||||
QAudioOutput *audio_output;
|
||||
QIODevice *audio_io;
|
||||
SDL_AudioDeviceID haptics_output;
|
||||
uint8_t *haptics_resampler_buf;
|
||||
|
||||
QMap<Qt::Key, int> key_map;
|
||||
|
||||
void PushAudioFrame(int16_t *buf, size_t samples_count);
|
||||
void PushHapticsFrame(uint8_t *buf, size_t buf_size);
|
||||
#if CHIAKI_GUI_ENABLE_SETSU
|
||||
void HandleSetsuEvent(SetsuEvent *event);
|
||||
#endif
|
||||
|
||||
private slots:
|
||||
void InitAudio(unsigned int channels, unsigned int rate);
|
||||
void InitHaptics();
|
||||
void Event(ChiakiEvent *event);
|
||||
void DisconnectHaptics();
|
||||
void ConnectHaptics();
|
||||
|
||||
public:
|
||||
explicit StreamSession(const StreamSessionConnectInfo &connect_info, QObject *parent = nullptr);
|
||||
|
@ -124,7 +140,7 @@ class StreamSession : public QObject
|
|||
#endif
|
||||
|
||||
void HandleKeyboardEvent(QKeyEvent *event);
|
||||
void HandleMouseEvent(QMouseEvent *event);
|
||||
bool HandleMouseEvent(QMouseEvent *event);
|
||||
|
||||
signals:
|
||||
void FfmpegFrameAvailable();
|
||||
|
|
|
@ -22,10 +22,14 @@ class StreamWindow: public QMainWindow
|
|||
const StreamSessionConnectInfo connect_info;
|
||||
StreamSession *session;
|
||||
|
||||
QAction *fullscreen_action;
|
||||
QAction *stretch_action;
|
||||
QAction *zoom_action;
|
||||
AVOpenGLWidget *av_widget;
|
||||
|
||||
void Init();
|
||||
void UpdateVideoTransform();
|
||||
void UpdateTransformModeActions();
|
||||
|
||||
protected:
|
||||
void keyPressEvent(QKeyEvent *event) override;
|
||||
|
@ -42,6 +46,9 @@ class StreamWindow: public QMainWindow
|
|||
void SessionQuit(ChiakiQuitReason reason, const QString &reason_str);
|
||||
void LoginPINRequested(bool incorrect);
|
||||
void ToggleFullscreen();
|
||||
void ToggleStretch();
|
||||
void ToggleZoom();
|
||||
void Quit();
|
||||
};
|
||||
|
||||
#endif // CHIAKI_GUI_STREAMWINDOW_H
|
||||
|
|
12
gui/include/transformmode.h
Normal file
12
gui/include/transformmode.h
Normal file
|
@ -0,0 +1,12 @@
|
|||
// SPDX-License-Identifier: LicenseRef-AGPL-3.0-only-OpenSSL
|
||||
|
||||
#ifndef CHIAKI_TRANSFORMMODE_H
|
||||
#define CHIAKI_TRANSFORMMODE_H
|
||||
|
||||
enum class TransformMode {
|
||||
Fit,
|
||||
Zoom,
|
||||
Stretch
|
||||
};
|
||||
|
||||
#endif
|
102
gui/res/chiaki_macos.svg
Normal file
102
gui/res/chiaki_macos.svg
Normal file
|
@ -0,0 +1,102 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="1024"
|
||||
height="1024"
|
||||
viewBox="0 0 270.93332 270.93334"
|
||||
version="1.1"
|
||||
id="svg5"
|
||||
xml:space="preserve"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"><defs
|
||||
id="defs2"><linearGradient
|
||||
id="linearGradient4465"><stop
|
||||
style="stop-color:#f6ffbc;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop4461" /><stop
|
||||
style="stop-color:#b4d700;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop4463" /></linearGradient><filter
|
||||
x="-0.014563107"
|
||||
y="-0.014563107"
|
||||
width="1.0291262"
|
||||
height="1.0412621"
|
||||
filterUnits="objectBoundingBox"
|
||||
id="filter-80aygx4sbj-3"><feOffset
|
||||
dx="0"
|
||||
dy="5"
|
||||
in="SourceAlpha"
|
||||
result="shadowOffsetOuter1"
|
||||
id="feOffset424" /><feGaussianBlur
|
||||
stdDeviation="2.5"
|
||||
in="shadowOffsetOuter1"
|
||||
result="shadowBlurOuter1"
|
||||
id="feGaussianBlur426" /><feColorMatrix
|
||||
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.3 0"
|
||||
type="matrix"
|
||||
in="shadowBlurOuter1"
|
||||
id="feColorMatrix428" /></filter><clipPath
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath964"><circle
|
||||
style="display:inline;fill:#ff9955;fill-opacity:1;stroke:none;stroke-width:8.46667;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="circle966"
|
||||
cx="-135.46669"
|
||||
cy="161.49431"
|
||||
r="135.46667"
|
||||
transform="scale(-1,1)" /></clipPath><linearGradient
|
||||
xlink:href="#linearGradient4465"
|
||||
id="linearGradient4467"
|
||||
x1="67.73333"
|
||||
y1="13.229165"
|
||||
x2="67.73333"
|
||||
y2="122.2375"
|
||||
gradientUnits="userSpaceOnUse" /><linearGradient
|
||||
xlink:href="#linearGradient4465-9"
|
||||
id="linearGradient4467-7"
|
||||
x1="67.73333"
|
||||
y1="13.229165"
|
||||
x2="67.73333"
|
||||
y2="122.2375"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(-7.288516e-4,6.5027792e-5)" /><linearGradient
|
||||
id="linearGradient4465-9"><stop
|
||||
style="stop-color:#f1ff7f;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop4461-3" /><stop
|
||||
style="stop-color:#b2d400;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop4463-8" /></linearGradient></defs><g
|
||||
id="layer1"
|
||||
transform="matrix(2.0000001,0,0,2.0000001,4.2905177e-6,-3.0059484e-5)"><path
|
||||
d="m 417,128.31353 c 0,-4.89098 0,-9.78246 -0.0281,-14.67394 -0.0245,-4.12049 -0.072,-8.23997 -0.184,-12.35846 -0.242,-8.976466 -0.77149,-18.029933 -2.36798,-26.906401 C 412.80098,65.370262 410.157,56.989792 405.99053,48.808322 401.89456,40.766852 396.5441,33.408378 390.16015,27.028902 383.7777,20.649425 376.41725,15.302444 368.37281,11.208959 360.18287,7.0414744 351.79343,4.398484 342.779,2.7799899 333.90156,1.1859957 324.84563,0.65749761 315.8692,0.41499849 311.74773,0.3034989 307.62626,0.25649907 303.50379,0.23099916 298.60983,0.20099927 293.71586,0.20349926 288.8219,0.20349926 L 231.99832,0 h -42.49969 l -55.81808,0.20349926 c -4.90347,0 -9.80693,-0.0025 -14.71039,0.0274999 -4.13097,0.0254999 -8.25994,0.0724997 -12.38941,0.18399933 C 97.583315,0.65749761 88.506882,1.1864957 79.608448,2.7824899 70.582015,4.400484 62.180077,7.0424744 53.979137,11.206959 45.917697,15.300944 38.541252,20.648425 32.145299,27.028902 25.750346,33.407878 20.389886,40.764852 16.286417,48.804822 12.108447,56.990293 9.459467,65.375762 7.836479,74.385229 6.2384908,83.258197 5.7089948,92.308664 5.4654965,101.28113 5.3544974,105.40012 5.3064977,109.5196 5.2814979,113.63959 5.2514981,118.53157 5,124.60805 5,129.49953 v 55.0448 42.95484 l 0.2539981,56.2143 c 0,4.89798 -0.002,9.79596 0.0275,14.69394 0.025,4.12599 0.072999,8.25097 0.1844986,12.37546 0.2429983,8.98797 0.7734943,18.05443 2.3729825,26.9429 1.622488,9.01647 4.2709678,17.40894 8.4454378,25.60091 4.103969,8.05297 9.465429,15.42094 15.860882,21.80942 6.395453,6.38848 13.769898,11.74245 21.829839,15.84194 8.205939,4.17298 16.611876,6.81947 25.64381,8.43997 8.894434,1.59649 17.967867,2.12599 26.961802,2.36849 4.12947,0.1115 8.25894,0.159 12.38991,0.184 C 123.87412,412 128.77708,412 133.68055,412 h 56.32258 42.60518 56.21359 c 4.89396,0 9.78793,0 14.68189,-0.0295 4.12247,-0.025 8.24394,-0.0725 12.36541,-0.184 8.97993,-0.243 18.03887,-0.773 26.9203,-2.37049 9.00893,-1.62049 17.39437,-4.26598 25.57981,-8.43647 8.04594,-4.09898 15.40789,-9.45397 21.79084,-15.84344 6.38295,-6.38748 11.73291,-13.75445 15.82888,-21.80592 4.16897,-8.19597 6.81295,-16.59244 8.43294,-25.61491 1.59499,-8.88497 2.12398,-17.94793 2.36648,-26.9324 0.1115,-4.12499 0.159,-8.24997 0.1835,-12.37546 C 417,293.50943 417,288.61145 417,283.71347 c 0,0 0,-55.2218 0,-56.2143 v -42.99984 c 0,-0.733 0,-56.1858 0,-56.1858"
|
||||
id="use436"
|
||||
style="display:inline;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;filter:url(#filter-80aygx4sbj-3)"
|
||||
transform="matrix(0.26458333,0,0,0.26458333,11.906247,13.229181)" /><path
|
||||
id="path1446-0"
|
||||
style="display:inline;fill:url(#linearGradient4467-7);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.264583"
|
||||
d="m 62.044061,13.229232 -14.7686,0.05374 c -1.29738,0 -2.59438,-7.27e-4 -3.89175,0.0072 -1.09299,0.0067 -2.18577,0.01959 -3.27836,0.04909 -2.38057,0.06416 -4.78214,0.204046 -7.13651,0.626319 -2.38824,0.428094 -4.61115,1.126951 -6.78098,2.228804 -2.13292,1.083199 -4.08465,2.498142 -5.77691,4.186308 -1.692,1.687769 -3.1099,3.634166 -4.19561,5.761406 -1.10542,2.165736 -1.80663,4.38431 -2.23604,6.768062 -0.4228,2.347638 -0.56293,4.7424 -0.62735,7.116361 -0.0294,1.089816 -0.042,2.179488 -0.0486,3.269568 -0.008,1.294336 -0.0744,2.902441 -0.0744,4.196643 v 6.872449 H 122.23676 v -7.186125 h 5.2e-4 c 0,-1.29407 -2.4e-4,-2.588764 -0.007,-3.882967 -0.007,-1.090212 -0.019,-2.179885 -0.0486,-3.269568 -0.064,-2.37502 -0.20392,-4.770381 -0.62632,-7.118945 -0.42834,-2.38243 -1.12798,-4.599766 -2.23036,-6.764445 -1.08372,-2.127637 -2.49928,-4.074538 -4.18837,-5.762439 -1.68869,-1.687901 -3.63608,-3.102724 -5.76451,-4.185791 -2.16692,-1.102646 -4.38662,-1.802128 -6.77168,-2.230355 -2.34883,-0.421743 -4.744969,-0.561124 -7.119979,-0.625285 -1.09047,-0.0295 -2.1809,-0.04235 -3.27163,-0.04909 -1.29486,-0.0079 -2.59018,-0.0072 -3.88504,-0.0072 l -15.03474,-0.05374 z m -48.74947,74.745825 0.002,0.319877 c 0,1.295923 -6e-4,2.592212 0.007,3.888135 0.007,1.091667 0.0196,2.182948 0.0491,3.274218 0.0643,2.378065 0.20415,4.777033 0.62735,7.128773 0.42928,2.3856 1.13051,4.60577 2.235,6.77323 1.08584,2.13067 2.504,4.08043 4.19613,5.7707 1.69213,1.69029 3.64335,3.10682 5.77587,4.19148 2.17116,1.1041 4.39542,1.80418 6.78512,2.23294 2.35332,0.42241 4.75377,0.56267 7.13341,0.62683 1.09259,0.0295 2.18537,0.042 3.27836,0.0486 1.29737,0.008 2.59437,0.008 3.89175,0.008 h 14.90244 11.27219 14.87351 c 1.29485,0 2.58965,2.5e-4 3.88451,-0.008 1.09074,-0.007 2.18117,-0.0191 3.27164,-0.0486 2.37594,-0.0643 4.772679,-0.20468 7.122559,-0.62735 2.38361,-0.42875 4.60233,-1.12847 6.76806,-2.2319 2.12882,-1.08452 4.07671,-2.50145 5.76554,-4.192 1.68882,-1.69001 3.10414,-3.63939 4.18786,-5.76967 1.10304,-2.16852 1.80277,-4.39017 2.23139,-6.77736 0.42201,-2.35081 0.56216,-4.748534 0.62632,-7.125673 0.0295,-1.091402 0.0417,-2.182683 0.0481,-3.274218 0.007,-1.295923 0.007,-2.592212 0.007,-3.888135 v -0.319877 z" /><path
|
||||
id="path4518"
|
||||
style="display:inline;fill:#162d50;stroke:none;stroke-width:0.106942px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 51.096105,40.852287 -4.064351,8.567436 -2.345593,4.945434 H 13.229682 v 7.69152 11.365198 l 0.06563,14.553117 H 60.017007 L 67.733332,99.65955 75.449657,87.974992 H 122.2375 V 73.421875 62.044791 54.365157 H 90.780505 l -2.345594,-4.945434 -4.064351,-8.567436 -4.064351,8.567436 -2.346111,4.945434 H 67.733332 57.506567 l -2.34611,-4.945434 z" /><rect
|
||||
y="66.785446"
|
||||
x="-81.742691"
|
||||
height="12.833001"
|
||||
width="6.4165006"
|
||||
id="rect1043"
|
||||
style="display:inline;fill:#ffaaee;fill-opacity:1;stroke:none;stroke-width:0.075952;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
transform="scale(-1,1)" /><rect
|
||||
style="display:inline;fill:#ffaaee;fill-opacity:1;stroke:none;stroke-width:0.075952;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
id="rect1047"
|
||||
width="6.4165006"
|
||||
height="12.833001"
|
||||
x="-60.140472"
|
||||
y="66.785446"
|
||||
transform="scale(-1,1)" /><path
|
||||
id="path830"
|
||||
style="color:#000000;fill:#162d50;-inkscape-stroke:none"
|
||||
d="m 51.095589,26.798881 c -6.169023,0 -11.826367,2.225125 -16.215031,5.913334 l 2.185913,2.605009 c 3.790164,-3.181711 8.681211,-5.09633 14.029118,-5.09633 5.348221,0 10.239895,1.9148 14.030152,5.096847 l 2.185913,-2.605009 C 62.922884,29.024147 57.264963,26.798881 51.095589,26.798881 Z" /><path
|
||||
id="circle840"
|
||||
style="color:#000000;fill:#162d50;-inkscape-stroke:none"
|
||||
d="m 51.095589,33.656344 c -4.49058,0 -8.610793,1.621713 -11.807548,4.308781 l 2.18643,2.605525 c 2.597877,-2.180752 5.951484,-3.492293 9.621118,-3.492293 3.669777,0 7.024322,1.311388 9.622669,3.492293 l 2.185913,-2.605009 C 59.707311,35.278198 55.58652,33.656344 51.095589,33.656344 Z" /></g></svg>
|
After Width: | Height: | Size: 9.2 KiB |
|
@ -5,6 +5,7 @@
|
|||
<file>discover-24px.svg</file>
|
||||
<file>discover-off-24px.svg</file>
|
||||
<file>chiaki.svg</file>
|
||||
<file>chiaki_macos.svg</file>
|
||||
<file>console-ps4.svg</file>
|
||||
<file>console-ps5.svg</file>
|
||||
</qresource>
|
||||
|
|
|
@ -122,9 +122,9 @@ QSurfaceFormat AVOpenGLWidget::CreateSurfaceFormat()
|
|||
return format;
|
||||
}
|
||||
|
||||
AVOpenGLWidget::AVOpenGLWidget(StreamSession *session, QWidget *parent)
|
||||
AVOpenGLWidget::AVOpenGLWidget(StreamSession *session, QWidget *parent, TransformMode transform_mode)
|
||||
: QOpenGLWidget(parent),
|
||||
session(session)
|
||||
session(session), transform_mode(transform_mode)
|
||||
{
|
||||
enum AVPixelFormat pixel_format = chiaki_ffmpeg_decoder_get_pixel_format(session->GetFfmpegDecoder());
|
||||
conversion_config = nullptr;
|
||||
|
@ -381,10 +381,10 @@ void AVOpenGLWidget::paintGL()
|
|||
vp_width = widget_width;
|
||||
vp_height = widget_height;
|
||||
}
|
||||
else
|
||||
else if(transform_mode == TransformMode::Fit)
|
||||
{
|
||||
float aspect = (float)frame->width / (float)frame->height;
|
||||
if(aspect < (float)widget_width / (float)widget_height)
|
||||
if(widget_height && aspect < (float)widget_width / (float)widget_height)
|
||||
{
|
||||
vp_height = widget_height;
|
||||
vp_width = (GLsizei)(vp_height * aspect);
|
||||
|
@ -395,6 +395,34 @@ void AVOpenGLWidget::paintGL()
|
|||
vp_height = (GLsizei)(vp_width / aspect);
|
||||
}
|
||||
}
|
||||
else if(transform_mode == TransformMode::Zoom)
|
||||
{
|
||||
float aspect = (float)frame->width / (float)frame->height;
|
||||
if(widget_height && aspect < (float)widget_width / (float)widget_height)
|
||||
{
|
||||
vp_width = widget_width;
|
||||
vp_height = (GLsizei)(vp_width / aspect);
|
||||
}
|
||||
else
|
||||
{
|
||||
vp_height = widget_height;
|
||||
vp_width = (GLsizei)(vp_height * aspect);
|
||||
}
|
||||
}
|
||||
else // transform_mode == TransformMode::Stretch
|
||||
{
|
||||
float aspect = (float)frame->width / (float)frame->height;
|
||||
if(widget_height && aspect < (float)widget_width / (float)widget_height)
|
||||
{
|
||||
vp_height = widget_height;
|
||||
vp_width = widget_width;
|
||||
}
|
||||
else
|
||||
{
|
||||
vp_width = widget_width;
|
||||
vp_height = widget_height;
|
||||
}
|
||||
}
|
||||
|
||||
f->glViewport((widget_width - vp_width) / 2, (widget_height - vp_height) / 2, vp_width, vp_height);
|
||||
|
||||
|
|
|
@ -68,6 +68,12 @@ static QSet<QString> chiaki_motion_controller_guids({
|
|||
"030000008f0e00001431000000000000",
|
||||
});
|
||||
|
||||
static QSet<QPair<int16_t, int16_t>> chiaki_dualsense_controller_ids({
|
||||
// in format (vendor id, product id)
|
||||
QPair<int16_t, int16_t>(0x054c, 0x0ce6), // DualSense controller
|
||||
QPair<int16_t, int16_t>(0x054c, 0x0df2), // DualSense Edge controller
|
||||
});
|
||||
|
||||
static ControllerManager *instance = nullptr;
|
||||
|
||||
#define UPDATE_INTERVAL_MS 4
|
||||
|
@ -84,6 +90,15 @@ ControllerManager::ControllerManager(QObject *parent)
|
|||
{
|
||||
#ifdef CHIAKI_GUI_ENABLE_SDL_GAMECONTROLLER
|
||||
SDL_SetMainReady();
|
||||
#ifdef SDL_HINT_JOYSTICK_HIDAPI_PS4_RUMBLE
|
||||
SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_PS4_RUMBLE, "1");
|
||||
#endif
|
||||
#ifdef SDL_HINT_JOYSTICK_HIDAPI_PS5_RUMBLE
|
||||
SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_PS5_RUMBLE, "1");
|
||||
#endif
|
||||
#ifdef SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS
|
||||
SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1");
|
||||
#endif
|
||||
if(SDL_Init(SDL_INIT_GAMECONTROLLER) < 0)
|
||||
{
|
||||
const char *err = SDL_GetError();
|
||||
|
@ -156,22 +171,51 @@ void ControllerManager::HandleEvents()
|
|||
break;
|
||||
case SDL_CONTROLLERBUTTONUP:
|
||||
case SDL_CONTROLLERBUTTONDOWN:
|
||||
ControllerEvent(event.cbutton.which);
|
||||
break;
|
||||
case SDL_CONTROLLERAXISMOTION:
|
||||
ControllerEvent(event.caxis.which);
|
||||
#if not defined(CHIAKI_ENABLE_SETSU) and SDL_VERSION_ATLEAST(2, 0, 14)
|
||||
case SDL_CONTROLLERSENSORUPDATE:
|
||||
case SDL_CONTROLLERTOUCHPADDOWN:
|
||||
case SDL_CONTROLLERTOUCHPADMOTION:
|
||||
case SDL_CONTROLLERTOUCHPADUP:
|
||||
#endif
|
||||
ControllerEvent(event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void ControllerManager::ControllerEvent(int device_id)
|
||||
#ifdef CHIAKI_GUI_ENABLE_SDL_GAMECONTROLLER
|
||||
void ControllerManager::ControllerEvent(SDL_Event event)
|
||||
{
|
||||
int device_id;
|
||||
switch(event.type)
|
||||
{
|
||||
case SDL_CONTROLLERBUTTONDOWN:
|
||||
case SDL_CONTROLLERBUTTONUP:
|
||||
device_id = event.cbutton.which;
|
||||
break;
|
||||
case SDL_CONTROLLERAXISMOTION:
|
||||
device_id = event.caxis.which;
|
||||
break;
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 14)
|
||||
case SDL_CONTROLLERSENSORUPDATE:
|
||||
device_id = event.csensor.which;
|
||||
break;
|
||||
case SDL_CONTROLLERTOUCHPADDOWN:
|
||||
case SDL_CONTROLLERTOUCHPADMOTION:
|
||||
case SDL_CONTROLLERTOUCHPADUP:
|
||||
device_id = event.ctouchpad.which;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return;
|
||||
}
|
||||
if(!open_controllers.contains(device_id))
|
||||
return;
|
||||
open_controllers[device_id]->UpdateState();
|
||||
open_controllers[device_id]->UpdateState(event);
|
||||
}
|
||||
#endif
|
||||
|
||||
QSet<int> ControllerManager::GetAvailableControllers()
|
||||
{
|
||||
|
@ -196,10 +240,13 @@ void ControllerManager::ControllerClosed(Controller *controller)
|
|||
open_controllers.remove(controller->GetDeviceID());
|
||||
}
|
||||
|
||||
Controller::Controller(int device_id, ControllerManager *manager) : QObject(manager)
|
||||
Controller::Controller(int device_id, ControllerManager *manager)
|
||||
: QObject(manager), is_dualsense(false)
|
||||
{
|
||||
this->id = device_id;
|
||||
this->manager = manager;
|
||||
chiaki_orientation_tracker_init(&this->orientation_tracker);
|
||||
chiaki_controller_state_set_idle(&this->state);
|
||||
|
||||
#ifdef CHIAKI_GUI_ENABLE_SDL_GAMECONTROLLER
|
||||
controller = nullptr;
|
||||
|
@ -208,6 +255,14 @@ Controller::Controller(int device_id, ControllerManager *manager) : QObject(mana
|
|||
if(SDL_JoystickGetDeviceInstanceID(i) == device_id)
|
||||
{
|
||||
controller = SDL_GameControllerOpen(i);
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 14)
|
||||
if(SDL_GameControllerHasSensor(controller, SDL_SENSOR_ACCEL))
|
||||
SDL_GameControllerSetSensorEnabled(controller, SDL_SENSOR_ACCEL, SDL_TRUE);
|
||||
if(SDL_GameControllerHasSensor(controller, SDL_SENSOR_GYRO))
|
||||
SDL_GameControllerSetSensorEnabled(controller, SDL_SENSOR_GYRO, SDL_TRUE);
|
||||
#endif
|
||||
auto controller_id = QPair<int16_t, int16_t>(SDL_GameControllerGetVendor(controller), SDL_GameControllerGetProduct(controller));
|
||||
is_dualsense = chiaki_dualsense_controller_ids.contains(controller_id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -218,16 +273,197 @@ Controller::~Controller()
|
|||
{
|
||||
#ifdef CHIAKI_GUI_ENABLE_SDL_GAMECONTROLLER
|
||||
if(controller)
|
||||
{
|
||||
// Clear trigger effects, SDL doesn't do it automatically
|
||||
const uint8_t clear_effect[10] = { 0 };
|
||||
this->SetTriggerEffects(0x05, clear_effect, 0x05, clear_effect);
|
||||
SDL_GameControllerClose(controller);
|
||||
}
|
||||
#endif
|
||||
manager->ControllerClosed(this);
|
||||
}
|
||||
|
||||
void Controller::UpdateState()
|
||||
#ifdef CHIAKI_GUI_ENABLE_SDL_GAMECONTROLLER
|
||||
void Controller::UpdateState(SDL_Event event)
|
||||
{
|
||||
switch(event.type)
|
||||
{
|
||||
case SDL_CONTROLLERBUTTONDOWN:
|
||||
case SDL_CONTROLLERBUTTONUP:
|
||||
if(!HandleButtonEvent(event.cbutton))
|
||||
return;
|
||||
break;
|
||||
case SDL_CONTROLLERAXISMOTION:
|
||||
if(!HandleAxisEvent(event.caxis))
|
||||
return;
|
||||
break;
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 14)
|
||||
case SDL_CONTROLLERSENSORUPDATE:
|
||||
if(!HandleSensorEvent(event.csensor))
|
||||
return;
|
||||
break;
|
||||
case SDL_CONTROLLERTOUCHPADDOWN:
|
||||
case SDL_CONTROLLERTOUCHPADMOTION:
|
||||
case SDL_CONTROLLERTOUCHPADUP:
|
||||
if(!HandleTouchpadEvent(event.ctouchpad))
|
||||
return;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return;
|
||||
|
||||
}
|
||||
emit StateChanged();
|
||||
}
|
||||
|
||||
inline bool Controller::HandleButtonEvent(SDL_ControllerButtonEvent event) {
|
||||
ChiakiControllerButton ps_btn;
|
||||
switch(event.button)
|
||||
{
|
||||
case SDL_CONTROLLER_BUTTON_A:
|
||||
ps_btn = CHIAKI_CONTROLLER_BUTTON_CROSS;
|
||||
break;
|
||||
case SDL_CONTROLLER_BUTTON_B:
|
||||
ps_btn = CHIAKI_CONTROLLER_BUTTON_MOON;
|
||||
break;
|
||||
case SDL_CONTROLLER_BUTTON_X:
|
||||
ps_btn = CHIAKI_CONTROLLER_BUTTON_BOX;
|
||||
break;
|
||||
case SDL_CONTROLLER_BUTTON_Y:
|
||||
ps_btn = CHIAKI_CONTROLLER_BUTTON_PYRAMID;
|
||||
break;
|
||||
case SDL_CONTROLLER_BUTTON_DPAD_LEFT:
|
||||
ps_btn = CHIAKI_CONTROLLER_BUTTON_DPAD_LEFT;
|
||||
break;
|
||||
case SDL_CONTROLLER_BUTTON_DPAD_RIGHT:
|
||||
ps_btn = CHIAKI_CONTROLLER_BUTTON_DPAD_RIGHT;
|
||||
break;
|
||||
case SDL_CONTROLLER_BUTTON_DPAD_UP:
|
||||
ps_btn = CHIAKI_CONTROLLER_BUTTON_DPAD_UP;
|
||||
break;
|
||||
case SDL_CONTROLLER_BUTTON_DPAD_DOWN:
|
||||
ps_btn = CHIAKI_CONTROLLER_BUTTON_DPAD_DOWN;
|
||||
break;
|
||||
case SDL_CONTROLLER_BUTTON_LEFTSHOULDER:
|
||||
ps_btn = CHIAKI_CONTROLLER_BUTTON_L1;
|
||||
break;
|
||||
case SDL_CONTROLLER_BUTTON_RIGHTSHOULDER:
|
||||
ps_btn = CHIAKI_CONTROLLER_BUTTON_R1;
|
||||
break;
|
||||
case SDL_CONTROLLER_BUTTON_LEFTSTICK:
|
||||
ps_btn = CHIAKI_CONTROLLER_BUTTON_L3;
|
||||
break;
|
||||
case SDL_CONTROLLER_BUTTON_RIGHTSTICK:
|
||||
ps_btn = CHIAKI_CONTROLLER_BUTTON_R3;
|
||||
break;
|
||||
case SDL_CONTROLLER_BUTTON_START:
|
||||
ps_btn = CHIAKI_CONTROLLER_BUTTON_OPTIONS;
|
||||
break;
|
||||
case SDL_CONTROLLER_BUTTON_BACK:
|
||||
ps_btn = CHIAKI_CONTROLLER_BUTTON_SHARE;
|
||||
break;
|
||||
case SDL_CONTROLLER_BUTTON_GUIDE:
|
||||
ps_btn = CHIAKI_CONTROLLER_BUTTON_PS;
|
||||
break;
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 14)
|
||||
case SDL_CONTROLLER_BUTTON_TOUCHPAD:
|
||||
ps_btn = CHIAKI_CONTROLLER_BUTTON_TOUCHPAD;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
if(event.type == SDL_CONTROLLERBUTTONDOWN)
|
||||
state.buttons |= ps_btn;
|
||||
else
|
||||
state.buttons &= ~ps_btn;
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool Controller::HandleAxisEvent(SDL_ControllerAxisEvent event) {
|
||||
switch(event.axis)
|
||||
{
|
||||
case SDL_CONTROLLER_AXIS_TRIGGERLEFT:
|
||||
state.l2_state = (uint8_t)(event.value >> 7);
|
||||
break;
|
||||
case SDL_CONTROLLER_AXIS_TRIGGERRIGHT:
|
||||
state.r2_state = (uint8_t)(event.value >> 7);
|
||||
break;
|
||||
case SDL_CONTROLLER_AXIS_LEFTX:
|
||||
state.left_x = event.value;
|
||||
break;
|
||||
case SDL_CONTROLLER_AXIS_LEFTY:
|
||||
state.left_y = event.value;
|
||||
break;
|
||||
case SDL_CONTROLLER_AXIS_RIGHTX:
|
||||
state.right_x = event.value;
|
||||
break;
|
||||
case SDL_CONTROLLER_AXIS_RIGHTY:
|
||||
state.right_y = event.value;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 14)
|
||||
inline bool Controller::HandleSensorEvent(SDL_ControllerSensorEvent event)
|
||||
{
|
||||
switch(event.sensor)
|
||||
{
|
||||
case SDL_SENSOR_ACCEL:
|
||||
state.accel_x = event.data[0] / SDL_STANDARD_GRAVITY;
|
||||
state.accel_y = event.data[1] / SDL_STANDARD_GRAVITY;
|
||||
state.accel_z = event.data[2] / SDL_STANDARD_GRAVITY;
|
||||
break;
|
||||
case SDL_SENSOR_GYRO:
|
||||
state.gyro_x = event.data[0];
|
||||
state.gyro_y = event.data[1];
|
||||
state.gyro_z = event.data[2];
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
chiaki_orientation_tracker_update(
|
||||
&orientation_tracker, state.gyro_x, state.gyro_y, state.gyro_z,
|
||||
state.accel_x, state.accel_y, state.accel_z, event.timestamp * 1000);
|
||||
chiaki_orientation_tracker_apply_to_controller_state(&orientation_tracker, &state);
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool Controller::HandleTouchpadEvent(SDL_ControllerTouchpadEvent event)
|
||||
{
|
||||
auto key = qMakePair(event.touchpad, event.finger);
|
||||
bool exists = touch_ids.contains(key);
|
||||
uint8_t chiaki_id;
|
||||
switch(event.type)
|
||||
{
|
||||
case SDL_CONTROLLERTOUCHPADDOWN:
|
||||
if(touch_ids.size() >= CHIAKI_CONTROLLER_TOUCHES_MAX)
|
||||
return false;
|
||||
chiaki_id = chiaki_controller_state_start_touch(&state, event.x * PS_TOUCHPAD_MAX_X, event.y * PS_TOUCHPAD_MAX_Y);
|
||||
touch_ids.insert(key, chiaki_id);
|
||||
break;
|
||||
case SDL_CONTROLLERTOUCHPADMOTION:
|
||||
if(!exists)
|
||||
return false;
|
||||
chiaki_controller_state_set_touch_pos(&state, touch_ids[key], event.x * PS_TOUCHPAD_MAX_X, event.y * PS_TOUCHPAD_MAX_Y);
|
||||
break;
|
||||
case SDL_CONTROLLERTOUCHPADUP:
|
||||
if(!exists)
|
||||
return false;
|
||||
chiaki_controller_state_stop_touch(&state, touch_ids[key]);
|
||||
touch_ids.remove(key);
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
bool Controller::IsConnected()
|
||||
{
|
||||
#ifdef CHIAKI_GUI_ENABLE_SDL_GAMECONTROLLER
|
||||
|
@ -263,35 +499,6 @@ QString Controller::GetName()
|
|||
|
||||
ChiakiControllerState Controller::GetState()
|
||||
{
|
||||
ChiakiControllerState state;
|
||||
chiaki_controller_state_set_idle(&state);
|
||||
#ifdef CHIAKI_GUI_ENABLE_SDL_GAMECONTROLLER
|
||||
if(!controller)
|
||||
return state;
|
||||
|
||||
state.buttons |= SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_A) ? CHIAKI_CONTROLLER_BUTTON_CROSS : 0;
|
||||
state.buttons |= SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_B) ? CHIAKI_CONTROLLER_BUTTON_MOON : 0;
|
||||
state.buttons |= SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_X) ? CHIAKI_CONTROLLER_BUTTON_BOX : 0;
|
||||
state.buttons |= SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_Y) ? CHIAKI_CONTROLLER_BUTTON_PYRAMID : 0;
|
||||
state.buttons |= SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_DPAD_LEFT) ? CHIAKI_CONTROLLER_BUTTON_DPAD_LEFT : 0;
|
||||
state.buttons |= SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_DPAD_RIGHT) ? CHIAKI_CONTROLLER_BUTTON_DPAD_RIGHT : 0;
|
||||
state.buttons |= SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_DPAD_UP) ? CHIAKI_CONTROLLER_BUTTON_DPAD_UP : 0;
|
||||
state.buttons |= SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_DPAD_DOWN) ? CHIAKI_CONTROLLER_BUTTON_DPAD_DOWN : 0;
|
||||
state.buttons |= SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_LEFTSHOULDER) ? CHIAKI_CONTROLLER_BUTTON_L1 : 0;
|
||||
state.buttons |= SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER) ? CHIAKI_CONTROLLER_BUTTON_R1 : 0;
|
||||
state.buttons |= SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_LEFTSTICK) ? CHIAKI_CONTROLLER_BUTTON_L3 : 0;
|
||||
state.buttons |= SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_RIGHTSTICK) ? CHIAKI_CONTROLLER_BUTTON_R3 : 0;
|
||||
state.buttons |= SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_START) ? CHIAKI_CONTROLLER_BUTTON_OPTIONS : 0;
|
||||
state.buttons |= SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_BACK) ? CHIAKI_CONTROLLER_BUTTON_SHARE : 0;
|
||||
state.buttons |= SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_GUIDE) ? CHIAKI_CONTROLLER_BUTTON_PS : 0;
|
||||
state.l2_state = (uint8_t)(SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_TRIGGERLEFT) >> 7);
|
||||
state.r2_state = (uint8_t)(SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_TRIGGERRIGHT) >> 7);
|
||||
state.left_x = SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_LEFTX);
|
||||
state.left_y = SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_LEFTY);
|
||||
state.right_x = SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_RIGHTX);
|
||||
state.right_y = SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_RIGHTY);
|
||||
|
||||
#endif
|
||||
return state;
|
||||
}
|
||||
|
||||
|
@ -303,3 +510,28 @@ void Controller::SetRumble(uint8_t left, uint8_t right)
|
|||
SDL_GameControllerRumble(controller, (uint16_t)left << 8, (uint16_t)right << 8, 5000);
|
||||
#endif
|
||||
}
|
||||
|
||||
void Controller::SetTriggerEffects(uint8_t type_left, const uint8_t *data_left, uint8_t type_right, const uint8_t *data_right)
|
||||
{
|
||||
#if defined(CHIAKI_GUI_ENABLE_SDL_GAMECONTROLLER) && SDL_VERSION_ATLEAST(2, 0, 16)
|
||||
if(!is_dualsense || !controller)
|
||||
return;
|
||||
DS5EffectsState_t state;
|
||||
SDL_zero(state);
|
||||
state.ucEnableBits1 |= (0x04 /* left trigger */ | 0x08 /* right trigger */);
|
||||
state.rgucLeftTriggerEffect[0] = type_left;
|
||||
SDL_memcpy(state.rgucLeftTriggerEffect + 1, data_left, 10);
|
||||
state.rgucRightTriggerEffect[0] = type_right;
|
||||
SDL_memcpy(state.rgucRightTriggerEffect + 1, data_right, 10);
|
||||
SDL_GameControllerSendEffect(controller, &state, sizeof(state));
|
||||
#endif
|
||||
}
|
||||
|
||||
bool Controller::IsDualSense()
|
||||
{
|
||||
#ifdef CHIAKI_GUI_ENABLE_SDL_GAMECONTROLLER
|
||||
if(!controller)
|
||||
return false;
|
||||
return is_dualsense;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -71,7 +71,11 @@ int real_main(int argc, char *argv[])
|
|||
|
||||
QApplication app(argc, argv);
|
||||
|
||||
#ifdef Q_OS_MACOS
|
||||
QApplication::setWindowIcon(QIcon(":/icons/chiaki_macos.svg"));
|
||||
#else
|
||||
QApplication::setWindowIcon(QIcon(":/icons/chiaki.svg"));
|
||||
#endif
|
||||
|
||||
QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
|
||||
|
||||
|
@ -99,9 +103,15 @@ int real_main(int argc, char *argv[])
|
|||
QCommandLineOption morning_option("morning", "", "morning");
|
||||
parser.addOption(morning_option);
|
||||
|
||||
QCommandLineOption fullscreen_option("fullscreen", "Start window in fullscreen (only for use with stream command)");
|
||||
QCommandLineOption fullscreen_option("fullscreen", "Start window in fullscreen mode [maintains aspect ratio, adds black bars to fill unsused parts of screen if applicable] (only for use with stream command)");
|
||||
parser.addOption(fullscreen_option);
|
||||
|
||||
QCommandLineOption zoom_option("zoom", "Start window in fullscreen zoomed in to fit screen [maintains aspect ratio, cutting off edges of image to fill screen] (only for use with stream command)");
|
||||
parser.addOption(zoom_option);
|
||||
|
||||
QCommandLineOption stretch_option("stretch", "Start window in fullscreen stretched to fit screen [distorts aspect ratio to fill screen] (only for use with stream command)");
|
||||
parser.addOption(stretch_option);
|
||||
|
||||
parser.process(app);
|
||||
QStringList args = parser.positionalArguments();
|
||||
|
||||
|
@ -129,15 +139,21 @@ int real_main(int argc, char *argv[])
|
|||
{
|
||||
if(args.length() < 3)
|
||||
parser.showHelp(1);
|
||||
|
||||
bool found = false;
|
||||
for(const auto &temphost : settings.GetRegisteredHosts())
|
||||
{
|
||||
if(temphost.GetServerNickname() == args[1])
|
||||
{
|
||||
found = true;
|
||||
morning = temphost.GetRPKey();
|
||||
regist_key = temphost.GetRPRegistKey();
|
||||
target = temphost.GetTarget();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!found)
|
||||
{
|
||||
printf("No configuration found for '%s'\n", args[1].toLocal8Bit().constData());
|
||||
return 1;
|
||||
}
|
||||
|
@ -164,7 +180,21 @@ int real_main(int argc, char *argv[])
|
|||
return 1;
|
||||
}
|
||||
}
|
||||
StreamSessionConnectInfo connect_info(&settings, target, host, regist_key, morning, parser.isSet(fullscreen_option));
|
||||
if ((parser.isSet(stretch_option) && (parser.isSet(zoom_option) || parser.isSet(fullscreen_option))) || (parser.isSet(zoom_option) && parser.isSet(fullscreen_option)))
|
||||
{
|
||||
printf("Must choose between fullscreen, zoom or stretch option.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
StreamSessionConnectInfo connect_info(
|
||||
&settings,
|
||||
target,
|
||||
host,
|
||||
regist_key,
|
||||
morning,
|
||||
parser.isSet(fullscreen_option),
|
||||
parser.isSet(zoom_option) ? TransformMode::Zoom : parser.isSet(stretch_option) ? TransformMode::Stretch : TransformMode::Fit);
|
||||
|
||||
return RunStream(app, connect_info);
|
||||
}
|
||||
#ifdef CHIAKI_ENABLE_CLI
|
||||
|
|
|
@ -146,6 +146,11 @@ MainWindow::MainWindow(Settings *settings, QWidget *parent)
|
|||
AddToolBarAction(settings_action);
|
||||
connect(settings_action, &QAction::triggered, this, &MainWindow::ShowSettings);
|
||||
|
||||
auto quit_action = new QAction(tr("Quit"), this);
|
||||
quit_action->setShortcut(Qt::CTRL + Qt::Key_Q);
|
||||
addAction(quit_action);
|
||||
connect(quit_action, &QAction::triggered, this, &MainWindow::Quit);
|
||||
|
||||
auto scroll_area = new QScrollArea(this);
|
||||
scroll_area->setWidgetResizable(true);
|
||||
scroll_area->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
|
@ -249,7 +254,14 @@ void MainWindow::ServerItemWidgetTriggered()
|
|||
}
|
||||
|
||||
QString host = server.GetHostAddr();
|
||||
StreamSessionConnectInfo info(settings, server.registered_host.GetTarget(), host, server.registered_host.GetRPRegistKey(), server.registered_host.GetRPKey(), false);
|
||||
StreamSessionConnectInfo info(
|
||||
settings,
|
||||
server.registered_host.GetTarget(),
|
||||
host,
|
||||
server.registered_host.GetRPRegistKey(),
|
||||
server.registered_host.GetRPKey(),
|
||||
false,
|
||||
TransformMode::Fit);
|
||||
new StreamWindow(info);
|
||||
}
|
||||
else
|
||||
|
@ -298,6 +310,11 @@ void MainWindow::ShowSettings()
|
|||
dialog.exec();
|
||||
}
|
||||
|
||||
void MainWindow::Quit()
|
||||
{
|
||||
qApp->exit();
|
||||
}
|
||||
|
||||
void MainWindow::UpdateDisplayServers()
|
||||
{
|
||||
display_servers.clear();
|
||||
|
|
|
@ -69,6 +69,11 @@ SettingsDialog::SettingsDialog(Settings *settings, QWidget *parent) : QDialog(pa
|
|||
log_verbose_check_box->setChecked(settings->GetLogVerbose());
|
||||
connect(log_verbose_check_box, &QCheckBox::stateChanged, this, &SettingsDialog::LogVerboseChanged);
|
||||
|
||||
dualsense_check_box = new QCheckBox(this);
|
||||
general_layout->addRow(tr("Extended DualSense Support:\nEnable haptics and adaptive triggers\nfor attached DualSense controllers.\nThis is currently experimental."), dualsense_check_box);
|
||||
dualsense_check_box->setChecked(settings->GetDualSenseEnabled());
|
||||
connect(dualsense_check_box, &QCheckBox::stateChanged, this, &SettingsDialog::DualSenseChanged);
|
||||
|
||||
auto log_directory_label = new QLineEdit(GetLogBaseDir(), this);
|
||||
log_directory_label->setReadOnly(true);
|
||||
general_layout->addRow(tr("Log Directory:"), log_directory_label);
|
||||
|
@ -322,6 +327,11 @@ void SettingsDialog::LogVerboseChanged()
|
|||
settings->SetLogVerbose(log_verbose_check_box->isChecked());
|
||||
}
|
||||
|
||||
void SettingsDialog::DualSenseChanged()
|
||||
{
|
||||
settings->SetDualSenseEnabled(dualsense_check_box->isChecked());
|
||||
}
|
||||
|
||||
void SettingsDialog::FPSSelected()
|
||||
{
|
||||
settings->SetFPS((ChiakiVideoFPSPreset)fps_combo_box->currentData().toInt());
|
||||
|
|
|
@ -14,7 +14,20 @@
|
|||
|
||||
#define SETSU_UPDATE_INTERVAL_MS 4
|
||||
|
||||
StreamSessionConnectInfo::StreamSessionConnectInfo(Settings *settings, ChiakiTarget target, QString host, QByteArray regist_key, QByteArray morning, bool fullscreen)
|
||||
#ifdef Q_OS_LINUX
|
||||
#define DUALSENSE_AUDIO_DEVICE_NEEDLE "DualSense"
|
||||
#else
|
||||
#define DUALSENSE_AUDIO_DEVICE_NEEDLE "Wireless Controller"
|
||||
#endif
|
||||
|
||||
StreamSessionConnectInfo::StreamSessionConnectInfo(
|
||||
Settings *settings,
|
||||
ChiakiTarget target,
|
||||
QString host,
|
||||
QByteArray regist_key,
|
||||
QByteArray morning,
|
||||
bool fullscreen,
|
||||
TransformMode transform_mode)
|
||||
: settings(settings)
|
||||
{
|
||||
key_map = settings->GetControllerMappingForDecoding();
|
||||
|
@ -30,11 +43,14 @@ StreamSessionConnectInfo::StreamSessionConnectInfo(Settings *settings, ChiakiTar
|
|||
this->morning = morning;
|
||||
audio_buffer_size = settings->GetAudioBufferSize();
|
||||
this->fullscreen = fullscreen;
|
||||
this->transform_mode = transform_mode;
|
||||
this->enable_keyboard = false; // TODO: from settings
|
||||
this->enable_dualsense = settings->GetDualSenseEnabled();
|
||||
}
|
||||
|
||||
static void AudioSettingsCb(uint32_t channels, uint32_t rate, void *user);
|
||||
static void AudioFrameCb(int16_t *buf, size_t samples_count, void *user);
|
||||
static void HapticsFrameCb(uint8_t *buf, size_t buf_size, void *user);
|
||||
static void EventCb(ChiakiEvent *event, void *user);
|
||||
#if CHIAKI_GUI_ENABLE_SETSU
|
||||
static void SessionSetsuCb(SetsuEvent *event, void *user);
|
||||
|
@ -49,7 +65,9 @@ StreamSession::StreamSession(const StreamSessionConnectInfo &connect_info, QObje
|
|||
pi_decoder(nullptr),
|
||||
#endif
|
||||
audio_output(nullptr),
|
||||
audio_io(nullptr)
|
||||
audio_io(nullptr),
|
||||
haptics_output(0),
|
||||
haptics_resampler_buf(nullptr)
|
||||
{
|
||||
connected = false;
|
||||
ChiakiErrorCode err;
|
||||
|
@ -108,6 +126,7 @@ StreamSession::StreamSession(const StreamSessionConnectInfo &connect_info, QObje
|
|||
chiaki_connect_info.video_profile = connect_info.video_profile;
|
||||
chiaki_connect_info.video_profile_auto_downgrade = true;
|
||||
chiaki_connect_info.enable_keyboard = false;
|
||||
chiaki_connect_info.enable_dualsense = connect_info.enable_dualsense;
|
||||
|
||||
#if CHIAKI_LIB_ENABLE_PI_DECODER
|
||||
if(connect_info.decoder == Decoder::Pi && chiaki_connect_info.video_profile.codec != CHIAKI_CODEC_H264)
|
||||
|
@ -136,6 +155,14 @@ StreamSession::StreamSession(const StreamSessionConnectInfo &connect_info, QObje
|
|||
chiaki_opus_decoder_get_sink(&opus_decoder, &audio_sink);
|
||||
chiaki_session_set_audio_sink(&session, &audio_sink);
|
||||
|
||||
if(connect_info.enable_dualsense)
|
||||
{
|
||||
ChiakiAudioSink haptics_sink;
|
||||
haptics_sink.user = this;
|
||||
haptics_sink.frame_cb = HapticsFrameCb;
|
||||
chiaki_session_set_haptics_sink(&session, &haptics_sink);
|
||||
}
|
||||
|
||||
#if CHIAKI_LIB_ENABLE_PI_DECODER
|
||||
if(pi_decoder)
|
||||
chiaki_session_set_video_sample_cb(&session, chiaki_pi_decoder_video_sample_cb, pi_decoder);
|
||||
|
@ -173,6 +200,10 @@ StreamSession::StreamSession(const StreamSessionConnectInfo &connect_info, QObje
|
|||
#endif
|
||||
|
||||
key_map = connect_info.key_map;
|
||||
if(connect_info.enable_dualsense)
|
||||
{
|
||||
InitHaptics();
|
||||
}
|
||||
UpdateGamepads();
|
||||
}
|
||||
|
||||
|
@ -200,6 +231,16 @@ StreamSession::~StreamSession()
|
|||
chiaki_ffmpeg_decoder_fini(ffmpeg_decoder);
|
||||
delete ffmpeg_decoder;
|
||||
}
|
||||
if(haptics_output > 0)
|
||||
{
|
||||
SDL_CloseAudioDevice(haptics_output);
|
||||
haptics_output = 0;
|
||||
}
|
||||
if(haptics_resampler_buf)
|
||||
{
|
||||
free(haptics_resampler_buf);
|
||||
haptics_resampler_buf = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void StreamSession::Start()
|
||||
|
@ -228,13 +269,16 @@ void StreamSession::SetLoginPIN(const QString &pin)
|
|||
chiaki_session_set_login_pin(&session, (const uint8_t *)data.constData(), data.size());
|
||||
}
|
||||
|
||||
void StreamSession::HandleMouseEvent(QMouseEvent *event)
|
||||
bool StreamSession::HandleMouseEvent(QMouseEvent *event)
|
||||
{
|
||||
if(event->button() != Qt::MouseButton::LeftButton)
|
||||
return false;
|
||||
if(event->type() == QEvent::MouseButtonPress)
|
||||
keyboard_state.buttons |= CHIAKI_CONTROLLER_BUTTON_TOUCHPAD;
|
||||
else
|
||||
keyboard_state.buttons &= ~CHIAKI_CONTROLLER_BUTTON_TOUCHPAD;
|
||||
SendFeedbackState();
|
||||
return true;
|
||||
}
|
||||
|
||||
void StreamSession::HandleKeyboardEvent(QKeyEvent *event)
|
||||
|
@ -301,6 +345,8 @@ void StreamSession::UpdateGamepads()
|
|||
{
|
||||
CHIAKI_LOGI(log.GetChiakiLog(), "Controller %d disconnected", controller->GetDeviceID());
|
||||
controllers.remove(controller_id);
|
||||
if(controller->IsDualSense())
|
||||
DisconnectHaptics();
|
||||
delete controller;
|
||||
}
|
||||
}
|
||||
|
@ -319,6 +365,11 @@ void StreamSession::UpdateGamepads()
|
|||
CHIAKI_LOGI(log.GetChiakiLog(), "Controller %d opened: \"%s\"", controller_id, controller->GetName().toLocal8Bit().constData());
|
||||
connect(controller, &Controller::StateChanged, this, &StreamSession::SendFeedbackState);
|
||||
controllers[controller_id] = controller;
|
||||
if(controller->IsDualSense())
|
||||
{
|
||||
// Connect haptics audio device with a delay to give the sound system time to set up
|
||||
QTimer::singleShot(1000, this, &StreamSession::ConnectHaptics);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -377,6 +428,82 @@ void StreamSession::InitAudio(unsigned int channels, unsigned int rate)
|
|||
channels, rate, audio_output->bufferSize());
|
||||
}
|
||||
|
||||
void StreamSession::InitHaptics()
|
||||
{
|
||||
haptics_output = 0;
|
||||
haptics_resampler_buf = nullptr;
|
||||
#ifdef Q_OS_LINUX
|
||||
// Haptics work most reliably with Pipewire, so try to use that if available
|
||||
SDL_SetHint("SDL_AUDIODRIVER", "pipewire");
|
||||
#endif
|
||||
|
||||
if(SDL_Init(SDL_INIT_AUDIO) < 0)
|
||||
{
|
||||
CHIAKI_LOGE(log.GetChiakiLog(), "Could not initialize SDL Audio for haptics output: %s", SDL_GetError());
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef Q_OS_LINUX
|
||||
if(!strstr(SDL_GetCurrentAudioDriver(), "pipewire"))
|
||||
{
|
||||
CHIAKI_LOGW(
|
||||
log.GetChiakiLog(),
|
||||
"Haptics output is not using Pipewire, this may not work reliably. (was: '%s')",
|
||||
SDL_GetCurrentAudioDriver());
|
||||
}
|
||||
#endif
|
||||
|
||||
SDL_AudioCVT cvt;
|
||||
SDL_BuildAudioCVT(&cvt, AUDIO_S16LSB, 4, 3000, AUDIO_S16LSB, 4, 48000);
|
||||
cvt.len = 240; // 10 16bit stereo samples
|
||||
haptics_resampler_buf = (uint8_t*) calloc(cvt.len * cvt.len_mult, sizeof(uint8_t));
|
||||
}
|
||||
|
||||
void StreamSession::DisconnectHaptics()
|
||||
{
|
||||
if(this->haptics_output > 0)
|
||||
{
|
||||
SDL_CloseAudioDevice(haptics_output);
|
||||
this->haptics_output = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void StreamSession::ConnectHaptics()
|
||||
{
|
||||
if(this->haptics_output > 0)
|
||||
{
|
||||
CHIAKI_LOGW(this->log.GetChiakiLog(), "Haptics already connected to an attached DualSense controller, ignoring additional controllers.");
|
||||
return;
|
||||
}
|
||||
|
||||
SDL_AudioSpec want, have;
|
||||
SDL_zero(want);
|
||||
want.freq = 48000;
|
||||
want.format = AUDIO_S16LSB;
|
||||
want.channels = 4;
|
||||
want.samples = 480; // 10ms buffer
|
||||
want.callback = NULL;
|
||||
|
||||
const char *device_name = nullptr;
|
||||
for(int i=0; i < SDL_GetNumAudioDevices(0); i++)
|
||||
{
|
||||
device_name = SDL_GetAudioDeviceName(i, 0);
|
||||
if(!device_name || !strstr(device_name, DUALSENSE_AUDIO_DEVICE_NEEDLE))
|
||||
continue;
|
||||
haptics_output = SDL_OpenAudioDevice(device_name, 0, &want, &have, 0);
|
||||
if(haptics_output == 0)
|
||||
{
|
||||
CHIAKI_LOGE(log.GetChiakiLog(), "Could not open SDL Audio Device %s for haptics output: %s", device_name, SDL_GetError());
|
||||
continue;
|
||||
}
|
||||
SDL_PauseAudioDevice(haptics_output, 0);
|
||||
CHIAKI_LOGI(log.GetChiakiLog(), "Haptics Audio Device '%s' opened with %d channels @ %d Hz, buffer size %u (driver=%s)", device_name, have.channels, have.freq, have.size, SDL_GetCurrentAudioDriver());
|
||||
return;
|
||||
}
|
||||
CHIAKI_LOGW(log.GetChiakiLog(), "DualSense features were enabled and a DualSense is connected, but could not find the DualSense audio device!");
|
||||
return;
|
||||
}
|
||||
|
||||
void StreamSession::PushAudioFrame(int16_t *buf, size_t samples_count)
|
||||
{
|
||||
if(!audio_io)
|
||||
|
@ -384,6 +511,35 @@ void StreamSession::PushAudioFrame(int16_t *buf, size_t samples_count)
|
|||
audio_io->write((const char *)buf, static_cast<qint64>(samples_count * 2 * 2));
|
||||
}
|
||||
|
||||
void StreamSession::PushHapticsFrame(uint8_t *buf, size_t buf_size)
|
||||
{
|
||||
if(haptics_output == 0)
|
||||
return;
|
||||
SDL_AudioCVT cvt;
|
||||
// Haptics samples are coming in at 3KHZ, but the DualSense expects 48KHZ
|
||||
SDL_BuildAudioCVT(&cvt, AUDIO_S16LSB, 4, 3000, AUDIO_S16LSB, 4, 48000);
|
||||
cvt.len = buf_size * 2;
|
||||
cvt.buf = haptics_resampler_buf;
|
||||
// Remix to 4 channels
|
||||
for (int i=0; i < buf_size; i+=4)
|
||||
{
|
||||
SDL_memset(haptics_resampler_buf + i * 2, 0, 4);
|
||||
SDL_memcpy(haptics_resampler_buf + (i * 2) + 4, buf + i, 4);
|
||||
}
|
||||
// Resample to 48kHZ
|
||||
if(SDL_ConvertAudio(&cvt) != 0)
|
||||
{
|
||||
CHIAKI_LOGE(log.GetChiakiLog(), "Failed to resample haptics audio: %s", SDL_GetError());
|
||||
return;
|
||||
}
|
||||
|
||||
if(SDL_QueueAudio(haptics_output, cvt.buf, cvt.len_cvt) < 0)
|
||||
{
|
||||
CHIAKI_LOGE(log.GetChiakiLog(), "Failed to submit haptics audio to device: %s", SDL_GetError());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void StreamSession::Event(ChiakiEvent *event)
|
||||
{
|
||||
switch(event->type)
|
||||
|
@ -407,6 +563,19 @@ void StreamSession::Event(ChiakiEvent *event)
|
|||
});
|
||||
break;
|
||||
}
|
||||
case CHIAKI_EVENT_TRIGGER_EFFECTS: {
|
||||
uint8_t type_left = event->trigger_effects.type_left;
|
||||
uint8_t data_left[10];
|
||||
memcpy(data_left, event->trigger_effects.left, 10);
|
||||
uint8_t data_right[10];
|
||||
memcpy(data_right, event->trigger_effects.right, 10);
|
||||
uint8_t type_right = event->trigger_effects.type_right;
|
||||
QMetaObject::invokeMethod(this, [this, type_left, data_left, type_right, data_right]() {
|
||||
for(auto controller : controllers)
|
||||
controller->SetTriggerEffects(type_left, data_left, type_right, data_right);
|
||||
});
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -533,6 +702,7 @@ class StreamSessionPrivate
|
|||
}
|
||||
|
||||
static void PushAudioFrame(StreamSession *session, int16_t *buf, size_t samples_count) { session->PushAudioFrame(buf, samples_count); }
|
||||
static void PushHapticsFrame(StreamSession *session, uint8_t *buf, size_t buf_size) { session->PushHapticsFrame(buf, buf_size); }
|
||||
static void Event(StreamSession *session, ChiakiEvent *event) { session->Event(event); }
|
||||
#if CHIAKI_GUI_ENABLE_SETSU
|
||||
static void HandleSetsuEvent(StreamSession *session, SetsuEvent *event) { session->HandleSetsuEvent(event); }
|
||||
|
@ -552,6 +722,12 @@ static void AudioFrameCb(int16_t *buf, size_t samples_count, void *user)
|
|||
StreamSessionPrivate::PushAudioFrame(session, buf, samples_count);
|
||||
}
|
||||
|
||||
static void HapticsFrameCb(uint8_t *buf, size_t buf_size, void *user)
|
||||
{
|
||||
auto session = reinterpret_cast<StreamSession *>(user);
|
||||
StreamSessionPrivate::PushHapticsFrame(session, buf, buf_size);
|
||||
}
|
||||
|
||||
static void EventCb(ChiakiEvent *event, void *user)
|
||||
{
|
||||
auto session = reinterpret_cast<StreamSession *>(user);
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include <QMessageBox>
|
||||
#include <QCoreApplication>
|
||||
#include <QAction>
|
||||
#include <QMenu>
|
||||
|
||||
StreamWindow::StreamWindow(const StreamSessionConnectInfo &connect_info, QWidget *parent)
|
||||
: QMainWindow(parent),
|
||||
|
@ -23,8 +24,6 @@ StreamWindow::StreamWindow(const StreamSessionConnectInfo &connect_info, QWidget
|
|||
|
||||
try
|
||||
{
|
||||
if(connect_info.fullscreen)
|
||||
showFullScreen();
|
||||
Init();
|
||||
}
|
||||
catch(const Exception &e)
|
||||
|
@ -40,6 +39,8 @@ StreamWindow::~StreamWindow()
|
|||
delete av_widget;
|
||||
}
|
||||
|
||||
#include <QGuiApplication>
|
||||
|
||||
void StreamWindow::Init()
|
||||
{
|
||||
session = new StreamSession(connect_info, this);
|
||||
|
@ -47,10 +48,36 @@ void StreamWindow::Init()
|
|||
connect(session, &StreamSession::SessionQuit, this, &StreamWindow::SessionQuit);
|
||||
connect(session, &StreamSession::LoginPINRequested, this, &StreamWindow::LoginPINRequested);
|
||||
|
||||
const QKeySequence fullscreen_shortcut = Qt::Key_F11;
|
||||
const QKeySequence stretch_shortcut = Qt::CTRL + Qt::Key_S;
|
||||
const QKeySequence zoom_shortcut = Qt::CTRL + Qt::Key_Z;
|
||||
|
||||
fullscreen_action = new QAction(tr("Fullscreen"), this);
|
||||
fullscreen_action->setCheckable(true);
|
||||
fullscreen_action->setShortcut(fullscreen_shortcut);
|
||||
addAction(fullscreen_action);
|
||||
connect(fullscreen_action, &QAction::triggered, this, &StreamWindow::ToggleFullscreen);
|
||||
|
||||
if(session->GetFfmpegDecoder())
|
||||
{
|
||||
av_widget = new AVOpenGLWidget(session, this);
|
||||
av_widget = new AVOpenGLWidget(session, this, connect_info.transform_mode);
|
||||
setCentralWidget(av_widget);
|
||||
|
||||
av_widget->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
connect(av_widget, &QWidget::customContextMenuRequested, this, [this](const QPoint &pos) {
|
||||
av_widget->ResetMouseTimeout();
|
||||
|
||||
QMenu menu(av_widget);
|
||||
menu.addAction(fullscreen_action);
|
||||
menu.addSeparator();
|
||||
menu.addAction(stretch_action);
|
||||
menu.addAction(zoom_action);
|
||||
releaseKeyboard();
|
||||
connect(&menu, &QMenu::aboutToHide, this, [this] {
|
||||
grabKeyboard();
|
||||
});
|
||||
menu.exec(av_widget->mapToGlobal(pos));
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -63,13 +90,34 @@ void StreamWindow::Init()
|
|||
|
||||
session->Start();
|
||||
|
||||
auto fullscreen_action = new QAction(tr("Fullscreen"), this);
|
||||
fullscreen_action->setShortcut(Qt::Key_F11);
|
||||
addAction(fullscreen_action);
|
||||
connect(fullscreen_action, &QAction::triggered, this, &StreamWindow::ToggleFullscreen);
|
||||
stretch_action = new QAction(tr("Stretch"), this);
|
||||
stretch_action->setCheckable(true);
|
||||
stretch_action->setShortcut(stretch_shortcut);
|
||||
addAction(stretch_action);
|
||||
connect(stretch_action, &QAction::triggered, this, &StreamWindow::ToggleStretch);
|
||||
|
||||
zoom_action = new QAction(tr("Zoom"), this);
|
||||
zoom_action->setCheckable(true);
|
||||
zoom_action->setShortcut(zoom_shortcut);
|
||||
addAction(zoom_action);
|
||||
connect(zoom_action, &QAction::triggered, this, &StreamWindow::ToggleZoom);
|
||||
|
||||
auto quit_action = new QAction(tr("Quit"), this);
|
||||
quit_action->setShortcut(Qt::CTRL + Qt::Key_Q);
|
||||
addAction(quit_action);
|
||||
connect(quit_action, &QAction::triggered, this, &StreamWindow::Quit);
|
||||
|
||||
resize(connect_info.video_profile.width, connect_info.video_profile.height);
|
||||
show();
|
||||
|
||||
if(connect_info.fullscreen)
|
||||
{
|
||||
showFullScreen();
|
||||
fullscreen_action->setChecked(true);
|
||||
}
|
||||
else
|
||||
show();
|
||||
|
||||
UpdateTransformModeActions();
|
||||
}
|
||||
|
||||
void StreamWindow::keyPressEvent(QKeyEvent *event)
|
||||
|
@ -84,22 +132,32 @@ void StreamWindow::keyReleaseEvent(QKeyEvent *event)
|
|||
session->HandleKeyboardEvent(event);
|
||||
}
|
||||
|
||||
void StreamWindow::Quit()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
void StreamWindow::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
if(session)
|
||||
session->HandleMouseEvent(event);
|
||||
if(session && session->HandleMouseEvent(event))
|
||||
return;
|
||||
QMainWindow::mousePressEvent(event);
|
||||
}
|
||||
|
||||
void StreamWindow::mouseReleaseEvent(QMouseEvent *event)
|
||||
{
|
||||
if(session)
|
||||
session->HandleMouseEvent(event);
|
||||
if(session && session->HandleMouseEvent(event))
|
||||
return;
|
||||
QMainWindow::mouseReleaseEvent(event);
|
||||
}
|
||||
|
||||
void StreamWindow::mouseDoubleClickEvent(QMouseEvent *event)
|
||||
{
|
||||
ToggleFullscreen();
|
||||
|
||||
if(event->button() == Qt::MouseButton::LeftButton)
|
||||
{
|
||||
ToggleFullscreen();
|
||||
return;
|
||||
}
|
||||
QMainWindow::mouseDoubleClickEvent(event);
|
||||
}
|
||||
|
||||
|
@ -143,7 +201,7 @@ void StreamWindow::closeEvent(QCloseEvent *event)
|
|||
|
||||
void StreamWindow::SessionQuit(ChiakiQuitReason reason, const QString &reason_str)
|
||||
{
|
||||
if(reason != CHIAKI_QUIT_REASON_STOPPED)
|
||||
if(chiaki_quit_reason_is_error(reason))
|
||||
{
|
||||
QString m = tr("Chiaki Session has quit") + ":\n" + chiaki_quit_reason_string(reason);
|
||||
if(!reason_str.isEmpty())
|
||||
|
@ -175,15 +233,48 @@ void StreamWindow::LoginPINRequested(bool incorrect)
|
|||
void StreamWindow::ToggleFullscreen()
|
||||
{
|
||||
if(isFullScreen())
|
||||
{
|
||||
showNormal();
|
||||
fullscreen_action->setChecked(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
showFullScreen();
|
||||
if(av_widget)
|
||||
av_widget->HideMouse();
|
||||
fullscreen_action->setChecked(true);
|
||||
}
|
||||
}
|
||||
|
||||
void StreamWindow::UpdateTransformModeActions()
|
||||
{
|
||||
TransformMode tm = av_widget ? av_widget->GetTransformMode() : TransformMode::Fit;
|
||||
stretch_action->setChecked(tm == TransformMode::Stretch);
|
||||
zoom_action->setChecked(tm == TransformMode::Zoom);
|
||||
}
|
||||
|
||||
void StreamWindow::ToggleStretch()
|
||||
{
|
||||
if(!av_widget)
|
||||
return;
|
||||
av_widget->SetTransformMode(
|
||||
av_widget->GetTransformMode() == TransformMode::Stretch
|
||||
? TransformMode::Fit
|
||||
: TransformMode::Stretch);
|
||||
UpdateTransformModeActions();
|
||||
}
|
||||
|
||||
void StreamWindow::ToggleZoom()
|
||||
{
|
||||
if(!av_widget)
|
||||
return;
|
||||
av_widget->SetTransformMode(
|
||||
av_widget->GetTransformMode() == TransformMode::Zoom
|
||||
? TransformMode::Fit
|
||||
: TransformMode::Zoom);
|
||||
UpdateTransformModeActions();
|
||||
}
|
||||
|
||||
void StreamWindow::resizeEvent(QResizeEvent *event)
|
||||
{
|
||||
UpdateVideoTransform();
|
||||
|
|
|
@ -72,7 +72,7 @@ set(SOURCE_FILES
|
|||
src/controller.c
|
||||
src/takionsendbuffer.c
|
||||
src/time.c
|
||||
src/fec
|
||||
src/fec.c
|
||||
src/regist.c
|
||||
src/opusdecoder.c
|
||||
src/orientation.c)
|
||||
|
@ -119,11 +119,15 @@ find_package(Threads REQUIRED)
|
|||
target_link_libraries(chiaki-lib Threads::Threads)
|
||||
|
||||
if(CHIAKI_LIB_ENABLE_MBEDTLS)
|
||||
# provided by mbedtls-static (mbedtls-devel)
|
||||
find_library(MBEDTLS mbedtls)
|
||||
find_library(MBEDX509 mbedx509)
|
||||
find_library(MBEDCRYPTO mbedcrypto)
|
||||
target_link_libraries(chiaki-lib ${MBEDTLS} ${MBEDX509} ${MBEDCRYPTO})
|
||||
if(CHIAKI_LIB_MBEDTLS_EXTERNAL_PROJECT)
|
||||
target_link_libraries(chiaki-lib mbedtls mbedx509 mbedcrypto)
|
||||
else()
|
||||
# provided by mbedtls-static (mbedtls-devel)
|
||||
find_library(MBEDTLS mbedtls)
|
||||
find_library(MBEDX509 mbedx509)
|
||||
find_library(MBEDCRYPTO mbedcrypto)
|
||||
target_link_libraries(chiaki-lib ${MBEDTLS} ${MBEDX509} ${MBEDCRYPTO})
|
||||
endif()
|
||||
elseif(CHIAKI_LIB_OPENSSL_EXTERNAL_PROJECT)
|
||||
target_link_libraries(chiaki-lib OpenSSL_Crypto)
|
||||
else()
|
||||
|
|
|
@ -78,6 +78,7 @@ typedef struct chiaki_connect_info_t
|
|||
ChiakiConnectVideoProfile video_profile;
|
||||
bool video_profile_auto_downgrade; // Downgrade video_profile if server does not seem to support it.
|
||||
bool enable_keyboard;
|
||||
bool enable_dualsense;
|
||||
} ChiakiConnectInfo;
|
||||
|
||||
|
||||
|
@ -93,11 +94,17 @@ typedef enum {
|
|||
CHIAKI_QUIT_REASON_CTRL_CONNECT_FAILED,
|
||||
CHIAKI_QUIT_REASON_CTRL_CONNECTION_REFUSED,
|
||||
CHIAKI_QUIT_REASON_STREAM_CONNECTION_UNKNOWN,
|
||||
CHIAKI_QUIT_REASON_STREAM_CONNECTION_REMOTE_DISCONNECTED
|
||||
CHIAKI_QUIT_REASON_STREAM_CONNECTION_REMOTE_DISCONNECTED,
|
||||
CHIAKI_QUIT_REASON_STREAM_CONNECTION_REMOTE_SHUTDOWN, // like REMOTE_DISCONNECTED, but because the server shut down
|
||||
} ChiakiQuitReason;
|
||||
|
||||
CHIAKI_EXPORT const char *chiaki_quit_reason_string(ChiakiQuitReason reason);
|
||||
|
||||
static inline bool chiaki_quit_reason_is_error(ChiakiQuitReason reason)
|
||||
{
|
||||
return reason != CHIAKI_QUIT_REASON_STOPPED && reason != CHIAKI_QUIT_REASON_STREAM_CONNECTION_REMOTE_SHUTDOWN;
|
||||
}
|
||||
|
||||
typedef struct chiaki_quit_event_t
|
||||
{
|
||||
ChiakiQuitReason reason;
|
||||
|
@ -121,6 +128,14 @@ typedef struct chiaki_rumble_event_t
|
|||
uint8_t right; // high-frequency
|
||||
} ChiakiRumbleEvent;
|
||||
|
||||
typedef struct chiaki_trigger_effects_event_t
|
||||
{
|
||||
uint8_t type_left;
|
||||
uint8_t type_right;
|
||||
uint8_t left[10];
|
||||
uint8_t right[10];
|
||||
} ChiakiTriggerEffectsEvent;
|
||||
|
||||
typedef enum {
|
||||
CHIAKI_EVENT_CONNECTED,
|
||||
CHIAKI_EVENT_LOGIN_PIN_REQUEST,
|
||||
|
@ -129,6 +144,7 @@ typedef enum {
|
|||
CHIAKI_EVENT_KEYBOARD_REMOTE_CLOSE,
|
||||
CHIAKI_EVENT_RUMBLE,
|
||||
CHIAKI_EVENT_QUIT,
|
||||
CHIAKI_EVENT_TRIGGER_EFFECTS,
|
||||
} ChiakiEventType;
|
||||
|
||||
typedef struct chiaki_event_t
|
||||
|
@ -139,6 +155,7 @@ typedef struct chiaki_event_t
|
|||
ChiakiQuitEvent quit;
|
||||
ChiakiKeyboardEvent keyboard;
|
||||
ChiakiRumbleEvent rumble;
|
||||
ChiakiTriggerEffectsEvent trigger_effects;
|
||||
struct
|
||||
{
|
||||
bool pin_incorrect; // false on first request, true if the pin entered before was incorrect
|
||||
|
@ -170,6 +187,7 @@ typedef struct chiaki_session_t
|
|||
ChiakiConnectVideoProfile video_profile;
|
||||
bool video_profile_auto_downgrade;
|
||||
bool enable_keyboard;
|
||||
bool enable_dualsense;
|
||||
} connect_info;
|
||||
|
||||
ChiakiTarget target;
|
||||
|
@ -191,6 +209,7 @@ typedef struct chiaki_session_t
|
|||
ChiakiVideoSampleCallback video_sample_cb;
|
||||
void *video_sample_cb_user;
|
||||
ChiakiAudioSink audio_sink;
|
||||
ChiakiAudioSink haptics_sink;
|
||||
|
||||
ChiakiThread session_thread;
|
||||
|
||||
|
@ -246,6 +265,14 @@ static inline void chiaki_session_set_audio_sink(ChiakiSession *session, ChiakiA
|
|||
session->audio_sink = *sink;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param sink contents are copied
|
||||
*/
|
||||
static inline void chiaki_session_set_haptics_sink(ChiakiSession *session, ChiakiAudioSink *sink)
|
||||
{
|
||||
session->haptics_sink = *sink;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -32,6 +32,7 @@ typedef struct chiaki_stream_connection_t
|
|||
ChiakiPacketStats packet_stats;
|
||||
ChiakiAudioReceiver *audio_receiver;
|
||||
ChiakiVideoReceiver *video_receiver;
|
||||
ChiakiAudioReceiver *haptics_receiver;
|
||||
|
||||
ChiakiFeedbackSender feedback_sender;
|
||||
/**
|
||||
|
|
|
@ -27,7 +27,8 @@ extern "C" {
|
|||
typedef enum chiaki_takion_message_data_type_t {
|
||||
CHIAKI_TAKION_MESSAGE_DATA_TYPE_PROTOBUF = 0,
|
||||
CHIAKI_TAKION_MESSAGE_DATA_TYPE_RUMBLE = 7,
|
||||
CHIAKI_TAKION_MESSAGE_DATA_TYPE_9 = 9
|
||||
CHIAKI_TAKION_MESSAGE_DATA_TYPE_9 = 9,
|
||||
CHIAKI_TAKION_MESSAGE_DATA_TYPE_TRIGGER_EFFECTS = 11,
|
||||
} ChiakiTakionMessageDataType;
|
||||
|
||||
typedef struct chiaki_takion_av_packet_t
|
||||
|
@ -36,6 +37,7 @@ typedef struct chiaki_takion_av_packet_t
|
|||
ChiakiSeqNum16 frame_index;
|
||||
bool uses_nalu_info_structs;
|
||||
bool is_video;
|
||||
bool is_haptics;
|
||||
ChiakiSeqNum16 unit_index;
|
||||
uint16_t units_in_frame_total; // source + units_in_frame_fec
|
||||
uint16_t units_in_frame_fec;
|
||||
|
@ -46,8 +48,6 @@ typedef struct chiaki_takion_av_packet_t
|
|||
|
||||
uint64_t key_pos;
|
||||
|
||||
uint8_t byte_before_audio_data;
|
||||
|
||||
uint8_t *data; // not owned
|
||||
size_t data_size;
|
||||
} ChiakiTakionAVPacket;
|
||||
|
@ -106,6 +106,7 @@ typedef struct chiaki_takion_connect_info_t
|
|||
ChiakiTakionCallback cb;
|
||||
void *cb_user;
|
||||
bool enable_crypt;
|
||||
bool enable_dualsense;
|
||||
uint8_t protocol_version;
|
||||
} ChiakiTakionConnectInfo;
|
||||
|
||||
|
@ -162,6 +163,8 @@ typedef struct chiaki_takion_t
|
|||
ChiakiTakionAVPacketParse av_packet_parse;
|
||||
|
||||
ChiakiKeyState key_state;
|
||||
|
||||
bool enable_dualsense;
|
||||
} ChiakiTakion;
|
||||
|
||||
|
||||
|
|
|
@ -11,8 +11,16 @@ add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/takion.pb"
|
|||
set(SOURCE_FILES "${CMAKE_CURRENT_BINARY_DIR}/takion.pb.c")
|
||||
set(HEADER_FILES "${CMAKE_CURRENT_BINARY_DIR}/takion.pb.h")
|
||||
|
||||
if(UNIX AND IS_ABSOLUTE "${PROTOC}")
|
||||
# make sure protoc is in PATH when invoking the generator below, which needs it.
|
||||
get_filename_component(PROTOC_PATH "${PROTOC}" DIRECTORY)
|
||||
set(GEN_PREFIX "${CMAKE_COMMAND}" -E env "PATH=${PROTOC_PATH}:$ENV{PATH}")
|
||||
else()
|
||||
set(GEN_PREFIX "")
|
||||
endif()
|
||||
|
||||
add_custom_command(OUTPUT ${SOURCE_FILES} ${HEADER_FILES}
|
||||
COMMAND "${PYTHON_EXECUTABLE}" "${NANOPB_GENERATOR_PY}" "${CMAKE_CURRENT_BINARY_DIR}/takion.pb"
|
||||
COMMAND ${GEN_PREFIX} "${PYTHON_EXECUTABLE}" "${NANOPB_GENERATOR_PY}" "${CMAKE_CURRENT_BINARY_DIR}/takion.pb"
|
||||
MAIN_DEPENDENCY "${CMAKE_CURRENT_BINARY_DIR}/takion.pb")
|
||||
|
||||
set(CHIAKI_LIB_PROTO_SOURCE_FILES "${SOURCE_FILES}" PARENT_SCOPE)
|
||||
|
|
|
@ -312,7 +312,8 @@ message ControllerConnectionPayload {
|
|||
VITA = 3;
|
||||
XINPUT = 4;
|
||||
MOBILE = 5;
|
||||
BOND = 6;
|
||||
DUALSENSE = 6;
|
||||
VR2SENSE = 7;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
#include <string.h>
|
||||
|
||||
static void chiaki_audio_receiver_frame(ChiakiAudioReceiver *audio_receiver, ChiakiSeqNum16 frame_index, uint8_t *buf, size_t buf_size);
|
||||
static void chiaki_audio_receiver_frame(ChiakiAudioReceiver *audio_receiver, ChiakiSeqNum16 frame_index, bool is_haptics, uint8_t *buf, size_t buf_size);
|
||||
|
||||
CHIAKI_EXPORT ChiakiErrorCode chiaki_audio_receiver_init(ChiakiAudioReceiver *audio_receiver, ChiakiSession *session, ChiakiPacketStats *packet_stats)
|
||||
{
|
||||
|
@ -102,14 +102,14 @@ CHIAKI_EXPORT void chiaki_audio_receiver_av_packet(ChiakiAudioReceiver *audio_re
|
|||
frame_index = packet->frame_index - fec_units_count + fec_index;
|
||||
}
|
||||
|
||||
chiaki_audio_receiver_frame(audio_receiver, frame_index, packet->data + unit_size * i, unit_size);
|
||||
chiaki_audio_receiver_frame(audio_receiver, frame_index, packet->is_haptics, packet->data + unit_size * i, unit_size);
|
||||
}
|
||||
|
||||
if(audio_receiver->packet_stats)
|
||||
chiaki_packet_stats_push_seq(audio_receiver->packet_stats, packet->frame_index);
|
||||
}
|
||||
|
||||
static void chiaki_audio_receiver_frame(ChiakiAudioReceiver *audio_receiver, ChiakiSeqNum16 frame_index, uint8_t *buf, size_t buf_size)
|
||||
static void chiaki_audio_receiver_frame(ChiakiAudioReceiver *audio_receiver, ChiakiSeqNum16 frame_index, bool is_haptics, uint8_t *buf, size_t buf_size)
|
||||
{
|
||||
chiaki_mutex_lock(&audio_receiver->mutex);
|
||||
|
||||
|
@ -117,7 +117,9 @@ static void chiaki_audio_receiver_frame(ChiakiAudioReceiver *audio_receiver, Chi
|
|||
goto beach;
|
||||
audio_receiver->frame_index_prev = frame_index;
|
||||
|
||||
if(audio_receiver->session->audio_sink.frame_cb)
|
||||
if(is_haptics && audio_receiver->session->haptics_sink.frame_cb)
|
||||
audio_receiver->session->haptics_sink.frame_cb(buf, buf_size, audio_receiver->session->haptics_sink.user);
|
||||
else if(!is_haptics && audio_receiver->session->audio_sink.frame_cb)
|
||||
audio_receiver->session->audio_sink.frame_cb(buf, buf_size, audio_receiver->session->audio_sink.user);
|
||||
|
||||
beach:
|
||||
|
|
|
@ -121,6 +121,19 @@ CHIAKI_EXPORT void chiaki_controller_state_or(ChiakiControllerState *out, Chiaki
|
|||
out->right_x = MAX_ABS(a->right_x, b->right_x);
|
||||
out->right_y = MAX_ABS(a->right_y, b->right_y);
|
||||
|
||||
#define ORF(n, idle_val) if(a->n == idle_val) out->n = b->n; else out->n = a->n
|
||||
ORF(accel_x, 0.0f);
|
||||
ORF(accel_y, 1.0f);
|
||||
ORF(accel_z, 0.0f);
|
||||
ORF(gyro_x, 0.0f);
|
||||
ORF(gyro_y, 0.0f);
|
||||
ORF(gyro_z, 0.0f);
|
||||
ORF(orient_x, 0.0f);
|
||||
ORF(orient_y, 0.0f);
|
||||
ORF(orient_z, 0.0f);
|
||||
ORF(orient_w, 1.0f);
|
||||
#undef ORF
|
||||
|
||||
out->touch_id_next = 0;
|
||||
for(size_t i = 0; i < CHIAKI_CONTROLLER_TOUCHES_MAX; i++)
|
||||
{
|
||||
|
|
|
@ -488,17 +488,25 @@ static void ctrl_message_received(ChiakiCtrl *ctrl, uint16_t msg_type, uint8_t *
|
|||
|
||||
static void ctrl_enable_optional_features(ChiakiCtrl *ctrl)
|
||||
{
|
||||
if(!ctrl->session->connect_info.enable_keyboard)
|
||||
return;
|
||||
// TODO: Last byte of pre_enable request is random (?)
|
||||
// TODO: Signature ?!
|
||||
uint8_t enable = 1;
|
||||
uint8_t pre_enable[4] = { 0x00, 0x01, 0x01, 0x80 };
|
||||
uint8_t signature[0x10] = { 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x05, 0xAE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
ctrl_message_send(ctrl, 0xD, signature, 0x10);
|
||||
ctrl_message_send(ctrl, 0x36, pre_enable, 4);
|
||||
ctrl_message_send(ctrl, CTRL_MESSAGE_TYPE_KEYBOARD_ENABLE_TOGGLE, &enable, 1);
|
||||
ctrl_message_send(ctrl, 0x36, pre_enable, 4);
|
||||
if(ctrl->session->connect_info.enable_dualsense)
|
||||
{
|
||||
CHIAKI_LOGI(ctrl->session->log, "Enabling DualSense features");
|
||||
const uint8_t enable[3] = { 0x00, 0x40, 0x00 };
|
||||
ctrl_message_send(ctrl, 0x13, enable, 3);
|
||||
}
|
||||
if(ctrl->session->connect_info.enable_keyboard)
|
||||
{
|
||||
CHIAKI_LOGI(ctrl->session->log, "Enabling Keyboard");
|
||||
// TODO: Last byte of pre_enable request is random (?)
|
||||
// TODO: Signature ?!
|
||||
uint8_t enable = 1;
|
||||
uint8_t pre_enable[4] = { 0x00, 0x01, 0x01, 0x80 };
|
||||
uint8_t signature[0x10] = { 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x05, 0xAE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
ctrl_message_send(ctrl, 0xD, signature, 0x10);
|
||||
ctrl_message_send(ctrl, 0x36, pre_enable, 4);
|
||||
ctrl_message_send(ctrl, CTRL_MESSAGE_TYPE_KEYBOARD_ENABLE_TOGGLE, &enable, 1);
|
||||
ctrl_message_send(ctrl, 0x36, pre_enable, 4);
|
||||
}
|
||||
}
|
||||
|
||||
static void ctrl_message_received_session_id(ChiakiCtrl *ctrl, uint8_t *payload, size_t payload_size)
|
||||
|
|
|
@ -81,7 +81,11 @@ CHIAKI_EXPORT void chiaki_feedback_state_format_v12(uint8_t *buf, ChiakiFeedback
|
|||
chiaki_feedback_state_format_v9(buf, state);
|
||||
buf[0x19] = 0x0;
|
||||
buf[0x1a] = 0x0;
|
||||
buf[0x1b] = 0x1; // 1 for Shock, 0 for Sense
|
||||
|
||||
// 1 is classic DualShock, 0 is DualSense, but using 0 requires setting [0x19] and [0x1a] to
|
||||
// values taken from raw HID, which is generally not available. But setting 1 for both seems
|
||||
// to always work fine.
|
||||
buf[0x1b] = 0x1;
|
||||
}
|
||||
|
||||
CHIAKI_EXPORT ChiakiErrorCode chiaki_feedback_history_event_set_button(ChiakiFeedbackHistoryEvent *event, uint64_t button, uint8_t state)
|
||||
|
|
|
@ -146,7 +146,15 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_recv_http_header(int sock, char *buf, size_
|
|||
return err;
|
||||
}
|
||||
|
||||
int received = (int)recv(sock, buf, (int)buf_size, 0);
|
||||
int received;
|
||||
do
|
||||
{
|
||||
received = (int)recv(sock, buf, (int)buf_size, 0);
|
||||
#if _WIN32
|
||||
} while(false);
|
||||
#else
|
||||
} while(received < 0 && errno == EINTR);
|
||||
#endif
|
||||
if(received <= 0)
|
||||
return received == 0 ? CHIAKI_ERR_DISCONNECTED : CHIAKI_ERR_NETWORK;
|
||||
|
||||
|
|
|
@ -158,6 +158,8 @@ CHIAKI_EXPORT const char *chiaki_quit_reason_string(ChiakiQuitReason reason)
|
|||
return "Unknown Error in Stream Connection";
|
||||
case CHIAKI_QUIT_REASON_STREAM_CONNECTION_REMOTE_DISCONNECTED:
|
||||
return "Remote has disconnected from Stream Connection";
|
||||
case CHIAKI_QUIT_REASON_STREAM_CONNECTION_REMOTE_SHUTDOWN:
|
||||
return "Remote has disconnected from Stream Connection the because Server shut down";
|
||||
case CHIAKI_QUIT_REASON_NONE:
|
||||
default:
|
||||
return "Unknown";
|
||||
|
@ -227,6 +229,7 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_session_init(ChiakiSession *session, Chiaki
|
|||
session->connect_info.video_profile = connect_info->video_profile;
|
||||
session->connect_info.video_profile_auto_downgrade = connect_info->video_profile_auto_downgrade;
|
||||
session->connect_info.enable_keyboard = connect_info->enable_keyboard;
|
||||
session->connect_info.enable_dualsense = connect_info->enable_dualsense;
|
||||
|
||||
return CHIAKI_ERR_SUCCESS;
|
||||
error_stop_pipe:
|
||||
|
@ -504,7 +507,10 @@ ctrl_failed:
|
|||
if(err == CHIAKI_ERR_DISCONNECTED)
|
||||
{
|
||||
CHIAKI_LOGE(session->log, "Remote disconnected from StreamConnection");
|
||||
session->quit_reason = CHIAKI_QUIT_REASON_STREAM_CONNECTION_REMOTE_DISCONNECTED;
|
||||
if(!strcmp(session->stream_connection.remote_disconnect_reason, "Server shutting down"))
|
||||
session->quit_reason = CHIAKI_QUIT_REASON_STREAM_CONNECTION_REMOTE_SHUTDOWN;
|
||||
else
|
||||
session->quit_reason = CHIAKI_QUIT_REASON_STREAM_CONNECTION_REMOTE_DISCONNECTED;
|
||||
session->quit_reason_str = strdup(session->stream_connection.remote_disconnect_reason);
|
||||
}
|
||||
else if(err != CHIAKI_ERR_SUCCESS && err != CHIAKI_ERR_CANCELED)
|
||||
|
|
|
@ -147,7 +147,11 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_stop_pipe_select_single(ChiakiStopPipe *sto
|
|||
timeout = &timeout_s;
|
||||
}
|
||||
|
||||
int r = select(nfds, &rfds, write ? &wfds : NULL, NULL, timeout);
|
||||
int r;
|
||||
do
|
||||
{
|
||||
r = select(nfds, &rfds, write ? &wfds : NULL, NULL, timeout);
|
||||
} while(r < 0 && errno == EINTR);
|
||||
|
||||
if(r < 0)
|
||||
return CHIAKI_ERR_UNKNOWN;
|
||||
|
|
|
@ -47,7 +47,9 @@ static void stream_connection_takion_cb(ChiakiTakionEvent *event, void *user);
|
|||
static void stream_connection_takion_data(ChiakiStreamConnection *stream_connection, ChiakiTakionMessageDataType data_type, uint8_t *buf, size_t buf_size);
|
||||
static void stream_connection_takion_data_protobuf(ChiakiStreamConnection *stream_connection, uint8_t *buf, size_t buf_size);
|
||||
static void stream_connection_takion_data_rumble(ChiakiStreamConnection *stream_connection, uint8_t *buf, size_t buf_size);
|
||||
static void stream_connection_takion_data_trigger_effects(ChiakiStreamConnection *stream_connection, uint8_t *buf, size_t buf_size);
|
||||
static ChiakiErrorCode stream_connection_send_big(ChiakiStreamConnection *stream_connection);
|
||||
static ChiakiErrorCode stream_connection_send_controller_connection(ChiakiStreamConnection *stream_connection);
|
||||
static ChiakiErrorCode stream_connection_send_disconnect(ChiakiStreamConnection *stream_connection);
|
||||
static void stream_connection_takion_data_idle(ChiakiStreamConnection *stream_connection, uint8_t *buf, size_t buf_size);
|
||||
static void stream_connection_takion_data_expect_bang(ChiakiStreamConnection *stream_connection, uint8_t *buf, size_t buf_size);
|
||||
|
@ -79,6 +81,7 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_stream_connection_init(ChiakiStreamConnecti
|
|||
|
||||
stream_connection->video_receiver = NULL;
|
||||
stream_connection->audio_receiver = NULL;
|
||||
stream_connection->haptics_receiver = NULL;
|
||||
|
||||
err = chiaki_mutex_init(&stream_connection->feedback_sender_mutex, false);
|
||||
if(err != CHIAKI_ERR_SUCCESS)
|
||||
|
@ -143,6 +146,7 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_stream_connection_run(ChiakiStreamConnectio
|
|||
takion_info.ip_dontfrag = false;
|
||||
|
||||
takion_info.enable_crypt = true;
|
||||
takion_info.enable_dualsense = session->connect_info.enable_dualsense;
|
||||
takion_info.protocol_version = chiaki_target_is_ps5(session->target) ? 12 : 9;
|
||||
|
||||
takion_info.cb = stream_connection_takion_cb;
|
||||
|
@ -164,12 +168,20 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_stream_connection_run(ChiakiStreamConnectio
|
|||
return CHIAKI_ERR_UNKNOWN;
|
||||
}
|
||||
|
||||
stream_connection->haptics_receiver = chiaki_audio_receiver_new(session, NULL);
|
||||
if(!stream_connection->haptics_receiver)
|
||||
{
|
||||
CHIAKI_LOGE(session->log, "StreamConnection failed to initialize Haptics Receiver");
|
||||
err = CHIAKI_ERR_UNKNOWN;
|
||||
goto err_audio_receiver;
|
||||
}
|
||||
|
||||
stream_connection->video_receiver = chiaki_video_receiver_new(session, &stream_connection->packet_stats);
|
||||
if(!stream_connection->video_receiver)
|
||||
{
|
||||
CHIAKI_LOGE(session->log, "StreamConnection failed to initialize Video Receiver");
|
||||
err = CHIAKI_ERR_UNKNOWN;
|
||||
goto err_audio_receiver;
|
||||
goto err_haptics_receiver;
|
||||
}
|
||||
|
||||
stream_connection->state = STATE_TAKION_CONNECT;
|
||||
|
@ -321,6 +333,10 @@ err_video_receiver:
|
|||
chiaki_video_receiver_free(stream_connection->video_receiver);
|
||||
stream_connection->video_receiver = NULL;
|
||||
|
||||
err_haptics_receiver:
|
||||
chiaki_audio_receiver_free(stream_connection->haptics_receiver);
|
||||
stream_connection->haptics_receiver = NULL;
|
||||
|
||||
err_audio_receiver:
|
||||
chiaki_audio_receiver_free(stream_connection->audio_receiver);
|
||||
stream_connection->audio_receiver = NULL;
|
||||
|
@ -376,6 +392,9 @@ static void stream_connection_takion_data(ChiakiStreamConnection *stream_connect
|
|||
case CHIAKI_TAKION_MESSAGE_DATA_TYPE_RUMBLE:
|
||||
stream_connection_takion_data_rumble(stream_connection, buf, buf_size);
|
||||
break;
|
||||
case CHIAKI_TAKION_MESSAGE_DATA_TYPE_TRIGGER_EFFECTS:
|
||||
stream_connection_takion_data_trigger_effects(stream_connection, buf, buf_size);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -415,6 +434,24 @@ static void stream_connection_takion_data_rumble(ChiakiStreamConnection *stream_
|
|||
chiaki_session_send_event(stream_connection->session, &event);
|
||||
}
|
||||
|
||||
|
||||
static void stream_connection_takion_data_trigger_effects(ChiakiStreamConnection *stream_connection, uint8_t *buf, size_t buf_size)
|
||||
{
|
||||
if(buf_size < 25)
|
||||
{
|
||||
CHIAKI_LOGE(stream_connection->log, "StreamConnection got trigger effects packet with size %#llx < 25",
|
||||
(unsigned long long)buf_size);
|
||||
return;
|
||||
}
|
||||
ChiakiEvent event = { 0 };
|
||||
event.type = CHIAKI_EVENT_TRIGGER_EFFECTS;
|
||||
event.trigger_effects.type_left = buf[1];
|
||||
event.trigger_effects.type_right = buf[2];
|
||||
memcpy(&event.trigger_effects.left, buf + 5, 10);
|
||||
memcpy(&event.trigger_effects.right, buf + 15, 10);
|
||||
chiaki_session_send_event(stream_connection->session, &event);
|
||||
}
|
||||
|
||||
static void stream_connection_takion_data_handle_disconnect(ChiakiStreamConnection *stream_connection, uint8_t *buf, size_t buf_size)
|
||||
{
|
||||
tkproto_TakionMessage msg;
|
||||
|
@ -460,7 +497,7 @@ static void stream_connection_takion_data_idle(ChiakiStreamConnection *stream_co
|
|||
return;
|
||||
}
|
||||
|
||||
CHIAKI_LOGV(stream_connection->log, "StreamConnection received data");
|
||||
CHIAKI_LOGV(stream_connection->log, "StreamConnection received data with msg.type == %d", msg.type);
|
||||
chiaki_log_hexdump(stream_connection->log, CHIAKI_LOG_VERBOSE, buf, buf_size);
|
||||
|
||||
if(msg.type == tkproto_TakionMessage_PayloadType_DISCONNECT)
|
||||
|
@ -522,7 +559,8 @@ static void stream_connection_takion_data_expect_bang(ChiakiStreamConnection *st
|
|||
return;
|
||||
}
|
||||
|
||||
CHIAKI_LOGE(stream_connection->log, "StreamConnection expected bang payload but received something else");
|
||||
CHIAKI_LOGE(stream_connection->log, "StreamConnection expected bang payload but received something else: %d", msg.type);
|
||||
chiaki_log_hexdump(stream_connection->log, CHIAKI_LOG_VERBOSE, buf, buf_size);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -584,6 +622,12 @@ static void stream_connection_takion_data_expect_bang(ChiakiStreamConnection *st
|
|||
// stream_connection->state_mutex is expected to be locked by the caller of this function
|
||||
stream_connection->state_finished = true;
|
||||
chiaki_cond_signal(&stream_connection->state_cond);
|
||||
err = stream_connection_send_controller_connection(stream_connection);
|
||||
if(err != CHIAKI_ERR_SUCCESS)
|
||||
{
|
||||
CHIAKI_LOGE(stream_connection->log, "StreamConnection failed to send controller connection");
|
||||
goto error;
|
||||
}
|
||||
return;
|
||||
error:
|
||||
stream_connection->state_failed = true;
|
||||
|
@ -811,6 +855,37 @@ static ChiakiErrorCode stream_connection_send_big(ChiakiStreamConnection *stream
|
|||
return err;
|
||||
}
|
||||
|
||||
static ChiakiErrorCode stream_connection_send_controller_connection(ChiakiStreamConnection *stream_connection)
|
||||
{
|
||||
ChiakiSession *session = stream_connection->session;
|
||||
tkproto_TakionMessage msg;
|
||||
memset(&msg, 0, sizeof(msg));
|
||||
|
||||
msg.type = tkproto_TakionMessage_PayloadType_CONTROLLERCONNECTION;
|
||||
msg.has_controller_connection_payload = true;
|
||||
msg.controller_connection_payload.has_connected = true;
|
||||
msg.controller_connection_payload.connected = true;
|
||||
msg.controller_connection_payload.has_controller_id = false;
|
||||
msg.controller_connection_payload.has_controller_type = true;
|
||||
msg.controller_connection_payload.controller_type = session->connect_info.enable_dualsense
|
||||
? tkproto_ControllerConnectionPayload_ControllerType_DUALSENSE
|
||||
: tkproto_ControllerConnectionPayload_ControllerType_DUALSHOCK4;
|
||||
|
||||
uint8_t buf[2048];
|
||||
size_t buf_size;
|
||||
|
||||
pb_ostream_t stream = pb_ostream_from_buffer(buf, sizeof(buf));
|
||||
bool pbr = pb_encode(&stream, tkproto_TakionMessage_fields, &msg);
|
||||
if(!pbr)
|
||||
{
|
||||
CHIAKI_LOGE(stream_connection->log, "StreamConnection controller connection protobuf encoding failed");
|
||||
return CHIAKI_ERR_UNKNOWN;
|
||||
}
|
||||
|
||||
buf_size = stream.bytes_written;
|
||||
return chiaki_takion_send_message_data(&stream_connection->takion, 1, 1, buf, buf_size, NULL);
|
||||
}
|
||||
|
||||
static ChiakiErrorCode stream_connection_send_streaminfo_ack(ChiakiStreamConnection *stream_connection)
|
||||
{
|
||||
tkproto_TakionMessage msg;
|
||||
|
@ -867,6 +942,8 @@ static void stream_connection_takion_av(ChiakiStreamConnection *stream_connectio
|
|||
|
||||
if(packet->is_video)
|
||||
chiaki_video_receiver_av_packet(stream_connection->video_receiver, packet);
|
||||
else if(packet->is_haptics)
|
||||
chiaki_audio_receiver_av_packet(stream_connection->haptics_receiver, packet);
|
||||
else
|
||||
chiaki_audio_receiver_av_packet(stream_connection->audio_receiver, packet);
|
||||
}
|
||||
|
|
|
@ -57,7 +57,8 @@ typedef enum takion_packet_type_t {
|
|||
TAKION_PACKET_TYPE_CONGESTION = 5,
|
||||
TAKION_PACKET_TYPE_FEEDBACK_STATE = 6,
|
||||
TAKION_PACKET_TYPE_CLIENT_INFO = 8,
|
||||
TAKION_PACKET_TYPE_PAD_INFO_EVENT = 9
|
||||
TAKION_PACKET_TYPE_PAD_INFO_EVENT = 9,
|
||||
TAKION_PACKET_TYPE_PAD_ADAPTIVE_TRIGGERS = 11,
|
||||
} TakionPacketType;
|
||||
|
||||
/**
|
||||
|
@ -215,6 +216,7 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_connect(ChiakiTakion *takion, Chiaki
|
|||
takion->postponed_packets = NULL;
|
||||
takion->postponed_packets_size = 0;
|
||||
takion->postponed_packets_count = 0;
|
||||
takion->enable_dualsense = info->enable_dualsense;
|
||||
|
||||
CHIAKI_LOGI(takion->log, "Takion connecting (version %u)", (unsigned int)info->protocol_version);
|
||||
|
||||
|
@ -950,6 +952,7 @@ static void takion_flush_data_queue(ChiakiTakion *takion)
|
|||
|
||||
if(data_type != CHIAKI_TAKION_MESSAGE_DATA_TYPE_PROTOBUF
|
||||
&& data_type != CHIAKI_TAKION_MESSAGE_DATA_TYPE_RUMBLE
|
||||
&& data_type != CHIAKI_TAKION_MESSAGE_DATA_TYPE_TRIGGER_EFFECTS
|
||||
&& data_type != CHIAKI_TAKION_MESSAGE_DATA_TYPE_9)
|
||||
{
|
||||
CHIAKI_LOGW(takion->log, "Takion received data with unexpected data type %#x", data_type);
|
||||
|
@ -1308,7 +1311,7 @@ static ChiakiErrorCode av_packet_parse(bool v12, ChiakiTakionAVPacket *packet, C
|
|||
|
||||
if(v12 && !packet->is_video)
|
||||
{
|
||||
packet->byte_before_audio_data = *av;
|
||||
packet->is_haptics = *av == 0x02;
|
||||
av += 1;
|
||||
av_size -= 1;
|
||||
}
|
||||
|
|
13
scripts/Dockerfile.noble
Normal file
13
scripts/Dockerfile.noble
Normal file
|
@ -0,0 +1,13 @@
|
|||
|
||||
FROM ubuntu:noble
|
||||
|
||||
RUN apt-get update
|
||||
# Hint: python3-setuptools should not be needed with nanopb >= 0.4.9
|
||||
RUN apt-get -y install git g++ cmake ninja-build curl pkg-config unzip \
|
||||
python3-protobuf protobuf-compiler \
|
||||
python3-setuptools \
|
||||
libssl-dev libopus-dev qtbase5-dev qtmultimedia5-dev libqt5multimedia5-plugins libqt5svg5-dev \
|
||||
libgl1-mesa-dev nasm libudev-dev libva-dev fuse libevdev-dev libudev-dev file
|
||||
|
||||
CMD []
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
|
||||
FROM ubuntu:xenial
|
||||
|
||||
RUN apt-get update
|
||||
RUN apt-get install -y software-properties-common
|
||||
RUN add-apt-repository ppa:beineri/opt-qt-5.12.3-xenial
|
||||
RUN apt-get update
|
||||
RUN apt-get -y install git g++ cmake ninja-build curl pkg-config unzip python3-pip \
|
||||
libssl-dev libopus-dev qt512base qt512multimedia qt512svg \
|
||||
libgl1-mesa-dev nasm libudev-dev libva-dev fuse libevdev-dev libudev-dev
|
||||
|
||||
CMD []
|
||||
|
|
@ -1,77 +1,92 @@
|
|||
#!/bin/bash
|
||||
|
||||
echo "APPVEYOR_BUILD_FOLDER=$APPVEYOR_BUILD_FOLDER"
|
||||
set -xe
|
||||
|
||||
mkdir ninja && cd ninja || exit 1
|
||||
wget https://github.com/ninja-build/ninja/releases/download/v1.9.0/ninja-win.zip && 7z x ninja-win.zip || exit 1
|
||||
cd .. || exit 1
|
||||
BUILD_ROOT="$( cd "$( dirname "${BASH_SOURCE[0]}" )/.." && pwd )"
|
||||
BUILD_ROOT="$(echo $BUILD_ROOT | sed 's|^/\([a-z]\)|\1:|g')" # replace /c/... by c:/... for cmake to understand it
|
||||
echo "BUILD_ROOT=$BUILD_ROOT"
|
||||
|
||||
mkdir yasm && cd yasm || exit 1
|
||||
wget http://www.tortall.net/projects/yasm/releases/yasm-1.3.0-win64.exe && mv yasm-1.3.0-win64.exe yasm.exe || exit 1
|
||||
cd .. || exit 1
|
||||
mkdir ninja && cd ninja
|
||||
wget https://github.com/ninja-build/ninja/releases/download/v1.9.0/ninja-win.zip && 7z x ninja-win.zip
|
||||
cd ..
|
||||
|
||||
mkdir yasm && cd yasm
|
||||
wget http://www.tortall.net/projects/yasm/releases/yasm-1.3.0-win64.exe && mv yasm-1.3.0-win64.exe yasm.exe
|
||||
cd ..
|
||||
|
||||
export PATH="$PWD/ninja:$PWD/yasm:/c/Qt/5.12/msvc2017_64/bin:$PATH"
|
||||
|
||||
scripts/build-ffmpeg.sh . --target-os=win64 --arch=x86_64 --toolchain=msvc || exit 1
|
||||
scripts/build-ffmpeg.sh . --target-os=win64 --arch=x86_64 --toolchain=msvc
|
||||
|
||||
git clone https://github.com/xiph/opus.git && cd opus && git checkout ad8fe90db79b7d2a135e3dfd2ed6631b0c5662ab || exit 1
|
||||
mkdir build && cd build || exit 1
|
||||
git clone https://github.com/xiph/opus.git && cd opus && git checkout ad8fe90db79b7d2a135e3dfd2ed6631b0c5662ab
|
||||
mkdir build && cd build
|
||||
cmake \
|
||||
-G Ninja \
|
||||
-DCMAKE_C_COMPILER=cl \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_INSTALL_PREFIX="$APPVEYOR_BUILD_FOLDER/opus-prefix" \
|
||||
.. || exit 1
|
||||
ninja || exit 1
|
||||
ninja install || exit 1
|
||||
cd ../.. || exit 1
|
||||
-DCMAKE_INSTALL_PREFIX="$BUILD_ROOT/opus-prefix" \
|
||||
..
|
||||
ninja
|
||||
ninja install
|
||||
cd ../..
|
||||
|
||||
wget https://mirror.firedaemon.com/OpenSSL/openssl-1.1.1d-dev.zip && 7z x openssl-1.1.1d-dev.zip || exit 1
|
||||
wget https://download.firedaemon.com/FireDaemon-OpenSSL/openssl-1.1.1s.zip && 7z x openssl-1.1.*.zip
|
||||
|
||||
wget https://www.libsdl.org/release/SDL2-devel-2.0.10-VC.zip && 7z x SDL2-devel-2.0.10-VC.zip || exit 1
|
||||
export SDL_ROOT="$APPVEYOR_BUILD_FOLDER/SDL2-2.0.10" || exit 1
|
||||
export SDL_ROOT=${SDL_ROOT//[\\]//} || exit 1
|
||||
wget https://www.libsdl.org/release/SDL2-devel-2.26.2-VC.zip && 7z x SDL2-devel-2.26.2-VC.zip
|
||||
export SDL_ROOT="$BUILD_ROOT/SDL2-2.26.2"
|
||||
export SDL_ROOT=${SDL_ROOT//[\\]//}
|
||||
echo "set(SDL2_INCLUDE_DIRS \"$SDL_ROOT/include\")
|
||||
set(SDL2_LIBRARIES \"$SDL_ROOT/lib/x64/SDL2.lib\")
|
||||
set(SDL2_LIBDIR \"$SDL_ROOT/lib/x64\")" > "$SDL_ROOT/SDL2Config.cmake" || exit 1
|
||||
set(SDL2_LIBDIR \"$SDL_ROOT/lib/x64\")
|
||||
include($SDL_ROOT/cmake/sdl2-config-version.cmake)" > "$SDL_ROOT/SDL2Config.cmake"
|
||||
|
||||
mkdir protoc && cd protoc || exit 1
|
||||
wget https://github.com/protocolbuffers/protobuf/releases/download/v3.9.1/protoc-3.9.1-win64.zip && 7z x protoc-3.9.1-win64.zip || exit 1
|
||||
cd .. || exit 1
|
||||
export PATH="$PWD/protoc/bin:$PATH" || exit 1
|
||||
mkdir protoc && cd protoc
|
||||
wget https://github.com/protocolbuffers/protobuf/releases/download/v3.9.1/protoc-3.9.1-win64.zip && 7z x protoc-3.9.1-win64.zip
|
||||
cd ..
|
||||
export PATH="$PWD/protoc/bin:$PATH"
|
||||
|
||||
PYTHON="C:/Python37/python.exe"
|
||||
"$PYTHON" -m pip install protobuf || exit 1
|
||||
"$PYTHON" -m pip install protobuf==3.19.5
|
||||
|
||||
QT_PATH="C:/Qt/5.12/msvc2017_64"
|
||||
QT_PATH="C:/Qt/5.15/msvc2019_64"
|
||||
|
||||
COPY_DLLS="$PWD/openssl-1.1/x64/bin/libcrypto-1_1-x64.dll $PWD/openssl-1.1/x64/bin/libssl-1_1-x64.dll $SDL_ROOT/lib/x64/SDL2.dll"
|
||||
|
||||
mkdir build && cd build || exit 1
|
||||
echo "-- Configure"
|
||||
|
||||
mkdir build && cd build
|
||||
|
||||
|
||||
cmake \
|
||||
-G Ninja \
|
||||
-DCMAKE_C_COMPILER=cl \
|
||||
-DCMAKE_C_FLAGS="-we4013" \
|
||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
|
||||
-DCMAKE_PREFIX_PATH="$APPVEYOR_BUILD_FOLDER/ffmpeg-prefix;$APPVEYOR_BUILD_FOLDER/opus-prefix;$APPVEYOR_BUILD_FOLDER/openssl-1.1/x64;$QT_PATH;$SDL_ROOT" \
|
||||
-DCMAKE_PREFIX_PATH="$BUILD_ROOT/ffmpeg-prefix;$BUILD_ROOT/opus-prefix;$BUILD_ROOT/openssl-1.1/x64;$QT_PATH;$SDL_ROOT" \
|
||||
-DPYTHON_EXECUTABLE="$PYTHON" \
|
||||
-DCHIAKI_ENABLE_TESTS=ON \
|
||||
-DCHIAKI_ENABLE_CLI=OFF \
|
||||
-DCHIAKI_GUI_ENABLE_SDL_GAMECONTROLLER=ON \
|
||||
.. || exit 1
|
||||
..
|
||||
|
||||
ninja || exit 1
|
||||
echo "-- Build"
|
||||
|
||||
test/chiaki-unit.exe || exit 1
|
||||
ninja
|
||||
|
||||
cd .. || exit 1
|
||||
echo "-- Test"
|
||||
|
||||
cp $COPY_DLLS test/
|
||||
test/chiaki-unit.exe
|
||||
|
||||
cd ..
|
||||
|
||||
|
||||
# Deploy
|
||||
|
||||
mkdir Chiaki && cp build/gui/chiaki.exe Chiaki || exit 1
|
||||
mkdir Chiaki-PDB && cp build/gui/chiaki.pdb Chiaki-PDB || exit 1
|
||||
echo "-- Deploy"
|
||||
|
||||
"$QT_PATH/bin/windeployqt.exe" Chiaki/chiaki.exe || exit 1
|
||||
mkdir Chiaki && cp build/gui/chiaki.exe Chiaki
|
||||
mkdir Chiaki-PDB && cp build/gui/chiaki.pdb Chiaki-PDB
|
||||
|
||||
"$QT_PATH/bin/windeployqt.exe" Chiaki/chiaki.exe
|
||||
cp -v $COPY_DLLS Chiaki
|
||||
|
|
|
@ -2,10 +2,11 @@
|
|||
|
||||
set -xe
|
||||
|
||||
# sometimes there are errors in linuxdeploy in docker/podman when the appdir is on a mount
|
||||
appdir=${1:-`pwd`/appimage/appdir}
|
||||
|
||||
mkdir appimage
|
||||
|
||||
pip3 install --user protobuf
|
||||
scripts/fetch-protoc.sh appimage
|
||||
export PATH="`pwd`/appimage/protoc/bin:$PATH"
|
||||
scripts/build-ffmpeg.sh appimage
|
||||
scripts/build-sdl2.sh appimage
|
||||
|
@ -15,31 +16,31 @@ cd build_appimage
|
|||
cmake \
|
||||
-GNinja \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
"-DCMAKE_PREFIX_PATH=`pwd`/../appimage/ffmpeg-prefix;`pwd`/../appimage/sdl2-prefix;/opt/qt512" \
|
||||
"-DCMAKE_PREFIX_PATH=`pwd`/../appimage/ffmpeg-prefix;`pwd`/../appimage/sdl2-prefix" \
|
||||
-DCHIAKI_ENABLE_TESTS=ON \
|
||||
-DCHIAKI_ENABLE_CLI=OFF \
|
||||
-DCHIAKI_ENABLE_GUI=ON \
|
||||
-DCHIAKI_ENABLE_SETSU=ON \
|
||||
-DCHIAKI_GUI_ENABLE_SDL_GAMECONTROLLER=ON \
|
||||
-DCMAKE_INSTALL_PREFIX=/usr \
|
||||
..
|
||||
cd ..
|
||||
|
||||
# purge leftover proto/nanopb_pb2.py which may have been created with another protobuf version
|
||||
rm -fv third-party/nanopb/generator/proto/nanopb_pb2.py
|
||||
|
||||
ninja -C build_appimage
|
||||
build_appimage/test/chiaki-unit
|
||||
|
||||
DESTDIR=`pwd`/appimage/appdir ninja -C build_appimage install
|
||||
DESTDIR="${appdir}" ninja -C build_appimage install
|
||||
cd appimage
|
||||
|
||||
curl -L -O https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage
|
||||
chmod +x linuxdeploy-x86_64.AppImage
|
||||
curl -L -O https://github.com/linuxdeploy/linuxdeploy-plugin-qt/releases/download/continuous/linuxdeploy-plugin-qt-x86_64.AppImage
|
||||
chmod +x linuxdeploy-plugin-qt-x86_64.AppImage
|
||||
set +e
|
||||
source /opt/qt512/bin/qt512-env.sh
|
||||
set -e
|
||||
|
||||
export LD_LIBRARY_PATH="`pwd`/sdl2-prefix/lib:$LD_LIBRARY_PATH"
|
||||
export EXTRA_QT_PLUGINS=opengl
|
||||
|
||||
./linuxdeploy-x86_64.AppImage --appdir=appdir -e appdir/usr/bin/chiaki -d appdir/usr/share/applications/chiaki.desktop --plugin qt --output appimage
|
||||
mv Chiaki-*-x86_64.AppImage Chiaki.AppImage
|
||||
./linuxdeploy-x86_64.AppImage --appdir="${appdir}" -e "${appdir}/usr/bin/chiaki" -d "${appdir}/usr/share/applications/chiaki.desktop" --plugin qt --output appimage
|
||||
mv Chiaki*-x86_64.AppImage Chiaki.AppImage
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
#!/bin/bash
|
||||
|
||||
# purge leftover proto/nanopb_pb2.py which may have been created with another protobuf version
|
||||
rm -fv third-party/nanopb/generator/proto/nanopb_pb2.py
|
||||
|
||||
mkdir build && cd build || exit 1
|
||||
cmake \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
|
|
|
@ -5,7 +5,7 @@ cd "./$1"
|
|||
shift
|
||||
ROOT="`pwd`"
|
||||
|
||||
TAG=n4.3.1
|
||||
TAG=n4.3.9
|
||||
|
||||
git clone https://git.ffmpeg.org/ffmpeg.git --depth 1 -b $TAG && cd ffmpeg || exit 1
|
||||
|
||||
|
|
|
@ -6,9 +6,10 @@ cd $(dirname "${BASH_SOURCE[0]}")/..
|
|||
cd "./$1"
|
||||
ROOT="`pwd`"
|
||||
|
||||
URL=https://www.libsdl.org/release/SDL2-2.0.10.tar.gz
|
||||
FILE=SDL2-2.0.10.tar.gz
|
||||
DIR=SDL2-2.0.10
|
||||
SDL_VER=2.26.1
|
||||
URL=https://www.libsdl.org/release/SDL2-${SDL_VER}.tar.gz
|
||||
FILE=SDL2-${SDL_VER}.tar.gz
|
||||
DIR=SDL2-${SDL_VER}
|
||||
|
||||
if [ ! -d "$DIR" ]; then
|
||||
curl -L "$URL" -O
|
||||
|
@ -21,14 +22,14 @@ mkdir -p build && cd build || exit 1
|
|||
cmake \
|
||||
-DCMAKE_INSTALL_PREFIX="$ROOT/sdl2-prefix" \
|
||||
-DSDL_ATOMIC=OFF \
|
||||
-DSDL_AUDIO=OFF \
|
||||
-DSDL_AUDIO=ON \
|
||||
-DSDL_CPUINFO=OFF \
|
||||
-DSDL_EVENTS=ON \
|
||||
-DSDL_FILE=OFF \
|
||||
-DSDL_FILESYSTEM=OFF \
|
||||
-DSDL_HAPTIC=ON \
|
||||
-DSDL_JOYSTICK=ON \
|
||||
-DSDL_LOADSO=OFF \
|
||||
-DSDL_LOADSO=ON \
|
||||
-DSDL_RENDER=OFF \
|
||||
-DSDL_SHARED=ON \
|
||||
-DSDL_STATIC=OFF \
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -xe
|
||||
|
||||
cd $(dirname "${BASH_SOURCE[0]}")/..
|
||||
cd "./$1"
|
||||
ROOT="`pwd`"
|
||||
|
||||
URL=https://github.com/protocolbuffers/protobuf/releases/download/v3.9.1/protoc-3.9.1-linux-x86_64.zip
|
||||
|
||||
curl -L "$URL" -o protoc.zip
|
||||
unzip protoc.zip -d protoc
|
||||
|
|
@ -89,8 +89,8 @@
|
|||
{
|
||||
"type": "git",
|
||||
"url": "https://git.sr.ht/~thestr4ng3r/chiaki",
|
||||
"tag": "v2.0.1",
|
||||
"commit": "9e698dd7c4e4011ff6e136741abef5cf4b32527c"
|
||||
"tag": "v2.1.1",
|
||||
"commit": "2257030adeb5c5a84380c78d34be4d783971663c"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
18
scripts/macos-dist-local.sh
Executable file
18
scripts/macos-dist-local.sh
Executable file
|
@ -0,0 +1,18 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Build Chiaki for macOS distribution using dependencies from MacPorts and custom ffmpeg
|
||||
|
||||
set -xe
|
||||
cd $(dirname "${BASH_SOURCE[0]}")/..
|
||||
scripts/build-ffmpeg.sh
|
||||
export CMAKE_PREFIX_PATH="`pwd`/ffmpeg-prefix"
|
||||
scripts/build-common.sh
|
||||
cp -a build/gui/chiaki.app Chiaki.app
|
||||
/opt/local/libexec/qt5/bin/macdeployqt Chiaki.app
|
||||
|
||||
# Remove all LC_RPATH load commands that have absolute paths of the build machine
|
||||
RPATHS=$(otool -l Chiaki.app/Contents/MacOS/chiaki | grep -A 2 LC_RPATH | grep 'path /' | awk '{print $2}')
|
||||
for p in ${RPATHS}; do install_name_tool -delete_rpath "$p" Chiaki.app/Contents/MacOS/chiaki; done
|
||||
|
||||
# This may warn because we already ran macdeployqt above
|
||||
/opt/local/libexec/qt5/bin/macdeployqt Chiaki.app -dmg
|
|
@ -1,15 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -xe
|
||||
cd "`dirname $(readlink -f ${0})`"
|
||||
|
||||
docker build -t chiaki-xenial . -f Dockerfile.xenial
|
||||
cd ..
|
||||
docker run --rm \
|
||||
-v "`pwd`:/build/chiaki" \
|
||||
-w "/build/chiaki" \
|
||||
--device /dev/fuse \
|
||||
--cap-add SYS_ADMIN \
|
||||
-t chiaki-xenial \
|
||||
/bin/bash -c "scripts/build-appimage.sh"
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -xe
|
||||
cd "`dirname $(readlink -f ${0})`"
|
||||
|
||||
docker build -t chiaki-bullseye . -f Dockerfile.bullseye
|
||||
cd ..
|
||||
docker run --rm -v "`pwd`:/build" chiaki-bullseye /bin/bash -c "
|
||||
cd /build &&
|
||||
mkdir build_bullseye &&
|
||||
cmake -Bbuild_bullseye -GNinja -DCHIAKI_ENABLE_SETSU=ON -DCHIAKI_USE_SYSTEM_JERASURE=ON -DCHIAKI_USE_SYSTEM_NANOPB=ON &&
|
||||
ninja -C build_bullseye &&
|
||||
ninja -C build_bullseye test"
|
||||
|
16
scripts/run-podman-build-appimage.sh
Executable file
16
scripts/run-podman-build-appimage.sh
Executable file
|
@ -0,0 +1,16 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -xe
|
||||
cd "`dirname $(readlink -f ${0})`"
|
||||
|
||||
podman build --arch amd64 -t localhost/chiaki-noble . -f Dockerfile.noble
|
||||
cd ..
|
||||
podman run --rm \
|
||||
--arch amd64 \
|
||||
-v "`pwd`:/build/chiaki" \
|
||||
-w "/build/chiaki" \
|
||||
--device /dev/fuse \
|
||||
--cap-add SYS_ADMIN \
|
||||
-t localhost/chiaki-noble \
|
||||
/bin/bash -c "scripts/build-appimage.sh /build/appdir"
|
||||
|
15
scripts/run-podman-build-bullseye.sh
Executable file
15
scripts/run-podman-build-bullseye.sh
Executable file
|
@ -0,0 +1,15 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -xe
|
||||
cd "`dirname $(readlink -f ${0})`"
|
||||
|
||||
podman build -t chiaki-bullseye . -f Dockerfile.bullseye
|
||||
cd ..
|
||||
podman run --rm -v "`pwd`:/build" chiaki-bullseye /bin/bash -c "
|
||||
cd /build &&
|
||||
rm -fv third-party/nanopb/generator/proto/nanopb_pb2.py &&
|
||||
mkdir build_bullseye &&
|
||||
cmake -Bbuild_bullseye -GNinja -DCHIAKI_USE_SYSTEM_JERASURE=ON -DCHIAKI_USE_SYSTEM_NANOPB=ON &&
|
||||
ninja -C build_bullseye &&
|
||||
ninja -C build_bullseye test"
|
||||
|
|
@ -5,10 +5,7 @@ set -xveo pipefail
|
|||
arg1=$1
|
||||
build="./build"
|
||||
if [ "$arg1" != "linux" ]; then
|
||||
# source /opt/devkitpro/switchvars.sh
|
||||
# toolchain="${DEVKITPRO}/switch.cmake"
|
||||
toolchain="cmake/switch.cmake"
|
||||
export PORTLIBS_PREFIX="$(${DEVKITPRO}/portlibs_prefix.sh switch)"
|
||||
build="./build_switch"
|
||||
fi
|
||||
|
||||
|
@ -19,6 +16,9 @@ build_chiaki (){
|
|||
pushd "${BASEDIR}"
|
||||
#rm -rf ./build
|
||||
|
||||
# purge leftover proto/nanopb_pb2.py which may have been created with another protobuf version
|
||||
rm -fv third-party/nanopb/generator/proto/nanopb_pb2.py
|
||||
|
||||
cmake -B "${build}" \
|
||||
-GNinja \
|
||||
-DCMAKE_TOOLCHAIN_FILE=${toolchain} \
|
||||
|
|
|
@ -2,10 +2,9 @@
|
|||
|
||||
cd "`dirname $(readlink -f ${0})`/../.."
|
||||
|
||||
docker run \
|
||||
podman run --rm \
|
||||
-v "`pwd`:/build/chiaki" \
|
||||
-w "/build/chiaki" \
|
||||
-t \
|
||||
thestr4ng3r/chiaki-build-switch \
|
||||
-c "scripts/switch/build.sh"
|
||||
|
||||
-it \
|
||||
quay.io/thestr4ng3r/chiaki-build-switch:v3 \
|
||||
/bin/bash
|
10
scripts/switch/run-podman-build-chiaki.sh
Executable file
10
scripts/switch/run-podman-build-chiaki.sh
Executable file
|
@ -0,0 +1,10 @@
|
|||
#!/bin/bash
|
||||
|
||||
cd "`dirname $(readlink -f ${0})`/../.."
|
||||
|
||||
podman run --rm \
|
||||
-v "`pwd`:/build/chiaki" \
|
||||
-w "/build/chiaki" \
|
||||
-it \
|
||||
quay.io/thestr4ng3r/chiaki-build-switch:v3 \
|
||||
${1:-/bin/bash -c "scripts/switch/build.sh"}
|
|
@ -61,17 +61,16 @@ target_include_directories(borealis PUBLIC
|
|||
|
||||
find_package(glfw3 REQUIRED)
|
||||
find_library(EGL EGL)
|
||||
find_library(GLAPI glapi)
|
||||
find_library(DRM_NOUVEAU drm_nouveau)
|
||||
target_link_libraries(borealis
|
||||
target_link_libraries(borealis PUBLIC
|
||||
glfw
|
||||
${EGL}
|
||||
${GLAPI}
|
||||
${DRM_NOUVEAU})
|
||||
${EGL})
|
||||
|
||||
if(CHIAKI_IS_SWITCH)
|
||||
target_compile_definitions(borealis PUBLIC
|
||||
BOREALIS_RESOURCES="romfs:/")
|
||||
find_library(GLAPI glapi)
|
||||
find_library(DRM_NOUVEAU drm_nouveau)
|
||||
target_link_libraries(borealis PUBLIC ${GLAPI} ${DRM_NOUVEAU})
|
||||
else()
|
||||
target_compile_definitions(borealis PUBLIC
|
||||
BOREALIS_RESOURCES="./switch/res/")
|
||||
|
@ -114,9 +113,7 @@ target_link_libraries(chiaki-borealis
|
|||
if(CHIAKI_IS_SWITCH)
|
||||
# libnx is forced by the switch toolchain
|
||||
find_library(Z z)
|
||||
find_library(GLAPI glapi) # TODO: make it transitive from borealis
|
||||
find_library(DRM_NOUVEAU drm_nouveau) # TODO: make it transitive from borealis
|
||||
target_link_libraries(chiaki-borealis ${Z} ${GLAPI} ${DRM_NOUVEAU})
|
||||
target_link_libraries(chiaki-borealis ${Z} ${GLAPI})
|
||||
endif()
|
||||
|
||||
install(TARGETS chiaki-borealis
|
||||
|
|
|
@ -7,7 +7,7 @@ but the easiest way is to use the following container.
|
|||
Build Project
|
||||
-------------
|
||||
```
|
||||
bash scripts/switch/run-docker-build-chiaki.sh
|
||||
bash scripts/switch/run-podman-build-chiaki.sh
|
||||
```
|
||||
|
||||
tools
|
||||
|
@ -15,7 +15,7 @@ tools
|
|||
Push to homebrew Netloader
|
||||
```
|
||||
# where X.X.X.X is the IP of your switch
|
||||
bash scripts/switch/push-docker-build-chiaki.sh -a 192.168.0.200
|
||||
bash scripts/switch/push-podman-build-chiaki.sh -a 192.168.0.200
|
||||
```
|
||||
|
||||
Troubleshoot
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit cbdc1b65314d1eeb2799deae5cf6f113d6d67b46
|
||||
Subproject commit eae1371831d6cebf11b8ebd4c611069bccc6fb9b
|
|
@ -67,7 +67,7 @@ class IO
|
|||
// default nintendo switch res
|
||||
int screen_width = 1280;
|
||||
int screen_height = 720;
|
||||
AVCodec *codec;
|
||||
const AVCodec *codec;
|
||||
AVCodecContext *codec_context;
|
||||
AVFrame *frame;
|
||||
SDL_AudioDeviceID sdl_audio_device_id = 0;
|
||||
|
|
|
@ -49,7 +49,7 @@ class Settings
|
|||
// the goal is to read/write inernal flat configuration file
|
||||
const std::map<Settings::ConfigurationItem, std::regex> re_map = {
|
||||
{HOST_NAME, std::regex("^\\[\\s*(.+)\\s*\\]")},
|
||||
{HOST_ADDR, std::regex("^\\s*host_(?:ip|addr)\\s*=\\s*\"?((\\d+\\.\\d+\\.\\d+\\.\\d+)|([A-Za-z0-9-]{1,255}))\"?")},
|
||||
{HOST_ADDR, std::regex("^\\s*host_(?:ip|addr)\\s*=\\s*\"?([^\"]*)\"?")},
|
||||
{PSN_ONLINE_ID, std::regex("^\\s*psn_online_id\\s*=\\s*\"?([\\w_-]+)\"?")},
|
||||
{PSN_ACCOUNT_ID, std::regex("^\\s*psn_account_id\\s*=\\s*\"?([\\w/=+]+)\"?")},
|
||||
{RP_KEY, std::regex("^\\s*rp_key\\s*=\\s*\"?([\\w/=+]+)\"?")},
|
||||
|
@ -61,7 +61,6 @@ class Settings
|
|||
};
|
||||
|
||||
ConfigurationItem ParseLine(std::string * line, std::string * value);
|
||||
size_t GetB64encodeSize(size_t);
|
||||
|
||||
public:
|
||||
// singleton configuration
|
||||
|
|
|
@ -117,6 +117,7 @@ int Host::Register(int pin)
|
|||
throw Exception("Undefined PS4 system version (please run discover first)");
|
||||
}
|
||||
|
||||
this->regist_info.pin = pin;
|
||||
this->regist_info.host = this->host_addr.c_str();
|
||||
this->regist_info.broadcast = false;
|
||||
|
||||
|
|
|
@ -28,8 +28,6 @@ bool appletMainLoop()
|
|||
// use a custom nintendo switch socket config
|
||||
// chiaki requiers many threads with udp/tcp sockets
|
||||
static const SocketInitConfig g_chiakiSocketInitConfig = {
|
||||
.bsdsockets_version = 1,
|
||||
|
||||
.tcp_tx_buf_size = 0x8000,
|
||||
.tcp_rx_buf_size = 0x10000,
|
||||
.tcp_tx_buf_max_size = 0x40000,
|
||||
|
|
|
@ -7,9 +7,9 @@
|
|||
Settings::Settings()
|
||||
{
|
||||
#if defined(__SWITCH__)
|
||||
chiaki_log_init(&this->log, CHIAKI_LOG_ALL ^ CHIAKI_LOG_VERBOSE ^ CHIAKI_LOG_DEBUG, chiaki_log_cb_print, NULL);
|
||||
chiaki_log_init(&this->log, CHIAKI_LOG_ALL & ~(CHIAKI_LOG_VERBOSE | CHIAKI_LOG_DEBUG), chiaki_log_cb_print, NULL);
|
||||
#else
|
||||
chiaki_log_init(&this->log, CHIAKI_LOG_ALL, chiaki_log_cb_print, NULL);
|
||||
chiaki_log_init(&this->log, CHIAKI_LOG_ALL & ~CHIAKI_LOG_VERBOSE, chiaki_log_cb_print, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -29,11 +29,7 @@ Settings::ConfigurationItem Settings::ParseLine(std::string *line, std::string *
|
|||
return UNKNOWN;
|
||||
}
|
||||
|
||||
size_t Settings::GetB64encodeSize(size_t in)
|
||||
{
|
||||
// calculate base64 buffer size after encode
|
||||
return ((4 * in / 3) + 3) & ~3;
|
||||
}
|
||||
#define B64_ENCODED_SIZE(in) (((4 * in / 3) + 3) & ~3)
|
||||
|
||||
Settings *Settings::instance = nullptr;
|
||||
|
||||
|
@ -458,8 +454,7 @@ std::string Settings::GetHostRPKey(Host *host)
|
|||
{
|
||||
if(host->rp_key_data || host->registered)
|
||||
{
|
||||
size_t rp_key_b64_sz = this->GetB64encodeSize(0x10);
|
||||
char rp_key_b64[rp_key_b64_sz + 1] = { 0 };
|
||||
char rp_key_b64[B64_ENCODED_SIZE(0x10) + 1] = { 0 };
|
||||
ChiakiErrorCode err;
|
||||
err = chiaki_base64_encode(
|
||||
host->rp_key, 0x10,
|
||||
|
@ -502,8 +497,7 @@ std::string Settings::GetHostRPRegistKey(Host *host)
|
|||
{
|
||||
if(host->rp_key_data || host->registered)
|
||||
{
|
||||
size_t rp_regist_key_b64_sz = this->GetB64encodeSize(CHIAKI_SESSION_AUTH_SIZE);
|
||||
char rp_regist_key_b64[rp_regist_key_b64_sz + 1] = { 0 };
|
||||
char rp_regist_key_b64[B64_ENCODED_SIZE(CHIAKI_SESSION_AUTH_SIZE) + 1] = { 0 };
|
||||
ChiakiErrorCode err;
|
||||
err = chiaki_base64_encode(
|
||||
(uint8_t *)host->rp_regist_key, CHIAKI_SESSION_AUTH_SIZE,
|
||||
|
|
2
third-party/CMakeLists.txt
vendored
2
third-party/CMakeLists.txt
vendored
|
@ -4,11 +4,13 @@ if(NOT CHIAKI_USE_SYSTEM_NANOPB)
|
|||
# nanopb
|
||||
##################
|
||||
|
||||
add_definitions(-DPB_C99_STATIC_ASSERT) # Fix PB_STATIC_ASSERT on msvc without using C11 for now
|
||||
add_subdirectory(nanopb EXCLUDE_FROM_ALL)
|
||||
set(NANOPB_GENERATOR_PY "${CMAKE_CURRENT_SOURCE_DIR}/nanopb/generator/nanopb_generator.py" PARENT_SCOPE)
|
||||
add_library(nanopb INTERFACE)
|
||||
target_link_libraries(nanopb INTERFACE protobuf-nanopb-static)
|
||||
target_include_directories(nanopb INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/nanopb")
|
||||
target_compile_definitions(nanopb INTERFACE -DPB_C99_STATIC_ASSERT) # see above
|
||||
add_library(Nanopb::nanopb ALIAS nanopb)
|
||||
endif()
|
||||
|
||||
|
|
2
third-party/nanopb
vendored
2
third-party/nanopb
vendored
|
@ -1 +1 @@
|
|||
Subproject commit ae9901f2a31500e8fdc93fa9804d24851c58bb1e
|
||||
Subproject commit afc499f9a410fc9bbf6c9c48cdd8d8b199d49eb4
|
Loading…
Add table
Add a link
Reference in a new issue