mirror of
https://github.com/cemu-project/Cemu.git
synced 2024-11-25 18:46:55 +01:00
Merge branch 'main' into metal
This commit is contained in:
commit
41ee2e75ae
9
.github/getversion.cpp
vendored
9
.github/getversion.cpp
vendored
@ -1,9 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include "./../src/Common/version.h"
|
||||
|
||||
// output current Cemu version for CI workflow. Do not modify
|
||||
int main()
|
||||
{
|
||||
printf("%d.%d", EMULATOR_VERSION_LEAD, EMULATOR_VERSION_MAJOR);
|
||||
return 0;
|
||||
}
|
86
.github/workflows/build.yml
vendored
86
.github/workflows/build.yml
vendored
@ -3,10 +3,10 @@ name: Build Cemu
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
deploymode:
|
||||
next_version_major:
|
||||
required: false
|
||||
type: string
|
||||
experimentalversion:
|
||||
next_version_minor:
|
||||
required: false
|
||||
type: string
|
||||
|
||||
@ -24,25 +24,17 @@ jobs:
|
||||
submodules: "recursive"
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup release mode parameters (for deploy)
|
||||
if: ${{ inputs.deploymode == 'release' }}
|
||||
- name: Setup release mode parameters
|
||||
run: |
|
||||
echo "BUILD_MODE=release" >> $GITHUB_ENV
|
||||
echo "BUILD_FLAGS=" >> $GITHUB_ENV
|
||||
echo "Build mode is release"
|
||||
|
||||
- name: Setup debug mode parameters (for continous build)
|
||||
if: ${{ inputs.deploymode != 'release' }}
|
||||
- name: Setup build flags for version
|
||||
if: ${{ inputs.next_version_major != '' }}
|
||||
run: |
|
||||
echo "BUILD_MODE=debug" >> $GITHUB_ENV
|
||||
echo "BUILD_FLAGS=" >> $GITHUB_ENV
|
||||
echo "Build mode is debug"
|
||||
|
||||
- name: Setup version for experimental
|
||||
if: ${{ inputs.experimentalversion != '' }}
|
||||
run: |
|
||||
echo "[INFO] Experimental version ${{ inputs.experimentalversion }}"
|
||||
echo "BUILD_FLAGS=${{ env.BUILD_FLAGS }} -DEXPERIMENTAL_VERSION=${{ inputs.experimentalversion }}" >> $GITHUB_ENV
|
||||
echo "[INFO] Version ${{ inputs.next_version_major }}.${{ inputs.next_version_minor }}"
|
||||
echo "BUILD_FLAGS=${{ env.BUILD_FLAGS }} -DEMULATOR_VERSION_MAJOR=${{ inputs.next_version_major }} -DEMULATOR_VERSION_MINOR=${{ inputs.next_version_minor }}" >> $GITHUB_ENV
|
||||
|
||||
- name: "Install system dependencies"
|
||||
run: |
|
||||
@ -81,12 +73,10 @@ jobs:
|
||||
cmake --build build
|
||||
|
||||
- name: Prepare artifact
|
||||
if: ${{ inputs.deploymode == 'release' }}
|
||||
run: mv bin/Cemu_release bin/Cemu
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
if: ${{ inputs.deploymode == 'release' }}
|
||||
with:
|
||||
name: cemu-bin-linux-x64
|
||||
path: ./bin/Cemu
|
||||
@ -128,24 +118,17 @@ jobs:
|
||||
with:
|
||||
submodules: "recursive"
|
||||
|
||||
- name: Setup release mode parameters (for deploy)
|
||||
if: ${{ inputs.deploymode == 'release' }}
|
||||
- name: Setup release mode parameters
|
||||
run: |
|
||||
echo "BUILD_MODE=release" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf8 -Append
|
||||
echo "BUILD_FLAGS=" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf8 -Append
|
||||
echo "Build mode is release"
|
||||
|
||||
- name: Setup debug mode parameters (for continous build)
|
||||
if: ${{ inputs.deploymode != 'release' }}
|
||||
|
||||
- name: Setup build flags for version
|
||||
if: ${{ inputs.next_version_major != '' }}
|
||||
run: |
|
||||
echo "BUILD_MODE=debug" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf8 -Append
|
||||
echo "BUILD_FLAGS=" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf8 -Append
|
||||
echo "Build mode is debug"
|
||||
- name: Setup version for experimental
|
||||
if: ${{ inputs.experimentalversion != '' }}
|
||||
run: |
|
||||
echo "[INFO] Experimental version ${{ inputs.experimentalversion }}"
|
||||
echo "BUILD_FLAGS=${{ env.BUILD_FLAGS }} -DEXPERIMENTAL_VERSION=${{ inputs.experimentalversion }}" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf8 -Append
|
||||
echo "[INFO] Version ${{ inputs.next_version_major }}.${{ inputs.next_version_minor }}"
|
||||
echo "BUILD_FLAGS=${{ env.BUILD_FLAGS }} -DEMULATOR_VERSION_MAJOR=${{ inputs.next_version_major }} -DEMULATOR_VERSION_MINOR=${{ inputs.next_version_minor }}" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf8 -Append
|
||||
|
||||
- name: "Setup cmake"
|
||||
uses: jwlawson/actions-setup-cmake@v2
|
||||
@ -184,57 +167,45 @@ jobs:
|
||||
cmake --build . --config ${{ env.BUILD_MODE }}
|
||||
|
||||
- name: Prepare artifact
|
||||
if: ${{ inputs.deploymode == 'release' }}
|
||||
run: Rename-Item bin/Cemu_release.exe Cemu.exe
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
if: ${{ inputs.deploymode == 'release' }}
|
||||
with:
|
||||
name: cemu-bin-windows-x64
|
||||
path: ./bin/Cemu.exe
|
||||
|
||||
build-macos:
|
||||
runs-on: macos-12
|
||||
runs-on: macos-14
|
||||
steps:
|
||||
- name: "Checkout repo"
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: "recursive"
|
||||
|
||||
- name: Setup release mode parameters (for deploy)
|
||||
if: ${{ inputs.deploymode == 'release' }}
|
||||
- name: Setup release mode parameters
|
||||
run: |
|
||||
echo "BUILD_MODE=release" >> $GITHUB_ENV
|
||||
echo "BUILD_FLAGS=" >> $GITHUB_ENV
|
||||
echo "Build mode is release"
|
||||
- name: Setup debug mode parameters (for continous build)
|
||||
if: ${{ inputs.deploymode != 'release' }}
|
||||
|
||||
- name: Setup build flags for version
|
||||
if: ${{ inputs.next_version_major != '' }}
|
||||
run: |
|
||||
echo "BUILD_MODE=debug" >> $GITHUB_ENV
|
||||
echo "BUILD_FLAGS=" >> $GITHUB_ENV
|
||||
echo "Build mode is debug"
|
||||
|
||||
- name: Setup version for experimental
|
||||
if: ${{ inputs.experimentalversion != '' }}
|
||||
run: |
|
||||
echo "[INFO] Experimental version ${{ inputs.experimentalversion }}"
|
||||
echo "BUILD_FLAGS=${{ env.BUILD_FLAGS }} -DEXPERIMENTAL_VERSION=${{ inputs.experimentalversion }}" >> $GITHUB_ENV
|
||||
echo "[INFO] Version ${{ inputs.next_version_major }}.${{ inputs.next_version_minor }}"
|
||||
echo "BUILD_FLAGS=${{ env.BUILD_FLAGS }} -DEMULATOR_VERSION_MAJOR=${{ inputs.next_version_major }} -DEMULATOR_VERSION_MINOR=${{ inputs.next_version_minor }}" >> $GITHUB_ENV
|
||||
|
||||
- name: "Install system dependencies"
|
||||
run: |
|
||||
brew update
|
||||
brew install llvm@15 ninja nasm automake libtool
|
||||
brew install cmake ninja
|
||||
brew install ninja nasm automake libtool
|
||||
|
||||
- name: "Build and install molten-vk"
|
||||
- name: "Install molten-vk"
|
||||
run: |
|
||||
git clone https://github.com/KhronosGroup/MoltenVK.git
|
||||
cd MoltenVK
|
||||
git checkout bf097edc74ec3b6dfafdcd5a38d3ce14b11952d6
|
||||
./fetchDependencies --macos
|
||||
make macos
|
||||
make install
|
||||
curl -L -O https://github.com/KhronosGroup/MoltenVK/releases/download/v1.2.9/MoltenVK-macos.tar
|
||||
tar xf MoltenVK-macos.tar
|
||||
sudo mkdir -p /usr/local/lib
|
||||
sudo cp MoltenVK/MoltenVK/dynamic/dylib/macOS/libMoltenVK.dylib /usr/local/lib
|
||||
|
||||
- name: "Setup cmake"
|
||||
uses: jwlawson/actions-setup-cmake@v2
|
||||
@ -265,9 +236,8 @@ jobs:
|
||||
cd build
|
||||
cmake .. ${{ env.BUILD_FLAGS }} \
|
||||
-DCMAKE_BUILD_TYPE=${{ env.BUILD_MODE }} \
|
||||
-DCMAKE_OSX_ARCHITECTURES=x86_64 \
|
||||
-DMACOS_BUNDLE=ON \
|
||||
-DCMAKE_C_COMPILER=/usr/local/opt/llvm@15/bin/clang \
|
||||
-DCMAKE_CXX_COMPILER=/usr/local/opt/llvm@15/bin/clang++ \
|
||||
-G Ninja
|
||||
|
||||
- name: "Build Cemu"
|
||||
@ -275,7 +245,6 @@ jobs:
|
||||
cmake --build build
|
||||
|
||||
- name: Prepare artifact
|
||||
if: ${{ inputs.deploymode == 'release' }}
|
||||
run: |
|
||||
mkdir bin/Cemu_app
|
||||
mv bin/Cemu_release.app bin/Cemu_app/Cemu.app
|
||||
@ -289,7 +258,6 @@ jobs:
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
if: ${{ inputs.deploymode == 'release' }}
|
||||
with:
|
||||
name: cemu-bin-macos-x64
|
||||
path: ./bin/Cemu.dmg
|
||||
|
3
.github/workflows/build_check.yml
vendored
3
.github/workflows/build_check.yml
vendored
@ -16,6 +16,3 @@ on:
|
||||
jobs:
|
||||
build:
|
||||
uses: ./.github/workflows/build.yml
|
||||
with:
|
||||
deploymode: release
|
||||
experimentalversion: 999999
|
||||
|
@ -1,20 +1,83 @@
|
||||
name: Deploy experimental release
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
changelog0:
|
||||
description: 'Enter the changelog lines for this release. Each line is a feature / bullet point. Do not use dash.'
|
||||
required: true
|
||||
type: string
|
||||
changelog1:
|
||||
description: 'Feature 2'
|
||||
required: false
|
||||
type: string
|
||||
changelog2:
|
||||
description: 'Feature 3'
|
||||
required: false
|
||||
type: string
|
||||
changelog3:
|
||||
description: 'Feature 4'
|
||||
required: false
|
||||
type: string
|
||||
changelog4:
|
||||
description: 'Feature 5'
|
||||
required: false
|
||||
type: string
|
||||
changelog5:
|
||||
description: 'Feature 6'
|
||||
required: false
|
||||
type: string
|
||||
changelog6:
|
||||
description: 'Feature 7'
|
||||
required: false
|
||||
type: string
|
||||
changelog7:
|
||||
description: 'Feature 8'
|
||||
required: false
|
||||
type: string
|
||||
changelog8:
|
||||
description: 'Feature 9'
|
||||
required: false
|
||||
type: string
|
||||
changelog9:
|
||||
description: 'Feature 10'
|
||||
required: false
|
||||
type: string
|
||||
|
||||
jobs:
|
||||
calculate-version:
|
||||
name: Calculate Version
|
||||
uses: ./.github/workflows/determine_release_version.yml
|
||||
call-release-build:
|
||||
uses: ./.github/workflows/build.yml
|
||||
needs: calculate-version
|
||||
with:
|
||||
deploymode: release
|
||||
experimentalversion: ${{ github.run_number }}
|
||||
next_version_major: ${{ needs.calculate-version.outputs.next_version_major }}
|
||||
next_version_minor: ${{ needs.calculate-version.outputs.next_version_minor }}
|
||||
deploy:
|
||||
name: Deploy experimental release
|
||||
runs-on: ubuntu-22.04
|
||||
needs: call-release-build
|
||||
needs: [call-release-build, calculate-version]
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Generate changelog
|
||||
id: generate_changelog
|
||||
run: |
|
||||
CHANGELOG=""
|
||||
if [ -n "${{ github.event.inputs.changelog0 }}" ]; then CHANGELOG="$CHANGELOG- ${{ github.event.inputs.changelog0 }}\n"; fi
|
||||
if [ -n "${{ github.event.inputs.changelog1 }}" ]; then CHANGELOG="$CHANGELOG- ${{ github.event.inputs.changelog1 }}\n"; fi
|
||||
if [ -n "${{ github.event.inputs.changelog2 }}" ]; then CHANGELOG="$CHANGELOG- ${{ github.event.inputs.changelog2 }}\n"; fi
|
||||
if [ -n "${{ github.event.inputs.changelog3 }}" ]; then CHANGELOG="$CHANGELOG- ${{ github.event.inputs.changelog3 }}\n"; fi
|
||||
if [ -n "${{ github.event.inputs.changelog4 }}" ]; then CHANGELOG="$CHANGELOG- ${{ github.event.inputs.changelog4 }}\n"; fi
|
||||
if [ -n "${{ github.event.inputs.changelog5 }}" ]; then CHANGELOG="$CHANGELOG- ${{ github.event.inputs.changelog5 }}\n"; fi
|
||||
if [ -n "${{ github.event.inputs.changelog6 }}" ]; then CHANGELOG="$CHANGELOG- ${{ github.event.inputs.changelog6 }}\n"; fi
|
||||
if [ -n "${{ github.event.inputs.changelog7 }}" ]; then CHANGELOG="$CHANGELOG- ${{ github.event.inputs.changelog7 }}\n"; fi
|
||||
if [ -n "${{ github.event.inputs.changelog8 }}" ]; then CHANGELOG="$CHANGELOG- ${{ github.event.inputs.changelog8 }}\n"; fi
|
||||
if [ -n "${{ github.event.inputs.changelog9 }}" ]; then CHANGELOG="$CHANGELOG- ${{ github.event.inputs.changelog9 }}\n"; fi
|
||||
echo -e "$CHANGELOG"
|
||||
echo "RELEASE_BODY=$CHANGELOG" >> $GITHUB_ENV
|
||||
- uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: cemu-bin-linux-x64
|
||||
@ -40,15 +103,13 @@ jobs:
|
||||
mkdir upload
|
||||
sudo apt install zip
|
||||
|
||||
- name: Get version
|
||||
- name: Set version dependent vars
|
||||
run: |
|
||||
echo "Experimental version: ${{ github.run_number }}"
|
||||
ls
|
||||
gcc -o getversion .github/getversion.cpp
|
||||
./getversion
|
||||
echo "Cemu CI version: $(./getversion)"
|
||||
echo "CEMU_FOLDER_NAME=Cemu_$(./getversion)-${{ github.run_number }}" >> $GITHUB_ENV
|
||||
echo "CEMU_VERSION=$(./getversion)-${{ github.run_number }}" >> $GITHUB_ENV
|
||||
echo "Version: ${{ needs.calculate-version.outputs.next_version }}"
|
||||
echo "CEMU_FOLDER_NAME=Cemu_${{ needs.calculate-version.outputs.next_version }}"
|
||||
echo "CEMU_VERSION=${{ needs.calculate-version.outputs.next_version }}"
|
||||
echo "CEMU_FOLDER_NAME=Cemu_${{ needs.calculate-version.outputs.next_version }}" >> $GITHUB_ENV
|
||||
echo "CEMU_VERSION=${{ needs.calculate-version.outputs.next_version }}" >> $GITHUB_ENV
|
||||
|
||||
- name: Create release from windows-bin
|
||||
run: |
|
||||
@ -83,4 +144,8 @@ jobs:
|
||||
wget -O ghr.tar.gz https://github.com/tcnksm/ghr/releases/download/v0.15.0/ghr_v0.15.0_linux_amd64.tar.gz
|
||||
tar xvzf ghr.tar.gz; rm ghr.tar.gz
|
||||
echo "[INFO] Release tag: v${{ env.CEMU_VERSION }}"
|
||||
ghr_v0.15.0_linux_amd64/ghr -prerelease -t ${{ secrets.GITHUB_TOKEN }} -n "Cemu ${{ env.CEMU_VERSION }} (Experimental)" -b "Cemu experimental release" "v${{ env.CEMU_VERSION }}" ./upload
|
||||
CHANGELOG_UNESCAPED=$(printf "%s\n" "${{ env.RELEASE_BODY }}" | sed 's/\\n/\n/g')
|
||||
RELEASE_BODY=$(printf "%s\n%s" \
|
||||
"**Changelog:**" \
|
||||
"$CHANGELOG_UNESCAPED")
|
||||
ghr_v0.15.0_linux_amd64/ghr -draft -t ${{ secrets.GITHUB_TOKEN }} -n "Cemu ${{ env.CEMU_VERSION }}" -b "$RELEASE_BODY" "v${{ env.CEMU_VERSION }}" ./upload
|
||||
|
74
.github/workflows/determine_release_version.yml
vendored
Normal file
74
.github/workflows/determine_release_version.yml
vendored
Normal file
@ -0,0 +1,74 @@
|
||||
name: Calculate Next Version from release history
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
workflow_call:
|
||||
outputs:
|
||||
next_version:
|
||||
description: "The next semantic version"
|
||||
value: ${{ jobs.calculate-version.outputs.next_version }}
|
||||
next_version_major:
|
||||
description: "The next semantic version (major)"
|
||||
value: ${{ jobs.calculate-version.outputs.next_version_major }}
|
||||
next_version_minor:
|
||||
description: "The next semantic version (minor)"
|
||||
value: ${{ jobs.calculate-version.outputs.next_version_minor }}
|
||||
|
||||
jobs:
|
||||
calculate-version:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
next_version: ${{ steps.calculate_next_version.outputs.next_version }}
|
||||
next_version_major: ${{ steps.calculate_next_version.outputs.next_version_major }}
|
||||
next_version_minor: ${{ steps.calculate_next_version.outputs.next_version_minor }}
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Get all releases
|
||||
id: get_all_releases
|
||||
run: |
|
||||
# Fetch all releases and check for API errors
|
||||
RESPONSE=$(curl -s -o response.json -w "%{http_code}" "https://api.github.com/repos/${{ github.repository }}/releases?per_page=100")
|
||||
if [ "$RESPONSE" -ne 200 ]; then
|
||||
echo "Failed to fetch releases. HTTP status: $RESPONSE"
|
||||
cat response.json
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Extract and sort tags
|
||||
ALL_TAGS=$(jq -r '.[].tag_name' response.json | grep -E '^v[0-9]+\.[0-9]+(-[0-9]+)?$' | sed 's/-.*//' | sort -V | tail -n 1)
|
||||
|
||||
# Exit if no tags were found
|
||||
if [ -z "$ALL_TAGS" ]; then
|
||||
echo "No valid tags found."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "::set-output name=tag::$ALL_TAGS"
|
||||
# echo "tag=$ALL_TAGS" >> $GITHUB_STATE
|
||||
|
||||
- name: Calculate next semver minor
|
||||
id: calculate_next_version
|
||||
run: |
|
||||
LATEST_VERSION=${{ steps.get_all_releases.outputs.tag }}
|
||||
|
||||
# strip 'v' prefix and split into major.minor
|
||||
LATEST_VERSION=${LATEST_VERSION//v/}
|
||||
IFS='.' read -r -a VERSION_PARTS <<< "$LATEST_VERSION"
|
||||
|
||||
MAJOR=${VERSION_PARTS[0]}
|
||||
MINOR=${VERSION_PARTS[1]}
|
||||
|
||||
# increment the minor version
|
||||
MINOR=$((MINOR + 1))
|
||||
|
||||
NEXT_VERSION="${MAJOR}.${MINOR}"
|
||||
|
||||
echo "Major: $MAJOR"
|
||||
echo "Minor: $MINOR"
|
||||
|
||||
echo "Next version: $NEXT_VERSION"
|
||||
echo "::set-output name=next_version::$NEXT_VERSION"
|
||||
echo "::set-output name=next_version_major::$MAJOR"
|
||||
echo "::set-output name=next_version_minor::$MINOR"
|
50
BUILD.md
50
BUILD.md
@ -16,11 +16,11 @@
|
||||
- [Compiling Errors](#compiling-errors)
|
||||
- [Building Errors](#building-errors)
|
||||
- [macOS](#macos)
|
||||
- [On Apple Silicon Macs, Rosetta 2 and the x86_64 version of Homebrew must be used](#on-apple-silicon-macs-rosetta-2-and-the-x86_64-version-of-homebrew-must-be-used)
|
||||
- [Installing brew](#installing-brew)
|
||||
- [Installing Dependencies](#installing-dependencies)
|
||||
- [Build Cemu using CMake and Clang](#build-cemu-using-cmake-and-clang)
|
||||
- [Updating Cemu and source code](#updating-cemu-and-source-code)
|
||||
- [Installing Tool Dependencies](#installing-tool-dependencies)
|
||||
- [Installing Library Dependencies](#installing-library-dependencies)
|
||||
- [Build Cemu using CMake](#build-cemu-using-cmake)
|
||||
- [Updating Cemu and source code](#updating-cemu-and-source-code)
|
||||
|
||||
## Windows
|
||||
|
||||
@ -141,31 +141,41 @@ If you are getting a different error than any of the errors listed above, you ma
|
||||
|
||||
## macOS
|
||||
|
||||
To compile Cemu, a recent enough compiler and STL with C++20 support is required! LLVM 13 and
|
||||
below, built in LLVM, and Xcode LLVM don't support the C++20 feature set required. The OpenGL graphics
|
||||
API isn't support on macOS, Vulkan must be used. Additionally Vulkan must be used through the
|
||||
Molten-VK compatibility layer
|
||||
|
||||
### On Apple Silicon Macs, Rosetta 2 and the x86_64 version of Homebrew must be used
|
||||
|
||||
You can skip this section if you have an Intel Mac. Every time you compile, you need to perform steps 2.
|
||||
|
||||
1. `softwareupdate --install-rosetta` # Install Rosetta 2 if you don't have it. This only has to be done once
|
||||
2. `arch -x86_64 zsh` # run an x64 shell
|
||||
To compile Cemu, a recent enough compiler and STL with C++20 support is required! LLVM 13 and below
|
||||
don't support the C++20 feature set required, so either install LLVM from Homebrew or make sure that
|
||||
you have a recent enough version of Xcode. Xcode 15 is known to work. The OpenGL graphics API isn't
|
||||
supported on macOS, so Vulkan must be used through the Molten-VK compatibility layer.
|
||||
|
||||
### Installing brew
|
||||
|
||||
1. `/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"`
|
||||
2. `eval "$(/usr/local/Homebrew/bin/brew shellenv)"` # set x86_64 brew env
|
||||
2. Set up the Homebrew shell environment:
|
||||
1. **On an Intel Mac:** `eval "$(/usr/local/Homebrew/bin/brew shellenv)"`
|
||||
2. **On an Apple Silicon Mac:** eval `"$(/opt/homebrew/bin/brew shellenv)"`
|
||||
|
||||
### Installing Dependencies
|
||||
### Installing Tool Dependencies
|
||||
|
||||
`brew install boost git cmake llvm ninja nasm molten-vk automake libtool`
|
||||
The native versions of these can be used regardless of what type of Mac you have.
|
||||
|
||||
`brew install git cmake ninja nasm automake libtool`
|
||||
|
||||
### Installing Library Dependencies
|
||||
|
||||
**On Apple Silicon Macs, Rosetta 2 and the x86_64 version of Homebrew must be used to install these dependencies:**
|
||||
1. `softwareupdate --install-rosetta` # Install Rosetta 2 if you don't have it. This only has to be done once
|
||||
2. `arch -x86_64 zsh` # run an x64 shell
|
||||
3. `/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"`
|
||||
4. `eval "$(/usr/local/Homebrew/bin/brew shellenv)"`
|
||||
|
||||
Then install the dependencies:
|
||||
|
||||
`brew install boost molten-vk`
|
||||
|
||||
### Build Cemu using CMake
|
||||
|
||||
### Build Cemu using CMake and Clang
|
||||
1. `git clone --recursive https://github.com/cemu-project/Cemu`
|
||||
2. `cd Cemu`
|
||||
3. `cmake -S . -B build -DCMAKE_BUILD_TYPE=release -DCMAKE_C_COMPILER=/usr/local/opt/llvm/bin/clang -DCMAKE_CXX_COMPILER=/usr/local/opt/llvm/bin/clang++ -G Ninja`
|
||||
3. `cmake -S . -B build -DCMAKE_BUILD_TYPE=release -DCMAKE_OSX_ARCHITECTURES=x86_64 -G Ninja`
|
||||
4. `cmake --build build`
|
||||
5. You should now have a Cemu executable file in the /bin folder, which you can run using `./bin/Cemu_release`.
|
||||
|
||||
|
@ -5,18 +5,19 @@ set(CMAKE_CXX_FLAGS_DEBUG "-g")
|
||||
|
||||
option(ENABLE_VCPKG "Enable the vcpkg package manager" ON)
|
||||
option(MACOS_BUNDLE "The executable when built on macOS will be created as an application bundle" OFF)
|
||||
set(EXPERIMENTAL_VERSION "" CACHE STRING "") # used by CI script to set experimental version
|
||||
|
||||
if (EXPERIMENTAL_VERSION)
|
||||
add_definitions(-DEMULATOR_VERSION_MINOR=${EXPERIMENTAL_VERSION})
|
||||
execute_process(
|
||||
COMMAND git log --format=%h -1
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
|
||||
OUTPUT_VARIABLE GIT_HASH
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
add_definitions(-DEMULATOR_HASH=${GIT_HASH})
|
||||
endif()
|
||||
# used by CI script to set version:
|
||||
set(EMULATOR_VERSION_MAJOR "0" CACHE STRING "")
|
||||
set(EMULATOR_VERSION_MINOR "0" CACHE STRING "")
|
||||
set(EMULATOR_VERSION_PATCH "0" CACHE STRING "")
|
||||
|
||||
execute_process(
|
||||
COMMAND git log --format=%h -1
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
|
||||
OUTPUT_VARIABLE GIT_HASH
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
add_definitions(-DEMULATOR_HASH=${GIT_HASH})
|
||||
|
||||
if (ENABLE_VCPKG)
|
||||
# check if vcpkg is shallow and unshallow it if necessary
|
||||
@ -65,6 +66,10 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
|
||||
add_compile_definitions($<$<CONFIG:Debug>:CEMU_DEBUG_ASSERT>) # if build type is debug, set CEMU_DEBUG_ASSERT
|
||||
|
||||
add_definitions(-DEMULATOR_VERSION_MAJOR=${EMULATOR_VERSION_MAJOR})
|
||||
add_definitions(-DEMULATOR_VERSION_MINOR=${EMULATOR_VERSION_MINOR})
|
||||
add_definitions(-DEMULATOR_VERSION_PATCH=${EMULATOR_VERSION_PATCH})
|
||||
|
||||
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
||||
|
||||
# enable link time optimization for release builds
|
||||
@ -90,6 +95,7 @@ endif()
|
||||
|
||||
if (APPLE)
|
||||
enable_language(OBJC OBJCXX)
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "12.0")
|
||||
endif()
|
||||
|
||||
if (UNIX AND NOT APPLE)
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
12
dependencies/ih264d/CMakeLists.txt
vendored
12
dependencies/ih264d/CMakeLists.txt
vendored
@ -117,7 +117,13 @@ add_library (ih264d
|
||||
"decoder/ivd.h"
|
||||
)
|
||||
|
||||
if (CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "amd64" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "AMD64")
|
||||
if (CMAKE_OSX_ARCHITECTURES)
|
||||
set(IH264D_ARCHITECTURE ${CMAKE_OSX_ARCHITECTURES})
|
||||
else()
|
||||
set(IH264D_ARCHITECTURE ${CMAKE_SYSTEM_PROCESSOR})
|
||||
endif()
|
||||
|
||||
if (IH264D_ARCHITECTURE STREQUAL "x86_64" OR IH264D_ARCHITECTURE STREQUAL "amd64" OR IH264D_ARCHITECTURE STREQUAL "AMD64")
|
||||
set(LIBAVCDEC_X86_INCLUDES "common/x86" "decoder/x86")
|
||||
include_directories("common/" "decoder/" ${LIBAVCDEC_X86_INCLUDES})
|
||||
target_sources(ih264d PRIVATE
|
||||
@ -140,7 +146,7 @@ target_sources(ih264d PRIVATE
|
||||
"decoder/x86/ih264d_function_selector_sse42.c"
|
||||
"decoder/x86/ih264d_function_selector_ssse3.c"
|
||||
)
|
||||
elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64")
|
||||
elseif(IH264D_ARCHITECTURE STREQUAL "aarch64" OR IH264D_ARCHITECTURE STREQUAL "arm64")
|
||||
enable_language( C CXX ASM )
|
||||
set(LIBAVCDEC_ARM_INCLUDES "common/armv8" "decoder/arm")
|
||||
include_directories("common/" "decoder/" ${LIBAVCDEC_ARM_INCLUDES})
|
||||
@ -178,7 +184,7 @@ target_sources(ih264d PRIVATE
|
||||
)
|
||||
target_compile_options(ih264d PRIVATE -DARMV8)
|
||||
else()
|
||||
message(FATAL_ERROR "ih264d unknown architecture: ${CMAKE_SYSTEM_PROCESSOR}")
|
||||
message(FATAL_ERROR "ih264d unknown architecture: ${IH264D_ARCHITECTURE}")
|
||||
endif()
|
||||
|
||||
if(MSVC)
|
||||
|
5
dist/linux/appimage.sh
vendored
5
dist/linux/appimage.sh
vendored
@ -10,6 +10,8 @@ curl -sSfL https://github.com"$(curl https://github.com/probonopd/go-appimage/re
|
||||
chmod a+x mkappimage.AppImage
|
||||
curl -sSfLO "https://raw.githubusercontent.com/linuxdeploy/linuxdeploy-plugin-gtk/master/linuxdeploy-plugin-gtk.sh"
|
||||
chmod a+x linuxdeploy-plugin-gtk.sh
|
||||
curl -sSfLO "https://github.com/darealshinji/linuxdeploy-plugin-checkrt/releases/download/continuous/linuxdeploy-plugin-checkrt.sh"
|
||||
chmod a+x linuxdeploy-plugin-checkrt.sh
|
||||
|
||||
if [[ ! -e /usr/lib/x86_64-linux-gnu ]]; then
|
||||
sed -i 's#lib\/x86_64-linux-gnu#lib64#g' linuxdeploy-plugin-gtk.sh
|
||||
@ -39,7 +41,8 @@ export NO_STRIP=1
|
||||
-d "${GITHUB_WORKSPACE}"/AppDir/info.cemu.Cemu.desktop \
|
||||
-i "${GITHUB_WORKSPACE}"/AppDir/info.cemu.Cemu.png \
|
||||
-e "${GITHUB_WORKSPACE}"/AppDir/usr/bin/Cemu \
|
||||
--plugin gtk
|
||||
--plugin gtk \
|
||||
--plugin checkrt
|
||||
|
||||
if ! GITVERSION="$(git rev-parse --short HEAD 2>/dev/null)"; then
|
||||
GITVERSION=experimental
|
||||
|
@ -525,7 +525,7 @@ void LatteSHRC_UpdateGSBaseHash(uint8* geometryShaderPtr, uint32 geometryShaderS
|
||||
// update hash from geometry shader data
|
||||
uint64 gsHash1 = 0;
|
||||
uint64 gsHash2 = 0;
|
||||
_calculateShaderProgramHash((uint32*)geometryShaderPtr, geometryShaderSize, &hashCacheVS, &gsHash1, &gsHash2);
|
||||
_calculateShaderProgramHash((uint32*)geometryShaderPtr, geometryShaderSize, &hashCacheGS, &gsHash1, &gsHash2);
|
||||
// get geometry shader
|
||||
uint64 gsHash = gsHash1 + gsHash2;
|
||||
gsHash += (uint64)_activeVertexShader->ringParameterCount;
|
||||
|
@ -12,9 +12,9 @@ uint32 RendererShader::GeneratePrecompiledCacheId()
|
||||
v += (uint32)(*s);
|
||||
s++;
|
||||
}
|
||||
v += (EMULATOR_VERSION_LEAD * 1000000u);
|
||||
v += (EMULATOR_VERSION_MAJOR * 10000u);
|
||||
v += (EMULATOR_VERSION_MINOR * 100u);
|
||||
v += (EMULATOR_VERSION_MAJOR * 1000000u);
|
||||
v += (EMULATOR_VERSION_MINOR * 10000u);
|
||||
v += (EMULATOR_VERSION_PATCH * 100u);
|
||||
|
||||
// settings that can influence shaders
|
||||
v += (uint32)g_current_game_profile->GetAccurateShaderMul() * 133;
|
||||
|
@ -125,7 +125,7 @@ std::vector<VulkanRenderer::DeviceInfo> VulkanRenderer::GetDevices()
|
||||
VkApplicationInfo app_info{};
|
||||
app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
|
||||
app_info.pApplicationName = EMULATOR_NAME;
|
||||
app_info.applicationVersion = VK_MAKE_VERSION(EMULATOR_VERSION_LEAD, EMULATOR_VERSION_MAJOR, EMULATOR_VERSION_MINOR);
|
||||
app_info.applicationVersion = VK_MAKE_VERSION(EMULATOR_VERSION_MAJOR, EMULATOR_VERSION_MINOR, EMULATOR_VERSION_PATCH);
|
||||
app_info.pEngineName = EMULATOR_NAME;
|
||||
app_info.engineVersion = app_info.applicationVersion;
|
||||
app_info.apiVersion = apiVersion;
|
||||
@ -339,7 +339,7 @@ VulkanRenderer::VulkanRenderer()
|
||||
VkApplicationInfo app_info{};
|
||||
app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
|
||||
app_info.pApplicationName = EMULATOR_NAME;
|
||||
app_info.applicationVersion = VK_MAKE_VERSION(EMULATOR_VERSION_LEAD, EMULATOR_VERSION_MAJOR, EMULATOR_VERSION_MINOR);
|
||||
app_info.applicationVersion = VK_MAKE_VERSION(EMULATOR_VERSION_MAJOR, EMULATOR_VERSION_MINOR, EMULATOR_VERSION_PATCH);
|
||||
app_info.pEngineName = EMULATOR_NAME;
|
||||
app_info.engineVersion = app_info.applicationVersion;
|
||||
app_info.apiVersion = apiVersion;
|
||||
|
@ -511,6 +511,8 @@ namespace iosu
|
||||
return CallHandler_GetBlackList(fpdClient, vecIn, numVecIn, vecOut, numVecOut);
|
||||
case FPD_REQUEST_ID::GetFriendListEx:
|
||||
return CallHandler_GetFriendListEx(fpdClient, vecIn, numVecIn, vecOut, numVecOut);
|
||||
case FPD_REQUEST_ID::UpdateCommentAsync:
|
||||
return CallHandler_UpdateCommentAsync(fpdClient, vecIn, numVecIn, vecOut, numVecOut);
|
||||
case FPD_REQUEST_ID::UpdatePreferenceAsync:
|
||||
return CallHandler_UpdatePreferenceAsync(fpdClient, vecIn, numVecIn, vecOut, numVecOut);
|
||||
case FPD_REQUEST_ID::AddFriendRequestByPlayRecordAsync:
|
||||
@ -719,18 +721,23 @@ namespace iosu
|
||||
|
||||
nnResult CallHandler_GetMyComment(FPDClient* fpdClient, IPCIoctlVector* vecIn, uint32 numVecIn, IPCIoctlVector* vecOut, uint32 numVecOut)
|
||||
{
|
||||
static constexpr uint32 MY_COMMENT_LENGTH = 0x12; // are comments utf16? Buffer length is 0x24
|
||||
if(numVecIn != 0 || numVecOut != 1)
|
||||
return FPResult_InvalidIPCParam;
|
||||
if(vecOut->size != MY_COMMENT_LENGTH*sizeof(uint16be))
|
||||
{
|
||||
cemuLog_log(LogType::Force, "GetMyComment: Unexpected output size");
|
||||
return FPResult_InvalidIPCParam;
|
||||
}
|
||||
std::basic_string<uint16be> myComment;
|
||||
myComment.resize(MY_COMMENT_LENGTH);
|
||||
memcpy(vecOut->basePhys.GetPtr(), myComment.data(), MY_COMMENT_LENGTH*sizeof(uint16be));
|
||||
return 0;
|
||||
if(g_fpd.nexFriendSession)
|
||||
{
|
||||
if(vecOut->size != MY_COMMENT_LENGTH * sizeof(uint16be))
|
||||
{
|
||||
cemuLog_log(LogType::Force, "GetMyComment: Unexpected output size");
|
||||
return FPResult_InvalidIPCParam;
|
||||
}
|
||||
nexComment myNexComment;
|
||||
g_fpd.nexFriendSession->getMyComment(myNexComment);
|
||||
myComment = StringHelpers::FromUtf8(myNexComment.commentString);
|
||||
}
|
||||
myComment.insert(0, 1, '\0');
|
||||
memcpy(vecOut->basePhys.GetPtr(), myComment.c_str(), MY_COMMENT_LENGTH * sizeof(uint16be));
|
||||
return FPResult_Ok;
|
||||
}
|
||||
|
||||
nnResult CallHandler_GetMyPreference(FPDClient* fpdClient, IPCIoctlVector* vecIn, uint32 numVecIn, IPCIoctlVector* vecOut, uint32 numVecOut)
|
||||
@ -1143,6 +1150,36 @@ namespace iosu
|
||||
return FPResult_Ok;
|
||||
}
|
||||
|
||||
nnResult CallHandler_UpdateCommentAsync(FPDClient* fpdClient, IPCIoctlVector* vecIn, uint32 numVecIn, IPCIoctlVector* vecOut, uint32 numVecOut)
|
||||
{
|
||||
std::unique_lock _l(g_fpd.mtxFriendSession);
|
||||
if (numVecIn != 1 || numVecOut != 0)
|
||||
return FPResult_InvalidIPCParam;
|
||||
if (!g_fpd.nexFriendSession)
|
||||
return FPResult_RequestFailed;
|
||||
uint32 messageLength = vecIn[0].size / sizeof(uint16be);
|
||||
DeclareInputPtr(newComment, uint16be, messageLength, 0);
|
||||
if (messageLength == 0 || newComment[messageLength-1] != 0)
|
||||
{
|
||||
cemuLog_log(LogType::Force, "UpdateCommentAsync: Message must contain at least a null-termination character");
|
||||
return FPResult_InvalidIPCParam;
|
||||
}
|
||||
IPCCommandBody* cmd = ServiceCallDelayCurrentResponse();
|
||||
|
||||
auto utf8_comment = StringHelpers::ToUtf8(newComment, messageLength);
|
||||
nexComment temporaryComment;
|
||||
temporaryComment.ukn0 = 0;
|
||||
temporaryComment.commentString = utf8_comment;
|
||||
temporaryComment.ukn1 = 0;
|
||||
|
||||
g_fpd.nexFriendSession->updateCommentAsync(temporaryComment, [cmd](NexFriends::RpcErrorCode result) {
|
||||
if (result != NexFriends::ERR_NONE)
|
||||
return ServiceCallAsyncRespond(cmd, FPResult_RequestFailed);
|
||||
ServiceCallAsyncRespond(cmd, FPResult_Ok);
|
||||
});
|
||||
return FPResult_Ok;
|
||||
}
|
||||
|
||||
nnResult CallHandler_UpdatePreferenceAsync(FPDClient* fpdClient, IPCIoctlVector* vecIn, uint32 numVecIn, IPCIoctlVector* vecOut, uint32 numVecOut)
|
||||
{
|
||||
std::unique_lock _l(g_fpd.mtxFriendSession);
|
||||
|
@ -212,6 +212,7 @@ namespace iosu
|
||||
static const int RELATIONSHIP_FRIEND = 3;
|
||||
|
||||
static const int GAMEMODE_MAX_MESSAGE_LENGTH = 0x80; // limit includes null-terminator character, so only 0x7F actual characters can be used
|
||||
static const int MY_COMMENT_LENGTH = 0x12;
|
||||
|
||||
enum class FPD_REQUEST_ID
|
||||
{
|
||||
@ -245,6 +246,7 @@ namespace iosu
|
||||
CheckSettingStatusAsync = 0x7596,
|
||||
GetFriendListEx = 0x75F9,
|
||||
GetFriendRequestListEx = 0x76C1,
|
||||
UpdateCommentAsync = 0x7726,
|
||||
UpdatePreferenceAsync = 0x7727,
|
||||
RemoveFriendAsync = 0x7789,
|
||||
DeleteFriendFlagsAsync = 0x778A,
|
||||
|
@ -140,7 +140,7 @@ namespace coreinit
|
||||
// we are in single-core mode and the lock will never be released unless we let other threads resume work
|
||||
// to avoid an infinite loop we have no choice but to yield the thread even it is in an uninterruptible state
|
||||
if( !OSIsInterruptEnabled() )
|
||||
cemuLog_log(LogType::APIErrors, "OSUninterruptibleSpinLock_Acquire(): Lock is occupied which requires a wait but current thread is already in an uninterruptible state (Avoid cascaded OSDisableInterrupts and/or OSUninterruptibleSpinLock)");
|
||||
cemuLog_logOnce(LogType::APIErrors, "OSUninterruptibleSpinLock_Acquire(): Lock is occupied which requires a wait but current thread is already in an uninterruptible state (Avoid cascaded OSDisableInterrupts and/or OSUninterruptibleSpinLock)");
|
||||
while (!spinlock->ownerThread.atomic_compare_exchange(nullptr, currentThread))
|
||||
{
|
||||
OSYieldThread();
|
||||
|
@ -464,6 +464,14 @@ namespace nn
|
||||
return ipcCtx->Submit(std::move(ipcCtx));
|
||||
}
|
||||
|
||||
nnResult GetMyPlayingGame(iosu::fpd::GameKey* myPlayingGame)
|
||||
{
|
||||
FP_API_BASE();
|
||||
auto ipcCtx = std::make_unique<FPIpcContext>(iosu::fpd::FPD_REQUEST_ID::GetMyPlayingGame);
|
||||
ipcCtx->AddOutput(myPlayingGame, sizeof(iosu::fpd::GameKey));
|
||||
return ipcCtx->Submit(std::move(ipcCtx));
|
||||
}
|
||||
|
||||
nnResult GetMyPreference(iosu::fpd::FPDPreference* myPreference)
|
||||
{
|
||||
FP_API_BASE();
|
||||
@ -472,6 +480,14 @@ namespace nn
|
||||
return ipcCtx->Submit(std::move(ipcCtx));
|
||||
}
|
||||
|
||||
nnResult GetMyComment(uint16be* myComment)
|
||||
{
|
||||
FP_API_BASE();
|
||||
auto ipcCtx = std::make_unique<FPIpcContext>(iosu::fpd::FPD_REQUEST_ID::GetMyComment);
|
||||
ipcCtx->AddOutput(myComment, iosu::fpd::MY_COMMENT_LENGTH * sizeof(uint16be));
|
||||
return ipcCtx->Submit(std::move(ipcCtx));
|
||||
}
|
||||
|
||||
nnResult GetMyMii(FFLData_t* fflData)
|
||||
{
|
||||
FP_API_BASE();
|
||||
@ -607,6 +623,20 @@ namespace nn
|
||||
return resultBuf != 0 ? 1 : 0;
|
||||
}
|
||||
|
||||
nnResult UpdateCommentAsync(uint16be* newComment, void* funcPtr, void* customParam)
|
||||
{
|
||||
FP_API_BASE();
|
||||
auto ipcCtx = std::make_unique<FPIpcContext>(iosu::fpd::FPD_REQUEST_ID::UpdateCommentAsync);
|
||||
uint32 commentLen = CafeStringHelpers::Length(newComment, iosu::fpd::MY_COMMENT_LENGTH-1);
|
||||
if (commentLen >= iosu::fpd::MY_COMMENT_LENGTH-1)
|
||||
{
|
||||
cemuLog_log(LogType::Force, "UpdateCommentAsync: message too long");
|
||||
return FPResult_InvalidIPCParam;
|
||||
}
|
||||
ipcCtx->AddInput(newComment, sizeof(uint16be) * commentLen + 2);
|
||||
return ipcCtx->SubmitAsync(std::move(ipcCtx), funcPtr, customParam);
|
||||
}
|
||||
|
||||
nnResult UpdatePreferenceAsync(iosu::fpd::FPDPreference* newPreference, void* funcPtr, void* customParam)
|
||||
{
|
||||
FP_API_BASE();
|
||||
@ -763,7 +793,9 @@ namespace nn
|
||||
cafeExportRegisterFunc(GetMyAccountId, "nn_fp", "GetMyAccountId__Q2_2nn2fpFPc", LogType::NN_FP);
|
||||
cafeExportRegisterFunc(GetMyScreenName, "nn_fp", "GetMyScreenName__Q2_2nn2fpFPw", LogType::NN_FP);
|
||||
cafeExportRegisterFunc(GetMyMii, "nn_fp", "GetMyMii__Q2_2nn2fpFP12FFLStoreData", LogType::NN_FP);
|
||||
cafeExportRegisterFunc(GetMyPlayingGame, "nn_fp", "GetMyPlayingGame__Q2_2nn2fpFPQ3_2nn2fp7GameKey", LogType::NN_FP);
|
||||
cafeExportRegisterFunc(GetMyPreference, "nn_fp", "GetMyPreference__Q2_2nn2fpFPQ3_2nn2fp10Preference", LogType::NN_FP);
|
||||
cafeExportRegisterFunc(GetMyComment, "nn_fp", "GetMyComment__Q2_2nn2fpFPQ3_2nn2fp7Comment", LogType::NN_FP);
|
||||
|
||||
cafeExportRegisterFunc(GetFriendAccountId, "nn_fp", "GetFriendAccountId__Q2_2nn2fpFPA17_cPCUiUi", LogType::NN_FP);
|
||||
cafeExportRegisterFunc(GetFriendScreenName, "nn_fp", "GetFriendScreenName__Q2_2nn2fpFPA11_wPCUiUibPUc", LogType::NN_FP);
|
||||
@ -774,6 +806,7 @@ namespace nn
|
||||
|
||||
cafeExportRegisterFunc(CheckSettingStatusAsync, "nn_fp", "CheckSettingStatusAsync__Q2_2nn2fpFPUcPFQ2_2nn6ResultPv_vPv", LogType::NN_FP);
|
||||
cafeExportRegisterFunc(IsPreferenceValid, "nn_fp", "IsPreferenceValid__Q2_2nn2fpFv", LogType::NN_FP);
|
||||
cafeExportRegisterFunc(UpdateCommentAsync, "nn_fp", "UpdateCommentAsync__Q2_2nn2fpFPCwPFQ2_2nn6ResultPv_vPv", LogType::NN_FP);
|
||||
cafeExportRegisterFunc(UpdatePreferenceAsync, "nn_fp", "UpdatePreferenceAsync__Q2_2nn2fpFPCQ3_2nn2fp10PreferencePFQ2_2nn6ResultPv_vPv", LogType::NN_FP);
|
||||
cafeExportRegisterFunc(GetRequestBlockSettingAsync, "nn_fp", "GetRequestBlockSettingAsync__Q2_2nn2fpFPUcPCUiUiPFQ2_2nn6ResultPv_vPv", LogType::NN_FP);
|
||||
|
||||
|
@ -12,6 +12,7 @@
|
||||
enum class KPAD_ERROR : sint32
|
||||
{
|
||||
NONE = 0,
|
||||
NO_SAMPLE_DATA = -1,
|
||||
NO_CONTROLLER = -2,
|
||||
NOT_INITIALIZED = -5,
|
||||
};
|
||||
@ -106,6 +107,9 @@ void padscoreExport_WPADProbe(PPCInterpreter_t* hCPU)
|
||||
}
|
||||
else
|
||||
{
|
||||
if(type)
|
||||
*type = 253;
|
||||
|
||||
osLib_returnFromFunction(hCPU, WPAD_ERR_NO_CONTROLLER);
|
||||
}
|
||||
}
|
||||
@ -420,9 +424,12 @@ void padscoreExport_KPADSetConnectCallback(PPCInterpreter_t* hCPU)
|
||||
osLib_returnFromFunction(hCPU, old_callback.GetMPTR());
|
||||
}
|
||||
|
||||
uint64 g_kpadLastRead[InputManager::kMaxWPADControllers] = {0};
|
||||
bool g_kpadIsInited = true;
|
||||
|
||||
sint32 _KPADRead(uint32 channel, KPADStatus_t* samplingBufs, uint32 length, betype<KPAD_ERROR>* errResult)
|
||||
{
|
||||
|
||||
if (channel >= InputManager::kMaxWPADControllers)
|
||||
{
|
||||
debugBreakpoint();
|
||||
@ -446,6 +453,19 @@ sint32 _KPADRead(uint32 channel, KPADStatus_t* samplingBufs, uint32 length, bety
|
||||
return 0;
|
||||
}
|
||||
|
||||
// On console new input samples are only received every few ms and calling KPADRead(Ex) clears the internal queue regardless of length value
|
||||
// thus calling KPADRead(Ex) again too soon on the same channel will result in no data being returned
|
||||
// Games that depend on this: Affordable Space Adventures
|
||||
uint64 currentTime = coreinit::OSGetTime();
|
||||
uint64 timeDif = currentTime - g_kpadLastRead[channel];
|
||||
if(length == 0 || timeDif < coreinit::EspressoTime::ConvertNsToTimerTicks(1000000))
|
||||
{
|
||||
if (errResult)
|
||||
*errResult = KPAD_ERROR::NO_SAMPLE_DATA;
|
||||
return 0;
|
||||
}
|
||||
g_kpadLastRead[channel] = currentTime;
|
||||
|
||||
memset(samplingBufs, 0x00, sizeof(KPADStatus_t));
|
||||
samplingBufs->wpadErr = WPAD_ERR_NONE;
|
||||
samplingBufs->data_format = controller->get_data_format();
|
||||
@ -474,7 +494,6 @@ void padscoreExport_KPADReadEx(PPCInterpreter_t* hCPU)
|
||||
osLib_returnFromFunction(hCPU, samplesRead);
|
||||
}
|
||||
|
||||
bool debugUseDRC1 = true;
|
||||
void padscoreExport_KPADRead(PPCInterpreter_t* hCPU)
|
||||
{
|
||||
ppcDefineParamU32(channel, 0);
|
||||
@ -726,7 +745,8 @@ namespace padscore
|
||||
// call sampling callback
|
||||
for (auto i = 0; i < InputManager::kMaxWPADControllers; ++i)
|
||||
{
|
||||
if (g_padscore.controller_data[i].sampling_callback) {
|
||||
if (g_padscore.controller_data[i].sampling_callback)
|
||||
{
|
||||
if (const auto controller = instance.get_wpad_controller(i))
|
||||
{
|
||||
cemuLog_log(LogType::InputAPI, "Calling WPADsamplingCallback({})", i);
|
||||
@ -741,7 +761,7 @@ namespace padscore
|
||||
{
|
||||
OSCreateAlarm(&g_padscore.alarm);
|
||||
const uint64 start_tick = coreinit::coreinit_getOSTime();
|
||||
const uint64 period_tick = coreinit::EspressoTime::GetTimerClock(); // once a second
|
||||
const uint64 period_tick = coreinit::EspressoTime::GetTimerClock() / 200; // every 5ms
|
||||
MPTR handler = PPCInterpreter_makeCallableExportDepr(TickFunction);
|
||||
OSSetPeriodicAlarm(&g_padscore.alarm, start_tick, period_tick, handler);
|
||||
}
|
||||
|
@ -50,7 +50,6 @@
|
||||
|
||||
extern bool isLaunchTypeELF;
|
||||
|
||||
bool debugUseDRC = true;
|
||||
VPADDir g_vpadGyroDirOverwrite[VPAD_MAX_CONTROLLERS] =
|
||||
{
|
||||
{{1.0f,0.0f,0.0f}, {0.0f,1.0f,0.0f}, {0.0f, 0.0f, 0.1f}},
|
||||
@ -240,19 +239,20 @@ namespace vpad
|
||||
status->tpProcessed2.validity = VPAD_TP_VALIDITY_INVALID_XY;
|
||||
|
||||
const auto controller = InputManager::instance().get_vpad_controller(channel);
|
||||
if (!controller || debugUseDRC == false)
|
||||
if (!controller)
|
||||
{
|
||||
// no controller
|
||||
// most games expect the Wii U GamePad to be connected, so even if the user has not set it up we should still return empty samples for channel 0
|
||||
if(channel != 0)
|
||||
{
|
||||
if (error)
|
||||
*error = VPAD_READ_ERR_NO_CONTROLLER;
|
||||
if (length > 0)
|
||||
status->vpadErr = -1;
|
||||
return 0;
|
||||
}
|
||||
if (error)
|
||||
*error = VPAD_READ_ERR_NONE; // VPAD_READ_ERR_NO_DATA; // VPAD_READ_ERR_NO_CONTROLLER;
|
||||
|
||||
*error = VPAD_READ_ERR_NONE;
|
||||
return 1;
|
||||
//osLib_returnFromFunction(hCPU, 1); return;
|
||||
}
|
||||
|
||||
if (channel != 0)
|
||||
{
|
||||
debugBreakpoint();
|
||||
}
|
||||
|
||||
const bool vpadDelayEnabled = ActiveSettings::VPADDelayEnabled();
|
||||
@ -274,9 +274,7 @@ namespace vpad
|
||||
// not ready yet
|
||||
if (error)
|
||||
*error = VPAD_READ_ERR_NONE;
|
||||
|
||||
return 0;
|
||||
//osLib_returnFromFunction(hCPU, 0); return;
|
||||
}
|
||||
else if (dif <= ESPRESSO_TIMER_CLOCK)
|
||||
{
|
||||
|
@ -277,7 +277,8 @@ void NexFriends::handleResponse_getAllInformation(nexServiceResponse_t* response
|
||||
}
|
||||
NexFriends* session = (NexFriends*)nexFriends;
|
||||
session->myPreference = nexPrincipalPreference(&response->data);
|
||||
nexComment comment(&response->data);
|
||||
auto comment = nexComment(&response->data);
|
||||
session->myComment = comment;
|
||||
if (response->data.hasReadOutOfBounds())
|
||||
return;
|
||||
// acquire lock on lists
|
||||
@ -391,6 +392,28 @@ void NexFriends::getMyPreference(nexPrincipalPreference& preference)
|
||||
preference = myPreference;
|
||||
}
|
||||
|
||||
bool NexFriends::updateCommentAsync(nexComment newComment, std::function<void(RpcErrorCode)> cb)
|
||||
{
|
||||
uint8 tempNexBufferArray[1024];
|
||||
nexPacketBuffer packetBuffer(tempNexBufferArray, sizeof(tempNexBufferArray), true);
|
||||
newComment.writeData(&packetBuffer);
|
||||
nexCon->callMethod(
|
||||
NEX_PROTOCOL_FRIENDS_WIIU, 15, &packetBuffer, [this, cb, newComment](nexServiceResponse_t* response) -> void {
|
||||
if (!response->isSuccessful)
|
||||
return cb(NexFriends::ERR_RPC_FAILED);
|
||||
this->myComment = newComment;
|
||||
return cb(NexFriends::ERR_NONE);
|
||||
},
|
||||
true);
|
||||
// TEST
|
||||
return true;
|
||||
}
|
||||
|
||||
void NexFriends::getMyComment(nexComment& comment)
|
||||
{
|
||||
comment = myComment;
|
||||
}
|
||||
|
||||
bool NexFriends::addProvisionalFriendByPidGuessed(uint32 principalId)
|
||||
{
|
||||
uint8 tempNexBufferArray[512];
|
||||
|
@ -297,7 +297,9 @@ public:
|
||||
|
||||
void writeData(nexPacketBuffer* pb) const override
|
||||
{
|
||||
cemu_assert_unimplemented();
|
||||
pb->writeU8(ukn0);
|
||||
pb->writeString(commentString.c_str());
|
||||
pb->writeU64(ukn1);
|
||||
}
|
||||
|
||||
void readData(nexPacketBuffer* pb) override
|
||||
@ -554,6 +556,7 @@ public:
|
||||
bool getFriendRequestByMessageId(nexFriendRequest& friendRequestData, bool* isIncoming, uint64 messageId);
|
||||
bool isOnline();
|
||||
void getMyPreference(nexPrincipalPreference& preference);
|
||||
void getMyComment(nexComment& comment);
|
||||
|
||||
// asynchronous API (data has to be requested)
|
||||
bool addProvisionalFriend(char* name, std::function<void(RpcErrorCode)> cb);
|
||||
@ -565,6 +568,7 @@ public:
|
||||
void acceptFriendRequest(uint64 messageId, std::function<void(RpcErrorCode)> cb);
|
||||
void deleteFriendRequest(uint64 messageId, std::function<void(RpcErrorCode)> cb); // rejecting incoming friend request (differs from blocking friend requests)
|
||||
bool updatePreferencesAsync(const nexPrincipalPreference newPreferences, std::function<void(RpcErrorCode)> cb);
|
||||
bool updateCommentAsync(const nexComment newComment, std::function<void(RpcErrorCode)> cb);
|
||||
void updateMyPresence(nexPresenceV2& myPresence);
|
||||
|
||||
void setNotificationHandler(void(*notificationHandler)(NOTIFICATION_TYPE notificationType, uint32 pid));
|
||||
@ -619,6 +623,7 @@ private:
|
||||
// local friend state
|
||||
nexPresenceV2 myPresence;
|
||||
nexPrincipalPreference myPreference;
|
||||
nexComment myComment;
|
||||
|
||||
std::recursive_mutex mtx_lists;
|
||||
std::vector<nexFriend> list_friends;
|
||||
|
@ -1,36 +1,19 @@
|
||||
#ifndef EMULATOR_NAME
|
||||
|
||||
#define EMULATOR_NAME "Cemu"
|
||||
#define EMULATOR_VERSION_LEAD 2
|
||||
#define EMULATOR_VERSION_MAJOR 0
|
||||
|
||||
// the minor version is used for experimental builds to indicate the build index. Set by command line option from CI build script
|
||||
// if zero, the version text will be constructed as LEAD.MAJOR, otherwise as LEAD.MAJOR-MINOR
|
||||
|
||||
#if defined(EMULATOR_VERSION_MINOR) && EMULATOR_VERSION_MINOR == 0
|
||||
#define EMULATOR_VERSION_SUFFIX ""
|
||||
#else
|
||||
#define EMULATOR_VERSION_SUFFIX " (experimental)"
|
||||
#endif
|
||||
|
||||
#ifndef EMULATOR_VERSION_MINOR
|
||||
#define EMULATOR_VERSION_MINOR 0
|
||||
#endif
|
||||
|
||||
#define _XSTRINGFY(s) _STRINGFY(s)
|
||||
#define _STRINGFY(s) #s
|
||||
|
||||
#if EMULATOR_VERSION_MINOR != 0
|
||||
#if defined(EMULATOR_HASH) && EMULATOR_VERSION_MINOR == 999999
|
||||
#define BUILD_VERSION_WITH_NAME_STRING (EMULATOR_NAME " " _XSTRINGFY(EMULATOR_VERSION_LEAD) "." _XSTRINGFY(EMULATOR_VERSION_MAJOR) "-" _XSTRINGFY(EMULATOR_HASH) EMULATOR_VERSION_SUFFIX)
|
||||
#define BUILD_VERSION_STRING (_XSTRINGFY(EMULATOR_VERSION_LEAD) "." _XSTRINGFY(EMULATOR_VERSION_MAJOR) "-" _XSTRINGFY(EMULATOR_HASH) EMULATOR_VERSION_SUFFIX)
|
||||
#if EMULATOR_VERSION_MAJOR != 0
|
||||
#define BUILD_VERSION_WITH_NAME_STRING (EMULATOR_NAME " " _XSTRINGFY(EMULATOR_VERSION_MAJOR) "." _XSTRINGFY(EMULATOR_VERSION_MINOR) EMULATOR_VERSION_SUFFIX)
|
||||
#define BUILD_VERSION_STRING (_XSTRINGFY(EMULATOR_VERSION_MAJOR) "." _XSTRINGFY(EMULATOR_VERSION_MINOR) EMULATOR_VERSION_SUFFIX)
|
||||
#else
|
||||
#define BUILD_VERSION_WITH_NAME_STRING (EMULATOR_NAME " " _XSTRINGFY(EMULATOR_VERSION_LEAD) "." _XSTRINGFY(EMULATOR_VERSION_MAJOR) "-" _XSTRINGFY(EMULATOR_VERSION_MINOR) EMULATOR_VERSION_SUFFIX)
|
||||
#define BUILD_VERSION_STRING (_XSTRINGFY(EMULATOR_VERSION_LEAD) "." _XSTRINGFY(EMULATOR_VERSION_MAJOR) "-" _XSTRINGFY(EMULATOR_VERSION_MINOR) EMULATOR_VERSION_SUFFIX)
|
||||
#endif
|
||||
#else
|
||||
#define BUILD_VERSION_STRING (_XSTRINGFY(EMULATOR_VERSION_LEAD) "." _XSTRINGFY(EMULATOR_VERSION_MAJOR) EMULATOR_VERSION_SUFFIX)
|
||||
#define BUILD_VERSION_WITH_NAME_STRING (EMULATOR_NAME " " _XSTRINGFY(EMULATOR_VERSION_LEAD) "." _XSTRINGFY(EMULATOR_VERSION_MAJOR) EMULATOR_VERSION_SUFFIX)
|
||||
// no version provided. Only show commit hash
|
||||
#define BUILD_VERSION_STRING (_XSTRINGFY(EMULATOR_HASH) EMULATOR_VERSION_SUFFIX)
|
||||
#define BUILD_VERSION_WITH_NAME_STRING (EMULATOR_NAME " " _XSTRINGFY(EMULATOR_HASH) EMULATOR_VERSION_SUFFIX)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -1,6 +1,12 @@
|
||||
project(CemuAsm C)
|
||||
|
||||
if (CMAKE_SYSTEM_PROCESSOR MATCHES "(x86)|(X86)|(amd64)|(AMD64)")
|
||||
if (CMAKE_OSX_ARCHITECTURES)
|
||||
set(CEMU_ASM_ARCHITECTURE ${CMAKE_OSX_ARCHITECTURES})
|
||||
else()
|
||||
set(CEMU_ASM_ARCHITECTURE ${CMAKE_SYSTEM_PROCESSOR})
|
||||
endif()
|
||||
|
||||
if (CEMU_ASM_ARCHITECTURE MATCHES "(x86)|(X86)|(amd64)|(AMD64)")
|
||||
|
||||
if (WIN32)
|
||||
|
||||
@ -40,8 +46,8 @@ if (CMAKE_SYSTEM_PROCESSOR MATCHES "(x86)|(X86)|(amd64)|(AMD64)")
|
||||
|
||||
endif()
|
||||
|
||||
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "(aarch64)|(AARCH64)")
|
||||
elseif(CEMU_ASM_ARCHITECTURE MATCHES "(aarch64)|(AARCH64)|(arm64)|(ARM64)")
|
||||
add_library(CemuAsm stub.cpp)
|
||||
else()
|
||||
message(STATUS "CemuAsm - Unsupported arch: ${CMAKE_SYSTEM_PROCESSOR}")
|
||||
message(STATUS "CemuAsm - Unsupported arch: ${CEMU_ASM_ARCHITECTURE}")
|
||||
endif()
|
||||
|
@ -38,6 +38,7 @@ void CemuConfig::Load(XMLConfigParser& parser)
|
||||
fullscreen_menubar = parser.get("fullscreen_menubar", false);
|
||||
feral_gamemode = parser.get("feral_gamemode", false);
|
||||
check_update = parser.get("check_update", check_update);
|
||||
receive_untested_updates = parser.get("receive_untested_updates", check_update);
|
||||
save_screenshot = parser.get("save_screenshot", save_screenshot);
|
||||
did_show_vulkan_warning = parser.get("vk_warning", did_show_vulkan_warning);
|
||||
did_show_graphic_pack_download = parser.get("gp_download", did_show_graphic_pack_download);
|
||||
@ -360,6 +361,7 @@ void CemuConfig::Save(XMLConfigParser& parser)
|
||||
config.set<bool>("fullscreen_menubar", fullscreen_menubar);
|
||||
config.set<bool>("feral_gamemode", feral_gamemode);
|
||||
config.set<bool>("check_update", check_update);
|
||||
config.set<bool>("receive_untested_updates", receive_untested_updates);
|
||||
config.set<bool>("save_screenshot", save_screenshot);
|
||||
config.set<bool>("vk_warning", did_show_vulkan_warning);
|
||||
config.set<bool>("gp_download", did_show_graphic_pack_download);
|
||||
|
@ -414,7 +414,8 @@ struct CemuConfig
|
||||
Vector2i pad_size{ -1,-1 };
|
||||
ConfigValue<bool> pad_maximized;
|
||||
|
||||
ConfigValue<bool> check_update{false};
|
||||
ConfigValue<bool> check_update{true};
|
||||
ConfigValue<bool> receive_untested_updates{false};
|
||||
ConfigValue<bool> save_screenshot{true};
|
||||
|
||||
ConfigValue<bool> did_show_vulkan_warning{false};
|
||||
|
@ -112,10 +112,10 @@ bool LaunchSettings::HandleCommandline(const std::vector<std::wstring>& args)
|
||||
{
|
||||
requireConsole();
|
||||
std::string versionStr;
|
||||
#if EMULATOR_VERSION_MINOR == 0
|
||||
versionStr = fmt::format("{}.{}{}", EMULATOR_VERSION_LEAD, EMULATOR_VERSION_MAJOR, EMULATOR_VERSION_SUFFIX);
|
||||
#if EMULATOR_VERSION_PATCH == 0
|
||||
versionStr = fmt::format("{}.{}{}", EMULATOR_VERSION_MAJOR, EMULATOR_VERSION_MINOR, EMULATOR_VERSION_SUFFIX);
|
||||
#else
|
||||
versionStr = fmt::format("{}.{}-{}{}", EMULATOR_VERSION_LEAD, EMULATOR_VERSION_MAJOR, EMULATOR_VERSION_MINOR, EMULATOR_VERSION_SUFFIX);
|
||||
versionStr = fmt::format("{}.{}-{}{}", EMULATOR_VERSION_MAJOR, EMULATOR_VERSION_MINOR, EMULATOR_VERSION_PATCH, EMULATOR_VERSION_SUFFIX);
|
||||
#endif
|
||||
std::cout << versionStr << std::endl;
|
||||
return false; // exit in main
|
||||
|
@ -116,9 +116,11 @@ bool CemuUpdateWindow::QueryUpdateInfo(std::string& downloadUrlOut, std::string&
|
||||
#elif BOOST_OS_MACOS
|
||||
urlStr.append("&platform=macos_bundle_x86");
|
||||
#elif
|
||||
|
||||
#error Name for current platform is missing
|
||||
#endif
|
||||
const auto& config = GetConfig();
|
||||
if(config.receive_untested_updates)
|
||||
urlStr.append("&allowNewUpdates=1");
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_URL, urlStr.c_str());
|
||||
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
|
||||
|
@ -115,7 +115,7 @@ void DownloadGraphicPacksWindow::UpdateThread()
|
||||
curlDownloadFileState_t tempDownloadState;
|
||||
std::string queryUrl("https://cemu.info/api2/query_graphicpack_url.php?");
|
||||
char temp[64];
|
||||
sprintf(temp, "version=%d.%d.%d", EMULATOR_VERSION_LEAD, EMULATOR_VERSION_MAJOR, EMULATOR_VERSION_MINOR);
|
||||
sprintf(temp, "version=%d.%d.%d", EMULATOR_VERSION_MAJOR, EMULATOR_VERSION_MINOR, EMULATOR_VERSION_PATCH);
|
||||
queryUrl.append(temp);
|
||||
queryUrl.append("&");
|
||||
sprintf(temp, "t=%u", (uint32)std::chrono::seconds(std::time(NULL)).count()); // add a dynamic part to the url to bypass overly aggressive caching (like some proxies do)
|
||||
|
@ -141,49 +141,66 @@ wxPanel* GeneralSettings2::AddGeneralPage(wxNotebook* notebook)
|
||||
second_row->SetFlexibleDirection(wxBOTH);
|
||||
second_row->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED);
|
||||
|
||||
sint32 checkboxCount = 0;
|
||||
auto CountRowElement = [&]()
|
||||
{
|
||||
checkboxCount++;
|
||||
if(checkboxCount != 2)
|
||||
return;
|
||||
second_row->AddSpacer(10);
|
||||
checkboxCount = 0;
|
||||
};
|
||||
|
||||
auto InsertEmptyRow = [&]()
|
||||
{
|
||||
while(checkboxCount != 0)
|
||||
CountRowElement();
|
||||
second_row->AddSpacer(10);
|
||||
second_row->AddSpacer(10);
|
||||
second_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);
|
||||
second_row->AddSpacer(10);
|
||||
CountRowElement();
|
||||
//second_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);
|
||||
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);
|
||||
CountRowElement();
|
||||
#ifndef ENABLE_DISCORD_RPC
|
||||
m_discord_presence->Disable();
|
||||
#endif
|
||||
second_row->AddSpacer(10);
|
||||
//second_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);
|
||||
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);
|
||||
#if BOOST_OS_LINUX
|
||||
if (!std::getenv("APPIMAGE")) {
|
||||
m_auto_update->Disable();
|
||||
}
|
||||
#endif
|
||||
second_row->AddSpacer(10);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
CountRowElement();
|
||||
#endif
|
||||
|
||||
// temporary workaround because feature crashes on macOS
|
||||
@ -191,6 +208,22 @@ wxPanel* GeneralSettings2::AddGeneralPage(wxNotebook* notebook)
|
||||
m_disable_screensaver->Enable(false);
|
||||
#endif
|
||||
|
||||
// InsertEmptyRow();
|
||||
|
||||
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);
|
||||
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);
|
||||
#if BOOST_OS_LINUX
|
||||
if (!std::getenv("APPIMAGE")) {
|
||||
m_auto_update->Disable();
|
||||
}
|
||||
#endif
|
||||
|
||||
box_sizer->Add(second_row, 0, wxEXPAND, 5);
|
||||
}
|
||||
|
||||
@ -1538,6 +1571,7 @@ void GeneralSettings2::ApplyConfig()
|
||||
m_fullscreen_menubar->SetValue(config.fullscreen_menubar);
|
||||
|
||||
m_auto_update->SetValue(config.check_update);
|
||||
m_receive_untested_releases->SetValue(config.receive_untested_updates);
|
||||
m_save_screenshot->SetValue(config.save_screenshot);
|
||||
|
||||
m_disable_screensaver->SetValue(config.disable_screensaver);
|
||||
|
@ -41,7 +41,7 @@ private:
|
||||
wxCheckBox* m_save_window_position_size;
|
||||
wxCheckBox* m_save_padwindow_position_size;
|
||||
wxCheckBox* m_discord_presence, *m_fullscreen_menubar;
|
||||
wxCheckBox* m_auto_update, *m_save_screenshot;
|
||||
wxCheckBox* m_auto_update, *m_receive_untested_releases, *m_save_screenshot;
|
||||
wxCheckBox* m_disable_screensaver;
|
||||
#if BOOST_OS_LINUX && defined(ENABLE_FERAL_GAMEMODE)
|
||||
wxCheckBox* m_feral_gamemode;
|
||||
|
@ -458,10 +458,10 @@ void GraphicPacksWindow2::OnTreeSelectionChanged(wxTreeEvent& event)
|
||||
|
||||
m_shown_graphic_pack = gp;
|
||||
|
||||
m_graphic_pack_name->Wrap(m_graphic_pack_name->GetParent()->GetClientSize().GetWidth() - 10);
|
||||
m_graphic_pack_name->Wrap(m_graphic_pack_name->GetParent()->GetClientSize().GetWidth() - 20);
|
||||
m_graphic_pack_name->GetGrandParent()->Layout();
|
||||
|
||||
m_graphic_pack_description->Wrap(m_graphic_pack_description->GetParent()->GetClientSize().GetWidth() - 10);
|
||||
m_graphic_pack_description->Wrap(m_graphic_pack_description->GetParent()->GetClientSize().GetWidth() - 20);
|
||||
m_graphic_pack_description->GetGrandParent()->Layout();
|
||||
|
||||
m_right_panel->FitInside();
|
||||
|
@ -73,8 +73,8 @@ END
|
||||
#define str(s) #s
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION EMULATOR_VERSION_LEAD, EMULATOR_VERSION_MAJOR, EMULATOR_VERSION_MINOR, 0
|
||||
PRODUCTVERSION EMULATOR_VERSION_LEAD, EMULATOR_VERSION_MAJOR, EMULATOR_VERSION_MINOR, 0
|
||||
FILEVERSION EMULATOR_VERSION_MAJOR, EMULATOR_VERSION_MINOR, EMULATOR_VERSION_PATCH, 0
|
||||
PRODUCTVERSION EMULATOR_VERSION_MAJOR, EMULATOR_VERSION_MINOR, EMULATOR_VERSION_PATCH, 0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@ -94,7 +94,7 @@ BEGIN
|
||||
VALUE "LegalCopyright", "Team Cemu"
|
||||
VALUE "OriginalFilename", "Cemu.exe"
|
||||
VALUE "ProductName", "Cemu"
|
||||
VALUE "ProductVersion", xstr(EMULATOR_VERSION_LEAD) "." xstr(EMULATOR_VERSION_MAJOR) "." xstr(EMULATOR_VERSION_MINOR) EMULATOR_VERSION_SUFFIX "\0"
|
||||
VALUE "ProductVersion", xstr(EMULATOR_VERSION_MAJOR) "." xstr(EMULATOR_VERSION_MINOR) "." xstr(EMULATOR_VERSION_PATCH) EMULATOR_VERSION_SUFFIX "\0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
Loading…
Reference in New Issue
Block a user