diff --git a/.github/workflows/deploy_release.yml b/.github/workflows/deploy_release.yml index 01d5c0f5..43f4d1c9 100644 --- a/.github/workflows/deploy_release.yml +++ b/.github/workflows/deploy_release.yml @@ -95,8 +95,8 @@ jobs: - uses: actions/download-artifact@v4 with: - name: cemu-bin-macos-x64 - path: cemu-bin-macos-x64 + pattern: cemu-bin-macos* + path: cemu-macos - name: Initialize run: | @@ -137,7 +137,12 @@ jobs: rm -r ./${{ env.CEMU_FOLDER_NAME }} - name: Create release from macos-bin - run: cp cemu-bin-macos-x64/Cemu.dmg upload/cemu-${{ env.CEMU_VERSION }}-macos-12-x64.dmg + run: | + cd cemu-macos + for bin_dir in cemu-bin-macos-*; do + arch="${bin_dir##cemu-bin-macos-}" + cp $bin_dir/Cemu.dmg ../upload/cemu-${{ env.CEMU_VERSION }}-macos-12-$arch.dmg + done - name: Create release from android-bin run: cp cemu-bin-android/*.apk upload/cemu-${{ env.CEMU_VERSION }}.apk diff --git a/BUILD.md b/BUILD.md index 2a2885ec..f9a951f3 100644 --- a/BUILD.md +++ b/BUILD.md @@ -21,6 +21,9 @@ - [Installing Library Dependencies](#installing-library-dependencies) - [Build Cemu using CMake](#build-cemu-using-cmake) - [Android](#android) +- [FreeBSD](#freebsd) + - [Installing Dependencies](#installing-dependencies) + - [Build Cemu on BSD with CMake](#build-cemu-on-bsd-with-cmake) - [Updating Cemu and source code](#updating-cemu-and-source-code) ## Windows @@ -196,6 +199,33 @@ Instructions: 2. Open the project located in `src/android` in Android Studio 3. Click Build > Make Project +## FreeBSD + +The following instructions to build Cemu on FreeBSD are experimental. Some features available on other platforms are not available on FreeBSD (discord rich presence, bluetooth/support for actual Wii U controllers, auto-updates, etc.) + +To compile Cemu, a recent enough compiler and STL with C++20 support is required! Clang-15 or higher is what we recommend. Any version of FreeBSD 13.3-RELEASE or higher comes bundled with LLVM > version 15 as part of the base system. However, if for whatever reason your system lacks a recent version of LLVM you can install one by executing: + +`sudo pkg install llvm15` + +Or a higher version as desired. + +### Installing Dependencies + +`sudo pkg install boost-libs cmake-core curl glslang gtk3 libzip ninja png pkgconf pugixml rapidjson sdl2 wayland wayland-protocols wx32-gtk3 xorg zstd` + +### Build Cemu on BSD with CMake + +``` +git clone --recursive https://github.com/cemu-project/Cemu +cd Cemu +cmake -B build -DCMAKE_BUILD_TYPE=release -DENABLE_BLUEZ=OFF -DENABLE_DISCORD_RPC=OFF -DENABLE_FERAL_GAMEMODE=OFF -DENABLE_HIDAPI=OFF -DENABLE_VCPKG=OFF -G Ninja +cmake --build build + +cd build && ninja install +``` + +You should now have a Cemu executable file in the /bin folder, which you can run using `./bin/Cemu_release`. + ## Updating Cemu and source code 1. To update your Cemu local repository, use the command `git pull --recurse-submodules` (run this command on the Cemu root). - This should update your local copy of Cemu and all of its dependencies. diff --git a/CMakeLists.txt b/CMakeLists.txt index 270b4bd4..6dbbb759 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -38,11 +38,11 @@ if (ENABLE_VCPKG) if(UNIX AND NOT APPLE AND NOT VCPKG_TARGET_ANDROID) - set(VCPKG_OVERLAY_PORTS "${CMAKE_CURRENT_LIST_DIR}/dependencies/vcpkg_overlay_ports_linux") + set(VCPKG_OVERLAY_PORTS "${CMAKE_CURRENT_LIST_DIR}/dependencies/vcpkg_overlay_ports_linux;${CMAKE_CURRENT_LIST_DIR}/dependencies/vcpkg_overlay_ports") elseif(APPLE) - set(VCPKG_OVERLAY_PORTS "${CMAKE_CURRENT_LIST_DIR}/dependencies/vcpkg_overlay_ports_mac") + set(VCPKG_OVERLAY_PORTS "${CMAKE_CURRENT_LIST_DIR}/dependencies/vcpkg_overlay_ports_mac;${CMAKE_CURRENT_LIST_DIR}/dependencies/vcpkg_overlay_ports") else() - set(VCPKG_OVERLAY_PORTS "${CMAKE_CURRENT_LIST_DIR}/dependencies/vcpkg_overlay_ports") + set(VCPKG_OVERLAY_PORTS "${CMAKE_CURRENT_LIST_DIR}/dependencies/vcpkg_overlay_ports_win;${CMAKE_CURRENT_LIST_DIR}/dependencies/vcpkg_overlay_ports") endif() if(VCPKG_TARGET_ANDROID) set(ENV{ANDROID_NDK_HOME} ${ANDROID_NDK}) @@ -172,7 +172,7 @@ if (UNIX AND NOT APPLE AND NOT ANDROID) BASENAME viewporter) add_library(CemuWaylandProtocols STATIC ${WAYLAND_PROTOCOL_SRCS}) target_include_directories(CemuWaylandProtocols PUBLIC "${CMAKE_CURRENT_BINARY_DIR}") - + target_include_directories(CemuWaylandProtocols PRIVATE ${Wayland_INCLUDE_DIRS}) add_compile_definitions(HAS_WAYLAND) endif() find_package(GTK3 REQUIRED) @@ -195,8 +195,6 @@ endif() if (ENABLE_DISCORD_RPC) add_compile_definitions(ENABLE_DISCORD_RPC) - add_subdirectory(dependencies/discord-rpc EXCLUDE_FROM_ALL) - target_include_directories(discord-rpc INTERFACE ./dependencies/discord-rpc/include) endif() if (ENABLE_HIDAPI) @@ -214,7 +212,7 @@ if(UNIX AND NOT APPLE AND NOT ANDROID) endif() if (ENABLE_WXWIDGETS) - find_package(wxWidgets 3.2 REQUIRED COMPONENTS base core gl propgrid xrc) + find_package(wxWidgets 3.3 REQUIRED COMPONENTS base core gl propgrid xrc) endif() if (ENABLE_CUBEB) @@ -257,4 +255,4 @@ if(ANDROID) add_subdirectory("dependencies/stb" EXCLUDE_FROM_ALL) endif() -add_subdirectory(src) \ No newline at end of file +add_subdirectory(src) diff --git a/dependencies/discord-rpc/.clang-format b/dependencies/discord-rpc/.clang-format deleted file mode 100644 index 1be83906..00000000 --- a/dependencies/discord-rpc/.clang-format +++ /dev/null @@ -1,92 +0,0 @@ ---- -AccessModifierOffset: -4 -AlignAfterOpenBracket: true -AlignConsecutiveAssignments: false -AlignConsecutiveDeclarations: false -AlignEscapedNewlines: Left -AlignOperands: false -AlignTrailingComments: true -AllowAllParametersOfDeclarationOnNextLine: false -AllowShortBlocksOnASingleLine: false -AllowShortCaseLabelsOnASingleLine: false -AllowShortFunctionsOnASingleLine: InlineOnly -AllowShortIfStatementsOnASingleLine: false -AllowShortLoopsOnASingleLine: false -AlwaysBreakAfterReturnType: None -AlwaysBreakBeforeMultilineStrings: false -AlwaysBreakTemplateDeclarations: true -BinPackArguments: false -BinPackParameters: false -BreakBeforeBinaryOperators: None -BreakBeforeBraces: Stroustrup -BreakBeforeInheritanceComma: true -BreakBeforeTernaryOperators: true -BreakConstructorInitializers: BeforeComma -BreakStringLiterals: true -ColumnLimit: 100 -CommentPragmas: '' -CompactNamespaces: false -ConstructorInitializerAllOnOneLineOrOnePerLine: false -ConstructorInitializerIndentWidth: 2 -ContinuationIndentWidth: 2 -Cpp11BracedListStyle: true -DerivePointerAlignment: false -DisableFormat: false -FixNamespaceComments: true -ForEachMacros: [] -IndentCaseLabels: false -IncludeCategories: - - Regex: '^("|<)stdafx\.h(pp)?("|>)' - Priority: -1 - - Regex: '^<(W|w)indows.h>' - Priority: 1 - - Regex: '^<' - Priority: 2 - - Regex: '.*' - Priority: 3 -IncludeIsMainRegex: '(_test|_win|_linux|_mac|_ios|_osx|_null)?$' -IndentCaseLabels: false -IndentWidth: 4 -IndentWrappedFunctionNames: false -KeepEmptyLinesAtTheStartOfBlocks: false -MacroBlockBegin: '' -MacroBlockEnd: '' -MaxEmptyLinesToKeep: 1 -NamespaceIndentation: None -PenaltyBreakAssignment: 0 -PenaltyBreakBeforeFirstCallParameter: 1 -PenaltyBreakComment: 300 -PenaltyBreakFirstLessLess: 120 -PenaltyBreakString: 1000 -PenaltyExcessCharacter: 1000000 -PenaltyReturnTypeOnItsOwnLine: 9999999 -PointerAlignment: Left -ReflowComments: true -SortIncludes: false -SortUsingDeclarations: true -SpaceAfterCStyleCast: false -SpaceAfterTemplateKeyword: true -SpaceBeforeAssignmentOperators: true -SpaceBeforeParens: ControlStatements -SpaceInEmptyParentheses: false -SpacesBeforeTrailingComments: 1 -SpacesInAngles: false -SpacesInCStyleCastParentheses: false -SpacesInContainerLiterals: true -SpacesInParentheses: false -SpacesInSquareBrackets: false -Standard: Cpp11 -TabWidth: 4 -UseTab: Never ---- -Language: Cpp ---- -Language: ObjC -ObjCBlockIndentWidth: 4 -ObjCSpaceAfterProperty: true -ObjCSpaceBeforeProtocolList: false ---- -Language: Java -BasedOnStyle: Google -BreakAfterJavaFieldAnnotations: true -... diff --git a/dependencies/discord-rpc/.gitignore b/dependencies/discord-rpc/.gitignore deleted file mode 100644 index 223c07d7..00000000 --- a/dependencies/discord-rpc/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -/build*/ -/.vscode/ -/thirdparty/ -.vs/ -.DS_Store \ No newline at end of file diff --git a/dependencies/discord-rpc/.travis.yml b/dependencies/discord-rpc/.travis.yml deleted file mode 100644 index 42cc09d5..00000000 --- a/dependencies/discord-rpc/.travis.yml +++ /dev/null @@ -1,47 +0,0 @@ -language: cpp - -env: - global: - - CLANG_FORMAT_SUFFIX="-dummy" # don't use formatting on Travis, this is - # needed not to use default 3.5 version - # which is too old. - -matrix: - include: - - os: linux - env: MATRIX_EVAL="CC=gcc-5 && CXX=g++-5" - addons: - apt: - sources: - - ubuntu-toolchain-r-test - packages: - - g++-5 - - os: linux - env: MATRIX_EVAL="CC=clang-4.0 && CXX=clang++-4.0" - addons: - apt: - sources: - - llvm-toolchain-trusty-4.0 - packages: - - clang-4.0 - - os: linux - env: MATRIX_EVAL="CC=clang-5.0 && CXX=clang++-5.0" - addons: - apt: - sources: - - llvm-toolchain-trusty-5.0 - packages: - - clang-5.0 - - os: osx - osx_image: xcode9 - -# prevent Travis from overwriting our CXX variables -before_install: - - eval "${MATRIX_EVAL}" - - echo $CXX - -script: - - mkdir build - - cd build - - cmake -DCLANG_FORMAT_SUFFIX=$CLANG_FORMAT_SUFFIX -DWARNINGS_AS_ERRORS=On --config Release .. - - cmake --build . -- -j2 diff --git a/dependencies/discord-rpc/CMakeLists.txt b/dependencies/discord-rpc/CMakeLists.txt deleted file mode 100644 index 4aa11080..00000000 --- a/dependencies/discord-rpc/CMakeLists.txt +++ /dev/null @@ -1,42 +0,0 @@ -cmake_minimum_required (VERSION 3.2.0) -project (DiscordRPC) - -include(GNUInstallDirs) - -option(BUILD_EXAMPLES "Build example apps" OFF) - -# format -file(GLOB_RECURSE ALL_SOURCE_FILES - examples/*.cpp examples/*.h examples/*.c - include/*.h - src/*.cpp src/*.h src/*.c -) - -# thirdparty stuff -execute_process( - COMMAND mkdir ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty - ERROR_QUIET -) - -#find_file(RAPIDJSONTEST NAMES rapidjson rapidjson-1.1.0 PATHS ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty CMAKE_FIND_ROOT_PATH_BOTH) -#if (NOT RAPIDJSONTEST) -# message("no rapidjson, download") -# set(RJ_TAR_FILE ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/v1.1.0.tar.gz) -# file(DOWNLOAD https://github.com/miloyip/rapidjson/archive/v1.1.0.tar.gz ${RJ_TAR_FILE}) -# execute_process( -# COMMAND ${CMAKE_COMMAND} -E tar xzf ${RJ_TAR_FILE} -# WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty -# ) -# file(REMOVE ${RJ_TAR_FILE}) -#endif(NOT RAPIDJSONTEST) - -#find_file(RAPIDJSON NAMES rapidjson rapidjson-1.1.0 PATHS ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty CMAKE_FIND_ROOT_PATH_BOTH) - -#add_library(rapidjson STATIC IMPORTED ${RAPIDJSON}) - -# add subdirs - -add_subdirectory(src) -if (BUILD_EXAMPLES) - add_subdirectory(examples/send-presence) -endif(BUILD_EXAMPLES) diff --git a/dependencies/discord-rpc/LICENSE b/dependencies/discord-rpc/LICENSE deleted file mode 100644 index 17fca3d5..00000000 --- a/dependencies/discord-rpc/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -Copyright 2017 Discord, Inc. - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/dependencies/discord-rpc/README.md b/dependencies/discord-rpc/README.md deleted file mode 100644 index 1285fb84..00000000 --- a/dependencies/discord-rpc/README.md +++ /dev/null @@ -1,158 +0,0 @@ -# Discord RPC - -## Deprecation Notice - -This library has been deprecated in favor of Discord's GameSDK. [Learn more here](https://discordapp.com/developers/docs/game-sdk/sdk-starter-guide) - ---- - -This is a library for interfacing your game with a locally running Discord desktop client. It's known to work on Windows, macOS, and Linux. You can use the lib directly if you like, or use it as a guide to writing your own if it doesn't suit your game as is. PRs/feedback welcome if you have an improvement everyone might want, or can describe how this doesn't meet your needs. - -Included here are some quick demos that implement the very minimal subset to show current status, and -have callbacks for where a more complete game would do more things (joining, spectating, etc). - -## Documentation - -The most up to date documentation for Rich Presence can always be found on our [developer site](https://discordapp.com/developers/docs/rich-presence/how-to)! If you're interested in rolling your own native implementation of Rich Presence via IPC sockets instead of using our SDK—hey, you've got free time, right?—check out the ["Hard Mode" documentation](https://github.com/discordapp/discord-rpc/blob/master/documentation/hard-mode.md). - -## Basic Usage - -Zeroith, you should be set up to build things because you are a game developer, right? - -First, head on over to the [Discord developers site](https://discordapp.com/developers/applications/me) and make yourself an app. Keep track of `Client ID` -- you'll need it here to pass to the init function. - -### Unreal Engine 4 Setup - -To use the Rich Presense plugin with Unreal Engine Projects: - -1. Download the latest [release](https://github.com/discordapp/discord-rpc/releases) for each operating system you are targeting and the zipped source code -2. In the source code zip, copy the UE plugin—`examples/unrealstatus/Plugins/discordrpc`—to your project's plugin directory -3. At `[YOUR_UE_PROJECT]/Plugins/discordrpc/source/ThirdParty/DiscordRpcLibrary/`, create an `Include` folder and copy `discord_rpc.h` and `discord_register.h` to it from the zip -4. Follow the steps below for each OS -5. Build your UE4 project -6. Launch the editor, and enable the Discord plugin. - -#### Windows - -- At `[YOUR_UE_PROJECT]/Plugins/discordrpc/source/ThirdParty/DiscordRpcLibrary/`, create a `Win64` folder -- Copy `lib/discord-rpc.lib` and `bin/discord-rpc.dll` from `[RELEASE_ZIP]/win64-dynamic` to the `Win64` folder - -#### Mac - -- At `[YOUR_UE_PROJECT]/Plugins/discordrpc/source/ThirdParty/DiscordRpcLibrary/`, create a `Mac` folder -- Copy `libdiscord-rpc.dylib` from `[RELEASE_ZIP]/osx-dynamic/lib` to the `Mac` folder - -#### Linux - -- At `[YOUR_UE_PROJECT]/Plugins/discordrpc/source/ThirdParty/DiscordRpcLibrary/`, create a `Linux` folder -- Inside, create another folder `x86_64-unknown-linux-gnu` -- Copy `libdiscord-rpc.so` from `[RELEASE_ZIP]/linux-dynamic/lib` to `Linux/x86_64-unknown-linux-gnu` - -### Unity Setup - -If you're a Unity developer looking to integrate Rich Presence into your game, follow this simple guide to get started towards success: - -1. Download the DLLs for any platform that you need from [our releases](https://github.com/discordapp/discord-rpc/releases) -2. In your Unity project, create a `Plugins` folder inside your `Assets` folder if you don't already have one -3. Copy the file `DiscordRpc.cs` from [here](https://github.com/discordapp/discord-rpc/blob/master/examples/button-clicker/Assets/DiscordRpc.cs) into your `Assets` folder. This is basically your header file for the SDK - -We've got our `Plugins` folder ready, so let's get platform-specific! - -#### Windows - -4. Create `x86` and `x86_64` folders inside `Assets/Plugins/` -5. Copy `discord-rpc-win/win64-dynamic/bin/discord-rpc.dll` to `Assets/Plugins/x86_64/` -6. Copy `discord-rpc-win/win32-dynamic/bin/discord-rpc.dll` to `Assets/Plugins/x86/` -7. Click on both DLLs and make sure they are targetting the correct architectures in the Unity editor properties pane -8. Done! - -#### MacOS - -4. Copy `discord-rpc-osx/osx-dynamic/lib/libdiscord-rpc.dylib` to `Assets/Plugins/` -5. Rename `libdiscord-rpc.dylib` to `discord-rpc.bundle` -6. Done! - -#### Linux - -4. Copy `discord-rpc-linux/linux-dynamic-lib/libdiscord-rpc.so` to `Assets/Plugins/` -5. Done! - -You're ready to roll! For code examples on how to interact with the SDK using the `DiscordRpc.cs` header file, check out [our example](https://github.com/discordapp/discord-rpc/blob/master/examples/button-clicker/Assets/DiscordController.cs) - -### From package - -Download a release package for your platform(s) -- they have subdirs with various prebuilt options, select the one you need add `/include` to your compile includes, `/lib` to your linker paths, and link with `discord-rpc`. For the dynamically linked builds, you'll need to ship the associated file along with your game. - -### From repo - -First-eth, you'll want `CMake`. There's a few different ways to install it on your system, and you should refer to [their website](https://cmake.org/install/). Many package managers provide ways of installing CMake as well. - -To make sure it's installed correctly, type `cmake --version` into your flavor of terminal/cmd. If you get a response with a version number, you're good to go! - -There's a [CMake](https://cmake.org/download/) file that should be able to generate the lib for you; Sometimes I use it like this: - -```sh - cd - mkdir build - cd build - cmake .. -DCMAKE_INSTALL_PREFIX= - cmake --build . --config Release --target install -``` - -There is a wrapper build script `build.py` that runs `cmake` with a few different options. - -Usually, I run `build.py` to get things started, then use the generated project files as I work on things. It does depend on `click` library, so do a quick `pip install click` to make sure you have it if you want to run `build.py`. - -There are some CMake options you might care about: - -| flag | default | does | -| ---------------------------------------------------------------------------------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | -| `ENABLE_IO_THREAD` | `ON` | When enabled, we start up a thread to do io processing, if disabled you should call `Discord_UpdateConnection` yourself. | -| `USE_STATIC_CRT` | `OFF` | (Windows) Enable to statically link the CRT, avoiding requiring users install the redistributable package. (The prebuilt binaries enable this option) | -| [`BUILD_SHARED_LIBS`](https://cmake.org/cmake/help/v3.7/variable/BUILD_SHARED_LIBS.html) | `OFF` | Build library as a DLL | -| `WARNINGS_AS_ERRORS` | `OFF` | When enabled, compiles with `-Werror` (on \*nix platforms). | - -## Continuous Builds - -Why do we have three of these? Three times the fun! - -| CI | badge | -| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | -| TravisCI | [![Build status](https://travis-ci.org/discordapp/discord-rpc.svg?branch=master)](https://travis-ci.org/discordapp/discord-rpc) | -| AppVeyor | [![Build status](https://ci.appveyor.com/api/projects/status/qvkoc0w1c4f4b8tj?svg=true)](https://ci.appveyor.com/project/crmarsh/discord-rpc) | -| Buildkite (internal) | [![Build status](https://badge.buildkite.com/e103d79d247f6776605a15246352a04b8fd83d69211b836111.svg)](https://buildkite.com/discord/discord-rpc) | - -## Sample: send-presence - -This is a text adventure "game" that inits/deinits the connection to Discord, and sends a presence update on each command. - -## Sample: button-clicker - -This is a sample [Unity](https://unity3d.com/) project that wraps a DLL version of the library, and sends presence updates when you click on a button. Run `python build.py unity` in the root directory to build the correct library files and place them in their respective folders. - -## Sample: unrealstatus - -This is a sample [Unreal](https://www.unrealengine.com) project that wraps the DLL version of the library with an Unreal plugin, exposes a blueprint class for interacting with it, and uses that to make a very simple UI. Run `python build.py unreal` in the root directory to build the correct library files and place them in their respective folders. - -## Wrappers and Implementations - -Below is a table of unofficial, community-developed wrappers for and implementations of Rich Presence in various languages. If you would like to have yours added, please make a pull request adding your repository to the table. The repository should include: - -- The code -- A brief ReadMe of how to use it -- A working example - -###### Rich Presence Wrappers and Implementations - -| Name | Language | -| ------------------------------------------------------------------------- | --------------------------------- | -| [Discord RPC C#](https://github.com/Lachee/discord-rpc-csharp) | C# | -| [Discord RPC D](https://github.com/voidblaster/discord-rpc-d) | [D](https://dlang.org/) | -| [discord-rpc.jar](https://github.com/Vatuu/discord-rpc 'Discord-RPC.jar') | Java | -| [java-discord-rpc](https://github.com/MinnDevelopment/java-discord-rpc) | Java | -| [Discord-IPC](https://github.com/jagrosh/DiscordIPC) | Java | -| [Discord Rich Presence](https://npmjs.org/discord-rich-presence) | JavaScript | -| [drpc4k](https://github.com/Bluexin/drpc4k) | [Kotlin](https://kotlinlang.org/) | -| [lua-discordRPC](https://github.com/pfirsich/lua-discordRPC) | LuaJIT (FFI) | -| [pypresence](https://github.com/qwertyquerty/pypresence) | [Python](https://python.org/) | -| [SwordRPC](https://github.com/Azoy/SwordRPC) | [Swift](https://swift.org) | diff --git a/dependencies/discord-rpc/appveyor.yml b/dependencies/discord-rpc/appveyor.yml deleted file mode 100644 index 1c328b87..00000000 --- a/dependencies/discord-rpc/appveyor.yml +++ /dev/null @@ -1,17 +0,0 @@ -version: '{build}' -install: - - python -m pip install click - -build_script: - - mkdir examples\unrealstatus\Plugins\discordrpc\Binaries\ThirdParty\discordrpcLibrary\Win64 - - python build.py - -artifacts: -- path: builds\install\win32-dynamic - name: win32-dynamic -- path: builds\install\win32-static - name: win32-static -- path: builds\install\win64-dynamic - name: win64-dynamic -- path: builds\install\win64-static - name: win64-static diff --git a/dependencies/discord-rpc/build.py b/dependencies/discord-rpc/build.py deleted file mode 100644 index 215d3586..00000000 --- a/dependencies/discord-rpc/build.py +++ /dev/null @@ -1,304 +0,0 @@ -#!/usr/bin/env python - -import os -import subprocess -import sys -import shutil -import zipfile -from contextlib import contextmanager -import click - - -def get_platform(): - """ a name for the platform """ - if sys.platform.startswith('win'): - return 'win' - elif sys.platform == 'darwin': - return 'osx' - elif sys.platform.startswith('linux'): - return 'linux' - raise Exception('Unsupported platform ' + sys.platform) - - -SCRIPT_PATH = os.path.dirname(os.path.abspath(__file__)) -# we use Buildkite which sets this env variable by default -IS_BUILD_MACHINE = os.environ.get('CI', '') == 'true' -PLATFORM = get_platform() -INSTALL_ROOT = os.path.join(SCRIPT_PATH, 'builds', 'install') - - -def get_signtool(): - """ get path to code signing tool """ - if PLATFORM == 'win': - sdk_dir = 'c:\\Program Files (x86)\\Windows Kits\\10' # os.environ['WindowsSdkDir'] - return os.path.join(sdk_dir, 'bin', 'x86', 'signtool.exe') - elif PLATFORM == 'osx': - return '/usr/bin/codesign' - - -@contextmanager -def cd(new_dir): - """ Temporarily change current directory """ - if new_dir: - old_dir = os.getcwd() - os.chdir(new_dir) - yield - if new_dir: - os.chdir(old_dir) - - -def mkdir_p(path): - """ mkdir -p """ - if not os.path.isdir(path): - click.secho('Making ' + path, fg='yellow') - os.makedirs(path) - - -@click.group(invoke_without_command=True) -@click.pass_context -@click.option('--clean', is_flag=True) -def cli(ctx, clean): - """ click wrapper for command line stuff """ - if ctx.invoked_subcommand is None: - ctx.invoke(libs, clean=clean) - if IS_BUILD_MACHINE: - ctx.invoke(sign) - ctx.invoke(archive) - - -@cli.command() -@click.pass_context -def unity(ctx): - """ build just dynamic libs for use in unity project """ - ctx.invoke(libs, clean=False, static=False, shared=True, skip_formatter=True, just_release=True) - BUILDS = [] - - click.echo('--- Copying libs and header into unity example') - UNITY_PROJECT_PATH = os.path.join(SCRIPT_PATH, 'examples', 'button-clicker', 'Assets', 'Plugins') - - if sys.platform.startswith('win'): - LIBRARY_NAME = 'discord-rpc.dll' - BUILD_64_BASE_PATH = os.path.join(SCRIPT_PATH, 'builds', 'win64-dynamic', 'src', 'Release') - UNITY_64_DLL_PATH = os.path.join(UNITY_PROJECT_PATH, 'x86_64') - BUILDS.append({BUILD_64_BASE_PATH: UNITY_64_DLL_PATH}) - - BUILD_32_BASE_PATH = os.path.join(SCRIPT_PATH, 'builds', 'win32-dynamic', 'src', 'Release') - UNITY_32_DLL_PATH = os.path.join(UNITY_PROJECT_PATH, 'x86') - BUILDS.append({BUILD_32_BASE_PATH: UNITY_32_DLL_PATH}) - - elif sys.platform == 'darwin': - LIBRARY_NAME = 'discord-rpc.bundle' - BUILD_BASE_PATH = os.path.join(SCRIPT_PATH, 'builds', 'osx-dynamic', 'src') - UNITY_DLL_PATH = UNITY_PROJECT_PATH - os.rename( - os.path.join(BUILD_BASE_PATH, 'libdiscord-rpc.dylib'), os.path.join(BUILD_BASE_PATH, 'discord-rpc.bundle')) - - BUILDS.append({BUILD_BASE_PATH: UNITY_DLL_PATH}) - - elif sys.platform.startswith('linux'): - LIBRARY_NAME = 'discord-rpc.so' - BUILD_BASE_PATH = os.path.join(SCRIPT_PATH, 'builds', 'linux-dynamic', 'src') - UNITY_DLL_PATH = os.path.join(UNITY_PROJECT_PATH, 'x86') - os.rename(os.path.join(BUILD_BASE_PATH, 'libdiscord-rpc.so'), os.path.join(BUILD_BASE_PATH, 'discord-rpc.so')) - - BUILDS.append({BUILD_BASE_PATH: UNITY_DLL_PATH}) - - else: - raise Exception('Unsupported platform ' + sys.platform) - - for build in BUILDS: - for i in build: - mkdir_p(build[i]) - shutil.copy(os.path.join(i, LIBRARY_NAME), build[i]) - - -@cli.command() -@click.pass_context -def unreal(ctx): - """ build libs and copy them into the unreal project """ - ctx.invoke(libs, clean=False, static=False, shared=True, skip_formatter=True, just_release=True) - BUILDS = [] - - click.echo('--- Copying libs and header into unreal example') - UNREAL_PROJECT_PATH = os.path.join(SCRIPT_PATH, 'examples', 'unrealstatus', 'Plugins', 'discordrpc') - UNREAL_INCLUDE_PATH = os.path.join(UNREAL_PROJECT_PATH, 'Source', 'ThirdParty', 'DiscordRpcLibrary', 'Include') - mkdir_p(UNREAL_INCLUDE_PATH) - shutil.copy(os.path.join(SCRIPT_PATH, 'include', 'discord_rpc.h'), UNREAL_INCLUDE_PATH) - - if sys.platform.startswith('win'): - LIBRARY_NAME = 'discord-rpc.lib' - BUILD_64_BASE_PATH = os.path.join(SCRIPT_PATH, 'builds', 'win64-dynamic', 'src', 'Release') - UNREAL_64_DLL_PATH = os.path.join(UNREAL_PROJECT_PATH, 'Source', 'ThirdParty', 'DiscordRpcLibrary', 'Win64') - BUILDS.append({BUILD_64_BASE_PATH: UNREAL_64_DLL_PATH}) - - BUILD_32_BASE_PATH = os.path.join(SCRIPT_PATH, 'builds', 'win32-dynamic', 'src', 'Release') - UNREAL_32_DLL_PATH = os.path.join(UNREAL_PROJECT_PATH, 'Source', 'ThirdParty', 'DiscordRpcLibrary', 'Win32') - BUILDS.append({BUILD_32_BASE_PATH: UNREAL_32_DLL_PATH}) - - elif sys.platform == 'darwin': - LIBRARY_NAME = 'libdiscord-rpc.dylib' - BUILD_BASE_PATH = os.path.join(SCRIPT_PATH, 'builds', 'osx-dynamic', 'src') - UNREAL_DLL_PATH = os.path.join(UNREAL_PROJECT_PATH, 'Source', 'ThirdParty', 'DiscordRpcLibrary', 'Mac') - - BUILDS.append({BUILD_BASE_PATH: UNREAL_DLL_PATH}) - - elif sys.platform.startswith('linux'): - LIBRARY_NAME = 'libdiscord-rpc.so' - BUILD_BASE_PATH = os.path.join(SCRIPT_PATH, 'builds', 'linux-dynamic', 'src') - UNREAL_DLL_PATH = os.path.join(UNREAL_PROJECT_PATH, 'Source', 'ThirdParty', 'DiscordRpcLibrary', 'Linux') - - BUILDS.append({BUILD_BASE_PATH: UNREAL_DLL_PATH}) - - else: - raise Exception('Unsupported platform ' + sys.platform) - - for build in BUILDS: - for i in build: - mkdir_p(build[i]) - shutil.copy(os.path.join(i, LIBRARY_NAME), build[i]) - - -def build_lib(build_name, generator, options, just_release): - """ Create a dir under builds, run build and install in it """ - build_path = os.path.join(SCRIPT_PATH, 'builds', build_name) - install_path = os.path.join(INSTALL_ROOT, build_name) - mkdir_p(build_path) - mkdir_p(install_path) - with cd(build_path): - initial_cmake = ['cmake', SCRIPT_PATH, '-DCMAKE_INSTALL_PREFIX=%s' % os.path.join('..', 'install', build_name)] - if generator: - initial_cmake.extend(['-G', generator]) - for key in options: - val = options[key] - if type(val) is bool: - val = 'ON' if val else 'OFF' - initial_cmake.append('-D%s=%s' % (key, val)) - click.echo('--- Building ' + build_name) - subprocess.check_call(initial_cmake) - if not just_release: - subprocess.check_call(['cmake', '--build', '.', '--config', 'Debug']) - subprocess.check_call(['cmake', '--build', '.', '--config', 'Release', '--target', 'install']) - - -@cli.command() -def archive(): - """ create zip of install dir """ - click.echo('--- Archiving') - archive_file_path = os.path.join(SCRIPT_PATH, 'builds', 'discord-rpc-%s.zip' % get_platform()) - archive_file = zipfile.ZipFile(archive_file_path, 'w', zipfile.ZIP_DEFLATED) - archive_src_base_path = INSTALL_ROOT - archive_dst_base_path = 'discord-rpc' - with cd(archive_src_base_path): - for path, _, filenames in os.walk('.'): - for fname in filenames: - fpath = os.path.join(path, fname) - dst_path = os.path.normpath(os.path.join(archive_dst_base_path, fpath)) - click.echo('Adding ' + dst_path) - archive_file.write(fpath, dst_path) - - -@cli.command() -def sign(): - """ Do code signing within install directory using our cert """ - tool = get_signtool() - signable_extensions = set() - if PLATFORM == 'win': - signable_extensions.add('.dll') - sign_command_base = [ - tool, - 'sign', - '/n', - 'Discord Inc.', - '/a', - '/tr', - 'http://timestamp.digicert.com/rfc3161', - '/as', - '/td', - 'sha256', - '/fd', - 'sha256', - ] - elif PLATFORM == 'osx': - signable_extensions.add('.dylib') - sign_command_base = [ - tool, - '--keychain', - os.path.expanduser('~/Library/Keychains/login.keychain'), - '-vvvv', - '--deep', - '--force', - '--sign', - 'Developer ID Application: Hammer & Chisel Inc. (53Q6R32WPB)', - ] - else: - click.secho('Not signing things on this platform yet', fg='red') - return - - click.echo('--- Signing') - for path, _, filenames in os.walk(INSTALL_ROOT): - for fname in filenames: - ext = os.path.splitext(fname)[1] - if ext not in signable_extensions: - continue - fpath = os.path.join(path, fname) - click.echo('Sign ' + fpath) - sign_command = sign_command_base + [fpath] - subprocess.check_call(sign_command) - - -@cli.command() -@click.option('--clean', is_flag=True) -@click.option('--static', is_flag=True) -@click.option('--shared', is_flag=True) -@click.option('--skip_formatter', is_flag=True) -@click.option('--just_release', is_flag=True) -def libs(clean, static, shared, skip_formatter, just_release): - """ Do all the builds for this platform """ - if clean: - shutil.rmtree('builds', ignore_errors=True) - - mkdir_p('builds') - - if not (static or shared): - static = True - shared = True - - static_options = {} - dynamic_options = { - 'BUILD_SHARED_LIBS': True, - 'USE_STATIC_CRT': True, - } - - if skip_formatter or IS_BUILD_MACHINE: - static_options['CLANG_FORMAT_SUFFIX'] = 'none' - dynamic_options['CLANG_FORMAT_SUFFIX'] = 'none' - - if IS_BUILD_MACHINE: - just_release = True - static_options['WARNINGS_AS_ERRORS'] = True - dynamic_options['WARNINGS_AS_ERRORS'] = True - - if PLATFORM == 'win': - generator32 = 'Visual Studio 14 2015' - generator64 = 'Visual Studio 14 2015 Win64' - if static: - build_lib('win32-static', generator32, static_options, just_release) - build_lib('win64-static', generator64, static_options, just_release) - if shared: - build_lib('win32-dynamic', generator32, dynamic_options, just_release) - build_lib('win64-dynamic', generator64, dynamic_options, just_release) - elif PLATFORM == 'osx': - if static: - build_lib('osx-static', None, static_options, just_release) - if shared: - build_lib('osx-dynamic', None, dynamic_options, just_release) - elif PLATFORM == 'linux': - if static: - build_lib('linux-static', None, static_options, just_release) - if shared: - build_lib('linux-dynamic', None, dynamic_options, just_release) - - -if __name__ == '__main__': - os.chdir(SCRIPT_PATH) - sys.exit(cli()) diff --git a/dependencies/discord-rpc/documentation/hard-mode.md b/dependencies/discord-rpc/documentation/hard-mode.md deleted file mode 100644 index 35042cbc..00000000 --- a/dependencies/discord-rpc/documentation/hard-mode.md +++ /dev/null @@ -1,164 +0,0 @@ -# Hard Mode: Roll Your Own Client - -Discord's Rich Presence feature is designed as an obfuscated addition to our existing [RPC infrastructure](https://discordapp.com/developers/docs/topics/rpc). The standalone library and header files make it easy for any dev to drop it into their game. - -Our library communicates with Discord over the local Discord RPC socket. We've already done the work in connecting properly, handling disconnects and reconnects, and other RPC intracacies, but those who have done this implementation for our private alpha Voice and Chat SDK can simply make use of the new RPC commands and events to implement Rich Presence. - -## Hark! A warning! - -By committing to an RPC-only integration, you decide to forego the work our library and header file have done for you in the way of error handling, state storage, disconnecting and reconnecting, and other quality of life abstractions. While simply implementing the new RPC command and events will enable Rich Presence for your game, we highly suggest that you do your best to mimic the functionality of the SDK the most that you can. It ensure not only code quality on your part, but also an excellent experience on the part of your players. - -## Application Protocol Registration - -One thing that cannot be explicitly done over RPC is registering an application protocol for your game. If you choose to do an RPC-only implementation, you will have to register your application protocol yourself in the format of `discord-[your_app_id]://`. You can use `Discord_Register()` as a good(?) example of how to properly register an application protocol for use with Discord. For OSX and Linux it is probably simpler to handle the protocol registration as part of your install/packaging. - -## New RPC Command - -The new RPC command for Rich Presence is `SET_ACTIVITY`. The fields are similar to what is outlined in the SDK; we've combined similar fields into objects for the sake of less data on the wire. - -The one major difference is the `party.size` field. It is an array with a size of two. The first element is the current party size, `partySize` from the main documentation. The second element is the maximum party size, `partyMax` from the main documentation. - -Below is a full example of a `SET_ACTIVITY` command. Field restrictions like size are the same as outlined in the main documentation. - -``` -{ - "cmd": "SET_ACTIVITY", - "args": { - "pid": 9999, // Your application's process id - required field - "activity": { - "state": "In a Group", - "details": "Competitive | In a Match", - "timestamps": { - "start": time(nullptr), - "end": time(nullptr) + ((60 * 5) + 23) - }, - "assets": { - "large_image": "numbani_map", - "large_text": "Numbani", - "small_image": "pharah_profile", - "small_text": "Pharah" - }, - "party": { - "id": GameEngine.GetPartyId(), - "size": [3, 6] - }, - "secrets": { - "join": "025ed05c71f639de8bfaa0d679d7c94b2fdce12f", - "spectate": "e7eb30d2ee025ed05c71ea495f770b76454ee4e0", - "match": "4b2fdce12f639de8bfa7e3591b71a0d679d7c93f" - }, - "instance": true - } - }, - "nonce": "647d814a-4cf8-4fbb-948f-898abd24f55b" -} -``` - -## New RPC Events - -The three new RPC events for Rich Presence power the ability to join and spectate your friends' games. - -First is the `ACTIVITY_JOIN` event: - -```json -{ - "cmd": "DISPATCH", - "data": { - "secret": "025ed05c71f639de8bfaa0d679d7c94b2fdce12f" - }, - "evt": "ACTIVITY_JOIN" -} -``` - -Second is the `ACTIVITY_SPECTATE` event: - -```json -{ - "cmd": "DISPATCH", - "data": { - "secret": "e7eb30d2ee025ed05c71ea495f770b76454ee4e0" - }, - "evt": "ACTIVITY_SPECTATE" -} -``` - -And third is the `ACTIVITY_JOIN_REQUEST` event: - -```json -{ - "cmd": "DISPATCH", - "data": { - "user": { - "id": "53908232506183680", - "username": "Mason", - "discriminator": "1337", - "avatar": "a_bab14f271d565501444b2ca3be944b25" - } - }, - "evt": "ACTIVITY_JOIN_REQUEST" -} -``` - -In order to receive these events, you need to [subscribe](https://discordapp.com/developers/docs/topics/rpc#subscribe) to them like so: - -```json -{ - "nonce": "be9a6de3-31d0-4767-a8e9-4818c5690015", - "evt": "ACTIVITY_JOIN", - "cmd": "SUBSCRIBE" -} -``` - -```json -{ - "nonce": "ae9qdde3-31d0-8989-a8e9-dnakwy174he", - "evt": "ACTIVITY_SPECTATE", - "cmd": "SUBSCRIBE" -} -``` - -```json -{ - "nonce": "5dc0c062-98c6-47a0-8922-bbb52e9d6afa", - "evt": "ACTIVITY_JOIN_REQUEST", - "cmd": "SUBSCRIBE" -} -``` - -To unsubscribe from these events, resend with the command `UNSUBSCRIBE` - -## Responding -A discord user will request access to the game. If the ACTIVITY_JOIN_REQUEST has been subscribed too, the ACTIVITY_JOIN_REQUEST event will be sent to the host's game. Accept it with following model: -```json -{ - "nonce": "5dc0c062-98c6-47a0-8922-15aerg126", - "cmd": "SEND_ACTIVITY_JOIN_INVITE", - "args": - { - "user_id": "53908232506183680" - } -} -``` - -To reject the request, use `CLOSE_ACTIVITY_REQUEST`: -```json -{ - "nonce": "5dc0c062-98c6-47a0-8922-dasg256eafg", - "cmd": "CLOSE_ACTIVITY_REQUEST", - "args": - { - "user_id": "53908232506183680" - } -} -``` - -## Notes -Here are just some quick notes to help with some common troubleshooting problems. -* IPC will echo back every command you send as a response. Use this as a lock-step feature to avoid flooding messages. Can be used to validate messages such as the Presence or Subscribes. -* The pipe expects for frames to be written in a single byte array. You cannot do multiple `stream.Write(opcode);` `stream.Write(length);` as it will break the pipe. Instead create a buffer, write the data to the buffer, then send the entire buffer to the stream. -* Discord can be on any pipe ranging from `discord-ipc-0` to `discord-ipc-9`. It is a good idea to try and connect to each one and keeping the first one you connect too. For multiple clients (eg Discord and Canary), you might want to add a feature to manually select the pipe so you can more easily debug the application. -* All enums are `lower_snake_case`. -* The opcode and length in the header are `Little Endian Unsigned Integers (32bits)`. In some languages, you must convert them as they can be architecture specific. -* [Discord Rich Presence How-To](https://discordapp.com/developers/docs/rich-presence/how-to) contains a lot of the information this document doesn't. For example, it will tell you about the response payload. -* In the documentation, DISCORD_REPLY_IGNORE is just implemented the same as DISCORD_REPLY_NO. -* You can test the Join / Spectate feature by enabling them in your profile and whitelisting a test account. Use Canary to run 2 accounts on the same machine. diff --git a/dependencies/discord-rpc/documentation/images/rp-dev-dashboard.png b/dependencies/discord-rpc/documentation/images/rp-dev-dashboard.png deleted file mode 100644 index f246cfb2..00000000 Binary files a/dependencies/discord-rpc/documentation/images/rp-dev-dashboard.png and /dev/null differ diff --git a/dependencies/discord-rpc/documentation/images/rp-profile-view.png b/dependencies/discord-rpc/documentation/images/rp-profile-view.png deleted file mode 100644 index f9ddc313..00000000 Binary files a/dependencies/discord-rpc/documentation/images/rp-profile-view.png and /dev/null differ diff --git a/dependencies/discord-rpc/documentation/images/rp-secret-example.png b/dependencies/discord-rpc/documentation/images/rp-secret-example.png deleted file mode 100644 index 4ff21b09..00000000 Binary files a/dependencies/discord-rpc/documentation/images/rp-secret-example.png and /dev/null differ diff --git a/dependencies/discord-rpc/examples/button-clicker/.gitignore b/dependencies/discord-rpc/examples/button-clicker/.gitignore deleted file mode 100644 index 2695047f..00000000 --- a/dependencies/discord-rpc/examples/button-clicker/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -/Library/ -/Temp/ -/obj/ -/Assets/Plugins/ -/Assets/Plugins.meta -*.sln -*.csproj -*.userprefs diff --git a/dependencies/discord-rpc/examples/button-clicker/Assets/DiscordController.cs b/dependencies/discord-rpc/examples/button-clicker/Assets/DiscordController.cs deleted file mode 100644 index 7319d5fa..00000000 --- a/dependencies/discord-rpc/examples/button-clicker/Assets/DiscordController.cs +++ /dev/null @@ -1,125 +0,0 @@ -using UnityEngine; - -[System.Serializable] -public class DiscordJoinEvent : UnityEngine.Events.UnityEvent { } - -[System.Serializable] -public class DiscordSpectateEvent : UnityEngine.Events.UnityEvent { } - -[System.Serializable] -public class DiscordJoinRequestEvent : UnityEngine.Events.UnityEvent { } - -public class DiscordController : MonoBehaviour -{ - public DiscordRpc.RichPresence presence = new DiscordRpc.RichPresence(); - public string applicationId; - public string optionalSteamId; - public int clickCounter; - public DiscordRpc.DiscordUser joinRequest; - public UnityEngine.Events.UnityEvent onConnect; - public UnityEngine.Events.UnityEvent onDisconnect; - public UnityEngine.Events.UnityEvent hasResponded; - public DiscordJoinEvent onJoin; - public DiscordJoinEvent onSpectate; - public DiscordJoinRequestEvent onJoinRequest; - - DiscordRpc.EventHandlers handlers; - - public void OnClick() - { - Debug.Log("Discord: on click!"); - clickCounter++; - - presence.details = string.Format("Button clicked {0} times", clickCounter); - presence.joinSecret = "aSecret"; - presence.partyId = "aPartyId"; - presence.partySize = 1; - presence.partyMax = 3; - presence.partyPrivacy = DiscordRpc.PartyPrivacy.Public; - - DiscordRpc.UpdatePresence(presence); - } - - public void RequestRespondYes() - { - Debug.Log("Discord: responding yes to Ask to Join request"); - DiscordRpc.Respond(joinRequest.userId, DiscordRpc.Reply.Yes); - hasResponded.Invoke(); - } - - public void RequestRespondNo() - { - Debug.Log("Discord: responding no to Ask to Join request"); - DiscordRpc.Respond(joinRequest.userId, DiscordRpc.Reply.No); - hasResponded.Invoke(); - } - - public void ReadyCallback(ref DiscordRpc.DiscordUser connectedUser) - { - Debug.Log(string.Format("Discord: connected to {0}#{1}: {2}", connectedUser.username, connectedUser.discriminator, connectedUser.userId)); - onConnect.Invoke(); - } - - public void DisconnectedCallback(int errorCode, string message) - { - Debug.Log(string.Format("Discord: disconnect {0}: {1}", errorCode, message)); - onDisconnect.Invoke(); - } - - public void ErrorCallback(int errorCode, string message) - { - Debug.Log(string.Format("Discord: error {0}: {1}", errorCode, message)); - } - - public void JoinCallback(string secret) - { - Debug.Log(string.Format("Discord: join ({0})", secret)); - onJoin.Invoke(secret); - } - - public void SpectateCallback(string secret) - { - Debug.Log(string.Format("Discord: spectate ({0})", secret)); - onSpectate.Invoke(secret); - } - - public void RequestCallback(ref DiscordRpc.DiscordUser request) - { - Debug.Log(string.Format("Discord: join request {0}#{1}: {2}", request.username, request.discriminator, request.userId)); - joinRequest = request; - onJoinRequest.Invoke(request); - } - - void Start() - { - } - - void Update() - { - DiscordRpc.RunCallbacks(); - } - - void OnEnable() - { - Debug.Log("Discord: init"); - handlers = new DiscordRpc.EventHandlers(); - handlers.readyCallback += ReadyCallback; - handlers.disconnectedCallback += DisconnectedCallback; - handlers.errorCallback += ErrorCallback; - handlers.joinCallback += JoinCallback; - handlers.spectateCallback += SpectateCallback; - handlers.requestCallback += RequestCallback; - DiscordRpc.Initialize(applicationId, ref handlers, true, optionalSteamId); - } - - void OnDisable() - { - Debug.Log("Discord: shutdown"); - DiscordRpc.Shutdown(); - } - - void OnDestroy() - { - - } -} diff --git a/dependencies/discord-rpc/examples/button-clicker/Assets/DiscordController.cs.meta b/dependencies/discord-rpc/examples/button-clicker/Assets/DiscordController.cs.meta deleted file mode 100644 index ee24c7e4..00000000 --- a/dependencies/discord-rpc/examples/button-clicker/Assets/DiscordController.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 27f0a5f59ffffa84c86547736e2e730a -timeCreated: 1501697692 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/dependencies/discord-rpc/examples/button-clicker/Assets/DiscordRpc.cs b/dependencies/discord-rpc/examples/button-clicker/Assets/DiscordRpc.cs deleted file mode 100644 index f3b1ee59..00000000 --- a/dependencies/discord-rpc/examples/button-clicker/Assets/DiscordRpc.cs +++ /dev/null @@ -1,231 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Runtime.InteropServices; -using System.Text; -using AOT; - -public class DiscordRpc -{ - [MonoPInvokeCallback(typeof(OnReadyInfo))] - public static void ReadyCallback(ref DiscordUser connectedUser) { Callbacks.readyCallback(ref connectedUser); } - public delegate void OnReadyInfo(ref DiscordUser connectedUser); - - [MonoPInvokeCallback(typeof(OnDisconnectedInfo))] - public static void DisconnectedCallback(int errorCode, string message) { Callbacks.disconnectedCallback(errorCode, message); } - public delegate void OnDisconnectedInfo(int errorCode, string message); - - [MonoPInvokeCallback(typeof(OnErrorInfo))] - public static void ErrorCallback(int errorCode, string message) { Callbacks.errorCallback(errorCode, message); } - public delegate void OnErrorInfo(int errorCode, string message); - - [MonoPInvokeCallback(typeof(OnJoinInfo))] - public static void JoinCallback(string secret) { Callbacks.joinCallback(secret); } - public delegate void OnJoinInfo(string secret); - - [MonoPInvokeCallback(typeof(OnSpectateInfo))] - public static void SpectateCallback(string secret) { Callbacks.spectateCallback(secret); } - public delegate void OnSpectateInfo(string secret); - - [MonoPInvokeCallback(typeof(OnRequestInfo))] - public static void RequestCallback(ref DiscordUser request) { Callbacks.requestCallback(ref request); } - public delegate void OnRequestInfo(ref DiscordUser request); - - static EventHandlers Callbacks { get; set; } - - public struct EventHandlers - { - public OnReadyInfo readyCallback; - public OnDisconnectedInfo disconnectedCallback; - public OnErrorInfo errorCallback; - public OnJoinInfo joinCallback; - public OnSpectateInfo spectateCallback; - public OnRequestInfo requestCallback; - } - - [Serializable, StructLayout(LayoutKind.Sequential)] - public struct RichPresenceStruct - { - public IntPtr state; /* max 128 bytes */ - public IntPtr details; /* max 128 bytes */ - public long startTimestamp; - public long endTimestamp; - public IntPtr largeImageKey; /* max 32 bytes */ - public IntPtr largeImageText; /* max 128 bytes */ - public IntPtr smallImageKey; /* max 32 bytes */ - public IntPtr smallImageText; /* max 128 bytes */ - public IntPtr partyId; /* max 128 bytes */ - public int partySize; - public int partyMax; - public int partyPrivacy; - public IntPtr matchSecret; /* max 128 bytes */ - public IntPtr joinSecret; /* max 128 bytes */ - public IntPtr spectateSecret; /* max 128 bytes */ - public bool instance; - } - - [Serializable] - public struct DiscordUser - { - public string userId; - public string username; - public string discriminator; - public string avatar; - } - - public enum Reply - { - No = 0, - Yes = 1, - Ignore = 2 - } - - public enum PartyPrivacy - { - Private = 0, - Public = 1 - } - - public static void Initialize(string applicationId, ref EventHandlers handlers, bool autoRegister, string optionalSteamId) - { - Callbacks = handlers; - - EventHandlers staticEventHandlers = new EventHandlers(); - staticEventHandlers.readyCallback += DiscordRpc.ReadyCallback; - staticEventHandlers.disconnectedCallback += DiscordRpc.DisconnectedCallback; - staticEventHandlers.errorCallback += DiscordRpc.ErrorCallback; - staticEventHandlers.joinCallback += DiscordRpc.JoinCallback; - staticEventHandlers.spectateCallback += DiscordRpc.SpectateCallback; - staticEventHandlers.requestCallback += DiscordRpc.RequestCallback; - - InitializeInternal(applicationId, ref staticEventHandlers, autoRegister, optionalSteamId); - } - - [DllImport("discord-rpc", EntryPoint = "Discord_Initialize", CallingConvention = CallingConvention.Cdecl)] - static extern void InitializeInternal(string applicationId, ref EventHandlers handlers, bool autoRegister, string optionalSteamId); - - [DllImport("discord-rpc", EntryPoint = "Discord_Shutdown", CallingConvention = CallingConvention.Cdecl)] - public static extern void Shutdown(); - - [DllImport("discord-rpc", EntryPoint = "Discord_RunCallbacks", CallingConvention = CallingConvention.Cdecl)] - public static extern void RunCallbacks(); - - [DllImport("discord-rpc", EntryPoint = "Discord_UpdatePresence", CallingConvention = CallingConvention.Cdecl)] - private static extern void UpdatePresenceNative(ref RichPresenceStruct presence); - - [DllImport("discord-rpc", EntryPoint = "Discord_ClearPresence", CallingConvention = CallingConvention.Cdecl)] - public static extern void ClearPresence(); - - [DllImport("discord-rpc", EntryPoint = "Discord_Respond", CallingConvention = CallingConvention.Cdecl)] - public static extern void Respond(string userId, Reply reply); - - [DllImport("discord-rpc", EntryPoint = "Discord_UpdateHandlers", CallingConvention = CallingConvention.Cdecl)] - public static extern void UpdateHandlers(ref EventHandlers handlers); - - public static void UpdatePresence(RichPresence presence) - { - var presencestruct = presence.GetStruct(); - UpdatePresenceNative(ref presencestruct); - presence.FreeMem(); - } - - public class RichPresence - { - private RichPresenceStruct _presence; - private readonly List _buffers = new List(10); - - public string state; /* max 128 bytes */ - public string details; /* max 128 bytes */ - public long startTimestamp; - public long endTimestamp; - public string largeImageKey; /* max 32 bytes */ - public string largeImageText; /* max 128 bytes */ - public string smallImageKey; /* max 32 bytes */ - public string smallImageText; /* max 128 bytes */ - public string partyId; /* max 128 bytes */ - public int partySize; - public int partyMax; - public PartyPrivacy partyPrivacy; - public string matchSecret; /* max 128 bytes */ - public string joinSecret; /* max 128 bytes */ - public string spectateSecret; /* max 128 bytes */ - public bool instance; - - /// - /// Get the reprensentation of this instance - /// - /// reprensentation of this instance - internal RichPresenceStruct GetStruct() - { - if (_buffers.Count > 0) - { - FreeMem(); - } - - _presence.state = StrToPtr(state); - _presence.details = StrToPtr(details); - _presence.startTimestamp = startTimestamp; - _presence.endTimestamp = endTimestamp; - _presence.largeImageKey = StrToPtr(largeImageKey); - _presence.largeImageText = StrToPtr(largeImageText); - _presence.smallImageKey = StrToPtr(smallImageKey); - _presence.smallImageText = StrToPtr(smallImageText); - _presence.partyId = StrToPtr(partyId); - _presence.partySize = partySize; - _presence.partyMax = partyMax; - _presence.partyPrivacy = (int)partyPrivacy; - _presence.matchSecret = StrToPtr(matchSecret); - _presence.joinSecret = StrToPtr(joinSecret); - _presence.spectateSecret = StrToPtr(spectateSecret); - _presence.instance = instance; - - return _presence; - } - - /// - /// Returns a pointer to a representation of the given string with a size of maxbytes - /// - /// String to convert - /// Pointer to the UTF-8 representation of - private IntPtr StrToPtr(string input) - { - if (string.IsNullOrEmpty(input)) return IntPtr.Zero; - var convbytecnt = Encoding.UTF8.GetByteCount(input); - var buffer = Marshal.AllocHGlobal(convbytecnt + 1); - for (int i = 0; i < convbytecnt + 1; i++) - { - Marshal.WriteByte(buffer, i, 0); - } - _buffers.Add(buffer); - Marshal.Copy(Encoding.UTF8.GetBytes(input), 0, buffer, convbytecnt); - return buffer; - } - - /// - /// Convert string to UTF-8 and add null termination - /// - /// string to convert - /// UTF-8 representation of with added null termination - private static string StrToUtf8NullTerm(string toconv) - { - var str = toconv.Trim(); - var bytes = Encoding.Default.GetBytes(str); - if (bytes.Length > 0 && bytes[bytes.Length - 1] != 0) - { - str += "\0\0"; - } - return Encoding.UTF8.GetString(Encoding.UTF8.GetBytes(str)); - } - - /// - /// Free the allocated memory for conversion to - /// - internal void FreeMem() - { - for (var i = _buffers.Count - 1; i >= 0; i--) - { - Marshal.FreeHGlobal(_buffers[i]); - _buffers.RemoveAt(i); - } - } - } -} \ No newline at end of file diff --git a/dependencies/discord-rpc/examples/button-clicker/Assets/DiscordRpc.cs.meta b/dependencies/discord-rpc/examples/button-clicker/Assets/DiscordRpc.cs.meta deleted file mode 100644 index acd04b10..00000000 --- a/dependencies/discord-rpc/examples/button-clicker/Assets/DiscordRpc.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: b4474a677de9d80409e98c5393ec5b1e -timeCreated: 1501697692 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/dependencies/discord-rpc/examples/button-clicker/Assets/Editor/BuildHelper.cs b/dependencies/discord-rpc/examples/button-clicker/Assets/Editor/BuildHelper.cs deleted file mode 100644 index 97774531..00000000 --- a/dependencies/discord-rpc/examples/button-clicker/Assets/Editor/BuildHelper.cs +++ /dev/null @@ -1,101 +0,0 @@ -using UnityEditor; -using System.Diagnostics; -using System.IO; - -[InitializeOnLoad] -public class ScriptBatch -{ - static ScriptBatch() - { - EnsureDLL(); - } - - public static bool FileExists(string filename) - { - return new FileInfo(filename).Exists; - } - - public static bool RunRpcBuildScript() - { - UnityEngine.Debug.Log("Try to run build script"); - - Process proc = new Process(); -#if UNITY_STANDALONE_OSX || UNITY_EDITOR_OSX - proc.StartInfo.UseShellExecute = false; - // brew installs cmake in /usr/local/bin, which Unity seems to strip from PATH? - string newPath = proc.StartInfo.EnvironmentVariables["PATH"] + ":/usr/local/bin"; - proc.StartInfo.EnvironmentVariables["PATH"] = newPath; -#endif - proc.StartInfo.FileName = "python"; - proc.StartInfo.Arguments = "build.py unity"; - proc.StartInfo.WorkingDirectory = "../.."; - proc.Start(); - proc.WaitForExit(); - return proc.ExitCode == 0; - } - - public static void EnsureDLL() - { - #if UNITY_STANDALONE_WIN || UNITY_EDITOR_WIN - string[] dstDirs = { "Assets/Plugins", "Assets/Plugins/x86", "Assets/Plugins/x86_64" }; - string[] dstDlls = { "Assets/Plugins/x86/discord-rpc.dll", "Assets/Plugins/x86_64/discord-rpc.dll" }; - string[] srcDlls = { "../../builds/install/win64-dynamic/bin/discord-rpc.dll", "../../builds/install/win64-dynamic/bin/discord-rpc.dll" }; - #elif UNITY_STANDALONE_OSX || UNITY_EDITOR_OSX - string[] dstDirs = { "Assets/Plugins" }; - string[] dstDlls = { "Assets/Plugins/discord-rpc.bundle" }; - string[] srcDlls = { "../../builds/install/osx-dynamic/lib/libdiscord-rpc.dylib" }; - #else - string[] dstDirs = { "Assets/Plugins", "Assets/Plugins/x86", "Assets/Plugins/x86_64" }; - string[] dstDlls = { "Assets/Plugins/discord-rpc.so" }; - string[] srcDlls = { "../../builds/install/linux-dynamic/lib/libdiscord-rpc.so" }; - #endif - - Debug.Assert(dstDlls.Length == srcDlls.Length); - - bool exists = true; - foreach (string fname in dstDlls) - { - if (!FileExists(fname)) - { - exists = false; - break; - } - } - - if (exists) - { - return; - } - - exists = true; - foreach (string fname in srcDlls) - { - if (!FileExists(fname)) - { - exists = false; - break; - } - } - - if (!exists) - { - if (!RunRpcBuildScript()) - { - UnityEngine.Debug.LogError("Build failed"); - return; - } - } - - // make sure the dirs exist - foreach (string dirname in dstDirs) - { - Directory.CreateDirectory(dirname); - } - - // Copy dlls - for (int i = 0; i < dstDlls.Length; ++i) - { - FileUtil.CopyFileOrDirectory(srcDlls[i], dstDlls[i]); - } - } -} \ No newline at end of file diff --git a/dependencies/discord-rpc/examples/button-clicker/Assets/Editor/BuildHelper.cs.meta b/dependencies/discord-rpc/examples/button-clicker/Assets/Editor/BuildHelper.cs.meta deleted file mode 100644 index c14e1e8b..00000000 --- a/dependencies/discord-rpc/examples/button-clicker/Assets/Editor/BuildHelper.cs.meta +++ /dev/null @@ -1,13 +0,0 @@ -fileFormatVersion: 2 -guid: e5aecc4633e5f594b85eaa39f49bb402 -timeCreated: 1512071254 -licenseType: Free -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/dependencies/discord-rpc/examples/button-clicker/Assets/main.unity b/dependencies/discord-rpc/examples/button-clicker/Assets/main.unity deleted file mode 100644 index c5074d55..00000000 --- a/dependencies/discord-rpc/examples/button-clicker/Assets/main.unity +++ /dev/null @@ -1,1278 +0,0 @@ -%YAML 1.1 -%TAG !u! tag:unity3d.com,2011: ---- !u!29 &1 -OcclusionCullingSettings: - m_ObjectHideFlags: 0 - serializedVersion: 2 - m_OcclusionBakeSettings: - smallestOccluder: 5 - smallestHole: 0.25 - backfaceThreshold: 100 - m_SceneGUID: 00000000000000000000000000000000 - m_OcclusionCullingData: {fileID: 0} ---- !u!104 &2 -RenderSettings: - m_ObjectHideFlags: 0 - serializedVersion: 8 - m_Fog: 0 - m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} - m_FogMode: 3 - m_FogDensity: 0.01 - m_LinearFogStart: 0 - m_LinearFogEnd: 300 - m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} - m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} - m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} - m_AmbientIntensity: 1 - m_AmbientMode: 3 - m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} - m_SkyboxMaterial: {fileID: 0} - m_HaloStrength: 0.5 - m_FlareStrength: 1 - m_FlareFadeSpeed: 3 - m_HaloTexture: {fileID: 0} - m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} - m_DefaultReflectionMode: 0 - m_DefaultReflectionResolution: 128 - m_ReflectionBounces: 1 - m_ReflectionIntensity: 1 - m_CustomReflection: {fileID: 0} - m_Sun: {fileID: 0} - m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1} ---- !u!157 &3 -LightmapSettings: - m_ObjectHideFlags: 0 - serializedVersion: 11 - m_GIWorkflowMode: 1 - m_GISettings: - serializedVersion: 2 - m_BounceScale: 1 - m_IndirectOutputScale: 1 - m_AlbedoBoost: 1 - m_TemporalCoherenceThreshold: 1 - m_EnvironmentLightingMode: 0 - m_EnableBakedLightmaps: 0 - m_EnableRealtimeLightmaps: 0 - m_LightmapEditorSettings: - serializedVersion: 9 - m_Resolution: 2 - m_BakeResolution: 40 - m_TextureWidth: 1024 - m_TextureHeight: 1024 - m_AO: 0 - m_AOMaxDistance: 1 - m_CompAOExponent: 1 - m_CompAOExponentDirect: 0 - m_Padding: 2 - m_LightmapParameters: {fileID: 0} - m_LightmapsBakeMode: 1 - m_TextureCompression: 1 - m_FinalGather: 0 - m_FinalGatherFiltering: 1 - m_FinalGatherRayCount: 256 - m_ReflectionCompression: 2 - m_MixedBakeMode: 2 - m_BakeBackend: 0 - m_PVRSampling: 1 - m_PVRDirectSampleCount: 32 - m_PVRSampleCount: 500 - m_PVRBounces: 2 - m_PVRFiltering: 0 - m_PVRFilteringMode: 1 - m_PVRCulling: 1 - m_PVRFilteringGaussRadiusDirect: 1 - m_PVRFilteringGaussRadiusIndirect: 5 - m_PVRFilteringGaussRadiusAO: 2 - m_PVRFilteringAtrousColorSigma: 1 - m_PVRFilteringAtrousNormalSigma: 1 - m_PVRFilteringAtrousPositionSigma: 1 - m_LightingDataAsset: {fileID: 0} - m_UseShadowmask: 1 ---- !u!196 &4 -NavMeshSettings: - serializedVersion: 2 - m_ObjectHideFlags: 0 - m_BuildSettings: - serializedVersion: 2 - agentTypeID: 0 - agentRadius: 0.5 - agentHeight: 2 - agentSlope: 45 - agentClimb: 0.4 - ledgeDropHeight: 0 - maxJumpAcrossDistance: 0 - minRegionArea: 2 - manualCellSize: 0 - cellSize: 0.16666667 - manualTileSize: 0 - tileSize: 256 - accuratePlacement: 0 - m_NavMeshData: {fileID: 0} ---- !u!1 &134146651 -GameObject: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - serializedVersion: 5 - m_Component: - - component: {fileID: 134146656} - - component: {fileID: 134146655} - - component: {fileID: 134146654} - - component: {fileID: 134146653} - - component: {fileID: 134146652} - m_Layer: 0 - m_Name: Main Camera - m_TagString: MainCamera - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!81 &134146652 -AudioListener: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 134146651} - m_Enabled: 1 ---- !u!124 &134146653 -Behaviour: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 134146651} - m_Enabled: 1 ---- !u!92 &134146654 -Behaviour: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 134146651} - m_Enabled: 1 ---- !u!20 &134146655 -Camera: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 134146651} - m_Enabled: 1 - serializedVersion: 2 - m_ClearFlags: 1 - m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} - m_NormalizedViewPortRect: - serializedVersion: 2 - x: 0 - y: 0 - width: 1 - height: 1 - near clip plane: 0.3 - far clip plane: 1000 - field of view: 60 - orthographic: 1 - orthographic size: 5 - m_Depth: -1 - m_CullingMask: - serializedVersion: 2 - m_Bits: 4294967295 - m_RenderingPath: -1 - m_TargetTexture: {fileID: 0} - m_TargetDisplay: 0 - m_TargetEye: 3 - m_HDR: 1 - m_AllowMSAA: 1 - m_ForceIntoRT: 0 - m_OcclusionCulling: 1 - m_StereoConvergence: 10 - m_StereoSeparation: 0.022 - m_StereoMirrorMode: 0 ---- !u!4 &134146656 -Transform: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 134146651} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: -10} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 0} - m_RootOrder: 0 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!1 &359174702 -GameObject: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - serializedVersion: 5 - m_Component: - - component: {fileID: 359174703} - - component: {fileID: 359174705} - - component: {fileID: 359174704} - m_Layer: 5 - m_Name: Text - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &359174703 -RectTransform: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 359174702} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 1032248339} - m_RootOrder: 0 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 0, y: 0} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &359174704 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 359174702} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 708705254, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} - m_RaycastTarget: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_FontData: - m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} - m_FontSize: 14 - m_FontStyle: 0 - m_BestFit: 0 - m_MinSize: 10 - m_MaxSize: 40 - m_Alignment: 4 - m_AlignByGeometry: 0 - m_RichText: 1 - m_HorizontalOverflow: 0 - m_VerticalOverflow: 0 - m_LineSpacing: 1 - m_Text: Button ---- !u!222 &359174705 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 359174702} ---- !u!1 &520806049 -GameObject: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - serializedVersion: 5 - m_Component: - - component: {fileID: 520806050} - - component: {fileID: 520806052} - - component: {fileID: 520806051} - m_Layer: 5 - m_Name: Text - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &520806050 -RectTransform: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 520806049} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 806911717} - m_RootOrder: 0 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 0, y: 0} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &520806051 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 520806049} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 708705254, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} - m_RaycastTarget: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_FontData: - m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} - m_FontSize: 14 - m_FontStyle: 0 - m_BestFit: 0 - m_MinSize: 10 - m_MaxSize: 40 - m_Alignment: 4 - m_AlignByGeometry: 0 - m_RichText: 1 - m_HorizontalOverflow: 0 - m_VerticalOverflow: 0 - m_LineSpacing: 1 - m_Text: Yes ---- !u!222 &520806052 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 520806049} ---- !u!1 &657463235 -GameObject: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - serializedVersion: 5 - m_Component: - - component: {fileID: 657463238} - - component: {fileID: 657463237} - - component: {fileID: 657463236} - m_Layer: 5 - m_Name: IsConnectedLabel - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!114 &657463236 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 657463235} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 0.89518255, g: 0.9338235, b: 0.23345588, a: 1} - m_RaycastTarget: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_FontData: - m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} - m_FontSize: 24 - m_FontStyle: 0 - m_BestFit: 0 - m_MinSize: 2 - m_MaxSize: 40 - m_Alignment: 0 - m_AlignByGeometry: 0 - m_RichText: 1 - m_HorizontalOverflow: 0 - m_VerticalOverflow: 0 - m_LineSpacing: 1 - m_Text: Discord Disconnected ---- !u!222 &657463237 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 657463235} ---- !u!224 &657463238 -RectTransform: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 657463235} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 1766020814} - m_RootOrder: 1 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 1} - m_AnchorMax: {x: 0, y: 1} - m_AnchoredPosition: {x: 16, y: -19.00003} - m_SizeDelta: {x: 239.20001, y: 37.799988} - m_Pivot: {x: 0, y: 1} ---- !u!1 &806911716 -GameObject: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - serializedVersion: 5 - m_Component: - - component: {fileID: 806911717} - - component: {fileID: 806911720} - - component: {fileID: 806911719} - - component: {fileID: 806911718} - m_Layer: 5 - m_Name: ButtonRespondYes - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &806911717 -RectTransform: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 806911716} - m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: - - {fileID: 520806050} - m_Father: {fileID: 1766020814} - m_RootOrder: 2 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0.5, y: 0.5} - m_AnchorMax: {x: 0.5, y: 0.5} - m_AnchoredPosition: {x: -129.1, y: -116.3} - m_SizeDelta: {x: 160, y: 30} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &806911718 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 806911716} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 1392445389, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Navigation: - m_Mode: 3 - m_SelectOnUp: {fileID: 0} - m_SelectOnDown: {fileID: 0} - m_SelectOnLeft: {fileID: 0} - m_SelectOnRight: {fileID: 0} - m_Transition: 1 - m_Colors: - m_NormalColor: {r: 1, g: 1, b: 1, a: 1} - m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} - m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} - m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} - m_ColorMultiplier: 1 - m_FadeDuration: 0.1 - m_SpriteState: - m_HighlightedSprite: {fileID: 0} - m_PressedSprite: {fileID: 0} - m_DisabledSprite: {fileID: 0} - m_AnimationTriggers: - m_NormalTrigger: Normal - m_HighlightedTrigger: Highlighted - m_PressedTrigger: Pressed - m_DisabledTrigger: Disabled - m_Interactable: 0 - m_TargetGraphic: {fileID: 806911719} - m_OnClick: - m_PersistentCalls: - m_Calls: - - m_Target: {fileID: 1929635629} - m_MethodName: RequestRespondYes - m_Mode: 1 - m_Arguments: - m_ObjectArgument: {fileID: 0} - m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine - m_IntArgument: 0 - m_FloatArgument: 0 - m_StringArgument: - m_BoolArgument: 0 - m_CallState: 2 - m_TypeName: UnityEngine.UI.Button+ButtonClickedEvent, UnityEngine.UI, Version=1.0.0.0, - Culture=neutral, PublicKeyToken=null ---- !u!114 &806911719 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 806911716} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: -765806418, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 1, g: 1, b: 1, a: 1} - m_RaycastTarget: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} - m_Type: 1 - m_PreserveAspect: 0 - m_FillCenter: 1 - m_FillMethod: 4 - m_FillAmount: 1 - m_FillClockwise: 1 - m_FillOrigin: 0 ---- !u!222 &806911720 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 806911716} ---- !u!1 &1032248338 -GameObject: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - serializedVersion: 5 - m_Component: - - component: {fileID: 1032248339} - - component: {fileID: 1032248342} - - component: {fileID: 1032248341} - - component: {fileID: 1032248340} - m_Layer: 5 - m_Name: Button - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &1032248339 -RectTransform: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 1032248338} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: - - {fileID: 359174703} - m_Father: {fileID: 1766020814} - m_RootOrder: 0 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0.5, y: 0.5} - m_AnchorMax: {x: 0.5, y: 0.5} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 160, y: 30} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &1032248340 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 1032248338} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 1392445389, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Navigation: - m_Mode: 3 - m_SelectOnUp: {fileID: 0} - m_SelectOnDown: {fileID: 0} - m_SelectOnLeft: {fileID: 0} - m_SelectOnRight: {fileID: 0} - m_Transition: 1 - m_Colors: - m_NormalColor: {r: 1, g: 1, b: 1, a: 1} - m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} - m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} - m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} - m_ColorMultiplier: 1 - m_FadeDuration: 0.1 - m_SpriteState: - m_HighlightedSprite: {fileID: 0} - m_PressedSprite: {fileID: 0} - m_DisabledSprite: {fileID: 0} - m_AnimationTriggers: - m_NormalTrigger: Normal - m_HighlightedTrigger: Highlighted - m_PressedTrigger: Pressed - m_DisabledTrigger: Disabled - m_Interactable: 1 - m_TargetGraphic: {fileID: 1032248341} - m_OnClick: - m_PersistentCalls: - m_Calls: - - m_Target: {fileID: 1929635629} - m_MethodName: OnClick - m_Mode: 1 - m_Arguments: - m_ObjectArgument: {fileID: 0} - m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine - m_IntArgument: 0 - m_FloatArgument: 0 - m_StringArgument: - m_BoolArgument: 0 - m_CallState: 2 - m_TypeName: UnityEngine.UI.Button+ButtonClickedEvent, UnityEngine.UI, Version=1.0.0.0, - Culture=neutral, PublicKeyToken=null ---- !u!114 &1032248341 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 1032248338} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: -765806418, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 1, g: 1, b: 1, a: 1} - m_RaycastTarget: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} - m_Type: 1 - m_PreserveAspect: 0 - m_FillCenter: 1 - m_FillMethod: 4 - m_FillAmount: 1 - m_FillClockwise: 1 - m_FillOrigin: 0 ---- !u!222 &1032248342 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 1032248338} ---- !u!1 &1238162986 -GameObject: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - serializedVersion: 5 - m_Component: - - component: {fileID: 1238162987} - - component: {fileID: 1238162989} - - component: {fileID: 1238162988} - m_Layer: 5 - m_Name: JoinRequestInfo - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &1238162987 -RectTransform: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 1238162986} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 1766020814} - m_RootOrder: 4 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0.5, y: 0.5} - m_AnchorMax: {x: 0.5, y: 0.5} - m_AnchoredPosition: {x: -0.0000085831, y: -66.9} - m_SizeDelta: {x: 323.38, y: 55.29} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &1238162988 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 1238162986} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 1, g: 0.88965523, b: 0, a: 1} - m_RaycastTarget: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_FontData: - m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} - m_FontSize: 14 - m_FontStyle: 0 - m_BestFit: 0 - m_MinSize: 10 - m_MaxSize: 40 - m_Alignment: 1 - m_AlignByGeometry: 0 - m_RichText: 1 - m_HorizontalOverflow: 0 - m_VerticalOverflow: 0 - m_LineSpacing: 1 - m_Text: No requests yet ---- !u!222 &1238162989 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 1238162986} ---- !u!1 &1470895131 -GameObject: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - serializedVersion: 5 - m_Component: - - component: {fileID: 1470895134} - - component: {fileID: 1470895133} - - component: {fileID: 1470895132} - m_Layer: 0 - m_Name: EventSystem - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!114 &1470895132 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 1470895131} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 1077351063, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3} - m_Name: - m_EditorClassIdentifier: - m_HorizontalAxis: Horizontal - m_VerticalAxis: Vertical - m_SubmitButton: Submit - m_CancelButton: Cancel - m_InputActionsPerSecond: 10 - m_RepeatDelay: 0.5 - m_ForceModuleActive: 0 ---- !u!114 &1470895133 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 1470895131} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: -619905303, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3} - m_Name: - m_EditorClassIdentifier: - m_FirstSelected: {fileID: 0} - m_sendNavigationEvents: 1 - m_DragThreshold: 5 ---- !u!4 &1470895134 -Transform: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 1470895131} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 0} - m_RootOrder: 2 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!1 &1766020810 -GameObject: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - serializedVersion: 5 - m_Component: - - component: {fileID: 1766020814} - - component: {fileID: 1766020813} - - component: {fileID: 1766020812} - - component: {fileID: 1766020811} - m_Layer: 5 - m_Name: Canvas - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!114 &1766020811 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 1766020810} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 1301386320, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3} - m_Name: - m_EditorClassIdentifier: - m_IgnoreReversedGraphics: 1 - m_BlockingObjects: 0 - m_BlockingMask: - serializedVersion: 2 - m_Bits: 4294967295 ---- !u!114 &1766020812 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 1766020810} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 1980459831, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3} - m_Name: - m_EditorClassIdentifier: - m_UiScaleMode: 0 - m_ReferencePixelsPerUnit: 100 - m_ScaleFactor: 1 - m_ReferenceResolution: {x: 800, y: 600} - m_ScreenMatchMode: 0 - m_MatchWidthOrHeight: 0 - m_PhysicalUnit: 3 - m_FallbackScreenDPI: 96 - m_DefaultSpriteDPI: 96 - m_DynamicPixelsPerUnit: 1 ---- !u!223 &1766020813 -Canvas: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 1766020810} - m_Enabled: 1 - serializedVersion: 3 - m_RenderMode: 0 - m_Camera: {fileID: 0} - m_PlaneDistance: 100 - m_PixelPerfect: 0 - m_ReceivesEvents: 1 - m_OverrideSorting: 0 - m_OverridePixelPerfect: 0 - m_SortingBucketNormalizedSize: 0 - m_AdditionalShaderChannelsFlag: 0 - m_SortingLayerID: 0 - m_SortingOrder: 0 - m_TargetDisplay: 0 ---- !u!224 &1766020814 -RectTransform: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 1766020810} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 0, y: 0, z: 0} - m_Children: - - {fileID: 1032248339} - - {fileID: 657463238} - - {fileID: 806911717} - - {fileID: 1858885002} - - {fileID: 1238162987} - m_Father: {fileID: 0} - m_RootOrder: 1 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 0, y: 0} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 0, y: 0} - m_Pivot: {x: 0, y: 0} ---- !u!1 &1858885001 -GameObject: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - serializedVersion: 5 - m_Component: - - component: {fileID: 1858885002} - - component: {fileID: 1858885005} - - component: {fileID: 1858885004} - - component: {fileID: 1858885003} - m_Layer: 5 - m_Name: ButtonRespondNo - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &1858885002 -RectTransform: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 1858885001} - m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: - - {fileID: 1958982062} - m_Father: {fileID: 1766020814} - m_RootOrder: 3 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0.5, y: 0.5} - m_AnchorMax: {x: 0.5, y: 0.5} - m_AnchoredPosition: {x: 128.7, y: -116.3} - m_SizeDelta: {x: 160, y: 30} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &1858885003 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 1858885001} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 1392445389, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Navigation: - m_Mode: 3 - m_SelectOnUp: {fileID: 0} - m_SelectOnDown: {fileID: 0} - m_SelectOnLeft: {fileID: 0} - m_SelectOnRight: {fileID: 0} - m_Transition: 1 - m_Colors: - m_NormalColor: {r: 1, g: 1, b: 1, a: 1} - m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} - m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} - m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} - m_ColorMultiplier: 1 - m_FadeDuration: 0.1 - m_SpriteState: - m_HighlightedSprite: {fileID: 0} - m_PressedSprite: {fileID: 0} - m_DisabledSprite: {fileID: 0} - m_AnimationTriggers: - m_NormalTrigger: Normal - m_HighlightedTrigger: Highlighted - m_PressedTrigger: Pressed - m_DisabledTrigger: Disabled - m_Interactable: 0 - m_TargetGraphic: {fileID: 1858885004} - m_OnClick: - m_PersistentCalls: - m_Calls: - - m_Target: {fileID: 1929635629} - m_MethodName: RequestRespondNo - m_Mode: 1 - m_Arguments: - m_ObjectArgument: {fileID: 0} - m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine - m_IntArgument: 0 - m_FloatArgument: 0 - m_StringArgument: - m_BoolArgument: 0 - m_CallState: 2 - m_TypeName: UnityEngine.UI.Button+ButtonClickedEvent, UnityEngine.UI, Version=1.0.0.0, - Culture=neutral, PublicKeyToken=null ---- !u!114 &1858885004 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 1858885001} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: -765806418, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 1, g: 1, b: 1, a: 1} - m_RaycastTarget: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} - m_Type: 1 - m_PreserveAspect: 0 - m_FillCenter: 1 - m_FillMethod: 4 - m_FillAmount: 1 - m_FillClockwise: 1 - m_FillOrigin: 0 ---- !u!222 &1858885005 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 1858885001} ---- !u!1 &1929635628 -GameObject: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - serializedVersion: 5 - m_Component: - - component: {fileID: 1929635630} - - component: {fileID: 1929635629} - m_Layer: 0 - m_Name: Discord - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!114 &1929635629 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 1929635628} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 27f0a5f59ffffa84c86547736e2e730a, type: 3} - m_Name: - m_EditorClassIdentifier: - presence: - state: Button clicking - details: Best game ever - startTimestamp: 0 - endTimestamp: 0 - largeImageKey: stable-large - largeImageText: - smallImageKey: canary-small - smallImageText: - partyId: abcdefg - partySize: 1 - partyMax: 10 - matchSecret: match_secret - joinSecret: join_secret - spectateSecret: spectate_secret - instance: 1 - applicationId: 345229890980937739 - optionalSteamId: - callbackCalls: 0 - clickCounter: 0 - joinRequest: - userId: - username: - discriminator: - avatar: - onConnect: - m_PersistentCalls: - m_Calls: - - m_Target: {fileID: 657463236} - m_MethodName: set_text - m_Mode: 5 - m_Arguments: - m_ObjectArgument: {fileID: 0} - m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine - m_IntArgument: 0 - m_FloatArgument: 0 - m_StringArgument: Discord Connected - m_BoolArgument: 1 - m_CallState: 2 - m_TypeName: UnityEngine.Events.UnityEvent, UnityEngine, Version=0.0.0.0, Culture=neutral, - PublicKeyToken=null - onDisconnect: - m_PersistentCalls: - m_Calls: - - m_Target: {fileID: 657463236} - m_MethodName: set_text - m_Mode: 5 - m_Arguments: - m_ObjectArgument: {fileID: 0} - m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine - m_IntArgument: 0 - m_FloatArgument: 0 - m_StringArgument: Discord Disconnected - m_BoolArgument: 0 - m_CallState: 2 - m_TypeName: UnityEngine.Events.UnityEvent, UnityEngine, Version=0.0.0.0, Culture=neutral, - PublicKeyToken=null - hasResponded: - m_PersistentCalls: - m_Calls: - - m_Target: {fileID: 1238162988} - m_MethodName: set_text - m_Mode: 5 - m_Arguments: - m_ObjectArgument: {fileID: 0} - m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine - m_IntArgument: 0 - m_FloatArgument: 0 - m_StringArgument: No requests yet - m_BoolArgument: 0 - m_CallState: 2 - - m_Target: {fileID: 806911718} - m_MethodName: set_interactable - m_Mode: 6 - m_Arguments: - m_ObjectArgument: {fileID: 0} - m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine - m_IntArgument: 0 - m_FloatArgument: 0 - m_StringArgument: - m_BoolArgument: 0 - m_CallState: 2 - - m_Target: {fileID: 1858885003} - m_MethodName: set_interactable - m_Mode: 6 - m_Arguments: - m_ObjectArgument: {fileID: 0} - m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine - m_IntArgument: 0 - m_FloatArgument: 0 - m_StringArgument: - m_BoolArgument: 0 - m_CallState: 2 - m_TypeName: UnityEngine.Events.UnityEvent, UnityEngine, Version=0.0.0.0, Culture=neutral, - PublicKeyToken=null - onJoin: - m_PersistentCalls: - m_Calls: [] - m_TypeName: DiscordJoinEvent, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, - PublicKeyToken=null - onSpectate: - m_PersistentCalls: - m_Calls: [] - m_TypeName: DiscordJoinEvent, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, - PublicKeyToken=null - onJoinRequest: - m_PersistentCalls: - m_Calls: - - m_Target: {fileID: 1238162988} - m_MethodName: set_text - m_Mode: 5 - m_Arguments: - m_ObjectArgument: {fileID: 0} - m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine - m_IntArgument: 0 - m_FloatArgument: 0 - m_StringArgument: Someone asked to join! - m_BoolArgument: 0 - m_CallState: 2 - - m_Target: {fileID: 806911718} - m_MethodName: set_interactable - m_Mode: 6 - m_Arguments: - m_ObjectArgument: {fileID: 0} - m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine - m_IntArgument: 0 - m_FloatArgument: 0 - m_StringArgument: - m_BoolArgument: 1 - m_CallState: 2 - - m_Target: {fileID: 1858885003} - m_MethodName: set_interactable - m_Mode: 6 - m_Arguments: - m_ObjectArgument: {fileID: 0} - m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine - m_IntArgument: 0 - m_FloatArgument: 0 - m_StringArgument: - m_BoolArgument: 1 - m_CallState: 2 - m_TypeName: DiscordJoinRequestEvent, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, - PublicKeyToken=null ---- !u!4 &1929635630 -Transform: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 1929635628} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 0} - m_RootOrder: 3 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!1 &1958982061 -GameObject: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - serializedVersion: 5 - m_Component: - - component: {fileID: 1958982062} - - component: {fileID: 1958982064} - - component: {fileID: 1958982063} - m_Layer: 5 - m_Name: Text - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &1958982062 -RectTransform: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 1958982061} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 1858885002} - m_RootOrder: 0 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 0, y: 0} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &1958982063 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 1958982061} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 708705254, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} - m_RaycastTarget: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_FontData: - m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} - m_FontSize: 14 - m_FontStyle: 0 - m_BestFit: 0 - m_MinSize: 10 - m_MaxSize: 40 - m_Alignment: 4 - m_AlignByGeometry: 0 - m_RichText: 1 - m_HorizontalOverflow: 0 - m_VerticalOverflow: 0 - m_LineSpacing: 1 - m_Text: No ---- !u!222 &1958982064 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 1958982061} diff --git a/dependencies/discord-rpc/examples/button-clicker/Assets/main.unity.meta b/dependencies/discord-rpc/examples/button-clicker/Assets/main.unity.meta deleted file mode 100644 index 75654f19..00000000 --- a/dependencies/discord-rpc/examples/button-clicker/Assets/main.unity.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 3b03d21bb25fa494e8694cd6e4b6d769 -timeCreated: 1501696924 -licenseType: Free -DefaultImporter: - userData: - assetBundleName: - assetBundleVariant: diff --git a/dependencies/discord-rpc/examples/button-clicker/ProjectSettings/AudioManager.asset b/dependencies/discord-rpc/examples/button-clicker/ProjectSettings/AudioManager.asset deleted file mode 100644 index da611257..00000000 --- a/dependencies/discord-rpc/examples/button-clicker/ProjectSettings/AudioManager.asset +++ /dev/null @@ -1,17 +0,0 @@ -%YAML 1.1 -%TAG !u! tag:unity3d.com,2011: ---- !u!11 &1 -AudioManager: - m_ObjectHideFlags: 0 - m_Volume: 1 - Rolloff Scale: 1 - Doppler Factor: 1 - Default Speaker Mode: 2 - m_SampleRate: 0 - m_DSPBufferSize: 0 - m_VirtualVoiceCount: 512 - m_RealVoiceCount: 32 - m_SpatializerPlugin: - m_AmbisonicDecoderPlugin: - m_DisableAudio: 0 - m_VirtualizeEffects: 1 diff --git a/dependencies/discord-rpc/examples/button-clicker/ProjectSettings/ClusterInputManager.asset b/dependencies/discord-rpc/examples/button-clicker/ProjectSettings/ClusterInputManager.asset deleted file mode 100644 index e7886b26..00000000 --- a/dependencies/discord-rpc/examples/button-clicker/ProjectSettings/ClusterInputManager.asset +++ /dev/null @@ -1,6 +0,0 @@ -%YAML 1.1 -%TAG !u! tag:unity3d.com,2011: ---- !u!236 &1 -ClusterInputManager: - m_ObjectHideFlags: 0 - m_Inputs: [] diff --git a/dependencies/discord-rpc/examples/button-clicker/ProjectSettings/DynamicsManager.asset b/dependencies/discord-rpc/examples/button-clicker/ProjectSettings/DynamicsManager.asset deleted file mode 100644 index 0be3d787..00000000 --- a/dependencies/discord-rpc/examples/button-clicker/ProjectSettings/DynamicsManager.asset +++ /dev/null @@ -1,20 +0,0 @@ -%YAML 1.1 -%TAG !u! tag:unity3d.com,2011: ---- !u!55 &1 -PhysicsManager: - m_ObjectHideFlags: 0 - serializedVersion: 3 - m_Gravity: {x: 0, y: -9.81, z: 0} - m_DefaultMaterial: {fileID: 0} - m_BounceThreshold: 2 - m_SleepThreshold: 0.005 - m_DefaultContactOffset: 0.01 - m_DefaultSolverIterations: 6 - m_DefaultSolverVelocityIterations: 1 - m_QueriesHitBackfaces: 0 - m_QueriesHitTriggers: 1 - m_EnableAdaptiveForce: 0 - m_EnablePCM: 1 - m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff - m_AutoSimulation: 1 - m_AutoSyncTransforms: 1 diff --git a/dependencies/discord-rpc/examples/button-clicker/ProjectSettings/EditorBuildSettings.asset b/dependencies/discord-rpc/examples/button-clicker/ProjectSettings/EditorBuildSettings.asset deleted file mode 100644 index d8fda848..00000000 --- a/dependencies/discord-rpc/examples/button-clicker/ProjectSettings/EditorBuildSettings.asset +++ /dev/null @@ -1,10 +0,0 @@ -%YAML 1.1 -%TAG !u! tag:unity3d.com,2011: ---- !u!1045 &1 -EditorBuildSettings: - m_ObjectHideFlags: 0 - serializedVersion: 2 - m_Scenes: - - enabled: 1 - path: Assets/main.unity - guid: 3b03d21bb25fa494e8694cd6e4b6d769 diff --git a/dependencies/discord-rpc/examples/button-clicker/ProjectSettings/EditorSettings.asset b/dependencies/discord-rpc/examples/button-clicker/ProjectSettings/EditorSettings.asset deleted file mode 100644 index c0c814fd..00000000 --- a/dependencies/discord-rpc/examples/button-clicker/ProjectSettings/EditorSettings.asset +++ /dev/null @@ -1,16 +0,0 @@ -%YAML 1.1 -%TAG !u! tag:unity3d.com,2011: ---- !u!159 &1 -EditorSettings: - m_ObjectHideFlags: 0 - serializedVersion: 4 - m_ExternalVersionControlSupport: Visible Meta Files - m_SerializationMode: 2 - m_DefaultBehaviorMode: 1 - m_SpritePackerMode: 4 - m_SpritePackerPaddingPower: 1 - m_ProjectGenerationIncludedExtensions: txt;xml;fnt;cd - m_ProjectGenerationRootNamespace: - m_UserGeneratedProjectSuffix: - m_CollabEditorSettings: - inProgressEnabled: 1 diff --git a/dependencies/discord-rpc/examples/button-clicker/ProjectSettings/GraphicsSettings.asset b/dependencies/discord-rpc/examples/button-clicker/ProjectSettings/GraphicsSettings.asset deleted file mode 100644 index 74d7b532..00000000 --- a/dependencies/discord-rpc/examples/button-clicker/ProjectSettings/GraphicsSettings.asset +++ /dev/null @@ -1,61 +0,0 @@ -%YAML 1.1 -%TAG !u! tag:unity3d.com,2011: ---- !u!30 &1 -GraphicsSettings: - m_ObjectHideFlags: 0 - serializedVersion: 12 - m_Deferred: - m_Mode: 1 - m_Shader: {fileID: 69, guid: 0000000000000000f000000000000000, type: 0} - m_DeferredReflections: - m_Mode: 1 - m_Shader: {fileID: 74, guid: 0000000000000000f000000000000000, type: 0} - m_ScreenSpaceShadows: - m_Mode: 1 - m_Shader: {fileID: 64, guid: 0000000000000000f000000000000000, type: 0} - m_LegacyDeferred: - m_Mode: 1 - m_Shader: {fileID: 63, guid: 0000000000000000f000000000000000, type: 0} - m_DepthNormals: - m_Mode: 1 - m_Shader: {fileID: 62, guid: 0000000000000000f000000000000000, type: 0} - m_MotionVectors: - m_Mode: 1 - m_Shader: {fileID: 75, guid: 0000000000000000f000000000000000, type: 0} - m_LightHalo: - m_Mode: 1 - m_Shader: {fileID: 105, guid: 0000000000000000f000000000000000, type: 0} - m_LensFlare: - m_Mode: 1 - m_Shader: {fileID: 102, guid: 0000000000000000f000000000000000, type: 0} - m_AlwaysIncludedShaders: - - {fileID: 7, guid: 0000000000000000f000000000000000, type: 0} - - {fileID: 15104, guid: 0000000000000000f000000000000000, type: 0} - - {fileID: 15105, guid: 0000000000000000f000000000000000, type: 0} - - {fileID: 15106, guid: 0000000000000000f000000000000000, type: 0} - - {fileID: 10753, guid: 0000000000000000f000000000000000, type: 0} - - {fileID: 10770, guid: 0000000000000000f000000000000000, type: 0} - m_PreloadedShaders: [] - m_SpritesDefaultMaterial: {fileID: 10754, guid: 0000000000000000f000000000000000, - type: 0} - m_CustomRenderPipeline: {fileID: 0} - m_TransparencySortMode: 0 - m_TransparencySortAxis: {x: 0, y: 0, z: 1} - m_DefaultRenderingPath: 1 - m_DefaultMobileRenderingPath: 1 - m_TierSettings: [] - m_LightmapStripping: 0 - m_FogStripping: 0 - m_InstancingStripping: 0 - m_LightmapKeepPlain: 1 - m_LightmapKeepDirCombined: 1 - m_LightmapKeepDynamicPlain: 1 - m_LightmapKeepDynamicDirCombined: 1 - m_LightmapKeepShadowMask: 1 - m_LightmapKeepSubtractive: 1 - m_FogKeepLinear: 1 - m_FogKeepExp: 1 - m_FogKeepExp2: 1 - m_AlbedoSwatchInfos: [] - m_LightsUseLinearIntensity: 0 - m_LightsUseColorTemperature: 0 diff --git a/dependencies/discord-rpc/examples/button-clicker/ProjectSettings/InputManager.asset b/dependencies/discord-rpc/examples/button-clicker/ProjectSettings/InputManager.asset deleted file mode 100644 index 17c8f538..00000000 --- a/dependencies/discord-rpc/examples/button-clicker/ProjectSettings/InputManager.asset +++ /dev/null @@ -1,295 +0,0 @@ -%YAML 1.1 -%TAG !u! tag:unity3d.com,2011: ---- !u!13 &1 -InputManager: - m_ObjectHideFlags: 0 - serializedVersion: 2 - m_Axes: - - serializedVersion: 3 - m_Name: Horizontal - descriptiveName: - descriptiveNegativeName: - negativeButton: left - positiveButton: right - altNegativeButton: a - altPositiveButton: d - gravity: 3 - dead: 0.001 - sensitivity: 3 - snap: 1 - invert: 0 - type: 0 - axis: 0 - joyNum: 0 - - serializedVersion: 3 - m_Name: Vertical - descriptiveName: - descriptiveNegativeName: - negativeButton: down - positiveButton: up - altNegativeButton: s - altPositiveButton: w - gravity: 3 - dead: 0.001 - sensitivity: 3 - snap: 1 - invert: 0 - type: 0 - axis: 0 - joyNum: 0 - - serializedVersion: 3 - m_Name: Fire1 - descriptiveName: - descriptiveNegativeName: - negativeButton: - positiveButton: left ctrl - altNegativeButton: - altPositiveButton: mouse 0 - gravity: 1000 - dead: 0.001 - sensitivity: 1000 - snap: 0 - invert: 0 - type: 0 - axis: 0 - joyNum: 0 - - serializedVersion: 3 - m_Name: Fire2 - descriptiveName: - descriptiveNegativeName: - negativeButton: - positiveButton: left alt - altNegativeButton: - altPositiveButton: mouse 1 - gravity: 1000 - dead: 0.001 - sensitivity: 1000 - snap: 0 - invert: 0 - type: 0 - axis: 0 - joyNum: 0 - - serializedVersion: 3 - m_Name: Fire3 - descriptiveName: - descriptiveNegativeName: - negativeButton: - positiveButton: left shift - altNegativeButton: - altPositiveButton: mouse 2 - gravity: 1000 - dead: 0.001 - sensitivity: 1000 - snap: 0 - invert: 0 - type: 0 - axis: 0 - joyNum: 0 - - serializedVersion: 3 - m_Name: Jump - descriptiveName: - descriptiveNegativeName: - negativeButton: - positiveButton: space - altNegativeButton: - altPositiveButton: - gravity: 1000 - dead: 0.001 - sensitivity: 1000 - snap: 0 - invert: 0 - type: 0 - axis: 0 - joyNum: 0 - - serializedVersion: 3 - m_Name: Mouse X - descriptiveName: - descriptiveNegativeName: - negativeButton: - positiveButton: - altNegativeButton: - altPositiveButton: - gravity: 0 - dead: 0 - sensitivity: 0.1 - snap: 0 - invert: 0 - type: 1 - axis: 0 - joyNum: 0 - - serializedVersion: 3 - m_Name: Mouse Y - descriptiveName: - descriptiveNegativeName: - negativeButton: - positiveButton: - altNegativeButton: - altPositiveButton: - gravity: 0 - dead: 0 - sensitivity: 0.1 - snap: 0 - invert: 0 - type: 1 - axis: 1 - joyNum: 0 - - serializedVersion: 3 - m_Name: Mouse ScrollWheel - descriptiveName: - descriptiveNegativeName: - negativeButton: - positiveButton: - altNegativeButton: - altPositiveButton: - gravity: 0 - dead: 0 - sensitivity: 0.1 - snap: 0 - invert: 0 - type: 1 - axis: 2 - joyNum: 0 - - serializedVersion: 3 - m_Name: Horizontal - descriptiveName: - descriptiveNegativeName: - negativeButton: - positiveButton: - altNegativeButton: - altPositiveButton: - gravity: 0 - dead: 0.19 - sensitivity: 1 - snap: 0 - invert: 0 - type: 2 - axis: 0 - joyNum: 0 - - serializedVersion: 3 - m_Name: Vertical - descriptiveName: - descriptiveNegativeName: - negativeButton: - positiveButton: - altNegativeButton: - altPositiveButton: - gravity: 0 - dead: 0.19 - sensitivity: 1 - snap: 0 - invert: 1 - type: 2 - axis: 1 - joyNum: 0 - - serializedVersion: 3 - m_Name: Fire1 - descriptiveName: - descriptiveNegativeName: - negativeButton: - positiveButton: joystick button 0 - altNegativeButton: - altPositiveButton: - gravity: 1000 - dead: 0.001 - sensitivity: 1000 - snap: 0 - invert: 0 - type: 0 - axis: 0 - joyNum: 0 - - serializedVersion: 3 - m_Name: Fire2 - descriptiveName: - descriptiveNegativeName: - negativeButton: - positiveButton: joystick button 1 - altNegativeButton: - altPositiveButton: - gravity: 1000 - dead: 0.001 - sensitivity: 1000 - snap: 0 - invert: 0 - type: 0 - axis: 0 - joyNum: 0 - - serializedVersion: 3 - m_Name: Fire3 - descriptiveName: - descriptiveNegativeName: - negativeButton: - positiveButton: joystick button 2 - altNegativeButton: - altPositiveButton: - gravity: 1000 - dead: 0.001 - sensitivity: 1000 - snap: 0 - invert: 0 - type: 0 - axis: 0 - joyNum: 0 - - serializedVersion: 3 - m_Name: Jump - descriptiveName: - descriptiveNegativeName: - negativeButton: - positiveButton: joystick button 3 - altNegativeButton: - altPositiveButton: - gravity: 1000 - dead: 0.001 - sensitivity: 1000 - snap: 0 - invert: 0 - type: 0 - axis: 0 - joyNum: 0 - - serializedVersion: 3 - m_Name: Submit - descriptiveName: - descriptiveNegativeName: - negativeButton: - positiveButton: return - altNegativeButton: - altPositiveButton: joystick button 0 - gravity: 1000 - dead: 0.001 - sensitivity: 1000 - snap: 0 - invert: 0 - type: 0 - axis: 0 - joyNum: 0 - - serializedVersion: 3 - m_Name: Submit - descriptiveName: - descriptiveNegativeName: - negativeButton: - positiveButton: enter - altNegativeButton: - altPositiveButton: space - gravity: 1000 - dead: 0.001 - sensitivity: 1000 - snap: 0 - invert: 0 - type: 0 - axis: 0 - joyNum: 0 - - serializedVersion: 3 - m_Name: Cancel - descriptiveName: - descriptiveNegativeName: - negativeButton: - positiveButton: escape - altNegativeButton: - altPositiveButton: joystick button 1 - gravity: 1000 - dead: 0.001 - sensitivity: 1000 - snap: 0 - invert: 0 - type: 0 - axis: 0 - joyNum: 0 diff --git a/dependencies/discord-rpc/examples/button-clicker/ProjectSettings/NavMeshAreas.asset b/dependencies/discord-rpc/examples/button-clicker/ProjectSettings/NavMeshAreas.asset deleted file mode 100644 index 6dd520f6..00000000 --- a/dependencies/discord-rpc/examples/button-clicker/ProjectSettings/NavMeshAreas.asset +++ /dev/null @@ -1,89 +0,0 @@ -%YAML 1.1 -%TAG !u! tag:unity3d.com,2011: ---- !u!126 &1 -NavMeshProjectSettings: - m_ObjectHideFlags: 0 - serializedVersion: 2 - areas: - - name: Walkable - cost: 1 - - name: Not Walkable - cost: 1 - - name: Jump - cost: 2 - - name: - cost: 1 - - name: - cost: 1 - - name: - cost: 1 - - name: - cost: 1 - - name: - cost: 1 - - name: - cost: 1 - - name: - cost: 1 - - name: - cost: 1 - - name: - cost: 1 - - name: - cost: 1 - - name: - cost: 1 - - name: - cost: 1 - - name: - cost: 1 - - name: - cost: 1 - - name: - cost: 1 - - name: - cost: 1 - - name: - cost: 1 - - name: - cost: 1 - - name: - cost: 1 - - name: - cost: 1 - - name: - cost: 1 - - name: - cost: 1 - - name: - cost: 1 - - name: - cost: 1 - - name: - cost: 1 - - name: - cost: 1 - - name: - cost: 1 - - name: - cost: 1 - - name: - cost: 1 - m_LastAgentTypeID: -887442657 - m_Settings: - - serializedVersion: 2 - agentTypeID: 0 - agentRadius: 0.5 - agentHeight: 2 - agentSlope: 45 - agentClimb: 0.75 - ledgeDropHeight: 0 - maxJumpAcrossDistance: 0 - minRegionArea: 2 - manualCellSize: 0 - cellSize: 0.16666667 - manualTileSize: 0 - tileSize: 256 - accuratePlacement: 0 - m_SettingNames: - - Humanoid diff --git a/dependencies/discord-rpc/examples/button-clicker/ProjectSettings/NetworkManager.asset b/dependencies/discord-rpc/examples/button-clicker/ProjectSettings/NetworkManager.asset deleted file mode 100644 index 5dc6a831..00000000 --- a/dependencies/discord-rpc/examples/button-clicker/ProjectSettings/NetworkManager.asset +++ /dev/null @@ -1,8 +0,0 @@ -%YAML 1.1 -%TAG !u! tag:unity3d.com,2011: ---- !u!149 &1 -NetworkManager: - m_ObjectHideFlags: 0 - m_DebugLevel: 0 - m_Sendrate: 15 - m_AssetToPrefab: {} diff --git a/dependencies/discord-rpc/examples/button-clicker/ProjectSettings/Physics2DSettings.asset b/dependencies/discord-rpc/examples/button-clicker/ProjectSettings/Physics2DSettings.asset deleted file mode 100644 index 132ee6bc..00000000 --- a/dependencies/discord-rpc/examples/button-clicker/ProjectSettings/Physics2DSettings.asset +++ /dev/null @@ -1,37 +0,0 @@ -%YAML 1.1 -%TAG !u! tag:unity3d.com,2011: ---- !u!19 &1 -Physics2DSettings: - m_ObjectHideFlags: 0 - serializedVersion: 3 - m_Gravity: {x: 0, y: -9.81} - m_DefaultMaterial: {fileID: 0} - m_VelocityIterations: 8 - m_PositionIterations: 3 - m_VelocityThreshold: 1 - m_MaxLinearCorrection: 0.2 - m_MaxAngularCorrection: 8 - m_MaxTranslationSpeed: 100 - m_MaxRotationSpeed: 360 - m_BaumgarteScale: 0.2 - m_BaumgarteTimeOfImpactScale: 0.75 - m_TimeToSleep: 0.5 - m_LinearSleepTolerance: 0.01 - m_AngularSleepTolerance: 2 - m_DefaultContactOffset: 0.01 - m_AutoSimulation: 1 - m_QueriesHitTriggers: 1 - m_QueriesStartInColliders: 1 - m_ChangeStopsCallbacks: 0 - m_CallbacksOnDisable: 1 - m_AutoSyncTransforms: 1 - m_AlwaysShowColliders: 0 - m_ShowColliderSleep: 1 - m_ShowColliderContacts: 0 - m_ShowColliderAABB: 0 - m_ContactArrowScale: 0.2 - m_ColliderAwakeColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.7529412} - m_ColliderAsleepColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.36078432} - m_ColliderContactColor: {r: 1, g: 0, b: 1, a: 0.6862745} - m_ColliderAABBColor: {r: 1, g: 1, b: 0, a: 0.2509804} - m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff diff --git a/dependencies/discord-rpc/examples/button-clicker/ProjectSettings/ProjectSettings.asset b/dependencies/discord-rpc/examples/button-clicker/ProjectSettings/ProjectSettings.asset deleted file mode 100644 index f60fe83a..00000000 --- a/dependencies/discord-rpc/examples/button-clicker/ProjectSettings/ProjectSettings.asset +++ /dev/null @@ -1,610 +0,0 @@ -%YAML 1.1 -%TAG !u! tag:unity3d.com,2011: ---- !u!129 &1 -PlayerSettings: - m_ObjectHideFlags: 0 - serializedVersion: 13 - productGUID: 5eccc60d3e382a346a65f512d6b81b84 - AndroidProfiler: 0 - AndroidFilterTouchesWhenObscured: 0 - defaultScreenOrientation: 4 - targetDevice: 2 - useOnDemandResources: 0 - accelerometerFrequency: 60 - companyName: Discord Inc. - productName: button-clicker - defaultCursor: {fileID: 0} - cursorHotspot: {x: 0, y: 0} - m_SplashScreenBackgroundColor: {r: 0.13725491, g: 0.12156863, b: 0.1254902, a: 1} - m_ShowUnitySplashScreen: 1 - m_ShowUnitySplashLogo: 1 - m_SplashScreenOverlayOpacity: 1 - m_SplashScreenAnimation: 1 - m_SplashScreenLogoStyle: 1 - m_SplashScreenDrawMode: 0 - m_SplashScreenBackgroundAnimationZoom: 1 - m_SplashScreenLogoAnimationZoom: 1 - m_SplashScreenBackgroundLandscapeAspect: 1 - m_SplashScreenBackgroundPortraitAspect: 1 - m_SplashScreenBackgroundLandscapeUvs: - serializedVersion: 2 - x: 0 - y: 0 - width: 1 - height: 1 - m_SplashScreenBackgroundPortraitUvs: - serializedVersion: 2 - x: 0 - y: 0 - width: 1 - height: 1 - m_SplashScreenLogos: [] - m_VirtualRealitySplashScreen: {fileID: 0} - m_HolographicTrackingLossScreen: {fileID: 0} - defaultScreenWidth: 1024 - defaultScreenHeight: 768 - defaultScreenWidthWeb: 960 - defaultScreenHeightWeb: 600 - m_StereoRenderingPath: 0 - m_ActiveColorSpace: 0 - m_MTRendering: 1 - m_StackTraceTypes: 010000000100000001000000010000000100000001000000 - iosShowActivityIndicatorOnLoading: -1 - androidShowActivityIndicatorOnLoading: -1 - tizenShowActivityIndicatorOnLoading: -1 - iosAppInBackgroundBehavior: 0 - displayResolutionDialog: 1 - iosAllowHTTPDownload: 1 - allowedAutorotateToPortrait: 1 - allowedAutorotateToPortraitUpsideDown: 1 - allowedAutorotateToLandscapeRight: 1 - allowedAutorotateToLandscapeLeft: 1 - useOSAutorotation: 1 - use32BitDisplayBuffer: 1 - disableDepthAndStencilBuffers: 0 - androidBlitType: 0 - defaultIsFullScreen: 1 - defaultIsNativeResolution: 1 - macRetinaSupport: 1 - runInBackground: 0 - captureSingleScreen: 0 - muteOtherAudioSources: 0 - Prepare IOS For Recording: 0 - Force IOS Speakers When Recording: 0 - submitAnalytics: 1 - usePlayerLog: 1 - bakeCollisionMeshes: 0 - forceSingleInstance: 0 - resizableWindow: 0 - useMacAppStoreValidation: 0 - macAppStoreCategory: public.app-category.games - gpuSkinning: 0 - graphicsJobs: 0 - xboxPIXTextureCapture: 0 - xboxEnableAvatar: 0 - xboxEnableKinect: 0 - xboxEnableKinectAutoTracking: 0 - xboxEnableFitness: 0 - visibleInBackground: 1 - allowFullscreenSwitch: 1 - graphicsJobMode: 0 - macFullscreenMode: 2 - d3d9FullscreenMode: 1 - d3d11FullscreenMode: 1 - xboxSpeechDB: 0 - xboxEnableHeadOrientation: 0 - xboxEnableGuest: 0 - xboxEnablePIXSampling: 0 - metalFramebufferOnly: 0 - n3dsDisableStereoscopicView: 0 - n3dsEnableSharedListOpt: 1 - n3dsEnableVSync: 0 - ignoreAlphaClear: 0 - xboxOneResolution: 0 - xboxOneMonoLoggingLevel: 0 - xboxOneLoggingLevel: 1 - xboxOneDisableEsram: 0 - xboxOnePresentImmediateThreshold: 0 - videoMemoryForVertexBuffers: 0 - psp2PowerMode: 0 - psp2AcquireBGM: 1 - wiiUTVResolution: 0 - wiiUGamePadMSAA: 1 - wiiUSupportsNunchuk: 0 - wiiUSupportsClassicController: 0 - wiiUSupportsBalanceBoard: 0 - wiiUSupportsMotionPlus: 0 - wiiUSupportsProController: 0 - wiiUAllowScreenCapture: 1 - wiiUControllerCount: 0 - m_SupportedAspectRatios: - 4:3: 1 - 5:4: 1 - 16:10: 1 - 16:9: 1 - Others: 1 - bundleVersion: 1.0 - preloadedAssets: [] - metroInputSource: 0 - m_HolographicPauseOnTrackingLoss: 1 - xboxOneDisableKinectGpuReservation: 0 - xboxOneEnable7thCore: 0 - vrSettings: - cardboard: - depthFormat: 0 - enableTransitionView: 0 - daydream: - depthFormat: 0 - useSustainedPerformanceMode: 0 - enableVideoLayer: 0 - useProtectedVideoMemory: 0 - hololens: - depthFormat: 1 - protectGraphicsMemory: 0 - useHDRDisplay: 0 - m_ColorGamuts: 00000000 - targetPixelDensity: 0 - resolutionScalingMode: 0 - androidSupportedAspectRatio: 1 - androidMaxAspectRatio: 2.1 - applicationIdentifier: {} - buildNumber: {} - AndroidBundleVersionCode: 1 - AndroidMinSdkVersion: 16 - AndroidTargetSdkVersion: 0 - AndroidPreferredInstallLocation: 1 - aotOptions: - stripEngineCode: 1 - iPhoneStrippingLevel: 0 - iPhoneScriptCallOptimization: 0 - ForceInternetPermission: 0 - ForceSDCardPermission: 0 - CreateWallpaper: 0 - APKExpansionFiles: 0 - keepLoadedShadersAlive: 0 - StripUnusedMeshComponents: 0 - VertexChannelCompressionMask: - serializedVersion: 2 - m_Bits: 238 - iPhoneSdkVersion: 988 - iOSTargetOSVersionString: 7.0 - tvOSSdkVersion: 0 - tvOSRequireExtendedGameController: 0 - tvOSTargetOSVersionString: 9.0 - uIPrerenderedIcon: 0 - uIRequiresPersistentWiFi: 0 - uIRequiresFullScreen: 1 - uIStatusBarHidden: 1 - uIExitOnSuspend: 0 - uIStatusBarStyle: 0 - iPhoneSplashScreen: {fileID: 0} - iPhoneHighResSplashScreen: {fileID: 0} - iPhoneTallHighResSplashScreen: {fileID: 0} - iPhone47inSplashScreen: {fileID: 0} - iPhone55inPortraitSplashScreen: {fileID: 0} - iPhone55inLandscapeSplashScreen: {fileID: 0} - iPadPortraitSplashScreen: {fileID: 0} - iPadHighResPortraitSplashScreen: {fileID: 0} - iPadLandscapeSplashScreen: {fileID: 0} - iPadHighResLandscapeSplashScreen: {fileID: 0} - appleTVSplashScreen: {fileID: 0} - tvOSSmallIconLayers: [] - tvOSLargeIconLayers: [] - tvOSTopShelfImageLayers: [] - tvOSTopShelfImageWideLayers: [] - iOSLaunchScreenType: 0 - iOSLaunchScreenPortrait: {fileID: 0} - iOSLaunchScreenLandscape: {fileID: 0} - iOSLaunchScreenBackgroundColor: - serializedVersion: 2 - rgba: 0 - iOSLaunchScreenFillPct: 100 - iOSLaunchScreenSize: 100 - iOSLaunchScreenCustomXibPath: - iOSLaunchScreeniPadType: 0 - iOSLaunchScreeniPadImage: {fileID: 0} - iOSLaunchScreeniPadBackgroundColor: - serializedVersion: 2 - rgba: 0 - iOSLaunchScreeniPadFillPct: 100 - iOSLaunchScreeniPadSize: 100 - iOSLaunchScreeniPadCustomXibPath: - iOSDeviceRequirements: [] - iOSURLSchemes: [] - iOSBackgroundModes: 0 - iOSMetalForceHardShadows: 0 - metalEditorSupport: 1 - metalAPIValidation: 1 - iOSRenderExtraFrameOnPause: 0 - appleDeveloperTeamID: - iOSManualSigningProvisioningProfileID: - tvOSManualSigningProvisioningProfileID: - appleEnableAutomaticSigning: 0 - AndroidTargetDevice: 0 - AndroidSplashScreenScale: 0 - androidSplashScreen: {fileID: 0} - AndroidKeystoreName: - AndroidKeyaliasName: - AndroidTVCompatibility: 1 - AndroidIsGame: 1 - AndroidEnableTango: 0 - androidEnableBanner: 1 - androidUseLowAccuracyLocation: 0 - m_AndroidBanners: - - width: 320 - height: 180 - banner: {fileID: 0} - androidGamepadSupportLevel: 0 - resolutionDialogBanner: {fileID: 0} - m_BuildTargetIcons: [] - m_BuildTargetBatching: [] - m_BuildTargetGraphicsAPIs: [] - m_BuildTargetVRSettings: [] - m_BuildTargetEnableVuforiaSettings: [] - openGLRequireES31: 0 - openGLRequireES31AEP: 0 - m_TemplateCustomTags: {} - mobileMTRendering: - Android: 1 - iPhone: 1 - tvOS: 1 - wiiUTitleID: 0005000011000000 - wiiUGroupID: 00010000 - wiiUCommonSaveSize: 4096 - wiiUAccountSaveSize: 2048 - wiiUOlvAccessKey: 0 - wiiUTinCode: 0 - wiiUJoinGameId: 0 - wiiUJoinGameModeMask: 0000000000000000 - wiiUCommonBossSize: 0 - wiiUAccountBossSize: 0 - wiiUAddOnUniqueIDs: [] - wiiUMainThreadStackSize: 3072 - wiiULoaderThreadStackSize: 1024 - wiiUSystemHeapSize: 128 - wiiUTVStartupScreen: {fileID: 0} - wiiUGamePadStartupScreen: {fileID: 0} - wiiUDrcBufferDisabled: 0 - wiiUProfilerLibPath: - playModeTestRunnerEnabled: 0 - actionOnDotNetUnhandledException: 1 - enableInternalProfiler: 0 - logObjCUncaughtExceptions: 1 - enableCrashReportAPI: 0 - cameraUsageDescription: - locationUsageDescription: - microphoneUsageDescription: - switchNetLibKey: - switchSocketMemoryPoolSize: 6144 - switchSocketAllocatorPoolSize: 128 - switchSocketConcurrencyLimit: 14 - switchScreenResolutionBehavior: 2 - switchUseCPUProfiler: 0 - switchApplicationID: 0x01004b9000490000 - switchNSODependencies: - switchTitleNames_0: - switchTitleNames_1: - switchTitleNames_2: - switchTitleNames_3: - switchTitleNames_4: - switchTitleNames_5: - switchTitleNames_6: - switchTitleNames_7: - switchTitleNames_8: - switchTitleNames_9: - switchTitleNames_10: - switchTitleNames_11: - switchPublisherNames_0: - switchPublisherNames_1: - switchPublisherNames_2: - switchPublisherNames_3: - switchPublisherNames_4: - switchPublisherNames_5: - switchPublisherNames_6: - switchPublisherNames_7: - switchPublisherNames_8: - switchPublisherNames_9: - switchPublisherNames_10: - switchPublisherNames_11: - switchIcons_0: {fileID: 0} - switchIcons_1: {fileID: 0} - switchIcons_2: {fileID: 0} - switchIcons_3: {fileID: 0} - switchIcons_4: {fileID: 0} - switchIcons_5: {fileID: 0} - switchIcons_6: {fileID: 0} - switchIcons_7: {fileID: 0} - switchIcons_8: {fileID: 0} - switchIcons_9: {fileID: 0} - switchIcons_10: {fileID: 0} - switchIcons_11: {fileID: 0} - switchSmallIcons_0: {fileID: 0} - switchSmallIcons_1: {fileID: 0} - switchSmallIcons_2: {fileID: 0} - switchSmallIcons_3: {fileID: 0} - switchSmallIcons_4: {fileID: 0} - switchSmallIcons_5: {fileID: 0} - switchSmallIcons_6: {fileID: 0} - switchSmallIcons_7: {fileID: 0} - switchSmallIcons_8: {fileID: 0} - switchSmallIcons_9: {fileID: 0} - switchSmallIcons_10: {fileID: 0} - switchSmallIcons_11: {fileID: 0} - switchManualHTML: - switchAccessibleURLs: - switchLegalInformation: - switchMainThreadStackSize: 1048576 - switchPresenceGroupId: 0x01004b9000490000 - switchLogoHandling: 0 - switchReleaseVersion: 0 - switchDisplayVersion: 1.0.0 - switchStartupUserAccount: 0 - switchTouchScreenUsage: 0 - switchSupportedLanguagesMask: 0 - switchLogoType: 0 - switchApplicationErrorCodeCategory: - switchUserAccountSaveDataSize: 0 - switchUserAccountSaveDataJournalSize: 0 - switchApplicationAttribute: 0 - switchCardSpecSize: 4 - switchCardSpecClock: 25 - switchRatingsMask: 0 - switchRatingsInt_0: 0 - switchRatingsInt_1: 0 - switchRatingsInt_2: 0 - switchRatingsInt_3: 0 - switchRatingsInt_4: 0 - switchRatingsInt_5: 0 - switchRatingsInt_6: 0 - switchRatingsInt_7: 0 - switchRatingsInt_8: 0 - switchRatingsInt_9: 0 - switchRatingsInt_10: 0 - switchRatingsInt_11: 0 - switchLocalCommunicationIds_0: 0x01004b9000490000 - switchLocalCommunicationIds_1: - switchLocalCommunicationIds_2: - switchLocalCommunicationIds_3: - switchLocalCommunicationIds_4: - switchLocalCommunicationIds_5: - switchLocalCommunicationIds_6: - switchLocalCommunicationIds_7: - switchParentalControl: 0 - switchAllowsScreenshot: 1 - switchDataLossConfirmation: 0 - switchSupportedNpadStyles: 3 - switchSocketConfigEnabled: 0 - switchTcpInitialSendBufferSize: 32 - switchTcpInitialReceiveBufferSize: 64 - switchTcpAutoSendBufferSizeMax: 256 - switchTcpAutoReceiveBufferSizeMax: 256 - switchUdpSendBufferSize: 9 - switchUdpReceiveBufferSize: 42 - switchSocketBufferEfficiency: 4 - switchSocketInitializeEnabled: 1 - switchNetworkInterfaceManagerInitializeEnabled: 1 - switchPlayerConnectionEnabled: 1 - ps4NPAgeRating: 12 - ps4NPTitleSecret: - ps4NPTrophyPackPath: - ps4ParentalLevel: 11 - ps4ContentID: ED1633-NPXX51362_00-0000000000000000 - ps4Category: 0 - ps4MasterVersion: 01.00 - ps4AppVersion: 01.00 - ps4AppType: 0 - ps4ParamSfxPath: - ps4VideoOutPixelFormat: 0 - ps4VideoOutInitialWidth: 1920 - ps4VideoOutBaseModeInitialWidth: 1920 - ps4VideoOutReprojectionRate: 120 - ps4PronunciationXMLPath: - ps4PronunciationSIGPath: - ps4BackgroundImagePath: - ps4StartupImagePath: - ps4SaveDataImagePath: - ps4SdkOverride: - ps4BGMPath: - ps4ShareFilePath: - ps4ShareOverlayImagePath: - ps4PrivacyGuardImagePath: - ps4NPtitleDatPath: - ps4RemotePlayKeyAssignment: -1 - ps4RemotePlayKeyMappingDir: - ps4PlayTogetherPlayerCount: 0 - ps4EnterButtonAssignment: 1 - ps4ApplicationParam1: 0 - ps4ApplicationParam2: 0 - ps4ApplicationParam3: 0 - ps4ApplicationParam4: 0 - ps4DownloadDataSize: 0 - ps4GarlicHeapSize: 2048 - ps4ProGarlicHeapSize: 2560 - ps4Passcode: frAQBc8Wsa1xVPfvJcrgRYwTiizs2trQ - ps4pnSessions: 1 - ps4pnPresence: 1 - ps4pnFriends: 1 - ps4pnGameCustomData: 1 - playerPrefsSupport: 0 - restrictedAudioUsageRights: 0 - ps4UseResolutionFallback: 0 - ps4ReprojectionSupport: 0 - ps4UseAudio3dBackend: 0 - ps4SocialScreenEnabled: 0 - ps4ScriptOptimizationLevel: 0 - ps4Audio3dVirtualSpeakerCount: 14 - ps4attribCpuUsage: 0 - ps4PatchPkgPath: - ps4PatchLatestPkgPath: - ps4PatchChangeinfoPath: - ps4PatchDayOne: 0 - ps4attribUserManagement: 0 - ps4attribMoveSupport: 0 - ps4attrib3DSupport: 0 - ps4attribShareSupport: 0 - ps4attribExclusiveVR: 0 - ps4disableAutoHideSplash: 0 - ps4videoRecordingFeaturesUsed: 0 - ps4contentSearchFeaturesUsed: 0 - ps4attribEyeToEyeDistanceSettingVR: 0 - ps4IncludedModules: [] - monoEnv: - psp2Splashimage: {fileID: 0} - psp2NPTrophyPackPath: - psp2NPSupportGBMorGJP: 0 - psp2NPAgeRating: 12 - psp2NPTitleDatPath: - psp2NPCommsID: - psp2NPCommunicationsID: - psp2NPCommsPassphrase: - psp2NPCommsSig: - psp2ParamSfxPath: - psp2ManualPath: - psp2LiveAreaGatePath: - psp2LiveAreaBackroundPath: - psp2LiveAreaPath: - psp2LiveAreaTrialPath: - psp2PatchChangeInfoPath: - psp2PatchOriginalPackage: - psp2PackagePassword: F69AzBlax3CF3EDNhm3soLBPh71Yexui - psp2KeystoneFile: - psp2MemoryExpansionMode: 0 - psp2DRMType: 0 - psp2StorageType: 0 - psp2MediaCapacity: 0 - psp2DLCConfigPath: - psp2ThumbnailPath: - psp2BackgroundPath: - psp2SoundPath: - psp2TrophyCommId: - psp2TrophyPackagePath: - psp2PackagedResourcesPath: - psp2SaveDataQuota: 10240 - psp2ParentalLevel: 1 - psp2ShortTitle: Not Set - psp2ContentID: IV0000-ABCD12345_00-0123456789ABCDEF - psp2Category: 0 - psp2MasterVersion: 01.00 - psp2AppVersion: 01.00 - psp2TVBootMode: 0 - psp2EnterButtonAssignment: 2 - psp2TVDisableEmu: 0 - psp2AllowTwitterDialog: 1 - psp2Upgradable: 0 - psp2HealthWarning: 0 - psp2UseLibLocation: 0 - psp2InfoBarOnStartup: 0 - psp2InfoBarColor: 0 - psp2ScriptOptimizationLevel: 0 - psmSplashimage: {fileID: 0} - splashScreenBackgroundSourceLandscape: {fileID: 0} - splashScreenBackgroundSourcePortrait: {fileID: 0} - spritePackerPolicy: - webGLMemorySize: 256 - webGLExceptionSupport: 1 - webGLNameFilesAsHashes: 0 - webGLDataCaching: 0 - webGLDebugSymbols: 0 - webGLEmscriptenArgs: - webGLModulesDirectory: - webGLTemplate: APPLICATION:Default - webGLAnalyzeBuildSize: 0 - webGLUseEmbeddedResources: 0 - webGLUseWasm: 0 - webGLCompressionFormat: 1 - scriptingDefineSymbols: {} - platformArchitecture: {} - scriptingBackend: {} - incrementalIl2cppBuild: {} - additionalIl2CppArgs: - scriptingRuntimeVersion: 0 - apiCompatibilityLevelPerPlatform: {} - m_RenderingPath: 1 - m_MobileRenderingPath: 1 - metroPackageName: button-clicker - metroPackageVersion: - metroCertificatePath: - metroCertificatePassword: - metroCertificateSubject: - metroCertificateIssuer: - metroCertificateNotAfter: 0000000000000000 - metroApplicationDescription: button-clicker - wsaImages: {} - metroTileShortName: - metroCommandLineArgsFile: - metroTileShowName: 0 - metroMediumTileShowName: 0 - metroLargeTileShowName: 0 - metroWideTileShowName: 0 - metroDefaultTileSize: 1 - metroTileForegroundText: 2 - metroTileBackgroundColor: {r: 0.13333334, g: 0.17254902, b: 0.21568628, a: 0} - metroSplashScreenBackgroundColor: {r: 0.12941177, g: 0.17254902, b: 0.21568628, - a: 1} - metroSplashScreenUseBackgroundColor: 0 - platformCapabilities: {} - metroFTAName: - metroFTAFileTypes: [] - metroProtocolName: - metroCompilationOverrides: 1 - tizenProductDescription: - tizenProductURL: - tizenSigningProfileName: - tizenGPSPermissions: 0 - tizenMicrophonePermissions: 0 - tizenDeploymentTarget: - tizenDeploymentTargetType: -1 - tizenMinOSVersion: 1 - n3dsUseExtSaveData: 0 - n3dsCompressStaticMem: 1 - n3dsExtSaveDataNumber: 0x12345 - n3dsStackSize: 131072 - n3dsTargetPlatform: 2 - n3dsRegion: 7 - n3dsMediaSize: 0 - n3dsLogoStyle: 3 - n3dsTitle: GameName - n3dsProductCode: - n3dsApplicationId: 0xFF3FF - stvDeviceAddress: - stvProductDescription: - stvProductAuthor: - stvProductAuthorEmail: - stvProductLink: - stvProductCategory: 0 - XboxOneProductId: - XboxOneUpdateKey: - XboxOneSandboxId: - XboxOneContentId: - XboxOneTitleId: - XboxOneSCId: - XboxOneGameOsOverridePath: - XboxOnePackagingOverridePath: - XboxOneAppManifestOverridePath: - XboxOnePackageEncryption: 0 - XboxOnePackageUpdateGranularity: 2 - XboxOneDescription: - XboxOneLanguage: - - enus - XboxOneCapability: [] - XboxOneGameRating: {} - XboxOneIsContentPackage: 0 - XboxOneEnableGPUVariability: 0 - XboxOneSockets: {} - XboxOneSplashScreen: {fileID: 0} - XboxOneAllowedProductIds: [] - XboxOnePersistentLocalStorageSize: 0 - xboxOneScriptCompiler: 0 - vrEditorSettings: - daydream: - daydreamIconForeground: {fileID: 0} - daydreamIconBackground: {fileID: 0} - cloudServicesEnabled: {} - facebookSdkVersion: 7.9.4 - apiCompatibilityLevel: 2 - cloudProjectId: - projectName: - organizationId: - cloudEnabled: 0 - enableNativePlatformBackendsForNewInputSystem: 0 - disableOldInputManagerSupport: 0 diff --git a/dependencies/discord-rpc/examples/button-clicker/ProjectSettings/ProjectVersion.txt b/dependencies/discord-rpc/examples/button-clicker/ProjectSettings/ProjectVersion.txt deleted file mode 100644 index 7a6fffb8..00000000 --- a/dependencies/discord-rpc/examples/button-clicker/ProjectSettings/ProjectVersion.txt +++ /dev/null @@ -1 +0,0 @@ -m_EditorVersion: 2017.2.0f3 diff --git a/dependencies/discord-rpc/examples/button-clicker/ProjectSettings/QualitySettings.asset b/dependencies/discord-rpc/examples/button-clicker/ProjectSettings/QualitySettings.asset deleted file mode 100644 index 86c047f2..00000000 --- a/dependencies/discord-rpc/examples/button-clicker/ProjectSettings/QualitySettings.asset +++ /dev/null @@ -1,193 +0,0 @@ -%YAML 1.1 -%TAG !u! tag:unity3d.com,2011: ---- !u!47 &1 -QualitySettings: - m_ObjectHideFlags: 0 - serializedVersion: 5 - m_CurrentQuality: 5 - m_QualitySettings: - - serializedVersion: 2 - name: Very Low - pixelLightCount: 0 - shadows: 0 - shadowResolution: 0 - shadowProjection: 1 - shadowCascades: 1 - shadowDistance: 15 - shadowNearPlaneOffset: 3 - shadowCascade2Split: 0.33333334 - shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} - shadowmaskMode: 0 - blendWeights: 1 - textureQuality: 1 - anisotropicTextures: 0 - antiAliasing: 0 - softParticles: 0 - softVegetation: 0 - realtimeReflectionProbes: 0 - billboardsFaceCameraPosition: 0 - vSyncCount: 0 - lodBias: 0.3 - maximumLODLevel: 0 - particleRaycastBudget: 4 - asyncUploadTimeSlice: 2 - asyncUploadBufferSize: 4 - resolutionScalingFixedDPIFactor: 1 - excludedTargetPlatforms: [] - - serializedVersion: 2 - name: Low - pixelLightCount: 0 - shadows: 0 - shadowResolution: 0 - shadowProjection: 1 - shadowCascades: 1 - shadowDistance: 20 - shadowNearPlaneOffset: 3 - shadowCascade2Split: 0.33333334 - shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} - shadowmaskMode: 0 - blendWeights: 2 - textureQuality: 0 - anisotropicTextures: 0 - antiAliasing: 0 - softParticles: 0 - softVegetation: 0 - realtimeReflectionProbes: 0 - billboardsFaceCameraPosition: 0 - vSyncCount: 0 - lodBias: 0.4 - maximumLODLevel: 0 - particleRaycastBudget: 16 - asyncUploadTimeSlice: 2 - asyncUploadBufferSize: 4 - resolutionScalingFixedDPIFactor: 1 - excludedTargetPlatforms: [] - - serializedVersion: 2 - name: Medium - pixelLightCount: 1 - shadows: 1 - shadowResolution: 0 - shadowProjection: 1 - shadowCascades: 1 - shadowDistance: 20 - shadowNearPlaneOffset: 3 - shadowCascade2Split: 0.33333334 - shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} - shadowmaskMode: 0 - blendWeights: 2 - textureQuality: 0 - anisotropicTextures: 1 - antiAliasing: 0 - softParticles: 0 - softVegetation: 0 - realtimeReflectionProbes: 0 - billboardsFaceCameraPosition: 0 - vSyncCount: 1 - lodBias: 0.7 - maximumLODLevel: 0 - particleRaycastBudget: 64 - asyncUploadTimeSlice: 2 - asyncUploadBufferSize: 4 - resolutionScalingFixedDPIFactor: 1 - excludedTargetPlatforms: [] - - serializedVersion: 2 - name: High - pixelLightCount: 2 - shadows: 2 - shadowResolution: 1 - shadowProjection: 1 - shadowCascades: 2 - shadowDistance: 40 - shadowNearPlaneOffset: 3 - shadowCascade2Split: 0.33333334 - shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} - shadowmaskMode: 1 - blendWeights: 2 - textureQuality: 0 - anisotropicTextures: 1 - antiAliasing: 0 - softParticles: 0 - softVegetation: 1 - realtimeReflectionProbes: 1 - billboardsFaceCameraPosition: 1 - vSyncCount: 1 - lodBias: 1 - maximumLODLevel: 0 - particleRaycastBudget: 256 - asyncUploadTimeSlice: 2 - asyncUploadBufferSize: 4 - resolutionScalingFixedDPIFactor: 1 - excludedTargetPlatforms: [] - - serializedVersion: 2 - name: Very High - pixelLightCount: 3 - shadows: 2 - shadowResolution: 2 - shadowProjection: 1 - shadowCascades: 2 - shadowDistance: 70 - shadowNearPlaneOffset: 3 - shadowCascade2Split: 0.33333334 - shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} - shadowmaskMode: 1 - blendWeights: 4 - textureQuality: 0 - anisotropicTextures: 2 - antiAliasing: 2 - softParticles: 1 - softVegetation: 1 - realtimeReflectionProbes: 1 - billboardsFaceCameraPosition: 1 - vSyncCount: 1 - lodBias: 1.5 - maximumLODLevel: 0 - particleRaycastBudget: 1024 - asyncUploadTimeSlice: 2 - asyncUploadBufferSize: 4 - resolutionScalingFixedDPIFactor: 1 - excludedTargetPlatforms: [] - - serializedVersion: 2 - name: Ultra - pixelLightCount: 4 - shadows: 2 - shadowResolution: 2 - shadowProjection: 1 - shadowCascades: 4 - shadowDistance: 150 - shadowNearPlaneOffset: 3 - shadowCascade2Split: 0.33333334 - shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} - shadowmaskMode: 1 - blendWeights: 4 - textureQuality: 0 - anisotropicTextures: 2 - antiAliasing: 2 - softParticles: 1 - softVegetation: 1 - realtimeReflectionProbes: 1 - billboardsFaceCameraPosition: 1 - vSyncCount: 1 - lodBias: 2 - maximumLODLevel: 0 - particleRaycastBudget: 4096 - asyncUploadTimeSlice: 2 - asyncUploadBufferSize: 4 - resolutionScalingFixedDPIFactor: 1 - excludedTargetPlatforms: [] - m_PerPlatformDefaultQuality: - Android: 2 - Nintendo 3DS: 5 - Nintendo Switch: 5 - PS4: 5 - PSM: 5 - PSP2: 2 - Samsung TV: 2 - Standalone: 5 - Tizen: 2 - Web: 5 - WebGL: 3 - WiiU: 5 - Windows Store Apps: 5 - XboxOne: 5 - iPhone: 2 - tvOS: 2 diff --git a/dependencies/discord-rpc/examples/button-clicker/ProjectSettings/TagManager.asset b/dependencies/discord-rpc/examples/button-clicker/ProjectSettings/TagManager.asset deleted file mode 100644 index 1c92a784..00000000 --- a/dependencies/discord-rpc/examples/button-clicker/ProjectSettings/TagManager.asset +++ /dev/null @@ -1,43 +0,0 @@ -%YAML 1.1 -%TAG !u! tag:unity3d.com,2011: ---- !u!78 &1 -TagManager: - serializedVersion: 2 - tags: [] - layers: - - Default - - TransparentFX - - Ignore Raycast - - - - Water - - UI - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - m_SortingLayers: - - name: Default - uniqueID: 0 - locked: 0 diff --git a/dependencies/discord-rpc/examples/button-clicker/ProjectSettings/TimeManager.asset b/dependencies/discord-rpc/examples/button-clicker/ProjectSettings/TimeManager.asset deleted file mode 100644 index 558a017e..00000000 --- a/dependencies/discord-rpc/examples/button-clicker/ProjectSettings/TimeManager.asset +++ /dev/null @@ -1,9 +0,0 @@ -%YAML 1.1 -%TAG !u! tag:unity3d.com,2011: ---- !u!5 &1 -TimeManager: - m_ObjectHideFlags: 0 - Fixed Timestep: 0.02 - Maximum Allowed Timestep: 0.33333334 - m_TimeScale: 1 - Maximum Particle Timestep: 0.03 diff --git a/dependencies/discord-rpc/examples/button-clicker/ProjectSettings/UnityConnectSettings.asset b/dependencies/discord-rpc/examples/button-clicker/ProjectSettings/UnityConnectSettings.asset deleted file mode 100644 index 1cc5485b..00000000 --- a/dependencies/discord-rpc/examples/button-clicker/ProjectSettings/UnityConnectSettings.asset +++ /dev/null @@ -1,34 +0,0 @@ -%YAML 1.1 -%TAG !u! tag:unity3d.com,2011: ---- !u!310 &1 -UnityConnectSettings: - m_ObjectHideFlags: 0 - m_Enabled: 0 - m_TestMode: 0 - m_TestEventUrl: - m_TestConfigUrl: - m_TestInitMode: 0 - CrashReportingSettings: - m_EventUrl: https://perf-events.cloud.unity3d.com/api/events/crashes - m_Enabled: 0 - m_CaptureEditorExceptions: 1 - UnityPurchasingSettings: - m_Enabled: 0 - m_TestMode: 0 - UnityAnalyticsSettings: - m_Enabled: 0 - m_InitializeOnStartup: 1 - m_TestMode: 0 - m_TestEventUrl: - m_TestConfigUrl: - UnityAdsSettings: - m_Enabled: 0 - m_InitializeOnStartup: 1 - m_TestMode: 0 - m_EnabledPlatforms: 4294967295 - m_IosGameId: - m_AndroidGameId: - m_GameIds: {} - m_GameId: - PerformanceReportingSettings: - m_Enabled: 0 diff --git a/dependencies/discord-rpc/examples/button-clicker/UnityPackageManager/manifest.json b/dependencies/discord-rpc/examples/button-clicker/UnityPackageManager/manifest.json deleted file mode 100644 index 526aca60..00000000 --- a/dependencies/discord-rpc/examples/button-clicker/UnityPackageManager/manifest.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "dependencies": { - } -} diff --git a/dependencies/discord-rpc/examples/send-presence/CMakeLists.txt b/dependencies/discord-rpc/examples/send-presence/CMakeLists.txt deleted file mode 100644 index 8a67d472..00000000 --- a/dependencies/discord-rpc/examples/send-presence/CMakeLists.txt +++ /dev/null @@ -1,21 +0,0 @@ -include_directories(${PROJECT_SOURCE_DIR}/include) -add_executable( - send-presence - MACOSX_BUNDLE - send-presence.c -) -set_target_properties(send-presence PROPERTIES - MACOSX_BUNDLE_BUNDLE_NAME "Send Presence" - MACOSX_BUNDLE_GUI_IDENTIFIER "com.discordapp.examples.send-presence" -) -target_link_libraries(send-presence discord-rpc) - -install( - TARGETS send-presence - RUNTIME - DESTINATION "bin" - CONFIGURATIONS Release - BUNDLE - DESTINATION "bin" - CONFIGURATIONS Release -) \ No newline at end of file diff --git a/dependencies/discord-rpc/examples/send-presence/send-presence.c b/dependencies/discord-rpc/examples/send-presence/send-presence.c deleted file mode 100644 index 1b651f2c..00000000 --- a/dependencies/discord-rpc/examples/send-presence/send-presence.c +++ /dev/null @@ -1,206 +0,0 @@ -/* - This is a simple example in C of using the rich presence API asynchronously. -*/ - -#define _CRT_SECURE_NO_WARNINGS /* thanks Microsoft */ - -#include -#include -#include -#include - -#include "discord_rpc.h" - -static const char* APPLICATION_ID = "345229890980937739"; -static int FrustrationLevel = 0; -static int64_t StartTime; -static int SendPresence = 1; - -static int prompt(char* line, size_t size) -{ - int res; - char* nl; - printf("\n> "); - fflush(stdout); - res = fgets(line, (int)size, stdin) ? 1 : 0; - line[size - 1] = 0; - nl = strchr(line, '\n'); - if (nl) { - *nl = 0; - } - return res; -} - -static void updateDiscordPresence() -{ - if (SendPresence) { - char buffer[256]; - DiscordRichPresence discordPresence; - memset(&discordPresence, 0, sizeof(discordPresence)); - discordPresence.state = "West of House"; - sprintf(buffer, "Frustration level: %d", FrustrationLevel); - discordPresence.details = buffer; - discordPresence.startTimestamp = StartTime; - discordPresence.endTimestamp = time(0) + 5 * 60; - discordPresence.largeImageKey = "canary-large"; - discordPresence.smallImageKey = "ptb-small"; - discordPresence.partyId = "party1234"; - discordPresence.partySize = 1; - discordPresence.partyMax = 6; - discordPresence.partyPrivacy = DISCORD_PARTY_PUBLIC; - discordPresence.matchSecret = "xyzzy"; - discordPresence.joinSecret = "join"; - discordPresence.spectateSecret = "look"; - discordPresence.instance = 0; - Discord_UpdatePresence(&discordPresence); - } - else { - Discord_ClearPresence(); - } -} - -static void handleDiscordReady(const DiscordUser* connectedUser) -{ - printf("\nDiscord: connected to user %s#%s - %s\n", - connectedUser->username, - connectedUser->discriminator, - connectedUser->userId); -} - -static void handleDiscordDisconnected(int errcode, const char* message) -{ - printf("\nDiscord: disconnected (%d: %s)\n", errcode, message); -} - -static void handleDiscordError(int errcode, const char* message) -{ - printf("\nDiscord: error (%d: %s)\n", errcode, message); -} - -static void handleDiscordJoin(const char* secret) -{ - printf("\nDiscord: join (%s)\n", secret); -} - -static void handleDiscordSpectate(const char* secret) -{ - printf("\nDiscord: spectate (%s)\n", secret); -} - -static void handleDiscordJoinRequest(const DiscordUser* request) -{ - int response = -1; - char yn[4]; - printf("\nDiscord: join request from %s#%s - %s\n", - request->username, - request->discriminator, - request->userId); - do { - printf("Accept? (y/n)"); - if (!prompt(yn, sizeof(yn))) { - break; - } - - if (!yn[0]) { - continue; - } - - if (yn[0] == 'y') { - response = DISCORD_REPLY_YES; - break; - } - - if (yn[0] == 'n') { - response = DISCORD_REPLY_NO; - break; - } - } while (1); - if (response != -1) { - Discord_Respond(request->userId, response); - } -} - -static void discordInit() -{ - DiscordEventHandlers handlers; - memset(&handlers, 0, sizeof(handlers)); - handlers.ready = handleDiscordReady; - handlers.disconnected = handleDiscordDisconnected; - handlers.errored = handleDiscordError; - handlers.joinGame = handleDiscordJoin; - handlers.spectateGame = handleDiscordSpectate; - handlers.joinRequest = handleDiscordJoinRequest; - Discord_Initialize(APPLICATION_ID, &handlers, 1, NULL); -} - -static void gameLoop() -{ - char line[512]; - char* space; - - StartTime = time(0); - - printf("You are standing in an open field west of a white house.\n"); - while (prompt(line, sizeof(line))) { - if (line[0]) { - if (line[0] == 'q') { - break; - } - - if (line[0] == 't') { - printf("Shutting off Discord.\n"); - Discord_Shutdown(); - continue; - } - - if (line[0] == 'c') { - if (SendPresence) { - printf("Clearing presence information.\n"); - SendPresence = 0; - } - else { - printf("Restoring presence information.\n"); - SendPresence = 1; - } - updateDiscordPresence(); - continue; - } - - if (line[0] == 'y') { - printf("Reinit Discord.\n"); - discordInit(); - continue; - } - - if (time(NULL) & 1) { - printf("I don't understand that.\n"); - } - else { - space = strchr(line, ' '); - if (space) { - *space = 0; - } - printf("I don't know the word \"%s\".\n", line); - } - - ++FrustrationLevel; - - updateDiscordPresence(); - } - -#ifdef DISCORD_DISABLE_IO_THREAD - Discord_UpdateConnection(); -#endif - Discord_RunCallbacks(); - } -} - -int main(int argc, char* argv[]) -{ - discordInit(); - - gameLoop(); - - Discord_Shutdown(); - return 0; -} diff --git a/dependencies/discord-rpc/examples/unrealstatus/.gitignore b/dependencies/discord-rpc/examples/unrealstatus/.gitignore deleted file mode 100644 index bd472d50..00000000 --- a/dependencies/discord-rpc/examples/unrealstatus/.gitignore +++ /dev/null @@ -1,78 +0,0 @@ -# Visual Studio 2015 user specific files -.vs/ - -# Visual Studio 2015 database file -*.VC.db - -# Compiled Object files -*.slo -*.lo -*.o -*.obj - -# Precompiled Headers -*.gch -*.pch - -# Compiled Dynamic libraries -*.so -*.dylib -*.dll - -# Fortran module files -*.mod - -# Compiled Static libraries -*.lai -*.la -*.a -*.lib - -# Executables -*.exe -*.out -*.app -*.ipa - -# These project files can be generated by the engine -*.xcodeproj -*.xcworkspace -*.sln -*.suo -*.opensdf -*.sdf -*.VC.db -*.VC.opendb - -# Precompiled Assets -SourceArt/**/*.png -SourceArt/**/*.tga - -# Binary Files -Binaries/ - -# Builds -Build/* - -# Whitelist PakBlacklist-.txt files -!Build/*/ -Build/*/** -!Build/*/PakBlacklist*.txt - -# Don't ignore icon files in Build -!Build/**/*.ico - -# Built data for maps -*_BuiltData.uasset - -# Configuration files generated by the Editor -Saved/* - -# Compiled source files for the engine to use -Intermediate/ - -# Cache files for the editor to use -DerivedDataCache/ - -# Library headers must be copied automatically by the build script (build.py unreal) -Plugins/DiscordRpc/Source/ThirdParty/DiscordRpcLibrary/Include diff --git a/dependencies/discord-rpc/examples/unrealstatus/Config/DefaultEngine.ini b/dependencies/discord-rpc/examples/unrealstatus/Config/DefaultEngine.ini deleted file mode 100644 index 84c38f35..00000000 --- a/dependencies/discord-rpc/examples/unrealstatus/Config/DefaultEngine.ini +++ /dev/null @@ -1,54 +0,0 @@ -[URL] - -[/Script/HardwareTargeting.HardwareTargetingSettings] -TargetedHardwareClass=Desktop -AppliedTargetedHardwareClass=Desktop -DefaultGraphicsPerformance=Maximum -AppliedDefaultGraphicsPerformance=Maximum - -[/Script/Engine.EndUserSettings] -bSendAnonymousUsageDataToEpic=False - -[/Script/Engine.PhysicsSettings] -DefaultGravityZ=-980.000000 -DefaultTerminalVelocity=4000.000000 -DefaultFluidFriction=0.300000 -SimulateScratchMemorySize=262144 -RagdollAggregateThreshold=4 -TriangleMeshTriangleMinAreaThreshold=5.000000 -bEnableAsyncScene=False -bEnableShapeSharing=False -bEnablePCM=False -bEnableStabilization=False -bWarnMissingLocks=True -bEnable2DPhysics=False -LockedAxis=Invalid -DefaultDegreesOfFreedom=Full3D -BounceThresholdVelocity=200.000000 -FrictionCombineMode=Average -RestitutionCombineMode=Average -MaxAngularVelocity=3600.000000 -MaxDepenetrationVelocity=0.000000 -ContactOffsetMultiplier=0.010000 -MinContactOffset=0.000100 -MaxContactOffset=1.000000 -bSimulateSkeletalMeshOnDedicatedServer=True -DefaultShapeComplexity=CTF_UseSimpleAndComplex -bDefaultHasComplexCollision=True -bSuppressFaceRemapTable=False -bSupportUVFromHitResults=False -bDisableActiveActors=False -bDisableCCD=False -MaxPhysicsDeltaTime=0.033333 -bSubstepping=False -bSubsteppingAsync=False -MaxSubstepDeltaTime=0.016667 -MaxSubsteps=6 -SyncSceneSmoothingFactor=0.000000 -AsyncSceneSmoothingFactor=0.990000 -InitialAverageFrameRate=0.016667 - -[/Script/EngineSettings.GameMapsSettings] -EditorStartupMap=/Game/ShowTheUILevel.ShowTheUILevel -GameDefaultMap=/Game/ShowTheUILevel.ShowTheUILevel - diff --git a/dependencies/discord-rpc/examples/unrealstatus/Config/DefaultGame.ini b/dependencies/discord-rpc/examples/unrealstatus/Config/DefaultGame.ini deleted file mode 100644 index 7b5e2dc2..00000000 --- a/dependencies/discord-rpc/examples/unrealstatus/Config/DefaultGame.ini +++ /dev/null @@ -1,7 +0,0 @@ -[/Script/EngineSettings.GeneralProjectSettings] -ProjectID=E5977A24492699DF20B8ADBF736AF6C6 -ProjectName=Discord RPC Example -CompanyName=Discord Inc. -Homepage="https://discordapp.com/" -CopyrightNotice= - diff --git a/dependencies/discord-rpc/examples/unrealstatus/Content/MainScreenBP.uasset b/dependencies/discord-rpc/examples/unrealstatus/Content/MainScreenBP.uasset deleted file mode 100644 index e903b538..00000000 Binary files a/dependencies/discord-rpc/examples/unrealstatus/Content/MainScreenBP.uasset and /dev/null differ diff --git a/dependencies/discord-rpc/examples/unrealstatus/Content/MouseGameModeBP.uasset b/dependencies/discord-rpc/examples/unrealstatus/Content/MouseGameModeBP.uasset deleted file mode 100644 index 410af19a..00000000 Binary files a/dependencies/discord-rpc/examples/unrealstatus/Content/MouseGameModeBP.uasset and /dev/null differ diff --git a/dependencies/discord-rpc/examples/unrealstatus/Content/MousePlayerControllerBP.uasset b/dependencies/discord-rpc/examples/unrealstatus/Content/MousePlayerControllerBP.uasset deleted file mode 100644 index 0aaf50ba..00000000 Binary files a/dependencies/discord-rpc/examples/unrealstatus/Content/MousePlayerControllerBP.uasset and /dev/null differ diff --git a/dependencies/discord-rpc/examples/unrealstatus/Content/ShowTheUILevel.umap b/dependencies/discord-rpc/examples/unrealstatus/Content/ShowTheUILevel.umap deleted file mode 100644 index bc0e5b7c..00000000 Binary files a/dependencies/discord-rpc/examples/unrealstatus/Content/ShowTheUILevel.umap and /dev/null differ diff --git a/dependencies/discord-rpc/examples/unrealstatus/Plugins/discordrpc/DiscordRpc.uplugin b/dependencies/discord-rpc/examples/unrealstatus/Plugins/discordrpc/DiscordRpc.uplugin deleted file mode 100644 index 309df129..00000000 --- a/dependencies/discord-rpc/examples/unrealstatus/Plugins/discordrpc/DiscordRpc.uplugin +++ /dev/null @@ -1,29 +0,0 @@ -{ - "FileVersion": 3, - "Version": 1, - "VersionName": "1.0", - "FriendlyName": "Discord RPC", - "Description": "Wrap the Discord RPC library.", - "Category": "Messaging", - "CreatedBy": "Chris Marsh ", - "CreatedByURL": "https://discordapp.com/", - "DocsURL": "", - "MarketplaceURL": "", - "SupportURL": "", - "CanContainContent": true, - "IsBetaVersion": true, - "Installed": false, - "Modules": [ - { - "Name": "DiscordRpc", - "Type": "Runtime", - "LoadingPhase": "PreDefault", - "WhitelistPlatforms" : - [ - "Win64", - "Linux", - "Mac" - ] - } - ] -} \ No newline at end of file diff --git a/dependencies/discord-rpc/examples/unrealstatus/Plugins/discordrpc/Resources/Icon128.png b/dependencies/discord-rpc/examples/unrealstatus/Plugins/discordrpc/Resources/Icon128.png deleted file mode 100644 index 8b7f8e1c..00000000 Binary files a/dependencies/discord-rpc/examples/unrealstatus/Plugins/discordrpc/Resources/Icon128.png and /dev/null differ diff --git a/dependencies/discord-rpc/examples/unrealstatus/Plugins/discordrpc/Resources/discord.png b/dependencies/discord-rpc/examples/unrealstatus/Plugins/discordrpc/Resources/discord.png deleted file mode 100644 index 8b7f8e1c..00000000 Binary files a/dependencies/discord-rpc/examples/unrealstatus/Plugins/discordrpc/Resources/discord.png and /dev/null differ diff --git a/dependencies/discord-rpc/examples/unrealstatus/Plugins/discordrpc/Source/DiscordRpc/DiscordRpc.Build.cs b/dependencies/discord-rpc/examples/unrealstatus/Plugins/discordrpc/Source/DiscordRpc/DiscordRpc.Build.cs deleted file mode 100644 index 3678f985..00000000 --- a/dependencies/discord-rpc/examples/unrealstatus/Plugins/discordrpc/Source/DiscordRpc/DiscordRpc.Build.cs +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved. - -using UnrealBuildTool; -using System.IO; - -public class DiscordRpc : ModuleRules -{ -#if WITH_FORWARDED_MODULE_RULES_CTOR - public DiscordRpc(ReadOnlyTargetRules Target) : base(Target) -#else - public DiscordRpc(TargetInfo Target) -#endif - { - Definitions.Add("DISCORD_DYNAMIC_LIB=1"); - - PublicIncludePaths.AddRange( - new string[] { - "DiscordRpc/Public" - } - ); - - PrivateIncludePaths.AddRange( - new string[] { - "DiscordRpc/Private" - } - ); - - PublicDependencyModuleNames.AddRange( - new string[] - { - "Core", - "DiscordRpcLibrary" - } - ); - - PrivateDependencyModuleNames.AddRange( - new string[] - { - "CoreUObject", - "Engine", - "Slate", - "SlateCore", - "Projects" - } - ); - - DynamicallyLoadedModuleNames.AddRange( - new string[] - { - // ... add any modules that your module loads dynamically here ... - } - ); - - string BaseDirectory = Path.GetFullPath(Path.Combine(ModuleDirectory, "..", "..", "Source", "ThirdParty", "DiscordRpcLibrary")); - PublicIncludePaths.Add(Path.Combine(BaseDirectory, "Include")); - } -} \ No newline at end of file diff --git a/dependencies/discord-rpc/examples/unrealstatus/Plugins/discordrpc/Source/DiscordRpc/Private/DiscordRpc.cpp b/dependencies/discord-rpc/examples/unrealstatus/Plugins/discordrpc/Source/DiscordRpc/Private/DiscordRpc.cpp deleted file mode 100644 index d539dab0..00000000 --- a/dependencies/discord-rpc/examples/unrealstatus/Plugins/discordrpc/Source/DiscordRpc/Private/DiscordRpc.cpp +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved. - -#include "DiscordRpcPrivatePCH.h" -#include "IPluginManager.h" -#include "ModuleManager.h" - -#define LOCTEXT_NAMESPACE "FDiscordRpcModule" - -void FDiscordRpcModule::StartupModule() -{ -#if !PLATFORM_LINUX -#if defined(DISCORD_DYNAMIC_LIB) - // Get the base directory of this plugin - FString BaseDir = IPluginManager::Get().FindPlugin("DiscordRpc")->GetBaseDir(); - const FString SDKDir = - FPaths::Combine(*BaseDir, TEXT("Source"), TEXT("ThirdParty"), TEXT("DiscordRpcLibrary")); -#if PLATFORM_WINDOWS - const FString LibName = TEXT("discord-rpc"); - const FString LibDir = FPaths::Combine(*SDKDir, TEXT("Win64")); - if (!LoadDependency(LibDir, LibName, DiscordRpcLibraryHandle)) { - FMessageDialog::Open( - EAppMsgType::Ok, - LOCTEXT(LOCTEXT_NAMESPACE, - "Failed to load DiscordRpc plugin. Plug-in will not be functional.")); - FreeDependency(DiscordRpcLibraryHandle); - } -#elif PLATFORM_MAC - const FString LibName = TEXT("libdiscord-rpc"); - const FString LibDir = FPaths::Combine(*SDKDir, TEXT("Mac")); - if (!LoadDependency(LibDir, LibName, DiscordRpcLibraryHandle)) { - FMessageDialog::Open( - EAppMsgType::Ok, - LOCTEXT(LOCTEXT_NAMESPACE, - "Failed to load DiscordRpc plugin. Plug-in will not be functional.")); - FreeDependency(DiscordRpcLibraryHandle); - } -#endif -#endif -#endif -} - -void FDiscordRpcModule::ShutdownModule() -{ - // Free the dll handle -#if !PLATFORM_LINUX -#if defined(DISCORD_DYNAMIC_LIB) - FreeDependency(DiscordRpcLibraryHandle); -#endif -#endif -} - -bool FDiscordRpcModule::LoadDependency(const FString& Dir, const FString& Name, void*& Handle) -{ - FString Lib = Name + TEXT(".") + FPlatformProcess::GetModuleExtension(); - FString Path = Dir.IsEmpty() ? *Lib : FPaths::Combine(*Dir, *Lib); - - Handle = FPlatformProcess::GetDllHandle(*Path); - - if (Handle == nullptr) { - return false; - } - - return true; -} - -void FDiscordRpcModule::FreeDependency(void*& Handle) -{ - if (Handle != nullptr) { - FPlatformProcess::FreeDllHandle(Handle); - Handle = nullptr; - } -} - -#undef LOCTEXT_NAMESPACE - -IMPLEMENT_MODULE(FDiscordRpcModule, DiscordRpc) \ No newline at end of file diff --git a/dependencies/discord-rpc/examples/unrealstatus/Plugins/discordrpc/Source/DiscordRpc/Private/DiscordRpcBlueprint.cpp b/dependencies/discord-rpc/examples/unrealstatus/Plugins/discordrpc/Source/DiscordRpc/Private/DiscordRpcBlueprint.cpp deleted file mode 100644 index 8925d8e4..00000000 --- a/dependencies/discord-rpc/examples/unrealstatus/Plugins/discordrpc/Source/DiscordRpc/Private/DiscordRpcBlueprint.cpp +++ /dev/null @@ -1,172 +0,0 @@ -#include "DiscordRpcPrivatePCH.h" -#include "DiscordRpcBlueprint.h" -#include "discord_rpc.h" - -DEFINE_LOG_CATEGORY(Discord) - -static UDiscordRpc* self = nullptr; - -static void ReadyHandler(const DiscordUser* connectedUser) -{ - FDiscordUserData ud; - ud.userId = ANSI_TO_TCHAR(connectedUser->userId); - ud.username = ANSI_TO_TCHAR(connectedUser->username); - ud.discriminator = ANSI_TO_TCHAR(connectedUser->discriminator); - ud.avatar = ANSI_TO_TCHAR(connectedUser->avatar); - UE_LOG(Discord, - Log, - TEXT("Discord connected to %s - %s#%s"), - *ud.userId, - *ud.username, - *ud.discriminator); - if (self) { - self->IsConnected = true; - self->OnConnected.Broadcast(ud); - } -} - -static void DisconnectHandler(int errorCode, const char* message) -{ - auto msg = FString(message); - UE_LOG(Discord, Log, TEXT("Discord disconnected (%d): %s"), errorCode, *msg); - if (self) { - self->IsConnected = false; - self->OnDisconnected.Broadcast(errorCode, msg); - } -} - -static void ErroredHandler(int errorCode, const char* message) -{ - auto msg = FString(message); - UE_LOG(Discord, Log, TEXT("Discord error (%d): %s"), errorCode, *msg); - if (self) { - self->OnErrored.Broadcast(errorCode, msg); - } -} - -static void JoinGameHandler(const char* joinSecret) -{ - auto secret = FString(joinSecret); - UE_LOG(Discord, Log, TEXT("Discord join %s"), *secret); - if (self) { - self->OnJoin.Broadcast(secret); - } -} - -static void SpectateGameHandler(const char* spectateSecret) -{ - auto secret = FString(spectateSecret); - UE_LOG(Discord, Log, TEXT("Discord spectate %s"), *secret); - if (self) { - self->OnSpectate.Broadcast(secret); - } -} - -static void JoinRequestHandler(const DiscordUser* request) -{ - FDiscordUserData ud; - ud.userId = ANSI_TO_TCHAR(request->userId); - ud.username = ANSI_TO_TCHAR(request->username); - ud.discriminator = ANSI_TO_TCHAR(request->discriminator); - ud.avatar = ANSI_TO_TCHAR(request->avatar); - UE_LOG(Discord, - Log, - TEXT("Discord join request from %s - %s#%s"), - *ud.userId, - *ud.username, - *ud.discriminator); - if (self) { - self->OnJoinRequest.Broadcast(ud); - } -} - -void UDiscordRpc::Initialize(const FString& applicationId, - bool autoRegister, - const FString& optionalSteamId) -{ - self = this; - IsConnected = false; - DiscordEventHandlers handlers{}; - handlers.ready = ReadyHandler; - handlers.disconnected = DisconnectHandler; - handlers.errored = ErroredHandler; - if (OnJoin.IsBound()) { - handlers.joinGame = JoinGameHandler; - } - if (OnSpectate.IsBound()) { - handlers.spectateGame = SpectateGameHandler; - } - if (OnJoinRequest.IsBound()) { - handlers.joinRequest = JoinRequestHandler; - } - auto appId = StringCast(*applicationId); - auto steamId = StringCast(*optionalSteamId); - Discord_Initialize( - (const char*)appId.Get(), &handlers, autoRegister, (const char*)steamId.Get()); -} - -void UDiscordRpc::Shutdown() -{ - Discord_Shutdown(); - self = nullptr; -} - -void UDiscordRpc::RunCallbacks() -{ - Discord_RunCallbacks(); -} - -void UDiscordRpc::UpdatePresence() -{ - DiscordRichPresence rp{}; - - auto state = StringCast(*RichPresence.state); - rp.state = state.Get(); - - auto details = StringCast(*RichPresence.details); - rp.details = details.Get(); - - auto largeImageKey = StringCast(*RichPresence.largeImageKey); - rp.largeImageKey = largeImageKey.Get(); - - auto largeImageText = StringCast(*RichPresence.largeImageText); - rp.largeImageText = largeImageText.Get(); - - auto smallImageKey = StringCast(*RichPresence.smallImageKey); - rp.smallImageKey = smallImageKey.Get(); - - auto smallImageText = StringCast(*RichPresence.smallImageText); - rp.smallImageText = smallImageText.Get(); - - auto partyId = StringCast(*RichPresence.partyId); - rp.partyId = partyId.Get(); - - auto matchSecret = StringCast(*RichPresence.matchSecret); - rp.matchSecret = matchSecret.Get(); - - auto joinSecret = StringCast(*RichPresence.joinSecret); - rp.joinSecret = joinSecret.Get(); - - auto spectateSecret = StringCast(*RichPresence.spectateSecret); - rp.spectateSecret = spectateSecret.Get(); - rp.startTimestamp = RichPresence.startTimestamp; - rp.endTimestamp = RichPresence.endTimestamp; - rp.partySize = RichPresence.partySize; - rp.partyMax = RichPresence.partyMax; - rp.partyPrivacy = (int)RichPresence.partyPrivacy; - rp.instance = RichPresence.instance; - - Discord_UpdatePresence(&rp); -} - -void UDiscordRpc::ClearPresence() -{ - Discord_ClearPresence(); -} - -void UDiscordRpc::Respond(const FString& userId, int reply) -{ - UE_LOG(Discord, Log, TEXT("Responding %d to join request from %s"), reply, *userId); - FTCHARToUTF8 utf8_userid(*userId); - Discord_Respond(utf8_userid.Get(), reply); -} diff --git a/dependencies/discord-rpc/examples/unrealstatus/Plugins/discordrpc/Source/DiscordRpc/Private/DiscordRpcPrivatePCH.h b/dependencies/discord-rpc/examples/unrealstatus/Plugins/discordrpc/Source/DiscordRpc/Private/DiscordRpcPrivatePCH.h deleted file mode 100644 index 11668017..00000000 --- a/dependencies/discord-rpc/examples/unrealstatus/Plugins/discordrpc/Source/DiscordRpc/Private/DiscordRpcPrivatePCH.h +++ /dev/null @@ -1,2 +0,0 @@ -#include "Core.h" -#include "DiscordRpc.h" \ No newline at end of file diff --git a/dependencies/discord-rpc/examples/unrealstatus/Plugins/discordrpc/Source/DiscordRpc/Public/DiscordRpc.h b/dependencies/discord-rpc/examples/unrealstatus/Plugins/discordrpc/Source/DiscordRpc/Public/DiscordRpc.h deleted file mode 100644 index 727833b0..00000000 --- a/dependencies/discord-rpc/examples/unrealstatus/Plugins/discordrpc/Source/DiscordRpc/Public/DiscordRpc.h +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved. - -#pragma once - -#include "ModuleManager.h" - -class FDiscordRpcModule : public IModuleInterface { -public: - /** IModuleInterface implementation */ - virtual void StartupModule() override; - virtual void ShutdownModule() override; - -private: - /** Handle to the test dll we will load */ - void* DiscordRpcLibraryHandle; - - /** StartupModule is covered with defines, these functions are the place to put breakpoints */ - static bool LoadDependency(const FString& Dir, const FString& Name, void*& Handle); - static void FreeDependency(void*& Handle); -}; \ No newline at end of file diff --git a/dependencies/discord-rpc/examples/unrealstatus/Plugins/discordrpc/Source/DiscordRpc/Public/DiscordRpcBlueprint.h b/dependencies/discord-rpc/examples/unrealstatus/Plugins/discordrpc/Source/DiscordRpc/Public/DiscordRpcBlueprint.h deleted file mode 100644 index 409eee0d..00000000 --- a/dependencies/discord-rpc/examples/unrealstatus/Plugins/discordrpc/Source/DiscordRpc/Public/DiscordRpcBlueprint.h +++ /dev/null @@ -1,181 +0,0 @@ -#pragma once - -#include "CoreMinimal.h" -#include "Engine.h" -#include "DiscordRpcBlueprint.generated.h" - -// unreal's header tool hates clang-format -// clang-format off - -/** -* Ask to join callback data -*/ -USTRUCT(BlueprintType) -struct FDiscordUserData { - GENERATED_USTRUCT_BODY() - - UPROPERTY(BlueprintReadOnly) - FString userId; - UPROPERTY(BlueprintReadOnly) - FString username; - UPROPERTY(BlueprintReadOnly) - FString discriminator; - UPROPERTY(BlueprintReadOnly) - FString avatar; -}; - -/** -* Valid response codes for Respond function -*/ -UENUM(BlueprintType) -enum class EDiscordJoinResponseCodes : uint8 -{ - DISCORD_REPLY_NO UMETA(DisplayName="No"), - DISCORD_REPLY_YES UMETA(DisplayName="Yes"), - DISCORD_REPLY_IGNORE UMETA(DisplayName="Ignore") -}; - -/** -* Valid party privacy values -*/ -UENUM(BlueprintType) -enum class EDiscordPartyPrivacy: uint8 -{ - DISCORD_PARTY_PRIVATE UMETA(DisplayName="Private"), - DISCORD_PARTY_PUBLIC UMETA(DisplayName="Public") -}; - -DECLARE_LOG_CATEGORY_EXTERN(Discord, Log, All); - -DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FDiscordConnected, const FDiscordUserData&, joinRequest); -DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FDiscordDisconnected, int, errorCode, const FString&, errorMessage); -DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FDiscordErrored, int, errorCode, const FString&, errorMessage); -DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FDiscordJoin, const FString&, joinSecret); -DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FDiscordSpectate, const FString&, spectateSecret); -DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FDiscordJoinRequest, const FDiscordUserData&, joinRequest); - -// clang-format on - -/** - * Rich presence data - */ -USTRUCT(BlueprintType) -struct FDiscordRichPresence { - GENERATED_USTRUCT_BODY() - - UPROPERTY(BlueprintReadWrite) - FString state; - UPROPERTY(BlueprintReadWrite) - FString details; - // todo, timestamps are 64bit, does that even matter? - UPROPERTY(BlueprintReadWrite) - int startTimestamp; - UPROPERTY(BlueprintReadWrite) - int endTimestamp; - UPROPERTY(BlueprintReadWrite) - FString largeImageKey; - UPROPERTY(BlueprintReadWrite) - FString largeImageText; - UPROPERTY(BlueprintReadWrite) - FString smallImageKey; - UPROPERTY(BlueprintReadWrite) - FString smallImageText; - UPROPERTY(BlueprintReadWrite) - FString partyId; - UPROPERTY(BlueprintReadWrite) - int partySize; - UPROPERTY(BlueprintReadWrite) - int partyMax; - UPROPERTY(BlueprintReadWrite) - EDiscordPartyPrivacy partyPrivacy; - UPROPERTY(BlueprintReadWrite) - FString matchSecret; - UPROPERTY(BlueprintReadWrite) - FString joinSecret; - UPROPERTY(BlueprintReadWrite) - FString spectateSecret; - UPROPERTY(BlueprintReadWrite) - bool instance; -}; - -/** - * - */ -UCLASS(BlueprintType, meta = (DisplayName = "Discord RPC"), Category = "Discord") -class DISCORDRPC_API UDiscordRpc : public UObject { - GENERATED_BODY() - -public: - UFUNCTION(BlueprintCallable, - meta = (DisplayName = "Initialize connection", Keywords = "Discord rpc"), - Category = "Discord") - void Initialize(const FString& applicationId, - bool autoRegister, - const FString& optionalSteamId); - - UFUNCTION(BlueprintCallable, - meta = (DisplayName = "Shut down connection", Keywords = "Discord rpc"), - Category = "Discord") - void Shutdown(); - - UFUNCTION(BlueprintCallable, - meta = (DisplayName = "Check for callbacks", Keywords = "Discord rpc"), - Category = "Discord") - void RunCallbacks(); - - UFUNCTION(BlueprintCallable, - meta = (DisplayName = "Send presence", Keywords = "Discord rpc"), - Category = "Discord") - void UpdatePresence(); - - UFUNCTION(BlueprintCallable, - meta = (DisplayName = "Clear presence", Keywords = "Discord rpc"), - Category = "Discord") - void ClearPresence(); - - UFUNCTION(BlueprintCallable, - meta = (DisplayName = "Respond to join request", Keywords = "Discord rpc"), - Category = "Discord") - void Respond(const FString& userId, int reply); - - UPROPERTY(BlueprintReadOnly, - meta = (DisplayName = "Is Discord connected", Keywords = "Discord rpc"), - Category = "Discord") - bool IsConnected; - - UPROPERTY(BlueprintAssignable, - meta = (DisplayName = "On connection", Keywords = "Discord rpc"), - Category = "Discord") - FDiscordConnected OnConnected; - - UPROPERTY(BlueprintAssignable, - meta = (DisplayName = "On disconnection", Keywords = "Discord rpc"), - Category = "Discord") - FDiscordDisconnected OnDisconnected; - - UPROPERTY(BlueprintAssignable, - meta = (DisplayName = "On error message", Keywords = "Discord rpc"), - Category = "Discord") - FDiscordErrored OnErrored; - - UPROPERTY(BlueprintAssignable, - meta = (DisplayName = "When Discord user presses join", Keywords = "Discord rpc"), - Category = "Discord") - FDiscordJoin OnJoin; - - UPROPERTY(BlueprintAssignable, - meta = (DisplayName = "When Discord user presses spectate", Keywords = "Discord rpc"), - Category = "Discord") - FDiscordSpectate OnSpectate; - - UPROPERTY(BlueprintAssignable, - meta = (DisplayName = "When Discord another user sends a join request", - Keywords = "Discord rpc"), - Category = "Discord") - FDiscordJoinRequest OnJoinRequest; - - UPROPERTY(BlueprintReadWrite, - meta = (DisplayName = "Rich presence info", Keywords = "Discord rpc"), - Category = "Discord") - FDiscordRichPresence RichPresence; -}; diff --git a/dependencies/discord-rpc/examples/unrealstatus/Plugins/discordrpc/Source/ThirdParty/DiscordRpcLibrary/DiscordRpcLibrary.Build.cs b/dependencies/discord-rpc/examples/unrealstatus/Plugins/discordrpc/Source/ThirdParty/DiscordRpcLibrary/DiscordRpcLibrary.Build.cs deleted file mode 100644 index 8591b159..00000000 --- a/dependencies/discord-rpc/examples/unrealstatus/Plugins/discordrpc/Source/ThirdParty/DiscordRpcLibrary/DiscordRpcLibrary.Build.cs +++ /dev/null @@ -1,59 +0,0 @@ -// Fill out your copyright notice in the Description page of Project Settings. - -using System.IO; -using UnrealBuildTool; - -public class DiscordRpcLibrary : ModuleRules -{ -#if WITH_FORWARDED_MODULE_RULES_CTOR - public DiscordRpcLibrary(ReadOnlyTargetRules Target) : base(Target) -#else - public DiscordRpcLibrary(TargetInfo Target) -#endif - { - Type = ModuleType.External; - Definitions.Add("DISCORD_DYNAMIC_LIB=1"); - - string BaseDirectory = Path.GetFullPath(Path.Combine(ModuleDirectory, "..", "..", "ThirdParty", "DiscordRpcLibrary")); - - if (Target.Platform == UnrealTargetPlatform.Win64) - { - string lib = Path.Combine(BaseDirectory, "Win64"); - - // Include headers - PublicIncludePaths.Add(Path.Combine(BaseDirectory, "Include")); - - // Add the import library - PublicLibraryPaths.Add(lib); - PublicAdditionalLibraries.Add(Path.Combine(lib, "discord-rpc.lib")); - - // Dynamic - RuntimeDependencies.Add(new RuntimeDependency(Path.Combine(lib, "discord-rpc.dll"))); - PublicDelayLoadDLLs.Add("discord-rpc.dll"); - } - else if (Target.Platform == UnrealTargetPlatform.Linux) - { - string lib = Path.Combine(BaseDirectory, "Linux", "x86_64-unknown-linux-gnu"); - - // Include headers - PublicIncludePaths.Add(Path.Combine(BaseDirectory, "Include")); - - // Add the import library - PublicLibraryPaths.Add(lib); - PublicAdditionalLibraries.Add(Path.Combine(lib, "libdiscord-rpc.so")); - RuntimeDependencies.Add(new RuntimeDependency(Path.Combine(lib, "libdiscord-rpc.so"))); - } - else if (Target.Platform == UnrealTargetPlatform.Mac) - { - string lib = Path.Combine(BaseDirectory, "Mac"); - - // Include headers - PublicIncludePaths.Add(Path.Combine(BaseDirectory, "Include")); - - // Add the import library - PublicLibraryPaths.Add(lib); - PublicAdditionalLibraries.Add(Path.Combine(lib, "libdiscord-rpc.dylib")); - RuntimeDependencies.Add(new RuntimeDependency(Path.Combine(lib, "libdiscord-rpc.dylib"))); - } - } -} \ No newline at end of file diff --git a/dependencies/discord-rpc/examples/unrealstatus/Source/unrealstatus.Target.cs b/dependencies/discord-rpc/examples/unrealstatus/Source/unrealstatus.Target.cs deleted file mode 100644 index 0c7c3c88..00000000 --- a/dependencies/discord-rpc/examples/unrealstatus/Source/unrealstatus.Target.cs +++ /dev/null @@ -1,14 +0,0 @@ -// Fill out your copyright notice in the Description page of Project Settings. - -using UnrealBuildTool; -using System.Collections.Generic; - -public class unrealstatusTarget : TargetRules -{ - public unrealstatusTarget(TargetInfo Target) : base(Target) - { - Type = TargetType.Game; - - ExtraModuleNames.AddRange( new string[] { "unrealstatus" } ); - } -} diff --git a/dependencies/discord-rpc/examples/unrealstatus/Source/unrealstatus/unrealstatus.Build.cs b/dependencies/discord-rpc/examples/unrealstatus/Source/unrealstatus/unrealstatus.Build.cs deleted file mode 100644 index 9560370e..00000000 --- a/dependencies/discord-rpc/examples/unrealstatus/Source/unrealstatus/unrealstatus.Build.cs +++ /dev/null @@ -1,23 +0,0 @@ -// Fill out your copyright notice in the Description page of Project Settings. - -using UnrealBuildTool; - -public class unrealstatus : ModuleRules -{ - public unrealstatus(ReadOnlyTargetRules Target) : base(Target) - { - PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs; - - PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore" }); - - PrivateDependencyModuleNames.AddRange(new string[] { }); - - // Uncomment if you are using Slate UI - // PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" }); - - // Uncomment if you are using online features - // PrivateDependencyModuleNames.Add("OnlineSubsystem"); - - // To include OnlineSubsystemSteam, add it to the plugins section in your uproject file with the Enabled attribute set to true - } -} diff --git a/dependencies/discord-rpc/examples/unrealstatus/Source/unrealstatus/unrealstatus.cpp b/dependencies/discord-rpc/examples/unrealstatus/Source/unrealstatus/unrealstatus.cpp deleted file mode 100644 index 9dd53886..00000000 --- a/dependencies/discord-rpc/examples/unrealstatus/Source/unrealstatus/unrealstatus.cpp +++ /dev/null @@ -1,6 +0,0 @@ -// Fill out your copyright notice in the Description page of Project Settings. - -#include "unrealstatus.h" -#include "Modules/ModuleManager.h" - -IMPLEMENT_PRIMARY_GAME_MODULE(FDefaultGameModuleImpl, unrealstatus, "unrealstatus"); diff --git a/dependencies/discord-rpc/examples/unrealstatus/Source/unrealstatus/unrealstatus.h b/dependencies/discord-rpc/examples/unrealstatus/Source/unrealstatus/unrealstatus.h deleted file mode 100644 index 73407dd1..00000000 --- a/dependencies/discord-rpc/examples/unrealstatus/Source/unrealstatus/unrealstatus.h +++ /dev/null @@ -1,5 +0,0 @@ -// Fill out your copyright notice in the Description page of Project Settings. - -#pragma once - -#include "CoreMinimal.h" diff --git a/dependencies/discord-rpc/examples/unrealstatus/Source/unrealstatus/unrealstatusGameModeBase.cpp b/dependencies/discord-rpc/examples/unrealstatus/Source/unrealstatus/unrealstatusGameModeBase.cpp deleted file mode 100644 index 1af30948..00000000 --- a/dependencies/discord-rpc/examples/unrealstatus/Source/unrealstatus/unrealstatusGameModeBase.cpp +++ /dev/null @@ -1,3 +0,0 @@ -// Fill out your copyright notice in the Description page of Project Settings. - -#include "unrealstatusGameModeBase.h" diff --git a/dependencies/discord-rpc/examples/unrealstatus/Source/unrealstatus/unrealstatusGameModeBase.h b/dependencies/discord-rpc/examples/unrealstatus/Source/unrealstatus/unrealstatusGameModeBase.h deleted file mode 100644 index 8dd9bd47..00000000 --- a/dependencies/discord-rpc/examples/unrealstatus/Source/unrealstatus/unrealstatusGameModeBase.h +++ /dev/null @@ -1,15 +0,0 @@ -// Fill out your copyright notice in the Description page of Project Settings. - -#pragma once - -#include "CoreMinimal.h" -#include "GameFramework/GameModeBase.h" -#include "unrealstatusGameModeBase.generated.h" - -/** - * - */ -UCLASS() -class UNREALSTATUS_API AunrealstatusGameModeBase : public AGameModeBase { - GENERATED_BODY() -}; diff --git a/dependencies/discord-rpc/examples/unrealstatus/Source/unrealstatusEditor.Target.cs b/dependencies/discord-rpc/examples/unrealstatus/Source/unrealstatusEditor.Target.cs deleted file mode 100644 index 2e8ad022..00000000 --- a/dependencies/discord-rpc/examples/unrealstatus/Source/unrealstatusEditor.Target.cs +++ /dev/null @@ -1,14 +0,0 @@ -// Fill out your copyright notice in the Description page of Project Settings. - -using UnrealBuildTool; -using System.Collections.Generic; - -public class unrealstatusEditorTarget : TargetRules -{ - public unrealstatusEditorTarget(TargetInfo Target) : base(Target) - { - Type = TargetType.Editor; - - ExtraModuleNames.AddRange( new string[] { "unrealstatus" } ); - } -} diff --git a/dependencies/discord-rpc/examples/unrealstatus/unrealstatus.uproject b/dependencies/discord-rpc/examples/unrealstatus/unrealstatus.uproject deleted file mode 100644 index 8a4a40b4..00000000 --- a/dependencies/discord-rpc/examples/unrealstatus/unrealstatus.uproject +++ /dev/null @@ -1,19 +0,0 @@ -{ - "FileVersion": 3, - "EngineAssociation": "4.18", - "Category": "", - "Description": "", - "Modules": [ - { - "Name": "unrealstatus", - "Type": "Runtime", - "LoadingPhase": "Default" - } - ], - "TargetPlatforms": [ - "LinuxNoEditor", - "MacNoEditor", - "WindowsNoEditor", - "AllDesktop" - ] -} \ No newline at end of file diff --git a/dependencies/discord-rpc/include/discord_register.h b/dependencies/discord-rpc/include/discord_register.h deleted file mode 100644 index 16fb42f3..00000000 --- a/dependencies/discord-rpc/include/discord_register.h +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once - -#if defined(DISCORD_DYNAMIC_LIB) -#if defined(_WIN32) -#if defined(DISCORD_BUILDING_SDK) -#define DISCORD_EXPORT __declspec(dllexport) -#else -#define DISCORD_EXPORT __declspec(dllimport) -#endif -#else -#define DISCORD_EXPORT __attribute__((visibility("default"))) -#endif -#else -#define DISCORD_EXPORT -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -DISCORD_EXPORT void Discord_Register(const char* applicationId, const char* command); -DISCORD_EXPORT void Discord_RegisterSteamGame(const char* applicationId, const char* steamId); - -#ifdef __cplusplus -} -#endif diff --git a/dependencies/discord-rpc/include/discord_rpc.h b/dependencies/discord-rpc/include/discord_rpc.h deleted file mode 100644 index 9470434a..00000000 --- a/dependencies/discord-rpc/include/discord_rpc.h +++ /dev/null @@ -1,90 +0,0 @@ -#pragma once -#include - -// clang-format off - -#if defined(DISCORD_DYNAMIC_LIB) -# if defined(_WIN32) -# if defined(DISCORD_BUILDING_SDK) -# define DISCORD_EXPORT __declspec(dllexport) -# else -# define DISCORD_EXPORT __declspec(dllimport) -# endif -# else -# define DISCORD_EXPORT __attribute__((visibility("default"))) -# endif -#else -# define DISCORD_EXPORT -#endif - -// clang-format on - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct DiscordRichPresence { - const char* state; /* max 128 bytes */ - const char* details; /* max 128 bytes */ - int64_t startTimestamp; - int64_t endTimestamp; - const char* largeImageKey; /* max 32 bytes */ - const char* largeImageText; /* max 128 bytes */ - const char* smallImageKey; /* max 32 bytes */ - const char* smallImageText; /* max 128 bytes */ - const char* partyId; /* max 128 bytes */ - int partySize; - int partyMax; - int partyPrivacy; - const char* matchSecret; /* max 128 bytes */ - const char* joinSecret; /* max 128 bytes */ - const char* spectateSecret; /* max 128 bytes */ - int8_t instance; -} DiscordRichPresence; - -typedef struct DiscordUser { - const char* userId; - const char* username; - const char* discriminator; - const char* avatar; -} DiscordUser; - -typedef struct DiscordEventHandlers { - void (*ready)(const DiscordUser* request); - void (*disconnected)(int errorCode, const char* message); - void (*errored)(int errorCode, const char* message); - void (*joinGame)(const char* joinSecret); - void (*spectateGame)(const char* spectateSecret); - void (*joinRequest)(const DiscordUser* request); -} DiscordEventHandlers; - -#define DISCORD_REPLY_NO 0 -#define DISCORD_REPLY_YES 1 -#define DISCORD_REPLY_IGNORE 2 -#define DISCORD_PARTY_PRIVATE 0 -#define DISCORD_PARTY_PUBLIC 1 - -DISCORD_EXPORT void Discord_Initialize(const char* applicationId, - DiscordEventHandlers* handlers, - int autoRegister, - const char* optionalSteamId); -DISCORD_EXPORT void Discord_Shutdown(void); - -/* checks for incoming messages, dispatches callbacks */ -DISCORD_EXPORT void Discord_RunCallbacks(void); - -/* If you disable the lib starting its own io thread, you'll need to call this from your own */ -#ifdef DISCORD_DISABLE_IO_THREAD -DISCORD_EXPORT void Discord_UpdateConnection(void); -#endif - -DISCORD_EXPORT void Discord_UpdatePresence(const DiscordRichPresence* presence); -DISCORD_EXPORT void Discord_ClearPresence(void); - -DISCORD_EXPORT void Discord_Respond(const char* userid, /* DISCORD_REPLY_ */ int reply); - -DISCORD_EXPORT void Discord_UpdateHandlers(DiscordEventHandlers* handlers); - -#ifdef __cplusplus -} /* extern "C" */ -#endif diff --git a/dependencies/discord-rpc/src/CMakeLists.txt b/dependencies/discord-rpc/src/CMakeLists.txt deleted file mode 100644 index afd8902d..00000000 --- a/dependencies/discord-rpc/src/CMakeLists.txt +++ /dev/null @@ -1,136 +0,0 @@ -include_directories(${PROJECT_SOURCE_DIR}/include) - -option(ENABLE_IO_THREAD "Start up a separate I/O thread, otherwise I'd need to call an update function" ON) -option(WARNINGS_AS_ERRORS "When enabled, compiles with `-Werror` (on *nix platforms)." OFF) - -set(CMAKE_CXX_STANDARD 14) - -set(BASE_RPC_SRC - ${PROJECT_SOURCE_DIR}/include/discord_rpc.h - discord_rpc.cpp - ${PROJECT_SOURCE_DIR}/include/discord_register.h - rpc_connection.h - rpc_connection.cpp - serialization.h - serialization.cpp - connection.h - backoff.h - msg_queue.h -) - -if (${BUILD_SHARED_LIBS}) - if(WIN32) - set(BASE_RPC_SRC ${BASE_RPC_SRC} dllmain.cpp) - endif(WIN32) -endif(${BUILD_SHARED_LIBS}) - -if(WIN32) - add_definitions(-DDISCORD_WINDOWS) - set(BASE_RPC_SRC ${BASE_RPC_SRC} connection_win.cpp discord_register_win.cpp) - add_library(discord-rpc ${BASE_RPC_SRC}) - if (MSVC) - set_property(TARGET discord-rpc PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") - target_compile_options(discord-rpc PRIVATE /EHsc - /Wall - /wd4100 # unreferenced formal parameter - /wd4514 # unreferenced inline - /wd4625 # copy constructor deleted - /wd5026 # move constructor deleted - /wd4626 # move assignment operator deleted - /wd4668 # not defined preprocessor macro - /wd4710 # function not inlined - /wd4711 # function was inlined - /wd4820 # structure padding - /wd4946 # reinterpret_cast used between related classes - /wd5027 # move assignment operator was implicitly defined as deleted - ) - endif(MSVC) - target_link_libraries(discord-rpc PRIVATE psapi advapi32) -endif(WIN32) - -if(UNIX) - set(BASE_RPC_SRC ${BASE_RPC_SRC} connection_unix.cpp) - - if (APPLE) - add_definitions(-DDISCORD_OSX) - set(BASE_RPC_SRC ${BASE_RPC_SRC} discord_register_osx.m) - else (APPLE) - add_definitions(-DDISCORD_LINUX) - set(BASE_RPC_SRC ${BASE_RPC_SRC} discord_register_linux.cpp) - endif(APPLE) - - add_library(discord-rpc ${BASE_RPC_SRC}) - target_link_libraries(discord-rpc PUBLIC pthread) - - if (APPLE) - target_link_libraries(discord-rpc PRIVATE "-framework AppKit, -mmacosx-version-min=10.10") - endif (APPLE) - - target_compile_options(discord-rpc PRIVATE - -g - -Wall - -Wextra - -Wpedantic - ) - - if (${WARNINGS_AS_ERRORS}) - target_compile_options(discord-rpc PRIVATE -Werror) - endif (${WARNINGS_AS_ERRORS}) - - target_compile_options(discord-rpc PRIVATE - -Wno-unknown-pragmas # pragma push thing doesn't work on clang - -Wno-old-style-cast # it's fine - -Wno-c++98-compat # that was almost 2 decades ago - -Wno-c++98-compat-pedantic - -Wno-missing-noreturn - -Wno-padded # structure padding - -Wno-covered-switch-default - -Wno-exit-time-destructors # not sure about these - -Wno-global-constructors - ) - - if (${BUILD_SHARED_LIBS}) - target_compile_options(discord-rpc PRIVATE -fPIC) - endif (${BUILD_SHARED_LIBS}) - - if (APPLE) - target_link_libraries(discord-rpc PRIVATE "-framework AppKit") - endif (APPLE) -endif(UNIX) - -target_include_directories(discord-rpc PRIVATE ${RAPIDJSON_INCLUDE_DIRS}) - -if (NOT ${ENABLE_IO_THREAD}) - target_compile_definitions(discord-rpc PUBLIC -DDISCORD_DISABLE_IO_THREAD) -endif (NOT ${ENABLE_IO_THREAD}) - -if (${BUILD_SHARED_LIBS}) - target_compile_definitions(discord-rpc PUBLIC -DDISCORD_DYNAMIC_LIB) - target_compile_definitions(discord-rpc PRIVATE -DDISCORD_BUILDING_SDK) -endif(${BUILD_SHARED_LIBS}) - -if (CLANG_FORMAT_CMD) - add_dependencies(discord-rpc clangformat) -endif(CLANG_FORMAT_CMD) - -# install - -install( - TARGETS discord-rpc - EXPORT "discord-rpc" - RUNTIME - DESTINATION "${CMAKE_INSTALL_BINDIR}" - LIBRARY - DESTINATION "${CMAKE_INSTALL_LIBDIR}" - ARCHIVE - DESTINATION "${CMAKE_INSTALL_LIBDIR}" - INCLUDES - DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" -) - -install( - FILES - "../include/discord_rpc.h" - "../include/discord_register.h" - DESTINATION "include" -) diff --git a/dependencies/discord-rpc/src/backoff.h b/dependencies/discord-rpc/src/backoff.h deleted file mode 100644 index a3e736fb..00000000 --- a/dependencies/discord-rpc/src/backoff.h +++ /dev/null @@ -1,40 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -struct Backoff { - int64_t minAmount; - int64_t maxAmount; - int64_t current; - int fails; - std::mt19937_64 randGenerator; - std::uniform_real_distribution<> randDistribution; - - double rand01() { return randDistribution(randGenerator); } - - Backoff(int64_t min, int64_t max) - : minAmount(min) - , maxAmount(max) - , current(min) - , fails(0) - , randGenerator((uint64_t)time(0)) - { - } - - void reset() - { - fails = 0; - current = minAmount; - } - - int64_t nextDelay() - { - ++fails; - int64_t delay = (int64_t)((double)current * 2.0 * rand01()); - current = std::min(current + delay, maxAmount); - return current; - } -}; diff --git a/dependencies/discord-rpc/src/connection.h b/dependencies/discord-rpc/src/connection.h deleted file mode 100644 index a8f99b9f..00000000 --- a/dependencies/discord-rpc/src/connection.h +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once - -// This is to wrap the platform specific kinds of connect/read/write. - -#include -#include - -// not really connectiony, but need per-platform -int GetProcessId(); - -struct BaseConnection { - static BaseConnection* Create(); - static void Destroy(BaseConnection*&); - bool isOpen{false}; - bool Open(); - bool Close(); - bool Write(const void* data, size_t length); - bool Read(void* data, size_t length); -}; diff --git a/dependencies/discord-rpc/src/connection_unix.cpp b/dependencies/discord-rpc/src/connection_unix.cpp deleted file mode 100644 index 85dace3c..00000000 --- a/dependencies/discord-rpc/src/connection_unix.cpp +++ /dev/null @@ -1,125 +0,0 @@ -#include "connection.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -int GetProcessId() -{ - return ::getpid(); -} - -struct BaseConnectionUnix : public BaseConnection { - int sock{-1}; -}; - -static BaseConnectionUnix Connection; -static sockaddr_un PipeAddr{}; -#ifdef MSG_NOSIGNAL -static int MsgFlags = MSG_NOSIGNAL; -#else -static int MsgFlags = 0; -#endif - -static const char* GetTempPath() -{ - const char* temp = getenv("XDG_RUNTIME_DIR"); - temp = temp ? temp : getenv("TMPDIR"); - temp = temp ? temp : getenv("TMP"); - temp = temp ? temp : getenv("TEMP"); - temp = temp ? temp : "/tmp"; - return temp; -} - -/*static*/ BaseConnection* BaseConnection::Create() -{ - PipeAddr.sun_family = AF_UNIX; - return &Connection; -} - -/*static*/ void BaseConnection::Destroy(BaseConnection*& c) -{ - auto self = reinterpret_cast(c); - self->Close(); - c = nullptr; -} - -bool BaseConnection::Open() -{ - const char* tempPath = GetTempPath(); - auto self = reinterpret_cast(this); - self->sock = socket(AF_UNIX, SOCK_STREAM, 0); - if (self->sock == -1) { - return false; - } - fcntl(self->sock, F_SETFL, O_NONBLOCK); -#ifdef SO_NOSIGPIPE - int optval = 1; - setsockopt(self->sock, SOL_SOCKET, SO_NOSIGPIPE, &optval, sizeof(optval)); -#endif - - for (int pipeNum = 0; pipeNum < 10; ++pipeNum) { - snprintf( - PipeAddr.sun_path, sizeof(PipeAddr.sun_path), "%s/discord-ipc-%d", tempPath, pipeNum); - int err = connect(self->sock, (const sockaddr*)&PipeAddr, sizeof(PipeAddr)); - if (err == 0) { - self->isOpen = true; - return true; - } - } - self->Close(); - return false; -} - -bool BaseConnection::Close() -{ - auto self = reinterpret_cast(this); - if (self->sock == -1) { - return false; - } - close(self->sock); - self->sock = -1; - self->isOpen = false; - return true; -} - -bool BaseConnection::Write(const void* data, size_t length) -{ - auto self = reinterpret_cast(this); - - if (self->sock == -1) { - return false; - } - - ssize_t sentBytes = send(self->sock, data, length, MsgFlags); - if (sentBytes < 0) { - Close(); - } - return sentBytes == (ssize_t)length; -} - -bool BaseConnection::Read(void* data, size_t length) -{ - auto self = reinterpret_cast(this); - - if (self->sock == -1) { - return false; - } - - int res = (int)recv(self->sock, data, length, MsgFlags); - if (res < 0) { - if (errno == EAGAIN) { - return false; - } - Close(); - } - else if (res == 0) { - Close(); - } - return res == (int)length; -} diff --git a/dependencies/discord-rpc/src/connection_win.cpp b/dependencies/discord-rpc/src/connection_win.cpp deleted file mode 100644 index 2dd2750c..00000000 --- a/dependencies/discord-rpc/src/connection_win.cpp +++ /dev/null @@ -1,128 +0,0 @@ -#include "connection.h" - -#define WIN32_LEAN_AND_MEAN -#define NOMCX -#define NOSERVICE -#define NOIME -#include -#include - -int GetProcessId() -{ - return (int)::GetCurrentProcessId(); -} - -struct BaseConnectionWin : public BaseConnection { - HANDLE pipe{INVALID_HANDLE_VALUE}; -}; - -static BaseConnectionWin Connection; - -/*static*/ BaseConnection* BaseConnection::Create() -{ - return &Connection; -} - -/*static*/ void BaseConnection::Destroy(BaseConnection*& c) -{ - auto self = reinterpret_cast(c); - self->Close(); - c = nullptr; -} - -bool BaseConnection::Open() -{ - wchar_t pipeName[]{L"\\\\?\\pipe\\discord-ipc-0"}; - const size_t pipeDigit = sizeof(pipeName) / sizeof(wchar_t) - 2; - pipeName[pipeDigit] = L'0'; - auto self = reinterpret_cast(this); - for (;;) { - self->pipe = ::CreateFileW( - pipeName, GENERIC_READ | GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, 0, nullptr); - if (self->pipe != INVALID_HANDLE_VALUE) { - self->isOpen = true; - return true; - } - - auto lastError = GetLastError(); - if (lastError == ERROR_FILE_NOT_FOUND) { - if (pipeName[pipeDigit] < L'9') { - pipeName[pipeDigit]++; - continue; - } - } - else if (lastError == ERROR_PIPE_BUSY) { - if (!WaitNamedPipeW(pipeName, 10000)) { - return false; - } - continue; - } - return false; - } -} - -bool BaseConnection::Close() -{ - auto self = reinterpret_cast(this); - ::CloseHandle(self->pipe); - self->pipe = INVALID_HANDLE_VALUE; - self->isOpen = false; - return true; -} - -bool BaseConnection::Write(const void* data, size_t length) -{ - if (length == 0) { - return true; - } - auto self = reinterpret_cast(this); - assert(self); - if (!self) { - return false; - } - if (self->pipe == INVALID_HANDLE_VALUE) { - return false; - } - assert(data); - if (!data) { - return false; - } - const DWORD bytesLength = (DWORD)length; - DWORD bytesWritten = 0; - return ::WriteFile(self->pipe, data, bytesLength, &bytesWritten, nullptr) == TRUE && - bytesWritten == bytesLength; -} - -bool BaseConnection::Read(void* data, size_t length) -{ - assert(data); - if (!data) { - return false; - } - auto self = reinterpret_cast(this); - assert(self); - if (!self) { - return false; - } - if (self->pipe == INVALID_HANDLE_VALUE) { - return false; - } - DWORD bytesAvailable = 0; - if (::PeekNamedPipe(self->pipe, nullptr, 0, nullptr, &bytesAvailable, nullptr)) { - if (bytesAvailable >= length) { - DWORD bytesToRead = (DWORD)length; - DWORD bytesRead = 0; - if (::ReadFile(self->pipe, data, bytesToRead, &bytesRead, nullptr) == TRUE) { - assert(bytesToRead == bytesRead); - return true; - } - else { - Close(); - } - } - } - else { - Close(); - } - return false; -} diff --git a/dependencies/discord-rpc/src/discord_register_linux.cpp b/dependencies/discord-rpc/src/discord_register_linux.cpp deleted file mode 100644 index dd92eea0..00000000 --- a/dependencies/discord-rpc/src/discord_register_linux.cpp +++ /dev/null @@ -1,102 +0,0 @@ -#include "discord_rpc.h" -#include "discord_register.h" -#include - -#include -#include -#include -#include -#include -#include - -static bool Mkdir(const char* path) -{ - int result = mkdir(path, 0755); - if (result == 0) { - return true; - } - if (errno == EEXIST) { - return true; - } - return false; -} - -// we want to register games so we can run them from Discord client as discord-:// -extern "C" DISCORD_EXPORT void Discord_Register(const char* applicationId, const char* command) -{ - // Add a desktop file and update some mime handlers so that xdg-open does the right thing. - - const char* home = getenv("HOME"); - if (!home) { - return; - } - - char exePath[1024]; - if (!command || !command[0]) { - ssize_t size = readlink("/proc/self/exe", exePath, sizeof(exePath)); - if (size <= 0 || size >= (ssize_t)sizeof(exePath)) { - return; - } - exePath[size] = '\0'; - command = exePath; - } - - const char* desktopFileFormat = "[Desktop Entry]\n" - "Name=Game %s\n" - "Exec=%s %%u\n" // note: it really wants that %u in there - "Type=Application\n" - "NoDisplay=true\n" - "Categories=Discord;Games;\n" - "MimeType=x-scheme-handler/discord-%s;\n"; - char desktopFile[2048]; - int fileLen = snprintf( - desktopFile, sizeof(desktopFile), desktopFileFormat, applicationId, command, applicationId); - if (fileLen <= 0) { - return; - } - - char desktopFilename[256]; - snprintf(desktopFilename, sizeof(desktopFilename), "/discord-%s.desktop", applicationId); - - char desktopFilePath[1024]; - snprintf(desktopFilePath, sizeof(desktopFilePath), "%s/.local", home); - if (!Mkdir(desktopFilePath)) { - return; - } - strcat(desktopFilePath, "/share"); - if (!Mkdir(desktopFilePath)) { - return; - } - strcat(desktopFilePath, "/applications"); - if (!Mkdir(desktopFilePath)) { - return; - } - strcat(desktopFilePath, desktopFilename); - - FILE* fp = fopen(desktopFilePath, "w"); - if (fp) { - fwrite(desktopFile, 1, fileLen, fp); - fclose(fp); - } - else { - return; - } - - char xdgMimeCommand[1024]; - snprintf(xdgMimeCommand, - sizeof(xdgMimeCommand), - "xdg-mime default discord-%s.desktop x-scheme-handler/discord-%s", - applicationId, - applicationId); - if (system(xdgMimeCommand) < 0) { - fprintf(stderr, "Failed to register mime handler\n"); - } -} - -extern "C" DISCORD_EXPORT void Discord_RegisterSteamGame(const char* applicationId, - const char* steamId) -{ - char command[256]; - sprintf(command, "xdg-open steam://rungameid/%s", steamId); - Discord_Register(applicationId, command); -} diff --git a/dependencies/discord-rpc/src/discord_register_osx.m b/dependencies/discord-rpc/src/discord_register_osx.m deleted file mode 100644 index d7101028..00000000 --- a/dependencies/discord-rpc/src/discord_register_osx.m +++ /dev/null @@ -1,80 +0,0 @@ -#include -#include - -#import - -#include "discord_register.h" - -static void RegisterCommand(const char* applicationId, const char* command) -{ - // There does not appear to be a way to register arbitrary commands on OSX, so instead we'll save the command - // to a file in the Discord config path, and when it is needed, Discord can try to load the file there, open - // the command therein (will pass to js's window.open, so requires a url-like thing) - - // Note: will not work for sandboxed apps - NSString *home = NSHomeDirectory(); - if (!home) { - return; - } - - NSString *path = [[[[[[home stringByAppendingPathComponent:@"Library"] - stringByAppendingPathComponent:@"Application Support"] - stringByAppendingPathComponent:@"discord"] - stringByAppendingPathComponent:@"games"] - stringByAppendingPathComponent:[NSString stringWithUTF8String:applicationId]] - stringByAppendingPathExtension:@"json"]; - [[NSFileManager defaultManager] createDirectoryAtPath:[path stringByDeletingLastPathComponent] withIntermediateDirectories:YES attributes:nil error:nil]; - - NSString *jsonBuffer = [NSString stringWithFormat:@"{\"command\": \"%s\"}", command]; - [jsonBuffer writeToFile:path atomically:NO encoding:NSUTF8StringEncoding error:nil]; -} - -static void RegisterURL(const char* applicationId) -{ - char url[256]; - snprintf(url, sizeof(url), "discord-%s", applicationId); - CFStringRef cfURL = CFStringCreateWithCString(NULL, url, kCFStringEncodingUTF8); - - NSString* myBundleId = [[NSBundle mainBundle] bundleIdentifier]; - if (!myBundleId) { - fprintf(stderr, "No bundle id found\n"); - return; - } - - NSURL* myURL = [[NSBundle mainBundle] bundleURL]; - if (!myURL) { - fprintf(stderr, "No bundle url found\n"); - return; - } - - OSStatus status = LSSetDefaultHandlerForURLScheme(cfURL, (__bridge CFStringRef)myBundleId); - if (status != noErr) { - fprintf(stderr, "Error in LSSetDefaultHandlerForURLScheme: %d\n", (int)status); - return; - } - - status = LSRegisterURL((__bridge CFURLRef)myURL, true); - if (status != noErr) { - fprintf(stderr, "Error in LSRegisterURL: %d\n", (int)status); - } -} - -void Discord_Register(const char* applicationId, const char* command) -{ - if (command) { - RegisterCommand(applicationId, command); - } - else { - // raii lite - @autoreleasepool { - RegisterURL(applicationId); - } - } -} - -void Discord_RegisterSteamGame(const char* applicationId, const char* steamId) -{ - char command[256]; - snprintf(command, 256, "steam://rungameid/%s", steamId); - Discord_Register(applicationId, command); -} diff --git a/dependencies/discord-rpc/src/discord_register_win.cpp b/dependencies/discord-rpc/src/discord_register_win.cpp deleted file mode 100644 index 0b1c4a13..00000000 --- a/dependencies/discord-rpc/src/discord_register_win.cpp +++ /dev/null @@ -1,186 +0,0 @@ -#include "discord_rpc.h" -#include "discord_register.h" - -#define WIN32_LEAN_AND_MEAN -#define NOMCX -#define NOSERVICE -#define NOIME -#include -#include -#include - -/** - * Updated fixes for MinGW and WinXP - * This block is written the way it does not involve changing the rest of the code - * Checked to be compiling - * 1) strsafe.h belongs to Windows SDK and cannot be added to MinGW - * #include guarded, functions redirected to substitutes - * 2) RegSetKeyValueW and LSTATUS are not declared in - * The entire function is rewritten - */ -#ifdef __MINGW32__ -#include -/// strsafe.h fixes -static HRESULT StringCbPrintfW(LPWSTR pszDest, size_t cbDest, LPCWSTR pszFormat, ...) -{ - HRESULT ret; - va_list va; - va_start(va, pszFormat); - cbDest /= 2; // Size is divided by 2 to convert from bytes to wide characters - causes segfault - // othervise - ret = vsnwprintf(pszDest, cbDest, pszFormat, va); - pszDest[cbDest - 1] = 0; // Terminate the string in case a buffer overflow; -1 will be returned - va_end(va); - return ret; -} -#else -#include -#include -#endif // __MINGW32__ - -/// winreg.h fixes -#ifndef LSTATUS -#define LSTATUS LONG -#endif -#ifdef RegSetKeyValueW -#undefine RegSetKeyValueW -#endif -#define RegSetKeyValueW regset -static LSTATUS regset(HKEY hkey, - LPCWSTR subkey, - LPCWSTR name, - DWORD type, - const void* data, - DWORD len) -{ - HKEY htkey = hkey, hsubkey = nullptr; - LSTATUS ret; - if (subkey && subkey[0]) { - if ((ret = RegCreateKeyExW(hkey, subkey, 0, 0, 0, KEY_ALL_ACCESS, 0, &hsubkey, 0)) != - ERROR_SUCCESS) - return ret; - htkey = hsubkey; - } - ret = RegSetValueExW(htkey, name, 0, type, (const BYTE*)data, len); - if (hsubkey && hsubkey != hkey) - RegCloseKey(hsubkey); - return ret; -} - -static void Discord_RegisterW(const wchar_t* applicationId, const wchar_t* command) -{ - // https://msdn.microsoft.com/en-us/library/aa767914(v=vs.85).aspx - // we want to register games so we can run them as discord-:// - // Update the HKEY_CURRENT_USER, because it doesn't seem to require special permissions. - - wchar_t exeFilePath[MAX_PATH]; - DWORD exeLen = GetModuleFileNameW(nullptr, exeFilePath, MAX_PATH); - wchar_t openCommand[1024]; - - if (command && command[0]) { - StringCbPrintfW(openCommand, sizeof(openCommand), L"%s", command); - } - else { - // StringCbCopyW(openCommand, sizeof(openCommand), exeFilePath); - StringCbPrintfW(openCommand, sizeof(openCommand), L"%s", exeFilePath); - } - - wchar_t protocolName[64]; - StringCbPrintfW(protocolName, sizeof(protocolName), L"discord-%s", applicationId); - wchar_t protocolDescription[128]; - StringCbPrintfW( - protocolDescription, sizeof(protocolDescription), L"URL:Run game %s protocol", applicationId); - wchar_t urlProtocol = 0; - - wchar_t keyName[256]; - StringCbPrintfW(keyName, sizeof(keyName), L"Software\\Classes\\%s", protocolName); - HKEY key; - auto status = - RegCreateKeyExW(HKEY_CURRENT_USER, keyName, 0, nullptr, 0, KEY_WRITE, nullptr, &key, nullptr); - if (status != ERROR_SUCCESS) { - fprintf(stderr, "Error creating key\n"); - return; - } - DWORD len; - LSTATUS result; - len = (DWORD)lstrlenW(protocolDescription) + 1; - result = - RegSetKeyValueW(key, nullptr, nullptr, REG_SZ, protocolDescription, len * sizeof(wchar_t)); - if (FAILED(result)) { - fprintf(stderr, "Error writing description\n"); - } - - len = (DWORD)lstrlenW(protocolDescription) + 1; - result = RegSetKeyValueW(key, nullptr, L"URL Protocol", REG_SZ, &urlProtocol, sizeof(wchar_t)); - if (FAILED(result)) { - fprintf(stderr, "Error writing description\n"); - } - - result = RegSetKeyValueW( - key, L"DefaultIcon", nullptr, REG_SZ, exeFilePath, (exeLen + 1) * sizeof(wchar_t)); - if (FAILED(result)) { - fprintf(stderr, "Error writing icon\n"); - } - - len = (DWORD)lstrlenW(openCommand) + 1; - result = RegSetKeyValueW( - key, L"shell\\open\\command", nullptr, REG_SZ, openCommand, len * sizeof(wchar_t)); - if (FAILED(result)) { - fprintf(stderr, "Error writing command\n"); - } - RegCloseKey(key); -} - -extern "C" DISCORD_EXPORT void Discord_Register(const char* applicationId, const char* command) -{ - wchar_t appId[32]; - MultiByteToWideChar(CP_UTF8, 0, applicationId, -1, appId, 32); - - wchar_t openCommand[1024]; - const wchar_t* wcommand = nullptr; - if (command && command[0]) { - const auto commandBufferLen = sizeof(openCommand) / sizeof(*openCommand); - MultiByteToWideChar(CP_UTF8, 0, command, -1, openCommand, commandBufferLen); - wcommand = openCommand; - } - - Discord_RegisterW(appId, wcommand); -} - -extern "C" DISCORD_EXPORT void Discord_RegisterSteamGame(const char* applicationId, - const char* steamId) -{ - wchar_t appId[32]; - MultiByteToWideChar(CP_UTF8, 0, applicationId, -1, appId, 32); - - wchar_t wSteamId[32]; - MultiByteToWideChar(CP_UTF8, 0, steamId, -1, wSteamId, 32); - - HKEY key; - auto status = RegOpenKeyExW(HKEY_CURRENT_USER, L"Software\\Valve\\Steam", 0, KEY_READ, &key); - if (status != ERROR_SUCCESS) { - fprintf(stderr, "Error opening Steam key\n"); - return; - } - - wchar_t steamPath[MAX_PATH]; - DWORD pathBytes = sizeof(steamPath); - status = RegQueryValueExW(key, L"SteamExe", nullptr, nullptr, (BYTE*)steamPath, &pathBytes); - RegCloseKey(key); - if (status != ERROR_SUCCESS || pathBytes < 1) { - fprintf(stderr, "Error reading SteamExe key\n"); - return; - } - - DWORD pathChars = pathBytes / sizeof(wchar_t); - for (DWORD i = 0; i < pathChars; ++i) { - if (steamPath[i] == L'/') { - steamPath[i] = L'\\'; - } - } - - wchar_t command[1024]; - StringCbPrintfW(command, sizeof(command), L"\"%s\" steam://rungameid/%s", steamPath, wSteamId); - - Discord_RegisterW(appId, command); -} diff --git a/dependencies/discord-rpc/src/discord_rpc.cpp b/dependencies/discord-rpc/src/discord_rpc.cpp deleted file mode 100644 index 03924538..00000000 --- a/dependencies/discord-rpc/src/discord_rpc.cpp +++ /dev/null @@ -1,504 +0,0 @@ -#include "discord_rpc.h" - -#include "backoff.h" -#include "discord_register.h" -#include "msg_queue.h" -#include "rpc_connection.h" -#include "serialization.h" - -#include -#include -#include - -#ifndef DISCORD_DISABLE_IO_THREAD -#include -#include -#endif - -constexpr size_t MaxMessageSize{16 * 1024}; -constexpr size_t MessageQueueSize{8}; -constexpr size_t JoinQueueSize{8}; - -struct QueuedMessage { - size_t length; - char buffer[MaxMessageSize]; - - void Copy(const QueuedMessage& other) - { - length = other.length; - if (length) { - memcpy(buffer, other.buffer, length); - } - } -}; - -struct User { - // snowflake (64bit int), turned into a ascii decimal string, at most 20 chars +1 null - // terminator = 21 - char userId[32]; - // 32 unicode glyphs is max name size => 4 bytes per glyph in the worst case, +1 for null - // terminator = 129 - char username[344]; - // 4 decimal digits + 1 null terminator = 5 - char discriminator[8]; - // optional 'a_' + md5 hex digest (32 bytes) + null terminator = 35 - char avatar[128]; - // Rounded way up because I'm paranoid about games breaking from future changes in these sizes -}; - -static RpcConnection* Connection{nullptr}; -static DiscordEventHandlers QueuedHandlers{}; -static DiscordEventHandlers Handlers{}; -static std::atomic_bool WasJustConnected{false}; -static std::atomic_bool WasJustDisconnected{false}; -static std::atomic_bool GotErrorMessage{false}; -static std::atomic_bool WasJoinGame{false}; -static std::atomic_bool WasSpectateGame{false}; -static std::atomic_bool UpdatePresence{false}; -static char JoinGameSecret[256]; -static char SpectateGameSecret[256]; -static int LastErrorCode{0}; -static char LastErrorMessage[256]; -static int LastDisconnectErrorCode{0}; -static char LastDisconnectErrorMessage[256]; -static std::mutex PresenceMutex; -static std::mutex HandlerMutex; -static QueuedMessage QueuedPresence{}; -static MsgQueue SendQueue; -static MsgQueue JoinAskQueue; -static User connectedUser; - -// We want to auto connect, and retry on failure, but not as fast as possible. This does expoential -// backoff from 0.5 seconds to 1 minute -static Backoff ReconnectTimeMs(500, 60 * 1000); -static auto NextConnect = std::chrono::system_clock::now(); -static int Pid{0}; -static int Nonce{1}; - -#ifndef DISCORD_DISABLE_IO_THREAD -static void Discord_UpdateConnection(void); -class IoThreadHolder { -private: - std::atomic_bool keepRunning{true}; - std::mutex waitForIOMutex; - std::condition_variable waitForIOActivity; - std::thread ioThread; - -public: - void Start() - { - keepRunning.store(true); - ioThread = std::thread([&]() { - const std::chrono::duration maxWait{500LL}; - Discord_UpdateConnection(); - while (keepRunning.load()) { - std::unique_lock lock(waitForIOMutex); - waitForIOActivity.wait_for(lock, maxWait); - Discord_UpdateConnection(); - } - }); - } - - void Notify() { waitForIOActivity.notify_all(); } - - void Stop() - { - keepRunning.exchange(false); - Notify(); - if (ioThread.joinable()) { - ioThread.join(); - } - } - - ~IoThreadHolder() { Stop(); } -}; -#else -class IoThreadHolder { -public: - void Start() {} - void Stop() {} - void Notify() {} -}; -#endif // DISCORD_DISABLE_IO_THREAD -static IoThreadHolder* IoThread{nullptr}; - -static void UpdateReconnectTime() -{ - NextConnect = std::chrono::system_clock::now() + - std::chrono::duration{ReconnectTimeMs.nextDelay()}; -} - -#ifdef DISCORD_DISABLE_IO_THREAD -extern "C" DISCORD_EXPORT void Discord_UpdateConnection(void) -#else -static void Discord_UpdateConnection(void) -#endif -{ - if (!Connection) { - return; - } - - if (!Connection->IsOpen()) { - if (std::chrono::system_clock::now() >= NextConnect) { - UpdateReconnectTime(); - Connection->Open(); - } - } - else { - // reads - - for (;;) { - JsonDocument message; - - if (!Connection->Read(message)) { - break; - } - - const char* evtName = GetStrMember(&message, "evt"); - const char* nonce = GetStrMember(&message, "nonce"); - - if (nonce) { - // in responses only -- should use to match up response when needed. - - if (evtName && strcmp(evtName, "ERROR") == 0) { - auto data = GetObjMember(&message, "data"); - LastErrorCode = GetIntMember(data, "code"); - StringCopy(LastErrorMessage, GetStrMember(data, "message", "")); - GotErrorMessage.store(true); - } - } - else { - // should have evt == name of event, optional data - if (evtName == nullptr) { - continue; - } - - auto data = GetObjMember(&message, "data"); - - if (strcmp(evtName, "ACTIVITY_JOIN") == 0) { - auto secret = GetStrMember(data, "secret"); - if (secret) { - StringCopy(JoinGameSecret, secret); - WasJoinGame.store(true); - } - } - else if (strcmp(evtName, "ACTIVITY_SPECTATE") == 0) { - auto secret = GetStrMember(data, "secret"); - if (secret) { - StringCopy(SpectateGameSecret, secret); - WasSpectateGame.store(true); - } - } - else if (strcmp(evtName, "ACTIVITY_JOIN_REQUEST") == 0) { - auto user = GetObjMember(data, "user"); - auto userId = GetStrMember(user, "id"); - auto username = GetStrMember(user, "username"); - auto avatar = GetStrMember(user, "avatar"); - auto joinReq = JoinAskQueue.GetNextAddMessage(); - if (userId && username && joinReq) { - StringCopy(joinReq->userId, userId); - StringCopy(joinReq->username, username); - auto discriminator = GetStrMember(user, "discriminator"); - if (discriminator) { - StringCopy(joinReq->discriminator, discriminator); - } - if (avatar) { - StringCopy(joinReq->avatar, avatar); - } - else { - joinReq->avatar[0] = 0; - } - JoinAskQueue.CommitAdd(); - } - } - } - } - - // writes - if (UpdatePresence.exchange(false) && QueuedPresence.length) { - QueuedMessage local; - { - std::lock_guard guard(PresenceMutex); - local.Copy(QueuedPresence); - } - if (!Connection->Write(local.buffer, local.length)) { - // if we fail to send, requeue - std::lock_guard guard(PresenceMutex); - QueuedPresence.Copy(local); - UpdatePresence.exchange(true); - } - } - - while (SendQueue.HavePendingSends()) { - auto qmessage = SendQueue.GetNextSendMessage(); - Connection->Write(qmessage->buffer, qmessage->length); - SendQueue.CommitSend(); - } - } -} - -static void SignalIOActivity() -{ - if (IoThread != nullptr) { - IoThread->Notify(); - } -} - -static bool RegisterForEvent(const char* evtName) -{ - auto qmessage = SendQueue.GetNextAddMessage(); - if (qmessage) { - qmessage->length = - JsonWriteSubscribeCommand(qmessage->buffer, sizeof(qmessage->buffer), Nonce++, evtName); - SendQueue.CommitAdd(); - SignalIOActivity(); - return true; - } - return false; -} - -static bool DeregisterForEvent(const char* evtName) -{ - auto qmessage = SendQueue.GetNextAddMessage(); - if (qmessage) { - qmessage->length = - JsonWriteUnsubscribeCommand(qmessage->buffer, sizeof(qmessage->buffer), Nonce++, evtName); - SendQueue.CommitAdd(); - SignalIOActivity(); - return true; - } - return false; -} - -extern "C" DISCORD_EXPORT void Discord_Initialize(const char* applicationId, - DiscordEventHandlers* handlers, - int autoRegister, - const char* optionalSteamId) -{ - IoThread = new (std::nothrow) IoThreadHolder(); - if (IoThread == nullptr) { - return; - } - - if (autoRegister) { - if (optionalSteamId && optionalSteamId[0]) { - Discord_RegisterSteamGame(applicationId, optionalSteamId); - } - else { - Discord_Register(applicationId, nullptr); - } - } - - Pid = GetProcessId(); - - { - std::lock_guard guard(HandlerMutex); - - if (handlers) { - QueuedHandlers = *handlers; - } - else { - QueuedHandlers = {}; - } - - Handlers = {}; - } - - if (Connection) { - return; - } - - Connection = RpcConnection::Create(applicationId); - Connection->onConnect = [](JsonDocument& readyMessage) { - Discord_UpdateHandlers(&QueuedHandlers); - if (QueuedPresence.length > 0) { - UpdatePresence.exchange(true); - SignalIOActivity(); - } - auto data = GetObjMember(&readyMessage, "data"); - auto user = GetObjMember(data, "user"); - auto userId = GetStrMember(user, "id"); - auto username = GetStrMember(user, "username"); - auto avatar = GetStrMember(user, "avatar"); - if (userId && username) { - StringCopy(connectedUser.userId, userId); - StringCopy(connectedUser.username, username); - auto discriminator = GetStrMember(user, "discriminator"); - if (discriminator) { - StringCopy(connectedUser.discriminator, discriminator); - } - if (avatar) { - StringCopy(connectedUser.avatar, avatar); - } - else { - connectedUser.avatar[0] = 0; - } - } - WasJustConnected.exchange(true); - ReconnectTimeMs.reset(); - }; - Connection->onDisconnect = [](int err, const char* message) { - LastDisconnectErrorCode = err; - StringCopy(LastDisconnectErrorMessage, message); - WasJustDisconnected.exchange(true); - UpdateReconnectTime(); - }; - - IoThread->Start(); -} - -extern "C" DISCORD_EXPORT void Discord_Shutdown(void) -{ - if (!Connection) { - return; - } - Connection->onConnect = nullptr; - Connection->onDisconnect = nullptr; - Handlers = {}; - QueuedPresence.length = 0; - UpdatePresence.exchange(false); - if (IoThread != nullptr) { - IoThread->Stop(); - delete IoThread; - IoThread = nullptr; - } - - RpcConnection::Destroy(Connection); -} - -extern "C" DISCORD_EXPORT void Discord_UpdatePresence(const DiscordRichPresence* presence) -{ - { - std::lock_guard guard(PresenceMutex); - QueuedPresence.length = JsonWriteRichPresenceObj( - QueuedPresence.buffer, sizeof(QueuedPresence.buffer), Nonce++, Pid, presence); - UpdatePresence.exchange(true); - } - SignalIOActivity(); -} - -extern "C" DISCORD_EXPORT void Discord_ClearPresence(void) -{ - Discord_UpdatePresence(nullptr); -} - -extern "C" DISCORD_EXPORT void Discord_Respond(const char* userId, /* DISCORD_REPLY_ */ int reply) -{ - // if we are not connected, let's not batch up stale messages for later - if (!Connection || !Connection->IsOpen()) { - return; - } - auto qmessage = SendQueue.GetNextAddMessage(); - if (qmessage) { - qmessage->length = - JsonWriteJoinReply(qmessage->buffer, sizeof(qmessage->buffer), userId, reply, Nonce++); - SendQueue.CommitAdd(); - SignalIOActivity(); - } -} - -extern "C" DISCORD_EXPORT void Discord_RunCallbacks(void) -{ - // Note on some weirdness: internally we might connect, get other signals, disconnect any number - // of times inbetween calls here. Externally, we want the sequence to seem sane, so any other - // signals are book-ended by calls to ready and disconnect. - - if (!Connection) { - return; - } - - bool wasDisconnected = WasJustDisconnected.exchange(false); - bool isConnected = Connection->IsOpen(); - - if (isConnected) { - // if we are connected, disconnect cb first - std::lock_guard guard(HandlerMutex); - if (wasDisconnected && Handlers.disconnected) { - Handlers.disconnected(LastDisconnectErrorCode, LastDisconnectErrorMessage); - } - } - - if (WasJustConnected.exchange(false)) { - std::lock_guard guard(HandlerMutex); - if (Handlers.ready) { - DiscordUser du{connectedUser.userId, - connectedUser.username, - connectedUser.discriminator, - connectedUser.avatar}; - Handlers.ready(&du); - } - } - - if (GotErrorMessage.exchange(false)) { - std::lock_guard guard(HandlerMutex); - if (Handlers.errored) { - Handlers.errored(LastErrorCode, LastErrorMessage); - } - } - - if (WasJoinGame.exchange(false)) { - std::lock_guard guard(HandlerMutex); - if (Handlers.joinGame) { - Handlers.joinGame(JoinGameSecret); - } - } - - if (WasSpectateGame.exchange(false)) { - std::lock_guard guard(HandlerMutex); - if (Handlers.spectateGame) { - Handlers.spectateGame(SpectateGameSecret); - } - } - - // Right now this batches up any requests and sends them all in a burst; I could imagine a world - // where the implementer would rather sequentially accept/reject each one before the next invite - // is sent. I left it this way because I could also imagine wanting to process these all and - // maybe show them in one common dialog and/or start fetching the avatars in parallel, and if - // not it should be trivial for the implementer to make a queue themselves. - while (JoinAskQueue.HavePendingSends()) { - auto req = JoinAskQueue.GetNextSendMessage(); - { - std::lock_guard guard(HandlerMutex); - if (Handlers.joinRequest) { - DiscordUser du{req->userId, req->username, req->discriminator, req->avatar}; - Handlers.joinRequest(&du); - } - } - JoinAskQueue.CommitSend(); - } - - if (!isConnected) { - // if we are not connected, disconnect message last - std::lock_guard guard(HandlerMutex); - if (wasDisconnected && Handlers.disconnected) { - Handlers.disconnected(LastDisconnectErrorCode, LastDisconnectErrorMessage); - } - } -} - -extern "C" DISCORD_EXPORT void Discord_UpdateHandlers(DiscordEventHandlers* newHandlers) -{ - if (newHandlers) { -#define HANDLE_EVENT_REGISTRATION(handler_name, event) \ - if (!Handlers.handler_name && newHandlers->handler_name) { \ - RegisterForEvent(event); \ - } \ - else if (Handlers.handler_name && !newHandlers->handler_name) { \ - DeregisterForEvent(event); \ - } - - std::lock_guard guard(HandlerMutex); - HANDLE_EVENT_REGISTRATION(joinGame, "ACTIVITY_JOIN") - HANDLE_EVENT_REGISTRATION(spectateGame, "ACTIVITY_SPECTATE") - HANDLE_EVENT_REGISTRATION(joinRequest, "ACTIVITY_JOIN_REQUEST") - -#undef HANDLE_EVENT_REGISTRATION - - Handlers = *newHandlers; - } - else { - std::lock_guard guard(HandlerMutex); - Handlers = {}; - } - return; -} diff --git a/dependencies/discord-rpc/src/dllmain.cpp b/dependencies/discord-rpc/src/dllmain.cpp deleted file mode 100644 index fbfc2950..00000000 --- a/dependencies/discord-rpc/src/dllmain.cpp +++ /dev/null @@ -1,8 +0,0 @@ -#include - -// outsmart GCC's missing-declarations warning -BOOL WINAPI DllMain(HMODULE, DWORD, LPVOID); -BOOL WINAPI DllMain(HMODULE, DWORD, LPVOID) -{ - return TRUE; -} diff --git a/dependencies/discord-rpc/src/msg_queue.h b/dependencies/discord-rpc/src/msg_queue.h deleted file mode 100644 index 77f380e7..00000000 --- a/dependencies/discord-rpc/src/msg_queue.h +++ /dev/null @@ -1,36 +0,0 @@ -#pragma once - -#include - -// A simple queue. No locks, but only works with a single thread as producer and a single thread as -// a consumer. Mutex up as needed. - -template -class MsgQueue { - ElementType queue_[QueueSize]; - std::atomic_uint nextAdd_{0}; - std::atomic_uint nextSend_{0}; - std::atomic_uint pendingSends_{0}; - -public: - MsgQueue() {} - - ElementType* GetNextAddMessage() - { - // if we are falling behind, bail - if (pendingSends_.load() >= QueueSize) { - return nullptr; - } - auto index = (nextAdd_++) % QueueSize; - return &queue_[index]; - } - void CommitAdd() { ++pendingSends_; } - - bool HavePendingSends() const { return pendingSends_.load() != 0; } - ElementType* GetNextSendMessage() - { - auto index = (nextSend_++) % QueueSize; - return &queue_[index]; - } - void CommitSend() { --pendingSends_; } -}; diff --git a/dependencies/discord-rpc/src/rpc_connection.cpp b/dependencies/discord-rpc/src/rpc_connection.cpp deleted file mode 100644 index 09331621..00000000 --- a/dependencies/discord-rpc/src/rpc_connection.cpp +++ /dev/null @@ -1,137 +0,0 @@ -#include "rpc_connection.h" -#include "serialization.h" - -#include - -static const int RpcVersion = 1; -static RpcConnection Instance; - -/*static*/ RpcConnection* RpcConnection::Create(const char* applicationId) -{ - Instance.connection = BaseConnection::Create(); - StringCopy(Instance.appId, applicationId); - return &Instance; -} - -/*static*/ void RpcConnection::Destroy(RpcConnection*& c) -{ - c->Close(); - BaseConnection::Destroy(c->connection); - c = nullptr; -} - -void RpcConnection::Open() -{ - if (state == State::Connected) { - return; - } - - if (state == State::Disconnected && !connection->Open()) { - return; - } - - if (state == State::SentHandshake) { - JsonDocument message; - if (Read(message)) { - auto cmd = GetStrMember(&message, "cmd"); - auto evt = GetStrMember(&message, "evt"); - if (cmd && evt && !strcmp(cmd, "DISPATCH") && !strcmp(evt, "READY")) { - state = State::Connected; - if (onConnect) { - onConnect(message); - } - } - } - } - else { - sendFrame.opcode = Opcode::Handshake; - sendFrame.length = (uint32_t)JsonWriteHandshakeObj( - sendFrame.message, sizeof(sendFrame.message), RpcVersion, appId); - - if (connection->Write(&sendFrame, sizeof(MessageFrameHeader) + sendFrame.length)) { - state = State::SentHandshake; - } - else { - Close(); - } - } -} - -void RpcConnection::Close() -{ - if (onDisconnect && (state == State::Connected || state == State::SentHandshake)) { - onDisconnect(lastErrorCode, lastErrorMessage); - } - connection->Close(); - state = State::Disconnected; -} - -bool RpcConnection::Write(const void* data, size_t length) -{ - sendFrame.opcode = Opcode::Frame; - memcpy(sendFrame.message, data, length); - sendFrame.length = (uint32_t)length; - if (!connection->Write(&sendFrame, sizeof(MessageFrameHeader) + length)) { - Close(); - return false; - } - return true; -} - -bool RpcConnection::Read(JsonDocument& message) -{ - if (state != State::Connected && state != State::SentHandshake) { - return false; - } - MessageFrame readFrame; - for (;;) { - bool didRead = connection->Read(&readFrame, sizeof(MessageFrameHeader)); - if (!didRead) { - if (!connection->isOpen) { - lastErrorCode = (int)ErrorCode::PipeClosed; - StringCopy(lastErrorMessage, "Pipe closed"); - Close(); - } - return false; - } - - if (readFrame.length > 0) { - didRead = connection->Read(readFrame.message, readFrame.length); - if (!didRead) { - lastErrorCode = (int)ErrorCode::ReadCorrupt; - StringCopy(lastErrorMessage, "Partial data in frame"); - Close(); - return false; - } - readFrame.message[readFrame.length] = 0; - } - - switch (readFrame.opcode) { - case Opcode::Close: { - message.ParseInsitu(readFrame.message); - lastErrorCode = GetIntMember(&message, "code"); - StringCopy(lastErrorMessage, GetStrMember(&message, "message", "")); - Close(); - return false; - } - case Opcode::Frame: - message.ParseInsitu(readFrame.message); - return true; - case Opcode::Ping: - readFrame.opcode = Opcode::Pong; - if (!connection->Write(&readFrame, sizeof(MessageFrameHeader) + readFrame.length)) { - Close(); - } - break; - case Opcode::Pong: - break; - case Opcode::Handshake: - default: - // something bad happened - lastErrorCode = (int)ErrorCode::ReadCorrupt; - StringCopy(lastErrorMessage, "Bad ipc frame"); - Close(); - return false; - } - } -} diff --git a/dependencies/discord-rpc/src/rpc_connection.h b/dependencies/discord-rpc/src/rpc_connection.h deleted file mode 100644 index bbdd05c7..00000000 --- a/dependencies/discord-rpc/src/rpc_connection.h +++ /dev/null @@ -1,59 +0,0 @@ -#pragma once - -#include "connection.h" -#include "serialization.h" - -// I took this from the buffer size libuv uses for named pipes; I suspect ours would usually be much -// smaller. -constexpr size_t MaxRpcFrameSize = 64 * 1024; - -struct RpcConnection { - enum class ErrorCode : int { - Success = 0, - PipeClosed = 1, - ReadCorrupt = 2, - }; - - enum class Opcode : uint32_t { - Handshake = 0, - Frame = 1, - Close = 2, - Ping = 3, - Pong = 4, - }; - - struct MessageFrameHeader { - Opcode opcode; - uint32_t length; - }; - - struct MessageFrame : public MessageFrameHeader { - char message[MaxRpcFrameSize - sizeof(MessageFrameHeader)]; - }; - - enum class State : uint32_t { - Disconnected, - SentHandshake, - AwaitingResponse, - Connected, - }; - - BaseConnection* connection{nullptr}; - State state{State::Disconnected}; - void (*onConnect)(JsonDocument& message){nullptr}; - void (*onDisconnect)(int errorCode, const char* message){nullptr}; - char appId[64]{}; - int lastErrorCode{0}; - char lastErrorMessage[256]{}; - RpcConnection::MessageFrame sendFrame; - - static RpcConnection* Create(const char* applicationId); - static void Destroy(RpcConnection*&); - - inline bool IsOpen() const { return state == State::Connected; } - - void Open(); - void Close(); - bool Write(const void* data, size_t length); - bool Read(JsonDocument& message); -}; diff --git a/dependencies/discord-rpc/src/serialization.cpp b/dependencies/discord-rpc/src/serialization.cpp deleted file mode 100644 index 70efa637..00000000 --- a/dependencies/discord-rpc/src/serialization.cpp +++ /dev/null @@ -1,250 +0,0 @@ -#include "serialization.h" -#include "connection.h" -#include "discord_rpc.h" - -template -void NumberToString(char* dest, T number) -{ - if (!number) { - *dest++ = '0'; - *dest++ = 0; - return; - } - if (number < 0) { - *dest++ = '-'; - number = -number; - } - char temp[32]; - int place = 0; - while (number) { - auto digit = number % 10; - number = number / 10; - temp[place++] = '0' + (char)digit; - } - for (--place; place >= 0; --place) { - *dest++ = temp[place]; - } - *dest = 0; -} - -// it's ever so slightly faster to not have to strlen the key -template -void WriteKey(JsonWriter& w, T& k) -{ - w.Key(k, sizeof(T) - 1); -} - -struct WriteObject { - JsonWriter& writer; - WriteObject(JsonWriter& w) - : writer(w) - { - writer.StartObject(); - } - template - WriteObject(JsonWriter& w, T& name) - : writer(w) - { - WriteKey(writer, name); - writer.StartObject(); - } - ~WriteObject() { writer.EndObject(); } -}; - -struct WriteArray { - JsonWriter& writer; - template - WriteArray(JsonWriter& w, T& name) - : writer(w) - { - WriteKey(writer, name); - writer.StartArray(); - } - ~WriteArray() { writer.EndArray(); } -}; - -template -void WriteOptionalString(JsonWriter& w, T& k, const char* value) -{ - if (value && value[0]) { - w.Key(k, sizeof(T) - 1); - w.String(value); - } -} - -static void JsonWriteNonce(JsonWriter& writer, int nonce) -{ - WriteKey(writer, "nonce"); - char nonceBuffer[32]; - NumberToString(nonceBuffer, nonce); - writer.String(nonceBuffer); -} - -size_t JsonWriteRichPresenceObj(char* dest, - size_t maxLen, - int nonce, - int pid, - const DiscordRichPresence* presence) -{ - JsonWriter writer(dest, maxLen); - - { - WriteObject top(writer); - - JsonWriteNonce(writer, nonce); - - WriteKey(writer, "cmd"); - writer.String("SET_ACTIVITY"); - - { - WriteObject args(writer, "args"); - - WriteKey(writer, "pid"); - writer.Int(pid); - - if (presence != nullptr) { - WriteObject activity(writer, "activity"); - - WriteOptionalString(writer, "state", presence->state); - WriteOptionalString(writer, "details", presence->details); - - if (presence->startTimestamp || presence->endTimestamp) { - WriteObject timestamps(writer, "timestamps"); - - if (presence->startTimestamp) { - WriteKey(writer, "start"); - writer.Int64(presence->startTimestamp); - } - - if (presence->endTimestamp) { - WriteKey(writer, "end"); - writer.Int64(presence->endTimestamp); - } - } - - if ((presence->largeImageKey && presence->largeImageKey[0]) || - (presence->largeImageText && presence->largeImageText[0]) || - (presence->smallImageKey && presence->smallImageKey[0]) || - (presence->smallImageText && presence->smallImageText[0])) { - WriteObject assets(writer, "assets"); - WriteOptionalString(writer, "large_image", presence->largeImageKey); - WriteOptionalString(writer, "large_text", presence->largeImageText); - WriteOptionalString(writer, "small_image", presence->smallImageKey); - WriteOptionalString(writer, "small_text", presence->smallImageText); - } - - if ((presence->partyId && presence->partyId[0]) || presence->partySize || - presence->partyMax || presence->partyPrivacy) { - WriteObject party(writer, "party"); - WriteOptionalString(writer, "id", presence->partyId); - if (presence->partySize && presence->partyMax) { - WriteArray size(writer, "size"); - writer.Int(presence->partySize); - writer.Int(presence->partyMax); - } - - if (presence->partyPrivacy) { - WriteKey(writer, "privacy"); - writer.Int(presence->partyPrivacy); - } - } - - if ((presence->matchSecret && presence->matchSecret[0]) || - (presence->joinSecret && presence->joinSecret[0]) || - (presence->spectateSecret && presence->spectateSecret[0])) { - WriteObject secrets(writer, "secrets"); - WriteOptionalString(writer, "match", presence->matchSecret); - WriteOptionalString(writer, "join", presence->joinSecret); - WriteOptionalString(writer, "spectate", presence->spectateSecret); - } - - writer.Key("instance"); - writer.Bool(presence->instance != 0); - } - } - } - - return writer.Size(); -} - -size_t JsonWriteHandshakeObj(char* dest, size_t maxLen, int version, const char* applicationId) -{ - JsonWriter writer(dest, maxLen); - - { - WriteObject obj(writer); - WriteKey(writer, "v"); - writer.Int(version); - WriteKey(writer, "client_id"); - writer.String(applicationId); - } - - return writer.Size(); -} - -size_t JsonWriteSubscribeCommand(char* dest, size_t maxLen, int nonce, const char* evtName) -{ - JsonWriter writer(dest, maxLen); - - { - WriteObject obj(writer); - - JsonWriteNonce(writer, nonce); - - WriteKey(writer, "cmd"); - writer.String("SUBSCRIBE"); - - WriteKey(writer, "evt"); - writer.String(evtName); - } - - return writer.Size(); -} - -size_t JsonWriteUnsubscribeCommand(char* dest, size_t maxLen, int nonce, const char* evtName) -{ - JsonWriter writer(dest, maxLen); - - { - WriteObject obj(writer); - - JsonWriteNonce(writer, nonce); - - WriteKey(writer, "cmd"); - writer.String("UNSUBSCRIBE"); - - WriteKey(writer, "evt"); - writer.String(evtName); - } - - return writer.Size(); -} - -size_t JsonWriteJoinReply(char* dest, size_t maxLen, const char* userId, int reply, int nonce) -{ - JsonWriter writer(dest, maxLen); - - { - WriteObject obj(writer); - - WriteKey(writer, "cmd"); - if (reply == DISCORD_REPLY_YES) { - writer.String("SEND_ACTIVITY_JOIN_INVITE"); - } - else { - writer.String("CLOSE_ACTIVITY_JOIN_REQUEST"); - } - - WriteKey(writer, "args"); - { - WriteObject args(writer); - - WriteKey(writer, "user_id"); - writer.String(userId); - } - - JsonWriteNonce(writer, nonce); - } - - return writer.Size(); -} diff --git a/dependencies/discord-rpc/src/serialization.h b/dependencies/discord-rpc/src/serialization.h deleted file mode 100644 index 9c462dc2..00000000 --- a/dependencies/discord-rpc/src/serialization.h +++ /dev/null @@ -1,215 +0,0 @@ -#pragma once - -#include - -#ifndef __MINGW32__ -#pragma warning(push) - -#pragma warning(disable : 4061) // enum is not explicitly handled by a case label -#pragma warning(disable : 4365) // signed/unsigned mismatch -#pragma warning(disable : 4464) // relative include path contains -#pragma warning(disable : 4668) // is not defined as a preprocessor macro -#pragma warning(disable : 6313) // Incorrect operator -#endif // __MINGW32__ - -#include "rapidjson/document.h" -#include "rapidjson/stringbuffer.h" -#include "rapidjson/writer.h" - -#ifndef __MINGW32__ -#pragma warning(pop) -#endif // __MINGW32__ - -// if only there was a standard library function for this -template -inline size_t StringCopy(char (&dest)[Len], const char* src) -{ - if (!src || !Len) { - return 0; - } - size_t copied; - char* out = dest; - for (copied = 1; *src && copied < Len; ++copied) { - *out++ = *src++; - } - *out = 0; - return copied - 1; -} - -size_t JsonWriteHandshakeObj(char* dest, size_t maxLen, int version, const char* applicationId); - -// Commands -struct DiscordRichPresence; -size_t JsonWriteRichPresenceObj(char* dest, - size_t maxLen, - int nonce, - int pid, - const DiscordRichPresence* presence); -size_t JsonWriteSubscribeCommand(char* dest, size_t maxLen, int nonce, const char* evtName); - -size_t JsonWriteUnsubscribeCommand(char* dest, size_t maxLen, int nonce, const char* evtName); - -size_t JsonWriteJoinReply(char* dest, size_t maxLen, const char* userId, int reply, int nonce); - -// I want to use as few allocations as I can get away with, and to do that with RapidJson, you need -// to supply some of your own allocators for stuff rather than use the defaults - -class LinearAllocator { -public: - char* buffer_; - char* end_; - LinearAllocator() - { - assert(0); // needed for some default case in rapidjson, should not use - } - LinearAllocator(char* buffer, size_t size) - : buffer_(buffer) - , end_(buffer + size) - { - } - static const bool kNeedFree = false; - void* Malloc(size_t size) - { - char* res = buffer_; - buffer_ += size; - if (buffer_ > end_) { - buffer_ = res; - return nullptr; - } - return res; - } - void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) - { - if (newSize == 0) { - return nullptr; - } - // allocate how much you need in the first place - assert(!originalPtr && !originalSize); - // unused parameter warning - (void)(originalPtr); - (void)(originalSize); - return Malloc(newSize); - } - static void Free(void* ptr) - { - /* shrug */ - (void)ptr; - } -}; - -template -class FixedLinearAllocator : public LinearAllocator { -public: - char fixedBuffer_[Size]; - FixedLinearAllocator() - : LinearAllocator(fixedBuffer_, Size) - { - } - static const bool kNeedFree = false; -}; - -// wonder why this isn't a thing already, maybe I missed it -class DirectStringBuffer { -public: - using Ch = char; - char* buffer_; - char* end_; - char* current_; - - DirectStringBuffer(char* buffer, size_t maxLen) - : buffer_(buffer) - , end_(buffer + maxLen) - , current_(buffer) - { - } - - void Put(char c) - { - if (current_ < end_) { - *current_++ = c; - } - } - void Flush() {} - size_t GetSize() const { return (size_t)(current_ - buffer_); } -}; - -using MallocAllocator = rapidjson::CrtAllocator; -using PoolAllocator = rapidjson::MemoryPoolAllocator; -using UTF8 = rapidjson::UTF8; -// Writer appears to need about 16 bytes per nested object level (with 64bit size_t) -using StackAllocator = FixedLinearAllocator<2048>; -constexpr size_t WriterNestingLevels = 2048 / (2 * sizeof(size_t)); -using JsonWriterBase = - rapidjson::Writer; -class JsonWriter : public JsonWriterBase { -public: - DirectStringBuffer stringBuffer_; - StackAllocator stackAlloc_; - - JsonWriter(char* dest, size_t maxLen) - : JsonWriterBase(stringBuffer_, &stackAlloc_, WriterNestingLevels) - , stringBuffer_(dest, maxLen) - , stackAlloc_() - { - } - - size_t Size() const { return stringBuffer_.GetSize(); } -}; - -using JsonDocumentBase = rapidjson::GenericDocument; -class JsonDocument : public JsonDocumentBase { -public: - static const int kDefaultChunkCapacity = 32 * 1024; - // json parser will use this buffer first, then allocate more if needed; I seriously doubt we - // send any messages that would use all of this, though. - char parseBuffer_[32 * 1024]; - MallocAllocator mallocAllocator_; - PoolAllocator poolAllocator_; - StackAllocator stackAllocator_; - JsonDocument() - : JsonDocumentBase(rapidjson::kObjectType, - &poolAllocator_, - sizeof(stackAllocator_.fixedBuffer_), - &stackAllocator_) - , poolAllocator_(parseBuffer_, sizeof(parseBuffer_), kDefaultChunkCapacity, &mallocAllocator_) - , stackAllocator_() - { - } -}; - -using JsonValue = rapidjson::GenericValue; - -inline JsonValue* GetObjMember(JsonValue* obj, const char* name) -{ - if (obj) { - auto member = obj->FindMember(name); - if (member != obj->MemberEnd() && member->value.IsObject()) { - return &member->value; - } - } - return nullptr; -} - -inline int GetIntMember(JsonValue* obj, const char* name, int notFoundDefault = 0) -{ - if (obj) { - auto member = obj->FindMember(name); - if (member != obj->MemberEnd() && member->value.IsInt()) { - return member->value.GetInt(); - } - } - return notFoundDefault; -} - -inline const char* GetStrMember(JsonValue* obj, - const char* name, - const char* notFoundDefault = nullptr) -{ - if (obj) { - auto member = obj->FindMember(name); - if (member != obj->MemberEnd() && member->value.IsString()) { - return member->value.GetString(); - } - } - return notFoundDefault; -} diff --git a/dependencies/vcpkg b/dependencies/vcpkg index 533a5fda..f0fb3ddb 160000 --- a/dependencies/vcpkg +++ b/dependencies/vcpkg @@ -1 +1 @@ -Subproject commit 533a5fda5c0646d1771345fb572e759283444d5f +Subproject commit f0fb3ddba5135b80982668de39dbaa139c00d281 diff --git a/dependencies/vcpkg_overlay_ports/wxwidgets/example/CMakeLists.txt b/dependencies/vcpkg_overlay_ports/wxwidgets/example/CMakeLists.txt new file mode 100644 index 00000000..229b7107 --- /dev/null +++ b/dependencies/vcpkg_overlay_ports/wxwidgets/example/CMakeLists.txt @@ -0,0 +1,31 @@ +cmake_minimum_required(VERSION 3.7) + +project(wxwidgets-example) + +add_executable(main WIN32 popup.cpp) + +find_package(wxWidgets REQUIRED) +target_compile_definitions(main PRIVATE ${wxWidgets_DEFINITIONS} "$<$:${wxWidgets_DEFINITIONS_DEBUG}>") +target_include_directories(main PRIVATE ${wxWidgets_INCLUDE_DIRS}) +target_link_libraries(main PRIVATE ${wxWidgets_LIBRARIES}) + +add_executable(main2 WIN32 popup.cpp) + +find_package(wxWidgets CONFIG REQUIRED) +target_link_libraries(main2 PRIVATE wx::core wx::base) + +option(USE_WXRC "Use the wxrc resource compiler" ON) +if(USE_WXRC) + execute_process( + COMMAND "${wxWidgets_wxrc_EXECUTABLE}" --help + RESULTS_VARIABLE error_result + ) + if(error_result) + message(FATAL_ERROR "Failed to run wxWidgets_wxrc_EXECUTABLE (${wxWidgets_wxrc_EXECUTABLE})") + endif() +endif() + +set(PRINT_VARS "" CACHE STRING "Variables to print at the end of configuration") +foreach(var IN LISTS PRINT_VARS) + message(STATUS "${var}:=${${var}}") +endforeach() diff --git a/dependencies/vcpkg_overlay_ports/wxwidgets/fix-dark-mode-offset.patch b/dependencies/vcpkg_overlay_ports/wxwidgets/fix-dark-mode-offset.patch new file mode 100644 index 00000000..9b8a979a --- /dev/null +++ b/dependencies/vcpkg_overlay_ports/wxwidgets/fix-dark-mode-offset.patch @@ -0,0 +1,25 @@ +diff --git a/src/msw/listctrl.cpp b/src/msw/listctrl.cpp +index 2b9e0d7f7e..7eab8b37df 100644 +--- a/src/msw/listctrl.cpp ++++ b/src/msw/listctrl.cpp +@@ -3110,6 +3110,11 @@ bool HandleSubItemPrepaint(wxListCtrl* listctrl, LPNMLVCUSTOMDRAW pLVCD, HFONT h + + if ( it.iImage != -1 ) + { ++ if ( !listctrl->HasCheckBoxes() ) ++ { ++ rc.left -= 6; ++ } ++ + const int yImage = rc.top + ((rc.bottom - rc.top) / 2 - hImage / 2); + ImageList_Draw(himl, it.iImage, hdc, rc.left, yImage, + nmcd.uItemState & CDIS_SELECTED ? ILD_SELECTED +@@ -3235,7 +3240,7 @@ void HandleItemPaint(wxListCtrl* listctrl, LPNMLVCUSTOMDRAW pLVCD, HFONT hfont) + // do not draw item background colour under the checkbox/image + RECT rcIcon; + wxGetListCtrlItemRect(nmcd.hdr.hwndFrom, nmcd.dwItemSpec, LVIR_ICON, rcIcon); +- if ( !::IsRectEmpty(&rcIcon) ) ++ if ( !::IsRectEmpty(&rcIcon) && listctrl->HasCheckBoxes() ) + rc.left = rcIcon.right + listctrl->FromDIP(GAP_BETWEEN_CHECKBOX_AND_TEXT); + } + diff --git a/dependencies/vcpkg_overlay_ports/wxwidgets/fix-libs-export.patch b/dependencies/vcpkg_overlay_ports/wxwidgets/fix-libs-export.patch new file mode 100644 index 00000000..df4b7c26 --- /dev/null +++ b/dependencies/vcpkg_overlay_ports/wxwidgets/fix-libs-export.patch @@ -0,0 +1,21 @@ +diff --git a/build/cmake/config.cmake b/build/cmake/config.cmake +index b359560..7504458 100644 +--- a/build/cmake/config.cmake ++++ b/build/cmake/config.cmake +@@ -39,8 +39,14 @@ macro(wx_get_dependencies var lib) + else() + # For the value like $<$:LIB_PATH> + # Or $<$>:LIB_PATH> +- string(REGEX REPLACE "^.+>:(.+)>$" "\\1" dep_name ${dep}) +- if (NOT dep_name) ++ if(dep MATCHES "^(.+>):(.+)>$") ++ if(CMAKE_BUILD_TYPE STREQUAL "Debug" AND CMAKE_MATCH_1 STREQUAL [[$<$>]]) ++ continue() ++ elseif(CMAKE_BUILD_TYPE STREQUAL "Release" AND CMAKE_MATCH_1 STREQUAL [[$<$]]) ++ continue() ++ endif() ++ set(dep_name "${CMAKE_MATCH_2}") ++ else() + set(dep_name ${dep}) + endif() + endif() diff --git a/dependencies/vcpkg_overlay_ports/wxwidgets/fix-pcre2.patch b/dependencies/vcpkg_overlay_ports/wxwidgets/fix-pcre2.patch new file mode 100644 index 00000000..20063f44 --- /dev/null +++ b/dependencies/vcpkg_overlay_ports/wxwidgets/fix-pcre2.patch @@ -0,0 +1,23 @@ +diff --git a/build/cmake/modules/FindPCRE2.cmake b/build/cmake/modules/FindPCRE2.cmake +index a27693a..455675a 100644 +--- a/build/cmake/modules/FindPCRE2.cmake ++++ b/build/cmake/modules/FindPCRE2.cmake +@@ -24,7 +24,10 @@ set(PCRE2_CODE_UNIT_WIDTH_USED "${PCRE2_CODE_UNIT_WIDTH}" CACHE INTERNAL "") + + find_package(PkgConfig QUIET) + pkg_check_modules(PC_PCRE2 QUIET libpcre2-${PCRE2_CODE_UNIT_WIDTH}) ++set(PCRE2_LIBRARIES ${PC_PCRE2_LINK_LIBRARIES}) ++set(PCRE2_INCLUDE_DIRS ${PC_PCRE2_INCLUDE_DIRS}) + ++if (0) + find_path(PCRE2_INCLUDE_DIRS + NAMES pcre2.h + HINTS ${PC_PCRE2_INCLUDEDIR} +@@ -36,6 +39,7 @@ find_library(PCRE2_LIBRARIES + HINTS ${PC_PCRE2_LIBDIR} + ${PC_PCRE2_LIBRARY_DIRS} + ) ++endif() + + include(FindPackageHandleStandardArgs) + FIND_PACKAGE_HANDLE_STANDARD_ARGS(PCRE2 REQUIRED_VARS PCRE2_LIBRARIES PCRE2_INCLUDE_DIRS VERSION_VAR PC_PCRE2_VERSION) diff --git a/dependencies/vcpkg_overlay_ports/wxwidgets/gtk3-link-libraries.patch b/dependencies/vcpkg_overlay_ports/wxwidgets/gtk3-link-libraries.patch new file mode 100644 index 00000000..4e4c4819 --- /dev/null +++ b/dependencies/vcpkg_overlay_ports/wxwidgets/gtk3-link-libraries.patch @@ -0,0 +1,17 @@ +diff --git a/build/cmake/modules/FindGTK3.cmake b/build/cmake/modules/FindGTK3.cmake +index d2939a1..daf33fe 100644 +--- a/build/cmake/modules/FindGTK3.cmake ++++ b/build/cmake/modules/FindGTK3.cmake +@@ -47,6 +47,12 @@ include(CheckSymbolExists) + set(CMAKE_REQUIRED_INCLUDES ${GTK3_INCLUDE_DIRS}) + check_symbol_exists(GDK_WINDOWING_WAYLAND "gdk/gdk.h" wxHAVE_GDK_WAYLAND) + check_symbol_exists(GDK_WINDOWING_X11 "gdk/gdk.h" wxHAVE_GDK_X11) ++# With Lerc support in TIFF, Gtk3 may carry C++ compiler libs which break FindWxWidgets.cmake. ++# WxWidgets is C++, so we can remove them here using the inverse pattern. ++set(cxx_libs "${CMAKE_CXX_IMPLICIT_LINK_LIBRARIES}") ++list(REMOVE_ITEM cxx_libs ${CMAKE_C_IMPLICIT_LINK_LIBRARIES}) ++list(REMOVE_ITEM GTK3_LINK_LIBRARIES ${cxx_libs}) ++set(GTK3_LIBRARIES "${GTK3_LINK_LIBRARIES}" CACHE INTERNAL "") + include(FindPackageHandleStandardArgs) + FIND_PACKAGE_HANDLE_STANDARD_ARGS(GTK3 DEFAULT_MSG GTK3_INCLUDE_DIRS GTK3_LIBRARIES VERSION_OK) + diff --git a/dependencies/vcpkg_overlay_ports/wxwidgets/install-layout.patch b/dependencies/vcpkg_overlay_ports/wxwidgets/install-layout.patch new file mode 100644 index 00000000..6ec4db46 --- /dev/null +++ b/dependencies/vcpkg_overlay_ports/wxwidgets/install-layout.patch @@ -0,0 +1,39 @@ +diff --git a/build/cmake/init.cmake b/build/cmake/init.cmake +index f044d22d4d..48fc5ad072 100644 +--- a/build/cmake/init.cmake ++++ b/build/cmake/init.cmake +@@ -198,7 +198,7 @@ if(WIN32) + endif() + endif() + +-if(WIN32_MSVC_NAMING) ++if(0) + if(wxBUILD_SHARED) + set(lib_suffix "_dll") + else() +diff --git a/build/cmake/install.cmake b/build/cmake/install.cmake +index a373983043..2e1ace7bf9 100644 +--- a/build/cmake/install.cmake ++++ b/build/cmake/install.cmake +@@ -63,7 +63,7 @@ else() + + install(DIRECTORY DESTINATION "bin") + install(CODE "execute_process( \ +- COMMAND ${CMAKE_COMMAND} -E create_symlink \ ++ COMMAND ${CMAKE_COMMAND} -E copy \ + \"\$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/lib/wx/config/${wxBUILD_FILE_ID}\" \ + \"\$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/wx-config\" \ + )" +diff --git a/build/cmake/utils/CMakeLists.txt b/build/cmake/utils/CMakeLists.txt +index 15f4339ef9..f93849e025 100644 +--- a/build/cmake/utils/CMakeLists.txt ++++ b/build/cmake/utils/CMakeLists.txt +@@ -39,7 +39,7 @@ if(wxUSE_XRC) + + # Don't use wx_install() here to preserve escaping. + install(CODE "execute_process( \ +- COMMAND ${CMAKE_COMMAND} -E create_symlink \ ++ COMMAND ${CMAKE_COMMAND} -E copy \ + \"\$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/${wxrc_output_name}${EXE_SUFFIX}\" \ + \"\$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/wxrc${EXE_SUFFIX}\" \ + )" diff --git a/dependencies/vcpkg_overlay_ports/wxwidgets/nanosvg-ext-depend.patch b/dependencies/vcpkg_overlay_ports/wxwidgets/nanosvg-ext-depend.patch new file mode 100644 index 00000000..f76a4562 --- /dev/null +++ b/dependencies/vcpkg_overlay_ports/wxwidgets/nanosvg-ext-depend.patch @@ -0,0 +1,13 @@ +diff --git a/build/cmake/wxWidgetsConfig.cmake.in b/build/cmake/wxWidgetsConfig.cmake.in +index b251109..60cf762 100644 +--- a/build/cmake/wxWidgetsConfig.cmake.in ++++ b/build/cmake/wxWidgetsConfig.cmake.in +@@ -1,5 +1,8 @@ + @PACKAGE_INIT@ + ++include(CMakeFindDependencyMacro) ++find_dependency(NanoSVG CONFIG) ++ + cmake_policy(PUSH) + # Set policies to prevent warnings + if(POLICY CMP0057) diff --git a/dependencies/vcpkg_overlay_ports/wxwidgets/portfile.cmake b/dependencies/vcpkg_overlay_ports/wxwidgets/portfile.cmake new file mode 100644 index 00000000..12491480 --- /dev/null +++ b/dependencies/vcpkg_overlay_ports/wxwidgets/portfile.cmake @@ -0,0 +1,211 @@ +vcpkg_from_github( + OUT_SOURCE_PATH SOURCE_PATH + REPO wxWidgets/wxWidgets + REF "v${VERSION}" + SHA512 8ad17582c4ba721ffe76ada4bb8bd7bc4b050491220aca335fd0506a51354fb789d5bc3d965f0f459dc81784d6427c88272e2acc2099cddf73730231b5a16f62 + HEAD_REF master + PATCHES + install-layout.patch + relocatable-wx-config.patch + nanosvg-ext-depend.patch + fix-libs-export.patch + fix-pcre2.patch + gtk3-link-libraries.patch + sdl2.patch + fix-dark-mode-offset.patch +) + +vcpkg_check_features( + OUT_FEATURE_OPTIONS FEATURE_OPTIONS + FEATURES + fonts wxUSE_PRIVATE_FONTS + media wxUSE_MEDIACTRL + secretstore wxUSE_SECRETSTORE + sound wxUSE_SOUND + webview wxUSE_WEBVIEW + webview wxUSE_WEBVIEW_EDGE +) + +set(OPTIONS_RELEASE "") +if(NOT "debug-support" IN_LIST FEATURES) + list(APPEND OPTIONS_RELEASE "-DwxBUILD_DEBUG_LEVEL=0") +endif() + +set(OPTIONS "") +if(VCPKG_TARGET_IS_WINDOWS AND (VCPKG_TARGET_ARCHITECTURE STREQUAL "arm64" OR VCPKG_TARGET_ARCHITECTURE STREQUAL "arm")) + list(APPEND OPTIONS + -DwxUSE_STACKWALKER=OFF + ) +endif() + +if(VCPKG_TARGET_IS_WINDOWS OR VCPKG_TARGET_IS_OSX) + list(APPEND OPTIONS -DwxUSE_WEBREQUEST_CURL=OFF) +else() + list(APPEND OPTIONS -DwxUSE_WEBREQUEST_CURL=ON) +endif() + +if(VCPKG_TARGET_IS_WINDOWS) + if(VCPKG_CRT_LINKAGE STREQUAL "dynamic") + list(APPEND OPTIONS -DwxBUILD_USE_STATIC_RUNTIME=OFF) + else() + list(APPEND OPTIONS -DwxBUILD_USE_STATIC_RUNTIME=ON) + endif() +endif() + +vcpkg_find_acquire_program(PKGCONFIG) + +# This may be set to ON by users in a custom triplet. +# The use of 'wxUSE_STL' and 'WXWIDGETS_USE_STD_CONTAINERS' (ON or OFF) are not API compatible +# which is why they must be set in a custom triplet rather than a port feature. +if(NOT DEFINED WXWIDGETS_USE_STL) + set(WXWIDGETS_USE_STL OFF) + set(WXWIDGETS_USE_STD_STRING_CONV_IN_WXSTRING OFF) +endif() + +if(NOT DEFINED WXWIDGETS_USE_STD_CONTAINERS) + set(WXWIDGETS_USE_STD_CONTAINERS OFF) +endif() + +vcpkg_cmake_configure( + SOURCE_PATH "${SOURCE_PATH}" + OPTIONS + ${FEATURE_OPTIONS} + -DwxUSE_STC=OFF + -DwxUSE_REGEX=sys + -DwxUSE_ZLIB=sys + -DwxUSE_EXPAT=sys + -DwxUSE_LIBJPEG=sys + -DwxUSE_LIBPNG=sys + -DwxUSE_LIBTIFF=sys + -DwxUSE_LIBWEBP=sys + -DwxUSE_NANOSVG=sys + -DwxUSE_GLCANVAS=ON + -DwxUSE_LIBGNOMEVFS=OFF + -DwxUSE_LIBNOTIFY=OFF + -DwxUSE_STD_STRING_CONV_IN_WXSTRING=${WXWIDGETS_USE_STD_STRING_CONV_IN_WXSTRING} + -DwxUSE_STD_CONTAINERS=${WXWIDGETS_USE_STD_CONTAINERS} + -DwxUSE_UIACTIONSIMULATOR=OFF + -DCMAKE_DISABLE_FIND_PACKAGE_GSPELL=ON + -DCMAKE_DISABLE_FIND_PACKAGE_MSPACK=ON + -DwxBUILD_INSTALL_RUNTIME_DIR:PATH=bin + ${OPTIONS} + "-DPKG_CONFIG_EXECUTABLE=${PKGCONFIG}" + # The minimum cmake version requirement for Cotire is 2.8.12. + # however, we need to declare that the minimum cmake version requirement is at least 3.1 to use CMAKE_PREFIX_PATH as the path to find .pc. + -DPKG_CONFIG_USE_CMAKE_PREFIX_PATH=ON + OPTIONS_RELEASE + ${OPTIONS_RELEASE} + MAYBE_UNUSED_VARIABLES + CMAKE_DISABLE_FIND_PACKAGE_GSPELL + CMAKE_DISABLE_FIND_PACKAGE_MSPACK +) + +vcpkg_cmake_install() +vcpkg_cmake_config_fixup(CONFIG_PATH lib/cmake/wxWidgets) + +# The CMake export is not ready for use: It lacks a config file. +file(REMOVE_RECURSE + ${CURRENT_PACKAGES_DIR}/lib/cmake + ${CURRENT_PACKAGES_DIR}/debug/lib/cmake +) + +set(tools wxrc) +if(NOT VCPKG_TARGET_IS_WINDOWS) + list(APPEND tools wxrc-3.3) + file(MAKE_DIRECTORY "${CURRENT_PACKAGES_DIR}/tools/${PORT}") + file(RENAME "${CURRENT_PACKAGES_DIR}/bin/wx-config" "${CURRENT_PACKAGES_DIR}/tools/${PORT}/wx-config") + if(NOT VCPKG_BUILD_TYPE) + file(MAKE_DIRECTORY "${CURRENT_PACKAGES_DIR}/tools/${PORT}/debug") + file(RENAME "${CURRENT_PACKAGES_DIR}/debug/bin/wx-config" "${CURRENT_PACKAGES_DIR}/tools/${PORT}/debug/wx-config") + endif() +endif() +vcpkg_copy_tools(TOOL_NAMES ${tools} AUTO_CLEAN) + +# do the copy pdbs now after the dlls got moved to the expected /bin folder above +vcpkg_copy_pdbs() + +file(REMOVE_RECURSE "${CURRENT_PACKAGES_DIR}/include/msvc") +file(REMOVE_RECURSE "${CURRENT_PACKAGES_DIR}/debug/include") +file(GLOB_RECURSE INCLUDES "${CURRENT_PACKAGES_DIR}/include/*.h") +if(EXISTS "${CURRENT_PACKAGES_DIR}/lib/mswu/wx/setup.h") + list(APPEND INCLUDES "${CURRENT_PACKAGES_DIR}/lib/mswu/wx/setup.h") +endif() +if(EXISTS "${CURRENT_PACKAGES_DIR}/debug/lib/mswud/wx/setup.h") + list(APPEND INCLUDES "${CURRENT_PACKAGES_DIR}/debug/lib/mswud/wx/setup.h") +endif() +foreach(INC IN LISTS INCLUDES) + file(READ "${INC}" _contents) + if(VCPKG_LIBRARY_LINKAGE STREQUAL "static") + string(REPLACE "defined(WXUSINGDLL)" "0" _contents "${_contents}") + else() + string(REPLACE "defined(WXUSINGDLL)" "1" _contents "${_contents}") + endif() + # Remove install prefix from setup.h to ensure package is relocatable + string(REGEX REPLACE "\n#define wxINSTALL_PREFIX [^\n]*" "\n#define wxINSTALL_PREFIX \"\"" _contents "${_contents}") + file(WRITE "${INC}" "${_contents}") +endforeach() + +if(NOT EXISTS "${CURRENT_PACKAGES_DIR}/include/wx/setup.h") + file(GLOB_RECURSE WX_SETUP_H_FILES_DBG "${CURRENT_PACKAGES_DIR}/debug/lib/*.h") + file(GLOB_RECURSE WX_SETUP_H_FILES_REL "${CURRENT_PACKAGES_DIR}/lib/*.h") + + if(NOT DEFINED VCPKG_BUILD_TYPE OR VCPKG_BUILD_TYPE STREQUAL "release") + vcpkg_replace_string("${WX_SETUP_H_FILES_REL}" "${CURRENT_PACKAGES_DIR}" "" IGNORE_UNCHANGED) + + string(REPLACE "${CURRENT_PACKAGES_DIR}/lib/" "" WX_SETUP_H_FILES_REL "${WX_SETUP_H_FILES_REL}") + string(REPLACE "/setup.h" "" WX_SETUP_H_REL_RELATIVE "${WX_SETUP_H_FILES_REL}") + endif() + if(NOT DEFINED VCPKG_BUILD_TYPE OR VCPKG_BUILD_TYPE STREQUAL "debug") + vcpkg_replace_string("${WX_SETUP_H_FILES_DBG}" "${CURRENT_PACKAGES_DIR}" "" IGNORE_UNCHANGED) + + string(REPLACE "${CURRENT_PACKAGES_DIR}/debug/lib/" "" WX_SETUP_H_FILES_DBG "${WX_SETUP_H_FILES_DBG}") + string(REPLACE "/setup.h" "" WX_SETUP_H_DBG_RELATIVE "${WX_SETUP_H_FILES_DBG}") + endif() + + configure_file("${CMAKE_CURRENT_LIST_DIR}/setup.h.in" "${CURRENT_PACKAGES_DIR}/include/wx/setup.h" @ONLY) +endif() + +file(GLOB configs LIST_DIRECTORIES false "${CURRENT_PACKAGES_DIR}/lib/wx/config/*" "${CURRENT_PACKAGES_DIR}/tools/${PORT}/wx-config") +foreach(config IN LISTS configs) + vcpkg_replace_string("${config}" "${CURRENT_INSTALLED_DIR}" [[${prefix}]]) +endforeach() +file(GLOB configs LIST_DIRECTORIES false "${CURRENT_PACKAGES_DIR}/debug/lib/wx/config/*" "${CURRENT_PACKAGES_DIR}/tools/${PORT}/debug/wx-config") +foreach(config IN LISTS configs) + vcpkg_replace_string("${config}" "${CURRENT_INSTALLED_DIR}/debug" [[${prefix}]]) +endforeach() + +# For CMake multi-config in connection with wrapper +if(EXISTS "${CURRENT_PACKAGES_DIR}/debug/lib/mswud/wx/setup.h") + file(INSTALL "${CURRENT_PACKAGES_DIR}/debug/lib/mswud/wx/setup.h" + DESTINATION "${CURRENT_PACKAGES_DIR}/lib/mswud/wx" + ) +endif() + +if(NOT "debug-support" IN_LIST FEATURES) + if(VCPKG_TARGET_IS_WINDOWS) + vcpkg_replace_string("${CURRENT_PACKAGES_DIR}/include/wx/debug.h" "#define wxDEBUG_LEVEL 1" "#define wxDEBUG_LEVEL 0") + else() + vcpkg_replace_string("${CURRENT_PACKAGES_DIR}/include/wx-3.3/wx/debug.h" "#define wxDEBUG_LEVEL 1" "#define wxDEBUG_LEVEL 0") + endif() +endif() + +if("example" IN_LIST FEATURES) + file(INSTALL + "${CMAKE_CURRENT_LIST_DIR}/example/CMakeLists.txt" + "${SOURCE_PATH}/samples/popup/popup.cpp" + "${SOURCE_PATH}/samples/sample.xpm" + DESTINATION "${CURRENT_PACKAGES_DIR}/share/${PORT}/example" + ) + vcpkg_replace_string("${CURRENT_PACKAGES_DIR}/share/${PORT}/example/popup.cpp" "../sample.xpm" "sample.xpm") +endif() + +configure_file("${CMAKE_CURRENT_LIST_DIR}/vcpkg-cmake-wrapper.cmake" "${CURRENT_PACKAGES_DIR}/share/${PORT}/vcpkg-cmake-wrapper.cmake" @ONLY) + +file(REMOVE "${CURRENT_PACKAGES_DIR}/wxwidgets.props") +file(REMOVE "${CURRENT_PACKAGES_DIR}/debug/wxwidgets.props") +file(REMOVE_RECURSE "${CURRENT_PACKAGES_DIR}/build") +file(REMOVE_RECURSE "${CURRENT_PACKAGES_DIR}/debug/build") +file(REMOVE_RECURSE "${CURRENT_PACKAGES_DIR}/debug/share") + +file(INSTALL "${CMAKE_CURRENT_LIST_DIR}/usage" DESTINATION "${CURRENT_PACKAGES_DIR}/share/${PORT}") +vcpkg_install_copyright(FILE_LIST "${SOURCE_PATH}/docs/licence.txt") diff --git a/dependencies/vcpkg_overlay_ports/wxwidgets/relocatable-wx-config.patch b/dependencies/vcpkg_overlay_ports/wxwidgets/relocatable-wx-config.patch new file mode 100644 index 00000000..608c9c54 --- /dev/null +++ b/dependencies/vcpkg_overlay_ports/wxwidgets/relocatable-wx-config.patch @@ -0,0 +1,40 @@ +diff --git a/wx-config.in b/wx-config.in +index 4df8571..a90db3d 100644 +--- a/wx-config.in ++++ b/wx-config.in +@@ -398,8 +398,23 @@ is_cross() { [ "x@cross_compiling@" = "xyes" ]; } + + + # Determine the base directories we require. +-prefix=${input_option_prefix-${this_prefix:-@prefix@}} +-exec_prefix=${input_option_exec_prefix-${input_option_prefix-${this_exec_prefix:-@exec_prefix@}}} ++vcpkg_prefix=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd -P) ++case "$vcpkg_prefix" in ++ */lib/wx/config) ++ vcpkg_prefix=${vcpkg_prefix%/*/*/*} ++ ;; ++ */tools/wxwidgets/debug) ++ vcpkg_prefix=${vcpkg_prefix%/*/*/*}/debug ++ ;; ++ */tools/wxwidgets) ++ vcpkg_prefix=${vcpkg_prefix%/*/*} ++ ;; ++esac ++if [ -n "@MINGW@" -a -n "@CMAKE_HOST_WIN32@" ]; then ++ vcpkg_prefix=$(cygpath -m "$vcpkg_prefix") ++fi ++prefix=${input_option_prefix-${this_prefix:-$vcpkg_prefix}} ++exec_prefix=${input_option_exec_prefix-${input_option_prefix-${this_exec_prefix:-$prefix}}} + wxconfdir="@libdir@/wx/config" + + installed_configs=`cd "$wxconfdir" 2> /dev/null && ls | grep -v "^inplace-"` +@@ -936,6 +951,9 @@ prefix=${this_prefix-$prefix} + exec_prefix=${this_exec_prefix-$exec_prefix} + + includedir="@includedir@" ++if [ "@CMAKE_BUILD_TYPE@" = "Debug" ] ; then ++ includedir="${includedir%/debug/include}/include" ++fi + libdir="@libdir@" + bindir="@bindir@" + diff --git a/dependencies/vcpkg_overlay_ports/wxwidgets/sdl2.patch b/dependencies/vcpkg_overlay_ports/wxwidgets/sdl2.patch new file mode 100644 index 00000000..511775cc --- /dev/null +++ b/dependencies/vcpkg_overlay_ports/wxwidgets/sdl2.patch @@ -0,0 +1,29 @@ +diff --git a/build/cmake/init.cmake b/build/cmake/init.cmake +index 5447d33..f5440b4 100644 +--- a/build/cmake/init.cmake ++++ b/build/cmake/init.cmake +@@ -530,7 +530,9 @@ if(wxUSE_GUI) + endif() + + if(wxUSE_SOUND AND wxUSE_LIBSDL AND UNIX AND NOT APPLE) +- find_package(SDL2) ++ find_package(SDL2 CONFIG REQUIRED) ++ set(SDL2_INCLUDE_DIR "" CACHE INTERNAL "") ++ set(SDL2_LIBRARY SDL2::SDL2 CACHE INTERNAL "") + if(NOT SDL2_FOUND) + find_package(SDL) + endif() +diff --git a/build/cmake/wxWidgetsConfig.cmake.in b/build/cmake/wxWidgetsConfig.cmake.in +index 60cf762..202a8c3 100644 +--- a/build/cmake/wxWidgetsConfig.cmake.in ++++ b/build/cmake/wxWidgetsConfig.cmake.in +@@ -2,6 +2,9 @@ + + include(CMakeFindDependencyMacro) + find_dependency(NanoSVG CONFIG) ++if("@wxUSE_LIBSDL@") ++ find_dependency(SDL2 CONFIG) ++endif() + + cmake_policy(PUSH) + # Set policies to prevent warnings diff --git a/dependencies/vcpkg_overlay_ports/wxwidgets/setup.h.in b/dependencies/vcpkg_overlay_ports/wxwidgets/setup.h.in new file mode 100644 index 00000000..b927735b --- /dev/null +++ b/dependencies/vcpkg_overlay_ports/wxwidgets/setup.h.in @@ -0,0 +1,5 @@ +#ifdef _DEBUG +#include "../../debug/lib/@WX_SETUP_H_DBG_RELATIVE@/setup.h" +#else +#include "../../lib/@WX_SETUP_H_REL_RELATIVE@/setup.h" +#endif diff --git a/dependencies/vcpkg_overlay_ports/wxwidgets/usage b/dependencies/vcpkg_overlay_ports/wxwidgets/usage new file mode 100644 index 00000000..bf1043e8 --- /dev/null +++ b/dependencies/vcpkg_overlay_ports/wxwidgets/usage @@ -0,0 +1,4 @@ +The package wxwidgets provides CMake targets: + + find_package(wxWidgets CONFIG REQUIRED) + target_link_libraries(main PRIVATE wx::core wx::base) diff --git a/dependencies/vcpkg_overlay_ports/wxwidgets/vcpkg-cmake-wrapper.cmake b/dependencies/vcpkg_overlay_ports/wxwidgets/vcpkg-cmake-wrapper.cmake new file mode 100644 index 00000000..635b509b --- /dev/null +++ b/dependencies/vcpkg_overlay_ports/wxwidgets/vcpkg-cmake-wrapper.cmake @@ -0,0 +1,87 @@ +cmake_policy(PUSH) +cmake_policy(SET CMP0012 NEW) +cmake_policy(SET CMP0054 NEW) +cmake_policy(SET CMP0057 NEW) + +get_filename_component(_vcpkg_wx_root "${CMAKE_CURRENT_LIST_DIR}/../.." ABSOLUTE) +set(wxWidgets_ROOT_DIR "${_vcpkg_wx_root}" CACHE INTERNAL "") +set(WX_ROOT_DIR "${_vcpkg_wx_root}" CACHE INTERNAL "") +unset(_vcpkg_wx_root) + +if(WIN32) + # Find all libs with "32" infix which is unknown to FindwxWidgets.cmake + function(z_vcpkg_wxwidgets_find_base_library BASENAME) + find_library(WX_${BASENAME}d wx${BASENAME}33ud NAMES wx${BASENAME}d PATHS "${wxWidgets_ROOT_DIR}/debug/lib" NO_DEFAULT_PATH) + find_library(WX_${BASENAME} wx${BASENAME}33u NAMES wx${BASENAME} PATHS "${wxWidgets_ROOT_DIR}/lib" NO_DEFAULT_PATH REQUIRED) + endfunction() + function(z_vcpkg_wxwidgets_find_suffix_library BASENAME) + foreach(lib IN LISTS ARGN) + find_library(WX_${lib}d NAMES wx${BASENAME}33ud_${lib} PATHS "${wxWidgets_ROOT_DIR}/debug/lib" NO_DEFAULT_PATH) + find_library(WX_${lib} NAMES wx${BASENAME}33u_${lib} PATHS "${wxWidgets_ROOT_DIR}/lib" NO_DEFAULT_PATH) + endforeach() + endfunction() + z_vcpkg_wxwidgets_find_base_library(base) + z_vcpkg_wxwidgets_find_suffix_library(base net odbc xml) + z_vcpkg_wxwidgets_find_suffix_library(msw core adv aui html media xrc dbgrid gl qa richtext stc ribbon propgrid webview) + if(WX_stc AND "@VCPKG_LIBRARY_LINKAGE@" STREQUAL "static") + z_vcpkg_wxwidgets_find_base_library(scintilla) + endif() + # Force FindwxWidgets.cmake win32 mode for all windows targets built on windows + set(_vcpkg_wxwidgets_backup_crosscompiling "${CMAKE_CROSSCOMPILING}") + set(CMAKE_CROSSCOMPILING 0) + set(wxWidgets_LIB_DIR "${wxWidgets_ROOT_DIR}/lib" CACHE INTERNAL "") +else() + # FindwxWidgets.cmake unix mode, single-config + set(_vcpkg_wxconfig "") + if(CMAKE_BUILD_TYPE STREQUAL "Debug" OR "Debug" IN_LIST MAP_IMPORTED_CONFIG_${CMAKE_BUILD_TYPE}) + # Debug + set(wxWidgets_LIB_DIR "${wxWidgets_ROOT_DIR}/debug/lib" CACHE INTERNAL "") + file(GLOB _vcpkg_wxconfig LIST_DIRECTORIES false "${wxWidgets_LIB_DIR}/wx/config/*") + endif() + if(NOT _vcpkg_wxconfig) + # Release or fallback + set(wxWidgets_LIB_DIR "${wxWidgets_ROOT_DIR}/lib" CACHE INTERNAL "") + file(GLOB _vcpkg_wxconfig LIST_DIRECTORIES false "${wxWidgets_LIB_DIR}/wx/config/*") + endif() + set(wxWidgets_CONFIG_EXECUTABLE "${_vcpkg_wxconfig}" CACHE INTERNAL "") + unset(_vcpkg_wxconfig) +endif() +set(WX_LIB_DIR "${wxWidgets_LIB_DIR}" CACHE INTERNAL "") + +# https://gitlab.kitware.com/cmake/cmake/-/issues/26718 +# Instead of special-casing the `atomic` library, we skip the checks entirely. +set(_wx_lib_found TRUE) + +_find_package(${ARGS}) + +unset(_wx_lib_found) + +if(DEFINED _vcpkg_wxwidgets_backup_crosscompiling) + set(CMAKE_CROSSCOMPILING "${_vcpkg_wxwidgets_backup_crosscompiling}") + unset(_vcpkg_wxwidgets_backup_crosscompiling) +endif() + +if("@VCPKG_LIBRARY_LINKAGE@" STREQUAL "static" AND NOT "wx::core" IN_LIST wxWidgets_LIBRARIES) + find_package(NanoSVG CONFIG QUIET) + list(APPEND wxWidgets_LIBRARIES + NanoSVG::nanosvg NanoSVG::nanosvgrast + ) +endif() + + +if(WIN32 AND "@VCPKG_LIBRARY_LINKAGE@" STREQUAL "static" AND NOT "wx::core" IN_LIST wxWidgets_LIBRARIES) + find_package(EXPAT QUIET) + find_package(JPEG QUIET) + find_package(PNG QUIET) + find_package(TIFF QUIET) + find_package(ZLIB QUIET) + list(APPEND wxWidgets_LIBRARIES + ${EXPAT_LIBRARIES} + ${JPEG_LIBRARIES} + ${PNG_LIBRARIES} + ${TIFF_LIBRARIES} + ${ZLIB_LIBRARIES} + ) +endif() + +cmake_policy(POP) diff --git a/dependencies/vcpkg_overlay_ports/wxwidgets/vcpkg.json b/dependencies/vcpkg_overlay_ports/wxwidgets/vcpkg.json new file mode 100644 index 00000000..132f4fe3 --- /dev/null +++ b/dependencies/vcpkg_overlay_ports/wxwidgets/vcpkg.json @@ -0,0 +1,109 @@ +{ + "name": "wxwidgets", + "version": "3.3.1", + "description": [ + "Widget toolkit and tools library for creating graphical user interfaces (GUIs) for cross-platform applications. ", + "Set WXWIDGETS_USE_STL in a custom triplet to build with the wxUSE_STL build option.", + "Set WXWIDGETS_USE_STD_CONTAINERS in a custom triplet to build with the wxUSE_STD_CONTAINERS build option." + ], + "homepage": "https://github.com/wxWidgets/wxWidgets", + "license": "LGPL-2.0-or-later WITH WxWindows-exception-3.1", + "supports": "!uwp & !xbox", + "dependencies": [ + { + "name": "cairo", + "default-features": false, + "platform": "!windows & !osx & !ios" + }, + { + "name": "curl", + "default-features": false, + "platform": "!windows & !osx" + }, + "expat", + { + "name": "gtk3", + "platform": "!windows & !osx & !ios" + }, + { + "name": "libiconv", + "platform": "!windows" + }, + "libjpeg-turbo", + "libpng", + "libwebp", + "nanosvg", + "opengl", + { + "name": "pcre2", + "default-features": false + }, + { + "name": "tiff", + "default-features": false + }, + { + "name": "vcpkg-cmake", + "host": true + }, + { + "name": "vcpkg-cmake-config", + "host": true + }, + "zlib" + ], + "default-features": [ + "debug-support", + "sound" + ], + "features": { + "debug-support": { + "description": "Enable wxWidgets debugging support hooks even for release builds (wxDEBUG_LEVEL 1)" + }, + "example": { + "description": "Example source code and CMake project" + }, + "fonts": { + "description": "Enable to use the font functionality of wxWidgets", + "dependencies": [ + { + "name": "fontconfig", + "platform": "!windows & !osx" + }, + { + "name": "pango", + "platform": "!windows & !osx" + } + ] + }, + "media": { + "description": "Build wxMediaCtrl support", + "dependencies": [ + { + "name": "gstreamer", + "default-features": false, + "platform": "!windows & !osx & !ios" + } + ] + }, + "secretstore": { + "description": "Use wxSecretStore class" + }, + "sound": { + "description": "Build wxSound support", + "dependencies": [ + { + "name": "sdl2", + "default-features": false, + "platform": "!windows & !osx & !ios" + } + ] + }, + "webview": { + "description": "The Edge backend uses Microsoft's Edge WebView2", + "dependencies": [ + "webview2" + ] + } + } +} diff --git a/dependencies/discord-rpc/examples/unrealstatus/Config/DefaultEditor.ini b/dependencies/vcpkg_overlay_ports_win/.gitkeep similarity index 100% rename from dependencies/discord-rpc/examples/unrealstatus/Config/DefaultEditor.ini rename to dependencies/vcpkg_overlay_ports_win/.gitkeep diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8a820865..f3e2e631 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -165,3 +165,7 @@ if(UNIX AND NOT APPLE) # most likely not helpful in debugging problems with cemu code target_link_options(CemuBin PRIVATE "$<$:-Xlinker;--strip-debug>") endif() + +if (BSD) + target_link_libraries(CemuBin PRIVATE execinfo SPIRV-Tools SPIRV-Tools-opt) +endif() diff --git a/src/Cafe/CafeSystem.cpp b/src/Cafe/CafeSystem.cpp index 9e27c22d..532d3383 100644 --- a/src/Cafe/CafeSystem.cpp +++ b/src/Cafe/CafeSystem.cpp @@ -69,7 +69,7 @@ #if BOOST_OS_LINUX #include -#elif BOOST_OS_MACOS +#elif BOOST_OS_MACOS || BOOST_OS_BSD #include #include #endif @@ -491,6 +491,12 @@ namespace CafeSystem int64_t totalRam; size_t size = sizeof(totalRam); int result = sysctlbyname("hw.memsize", &totalRam, &size, NULL, 0); + if (result == 0) + cemuLog_log(LogType::Force, "RAM: {}MB", (totalRam / 1024LL / 1024LL)); + #elif BOOST_OS_BSD + int64_t totalRam; + size_t size = sizeof(totalRam); + int result = sysctlbyname("hw.physmem", &totalRam, &size, NULL, 0); if (result == 0) cemuLog_log(LogType::Force, "RAM: {}MB", (totalRam / 1024LL / 1024LL)); #endif @@ -544,6 +550,16 @@ namespace CafeSystem platform = "Linux"; #elif BOOST_OS_MACOS platform = "MacOS"; + #elif BOOST_OS_BSD + #if defined(__FreeBSD__) + platform = "FreeBSD"; + #elif defined(__OpenBSD__) + platform = "OpenBSD"; + #elif defined(__NetBSD__) + platform = "NetBSD"; + #else + platform = "Unknown BSD"; + #endif #endif cemuLog_log(LogType::Force, "Platform: {}", platform); } diff --git a/src/Cafe/GameProfile/GameProfile.cpp b/src/Cafe/GameProfile/GameProfile.cpp index ea303226..286f3411 100644 --- a/src/Cafe/GameProfile/GameProfile.cpp +++ b/src/Cafe/GameProfile/GameProfile.cpp @@ -106,7 +106,7 @@ bool gameProfile_loadIntegerOption(IniParser* iniParser, const char* optionName, template bool gameProfile_loadIntegerOption(IniParser& iniParser, const char* optionName, T& option, T minVal, T maxVal) { - static_assert(std::is_integral::value); + static_assert(std::is_integral_v); auto option_value = iniParser.FindOption(optionName); if (!option_value) return false; @@ -133,7 +133,7 @@ bool gameProfile_loadIntegerOption(IniParser& iniParser, const char* optionName, template bool gameProfile_loadEnumOption(IniParser& iniParser, const char* optionName, T& option) { - static_assert(std::is_enum::value); + static_assert(std::is_enum_v); auto option_value = iniParser.FindOption(optionName); if (!option_value) return false; @@ -366,4 +366,4 @@ void GameProfile::Reset() // controller settings for (auto& profile : m_controllerProfile) profile.reset(); -} \ No newline at end of file +} diff --git a/src/Cafe/GraphicPack/GraphicPack2.cpp b/src/Cafe/GraphicPack/GraphicPack2.cpp index ab4dbd3a..98149c93 100644 --- a/src/Cafe/GraphicPack/GraphicPack2.cpp +++ b/src/Cafe/GraphicPack/GraphicPack2.cpp @@ -11,6 +11,8 @@ #include "util/IniParser/IniParser.h" #include "util/helpers/StringHelpers.h" #include "Cafe/CafeSystem.h" +#include "HW/Espresso/Debugger/Debugger.h" + #include std::vector GraphicPack2::s_graphic_packs; @@ -130,6 +132,7 @@ bool GraphicPack2::ActivateGraphicPack(const std::shared_ptr& grap if (graphic_pack->Activate()) { s_active_graphic_packs.push_back(graphic_pack); + g_debuggerDispatcher.NotifyGraphicPacksModified(); return true; } @@ -153,6 +156,7 @@ bool GraphicPack2::DeactivateGraphicPack(const std::shared_ptr& gr graphic_pack->Deactivate(); s_active_graphic_packs.erase(it); + g_debuggerDispatcher.NotifyGraphicPacksModified(); return true; } diff --git a/src/Cafe/HW/Espresso/Debugger/Debugger.h b/src/Cafe/HW/Espresso/Debugger/Debugger.h index eac26658..c16e4173 100644 --- a/src/Cafe/HW/Espresso/Debugger/Debugger.h +++ b/src/Cafe/HW/Espresso/Debugger/Debugger.h @@ -24,6 +24,7 @@ class DebuggerCallbacks virtual void MoveIP() {} virtual void NotifyModuleLoaded(void* module) {} virtual void NotifyModuleUnloaded(void* module) {} + virtual void NotifyGraphicPacksModified() {} virtual ~DebuggerCallbacks() = default; }; @@ -77,6 +78,11 @@ class DebuggerDispatcher { m_callbacks->NotifyModuleUnloaded(module); } + + void NotifyGraphicPacksModified() + { + m_callbacks->NotifyGraphicPacksModified(); + } } extern g_debuggerDispatcher; struct DebuggerBreakpoint diff --git a/src/Cafe/HW/Espresso/Recompiler/IML/IMLRegisterAllocatorRanges.cpp b/src/Cafe/HW/Espresso/Recompiler/IML/IMLRegisterAllocatorRanges.cpp index 583d5905..fc037537 100644 --- a/src/Cafe/HW/Espresso/Recompiler/IML/IMLRegisterAllocatorRanges.cpp +++ b/src/Cafe/HW/Espresso/Recompiler/IML/IMLRegisterAllocatorRanges.cpp @@ -276,7 +276,7 @@ void IMLRA_DeleteAllRanges(ppcImlGenContext_t* ppcImlGenContext) for(auto& seg : ppcImlGenContext->segmentList2) { raLivenessRange* cur; - while(cur = seg->raInfo.linkedList_allSubranges) + while ((cur = seg->raInfo.linkedList_allSubranges)) IMLRA_DeleteRange(ppcImlGenContext, cur); seg->raInfo.linkedList_allSubranges = nullptr; seg->raInfo.linkedList_perVirtualRegister.clear(); @@ -632,4 +632,4 @@ sint32 IMLRA_CalculateAdditionalCostAfterSplit(raLivenessRange* subrange, raInst cost = newCost - baseCost; return cost; -} \ No newline at end of file +} diff --git a/src/Cafe/HW/Latte/Core/LatteBufferCache.cpp b/src/Cafe/HW/Latte/Core/LatteBufferCache.cpp index 716312a3..0395771e 100644 --- a/src/Cafe/HW/Latte/Core/LatteBufferCache.cpp +++ b/src/Cafe/HW/Latte/Core/LatteBufferCache.cpp @@ -25,7 +25,7 @@ class IntervalTree2 // static TNodeObject* Split(TNodeObject* nodeObject, TRangeData firstRangeBegin, TRangeData firstRangeEnd, TRangeData secondRangeBegin, TRangeData secondRangeEnd) // Cut a hole into an existing range and split it in two. Should return the newly created node object after the hole - static_assert(std::is_pointer::value == false, "TNodeObject must be a non-pointer type"); + static_assert(!std::is_pointer_v, "TNodeObject must be a non-pointer type"); struct InternalRange { diff --git a/src/Cafe/HW/Latte/LatteAddrLib/LatteAddrLib_Coord.cpp b/src/Cafe/HW/Latte/LatteAddrLib/LatteAddrLib_Coord.cpp index bc43202a..26da5ec1 100644 --- a/src/Cafe/HW/Latte/LatteAddrLib/LatteAddrLib_Coord.cpp +++ b/src/Cafe/HW/Latte/LatteAddrLib/LatteAddrLib_Coord.cpp @@ -7,7 +7,7 @@ using namespace Latte; namespace LatteAddrLib { -#if BOOST_OS_LINUX || BOOST_OS_MACOS +#if BOOST_OS_LINUX || BOOST_OS_MACOS || BOOST_OS_BSD unsigned char _BitScanReverse(uint32* _Index, uint32 _Mask) { if (!_Mask) @@ -402,4 +402,4 @@ namespace LatteAddrLib return finalMacroTileOffset | pipeOffset | bankOffset; } -}; \ No newline at end of file +}; diff --git a/src/Cafe/HW/Latte/Renderer/OpenGL/OpenGLRenderer.cpp b/src/Cafe/HW/Latte/Renderer/OpenGL/OpenGLRenderer.cpp index e2ec3731..dbcab6f9 100644 --- a/src/Cafe/HW/Latte/Renderer/OpenGL/OpenGLRenderer.cpp +++ b/src/Cafe/HW/Latte/Renderer/OpenGL/OpenGLRenderer.cpp @@ -246,7 +246,7 @@ void LoadOpenGLImports() { cemu_assert_unimplemented(); } -#elif BOOST_OS_LINUX +#elif BOOST_OS_LINUX || BOOST_OS_BSD GL_IMPORT _GetOpenGLFunction(void* hLib, PFNGLXGETPROCADDRESSPROC func, const char* name) { GL_IMPORT r = (GL_IMPORT)func((const GLubyte*)name); @@ -281,7 +281,7 @@ void LoadOpenGLImports() #undef EGLFUNC } -#if BOOST_OS_LINUX +#if BOOST_OS_LINUX || BOOST_OS_BSD // dummy function for all code that is statically linked with cemu and attempts to use eglSwapInterval // used to suppress wxWidgets calls to eglSwapInterval extern "C" diff --git a/src/Cafe/HW/Latte/Renderer/Vulkan/RendererShaderVk.cpp b/src/Cafe/HW/Latte/Renderer/Vulkan/RendererShaderVk.cpp index 8a66c81b..665a5da3 100644 --- a/src/Cafe/HW/Latte/Renderer/Vulkan/RendererShaderVk.cpp +++ b/src/Cafe/HW/Latte/Renderer/Vulkan/RendererShaderVk.cpp @@ -8,7 +8,7 @@ #include #include -#include +#include "util/helpers/helpers.h" bool s_isLoadingShadersVk{ false }; class FileCache* s_spirvCache{nullptr}; diff --git a/src/Cafe/HW/Latte/Renderer/Vulkan/VsyncDriver.cpp b/src/Cafe/HW/Latte/Renderer/Vulkan/VsyncDriver.cpp index 74547a03..64cbbb6b 100644 --- a/src/Cafe/HW/Latte/Renderer/Vulkan/VsyncDriver.cpp +++ b/src/Cafe/HW/Latte/Renderer/Vulkan/VsyncDriver.cpp @@ -80,7 +80,7 @@ private: D3DKMT_OPENADAPTERFROMHDC OpenAdapterData; - *phAdapter = NULL; + *phAdapter = 0; *pOutput = 0; HMONITOR hMonitor = MonitorFromWindow(hWnd, MONITOR_DEFAULTTONEAREST); diff --git a/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanAPI.cpp b/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanAPI.cpp index a3df6296..30282e68 100644 --- a/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanAPI.cpp +++ b/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanAPI.cpp @@ -3,7 +3,7 @@ #include "Cafe/HW/Latte/Renderer/Vulkan/VulkanAPI.h" #include // for std::iota -#if BOOST_OS_LINUX || BOOST_OS_MACOS +#if BOOST_OS_LINUX || BOOST_OS_MACOS || BOOST_OS_BSD #include #endif @@ -215,7 +215,7 @@ void* load_custom_driver() void* dlopen_vulkan_loader() { -#if BOOST_OS_LINUX +#if BOOST_OS_LINUX || BOOST_OS_BSD static void* vulkan_so = nullptr; #if __ANDROID__ && defined(__aarch64__) vulkan_so = load_custom_driver(); diff --git a/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanAPI.h b/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanAPI.h index 3977b69e..4b643b8f 100644 --- a/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanAPI.h +++ b/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanAPI.h @@ -135,17 +135,16 @@ VKFUNC_DEVICE(vkDestroyPipeline); VKFUNC_DEVICE(vkCmdBindPipeline); // swapchain -#if BOOST_OS_LINUX #if __ANDROID__ VKFUNC_INSTANCE(vkCreateAndroidSurfaceKHR); -#else +#elif BOOST_OS_LINUX || BOOST_OS_BSD VKFUNC_INSTANCE(vkCreateXlibSurfaceKHR); VKFUNC_INSTANCE(vkCreateXcbSurfaceKHR); #ifdef HAS_WAYLAND VKFUNC_INSTANCE(vkCreateWaylandSurfaceKHR); #endif // HAS_WAYLAND +#endif // BOOST_OS_LINUX || BOOST_OS_BSD #endif // __ANDROID__ -#endif // BOOST_OS_LINUX #if BOOST_OS_WINDOWS VKFUNC_INSTANCE(vkCreateWin32SurfaceKHR); diff --git a/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.cpp b/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.cpp index 9c01251d..303dba56 100644 --- a/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.cpp +++ b/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.cpp @@ -112,10 +112,9 @@ std::vector VulkanRenderer::GetDevices() requiredExtensions.emplace_back(VK_KHR_SURFACE_EXTENSION_NAME); #if BOOST_OS_WINDOWS requiredExtensions.emplace_back(VK_KHR_WIN32_SURFACE_EXTENSION_NAME); - #elif BOOST_OS_LINUX - #if __ANDROID__ + #elif __ANDROID__ requiredExtensions.emplace_back(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME); - #else + #elif BOOST_OS_LINUX || BOOST_OS_BSD auto backend = WindowSystem::GetWindowInfo().window_main.backend; if(backend == WindowSystem::WindowHandleInfo::Backend::X11) requiredExtensions.emplace_back(VK_KHR_XLIB_SURFACE_EXTENSION_NAME); @@ -123,7 +122,6 @@ std::vector VulkanRenderer::GetDevices() else if (backend == WindowSystem::WindowHandleInfo::Backend::Wayland) requiredExtensions.emplace_back(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME); #endif // HAS_WAYLAND - #endif // __ANDROID__ #elif BOOST_OS_MACOS requiredExtensions.emplace_back(VK_EXT_METAL_SURFACE_EXTENSION_NAME); #endif @@ -1331,11 +1329,9 @@ std::vector VulkanRenderer::CheckInstanceExtensionSupport(FeatureCo requiredInstanceExtensions.emplace_back(VK_KHR_SURFACE_EXTENSION_NAME); #if BOOST_OS_WINDOWS requiredInstanceExtensions.emplace_back(VK_KHR_WIN32_SURFACE_EXTENSION_NAME); -<<<<<<< Updated upstream - #elif BOOST_OS_LINUX - #if __ANDROID__ + #elif __ANDROID__ requiredInstanceExtensions.emplace_back(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME); - #else + #elif BOOST_OS_LINUX || BOOST_OS_BSD auto backend = WindowSystem::GetWindowInfo().window_main.backend; if(backend == WindowSystem::WindowHandleInfo::Backend::X11) requiredInstanceExtensions.emplace_back(VK_KHR_XLIB_SURFACE_EXTENSION_NAME); @@ -1343,7 +1339,6 @@ std::vector VulkanRenderer::CheckInstanceExtensionSupport(FeatureCo else if (backend == WindowSystem::WindowHandleInfo::Backend::Wayland) requiredInstanceExtensions.emplace_back(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME); #endif // HAS_WAYLAND - #endif // __ANDROID__ #elif BOOST_OS_MACOS requiredInstanceExtensions.emplace_back(VK_EXT_METAL_SURFACE_EXTENSION_NAME); #endif @@ -1423,7 +1418,6 @@ VkSurfaceKHR VulkanRenderer::CreateWinSurface(VkInstance instance, HWND hwindow) } #endif -#if BOOST_OS_LINUX #if __ANDROID__ VkSurfaceKHR VulkanRenderer::CreateAndroidSurface(VkInstance instance, ANativeWindow* window) { @@ -1442,7 +1436,7 @@ VkSurfaceKHR VulkanRenderer::CreateAndroidSurface(VkInstance instance, ANativeWi return result; } -#else +#elif BOOST_OS_LINUX || BOOST_OS_BSD VkSurfaceKHR VulkanRenderer::CreateXlibSurface(VkInstance instance, Display* dpy, Window window) { VkXlibSurfaceCreateInfoKHR sci{}; @@ -1499,18 +1493,17 @@ VkSurfaceKHR VulkanRenderer::CreateWaylandSurface(VkInstance instance, wl_displa return result; } -#endif // HAS_WAYLAND -#endif // __ANDROID__ -#endif // BOOST_OS_LINUX +#endif +#endif +#endif VkSurfaceKHR VulkanRenderer::CreateFramebufferSurface(VkInstance instance, WindowSystem::WindowHandleInfo& windowInfo) { #if BOOST_OS_WINDOWS return CreateWinSurface(instance, static_cast(windowInfo.surface)); -#elif BOOST_OS_LINUX -#if __ANDROID__ +#elif __ANDROID__ return CreateAndroidSurface(instance, static_cast(windowInfo.surface)); -#else +#elif BOOST_OS_LINUX || BOOST_OS_BSD if(windowInfo.backend == WindowSystem::WindowHandleInfo::Backend::X11) return CreateXlibSurface(instance, static_cast(windowInfo.display), reinterpret_cast(windowInfo.surface)); #ifdef HAS_WAYLAND @@ -1518,7 +1511,6 @@ VkSurfaceKHR VulkanRenderer::CreateFramebufferSurface(VkInstance instance, Windo return CreateWaylandSurface(instance, static_cast(windowInfo.display), static_cast(windowInfo.surface)); #endif return {}; -#endif // __ANDROID__ #elif BOOST_OS_MACOS return CreateCocoaSurface(instance, windowInfo.surface); #endif diff --git a/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.h b/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.h index 63124b5f..bc65651c 100644 --- a/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.h +++ b/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.h @@ -206,17 +206,15 @@ public: #if BOOST_OS_WINDOWS static VkSurfaceKHR CreateWinSurface(VkInstance instance, HWND hwindow); #endif -#if BOOST_OS_LINUX #if __ANDROID__ static VkSurfaceKHR CreateAndroidSurface(VkInstance instance, ANativeWindow* window); -#else +#elif BOOST_OS_LINUX || BOOST_OS_BSD static VkSurfaceKHR CreateXlibSurface(VkInstance instance, Display* dpy, Window window); static VkSurfaceKHR CreateXcbSurface(VkInstance instance, xcb_connection_t* connection, xcb_window_t window); #ifdef HAS_WAYLAND static VkSurfaceKHR CreateWaylandSurface(VkInstance instance, wl_display* display, wl_surface* surface); #endif // HAS_WAYLAND -#endif // __ANDROID__ -#endif // BOOST_OS_LINUX +#endif static VkSurfaceKHR CreateFramebufferSurface(VkInstance instance, struct WindowSystem::WindowHandleInfo& windowInfo); diff --git a/src/Cafe/HW/MMU/MMU.h b/src/Cafe/HW/MMU/MMU.h index a8367f88..6e3bee70 100644 --- a/src/Cafe/HW/MMU/MMU.h +++ b/src/Cafe/HW/MMU/MMU.h @@ -184,6 +184,16 @@ bool memory_isAddressRangeAccessible(MPTR virtualAddress, uint32 size); #define CPU_swapEndianU64(_v) OSSwapInt64((uint64)(_v)) #define CPU_swapEndianU32(_v) OSSwapInt32((uint32)(_v)) #define CPU_swapEndianU16(_v) OSSwapInt16((uint16)(_v)) +#elif BOOST_OS_BSD +#ifdef __OpenBSD__ +#define CPU_swapEndianU64(_v) swap64((uint64)(_v)) +#define CPU_swapEndianU32(_v) swap32((uint32)(_v)) +#define CPU_swapEndianU16(_v) swap16((uint16)(_v)) +#else // FreeBSD and NetBSD +#define CPU_swapEndianU64(_v) bswap64((uint64)(_v)) +#define CPU_swapEndianU32(_v) bswap32((uint32)(_v)) +#define CPU_swapEndianU16(_v) bswap16((uint16)(_v)) +#endif #endif // C-style memory access, deprecated. Use memory_read<> and memory_write<> templates instead @@ -266,4 +276,4 @@ namespace MMU } -#define MMU_IsInPPCMemorySpace(__ptr) ((const uint8*)(__ptr) >= memory_base && (const uint8*)(__ptr) < (memory_base + 0x100000000)) \ No newline at end of file +#define MMU_IsInPPCMemorySpace(__ptr) ((const uint8*)(__ptr) >= memory_base && (const uint8*)(__ptr) < (memory_base + 0x100000000)) diff --git a/src/Cafe/OS/common/OSUtil.h b/src/Cafe/OS/common/OSUtil.h index 84e38a6c..31784882 100644 --- a/src/Cafe/OS/common/OSUtil.h +++ b/src/Cafe/OS/common/OSUtil.h @@ -176,14 +176,14 @@ void cafeExportCallWrapper(PPCInterpreter_t* hCPU) if(cemuLog_advancedPPCLoggingEnabled()) { MPTR threadMPTR = memory_getVirtualOffsetFromPointer(coreinit::OSGetCurrentThread()); - if constexpr (std::tuple_size::value > 0) + if constexpr (std::tuple_size_v > 0) shouldLog = cemuLog_log(TLogType, "{}.{}{} # LR: {:#x} | Thread: {:#x}", TNames::GetLib(), TNames::GetFunc(), format_tup, hCPU->spr.LR, threadMPTR); else shouldLog = cemuLog_log(TLogType, "{}.{}() # LR: {:#x} | Thread: {:#x}", TNames::GetLib(), TNames::GetFunc(), hCPU->spr.LR, threadMPTR); } else { - if constexpr (std::tuple_size::value > 0) + if constexpr (std::tuple_size_v > 0) { shouldLog = cemuLog_log(TLogType, "{}.{}{}", TNames::GetLib(), TNames::GetFunc(), format_tup); } @@ -192,7 +192,7 @@ void cafeExportCallWrapper(PPCInterpreter_t* hCPU) } } - if constexpr (!std::is_void::value) + if constexpr (!std::is_void_v) { // has non-void return type decltype(auto) result = std::apply(fn, tup); @@ -241,4 +241,4 @@ MPTR makeCallableExport() return PPCInterpreter_makeCallableExportDepr(&cafeExportCallWrapper); } -void osLib_addVirtualPointer(const char* libraryName, const char* functionName, uint32 vPtr); \ No newline at end of file +void osLib_addVirtualPointer(const char* libraryName, const char* functionName, uint32 vPtr); diff --git a/src/Cafe/OS/libs/coreinit/coreinit_MCP.cpp b/src/Cafe/OS/libs/coreinit/coreinit_MCP.cpp index 330663ac..95f3c6db 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_MCP.cpp +++ b/src/Cafe/OS/libs/coreinit/coreinit_MCP.cpp @@ -466,7 +466,7 @@ typedef struct static_assert(sizeof(UCParamStruct_t) == 0x54); // unsure -#if BOOST_OS_LINUX || BOOST_OS_MACOS +#if BOOST_OS_LINUX || BOOST_OS_MACOS || BOOST_OS_BSD #define _strcmpi strcasecmp #endif diff --git a/src/Cafe/OS/libs/gx2/GX2_Command.h b/src/Cafe/OS/libs/gx2/GX2_Command.h index 00f5d427..a27b2a02 100644 --- a/src/Cafe/OS/libs/gx2/GX2_Command.h +++ b/src/Cafe/OS/libs/gx2/GX2_Command.h @@ -39,9 +39,9 @@ inline void gx2WriteGather_submit_(uint32 coreIndex, uint32be* writePtr, const b } template + requires std::is_floating_point_v inline -typename std::enable_if< std::is_floating_point::value, void>::type -gx2WriteGather_submit_(uint32 coreIndex, uint32be* writePtr, const T& arg, Targs... args) +void gx2WriteGather_submit_(uint32 coreIndex, uint32be* writePtr, const T& arg, Targs... args) { static_assert(sizeof(T) == sizeof(uint32)); *writePtr = *(uint32*)&arg; @@ -50,9 +50,9 @@ gx2WriteGather_submit_(uint32 coreIndex, uint32be* writePtr, const T& arg, Targs } template + requires std::is_base_of_v inline -typename std::enable_if< std::is_base_of::value, void>::type -gx2WriteGather_submit_(uint32 coreIndex, uint32be* writePtr, const T& arg, Targs... args) +void gx2WriteGather_submit_(uint32 coreIndex, uint32be* writePtr, const T& arg, Targs... args) { static_assert(sizeof(Latte::LATTEREG) == sizeof(uint32be)); *writePtr = arg.getRawValue(); @@ -61,9 +61,9 @@ gx2WriteGather_submit_(uint32 coreIndex, uint32be* writePtr, const T& arg, Targs } template + requires (!std::is_base_of_v) && (!std::is_floating_point_v) inline -typename std::enable_if< !std::is_base_of::value && !std::is_floating_point::value, void>::type -gx2WriteGather_submit_(uint32 coreIndex, uint32be* writePtr, const T& arg, Targs... args) +void gx2WriteGather_submit_(uint32 coreIndex, uint32be* writePtr, const T& arg, Targs... args) { *writePtr = arg; writePtr++; @@ -105,4 +105,4 @@ namespace GX2 void GX2Init_commandBufferPool(void* bufferBase, uint32 bufferSize); void GX2Shutdown_commandBufferPool(); void GX2CommandResetToDefaultState(); -} \ No newline at end of file +} diff --git a/src/Cafe/OS/libs/nn_olv/nn_olv_InitializeTypes.cpp b/src/Cafe/OS/libs/nn_olv/nn_olv_InitializeTypes.cpp index ba657ff7..8f7a7e03 100644 --- a/src/Cafe/OS/libs/nn_olv/nn_olv_InitializeTypes.cpp +++ b/src/Cafe/OS/libs/nn_olv/nn_olv_InitializeTypes.cpp @@ -1,5 +1,3 @@ -#pragma once - #include "nn_olv_InitializeTypes.h" #include "CafeSystem.h" #include "Cafe/OS/libs/nn_act/nn_act.h" diff --git a/src/Cafe/OS/libs/nn_olv/nn_olv_UploadCommunityTypes.cpp b/src/Cafe/OS/libs/nn_olv/nn_olv_UploadCommunityTypes.cpp index 21952ceb..a2ab461f 100644 --- a/src/Cafe/OS/libs/nn_olv/nn_olv_UploadCommunityTypes.cpp +++ b/src/Cafe/OS/libs/nn_olv/nn_olv_UploadCommunityTypes.cpp @@ -38,12 +38,12 @@ namespace nn if (!pParam->communityId) return OLV_RESULT_INVALID_PARAMETER; - snprintf(requestUrl, sizeof(requestUrl), "%s/v1/communities/%lu.delete", g_DiscoveryResults.apiEndpoint, pParam->communityId.value()); + snprintf(requestUrl, sizeof(requestUrl), "%s/v1/communities/%u.delete", g_DiscoveryResults.apiEndpoint, pParam->communityId.value()); } else { if (pParam->communityId) - snprintf(requestUrl, sizeof(requestUrl), "%s/v1/communities/%lu", g_DiscoveryResults.apiEndpoint, pParam->communityId.value()); + snprintf(requestUrl, sizeof(requestUrl), "%s/v1/communities/%u", g_DiscoveryResults.apiEndpoint, pParam->communityId.value()); else snprintf(requestUrl, sizeof(requestUrl), "%s/v1/communities", g_DiscoveryResults.apiEndpoint); } diff --git a/src/Cafe/OS/libs/nn_olv/nn_olv_UploadFavoriteTypes.cpp b/src/Cafe/OS/libs/nn_olv/nn_olv_UploadFavoriteTypes.cpp index 912e7a11..f3878188 100644 --- a/src/Cafe/OS/libs/nn_olv/nn_olv_UploadFavoriteTypes.cpp +++ b/src/Cafe/OS/libs/nn_olv/nn_olv_UploadFavoriteTypes.cpp @@ -36,9 +36,9 @@ namespace nn char requestUrl[512]; if (pParam->flags & UploadFavoriteToCommunityDataParam::FLAG_DELETION) - snprintf(requestUrl, sizeof(requestUrl), "%s/v1/communities/%lu.unfavorite", g_DiscoveryResults.apiEndpoint, pParam->communityId.value()); + snprintf(requestUrl, sizeof(requestUrl), "%s/v1/communities/%u.unfavorite", g_DiscoveryResults.apiEndpoint, pParam->communityId.value()); else - snprintf(requestUrl, sizeof(requestUrl), "%s/v1/communities/%lu.favorite", g_DiscoveryResults.apiEndpoint, pParam->communityId.value()); + snprintf(requestUrl, sizeof(requestUrl), "%s/v1/communities/%u.favorite", g_DiscoveryResults.apiEndpoint, pParam->communityId.value()); CurlRequestHelper req; req.initate(ActiveSettings::GetNetworkService(), requestUrl, CurlRequestHelper::SERVER_SSL_CONTEXT::OLIVE); diff --git a/src/Cafe/OS/libs/nsyshid/BackendLibusb.h b/src/Cafe/OS/libs/nsyshid/BackendLibusb.h index 6b2d8e1a..955b3071 100644 --- a/src/Cafe/OS/libs/nsyshid/BackendLibusb.h +++ b/src/Cafe/OS/libs/nsyshid/BackendLibusb.h @@ -1,6 +1,10 @@ #include "nsyshid.h" +#if BOOST_OS_BSD +#include +#else #include +#endif #include "Backend.h" namespace nsyshid::backend::libusb diff --git a/src/Cemu/CMakeLists.txt b/src/Cemu/CMakeLists.txt index 1fce8ec1..cdf71c62 100644 --- a/src/Cemu/CMakeLists.txt +++ b/src/Cemu/CMakeLists.txt @@ -1,6 +1,4 @@ add_library(CemuComponents - DiscordPresence/DiscordPresence.cpp - DiscordPresence/DiscordPresence.h ExpressionParser/ExpressionParser.cpp ExpressionParser/ExpressionParser.h FileCache/FileCache.cpp @@ -32,6 +30,14 @@ add_library(CemuComponents Tools/DownloadManager/DownloadManager.h ) +if(ENABLE_DISCORD_RPC) +target_sources(CemuComponents PRIVATE + DiscordPresence/DiscordPresence.cpp + DiscordPresence/DiscordPresence.h + DiscordPresence/DiscordRPCLite.cpp + DiscordPresence/DiscordRPCLite.h) +endif() + set_property(TARGET CemuComponents PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") target_include_directories(CemuComponents PUBLIC "../") @@ -52,7 +58,3 @@ target_link_libraries(CemuComponents PRIVATE # PUBLIC because fmt/format.h is included in ExpressionParser/ExpressionParser.h target_link_libraries(CemuComponents PUBLIC fmt::fmt) - -if(ENABLE_DISCORD_RPC) - target_link_libraries(CemuComponents PRIVATE discord-rpc) -endif() diff --git a/src/Cemu/DiscordPresence/DiscordPresence.cpp b/src/Cemu/DiscordPresence/DiscordPresence.cpp index a9feeba9..e82199dc 100644 --- a/src/Cemu/DiscordPresence/DiscordPresence.cpp +++ b/src/Cemu/DiscordPresence/DiscordPresence.cpp @@ -1,53 +1,51 @@ #include "DiscordPresence.h" - -#ifdef ENABLE_DISCORD_RPC - -#include #include "Common/version.h" +#include "DiscordRPCLite.h" DiscordPresence::DiscordPresence() { - DiscordEventHandlers handlers{}; - Discord_Initialize("460807638964371468", &handlers, 1, nullptr); + m_rpcClient = new DiscordRPCLite("460807638964371468"); UpdatePresence(Idling); } DiscordPresence::~DiscordPresence() { ClearPresence(); - Discord_Shutdown(); + if (m_rpcClient) + delete m_rpcClient; } void DiscordPresence::UpdatePresence(State state, const std::string& text) const { - DiscordRichPresence discord_presence{}; - - std::string state_string, details_string; + if (!m_rpcClient) + return; + DiscordLiteRichPresence discordPresence{}; + std::string stateString, detailsString; switch (state) { case Idling: - details_string = "Idling"; + detailsString = "Idling"; + stateString = ""; break; case Playing: - details_string = "Ingame"; - state_string = "Playing " + text; + detailsString = "Ingame"; + stateString = "Playing " + text; break; default: assert(false); break; } - - discord_presence.details = details_string.c_str(); - discord_presence.state = state_string.c_str(); - discord_presence.startTimestamp = time(nullptr); - discord_presence.largeImageText = BUILD_VERSION_WITH_NAME_STRING; - discord_presence.largeImageKey = "logo_icon_big_png"; - Discord_UpdatePresence(&discord_presence); + discordPresence.details = detailsString; + discordPresence.state = stateString; + discordPresence.startTimestamp = time(nullptr); + discordPresence.largeImageText = BUILD_VERSION_WITH_NAME_STRING; + discordPresence.largeImageKey = "logo_icon_big_png"; + m_rpcClient->UpdateRichPresence(discordPresence); } void DiscordPresence::ClearPresence() const { - Discord_ClearPresence(); -} - -#endif \ No newline at end of file + if (!m_rpcClient) + return; + m_rpcClient->ClearRichPresence(); +} \ No newline at end of file diff --git a/src/Cemu/DiscordPresence/DiscordPresence.h b/src/Cemu/DiscordPresence/DiscordPresence.h index f2491f4b..33fb9f11 100644 --- a/src/Cemu/DiscordPresence/DiscordPresence.h +++ b/src/Cemu/DiscordPresence/DiscordPresence.h @@ -1,7 +1,5 @@ #pragma once -#ifdef ENABLE_DISCORD_RPC - class DiscordPresence { public: @@ -16,6 +14,7 @@ public: void UpdatePresence(State state, const std::string& text = {}) const; void ClearPresence() const; -}; -#endif +private: + class DiscordRPCLite* m_rpcClient = nullptr; +}; diff --git a/src/Cemu/DiscordPresence/DiscordRPCLite.cpp b/src/Cemu/DiscordPresence/DiscordRPCLite.cpp new file mode 100644 index 00000000..bd04e96f --- /dev/null +++ b/src/Cemu/DiscordPresence/DiscordRPCLite.cpp @@ -0,0 +1,683 @@ +#include "DiscordRPCLite.h" + +#include +#include +#include + +#if defined(__cpp_lib_format) +#include +namespace shim +{ + using std::format; +} +#else +#include +namespace shim +{ + using fmt::format; +} +#endif + +#ifdef _WIN32 +#include +#else +#include +#include +#include +#endif + +enum RPCOpcode : uint32_t +{ + OpcodeHandshake = 0, + OpcodeFrame = 1, + OpcodeClose = 2, + OpcodePing = 3, + OpcodePong = 4, +}; + +#ifdef _WIN32 +class NamedPipeImpl +{ + public: + NamedPipeImpl() + { + m_readEvent = CreateEvent(nullptr, TRUE, FALSE, nullptr); + } + + ~NamedPipeImpl() + { + CloseHandle(m_readEvent); + ClosePipe(); + } + + bool OpenPipe() + { + std::string fullPipeName = R"(\\.\pipe\discord-ipc-0)"; + m_handle = CreateFileA(fullPipeName.c_str(), GENERIC_READ | GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, nullptr); + if (m_handle == INVALID_HANDLE_VALUE) + return false; + return true; + } + + void ClosePipe() + { + if (m_handle != INVALID_HANDLE_VALUE) + { + CloseHandle(m_handle); + m_handle = INVALID_HANDLE_VALUE; + } + } + + bool IsOpen() const + { + return m_handle != INVALID_HANDLE_VALUE; + } + + int Read(uint8_t* buffer, size_t maxSize, int timeoutMs) + { + if (m_handle == INVALID_HANDLE_VALUE || m_readEvent == nullptr) + return -1; + OVERLAPPED overlapped = {0}; + overlapped.hEvent = m_readEvent; + ResetEvent(m_readEvent); + DWORD bytesRead = 0; + BOOL success = ReadFile(m_handle, buffer, static_cast(maxSize), nullptr, &overlapped); + if (!success && GetLastError() == ERROR_IO_PENDING) + { + DWORD waitResult = WaitForSingleObject(m_readEvent, timeoutMs); + if (waitResult == WAIT_TIMEOUT) + { + CancelIo(m_handle); + return 0; + } + else if (waitResult != WAIT_OBJECT_0) // error + { + ClosePipe(); + return -1; + } + if (!GetOverlappedResult(m_handle, &overlapped, &bytesRead, FALSE)) + { + ClosePipe(); + return -1; + } + } + else if (!success) + { + ClosePipe(); + return -1; + } + else + { + GetOverlappedResult(m_handle, &overlapped, &bytesRead, FALSE); // immediate completion + } + return static_cast(bytesRead); + } + + int Write(const uint8_t* buffer, size_t size) + { + if (m_handle == INVALID_HANDLE_VALUE) + { + return -1; + } + DWORD bytesWritten = 0; + if (!WriteFile(m_handle, buffer, static_cast(size), &bytesWritten, nullptr)) + { + ClosePipe(); + return -1; + } + return static_cast(bytesWritten); + } + + private: + HANDLE m_handle = INVALID_HANDLE_VALUE; + HANDLE m_readEvent; +}; + +#else + +class NamedPipeImpl // posix +{ + public: + NamedPipeImpl() {} + ~NamedPipeImpl() + { + ClosePipe(); + } + + bool OpenPipe() + { + const char* tempPath = getenv("XDG_RUNTIME_DIR"); + if (!tempPath) + tempPath = getenv("TMPDIR"); + if (!tempPath) + tempPath = getenv("TMP"); + if (!tempPath) + tempPath = getenv("TEMP"); + if (!tempPath) + tempPath = "/tmp"; + sockaddr_un pipeAddr{}; + pipeAddr.sun_family = AF_UNIX; + m_fd = socket(AF_UNIX, SOCK_STREAM, 0); + if (m_fd == -1) + return false; + fcntl(m_fd, F_SETFL, O_NONBLOCK); +#ifdef SO_NOSIGPIPE + int optval = 1; + setsockopt(m_fd, SOL_SOCKET, SO_NOSIGPIPE, &optval, sizeof(optval)); +#endif + for (int pipeIndex = 0; pipeIndex < 10; pipeIndex++) + { + snprintf(pipeAddr.sun_path, sizeof(pipeAddr.sun_path), "%s/discord-ipc-%d", tempPath, pipeIndex); + int r = connect(m_fd, (const sockaddr*)&pipeAddr, sizeof(pipeAddr)); + if (r == 0) + return true; + } + ClosePipe(); + return false; + } + + void ClosePipe() + { + if (m_fd != -1) + { + close(m_fd); + m_fd = -1; + } + } + + bool IsOpen() const + { + return m_fd != -1; + } + + int Read(uint8_t* buffer, size_t maxSize, int timeoutMs) + { + if (m_fd == -1) + return -1; + if (!buffer || maxSize == 0) + return -1; + struct pollfd pfd; + pfd.fd = m_fd; + pfd.events = POLLIN; + pfd.revents = 0; + int ret = poll(&pfd, 1, timeoutMs); + if (ret < 0) + { + ClosePipe(); + return -1; + } + else if (ret == 0) + { + return 0; + } + else if (pfd.revents & (POLLERR | POLLHUP | POLLNVAL)) + { + ClosePipe(); + return -1; + } +#ifdef MSG_NOSIGNAL + int MsgFlags = MSG_NOSIGNAL; +#else + int MsgFlags = 0; +#endif + int res = (int)recv(m_fd, buffer, maxSize, MsgFlags); + if (res <= 0) + { + ClosePipe(); + return -1; + } + return res; + } + + int Write(const uint8_t* buffer, size_t size) + { + if (m_fd == -1 || !buffer || size == 0) + return -1; +#ifdef MSG_NOSIGNAL + int MsgFlags = MSG_NOSIGNAL; +#else + int MsgFlags = 0; +#endif + int sentBytes = send(m_fd, buffer, size, MsgFlags); + if (sentBytes == -1) + { + ClosePipe(); + return -1; + } + return sentBytes; + } + + private: + int m_fd = -1; +}; + +#endif + +#ifdef _WIN32 +int GetProcessId() +{ + return (int)GetCurrentProcessId(); +} +#else +int GetProcessId() +{ + return getpid(); +} +#endif + +class NamedPipe : public NamedPipeImpl +{ + public: + NamedPipe() + : NamedPipeImpl() {}; + + void SendJsonMsg(uint32_t opcode, std::string_view jsonText) + { + std::vector buffer; + buffer.resize(8 + jsonText.size()); + buffer[0] = (opcode >> 0) & 0xFF; + buffer[1] = (opcode >> 8) & 0xFF; + buffer[2] = (opcode >> 16) & 0xFF; + buffer[3] = (opcode >> 24) & 0xFF; + uint32_t length = static_cast(jsonText.size()); + buffer[4] = (length >> 0) & 0xFF; + buffer[5] = (length >> 8) & 0xFF; + buffer[6] = (length >> 16) & 0xFF; + buffer[7] = (length >> 24) & 0xFF; + std::copy(jsonText.begin(), jsonText.end(), buffer.begin() + 8); + Write(buffer.data(), buffer.size()); + } + + void SendPresenceUpdate(const DiscordLiteRichPresence& presence) + { + // note: According to older documentation SET_ACTIVITY has a rate limit of 15 seconds + std::string jsonPayload; + jsonPayload.append("{"); + jsonPayload.append(R"("cmd": "SET_ACTIVITY")"); + jsonPayload.append(shim::format(R"(,"nonce": "{}")", GetNonceStr())); + jsonPayload.append(R"(,"args": {)"); + // args + std::string pidStr = shim::format("{}", GetProcessId()); + jsonPayload.append(R"("pid": )").append(pidStr).append(R"(,)"); + // args->activity + if (!presence.state.empty() || !presence.details.empty()) + { + jsonPayload.append(R"("activity": {)"); + if (!presence.state.empty()) + jsonPayload.append(shim::format(R"("state": "{}",)", presence.state)); + if (!presence.details.empty()) + jsonPayload.append(shim::format(R"("details": "{}",)", presence.details)); + if (presence.startTimestamp || presence.endTimestamp) + { + jsonPayload.append(R"("timestamps": {)"); + if (presence.startTimestamp) + jsonPayload.append(shim::format(R"("start": {},)", presence.startTimestamp)); + if (presence.endTimestamp) + jsonPayload.append(shim::format(R"("end": {},)", presence.endTimestamp)); + if (jsonPayload.back() == ',') + jsonPayload.pop_back(); + jsonPayload.append("},"); + } + if (!presence.largeImageKey.empty() && !presence.largeImageText.empty() && !presence.smallImageKey.empty() && !presence.smallImageText.empty()) + { + jsonPayload.append(R"("assets": {)"); + jsonPayload.append(shim::format(R"("large_image": "{}",)", presence.largeImageKey)); + jsonPayload.append(shim::format(R"("large_text": "{}",)", presence.largeImageText)); + jsonPayload.append(shim::format(R"("small_image": "{}",)", presence.smallImageKey)); + jsonPayload.append(shim::format(R"("small_text": "{}",)", presence.smallImageText)); + jsonPayload.append("},"); + } + // party + if (!presence.partyId.empty() || (presence.partySize > 0 && presence.partyMax > 0)) + { + jsonPayload.append(R"("party": {)"); + if (!presence.partyId.empty()) + jsonPayload.append(shim::format(R"("id": "{}",)", presence.partyId)); + if (presence.partySize > 0 && presence.partyMax > 0) + jsonPayload.append(shim::format(R"("size": [{}, {}],)", presence.partySize, presence.partyMax)); + jsonPayload.append(R"("privacy": )").append(std::to_string(presence.partyPrivacy)).append(","); + jsonPayload.append("},"); + } + // match secret + if (!presence.matchSecret.empty() || !presence.joinSecret.empty() || !presence.spectateSecret.empty()) + { + jsonPayload.append(R"("secrets": {)"); + if (!presence.matchSecret.empty()) + jsonPayload.append(shim::format(R"("match": "{}",)", presence.matchSecret)); + if (!presence.joinSecret.empty()) + jsonPayload.append(shim::format(R"("join": "{}",)", presence.joinSecret)); + if (!presence.spectateSecret.empty()) + jsonPayload.append(shim::format(R"("spectate": "{}",)", presence.spectateSecret)); + if (jsonPayload.back() == ',') + jsonPayload.pop_back(); + jsonPayload.append("},"); + } + if (jsonPayload.back() == ',') + jsonPayload.pop_back(); + // end of args->activity + jsonPayload.append("}"); + } + if (jsonPayload.back() == ',') + jsonPayload.pop_back(); + jsonPayload.append("}}"); + SendJsonMsg(OpcodeFrame, jsonPayload); + } + + private: + std::string GetNonceStr() + { + std::string nonceStr = shim::format("{:016x}", nonce); + nonce++; + return nonceStr; + } + int64_t nonce = 1; +}; + +static std::optional ParseJSONField(std::string_view json, std::string_view fieldPath) +{ + size_t pos = 0; + auto skipWhitespace = [&]() { + while (pos < json.size() && isspace(json[pos])) + ++pos; + }; + auto nextToken = [&]() -> std::string_view { + skipWhitespace(); + if (pos >= json.size()) + return ""; + char c = json[pos]; + if (c == '{' || c == '}' || c == '[' || c == ']' || c == ':' || c == ',') + { + return json.substr(pos++, 1); + } + if (c == '"') + { + size_t start = ++pos; + while (pos < json.size() && json[pos] != '"') + ++pos; + auto tok = json.substr(start, pos > start ? pos - start : 0); + if (pos < json.size()) + ++pos; + return tok; + } + size_t start = pos; + while (pos < json.size() && !isspace(json[pos]) && json[pos] != ',' && json[pos] != '}' && json[pos] != ']') + ++pos; + return json.substr(start, pos - start); + }; + auto skipValue = [&]() { + skipWhitespace(); + if (pos >= json.size()) + return; + char c = json[pos]; + if (c == '{') + { + int depth = 1; + ++pos; + while (pos < json.size() && depth > 0) + { + auto tok = nextToken(); + if (tok == "{") + ++depth; + else if (tok == "}") + --depth; + } + } + else if (c == '[') + { + int depth = 1; + ++pos; + while (pos < json.size() && depth > 0) + { + auto tok = nextToken(); + if (tok == "[") + ++depth; + else if (tok == "]") + --depth; + } + } + else + { + nextToken(); + } + }; + auto findField = [&](std::string_view key) { + while (true) + { + auto tok = nextToken(); + if (tok == "}") + return false; + if (tok == "") + return false; + if (tok == key) + { + if (nextToken() == ":") + return true; + return false; + } + if (nextToken() != ":") + return false; + skipValue(); + auto sep = nextToken(); + if (sep == "}") + return false; + if (sep != ",") + return false; + } + }; + // initial "{" + skipWhitespace(); + if (nextToken() != "{") + return std::nullopt; + // traverse the path + size_t off = 0; + while (off <= fieldPath.size()) + { + size_t sep = fieldPath.find('/', off); + if (sep == std::string_view::npos) + sep = fieldPath.size(); + std::string_view seg = fieldPath.substr(off, sep - off); + if (!findField(seg)) + return std::nullopt; + auto val = nextToken(); // after ":" + if (sep == fieldPath.size()) + return std::string(val); + if (val == "{") + { + // traverse object + } + else if (val == "[") + { + // array + return std::nullopt; + } + else + { + return std::nullopt; // not object + } + off = sep + 1; + } + return std::nullopt; +} + +DiscordRPCLite::DiscordRPCLite(const char* applicationId) +{ + m_workerThread = std::thread(&DiscordRPCLite::WorkerThread, this, std::string(applicationId)); +} + +DiscordRPCLite::~DiscordRPCLite() +{ + m_shutdownSignal.store(true); + if (m_workerThread.joinable()) + m_workerThread.join(); +} + +static bool CompareStringI(std::string_view a, std::string_view b) +{ + auto toLower = [](char c) -> char { + if (c >= 'A' && c <= 'Z') + return c + ('a' - 'A'); + return c; + }; + if (a.size() != b.size()) + return false; + for (size_t i = 0; i < a.size(); i++) + { + if (toLower(a[i]) != toLower(b[i])) + return false; + } + return true; +} + +static int64_t GetMs() +{ + auto now = std::chrono::system_clock::now(); + auto duration = now.time_since_epoch(); + return std::chrono::duration_cast(duration).count(); +} + +void DiscordRPCLite::WorkerThread(std::string applicationId) +{ + enum class ConnectionState + { + Disconnected, + ConnectingBeforeHandshake, + ConnectingAfterHandshake, + Connected + }; + ConnectionState connectionState = ConnectionState::Disconnected; + + std::vector recvBuffer; + uint8_t recvMsgHeader[8] = {0}; + size_t recvSize = 0; // if < 8 then we are still receiving the header. If >= 8 then we are receiving the body + NamedPipe pipe; + auto SetDisconnected = [&]() { + pipe.ClosePipe(); + connectionState = ConnectionState::Disconnected; + recvSize = 0; + m_richPresenceDirty = true; // set so we always send current rich presence after (re)connecting + }; + SetDisconnected(); // set initial state + int64_t lastConnectionAttempt = 0; + int32_t numFailedConnectionAttempts = 0; // increases every time we try to connect but fail, resets to 0 when we successfully connect and receive a READY event + int64_t lastRichPresenceUpdate = 0; + while (!m_shutdownSignal) + { + if (connectionState == ConnectionState::Disconnected) + { + // wait at least one second before trying to reconnect + int64_t now = GetMs(); + int64_t delayTime = 1000 + (numFailedConnectionAttempts * 500); // increase delay by 500ms for each failed connection attempt + if (delayTime >= 90000) + delayTime = 90000; // max delay of 90 seconds + if ((now - lastConnectionAttempt) < delayTime) + { + std::this_thread::sleep_for(std::chrono::milliseconds(200)); + continue; + } + lastConnectionAttempt = now; + numFailedConnectionAttempts++; + if (!pipe.OpenPipe()) + { + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + continue; + } + connectionState = ConnectionState::ConnectingBeforeHandshake; + continue; + } + if (connectionState == ConnectionState::ConnectingBeforeHandshake) + { + std::string handshakeJson = shim::format(R"({{"v":1,"client_id":"{}"}})", applicationId); + pipe.SendJsonMsg(OpcodeHandshake, handshakeJson); + connectionState = ConnectionState::ConnectingAfterHandshake; + } + // check if we should send a presence update (rate limited to 1 per 15 seconds) + if (connectionState == ConnectionState::Connected && m_richPresenceDirty) + { + int64_t now = GetMs(); + if ((now - lastRichPresenceUpdate) >= 15000) + { + DiscordLiteRichPresence presence = {}; + { + std::lock_guard lock(m_presenceMutex); + presence = m_presence; + m_richPresenceDirty = false; + } + pipe.SendPresenceUpdate(presence); + lastRichPresenceUpdate = now; + } + } + // continue receiving messages + if (recvSize < 8) + { + // receive header + int readSize = pipe.Read(recvMsgHeader + recvSize, 8 - recvSize, 200); + if (readSize < 0) + { + SetDisconnected(); + continue; + } + recvSize += readSize; + } + else + { + // receive body + uint32_t opcode = (recvMsgHeader[0] << 0) | (recvMsgHeader[1] << 8) | (recvMsgHeader[2] << 16) | (recvMsgHeader[3] << 24); + uint32_t bodyLength = (recvMsgHeader[4] << 0) | (recvMsgHeader[5] << 8) | (recvMsgHeader[6] << 16) | (recvMsgHeader[7] << 24); + if (bodyLength >= 8 * 1024 * 1024) + { + SetDisconnected(); + continue; + } + if (recvBuffer.size() < bodyLength) + recvBuffer.resize(bodyLength); + int readSize = pipe.Read(recvBuffer.data() + (recvSize - 8), bodyLength - (recvSize - 8), 1000); + if (readSize < 0) + { + SetDisconnected(); + continue; + } + recvSize += readSize; + if (recvSize == bodyLength + 8) + { + std::string_view jsonText((const char*)recvBuffer.data(), bodyLength); + recvSize = 0; + // full message received + if (opcode == OpcodeFrame) + { + std::optional cmd = ParseJSONField(jsonText, "cmd"); + std::optional evt = ParseJSONField(jsonText, "evt"); + if (CompareStringI(*cmd, "DISPATCH")) + { + if (evt && CompareStringI(*evt, "READY")) + { + if (connectionState == ConnectionState::ConnectingAfterHandshake) + { + connectionState = ConnectionState::Connected; + numFailedConnectionAttempts = 0; + } + } + } + } + else if (opcode == OpcodePing) + { + pipe.SendJsonMsg(OpcodePong, jsonText); + } + else if (opcode == OpcodeClose) + { + SetDisconnected(); + } + if (recvBuffer.size() > 2048) + { + recvBuffer.resize(2048); + recvBuffer.shrink_to_fit(); + } + } + } + } + // if we are still connected then explicitly clear presence just in case + if (pipe.IsOpen()) + { + pipe.SendPresenceUpdate({}); + std::this_thread::sleep_for(std::chrono::milliseconds(75)); + } +} \ No newline at end of file diff --git a/src/Cemu/DiscordPresence/DiscordRPCLite.h b/src/Cemu/DiscordPresence/DiscordRPCLite.h new file mode 100644 index 00000000..b6f54440 --- /dev/null +++ b/src/Cemu/DiscordPresence/DiscordRPCLite.h @@ -0,0 +1,59 @@ +/* Standalone client for Discord RPC for the sole purpose of updating rich presence */ + +#pragma once +#include +#include +#include +#include +#include + +struct DiscordLiteRichPresence +{ + std::string state; + std::string details; + int64_t startTimestamp; + int64_t endTimestamp; + std::string largeImageKey; + std::string largeImageText; + std::string smallImageKey; + std::string smallImageText; + std::string partyId; + int partySize; + int partyMax; + int partyPrivacy; + std::string matchSecret; + std::string joinSecret; + std::string spectateSecret; + int8_t instance; +}; + +class DiscordRPCLite +{ + public: + DiscordRPCLite(const char* applicationId); + ~DiscordRPCLite(); + + void UpdateRichPresence(const DiscordLiteRichPresence& presence) + { + std::unique_lock _l(m_presenceMutex); + m_presence = presence; + m_richPresenceDirty = true; + } + + void ClearRichPresence() + { + std::unique_lock _l(m_presenceMutex); + m_presence = {}; + m_richPresenceDirty = false; + } + + private: + void WorkerThread(std::string applicationId); + + std::thread m_workerThread; + std::atomic_bool m_shutdownSignal{false}; + // rich presence state + std::mutex m_presenceMutex; + std::atomic_bool m_richPresenceDirty{false}; + DiscordLiteRichPresence m_presence; +}; \ No newline at end of file diff --git a/src/Cemu/ExpressionParser/ExpressionParser.h b/src/Cemu/ExpressionParser/ExpressionParser.h index ab14dc5d..e8ad6ce2 100644 --- a/src/Cemu/ExpressionParser/ExpressionParser.h +++ b/src/Cemu/ExpressionParser/ExpressionParser.h @@ -37,7 +37,7 @@ public: template T Evaluate(std::string_view expression) const { - static_assert(std::is_arithmetic::value, "type T must be an arithmetic type"); + static_assert(std::is_arithmetic_v, "type T must be an arithmetic type"); return (T)Evaluate(expression); } diff --git a/src/Common/CMakeLists.txt b/src/Common/CMakeLists.txt index b58a03bf..417ed034 100644 --- a/src/Common/CMakeLists.txt +++ b/src/Common/CMakeLists.txt @@ -47,7 +47,7 @@ PRIVATE ) endif() -if(UNIX AND NOT APPLE) +if(LINUX) target_sources(CemuCommon PRIVATE ExceptionHandler/ELFSymbolTable.cpp ExceptionHandler/ELFSymbolTable.h diff --git a/src/Common/GLInclude/GLInclude.h b/src/Common/GLInclude/GLInclude.h index 6446c53a..6459a428 100644 --- a/src/Common/GLInclude/GLInclude.h +++ b/src/Common/GLInclude/GLInclude.h @@ -6,12 +6,12 @@ #include "wglext.h" #endif -#if BOOST_OS_LINUX #if __ANDROID__ #define EGL_EGL_PROTOTYPES 0 #include "egl.h" #undef EGL_EGL_PROTOTYPES -#else +#elif ( BOOST_OS_LINUX || BOOST_OS_BSD ) > 0 + // from Xlib #define Bool int #define Status int @@ -37,8 +37,8 @@ typedef struct __GLXFBConfigRec *GLXFBConfig; #undef Status #undef True #undef False -#endif // __ANDROID__ -#endif // BOOST_OS_LINUX + +#endif namespace CemuGL { diff --git a/src/Common/GLInclude/glFunctions.h b/src/Common/GLInclude/glFunctions.h index 76308fdb..412816af 100644 --- a/src/Common/GLInclude/glFunctions.h +++ b/src/Common/GLInclude/glFunctions.h @@ -297,7 +297,7 @@ GLFUNC(PFNWGLSWAPINTERVALEXTPROC, wglSwapIntervalEXT) // x -#if BOOST_OS_LINUX +#if BOOST_OS_LINUX || BOOST_OS_BSD EGLFUNC(PFNEGLSWAPINTERVALPROC, eglSwapInterval) EGLFUNC(PFNEGLGETCURRENTDISPLAYPROC, eglGetCurrentDisplay) #endif diff --git a/src/Common/SysAllocator.h b/src/Common/SysAllocator.h index 7a11601e..80afc129 100644 --- a/src/Common/SysAllocator.h +++ b/src/Common/SysAllocator.h @@ -113,9 +113,8 @@ public: operator void*() { return m_sysMem->GetPtr(); } // for all arrays except bool - template - typename std::enable_if< count != 1 && !std::is_same::value, Q >::type& - operator[](int index) + T& operator[](int index) + requires(count != 1) && (!std::is_same_v) { // return tmp data until we allocated in sys mem if (m_sysMem.GetMPTR() == 0) @@ -125,7 +124,7 @@ public: return m_sysMem[index]; } -private: + private: SysAllocator(uint32 memptr) : m_sysMem(memptr) {} @@ -215,4 +214,4 @@ private: MEMPTR m_sysMem; T m_tempData; -}; \ No newline at end of file +}; diff --git a/src/Common/betype.h b/src/Common/betype.h index c91376e2..f3a18989 100644 --- a/src/Common/betype.h +++ b/src/Common/betype.h @@ -22,7 +22,7 @@ constexpr T bswap(T i) template constexpr T SwapEndian(T value) { - if constexpr (std::is_integral::value) + if constexpr (std::is_integral_v) { #ifdef _MSC_VER if constexpr (sizeof(T) == sizeof(uint32_t)) @@ -33,7 +33,7 @@ constexpr T SwapEndian(T value) return (T)bswap((std::make_unsigned_t)value); } - else if constexpr (std::is_floating_point::value) + else if constexpr (std::is_floating_point_v) { if constexpr (sizeof(T) == sizeof(uint32_t)) { @@ -46,18 +46,18 @@ constexpr T SwapEndian(T value) return *(T*)&tmp; } } - else if constexpr (std::is_enum::value) + else if constexpr (std::is_enum_v) { return (T)SwapEndian((std::underlying_type_t)value); } - else if constexpr (std::is_base_of::value) + else if constexpr (std::is_base_of_v) { const auto tmp = bswap(*(uint32_t*)&value); return *(T*)&tmp; } else { - static_assert(std::is_integral::value, "unsupported betype specialization!"); + static_assert(std::is_integral_v, "unsupported betype specialization!"); } return value; diff --git a/src/Common/enumFlags.h b/src/Common/enumFlags.h index ac63f4c6..a247b8e2 100644 --- a/src/Common/enumFlags.h +++ b/src/Common/enumFlags.h @@ -10,63 +10,65 @@ struct EnableBitMaskOperators }; template -typename std::enable_if::enable, TEnum>::type -operator &(TEnum lhs, TEnum rhs) + requires EnableBitMaskOperators::enable +TEnum operator &(TEnum lhs, TEnum rhs) { return static_cast (static_cast::type>(lhs) & static_cast::type>(rhs)); } template -typename std::enable_if::enable, TEnum>::type -operator |(TEnum lhs, TEnum rhs) + requires EnableBitMaskOperators::enable +TEnum operator |(TEnum lhs, TEnum rhs) { return static_cast (static_cast::type>(lhs) | static_cast::type>(rhs)); } template -typename std::enable_if::enable, TEnum>::type -operator ^(TEnum lhs, TEnum rhs) + requires EnableBitMaskOperators::enable +TEnum operator ^(TEnum lhs, TEnum rhs) { return static_cast (static_cast::type>(lhs) ^ static_cast::type>(rhs)); } template -typename std::enable_if::enable, TEnum>::type -operator ~(TEnum rhs) + requires EnableBitMaskOperators::enable +TEnum operator ~(TEnum rhs) { return static_cast (~static_cast::type>(rhs)); } template -typename std::enable_if::enable, TEnum>::type& -operator &=(TEnum& lhs, TEnum rhs) + requires EnableBitMaskOperators::enable +TEnum& operator &=(TEnum& lhs, TEnum rhs) { lhs = static_cast (static_cast::type>(lhs) & static_cast::type>(rhs)); return lhs; } template -typename std::enable_if::enable, TEnum>::type& -operator |=(TEnum& lhs, TEnum rhs) + requires EnableBitMaskOperators::enable +TEnum& operator |=(TEnum& lhs, TEnum rhs) { lhs = static_cast (static_cast::type>(lhs) | static_cast::type>(rhs)); return lhs; } template -typename std::enable_if::enable, TEnum>::type& -operator ^=(TEnum& lhs, TEnum rhs) + requires EnableBitMaskOperators::enable +TEnum& operator ^=(TEnum& lhs, TEnum rhs) { lhs = static_cast (static_cast::type>(lhs) ^ static_cast::type>(rhs)); return lhs; } -template::enable>> +template + requires EnableBitMaskOperators::enable constexpr bool operator==(TEnum lhs, std::underlying_type_t rhs) { return static_cast>(lhs) == rhs; } -template::enable>> +template + requires EnableBitMaskOperators::enable constexpr bool operator!=(TEnum lhs, std::underlying_type_t rhs) { return static_cast>(lhs) != rhs; @@ -82,43 +84,43 @@ struct EnableEnumIterators }; template -typename std::enable_if::enable, TEnum>::type& -operator++(TEnum& lhs) + requires EnableEnumIterators::enable +TEnum& operator++(TEnum& lhs) { lhs = static_cast(static_cast::type>(lhs) + 1); return lhs; } template -typename std::enable_if::enable, TEnum>::type -operator*(TEnum rhs) + requires EnableEnumIterators::enable +TEnum operator*(TEnum rhs) { return rhs; } template -typename std::enable_if::enable, TEnum>::type -begin(TEnum value) + requires EnableEnumIterators::enable +TEnum begin(TEnum value) { return EnableEnumIterators::begin; } template -typename std::enable_if::enable, TEnum>::type -rbegin(TEnum value) + requires EnableEnumIterators::enable +TEnum rbegin(TEnum value) { return EnableEnumIterators::rbegin; } template -typename std::enable_if::enable, TEnum>::type -end(TEnum r) { + requires EnableEnumIterators::enable +TEnum end(TEnum r) { return EnableEnumIterators::end; } template -typename std::enable_if::enable, TEnum>::type -rend(TEnum r) { + requires EnableEnumIterators::enable +TEnum rend(TEnum r) { return EnableEnumIterators::rend; } @@ -129,4 +131,4 @@ rend(TEnum r) { static const x end = static_cast(static_cast::type>(last_value) + 1);\ static const x rend = static_cast(static_cast::type>(first_value) - 1);\ }; -// todo: rend type must be signed? \ No newline at end of file +// todo: rend type must be signed? diff --git a/src/Common/platform.h b/src/Common/platform.h index 25006ecb..c14f69ff 100644 --- a/src/Common/platform.h +++ b/src/Common/platform.h @@ -8,8 +8,12 @@ #elif __ANDROID__ #include #include "Common/unix/platform.h" -#elif BOOST_OS_LINUX +#elif BOOST_OS_LINUX || BOOST_OS_BSD +#if BOOST_OS_LINUX #include +#elif BOOST_OS_BSD +#include +#endif #include #include #include diff --git a/src/Common/precompiled.h b/src/Common/precompiled.h index 5e795fa8..abac632c 100644 --- a/src/Common/precompiled.h +++ b/src/Common/precompiled.h @@ -242,6 +242,12 @@ inline uint64 _swapEndianU64(uint64 v) { #if BOOST_OS_MACOS return OSSwapInt64(v); +#elif BOOST_OS_BSD +#ifdef __OpenBSD__ + return swap64(v); +#else // FreeBSD and NetBSD + return bswap64(v); +#endif #else return bswap_64(v); #endif @@ -251,6 +257,12 @@ inline uint32 _swapEndianU32(uint32 v) { #if BOOST_OS_MACOS return OSSwapInt32(v); +#elif BOOST_OS_BSD +#ifdef __OpenBSD__ + return swap32(v); +#else // FreeBSD and NetBSD + return bswap32(v); +#endif #else return bswap_32(v); #endif @@ -260,6 +272,12 @@ inline sint32 _swapEndianS32(sint32 v) { #if BOOST_OS_MACOS return (sint32)OSSwapInt32((uint32)v); +#elif BOOST_OS_BSD +#ifdef __OpenBSD__ + return (sint32)swap32((uint32)v); +#else // FreeBSD and NetBSD + return (sint32)bswap32((uint32)v); +#endif #else return (sint32)bswap_32((uint32)v); #endif @@ -551,6 +569,11 @@ bool match_any_of(T1&& value, Types&&... others) #elif BOOST_OS_MACOS return std::chrono::steady_clock::time_point( std::chrono::nanoseconds(clock_gettime_nsec_np(CLOCK_MONOTONIC_RAW))); +#elif BOOST_OS_BSD + struct timespec tp; + clock_gettime(CLOCK_MONOTONIC, &tp); + return std::chrono::steady_clock::time_point( + std::chrono::seconds(tp.tv_sec) + std::chrono::nanoseconds(tp.tv_nsec)); #endif } @@ -688,7 +711,8 @@ struct fmt::formatter> : fmt::formatter namespace stdx { // std::to_underlying - template {} >> + template + requires (std::is_enum_v) constexpr std::underlying_type_t to_underlying(EnumT e) noexcept { return static_cast>(e); }; @@ -724,7 +748,7 @@ namespace stdx template class atomic_ref { - static_assert(std::is_trivially_copyable::value, "atomic_ref requires trivially copyable types"); + static_assert(std::is_trivially_copyable_v, "atomic_ref requires trivially copyable types"); public: using value_type = T; diff --git a/src/Common/unix/platform.cpp b/src/Common/unix/platform.cpp index 144d4f02..879ae4dc 100644 --- a/src/Common/unix/platform.cpp +++ b/src/Common/unix/platform.cpp @@ -9,6 +9,10 @@ uint32_t GetTickCount() return (1000 * ts.tv_sec + ts.tv_nsec / 1000000); #elif BOOST_OS_MACOS return clock_gettime_nsec_np(CLOCK_MONOTONIC_RAW) / 1000000; +#elif BOOST_OS_BSD + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + return (1000 * ts.tv_sec + ts.tv_nsec / 1000000); #endif -} \ No newline at end of file +} diff --git a/src/config/ConfigValue.h b/src/config/ConfigValue.h index 43e2ad3b..ecffc119 100644 --- a/src/config/ConfigValue.h +++ b/src/config/ConfigValue.h @@ -96,15 +96,15 @@ public: m_value = v; } - template >> void SetValue(std::string_view v) + requires std::is_same_v { std::lock_guard lock(m_mutex); m_value = v; } - template >> void SetValue(std::wstring_view v) + requires std::is_same_v { std::lock_guard lock(m_mutex); m_value = v; @@ -171,22 +171,22 @@ public: } // init from enum with iterators - template::value && EnableEnumIterators::enable, TType>> constexpr ConfigValueBounds() - : base_type(), m_min_value(begin(TEnum{})), m_max_value(rbegin(TEnum{})) + requires std::is_enum_v && EnableEnumIterators::enable + : base_type(), m_min_value(begin(TType{})), m_max_value(rbegin(TType{})) { assert(m_min_value <= this->GetInitValue() && this->GetInitValue() <= m_max_value); } - template::value && EnableEnumIterators::enable, TType>> constexpr ConfigValueBounds(const TType& init_value) + requires std::is_enum_v && EnableEnumIterators::enable : base_type(std::forward(init_value)), m_min_value(begin(init_value)), m_max_value(rbegin(init_value)) { assert(m_min_value <= init_value && init_value <= m_max_value); } - template::value && EnableEnumIterators::enable, TType>> constexpr ConfigValueBounds(TType&& init_value) + requires std::is_enum_v && EnableEnumIterators::enable : base_type(std::forward(init_value)), m_min_value(begin(init_value)), m_max_value(rbegin(init_value)) { assert(m_min_value <= init_value && init_value <= m_max_value); diff --git a/src/config/XMLConfig.h b/src/config/XMLConfig.h index 2e46b8db..049bc394 100644 --- a/src/config/XMLConfig.h +++ b/src/config/XMLConfig.h @@ -221,7 +221,7 @@ public: { auto* element = m_document->NewElement(name); - if constexpr (std::is_enum::value) + if constexpr (std::is_enum_v) element->SetText(fmt::format("{}", static_cast::type>(value)).c_str()); else element->SetText(fmt::format("{}", value).c_str()); @@ -480,8 +480,8 @@ class XMLChildConfig { m_parentConfig = { .lock = [getParentConfig]() { return getParentConfig().Lock(); }, - .save = [getParentConfig]() { return getParentConfig().Load(); }, - .load = [getParentConfig]() { return getParentConfig().Save(); }, + .save = [getParentConfig]() { return getParentConfig().Save(); }, + .load = [getParentConfig]() { return getParentConfig().Load(); }, }; auto configParser = std::make_pair( diff --git a/src/gui/wxgui/AudioDebuggerWindow.cpp b/src/gui/wxgui/AudioDebuggerWindow.cpp index b9bc45fc..d570e84b 100644 --- a/src/gui/wxgui/AudioDebuggerWindow.cpp +++ b/src/gui/wxgui/AudioDebuggerWindow.cpp @@ -24,7 +24,6 @@ wxEND_EVENT_TABLE() AudioDebuggerWindow::AudioDebuggerWindow(wxFrame& parent) : wxFrame(&parent, wxID_ANY, _("AX voice viewer"), wxDefaultPosition, wxSize(1126, 580), wxCLOSE_BOX | wxCLIP_CHILDREN | wxCAPTION | wxRESIZE_BORDER) { - wxPanel* mainPane = new wxPanel(this); wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL); @@ -141,8 +140,6 @@ AudioDebuggerWindow::AudioDebuggerWindow(wxFrame& parent) } RefreshVoiceList(); - wxFrame::SetBackgroundColour(*wxWHITE); - // start refresh timer static const int INTERVAL = 100; // milliseconds refreshTimer = new wxTimer(this, REFRESH_TIMER_ID); diff --git a/src/gui/wxgui/CMakeLists.txt b/src/gui/wxgui/CMakeLists.txt index 921ba053..1aa3e0a5 100644 --- a/src/gui/wxgui/CMakeLists.txt +++ b/src/gui/wxgui/CMakeLists.txt @@ -34,8 +34,6 @@ add_library(CemuWxGui debugger/DumpWindow.h debugger/ModuleWindow.cpp debugger/ModuleWindow.h - debugger/RegisterCtrl.cpp - debugger/RegisterCtrl.h debugger/RegisterWindow.cpp debugger/RegisterWindow.h debugger/SymbolCtrl.cpp @@ -114,22 +112,8 @@ add_library(CemuWxGui windows/TextureRelationViewer windows/TextureRelationViewer/TextureRelationWindow.cpp windows/TextureRelationViewer/TextureRelationWindow.h - wxcomponents/checked2.xpm - wxcomponents/checked_dis.xpm - wxcomponents/checked_d.xpm - wxcomponents/checked_ld.xpm - wxcomponents/checkedlistctrl.cpp - wxcomponents/checkedlistctrl.h - wxcomponents/checked_mo.xpm - wxcomponents/checked.xpm wxcomponents/checktree.cpp wxcomponents/checktree.h - wxcomponents/unchecked2.xpm - wxcomponents/unchecked_dis.xpm - wxcomponents/unchecked_d.xpm - wxcomponents/unchecked_ld.xpm - wxcomponents/unchecked_mo.xpm - wxcomponents/unchecked.xpm wxgui.h wxHelper.h ) diff --git a/src/gui/wxgui/CemuApp.cpp b/src/gui/wxgui/CemuApp.cpp index 78f4b83f..c35fb12e 100644 --- a/src/gui/wxgui/CemuApp.cpp +++ b/src/gui/wxgui/CemuApp.cpp @@ -14,7 +14,7 @@ #include "wxgui/input/HotkeySettings.h" #include -#if BOOST_OS_LINUX && HAS_WAYLAND +#if ( BOOST_OS_LINUX || BOOST_OS_BSD ) && HAS_WAYLAND #include "wxgui/helpers/wxWayland.h" #endif #if __WXGTK__ @@ -117,7 +117,7 @@ void CemuApp::DeterminePaths(std::set& failedWriteAccess) // for Windo } #endif -#if BOOST_OS_LINUX +#if BOOST_OS_LINUX || BOOST_OS_BSD void CemuApp::DeterminePaths(std::set& failedWriteAccess) // for Linux { std::error_code ec; @@ -285,6 +285,17 @@ bool CemuApp::OnInit() } SetTranslationCallback(TranslationCallback); +#if __WXMSW__ + auto& wxGuiConfig = GetWxGUIConfig(); + if (wxGuiConfig.msw_theme.GetValue() == static_cast(MSWThemeOption::kAuto)) + { + MSWEnableDarkMode(DarkMode_Auto); + } + else if (wxGuiConfig.msw_theme.GetValue() == static_cast(MSWThemeOption::kDark)) + { + MSWEnableDarkMode(DarkMode_Always); + } +#endif for (auto&& path : failedWriteAccess) { @@ -347,7 +358,7 @@ bool CemuApp::OnInit() SetTopWindow(m_mainFrame); m_mainFrame->Show(); -#if BOOST_OS_LINUX && HAS_WAYLAND +#if ( BOOST_OS_LINUX || BOOST_OS_BSD ) && HAS_WAYLAND if (wxWlIsWaylandWindow(m_mainFrame)) wxWlSetAppId(m_mainFrame, "info.cemu.Cemu"); #endif diff --git a/src/gui/wxgui/CemuUpdateWindow.cpp b/src/gui/wxgui/CemuUpdateWindow.cpp index c45a0ab8..542ae588 100644 --- a/src/gui/wxgui/CemuUpdateWindow.cpp +++ b/src/gui/wxgui/CemuUpdateWindow.cpp @@ -110,15 +110,26 @@ bool CemuUpdateWindow::QueryUpdateInfo(std::string& downloadUrlOut, std::string& std::string urlStr("https://cemu.info/api2/version.php?v="); auto* curl = curl_easy_init(); urlStr.append(_curlUrlEscape(curl, BUILD_VERSION_STRING)); -#if BOOST_OS_LINUX - urlStr.append("&platform=linux_appimage_x86"); +#if BOOST_OS_LINUX || BOOST_OS_BSD // dummy placeholder on BSD for now + urlStr.append("&platform=linux_appimage"); #elif BOOST_OS_WINDOWS urlStr.append("&platform=windows"); #elif BOOST_OS_MACOS - urlStr.append("&platform=macos_bundle_x86"); -#elif + urlStr.append("&platform=macos_bundle"); +#else #error Name for current platform is missing #endif +#if defined(__aarch64__) + urlStr.append("_aarch64"); +#elif defined(ARCH_X86_64) + urlStr.append("_x86_64"); +#else + urlStr.append("_unknown"); +#endif +#if BOOST_OS_BSD + return false; // BSD users must update from source; no binary available +#endif + const auto& config = GetWxGUIConfig(); if(config.receive_untested_updates) urlStr.append("&allowNewUpdates=1"); @@ -417,7 +428,7 @@ void CemuUpdateWindow::WorkerThread() #if BOOST_OS_WINDOWS const auto update_file = tmppath / L"update.zip"; -#elif BOOST_OS_LINUX +#elif BOOST_OS_LINUX || BOOST_OS_BSD // dummy placeholder on BSD for now const auto update_file = tmppath / L"Cemu.AppImage"; #elif BOOST_OS_MACOS const auto update_file = tmppath / L"cemu.dmg"; diff --git a/src/gui/wxgui/GameProfileWindow.cpp b/src/gui/wxgui/GameProfileWindow.cpp index 7948b1f9..0092bb84 100644 --- a/src/gui/wxgui/GameProfileWindow.cpp +++ b/src/gui/wxgui/GameProfileWindow.cpp @@ -11,7 +11,7 @@ #include "wxgui/helpers/wxHelpers.h" #include "input/InputManager.h" -#if BOOST_OS_LINUX || BOOST_OS_MACOS +#if BOOST_OS_LINUX || BOOST_OS_MACOS || BOOST_OS_BSD #include "resource/embedded/resources.h" #endif @@ -365,4 +365,4 @@ void GameProfileWindow::SetSliderValue(wxSlider* slider, sint32 new_value) const slider_event.SetEventObject(slider); slider_event.SetClientData((void*)IsFrozen()); wxPostEvent(slider->GetEventHandler(), slider_event); -} \ No newline at end of file +} diff --git a/src/gui/wxgui/GeneralSettings2.cpp b/src/gui/wxgui/GeneralSettings2.cpp index 8b576e4b..bc554722 100644 --- a/src/gui/wxgui/GeneralSettings2.cpp +++ b/src/gui/wxgui/GeneralSettings2.cpp @@ -137,18 +137,40 @@ wxPanel* GeneralSettings2::AddGeneralPage(wxNotebook* notebook) box_sizer->Add(first_row, 1, wxEXPAND, 5); } +#if BOOST_OS_WINDOWS { - auto* second_row = new wxFlexGridSizer(0, 3, 0, 0); + auto* second_row = new wxFlexGridSizer(0, 2, 0, 0); second_row->SetFlexibleDirection(wxBOTH); second_row->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED); + second_row->Add(new wxStaticText(box, wxID_ANY, _("Theme"), wxDefaultPosition, wxDefaultSize, 0), 0, wxALIGN_CENTER_VERTICAL | wxALL, 5); + + m_msw_theme = new wxChoice(box, wxID_ANY, wxDefaultPosition, wxDefaultSize); + m_msw_theme->SetToolTip(_("Changes the Windows theme used by Cemu\nThis only works on Windows 10 and later\nA restart will be required for any changes to take effect")); + + m_msw_theme->AppendString(_("Follow Windows theme")); + m_msw_theme->AppendString(_("Light Theme")); + m_msw_theme->AppendString(_("Dark Theme")); + m_msw_theme->SetSelection(0); + + second_row->Add(m_msw_theme, 0, wxALL, 5); + + box_sizer->Add(second_row, 0, wxEXPAND, 5); + } +#endif + + { + auto* third_row = new wxFlexGridSizer(0, 3, 0, 0); + third_row->SetFlexibleDirection(wxBOTH); + third_row->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED); + sint32 checkboxCount = 0; auto CountRowElement = [&]() { checkboxCount++; if(checkboxCount != 2) return; - second_row->AddSpacer(10); + third_row->AddSpacer(10); checkboxCount = 0; }; @@ -156,51 +178,51 @@ wxPanel* GeneralSettings2::AddGeneralPage(wxNotebook* notebook) { while(checkboxCount != 0) CountRowElement(); - second_row->AddSpacer(10); - second_row->AddSpacer(10); - second_row->AddSpacer(10); + third_row->AddSpacer(10); + third_row->AddSpacer(10); + third_row->AddSpacer(10); }; const int topflag = wxALIGN_CENTER_VERTICAL | wxALL; m_save_window_position_size = new wxCheckBox(box, wxID_ANY, _("Remember main window position")); m_save_window_position_size->SetToolTip(_("Restores the last known window position and size when starting Cemu")); - second_row->Add(m_save_window_position_size, 0, topflag, 5); + third_row->Add(m_save_window_position_size, 0, topflag, 5); CountRowElement(); - //second_row->AddSpacer(10); + //third_row->AddSpacer(10); m_save_padwindow_position_size = new wxCheckBox(box, wxID_ANY, _("Remember pad window position")); m_save_padwindow_position_size->SetToolTip(_("Restores the last known pad window position and size when opening it")); - second_row->Add(m_save_padwindow_position_size, 0, topflag, 5); + third_row->Add(m_save_padwindow_position_size, 0, topflag, 5); CountRowElement(); const int botflag = wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT | wxBOTTOM; m_discord_presence = new wxCheckBox(box, wxID_ANY, _("Discord Presence")); m_discord_presence->SetToolTip(_("Enables the Discord Rich Presence feature\nYou will also need to enable it in the Discord settings itself!")); - second_row->Add(m_discord_presence, 0, botflag, 5); + third_row->Add(m_discord_presence, 0, botflag, 5); CountRowElement(); #ifndef ENABLE_DISCORD_RPC m_discord_presence->Disable(); #endif - //second_row->AddSpacer(10); + //third_row->AddSpacer(10); m_fullscreen_menubar = new wxCheckBox(box, wxID_ANY, _("Fullscreen menu bar")); m_fullscreen_menubar->SetToolTip(_("Displays the menu bar when Cemu is running in fullscreen mode and the mouse cursor is moved to the top")); - second_row->Add(m_fullscreen_menubar, 0, botflag, 5); + third_row->Add(m_fullscreen_menubar, 0, botflag, 5); CountRowElement(); m_save_screenshot = new wxCheckBox(box, wxID_ANY, _("Save screenshot")); m_save_screenshot->SetToolTip(_("Pressing the screenshot key (F12) will save a screenshot directly to the screenshots folder")); - second_row->Add(m_save_screenshot, 0, botflag, 5); + third_row->Add(m_save_screenshot, 0, botflag, 5); CountRowElement(); m_disable_screensaver = new wxCheckBox(box, wxID_ANY, _("Disable screen saver")); m_disable_screensaver->SetToolTip(_("Prevents the system from activating the screen saver or going to sleep while running a game.")); - second_row->Add(m_disable_screensaver, 0, botflag, 5); + third_row->Add(m_disable_screensaver, 0, botflag, 5); CountRowElement(); // Enable/disable feral interactive gamemode #if BOOST_OS_LINUX && defined(ENABLE_FERAL_GAMEMODE) m_feral_gamemode = new wxCheckBox(box, wxID_ANY, _("Enable Feral GameMode")); m_feral_gamemode->SetToolTip(_("Use FeralInteractive GameMode if installed.")); - second_row->Add(m_feral_gamemode, 0, botflag, 5); + third_row->Add(m_feral_gamemode, 0, botflag, 5); CountRowElement(); #endif @@ -210,24 +232,26 @@ wxPanel* GeneralSettings2::AddGeneralPage(wxNotebook* notebook) #endif m_play_boot_sound = new wxCheckBox(box, wxID_ANY, _("Enable intro sound")); m_play_boot_sound->SetToolTip(_("Play bootSound file while compiling shaders/pipelines.")); - second_row->Add(m_play_boot_sound, 0, botflag, 5); + third_row->Add(m_play_boot_sound, 0, botflag, 5); CountRowElement(); m_auto_update = new wxCheckBox(box, wxID_ANY, _("Automatically check for updates")); m_auto_update->SetToolTip(_("Automatically checks for new cemu versions on startup")); - second_row->Add(m_auto_update, 0, botflag, 5); + third_row->Add(m_auto_update, 0, botflag, 5); CountRowElement(); m_receive_untested_releases = new wxCheckBox(box, wxID_ANY, _("Receive untested updates")); m_receive_untested_releases->SetToolTip(_("When checking for updates, include brand new and untested releases. These may contain bugs!")); - second_row->Add(m_receive_untested_releases, 0, botflag, 5); + third_row->Add(m_receive_untested_releases, 0, botflag, 5); #if BOOST_OS_LINUX if (!std::getenv("APPIMAGE")) { m_auto_update->Disable(); } +#elif BOOST_OS_BSD // BSD users must update from source so disable auto updates + m_auto_update->Disable(); #endif - box_sizer->Add(second_row, 0, wxEXPAND, 5); + box_sizer->Add(third_row, 0, wxEXPAND, 5); } general_panel_sizer->Add(box_sizer, 0, wxEXPAND | wxALL, 5); @@ -268,7 +292,7 @@ wxPanel* GeneralSettings2::AddGeneralPage(wxNotebook* notebook) auto* general_gamepath_sizer = new wxStaticBoxSizer(general_gamepath_box, wxVERTICAL); m_game_paths = new wxListBox(general_gamepath_box, wxID_ANY); - m_game_paths->SetMinSize(wxSize(150, 100)); + m_game_paths->SetMinSize(wxSize(150, 70)); m_game_paths->SetToolTip(_("Add the root directory of your game(s). It will scan all directories in it for games")); general_gamepath_sizer->Add(m_game_paths, 1, wxALL | wxEXPAND, 5); @@ -814,9 +838,6 @@ wxPanel* GeneralSettings2::AddAccountPage(wxNotebook* notebook) { m_account_information = new wxCollapsiblePane(online_panel, wxID_ANY, _("Account information")); - #if BOOST_OS_WINDOWS - m_account_information->GetControlWidget()->SetBackgroundColour(*wxWHITE); - #endif auto win = m_account_information->GetPane(); auto content = new wxBoxSizer(wxVERTICAL); @@ -969,6 +990,9 @@ void GeneralSettings2::StoreConfig() wxGuiConfig.receive_untested_updates = m_receive_untested_releases->IsChecked(); #if BOOST_OS_LINUX && defined(ENABLE_FERAL_GAMEMODE) wxGuiConfig.feral_gamemode = m_feral_gamemode->IsChecked(); +#endif +#if BOOST_OS_WINDOWS + wxGuiConfig.msw_theme = m_msw_theme->GetSelection(); #endif config.play_boot_sound = m_play_boot_sound->IsChecked(); config.disable_screensaver = m_disable_screensaver->IsChecked(); @@ -1144,7 +1168,6 @@ void GeneralSettings2::ValidateConfig() void GeneralSettings2::DisableSettings(bool game_launched) { - } void GeneralSettings2::OnAudioLatencyChanged(wxCommandEvent& event) @@ -1632,6 +1655,9 @@ void GeneralSettings2::ApplyConfig() m_disable_screensaver->SetValue(config.disable_screensaver); m_play_boot_sound->SetValue(config.play_boot_sound); +#if BOOST_OS_WINDOWS + m_msw_theme->SetSelection(wxGUIconfig.msw_theme); +#endif #if BOOST_OS_LINUX && defined(ENABLE_FERAL_GAMEMODE) m_feral_gamemode->SetValue(wxGUIconfig.feral_gamemode); #endif diff --git a/src/gui/wxgui/GeneralSettings2.h b/src/gui/wxgui/GeneralSettings2.h index 5e27d6e2..fb0cfe87 100644 --- a/src/gui/wxgui/GeneralSettings2.h +++ b/src/gui/wxgui/GeneralSettings2.h @@ -44,6 +44,9 @@ private: wxCheckBox* m_auto_update, *m_receive_untested_releases, *m_save_screenshot; wxCheckBox* m_disable_screensaver; wxCheckBox* m_play_boot_sound; +#if BOOST_OS_WINDOWS + wxChoice* m_msw_theme; +#endif #if BOOST_OS_LINUX && defined(ENABLE_FERAL_GAMEMODE) wxCheckBox* m_feral_gamemode; #endif diff --git a/src/gui/wxgui/GettingStartedDialog.cpp b/src/gui/wxgui/GettingStartedDialog.cpp index dc9bc811..c2a0eb2e 100644 --- a/src/gui/wxgui/GettingStartedDialog.cpp +++ b/src/gui/wxgui/GettingStartedDialog.cpp @@ -17,7 +17,7 @@ #include "Cafe/TitleList/TitleList.h" -#if BOOST_OS_LINUX || BOOST_OS_MACOS +#if BOOST_OS_LINUX || BOOST_OS_MACOS || BOOST_OS_BSD #include "resource/embedded/resources.h" #endif diff --git a/src/gui/wxgui/GraphicPacksWindow2.cpp b/src/gui/wxgui/GraphicPacksWindow2.cpp index 1298f72f..e70e2a9e 100644 --- a/src/gui/wxgui/GraphicPacksWindow2.cpp +++ b/src/gui/wxgui/GraphicPacksWindow2.cpp @@ -12,7 +12,7 @@ #include "wxHelper.h" -#if BOOST_OS_LINUX || BOOST_OS_MACOS +#if BOOST_OS_LINUX || BOOST_OS_MACOS || BOOST_OS_BSD #include "resource/embedded/resources.h" #endif @@ -131,11 +131,11 @@ void GraphicPacksWindow2::FillGraphicPackList() const { auto tmp_text = m_graphic_pack_tree->GetItemText(node); m_graphic_pack_tree->SetItemText(node, tmp_text + " (Unsupported version)"); - m_graphic_pack_tree->SetItemTextColour(node, 0x0000CC); + m_graphic_pack_tree->SetItemTextColour(node, m_incompatible_colour); canEnable = false; } else if (p->IsActivated()) - m_graphic_pack_tree->SetItemTextColour(node, 0x009900); + m_graphic_pack_tree->SetItemTextColour(node, m_activated_colour); m_graphic_pack_tree->MakeCheckable(node, p->IsEnabled()); if (!canEnable) @@ -509,7 +509,7 @@ void GraphicPacksWindow2::OnTreeChoiceChanged(wxTreeEvent& event) if (!requiresRestart) { ReloadPack(graphic_pack); - m_graphic_pack_tree->SetItemTextColour(item, 0x009900); + m_graphic_pack_tree->SetItemTextColour(item, m_activated_colour); } } else @@ -517,7 +517,7 @@ void GraphicPacksWindow2::OnTreeChoiceChanged(wxTreeEvent& event) if (!requiresRestart) { DeleteShadersFromRuntimeCache(graphic_pack); - m_graphic_pack_tree->SetItemTextColour(item, *wxBLACK); + m_graphic_pack_tree->SetItemTextColour(item, m_default_colour); } GraphicPack2::DeactivateGraphicPack(graphic_pack); } diff --git a/src/gui/wxgui/GraphicPacksWindow2.h b/src/gui/wxgui/GraphicPacksWindow2.h index a79c62c1..435d1031 100644 --- a/src/gui/wxgui/GraphicPacksWindow2.h +++ b/src/gui/wxgui/GraphicPacksWindow2.h @@ -53,6 +53,9 @@ private: std::string m_gp_name, m_gp_description; float m_ratio = 0.55f; + wxColour m_default_colour = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT); + wxColour m_activated_colour = wxSystemSettings::SelectLightDark(wxColour(0x00, 0xCC, 0x00), wxColour(0x42, 0xB3, 0x42)); + wxColour m_incompatible_colour = wxSystemSettings::SelectLightDark(wxColour(0xCC, 0x00, 0x00), wxColour(0xDE, 0x49, 0x49)); wxTreeItemId FindTreeItem(const wxTreeItemId& root, const wxString& text) const; void LoadPresetSelections(const GraphicPackPtr& gp); diff --git a/src/gui/wxgui/LoggingWindow.cpp b/src/gui/wxgui/LoggingWindow.cpp index 3d830f65..c4bfdccb 100644 --- a/src/gui/wxgui/LoggingWindow.cpp +++ b/src/gui/wxgui/LoggingWindow.cpp @@ -12,7 +12,7 @@ wxDEFINE_EVENT(EVT_LOG, wxLogEvent); LoggingWindow::LoggingWindow(wxFrame* parent) : wxFrame(parent, wxID_ANY, _("Logging window"), wxDefaultPosition, wxSize(800, 600), wxDEFAULT_FRAME_STYLE | wxTAB_TRAVERSAL) { - auto* sizer = new wxBoxSizer( wxVERTICAL ); + auto* sizer = new wxBoxSizer( wxVERTICAL ); { auto filter_row = new wxBoxSizer( wxHORIZONTAL ); @@ -31,7 +31,7 @@ LoggingWindow::LoggingWindow(wxFrame* parent) sizer->Add( filter_row, 0, wxEXPAND, 5 ); } - m_log_list = new wxLogCtrl(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxScrolledWindowStyle|wxVSCROLL);//( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, NULL, wxLB_HSCROLL ); + m_log_list = new wxLogCtrl(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxScrolledWindowStyle|wxVSCROLL, true);//( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, NULL, wxLB_HSCROLL ); sizer->Add( m_log_list, 1, wxALL | wxEXPAND, 5 ); this->SetSizer( sizer ); diff --git a/src/gui/wxgui/MainWindow.cpp b/src/gui/wxgui/MainWindow.cpp index a81ce250..93597068 100644 --- a/src/gui/wxgui/MainWindow.cpp +++ b/src/gui/wxgui/MainWindow.cpp @@ -51,11 +51,11 @@ #define exit(__c) _Exit(__c) #endif -#if BOOST_OS_LINUX || BOOST_OS_MACOS +#if BOOST_OS_LINUX || BOOST_OS_MACOS || BOOST_OS_BSD #include "resource/embedded/resources.h" #endif -#if BOOST_OS_LINUX && HAS_WAYLAND +#if ( BOOST_OS_LINUX || BOOST_OS_BSD ) && HAS_WAYLAND #include "wxgui/helpers/wxWayland.h" #endif @@ -710,7 +710,7 @@ void MainWindow::OnInstallUpdate(wxCommandEvent& event) break; if (modalChoice == wxID_OK) { - #if BOOST_OS_LINUX || BOOST_OS_MACOS + #if BOOST_OS_LINUX || BOOST_OS_MACOS || BOOST_OS_BSD fs::path dirPath((const char*)(openDirDialog.GetPath().fn_str())); #else fs::path dirPath(openDirDialog.GetPath().fn_str()); @@ -812,7 +812,7 @@ void MainWindow::TogglePadView() m_padView->Show(true); -#if BOOST_OS_LINUX && HAS_WAYLAND +#if ( BOOST_OS_LINUX || BOOST_OS_BSD ) && HAS_WAYLAND if (wxWlIsWaylandWindow(m_padView)) wxWlSetAppId(m_padView, "info.cemu.Cemu"); #endif @@ -1299,7 +1299,7 @@ void MainWindow::LoadSettings() if (config.window_position != Vector2i{ -1,-1 }) this->SetPosition({ config.window_position.x, config.window_position.y }); - if (config.window_size != Vector2i{ -1,-1 }) + if (config.window_size.x > 0 && config.window_size.y > 0) { this->SetSize({ config.window_size.x, config.window_size.y }); @@ -1861,7 +1861,7 @@ public: scrolledWindow->SetSizer(m_scrolledSizer); scrolledWindow->FitInside(); scrolledWindow->SetScrollRate(25, 25); - mainSizer->Add(scrolledWindow, wxSizerFlags(1).Expand().Border(wxLEFT | wxRIGHT, 10)); + mainSizer->Add(scrolledWindow, wxSizerFlags(1).Expand().Border(wxLEFT, 10)); SetSizer(mainSizer); CentreOnParent(); @@ -1872,7 +1872,7 @@ public: auto versionString = formatWxString(_("Cemu\nVersion {0}\nCompiled on {1}\nOriginal authors: {2}"), BUILD_VERSION_STRING, BUILD_DATE, "Exzap, Petergov"); sizer->Add(new wxStaticText(parent, wxID_ANY, versionString), wxSizerFlags().Border(wxALL, 3).Border(wxTOP, 10)); - sizer->Add(new wxHyperlinkCtrl(parent, wxID_ANY, "https://cemu.info", "https://cemu.info"), wxSizerFlags().Expand().Border(wxTOP | wxBOTTOM, 3)); + sizer->Add(new wxHyperlinkCtrl(parent, wxID_ANY, "https://cemu.info", "https://cemu.info", wxDefaultPosition, wxDefaultSize, (wxHL_CONTEXTMENU|wxNO_BORDER|wxHL_ALIGN_LEFT)), wxSizerFlags().Expand().Border(wxTOP | wxBOTTOM, 3)); sizer->AddSpacer(3); sizer->Add(new wxStaticLine(parent), wxSizerFlags().Expand().Border(wxRIGHT, 4)); @@ -1893,7 +1893,7 @@ public: { wxSizer* lineSizer = new wxBoxSizer(wxHORIZONTAL); lineSizer->Add(new wxStaticText(parent, wxID_ANY, "zLib ("), 0); - lineSizer->Add(new wxHyperlinkCtrl(parent, wxID_ANY, "https://www.zlib.net", "https://www.zlib.net"), 0); + lineSizer->Add(new wxHyperlinkCtrl(parent, wxID_ANY, "https://www.zlib.net", "https://www.zlib.net", wxDefaultPosition, wxDefaultSize, (wxHL_CONTEXTMENU|wxNO_BORDER|wxHL_ALIGN_LEFT)), 0); lineSizer->Add(new wxStaticText(parent, wxID_ANY, ")"), 0); sizer->Add(lineSizer); } @@ -1901,7 +1901,7 @@ public: { wxSizer* lineSizer = new wxBoxSizer(wxHORIZONTAL); lineSizer->Add(new wxStaticText(parent, wxID_ANY, "wxWidgets ("), 0); - lineSizer->Add(new wxHyperlinkCtrl(parent, wxID_ANY, "https://www.wxwidgets.org/", "https://www.wxwidgets.org/"), 0); + lineSizer->Add(new wxHyperlinkCtrl(parent, wxID_ANY, "https://www.wxwidgets.org/", "https://www.wxwidgets.org/", wxDefaultPosition, wxDefaultSize, (wxHL_CONTEXTMENU|wxNO_BORDER|wxHL_ALIGN_LEFT)), 0); lineSizer->Add(new wxStaticText(parent, wxID_ANY, ")"), 0); sizer->Add(lineSizer); } @@ -1909,7 +1909,7 @@ public: { wxSizer* lineSizer = new wxBoxSizer(wxHORIZONTAL); lineSizer->Add(new wxStaticText(parent, wxID_ANY, "OpenSSL ("), 0); - lineSizer->Add(new wxHyperlinkCtrl(parent, wxID_ANY, "https://www.openssl.org/", "https://www.openssl.org/"), 0); + lineSizer->Add(new wxHyperlinkCtrl(parent, wxID_ANY, "https://www.openssl.org/", "https://www.openssl.org/", wxDefaultPosition, wxDefaultSize, (wxHL_CONTEXTMENU|wxNO_BORDER|wxHL_ALIGN_LEFT)), 0); lineSizer->Add(new wxStaticText(parent, wxID_ANY, ")"), 0); sizer->Add(lineSizer); } @@ -1917,7 +1917,7 @@ public: { wxSizer* lineSizer = new wxBoxSizer(wxHORIZONTAL); lineSizer->Add(new wxStaticText(parent, wxID_ANY, "libcurl ("), 0); - lineSizer->Add(new wxHyperlinkCtrl(parent, wxID_ANY, "https://curl.haxx.se/libcurl/", "https://curl.haxx.se/libcurl/"), 0); + lineSizer->Add(new wxHyperlinkCtrl(parent, wxID_ANY, "https://curl.haxx.se/libcurl/", "https://curl.haxx.se/libcurl/", wxDefaultPosition, wxDefaultSize, (wxHL_CONTEXTMENU|wxNO_BORDER|wxHL_ALIGN_LEFT)), 0); lineSizer->Add(new wxStaticText(parent, wxID_ANY, ")"), 0); sizer->Add(lineSizer); } @@ -1925,7 +1925,7 @@ public: { wxSizer* lineSizer = new wxBoxSizer(wxHORIZONTAL); lineSizer->Add(new wxStaticText(parent, wxID_ANY, "imgui ("), 0); - lineSizer->Add(new wxHyperlinkCtrl(parent, wxID_ANY, "https://github.com/ocornut/imgui", "https://github.com/ocornut/imgui"), 0); + lineSizer->Add(new wxHyperlinkCtrl(parent, wxID_ANY, "https://github.com/ocornut/imgui", "https://github.com/ocornut/imgui", wxDefaultPosition, wxDefaultSize, (wxHL_CONTEXTMENU|wxNO_BORDER|wxHL_ALIGN_LEFT)), 0); lineSizer->Add(new wxStaticText(parent, wxID_ANY, ")"), 0); sizer->Add(lineSizer); } @@ -1933,7 +1933,7 @@ public: { wxSizer* lineSizer = new wxBoxSizer(wxHORIZONTAL); lineSizer->Add(new wxStaticText(parent, wxID_ANY, "fontawesome ("), 0); - lineSizer->Add(new wxHyperlinkCtrl(parent, wxID_ANY, "https://github.com/FortAwesome/Font-Awesome", "https://github.com/FortAwesome/Font-Awesome"), 0); + lineSizer->Add(new wxHyperlinkCtrl(parent, wxID_ANY, "https://github.com/FortAwesome/Font-Awesome", "https://github.com/FortAwesome/Font-Awesome", wxDefaultPosition, wxDefaultSize, (wxHL_CONTEXTMENU|wxNO_BORDER|wxHL_ALIGN_LEFT)), 0); lineSizer->Add(new wxStaticText(parent, wxID_ANY, ")"), 0); sizer->Add(lineSizer); } @@ -1941,7 +1941,7 @@ public: { wxSizer* lineSizer = new wxBoxSizer(wxHORIZONTAL); lineSizer->Add(new wxStaticText(parent, wxID_ANY, "boost ("), 0); - lineSizer->Add(new wxHyperlinkCtrl(parent, wxID_ANY, "https://www.boost.org", "https://www.boost.org"), 0); + lineSizer->Add(new wxHyperlinkCtrl(parent, wxID_ANY, "https://www.boost.org", "https://www.boost.org", wxDefaultPosition, wxDefaultSize, (wxHL_CONTEXTMENU|wxNO_BORDER|wxHL_ALIGN_LEFT)), 0); lineSizer->Add(new wxStaticText(parent, wxID_ANY, ")"), 0); sizer->Add(lineSizer); } @@ -1949,7 +1949,7 @@ public: { wxSizer* lineSizer = new wxBoxSizer(wxHORIZONTAL); lineSizer->Add(new wxStaticText(parent, wxID_ANY, "libusb ("), 0); - lineSizer->Add(new wxHyperlinkCtrl(parent, wxID_ANY, "https://libusb.info", "https://libusb.info"), 0); + lineSizer->Add(new wxHyperlinkCtrl(parent, wxID_ANY, "https://libusb.info", "https://libusb.info", wxDefaultPosition, wxDefaultSize, (wxHL_CONTEXTMENU|wxNO_BORDER|wxHL_ALIGN_LEFT)), 0); lineSizer->Add(new wxStaticText(parent, wxID_ANY, ")"), 0); sizer->Add(lineSizer); } @@ -1958,7 +1958,7 @@ public: { wxSizer* lineSizer = new wxBoxSizer(wxHORIZONTAL); lineSizer->Add(new wxStaticText(parent, -1, "MoltenVK ("), 0); - lineSizer->Add(new wxHyperlinkCtrl(parent, -1, "https://github.com/KhronosGroup/MoltenVK", "https://github.com/KhronosGroup/MoltenVK"), 0); + lineSizer->Add(new wxHyperlinkCtrl(parent, -1, "https://github.com/KhronosGroup/MoltenVK", "https://github.com/KhronosGroup/MoltenVK", wxDefaultPosition, wxDefaultSize, (wxHL_CONTEXTMENU|wxNO_BORDER|wxHL_ALIGN_LEFT)), 0); lineSizer->Add(new wxStaticText(parent, -1, ")"), 0); sizer->Add(lineSizer); } @@ -1967,20 +1967,20 @@ public: { wxSizer* lineSizer = new wxBoxSizer(wxHORIZONTAL); lineSizer->Add(new wxStaticText(parent, wxID_ANY, "icons from "), 0); - lineSizer->Add(new wxHyperlinkCtrl(parent, wxID_ANY, "https://icons8.com", "https://icons8.com"), 0); + lineSizer->Add(new wxHyperlinkCtrl(parent, wxID_ANY, "https://icons8.com", "https://icons8.com", wxDefaultPosition, wxDefaultSize, (wxHL_CONTEXTMENU|wxNO_BORDER|wxHL_ALIGN_LEFT)), 0); sizer->Add(lineSizer); } // Lato font (are we still using it?) { wxSizer* lineSizer = new wxBoxSizer(wxHORIZONTAL); - lineSizer->Add(new wxStaticText(parent, wxID_ANY, "\"Lato\" font by tyPoland Lukasz Dziedzic (OFL, V1.1)"), 0); + lineSizer->Add(new wxStaticText(parent, wxID_ANY, "\"Lato\" font by tyPoland Lukasz Dziedzic (OFL, V1.1)", wxDefaultPosition, wxDefaultSize, (wxHL_CONTEXTMENU|wxNO_BORDER|wxHL_ALIGN_LEFT)), 0); sizer->Add(lineSizer); } // SDL { wxSizer* lineSizer = new wxBoxSizer(wxHORIZONTAL); - lineSizer->Add(new wxStaticText(parent, wxID_ANY, "SDL ("), 0); - lineSizer->Add(new wxHyperlinkCtrl(parent, wxID_ANY, "https://github.com/libsdl-org/SDL", "https://github.com/libsdl-org/SDL"), 0); + lineSizer->Add(new wxStaticText(parent, wxID_ANY, "SDL ("), 0, wxALIGN_NOT, 0); + lineSizer->Add(new wxHyperlinkCtrl(parent, wxID_ANY, "https://github.com/libsdl-org/SDL", "https://github.com/libsdl-org/SDL", wxDefaultPosition, wxDefaultSize, (wxHL_CONTEXTMENU|wxNO_BORDER|wxHL_ALIGN_LEFT)), 0); lineSizer->Add(new wxStaticText(parent, wxID_ANY, ")"), 0); sizer->Add(lineSizer); } @@ -1988,9 +1988,9 @@ public: { wxSizer* lineSizer = new wxBoxSizer(wxHORIZONTAL); lineSizer->Add(new wxStaticText(parent, wxID_ANY, "Modified ih264 from Android project ("), 0); - lineSizer->Add(new wxHyperlinkCtrl(parent, wxID_ANY, "Source", "https://cemu.info/oss/ih264d.zip"), 0); - lineSizer->Add(new wxStaticText(parent, wxID_ANY, " "), 0); - wxHyperlinkCtrl* noticeLink = new wxHyperlinkCtrl(parent, wxID_ANY, "NOTICE", ""); + lineSizer->Add(new wxHyperlinkCtrl(parent, wxID_ANY, "Source", "https://cemu.info/oss/ih264d.zip", wxDefaultPosition, wxDefaultSize, (wxHL_CONTEXTMENU|wxNO_BORDER|wxHL_ALIGN_LEFT)), 0); + lineSizer->Add(new wxStaticText(parent, wxID_ANY, " "), 0); + wxHyperlinkCtrl* noticeLink = new wxHyperlinkCtrl(parent, wxID_ANY, "NOTICE", "", wxDefaultPosition, wxDefaultSize, (wxHL_CONTEXTMENU|wxNO_BORDER|wxHL_ALIGN_LEFT)); noticeLink->Bind(wxEVT_LEFT_DOWN, [](wxMouseEvent& event) { fs::path tempPath = fs::temp_directory_path(); @@ -2320,6 +2320,8 @@ void MainWindow::RecreateMenu() if (!std::getenv("APPIMAGE")) { m_check_update_menu->Enable(false); } +#elif BOOST_OS_BSD // BSD users must update from source so disable update checks + m_check_update_menu->Enable(false); #endif helpMenu->AppendSeparator(); helpMenu->Append(MAINFRAME_MENU_ID_HELP_ABOUT, _("&About Cemu")); diff --git a/src/gui/wxgui/MainWindow.h b/src/gui/wxgui/MainWindow.h index 2f251ca8..07464188 100644 --- a/src/gui/wxgui/MainWindow.h +++ b/src/gui/wxgui/MainWindow.h @@ -3,7 +3,6 @@ #include #include #include -#include "wxcomponents/checkedlistctrl.h" #include "wxgui/PadViewFrame.h" #include "wxgui/MemorySearcherTool.h" diff --git a/src/gui/wxgui/MemorySearcherTool.cpp b/src/gui/wxgui/MemorySearcherTool.cpp index 8faf87d9..cc99fb8b 100644 --- a/src/gui/wxgui/MemorySearcherTool.cpp +++ b/src/gui/wxgui/MemorySearcherTool.cpp @@ -51,7 +51,6 @@ MemorySearcherTool::MemorySearcherTool(wxFrame* parent) : wxFrame(parent, wxID_ANY, _("Memory Searcher"), wxDefaultPosition, wxSize(600, 540), wxDEFAULT_FRAME_STYLE | wxTAB_TRAVERSAL) { this->SetSizeHints(wxDefaultSize, wxDefaultSize); - this->wxWindowBase::SetBackgroundColour(*wxWHITE); this->wxTopLevelWindowBase::SetMinSize(wxSize(600, 540)); auto* sizer = new wxBoxSizer(wxVERTICAL); diff --git a/src/gui/wxgui/MemorySearcherTool.h b/src/gui/wxgui/MemorySearcherTool.h index 6ee36fbb..77820524 100644 --- a/src/gui/wxgui/MemorySearcherTool.h +++ b/src/gui/wxgui/MemorySearcherTool.h @@ -4,6 +4,8 @@ #include #include +#include + #include "Cafe/HW/MMU/MMU.h" #include "util/helpers/helpers.h" #include "wxgui/helpers/wxCustomEvents.h" diff --git a/src/gui/wxgui/PadViewFrame.cpp b/src/gui/wxgui/PadViewFrame.cpp index 7640342b..fd5949d9 100644 --- a/src/gui/wxgui/PadViewFrame.cpp +++ b/src/gui/wxgui/PadViewFrame.cpp @@ -13,7 +13,7 @@ #include "wxgui/helpers/wxHelpers.h" #include "input/InputManager.h" -#if BOOST_OS_LINUX || BOOST_OS_MACOS +#if BOOST_OS_LINUX || BOOST_OS_MACOS || BOOST_OS_BSD #include "resource/embedded/resources.h" #endif #include "wxHelper.h" diff --git a/src/gui/wxgui/TitleManager.cpp b/src/gui/wxgui/TitleManager.cpp index e94bb5bf..4dbf9341 100644 --- a/src/gui/wxgui/TitleManager.cpp +++ b/src/gui/wxgui/TitleManager.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include "Cafe/IOSU/legacy/iosu_crypto.h" #include "config/ActiveSettings.h" @@ -60,14 +61,15 @@ wxPanel* TitleManager::CreateTitleManagerPage() m_filter->Bind(wxEVT_TEXT, &TitleManager::OnFilterChanged, this); row->Add(m_filter, 1, wxALL | wxEXPAND, 5); - const wxImage refresh = wxBITMAP_PNG_FROM_DATA(PNG_REFRESH).ConvertToImage(); + const wxImage refresh = wxHelper::LoadThemedBitmapFromPNG(PNG_REFRESH_png, sizeof(PNG_REFRESH_png), wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT)).ConvertToImage(); m_refresh_button = new wxBitmapButton(panel, wxID_ANY, refresh.Scale(16, 16)); m_refresh_button->Disable(); m_refresh_button->Bind(wxEVT_BUTTON, &TitleManager::OnRefreshButton, this); m_refresh_button->SetToolTip(_("Refresh")); row->Add(m_refresh_button, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5); - auto* help_button = new wxStaticBitmap(panel, wxID_ANY, wxBITMAP_PNG_FROM_DATA(PNG_HELP)); + const wxBitmap help_bitmap = wxHelper::LoadThemedBitmapFromPNG(PNG_HELP_png, sizeof(PNG_HELP_png), wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT)); + auto* help_button = new wxStaticBitmap(panel, wxID_ANY, help_bitmap); help_button->SetToolTip(formatWxString(_("The following prefixes are supported:\n{0}\n{1}\n{2}\n{3}\n{4}"), "titleid:", "name:", "type:", "version:", "region:")); row->Add(help_button, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5); diff --git a/src/gui/wxgui/canvas/OpenGLCanvas.cpp b/src/gui/wxgui/canvas/OpenGLCanvas.cpp index 4e48e26c..0eb76a3d 100644 --- a/src/gui/wxgui/canvas/OpenGLCanvas.cpp +++ b/src/gui/wxgui/canvas/OpenGLCanvas.cpp @@ -124,7 +124,7 @@ public: #if BOOST_OS_WINDOWS if(wglSwapIntervalEXT) wglSwapIntervalEXT(configValue); // 1 = enabled, 0 = disabled -#elif BOOST_OS_LINUX +#elif BOOST_OS_LINUX || BOOST_OS_BSD if (eglSwapInterval) { if (eglSwapInterval(eglGetCurrentDisplay(), configValue) == EGL_FALSE) diff --git a/src/gui/wxgui/canvas/VulkanCanvas.cpp b/src/gui/wxgui/canvas/VulkanCanvas.cpp index 79d4de3b..df80b000 100644 --- a/src/gui/wxgui/canvas/VulkanCanvas.cpp +++ b/src/gui/wxgui/canvas/VulkanCanvas.cpp @@ -1,7 +1,7 @@ #include "wxgui/canvas/VulkanCanvas.h" #include "Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.h" -#if BOOST_OS_LINUX && HAS_WAYLAND +#if ( BOOST_OS_LINUX || BOOST_OS_BSD ) && HAS_WAYLAND #include "wxgui/helpers/wxWayland.h" #endif @@ -13,10 +13,13 @@ VulkanCanvas::VulkanCanvas(wxWindow* parent, const wxSize& size, bool is_main_wi { Bind(wxEVT_PAINT, &VulkanCanvas::OnPaint, this); Bind(wxEVT_SIZE, &VulkanCanvas::OnResize, this); +#if __WXMSW__ + MSWDisableComposited(); +#endif auto& canvas = is_main_window ? WindowSystem::GetWindowInfo().canvas_main : WindowSystem::GetWindowInfo().canvas_pad; canvas = initHandleContextFromWxWidgetsWindow(this); - #if BOOST_OS_LINUX && HAS_WAYLAND + #if ( BOOST_OS_LINUX || BOOST_OS_BSD ) && HAS_WAYLAND if (canvas.backend == WindowSystem::WindowHandleInfo::Backend::Wayland) { m_subsurface = std::make_unique(this); @@ -69,7 +72,7 @@ void VulkanCanvas::OnResize(wxSizeEvent& event) if (size.GetWidth() == 0 || size.GetHeight() == 0) return; -#if BOOST_OS_LINUX && HAS_WAYLAND +#if ( BOOST_OS_LINUX || BOOST_OS_BSD ) && HAS_WAYLAND if(m_subsurface) { auto sRect = GetScreenRect(); diff --git a/src/gui/wxgui/canvas/VulkanCanvas.h b/src/gui/wxgui/canvas/VulkanCanvas.h index 3db31520..731638f3 100644 --- a/src/gui/wxgui/canvas/VulkanCanvas.h +++ b/src/gui/wxgui/canvas/VulkanCanvas.h @@ -9,7 +9,7 @@ class VulkanCanvas : public IRenderCanvas, public wxWindow { -#if BOOST_OS_LINUX && HAS_WAYLAND +#if ( BOOST_OS_LINUX || BOOST_OS_BSD ) && HAS_WAYLAND std::unique_ptr m_subsurface; #endif public: diff --git a/src/gui/wxgui/components/TextList.cpp b/src/gui/wxgui/components/TextList.cpp index b7ff59e5..f5e3f133 100644 --- a/src/gui/wxgui/components/TextList.cpp +++ b/src/gui/wxgui/components/TextList.cpp @@ -1,5 +1,8 @@ #include "wxgui/wxgui.h" #include "TextList.h" + +#include "debugger/DisasmCtrl.h" + #include #include @@ -22,9 +25,11 @@ TextList::TextList(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wx : wxControl(parent, id, pos, size, style), wxScrollHelper(this) { m_font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT); - wxWindowBase::SetBackgroundStyle(wxBG_STYLE_PAINT); + this->wxWindowBase::SetBackgroundStyle(wxBG_STYLE_PAINT); - wxClientDC dc(this); + wxInfoDC dc(this); + this->DoPrepareReadOnlyDC(dc); + dc.SetFont(m_font); m_line_height = dc.GetCharHeight(); m_char_width = dc.GetCharWidth(); @@ -76,7 +81,7 @@ void TextList::RefreshLine(uint32 line) wxSize TextList::DoGetVirtualSize() const { - return {wxDefaultCoord, (int)(m_element_count + 1) * m_line_height}; + return {wxDefaultCoord, (int)m_element_count * m_line_height}; } void TextList::DoSetSize(int x, int y, int width, int height, int sizeFlags) @@ -252,7 +257,6 @@ void TextList::OnContextMenu(wxContextMenuEvent& event) OnContextMenu(clientPosition, line); } - void TextList::OnTooltipTimer(wxTimerEvent& event) { m_tooltip_window->Hide(); @@ -278,8 +282,7 @@ void TextList::OnTooltipTimer(wxTimerEvent& event) void TextList::OnPaintEvent(wxPaintEvent& event) { - wxBufferedPaintDC dc(m_targetWindow, wxBUFFER_VIRTUAL_AREA); - dc.SetFont(m_font); + wxAutoBufferedPaintDC dc(m_targetWindow); // get window position auto position = GetPosition(); @@ -291,9 +294,10 @@ void TextList::OnPaintEvent(wxPaintEvent& event) position.y = (rect_update.y / m_line_height) * m_line_height; // paint background - const wxColour window_colour = COLOR_WHITE; - dc.SetBrush(window_colour); - dc.SetPen(window_colour); + dc.SetFont(m_font); + const wxColour window_colour = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW); + dc.SetBrush(GetBackgroundColour()); + dc.SetPen(*wxTRANSPARENT_PEN); dc.DrawRectangle(rect_update); //// paint selection @@ -312,6 +316,5 @@ void TextList::OnPaintEvent(wxPaintEvent& event) OnDraw(dc, start, count, position); - - this->Update(); + // removed Update() here since all text is white } \ No newline at end of file diff --git a/src/gui/wxgui/components/TextList.h b/src/gui/wxgui/components/TextList.h index 6a281533..9a722a21 100644 --- a/src/gui/wxgui/components/TextList.h +++ b/src/gui/wxgui/components/TextList.h @@ -5,12 +5,6 @@ #include #include -#define COLOR_BLACK 0xFF000000 -#define COLOR_GREY 0xFFA0A0A0 -#define COLOR_LIGHT_GREY 0xFFE0E0E0 -#define COLOR_WHITE 0xFFFFFFFF -#define COLOR_RED 0xFF0000FF - class TextList : public wxControl, public wxScrollHelper { diff --git a/src/gui/wxgui/components/wxDownloadManagerList.cpp b/src/gui/wxgui/components/wxDownloadManagerList.cpp index cfc3c52d..132435ae 100644 --- a/src/gui/wxgui/components/wxDownloadManagerList.cpp +++ b/src/gui/wxgui/components/wxDownloadManagerList.cpp @@ -1,12 +1,12 @@ #include "wxgui/components/wxDownloadManagerList.h" +#include "wxHelper.h" #include "wxgui/helpers/wxHelpers.h" #include "util/helpers/SystemException.h" #include "Cafe/TitleList/GameInfo.h" #include "wxgui/components/wxGameList.h" #include "wxgui/helpers/wxCustomEvents.h" -#include #include #include #include @@ -167,8 +167,8 @@ wxItemAttr* wxDownloadManagerList::OnGetItemAttr(long item) const } } - const wxColour kSecondColor{ 0xFDF9F2 }; - static wxListItemAttr s_coloured_attr(GetTextColour(), kSecondColor, GetFont()); + wxColour bgColourSecondary = wxHelper::CalculateAccentColour(GetBackgroundColour()); + static wxListItemAttr s_coloured_attr(GetTextColour(), bgColourSecondary, GetFont()); return item % 2 == 0 ? nullptr : &s_coloured_attr; } diff --git a/src/gui/wxgui/components/wxGameList.cpp b/src/gui/wxgui/components/wxGameList.cpp index bb6e9653..f807042c 100644 --- a/src/gui/wxgui/components/wxGameList.cpp +++ b/src/gui/wxgui/components/wxGameList.cpp @@ -140,32 +140,32 @@ wxGameList::wxGameList(wxWindow* parent, wxWindowID id) { const auto& config = GetWxGUIConfig(); + char transparent_bitmap[kIconWidth * kIconWidth * 4] = {}; + memset((void*)transparent_bitmap, wxSystemSettings::GetAppearance().IsDark() ? 0xFF : 0x00, sizeof(transparent_bitmap)); + wxBitmap blank(transparent_bitmap, kIconWidth, kIconWidth); + + m_image_list_data = {}; + m_image_list_data.emplace_back(wxBitmapBundle::FromBitmap(blank)); + wxListCtrl::SetNormalImages(m_image_list_data); + + m_image_list_small_data = {}; + wxBitmap::Rescale(blank, {kListIconWidth, kListIconWidth}); + m_image_list_small_data.emplace_back(wxBitmapBundle::FromBitmap(blank)); + wxListCtrl::SetSmallImages(m_image_list_small_data); + InsertColumn(ColumnHiddenName, "", wxLIST_FORMAT_LEFT, 0); if(config.show_icon_column) - InsertColumn(ColumnIcon, _("Icon"), wxLIST_FORMAT_LEFT, kListIconWidth); + InsertColumn(ColumnIcon, _("Icon"), wxLIST_FORMAT_LEFT, GetColumnDefaultWidth(ColumnIcon)); else InsertColumn(ColumnIcon, _("Icon"), wxLIST_FORMAT_LEFT, 0); InsertColumn(ColumnName, _("Game"), wxLIST_FORMAT_LEFT, config.column_width.name); - InsertColumn(ColumnVersion, _("Version"), wxLIST_FORMAT_RIGHT, config.column_width.version); - InsertColumn(ColumnDLC, _("DLC"), wxLIST_FORMAT_RIGHT, config.column_width.dlc); + InsertColumn(ColumnVersion, _("Version"), wxLIST_FORMAT_LEFT, config.column_width.version); + InsertColumn(ColumnDLC, _("DLC"), wxLIST_FORMAT_LEFT, config.column_width.dlc); InsertColumn(ColumnGameTime, _("You've played"), wxLIST_FORMAT_LEFT, config.column_width.game_time); InsertColumn(ColumnGameStarted, _("Last played"), wxLIST_FORMAT_LEFT, config.column_width.game_started); InsertColumn(ColumnRegion, _("Region"), wxLIST_FORMAT_LEFT, config.column_width.region); InsertColumn(ColumnTitleID, _("Title ID"), wxLIST_FORMAT_LEFT, config.column_width.title_id); - const char transparent_bitmap[kIconWidth * kIconWidth * 4] = {0}; - wxBitmap blank(transparent_bitmap, kIconWidth, kIconWidth); - blank.UseAlpha(true); - - m_image_list = new wxImageList(kIconWidth, kIconWidth); - m_image_list->Add(blank); - wxListCtrl::SetImageList(m_image_list, wxIMAGE_LIST_NORMAL); - - m_image_list_small = new wxImageList(kListIconWidth, kListIconWidth); - wxBitmap::Rescale(blank, {kListIconWidth, kListIconWidth}); - m_image_list_small->Add(blank); - wxListCtrl::SetImageList(m_image_list_small, wxIMAGE_LIST_SMALL); - m_tooltip_window = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNO_BORDER); auto* tooltip_sizer = new wxBoxSizer(wxVERTICAL); tooltip_sizer->Add(new wxStaticText(m_tooltip_window, wxID_ANY, _("This game entry seems to be either an update or the base game was merged with update data\nBroken game dumps cause various problems during emulation and may even stop working at all in future Cemu versions\nPlease make sure the base game is intact and install updates only with the File->Install Update/DLC option")), 0, wxALL, 5); @@ -210,10 +210,6 @@ wxGameList::~wxGameList() m_async_task_count.increment(); m_async_worker_thread.join(); - // destroy image lists - delete m_image_list; - delete m_image_list_small; - // clear image cache m_icon_cache_mtx.lock(); m_icon_cache.clear(); @@ -306,6 +302,12 @@ int wxGameList::GetColumnDefaultWidth(int column) switch (column) { case ColumnIcon: +#if __WXMSW__ + // note: this is another workaround that could be used to fix the icon offset, but instead of this there's a vcpkg patch for wxWidgets that fixes the icon offset + // wxWidgets offsets the icon in the REPORT view so it's cut off if the column width is set to 64px, see https://github.com/wxWidgets/wxWidgets/blob/09f433faf39aab3f25b3c564b82448bb845fae56/src/msw/listctrl.cpp#L3091 + // so add 6px to the column width to compensate, and add another 6px to the right side so that it has equal whitespace on both sides + // return kListIconWidth + 6 + 6; +#endif return kListIconWidth; case ColumnName: return DefaultColumnSize::name; @@ -408,10 +410,11 @@ void wxGameList::SetStyle(Style style, bool save) switch(style) { case Style::kIcons: - wxListCtrl::SetImageList(m_image_list, wxIMAGE_LIST_NORMAL); + wxListCtrl::SetNormalImages(m_image_list_data); break; case Style::kSmallIcons: - wxListCtrl::SetImageList(m_image_list_small, wxIMAGE_LIST_NORMAL); + case Style::kList: + wxListCtrl::SetSmallImages(m_image_list_small_data); break; } @@ -464,7 +467,7 @@ void wxGameList::UpdateItemColors(sint32 startIndex) if (GetConfig().IsGameListFavorite(titleId)) { SetItemBackgroundColour(i, kFavoriteColor); - SetItemTextColour(i, 0x000000UL); + SetItemTextColour(i, wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT)); } else if ((i&1) != 0) { @@ -638,6 +641,7 @@ enum ContextMenuEntries kContextMenuCopyTitleId, kContextMenuCopyTitleImage }; + void wxGameList::OnContextMenu(wxContextMenuEvent& event) { auto& config = GetConfig(); @@ -809,33 +813,34 @@ void wxGameList::OnContextMenuSelected(wxCommandEvent& event) } case kContextMenuCopyTitleName: { - if (wxTheClipboard->Open()) + if (wxClipboard::Get()->Open()) { - wxTheClipboard->SetData(new wxTextDataObject(wxString::FromUTF8(gameInfo.GetTitleName()))); - wxTheClipboard->Close(); + wxClipboard::Get()->SetData(new wxTextDataObject(wxString::FromUTF8(gameInfo.GetTitleName()))); + wxClipboard::Get()->Close(); } break; } case kContextMenuCopyTitleId: { - if (wxTheClipboard->Open()) + if (wxClipboard::Get()->Open()) { - wxTheClipboard->SetData(new wxTextDataObject(fmt::format("{:016x}", gameInfo.GetBaseTitleId()))); - wxTheClipboard->Close(); + wxClipboard::Get()->SetData(new wxTextDataObject(fmt::format("{:016x}", gameInfo.GetBaseTitleId()))); + wxClipboard::Get()->Close(); } break; } case kContextMenuCopyTitleImage: { - if (wxTheClipboard->Open()) + if (wxClipboard::Get()->Open()) { int icon_large; int icon_small; if (!QueryIconForTitle(title_id, icon_large, icon_small)) break; - auto icon = m_image_list->GetBitmap(icon_large); - wxTheClipboard->SetData(new wxBitmapDataObject(icon)); - wxTheClipboard->Close(); + auto icon = m_image_list_data[icon_large]; + auto newClipboardData = wxBitmapDataObject(icon.GetBitmap(icon.GetDefaultSize())); + wxClipboard::Get()->SetData(&newClipboardData); + wxClipboard::Get()->Close(); } break; } @@ -994,7 +999,7 @@ void wxGameList::ApplyGameListColumnWidths() const auto& config = GetWxGUIConfig(); wxWindowUpdateLocker lock(this); if(config.show_icon_column) - SetColumnWidth(ColumnIcon, kListIconWidth); + SetColumnWidth(ColumnIcon, GetColumnDefaultWidth(ColumnIcon)); else SetColumnWidth(ColumnIcon, 0); SetColumnWidth(ColumnName, config.column_width.name); @@ -1109,6 +1114,23 @@ void wxGameList::OnGameEntryUpdatedByTitleId(wxTitleIdEvent& event) TitleId baseTitleId = gameInfo.GetBaseTitleId(); bool isNewEntry = false; + if (m_style == Style::kIcons) + { + wxListCtrl::SetNormalImages(m_image_list_data); + } + else if (m_style == Style::kSmallIcons) + { + wxListCtrl::SetSmallImages(m_image_list_small_data); + } + else if (m_style == Style::kList) + { + wxListCtrl::SetSmallImages(m_image_list_small_data); + } + + int icon = -1; /* 0 is the default empty icon */ + int icon_small = -1; /* 0 is the default empty icon */ + QueryIconForTitle(baseTitleId, icon, icon_small); + auto index = FindListItemByTitleId(baseTitleId); if(index == wxNOT_FOUND) { @@ -1118,10 +1140,6 @@ void wxGameList::OnGameEntryUpdatedByTitleId(wxTitleIdEvent& event) isNewEntry = true; } - int icon = 0; /* 0 is the default empty icon */ - int icon_small = 0; /* 0 is the default empty icon */ - QueryIconForTitle(baseTitleId, icon, icon_small); - if (m_style == Style::kList) { SetItemColumnImage(index, ColumnIcon, icon_small); @@ -1324,17 +1342,18 @@ void wxGameList::AsyncWorkerThread() wxMemoryInputStream tmp_stream(tgaData->data(), tgaData->size()); const wxImage image(tmp_stream); // todo - is wxImageList thread safe? - int icon = m_image_list->Add(image.Scale(kIconWidth, kIconWidth, wxIMAGE_QUALITY_BICUBIC)); - int icon_small = m_image_list_small->Add(image.Scale(kListIconWidth, kListIconWidth, wxIMAGE_QUALITY_BICUBIC)); + m_image_list_data.emplace_back(image.Scale(kIconWidth, kIconWidth, wxIMAGE_QUALITY_BICUBIC)); + m_image_list_small_data.emplace_back(image.Scale(kListIconWidth, kListIconWidth, wxIMAGE_QUALITY_BICUBIC)); // store in cache m_icon_cache_mtx.lock(); - m_icon_cache.try_emplace(titleId, icon, icon_small); + m_icon_cache.try_emplace(titleId, m_image_list_data.size() - 1, m_image_list_small_data.size() - 1); m_icon_cache_mtx.unlock(); iconSuccessfullyLoaded = true; } else { cemuLog_log(LogType::Force, "Failed to load icon for title {:016x}", titleId); + cemu_assert_debug(false); } titleInfo.Unmount(tempMountPath); // notify UI about loaded icon @@ -1373,7 +1392,7 @@ void wxGameList::DeleteCachedStrings() m_name_cache.clear(); } -#if BOOST_OS_LINUX +#if BOOST_OS_LINUX || BOOST_OS_BSD void wxGameList::CreateShortcut(GameInfo2& gameInfo) { const auto titleId = gameInfo.GetBaseTitleId(); @@ -1411,7 +1430,9 @@ void wxGameList::CreateShortcut(GameInfo2& gameInfo) iconPath = outIconDir / fmt::format("{:016x}.png", gameInfo.GetBaseTitleId()); wxFileOutputStream pngFileStream(_pathToUtf8(iconPath.value())); - auto image = m_image_list->GetIcon(iconIndex).ConvertToImage(); + const auto icon = m_image_list_data[iconIndex]; + wxBitmap bitmap{icon.GetBitmap(wxDefaultSize)}; + wxImage image = bitmap.ConvertToImage(); wxPNGHandler pngHandler; if (!pngHandler.SaveFile(&image, pngFileStream, false)) { @@ -1502,7 +1523,9 @@ void wxGameList::CreateShortcut(GameInfo2& gameInfo) iconPath = outIconDir / fmt::format("{:016x}.png", gameInfo.GetBaseTitleId()); wxFileOutputStream pngFileStream(_pathToUtf8(iconPath.value())); - auto image = m_image_list->GetIcon(iconIndex).ConvertToImage(); + const auto icon = m_image_list_data[iconIndex]; + wxBitmap bitmap{icon.GetBitmap(wxDefaultSize)}; + wxImage image = bitmap.ConvertToImage(); wxPNGHandler pngHandler; if (!pngHandler.SaveFile(&image, pngFileStream, false)) { @@ -1609,19 +1632,14 @@ void wxGameList::CreateShortcut(GameInfo2& gameInfo) cemuLog_log(LogType::Force, "Icon hasn't loaded"); return; } - const auto icon = m_image_list->GetIcon(iconIdx); + const auto icon = m_image_list_data[iconIdx]; const auto folder = ActiveSettings::GetUserDataPath("icons"); if (!fs::exists(folder) && !fs::create_directories(folder)) { cemuLog_log(LogType::Force, "Failed to create icon directory"); return; } - wxBitmap bitmap{}; - if (!bitmap.CopyFromIcon(icon)) - { - cemuLog_log(LogType::Force, "Failed to copy icon"); - return; - } + wxBitmap bitmap{icon.GetBitmap(wxDefaultSize)}; icon_path = folder / fmt::format("{:016x}.ico", titleId); auto stream = wxFileOutputStream(icon_path->wstring()); diff --git a/src/gui/wxgui/components/wxGameList.h b/src/gui/wxgui/components/wxGameList.h index 625f7976..ae2ea245 100644 --- a/src/gui/wxgui/components/wxGameList.h +++ b/src/gui/wxgui/components/wxGameList.h @@ -10,6 +10,7 @@ #include #include #include +#include #include #include "util/helpers/Semaphore.h" @@ -63,9 +64,9 @@ private: Style m_style; long GetStyleFlags(Style style) const; - inline static const wxColour kUpdateColor{ 0x3939c3 }; - inline static const wxColour kFavoriteColor{ 0xD3F6FD }; - inline static const wxColour kSecondColor{ 0xFDF9F2 }; + const wxColour kUpdateColor{ wxSystemSettings::SelectLightDark(wxColour(195, 57, 57), wxColour(84, 29, 29)) }; + const wxColour kFavoriteColor{ wxSystemSettings::SelectLightDark(wxColour(253, 246, 211), wxColour(82, 84, 48)) }; + const wxColour kSecondColor{ wxSystemSettings::SelectLightDark(wxColour(242, 249, 253), wxColour(34, 34, 34)) }; void UpdateItemColors(sint32 startIndex = 0); enum ItemColumns : int @@ -121,7 +122,7 @@ private: inline static constexpr int kListIconWidth = 64; inline static constexpr int kIconWidth = 128; - wxImageList* m_image_list, *m_image_list_small; + wxWithImages::Images m_image_list_data, m_image_list_small_data; std::mutex m_icon_cache_mtx; std::set m_icon_loaded; diff --git a/src/gui/wxgui/components/wxInputDraw.cpp b/src/gui/wxgui/components/wxInputDraw.cpp index a979a1c5..d12237c8 100644 --- a/src/gui/wxgui/components/wxInputDraw.cpp +++ b/src/gui/wxgui/components/wxInputDraw.cpp @@ -1,6 +1,7 @@ #include "wxgui/components/wxInputDraw.h" #include +#include wxInputDraw::wxInputDraw(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size) : wxWindow(parent, id, pos, size, 0, wxPanelNameStr) @@ -21,33 +22,35 @@ void wxInputDraw::OnRender(wxDC& dc) { dc.Clear(); - glm::vec2 position; - const wxPen *black, *red, *grey; - const wxBrush *black_brush, *red_brush, *grey_brush; - if(IsEnabled()) - { - position = m_position; + glm::vec2 position = m_position; - black = wxBLACK_PEN; - red = wxRED_PEN; - grey = wxGREY_PEN; + wxPen black = wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT)); + wxPen red = *wxRED_PEN; + wxPen grey = wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_GRAYTEXT)); + wxPen green = wxSystemSettings::SelectLightDark(0x336600, 0x99FF99); - black_brush = wxBLACK_BRUSH; - red_brush = wxRED_BRUSH; - grey_brush = wxGREY_BRUSH; - } - else + wxBrush black_brush = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT); + wxBrush red_brush = *wxRED_BRUSH; + wxBrush grey_brush = wxSystemSettings::GetColour(wxSYS_COLOUR_GRAYTEXT); + wxBrush green_brush = wxSystemSettings::SelectLightDark(0x336600, 0x99FF99); + + if(!IsEnabled()) { position = {}; - black = red = wxMEDIUM_GREY_PEN; - grey = wxLIGHT_GREY_PEN; + black.SetColour(black.GetColour()); + red.SetColour(wxSystemSettings::GetColour(wxSYS_COLOUR_GRAYTEXT)); + grey.SetColour(wxSystemSettings::GetColour(wxSYS_COLOUR_GRAYTEXT).MakeDisabled()); - black_brush = red_brush = wxMEDIUM_GREY_BRUSH; - grey_brush = wxLIGHT_GREY_BRUSH; + black_brush = wxSystemSettings::GetColour(wxSYS_COLOUR_GRAYTEXT); + red_brush = wxSystemSettings::GetColour(wxSYS_COLOUR_GRAYTEXT).MakeDisabled(); + grey_brush = wxSystemSettings::GetColour(wxSYS_COLOUR_GRAYTEXT).MakeDisabled(); } dc.SetBackgroundMode(wxSOLID); - dc.SetBackground(*wxWHITE_BRUSH); + dc.SetBackground(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); + dc.SetPen(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); + dc.SetBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); + dc.Clear(); const auto size = GetSize(); const auto min_size = (float)std::min(size.GetWidth(), size.GetHeight()) - 1.0f; @@ -55,16 +58,16 @@ void wxInputDraw::OnRender(wxDC& dc) // border const wxRect border{0, 0, (int)min_size, (int)min_size}; - dc.SetPen(*black); + dc.SetPen(wxSystemSettings::GetColour(wxSYS_COLOUR_GRAYTEXT)); dc.DrawRectangle(border); - dc.SetPen(IsEnabled() ? wxPen(wxColour(0x336600)) : *grey); // dark green + dc.SetPen(IsEnabled() ? green.GetColour() : grey.GetColour()); dc.DrawCircle((int)middle.x, (int)middle.y, (int)middle.x); if (m_deadzone > 0) { - dc.SetPen(*grey); - dc.SetBrush(*wxLIGHT_GREY_BRUSH); + dc.SetPen(grey); + dc.SetBrush(grey_brush); const auto deadzone_size = m_deadzone * min_size / 2.0f; dc.DrawCircle( static_cast(middle.x), @@ -73,25 +76,25 @@ void wxInputDraw::OnRender(wxDC& dc) if (length(position) >= m_deadzone) { - dc.SetPen(*red); - dc.SetBrush(*red_brush); + dc.SetPen(red); + dc.SetBrush(red_brush); if (std::abs(1.0f - length(position)) < 0.05f) { - dc.SetPen(wxPen(wxColour(0x336600))); - dc.SetBrush(wxColour(0x336600)); + dc.SetPen(green); + dc.SetBrush(green_brush); } } else { - dc.SetPen(*black); - dc.SetBrush(*black_brush); + dc.SetPen(black); + dc.SetBrush(black_brush); } } else { - dc.SetPen(*red); - dc.SetBrush(*red_brush); + dc.SetPen(red); + dc.SetBrush(red_brush); } // draw axis diff --git a/src/gui/wxgui/components/wxLogCtrl.cpp b/src/gui/wxgui/components/wxLogCtrl.cpp index 0ab38193..46ab9ad5 100644 --- a/src/gui/wxgui/components/wxLogCtrl.cpp +++ b/src/gui/wxgui/components/wxLogCtrl.cpp @@ -4,13 +4,15 @@ wxDEFINE_EVENT(EVT_ON_LIST_UPDATED, wxEvent); -wxLogCtrl::wxLogCtrl(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style) +wxLogCtrl::wxLogCtrl(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, bool alternateRowColours) : TextList(parent, id, pos, size, style) { m_timer = new wxTimer(this); this->Bind(wxEVT_TIMER, &wxLogCtrl::OnTimer, this); this->Bind(EVT_ON_LIST_UPDATED, &wxLogCtrl::OnActiveListUpdated, this); m_timer->Start(250); + + m_alternateRowColoursEnabled = alternateRowColours; } wxLogCtrl::~wxLogCtrl() @@ -93,15 +95,13 @@ void wxLogCtrl::OnDraw(wxDC& dc, sint32 start, sint32 count, const wxPoint& star for (sint32 i = 0; i <= count && it != m_active_entries.cend(); ++i, ++it) { - wxColour background_colour; - if((start + i) % 2 == 0) - background_colour = COLOR_WHITE; - else - background_colour = 0xFFFDF9F2; + wxColour background_colour = GetBackgroundColour(); + if((start + i) % 2 != 0 && m_alternateRowColoursEnabled) + background_colour = GetAlternateRowColour(); DrawLineBackground(dc, position, background_colour); - dc.SetTextForeground(COLOR_BLACK); + dc.SetTextForeground(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT)); dc.DrawText(it->get().second, position); NextLine(position, &start_position); diff --git a/src/gui/wxgui/components/wxLogCtrl.h b/src/gui/wxgui/components/wxLogCtrl.h index e6932b49..e4593b8c 100644 --- a/src/gui/wxgui/components/wxLogCtrl.h +++ b/src/gui/wxgui/components/wxLogCtrl.h @@ -4,7 +4,7 @@ class wxLogCtrl : public TextList { public: - wxLogCtrl(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style); + wxLogCtrl(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, bool alternateRowColours = false); ~wxLogCtrl(); void SetActiveFilter(const std::string& active_filter); @@ -23,6 +23,22 @@ private: wxTimer* m_timer; + bool m_alternateRowColoursEnabled = false; + wxColour m_alternateRowColour; + + wxColour GetAlternateRowColour() + { + if (m_alternateRowColour.IsOk()) + return m_alternateRowColour; + + // Depending on the background, alternate row colour should be a bit + // darker or brighter. + const wxColour bgColour = GetBackgroundColour(); + int alpha = bgColour.GetRGB() > 0x808080 ? 97 : 110; + m_alternateRowColour = bgColour.ChangeLightness(alpha); + return m_alternateRowColour; + } + std::string m_active_filter; std::thread m_update_worker; bool m_filter_messages = false; diff --git a/src/gui/wxgui/debugger/BreakpointWindow.cpp b/src/gui/wxgui/debugger/BreakpointWindow.cpp index 9b352553..7c4b1556 100644 --- a/src/gui/wxgui/debugger/BreakpointWindow.cpp +++ b/src/gui/wxgui/debugger/BreakpointWindow.cpp @@ -29,13 +29,11 @@ BreakpointWindow::BreakpointWindow(DebuggerWindow2& parent, const wxPoint& main_ : wxFrame(&parent, wxID_ANY, _("Breakpoints"), wxDefaultPosition, wxSize(420, 250), wxSYSTEM_MENU | wxCAPTION | wxCLIP_CHILDREN | wxRESIZE_BORDER | wxFRAME_FLOAT_ON_PARENT) { this->SetSizeHints(wxDefaultSize, wxDefaultSize); - - this->wxWindowBase::SetBackgroundColour(*wxWHITE); wxBoxSizer* main_sizer = new wxBoxSizer(wxVERTICAL); - m_breakpoints = new wxCheckedListCtrl(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_REPORT); - + m_breakpoints = new wxListView(this, wxID_ANY, wxDefaultPosition, wxDefaultSize); + m_breakpoints->EnableCheckBoxes(true); wxListItem col0; col0.SetId(ColumnEnabled); @@ -71,8 +69,8 @@ BreakpointWindow::BreakpointWindow(DebuggerWindow2& parent, const wxPoint& main_ if (parent.GetConfig().data().pin_to_main) OnMainMove(main_position, main_size); - m_breakpoints->Bind(wxEVT_COMMAND_LIST_ITEM_CHECKED, (wxObjectEventFunction)&BreakpointWindow::OnBreakpointToggled, this); - m_breakpoints->Bind(wxEVT_COMMAND_LIST_ITEM_UNCHECKED, (wxObjectEventFunction)&BreakpointWindow::OnBreakpointToggled, this); + m_breakpoints->Bind(wxEVT_LIST_ITEM_CHECKED, &BreakpointWindow::OnBreakpointToggled, this); + m_breakpoints->Bind(wxEVT_LIST_ITEM_UNCHECKED, &BreakpointWindow::OnBreakpointToggled, this); m_breakpoints->Bind(wxEVT_LEFT_DCLICK, &BreakpointWindow::OnLeftDClick, this); m_breakpoints->Bind(wxEVT_RIGHT_DOWN, &BreakpointWindow::OnRightDown, this); @@ -81,8 +79,10 @@ BreakpointWindow::BreakpointWindow(DebuggerWindow2& parent, const wxPoint& main_ BreakpointWindow::~BreakpointWindow() { - m_breakpoints->Unbind(wxEVT_COMMAND_LIST_ITEM_CHECKED, (wxObjectEventFunction)&BreakpointWindow::OnBreakpointToggled, this); - m_breakpoints->Unbind(wxEVT_COMMAND_LIST_ITEM_UNCHECKED, (wxObjectEventFunction)&BreakpointWindow::OnBreakpointToggled, this); + m_breakpoints->Unbind(wxEVT_LIST_ITEM_CHECKED, &BreakpointWindow::OnBreakpointToggled, this); + m_breakpoints->Unbind(wxEVT_LIST_ITEM_UNCHECKED, &BreakpointWindow::OnBreakpointToggled, this); + m_breakpoints->Unbind(wxEVT_LEFT_DCLICK, &BreakpointWindow::OnLeftDClick, this); + m_breakpoints->Unbind(wxEVT_RIGHT_DOWN, &BreakpointWindow::OnRightDown, this); } void BreakpointWindow::OnMainMove(const wxPoint& main_position, const wxSize& main_size) @@ -107,11 +107,10 @@ void BreakpointWindow::OnUpdateView() uint32_t i = 0; for (const auto bpBase : debuggerState.breakpoints) { - DebuggerBreakpoint* bp = bpBase; while (bp) { - wxListItem item; + wxListItem item = {}; item.SetId(i++); const auto index = m_breakpoints->InsertItem(item); @@ -130,12 +129,11 @@ void BreakpointWindow::OnUpdateView() m_breakpoints->SetItem(index, ColumnType, typeName); m_breakpoints->SetItem(index, ColumnComment, bp->comment); - m_breakpoints->SetItemPtrData(item, (wxUIntPtr)bp); - m_breakpoints->Check(index, bp->enabled); + m_breakpoints->CheckItem(index, bp->enabled); + m_breakpoints->SetItemPtrData(index, (wxUIntPtr)bp); bp = bp->next; } - } } @@ -152,11 +150,12 @@ void BreakpointWindow::OnBreakpointToggled(wxListEvent& event) const int32_t index = event.GetIndex(); if (0 <= index && index < m_breakpoints->GetItemCount()) { - const bool state = m_breakpoints->IsChecked(index); + const bool state = m_breakpoints->IsItemChecked(index); wxString line = m_breakpoints->GetItemText(index, ColumnAddress); DebuggerBreakpoint* bp = (DebuggerBreakpoint*)m_breakpoints->GetItemData(index); const uint32 address = std::stoul(line.c_str().AsChar(), nullptr, 16); debugger_toggleBreakpoint(address, state, bp); + m_breakpoints->CheckItem(index, state); } } diff --git a/src/gui/wxgui/debugger/BreakpointWindow.h b/src/gui/wxgui/debugger/BreakpointWindow.h index ac8fca53..79c10f1f 100644 --- a/src/gui/wxgui/debugger/BreakpointWindow.h +++ b/src/gui/wxgui/debugger/BreakpointWindow.h @@ -1,5 +1,4 @@ #pragma once -#include "wxgui/wxcomponents/checkedlistctrl.h" class DebuggerWindow2; @@ -21,5 +20,5 @@ private: void OnContextMenuClick(wxCommandEvent& evt); void OnContextMenuClickSelected(wxCommandEvent& evt); - wxCheckedListCtrl* m_breakpoints; + wxListView* m_breakpoints; }; \ No newline at end of file diff --git a/src/gui/wxgui/debugger/DebuggerWindow2.cpp b/src/gui/wxgui/debugger/DebuggerWindow2.cpp index c4758977..bcc1d6a9 100644 --- a/src/gui/wxgui/debugger/DebuggerWindow2.cpp +++ b/src/gui/wxgui/debugger/DebuggerWindow2.cpp @@ -1,6 +1,8 @@ #include "wxgui/wxgui.h" #include "wxgui/debugger/DebuggerWindow2.h" +#include "wxHelper.h" + #include #include "config/ActiveSettings.h" @@ -52,6 +54,7 @@ wxDEFINE_EVENT(wxEVT_MOVE_IP, wxCommandEvent); wxDEFINE_EVENT(wxEVT_RUN, wxCommandEvent); wxDEFINE_EVENT(wxEVT_NOTIFY_MODULE_LOADED, wxCommandEvent); wxDEFINE_EVENT(wxEVT_NOTIFY_MODULE_UNLOADED, wxCommandEvent); +wxDEFINE_EVENT(wxEVT_NOTIFY_GRAPHIC_PACKS_MODIFIED, wxCommandEvent); wxBEGIN_EVENT_TABLE(DebuggerWindow2, wxFrame) EVT_SHOW(DebuggerWindow2::OnShow) @@ -64,6 +67,7 @@ wxBEGIN_EVENT_TABLE(DebuggerWindow2, wxFrame) EVT_COMMAND(wxID_ANY, wxEVT_RUN, DebuggerWindow2::OnRunProgram) EVT_COMMAND(wxID_ANY, wxEVT_NOTIFY_MODULE_LOADED, DebuggerWindow2::OnNotifyModuleLoaded) EVT_COMMAND(wxID_ANY, wxEVT_NOTIFY_MODULE_UNLOADED, DebuggerWindow2::OnNotifyModuleUnloaded) + EVT_COMMAND(wxID_ANY, wxEVT_NOTIFY_GRAPHIC_PACKS_MODIFIED, DebuggerWindow2::OnNotifyGraphicPacksModified) EVT_COMMAND(wxID_ANY, wxEVT_DISASMCTRL_NOTIFY_GOTO_ADDRESS, DebuggerWindow2::OnDisasmCtrlGotoAddress) // file menu EVT_MENU(MENU_ID_FILE_EXIT, DebuggerWindow2::OnExit) @@ -220,18 +224,22 @@ void DebuggerWindow2::CreateToolBar() m_toolbar = wxFrame::CreateToolBar(wxTB_HORIZONTAL, wxID_ANY); m_toolbar->SetToolBitmapSize(wxSize(16, 16)); - m_toolbar->AddTool(TOOL_ID_GOTO, wxEmptyString, wxBITMAP_PNG_FROM_DATA(DEBUGGER_GOTO), wxNullBitmap, wxITEM_NORMAL, _("GoTo (CTRL + G)"), "test", NULL); + wxBitmap goto_bitmap = wxHelper::LoadThemedBitmapFromPNG(DEBUGGER_GOTO_png, sizeof(DEBUGGER_GOTO_png), wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT)); + m_toolbar->AddTool(TOOL_ID_GOTO, wxEmptyString, goto_bitmap, wxNullBitmap, wxITEM_NORMAL, _("GoTo (CTRL + G)"), "test", NULL); m_toolbar->AddSeparator(); - m_toolbar->AddTool(TOOL_ID_BP, wxEmptyString, wxBITMAP_PNG_FROM_DATA(DEBUGGER_BP_RED), wxNullBitmap, wxITEM_NORMAL, _("Toggle Breakpoint (F9)"), wxEmptyString, NULL); + wxBitmap bp_bitmap = wxHelper::LoadThemedBitmapFromPNG(DEBUGGER_BP_RED_png, sizeof(DEBUGGER_BP_RED_png), wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT)); + m_toolbar->AddTool(TOOL_ID_BP, wxEmptyString, bp_bitmap, wxNullBitmap, wxITEM_NORMAL, _("Toggle Breakpoint (F9)"), wxEmptyString, NULL); m_toolbar->AddSeparator(); - m_pause = wxBITMAP_PNG_FROM_DATA(DEBUGGER_PAUSE); - m_run = wxBITMAP_PNG_FROM_DATA(DEBUGGER_PLAY); + m_pause = wxHelper::LoadThemedBitmapFromPNG(DEBUGGER_PAUSE_png, sizeof(DEBUGGER_PAUSE_png), wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT)); + m_run = wxHelper::LoadThemedBitmapFromPNG(DEBUGGER_PLAY_png, sizeof(DEBUGGER_PLAY_png), wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT)); m_toolbar->AddTool(TOOL_ID_PAUSE, wxEmptyString, m_pause, wxNullBitmap, wxITEM_NORMAL, _("Break (F5)"), wxEmptyString, NULL); - - m_toolbar->AddTool(TOOL_ID_STEP_INTO, wxEmptyString, wxBITMAP_PNG_FROM_DATA(DEBUGGER_STEP_INTO), wxNullBitmap, wxITEM_NORMAL, _("Step Into (F11)"), wxEmptyString, NULL); - m_toolbar->AddTool(TOOL_ID_STEP_OVER, wxEmptyString, wxBITMAP_PNG_FROM_DATA(DEBUGGER_STEP_OVER), wxNullBitmap, wxITEM_NORMAL, _("Step Over (F10)"), wxEmptyString, NULL); + + wxBitmap step_into_bitmap = wxHelper::LoadThemedBitmapFromPNG(DEBUGGER_STEP_INTO_png, sizeof(DEBUGGER_STEP_INTO_png), wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT)); + wxBitmap step_over_bitmap = wxHelper::LoadThemedBitmapFromPNG(DEBUGGER_STEP_OVER_png, sizeof(DEBUGGER_STEP_OVER_png), wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT)); + m_toolbar->AddTool(TOOL_ID_STEP_INTO, wxEmptyString, step_into_bitmap, wxNullBitmap, wxITEM_NORMAL, _("Step Into (F11)"), wxEmptyString, NULL); + m_toolbar->AddTool(TOOL_ID_STEP_OVER, wxEmptyString, step_over_bitmap, wxNullBitmap, wxITEM_NORMAL, _("Step Over (F10)"), wxEmptyString, NULL); m_toolbar->AddSeparator(); m_toolbar->Realize(); @@ -272,8 +280,6 @@ DebuggerWindow2::DebuggerWindow2(wxFrame& parent, const wxRect& display_size) { g_debuggerDispatcher.SetDebuggerCallbacks(this); - this->wxWindowBase::SetBackgroundColour(*wxWHITE); - const auto file = ActiveSettings::GetConfigPath("debugger/config.xml"); m_config.SetFilename(file.generic_wstring()); m_config.Load(); @@ -311,7 +317,6 @@ DebuggerWindow2::DebuggerWindow2(wxFrame& parent, const wxRect& display_size) } m_module_label = new wxStaticText(this, wxID_ANY, label_text); - m_module_label->SetBackgroundColour(*wxWHITE); m_module_label->SetForegroundColour(wxColour(0xFFbf52fe)); main_sizer->Add(m_module_label, 0, wxEXPAND | wxALL, 5); @@ -434,6 +439,13 @@ void DebuggerWindow2::OnNotifyModuleUnloaded(wxCommandEvent& event) m_disasm_ctrl->Init(); } +void DebuggerWindow2::OnNotifyGraphicPacksModified(wxCommandEvent& event) +{ + m_module_window->OnGameLoaded(); + m_symbol_window->OnGameLoaded(); + m_disasm_ctrl->Init(); +} + void DebuggerWindow2::OnGameLoaded() { m_disasm_ctrl->Init(); @@ -717,6 +729,12 @@ void DebuggerWindow2::NotifyModuleLoaded(void* module) wxQueueEvent(this, evt); } +void DebuggerWindow2::NotifyGraphicPacksModified() +{ + auto* evt = new wxCommandEvent(wxEVT_NOTIFY_GRAPHIC_PACKS_MODIFIED); + wxQueueEvent(this, evt); +} + void DebuggerWindow2::NotifyModuleUnloaded(void* module) { auto* evt = new wxCommandEvent(wxEVT_NOTIFY_MODULE_UNLOADED); diff --git a/src/gui/wxgui/debugger/DebuggerWindow2.h b/src/gui/wxgui/debugger/DebuggerWindow2.h index a2dbbebf..b06601ba 100644 --- a/src/gui/wxgui/debugger/DebuggerWindow2.h +++ b/src/gui/wxgui/debugger/DebuggerWindow2.h @@ -8,6 +8,7 @@ #include #include +#include class BreakpointWindow; class RegisterWindow; @@ -23,6 +24,7 @@ wxDECLARE_EVENT(wxEVT_BREAKPOINT_CHANGE, wxCommandEvent); wxDECLARE_EVENT(wxEVT_MOVE_IP, wxCommandEvent); wxDECLARE_EVENT(wxEVT_NOTIFY_MODULE_LOADED, wxCommandEvent); wxDECLARE_EVENT(wxEVT_NOTIFY_MODULE_UNLOADED, wxCommandEvent); +wxDECLARE_EVENT(wxEVT_NOTIFY_GRAPHIC_PACKS_MODIFIED, wxCommandEvent); struct DebuggerConfig { @@ -56,6 +58,14 @@ struct DebuggerModuleStorage }; typedef XMLDataConfig XMLDebuggerModuleConfig; +static wxBitmap LoadThemedBitmapFromPNG(const uint8* data, size_t size, const wxColour& tint) +{ + wxMemoryInputStream strm(data, size); + wxImage img(strm, wxBITMAP_TYPE_PNG); + img.Replace(0x00, 0x00, 0x00, tint.Red(), tint.Green(), tint.Blue()); + return wxBitmap(img); +} + class DebuggerWindow2 : public wxFrame, public DebuggerCallbacks { public: @@ -86,6 +96,7 @@ private: void OnMoveIP(wxCommandEvent& event); void OnNotifyModuleLoaded(wxCommandEvent& event); void OnNotifyModuleUnloaded(wxCommandEvent& event); + void OnNotifyGraphicPacksModified(wxCommandEvent& event); // events from DisasmCtrl void OnDisasmCtrlGotoAddress(wxCommandEvent& event); @@ -97,6 +108,7 @@ private: void NotifyRun() override; void MoveIP() override; void NotifyModuleLoaded(void* module) override; + void NotifyGraphicPacksModified() override; void NotifyModuleUnloaded(void* module) override; XMLDebuggerConfig m_config; diff --git a/src/gui/wxgui/debugger/DisasmCtrl.cpp b/src/gui/wxgui/debugger/DisasmCtrl.cpp index 6d258cc5..7b24cb09 100644 --- a/src/gui/wxgui/debugger/DisasmCtrl.cpp +++ b/src/gui/wxgui/debugger/DisasmCtrl.cpp @@ -1,6 +1,7 @@ #include "wxgui/wxgui.h" #include "wxgui/debugger/DisasmCtrl.h" +#include "wxHelper.h" #include "Cafe/OS/RPL/rpl_structs.h" #include "Cafe/OS/RPL/rpl.h" #include "Cafe/OS/RPL/rpl_symbol_storage.h" @@ -12,35 +13,13 @@ #include "Cemu/ExpressionParser/ExpressionParser.h" #include "Cafe/HW/Espresso/Debugger/DebugSymbolStorage.h" -#include // for wxMemoryInputStream wxDEFINE_EVENT(wxEVT_DISASMCTRL_NOTIFY_GOTO_ADDRESS, wxCommandEvent); #define MAX_SYMBOL_LEN (120) -#define COLOR_DEBUG_ACTIVE_BP 0xFFFFA0FF -#define COLOR_DEBUG_ACTIVE 0xFFFFA080 -#define COLOR_DEBUG_BP 0xFF8080FF -#define SYNTAX_COLOR_GPR 0xFF000066 -#define SYNTAX_COLOR_FPR 0xFF006666 -#define SYNTAX_COLOR_SPR 0xFF666600 -#define SYNTAX_COLOR_CR 0xFF666600 -#define SYNTAX_COLOR_IMM 0xFF006600 -#define SYNTAX_COLOR_IMM_OFFSET 0xFF006600 -#define SYNTAX_COLOR_CIMM 0xFF880000 -#define SYNTAX_COLOR_PSEUDO 0xFFA0A0A0 // color for pseudo code -#define SYNTAX_COLOR_SYMBOL 0xFF0000A0 // color for function symbol - -#define OFFSET_ADDRESS (60) -#define OFFSET_ADDRESS_RELATIVE (90) -#define OFFSET_DISASSEMBLY (300) - -#define OFFSET_DISASSEMBLY_OPERAND (80) - -wxBitmap* g_ipArrowBitmap = nullptr; - -uint8 _arrowRightPNG[] = +constexpr uint8 arrowRightPNG[] = { 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00, 0x00, 0x00, 0x0D, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0B, @@ -59,17 +38,86 @@ uint8 _arrowRightPNG[] = 0x73, 0x8D, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4E, 0x44, 0xAE, 0x42, 0x60, 0x82 }; +std::optional g_ipArrowBitmap; + + +static wxColour theme_textForeground; +static wxColour theme_textForegroundMuted; +static wxColour theme_background; + +// background colors for lines in the disassembly view +static wxColour theme_lineBreakpointAndCurrentInstruction; +static wxColour theme_lineCurrentInstruction; +static wxColour theme_lineBreakpointSet; +static wxColour theme_lineLoggingBreakpointSet; +static wxColour theme_lineLastGotoAddress; + +// text colors for addresses in the disassembly view +static wxColour theme_syntaxGPR; +static wxColour theme_syntaxFPR; +static wxColour theme_syntaxSPR; +static wxColour theme_syntaxCR; +static wxColour theme_syntaxIMM; +static wxColour theme_syntaxIMMOffset; +static wxColour theme_syntaxCallIMM; +static wxColour theme_syntaxPseudoOrUnknown; +static wxColour theme_syntaxSymbol; + +static wxColour theme_opCode; +static wxColour theme_typeData; +static wxColour theme_patchedOpCode; +static wxColour theme_patchedData; + + +static void InitSyntaxColors() +{ + theme_textForeground = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT); + theme_textForegroundMuted = wxSystemSettings::GetAppearance().IsDark() ? wxColour(140,142,145) : wxSystemSettings::GetColour(wxSYS_COLOUR_GRAYTEXT); + theme_background = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW); + + // line background highlights + theme_lineBreakpointSet = wxSystemSettings::SelectLightDark(wxColour(0xFF,0x80,0x80), wxColour(0x84,0x21,0x21)); // red for a non-current breakpoint + theme_lineBreakpointAndCurrentInstruction = wxSystemSettings::SelectLightDark(wxColour(0xD2,0x7E,0xD2), wxColour(0x91,0x44,0xA4)); // pink for a current breakpoint + theme_lineCurrentInstruction = wxSystemSettings::SelectLightDark(wxColour(0xFF,0xA0,0x80), wxColour(0x87,0x53,0x1A)); // light orange + theme_lineLoggingBreakpointSet = wxSystemSettings::SelectLightDark(wxColour(0xAB,0xED,0xEE), wxColour(0x25,0x5D,0x6D)); // light blue + theme_lineLastGotoAddress = wxSystemSettings::SelectLightDark(wxColour(0xE0,0xE0,0xE0), wxColour(0x40,0x40,0x40)); // very light gray to indicate the line that was last jumped to + + // disassembly syntax colors + theme_syntaxGPR = wxSystemSettings::SelectLightDark(wxColour(0x66,0x00,0x00), wxColour(0xE0,0x6C,0x75)); + theme_syntaxFPR = wxSystemSettings::SelectLightDark(wxColour(0x66,0x66,0x00), wxColour(0xD1,0x9A,0x66)); + theme_syntaxSPR = wxSystemSettings::SelectLightDark(wxColour(0x00,0x66,0x66), wxColour(0x56,0xB6,0xC2)); + theme_syntaxCR = wxSystemSettings::SelectLightDark(wxColour(0x00,0x66,0x66), wxColour(0x56,0xB6,0xC2)); + theme_syntaxIMM = wxSystemSettings::SelectLightDark(wxColour(0x00,0x66,0x00), wxColour(0x9D,0xDE,0x6F)); + theme_syntaxIMMOffset = wxSystemSettings::SelectLightDark(wxColour(0x00,0x66,0x00), wxColour(0x9D,0xDE,0x6F)); + theme_syntaxCallIMM = wxSystemSettings::SelectLightDark(wxColour(0x00,0x00,0x88), wxColour(0x61,0xAF,0xEF)); + theme_syntaxPseudoOrUnknown = wxSystemSettings::SelectLightDark(wxColour(0xA0,0xA0,0xA0), wxColour(0x5C,0x63,0x70)); + theme_syntaxSymbol = wxSystemSettings::SelectLightDark(wxColour(0xA0,0x00,0x00), wxColour(0xE0,0x6C,0x75)); + + // opcode & data highlighting + theme_opCode = wxSystemSettings::SelectLightDark(wxColour(0xFF,0x00,0x40), wxColour(0xFF,0x70,0x7B)); + theme_patchedOpCode = wxSystemSettings::SelectLightDark(wxColour(0xFF,0x20,0x20), wxColour(0xCC,0x52,0xF5)); + theme_typeData = wxSystemSettings::SelectLightDark(wxColour(0xFF,0x20,0x20), wxColour(0xCE,0x91,0x78)); + theme_patchedData = wxSystemSettings::SelectLightDark(wxColour(0xFF,0x20,0x20), wxColour(0xF4,0x43,0x36)); + + // theme the current instruction pointer arrow + g_ipArrowBitmap = wxHelper::LoadThemedBitmapFromPNG(arrowRightPNG, sizeof(arrowRightPNG), wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT)); +} + + +#define OFFSET_ADDRESS (60) +#define OFFSET_ADDRESS_RELATIVE (90) +#define OFFSET_DISASSEMBLY (300) + +#define OFFSET_DISASSEMBLY_OPERAND (80) DisasmCtrl::DisasmCtrl(wxWindow* parent, const wxWindowID& id, const wxPoint& pos, const wxSize& size, long style) : TextList(parent, id, pos, size, style), m_mouse_line(-1), m_mouse_line_drawn(-1), m_active_line(-1) { Init(); - if (!g_ipArrowBitmap) + if (!g_ipArrowBitmap.has_value()) { - wxMemoryInputStream strm(_arrowRightPNG, sizeof(_arrowRightPNG)); - wxImage img(strm, wxBITMAP_TYPE_PNG); - g_ipArrowBitmap = new wxBitmap(img); + InitSyntaxColors(); } auto tooltip_sizer = new wxBoxSizer(wxVERTICAL); @@ -106,8 +154,8 @@ void DisasmCtrl::SelectCodeRegion(uint32 newAddress) // update line tracking sint32 element_count = currentCodeRegionEnd - currentCodeRegionStart; - if (element_count <= 0x00010000) - element_count = 0x00010000; + // if (element_count <= 0x00010000) + // element_count = 0x00010000; if (this->SetElementCount(element_count / 4)) { @@ -146,23 +194,23 @@ void DisasmCtrl::DrawDisassemblyLine(wxDC& dc, const wxPoint& linePosition, MPTR // write virtual address wxColour background_colour; if (is_active_bp && bp != nullptr) - background_colour = wxColour(0xFFFFA0FF); + background_colour = theme_lineBreakpointAndCurrentInstruction; else if (is_active_bp) - background_colour = wxColour(0xFF80A0FF); + background_colour = theme_lineCurrentInstruction; else if (bp != nullptr) - background_colour = wxColour(bp->bpType == DEBUGGER_BP_T_NORMAL ? 0xFF8080FF : 0x80FFFFFF); + background_colour = bp->bpType == DEBUGGER_BP_T_NORMAL ? theme_lineBreakpointSet : theme_lineLoggingBreakpointSet; else if(virtualAddress == m_lastGotoTarget) - background_colour = wxColour(0xFFE0E0E0); + background_colour = theme_lineLastGotoAddress; else - background_colour = wxColour(COLOR_WHITE); + background_colour = theme_background; DrawLineBackground(dc, position, background_colour); - dc.SetTextForeground(COLOR_BLACK); + dc.SetTextForeground(theme_textForeground); dc.DrawText(wxString::Format("%08x", virtualAddress), position); position.x += OFFSET_ADDRESS; - dc.SetTextForeground(COLOR_GREY); + dc.SetTextForeground(theme_textForegroundMuted); if (rplModule) dc.DrawText(wxString::Format("+0x%-8x", virtualAddress - rplModule->regionMappingBase_text.GetMPTR()), position); else @@ -178,29 +226,29 @@ void DisasmCtrl::DrawDisassemblyLine(wxDC& dc, const wxPoint& linePosition, MPTR auto debugSymbolDataType = DebugSymbolStorage::GetDataType(virtualAddress); if (debugSymbolDataType == DEBUG_SYMBOL_TYPE::FLOAT) { - dc.SetTextForeground(hasPatch ? wxColour(0xFF2020FF) : wxColour(0xFF400000)); + dc.SetTextForeground(hasPatch ? theme_patchedData : theme_typeData); dc.DrawText(fmt::format(".float"), position); position.x += OFFSET_DISASSEMBLY_OPERAND; - dc.SetTextForeground(hasPatch ? wxColour(0xFF2020FF) : wxColour(SYNTAX_COLOR_IMM)); + dc.SetTextForeground(hasPatch ? theme_patchedData : theme_syntaxIMM); dc.DrawText(fmt::format("{}", memory_readFloat(virtualAddress)), position); return; } else if (debugSymbolDataType == DEBUG_SYMBOL_TYPE::U32) { - dc.SetTextForeground(hasPatch ? wxColour(0xFF2020FF) : wxColour(0xFF400000)); + dc.SetTextForeground(hasPatch ? theme_patchedData : theme_typeData); dc.DrawText(fmt::format(".uint"), position); position.x += OFFSET_DISASSEMBLY_OPERAND; - dc.SetTextForeground(hasPatch ? wxColour(0xFF2020FF) : wxColour(SYNTAX_COLOR_IMM)); + dc.SetTextForeground(hasPatch ? theme_patchedData : theme_syntaxIMM); dc.DrawText(fmt::format("{}", memory_readU32(virtualAddress)), position); return; } sint32 start_width = position.x; - dc.SetTextForeground(hasPatch ? wxColour(0xFF2020FF) : wxColour(0xFF400000)); + dc.SetTextForeground(hasPatch ? theme_patchedOpCode : theme_opCode); char opName[32]; strcpy(opName, ppcAssembler_getInstructionName(disasmInstr.ppcAsmCode)); std::transform(opName, opName + sizeof(opName), opName, tolower); @@ -221,7 +269,7 @@ void DisasmCtrl::DrawDisassemblyLine(wxDC& dc, const wxPoint& linePosition, MPTR if (disasmInstr.ppcAsmCode == PPCASM_OP_UKN) { // show raw bytes - WriteText(dc, wxString::Format("%02x %02x %02x %02x", (opcode >> 24) & 0xFF, (opcode >> 16) & 0xFF, (opcode >> 8) & 0xFF, (opcode >> 0) & 0xFF), position, SYNTAX_COLOR_PSEUDO); + WriteText(dc, wxString::Format("%02x %02x %02x %02x", (opcode >> 24) & 0xFF, (opcode >> 16) & 0xFF, (opcode >> 8) & 0xFF, (opcode >> 0) & 0xFF), position, theme_syntaxPseudoOrUnknown); } bool is_first_operand = true; @@ -231,25 +279,25 @@ void DisasmCtrl::DrawDisassemblyLine(wxDC& dc, const wxPoint& linePosition, MPTR continue; if (!is_first_operand) - WriteText(dc, ", ", position, COLOR_BLACK); + WriteText(dc, ", ", position, theme_textForeground); is_first_operand = false; switch (disasmInstr.operand[o].type) { case PPCASM_OPERAND_TYPE_GPR: - WriteText(dc, wxString::Format("r%d", disasmInstr.operand[o].registerIndex), position, SYNTAX_COLOR_GPR); + WriteText(dc, wxString::Format("r%d", disasmInstr.operand[o].registerIndex), position, theme_syntaxGPR); break; case PPCASM_OPERAND_TYPE_FPR: - WriteText(dc, wxString::Format("f%d", disasmInstr.operand[o].registerIndex), position, SYNTAX_COLOR_FPR); + WriteText(dc, wxString::Format("f%d", disasmInstr.operand[o].registerIndex), position, theme_syntaxFPR); break; case PPCASM_OPERAND_TYPE_SPR: - WriteText(dc, wxString::Format("spr%d", disasmInstr.operand[o].registerIndex), position, SYNTAX_COLOR_SPR); + WriteText(dc, wxString::Format("spr%d", disasmInstr.operand[o].registerIndex), position, theme_syntaxSPR); break; case PPCASM_OPERAND_TYPE_CR: - WriteText(dc, wxString::Format("cr%d", disasmInstr.operand[o].registerIndex), position, SYNTAX_COLOR_CR); + WriteText(dc, wxString::Format("cr%d", disasmInstr.operand[o].registerIndex), position, theme_syntaxCR); break; case PPCASM_OPERAND_TYPE_IMM: @@ -280,16 +328,15 @@ void DisasmCtrl::DrawDisassemblyLine(wxDC& dc, const wxPoint& linePosition, MPTR string = wxString::Format("0x%x", uImm); } - - WriteText(dc, string, position, SYNTAX_COLOR_IMM); + WriteText(dc, string, position, theme_syntaxIMM); break; } case PPCASM_OPERAND_TYPE_PSQMODE: { if (disasmInstr.operand[o].immS32) - WriteText(dc, "single", position, SYNTAX_COLOR_IMM); + WriteText(dc, "single", position, theme_syntaxIMM); else - WriteText(dc, "paired", position, SYNTAX_COLOR_IMM); + WriteText(dc, "paired", position, theme_syntaxIMM); break; } case PPCASM_OPERAND_TYPE_CIMM: @@ -322,7 +369,7 @@ void DisasmCtrl::DrawDisassemblyLine(wxDC& dc, const wxPoint& linePosition, MPTR string = wxString::Format("0x%08x", disasmInstr.operand[o].immU32); } - WriteText(dc, string, position, SYNTAX_COLOR_CIMM); + WriteText(dc, string, position, theme_syntaxCallIMM); if (disasmInstr.ppcAsmCode != PPCASM_OP_BL) { @@ -332,7 +379,7 @@ void DisasmCtrl::DrawDisassemblyLine(wxDC& dc, const wxPoint& linePosition, MPTR else x.Append(wxUniChar(0x2193)); // arrow down - WriteText(dc, x, position, COLOR_BLACK); + WriteText(dc, x, position, theme_textForeground); } break; @@ -346,12 +393,12 @@ void DisasmCtrl::DrawDisassemblyLine(wxDC& dc, const wxPoint& linePosition, MPTR else string = wxString::Format("-0x%x", -disasmInstr.operand[o].immS32); - WriteText(dc, string, position, SYNTAX_COLOR_IMM_OFFSET); - WriteText(dc, "(", position, COLOR_BLACK); + WriteText(dc, string, position, theme_syntaxIMMOffset); + WriteText(dc, "(", position, theme_textForeground); // register - WriteText(dc, wxString::Format("r%d", disasmInstr.operand[o].registerIndex), position, SYNTAX_COLOR_GPR); - WriteText(dc, ")", position, COLOR_BLACK); + WriteText(dc, wxString::Format("r%d", disasmInstr.operand[o].registerIndex), position, theme_syntaxGPR); + WriteText(dc, ")", position, theme_textForeground); break; } default: @@ -363,7 +410,7 @@ void DisasmCtrl::DrawDisassemblyLine(wxDC& dc, const wxPoint& linePosition, MPTR position.x = start_width + OFFSET_DISASSEMBLY; const auto comment = static_cast(rplDebugSymbol_getForAddress(virtualAddress)); if (comment && comment->type == RplDebugSymbolComment) - WriteText(dc, comment->comment, position, COLOR_BLACK); + WriteText(dc, comment->comment, position, theme_textForeground); else if (isRLWINM) { sint32 rS, rA, SH, MB, ME; @@ -384,7 +431,7 @@ void DisasmCtrl::DrawDisassemblyLine(wxDC& dc, const wxPoint& linePosition, MPTR string = wxString::Format("r%d=r%d>>%d", rA, rS, 32 - SH); else string = wxString::Format("r%d=(r%d<<<%d)&0x%x", rA, rS, SH, mask); - WriteText(dc, string, position, COLOR_GREY); + WriteText(dc, string, position, theme_textForegroundMuted); } else if (disasmInstr.ppcAsmCode == PPCASM_OP_SUBF || disasmInstr.ppcAsmCode == PPCASM_OP_SUBF_) { @@ -395,7 +442,7 @@ void DisasmCtrl::DrawDisassemblyLine(wxDC& dc, const wxPoint& linePosition, MPTR wxString string; string = wxString::Format("r%d=r%d-r%d", rD, rB, rA); - WriteText(dc, string, position, COLOR_GREY); + WriteText(dc, string, position, theme_textForegroundMuted); } } @@ -408,7 +455,7 @@ void DisasmCtrl::DrawLabelName(wxDC& dc, const wxPoint& linePosition, MPTR virtu symbol_string.Append("..:"); } wxPoint tmpPos(linePosition); - WriteText(dc, symbol_string, tmpPos, SYNTAX_COLOR_SYMBOL); + WriteText(dc, symbol_string, tmpPos, theme_syntaxSymbol); } void DisasmCtrl::OnDraw(wxDC& dc, sint32 start, sint32 count, const wxPoint& start_position) @@ -646,7 +693,8 @@ void DisasmCtrl::OnMouseDClick(const wxPoint& position, uint32 line) } } -void DisasmCtrl::CopyToClipboard(std::string text) { +void DisasmCtrl::CopyToClipboard(std::string text) +{ #if BOOST_OS_WINDOWS if (OpenClipboard(nullptr)) { @@ -656,9 +704,7 @@ void DisasmCtrl::CopyToClipboard(std::string text) { { memcpy(GlobalLock(hGlobal), text.c_str(), text.size() + 1); GlobalUnlock(hGlobal); - SetClipboardData(CF_TEXT, hGlobal); - GlobalFree(hGlobal); } CloseClipboard(); } diff --git a/src/gui/wxgui/debugger/DisasmCtrl.h b/src/gui/wxgui/debugger/DisasmCtrl.h index 85a962e0..61f7afa6 100644 --- a/src/gui/wxgui/debugger/DisasmCtrl.h +++ b/src/gui/wxgui/debugger/DisasmCtrl.h @@ -30,8 +30,6 @@ public: void CenterOffset(uint32 offset); void GoToAddressDialog(); - - protected: void OnDraw(wxDC& dc, sint32 start, sint32 count, const wxPoint& start_position) override; void OnMouseMove(const wxPoint& position, uint32 line) override; diff --git a/src/gui/wxgui/debugger/DumpCtrl.cpp b/src/gui/wxgui/debugger/DumpCtrl.cpp index 2f192ec8..ffe18037 100644 --- a/src/gui/wxgui/debugger/DumpCtrl.cpp +++ b/src/gui/wxgui/debugger/DumpCtrl.cpp @@ -7,31 +7,11 @@ #include "Cemu/ExpressionParser/ExpressionParser.h" -#define COLOR_BLACK 0xFF000000 -#define COLOR_GREY 0xFFA0A0A0 -#define COLOR_WHITE 0xFFFFFFFF - -#define COLOR_DEBUG_ACTIVE_BP 0xFFFFA0FF -#define COLOR_DEBUG_ACTIVE 0xFFFFA080 -#define COLOR_DEBUG_BP 0xFF8080FF - -#define SYNTAX_COLOR_GPR 0xFF000066 -#define SYNTAX_COLOR_FPR 0xFF006666 -#define SYNTAX_COLOR_SPR 0xFF666600 -#define SYNTAX_COLOR_CR 0xFF666600 -#define SYNTAX_COLOR_IMM 0xFF006600 -#define SYNTAX_COLOR_IMM_OFFSET 0xFF006600 -#define SYNTAX_COLOR_CIMM 0xFF880000 -#define SYNTAX_COLOR_PSEUDO 0xFFA0A0A0 // color for pseudo code -#define SYNTAX_COLOR_SYMBOL 0xFF0000A0 // color for function symbol #define OFFSET_ADDRESS (60) #define OFFSET_ADDRESS_RELATIVE (90) #define OFFSET_MEMORY (450) -#define OFFSET_DISASSEMBLY_OPERAND (80) - - DumpCtrl::DumpCtrl(wxWindow* parent, const wxWindowID& id, const wxPoint& pos, const wxSize& size, long style) : TextList(parent, id, pos, size, style) { @@ -68,11 +48,11 @@ void DumpCtrl::OnDraw(wxDC& dc, sint32 start, sint32 count, const wxPoint& start { const uint32 virtual_address = m_memoryRegion.baseAddress + (start + i) * 0x10; - dc.SetTextForeground(wxColour(COLOR_BLACK)); + dc.SetTextForeground(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT)); dc.DrawText(wxString::Format("%08x", virtual_address), position); position.x += OFFSET_ADDRESS; - dc.SetTextForeground(wxColour(COLOR_GREY)); + dc.SetTextForeground(wxSystemSettings::GetColour(wxSYS_COLOUR_GRAYTEXT)); if (currentCodeRPL) { dc.DrawText(wxString::Format("+0x%-8x", virtual_address - currentCodeRPL->regionMappingBase_text.GetMPTR()), position); @@ -110,7 +90,7 @@ void DumpCtrl::OnDraw(wxDC& dc, sint32 start, sint32 count, const wxPoint& start position.x += (m_char_width * 3); } position.x = start_width = OFFSET_MEMORY; - dc.SetTextForeground(wxColour(COLOR_BLACK)); + dc.SetTextForeground(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT)); for (auto b : data) { if (isprint(b)) @@ -144,7 +124,7 @@ void DumpCtrl::OnDraw(wxDC& dc, sint32 start, sint32 count, const wxPoint& start start_position.y ); wxPoint line_to(line_from.x, line_from.y + m_line_height * (count + 1)); - dc.SetPen(*wxLIGHT_GREY_PEN); + dc.SetPen(wxSystemSettings::GetColour(wxSYS_COLOUR_INACTIVECAPTIONTEXT)); for (sint32 i = 0; i < 3; i++) { dc.DrawLine(line_from, line_to); diff --git a/src/gui/wxgui/debugger/DumpWindow.cpp b/src/gui/wxgui/debugger/DumpWindow.cpp index 738b738a..f152e8f6 100644 --- a/src/gui/wxgui/debugger/DumpWindow.cpp +++ b/src/gui/wxgui/debugger/DumpWindow.cpp @@ -17,8 +17,6 @@ enum DumpWindow::DumpWindow(DebuggerWindow2& parent, const wxPoint& main_position, const wxSize& main_size) : wxFrame(&parent, wxID_ANY, _("Memory Dump"), wxDefaultPosition, wxSize(600, 250), wxSYSTEM_MENU | wxCAPTION | wxCLIP_CHILDREN | wxRESIZE_BORDER | wxFRAME_FLOAT_ON_PARENT) { - this->wxWindowBase::SetBackgroundColour(*wxWHITE); - wxBoxSizer* main_sizer = new wxBoxSizer(wxVERTICAL); m_dump_ctrl = new DumpCtrl(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxScrolledWindowStyle); main_sizer->Add(m_dump_ctrl, 1, wxEXPAND); diff --git a/src/gui/wxgui/debugger/ModuleWindow.cpp b/src/gui/wxgui/debugger/ModuleWindow.cpp index 56b69cd4..32dfd89e 100644 --- a/src/gui/wxgui/debugger/ModuleWindow.cpp +++ b/src/gui/wxgui/debugger/ModuleWindow.cpp @@ -23,8 +23,6 @@ ModuleWindow::ModuleWindow(DebuggerWindow2& parent, const wxPoint& main_position { this->SetSizeHints(wxDefaultSize, wxDefaultSize); - this->wxWindowBase::SetBackgroundColour(*wxWHITE); - wxBoxSizer* main_sizer = new wxBoxSizer(wxVERTICAL); m_modules = new wxListView(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_REPORT); diff --git a/src/gui/wxgui/debugger/RegisterCtrl.cpp b/src/gui/wxgui/debugger/RegisterCtrl.cpp deleted file mode 100644 index 2a71770a..00000000 --- a/src/gui/wxgui/debugger/RegisterCtrl.cpp +++ /dev/null @@ -1,255 +0,0 @@ -#include "wxgui/wxgui.h" -#include "wxgui/debugger/RegisterCtrl.h" - -#include - -#include "Cafe/OS/RPL/rpl_structs.h" -#include "Cafe/OS/RPL/rpl.h" -#include "Cafe/HW/Espresso/Debugger/Debugger.h" -#include "wxgui/debugger/DebuggerWindow2.h" - -#define COLOR_DEBUG_ACTIVE_BP 0xFFFFA0FF -#define COLOR_DEBUG_ACTIVE 0xFFFFA080 -#define COLOR_DEBUG_BP 0xFF8080FF - -#define SYNTAX_COLOR_GPR 0xFF000066 -#define SYNTAX_COLOR_FPR 0xFF006666 -#define SYNTAX_COLOR_SPR 0xFF666600 -#define SYNTAX_COLOR_CR 0xFF666600 -#define SYNTAX_COLOR_IMM 0xFF006600 -#define SYNTAX_COLOR_IMM_OFFSET 0xFF006600 -#define SYNTAX_COLOR_CIMM 0xFF880000 -#define SYNTAX_COLOR_PSEUDO 0xFFA0A0A0 // color for pseudo code -#define SYNTAX_COLOR_SYMBOL 0xFF0000A0 // color for function symbol - -#define OFFSET_REGISTER (60) -#define OFFSET_REGISTER_LABEL (100) -#define OFFSET_FPR (120) - -RegisterCtrl::RegisterCtrl(wxWindow* parent, const wxWindowID& id, const wxPoint& pos, const wxSize& size, long style) - : TextList(parent, id, pos, size, style), m_prev_snapshot({}) -{ - this->SetElementCount(32 + 1 + 32); - RefreshControl(); -} - -void RegisterCtrl::OnDraw(wxDC& dc, sint32 start, sint32 count, const wxPoint& start_position) -{ - wxPoint position = start_position; - - //RPLModule* current_rpl_module = rpl3_getModuleByCodeAddr(MEMORY_CODEAREA_ADDR + start); - for (sint32 i = 0; i <= count; i++) - { - const uint32 line = start + i; - - if (line < 32) - { - dc.SetTextForeground(COLOR_BLACK); - dc.DrawText(wxString::Format("R%d", line), position); - position.x += OFFSET_REGISTER; - - const uint32 register_value = debuggerState.debugSession.ppcSnapshot.gpr[line]; - if(register_value != m_prev_snapshot.gpr[line]) - dc.SetTextForeground(COLOR_RED); - else - dc.SetTextForeground(COLOR_BLACK); - - dc.DrawText(wxString::Format("%08x", register_value), position); - position.x += OFFSET_REGISTER_LABEL; - - // check if address is a code offset - RPLModule* code_module = RPLLoader_FindModuleByCodeAddr(register_value); - if (code_module) - dc.DrawText(wxString::Format("<%s> + %x", code_module->moduleName2.c_str(), register_value - code_module->regionMappingBase_text.GetMPTR()), position); - - // check if address is a string - uint32 string_offset = register_value; - if (string_offset >= MEMORY_DATA_AREA_ADDR && string_offset < (MEMORY_DATA_AREA_ADDR+MEMORY_DATA_AREA_SIZE) ) - { - bool is_valid_string = true; - std::stringstream buffer; - - uint32 string_offset = register_value; - while (string_offset < (MEMORY_DATA_AREA_ADDR + MEMORY_DATA_AREA_SIZE)) - { - const uint8 c = memory_readU8(string_offset++); - if (isprint(c)) - { - buffer << c; - } - else if( c == '\0' ) - { - buffer << c; - break; - } - else - { - is_valid_string = false; - break; - } - } - - if(is_valid_string && buffer.tellp() > 1) - { - dc.DrawText(wxString::Format("s \"%s\"", buffer.str().c_str()), position); - } - else - { - // check for widestring - is_valid_string = true; - string_offset = register_value; - std::wstringstream wbuffer; - while (string_offset < (MEMORY_DATA_AREA_ADDR + MEMORY_DATA_AREA_SIZE)) - { - const uint16 c = memory_readU16(string_offset); - string_offset += 2; - - if (iswprint(c)) - { - wbuffer << c; - } - else if (c == L'\0') - { - wbuffer << c; - break; - } - else - { - is_valid_string = false; - break; - } - } - - if (is_valid_string && buffer.tellp() > 1) - { - dc.DrawText(wxString::Format(L"ws \"%s\"", wbuffer.str().c_str()), position); - } - } - } - } - else if( 32 + 1 <= line && line <= 32 + 1 + 32) - { - const uint32 register_index = line - 32 - 1; - dc.SetTextForeground(COLOR_BLACK); - dc.DrawText(wxString::Format("F0_%d", register_index), position); - position.x += OFFSET_REGISTER; - - const uint64 fpr0_value = debuggerState.debugSession.ppcSnapshot.fpr[register_index].fp0int; - if (fpr0_value != m_prev_snapshot.fpr[register_index].fp0int) - dc.SetTextForeground(COLOR_RED); - else - dc.SetTextForeground(COLOR_BLACK); - - //dc.DrawText(wxString::Format("%016llx", fpr0_value), position); - dc.DrawText(wxString::Format("%lf", debuggerState.debugSession.ppcSnapshot.fpr[register_index].fp0), position); - - position.x += OFFSET_FPR; - - dc.SetTextForeground(COLOR_BLACK); - dc.DrawText(wxString::Format("F1_%d", register_index), position); - position.x += OFFSET_REGISTER; - - const uint64 fpr1_value = debuggerState.debugSession.ppcSnapshot.fpr[register_index].fp1int; - if (fpr1_value != m_prev_snapshot.fpr[register_index].fp1int) - dc.SetTextForeground(COLOR_RED); - else - dc.SetTextForeground(COLOR_BLACK); - - //dc.DrawText(wxString::Format("%016llx", fpr1_value), position); - dc.DrawText(wxString::Format("%lf", debuggerState.debugSession.ppcSnapshot.fpr[register_index].fp1), position); - } - else - { - // empty line - } - - NextLine(position, &start_position); - } - - memcpy(&m_prev_snapshot, &debuggerState.debugSession.ppcSnapshot, sizeof(m_prev_snapshot)); -} - -void RegisterCtrl::OnMouseMove(const wxPoint& position, uint32 line) -{ - if (!m_mouse_down) - return; - - wxPoint pos = position; - if(pos.x <= OFFSET_REGISTER) - { - - } - - pos.x -= OFFSET_REGISTER; - - if (pos.x <= OFFSET_REGISTER_LABEL) - { - - } - - pos.x -= OFFSET_REGISTER_LABEL; -} - -void RegisterCtrl::OnMouseDClick(const wxPoint& position, uint32 line) -{ - if (!debuggerState.debugSession.isTrapped) - return; - - if(line < 32) - { - const uint32 register_index = line; - if (position.x <= OFFSET_REGISTER + OFFSET_REGISTER_LABEL) - { - const uint32 register_value = debuggerState.debugSession.ppcSnapshot.gpr[register_index]; - wxTextEntryDialog set_value_dialog(this, _("Enter a new value."), wxString::Format(_("Set R%d value"), register_index), wxString::Format("%08x", register_value)); - if (set_value_dialog.ShowModal() == wxID_OK) - { - const uint32 new_value = std::stoul(set_value_dialog.GetValue().ToStdString(), nullptr, 16); - debuggerState.debugSession.hCPU->gpr[register_index] = new_value; - debuggerState.debugSession.ppcSnapshot.gpr[register_index] = new_value; - - wxRect update_rect(0, line * m_line_height, GetSize().x, m_line_height); - RefreshControl(&update_rect); - } - } - } - // one line empty between = line 32 - else if (32 + 1 <= line && line <= 32 + 1 + 32) - { - const uint32 register_index = line - 32 - 1; - if (position.x <= OFFSET_REGISTER + OFFSET_FPR) - { - const double register_value = debuggerState.debugSession.ppcSnapshot.fpr[register_index].fp0; - wxTextEntryDialog set_value_dialog(this, _("Enter a new value."), wxString::Format(_("Set FP0_%d value"), register_index), wxString::Format("%lf", register_value)); - if (set_value_dialog.ShowModal() == wxID_OK) - { - const double new_value = std::stod(set_value_dialog.GetValue().ToStdString()); - debuggerState.debugSession.hCPU->fpr[register_index].fp0 = new_value; - debuggerState.debugSession.ppcSnapshot.fpr[register_index].fp0 = new_value; - - wxRect update_rect(0, line * m_line_height, GetSize().x, m_line_height); - RefreshControl(&update_rect); - } - } - else - { - const double register_value = debuggerState.debugSession.ppcSnapshot.fpr[register_index].fp1; - wxTextEntryDialog set_value_dialog(this, _("Enter a new value."), wxString::Format(_("Set FP1_%d value"), register_index), wxString::Format("%lf", register_value)); - if (set_value_dialog.ShowModal() == wxID_OK) - { - const double new_value = std::stod(set_value_dialog.GetValue().ToStdString()); - debuggerState.debugSession.hCPU->fpr[register_index].fp1 = new_value; - debuggerState.debugSession.ppcSnapshot.fpr[register_index].fp1 = new_value; - - wxRect update_rect(0, line * m_line_height, GetSize().x, m_line_height); - RefreshControl(&update_rect); - } - } - } -} - -void RegisterCtrl::OnGameLoaded() -{ - RefreshControl(); -} - diff --git a/src/gui/wxgui/debugger/RegisterCtrl.h b/src/gui/wxgui/debugger/RegisterCtrl.h deleted file mode 100644 index 19e5d199..00000000 --- a/src/gui/wxgui/debugger/RegisterCtrl.h +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once -#include "wxgui/components/TextList.h" -#include "Cafe/HW/Espresso/Debugger/Debugger.h" - -class RegisterCtrl : public TextList -{ -public: - RegisterCtrl(wxWindow* parent, const wxWindowID& id, const wxPoint& pos, const wxSize& size, long style); - void OnGameLoaded(); - -protected: - void OnDraw(wxDC& dc, sint32 start, sint32 count, const wxPoint& start_position) override; - void OnMouseMove(const wxPoint& position, uint32 line) override; - void OnMouseDClick(const wxPoint& position, uint32 line) override; - -private: - PPCSnapshot m_prev_snapshot; -}; diff --git a/src/gui/wxgui/debugger/RegisterWindow.cpp b/src/gui/wxgui/debugger/RegisterWindow.cpp index 0a2e4af2..aebff703 100644 --- a/src/gui/wxgui/debugger/RegisterWindow.cpp +++ b/src/gui/wxgui/debugger/RegisterWindow.cpp @@ -33,8 +33,8 @@ RegisterWindow::RegisterWindow(DebuggerWindow2& parent, const wxPoint& main_posi { SetSizeHints(wxDefaultSize, wxDefaultSize); SetMaxSize({ 400, 975 }); - wxWindowBase::SetBackgroundColour(*wxWHITE); - + this->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); + wxBoxSizer* main_sizer = new wxBoxSizer(wxVERTICAL); auto scrolled_win = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxVSCROLL); @@ -47,29 +47,33 @@ RegisterWindow::RegisterWindow(DebuggerWindow2& parent, const wxPoint& main_posi { gpr_sizer->Add(new wxStaticText(scrolled_win, wxID_ANY, wxString::Format("R%d", i)), 0, wxLEFT, 5); - auto value = new wxTextCtrl(scrolled_win, kRegisterValueR0 + i, wxString::Format("%08x", 0), wxDefaultPosition, wxDefaultSize, wxTE_READONLY | wxNO_BORDER); - value->SetBackgroundColour(*wxWHITE); + auto value = new wxTextCtrl(scrolled_win, kRegisterValueR0 + i, wxString::Format("%08x", 0), wxDefaultPosition, wxDefaultSize, wxTE_READONLY | wxNO_BORDER | wxTE_RICH2); + value->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); + value->SetForegroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT)); value->Bind(wxEVT_LEFT_DCLICK, &RegisterWindow::OnMouseDClickEvent, this); //value->Bind(wxEVT_CONTEXT_MENU, &RegisterWindow::OnValueContextMenu, this); gpr_sizer->Add(value, 0, wxLEFT|wxRIGHT, 5); - auto label = new wxTextCtrl(scrolled_win, kRegisterLabelR0 + i, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY | wxNO_BORDER); + auto label = new wxTextCtrl(scrolled_win, kRegisterLabelR0 + i, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY | wxNO_BORDER | wxTE_RICH2); + label->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); + label->SetForegroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT)); label->SetMinSize(wxSize(500, -1)); - label->SetBackgroundColour(*wxWHITE); gpr_sizer->Add(label, 0, wxEXPAND); } { // LR gpr_sizer->Add(new wxStaticText(scrolled_win, wxID_ANY, wxString::Format("LR")), 0, wxLEFT, 5); - auto value = new wxTextCtrl(scrolled_win, kRegisterValueLR, wxString::Format("%08x", 0), wxDefaultPosition, wxDefaultSize, wxTE_READONLY | wxNO_BORDER); - value->SetBackgroundColour(*wxWHITE); + auto value = new wxTextCtrl(scrolled_win, kRegisterValueLR, wxString::Format("%08x", 0), wxDefaultPosition, wxDefaultSize, wxTE_READONLY | wxNO_BORDER | wxTE_RICH2); + value->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); + value->SetForegroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT)); value->Bind(wxEVT_LEFT_DCLICK, &RegisterWindow::OnMouseDClickEvent, this); //value->Bind(wxEVT_CONTEXT_MENU, &RegisterWindow::OnValueContextMenu, this); gpr_sizer->Add(value, 0, wxLEFT | wxRIGHT, 5); - auto label = new wxTextCtrl(scrolled_win, kRegisterLabelLR, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY | wxNO_BORDER); + auto label = new wxTextCtrl(scrolled_win, kRegisterLabelLR, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY | wxNO_BORDER | wxTE_RICH2); + label->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); + label->SetForegroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT)); label->SetMinSize(wxSize(500, -1)); - label->SetBackgroundColour(*wxWHITE); gpr_sizer->Add(label, 0, wxEXPAND); } @@ -84,13 +88,15 @@ RegisterWindow::RegisterWindow(DebuggerWindow2& parent, const wxPoint& main_posi { fp_sizer->Add(new wxStaticText(scrolled_win, wxID_ANY, wxString::Format("FP%d", i)), 0, wxLEFT, 5); - auto value0 = new wxTextCtrl(scrolled_win, kRegisterValueFPR0_0 + i, wxString::Format("%lf", 0.0), wxDefaultPosition, wxDefaultSize, wxTE_READONLY | wxNO_BORDER); - value0->SetBackgroundColour(*wxWHITE); + auto value0 = new wxTextCtrl(scrolled_win, kRegisterValueFPR0_0 + i, wxString::Format("%lf", 0.0), wxDefaultPosition, wxDefaultSize, wxTE_READONLY | wxNO_BORDER | wxTE_RICH2); + value0->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); + value0->SetForegroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT)); value0->Bind(wxEVT_LEFT_DCLICK, &RegisterWindow::OnMouseDClickEvent, this); fp_sizer->Add(value0, 0, wxLEFT | wxRIGHT, 5); - auto value1 = new wxTextCtrl(scrolled_win, kRegisterValueFPR1_0 + i, wxString::Format("%lf", 0.0), wxDefaultPosition, wxDefaultSize, wxTE_READONLY | wxNO_BORDER); - value1->SetBackgroundColour(*wxWHITE); + auto value1 = new wxTextCtrl(scrolled_win, kRegisterValueFPR1_0 + i, wxString::Format("%lf", 0.0), wxDefaultPosition, wxDefaultSize, wxTE_READONLY | wxNO_BORDER | wxTE_RICH2); + value1->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); + value1->SetForegroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT)); value1->Bind(wxEVT_LEFT_DCLICK, &RegisterWindow::OnMouseDClickEvent, this); fp_sizer->Add(value1, 0, wxLEFT | wxRIGHT, 5); } @@ -102,8 +108,9 @@ RegisterWindow::RegisterWindow(DebuggerWindow2& parent, const wxPoint& main_posi for (sint32 i = 0; i < 8; ++i) { cr_sizer->Add(new wxStaticText(scrolled_win, wxID_ANY, wxString::Format("CR%d", i)), 0, wxLEFT, 5); - auto value = new wxTextCtrl(scrolled_win, kRegisterValueCR0 + i, "-", wxDefaultPosition, wxDefaultSize, wxTE_READONLY | wxNO_BORDER); - value->SetBackgroundColour(*wxWHITE); + auto value = new wxTextCtrl(scrolled_win, kRegisterValueCR0 + i, "-", wxDefaultPosition, wxDefaultSize, wxTE_READONLY | wxNO_BORDER | wxTE_RICH2); + value->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); + value->SetForegroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT)); //value->Bind(wxEVT_CONTEXT_MENU, &RegisterWindow::OnValueContextMenu, this); cr_sizer->Add(value, 0, wxRIGHT, 5); } @@ -141,15 +148,15 @@ void RegisterWindow::UpdateIntegerRegister(wxTextCtrl* label, wxTextCtrl* value, //const bool has_changed = register_value != m_prev_snapshot.gpr[i]; if (hasChanged) - value->SetForegroundColour(COLOR_RED); - else if (value->GetForegroundColour() != COLOR_BLACK) - value->SetForegroundColour(COLOR_BLACK); + value->SetForegroundColour(m_changed_color); + else if (value->GetForegroundColour() != wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT)) + value->SetForegroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT)); value->ChangeValue(wxString::Format("%08x", registerValue)); //const auto label = dynamic_cast(GetWindowChild(kRegisterLabelR0 + i)); //wxASSERT(label); - label->SetForegroundColour(hasChanged ? COLOR_RED : COLOR_BLACK); + label->SetForegroundColour(hasChanged ? m_changed_color : wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT)); // check if address is a string if (registerValue >= MEMORY_DATA_AREA_ADDR && registerValue < (MEMORY_DATA_AREA_ADDR + MEMORY_DATA_AREA_SIZE)) @@ -257,9 +264,9 @@ void RegisterWindow::OnUpdateView() const bool has_changed = register_value != m_prev_snapshot.fpr[i].fp0int; if (has_changed) - value->SetForegroundColour(COLOR_RED); - else if (value->GetForegroundColour() != COLOR_BLACK) - value->SetForegroundColour(COLOR_BLACK); + value->SetForegroundColour(m_changed_color); + else if (value->GetForegroundColour() != wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT)) + value->SetForegroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT)); else continue; @@ -278,9 +285,9 @@ void RegisterWindow::OnUpdateView() const bool has_changed = register_value != m_prev_snapshot.fpr[i].fp1int; if (has_changed) - value->SetForegroundColour(COLOR_RED); - else if (value->GetForegroundColour() != COLOR_BLACK) - value->SetForegroundColour(COLOR_BLACK); + value->SetForegroundColour(m_changed_color); + else if (value->GetForegroundColour() != wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT)) + value->SetForegroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT)); else continue; @@ -301,9 +308,9 @@ void RegisterWindow::OnUpdateView() const bool has_changed = !std::equal(cr_bits_ptr, cr_bits_ptr + 4, cr_bits_ptr_cmp); if (has_changed) - value->SetForegroundColour(COLOR_RED); - else if (value->GetForegroundColour() != COLOR_BLACK) - value->SetForegroundColour(COLOR_BLACK); + value->SetForegroundColour(m_changed_color); + else if (value->GetForegroundColour() != wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT)) + value->SetForegroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT)); else continue; diff --git a/src/gui/wxgui/debugger/RegisterWindow.h b/src/gui/wxgui/debugger/RegisterWindow.h index ad1be800..24fc4e5f 100644 --- a/src/gui/wxgui/debugger/RegisterWindow.h +++ b/src/gui/wxgui/debugger/RegisterWindow.h @@ -21,6 +21,7 @@ private: PPCSnapshot m_prev_snapshot; bool m_show_double_values; + wxColour m_changed_color = {0xFF0000FF}; wxTextCtrl* m_context_ctrl; }; \ No newline at end of file diff --git a/src/gui/wxgui/debugger/SymbolWindow.cpp b/src/gui/wxgui/debugger/SymbolWindow.cpp index 23537efe..c7aad6c8 100644 --- a/src/gui/wxgui/debugger/SymbolWindow.cpp +++ b/src/gui/wxgui/debugger/SymbolWindow.cpp @@ -14,8 +14,6 @@ enum ItemColumns SymbolWindow::SymbolWindow(DebuggerWindow2& parent, const wxPoint& main_position, const wxSize& main_size) : wxFrame(&parent, wxID_ANY, _("Symbols"), wxDefaultPosition, wxSize(600, 250), wxSYSTEM_MENU | wxCAPTION | wxCLIP_CHILDREN | wxRESIZE_BORDER | wxFRAME_FLOAT_ON_PARENT) { - this->wxWindowBase::SetBackgroundColour(*wxWHITE); - wxBoxSizer* main_sizer = new wxBoxSizer(wxVERTICAL); m_symbol_ctrl = new SymbolListCtrl(this, wxID_ANY, wxDefaultPosition, wxDefaultSize); main_sizer->Add(m_symbol_ctrl, 1, wxEXPAND); diff --git a/src/gui/wxgui/helpers/wxControlObject.h b/src/gui/wxgui/helpers/wxControlObject.h index 45cafa44..5726001f 100644 --- a/src/gui/wxgui/helpers/wxControlObject.h +++ b/src/gui/wxgui/helpers/wxControlObject.h @@ -11,7 +11,7 @@ public: template T* GetControl() const { - static_assert(std::is_base_of::value, "T must inherit from wxControl"); + static_assert(std::is_base_of_v, "T must inherit from wxControl"); return dynamic_cast(m_control); } @@ -30,7 +30,7 @@ public: template T* GetControl(int index) const { - static_assert(std::is_base_of::value, "T must inherit from wxControl"); + static_assert(std::is_base_of_v, "T must inherit from wxControl"); if (index < 0 || index >= m_controls.size()) return nullptr; @@ -41,4 +41,4 @@ public: private: std::vector m_controls; -}; \ No newline at end of file +}; diff --git a/src/gui/wxgui/helpers/wxHelpers.cpp b/src/gui/wxgui/helpers/wxHelpers.cpp index 7904a3bf..0d734372 100644 --- a/src/gui/wxgui/helpers/wxHelpers.cpp +++ b/src/gui/wxgui/helpers/wxHelpers.cpp @@ -5,7 +5,7 @@ #include #include -#if BOOST_OS_LINUX +#if BOOST_OS_LINUX || BOOST_OS_BSD #include #include #include @@ -81,7 +81,7 @@ WindowSystem::WindowHandleInfo initHandleContextFromWxWidgetsWindow(wxWindow* wx #if BOOST_OS_WINDOWS handleInfo.backend = WindowSystem::WindowHandleInfo::Backend::Windows; handleInfo.surface = reinterpret_cast(wxw->GetHWND()); -#elif BOOST_OS_LINUX +#elif BOOST_OS_LINUX || BOOST_OS_BSD GtkWidget* gtkWidget = (GtkWidget*)wxw->GetHandle(); // returns GtkWidget gtk_widget_realize(gtkWidget); GdkWindow* gdkWindow = gtk_widget_get_window(gtkWidget); diff --git a/src/gui/wxgui/helpers/wxWayland.cpp b/src/gui/wxgui/helpers/wxWayland.cpp index 6ec932bd..6e7ff789 100644 --- a/src/gui/wxgui/helpers/wxWayland.cpp +++ b/src/gui/wxgui/helpers/wxWayland.cpp @@ -1,6 +1,6 @@ #include "wxgui/helpers/wxWayland.h" -#if BOOST_OS_LINUX && HAS_WAYLAND +#if ( BOOST_OS_LINUX || BOOST_OS_BSD ) && HAS_WAYLAND #include diff --git a/src/gui/wxgui/helpers/wxWayland.h b/src/gui/wxgui/helpers/wxWayland.h index a3b82119..0f162787 100644 --- a/src/gui/wxgui/helpers/wxWayland.h +++ b/src/gui/wxgui/helpers/wxWayland.h @@ -1,6 +1,6 @@ #pragma once -#if BOOST_OS_LINUX && HAS_WAYLAND +#if ( BOOST_OS_LINUX || BOOST_OS_BSD ) && HAS_WAYLAND #include #include diff --git a/src/gui/wxgui/input/HotkeySettings.cpp b/src/gui/wxgui/input/HotkeySettings.cpp index 626bdcd1..195061d7 100644 --- a/src/gui/wxgui/input/HotkeySettings.cpp +++ b/src/gui/wxgui/input/HotkeySettings.cpp @@ -4,6 +4,7 @@ #include #include "input/InputManager.h" #include "HotkeySettings.h" +#include "MainWindow.h" #include @@ -11,7 +12,7 @@ #include #endif -#if BOOST_OS_LINUX || BOOST_OS_MACOS +#if BOOST_OS_LINUX || BOOST_OS_MACOS || BOOST_OS_BSD #include "resource/embedded/resources.h" #endif @@ -88,11 +89,11 @@ std::optional SaveScreenshot(std::vector data, int width, in if (SaveScreenshotToClipboard(image)) { if (!save_screenshot) - return "Screenshot saved to clipboard"; + return _tr("Screenshot saved to clipboard"); } else { - return "Failed to open clipboard"; + return _tr("Failed to open clipboard"); } } if (save_screenshot) @@ -101,24 +102,19 @@ std::optional SaveScreenshot(std::vector data, int width, in if (imagePath.has_value() && SaveScreenshotToFile(imagePath.value(), image)) { if (mainWindow) - return "Screenshot saved"; + return _tr("Screenshot saved"); } else { - return "Failed to save screenshot to file"; + return _tr("Failed to save screenshot to file"); } } return std::nullopt; } extern WindowSystem::WindowInfo g_window_info; -const std::unordered_map> HotkeySettings::s_cfgHotkeyToFuncMap{ - {&s_cfgHotkeys.toggleFullscreen, [](void) { s_mainWindow->ShowFullScreen(!s_mainWindow->IsFullScreen()); }}, - {&s_cfgHotkeys.toggleFullscreenAlt, [](void) { s_mainWindow->ShowFullScreen(!s_mainWindow->IsFullScreen()); }}, - {&s_cfgHotkeys.exitFullscreen, [](void) { s_mainWindow->ShowFullScreen(false); }}, - {&s_cfgHotkeys.takeScreenshot, [](void) { if(g_renderer) g_renderer->RequestScreenshot(SaveScreenshot); }}, - {&s_cfgHotkeys.toggleFastForward, [](void) { ActiveSettings::SetTimerShiftFactor((ActiveSettings::GetTimerShiftFactor() < 3) ? 3 : 1); }}, -}; + +std::unordered_map> HotkeySettings::s_cfgHotkeyToFuncMap; struct HotkeyEntry { @@ -144,9 +140,8 @@ HotkeySettings::HotkeySettings(wxWindow* parent) m_sizer->AddGrowableCol(1); m_sizer->AddGrowableCol(2); - m_panel = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxBORDER_SIMPLE); + m_panel = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxBORDER_THEME); m_panel->SetSizer(m_sizer); - m_panel->SetBackgroundColour(*wxWHITE); Center(); @@ -155,13 +150,13 @@ HotkeySettings::HotkeySettings(wxWindow* parent) CreateColumnHeaders(); /* global modifier */ - CreateHotkeyRow("Hotkey modifier", s_cfgHotkeys.modifiers); + CreateHotkeyRow(_tr("Hotkey modifier"), s_cfgHotkeys.modifiers); m_hotkeys.at(0).keyInput->Hide(); /* hotkeys */ - CreateHotkeyRow("Toggle fullscreen", s_cfgHotkeys.toggleFullscreen); - CreateHotkeyRow("Take screenshot", s_cfgHotkeys.takeScreenshot); - CreateHotkeyRow("Toggle fast-forward", s_cfgHotkeys.toggleFastForward); + CreateHotkeyRow(_tr("Toggle fullscreen"), s_cfgHotkeys.toggleFullscreen); + CreateHotkeyRow(_tr("Take screenshot"), s_cfgHotkeys.takeScreenshot); + CreateHotkeyRow(_tr("Toggle fast-forward"), s_cfgHotkeys.toggleFastForward); m_controllerTimer = new wxTimer(this); Bind(wxEVT_TIMER, &HotkeySettings::OnControllerTimer, this); @@ -178,8 +173,27 @@ HotkeySettings::~HotkeySettings() } } -void HotkeySettings::Init(wxFrame* mainWindowFrame) +void HotkeySettings::Init(MainWindow* mainWindowFrame) { + s_cfgHotkeyToFuncMap.insert({ + {&s_cfgHotkeys.toggleFullscreen, [](void) { + s_mainWindow->SetFullScreen(!s_mainWindow->IsFullScreen()); + }}, + {&s_cfgHotkeys.toggleFullscreenAlt, [](void) { + s_mainWindow->SetFullScreen(!s_mainWindow->IsFullScreen()); + }}, + {&s_cfgHotkeys.exitFullscreen, [](void) { + s_mainWindow->SetFullScreen(false); + }}, + {&s_cfgHotkeys.takeScreenshot, [](void) { + if (g_renderer) + g_renderer->RequestScreenshot(SaveScreenshot); + }}, + {&s_cfgHotkeys.toggleFastForward, [](void) { + ActiveSettings::SetTimerShiftFactor((ActiveSettings::GetTimerShiftFactor() < 3) ? 3 : 1); + }}, + }); + s_keyboardHotkeyToFuncMap.reserve(s_cfgHotkeyToFuncMap.size()); for (const auto& [cfgHotkey, func] : s_cfgHotkeyToFuncMap) { @@ -200,13 +214,15 @@ void HotkeySettings::Init(wxFrame* mainWindowFrame) void HotkeySettings::CreateColumnHeaders(void) { auto* emptySpace = new wxStaticText(m_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxALIGN_CENTER_HORIZONTAL); - auto* keyboard = new wxStaticText(m_panel, wxID_ANY, "Keyboard", wxDefaultPosition, wxDefaultSize, wxALIGN_CENTER_HORIZONTAL); - auto* controller = new wxStaticText(m_panel, wxID_ANY, "Controller", wxDefaultPosition, wxDefaultSize, wxALIGN_CENTER_HORIZONTAL); + auto* keyboard = new wxStaticText(m_panel, wxID_ANY, _tr("Keyboard"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTER_HORIZONTAL); + auto* controller = new wxStaticText(m_panel, wxID_ANY, _tr("Controller"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTER_HORIZONTAL); + keyboard->SetFont(keyboard->GetFont().Bold().Larger()); + controller->SetFont(controller->GetFont().Bold().Larger()); keyboard->SetMinSize(m_minButtonSize); controller->SetMinSize(m_minButtonSize); - auto flags = wxSizerFlags().Expand(); + auto flags = wxSizerFlags().Expand().Border(wxTOP, 10); m_sizer->Add(emptySpace, flags); m_sizer->Add(keyboard, flags); m_sizer->Add(controller, flags); @@ -229,11 +245,7 @@ void HotkeySettings::CreateHotkeyRow(const wxString& label, sHotkeyCfg& cfgHotke keyInput->SetMinSize(m_minButtonSize); controllerInput->SetMinSize(m_minButtonSize); -#if BOOST_OS_WINDOWS - const wxColour inputButtonColor = 0xfafafa; -#else const wxColour inputButtonColor = GetBackgroundColour(); -#endif keyInput->SetBackgroundColour(inputButtonColor); controllerInput->SetBackgroundColour(inputButtonColor); @@ -325,7 +337,7 @@ void HotkeySettings::OnKeyboardHotkeyInputRightClick(wxMouseEvent& event) } auto* inputButton = static_cast(event.GetEventObject()); auto& cfgHotkey = *static_cast(inputButton->GetClientData()); - uKeyboardHotkey newHotkey{ sHotkeyCfg::keyboardNone }; + uKeyboardHotkey newHotkey{sHotkeyCfg::keyboardNone}; if (cfgHotkey.keyboard.raw != newHotkey.raw) { m_needToSave |= true; @@ -344,7 +356,7 @@ void HotkeySettings::OnControllerHotkeyInputRightClick(wxMouseEvent& event) } auto* inputButton = static_cast(event.GetEventObject()); auto& cfgHotkey = *static_cast(inputButton->GetClientData()); - ControllerHotkey_t newHotkey{ sHotkeyCfg::controllerNone }; + ControllerHotkey_t newHotkey{sHotkeyCfg::controllerNone}; if (cfgHotkey.controller != newHotkey) { m_needToSave |= true; @@ -394,7 +406,7 @@ void HotkeySettings::OnKeyUp(wxKeyEvent& event) FinalizeInput(inputButton); } -template +template void HotkeySettings::FinalizeInput(wxButton* inputButton) { auto& cfgHotkey = *static_cast(inputButton->GetClientData()); @@ -402,14 +414,15 @@ void HotkeySettings::FinalizeInput(wxButton* inputButton) { inputButton->Unbind(wxEVT_KEY_UP, &HotkeySettings::OnKeyUp, this); inputButton->SetLabelText(To_wxString(cfgHotkey.keyboard)); - } else if constexpr (std::is_same_v) + } + else if constexpr (std::is_same_v) { inputButton->SetLabelText(To_wxString(cfgHotkey.controller)); } m_activeInputButton = nullptr; } -template +template void HotkeySettings::RestoreInputButton(void) { FinalizeInput(m_activeInputButton); diff --git a/src/gui/wxgui/input/HotkeySettings.h b/src/gui/wxgui/input/HotkeySettings.h index c9395b5a..4ed1e396 100644 --- a/src/gui/wxgui/input/HotkeySettings.h +++ b/src/gui/wxgui/input/HotkeySettings.h @@ -9,7 +9,7 @@ class HotkeyEntry; class HotkeySettings : public wxFrame { public: - static void Init(wxFrame* mainWindowFrame); + static void Init(class MainWindow* mainWindow); static void CaptureInput(wxKeyEvent& event); static void CaptureInput(const ControllerState& currentState, const ControllerState& lastState); @@ -18,8 +18,8 @@ public: ~HotkeySettings(); private: - inline static wxFrame* s_mainWindow = nullptr; - static const std::unordered_map> s_cfgHotkeyToFuncMap; + inline static class MainWindow* s_mainWindow = nullptr; + static std::unordered_map> s_cfgHotkeyToFuncMap; inline static std::unordered_map> s_keyboardHotkeyToFuncMap{}; inline static std::unordered_map> s_controllerHotkeyToFuncMap{}; inline static auto& s_cfgHotkeys = GetWxGUIConfig().hotkeys; diff --git a/src/gui/wxgui/input/InputAPIAddWindow.cpp b/src/gui/wxgui/input/InputAPIAddWindow.cpp index 6a9d74bd..1e5b1d66 100644 --- a/src/gui/wxgui/input/InputAPIAddWindow.cpp +++ b/src/gui/wxgui/input/InputAPIAddWindow.cpp @@ -190,7 +190,7 @@ void InputAPIAddWindow::on_api_selected(wxCommandEvent& event) } else { -#if BOOST_OS_LINUX +#if BOOST_OS_LINUX || BOOST_OS_BSD // We rely on the wxEVT_COMBOBOX_DROPDOWN event to trigger filling the controller list, // but on wxGTK the dropdown button cannot be clicked if the list is empty // so as a quick and dirty workaround we fill the list here diff --git a/src/gui/wxgui/input/InputSettings2.cpp b/src/gui/wxgui/input/InputSettings2.cpp index b36b2993..8fbc5027 100644 --- a/src/gui/wxgui/input/InputSettings2.cpp +++ b/src/gui/wxgui/input/InputSettings2.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include "config/ActiveSettings.h" #include "wxgui/input/InputAPIAddWindow.h" @@ -70,9 +71,9 @@ InputSettings2::InputSettings2(wxWindow* parent) g_inputConfigWindowHasFocus = true; - m_connected = wxBITMAP_PNG_FROM_DATA(INPUT_CONNECTED); - m_disconnected = wxBITMAP_PNG_FROM_DATA(INPUT_DISCONNECTED); - m_low_battery = wxBITMAP_PNG_FROM_DATA(INPUT_LOW_BATTERY); + m_connected = wxHelper::LoadThemedBitmapFromPNG(INPUT_CONNECTED_png, sizeof(INPUT_CONNECTED_png), wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT)); + m_disconnected = wxHelper::LoadThemedBitmapFromPNG(INPUT_DISCONNECTED_png, sizeof(INPUT_DISCONNECTED_png), wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT)); + m_low_battery = wxHelper::LoadThemedBitmapFromPNG(INPUT_LOW_BATTERY_png, sizeof(INPUT_LOW_BATTERY_png), wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT)); auto* sizer = new wxBoxSizer(wxVERTICAL); @@ -149,7 +150,7 @@ wxWindow* InputSettings2::initialize_page(size_t index) auto* profiles = new wxComboBox(page, wxID_ANY, kDefaultProfileName); sizer->Add(profiles, wxGBPosition(0, 1), wxDefaultSpan, wxALIGN_CENTER_VERTICAL | wxALL | wxEXPAND, 5); -#if BOOST_OS_LINUX +#if BOOST_OS_LINUX || BOOST_OS_BSD // We rely on the wxEVT_COMBOBOX_DROPDOWN event to trigger filling the profile list, // but on wxGTK the dropdown button cannot be clicked if the list is empty // so as a quick and dirty workaround we fill the list here diff --git a/src/gui/wxgui/input/panels/InputPanel.h b/src/gui/wxgui/input/panels/InputPanel.h index ef189191..818708eb 100644 --- a/src/gui/wxgui/input/panels/InputPanel.h +++ b/src/gui/wxgui/input/panels/InputPanel.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include "input/emulated/EmulatedController.h" #include "input/api/Controller.h" @@ -14,15 +15,9 @@ class wxComboBox; class InputPanel : public wxPanel { public: -#if BOOST_OS_WINDOWS - const wxColour kKeyColourNormalMode = 0xfafafa; - const wxColour kKeyColourEditMode = 0x99ccff; - const wxColour kKeyColourActiveMode = 0xE0E0E0; -#else const wxColour kKeyColourNormalMode = GetBackgroundColour(); - const wxColour kKeyColourEditMode = GetBackgroundColour(); - const wxColour kKeyColourActiveMode = wxHelper::CalculateAccentColour(kKeyColourNormalMode); -#endif + const wxColour kKeyColourEditMode = wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT); + const wxColour kKeyColourActiveMode = wxHelper::CalculateAccentColour(GetBackgroundColour()); InputPanel(wxWindow* parent); diff --git a/src/gui/wxgui/windows/PPCThreadsViewer/DebugPPCThreadsWindow.cpp b/src/gui/wxgui/windows/PPCThreadsViewer/DebugPPCThreadsWindow.cpp index 6bfcd69e..323eda39 100644 --- a/src/gui/wxgui/windows/PPCThreadsViewer/DebugPPCThreadsWindow.cpp +++ b/src/gui/wxgui/windows/PPCThreadsViewer/DebugPPCThreadsWindow.cpp @@ -40,8 +40,6 @@ DebugPPCThreadsWindow::DebugPPCThreadsWindow(wxFrame& parent) : wxFrame(&parent, wxID_ANY, _("PPC threads"), wxDefaultPosition, wxSize(930, 280), wxCLOSE_BOX | wxCLIP_CHILDREN | wxCAPTION | wxRESIZE_BORDER) { - wxFrame::SetBackgroundColour(*wxWHITE); - auto* sizer = new wxBoxSizer(wxVERTICAL); m_thread_list = new wxListView(this, GPLIST_ID, wxPoint(0, 0), wxSize(930, 240), wxLC_REPORT); diff --git a/src/gui/wxgui/windows/TextureRelationViewer/TextureRelationWindow.cpp b/src/gui/wxgui/windows/TextureRelationViewer/TextureRelationWindow.cpp index 3350d0c5..d0169ab0 100644 --- a/src/gui/wxgui/windows/TextureRelationViewer/TextureRelationWindow.cpp +++ b/src/gui/wxgui/windows/TextureRelationViewer/TextureRelationWindow.cpp @@ -1,4 +1,5 @@ #include "wxgui/wxgui.h" +#include "wxHelper.h" #include "TextureRelationWindow.h" #include "Cafe/HW/Latte/Core/LatteTexture.h" @@ -113,14 +114,14 @@ TextureRelationViewerWindow::TextureRelationViewerWindow(wxFrame& parent) wxBoxSizer* sizerBottom = new wxBoxSizer(wxHORIZONTAL); sizer->Add(textureRelationListA, 1, wxEXPAND | wxBOTTOM, 0); - wxButton* button = new wxButton(mainPane, REFRESH_ID, _("Refresh"), wxPoint(0, 0), wxSize(80, 26)); - sizerBottom->Add(button, 0, wxBOTTOM | wxTOP | wxLEFT, 10); + wxButton* button = new wxButton(mainPane, REFRESH_ID, _("Refresh")); + sizerBottom->Add(button, 0, wxALIGN_CENTER_VERTICAL | wxBOTTOM | wxTOP | wxLEFT, 10); - wxCheckBox* checkboxShowOnlyActive = new wxCheckBox(mainPane, CHECKBOX_SHOW_ONLY_ACTIVE, _("Show only active"), wxPoint(0, 0), wxSize(110, 26)); - sizerBottom->Add(checkboxShowOnlyActive, 0, wxBOTTOM | wxTOP | wxLEFT, 10); + wxCheckBox* checkboxShowOnlyActive = new wxCheckBox(mainPane, CHECKBOX_SHOW_ONLY_ACTIVE, _("Show only active")); + sizerBottom->Add(checkboxShowOnlyActive, 0, wxALIGN_CENTER_VERTICAL | wxBOTTOM | wxTOP | wxLEFT, 10); - wxCheckBox* checkboxShowViews = new wxCheckBox(mainPane, CHECKBOX_SHOW_VIEWS, _("Show views"), wxPoint(0, 0), wxSize(90, 26)); - sizerBottom->Add(checkboxShowViews, 0, wxBOTTOM | wxTOP | wxLEFT, 10); + wxCheckBox* checkboxShowViews = new wxCheckBox(mainPane, CHECKBOX_SHOW_VIEWS, _("Show views")); + sizerBottom->Add(checkboxShowViews, 0, wxALIGN_CENTER_VERTICAL | wxBOTTOM | wxTOP | wxLEFT, 10); checkboxShowViews->SetValue(true); textureRelationListA->Connect(wxEVT_RIGHT_DOWN, wxMouseEventHandler(TextureRelationViewerWindow::OnTextureListRightClick), NULL, this); @@ -132,8 +133,6 @@ TextureRelationViewerWindow::TextureRelationViewerWindow(wxFrame& parent) mainPane->SetSizer(sizer); RefreshTextureList(); - - wxFrame::SetBackgroundColour(*wxWHITE); } TextureRelationViewerWindow::~TextureRelationViewerWindow() @@ -183,11 +182,10 @@ void TextureRelationViewerWindow::_setTextureRelationListItemTexture(wxListCtrl* { sprintf(tempStr + strlen(tempStr), "(%d)", alternativeViewCount + 1); } - uint32 bgColor = 0xFFEEEEEE; wxListItem item; item.SetId(rowIndex); item.SetText(tempStr); - item.SetBackgroundColour(wxColour(bgColor)); + item.SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); uiList->InsertItem(item); sint32 columnIndex = 1; @@ -279,11 +277,10 @@ void TextureRelationViewerWindow::_setTextureRelationListItemView(wxListCtrl* ui else sprintf(tempStr, "> VIEW(%d)", alternativeViewCount+1); // find and handle highlight entry - uint32 bgColor = 0xFFDDDDDD; wxListItem item; item.SetId(rowIndex); item.SetText(tempStr); - item.SetBackgroundColour(wxColour(bgColor)); + item.SetBackgroundColour(wxHelper::CalculateAccentColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW))); uiList->InsertItem(item); //uiList->SetItemPtrData(item, (wxUIntPtr)viewInfo); sint32 columnIndex = 1; @@ -392,7 +389,6 @@ void TextureRelationViewerWindow::RefreshTextureList() void TextureRelationViewerWindow::OnTextureListRightClick(wxMouseEvent& event) { - } void TextureRelationViewerWindow::Close() diff --git a/src/gui/wxgui/wxCemuConfig.cpp b/src/gui/wxgui/wxCemuConfig.cpp index 87355797..bbd24ab4 100644 --- a/src/gui/wxgui/wxCemuConfig.cpp +++ b/src/gui/wxgui/wxCemuConfig.cpp @@ -26,6 +26,7 @@ void wxCemuConfig::AddRecentNfcFile(std::string_view file) void wxCemuConfig::Load(XMLConfigParser& parser) { language = parser.get("language", wxLANGUAGE_DEFAULT); + msw_theme = parser.get("msw_theme", msw_theme); use_discord_presence = parser.get("use_discord_presence", true); fullscreen_menubar = parser.get("fullscreen_menubar", false); feral_gamemode = parser.get("feral_gamemode", false); @@ -120,6 +121,7 @@ void wxCemuConfig::Save(XMLConfigParser& config) { // general settings config.set("language", language); + config.set("msw_theme", msw_theme); config.set("use_discord_presence", use_discord_presence); config.set("fullscreen_menubar", fullscreen_menubar); config.set("feral_gamemode", feral_gamemode); @@ -136,7 +138,6 @@ void wxCemuConfig::Save(XMLConfigParser& config) wpos.set("y", window_position.y); auto wsize = config.set("window_size"); wsize.set("x", window_size.x); - cemu_assert_debug(window_size.x != 0); wsize.set("y", window_size.y); config.set("window_maximized", window_maximized); diff --git a/src/gui/wxgui/wxCemuConfig.h b/src/gui/wxgui/wxCemuConfig.h index 8024e27e..9463d4df 100644 --- a/src/gui/wxgui/wxCemuConfig.h +++ b/src/gui/wxgui/wxCemuConfig.h @@ -20,6 +20,14 @@ namespace DefaultColumnSize }; }; +enum class MSWThemeOption : int +{ + kAuto = 0, + kLight = 1, + kDark = 2, +}; +ENABLE_ENUM_ITERATORS(MSWThemeOption, MSWThemeOption::kAuto, MSWThemeOption::kDark); + typedef union { struct @@ -67,6 +75,7 @@ struct fmt::formatter : formatter struct wxCemuConfig { ConfigValue language{wxLANGUAGE_DEFAULT}; + ConfigValue msw_theme { static_cast(MSWThemeOption::kAuto) }; ConfigValue use_discord_presence{true}; ConfigValue fullscreen{ false }; ConfigValue fullscreen_menubar{false}; diff --git a/src/gui/wxgui/wxHelper.h b/src/gui/wxgui/wxHelper.h index 468651ac..06315756 100644 --- a/src/gui/wxgui/wxHelper.h +++ b/src/gui/wxgui/wxHelper.h @@ -1,5 +1,7 @@ #pragma once #include +#include +#include namespace wxHelper { @@ -33,4 +35,11 @@ namespace wxHelper return bgColourSecondary; } + static wxBitmap LoadThemedBitmapFromPNG(const uint8* data, size_t size, const wxColour& tint) + { + wxMemoryInputStream strm(data, size); + wxImage img(strm, wxBITMAP_TYPE_PNG); + img.Replace(0x00, 0x00, 0x00, tint.Red(), tint.Green(), tint.Blue()); + return wxBitmap(img); + } }; diff --git a/src/gui/wxgui/wxWindowSystem.cpp b/src/gui/wxgui/wxWindowSystem.cpp index a444eb19..fe33829f 100644 --- a/src/gui/wxgui/wxWindowSystem.cpp +++ b/src/gui/wxgui/wxWindowSystem.cpp @@ -3,7 +3,7 @@ #include "helpers/wxHelpers.h" -#if BOOST_OS_LINUX +#if BOOST_OS_LINUX || BOOST_OS_BSD #include #include #include @@ -231,7 +231,7 @@ bool WindowSystem::IsKeyDown(PlatformKeyCodes platformKey) case PlatformKeyCodes::ESCAPE: key = VK_ESCAPE; break; -#elif BOOST_OS_LINUX +#elif BOOST_OS_LINUX || BOOST_OS_BSD case PlatformKeyCodes::LCONTROL: key = GDK_KEY_Control_L; break; @@ -300,7 +300,7 @@ std::string WindowSystem::GetKeyCodeName(uint32 button) return key_name; else return fmt::format("key_{}", button); -#elif BOOST_OS_LINUX +#elif BOOST_OS_LINUX || BOOST_OS_BSD return gdk_keyval_name(button); #else return fmt::format("key_{}", button); diff --git a/src/gui/wxgui/wxcomponents/checked.xpm b/src/gui/wxgui/wxcomponents/checked.xpm deleted file mode 100644 index e198a8c4..00000000 --- a/src/gui/wxgui/wxcomponents/checked.xpm +++ /dev/null @@ -1,24 +0,0 @@ -/* XPM */ -static const char * checked_xpm[] = { -"16 16 5 1", -" c None", -". c #808080", -"X c Black", -"o c #c0c0c0", -"w c White", -" ", -" ", -" ............ ", -" .XXXXXXXXXXo ", -" .Xwwwwwwwwwo ", -" .XwwwwwwwXwo ", -" .XwwwwwwXXwo ", -" .XwXwwwXXXwo ", -" .XwXXwXXXwwo ", -" .XwXXXXXwwwo ", -" .XwwXXXwwwwo ", -" .XwwwXwwwwwo ", -" .Xwwwwwwwwwo ", -" .ooooooooooo ", -" ", -" "}; diff --git a/src/gui/wxgui/wxcomponents/checked2.xpm b/src/gui/wxgui/wxcomponents/checked2.xpm deleted file mode 100644 index 60fce780..00000000 --- a/src/gui/wxgui/wxcomponents/checked2.xpm +++ /dev/null @@ -1,38 +0,0 @@ -/* XPM */ -static const char * checked2_xpm[] = { -"14 15 20 1", -" c None", -". c #1C5180", -"+ c #E2E2DD", -"@ c #E3E3DF", -"# c #E5E5E1", -"$ c #E7E7E3", -"% c #EAEAE6", -"& c #ECECE9", -"* c #EFEFEC", -"= c #F1F1EF", -"- c #F3F3F1", -"; c #F5F5F3", -"> c #21A121", -", c #F7F7F6", -"' c #F9F9F8", -") c #FAFAF9", -"! c #FCFCFB", -"~ c #FDFDFD", -"{ c #FEFEFE", -"] c #FFFFFF", -"............. ", -".+++@#$%&*=-. ", -".++@#$%&*=-;. ", -".+@#$%&*=>;,. ", -".@#$%&*=>>,'. ", -".#$>&*=>>>'). ", -".$%>>=>>>')!. ", -".%&>>>>>')!~. ", -".&*=>>>')!~{. ", -".*=-;>')!~{]. ", -".=-;,')!~{]]. ", -".-;,')!~{]]]. ", -"............. ", -" ", -" "}; diff --git a/src/gui/wxgui/wxcomponents/checked_d.xpm b/src/gui/wxgui/wxcomponents/checked_d.xpm deleted file mode 100644 index c187ffaa..00000000 --- a/src/gui/wxgui/wxcomponents/checked_d.xpm +++ /dev/null @@ -1,21 +0,0 @@ -/* XPM */ -static const char * checked_d_xpm[] = { -"14 15 3 1", -" c None", -". c #CAC8BB", -"+ c #FFFFFF", -"............. ", -".+++++++++++. ", -".+++++++++++. ", -".++++++++.++. ", -".+++++++..++. ", -".++.+++...++. ", -".++..+...+++. ", -".++.....++++. ", -".+++...+++++. ", -".++++.++++++. ", -".+++++++++++. ", -".+++++++++++. ", -"............. ", -" ", -" "}; diff --git a/src/gui/wxgui/wxcomponents/checked_dis.xpm b/src/gui/wxgui/wxcomponents/checked_dis.xpm deleted file mode 100644 index 2d9e6e5a..00000000 --- a/src/gui/wxgui/wxcomponents/checked_dis.xpm +++ /dev/null @@ -1,23 +0,0 @@ -/* XPM */ -static const char * checked_dis_xpm[] = { -"16 16 4 1", -" c None", -". c #808080", -"X c Black", -"o c #c0c0c0", -" ", -" ", -" ............ ", -" .XXXXXXXXXXo ", -" .Xoooooooooo ", -" .Xooooooo.oo ", -" .Xoooooo..oo ", -" .Xo.ooo...oo ", -" .Xo..o...ooo ", -" .Xo.....oooo ", -" .Xoo...ooooo ", -" .Xooo.oooooo ", -" .Xoooooooooo ", -" .ooooooooooo ", -" ", -" "}; diff --git a/src/gui/wxgui/wxcomponents/checked_ld.xpm b/src/gui/wxgui/wxcomponents/checked_ld.xpm deleted file mode 100644 index 8c860f9a..00000000 --- a/src/gui/wxgui/wxcomponents/checked_ld.xpm +++ /dev/null @@ -1,44 +0,0 @@ -/* XPM */ -static const char * checked_ld_xpm[] = { -"14 15 26 1", -" c None", -". c #1C5180", -"+ c #B0B0A7", -"@ c #B3B3AA", -"# c #B7B7AD", -"$ c #BCBBB1", -"% c #C1C1B6", -"& c #C7C6BB", -"* c #CDCCC0", -"= c #D2D1C5", -"- c #D7D5C8", -"; c #DBDACC", -"> c #1C861A", -", c #DFDDCF", -"' c #1C8A1A", -") c #E3E1D3", -"! c #197A18", -"~ c #1D8C1B", -"{ c #E6E5D6", -"] c #1A7D18", -"^ c #1B8119", -"/ c #EAE8D9", -"( c #1B8419", -"_ c #EDEBDB", -": c #EFEDDD", -"< c #F1EFDF", -"............. ", -".+++@#$%&*=-. ", -".++@#$%&*=-;. ", -".+@#$%&*=>;,. ", -".@#$%&*=>',). ", -".#$!&*=>'~){. ", -".$%]^=>'~){/. ", -".%&^(>'~){/_. ", -".&*=>'~){/_:. ", -".*=-;~){/_:<. ", -".=-;,){/_:<<. ", -".-;,){/_:<<<. ", -"............. ", -" ", -" "}; diff --git a/src/gui/wxgui/wxcomponents/checked_mo.xpm b/src/gui/wxgui/wxcomponents/checked_mo.xpm deleted file mode 100644 index 31ef1330..00000000 --- a/src/gui/wxgui/wxcomponents/checked_mo.xpm +++ /dev/null @@ -1,70 +0,0 @@ -/* XPM */ -static const char * checked_mo_xpm[] = { -"14 15 52 1", -" c None", -". c #1C5180", -"+ c #FFF0CF", -"@ c #FFEDC6", -"# c #FFE9BA", -"$ c #FEE4AC", -"% c #FEDF9C", -"& c #FDD98C", -"* c #FDD889", -"= c #FDDB95", -"- c #FDDC97", -"; c #FCD687", -"> c #FBCA6A", -", c #FDE3AC", -"' c #FDE6B6", -") c #FDDEA2", -"! c #FBD07A", -"~ c #FFEABD", -"{ c #FEE9BC", -"] c #F7F7F5", -"^ c #F6F6F4", -"/ c #F4F4F3", -"( c #F8F8F7", -"_ c #FAFAF9", -": c #21A121", -"< c #FDE3AE", -"[ c #FBD280", -"} c #FEECC4", -"| c #FDE1AB", -"1 c #FBD07B", -"2 c #FEE7B5", -"3 c #FEECC7", -"4 c #FDE0A8", -"5 c #FBCE77", -"6 c #FEE3A9", -"7 c #FEEBC3", -"8 c #FBD892", -"9 c #FAC867", -"0 c #FEE0A3", -"a c #FEE9BF", -"b c #F9BC46", -"c c #F9B73A", -"d c #FCD27A", -"e c #F8B636", -"f c #FBCC6B", -"g c #FCDB99", -"h c #F8B433", -"i c #FBC863", -"j c #FAC55A", -"k c #FAC55B", -"l c #FBCC70", -"m c #F8B330", -"............. ", -".+@#$%&*=-;>. ", -".@#$%&*=,')!. ", -".~{]^/^(_:<[. ", -".{}_(^(_::|1. ", -".23:_(_:::45. ", -".67::_:::_89. ", -".0a:::::_(9b. ", -".=,_:::_(^bc. ", -".d;(_:_(^/ce. ", -".f>!g489bceh. ", -".ijkl59bcehm. ", -"............. ", -" ", -" "}; diff --git a/src/gui/wxgui/wxcomponents/checkedlistctrl.cpp b/src/gui/wxgui/wxcomponents/checkedlistctrl.cpp deleted file mode 100644 index 62100f44..00000000 --- a/src/gui/wxgui/wxcomponents/checkedlistctrl.cpp +++ /dev/null @@ -1,402 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Name: checkedlistctrl.cpp -// Purpose: wxCheckedListCtrl -// Author: Unknown ? (found at http://wiki.wxwidgets.org/wiki.pl?WxListCtrl) -// Modified by: Francesco Montorsi -// Created: 2005/06/29 -// RCS-ID: $Id: checkedlistctrl.cpp 1309 2010-05-01 09:49:59Z frm $ -// Copyright: (c) 2005 Francesco Montorsi -// Licence: wxWidgets licence -///////////////////////////////////////////////////////////////////////////// - - -// For compilers that support precompilation, includes "wx.h". -#include "wx/wxprec.h" - -#ifdef __BORLANDC__ -#pragma hdrstop -#endif - -// includes -#include "wxgui/wxcomponents/checkedlistctrl.h" -#include - -#include - -#if wxUSE_CHECKEDLISTCTRL - -// resources - -#include "wxgui/wxcomponents/checked.xpm" -#include "wxgui/wxcomponents/unchecked.xpm" -#include "wxgui/wxcomponents/checked_dis.xpm" -#include "wxgui/wxcomponents/unchecked_dis.xpm" - -IMPLEMENT_CLASS(wxCheckedListCtrl, wxListCtrl) -BEGIN_EVENT_TABLE(wxCheckedListCtrl, wxListCtrl) - EVT_LEFT_DOWN(wxCheckedListCtrl::OnMouseEvent) -END_EVENT_TABLE() - -DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_ITEM_CHECKED); -DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_ITEM_UNCHECKED); - - - -// ------------------ -// wxCHECKEDLISTCTRL -// ------------------ - -bool wxCheckedListCtrl::Create(wxWindow* parent, wxWindowID id, const wxPoint& pt, - const wxSize& sz, long style, const wxValidator& validator, const wxString& name) -{ - if (!wxListCtrl::Create(parent, id, pt, sz, style, validator, name)) - return FALSE; - - SetImageList(&m_imageList, wxIMAGE_LIST_SMALL); - - // the add order must respect the wxCLC_XXX_IMGIDX defines in the headers ! - m_imageList.Add(wxIcon(unchecked_xpm)); - m_imageList.Add(wxIcon(checked_xpm)); - m_imageList.Add(wxIcon(unchecked_dis_xpm)); - m_imageList.Add(wxIcon(checked_dis_xpm)); - - return TRUE; -} - -/* static */ -int wxCheckedListCtrl::GetItemImageFromAdditionalState(int addstate) -{ - bool checked = (addstate & wxLIST_STATE_CHECKED) != 0; - bool enabled = (addstate & wxLIST_STATE_ENABLED) != 0; - - if (checked && enabled) - return wxCLC_CHECKED_IMGIDX; - else if (checked && !enabled) - return wxCLC_DISABLED_CHECKED_IMGIDX; - else if (!checked && enabled) - return wxCLC_UNCHECKED_IMGIDX; - - wxASSERT(!checked && !enabled); // this is the last possibility - return wxCLC_DISABLED_UNCHECKED_IMGIDX; -} - -wxColour wxCheckedListCtrl::GetBgColourFromAdditionalState(int additionalstate) -{ - if ((additionalstate & wxLIST_STATE_ENABLED) && - this->IsEnabled()) - return *wxWHITE; -#ifdef __WXMSW__ - return wxColour(212, 208, 200); -#else - return wxSystemSettings::GetColour(wxSYS_COLOUR_GRAYTEXT); -#endif -} - -/* static */ -int wxCheckedListCtrl::GetAndRemoveAdditionalState(long *state, int statemask) -{ - int additionalstate = 0; - if (!state) return -1; - - // extract the bits we are interested in - bool checked = (*state & wxLIST_STATE_CHECKED) != 0; - bool enabled = (*state & wxLIST_STATE_ENABLED) != 0; - - // and set them in a different variable if they are included in the statemask - if (checked && (statemask & wxLIST_STATE_CHECKED)) additionalstate |= wxLIST_STATE_CHECKED; - if (enabled && (statemask & wxLIST_STATE_ENABLED)) additionalstate |= wxLIST_STATE_ENABLED; - - // remove them from the original state var... - *state &= ~wxLIST_STATE_CHECKED; - *state &= ~wxLIST_STATE_ENABLED; - return additionalstate; -} - -bool wxCheckedListCtrl::GetItem(wxListItem& info) const -{ - // wx internal wxListCtrl::GetItem remove from the state mask the - // wxLIST_STATE_CHECKED & wxLIST_STATE_ENABLED bits since they - // are not part of wx standard flags... so we need to check those - // flags against the original wxListItem's statemask... - wxListItem original(info); - -#ifdef __WXDEBUG__ - // we always want to retrieve also the image state for checking purposes... - info.m_mask |= wxLIST_MASK_IMAGE; -#endif - - if (!wxListCtrl::GetItem(info)) - return FALSE; - - // these are our additional supported states: read them from m_stateList - bool checked = (m_stateList[info.m_itemId] & wxLIST_STATE_CHECKED) != 0; - bool enabled = (m_stateList[info.m_itemId] & wxLIST_STATE_ENABLED) != 0; - - // now intercept state requests about enable or check mode - if ((original.m_mask & wxLIST_MASK_STATE) && - (original.m_stateMask & wxLIST_STATE_CHECKED)) { - info.m_state |= (m_stateList[info.m_itemId] & wxLIST_STATE_CHECKED); - info.m_stateMask |= wxLIST_STATE_CHECKED; - info.m_mask |= wxLIST_MASK_STATE; // contains valid info ! - } - if ((original.m_mask & wxLIST_MASK_STATE) && - (original.m_stateMask & wxLIST_STATE_ENABLED)) { - info.m_state |= (m_stateList[info.m_itemId] & wxLIST_STATE_ENABLED); - info.m_stateMask |= wxLIST_STATE_ENABLED; - info.m_mask |= wxLIST_MASK_STATE; // contains valid info ! - } - - // check that state & image are synch -#ifdef __WXDEBUG__ - - wxASSERT_MSG((int)m_stateList.GetCount() == (int)GetItemCount(), - wxS("Something wrong ! See InsertItem()")); - - // read info by image index - bool imagecheck = (info.m_image == wxCLC_CHECKED_IMGIDX) || - (info.m_image == wxCLC_DISABLED_CHECKED_IMGIDX); - bool imageenabled = (info.m_image == wxCLC_CHECKED_IMGIDX) || - (info.m_image == wxCLC_UNCHECKED_IMGIDX); - wxASSERT_MSG((checked && imagecheck) || (!checked && !imagecheck), - wxS("This is item has checked state but it's shown as unchecked (or viceversa)")); - wxASSERT_MSG((enabled && imageenabled) || (!enabled && !imageenabled), - wxS("This is item has enabled state but it's shown as disabled (or viceversa)")); -#endif - - return TRUE; -} - -bool wxCheckedListCtrl::SetItem(wxListItem& info) -{ - // remove the checked & enabled states from the state flag: - // we'll store them in our separate array - int additionalstate = GetAndRemoveAdditionalState(&info.m_state, info.m_stateMask); - - // set image index - // we will ignore the info.m_image field since we need - // to overwrite it... - if (info.m_mask & wxLIST_MASK_STATE) { - - // if some state is not included in the state mask, then get the state info - // from our internal state array - if (!(info.m_stateMask & wxLIST_STATE_ENABLED)) - additionalstate |= (m_stateList[info.m_itemId] & wxLIST_STATE_ENABLED); - if (!(info.m_stateMask & wxLIST_STATE_CHECKED)) - additionalstate |= (m_stateList[info.m_itemId] & wxLIST_STATE_CHECKED); - - // state is valid: use it to determine the image to set... - info.m_mask |= wxLIST_MASK_IMAGE; - info.m_image = GetItemImageFromAdditionalState(additionalstate); - - // since when changing the background color, also the foreground color - // and the font of the item are changed, we try to respect the user - // choices of such attributes - info.SetTextColour(this->GetItemTextColour(info.GetId())); -#if wxCHECK_VERSION(2, 6, 2) - // before wx 2.6.2 the wxListCtrl::SetItemFont function is missing - info.SetFont(this->GetItemFont(info.GetId())); -#endif - - // change the background color to respect the enabled/disabled status... - info.SetBackgroundColour(GetBgColourFromAdditionalState(additionalstate)); - - m_stateList[info.m_itemId] = additionalstate; - - } else { - - // state is invalid; don't change image - info.m_mask &= ~wxLIST_MASK_IMAGE; - } - - // save the changes - return wxListCtrl::SetItem(info); -} - -long wxCheckedListCtrl::InsertItem(wxListItem &info) -{ - int additionalstate = GetAndRemoveAdditionalState(&info.m_state, info.m_stateMask); - if (!(info.m_mask & wxLIST_MASK_STATE) || - !(info.m_stateMask & wxLIST_STATE_ENABLED)) { - - // if not specified, the default additional state is ENABLED - additionalstate = wxLIST_STATE_ENABLED; - } - - // we always want to insert items with images... - info.m_mask |= wxLIST_MASK_IMAGE; - info.m_image = GetItemImageFromAdditionalState(additionalstate); - info.SetBackgroundColour(GetBgColourFromAdditionalState(additionalstate)); - - int itemcount = GetItemCount(); - wxASSERT_MSG(info.m_itemId <= itemcount, wxS("Invalid index !")); - wxASSERT_MSG((int)m_stateList.GetCount() == (int)GetItemCount(), - wxS("Something wrong !")); - if (info.m_itemId == itemcount) { - - // we are adding a new item at the end of the list - m_stateList.Add(additionalstate); - - } else { - - // we must shift all following items - cemu_assert_suspicious(); - //for (int i=itemcount; i > info.m_itemId; i--) - // m_stateList[i] = m_stateList[i-1]; - m_stateList[info.m_itemId] = additionalstate; - } - - return wxListCtrl::InsertItem(info); -} - -bool wxCheckedListCtrl::SetItemState(long item, long state, long stateMask) -{ - wxListItem li; - li.SetId(item); - li.SetMask(wxLIST_MASK_STATE); - li.SetState(state); - li.SetStateMask(stateMask); - - // so we are sure to use wxCheckedListCtrl::SetItem - // (and not wxListCtrl::SetItem) - return SetItem(li); -} - -int wxCheckedListCtrl::GetItemState(long item, long stateMask) const -{ - wxListItem li; - li.SetId(item); - li.SetMask(wxLIST_MASK_STATE); - li.SetStateMask(stateMask); - - // so we are sure to use wxCheckedListCtrl::GetItem - // (and not wxListCtrl::GetItem) - if (!GetItem(li)) - return -1; - return li.GetState(); -} - -long wxCheckedListCtrl::SetItem(long index, int col, const wxString& label, int WXUNUSED(imageId)) -{ - wxListItem li; - li.SetId(index); - li.SetColumn(col); - li.SetText(label); - li.SetMask(wxLIST_MASK_TEXT); - - // so we are sure to use wxCheckedListCtrl::SetItem - // (and not wxListCtrl::SetItem) - return SetItem(li); -} - -long wxCheckedListCtrl::InsertItem( long index, const wxString& label, int WXUNUSED(imageIndex) ) -{ - wxListItem info; - info.m_text = label; - info.m_mask = wxLIST_MASK_TEXT; - info.m_itemId = index; - return InsertItem(info); -} - -void wxCheckedListCtrl::Check(long item, bool checked) -{ - // NB: the "statemask" is not the "mask" of a list item; - // in the "mask" you use the wxLIST_MASK_XXXX defines; - // in the "statemask" you use the wxLIST_STATE_XXX defines - // to set a specific bit of the wxListInfo::m_state var - if (checked) - // the 2nd parameter says: activate the STATE bit relative to CHECK feature - // the 3rd parameter says: set only *that* bit - SetItemState(item, wxLIST_STATE_CHECKED, wxLIST_STATE_CHECKED); - else - SetItemState(item, 0, wxLIST_STATE_CHECKED); -} - -void wxCheckedListCtrl::Enable(long item, bool enable) -{ - if (enable) - // the 2nd parameter says: activate the STATE bit relative to ENABLE feature - // the 3rd parameter says: set only *that* bit - SetItemState(item, wxLIST_STATE_ENABLED, wxLIST_STATE_ENABLED); - else - SetItemState(item, 0, wxLIST_STATE_ENABLED); -} - -void wxCheckedListCtrl::EnableAll(bool enable) -{ - for (int i=0; i < GetItemCount(); i++) - Enable(i, enable); -} - -void wxCheckedListCtrl::CheckAll(bool check) -{ - for (int i=0; i < GetItemCount(); i++) - Check(i, check); -} - -bool wxCheckedListCtrl::DeleteItem(long item) -{ - // shift our additional state array - //for (int i=item,max=GetItemCount(); i < max-1; i++) - // m_stateList[i] = m_stateList[i+1]; - m_stateList.RemoveAt(item, 1); - - return wxListCtrl::DeleteItem(item); -} - -int wxCheckedListCtrl::GetCheckedItemCount() const -{ - int res = 0; - for (int i=0; i -#include - -#if wxUSE_CHECKEDLISTCTRL - -// image indexes (used internally by wxCheckedListCtrl) -#define wxCLC_UNCHECKED_IMGIDX 0 // unchecked & enabled -#define wxCLC_CHECKED_IMGIDX 1 // checked & enabled -#define wxCLC_DISABLED_UNCHECKED_IMGIDX 2 // unchecked & disabled -#define wxCLC_DISABLED_CHECKED_IMGIDX 3 // checked & disabled - -// additional state flags (wx's defines should end at 0x0100; see listbase.h) -#define wxLIST_STATE_CHECKED 0x010000 -#define wxLIST_STATE_ENABLED 0x100000 - -// additional wxCheckedListCtrl style flags -// (wx's defines should at 0x8000; see listbase.h) -#define wxCLC_CHECK_WHEN_SELECTING 0x10000 - - -// ------------------------- -// wxCheckedListCtrl events -// ------------------------- - -//DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_WEBUPDATE, wxEVT_COMMAND_LIST_ITEM_CHECKED, -1); -//DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_WEBUPDATE, wxEVT_COMMAND_LIST_ITEM_UNCHECKED, -1); - -DECLARE_EXPORTED_EVENT_TYPE(WXEXPORT, wxEVT_COMMAND_LIST_ITEM_CHECKED, -1); -DECLARE_EXPORTED_EVENT_TYPE(WXEXPORT, wxEVT_COMMAND_LIST_ITEM_UNCHECKED, -1); - - -//DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_ITEM_CHECKED); -//DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_ITEM_UNCHECKED); - -#ifndef EVT_LIST_ITEM_CHECKED -#define EVT_LIST_ITEM_CHECKED(id, fn) \ - DECLARE_EVENT_TABLE_ENTRY( \ - wxEVT_COMMAND_LIST_ITEM_CHECKED, id, -1, \ - (wxObjectEventFunction)(wxEventFunction)(wxListEventFunction)&fn, \ - (wxObject *) NULL \ - ), -#endif - -#ifndef EVT_LIST_ITEM_UNCHECKED -#define EVT_LIST_ITEM_UNCHECKED(id, fn) \ - DECLARE_EVENT_TABLE_ENTRY( \ - wxEVT_COMMAND_LIST_ITEM_UNCHECKED, id, -1, \ - (wxObjectEventFunction)(wxEventFunction)(wxListEventFunction)&fn, \ - (wxObject *) NULL \ - ), -#endif - - -//! This is the class which performs all transactions with the server. -//! It uses the wxSocket facilities. -class wxCheckedListCtrl : public wxListView -{ -protected: - - // we have to keep a different array to keep track of the additional - // states we support.... - wxArrayInt m_stateList; - - // our set of checkbox images... - wxImageList m_imageList; - -public: - wxCheckedListCtrl() - : wxListView(), m_imageList(16, 16, TRUE) {} - - wxCheckedListCtrl(wxWindow *parent, wxWindowID id = wxID_ANY, - const wxPoint& pt = wxDefaultPosition, - const wxSize& sz = wxDefaultSize, - long style = wxCLC_CHECK_WHEN_SELECTING, - const wxValidator& validator = wxDefaultValidator, - const wxString& name = wxListCtrlNameStr) - : wxListView(), m_imageList(16, 16, TRUE) - { Create(parent, id, pt, sz, style, validator, name); } - - bool Create(wxWindow *parent, wxWindowID id = wxID_ANY, - const wxPoint& pt = wxDefaultPosition, - const wxSize& sz = wxDefaultSize, - long style = wxCLC_CHECK_WHEN_SELECTING, - const wxValidator& validator = wxDefaultValidator, - const wxString& name = wxListCtrlNameStr); - - virtual ~wxCheckedListCtrl() {} - - -public: // utilities - - // core overloads (i.e. the most generic overloads) - bool GetItem(wxListItem& info) const; - bool SetItem(wxListItem& info); - long InsertItem(wxListItem& info); - bool DeleteItem(long item); - bool DeleteAllItems() - { m_stateList.Clear(); return wxListCtrl::DeleteAllItems(); } - - bool SortItems(wxListCtrlCompare, long) - { wxASSERT_MSG(0, wxT("Not implemented yet ! sorry... ")); return FALSE; } - - // shortcuts to the SetItemState function - void Check(long item, bool checked); - void Enable(long item, bool enable); - void CheckAll(bool checked = true); - void EnableAll(bool enable = true); - - // this needs to be redeclared otherwise it's hidden by our other Enable() function. - // However you should use #EnableAll instead of this function if you want to get - // good graphics (try to understand) - virtual bool Enable(bool enable = true) - { return wxListCtrl::Enable(enable); } - - // shortcuts to the GetItemState function - bool IsChecked(long item) const - { return GetItemState(item, wxLIST_STATE_CHECKED) != 0; } - bool IsEnabled(long item) const - { return GetItemState(item, wxLIST_STATE_ENABLED) != 0; } - - // this needs to be redeclared otherwise it's hidden by our other IsEnabled() function. - bool IsEnabled() const - { return wxWindow::IsEnabled(); } - - //! Returns the number of checked items in the control. - int GetCheckedItemCount() const; - - // we overload these so we are sure they will use our - // #GetItem and #SetItem functions... - bool SetItemState(long item, long state, long stateMask); - int GetItemState(long item, long stateMask) const; - long InsertItem( long index, const wxString& label, int imageIndex = -1); - long SetItem(long index, int col, const wxString& label, int imageId = -1); - - // the image associated with an element is already in used by wxCheckedListCtrl - // itself to show the checkbox and it cannot be handled by the user ! - bool SetItemImage(long, int) - { wxASSERT_MSG(0, wxT("This function cannot be used with wxCheckedListCtrl !")); return FALSE; } - -protected: // event handlers - - void OnMouseEvent(wxMouseEvent& event); - -protected: // internal utilities - - static int GetItemImageFromAdditionalState(int addstate); - static int GetAndRemoveAdditionalState(long *state, int statemask); - wxColour GetBgColourFromAdditionalState(int additionalstate); - -private: - DECLARE_CLASS(wxCheckedListCtrl) - DECLARE_EVENT_TABLE() -}; - - -#endif // wxUSE_CHECKEDLISTCTRL - -#endif // _WX_CHECKEDLISTCTRL_H_ - diff --git a/src/gui/wxgui/wxcomponents/checktree.cpp b/src/gui/wxgui/wxcomponents/checktree.cpp index a6818626..e368fa6a 100644 --- a/src/gui/wxgui/wxcomponents/checktree.cpp +++ b/src/gui/wxgui/wxcomponents/checktree.cpp @@ -1,14 +1,9 @@ #include "wxgui/wxcomponents/checktree.h" -#include "wxgui/wxcomponents/checked2.xpm" -#include "wxgui/wxcomponents/checked_d.xpm" -#include "wxgui/wxcomponents/checked_ld.xpm" -#include "wxgui/wxcomponents/checked_mo.xpm" -#include "wxgui/wxcomponents/unchecked2.xpm" -#include "wxgui/wxcomponents/unchecked_d.xpm" -#include "wxgui/wxcomponents/unchecked_ld.xpm" -#include "wxgui/wxcomponents/unchecked_mo.xpm" + +#include #include #include +#include wxDEFINE_EVENT(wxEVT_CHECKTREE_FOCUS, wxTreeEvent); wxDEFINE_EVENT(wxEVT_CHECKTREE_CHOICE, wxTreeEvent); @@ -108,16 +103,80 @@ wxCheckTree::wxCheckTree(wxWindow* parent, const wxWindowID id, const wxPoint& p void wxCheckTree::Init() { - wxIcon icons[8] = - { - wxIcon(unchecked2_xpm), wxIcon(unchecked_mo_xpm), wxIcon(unchecked_ld_xpm), wxIcon(unchecked_d_xpm), wxIcon(checked2_xpm), wxIcon(checked_mo_xpm), wxIcon(checked_ld_xpm), wxIcon(checked_d_xpm) - }; + int width = wxRendererNative::Get().GetCheckBoxSize(this).GetWidth(); + int height = wxRendererNative::Get().GetCheckBoxSize(this).GetHeight(); - // Make an state image list containing small icons - auto states = new wxImageList(icons[0].GetWidth(), icons[0].GetHeight(), true); + auto states = new wxImageList(width, height, true); - for (const auto& icon : icons) - states->Add(icon); + wxBitmap unchecked_bmp(width, height); + wxBitmap unchecked_mouse_over_bmp(width, height); + wxBitmap unchecked_left_down_bmp(width, height); + wxBitmap unchecked_disabled_bmp(width, height); + wxBitmap checked_bmp(width, height); + wxBitmap checked_mouse_over_bmp(width, height); + wxBitmap checked_left_down_bmp(width, height); + wxBitmap checked_disabled_bmp(width, height); + + wxMemoryDC renderer_dc; + + // Unchecked + renderer_dc.SelectObject(unchecked_bmp); + renderer_dc.SetBackground(*wxTheBrushList->FindOrCreateBrush(GetBackgroundColour(), wxSOLID)); + renderer_dc.Clear(); + wxRendererNative::Get().DrawCheckBox(this, renderer_dc, wxRect(0, 0, width, height), wxCONTROL_NONE); + + // Unchecked Mouse Over + renderer_dc.SelectObject(unchecked_mouse_over_bmp); + renderer_dc.SetBackground(*wxTheBrushList->FindOrCreateBrush(GetBackgroundColour(), wxSOLID)); + renderer_dc.Clear(); + wxRendererNative::Get().DrawCheckBox(this, renderer_dc, wxRect(0, 0, width, height), wxCONTROL_CURRENT); + + // Unchecked and Disabled + renderer_dc.SelectObject(unchecked_disabled_bmp); + renderer_dc.SetBackground(*wxTheBrushList->FindOrCreateBrush(GetBackgroundColour(), wxSOLID)); + renderer_dc.Clear(); + wxRendererNative::Get().DrawCheckBox(this, renderer_dc, wxRect(0, 0, width, height), wxCONTROL_DISABLED); + + // Unchecked Left Down + renderer_dc.SelectObject(unchecked_left_down_bmp); + renderer_dc.SetBackground(*wxTheBrushList->FindOrCreateBrush(GetBackgroundColour(), wxSOLID)); + renderer_dc.Clear(); + wxRendererNative::Get().DrawCheckBox(this, renderer_dc, wxRect(0, 0, width, height), wxCONTROL_CURRENT | wxCONTROL_PRESSED); + + // Checked + renderer_dc.SelectObject(checked_bmp); + renderer_dc.SetBackground(*wxTheBrushList->FindOrCreateBrush(GetBackgroundColour(), wxSOLID)); + renderer_dc.Clear(); + wxRendererNative::Get().DrawCheckBox(this, renderer_dc, wxRect(0, 0, width, height), wxCONTROL_CHECKED); + + // Checked Mouse Over + renderer_dc.SelectObject(checked_mouse_over_bmp); + renderer_dc.SetBackground(*wxTheBrushList->FindOrCreateBrush(GetBackgroundColour(), wxSOLID)); + renderer_dc.Clear(); + wxRendererNative::Get().DrawCheckBox(this, renderer_dc, wxRect(0, 0, width, height), wxCONTROL_CHECKED | wxCONTROL_CURRENT); + + // Checked Left Down + renderer_dc.SelectObject(checked_left_down_bmp); + renderer_dc.SetBackground(*wxTheBrushList->FindOrCreateBrush(GetBackgroundColour(), wxSOLID)); + renderer_dc.Clear(); + wxRendererNative::Get().DrawCheckBox(this, renderer_dc, wxRect(0, 0, width, height), wxCONTROL_CHECKED | wxCONTROL_CURRENT | wxCONTROL_PRESSED); + + // Checked and Disabled + renderer_dc.SelectObject(checked_disabled_bmp); + renderer_dc.SetBackground(*wxTheBrushList->FindOrCreateBrush(GetBackgroundColour(), wxSOLID)); + renderer_dc.Clear(); + wxRendererNative::Get().DrawCheckBox(this, renderer_dc, wxRect(0, 0, width, height), wxCONTROL_CHECKED | wxCONTROL_DISABLED); + + renderer_dc.SelectObject(wxNullBitmap); + + states->Add(unchecked_bmp); + states->Add(unchecked_mouse_over_bmp); + states->Add(unchecked_left_down_bmp); + states->Add(unchecked_disabled_bmp); + states->Add(checked_bmp); + states->Add(checked_mouse_over_bmp); + states->Add(checked_left_down_bmp); + states->Add(checked_disabled_bmp); AssignStateImageList(states); @@ -173,7 +232,7 @@ void wxCheckTree::SetItemTextColour(const wxTreeItemId& item, const wxColour& co { const auto it = m_colors.find(item); if (it == m_colors.end()) - m_colors.emplace(std::pair(item, col)); + m_colors.emplace(std::pair(item, col)); else m_colors[item] = col; @@ -218,7 +277,7 @@ bool wxCheckTree::EnableCheckBox(const wxTreeItemId& item, bool enable) else if (state == CHECKED || state == CHECKED_MOUSE_OVER || state == CHECKED_LEFT_DOWN) SetItemState(item, CHECKED_DISABLED); - const wxColor col = GetItemTextColour(item); + const wxColour col = GetItemTextColour(item); SetItemTextColour(item, wxColour(161, 161, 146)); m_colors[item] = col; return true; diff --git a/src/gui/wxgui/wxcomponents/checktree.h b/src/gui/wxgui/wxcomponents/checktree.h index 0e7c1b12..eb620b8b 100644 --- a/src/gui/wxgui/wxcomponents/checktree.h +++ b/src/gui/wxgui/wxcomponents/checktree.h @@ -82,7 +82,7 @@ class WXDLLIMPEXP_CHECKTREE wxCheckTree : public wxTreeCtrl void On_Tree_Focus_Lost( wxFocusEvent& event ); //private data: - std::map m_colors; + std::map m_colors; bool mouse_entered_tree_with_left_down = false; diff --git a/src/gui/wxgui/wxcomponents/unchecked.xpm b/src/gui/wxgui/wxcomponents/unchecked.xpm deleted file mode 100644 index eca65396..00000000 --- a/src/gui/wxgui/wxcomponents/unchecked.xpm +++ /dev/null @@ -1,24 +0,0 @@ -/* XPM */ -static const char * unchecked_xpm[] = { -"16 16 5 1", -" c None", -". c #808080", -"X c Black", -"o c #c0c0c0", -"w c White", -" ", -" ", -" ............ ", -" .XXXXXXXXXXo ", -" .Xwwwwwwwwwo ", -" .Xwwwwwwwwwo ", -" .Xwwwwwwwwwo ", -" .Xwwwwwwwwwo ", -" .Xwwwwwwwwwo ", -" .Xwwwwwwwwwo ", -" .Xwwwwwwwwwo ", -" .Xwwwwwwwwwo ", -" .Xwwwwwwwwwo ", -" .ooooooooooo ", -" ", -" "}; diff --git a/src/gui/wxgui/wxcomponents/unchecked2.xpm b/src/gui/wxgui/wxcomponents/unchecked2.xpm deleted file mode 100644 index 976f7ce5..00000000 --- a/src/gui/wxgui/wxcomponents/unchecked2.xpm +++ /dev/null @@ -1,37 +0,0 @@ -/* XPM */ -static const char * unchecked2_xpm[] = { -"14 15 19 1", -" c None", -". c #1C5180", -"+ c #DCDCD7", -"@ c #DEDED9", -"# c #E0E0DB", -"$ c #E2E2DE", -"% c #E5E5E2", -"& c #E8E8E5", -"* c #ECECE9", -"= c #EFEFEC", -"- c #F1F1EF", -"; c #F3F3F1", -"> c #F5F5F4", -", c #F7F7F6", -"' c #F9F9F8", -") c #FBFBFA", -"! c #FDFDFC", -"~ c #FEFEFE", -"{ c #FFFFFF", -"............. ", -".+++@#$%&*=-. ", -".++@#$%&*=-;. ", -".+@#$%&*=-;>. ", -".@#$%&*=-;>,. ", -".#$%&*=-;>,'. ", -".$%&*=-;>,'). ", -".%&*=-;>,')!. ", -".&*=-;>,')!~. ", -".*=-;>,')!~{. ", -".=-;>,')!~{{. ", -".-;>,')!~{{{. ", -"............. ", -" ", -" "}; diff --git a/src/gui/wxgui/wxcomponents/unchecked_d.xpm b/src/gui/wxgui/wxcomponents/unchecked_d.xpm deleted file mode 100644 index 69999704..00000000 --- a/src/gui/wxgui/wxcomponents/unchecked_d.xpm +++ /dev/null @@ -1,21 +0,0 @@ -/* XPM */ -static const char * unchecked_d_xpm[] = { -"14 15 3 1", -" c None", -". c #CAC8BB", -"+ c #FFFFFF", -"............. ", -".+++++++++++. ", -".+++++++++++. ", -".+++++++++++. ", -".+++++++++++. ", -".+++++++++++. ", -".+++++++++++. ", -".+++++++++++. ", -".+++++++++++. ", -".+++++++++++. ", -".+++++++++++. ", -".+++++++++++. ", -"............. ", -" ", -" "}; diff --git a/src/gui/wxgui/wxcomponents/unchecked_dis.xpm b/src/gui/wxgui/wxcomponents/unchecked_dis.xpm deleted file mode 100644 index e18e32e3..00000000 --- a/src/gui/wxgui/wxcomponents/unchecked_dis.xpm +++ /dev/null @@ -1,23 +0,0 @@ -/* XPM */ -static const char * unchecked_dis_xpm[] = { -"16 16 4 1", -" c None", -". c #808080", -"X c Black", -"o c #c0c0c0", -" ", -" ", -" ............ ", -" .XXXXXXXXXXo ", -" .Xoooooooooo ", -" .Xoooooooooo ", -" .Xoooooooooo ", -" .Xoooooooooo ", -" .Xoooooooooo ", -" .Xoooooooooo ", -" .Xoooooooooo ", -" .Xoooooooooo ", -" .Xoooooooooo ", -" .ooooooooooo ", -" ", -" "}; diff --git a/src/gui/wxgui/wxcomponents/unchecked_ld.xpm b/src/gui/wxgui/wxcomponents/unchecked_ld.xpm deleted file mode 100644 index e572efbc..00000000 --- a/src/gui/wxgui/wxcomponents/unchecked_ld.xpm +++ /dev/null @@ -1,37 +0,0 @@ -/* XPM */ -static const char * unchecked_ld_xpm[] = { -"14 15 19 1", -" c None", -". c #1C5180", -"+ c #B0B0A7", -"@ c #B3B3AA", -"# c #B7B7AD", -"$ c #BCBBB1", -"% c #C1C1B6", -"& c #C7C6BB", -"* c #CDCCC0", -"= c #D2D1C5", -"- c #D7D5C8", -"; c #DBDACC", -"> c #DFDDCF", -", c #E3E1D3", -"' c #E6E5D6", -") c #EAE8D9", -"! c #EDEBDB", -"~ c #EFEDDD", -"{ c #F1EFDF", -"............. ", -".+++@#$%&*=-. ", -".++@#$%&*=-;. ", -".+@#$%&*=-;>. ", -".@#$%&*=-;>,. ", -".#$%&*=-;>,'. ", -".$%&*=-;>,'). ", -".%&*=-;>,')!. ", -".&*=-;>,')!~. ", -".*=-;>,')!~{. ", -".=-;>,')!~{{. ", -".-;>,')!~{{{. ", -"............. ", -" ", -" "}; diff --git a/src/gui/wxgui/wxcomponents/unchecked_mo.xpm b/src/gui/wxgui/wxcomponents/unchecked_mo.xpm deleted file mode 100644 index 483f9778..00000000 --- a/src/gui/wxgui/wxcomponents/unchecked_mo.xpm +++ /dev/null @@ -1,42 +0,0 @@ -/* XPM */ -static const char * unchecked_mo_xpm[] = { -"14 15 24 1", -" c None", -". c #1C5180", -"+ c #FFF0CF", -"@ c #FFEDC6", -"# c #FFE9BA", -"$ c #FEE4AC", -"% c #FEDF9C", -"& c #FDD98C", -"* c #FDD684", -"= c #FCD37C", -"- c #FCD074", -"; c #FBCC6B", -"> c #FBC863", -", c #FAC55A", -"' c #E7E7E3", -") c #FAC254", -"! c #FAC04E", -"~ c #F9BD48", -"{ c #F9BB43", -"] c #F9B93E", -"^ c #F9B73A", -"/ c #F8B636", -"( c #F8B433", -"_ c #F8B330", -"............. ", -".+@#$%&*=-;>. ", -".@#$%&*=-;>,. ", -".#$''''''',). ", -".$%''''''')!. ", -".%&'''''''!~. ", -".&*'''''''~{. ", -".*='''''''{]. ", -".=-''''''']^. ", -".-;'''''''^/. ", -".;>,)!~{]^/(. ", -".>,)!~{]^/(_. ", -"............. ", -" ", -" "}; diff --git a/src/main.cpp b/src/main.cpp index a5afba85..7bf855cc 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -38,7 +38,7 @@ #if BOOST_OS_LINUX #define _putenv(__s) putenv((char*)(__s)) #include -#elif BOOST_OS_MACOS +#elif BOOST_OS_MACOS || BOOST_OS_BSD #define _putenv(__s) putenv((char*)(__s)) #include #include @@ -252,7 +252,7 @@ int main(int argc, char* argv[]) int main(int argc, char *argv[]) { -#if BOOST_OS_LINUX +#if BOOST_OS_LINUX || BOOST_OS_BSD XInitThreads(); #endif if (!LaunchSettings::HandleCommandline(argc, argv)) diff --git a/src/util/ChunkedHeap/ChunkedHeap.h b/src/util/ChunkedHeap/ChunkedHeap.h index 21a1b868..88a0bdfd 100644 --- a/src/util/ChunkedHeap/ChunkedHeap.h +++ b/src/util/ChunkedHeap/ChunkedHeap.h @@ -283,7 +283,7 @@ private: { if (itr.chunkIndex != dbgRange.chunkIndex) continue; - if (itr.offset < (dbgRange.offset + dbgRange.size) && (itr.offset + itr.size) >(dbgRange.offset)) + if (itr.offset < (dbgRange.offset + dbgRange.size) && (itr.offset + itr.size) > dbgRange.offset) cemu_assert_error(); } diff --git a/src/util/DXGIWrapper/DXGIWrapper.h b/src/util/DXGIWrapper/DXGIWrapper.h index 363733e7..5fe0ea61 100644 --- a/src/util/DXGIWrapper/DXGIWrapper.h +++ b/src/util/DXGIWrapper/DXGIWrapper.h @@ -1,5 +1,6 @@ #pragma once +#undef GetHwnd #include #include diff --git a/src/util/helpers/helpers.cpp b/src/util/helpers/helpers.cpp index 8d7a7db8..d13a31a2 100644 --- a/src/util/helpers/helpers.cpp +++ b/src/util/helpers/helpers.cpp @@ -116,6 +116,19 @@ typedef struct tagTHREADNAME_INFO void SetThreadName(const char* name) { #if BOOST_OS_WINDOWS + using SetThreadDescription_t = HRESULT (*)(HANDLE hThread, PCWSTR lpThreadDescription); + static SetThreadDescription_t pSetThreadDescription = nullptr; + if (!pSetThreadDescription) + pSetThreadDescription = (SetThreadDescription_t)GetProcAddress(LoadLibraryW(L"Kernel32.dll"), "SetThreadDescription"); + if (pSetThreadDescription) + { + size_t len = strlen(name) * 2 + 1; + auto threadDescription = new wchar_t[len]; + if (boost::nowide::widen(threadDescription, len, name)) + pSetThreadDescription(GetCurrentThread(), threadDescription); + delete[] threadDescription; + } +#ifdef _MSC_VER THREADNAME_INFO info; info.dwType = 0x1000; info.szName = name; @@ -129,6 +142,7 @@ void SetThreadName(const char* name) __except (EXCEPTION_EXECUTE_HANDLER) { } #pragma warning(pop) +#endif #elif BOOST_OS_MACOS pthread_setname_np(name); #else diff --git a/src/util/helpers/ringbuffer.h b/src/util/helpers/ringbuffer.h index aab77fc3..d58aca0f 100644 --- a/src/util/helpers/ringbuffer.h +++ b/src/util/helpers/ringbuffer.h @@ -10,9 +10,8 @@ public: bool Push(const T& v); - template - typename std::enable_if< !std::is_array::value, Q >::type - Pop() + T Pop() + requires (!std::is_array_v) { std::unique_lock lock(m_mutex); if (m_readPointer == m_writePointer) diff --git a/src/util/highresolutiontimer/HighResolutionTimer.cpp b/src/util/highresolutiontimer/HighResolutionTimer.cpp index bb4a40ab..48a7ad1f 100644 --- a/src/util/highresolutiontimer/HighResolutionTimer.cpp +++ b/src/util/highresolutiontimer/HighResolutionTimer.cpp @@ -14,6 +14,11 @@ HighResolutionTimer HighResolutionTimer::now() return HighResolutionTimer(nsec); #elif BOOST_OS_MACOS return HighResolutionTimer(clock_gettime_nsec_np(CLOCK_MONOTONIC_RAW)); +#elif BOOST_OS_BSD + timespec pc; + clock_gettime(CLOCK_MONOTONIC, &pc); + uint64 nsec = (uint64)pc.tv_sec * (uint64)1000000000 + (uint64)pc.tv_nsec; + return HighResolutionTimer(nsec); #endif } @@ -29,6 +34,10 @@ uint64 HighResolutionTimer::m_freq = []() -> uint64 { return (uint64)(freq.QuadPart); #elif BOOST_OS_MACOS return 1000000000; +#elif BOOST_OS_BSD + timespec pc; + clock_getres(CLOCK_MONOTONIC, &pc); + return (uint64)1000000000 / (uint64)pc.tv_nsec; #else timespec pc; clock_getres(CLOCK_MONOTONIC_RAW, &pc); diff --git a/vcpkg.json b/vcpkg.json index 01076806..3b831da4 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -1,7 +1,7 @@ { "name": "cemu", "version-string": "1.0", - "builtin-baseline": "a4275b7eee79fb24ec2e135481ef5fce8b41c339", + "builtin-baseline": "f0fb3ddba5135b80982668de39dbaa139c00d281", "dependencies": [ "pugixml", "zlib", @@ -50,6 +50,9 @@ "zstd", { "name": "wxwidgets", + "features": [ + "debug-support" + ], "default-features": false, "platform": "!android" }, @@ -57,7 +60,9 @@ { "name": "curl", "default-features": false, - "features": [ "openssl" ] + "features": [ + "openssl" + ] }, { "name": "dbus", @@ -67,7 +72,10 @@ { "name": "tiff", "default-features": false, - "features": ["jpeg", "zip"] + "features": [ + "jpeg", + "zip" + ] }, "libusb" ], @@ -78,7 +86,11 @@ }, { "name": "sdl2", - "version": "2.30.3" + "version": "2.32.8" + }, + { + "name": "wxwidgets", + "version": "3.3.1" } ] }