├── .dockerignore ├── .github ├── CONTRIBUTING.md ├── ISSUE_TEMPLATE.md ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── PULL_REQUEST_TEMPLATE.md └── workflows │ └── build-cia.yml ├── .gitignore ├── .gitmodules ├── .vscode └── tasks.json ├── 3ds ├── build-expat.sh ├── build-ffmpeg.sh ├── build-openssl.sh ├── gfx │ ├── gamepad.png │ ├── keyboard.png │ ├── keyboard_alt.png │ ├── keyboard_lock.png │ ├── keyboard_shift.png │ ├── keyboard_temp.png │ └── touchpad.png └── res │ ├── app.rsf │ ├── banner.png │ ├── banner.wav │ └── ic_moonlight.png ├── CMakeLists.txt ├── Dockerfile ├── LICENSE ├── Makefile ├── README.md ├── appveyor.yml ├── cmake ├── FindAmlogic.cmake ├── FindBroadcom-OMX.cmake ├── FindFreescale.cmake ├── FindLibUUID.cmake ├── FindMMAL.cmake ├── FindOpus.cmake ├── FindRockchip.cmake └── generate_version_header.cmake ├── docs ├── CMakeLists.txt └── README.pod ├── libgamestream ├── CMakeLists.txt ├── client.c ├── client.h ├── discover.c ├── discover.h ├── errors.h ├── http.c ├── http.h ├── mkcert.c ├── mkcert.h ├── sps.c ├── sps.h ├── xml.c └── xml.h ├── moonlight.conf ├── src ├── audio │ ├── alsa.c │ ├── audio.h │ ├── n3ds_audio.cpp │ ├── omx.c │ ├── oss.c │ ├── pulse.c │ └── sdl_audio.c ├── config.c ├── config.h ├── configuration.h.in ├── connection_main.c ├── connection_main.h ├── cpu.c ├── cpu.h ├── input │ ├── cec.c │ ├── cec.h │ ├── evdev.c │ ├── evdev.h │ ├── keyboard.h │ ├── mapping.c │ ├── mapping.h │ ├── n3ds │ │ ├── AbsoluteTouchHandler.cpp │ │ ├── GamepadTouchHandler.cpp │ │ ├── KeyboardTouchHandler.cpp │ │ ├── MouseTouchHandler.cpp │ │ ├── N3dsTouchscreenInput.cpp │ │ ├── N3dsTouchscreenInput.hpp │ │ ├── TouchHandlerBase.cpp │ │ └── keycode_map.hpp │ ├── n3ds_input.cpp │ ├── n3ds_input.hpp │ ├── sdl.h │ ├── sdl_input.c │ ├── udev.c │ ├── udev.h │ ├── x11.c │ └── x11.h ├── loop.c ├── loop.h ├── main.c ├── n3ds │ ├── compat_3ds.c │ ├── n3ds_connection.cpp │ ├── n3ds_connection.hpp │ ├── pair_record.cpp │ └── pair_record.hpp ├── n3ds_main.cpp ├── platform_main.c ├── platform_main.h ├── sdl_main.c ├── sdl_main.h ├── util.c ├── util.h └── video │ ├── aml.c │ ├── egl.c │ ├── egl.h │ ├── ffmpeg.c │ ├── ffmpeg.h │ ├── ffmpeg_vaapi.c │ ├── ffmpeg_vaapi.h │ ├── imx.c │ ├── imx_vpu.c │ ├── imx_vpu.h │ ├── mmal.c │ ├── n3ds │ ├── N3dsRenderer.hpp │ ├── N3dsRendererBase.cpp │ ├── N3dsRendererBottom.cpp │ ├── N3dsRendererDualScreenMirror.cpp │ ├── N3dsRendererDualScreenStretch.cpp │ ├── N3dsRendererTop.cpp │ └── vshader.v.pica │ ├── n3ds_video.cpp │ ├── n3ds_video_mvd.cpp │ ├── pi.c │ ├── rk.c │ ├── sdl_video.c │ ├── video.h │ └── x11.c └── third_party ├── h264bitstream ├── LICENSE ├── bs.h ├── h264_nal.c ├── h264_sei.c ├── h264_sei.h ├── h264_stream.c └── h264_stream.h ├── ilclient ├── ilclient.c ├── ilclient.h └── ilcore.c ├── libcec └── ceccloader.h └── libuuid ├── COPYING ├── all-io.h ├── c.h ├── clear.c ├── compare.c ├── config.h ├── copy.c ├── gen_uuid.c ├── isnull.c ├── pack.c ├── parse.c ├── randutils.c ├── randutils.h ├── unpack.c ├── unparse.c ├── uuid.h ├── uuidP.h └── uuidd.h /.dockerignore: -------------------------------------------------------------------------------- 1 | third_party\SDL\android-project-ant\src 2 | -------------------------------------------------------------------------------- /.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contribution Guide 2 | 3 | ## Got a Question or Problem? 4 | Please take a look at the [wiki](https://github.com/moonlight-stream/moonlight-embedded/wiki) for answers to your questions about using Moonlight Embedded. 5 | 6 | If you still have questions about Moonlight Embedded, please use one of the different forums discussing Moonlight Embedded. 7 | 8 | [XDA](http://forum.xda-developers.com/showthread.php?t=2505510) Moonlight in General 9 | [Raspberry Pi Forum](http://www.raspberrypi.org/forums/viewtopic.php?f=78&t=65878) Moonlight Embedded for Raspberry Pi 10 | [SolidRun Community](http://www.solid-run.com/community/viewtopic.php?f=13&t=1489&p=11173) Moonlight Embedded for Cubox-i and Hummingboard 11 | [ODROID Forum](http://forum.odroid.com/viewtopic.php?f=91&t=15456) Moonlight Embedded on ODROID 12 | 13 | ## Found an Issue? 14 | Found a bug in Moonlight Embedded? Please submit an issue. Ensure the following has been checked or we will mark the issue as invalid: 15 | - [ ] The bug is in Moonlight Embedded. If the bug is in NVidia Geforce Experience or Steam the bug can not be fixed. 16 | - [ ] Your system is set up correctly and there are no issues like a firewall misconfiguration. 17 | - [ ] Verify there is no other bug report containing the same issue. Also, check closed issues in case your bug is already solved. 18 | 19 | Provide as much information as possible about your setup and how to produce the issue so the chances are higher we can fix it. It's even better if you submit a Pull Request 20 | with a fix. 21 | 22 | ## Feature request 23 | There are not many developers working on Moonlight Embedded, and as such it currently doesn't make much sense to use the issue tracker to submit feature requests. Please try to implement feature requests yourself and submit a pull request, or discuss it on one of the forums to see if someone else can implement it. 24 | 25 | ## Submitting a Pull Request 26 | Have you created a cool new feature or fixed a few bugs? You can submit a pull request, but before your request is merged check the following. 27 | - [ ] Your branch is based on a recent commit and can be merged cleanly. 28 | - [ ] Your code uses the same code style as the rest of the code. 29 | - [ ] Your history is cleaned up and you provide one or multiple commits. 30 | - [ ] Your commits only change the necessery lines, and do not accidently changes whitespace or add/remove empty lines. 31 | 32 | If these guide lines are not met your pull request may not be mergeg or your pull request will reuire some cleanup before being merged. This depends on how necessary your code is. 33 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | Please provide the following info. 2 | 3 | **_NVidia Geforce Experience version:_** 4 | **Moonlight Embedded version:** 5 | **Moonlight Embedded source:** _repository/included in distribution/compiled from source/..._ 6 | **Moonlight Embedded running on:** _Raspberry Pi/Cubox-i/Hummingboard/Other linux device/..._ 7 | **Moonlight Embedded running on distribution:** _Arch Linux/Raspbian/OpenELEC/..._ 8 | 9 | **Verbose output `-verbose` of Moonlight Embedded:** 10 | 11 | **What is the expected result?** 12 | 13 | **What happens instead of that?** 14 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: enhancement 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | **Description** 2 | 3 | **Purpose** 4 | -------------------------------------------------------------------------------- /.github/workflows/build-cia.yml: -------------------------------------------------------------------------------- 1 | name: Build CIA 2 | 3 | on: 4 | workflow_dispatch: 5 | push: 6 | pull_request: 7 | 8 | jobs: 9 | build-cia: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: Checkout Repo 13 | uses: actions/checkout@v4 14 | with: 15 | submodules: recursive 16 | - name: Build Dockerfile 17 | run: docker build --network=host -t moonlight-n3ds . 18 | - name: Build CIA 19 | run: docker run --rm -v .:/moonlight-N3DS -w /moonlight-N3DS moonlight-n3ds:latest make 20 | - name: Upload Artifacts 21 | uses: actions/upload-artifact@v4 22 | with: 23 | name: ${{ github.event.repository.name }} 24 | path: | 25 | ./*.cia 26 | ./*.3dsx 27 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | *.3dsx 3 | *.cia 4 | *.elf 5 | *.smdh 6 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "common"] 2 | path = third_party/moonlight-common-c 3 | url = https://github.com/moonlight-stream/moonlight-common-c.git 4 | [submodule "third_party/openssl"] 5 | path = third_party/openssl 6 | url = https://github.com/zoeyjodon/openssl.git 7 | [submodule "third_party/SDL_GameControllerDB"] 8 | path = third_party/SDL_GameControllerDB 9 | url = https://github.com/gabomdq/SDL_GameControllerDB.git 10 | [submodule "third_party/libexpat"] 11 | path = third_party/libexpat 12 | url = https://github.com/libexpat/libexpat.git 13 | [submodule "third_party/FFmpeg_for_3DS"] 14 | path = third_party/FFmpeg_for_3DS 15 | url = https://github.com/Core-2-Extreme/FFmpeg_for_3DS.git 16 | -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | // See https://go.microsoft.com/fwlink/?LinkId=733558 3 | // for the documentation about the tasks.json format 4 | "version": "2.0.0", 5 | "tasks": [ 6 | { 7 | "label": "Build Docker", 8 | "type": "shell", 9 | "command": [ 10 | "docker", 11 | "build", 12 | "--network=host", 13 | "-t", 14 | "moonlight-n3ds", 15 | "${workspaceFolder}", 16 | ], 17 | "problemMatcher": [] 18 | }, 19 | { 20 | "label": "Run Docker", 21 | "type": "shell", 22 | "command": [ 23 | "docker", 24 | "run", 25 | "--network=host", 26 | "--rm", 27 | "-it", 28 | "-v", 29 | "${workspaceFolder}:/moonlight-N3DS", 30 | "-w", 31 | "/moonlight-N3DS", 32 | "moonlight-n3ds:latest", 33 | ], 34 | "problemMatcher": [] 35 | } 36 | ] 37 | } 38 | -------------------------------------------------------------------------------- /3ds/build-expat.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -ex 4 | 5 | SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) 6 | ROOT_DIR=$SCRIPT_DIR/.. 7 | EXPAT_DIR=$ROOT_DIR/third_party/libexpat 8 | 9 | cd $EXPAT_DIR/expat 10 | 11 | export CFLAGS="-march=armv6k -mtune=mpcore -mfloat-abi=hard -mtp=soft -mword-relocations -Wno-psabi -fomit-frame-pointer -ffunction-sections" 12 | export CXXFLAGS="${CFLAGS}" 13 | export CPPFLAGS="-D__3DS__ -I${DEVKITPRO}/libctru/include" 14 | export LDFLAGS="-L${DEVKITPRO}/libctru/lib" 15 | export LIBS="-lctru -lm" 16 | 17 | ./buildconf.sh 18 | ./configure \ 19 | --prefix=$DEVKITPRO/portlibs/3ds/ \ 20 | --host=arm-none-eabi \ 21 | --enable-static \ 22 | --without-examples \ 23 | --without-tests \ 24 | --without-docbook \ 25 | CC=$DEVKITARM/bin/arm-none-eabi-gcc \ 26 | CXX=$DEVKITARM/bin/arm-none-eabi-g++ \ 27 | AR=$DEVKITARM/bin/arm-none-eabi-ar \ 28 | RANLIB=$DEVKITARM/bin/arm-none-eabi-ranlib \ 29 | PKG_CONFIG=$DEVKITPRO/portlibs/3ds/bin/arm-none-eabi-pkg-config 30 | 31 | make -j$(nproc) 32 | make install 33 | 34 | cd - 35 | -------------------------------------------------------------------------------- /3ds/build-ffmpeg.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -ex 4 | 5 | SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) 6 | ROOT_DIR=$SCRIPT_DIR/.. 7 | FFMPEG_DIR=$ROOT_DIR/third_party/FFmpeg_for_3DS 8 | 9 | cd $FFMPEG_DIR 10 | 11 | ./configure --enable-cross-compile --cross-prefix=/opt/devkitpro/devkitARM/bin/arm-none-eabi- --prefix=/opt/devkitpro/extra_lib \ 12 | --cpu=armv6k --arch=arm --target-os=linux \ 13 | --extra-cflags="-mfloat-abi=hard -mtune=mpcore -mtp=cp15 -D_POSIX_THREADS -I/opt/devkitpro/extra_lib/include -Wno-incompatible-pointer-types" \ 14 | --extra-ldflags="-mfloat-abi=hard -L/opt/devkitpro/extra_lib/lib"\ 15 | --disable-filters --disable-devices --disable-bsfs --disable-parsers \ 16 | --disable-hwaccels --disable-debug --disable-stripping --disable-programs \ 17 | --disable-avdevice --disable-postproc --disable-avfilter --disable-decoders \ 18 | --disable-demuxers --disable-encoders --disable-muxers --disable-asm \ 19 | --disable-protocols --disable-txtpages --disable-podpages --disable-manpages \ 20 | --disable-htmlpages --disable-doc \ 21 | --enable-inline-asm --enable-vfp --enable-armv5te --enable-armv6 \ 22 | --enable-decoder="h264,hevc,av1" \ 23 | --enable-demuxer="h264,hevc,av1" \ 24 | --enable-muxer="mp4,mp3,mp2,ac3" \ 25 | --enable-protocol="file" \ 26 | --enable-libx264 --enable-libdav1d --enable-gpl --enable-pthreads 27 | 28 | make -j$(nproc) 29 | make install 30 | 31 | cd - 32 | -------------------------------------------------------------------------------- /3ds/build-openssl.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -ex 4 | 5 | SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) 6 | ROOT_DIR=$SCRIPT_DIR/.. 7 | OPENSSL_DIR=$ROOT_DIR/third_party/openssl 8 | 9 | 10 | cd $OPENSSL_DIR 11 | 12 | ./Configure 3ds \ 13 | no-threads no-shared no-asm no-ui-console no-unit-test no-tests no-buildtest-c++ no-external-tests no-autoload-config \ 14 | --with-rand-seed=os -static -Wno-implicit-function-declaration -Wno-incompatible-pointer-types -Wno-int-conversion 15 | make build_generated -j$(nproc) 16 | make libssl.a libcrypto.a -j$(nproc) 17 | 18 | # Install the library files 19 | cp libssl.a $DEVKITPRO/portlibs/3ds/lib/ 20 | cp libcrypto.a $DEVKITPRO/portlibs/3ds/lib/ 21 | cp -r include/openssl $DEVKITPRO/portlibs/3ds/include/openssl/ 22 | cp -r include/crypto $DEVKITPRO/portlibs/3ds/include/crypto/ 23 | 24 | cd - 25 | -------------------------------------------------------------------------------- /3ds/gfx/gamepad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zoeyjodon/moonlight-N3DS/873623d802bcd143e018e55adbe18a5937df527c/3ds/gfx/gamepad.png -------------------------------------------------------------------------------- /3ds/gfx/keyboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zoeyjodon/moonlight-N3DS/873623d802bcd143e018e55adbe18a5937df527c/3ds/gfx/keyboard.png -------------------------------------------------------------------------------- /3ds/gfx/keyboard_alt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zoeyjodon/moonlight-N3DS/873623d802bcd143e018e55adbe18a5937df527c/3ds/gfx/keyboard_alt.png -------------------------------------------------------------------------------- /3ds/gfx/keyboard_lock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zoeyjodon/moonlight-N3DS/873623d802bcd143e018e55adbe18a5937df527c/3ds/gfx/keyboard_lock.png -------------------------------------------------------------------------------- /3ds/gfx/keyboard_shift.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zoeyjodon/moonlight-N3DS/873623d802bcd143e018e55adbe18a5937df527c/3ds/gfx/keyboard_shift.png -------------------------------------------------------------------------------- /3ds/gfx/keyboard_temp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zoeyjodon/moonlight-N3DS/873623d802bcd143e018e55adbe18a5937df527c/3ds/gfx/keyboard_temp.png -------------------------------------------------------------------------------- /3ds/gfx/touchpad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zoeyjodon/moonlight-N3DS/873623d802bcd143e018e55adbe18a5937df527c/3ds/gfx/touchpad.png -------------------------------------------------------------------------------- /3ds/res/banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zoeyjodon/moonlight-N3DS/873623d802bcd143e018e55adbe18a5937df527c/3ds/res/banner.png -------------------------------------------------------------------------------- /3ds/res/banner.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zoeyjodon/moonlight-N3DS/873623d802bcd143e018e55adbe18a5937df527c/3ds/res/banner.wav -------------------------------------------------------------------------------- /3ds/res/ic_moonlight.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zoeyjodon/moonlight-N3DS/873623d802bcd143e018e55adbe18a5937df527c/3ds/res/ic_moonlight.png -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # docker build --network=host -t moonlight-n3ds . 2 | #FROM ubuntu:22.04 3 | FROM devkitpro/devkitarm:latest 4 | 5 | # Use bash instead of sh 6 | SHELL ["/bin/bash", "-c"] 7 | 8 | # Make sure Docker does not freeze while setting up the timezone 9 | ENV TZ=Asia/Dubai 10 | RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone 11 | 12 | # Install common build dependencies 13 | RUN apt-get update && apt-get install -y \ 14 | build-essential \ 15 | curl \ 16 | gdb \ 17 | lsb-release \ 18 | libreadline-dev \ 19 | software-properties-common \ 20 | wget \ 21 | unzip \ 22 | libc6 \ 23 | git \ 24 | autoconf \ 25 | libtool \ 26 | python3 \ 27 | python3-pip \ 28 | ffmpeg 29 | 30 | # Install the luma dump parser for inspecting crashes 31 | RUN pip install -U git+https://github.com/LumaTeam/luma3ds_exception_dump_parser.git 32 | 33 | # Install moonlight dependencies 34 | RUN apt-get install -y \ 35 | libssl-dev \ 36 | libopus-dev \ 37 | libasound2-dev \ 38 | libudev-dev \ 39 | libavahi-client-dev \ 40 | libcurl4-openssl-dev \ 41 | libevdev-dev \ 42 | libexpat1-dev \ 43 | libpulse-dev \ 44 | uuid-dev \ 45 | cmake \ 46 | gcc \ 47 | g++ 48 | 49 | # Install bannertool 50 | RUN wget https://github.com/Epicpkmn11/bannertool/releases/download/v1.2.2/bannertool.zip && \ 51 | unzip bannertool.zip -d /bannertool && \ 52 | cp /bannertool/linux-x86_64/bannertool /usr/local/bin && \ 53 | chmod +x /usr/local/bin/bannertool && \ 54 | rm -r /bannertool 55 | 56 | # Install MakeROM for CIA packaging 57 | RUN wget https://github.com/3DSGuy/Project_CTR/releases/download/makerom-v0.18.3/makerom-v0.18.3-ubuntu_x86_64.zip && \ 58 | unzip makerom-v0.18.3-ubuntu_x86_64.zip -d /usr/local/bin && \ 59 | chmod +x /usr/local/bin/makerom 60 | 61 | # Install custom third party libraries 62 | COPY . /moonlight-N3DS 63 | 64 | RUN source /etc/profile.d/devkit-env.sh && /moonlight-N3DS/3ds/build-expat.sh 65 | RUN source /etc/profile.d/devkit-env.sh && /moonlight-N3DS/3ds/build-openssl.sh 66 | RUN source /etc/profile.d/devkit-env.sh && /moonlight-N3DS/3ds/build-ffmpeg.sh 67 | RUN rm -rf /moonlight-N3DS 68 | 69 | CMD ["/bin/bash"] 70 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Moonlight for the \*New\* Nintendo 3DS 2 | 3 | Moonlight is an open source client for [Sunshine](https://github.com/LizardByte/Sunshine) and NVIDIA GameStream for the \*New\* Nintendo 3DS, forked from [Moonlight Embedded](https://github.com/moonlight-stream/moonlight-embedded). Moonlight allows you to stream your full collection of games and applications from your PC to other devices to play them remotely. 4 | 5 | ## Original 3DS Note 6 | 7 | While this app is operable on the original 3DS, the hardware decoder must be disabled and the framerate will be significantly lower due to the slower CPU. 8 | 9 | ## Configuration 10 | 11 | You can modify documented settings either in the app, or by creating/modifying the config file located at `sd:/3ds/moonlight/moonlight.conf`. 12 | 13 | ## Documentation 14 | 15 | More information about installing and runnning Moonlight Embedded is available on the [wiki](https://github.com/moonlight-stream/moonlight-embedded/wiki). 16 | 17 | ## Build 18 | 19 | I have included a Dockerfile which has all of the required build dependencies pre-installed. The easiest way to build moonlight.cia is by building and running the docker image. 20 | If you are using VS Code as your editor, you can use the `Build Docker` and `Run Docker` tasks for this. 21 | If you are not using VS Code, you can build and run the docker image with the following terminal commands from the root of the repository: 22 | 23 | ```bash 24 | docker build --network=host -t moonlight-n3ds . 25 | docker run --rm -it -v .:/moonlight-N3DS -w /moonlight-N3DS moonlight-n3ds:latest 26 | ``` 27 | 28 | Then, run the following command in the docker commandline: 29 | 30 | ```bash 31 | make 32 | ``` 33 | 34 | ## Install 35 | 36 | You can download the CIA file (moonlight.cia) from the [Releases](https://github.com/zoeyjodon/moonlight-N3DS/releases/latest) page, and install it using [FBI](https://github.com/Steveice10/FBI). 37 | 38 | Please note that to run Moonlight on the 3DS, you will need to install custom firmware. You can find instructions for installing CFW [here](https://3ds.hacks.guide/). 39 | 40 | ## See also 41 | 42 | [Moonlight-common-c](https://github.com/moonlight-stream/moonlight-common-c) is the shared codebase between different Moonlight implementations 43 | 44 | ## Contribute 45 | 46 | 1. Fork us 47 | 2. Write code 48 | 3. Send Pull Requests 49 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | version: 0.0.0.{build} 2 | 3 | clone_depth: 1 4 | 5 | environment: 6 | matrix: 7 | - APPVEYOR_BUILD_WORKER_IMAGE: Ubuntu2004 8 | PACKAGES: libssl-dev libopus-dev libasound2-dev libudev-dev libavahi-client-dev libcurl4-openssl-dev libevdev-dev libexpat1-dev libpulse-dev uuid-dev cmake gcc g++ libavcodec-dev libavutil-dev libsdl2-dev libva-dev libvdpau-dev libcec-dev libp8-platform-dev 9 | BUILD_TARGET: ubuntu 10 | - APPVEYOR_BUILD_WORKER_IMAGE: Ubuntu2004 11 | PACKAGES: qemu binfmt-support qemu-user-static 12 | BUILD_TARGET: raspbian 13 | 14 | install: 15 | - 'sudo apt update || true' 16 | - 'sudo apt install -y $PACKAGES' 17 | - '[ "$BUILD_TARGET" != raspbian ] || docker run --rm --privileged multiarch/qemu-user-static --reset -p yes' 18 | 19 | before_build: 20 | - 'git submodule update --init --recursive' 21 | 22 | build_script: 23 | - 'if [[ "$BUILD_TARGET" = ubuntu ]]; then mkdir build && cd build && cmake -DCMAKE_INSTALL_PREFIX=/tmp .. && make -j$(nproc) && make install; fi' 24 | - 'if [[ "$BUILD_TARGET" = raspbian ]]; then git clone --recursive https://github.com/cgutman/moonlight-embedded-packaging.git && cd moonlight-embedded-packaging && sh -c "./build-rpi-buster.sh $APPVEYOR_REPO_COMMIT"; fi' 25 | 26 | after_build: 27 | - sh: '[ "$BUILD_TARGET" != raspbian ] || appveyor PushArtifact out_*/moonlight-embedded_*.deb' 28 | - sh: '[ "$BUILD_TARGET" != raspbian ] || appveyor PushArtifact out_*/moonlight-embedded-dbgsym_*.deb' 29 | 30 | deploy: off 31 | -------------------------------------------------------------------------------- /cmake/FindAmlogic.cmake: -------------------------------------------------------------------------------- 1 | find_path(AMLOGIC_INCLUDE_DIR 2 | NAMES codec.h 3 | DOC "Amlogic include directory" 4 | PATHS /usr/local/include/amcodec /usr/osmc/include/amcodec /usr/include/amcodec /usr/include/) 5 | mark_as_advanced(AMLOGIC_INCLUDE_DIR) 6 | 7 | find_library(AMCODEC_LIBRARY 8 | NAMES libamcodec.so 9 | DOC "Path to Amlogic Video Codec Library" 10 | PATHS /usr/lib/aml_libs /usr/osmc/lib /usr/local/lib /usr/lib) 11 | mark_as_advanced(AMCODEC_LIBRARY) 12 | 13 | include(${CMAKE_ROOT}/Modules/FindPackageHandleStandardArgs.cmake) 14 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(Amlogic DEFAULT_MSG AMLOGIC_INCLUDE_DIR AMCODEC_LIBRARY) 15 | 16 | set(AMLOGIC_LIBRARIES ${AMCODEC_LIBRARY}) 17 | set(AMLOGIC_INCLUDE_DIRS ${AMLOGIC_INCLUDE_DIR}) 18 | -------------------------------------------------------------------------------- /cmake/FindBroadcom-OMX.cmake: -------------------------------------------------------------------------------- 1 | find_path(BROADCOM_INCLUDE_DIR 2 | NAMES bcm_host.h 3 | DOC "Broadcom include directory" 4 | PATHS /opt/vc/include) 5 | mark_as_advanced(BCM_INCLUDE_DIR) 6 | 7 | find_library(VCOS_LIBRARY 8 | NAMES libvcos.so 9 | DOC "Path to VCOS Library" 10 | PATHS /opt/vc/lib) 11 | mark_as_advanced(VCOS_LIBRARY) 12 | 13 | find_library(VCHIQ_LIBRARY 14 | NAMES libvchiq_arm.so 15 | DOC "Path to VCHIQ Library" 16 | PATHS /opt/vc/lib) 17 | mark_as_advanced(VCHIQ_LIBRARY) 18 | 19 | find_library(OPENMAXIL_LIBRARY 20 | NAMES libopenmaxil.so 21 | DOC "Path to OpenMAX IL Library" 22 | PATHS /opt/vc/lib) 23 | mark_as_advanced(OPENMAXIL_LIBRARY) 24 | 25 | find_library(BCM_HOST_LIBRARY 26 | NAMES libbcm_host.so 27 | DOC "Path to Broadcom Host Library" 28 | PATHS /opt/vc/lib) 29 | mark_as_advanced(BCM_HOST_LIBRARY) 30 | 31 | include(${CMAKE_ROOT}/Modules/FindPackageHandleStandardArgs.cmake) 32 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(Broadcom-OMX DEFAULT_MSG BROADCOM_INCLUDE_DIR VCOS_LIBRARY VCHIQ_LIBRARY OPENMAXIL_LIBRARY BCM_HOST_LIBRARY) 33 | 34 | set(BROADCOM_OMX_LIBRARIES ${BCM_HOST_LIBRARY} ${OPENMAXIL_LIBRARY} ${VCHIQ_LIBRARY} ${VCOS_LIBRARY}) 35 | set(BROADCOM_INCLUDE_DIRS ${BROADCOM_INCLUDE_DIR} ${BROADCOM_INCLUDE_DIR}/interface/vmcs_host/linux ${BROADCOM_INCLUDE_DIR}/interface/vcos/pthreads) 36 | set(BROADCOM_OMX_DEFINITIONS USE_VCHIQ_ARM HAVE_LIBOPENMAX=2 OMX OMX_SKIP64BIT USE_EXTERNAL_OMX HAVE_LIBBCM_HOST USE_EXTERNAL_LIBBCM_HOST) 37 | -------------------------------------------------------------------------------- /cmake/FindFreescale.cmake: -------------------------------------------------------------------------------- 1 | find_path(FREESCALE_INCLUDE_DIR 2 | NAMES vpu_lib.h 3 | DOC "Freescale include directory" 4 | PATHS /opt/fsl/include) 5 | mark_as_advanced(BROADCOM_INCLUDE_DIR) 6 | 7 | find_path(KERNEL_INCLUDE_DIR 8 | NAMES linux/mxc_v4l2.h 9 | DOC "Kernel include directory" 10 | PATHS /lib/modules/${CMAKE_SYSTEM_VERSION}/build/include) 11 | mark_as_advanced(KERNEL_INCLUDE_DIR) 12 | 13 | find_library(VPU_LIBRARY 14 | NAMES libvpu.so 15 | DOC "Path to Freescale VPU Library" 16 | PATHS /opt/fsl/lib) 17 | mark_as_advanced(VCOS_LIBRARY) 18 | 19 | include(${CMAKE_ROOT}/Modules/FindPackageHandleStandardArgs.cmake) 20 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(Freescale DEFAULT_MSG FREESCALE_INCLUDE_DIR KERNEL_INCLUDE_DIR VPU_LIBRARY) 21 | 22 | set(FREESCALE_LIBRARIES ${VPU_LIBRARY}) 23 | set(FREESCALE_INCLUDE_DIRS ${FREESCALE_INCLUDE_DIR} ${KERNEL_INCLUDE_DIR}) 24 | -------------------------------------------------------------------------------- /cmake/FindLibUUID.cmake: -------------------------------------------------------------------------------- 1 | # CMake - Cross Platform Makefile Generator 2 | # Copyright 2000-2024 Kitware, Inc. and Contributors 3 | # All rights reserved. 4 | # 5 | # Distributed under the OSI-approved BSD 3-Clause License. See 6 | # https://cmake.org/licensing for details. 7 | # 8 | #[=======================================================================[.rst: 9 | FindLibUUID 10 | ------------ 11 | 12 | Find LibUUID include directory and library. 13 | 14 | Imported Targets 15 | ^^^^^^^^^^^^^^^^ 16 | 17 | An :ref:`imported target ` named 18 | ``LibUUID::LibUUID`` is provided if LibUUID has been found. 19 | 20 | Result Variables 21 | ^^^^^^^^^^^^^^^^ 22 | 23 | This module defines the following variables: 24 | 25 | ``LibUUID_FOUND`` 26 | True if LibUUID was found, false otherwise. 27 | ``LibUUID_INCLUDE_DIRS`` 28 | Include directories needed to include LibUUID headers. 29 | ``LibUUID_LIBRARIES`` 30 | Libraries needed to link to LibUUID. 31 | 32 | Cache Variables 33 | ^^^^^^^^^^^^^^^ 34 | 35 | This module uses the following cache variables: 36 | 37 | ``LibUUID_LIBRARY`` 38 | The location of the LibUUID library file. 39 | ``LibUUID_INCLUDE_DIR`` 40 | The location of the LibUUID include directory containing ``uuid/uuid.h``. 41 | 42 | The cache variables should not be used by project code. 43 | They may be set by end users to point at LibUUID components. 44 | #]=======================================================================] 45 | 46 | #----------------------------------------------------------------------------- 47 | find_library(LibUUID_LIBRARY 48 | NAMES uuid 49 | ) 50 | mark_as_advanced(LibUUID_LIBRARY) 51 | 52 | find_path(LibUUID_INCLUDE_DIR 53 | NAMES uuid/uuid.h 54 | ) 55 | mark_as_advanced(LibUUID_INCLUDE_DIR) 56 | 57 | #----------------------------------------------------------------------------- 58 | include(FindPackageHandleStandardArgs) 59 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibUUID 60 | FOUND_VAR LibUUID_FOUND 61 | REQUIRED_VARS LibUUID_LIBRARY LibUUID_INCLUDE_DIR 62 | ) 63 | set(LIBUUID_FOUND ${LibUUID_FOUND}) 64 | 65 | #----------------------------------------------------------------------------- 66 | # Provide documented result variables and targets. 67 | if(LibUUID_FOUND) 68 | set(LibUUID_INCLUDE_DIRS ${LibUUID_INCLUDE_DIR}) 69 | set(LibUUID_LIBRARIES ${LibUUID_LIBRARY}) 70 | if(NOT TARGET LibUUID::LibUUID) 71 | add_library(LibUUID::LibUUID UNKNOWN IMPORTED) 72 | set_target_properties(LibUUID::LibUUID PROPERTIES 73 | IMPORTED_LOCATION "${LibUUID_LIBRARY}" 74 | INTERFACE_INCLUDE_DIRECTORIES "${LibUUID_INCLUDE_DIRS}" 75 | ) 76 | endif() 77 | endif() 78 | -------------------------------------------------------------------------------- /cmake/FindMMAL.cmake: -------------------------------------------------------------------------------- 1 | find_path(BROADCOM_INCLUDE_DIR 2 | NAMES bcm_host.h 3 | DOC "Broadcom include directory" 4 | PATHS /opt/vc/include) 5 | mark_as_advanced(BROADCOM_INCLUDE_DIR) 6 | 7 | find_library(VCOS_LIBRARY 8 | NAMES libvcos.so 9 | DOC "Path to VCOS Library" 10 | PATHS /opt/vc/lib) 11 | mark_as_advanced(VCOS_LIBRARY) 12 | 13 | find_library(BCM_HOST_LIBRARY 14 | NAMES libbcm_host.so 15 | DOC "Path to Broadcom Host Library" 16 | PATHS /opt/vc/lib) 17 | mark_as_advanced(BCM_HOST_LIBRARY) 18 | 19 | find_library(MMAL_CORE_LIBRARY 20 | NAMES libmmal_core.so 21 | DOC "Path to MMAL Core Library" 22 | PATHS /opt/vc/lib) 23 | mark_as_advanced(MMAL_CORE_LIBRARY) 24 | 25 | find_library(MMAL_UTIL_LIBRARY 26 | NAMES libmmal_util.so 27 | DOC "Path to MMAL Util Library" 28 | PATHS /opt/vc/lib) 29 | mark_as_advanced(MMAL_UTIL_LIBRARY) 30 | 31 | find_library(MMAL_VC_CLIENT_LIBRARY 32 | NAMES libmmal_vc_client.so 33 | DOC "Path to MMAL Client Library" 34 | PATHS /opt/vc/lib) 35 | mark_as_advanced(MMAL_VC_CLIENT_LIBRARY) 36 | 37 | include(${CMAKE_ROOT}/Modules/FindPackageHandleStandardArgs.cmake) 38 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(MMAL DEFAULT_MSG BROADCOM_INCLUDE_DIR VCOS_LIBRARY MMAL_CORE_LIBRARY MMAL_UTIL_LIBRARY MMAL_VC_CLIENT_LIBRARY BCM_HOST_LIBRARY) 39 | 40 | set(MMAL_LINK_LIBRARIES ${BCM_HOST_LIBRARY} ${VCOS_LIBRARY} ${MMAL_CORE_LIBRARY} ${MMAL_UTIL_LIBRARY} ${MMAL_VC_CLIENT_LIBRARY}) 41 | set(MMAL_INCLUDE_DIRS ${BROADCOM_INCLUDE_DIR}) -------------------------------------------------------------------------------- /cmake/FindOpus.cmake: -------------------------------------------------------------------------------- 1 | # - Find opus library 2 | # Find the native Opus headers and libraries. Opus depends on Ogg and will 3 | # provide Ogg headers/libraries as well. 4 | # 5 | # OPUS_INCLUDE_DIRS - where to find opus/opus.h, ogg/ogg.h, etc 6 | # OPUS_LIBRARIES - List of libraries when using libopus 7 | # OPUS_FOUND - True if opus is found. 8 | 9 | 10 | #============================================================================= 11 | #Copyright 2000-2009 Kitware, Inc., Insight Software Consortium 12 | #Copyright 2014, Mateusz "maxmati" Nowotynski 13 | #All rights reserved. 14 | # 15 | #Redistribution and use in source and binary forms, with or without 16 | # modification, are permitted provided that the following conditions are met: 17 | # 18 | #* Redistributions of source code must retain the above copyright notice, 19 | #this list of conditions and the following disclaimer. 20 | # 21 | #* Redistributions in binary form must reproduce the above copyright notice, 22 | #this list of conditions and the following disclaimer in the documentation 23 | #and/or other materials provided with the distribution. 24 | # 25 | #* Neither the names of Kitware, Inc., the Insight Software Consortium, nor 26 | #the names of their contributors may be used to endorse or promote products 27 | #derived from this software without specific prior written permission. 28 | # 29 | #THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 30 | #AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 31 | #IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 32 | #ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 33 | #LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 34 | #CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 35 | #SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 36 | #INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 37 | #CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 38 | #ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 39 | #POSSIBILITY OF SUCH DAMAGE. 40 | #============================================================================= 41 | 42 | 43 | # Look for the opusfile header file. 44 | find_path( OPUS_INCLUDE_DIR 45 | NAMES opus/opus.h 46 | DOC "Opus include directory" ) 47 | mark_as_advanced( OPUS_INCLUDE_DIR ) 48 | 49 | # Look for the opus library. 50 | find_library( OPUS_LIBRARY 51 | NAMES opus 52 | DOC "Path to Opus library" ) 53 | mark_as_advanced( OPUS_LIBRARY ) 54 | 55 | 56 | # handle the QUIETLY and REQUIRED arguments and set OPUSFILE_FOUND to TRUE if 57 | # all listed variables are TRUE 58 | include( ${CMAKE_ROOT}/Modules/FindPackageHandleStandardArgs.cmake ) 59 | FIND_PACKAGE_HANDLE_STANDARD_ARGS( Opus DEFAULT_MSG OPUS_LIBRARY OPUS_INCLUDE_DIR ) 60 | 61 | set( OPUS_LIBRARIES ${OPUS_LIBRARY}) 62 | set( OPUS_INCLUDE_DIRS ${OPUS_INCLUDE_DIR} ${OPUS_INCLUDE_DIR}/opus ) -------------------------------------------------------------------------------- /cmake/FindRockchip.cmake: -------------------------------------------------------------------------------- 1 | find_path(DRM_INCLUDE_DIR 2 | NAMES drm.h 3 | DOC "libdrm include directory" 4 | PATHS /usr/local/include/libdrm /usr/include/libdrm /usr/include) 5 | mark_as_advanced(DRM_INCLUDE_DIR) 6 | 7 | find_library(DRM_LIBRARY 8 | NAMES libdrm.so 9 | DOC "Path to libdrm Library" 10 | PATHS /usr/local/lib /usr/lib /usr/lib/aarch64-linux-gnu /usr/lib/arm-linux-gnueabihf) 11 | mark_as_advanced(DRM_INCLUDE_DIR) 12 | 13 | find_path(ROCKCHIP_INCLUDE_DIR 14 | NAMES rk_mpi.h 15 | DOC "Rockchip include directory" 16 | PATHS /usr/local/include/rockchip /usr/include/rockchip /usr/include) 17 | mark_as_advanced(ROCKCHIP_INCLUDE_DIR) 18 | 19 | find_library(ROCKCHIP_LIBRARY 20 | NAMES librockchip_mpp.so 21 | DOC "Path to Rockchip Media Process Platform Library" 22 | PATHS /usr/local/lib /usr/lib /usr/lib/aarch64-linux-gnu /usr/lib/arm-linux-gnueabihf) 23 | mark_as_advanced(ROCKCHIP_LIBRARY) 24 | 25 | include(${CMAKE_ROOT}/Modules/FindPackageHandleStandardArgs.cmake) 26 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(Rockchip DEFAULT_MSG ROCKCHIP_INCLUDE_DIR ROCKCHIP_LIBRARY) 27 | 28 | set(ROCKCHIP_INCLUDE_DIRS ${ROCKCHIP_INCLUDE_DIR} ${DRM_INCLUDE_DIR}) 29 | set(ROCKCHIP_LIBRARIES ${ROCKCHIP_LIBRARY} ${DRM_LIBRARY}) 30 | -------------------------------------------------------------------------------- /cmake/generate_version_header.cmake: -------------------------------------------------------------------------------- 1 | include(FindGit) 2 | 3 | if(GIT_FOUND AND IS_DIRECTORY "${PROJECT_SOURCE_DIR}/.git") 4 | set(GIT_BRANCH "") 5 | set(GIT_COMMIT_HASH "") 6 | 7 | # Get the current working branch 8 | execute_process( 9 | COMMAND ${GIT_EXECUTABLE} name-rev --name-only HEAD 10 | WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} 11 | OUTPUT_VARIABLE GIT_BRANCH0 12 | OUTPUT_STRIP_TRAILING_WHITESPACE 13 | ) 14 | 15 | # Clean Branch name to have only the branch 16 | STRING(REGEX REPLACE "((origin))+" "" GIT_BRANCH1 ${GIT_BRANCH0}) 17 | STRING(REGEX REPLACE "((remotes))+" "" GIT_BRANCH2 ${GIT_BRANCH1}) 18 | STRING(REGEX REPLACE "\\/+" "" GIT_BRANCH3 ${GIT_BRANCH2}) 19 | STRING(REGEX REPLACE "~[0-9]*" "" GIT_BRANCH4 ${GIT_BRANCH3}) 20 | STRING(REGEX REPLACE "\\^[0-9]*" "" GIT_BRANCH ${GIT_BRANCH4}) 21 | 22 | # Get the latest abbreviated commit hash of the working branch 23 | execute_process( 24 | COMMAND git log -1 --format=%h 25 | WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} 26 | OUTPUT_VARIABLE GIT_COMMIT_HASH 27 | OUTPUT_STRIP_TRAILING_WHITESPACE 28 | ) 29 | endif() 30 | -------------------------------------------------------------------------------- /docs/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_custom_command(OUTPUT moonlight.1 COMMAND pod2man --section=1 --center="Moonlight Embedded Manual" --name="MOONLIGHT" --release="moonlight 2.5.0" ${CMAKE_CURRENT_SOURCE_DIR}/README.pod > moonlight.1) 2 | add_custom_target(docs ALL DEPENDS moonlight.1) 3 | 4 | install(FILES ${CMAKE_CURRENT_BINARY_DIR}/moonlight.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1) 5 | -------------------------------------------------------------------------------- /libgamestream/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(SO_VERSION 4) 2 | 3 | find_package(LibUUID REQUIRED) 4 | find_package(Threads REQUIRED) 5 | find_package(CURL REQUIRED) 6 | find_package(OpenSSL 1.0.2 REQUIRED) 7 | find_package(EXPAT REQUIRED) 8 | 9 | pkg_check_modules(AVAHI REQUIRED avahi-client) 10 | 11 | aux_source_directory(./ GAMESTREAM_SRC_LIST) 12 | aux_source_directory(../third_party/h264bitstream GAMESTREAM_SRC_LIST) 13 | 14 | aux_source_directory(../third_party/moonlight-common-c/enet MOONLIGHT_COMMON_SRC_LIST) 15 | aux_source_directory(../third_party/moonlight-common-c/src MOONLIGHT_COMMON_SRC_LIST) 16 | aux_source_directory(../third_party/moonlight-common-c/reedsolomon MOONLIGHT_COMMON_SRC_LIST) 17 | 18 | add_library(moonlight-common SHARED ${MOONLIGHT_COMMON_SRC_LIST}) 19 | 20 | add_library(gamestream SHARED ${GAMESTREAM_SRC_LIST}) 21 | target_link_libraries(gamestream moonlight-common) 22 | 23 | set_target_properties(gamestream PROPERTIES SOVERSION ${SO_VERSION} VERSION ${PROJECT_VERSION}) 24 | set_target_properties(moonlight-common PROPERTIES SOVERSION ${SO_VERSION} VERSION ${PROJECT_VERSION}) 25 | 26 | target_include_directories(gamestream PRIVATE ../third_party/moonlight-common-c/src ../third_party/h264bitstream ${AVAHI_INCLUDE_DIRS} ${LibUUID_INCLUDE_DIRS}) 27 | target_include_directories(moonlight-common PRIVATE ../third_party/moonlight-common-c/reedsolomon ../third_party/moonlight-common-c/enet/include) 28 | target_link_libraries(gamestream ${CURL_LIBRARIES} ${OPENSSL_LIBRARIES} ${EXPAT_LIBRARIES} ${AVAHI_LIBRARIES} ${LibUUID_LIBRARIES}) 29 | 30 | target_link_libraries(gamestream ${CMAKE_THREAD_LIBS_INIT} ${CMAKE_DL_LIBS}) 31 | 32 | install(TARGETS gamestream moonlight-common DESTINATION ${CMAKE_INSTALL_LIBDIR}) 33 | -------------------------------------------------------------------------------- /libgamestream/client.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Moonlight Embedded. 3 | * 4 | * Copyright (C) 2015-2017 Iwan Timmer 5 | * 6 | * Moonlight is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Moonlight is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Moonlight; if not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #include "xml.h" 23 | 24 | #include 25 | 26 | #include 27 | 28 | #define MIN_SUPPORTED_GFE_VERSION 3 29 | #define MAX_SUPPORTED_GFE_VERSION 7 30 | 31 | #ifdef __cplusplus 32 | extern "C" { 33 | #endif 34 | 35 | typedef struct _SERVER_DATA { 36 | char* gpuType; 37 | bool paired; 38 | bool unsupported; 39 | bool isNvidiaSoftware; 40 | int currentGame; 41 | int serverMajorVersion; 42 | char* gsVersion; 43 | PDISPLAY_MODE modes; 44 | SERVER_INFORMATION serverInfo; 45 | unsigned short httpPort; 46 | unsigned short httpsPort; 47 | } SERVER_DATA, *PSERVER_DATA; 48 | 49 | int gs_init(PSERVER_DATA server, char* address, unsigned short httpPort, const char *keyDirectory, int logLevel, bool unsupported); 50 | void gs_cleanup(); 51 | int gs_start_app(PSERVER_DATA server, PSTREAM_CONFIGURATION config, int appId, bool sops, bool localaudio, int gamepad_mask); 52 | int gs_applist(PSERVER_DATA server, PAPP_LIST *app_list); 53 | int gs_unpair(PSERVER_DATA server); 54 | int gs_pair(PSERVER_DATA server, char* pin); 55 | int gs_quit_app(PSERVER_DATA server); 56 | 57 | #ifdef __cplusplus 58 | } 59 | #endif 60 | -------------------------------------------------------------------------------- /libgamestream/discover.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Moonlight Embedded. 3 | * 4 | * Based on Avahi example client-browse-services 5 | * 6 | * Moonlight is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Moonlight is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Moonlight; if not, see . 18 | */ 19 | 20 | #ifndef __3DS__ 21 | 22 | #include "errors.h" 23 | 24 | #include 25 | #include 26 | 27 | #include 28 | #include 29 | #include 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | 36 | static AvahiSimplePoll *simple_poll = NULL; 37 | 38 | struct cb_ctx { 39 | char* address; 40 | unsigned short* port; 41 | }; 42 | 43 | static void client_callback(AvahiClient *c, AvahiClientState state, void *userdata) { 44 | if (state == AVAHI_CLIENT_FAILURE) { 45 | gs_error = "Server connection failure"; 46 | avahi_simple_poll_quit(simple_poll); 47 | } 48 | } 49 | 50 | static void resolve_callback(AvahiServiceResolver *r, AvahiIfIndex interface, AvahiProtocol protocol, AvahiResolverEvent event, const char *name, const char *type, const char *domain, const char *host_name, const AvahiAddress *address, uint16_t port, AvahiStringList *txt, AvahiLookupResultFlags flags, void *userdata) { 51 | if (event == AVAHI_RESOLVER_FOUND) { 52 | if (userdata != NULL) { 53 | struct cb_ctx* ctx = userdata; 54 | avahi_address_snprint(ctx->address, AVAHI_ADDRESS_STR_MAX, address); 55 | *ctx->port = port; 56 | avahi_simple_poll_quit(simple_poll); 57 | } else { 58 | char strAddress[AVAHI_ADDRESS_STR_MAX]; 59 | avahi_address_snprint(strAddress, sizeof(strAddress), address); 60 | printf(" %s (%s:%u)\n", host_name, strAddress, port); 61 | } 62 | } 63 | 64 | avahi_service_resolver_free(r); 65 | } 66 | 67 | static void browse_callback(AvahiServiceBrowser *b, AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event, const char *name, const char *type, const char *domain, AvahiLookupResultFlags flags, void* userdata) { 68 | AvahiClient *c = avahi_service_browser_get_client(b); 69 | 70 | switch (event) { 71 | case AVAHI_BROWSER_FAILURE: 72 | gs_error = "Server browser failure"; 73 | avahi_simple_poll_quit(simple_poll); 74 | break; 75 | case AVAHI_BROWSER_NEW: 76 | if (!(avahi_service_resolver_new(c, interface, protocol, name, type, domain, AVAHI_PROTO_INET, 0, resolve_callback, userdata))) 77 | gs_error = "Failed to resolve service"; 78 | 79 | break; 80 | case AVAHI_BROWSER_REMOVE: 81 | break; 82 | } 83 | } 84 | 85 | void gs_discover_server(char* dest, unsigned short* port) { 86 | AvahiClient *client = NULL; 87 | AvahiServiceBrowser *sb = NULL; 88 | 89 | if (!(simple_poll = avahi_simple_poll_new())) { 90 | gs_error = "Failed to create simple poll object"; 91 | goto cleanup; 92 | } 93 | 94 | int error; 95 | client = avahi_client_new(avahi_simple_poll_get(simple_poll), 0, client_callback, NULL, &error); 96 | if (!client) { 97 | gs_error = "Failed to create client"; 98 | goto cleanup; 99 | } 100 | 101 | struct cb_ctx ctx; 102 | ctx.address = dest; 103 | ctx.port = port; 104 | if (!(sb = avahi_service_browser_new(client, AVAHI_IF_UNSPEC, AVAHI_PROTO_INET, "_nvstream._tcp", NULL, 0, browse_callback, &ctx))) { 105 | gs_error = "Failed to create service browser"; 106 | goto cleanup; 107 | } 108 | 109 | avahi_simple_poll_loop(simple_poll); 110 | 111 | cleanup: 112 | if (sb) 113 | avahi_service_browser_free(sb); 114 | 115 | if (client) 116 | avahi_client_free(client); 117 | 118 | if (simple_poll) 119 | avahi_simple_poll_free(simple_poll); 120 | } 121 | 122 | #endif 123 | -------------------------------------------------------------------------------- /libgamestream/discover.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Moonlight Embedded. 3 | * 4 | * Moonlight is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * Moonlight is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with Moonlight; if not, see . 16 | */ 17 | 18 | #pragma once 19 | 20 | #include "errors.h" 21 | 22 | #define MAX_ADDRESS_SIZE 40 23 | 24 | void gs_discover_server(char* dest, unsigned short* port); 25 | -------------------------------------------------------------------------------- /libgamestream/errors.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Moonlight Embedded. 3 | * 4 | * Copyright (C) 2015, 2016 Iwan Timmer 5 | * 6 | * Moonlight is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Moonlight is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Moonlight; if not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #define GS_OK 0 23 | #define GS_FAILED -1 24 | #define GS_OUT_OF_MEMORY -2 25 | #define GS_INVALID -3 26 | #define GS_WRONG_STATE -4 27 | #define GS_IO_ERROR -5 28 | #define GS_NOT_SUPPORTED_4K -6 29 | #define GS_UNSUPPORTED_VERSION -7 30 | #define GS_NOT_SUPPORTED_MODE -8 31 | #define GS_ERROR -9 32 | #define GS_NOT_SUPPORTED_SOPS_RESOLUTION -10 33 | 34 | extern const char* gs_error; 35 | -------------------------------------------------------------------------------- /libgamestream/http.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Moonlight Embedded. 3 | * 4 | * Copyright (C) 2015 Iwan Timmer 5 | * 6 | * Moonlight is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Moonlight is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Moonlight; if not, see . 18 | */ 19 | 20 | #include "http.h" 21 | #include "errors.h" 22 | 23 | #include 24 | #include 25 | #include 26 | 27 | static CURL *curl; 28 | 29 | static bool debug; 30 | 31 | static size_t _write_curl(void *contents, size_t size, size_t nmemb, void *userp) 32 | { 33 | size_t realsize = size * nmemb; 34 | PHTTP_DATA mem = (PHTTP_DATA)userp; 35 | 36 | mem->memory = realloc(mem->memory, mem->size + realsize + 1); 37 | if(mem->memory == NULL) 38 | return 0; 39 | 40 | memcpy(&(mem->memory[mem->size]), contents, realsize); 41 | mem->size += realsize; 42 | mem->memory[mem->size] = 0; 43 | 44 | return realsize; 45 | } 46 | 47 | int http_init(const char* keyDirectory, int logLevel) { 48 | curl = curl_easy_init(); 49 | debug = logLevel >= 2; 50 | if (!curl) 51 | return GS_FAILED; 52 | 53 | char certificateFilePath[4096]; 54 | snprintf(certificateFilePath, sizeof(certificateFilePath), "%s/%s", keyDirectory, CERTIFICATE_FILE_NAME); 55 | 56 | char keyFilePath[4096]; 57 | snprintf(keyFilePath, sizeof(keyFilePath), "%s/%s", keyDirectory, KEY_FILE_NAME); 58 | 59 | curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); 60 | curl_easy_setopt(curl, CURLOPT_SSLENGINE_DEFAULT, 1L); 61 | curl_easy_setopt(curl, CURLOPT_SSLCERTTYPE,"PEM"); 62 | curl_easy_setopt(curl, CURLOPT_SSLCERT, certificateFilePath); 63 | curl_easy_setopt(curl, CURLOPT_SSLKEYTYPE, "PEM"); 64 | curl_easy_setopt(curl, CURLOPT_SSLKEY, keyFilePath); 65 | curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); 66 | curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, _write_curl); 67 | curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1L); 68 | curl_easy_setopt(curl, CURLOPT_SSL_SESSIONID_CACHE, 0L); 69 | 70 | return GS_OK; 71 | } 72 | 73 | int http_request(char* url, PHTTP_DATA data) { 74 | curl_easy_setopt(curl, CURLOPT_WRITEDATA, data); 75 | curl_easy_setopt(curl, CURLOPT_URL, url); 76 | #ifdef __FreeBSD__ 77 | curl_easy_setopt(curl, CURLOPT_FORBID_REUSE, 1); 78 | #endif 79 | 80 | if (debug) 81 | printf("Request %s\n", url); 82 | 83 | if (data->size > 0) { 84 | free(data->memory); 85 | data->memory = malloc(1); 86 | if(data->memory == NULL) 87 | return GS_OUT_OF_MEMORY; 88 | 89 | data->size = 0; 90 | } 91 | CURLcode res = curl_easy_perform(curl); 92 | 93 | if(res != CURLE_OK) { 94 | gs_error = curl_easy_strerror(res); 95 | return GS_FAILED; 96 | } else if (data->memory == NULL) { 97 | return GS_OUT_OF_MEMORY; 98 | } 99 | 100 | if (debug) 101 | printf("Response:\n%s\n\n", data->memory); 102 | 103 | return GS_OK; 104 | } 105 | 106 | void http_cleanup() { 107 | curl_easy_cleanup(curl); 108 | } 109 | 110 | PHTTP_DATA http_create_data() { 111 | PHTTP_DATA data = malloc(sizeof(HTTP_DATA)); 112 | if (data == NULL) 113 | return NULL; 114 | 115 | data->memory = malloc(1); 116 | if(data->memory == NULL) { 117 | free(data); 118 | return NULL; 119 | } 120 | data->size = 0; 121 | 122 | return data; 123 | } 124 | 125 | void http_free_data(PHTTP_DATA data) { 126 | if (data != NULL) { 127 | if (data->memory != NULL) 128 | free(data->memory); 129 | 130 | free(data); 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /libgamestream/http.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Moonlight Embedded. 3 | * 4 | * Copyright (C) 2015 Iwan Timmer 5 | * 6 | * Moonlight is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Moonlight is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Moonlight; if not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #include 23 | 24 | #define CERTIFICATE_FILE_NAME "client.pem" 25 | #define KEY_FILE_NAME "key.pem" 26 | 27 | typedef struct _HTTP_DATA { 28 | char *memory; 29 | size_t size; 30 | } HTTP_DATA, *PHTTP_DATA; 31 | 32 | int http_init(const char* keyDirectory, int logLevel); 33 | PHTTP_DATA http_create_data(); 34 | int http_request(char* url, PHTTP_DATA data); 35 | void http_cleanup(); 36 | void http_free_data(PHTTP_DATA data); 37 | -------------------------------------------------------------------------------- /libgamestream/mkcert.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Moonlight is free software; you can redistribute it and/or modify 3 | * it under the terms of the GNU General Public License as published by 4 | * the Free Software Foundation; either version 3 of the License, or 5 | * (at your option) any later version. 6 | * 7 | * Moonlight is distributed in the hope that it will be useful, 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | * GNU General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU General Public License 13 | * along with Moonlight; if not, see . 14 | */ 15 | 16 | #include "mkcert.h" 17 | 18 | #include 19 | #include 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #ifndef OPENSSL_NO_ENGINE 27 | #include 28 | #endif 29 | 30 | static const int NUM_BITS = 2048; 31 | static const int SERIAL = 0; 32 | static const int NUM_YEARS = 10; 33 | 34 | int mkcert(X509 **x509p, EVP_PKEY **pkeyp, int bits, int serial, int years); 35 | 36 | CERT_KEY_PAIR mkcert_generate() { 37 | BIO *bio_err; 38 | X509 *x509 = NULL; 39 | EVP_PKEY *pkey = NULL; 40 | PKCS12 *p12 = NULL; 41 | 42 | bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); 43 | 44 | OpenSSL_add_all_algorithms(); 45 | ERR_load_crypto_strings(); 46 | 47 | mkcert(&x509, &pkey, NUM_BITS, SERIAL, NUM_YEARS); 48 | 49 | p12 = PKCS12_create("limelight", "GameStream", pkey, x509, NULL, 0, 0, 0, 0, 0); 50 | 51 | #ifndef OPENSSL_NO_ENGINE 52 | ENGINE_cleanup(); 53 | #endif 54 | CRYPTO_cleanup_all_ex_data(); 55 | 56 | BIO_free(bio_err); 57 | 58 | return (CERT_KEY_PAIR) {x509, pkey, p12}; 59 | } 60 | 61 | void mkcert_free(CERT_KEY_PAIR certKeyPair) { 62 | X509_free(certKeyPair.x509); 63 | EVP_PKEY_free(certKeyPair.pkey); 64 | PKCS12_free(certKeyPair.p12); 65 | } 66 | 67 | void mkcert_save(const char* certFile, const char* p12File, const char* keyPairFile, CERT_KEY_PAIR certKeyPair) { 68 | FILE* certFilePtr = fopen(certFile, "w"); 69 | FILE* keyPairFilePtr = fopen(keyPairFile, "w"); 70 | FILE* p12FilePtr = fopen(p12File, "wb"); 71 | 72 | //TODO: error check 73 | PEM_write_PrivateKey(keyPairFilePtr, certKeyPair.pkey, NULL, NULL, 0, NULL, NULL); 74 | PEM_write_X509(certFilePtr, certKeyPair.x509); 75 | i2d_PKCS12_fp(p12FilePtr, certKeyPair.p12); 76 | 77 | fclose(p12FilePtr); 78 | fclose(certFilePtr); 79 | fclose(keyPairFilePtr); 80 | } 81 | 82 | int mkcert(X509 **x509p, EVP_PKEY **pkeyp, int bits, int serial, int years) { 83 | EVP_PKEY_CTX* ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL); 84 | EVP_PKEY_keygen_init(ctx); 85 | EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, bits); 86 | 87 | // pk must be initialized on input 88 | EVP_PKEY *pk = NULL;; 89 | EVP_PKEY_keygen(ctx, &pk); 90 | 91 | EVP_PKEY_CTX_free(ctx); 92 | 93 | X509* cert = X509_new(); 94 | X509_set_version(cert, 2); 95 | ASN1_INTEGER_set(X509_get_serialNumber(cert), serial); 96 | #if OPENSSL_VERSION_NUMBER < 0x10100000L 97 | X509_gmtime_adj(X509_get_notBefore(cert), 0); 98 | X509_gmtime_adj(X509_get_notAfter(cert), 60 * 60 * 24 * 365 * years); 99 | #else 100 | ASN1_TIME* before = ASN1_STRING_dup(X509_get0_notBefore(cert)); 101 | ASN1_TIME* after = ASN1_STRING_dup(X509_get0_notAfter(cert)); 102 | 103 | X509_gmtime_adj(before, 0); 104 | X509_gmtime_adj(after, 60 * 60 * 24 * 365 * years); 105 | 106 | X509_set1_notBefore(cert, before); 107 | X509_set1_notAfter(cert, after); 108 | 109 | ASN1_STRING_free(before); 110 | ASN1_STRING_free(after); 111 | #endif 112 | 113 | X509_set_pubkey(cert, pk); 114 | 115 | X509_NAME* name = X509_get_subject_name(cert); 116 | X509_NAME_add_entry_by_txt(name,"CN", MBSTRING_ASC, (unsigned char*)"NVIDIA GameStream Client", -1, -1, 0); 117 | X509_set_issuer_name(cert, name); 118 | 119 | if (!X509_sign(cert, pk, EVP_sha256())) { 120 | goto err; 121 | } 122 | 123 | *x509p = cert; 124 | *pkeyp = pk; 125 | 126 | return(1); 127 | err: 128 | return(0); 129 | } 130 | -------------------------------------------------------------------------------- /libgamestream/mkcert.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Created by Diego Waxemberg on 10/16/14. 3 | * Copyright (c) 2014 Limelight Stream. All rights reserved. 4 | * 5 | * Moonlight is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * Moonlight is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with Moonlight; if not, see . 17 | */ 18 | 19 | #pragma once 20 | 21 | #include 22 | #include 23 | 24 | typedef struct _CERT_KEY_PAIR { 25 | X509 *x509; 26 | EVP_PKEY *pkey; 27 | PKCS12 *p12; 28 | } CERT_KEY_PAIR, *PCERT_KEY_PAIR; 29 | 30 | CERT_KEY_PAIR mkcert_generate(); 31 | void mkcert_free(CERT_KEY_PAIR); 32 | void mkcert_save(const char* certFile, const char* p12File, const char* keyPairFile, CERT_KEY_PAIR certKeyPair); 33 | -------------------------------------------------------------------------------- /libgamestream/sps.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Moonlight Embedded. 3 | * 4 | * Copyright (C) 2015 Iwan Timmer 5 | * 6 | * Moonlight is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Moonlight is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Moonlight; if not, see . 18 | */ 19 | 20 | #include "sps.h" 21 | 22 | #include "h264_stream.h" 23 | 24 | static h264_stream_t* h264_stream; 25 | static int initial_width, initial_height; 26 | 27 | void gs_sps_init(int width, int height) { 28 | h264_stream = h264_new(); 29 | initial_width = width; 30 | initial_height = height; 31 | } 32 | 33 | void gs_sps_fix(PLENTRY sps, int flags, uint8_t* out_buf, uint32_t* out_offset) { 34 | int start_len = sps->data[2] == 0x01 ? 3 : 4; 35 | 36 | read_nal_unit(h264_stream, sps->data+start_len, sps->length-start_len); 37 | 38 | // Some decoders rely on H264 level to decide how many buffers are needed 39 | // Since we only need one frame buffered, we'll set level as low as we can 40 | // for known resolution combinations. Otherwise leave the profile alone (currently 5.0) 41 | if (initial_width == 1280 && initial_height == 720) 42 | h264_stream->sps->level_idc = 32; // Max 5 buffered frames at 1280x720x60 43 | else if (initial_width == 1920 && initial_height == 1080) 44 | h264_stream->sps->level_idc = 42; // Max 4 buffered frames at 1920x1080x60 45 | 46 | // Some decoders requires a reference frame count of 1 to decode successfully. 47 | h264_stream->sps->num_ref_frames = 1; 48 | 49 | // GFE 2.5.11 changed the SPS to add additional extensions 50 | // Some devices don't like these so we remove them here. 51 | if (flags & GS_SPS_REMOVE_VST_FIXUP) 52 | h264_stream->sps->vui.video_signal_type_present_flag = 0; 53 | if (flags & GS_SPS_REMOVE_CLI_FIXUP) 54 | h264_stream->sps->vui.chroma_loc_info_present_flag = 0; 55 | 56 | if ((flags & GS_SPS_BITSTREAM_FIXUP) == GS_SPS_BITSTREAM_FIXUP) { 57 | // The SPS that comes in the current H264 bytestream doesn't set the bitstream_restriction_flag 58 | // or the max_dec_frame_buffering which increases decoding latency on some devices. 59 | // log2_max_mv_length_horizontal and log2_max_mv_length_vertical are set to more 60 | // conservative values by GFE 2.5.11. We'll let those values stand. 61 | if (!h264_stream->sps->vui.bitstream_restriction_flag) { 62 | h264_stream->sps->vui.bitstream_restriction_flag = 1; 63 | h264_stream->sps->vui.motion_vectors_over_pic_boundaries_flag = 1; 64 | h264_stream->sps->vui.max_bits_per_mb_denom = 1; 65 | h264_stream->sps->vui.log2_max_mv_length_horizontal = 16; 66 | h264_stream->sps->vui.log2_max_mv_length_vertical = 16; 67 | h264_stream->sps->vui.num_reorder_frames = 0; 68 | } 69 | 70 | // Some devices throw errors if max_dec_frame_buffering < num_ref_frames 71 | h264_stream->sps->vui.max_dec_frame_buffering = 1; 72 | 73 | // These values are the default for the fields, but they are more aggressive 74 | // than what GFE sends in 2.5.11, but it doesn't seem to cause picture problems. 75 | h264_stream->sps->vui.max_bytes_per_pic_denom = 2; 76 | h264_stream->sps->vui.max_bits_per_mb_denom = 1; 77 | } 78 | 79 | memcpy(out_buf+*out_offset, sps->data, start_len); 80 | *out_offset += start_len; 81 | 82 | *out_offset += write_nal_unit(h264_stream, out_buf+*out_offset, 128); 83 | } 84 | -------------------------------------------------------------------------------- /libgamestream/sps.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Moonlight Embedded. 3 | * 4 | * Copyright (C) 2015 Iwan Timmer 5 | * 6 | * Moonlight is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Moonlight is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Moonlight; if not, see . 18 | */ 19 | 20 | #include 21 | 22 | #define GS_SPS_BITSTREAM_FIXUP 0x01 23 | #define GS_SPS_REMOVE_VST_FIXUP 0x02 24 | #define GS_SPS_REMOVE_CLI_FIXUP 0x04 25 | 26 | void gs_sps_init(int width, int height); 27 | void gs_sps_fix(PLENTRY sps, int flags, uint8_t* out_buf, uint32_t* out_offset); 28 | -------------------------------------------------------------------------------- /libgamestream/xml.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Moonlight Embedded. 3 | * 4 | * Copyright (C) 2015 Iwan Timmer 5 | * 6 | * Moonlight is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Moonlight is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Moonlight; if not, see . 18 | */ 19 | #pragma once 20 | 21 | #include 22 | 23 | typedef struct _APP_LIST { 24 | char* name; 25 | int id; 26 | struct _APP_LIST *next; 27 | } APP_LIST, *PAPP_LIST; 28 | 29 | typedef struct _DISPLAY_MODE { 30 | unsigned int height; 31 | unsigned int width; 32 | unsigned int refresh; 33 | struct _DISPLAY_MODE *next; 34 | } DISPLAY_MODE, *PDISPLAY_MODE; 35 | 36 | int xml_search(char* data, size_t len, char* node, char** result); 37 | int xml_applist(char* data, size_t len, PAPP_LIST *app_list); 38 | int xml_modelist(char* data, size_t len, PDISPLAY_MODE *mode_list); 39 | int xml_status(char* data, size_t len); 40 | -------------------------------------------------------------------------------- /moonlight.conf: -------------------------------------------------------------------------------- 1 | ## Hostname or IP-address of host to connect to 2 | ## By default host is autodiscovered using mDNS 3 | #address = 1.2.3.4 4 | 5 | ## Video streaming configuration 6 | #width = 1280 7 | #height = 720 8 | #fps = 60 9 | 10 | ## Output rotation (independent of xrandr or framebuffer settings!) 11 | ## Allowed values: 0, 90, 180, 270 12 | #rotate = 0 13 | 14 | ## Bitrate depends by default on resolution and fps 15 | ## Set to -1 to enable default 16 | ## 20Mbps (20000) for 1080p (60 fps) 17 | ## 10Mbps (10000) for 1080p or 60 fps 18 | ## 5Mbps (5000) for lower resolution or fps 19 | #bitrate = -1 20 | 21 | ## Size of network packets should be lower than MTU 22 | ## If streaming with WAN optimizations, this will be capped at 1024. 23 | #packetsize = 1392 24 | 25 | ## Select video codec (auto/h264/h265) 26 | #codec = auto 27 | 28 | ## Default started application on host 29 | #app = Steam 30 | 31 | ## Default used mapping for streaming 32 | ## Searched for in $XDG_DATA_DIRS/moonlight or /usr/share/moonlight and /usr/local/share/moonlight 33 | ## Mapping can also be user overrided in $XDG_CONFIG_DIR/moonlight or ~/.config/moonlight or current directory 34 | #mapping = gamecontrollerdb.txt 35 | 36 | ## Enable selected input devices 37 | ## By default all available input devices should be used 38 | ## Only evdev devices /dev/input/event* are allowed 39 | ## To use a different mapping then default another mapping should be declared above the input 40 | #input = /dev/input/event1 41 | 42 | ## Enable GFE for changing graphical game settings for optimal performance and quality 43 | #sops = true 44 | 45 | ## Play audio on host instead of streaming to client 46 | #localaudio = false 47 | 48 | ## Send quit app request to remote after quitting session 49 | #quitappafter = false 50 | 51 | ## Disable all input processing (view-only mode) 52 | #viewonly = false 53 | 54 | ## Select audio device to play sound on 55 | #audio = sysdefault 56 | 57 | ## Select the audio and video decoder to use 58 | ## default - autodetect 59 | ## aml - hardware video decoder for ODROID-C1/C2 60 | ## rk - hardware video decoder for ODROID-N1 Rockchip 61 | ## omx - hardware video decoder for Raspberry Pi 62 | ## imx - hardware video decoder for i.MX6 devices 63 | ## x11 - software decoder 64 | ## sdl - software decoder with SDL input and audio 65 | ## fake - no audio and video 66 | #platform = default 67 | 68 | ## Directory to store encryption keys 69 | ## By default keys are stored in $XDG_CACHE_DIR/moonlight or ~/.cache/moonlight 70 | #keydir = /dir/to/keys 71 | 72 | ## Enable QOS settings to optimize for internet or local network 73 | ## yes - optimize for WAN streaming 74 | ## no - optimize for LAN streaming 75 | ## auto (default) - decide automatically based on target IP address 76 | #remote = auto 77 | 78 | ## Enable 5.1/7.1 surround sound 79 | #surround = 5.1 80 | 81 | ## Load additional configuration files 82 | #config = /path/to/config 83 | -------------------------------------------------------------------------------- /src/audio/audio.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Moonlight Embedded. 3 | * 4 | * Copyright (C) 2015-2017 Iwan Timmer 5 | * 6 | * Moonlight is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Moonlight is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Moonlight; if not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #include 23 | 24 | #include 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | #ifdef HAVE_ALSA 31 | extern AUDIO_RENDERER_CALLBACKS audio_callbacks_alsa; 32 | #endif 33 | #ifdef HAVE_SDL 34 | extern AUDIO_RENDERER_CALLBACKS audio_callbacks_sdl; 35 | #endif 36 | #ifdef HAVE_PULSE 37 | extern AUDIO_RENDERER_CALLBACKS audio_callbacks_pulse; 38 | bool audio_pulse_init(char* audio_device); 39 | #endif 40 | #ifdef __FreeBSD__ 41 | extern AUDIO_RENDERER_CALLBACKS audio_callbacks_oss; 42 | #endif 43 | #ifdef __3DS__ 44 | extern bool n3ds_audio_disabled; 45 | extern AUDIO_RENDERER_CALLBACKS audio_callbacks_n3ds; 46 | #endif 47 | 48 | #ifdef __cplusplus 49 | } 50 | #endif 51 | -------------------------------------------------------------------------------- /src/audio/n3ds_audio.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Moonlight Embedded. 3 | * 4 | * Copyright (C) 2015-2017 Iwan Timmer 5 | * 6 | * Moonlight is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Moonlight is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Moonlight; if not, see . 18 | */ 19 | 20 | #include "audio.h" 21 | 22 | #include <3ds.h> 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | #define WAVEBUF_SIZE 16 30 | bool n3ds_audio_disabled = false; 31 | 32 | static OpusMSDecoder* decoder; 33 | static u8* audioBuffer; 34 | static int samplesPerFrame; 35 | static int sampleRate; 36 | static int channelCount; 37 | static ndspWaveBuf audio_wave_buf[WAVEBUF_SIZE]; 38 | static int wave_buf_idx = 0; 39 | 40 | static int n3ds_renderer_init(int audioConfiguration, POPUS_MULTISTREAM_CONFIGURATION opusConfig, void* context, int arFlags) { 41 | int rc; 42 | decoder = opus_multistream_decoder_create(opusConfig->sampleRate, opusConfig->channelCount, opusConfig->streams, opusConfig->coupledStreams, opusConfig->mapping, &rc); 43 | 44 | sampleRate = opusConfig->sampleRate; 45 | channelCount = opusConfig->channelCount; 46 | samplesPerFrame = opusConfig->samplesPerFrame; 47 | int bytes_per_frame = sizeof(short) * channelCount * samplesPerFrame; 48 | 49 | if(ndspInit() != 0) 50 | { 51 | fprintf(stderr, "ndspInit() failed\n"); 52 | return -1; 53 | } 54 | 55 | u8 *audioBuffer = (u8*)linearAlloc(bytes_per_frame * WAVEBUF_SIZE); 56 | if (audioBuffer == NULL) 57 | return -1; 58 | memset(audioBuffer, 0, bytes_per_frame * WAVEBUF_SIZE); 59 | 60 | ndspChnWaveBufClear(0); 61 | ndspChnReset(0); 62 | ndspSetOutputMode(NDSP_OUTPUT_STEREO); 63 | ndspChnSetInterp(0, NDSP_INTERP_LINEAR); 64 | ndspChnSetRate(0, sampleRate); 65 | ndspChnSetFormat(0, NDSP_FORMAT_STEREO_PCM16); 66 | 67 | float mix[12]; 68 | memset(mix, 0, sizeof(mix)); 69 | mix[0] = mix[1] = 1.0f; 70 | ndspChnSetMix(0, mix); 71 | 72 | memset(audio_wave_buf,0,sizeof(audio_wave_buf)); 73 | for (int i = 0; i < WAVEBUF_SIZE; i++) { 74 | audio_wave_buf[i].data_vaddr = &audioBuffer[i * bytes_per_frame]; 75 | audio_wave_buf[i].status = NDSP_WBUF_DONE; 76 | } 77 | 78 | ndspChnSetPaused(0, false); 79 | 80 | return 0; 81 | } 82 | 83 | static void n3ds_renderer_cleanup() { 84 | if (decoder != NULL) { 85 | opus_multistream_decoder_destroy(decoder); 86 | decoder = NULL; 87 | } 88 | 89 | ndspChnWaveBufClear(0); 90 | ndspExit(); 91 | if (audioBuffer != NULL) { 92 | free(audioBuffer); 93 | audioBuffer = NULL; 94 | } 95 | } 96 | 97 | static void n3ds_renderer_decode_and_play_sample(char* data, int length) { 98 | if (n3ds_audio_disabled || (audio_wave_buf[wave_buf_idx].status != NDSP_WBUF_DONE)) { 99 | return; 100 | } 101 | 102 | int decodeLen = opus_multistream_decode(decoder, (const unsigned char *)data, length, (opus_int16 *)audio_wave_buf[wave_buf_idx].data_vaddr, samplesPerFrame, 0); 103 | if (decodeLen < 0) { 104 | fprintf(stderr, "Opus error from decode: %d\n", decodeLen); 105 | return; 106 | } 107 | DSP_FlushDataCache(audio_wave_buf[wave_buf_idx].data_vaddr, decodeLen * channelCount * sizeof(short)); 108 | audio_wave_buf[wave_buf_idx].nsamples = decodeLen; 109 | ndspChnWaveBufAdd(0, &audio_wave_buf[wave_buf_idx]); 110 | 111 | wave_buf_idx = (wave_buf_idx + 1) % WAVEBUF_SIZE; 112 | } 113 | 114 | AUDIO_RENDERER_CALLBACKS audio_callbacks_n3ds = { 115 | .init = n3ds_renderer_init, 116 | .cleanup = n3ds_renderer_cleanup, 117 | .decodeAndPlaySample = n3ds_renderer_decode_and_play_sample, 118 | .capabilities = CAPABILITY_DIRECT_SUBMIT | CAPABILITY_SLOW_OPUS_DECODER, 119 | }; 120 | -------------------------------------------------------------------------------- /src/audio/oss.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Moonlight Embedded. 3 | * 4 | * Copyright (C) 2015-2017 Iwan Timmer 5 | * 6 | * Moonlight is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Moonlight is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Moonlight; if not, see . 18 | */ 19 | 20 | #ifdef __FreeBSD__ 21 | #include 22 | #include 23 | #include "audio.h" 24 | 25 | #include 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | static OpusMSDecoder* decoder; 34 | static short* pcmBuffer; 35 | static int samplesPerFrame; 36 | static int channelCount; 37 | static int fd = -1; 38 | 39 | static int oss_renderer_init(int audioConfiguration, POPUS_MULTISTREAM_CONFIGURATION opusConfig, void* context, int arFlags) { 40 | int rc; 41 | decoder = opus_multistream_decoder_create(opusConfig->sampleRate, opusConfig->channelCount, opusConfig->streams, opusConfig->coupledStreams, opusConfig->mapping, &rc); 42 | 43 | channelCount = opusConfig->channelCount; 44 | samplesPerFrame = opusConfig->samplesPerFrame; 45 | pcmBuffer = malloc(sizeof(short) * channelCount * samplesPerFrame); 46 | if (pcmBuffer == NULL) 47 | return -1; 48 | 49 | const char* oss_name = "/dev/dsp"; 50 | fd = open(oss_name, O_WRONLY); 51 | if (fd == -1) { 52 | printf("Open audio device /dev/dsp failed! error %d\n", errno); 53 | return -1; 54 | } 55 | // buffer size for fragment ,selector 12 is 4096;11 is 2048;10 is 1024; 13is 8192 56 | int frag = 12; 57 | if (ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &frag) == -1) 58 | printf("Set fragment for /dev/dsp failed."); 59 | 60 | int format = AFMT_S16_LE; 61 | int channels = opusConfig->channelCount; 62 | int rate = opusConfig->sampleRate; 63 | if (ioctl(fd, SNDCTL_DSP_SETFMT, &format) == -1) 64 | printf("Set format for /dev/dsp failed."); 65 | if (ioctl(fd, SNDCTL_DSP_CHANNELS, &channels) == -1) 66 | printf("Set channels for /dev/dsp failed."); 67 | if (ioctl(fd, SNDCTL_DSP_SPEED, &rate) == -1) 68 | printf("Set sample rate for /dev/dsp failed."); 69 | 70 | return 0; 71 | } 72 | 73 | static void oss_renderer_cleanup() { 74 | if (decoder != NULL) { 75 | opus_multistream_decoder_destroy(decoder); 76 | decoder = NULL; 77 | } 78 | 79 | if (pcmBuffer != NULL) { 80 | free(pcmBuffer); 81 | pcmBuffer = NULL; 82 | } 83 | 84 | if (fd != -1) { 85 | close(fd); 86 | fd = -1; 87 | } 88 | } 89 | 90 | static void oss_renderer_decode_and_play_sample(char* data, int length) { 91 | int decodeLen = opus_multistream_decode(decoder, data, length, pcmBuffer, samplesPerFrame, 0); 92 | if (decodeLen > 0) { 93 | write(fd, pcmBuffer, decodeLen * channelCount * sizeof(short)); 94 | } else if (decodeLen < 0) { 95 | printf("Opus error from decode: %d\n", decodeLen); 96 | } 97 | } 98 | 99 | AUDIO_RENDERER_CALLBACKS audio_callbacks_oss = { 100 | .init = oss_renderer_init, 101 | .cleanup = oss_renderer_cleanup, 102 | .decodeAndPlaySample = oss_renderer_decode_and_play_sample, 103 | .capabilities = CAPABILITY_DIRECT_SUBMIT | CAPABILITY_SUPPORTS_ARBITRARY_AUDIO_DURATION, 104 | }; 105 | #endif 106 | -------------------------------------------------------------------------------- /src/audio/pulse.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Moonlight Embedded. 3 | * 4 | * Copyright (C) 2015-2017 Iwan Timmer 5 | * 6 | * Moonlight is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Moonlight is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Moonlight; if not, see . 18 | */ 19 | 20 | #ifndef __3DS__ 21 | 22 | #include "audio.h" 23 | 24 | #include 25 | #include 26 | #include 27 | 28 | #include 29 | #include 30 | #include 31 | 32 | static OpusMSDecoder* decoder; 33 | static pa_simple *dev = NULL; 34 | static short* pcmBuffer; 35 | static int samplesPerFrame; 36 | static int channelCount; 37 | 38 | bool audio_pulse_init(char* audio_device) { 39 | pa_sample_spec spec = { 40 | .format = PA_SAMPLE_S16LE, 41 | .rate = 48000, 42 | .channels = 2 43 | }; 44 | 45 | int error; 46 | dev = pa_simple_new(NULL, "Moonlight Embedded", PA_STREAM_PLAYBACK, audio_device, "Streaming", &spec, NULL, NULL, &error); 47 | 48 | if (dev) 49 | pa_simple_free(dev); 50 | 51 | return (bool) dev; 52 | } 53 | 54 | static int pulse_renderer_init(int audioConfiguration, POPUS_MULTISTREAM_CONFIGURATION opusConfig, void* context, int arFlags) { 55 | int rc, error; 56 | unsigned char alsaMapping[AUDIO_CONFIGURATION_MAX_CHANNEL_COUNT]; 57 | 58 | channelCount = opusConfig->channelCount; 59 | samplesPerFrame = opusConfig->samplesPerFrame; 60 | pcmBuffer = malloc(sizeof(short) * channelCount * samplesPerFrame); 61 | if (pcmBuffer == NULL) 62 | return -1; 63 | 64 | /* The supplied mapping array has order: FL-FR-C-LFE-RL-RR-SL-SR 65 | * ALSA expects the order: FL-FR-RL-RR-C-LFE-SL-SR 66 | * We need copy the mapping locally and swap the channels around. 67 | */ 68 | memcpy(alsaMapping, opusConfig->mapping, sizeof(alsaMapping)); 69 | if (opusConfig->channelCount >= 6) { 70 | alsaMapping[2] = opusConfig->mapping[4]; 71 | alsaMapping[3] = opusConfig->mapping[5]; 72 | alsaMapping[4] = opusConfig->mapping[2]; 73 | alsaMapping[5] = opusConfig->mapping[3]; 74 | } 75 | 76 | decoder = opus_multistream_decoder_create(opusConfig->sampleRate, opusConfig->channelCount, opusConfig->streams, opusConfig->coupledStreams, alsaMapping, &rc); 77 | 78 | pa_sample_spec spec = { 79 | .format = PA_SAMPLE_S16LE, 80 | .rate = opusConfig->sampleRate, 81 | .channels = opusConfig->channelCount 82 | }; 83 | 84 | pa_channel_map map; 85 | pa_channel_map_init_auto(&map, opusConfig->channelCount, PA_CHANNEL_MAP_ALSA); 86 | 87 | char* audio_device = (char*) context; 88 | dev = pa_simple_new(NULL, "Moonlight Embedded", PA_STREAM_PLAYBACK, audio_device, "Streaming", &spec, &map, NULL, &error); 89 | 90 | if (!dev) { 91 | printf("Pulseaudio error: %s\n", pa_strerror(error)); 92 | return -1; 93 | } 94 | 95 | return 0; 96 | } 97 | 98 | static void pulse_renderer_decode_and_play_sample(char* data, int length) { 99 | int decodeLen = opus_multistream_decode(decoder, data, length, pcmBuffer, samplesPerFrame, 0); 100 | if (decodeLen > 0) { 101 | int error; 102 | int rc = pa_simple_write(dev, pcmBuffer, decodeLen * sizeof(short) * channelCount, &error); 103 | 104 | if (rc<0) 105 | printf("Pulseaudio error: %s\n", pa_strerror(error)); 106 | } else if (decodeLen < 0) { 107 | printf("Opus error from decode: %d\n", decodeLen); 108 | } 109 | } 110 | 111 | static void pulse_renderer_cleanup() { 112 | if (decoder != NULL) { 113 | opus_multistream_decoder_destroy(decoder); 114 | decoder = NULL; 115 | } 116 | if (dev != NULL) { 117 | pa_simple_free(dev); 118 | dev = NULL; 119 | } 120 | if (pcmBuffer != NULL) { 121 | free(pcmBuffer); 122 | pcmBuffer = NULL; 123 | } 124 | } 125 | 126 | AUDIO_RENDERER_CALLBACKS audio_callbacks_pulse = { 127 | .init = pulse_renderer_init, 128 | .cleanup = pulse_renderer_cleanup, 129 | .decodeAndPlaySample = pulse_renderer_decode_and_play_sample, 130 | .capabilities = CAPABILITY_DIRECT_SUBMIT | CAPABILITY_SUPPORTS_ARBITRARY_AUDIO_DURATION, 131 | }; 132 | 133 | #endif 134 | -------------------------------------------------------------------------------- /src/audio/sdl_audio.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Moonlight Embedded. 3 | * 4 | * Copyright (C) 2015-2017 Iwan Timmer 5 | * 6 | * Moonlight is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Moonlight is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Moonlight; if not, see . 18 | */ 19 | 20 | #ifdef HAVE_SDL 21 | 22 | #include "audio.h" 23 | 24 | #include 25 | #include 26 | 27 | #include 28 | #include 29 | 30 | static OpusMSDecoder* decoder; 31 | static short* pcmBuffer; 32 | static int samplesPerFrame; 33 | static SDL_AudioDeviceID dev; 34 | static int channelCount; 35 | 36 | static int sdl_renderer_init(int audioConfiguration, POPUS_MULTISTREAM_CONFIGURATION opusConfig, void* context, int arFlags) { 37 | int rc; 38 | decoder = opus_multistream_decoder_create(opusConfig->sampleRate, opusConfig->channelCount, opusConfig->streams, opusConfig->coupledStreams, opusConfig->mapping, &rc); 39 | 40 | channelCount = opusConfig->channelCount; 41 | samplesPerFrame = opusConfig->samplesPerFrame; 42 | pcmBuffer = malloc(sizeof(short) * channelCount * samplesPerFrame); 43 | if (pcmBuffer == NULL) 44 | return -1; 45 | 46 | SDL_InitSubSystem(SDL_INIT_AUDIO); 47 | 48 | SDL_AudioSpec want, have; 49 | SDL_zero(want); 50 | want.freq = opusConfig->sampleRate; 51 | want.format = AUDIO_S16LSB; 52 | want.channels = opusConfig->channelCount; 53 | want.samples = 4096; 54 | 55 | dev = SDL_OpenAudioDevice(NULL, 0, &want, &have, 0); 56 | if (dev == 0) { 57 | printf("Failed to open audio: %s\n", SDL_GetError()); 58 | return -1; 59 | } else { 60 | SDL_PauseAudioDevice(dev, 0); // start audio playing. 61 | } 62 | 63 | return 0; 64 | } 65 | 66 | static void sdl_renderer_cleanup() { 67 | if (decoder != NULL) { 68 | opus_multistream_decoder_destroy(decoder); 69 | decoder = NULL; 70 | } 71 | 72 | if (pcmBuffer != NULL) { 73 | free(pcmBuffer); 74 | pcmBuffer = NULL; 75 | } 76 | 77 | if (dev != 0) { 78 | SDL_CloseAudioDevice(dev); 79 | dev = 0; 80 | } 81 | } 82 | 83 | static void sdl_renderer_decode_and_play_sample(char* data, int length) { 84 | int decodeLen = opus_multistream_decode(decoder, data, length, pcmBuffer, samplesPerFrame, 0); 85 | if (decodeLen > 0) { 86 | SDL_QueueAudio(dev, pcmBuffer, decodeLen * channelCount * sizeof(short)); 87 | } else if (decodeLen < 0) { 88 | printf("Opus error from decode: %d\n", decodeLen); 89 | } 90 | } 91 | 92 | AUDIO_RENDERER_CALLBACKS audio_callbacks_sdl = { 93 | .init = sdl_renderer_init, 94 | .cleanup = sdl_renderer_cleanup, 95 | .decodeAndPlaySample = sdl_renderer_decode_and_play_sample, 96 | .capabilities = CAPABILITY_DIRECT_SUBMIT | CAPABILITY_SUPPORTS_ARBITRARY_AUDIO_DURATION, 97 | }; 98 | 99 | #endif 100 | -------------------------------------------------------------------------------- /src/config.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Moonlight Embedded. 3 | * 4 | * Copyright (C) 2015-2017 Iwan Timmer 5 | * 6 | * Moonlight is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Moonlight is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Moonlight; if not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #include 23 | 24 | #include 25 | #include "platform_main.h" 26 | 27 | #define MAX_INPUTS 6 28 | 29 | #ifdef __cplusplus 30 | extern "C" { 31 | #endif 32 | 33 | typedef struct _CONFIGURATION { 34 | STREAM_CONFIGURATION stream; 35 | int debug_level; 36 | char* app; 37 | char* action; 38 | char* address; 39 | char* mapping; 40 | char* platform; 41 | char* audio_device; 42 | char* config_file; 43 | char key_dir[4096]; 44 | bool sops; 45 | bool localaudio; 46 | bool fullscreen; 47 | int rotate; 48 | bool unsupported; 49 | bool quitappafter; 50 | bool viewonly; 51 | bool mouse_emulation; 52 | char* inputs[MAX_INPUTS]; 53 | int inputsCount; 54 | enum codecs codec; 55 | bool hdr; 56 | int pin; 57 | unsigned short port; 58 | bool hwdecode; 59 | int display_type; 60 | bool motion_controls; 61 | bool swap_face_buttons; 62 | bool swap_triggers_and_shoulders; 63 | bool use_triggers_for_mouse; 64 | } CONFIGURATION, *PCONFIGURATION; 65 | 66 | extern bool inputAdded; 67 | 68 | bool config_file_parse(char* filename, PCONFIGURATION config); 69 | void config_parse(int argc, char* argv[], PCONFIGURATION config); 70 | void parse_argument(int c, char* value, PCONFIGURATION config); 71 | void config_save(char* filename, PCONFIGURATION config); 72 | 73 | #ifdef __cplusplus 74 | } 75 | #endif 76 | -------------------------------------------------------------------------------- /src/configuration.h.in: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Moonlight Embedded. 3 | * 4 | * Copyright (C) 2015-2017 Iwan Timmer 5 | * 6 | * Moonlight is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Moonlight is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Moonlight; if not, see . 18 | */ 19 | 20 | #define VERSION_MAJOR @PROJECT_VERSION_MAJOR@ 21 | #define VERSION_MINOR @PROJECT_VERSION_MINOR@ 22 | #define VERSION_PATCH @PROJECT_VERSION_PATCH@ 23 | #cmakedefine GIT_BRANCH "@GIT_BRANCH@" 24 | #cmakedefine GIT_COMMIT_HASH "@GIT_COMMIT_HASH@" 25 | 26 | #define COMPILE_OPTIONS "@MOONLIGHT_OPTIONS@" 27 | -------------------------------------------------------------------------------- /src/connection_main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Moonlight Embedded. 3 | * 4 | * Copyright (C) 2015-2017 Iwan Timmer 5 | * 6 | * Moonlight is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Moonlight is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Moonlight; if not, see . 18 | */ 19 | 20 | #ifndef __3DS__ 21 | 22 | #include "connection.h" 23 | 24 | #include 25 | #include 26 | #include 27 | 28 | #ifdef HAVE_SDL 29 | #include 30 | #endif 31 | 32 | pthread_t main_thread_id = 0; 33 | bool connection_debug; 34 | ConnListenerRumble rumble_handler = NULL; 35 | ConnListenerRumbleTriggers rumble_triggers_handler = NULL; 36 | ConnListenerSetMotionEventState set_motion_event_state_handler = NULL; 37 | ConnListenerSetControllerLED set_controller_led_handler = NULL; 38 | 39 | static void connection_terminated(int errorCode) { 40 | switch (errorCode) { 41 | case ML_ERROR_GRACEFUL_TERMINATION: 42 | printf("Connection has been terminated gracefully.\n"); 43 | break; 44 | case ML_ERROR_NO_VIDEO_TRAFFIC: 45 | printf("No video received from host. Check the host PC's firewall and port forwarding rules.\n"); 46 | break; 47 | case ML_ERROR_NO_VIDEO_FRAME: 48 | printf("Your network connection isn't performing well. Reduce your video bitrate setting or try a faster connection.\n"); 49 | break; 50 | case ML_ERROR_UNEXPECTED_EARLY_TERMINATION: 51 | printf("The connection was unexpectedly terminated by the host due to a video capture error. Make sure no DRM-protected content is playing on the host.\n"); 52 | break; 53 | case ML_ERROR_PROTECTED_CONTENT: 54 | printf("The connection was terminated by the host due to DRM-protected content. Close any DRM-protected content on the host and try again.\n"); 55 | break; 56 | default: 57 | printf("Connection terminated with error: %d\n", errorCode); 58 | break; 59 | } 60 | 61 | #ifdef HAVE_SDL 62 | SDL_Event event; 63 | event.type = SDL_EVENT_QUIT; 64 | SDL_PushEvent(&event); 65 | #endif 66 | 67 | if (main_thread_id != 0) 68 | pthread_kill(main_thread_id, SIGTERM); 69 | } 70 | 71 | static void connection_log_message(const char* format, ...) { 72 | va_list arglist; 73 | va_start(arglist, format); 74 | vprintf(format, arglist); 75 | va_end(arglist); 76 | } 77 | 78 | static void rumble(unsigned short controllerNumber, unsigned short lowFreqMotor, unsigned short highFreqMotor) { 79 | if (rumble_handler) 80 | rumble_handler(controllerNumber, lowFreqMotor, highFreqMotor); 81 | } 82 | 83 | static void rumble_triggers(unsigned short controllerNumber, unsigned short leftTrigger, unsigned short rightTrigger) { 84 | if (rumble_handler) 85 | rumble_triggers_handler(controllerNumber, leftTrigger, rightTrigger); 86 | } 87 | 88 | static void set_motion_event_state(unsigned short controllerNumber, unsigned char motionType, unsigned short reportRateHz) { 89 | if (set_motion_event_state_handler) 90 | set_motion_event_state_handler(controllerNumber, motionType, reportRateHz); 91 | } 92 | 93 | static void set_controller_led(unsigned short controllerNumber, unsigned char r, unsigned char g, unsigned char b) { 94 | if (set_controller_led_handler) 95 | set_controller_led_handler(controllerNumber, r, g, b); 96 | } 97 | 98 | static void connection_status_update(int status) { 99 | switch (status) { 100 | case CONN_STATUS_OKAY: 101 | printf("Connection is okay\n"); 102 | break; 103 | case CONN_STATUS_POOR: 104 | printf("Connection is poor\n"); 105 | break; 106 | } 107 | } 108 | 109 | CONNECTION_LISTENER_CALLBACKS connection_callbacks = { 110 | .stageStarting = NULL, 111 | .stageComplete = NULL, 112 | .stageFailed = NULL, 113 | .connectionStarted = NULL, 114 | .connectionTerminated = connection_terminated, 115 | .logMessage = connection_log_message, 116 | .rumble = rumble, 117 | .connectionStatusUpdate = connection_status_update, 118 | .setHdrMode = NULL, 119 | .rumbleTriggers = rumble_triggers, 120 | .setMotionEventState = set_motion_event_state, 121 | .setControllerLED = set_controller_led, 122 | }; 123 | 124 | #endif 125 | -------------------------------------------------------------------------------- /src/connection_main.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Moonlight Embedded. 3 | * 4 | * Copyright (C) 2015-2017 Iwan Timmer 5 | * 6 | * Moonlight is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Moonlight is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Moonlight; if not, see . 18 | */ 19 | 20 | #ifndef __3DS__ 21 | 22 | #include 23 | 24 | #include 25 | #include 26 | 27 | extern CONNECTION_LISTENER_CALLBACKS connection_callbacks; 28 | extern pthread_t main_thread_id; 29 | extern bool connection_debug; 30 | extern ConnListenerRumble rumble_handler; 31 | extern ConnListenerRumbleTriggers rumble_triggers_handler; 32 | extern ConnListenerSetMotionEventState set_motion_event_state_handler; 33 | extern ConnListenerSetControllerLED set_controller_led_handler; 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /src/cpu.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Moonlight Embedded. 3 | * 4 | * Moonlight is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * Moonlight is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with Moonlight; if not, see . 16 | */ 17 | 18 | #include "cpu.h" 19 | #include "util.h" 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #ifdef HAVE_GETAUXVAL 27 | #include 28 | 29 | #ifndef HWCAP2_AES 30 | #define HWCAP2_AES (1 << 0) 31 | #endif 32 | #endif 33 | 34 | #if defined(__linux__) && defined(__riscv) 35 | #if __has_include() 36 | #include 37 | #else 38 | #include 39 | 40 | #if __has_include() 41 | #include 42 | #include 43 | #else 44 | #define __NR_riscv_hwprobe 258 45 | struct riscv_hwprobe { 46 | int64_t key; 47 | uint64_t value; 48 | }; 49 | #define RISCV_HWPROBE_KEY_IMA_EXT_0 4 50 | #endif 51 | 52 | // RISC-V Scalar AES [E]ncryption and [D]ecryption 53 | #ifndef RISCV_HWPROBE_EXT_ZKND 54 | #define RISCV_HWPROBE_EXT_ZKND (1 << 11) 55 | #define RISCV_HWPROBE_EXT_ZKNE (1 << 12) 56 | #endif 57 | 58 | // RISC-V Vector AES 59 | #ifndef RISCV_HWPROBE_EXT_ZVKNED 60 | #define RISCV_HWPROBE_EXT_ZVKNED (1 << 21) 61 | #endif 62 | 63 | static int __riscv_hwprobe(struct riscv_hwprobe *pairs, size_t pair_count, 64 | size_t cpu_count, unsigned long *cpus, 65 | unsigned int flags) 66 | { 67 | return syscall(__NR_riscv_hwprobe, pairs, pair_count, cpu_count, cpus, flags); 68 | } 69 | 70 | #endif 71 | #endif 72 | 73 | bool has_fast_aes() { 74 | #if defined(HAVE_GETAUXVAL) && (defined(__arm__) || defined(__aarch64__)) 75 | #if defined(__arm__) && defined(HWCAP2_AES) 76 | return !!(getauxval(AT_HWCAP2) & HWCAP2_AES); 77 | #elif defined(__aarch64__) 78 | return !!(getauxval(AT_HWCAP) & HWCAP_AES); 79 | #else 80 | return false; 81 | #endif 82 | #elif defined(HAVE_BICS_AES) 83 | return __builtin_cpu_supports("aes"); 84 | #elif defined(__BUILTIN_CPU_SUPPORTS__) && defined(__powerpc__) 85 | return __builtin_cpu_supports("vcrypto"); 86 | #elif defined(__linux__) && defined(__riscv) 87 | struct riscv_hwprobe pairs[1] = { 88 | { RISCV_HWPROBE_KEY_IMA_EXT_0, 0 }, 89 | }; 90 | 91 | // If this syscall is not implemented, we'll get -ENOSYS 92 | // and the value field will remain zero. 93 | __riscv_hwprobe(pairs, sizeof(pairs) / sizeof(struct riscv_hwprobe), 0, NULL, 0); 94 | 95 | return (pairs[0].value & (RISCV_HWPROBE_EXT_ZKNE | RISCV_HWPROBE_EXT_ZKND)) == 96 | (RISCV_HWPROBE_EXT_ZKNE | RISCV_HWPROBE_EXT_ZKND) || 97 | (pairs[0].value & RISCV_HWPROBE_EXT_ZVKNED); 98 | #elif __SIZEOF_SIZE_T__ == 4 99 | #warning Unknown 32-bit platform. Assuming AES is slow on this CPU. 100 | return false; 101 | #else 102 | #warning Unknown 64-bit platform. Assuming AES is fast on this CPU. 103 | return true; 104 | #endif 105 | } 106 | 107 | bool has_slow_aes() { 108 | #ifdef __arm__ 109 | char cpuinfo[4096] = {}; 110 | if (read_file("/proc/cpuinfo", cpuinfo, sizeof(cpuinfo) - 1) > 0) { 111 | // If this is a ARMv6 CPU (like the Pi 1), we'll assume it's not 112 | // powerful enough to handle audio encryption. The Pi 1 could 113 | // barely handle Opus decoding alone. 114 | if (strstr(cpuinfo, "ARMv6")) { 115 | return true; 116 | } 117 | } 118 | #endif 119 | 120 | return false; 121 | } -------------------------------------------------------------------------------- /src/cpu.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Moonlight Embedded. 3 | * 4 | * Moonlight is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * Moonlight is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with Moonlight; if not, see . 16 | */ 17 | 18 | #include 19 | 20 | bool has_fast_aes(void); 21 | bool has_slow_aes(void); 22 | -------------------------------------------------------------------------------- /src/input/cec.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Moonlight Embedded. 3 | * 4 | * Copyright (C) 2015-2017 Iwan Timmer 5 | * 6 | * Moonlight is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Moonlight is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Moonlight; if not, see . 18 | */ 19 | 20 | #ifndef __3DS__ 21 | 22 | #include 23 | 24 | #include 25 | 26 | #define KEY_LEFT 0x25 27 | #define KEY_UP 0x26 28 | #define KEY_RIGHT 0x27 29 | #define KEY_DOWN 0x28 30 | #define KEY_ENTER 0x0D 31 | #define KEY_TAB 0x09 32 | #define KEY_ESC 0x1B 33 | 34 | static libcec_configuration g_config; 35 | static char g_strPort[50] = { 0 }; 36 | static libcec_interface_t g_iface; 37 | static ICECCallbacks g_callbacks; 38 | 39 | static void on_cec_keypress(void* userdata, const cec_keypress* key) { 40 | char value; 41 | switch (key->keycode) { 42 | case CEC_USER_CONTROL_CODE_UP: 43 | value = KEY_UP; 44 | break; 45 | case CEC_USER_CONTROL_CODE_DOWN: 46 | value = KEY_DOWN; 47 | break; 48 | case CEC_USER_CONTROL_CODE_LEFT: 49 | value = KEY_LEFT; 50 | break; 51 | case CEC_USER_CONTROL_CODE_RIGHT: 52 | value = KEY_RIGHT; 53 | break; 54 | case CEC_USER_CONTROL_CODE_ENTER: 55 | case CEC_USER_CONTROL_CODE_SELECT: 56 | value = KEY_ENTER; 57 | break; 58 | case CEC_USER_CONTROL_CODE_ROOT_MENU: 59 | value = KEY_TAB; 60 | break; 61 | case CEC_USER_CONTROL_CODE_AN_RETURN: 62 | case CEC_USER_CONTROL_CODE_EXIT: 63 | value = KEY_ESC; 64 | break; 65 | default: 66 | value = 0; 67 | break; 68 | } 69 | 70 | if (value != 0) { 71 | short code = 0x80 << 8 | value; 72 | LiSendKeyboardEvent(code, (key->duration > 0)?KEY_ACTION_UP:KEY_ACTION_DOWN, 0); 73 | } 74 | } 75 | 76 | void cec_init() { 77 | libcecc_reset_configuration(&g_config); 78 | g_config.clientVersion = LIBCEC_VERSION_CURRENT; 79 | g_config.bActivateSource = 0; 80 | g_callbacks.keyPress = &on_cec_keypress; 81 | g_config.callbacks = &g_callbacks; 82 | snprintf(g_config.strDeviceName, sizeof(g_config.strDeviceName), "Moonlight"); 83 | g_config.callbacks = &g_callbacks; 84 | g_config.deviceTypes.types[0] = CEC_DEVICE_TYPE_PLAYBACK_DEVICE; 85 | 86 | if (libcecc_initialise(&g_config, &g_iface, NULL) != 1) { 87 | fprintf(stderr, "Failed to initialize libcec interface\n"); 88 | fflush(stderr); 89 | return; 90 | } 91 | 92 | g_iface.init_video_standalone(g_iface.connection); 93 | 94 | cec_adapter devices[10]; 95 | int8_t iDevicesFound = g_iface.find_adapters(g_iface.connection, devices, sizeof(devices) / sizeof(devices[0]), NULL); 96 | 97 | if (iDevicesFound <= 0) { 98 | fprintf(stderr, "No CEC devices found\n"); 99 | fflush(stderr); 100 | libcecc_destroy(&g_iface); 101 | return; 102 | } 103 | 104 | strcpy(g_strPort, devices[0].comm); 105 | if (!g_iface.open(g_iface.connection, g_strPort, 5000)) { 106 | fprintf(stderr, "Unable to open the device on port %s\n", g_strPort); 107 | fflush(stderr); 108 | libcecc_destroy(&g_iface); 109 | return; 110 | } 111 | 112 | g_iface.set_active_source(g_iface.connection, g_config.deviceTypes.types[0]); 113 | } 114 | 115 | #endif 116 | -------------------------------------------------------------------------------- /src/input/cec.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Moonlight Embedded. 3 | * 4 | * Copyright (C) 2015 Iwan Timmer 5 | * 6 | * Moonlight is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Moonlight is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Moonlight; if not, see . 18 | */ 19 | 20 | void cec_init(); 21 | -------------------------------------------------------------------------------- /src/input/evdev.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Moonlight Embedded. 3 | * 4 | * Copyright (C) 2015-2017 Iwan Timmer 5 | * 6 | * Moonlight is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Moonlight is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Moonlight; if not, see . 18 | */ 19 | 20 | #include "mapping.h" 21 | 22 | extern int evdev_gamepads; 23 | 24 | void evdev_create(const char* device, struct mapping* mappings, bool verbose, int rotate); 25 | void evdev_loop(); 26 | 27 | void evdev_init(bool mouse_emulation_enabled); 28 | void evdev_start(); 29 | void evdev_stop(); 30 | void evdev_map(char* device); 31 | void evdev_rumble(unsigned short controller_id, unsigned short low_freq_motor, unsigned short high_freq_motor); 32 | -------------------------------------------------------------------------------- /src/input/keyboard.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Moonlight Embedded. 3 | * 4 | * Copyright (C) 2015 Iwan Timmer 5 | * 6 | * Moonlight is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Moonlight is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Moonlight; if not, see . 18 | */ 19 | 20 | static const short keyCodes[] = { 21 | 0, //VK_RESERVED 22 | 0x1B, //VK_ESCAPE 23 | 0x31, //VK_1 24 | 0x32, //VK_2 25 | 0x33, //VK_3 26 | 0x34, //VK_4 27 | 0x35, //VK_5 28 | 0x36, //VK_6 29 | 0x37, //VK_7 30 | 0x38, //VK_8 31 | 0x39, //VK_9 32 | 0x30, //VK_0 33 | 0xBD, //VK_MINUS 34 | 0xBB, //VK_EQUALS 35 | 0x08, //VK_BACK_SPACE 36 | 0x09, //VK_TAB 37 | 0x51, //VK_Q 38 | 0x57, //VK_W 39 | 0x45, //VK_E 40 | 0x52, //VK_R 41 | 0x54, //VK_T 42 | 0x59, //VK_Y 43 | 0x55, //VK_U 44 | 0x49, //VK_I 45 | 0x4F, //VK_O 46 | 0x50, //VK_P 47 | 0xDB, //VK_BRACELEFT 48 | 0xDD, //VK_BRACERIGHT 49 | 0x0D, //VK_ENTER 50 | 0xA2, //VK_CONTROL Left control 51 | 0x41, //VK_A 52 | 0x53, //VK_S 53 | 0x44, //VK_D 54 | 0x46, //VK_F 55 | 0x47, //VK_G 56 | 0x48, //VK_H 57 | 0x4A, //VK_J 58 | 0x4B, //VK_K 59 | 0x4C, //VK_L 60 | 0xBA, //VK_SEMICOLON 61 | 0xDE, //VK_APOSTROPHE 62 | 0xC0, //VK_GRAVE 63 | 0xA0, //VK_SHIFT Left shift 64 | 0xDC, //VK_BACK_SLASH 65 | 0x5A, //VK_Z 66 | 0x58, //VK_X 67 | 0x43, //VK_C 68 | 0x56, //VK_V 69 | 0x42, //VK_B 70 | 0x4E, //VK_N 71 | 0x4D, //VK_M 72 | 0xBC, //VK_COMMA 73 | 0xBE, //VK_DOT 74 | 0xBF, //VK_SLASH 75 | 0xA1, //VK_SHIFT Right shift 76 | 0x6A, //VK_KPASTERISK 77 | 0xA4, //VK_ALT Left alt 78 | 0x20, //VK_SPACE 79 | 0x14, //VK_CAPS_LOCK 80 | 0x70, //VK_F1 81 | 0x71, //VK_F2 82 | 0x72, //VK_F3 83 | 0x73, //VK_F4 84 | 0x74, //VK_F5 85 | 0x75, //VK_F6 86 | 0x76, //VK_F7 87 | 0x77, //VK_F8 88 | 0x78, //VK_F9 89 | 0x79, //VK_F10 90 | 0x90, //VK_NUM_LOCK 91 | 0x91, //VK_SCROLL_LOCK 92 | 0x67, //VK_NUMPAD7 93 | 0x68, //VK_NUMPAD8 94 | 0x69, //VK_NUMPAD9 95 | 0x6D, //VK_NUMPAD_MINUS 96 | 0x64, //VK_NUMPAD4 97 | 0x65, //VK_NUMPAD5 98 | 0x66, //VK_NUMPAD6 99 | 0x6B, //VK_NUMPADPLUS 100 | 0x61, //VK_NUMPAD1 101 | 0x62, //VK_NUMPAD2 102 | 0x63, //VK_NUMPAD3 103 | 0x60, //VK_NUMPAD0 104 | 0x6E, //KeyEvent.VK_NUMPADDOT 105 | 0, 106 | 0, //KeyEvent.VK_ZENKAKUHANKAKU 107 | 0, //KeyEvent.VK_102ND 108 | 0x7A, //VK_F11 109 | 0x7B, //VK_F12 110 | 0, //KeyEvent.VK_RO 111 | 0xF1, //VK_KATAKANA 112 | 0xF2, //VK_HIRAGANA 113 | 0, //VK_HENKAN 114 | 0, //VK_KATAKANAHIRAGANA 115 | 0, //VK_MUHENKAN 116 | 0, //VK_KPJPCOMMA 117 | 0x0D, //VK_KPENTER 118 | 0xA3, //VK_CONTROL Right ctrl 119 | 0x6F, //VK_KPSLASH 120 | 0x2C, //VK_SYSRQ 121 | 0xA5, //VK_ALT Right alt 122 | 0, //KeyEvent.VK_LINEFEED 123 | 0x24, //VK_HOME 124 | 0x26, //VK_UP 125 | 0x21, //VK_PAGE_UP 126 | 0x25, //VK_LEFT 127 | 0x27, //VK_RIGHT 128 | 0x23, //VK_END 129 | 0x28, //VK_DOWN 130 | 0x22, //VK_PAGE_DOWN 131 | 0x2D, //VK_INSERT 132 | 0x2E, //VK_DELETE 133 | 0, //VK_MACRO 134 | 0, //VK_MUTE 135 | 0, //VK_VOLUMEDOWN 136 | 0, //VK_VOLUMEUP 137 | 0, //VK_POWER SC System Power Down 138 | 0, //VK_KPEQUAL 139 | 0, //VK_KPPLUSMINUS 140 | 0x13, //VK_PAUSE 141 | 0, //VK_SCALE AL Compiz Scale (Expose) 142 | 0, //KEY_KPCOMMA 143 | 0, //KEY_HANGEUL 144 | 0, //KEY_HANJA 145 | 0, //KEY_YEN 146 | 0x5B, //KEY_LEFTMETA 147 | 0x5C, //KEY_RIGHTMETA 148 | 0, //KEY_COMPOSE 149 | }; 150 | -------------------------------------------------------------------------------- /src/input/mapping.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Moonlight Embedded. 3 | * 4 | * Copyright (C) 2015-2017 Iwan Timmer 5 | * 6 | * Moonlight is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Moonlight is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Moonlight; if not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #include 23 | 24 | struct mapping { 25 | char guid[33]; 26 | char platform[33]; 27 | char name[257]; 28 | 29 | bool reverse_leftx, reverse_lefty; 30 | bool reverse_rightx, reverse_righty; 31 | char halfaxis_lefttrigger, halfaxis_righttrigger; 32 | char halfaxis_dpright, halfaxis_dpleft; 33 | char halfaxis_dpup, halfaxis_dpdown; 34 | 35 | /* abs_leftx must be the first member of the list of mapping indices! */ 36 | short abs_leftx, abs_lefty; 37 | short abs_rightx, abs_righty; 38 | 39 | short hat_dpright, hat_dpleft, hat_dpup, hat_dpdown; 40 | short hat_dir_dpright, hat_dir_dpleft, hat_dir_dpup, hat_dir_dpdown; 41 | short btn_dpup, btn_dpdown, btn_dpleft, btn_dpright; 42 | short abs_dpright, abs_dpleft, abs_dpup, abs_dpdown; 43 | 44 | short btn_a, btn_x, btn_y, btn_b; 45 | short btn_back, btn_start, btn_guide; 46 | short btn_leftstick, btn_rightstick; 47 | short btn_leftshoulder, btn_rightshoulder; 48 | short btn_misc1; 49 | short btn_paddle1, btn_paddle2, btn_paddle3, btn_paddle4; 50 | short btn_touchpad; 51 | 52 | short abs_lefttrigger, abs_righttrigger; 53 | short btn_lefttrigger, btn_righttrigger; 54 | 55 | /* next must be the last member after the list of mapping indices! */ 56 | struct mapping* next; 57 | }; 58 | 59 | struct mapping* mapping_parse(char* mapping); 60 | struct mapping* mapping_load(char* fileName, bool verbose); 61 | void mapping_print(struct mapping*); 62 | -------------------------------------------------------------------------------- /src/input/n3ds/AbsoluteTouchHandler.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Moonlight Embedded. 3 | * 4 | * Copyright (C) 2015-2017 Iwan Timmer 5 | * 6 | * Moonlight is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Moonlight is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Moonlight; if not, see . 18 | */ 19 | 20 | #include "N3dsTouchscreenInput.hpp" 21 | #include 22 | 23 | void AbsoluteTouchHandler::_handle_touch_down(touchPosition touch) { 24 | LiSendMousePositionEvent(touch.px, touch.py + y_offset, 25 | GSP_SCREEN_HEIGHT_BOTTOM, 26 | y_scale * GSP_SCREEN_WIDTH); 27 | LiSendMouseButtonEvent(BUTTON_ACTION_PRESS, BUTTON_LEFT); 28 | } 29 | 30 | void AbsoluteTouchHandler::_handle_touch_up(touchPosition touch) { 31 | LiSendMouseButtonEvent(BUTTON_ACTION_RELEASE, BUTTON_LEFT); 32 | } 33 | 34 | void AbsoluteTouchHandler::_handle_touch_hold(touchPosition touch) { 35 | LiSendMousePositionEvent(touch.px, touch.py + y_offset, 36 | GSP_SCREEN_HEIGHT_BOTTOM, 37 | y_scale * GSP_SCREEN_WIDTH); 38 | } 39 | -------------------------------------------------------------------------------- /src/input/n3ds/GamepadTouchHandler.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Moonlight Embedded. 3 | * 4 | * Copyright (C) 2015-2017 Iwan Timmer 5 | * 6 | * Moonlight is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Moonlight is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Moonlight; if not, see . 18 | */ 19 | 20 | #include "N3dsTouchscreenInput.hpp" 21 | #include "gamepad_bgr.h" 22 | #include 23 | #include 24 | 25 | GamepadTouchHandler::GamepadTouchHandler(GAMEPAD_STATE *gamepad_in) 26 | : gamepad_state(gamepad_in) { 27 | u8 *gfxbtmadr = gfxGetFramebuffer(GFX_BOTTOM, GFX_LEFT, NULL, NULL); 28 | 29 | memcpy(gfxbtmadr, gamepad_bgr, gamepad_bgr_size); 30 | 31 | gfxFlushBuffers(); 32 | gfxScreenSwapBuffers(GFX_BOTTOM, false); 33 | } 34 | 35 | void GamepadTouchHandler::_handle_touch_down(touchPosition touch) { 36 | if (touch.py >= 120) { 37 | gamepad_state->buttons |= SPECIAL_FLAG; 38 | return; 39 | } 40 | 41 | if (touch.px < 235) 42 | gamepad_state->buttons |= LS_CLK_FLAG; 43 | if (touch.px > 104) 44 | gamepad_state->buttons |= RS_CLK_FLAG; 45 | } 46 | 47 | void GamepadTouchHandler::_handle_touch_up(touchPosition touch) { 48 | gamepad_state->buttons &= ~(SPECIAL_FLAG | LS_CLK_FLAG | RS_CLK_FLAG); 49 | } 50 | 51 | void GamepadTouchHandler::_handle_touch_hold(touchPosition touch) { 52 | gamepad_state->buttons &= ~(SPECIAL_FLAG | LS_CLK_FLAG | RS_CLK_FLAG); 53 | 54 | if (touch.py >= 120) { 55 | gamepad_state->buttons |= SPECIAL_FLAG; 56 | return; 57 | } 58 | 59 | if (touch.px < 235) 60 | gamepad_state->buttons |= LS_CLK_FLAG; 61 | if (touch.px > 104) 62 | gamepad_state->buttons |= RS_CLK_FLAG; 63 | } 64 | -------------------------------------------------------------------------------- /src/input/n3ds/MouseTouchHandler.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Moonlight Embedded. 3 | * 4 | * Copyright (C) 2015-2017 Iwan Timmer 5 | * 6 | * Moonlight is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Moonlight is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Moonlight; if not, see . 18 | */ 19 | 20 | #include "N3dsTouchscreenInput.hpp" 21 | #include "touchpad_bgr.h" 22 | #include 23 | #include 24 | 25 | #define N3DS_MOUSEPAD_SENSITIVITY 3 26 | 27 | MouseTouchHandler::MouseTouchHandler() { 28 | u8 *gfxbtmadr = gfxGetFramebuffer(GFX_BOTTOM, GFX_LEFT, NULL, NULL); 29 | 30 | memcpy(gfxbtmadr, touchpad_bgr, touchpad_bgr_size); 31 | 32 | gfxFlushBuffers(); 33 | gfxScreenSwapBuffers(GFX_BOTTOM, false); 34 | } 35 | 36 | void MouseTouchHandler::_handle_touch_down(touchPosition touch) { 37 | if (touch.py < 175) { 38 | previous_x = touch.px; 39 | previous_y = touch.py; 40 | if (touch.px > 285) { 41 | v_scroll = true; 42 | } else if (touch.py < 35) { 43 | h_scroll = true; 44 | } 45 | } else if (touch.px > 160) { 46 | mouse_button = BUTTON_RIGHT; 47 | LiSendMouseButtonEvent(BUTTON_ACTION_PRESS, BUTTON_RIGHT); 48 | } else { 49 | mouse_button = BUTTON_LEFT; 50 | LiSendMouseButtonEvent(BUTTON_ACTION_PRESS, BUTTON_LEFT); 51 | } 52 | } 53 | 54 | void MouseTouchHandler::_handle_touch_up(touchPosition touch) { 55 | if (mouse_button > -1) { 56 | LiSendMouseButtonEvent(BUTTON_ACTION_RELEASE, mouse_button); 57 | } 58 | mouse_button = -1; 59 | previous_x = -1; 60 | previous_y = -1; 61 | v_scroll = false; 62 | h_scroll = false; 63 | } 64 | 65 | void MouseTouchHandler::_handle_touch_hold(touchPosition touch) { 66 | if (previous_x == -1) { 67 | return; 68 | } 69 | short deltaX = touch.px - previous_x; 70 | short deltaY = touch.py - previous_y; 71 | previous_x = touch.px; 72 | previous_y = touch.py; 73 | 74 | if (v_scroll) { 75 | LiSendScrollEvent(-1 * deltaY); 76 | } else if (h_scroll) { 77 | LiSendHScrollEvent(deltaX); 78 | } else { 79 | LiSendMouseMoveEvent(N3DS_MOUSEPAD_SENSITIVITY * deltaX, 80 | N3DS_MOUSEPAD_SENSITIVITY * deltaY); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/input/n3ds/N3dsTouchscreenInput.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Moonlight Embedded. 3 | * 4 | * Copyright (C) 2015-2017 Iwan Timmer 5 | * 6 | * Moonlight is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Moonlight is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Moonlight; if not, see . 18 | */ 19 | 20 | #include "N3dsTouchscreenInput.hpp" 21 | 22 | N3dsTouchscreenInput::N3dsTouchscreenInput(GAMEPAD_STATE *gamepad_in, 23 | N3dsTouchType touch_type_in) 24 | : gamepad_state(gamepad_in), touch_type(touch_type_in) { 25 | init_touch_handler(); 26 | }; 27 | 28 | inline bool N3dsTouchscreenInput::next_touchpad_pressed(touchPosition touch) { 29 | if (touch_type == DISABLED || touch_type == ABSOLUTE_TOUCH || 30 | touch_type == DS_TOUCH) { 31 | return false; 32 | } 33 | if (touch.py >= 205 && touch.px >= 285) { 34 | switch (touch_type) { 35 | case GAMEPAD: 36 | touch_type = MOUSEPAD; 37 | break; 38 | case MOUSEPAD: 39 | touch_type = KEYBOARD; 40 | break; 41 | case KEYBOARD: 42 | touch_type = GAMEPAD; 43 | break; 44 | } 45 | init_touch_handler(); 46 | return true; 47 | } 48 | return false; 49 | } 50 | 51 | inline bool 52 | N3dsTouchscreenInput::previous_touchpad_pressed(touchPosition touch) { 53 | if (touch_type == DISABLED || touch_type == ABSOLUTE_TOUCH || 54 | touch_type == DS_TOUCH) { 55 | return false; 56 | } 57 | 58 | if (touch.py >= 205 && touch.px <= 35) { 59 | switch (touch_type) { 60 | case GAMEPAD: 61 | touch_type = KEYBOARD; 62 | break; 63 | case MOUSEPAD: 64 | touch_type = GAMEPAD; 65 | break; 66 | case KEYBOARD: 67 | touch_type = MOUSEPAD; 68 | break; 69 | } 70 | init_touch_handler(); 71 | return true; 72 | } 73 | return false; 74 | } 75 | 76 | inline void N3dsTouchscreenInput::init_touch_handler() { 77 | switch (touch_type) { 78 | case GAMEPAD: 79 | handler = std::make_unique(gamepad_state); 80 | break; 81 | case MOUSEPAD: 82 | handler = std::make_unique(); 83 | break; 84 | case KEYBOARD: 85 | handler = std::make_unique(); 86 | break; 87 | case ABSOLUTE_TOUCH: 88 | handler = std::make_unique(0, 1); 89 | break; 90 | case DS_TOUCH: 91 | handler = std::make_unique(GSP_SCREEN_WIDTH, 2); 92 | break; 93 | default: 94 | handler = nullptr; 95 | break; 96 | } 97 | } 98 | 99 | void N3dsTouchscreenInput::n3dsinput_handle_touch(u32 kDown, u32 kUp) { 100 | if (!handler) { 101 | return; 102 | } 103 | 104 | touchPosition touch; 105 | hidTouchRead(&touch); 106 | if (kDown & KEY_TOUCH) { 107 | if (!next_touchpad_pressed(touch) && 108 | !previous_touchpad_pressed(touch)) { 109 | handler->handle_touch_down(touch); 110 | } 111 | } else if (kUp & KEY_TOUCH) { 112 | handler->handle_touch_up(touch); 113 | } else { 114 | handler->handle_touch_hold(touch); 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /src/input/n3ds/N3dsTouchscreenInput.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Moonlight Embedded. 3 | * 4 | * Copyright (C) 2015-2017 Iwan Timmer 5 | * 6 | * Moonlight is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Moonlight is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Moonlight; if not, see . 18 | */ 19 | 20 | #include "keycode_map.hpp" 21 | #include <3ds.h> 22 | #include 23 | 24 | enum N3dsTouchType { 25 | DISABLED, 26 | GAMEPAD, 27 | MOUSEPAD, 28 | KEYBOARD, 29 | ABSOLUTE_TOUCH, 30 | DS_TOUCH 31 | }; 32 | typedef struct _GAMEPAD_STATE { 33 | unsigned char leftTrigger, rightTrigger; 34 | short leftStickX, leftStickY; 35 | short rightStickX, rightStickY; 36 | int buttons; 37 | float accel_vector_x, accel_vector_y, accel_vector_z; 38 | float gyro_rate_x, gyro_rate_y, gyro_rate_z; 39 | } GAMEPAD_STATE; 40 | 41 | class TouchHandlerBase { 42 | public: 43 | void handle_touch_down(touchPosition touch); 44 | void handle_touch_up(touchPosition touch); 45 | void handle_touch_hold(touchPosition touch); 46 | 47 | private: 48 | virtual void _handle_touch_down(touchPosition touch) = 0; 49 | virtual void _handle_touch_up(touchPosition touch) = 0; 50 | virtual void _handle_touch_hold(touchPosition touch) = 0; 51 | 52 | private: 53 | bool isActive = false; 54 | }; 55 | 56 | class GamepadTouchHandler : public TouchHandlerBase { 57 | public: 58 | GamepadTouchHandler(GAMEPAD_STATE *gamepad_in); 59 | 60 | private: 61 | void _handle_touch_down(touchPosition touch); 62 | void _handle_touch_up(touchPosition touch); 63 | void _handle_touch_hold(touchPosition touch); 64 | 65 | private: 66 | GAMEPAD_STATE *gamepad_state; 67 | }; 68 | 69 | class MouseTouchHandler : public TouchHandlerBase { 70 | public: 71 | MouseTouchHandler(); 72 | 73 | private: 74 | void _handle_touch_down(touchPosition touch); 75 | void _handle_touch_up(touchPosition touch); 76 | void _handle_touch_hold(touchPosition touch); 77 | 78 | private: 79 | int mouse_button = -1; 80 | int previous_x = 0; 81 | int previous_y = 0; 82 | bool v_scroll = false; 83 | bool h_scroll = false; 84 | }; 85 | 86 | enum KeyState { KEY_DISABLED, KEY_TEMPORARY, KEY_LOCKED, KEY_SHIFT }; 87 | struct KeyInfo { 88 | KeyState state = KEY_DISABLED; 89 | int min_x; 90 | int max_x; 91 | int min_y; 92 | int max_y; 93 | }; 94 | 95 | class KeyboardTouchHandler : public TouchHandlerBase { 96 | public: 97 | KeyboardTouchHandler(); 98 | 99 | private: 100 | void _handle_touch_down(touchPosition touch); 101 | void _handle_touch_up(touchPosition touch); 102 | void _handle_touch_hold(touchPosition touch); 103 | 104 | keycode_info get_keycode(touchPosition touch); 105 | void set_screen(const uint8_t *bgr_buffer, int bgr_size); 106 | void set_screen_key(KeyInfo &key_info); 107 | void set_shift_keys(); 108 | void handle_default(); 109 | void cycle_key_state(KeyInfo &key_info); 110 | void handle_alt_keyboard(); 111 | int get_key_mod(); 112 | 113 | private: 114 | int key_px_size; 115 | keycode_info active_keycode{-1, false}; 116 | KeyInfo shift_info = {KEY_DISABLED, 0, 48, 136, 169}; 117 | KeyInfo ctrl_info = {KEY_DISABLED, 64, 127, 0, 37}; 118 | KeyInfo alt_info = {KEY_DISABLED, 128, 192, 0, 37}; 119 | KeyInfo shift_keys = {KEY_SHIFT, 0, GSP_SCREEN_HEIGHT_BOTTOM, 37, 70}; 120 | bool alt_keyboard_active = false; 121 | std::map *selected_keycodes = nullptr; 122 | }; 123 | 124 | class AbsoluteTouchHandler : public TouchHandlerBase { 125 | public: 126 | AbsoluteTouchHandler(int y_offset_in, int y_scale_in) 127 | : y_offset(y_offset_in), y_scale(y_scale_in){}; 128 | 129 | private: 130 | void _handle_touch_down(touchPosition touch); 131 | void _handle_touch_up(touchPosition touch); 132 | void _handle_touch_hold(touchPosition touch); 133 | 134 | private: 135 | int y_offset = 0; 136 | int y_scale = 1; 137 | int previous_x = 0; 138 | int previous_y = 0; 139 | }; 140 | 141 | class N3dsTouchscreenInput { 142 | public: 143 | N3dsTouchscreenInput(GAMEPAD_STATE *gamepad_in, 144 | N3dsTouchType touch_type_in); 145 | ~N3dsTouchscreenInput() = default; 146 | 147 | void n3dsinput_handle_touch(u32 kDown, u32 kUp); 148 | 149 | private: 150 | inline void init_touch_handler(); 151 | inline void n3dsinput_set_touch(enum N3dsTouchType ttype); 152 | inline bool next_touchpad_pressed(touchPosition touch); 153 | inline bool previous_touchpad_pressed(touchPosition touch); 154 | 155 | private: 156 | GAMEPAD_STATE *gamepad_state; 157 | N3dsTouchType touch_type; 158 | std::unique_ptr handler = nullptr; 159 | }; 160 | -------------------------------------------------------------------------------- /src/input/n3ds/TouchHandlerBase.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Moonlight Embedded. 3 | * 4 | * Copyright (C) 2015-2017 Iwan Timmer 5 | * 6 | * Moonlight is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Moonlight is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Moonlight; if not, see . 18 | */ 19 | 20 | #include "N3dsTouchscreenInput.hpp" 21 | 22 | void TouchHandlerBase::handle_touch_down(touchPosition touch) { 23 | isActive = true; 24 | _handle_touch_down(touch); 25 | } 26 | 27 | void TouchHandlerBase::handle_touch_up(touchPosition touch) { 28 | isActive = false; 29 | _handle_touch_up(touch); 30 | } 31 | 32 | void TouchHandlerBase::handle_touch_hold(touchPosition touch) { 33 | if (isActive) { 34 | _handle_touch_hold(touch); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/input/n3ds_input.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Moonlight Embedded. 3 | * 4 | * Copyright (C) 2015-2017 Iwan Timmer 5 | * 6 | * Moonlight is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Moonlight is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Moonlight; if not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #include "n3ds/N3dsTouchscreenInput.hpp" 23 | #include 24 | 25 | extern bool enable_gyro; 26 | extern bool enable_accel; 27 | 28 | void n3dsinput_init(N3dsTouchType touch_type, bool swap_face_buttons, 29 | bool swap_triggers_and_shoulders, 30 | bool use_triggers_for_mouse_in); 31 | void n3dsinput_cleanup(); 32 | void n3dsinput_set_touch(enum N3dsTouchType ttype); 33 | int n3dsinput_handle_event(); 34 | -------------------------------------------------------------------------------- /src/input/sdl.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Moonlight Embedded. 3 | * 4 | * Copyright (C) 2015-2017 Iwan Timmer 5 | * 6 | * Moonlight is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Moonlight is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Moonlight; if not, see . 18 | */ 19 | 20 | #include 21 | #include 22 | 23 | extern int sdl_gamepads; 24 | 25 | void sdlinput_init(char* mappings); 26 | int sdlinput_handle_event(SDL_Window* window, SDL_Event* event); 27 | void sdlinput_rumble(unsigned short controller_id, unsigned short low_freq_motor, unsigned short high_freq_motor); 28 | void sdlinput_rumble_triggers(unsigned short controller_id, unsigned short left_trigger, unsigned short right_trigger); 29 | void sdlinput_set_motion_event_state(unsigned short controller_id, unsigned char motion_type, unsigned short report_rate_hz); 30 | void sdlinput_set_controller_led(unsigned short controller_id, unsigned char r, unsigned char g, unsigned char b); 31 | -------------------------------------------------------------------------------- /src/input/udev.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Moonlight Embedded. 3 | * 4 | * Copyright (C) 2015-2017 Iwan Timmer 5 | * 6 | * Moonlight is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Moonlight is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Moonlight; if not, see . 18 | */ 19 | 20 | #ifndef __3DS__ 21 | 22 | #include "../loop.h" 23 | 24 | #include "udev.h" 25 | #include "evdev.h" 26 | 27 | #include 28 | 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | 36 | static bool autoadd, debug; 37 | static struct mapping* defaultMappings; 38 | 39 | static struct udev *udev; 40 | static struct udev_monitor *udev_mon; 41 | static int inputRotate; 42 | 43 | static int udev_handle(int fd) { 44 | struct udev_device *dev = udev_monitor_receive_device(udev_mon); 45 | const char *action = udev_device_get_action(dev); 46 | if (action != NULL) { 47 | if (autoadd && strcmp("add", action) == 0) { 48 | const char *devnode = udev_device_get_devnode(dev); 49 | int id; 50 | if (devnode != NULL && sscanf(devnode, "/dev/input/event%d", &id) == 1) { 51 | evdev_create(devnode, defaultMappings, debug, inputRotate); 52 | } 53 | } 54 | udev_device_unref(dev); 55 | } 56 | return LOOP_OK; 57 | } 58 | 59 | void udev_init(bool autoload, struct mapping* mappings, bool verbose, int rotate) { 60 | udev = udev_new(); 61 | debug = verbose; 62 | if (!udev) { 63 | fprintf(stderr, "Can't create udev\n"); 64 | exit(1); 65 | } 66 | 67 | autoadd = autoload; 68 | if (autoload) { 69 | struct udev_enumerate *enumerate = udev_enumerate_new(udev); 70 | udev_enumerate_add_match_subsystem(enumerate, "input"); 71 | udev_enumerate_scan_devices(enumerate); 72 | struct udev_list_entry *devices = udev_enumerate_get_list_entry(enumerate); 73 | 74 | struct udev_list_entry *dev_list_entry; 75 | udev_list_entry_foreach(dev_list_entry, devices) { 76 | const char *path = udev_list_entry_get_name(dev_list_entry); 77 | struct udev_device *dev = udev_device_new_from_syspath(udev, path); 78 | const char *devnode = udev_device_get_devnode(dev); 79 | int id; 80 | if (devnode != NULL && sscanf(devnode, "/dev/input/event%d", &id) == 1) { 81 | evdev_create(devnode, mappings, verbose, rotate); 82 | } 83 | udev_device_unref(dev); 84 | } 85 | 86 | udev_enumerate_unref(enumerate); 87 | } 88 | 89 | udev_mon = udev_monitor_new_from_netlink(udev, "udev"); 90 | udev_monitor_filter_add_match_subsystem_devtype(udev_mon, "input", NULL); 91 | udev_monitor_enable_receiving(udev_mon); 92 | 93 | defaultMappings = mappings; 94 | inputRotate = rotate; 95 | 96 | loop_add_fd(udev_monitor_get_fd(udev_mon), &udev_handle, POLLIN); 97 | } 98 | 99 | void udev_destroy() { 100 | loop_remove_fd(udev_monitor_get_fd(udev_mon)); 101 | udev_monitor_unref(udev_mon); 102 | udev_unref(udev); 103 | } 104 | 105 | #endif 106 | -------------------------------------------------------------------------------- /src/input/udev.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Moonlight Embedded. 3 | * 4 | * Copyright (C) 2015 Iwan Timmer 5 | * 6 | * Moonlight is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Moonlight is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Moonlight; if not, see . 18 | */ 19 | 20 | #include "mapping.h" 21 | 22 | void udev_init(bool autoload, struct mapping* mappings, bool verbose, int rotate); 23 | void udev_destroy(); 24 | -------------------------------------------------------------------------------- /src/input/x11.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Moonlight Embedded. 3 | * 4 | * Copyright (C) 2017 Iwan Timmer 5 | * 6 | * Moonlight is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Moonlight is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Moonlight; if not, see . 18 | */ 19 | 20 | #include 21 | 22 | void x11_input_init(Display* display, Window window); 23 | -------------------------------------------------------------------------------- /src/loop.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Moonlight Embedded. 3 | * 4 | * Copyright (C) 2015-2019 Iwan Timmer 5 | * 6 | * Moonlight is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Moonlight is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Moonlight; if not, see . 18 | */ 19 | 20 | #ifndef __3DS__ 21 | 22 | #include "loop.h" 23 | 24 | #include "connection_main.h" 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | 35 | static struct pollfd* fds = NULL; 36 | static FdHandler* fdHandlers = NULL; 37 | static int numFds = 0; 38 | 39 | static int sigFd; 40 | 41 | static int loop_sig_handler(int fd) { 42 | struct signalfd_siginfo info; 43 | if (read(fd, &info, sizeof(info)) != sizeof(info)) 44 | return LOOP_RETURN; 45 | switch (info.ssi_signo) { 46 | case SIGINT: 47 | case SIGTERM: 48 | case SIGQUIT: 49 | case SIGHUP: 50 | return LOOP_RETURN; 51 | } 52 | return LOOP_OK; 53 | } 54 | 55 | void loop_add_fd(int fd, FdHandler handler, int events) { 56 | int fdindex = numFds; 57 | numFds++; 58 | 59 | if (fds == NULL) { 60 | fds = malloc(sizeof(struct pollfd)); 61 | fdHandlers = malloc(sizeof(FdHandler*)); 62 | } else { 63 | fds = realloc(fds, sizeof(struct pollfd)*numFds); 64 | fdHandlers = realloc(fdHandlers, sizeof(FdHandler*)*numFds); 65 | } 66 | 67 | if (fds == NULL || fdHandlers == NULL) { 68 | fprintf(stderr, "Not enough memory\n"); 69 | exit(EXIT_FAILURE); 70 | } 71 | 72 | fds[fdindex].fd = fd; 73 | fds[fdindex].events = events; 74 | fdHandlers[fdindex] = handler; 75 | } 76 | 77 | void loop_remove_fd(int fd) { 78 | numFds--; 79 | int fdindex = numFds; 80 | 81 | for (int i=0;i<=numFds;i++) { 82 | if (fds[i].fd == fd) { 83 | fdindex = i; 84 | break; 85 | } 86 | } 87 | 88 | if (fdindex != numFds && numFds > 0) { 89 | memcpy(&fds[fdindex], &fds[numFds], sizeof(struct pollfd)); 90 | memcpy(&fdHandlers[fdindex], &fdHandlers[numFds], sizeof(FdHandler)); 91 | } 92 | } 93 | 94 | void loop_init() { 95 | main_thread_id = pthread_self(); 96 | sigset_t sigset; 97 | sigemptyset(&sigset); 98 | sigaddset(&sigset, SIGHUP); 99 | sigaddset(&sigset, SIGTERM); 100 | sigaddset(&sigset, SIGINT); 101 | sigaddset(&sigset, SIGQUIT); 102 | sigprocmask(SIG_BLOCK, &sigset, NULL); 103 | sigFd = signalfd(-1, &sigset, 0); 104 | loop_add_fd(sigFd, loop_sig_handler, POLLIN | POLLERR | POLLHUP); 105 | } 106 | 107 | void loop_main() { 108 | while (poll(fds, numFds, -1)) { 109 | for (int i=0;i 0) { 111 | int ret = fdHandlers[i](fds[i].fd); 112 | if (ret == LOOP_RETURN) { 113 | return; 114 | } 115 | } 116 | } 117 | } 118 | } 119 | 120 | #endif 121 | -------------------------------------------------------------------------------- /src/loop.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Moonlight Embedded. 3 | * 4 | * Copyright (C) 2015-2019 Iwan Timmer 5 | * 6 | * Moonlight is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Moonlight is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Moonlight; if not, see . 18 | */ 19 | 20 | #define LOOP_RETURN 1 21 | #define LOOP_OK 0 22 | 23 | typedef int(*FdHandler)(int fd); 24 | 25 | void loop_add_fd(int fd, FdHandler handler, int events); 26 | void loop_remove_fd(int fd); 27 | 28 | void loop_init(); 29 | void loop_main(); 30 | -------------------------------------------------------------------------------- /src/n3ds/compat_3ds.c: -------------------------------------------------------------------------------- 1 | #ifdef __3DS__ 2 | 3 | #include 4 | #include 5 | 6 | ssize_t 7 | getdelim(char **buf, size_t *bufsiz, int delimiter, FILE *fp) 8 | { 9 | char *ptr, *eptr; 10 | 11 | 12 | if (*buf == NULL || *bufsiz == 0) { 13 | *bufsiz = BUFSIZ; 14 | if ((*buf = malloc(*bufsiz)) == NULL) 15 | return -1; 16 | } 17 | 18 | for (ptr = *buf, eptr = *buf + *bufsiz;;) { 19 | int c = fgetc(fp); 20 | if (c == -1) { 21 | if (feof(fp)) 22 | return ptr == *buf ? -1 : ptr - *buf; 23 | else 24 | return -1; 25 | } 26 | *ptr++ = c; 27 | if (c == delimiter) { 28 | *ptr = '\0'; 29 | return ptr - *buf; 30 | } 31 | if (ptr + 2 >= eptr) { 32 | char *nbuf; 33 | size_t nbufsiz = *bufsiz * 2; 34 | ssize_t d = ptr - *buf; 35 | if ((nbuf = realloc(*buf, nbufsiz)) == NULL) 36 | return -1; 37 | *buf = nbuf; 38 | *bufsiz = nbufsiz; 39 | eptr = nbuf + nbufsiz; 40 | ptr = nbuf + d; 41 | } 42 | } 43 | } 44 | 45 | ssize_t 46 | getline(char **buf, size_t *bufsiz, FILE *fp) 47 | { 48 | return getdelim(buf, bufsiz, '\n', fp); 49 | } 50 | 51 | #endif 52 | -------------------------------------------------------------------------------- /src/n3ds/n3ds_connection.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Moonlight Embedded. 3 | * 4 | * Copyright (C) 2015-2017 Iwan Timmer 5 | * 6 | * Moonlight is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Moonlight is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Moonlight; if not, see . 18 | */ 19 | 20 | #include "n3ds_connection.hpp" 21 | #include "../input/n3ds_input.hpp" 22 | 23 | #include <3ds.h> 24 | #include 25 | #include 26 | #include 27 | 28 | bool n3ds_connection_closed = false; 29 | bool n3ds_connection_debug = false; 30 | bool n3ds_enable_motion = false; 31 | 32 | static void connection_terminated(int errorCode) { 33 | switch (errorCode) { 34 | case ML_ERROR_GRACEFUL_TERMINATION: 35 | printf("Connection has been terminated gracefully.\n"); 36 | break; 37 | case ML_ERROR_NO_VIDEO_TRAFFIC: 38 | printf("No video received from host. Check the host PC's firewall and port forwarding rules.\n"); 39 | break; 40 | case ML_ERROR_NO_VIDEO_FRAME: 41 | printf("Your network connection isn't performing well. Reduce your video bitrate setting or try a faster connection.\n"); 42 | break; 43 | case ML_ERROR_UNEXPECTED_EARLY_TERMINATION: 44 | printf("The connection was unexpectedly terminated by the host due to a video capture error. Make sure no DRM-protected content is playing on the host.\n"); 45 | break; 46 | case ML_ERROR_PROTECTED_CONTENT: 47 | printf("The connection was terminated by the host due to DRM-protected content. Close any DRM-protected content on the host and try again.\n"); 48 | break; 49 | default: 50 | printf("Connection terminated with error: %d\n", errorCode); 51 | break; 52 | } 53 | 54 | HIDUSER_DisableAccelerometer(); 55 | HIDUSER_DisableGyroscope(); 56 | n3ds_connection_closed = true; 57 | } 58 | 59 | static void connection_log_message(const char* format, ...) { 60 | if (n3ds_connection_debug) { 61 | va_list arglist; 62 | va_start(arglist, format); 63 | vprintf(format, arglist); 64 | va_end(arglist); 65 | } 66 | } 67 | 68 | static void connection_status_update(int status) { 69 | if (n3ds_connection_debug) { 70 | switch (status) { 71 | case CONN_STATUS_OKAY: 72 | printf("Connection is okay\n"); 73 | break; 74 | case CONN_STATUS_POOR: 75 | printf("Connection is poor\n"); 76 | break; 77 | } 78 | } 79 | } 80 | 81 | static void set_motion_event_state(unsigned short controllerNumber, unsigned char motionType, unsigned short reportRateHz) { 82 | if (!n3ds_enable_motion){ 83 | return; 84 | } 85 | 86 | switch (motionType) { 87 | case LI_MOTION_TYPE_ACCEL: 88 | enable_accel = (reportRateHz > 0); 89 | if (enable_accel) { 90 | HIDUSER_EnableAccelerometer(); 91 | } 92 | else { 93 | HIDUSER_DisableAccelerometer(); 94 | } 95 | break; 96 | case LI_MOTION_TYPE_GYRO: 97 | enable_gyro = (reportRateHz > 0); 98 | if (enable_gyro) { 99 | HIDUSER_EnableGyroscope(); 100 | } 101 | else { 102 | HIDUSER_DisableGyroscope(); 103 | } 104 | break; 105 | } 106 | } 107 | 108 | CONNECTION_LISTENER_CALLBACKS n3ds_connection_callbacks = { 109 | .stageStarting = NULL, 110 | .stageComplete = NULL, 111 | .stageFailed = NULL, 112 | .connectionStarted = NULL, 113 | .connectionTerminated = connection_terminated, 114 | .logMessage = connection_log_message, 115 | .rumble = NULL, 116 | .connectionStatusUpdate = connection_status_update, 117 | .setHdrMode = NULL, 118 | .rumbleTriggers = NULL, 119 | .setMotionEventState = set_motion_event_state, 120 | .setControllerLED = NULL, 121 | }; 122 | -------------------------------------------------------------------------------- /src/n3ds/n3ds_connection.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Moonlight Embedded. 3 | * 4 | * Copyright (C) 2015-2017 Iwan Timmer 5 | * 6 | * Moonlight is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Moonlight is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Moonlight; if not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #include 23 | 24 | #ifdef __cplusplus 25 | extern "C" { 26 | #endif 27 | 28 | extern bool n3ds_connection_closed; 29 | extern bool n3ds_connection_debug; 30 | extern bool n3ds_enable_motion; 31 | extern CONNECTION_LISTENER_CALLBACKS n3ds_connection_callbacks; 32 | 33 | #ifdef __cplusplus 34 | } 35 | #endif 36 | -------------------------------------------------------------------------------- /src/n3ds/pair_record.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Moonlight Embedded. 3 | * 4 | * Copyright (C) 2015-2017 Iwan Timmer 5 | * 6 | * Moonlight is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Moonlight is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Moonlight; if not, see . 18 | */ 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | #include "pair_record.hpp" 30 | 31 | // trim from start (in place) 32 | inline void ltrim(std::string &s) { 33 | s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](unsigned char ch) { 34 | return !std::isspace(ch); 35 | })); 36 | } 37 | 38 | // trim from end (in place) 39 | inline void rtrim(std::string &s) { 40 | s.erase(std::find_if(s.rbegin(), s.rend(), [](unsigned char ch) { 41 | return !std::isspace(ch); 42 | }).base(), s.end()); 43 | } 44 | 45 | // trim from both ends (in place) 46 | void trim(std::string &s) { 47 | rtrim(s); 48 | ltrim(s); 49 | } 50 | 51 | void add_pair_address(std::string address) { 52 | // Prevent duplicates 53 | auto address_list = list_paired_addresses(); 54 | 55 | for (auto entry : address_list) { 56 | if (entry == address) { 57 | return; 58 | } 59 | } 60 | address_list.push_back(address); 61 | 62 | char* address_file = (char*) MOONLIGHT_3DS_PATH "/paired"; 63 | remove(address_file); 64 | 65 | FILE* fd = fopen(address_file, "w"); 66 | for (auto addr_string : address_list) { 67 | trim(addr_string); 68 | fprintf(fd, "%s\n", addr_string.c_str()); 69 | } 70 | fclose(fd); 71 | } 72 | 73 | void remove_pair_address(std::string address) { 74 | auto address_list = list_paired_addresses(); 75 | 76 | char* address_file = (char*) MOONLIGHT_3DS_PATH "/paired"; 77 | remove(address_file); 78 | 79 | FILE* fd = fopen(address_file, "w"); 80 | for (auto addr_string : address_list) { 81 | if (addr_string != address) { 82 | trim(addr_string); 83 | fprintf(fd, "%s\n", addr_string.c_str()); 84 | } 85 | } 86 | fclose(fd); 87 | } 88 | 89 | std::vector list_paired_addresses() { 90 | std::vector addresses = std::vector(); 91 | std::ifstream pair_file(MOONLIGHT_3DS_PATH "/paired"); 92 | std::string line; 93 | while (std::getline(pair_file, line)) 94 | { 95 | trim(line); 96 | addresses.push_back(line); 97 | } 98 | return addresses; 99 | } 100 | -------------------------------------------------------------------------------- /src/n3ds/pair_record.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Moonlight Embedded. 3 | * 4 | * Copyright (C) 2015-2017 Iwan Timmer 5 | * 6 | * Moonlight is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Moonlight is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Moonlight; if not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #define MOONLIGHT_3DS_PATH "/3ds/moonlight" 23 | 24 | #ifdef __cplusplus 25 | #include 26 | #include 27 | 28 | void trim(std::string &s); 29 | void add_pair_address(std::string address); 30 | void remove_pair_address(std::string address); 31 | std::vector list_paired_addresses(); 32 | #endif 33 | -------------------------------------------------------------------------------- /src/platform_main.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Moonlight Embedded. 3 | * 4 | * Copyright (C) 2015-2017 Iwan Timmer 5 | * 6 | * Moonlight is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Moonlight is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Moonlight; if not, see . 18 | */ 19 | #ifndef PLATFORM_MAIN_H 20 | #define PLATFORM_MAIN_H 21 | 22 | #include 23 | 24 | #ifndef __3DS__ 25 | #include 26 | #endif 27 | #include 28 | #include 29 | #include 30 | 31 | #define IS_EMBEDDED(SYSTEM) SYSTEM != SDL 32 | 33 | enum platform { NONE, SDL, X11, X11_VDPAU, X11_VAAPI, PI, MMAL, IMX, AML, RK, FAKE }; 34 | enum codecs { CODEC_UNSPECIFIED, CODEC_H264, CODEC_HEVC, CODEC_AV1 }; 35 | 36 | enum platform platform_check(char*); 37 | PDECODER_RENDERER_CALLBACKS platform_get_video(enum platform system); 38 | PAUDIO_RENDERER_CALLBACKS platform_get_audio(enum platform system, char* audio_device); 39 | bool platform_prefers_codec(enum platform system, enum codecs codec); 40 | char* platform_name(enum platform system); 41 | 42 | void platform_start(enum platform system); 43 | void platform_stop(enum platform system); 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /src/sdl_main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Moonlight Embedded. 3 | * 4 | * Copyright (C) 2015 Iwan Timmer 5 | * 6 | * Moonlight is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Moonlight is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Moonlight; if not, see . 18 | */ 19 | 20 | #ifdef HAVE_SDL 21 | 22 | #include "sdl_main.h" 23 | #include "input/sdl.h" 24 | 25 | #include 26 | 27 | static bool done; 28 | static int fullscreen_flags; 29 | 30 | static SDL_Window *window; 31 | static SDL_Renderer *renderer; 32 | static SDL_Texture *bmp; 33 | 34 | SDL_mutex *mutex; 35 | 36 | int sdlCurrentFrame, sdlNextFrame; 37 | 38 | void sdl_init(int width, int height, bool fullscreen) { 39 | sdlCurrentFrame = sdlNextFrame = 0; 40 | 41 | if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS)) { 42 | fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError()); 43 | exit(1); 44 | } 45 | 46 | fullscreen_flags = fullscreen?SDL_WINDOW_FULLSCREEN:0; 47 | window = SDL_CreateWindow("Moonlight", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height, SDL_WINDOW_OPENGL | fullscreen_flags); 48 | if(!window) { 49 | fprintf(stderr, "SDL: could not create window - exiting\n"); 50 | exit(1); 51 | } 52 | 53 | renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC); 54 | if (!renderer) { 55 | printf("SDL_CreateRenderer failed: %s\n", SDL_GetError()); 56 | exit(1); 57 | } 58 | 59 | bmp = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_YV12, SDL_TEXTUREACCESS_STREAMING, width, height); 60 | if (!bmp) { 61 | fprintf(stderr, "SDL: could not create texture - exiting\n"); 62 | exit(1); 63 | } 64 | 65 | mutex = SDL_CreateMutex(); 66 | if (!mutex) { 67 | fprintf(stderr, "Couldn't create mutex\n"); 68 | exit(1); 69 | } 70 | } 71 | 72 | void sdl_loop() { 73 | SDL_Event event; 74 | 75 | SDL_SetRelativeMouseMode(SDL_TRUE); 76 | 77 | while(!done && SDL_WaitEvent(&event)) { 78 | switch (sdlinput_handle_event(window, &event)) { 79 | case SDL_QUIT_APPLICATION: 80 | done = true; 81 | break; 82 | case SDL_TOGGLE_FULLSCREEN: 83 | fullscreen_flags ^= SDL_WINDOW_FULLSCREEN; 84 | SDL_SetWindowFullscreen(window, fullscreen_flags); 85 | break; 86 | case SDL_MOUSE_GRAB: 87 | SDL_ShowCursor(SDL_ENABLE); 88 | SDL_SetRelativeMouseMode(SDL_TRUE); 89 | break; 90 | case SDL_MOUSE_UNGRAB: 91 | SDL_SetRelativeMouseMode(SDL_FALSE); 92 | SDL_ShowCursor(SDL_DISABLE); 93 | break; 94 | default: 95 | if (event.type == SDL_QUIT) 96 | done = true; 97 | else if (event.type == SDL_USEREVENT) { 98 | if (event.user.code == SDL_CODE_FRAME) { 99 | if (++sdlCurrentFrame <= sdlNextFrame - SDL_BUFFER_FRAMES) { 100 | //Skip frame 101 | } else if (SDL_LockMutex(mutex) == 0) { 102 | Uint8** data = ((Uint8**) event.user.data1); 103 | int* linesize = ((int*) event.user.data2); 104 | SDL_UpdateYUVTexture(bmp, NULL, data[0], linesize[0], data[1], linesize[1], data[2], linesize[2]); 105 | SDL_UnlockMutex(mutex); 106 | SDL_RenderClear(renderer); 107 | SDL_RenderCopy(renderer, bmp, NULL, NULL); 108 | SDL_RenderPresent(renderer); 109 | } else 110 | fprintf(stderr, "Couldn't lock mutex\n"); 111 | } 112 | } 113 | } 114 | } 115 | 116 | SDL_DestroyWindow(window); 117 | SDL_Quit(); 118 | } 119 | 120 | #endif /* HAVE_SDL */ 121 | -------------------------------------------------------------------------------- /src/sdl_main.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Moonlight Embedded. 3 | * 4 | * Copyright (C) 2015 Iwan Timmer 5 | * 6 | * Moonlight is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Moonlight is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Moonlight; if not, see . 18 | */ 19 | 20 | #ifdef HAVE_SDL 21 | 22 | #include 23 | 24 | #include 25 | 26 | #define SDL_NOTHING 0 27 | #define SDL_QUIT_APPLICATION 1 28 | #define SDL_MOUSE_GRAB 2 29 | #define SDL_MOUSE_UNGRAB 3 30 | #define SDL_TOGGLE_FULLSCREEN 4 31 | 32 | #define SDL_CODE_FRAME 0 33 | 34 | #define SDL_BUFFER_FRAMES 2 35 | 36 | void sdl_init(int width, int height, bool fullscreen); 37 | void sdl_loop(); 38 | 39 | extern SDL_mutex *mutex; 40 | extern int sdlCurrentFrame, sdlNextFrame; 41 | 42 | #endif /* HAVE_SDL */ 43 | -------------------------------------------------------------------------------- /src/util.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Moonlight Embedded. 3 | * 4 | * Copyright (C) 2017 Iwan Timmer 5 | * 6 | * Moonlight is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Moonlight is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Moonlight; if not, see . 18 | */ 19 | 20 | #include "util.h" 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #ifdef __3DS__ 29 | #include <3ds.h> 30 | #endif 31 | 32 | int write_bool(char *path, bool val) { 33 | int fd = open(path, O_RDWR); 34 | 35 | if(fd >= 0) { 36 | int ret = write(fd, val ? "1" : "0", 1); 37 | if (ret < 0) 38 | fprintf(stderr, "Failed to write %d to %s: %d\n", val ? 1 : 0, path, ret); 39 | 40 | close(fd); 41 | return 0; 42 | } else 43 | return -1; 44 | } 45 | 46 | int read_file(char *path, char* output, int output_len) { 47 | int fd = open(path, O_RDONLY); 48 | 49 | if(fd >= 0) { 50 | output_len = read(fd, output, output_len); 51 | close(fd); 52 | return output_len; 53 | } else 54 | return -1; 55 | } 56 | 57 | bool ensure_buf_size(void **buf, size_t *buf_size, size_t required_size) { 58 | if (*buf_size >= required_size) 59 | return false; 60 | 61 | *buf_size = required_size; 62 | *buf = realloc(*buf, *buf_size); 63 | if (!*buf) { 64 | fprintf(stderr, "Failed to allocate %zu bytes\n", *buf_size); 65 | abort(); 66 | } 67 | 68 | return true; 69 | } 70 | 71 | #ifdef __3DS__ 72 | bool ensure_linear_buf_size(void **buf, size_t *buf_size, size_t required_size) { 73 | if (*buf_size >= required_size) 74 | return false; 75 | 76 | linearFree(*buf); 77 | 78 | *buf_size = required_size; 79 | *buf = linearAlloc(*buf_size); 80 | if (!*buf) { 81 | fprintf(stderr, "Failed to allocate %zu bytes\n", *buf_size); 82 | abort(); 83 | } 84 | 85 | return true; 86 | } 87 | #endif 88 | -------------------------------------------------------------------------------- /src/util.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Moonlight Embedded. 3 | * 4 | * Copyright (C) 2017 Iwan Timmer 5 | * 6 | * Moonlight is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Moonlight is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Moonlight; if not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #include 23 | #include 24 | 25 | #ifdef __cplusplus 26 | extern "C" { 27 | #endif 28 | 29 | int write_bool(char *path, bool val); 30 | int read_file(char *path, char *output, int output_len); 31 | bool ensure_buf_size(void **buf, size_t *buf_size, size_t required_size); 32 | bool has_fast_aes(void); 33 | #ifdef __3DS__ 34 | bool ensure_linear_buf_size(void **buf, size_t *buf_size, size_t required_size); 35 | #endif 36 | 37 | #ifdef __cplusplus 38 | } 39 | #endif 40 | -------------------------------------------------------------------------------- /src/video/egl.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Moonlight Embedded. 3 | * 4 | * Copyright (C) 2017 Iwan Timmer 5 | * 6 | * Moonlight is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Moonlight is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Moonlight; if not, see . 18 | */ 19 | 20 | #include 21 | 22 | void egl_init(EGLNativeDisplayType native_display, NativeWindowType native_window, int display_width, int display_height); 23 | void egl_draw(uint8_t* image[3]); 24 | void egl_destroy(); 25 | -------------------------------------------------------------------------------- /src/video/ffmpeg.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Moonlight Embedded. 3 | * 4 | * Based on Moonlight Pc implementation 5 | * 6 | * Moonlight is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Moonlight is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Moonlight; if not, see . 18 | */ 19 | 20 | #include 21 | 22 | #include 23 | 24 | // Enable multi-threaded decoding 25 | #define SLICE_THREADING 0x4 26 | // Uses hardware acceleration 27 | #define VDPAU_ACCELERATION 0x40 28 | #define VAAPI_ACCELERATION 0x80 29 | 30 | #ifdef __cplusplus 31 | extern "C" { 32 | #endif 33 | 34 | enum decoders {SOFTWARE, VDPAU, VAAPI}; 35 | extern enum decoders ffmpeg_decoder; 36 | 37 | int ffmpeg_init(int videoFormat, int width, int height, int perf_lvl, int buffer_count, int thread_count); 38 | void ffmpeg_destroy(void); 39 | 40 | int ffmpeg_draw_frame(AVFrame *pict); 41 | AVFrame* ffmpeg_get_frame(bool native_frame); 42 | int ffmpeg_decode(unsigned char* indata, int inlen); 43 | 44 | #ifdef __cplusplus 45 | } 46 | #endif 47 | -------------------------------------------------------------------------------- /src/video/ffmpeg_vaapi.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Moonlight Embedded. 3 | * 4 | * Copyright (C) 2017 Iwan Timmer 5 | * 6 | * Moonlight is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Moonlight is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Moonlight; if not, see . 18 | */ 19 | 20 | #ifndef __3DS__ 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | #define MAX_SURFACES 16 30 | 31 | static AVBufferRef* device_ref; 32 | 33 | static enum AVPixelFormat va_get_format(AVCodecContext* context, const enum AVPixelFormat* pixel_format) { 34 | AVBufferRef* hw_ctx = av_hwframe_ctx_alloc(device_ref); 35 | if (hw_ctx == NULL) { 36 | fprintf(stderr, "Failed to initialize Vaapi buffer\n"); 37 | return AV_PIX_FMT_NONE; 38 | } 39 | 40 | AVHWFramesContext* fr_ctx = (AVHWFramesContext*) hw_ctx->data; 41 | fr_ctx->format = AV_PIX_FMT_VAAPI; 42 | fr_ctx->sw_format = AV_PIX_FMT_NV12; 43 | fr_ctx->width = context->coded_width; 44 | fr_ctx->height = context->coded_height; 45 | fr_ctx->initial_pool_size = MAX_SURFACES + 1; 46 | 47 | if (av_hwframe_ctx_init(hw_ctx) < 0) { 48 | fprintf(stderr, "Failed to initialize VAAPI frame context"); 49 | return AV_PIX_FMT_NONE; 50 | } 51 | 52 | context->pix_fmt = AV_PIX_FMT_VAAPI; 53 | context->hw_device_ctx = device_ref; 54 | context->hw_frames_ctx = hw_ctx; 55 | context->slice_flags = SLICE_FLAG_CODED_ORDER | SLICE_FLAG_ALLOW_FIELD; 56 | return AV_PIX_FMT_VAAPI; 57 | } 58 | 59 | static int va_get_buffer(AVCodecContext* context, AVFrame* frame, int flags) { 60 | return av_hwframe_get_buffer(context->hw_frames_ctx, frame, 0); 61 | } 62 | 63 | int vaapi_init_lib() { 64 | return av_hwdevice_ctx_create(&device_ref, AV_HWDEVICE_TYPE_VAAPI, ":0", NULL, 0); 65 | } 66 | 67 | int vaapi_init(AVCodecContext* decoder_ctx) { 68 | decoder_ctx->get_format = va_get_format; 69 | decoder_ctx->get_buffer2 = va_get_buffer; 70 | return 0; 71 | } 72 | 73 | void vaapi_queue(AVFrame* dec_frame, Window win, int width, int height) { 74 | VASurfaceID surface = (VASurfaceID)(uintptr_t)dec_frame->data[3]; 75 | AVHWDeviceContext* device = (AVHWDeviceContext*) device_ref->data; 76 | AVVAAPIDeviceContext *va_ctx = device->hwctx; 77 | vaPutSurface(va_ctx->display, surface, win, 0, 0, dec_frame->width, dec_frame->height, 0, 0, width, height, NULL, 0, 0); 78 | } 79 | 80 | #endif 81 | -------------------------------------------------------------------------------- /src/video/ffmpeg_vaapi.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Moonlight Embedded. 3 | * 4 | * Copyright (C) 2017 Iwan Timmer 5 | * 6 | * Moonlight is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Moonlight is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Moonlight; if not, see . 18 | */ 19 | 20 | #include 21 | #include 22 | 23 | int vaapi_init_lib(); 24 | int vaapi_init(AVCodecContext* decoder_ctx); 25 | void vaapi_queue(AVFrame* dec_frame, Window win, int width, int height); 26 | -------------------------------------------------------------------------------- /src/video/imx_vpu.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Moonlight Embedded. 3 | * 4 | * Copyright (C) 2017 Iwan Timmer 5 | * 6 | * Moonlight is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Moonlight is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Moonlight; if not, see . 18 | */ 19 | 20 | #include 21 | 22 | #include 23 | 24 | #include 25 | 26 | struct vpu_buf { 27 | void *start; 28 | off_t offset; 29 | size_t length; 30 | }; 31 | 32 | bool vpu_init(); 33 | void vpu_setup(struct vpu_buf* buffers[], int bufferCount, int stride, int height); 34 | 35 | bool vpu_decode(PDECODE_UNIT decodeUnit); 36 | int vpu_get_frame(); 37 | void vpu_clear(int disp_clr_index); 38 | 39 | void vpu_cleanup(); 40 | -------------------------------------------------------------------------------- /src/video/n3ds/N3dsRenderer.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Moonlight Embedded. 3 | * 4 | * Copyright (C) 2015 Iwan Timmer 5 | * 6 | * Moonlight is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Moonlight is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Moonlight; if not, see . 18 | */ 19 | 20 | #include <3ds.h> 21 | #include 22 | 23 | #define MOON_CTR_VIDEO_TEX_W 1024 24 | #define MOON_CTR_VIDEO_TEX_H 512 25 | // TODO: No idea why, but this seems to be the magic number to make dual screen 26 | // offsets work 27 | #define MOON_CTR_VIDEO_TEX_H_OFFSET 32 28 | #define CMDLIST_SZ 0x800 29 | 30 | class N3dsRendererBase { 31 | public: 32 | N3dsRendererBase(gfxScreen_t screen_in, int surface_width_in, 33 | int surface_height_in, int image_width_in, 34 | int image_height_in, int pixel_size, 35 | bool debug_in = false); 36 | ~N3dsRendererBase(); 37 | virtual void write_px_to_framebuffer(uint8_t *source) = 0; 38 | 39 | public: 40 | u64 perf_frame_target_ticks = SYSCLOCK_ARM11 * ((double)(1.0 / 60.0)); 41 | u64 perf_decode_ticks; 42 | u64 perf_fbcopy_ticks; 43 | 44 | protected: 45 | inline void draw_perf_counters(); 46 | void write_px_to_framebuffer_gpu(uint8_t *__restrict source); 47 | void ensure_3d_enabled(); 48 | void ensure_3d_disabled(); 49 | inline void write24(u8 *p, u32 val); 50 | 51 | protected: 52 | gfxScreen_t screen; 53 | int surface_width; 54 | int surface_height; 55 | int image_width; 56 | int image_height; 57 | int px_size; 58 | bool debug; 59 | u32 *cmdlist = NULL; 60 | void *vramFb = NULL; 61 | void *vramTex = NULL; 62 | }; 63 | 64 | class N3dsRendererTop : public N3dsRendererBase { 65 | public: 66 | N3dsRendererTop(int dest_width, int dest_height, int src_width, 67 | int src_height, int px_size, bool debug_in = false); 68 | ~N3dsRendererTop(); 69 | void write_px_to_framebuffer(uint8_t *source); 70 | }; 71 | 72 | class N3dsRendererBottom : public N3dsRendererBase { 73 | public: 74 | N3dsRendererBottom(int src_width, int src_height, int px_size, 75 | bool debug_in = false); 76 | ~N3dsRendererBottom(); 77 | void write_px_to_framebuffer(uint8_t *source); 78 | }; 79 | 80 | class N3dsRendererDualScreenStretch : public N3dsRendererBase { 81 | public: 82 | N3dsRendererDualScreenStretch(int dest_width, int dest_height, 83 | int src_width, int src_height, int px_size); 84 | ~N3dsRendererDualScreenStretch(); 85 | void write_px_to_framebuffer(uint8_t *source); 86 | 87 | private: 88 | int source_offset; 89 | N3dsRendererTop top_renderer; 90 | N3dsRendererBottom bottom_renderer; 91 | }; 92 | 93 | class N3dsRendererDualScreenMirror : public N3dsRendererBase { 94 | public: 95 | N3dsRendererDualScreenMirror(int dest_width, int dest_height, int src_width, 96 | int src_height, int px_size); 97 | ~N3dsRendererDualScreenMirror(); 98 | void write_px_to_framebuffer(uint8_t *source); 99 | 100 | private: 101 | N3dsRendererTop top_renderer; 102 | N3dsRendererBottom bottom_renderer; 103 | }; 104 | -------------------------------------------------------------------------------- /src/video/n3ds/N3dsRendererBottom.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Moonlight Embedded. 3 | * 4 | * Copyright (C) 2015 Iwan Timmer 5 | * 6 | * Moonlight is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Moonlight is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Moonlight; if not, see . 18 | */ 19 | 20 | #include "N3dsRenderer.hpp" 21 | #include "vshader_shbin.h" 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | N3dsRendererBottom::N3dsRendererBottom(int src_width, int src_height, 30 | int px_size, bool debug_in) 31 | : N3dsRendererBase(GFX_BOTTOM, GSP_SCREEN_HEIGHT_BOTTOM, GSP_SCREEN_WIDTH, 32 | src_width, src_height, px_size, debug_in) {} 33 | 34 | N3dsRendererBottom::~N3dsRendererBottom() {} 35 | 36 | inline void N3dsRendererBottom::write_px_to_framebuffer(uint8_t *source) { 37 | write_px_to_framebuffer_gpu(source); 38 | } 39 | -------------------------------------------------------------------------------- /src/video/n3ds/N3dsRendererDualScreenMirror.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Moonlight Embedded. 3 | * 4 | * Copyright (C) 2015 Iwan Timmer 5 | * 6 | * Moonlight is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Moonlight is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Moonlight; if not, see . 18 | */ 19 | 20 | #include "N3dsRenderer.hpp" 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | N3dsRendererDualScreenMirror::N3dsRendererDualScreenMirror( 29 | int dest_width, int dest_height, int src_width, int src_height, int px_size) 30 | : N3dsRendererBase(GFX_TOP, dest_width, dest_height, src_width, src_height, 31 | px_size), 32 | top_renderer(dest_width, dest_height, src_width, src_height, px_size), 33 | bottom_renderer(src_width, src_height, px_size) {} 34 | 35 | N3dsRendererDualScreenMirror::~N3dsRendererDualScreenMirror() = default; 36 | 37 | void N3dsRendererDualScreenMirror::write_px_to_framebuffer(uint8_t *source) { 38 | top_renderer.write_px_to_framebuffer(source); 39 | bottom_renderer.write_px_to_framebuffer(source); 40 | } 41 | -------------------------------------------------------------------------------- /src/video/n3ds/N3dsRendererDualScreenStretch.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Moonlight Embedded. 3 | * 4 | * Copyright (C) 2015 Iwan Timmer 5 | * 6 | * Moonlight is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Moonlight is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Moonlight; if not, see . 18 | */ 19 | 20 | #include "N3dsRenderer.hpp" 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | N3dsRendererDualScreenStretch::N3dsRendererDualScreenStretch( 29 | int dest_width, int dest_height, int src_width, int src_height, int px_size) 30 | : N3dsRendererBase(GFX_TOP, dest_width, dest_height, src_width, src_height, 31 | px_size), 32 | source_offset(MOON_CTR_VIDEO_TEX_W * 33 | (MOON_CTR_VIDEO_TEX_H - MOON_CTR_VIDEO_TEX_H_OFFSET) * 34 | px_size / 2), 35 | top_renderer(dest_width, dest_height, src_width, src_height / 2, px_size), 36 | bottom_renderer(src_width, src_height / 2, px_size) {} 37 | 38 | N3dsRendererDualScreenStretch::~N3dsRendererDualScreenStretch() = default; 39 | 40 | void N3dsRendererDualScreenStretch::write_px_to_framebuffer(uint8_t *source) { 41 | top_renderer.write_px_to_framebuffer(source); 42 | bottom_renderer.write_px_to_framebuffer(source + source_offset); 43 | } 44 | -------------------------------------------------------------------------------- /src/video/n3ds/N3dsRendererTop.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Moonlight Embedded. 3 | * 4 | * Copyright (C) 2015 Iwan Timmer 5 | * 6 | * Moonlight is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Moonlight is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Moonlight; if not, see . 18 | */ 19 | 20 | #include "N3dsRenderer.hpp" 21 | #include "vshader_shbin.h" 22 | 23 | #include <3ds.h> 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | N3dsRendererTop::N3dsRendererTop(int dest_width, int dest_height, int src_width, 31 | int src_height, int px_size, bool debug_in) 32 | : N3dsRendererBase(GFX_TOP, dest_width, dest_height, src_width, src_height, 33 | px_size, debug_in) {} 34 | 35 | N3dsRendererTop::~N3dsRendererTop() = default; 36 | 37 | void N3dsRendererTop::write_px_to_framebuffer(uint8_t *source) { 38 | // TODO: Add logic for stretching 400px images to fit 2 400px screen buffers 39 | if (osGet3DSliderState() > 0.0 && 40 | surface_width >= GSP_SCREEN_HEIGHT_TOP_2X) { 41 | ensure_3d_enabled(); 42 | } else { 43 | ensure_3d_disabled(); 44 | } 45 | write_px_to_framebuffer_gpu(source); 46 | } 47 | -------------------------------------------------------------------------------- /src/video/n3ds/vshader.v.pica: -------------------------------------------------------------------------------- 1 | ; Example PICA200 vertex shader 2 | 3 | ; Uniforms 4 | .fvec projection[4] 5 | 6 | ; Constants 7 | .constf myconst(0.0, 1.0, -1.0, 0.5) 8 | .alias zeros myconst.xxxx ; Vector full of zeros 9 | .alias ones myconst.yyyy ; Vector full of ones 10 | 11 | ; Outputs 12 | .out outpos position 13 | .out outtc0 texcoord0 14 | 15 | ; Inputs (defined as aliases for convenience) 16 | .alias inpos v0 17 | .alias intex v1 18 | 19 | .proc main 20 | ; Force the w component of inpos to be 1.0 21 | mov r0.xyz, inpos 22 | mov r0.w, ones 23 | 24 | mov outpos, r0 25 | 26 | ; outtc0 = intex 27 | mov outtc0, intex 28 | 29 | ; We're finished 30 | end 31 | .end 32 | -------------------------------------------------------------------------------- /src/video/sdl_video.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Moonlight Embedded. 3 | * 4 | * Copyright (C) 2015 Iwan Timmer 5 | * 6 | * Moonlight is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Moonlight is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Moonlight; if not, see . 18 | */ 19 | 20 | #ifdef HAVE_SDL 21 | 22 | #include "video.h" 23 | #include "ffmpeg.h" 24 | 25 | #include "../sdl.h" 26 | #include "../util.h" 27 | 28 | #include 29 | #include 30 | 31 | #include 32 | #include 33 | 34 | #define SLICES_PER_FRAME 4 35 | 36 | static void* ffmpeg_buffer; 37 | static size_t ffmpeg_buffer_size; 38 | 39 | static int sdl_setup(int videoFormat, int width, int height, int redrawRate, void* context, int drFlags) { 40 | if (ffmpeg_init(videoFormat, width, height, SLICE_THREADING, SDL_BUFFER_FRAMES, SLICES_PER_FRAME) < 0) { 41 | fprintf(stderr, "Couldn't initialize video decoding\n"); 42 | return -1; 43 | } 44 | 45 | ensure_buf_size(&ffmpeg_buffer, &ffmpeg_buffer_size, INITIAL_DECODER_BUFFER_SIZE + AV_INPUT_BUFFER_PADDING_SIZE); 46 | 47 | return 0; 48 | } 49 | 50 | static void sdl_cleanup() { 51 | ffmpeg_destroy(); 52 | } 53 | 54 | static int sdl_submit_decode_unit(PDECODE_UNIT decodeUnit) { 55 | PLENTRY entry = decodeUnit->bufferList; 56 | int length = 0; 57 | 58 | ensure_buf_size(&ffmpeg_buffer, &ffmpeg_buffer_size, decodeUnit->fullLength + AV_INPUT_BUFFER_PADDING_SIZE); 59 | 60 | while (entry != NULL) { 61 | memcpy(ffmpeg_buffer+length, entry->data, entry->length); 62 | length += entry->length; 63 | entry = entry->next; 64 | } 65 | ffmpeg_decode(ffmpeg_buffer, length); 66 | 67 | SDL_LockMutex(mutex); 68 | AVFrame* frame = ffmpeg_get_frame(false); 69 | if (frame != NULL) { 70 | sdlNextFrame++; 71 | 72 | SDL_Event event; 73 | event.type = SDL_USEREVENT; 74 | event.user.code = SDL_CODE_FRAME; 75 | event.user.data1 = &frame->data; 76 | event.user.data2 = &frame->linesize; 77 | SDL_PushEvent(&event); 78 | } 79 | SDL_UnlockMutex(mutex); 80 | 81 | return DR_OK; 82 | } 83 | 84 | DECODER_RENDERER_CALLBACKS decoder_callbacks_sdl = { 85 | .setup = sdl_setup, 86 | .cleanup = sdl_cleanup, 87 | .submitDecodeUnit = sdl_submit_decode_unit, 88 | .capabilities = CAPABILITY_SLICES_PER_FRAME(SLICES_PER_FRAME) | CAPABILITY_REFERENCE_FRAME_INVALIDATION_HEVC | CAPABILITY_DIRECT_SUBMIT, 89 | }; 90 | 91 | #endif 92 | -------------------------------------------------------------------------------- /src/video/video.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Moonlight Embedded. 3 | * 4 | * Copyright (C) 2015-2017 Iwan Timmer 5 | * 6 | * Moonlight is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Moonlight is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Moonlight; if not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #include 23 | 24 | #include 25 | 26 | #define DISPLAY_FULLSCREEN 1 27 | #define ENABLE_HARDWARE_ACCELERATION_1 2 28 | #define ENABLE_HARDWARE_ACCELERATION_2 4 29 | #define DISPLAY_ROTATE_MASK 24 30 | #define DISPLAY_ROTATE_90 8 31 | #define DISPLAY_ROTATE_180 16 32 | #define DISPLAY_ROTATE_270 24 33 | 34 | #define INIT_EGL 1 35 | #define INIT_VDPAU 2 36 | #define INIT_VAAPI 3 37 | 38 | #define INITIAL_DECODER_BUFFER_SIZE (256 * 1024) 39 | 40 | #ifdef __cplusplus 41 | extern "C" { 42 | #endif 43 | 44 | #ifdef HAVE_X11 45 | int x11_init(bool vdpau, bool vaapi); 46 | extern DECODER_RENDERER_CALLBACKS decoder_callbacks_x11; 47 | #ifdef HAVE_VAAPI 48 | extern DECODER_RENDERER_CALLBACKS decoder_callbacks_x11_vaapi; 49 | #endif 50 | #ifdef HAVE_VDPAU 51 | extern DECODER_RENDERER_CALLBACKS decoder_callbacks_x11_vdpau; 52 | #endif 53 | #endif 54 | #ifdef __3DS__ 55 | #include <3ds/types.h> 56 | 57 | enum n3ds_render_type { 58 | RENDER_DEFAULT, 59 | RENDER_BOTTOM, 60 | RENDER_DUAL_SCREEN_STRETCH, 61 | RENDER_DUAL_SCREEN_MIRROR 62 | }; 63 | extern enum n3ds_render_type N3DS_RENDER_TYPE; 64 | 65 | extern DECODER_RENDERER_CALLBACKS decoder_callbacks_n3ds; 66 | extern DECODER_RENDERER_CALLBACKS decoder_callbacks_n3ds_mvd; 67 | #endif 68 | #ifdef HAVE_SDL 69 | extern DECODER_RENDERER_CALLBACKS decoder_callbacks_sdl; 70 | #endif 71 | 72 | #ifdef __cplusplus 73 | } 74 | #endif 75 | -------------------------------------------------------------------------------- /third_party/h264bitstream/h264_sei.c: -------------------------------------------------------------------------------- 1 | /* 2 | * h264bitstream - a library for reading and writing H.264 video 3 | * Copyright (C) 2005-2007 Auroras Entertainment, LLC 4 | * Copyright (C) 2008-2011 Avail-TVN 5 | * 6 | * Written by Alex Izvorski and Alex Giladi 7 | * 8 | * This library is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU Lesser General Public 10 | * License as published by the Free Software Foundation; either 11 | * version 2.1 of the License, or (at your option) any later version. 12 | * 13 | * This library is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public 19 | * License along with this library; if not, write to the Free Software 20 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 21 | */ 22 | 23 | #include "bs.h" 24 | #include "h264_stream.h" 25 | #include "h264_sei.h" 26 | 27 | #include 28 | #include // malloc 29 | #include // memset 30 | 31 | sei_t* sei_new() 32 | { 33 | sei_t* s = (sei_t*)malloc(sizeof(sei_t)); 34 | memset(s, 0, sizeof(sei_t)); 35 | s->payload = NULL; 36 | return s; 37 | } 38 | 39 | void sei_free(sei_t* s) 40 | { 41 | if ( s->payload != NULL ) free(s->payload); 42 | free(s); 43 | } 44 | 45 | void read_sei_end_bits(h264_stream_t* h, bs_t* b ) 46 | { 47 | // if the message doesn't end at a byte border 48 | if ( !bs_byte_aligned( b ) ) 49 | { 50 | if ( !bs_read_u1( b ) ) fprintf(stderr, "WARNING: bit_equal_to_one is 0!!!!\n"); 51 | while ( ! bs_byte_aligned( b ) ) 52 | { 53 | if ( bs_read_u1( b ) ) fprintf(stderr, "WARNING: bit_equal_to_zero is 1!!!!\n"); 54 | } 55 | } 56 | 57 | read_rbsp_trailing_bits(h, b); 58 | } 59 | 60 | // D.1 SEI payload syntax 61 | void read_sei_payload(h264_stream_t* h, bs_t* b, int payloadType, int payloadSize) 62 | { 63 | sei_t* s = h->sei; 64 | 65 | s->payload = (uint8_t*)malloc(payloadSize); 66 | 67 | int i; 68 | 69 | for ( i = 0; i < payloadSize; i++ ) 70 | s->payload[i] = bs_read_u(b, 8); 71 | 72 | //read_sei_end_bits(h, b); 73 | } 74 | 75 | // D.1 SEI payload syntax 76 | void write_sei_payload(h264_stream_t* h, bs_t* b, int payloadType, int payloadSize) 77 | { 78 | sei_t* s = h->sei; 79 | 80 | int i; 81 | for ( i = 0; i < s->payloadSize; i++ ) 82 | bs_write_u(b, 8, s->payload[i]); 83 | } 84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /third_party/h264bitstream/h264_sei.h: -------------------------------------------------------------------------------- 1 | /* 2 | * h264bitstream - a library for reading and writing H.264 video 3 | * Copyright (C) 2005-2007 Auroras Entertainment, LLC 4 | * Copyright (C) 2008-2011 Avail-TVN 5 | * 6 | * Written by Alex Izvorski and Alex Giladi 7 | * 8 | * This library is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU Lesser General Public 10 | * License as published by the Free Software Foundation; either 11 | * version 2.1 of the License, or (at your option) any later version. 12 | * 13 | * This library is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public 19 | * License along with this library; if not, write to the Free Software 20 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 21 | */ 22 | 23 | #include 24 | 25 | #ifndef _H264_SEI_H 26 | #define _H264_SEI_H 1 27 | 28 | #include 29 | 30 | #include "bs.h" 31 | 32 | #ifdef __cplusplus 33 | extern "C" { 34 | #endif 35 | 36 | typedef struct 37 | { 38 | int payloadType; 39 | int payloadSize; 40 | uint8_t* payload; 41 | } sei_t; 42 | 43 | sei_t* sei_new(); 44 | void sei_free(sei_t* s); 45 | 46 | //D.1 SEI payload syntax 47 | #define SEI_TYPE_BUFFERING_PERIOD 0 48 | #define SEI_TYPE_PIC_TIMING 1 49 | #define SEI_TYPE_PAN_SCAN_RECT 2 50 | #define SEI_TYPE_FILLER_PAYLOAD 3 51 | #define SEI_TYPE_USER_DATA_REGISTERED_ITU_T_T35 4 52 | #define SEI_TYPE_USER_DATA_UNREGISTERED 5 53 | #define SEI_TYPE_RECOVERY_POINT 6 54 | #define SEI_TYPE_DEC_REF_PIC_MARKING_REPETITION 7 55 | #define SEI_TYPE_SPARE_PIC 8 56 | #define SEI_TYPE_SCENE_INFO 9 57 | #define SEI_TYPE_SUB_SEQ_INFO 10 58 | #define SEI_TYPE_SUB_SEQ_LAYER_CHARACTERISTICS 11 59 | #define SEI_TYPE_SUB_SEQ_CHARACTERISTICS 12 60 | #define SEI_TYPE_FULL_FRAME_FREEZE 13 61 | #define SEI_TYPE_FULL_FRAME_FREEZE_RELEASE 14 62 | #define SEI_TYPE_FULL_FRAME_SNAPSHOT 15 63 | #define SEI_TYPE_PROGRESSIVE_REFINEMENT_SEGMENT_START 16 64 | #define SEI_TYPE_PROGRESSIVE_REFINEMENT_SEGMENT_END 17 65 | #define SEI_TYPE_MOTION_CONSTRAINED_SLICE_GROUP_SET 18 66 | #define SEI_TYPE_FILM_GRAIN_CHARACTERISTICS 19 67 | #define SEI_TYPE_DEBLOCKING_FILTER_DISPLAY_PREFERENCE 20 68 | #define SEI_TYPE_STEREO_VIDEO_INFO 21 69 | 70 | #ifdef __cplusplus 71 | } 72 | #endif 73 | 74 | #endif 75 | -------------------------------------------------------------------------------- /third_party/libuuid/COPYING: -------------------------------------------------------------------------------- 1 | This library is free software; you can redistribute it and/or 2 | modify it under the terms of the Modified BSD License. 3 | 4 | The complete text of the license is available at the 5 | Documentation/licenses/COPYING.BSD-3 file. 6 | -------------------------------------------------------------------------------- /third_party/libuuid/all-io.h: -------------------------------------------------------------------------------- 1 | /* 2 | * No copyright is claimed. This code is in the public domain; do with 3 | * it what you wish. 4 | * 5 | * Written by Karel Zak 6 | * Petr Uzel 7 | */ 8 | 9 | #ifndef UTIL_LINUX_ALL_IO_H 10 | #define UTIL_LINUX_ALL_IO_H 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | #include "c.h" 17 | 18 | static inline int write_all(int fd, const void *buf, size_t count) 19 | { 20 | while (count) { 21 | ssize_t tmp; 22 | 23 | errno = 0; 24 | tmp = write(fd, buf, count); 25 | if (tmp > 0) { 26 | count -= tmp; 27 | if (count) 28 | buf = (void *) ((char *) buf + tmp); 29 | } else if (errno != EINTR && errno != EAGAIN) 30 | return -1; 31 | if (errno == EAGAIN) /* Try later, *sigh* */ 32 | usleep(10000); 33 | } 34 | return 0; 35 | } 36 | 37 | static inline int fwrite_all(const void *ptr, size_t size, 38 | size_t nmemb, FILE *stream) 39 | { 40 | while (nmemb) { 41 | size_t tmp; 42 | 43 | errno = 0; 44 | tmp = fwrite(ptr, size, nmemb, stream); 45 | if (tmp > 0) { 46 | nmemb -= tmp; 47 | if (nmemb) 48 | ptr = (void *) ((char *) ptr + (tmp * size)); 49 | } else if (errno != EINTR && errno != EAGAIN) 50 | return -1; 51 | if (errno == EAGAIN) /* Try later, *sigh* */ 52 | usleep(10000); 53 | } 54 | return 0; 55 | } 56 | 57 | static inline ssize_t read_all(int fd, char *buf, size_t count) 58 | { 59 | ssize_t ret; 60 | ssize_t c = 0; 61 | int tries = 0; 62 | 63 | memset(buf, 0, count); 64 | while (count > 0) { 65 | ret = read(fd, buf, count); 66 | if (ret <= 0) { 67 | if ((errno == EAGAIN || errno == EINTR || ret == 0) && 68 | (tries++ < 5)) 69 | continue; 70 | return c ? c : -1; 71 | } 72 | if (ret > 0) 73 | tries = 0; 74 | count -= ret; 75 | buf += ret; 76 | c += ret; 77 | } 78 | return c; 79 | } 80 | 81 | 82 | #endif /* UTIL_LINUX_ALL_IO_H */ 83 | -------------------------------------------------------------------------------- /third_party/libuuid/clear.c: -------------------------------------------------------------------------------- 1 | /* 2 | * clear.c -- Clear a UUID 3 | * 4 | * Copyright (C) 1996, 1997 Theodore Ts'o. 5 | * 6 | * %Begin-Header% 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, and the entire permission notice in its entirety, 12 | * including the disclaimer of warranties. 13 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 3. The name of the author may not be used to endorse or promote 17 | * products derived from this software without specific prior 18 | * written permission. 19 | * 20 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 21 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 22 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF 23 | * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE 24 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 26 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 27 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 28 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 30 | * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH 31 | * DAMAGE. 32 | * %End-Header% 33 | */ 34 | 35 | #include "string.h" 36 | 37 | #include "uuidP.h" 38 | 39 | void uuid_clear(uuid_t uu) 40 | { 41 | memset(uu, 0, 16); 42 | } 43 | 44 | -------------------------------------------------------------------------------- /third_party/libuuid/compare.c: -------------------------------------------------------------------------------- 1 | /* 2 | * compare.c --- compare whether or not two UUIDs are the same 3 | * 4 | * Returns 0 if the two UUIDs are different, and 1 if they are the same. 5 | * 6 | * Copyright (C) 1996, 1997 Theodore Ts'o. 7 | * 8 | * %Begin-Header% 9 | * Redistribution and use in source and binary forms, with or without 10 | * modification, are permitted provided that the following conditions 11 | * are met: 12 | * 1. Redistributions of source code must retain the above copyright 13 | * notice, and the entire permission notice in its entirety, 14 | * including the disclaimer of warranties. 15 | * 2. Redistributions in binary form must reproduce the above copyright 16 | * notice, this list of conditions and the following disclaimer in the 17 | * documentation and/or other materials provided with the distribution. 18 | * 3. The name of the author may not be used to endorse or promote 19 | * products derived from this software without specific prior 20 | * written permission. 21 | * 22 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 23 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 24 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF 25 | * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE 26 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 27 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 28 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 29 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 30 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 32 | * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH 33 | * DAMAGE. 34 | * %End-Header% 35 | */ 36 | 37 | #include "uuidP.h" 38 | #include 39 | 40 | #define UUCMP(u1,u2) if (u1 != u2) return((u1 < u2) ? -1 : 1); 41 | 42 | int uuid_compare(const uuid_t uu1, const uuid_t uu2) 43 | { 44 | struct uuid uuid1, uuid2; 45 | 46 | uuid_unpack(uu1, &uuid1); 47 | uuid_unpack(uu2, &uuid2); 48 | 49 | UUCMP(uuid1.time_low, uuid2.time_low); 50 | UUCMP(uuid1.time_mid, uuid2.time_mid); 51 | UUCMP(uuid1.time_hi_and_version, uuid2.time_hi_and_version); 52 | UUCMP(uuid1.clock_seq, uuid2.clock_seq); 53 | return memcmp(uuid1.node, uuid2.node, 6); 54 | } 55 | 56 | -------------------------------------------------------------------------------- /third_party/libuuid/copy.c: -------------------------------------------------------------------------------- 1 | /* 2 | * copy.c --- copy UUIDs 3 | * 4 | * Copyright (C) 1996, 1997 Theodore Ts'o. 5 | * 6 | * %Begin-Header% 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, and the entire permission notice in its entirety, 12 | * including the disclaimer of warranties. 13 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 3. The name of the author may not be used to endorse or promote 17 | * products derived from this software without specific prior 18 | * written permission. 19 | * 20 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 21 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 22 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF 23 | * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE 24 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 26 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 27 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 28 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 30 | * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH 31 | * DAMAGE. 32 | * %End-Header% 33 | */ 34 | 35 | #include "uuidP.h" 36 | 37 | void uuid_copy(uuid_t dst, const uuid_t src) 38 | { 39 | unsigned char *cp1; 40 | const unsigned char *cp2; 41 | int i; 42 | 43 | for (i=0, cp1 = dst, cp2 = src; i < 16; i++) 44 | *cp1++ = *cp2++; 45 | } 46 | -------------------------------------------------------------------------------- /third_party/libuuid/isnull.c: -------------------------------------------------------------------------------- 1 | /* 2 | * isnull.c --- Check whether or not the UUID is null 3 | * 4 | * Copyright (C) 1996, 1997 Theodore Ts'o. 5 | * 6 | * %Begin-Header% 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, and the entire permission notice in its entirety, 12 | * including the disclaimer of warranties. 13 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 3. The name of the author may not be used to endorse or promote 17 | * products derived from this software without specific prior 18 | * written permission. 19 | * 20 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 21 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 22 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF 23 | * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE 24 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 26 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 27 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 28 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 30 | * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH 31 | * DAMAGE. 32 | * %End-Header% 33 | */ 34 | 35 | #include "uuidP.h" 36 | 37 | /* Returns 1 if the uuid is the NULL uuid */ 38 | int uuid_is_null(const uuid_t uu) 39 | { 40 | const unsigned char *cp; 41 | int i; 42 | 43 | for (i=0, cp = uu; i < 16; i++) 44 | if (*cp++) 45 | return 0; 46 | return 1; 47 | } 48 | 49 | -------------------------------------------------------------------------------- /third_party/libuuid/pack.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Internal routine for packing UUIDs 3 | * 4 | * Copyright (C) 1996, 1997 Theodore Ts'o. 5 | * 6 | * %Begin-Header% 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, and the entire permission notice in its entirety, 12 | * including the disclaimer of warranties. 13 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 3. The name of the author may not be used to endorse or promote 17 | * products derived from this software without specific prior 18 | * written permission. 19 | * 20 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 21 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 22 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF 23 | * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE 24 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 26 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 27 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 28 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 30 | * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH 31 | * DAMAGE. 32 | * %End-Header% 33 | */ 34 | 35 | #include 36 | #include "uuidP.h" 37 | 38 | void uuid_pack(const struct uuid *uu, uuid_t ptr) 39 | { 40 | uint32_t tmp; 41 | unsigned char *out = ptr; 42 | 43 | tmp = uu->time_low; 44 | out[3] = (unsigned char) tmp; 45 | tmp >>= 8; 46 | out[2] = (unsigned char) tmp; 47 | tmp >>= 8; 48 | out[1] = (unsigned char) tmp; 49 | tmp >>= 8; 50 | out[0] = (unsigned char) tmp; 51 | 52 | tmp = uu->time_mid; 53 | out[5] = (unsigned char) tmp; 54 | tmp >>= 8; 55 | out[4] = (unsigned char) tmp; 56 | 57 | tmp = uu->time_hi_and_version; 58 | out[7] = (unsigned char) tmp; 59 | tmp >>= 8; 60 | out[6] = (unsigned char) tmp; 61 | 62 | tmp = uu->clock_seq; 63 | out[9] = (unsigned char) tmp; 64 | tmp >>= 8; 65 | out[8] = (unsigned char) tmp; 66 | 67 | memcpy(out+10, uu->node, 6); 68 | } 69 | 70 | -------------------------------------------------------------------------------- /third_party/libuuid/parse.c: -------------------------------------------------------------------------------- 1 | /* 2 | * parse.c --- UUID parsing 3 | * 4 | * Copyright (C) 1996, 1997 Theodore Ts'o. 5 | * 6 | * %Begin-Header% 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, and the entire permission notice in its entirety, 12 | * including the disclaimer of warranties. 13 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 3. The name of the author may not be used to endorse or promote 17 | * products derived from this software without specific prior 18 | * written permission. 19 | * 20 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 21 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 22 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF 23 | * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE 24 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 26 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 27 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 28 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 30 | * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH 31 | * DAMAGE. 32 | * %End-Header% 33 | */ 34 | 35 | #include 36 | #include 37 | #include 38 | #include 39 | 40 | #include "uuidP.h" 41 | 42 | int uuid_parse(const char *in, uuid_t uu) 43 | { 44 | struct uuid uuid; 45 | int i; 46 | const char *cp; 47 | char buf[3]; 48 | 49 | if (strlen(in) != 36) 50 | return -1; 51 | for (i=0, cp = in; i <= 36; i++,cp++) { 52 | if ((i == 8) || (i == 13) || (i == 18) || 53 | (i == 23)) { 54 | if (*cp == '-') 55 | continue; 56 | else 57 | return -1; 58 | } 59 | if (i== 36) 60 | if (*cp == 0) 61 | continue; 62 | if (!isxdigit(*cp)) 63 | return -1; 64 | } 65 | uuid.time_low = strtoul(in, NULL, 16); 66 | uuid.time_mid = strtoul(in+9, NULL, 16); 67 | uuid.time_hi_and_version = strtoul(in+14, NULL, 16); 68 | uuid.clock_seq = strtoul(in+19, NULL, 16); 69 | cp = in+24; 70 | buf[2] = 0; 71 | for (i=0; i < 6; i++) { 72 | buf[0] = *cp++; 73 | buf[1] = *cp++; 74 | uuid.node[i] = strtoul(buf, NULL, 16); 75 | } 76 | 77 | uuid_pack(&uuid, uu); 78 | return 0; 79 | } 80 | -------------------------------------------------------------------------------- /third_party/libuuid/randutils.c: -------------------------------------------------------------------------------- 1 | /* 2 | * General purpose random utilities 3 | * 4 | * Based on libuuid code. 5 | * 6 | * This file may be redistributed under the terms of the 7 | * GNU Lesser General Public License. 8 | */ 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #ifndef __3DS__ 17 | #include 18 | #endif 19 | 20 | #include "randutils.h" 21 | 22 | #ifdef HAVE_TLS 23 | #define THREAD_LOCAL static __thread 24 | #else 25 | #define THREAD_LOCAL static 26 | #endif 27 | 28 | #if defined(__linux__) && defined(__NR_gettid) && defined(HAVE_JRAND48) 29 | #define DO_JRAND_MIX 30 | THREAD_LOCAL unsigned short ul_jrand_seed[3]; 31 | #endif 32 | 33 | int random_get_fd(void) 34 | { 35 | int i, fd; 36 | struct timeval tv; 37 | 38 | gettimeofday(&tv, 0); 39 | fd = open("/dev/urandom", O_RDONLY); 40 | if (fd == -1) 41 | fd = open("/dev/random", O_RDONLY | O_NONBLOCK); 42 | if (fd >= 0) { 43 | i = fcntl(fd, F_GETFD); 44 | if (i >= 0) 45 | fcntl(fd, F_SETFD, i | FD_CLOEXEC); 46 | } 47 | #ifdef __3DS__ 48 | srand((1 << 16) ^ tv.tv_sec ^ tv.tv_usec); 49 | #else 50 | srand((getpid() << 16) ^ getuid() ^ tv.tv_sec ^ tv.tv_usec); 51 | #endif 52 | 53 | #ifdef DO_JRAND_MIX 54 | ul_jrand_seed[0] = getpid() ^ (tv.tv_sec & 0xFFFF); 55 | ul_jrand_seed[1] = getppid() ^ (tv.tv_usec & 0xFFFF); 56 | ul_jrand_seed[2] = (tv.tv_sec ^ tv.tv_usec) >> 16; 57 | #endif 58 | /* Crank the random number generator a few times */ 59 | gettimeofday(&tv, 0); 60 | for (i = (tv.tv_sec ^ tv.tv_usec) & 0x1F; i > 0; i--) 61 | rand(); 62 | return fd; 63 | } 64 | 65 | 66 | /* 67 | * Generate a stream of random nbytes into buf. 68 | * Use /dev/urandom if possible, and if not, 69 | * use glibc pseudo-random functions. 70 | */ 71 | void random_get_bytes(void *buf, size_t nbytes) 72 | { 73 | size_t i, n = nbytes; 74 | int fd = random_get_fd(); 75 | int lose_counter = 0; 76 | unsigned char *cp = (unsigned char *) buf; 77 | 78 | if (fd >= 0) { 79 | while (n > 0) { 80 | ssize_t x = read(fd, cp, n); 81 | if (x <= 0) { 82 | if (lose_counter++ > 16) 83 | break; 84 | continue; 85 | } 86 | n -= x; 87 | cp += x; 88 | lose_counter = 0; 89 | } 90 | 91 | close(fd); 92 | } 93 | 94 | /* 95 | * We do this all the time, but this is the only source of 96 | * randomness if /dev/random/urandom is out to lunch. 97 | */ 98 | for (cp = buf, i = 0; i < nbytes; i++) 99 | *cp++ ^= (rand() >> 7) & 0xFF; 100 | 101 | #ifdef DO_JRAND_MIX 102 | { 103 | unsigned short tmp_seed[3]; 104 | 105 | memcpy(tmp_seed, ul_jrand_seed, sizeof(tmp_seed)); 106 | ul_jrand_seed[2] = ul_jrand_seed[2] ^ syscall(__NR_gettid); 107 | for (cp = buf, i = 0; i < nbytes; i++) 108 | *cp++ ^= (jrand48(tmp_seed) >> 7) & 0xFF; 109 | memcpy(ul_jrand_seed, tmp_seed, 110 | sizeof(ul_jrand_seed)-sizeof(unsigned short)); 111 | } 112 | #endif 113 | 114 | return; 115 | } 116 | 117 | #ifdef TEST_PROGRAM 118 | int main(int argc __attribute__ ((__unused__)), 119 | char *argv[] __attribute__ ((__unused__))) 120 | { 121 | unsigned int v, i; 122 | 123 | /* generate and print 10 random numbers */ 124 | for (i = 0; i < 10; i++) { 125 | random_get_bytes(&v, sizeof(v)); 126 | printf("%d\n", v); 127 | } 128 | 129 | return EXIT_SUCCESS; 130 | } 131 | #endif /* TEST_PROGRAM */ 132 | -------------------------------------------------------------------------------- /third_party/libuuid/randutils.h: -------------------------------------------------------------------------------- 1 | #ifndef UTIL_LINUX_RANDUTILS 2 | #define UTIL_LINUX_RANDUTILS 3 | 4 | #ifdef HAVE_SRANDOM 5 | #define srand(x) srandom(x) 6 | #define rand() random() 7 | #endif 8 | 9 | extern int random_get_fd(void); 10 | extern void random_get_bytes(void *buf, size_t nbytes); 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /third_party/libuuid/unpack.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Internal routine for unpacking UUID 3 | * 4 | * Copyright (C) 1996, 1997 Theodore Ts'o. 5 | * 6 | * %Begin-Header% 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, and the entire permission notice in its entirety, 12 | * including the disclaimer of warranties. 13 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 3. The name of the author may not be used to endorse or promote 17 | * products derived from this software without specific prior 18 | * written permission. 19 | * 20 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 21 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 22 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF 23 | * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE 24 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 26 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 27 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 28 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 30 | * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH 31 | * DAMAGE. 32 | * %End-Header% 33 | */ 34 | 35 | #include 36 | #include "uuidP.h" 37 | 38 | void uuid_unpack(const uuid_t in, struct uuid *uu) 39 | { 40 | const uint8_t *ptr = in; 41 | uint32_t tmp; 42 | 43 | tmp = *ptr++; 44 | tmp = (tmp << 8) | *ptr++; 45 | tmp = (tmp << 8) | *ptr++; 46 | tmp = (tmp << 8) | *ptr++; 47 | uu->time_low = tmp; 48 | 49 | tmp = *ptr++; 50 | tmp = (tmp << 8) | *ptr++; 51 | uu->time_mid = tmp; 52 | 53 | tmp = *ptr++; 54 | tmp = (tmp << 8) | *ptr++; 55 | uu->time_hi_and_version = tmp; 56 | 57 | tmp = *ptr++; 58 | tmp = (tmp << 8) | *ptr++; 59 | uu->clock_seq = tmp; 60 | 61 | memcpy(uu->node, ptr, 6); 62 | } 63 | 64 | -------------------------------------------------------------------------------- /third_party/libuuid/unparse.c: -------------------------------------------------------------------------------- 1 | /* 2 | * unparse.c -- convert a UUID to string 3 | * 4 | * Copyright (C) 1996, 1997 Theodore Ts'o. 5 | * 6 | * %Begin-Header% 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, and the entire permission notice in its entirety, 12 | * including the disclaimer of warranties. 13 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 3. The name of the author may not be used to endorse or promote 17 | * products derived from this software without specific prior 18 | * written permission. 19 | * 20 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 21 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 22 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF 23 | * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE 24 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 26 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 27 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 28 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 30 | * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH 31 | * DAMAGE. 32 | * %End-Header% 33 | */ 34 | 35 | #include 36 | 37 | #include "uuidP.h" 38 | 39 | static const char *fmt_lower = 40 | "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x"; 41 | 42 | static const char *fmt_upper = 43 | "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X"; 44 | 45 | #ifdef UUID_UNPARSE_DEFAULT_UPPER 46 | #define FMT_DEFAULT fmt_upper 47 | #else 48 | #define FMT_DEFAULT fmt_lower 49 | #endif 50 | 51 | static void uuid_unparse_x(const uuid_t uu, char *out, const char *fmt) 52 | { 53 | struct uuid uuid; 54 | 55 | uuid_unpack(uu, &uuid); 56 | sprintf(out, fmt, 57 | uuid.time_low, uuid.time_mid, uuid.time_hi_and_version, 58 | uuid.clock_seq >> 8, uuid.clock_seq & 0xFF, 59 | uuid.node[0], uuid.node[1], uuid.node[2], 60 | uuid.node[3], uuid.node[4], uuid.node[5]); 61 | } 62 | 63 | void uuid_unparse_lower(const uuid_t uu, char *out) 64 | { 65 | uuid_unparse_x(uu, out, fmt_lower); 66 | } 67 | 68 | void uuid_unparse_upper(const uuid_t uu, char *out) 69 | { 70 | uuid_unparse_x(uu, out, fmt_upper); 71 | } 72 | 73 | void uuid_unparse(const uuid_t uu, char *out) 74 | { 75 | uuid_unparse_x(uu, out, FMT_DEFAULT); 76 | } 77 | -------------------------------------------------------------------------------- /third_party/libuuid/uuid.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Public include file for the UUID library 3 | * 4 | * Copyright (C) 1996, 1997, 1998 Theodore Ts'o. 5 | * 6 | * %Begin-Header% 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, and the entire permission notice in its entirety, 12 | * including the disclaimer of warranties. 13 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 3. The name of the author may not be used to endorse or promote 17 | * products derived from this software without specific prior 18 | * written permission. 19 | * 20 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 21 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 22 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF 23 | * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE 24 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 26 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 27 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 28 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 30 | * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH 31 | * DAMAGE. 32 | * %End-Header% 33 | */ 34 | 35 | #ifndef _UUID_UUID_H 36 | #define _UUID_UUID_H 37 | 38 | #include 39 | #ifndef _WIN32 40 | #include 41 | #endif 42 | #include 43 | 44 | typedef unsigned char uuid_t[16]; 45 | 46 | /* UUID Variant definitions */ 47 | #define UUID_VARIANT_NCS 0 48 | #define UUID_VARIANT_DCE 1 49 | #define UUID_VARIANT_MICROSOFT 2 50 | #define UUID_VARIANT_OTHER 3 51 | 52 | /* UUID Type definitions */ 53 | #define UUID_TYPE_DCE_TIME 1 54 | #define UUID_TYPE_DCE_RANDOM 4 55 | 56 | /* Allow UUID constants to be defined */ 57 | #ifdef __GNUC__ 58 | #define UUID_DEFINE(name,u0,u1,u2,u3,u4,u5,u6,u7,u8,u9,u10,u11,u12,u13,u14,u15) \ 59 | static const uuid_t name __attribute__ ((unused)) = {u0,u1,u2,u3,u4,u5,u6,u7,u8,u9,u10,u11,u12,u13,u14,u15} 60 | #else 61 | #define UUID_DEFINE(name,u0,u1,u2,u3,u4,u5,u6,u7,u8,u9,u10,u11,u12,u13,u14,u15) \ 62 | static const uuid_t name = {u0,u1,u2,u3,u4,u5,u6,u7,u8,u9,u10,u11,u12,u13,u14,u15} 63 | #endif 64 | 65 | #ifdef __cplusplus 66 | extern "C" { 67 | #endif 68 | 69 | /* clear.c */ 70 | void uuid_clear(uuid_t uu); 71 | 72 | /* compare.c */ 73 | int uuid_compare(const uuid_t uu1, const uuid_t uu2); 74 | 75 | /* copy.c */ 76 | void uuid_copy(uuid_t dst, const uuid_t src); 77 | 78 | /* gen_uuid.c */ 79 | void uuid_generate(uuid_t out); 80 | void uuid_generate_random(uuid_t out); 81 | void uuid_generate_time(uuid_t out); 82 | int uuid_generate_time_safe(uuid_t out); 83 | 84 | /* isnull.c */ 85 | int uuid_is_null(const uuid_t uu); 86 | 87 | /* parse.c */ 88 | int uuid_parse(const char *in, uuid_t uu); 89 | 90 | /* unparse.c */ 91 | void uuid_unparse(const uuid_t uu, char *out); 92 | void uuid_unparse_lower(const uuid_t uu, char *out); 93 | void uuid_unparse_upper(const uuid_t uu, char *out); 94 | 95 | /* uuid_time.c */ 96 | time_t uuid_time(const uuid_t uu, struct timeval *ret_tv); 97 | int uuid_type(const uuid_t uu); 98 | int uuid_variant(const uuid_t uu); 99 | 100 | #ifdef __cplusplus 101 | } 102 | #endif 103 | 104 | #endif /* _UUID_UUID_H */ 105 | -------------------------------------------------------------------------------- /third_party/libuuid/uuidP.h: -------------------------------------------------------------------------------- 1 | /* 2 | * uuid.h -- private header file for uuids 3 | * 4 | * Copyright (C) 1996, 1997 Theodore Ts'o. 5 | * 6 | * %Begin-Header% 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, and the entire permission notice in its entirety, 12 | * including the disclaimer of warranties. 13 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 3. The name of the author may not be used to endorse or promote 17 | * products derived from this software without specific prior 18 | * written permission. 19 | * 20 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 21 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 22 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF 23 | * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE 24 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 26 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 27 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 28 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 30 | * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH 31 | * DAMAGE. 32 | * %End-Header% 33 | */ 34 | 35 | #include 36 | #include 37 | 38 | #include "uuid.h" 39 | 40 | #define LIBUUID_CLOCK_FILE "/var/lib/libuuid/clock.txt" 41 | 42 | /* 43 | * Offset between 15-Oct-1582 and 1-Jan-70 44 | */ 45 | #define TIME_OFFSET_HIGH 0x01B21DD2 46 | #define TIME_OFFSET_LOW 0x13814000 47 | 48 | struct uuid { 49 | uint32_t time_low; 50 | uint16_t time_mid; 51 | uint16_t time_hi_and_version; 52 | uint16_t clock_seq; 53 | uint8_t node[6]; 54 | }; 55 | 56 | 57 | /* 58 | * prototypes 59 | */ 60 | void uuid_pack(const struct uuid *uu, uuid_t ptr); 61 | void uuid_unpack(const uuid_t in, struct uuid *uu); 62 | -------------------------------------------------------------------------------- /third_party/libuuid/uuidd.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Definitions used by the uuidd daemon 3 | * 4 | * Copyright (C) 2007 Theodore Ts'o. 5 | * 6 | * %Begin-Header% 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, and the entire permission notice in its entirety, 12 | * including the disclaimer of warranties. 13 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 3. The name of the author may not be used to endorse or promote 17 | * products derived from this software without specific prior 18 | * written permission. 19 | * 20 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 21 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 22 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF 23 | * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE 24 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 26 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 27 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 28 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 30 | * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH 31 | * DAMAGE. 32 | * %End-Header% 33 | */ 34 | 35 | #ifndef _UUID_UUIDD_H 36 | #define _UUID_UUIDD_H 37 | 38 | #define UUIDD_DIR _PATH_LOCALSTATEDIR "/uuidd" 39 | #define UUIDD_SOCKET_PATH UUIDD_DIR "/request" 40 | #define UUIDD_PIDFILE_PATH UUIDD_DIR "/uuidd.pid" 41 | #define UUIDD_PATH "/usr/sbin/uuidd" 42 | 43 | #define UUIDD_OP_GETPID 0 44 | #define UUIDD_OP_GET_MAXOP 1 45 | #define UUIDD_OP_TIME_UUID 2 46 | #define UUIDD_OP_RANDOM_UUID 3 47 | #define UUIDD_OP_BULK_TIME_UUID 4 48 | #define UUIDD_OP_BULK_RANDOM_UUID 5 49 | #define UUIDD_MAX_OP UUIDD_OP_BULK_RANDOM_UUID 50 | 51 | extern int __uuid_generate_time(uuid_t out, int *num); 52 | extern void __uuid_generate_random(uuid_t out, int *num); 53 | 54 | #endif /* _UUID_UUID_H */ 55 | --------------------------------------------------------------------------------