Compare commits
2 Commits
__refs_pul
...
__refs_pul
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
41e855bd42 | ||
|
|
acc887cc34 |
@@ -33,14 +33,16 @@ DESTDIR="$PWD/AppDir" ninja install
|
||||
rm -vf AppDir/usr/bin/yuzu-cmd AppDir/usr/bin/yuzu-tester
|
||||
|
||||
# Download tools needed to build an AppImage
|
||||
wget -nc https://raw.githubusercontent.com/lat9nq/deploy/main/linux/deploy-linux.sh
|
||||
wget -nc https://raw.githubusercontent.com/yuzu-emu/AppImageKit-checkrt/old/AppRun.sh
|
||||
wget -nc https://github.com/yuzu-emu/ext-linux-bin/raw/main/appimage/linuxdeploy-x86_64.AppImage
|
||||
wget -nc https://github.com/yuzu-emu/ext-linux-bin/raw/main/appimage/linuxdeploy-plugin-qt-x86_64.AppImage
|
||||
wget -nc https://github.com/yuzu-emu/ext-linux-bin/raw/main/appimage/AppRun-patched-x86_64
|
||||
wget -nc https://github.com/yuzu-emu/ext-linux-bin/raw/main/appimage/exec-x86_64.so
|
||||
# Set executable bit
|
||||
chmod 755 \
|
||||
deploy-linux.sh \
|
||||
AppRun.sh \
|
||||
AppRun-patched-x86_64 \
|
||||
exec-x86_64.so \
|
||||
linuxdeploy-x86_64.AppImage \
|
||||
linuxdeploy-plugin-qt-x86_64.AppImage
|
||||
|
||||
# Workaround for https://github.com/AppImage/AppImageKit/issues/828
|
||||
export APPIMAGE_EXTRACT_AND_RUN=1
|
||||
@@ -50,7 +52,7 @@ mkdir -p AppDir/usr/optional/libstdc++
|
||||
mkdir -p AppDir/usr/optional/libgcc_s
|
||||
|
||||
# Deploy yuzu's needed dependencies
|
||||
DEPLOY_QT=1 ./deploy-linux.sh AppDir/usr/bin/yuzu AppDir
|
||||
./linuxdeploy-x86_64.AppImage --appdir AppDir --plugin qt
|
||||
|
||||
# Workaround for libQt5MultimediaGstTools indirectly requiring libwayland-client and breaking Vulkan usage on end-user systems
|
||||
find AppDir -type f -regex '.*libwayland-client\.so.*' -delete -print
|
||||
@@ -58,6 +60,6 @@ find AppDir -type f -regex '.*libwayland-client\.so.*' -delete -print
|
||||
# Workaround for building yuzu with GCC 10 but also trying to distribute it to Ubuntu 18.04 et al.
|
||||
# See https://github.com/darealshinji/AppImageKit-checkrt
|
||||
cp exec-x86_64.so AppDir/usr/optional/exec.so
|
||||
cp AppRun.sh AppDir/AppRun
|
||||
cp AppRun-patched-x86_64 AppDir/AppRun
|
||||
cp --dereference /usr/lib/x86_64-linux-gnu/libstdc++.so.6 AppDir/usr/optional/libstdc++/libstdc++.so.6
|
||||
cp --dereference /lib/x86_64-linux-gnu/libgcc_s.so.1 AppDir/usr/optional/libgcc_s/libgcc_s.so.1
|
||||
|
||||
@@ -7,6 +7,11 @@ function(get_timestamp _var)
|
||||
set(${_var} "${timestamp}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
list(APPEND CMAKE_MODULE_PATH "${SRC_DIR}/externals/cmake-modules")
|
||||
|
||||
# Find the package here with the known path so that the GetGit commands can find it as well
|
||||
find_package(Git QUIET PATHS "${GIT_EXECUTABLE}")
|
||||
|
||||
# generate git/build information
|
||||
include(GetGitRevisionDescription)
|
||||
if(NOT GIT_REF_SPEC)
|
||||
@@ -24,7 +29,6 @@ get_timestamp(BUILD_DATE)
|
||||
# Also if this is a CI build, add the build name (ie: Nightly, Canary) to the scm_rev file as well
|
||||
set(REPO_NAME "")
|
||||
set(BUILD_VERSION "0")
|
||||
set(BUILD_ID ${DISPLAY_VERSION})
|
||||
if (BUILD_REPOSITORY)
|
||||
# regex capture the string nightly or canary into CMAKE_MATCH_1
|
||||
string(REGEX MATCH "yuzu-emu/yuzu-?(.*)" OUTVAR ${BUILD_REPOSITORY})
|
||||
@@ -53,4 +57,6 @@ if (BUILD_REPOSITORY)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
configure_file(scm_rev.cpp.in scm_rev.cpp @ONLY)
|
||||
# The variable SRC_DIR must be passed into the script
|
||||
# (since it uses the current build directory for all values of CMAKE_*_DIR)
|
||||
configure_file("${SRC_DIR}/src/common/scm_rev.cpp.in" "scm_rev.cpp" @ONLY)
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
namespace AudioCore {
|
||||
|
||||
AudioCore::AudioCore(Core::System& system) : audio_manager{std::make_unique<AudioManager>()} {
|
||||
AudioCore::AudioCore(Core::System& system) : audio_manager{std::make_unique<AudioManager>(system)} {
|
||||
CreateSinks();
|
||||
// Must be created after the sinks
|
||||
adsp = std::make_unique<AudioRenderer::ADSP::ADSP>(system, *output_sink);
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "audio_core/audio_in_manager.h"
|
||||
#include "audio_core/audio_manager.h"
|
||||
#include "audio_core/audio_out_manager.h"
|
||||
#include "core/core.h"
|
||||
#include "core/hle/service/audio/errors.h"
|
||||
|
||||
namespace AudioCore {
|
||||
|
||||
AudioManager::AudioManager() {
|
||||
AudioManager::AudioManager(Core::System& system_) : system{system_} {
|
||||
thread = std::jthread([this]() { ThreadFunc(); });
|
||||
}
|
||||
|
||||
@@ -26,7 +27,7 @@ Result AudioManager::SetOutManager(BufferEventFunc buffer_func) {
|
||||
|
||||
const auto index{events.GetManagerIndex(Event::Type::AudioOutManager)};
|
||||
if (buffer_events[index] == nullptr) {
|
||||
buffer_events[index] = std::move(buffer_func);
|
||||
buffer_events[index] = buffer_func;
|
||||
needs_update = true;
|
||||
events.SetAudioEvent(Event::Type::AudioOutManager, true);
|
||||
}
|
||||
@@ -42,7 +43,7 @@ Result AudioManager::SetInManager(BufferEventFunc buffer_func) {
|
||||
|
||||
const auto index{events.GetManagerIndex(Event::Type::AudioInManager)};
|
||||
if (buffer_events[index] == nullptr) {
|
||||
buffer_events[index] = std::move(buffer_func);
|
||||
buffer_events[index] = buffer_func;
|
||||
needs_update = true;
|
||||
events.SetAudioEvent(Event::Type::AudioInManager, true);
|
||||
}
|
||||
@@ -59,21 +60,19 @@ void AudioManager::ThreadFunc() {
|
||||
running = true;
|
||||
|
||||
while (running) {
|
||||
const auto timed_out{events.Wait(l, std::chrono::seconds(2))};
|
||||
auto timed_out{events.Wait(l, std::chrono::seconds(2))};
|
||||
|
||||
if (events.CheckAudioEventSet(Event::Type::Max)) {
|
||||
break;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < buffer_events.size(); i++) {
|
||||
const auto event_type = static_cast<Event::Type>(i);
|
||||
|
||||
if (events.CheckAudioEventSet(event_type) || timed_out) {
|
||||
if (events.CheckAudioEventSet(Event::Type(i)) || timed_out) {
|
||||
if (buffer_events[i]) {
|
||||
buffer_events[i]();
|
||||
}
|
||||
}
|
||||
events.SetAudioEvent(event_type, false);
|
||||
events.SetAudioEvent(Event::Type(i), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,11 +10,22 @@
|
||||
#include <thread>
|
||||
|
||||
#include "audio_core/audio_event.h"
|
||||
#include "core/hle/service/audio/errors.h"
|
||||
|
||||
union Result;
|
||||
namespace Core {
|
||||
class System;
|
||||
}
|
||||
|
||||
namespace AudioCore {
|
||||
|
||||
namespace AudioOut {
|
||||
class Manager;
|
||||
}
|
||||
|
||||
namespace AudioIn {
|
||||
class Manager;
|
||||
}
|
||||
|
||||
/**
|
||||
* The AudioManager's main purpose is to wait for buffer events for the audio in and out managers,
|
||||
* and call an associated callback to release buffers.
|
||||
@@ -32,7 +43,7 @@ class AudioManager {
|
||||
using BufferEventFunc = std::function<void()>;
|
||||
|
||||
public:
|
||||
explicit AudioManager();
|
||||
explicit AudioManager(Core::System& system);
|
||||
|
||||
/**
|
||||
* Shutdown the audio manager.
|
||||
@@ -69,6 +80,10 @@ private:
|
||||
*/
|
||||
void ThreadFunc();
|
||||
|
||||
/// Core system
|
||||
Core::System& system;
|
||||
/// Have sessions started palying?
|
||||
bool sessions_started{};
|
||||
/// Is the main thread running?
|
||||
std::atomic<bool> running{};
|
||||
/// Unused
|
||||
|
||||
@@ -47,7 +47,7 @@ RenderMessage AudioRenderer_Mailbox::ADSPWaitMessage() {
|
||||
return msg;
|
||||
}
|
||||
|
||||
CommandBuffer& AudioRenderer_Mailbox::GetCommandBuffer(const u32 session_id) {
|
||||
CommandBuffer& AudioRenderer_Mailbox::GetCommandBuffer(const s32 session_id) {
|
||||
return command_buffers[session_id];
|
||||
}
|
||||
|
||||
|
||||
@@ -83,7 +83,7 @@ public:
|
||||
* @param session_id - The session id to get (0 or 1).
|
||||
* @return The command buffer.
|
||||
*/
|
||||
CommandBuffer& GetCommandBuffer(u32 session_id);
|
||||
CommandBuffer& GetCommandBuffer(s32 session_id);
|
||||
|
||||
/**
|
||||
* Set the command buffer with the given session id (0 or 1).
|
||||
|
||||
@@ -214,13 +214,8 @@ void SinkStream::ProcessAudioOutAndRender(std::span<s16> output_buffer, std::siz
|
||||
// video play out without attempting to stall.
|
||||
// Can hopefully remove this later with a more complete NVDEC implementation.
|
||||
const auto nvdec_active{system.AudioCore().IsNVDECActive()};
|
||||
|
||||
// Core timing cannot be paused in single-core mode, so Stall ends up being called over and over
|
||||
// and never recovers to a normal state, so just skip attempting to sync things on single-core.
|
||||
if (system.IsMulticore() && !nvdec_active && queued_buffers > max_queue_size) {
|
||||
if (!nvdec_active && queued_buffers > max_queue_size) {
|
||||
Stall();
|
||||
} else if (system.IsMulticore() && queued_buffers <= max_queue_size) {
|
||||
Unstall();
|
||||
}
|
||||
|
||||
while (frames_written < num_frames) {
|
||||
@@ -260,7 +255,7 @@ void SinkStream::ProcessAudioOutAndRender(std::span<s16> output_buffer, std::siz
|
||||
std::memcpy(&last_frame[0], &output_buffer[(frames_written - 1) * frame_size],
|
||||
frame_size_bytes);
|
||||
|
||||
if (system.IsMulticore() && queued_buffers <= max_queue_size) {
|
||||
if (stalled && queued_buffers <= max_queue_size) {
|
||||
Unstall();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,32 @@ if (DEFINED ENV{DISPLAYVERSION})
|
||||
set(DISPLAY_VERSION $ENV{DISPLAYVERSION})
|
||||
endif ()
|
||||
|
||||
include(GenerateSCMRev)
|
||||
# Pass the path to git to the GenerateSCMRev.cmake as well
|
||||
find_package(Git QUIET)
|
||||
|
||||
add_custom_command(OUTPUT scm_rev.cpp
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
-DSRC_DIR=${PROJECT_SOURCE_DIR}
|
||||
-DBUILD_REPOSITORY=${BUILD_REPOSITORY}
|
||||
-DTITLE_BAR_FORMAT_IDLE=${TITLE_BAR_FORMAT_IDLE}
|
||||
-DTITLE_BAR_FORMAT_RUNNING=${TITLE_BAR_FORMAT_RUNNING}
|
||||
-DBUILD_TAG=${BUILD_TAG}
|
||||
-DBUILD_ID=${DISPLAY_VERSION}
|
||||
-DGIT_REF_SPEC=${GIT_REF_SPEC}
|
||||
-DGIT_REV=${GIT_REV}
|
||||
-DGIT_DESC=${GIT_DESC}
|
||||
-DGIT_BRANCH=${GIT_BRANCH}
|
||||
-DBUILD_FULLNAME=${BUILD_FULLNAME}
|
||||
-DGIT_EXECUTABLE=${GIT_EXECUTABLE}
|
||||
-P ${PROJECT_SOURCE_DIR}/CMakeModules/GenerateSCMRev.cmake
|
||||
DEPENDS
|
||||
# Check that the scm_rev files haven't changed
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/scm_rev.cpp.in"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/scm_rev.h"
|
||||
# technically we should regenerate if the git version changed, but its not worth the effort imo
|
||||
"${PROJECT_SOURCE_DIR}/CMakeModules/GenerateSCMRev.cmake"
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
add_library(common STATIC
|
||||
algorithm.h
|
||||
@@ -92,7 +117,7 @@ add_library(common STATIC
|
||||
quaternion.h
|
||||
reader_writer_queue.h
|
||||
ring_buffer.h
|
||||
${CMAKE_CURRENT_BINARY_DIR}/scm_rev.cpp
|
||||
scm_rev.cpp
|
||||
scm_rev.h
|
||||
scope_exit.h
|
||||
settings.cpp
|
||||
|
||||
@@ -531,7 +531,6 @@ struct Values {
|
||||
Setting<bool> use_auto_stub{false, "use_auto_stub"};
|
||||
Setting<bool> enable_all_controllers{false, "enable_all_controllers"};
|
||||
Setting<bool> create_crash_dumps{false, "create_crash_dumps"};
|
||||
Setting<bool> perform_vulkan_check{true, "perform_vulkan_check"};
|
||||
|
||||
// Miscellaneous
|
||||
Setting<std::string> log_filter{"*:Info", "log_filter"};
|
||||
|
||||
@@ -460,8 +460,6 @@ add_library(core STATIC
|
||||
hle/service/hid/controllers/mouse.h
|
||||
hle/service/hid/controllers/npad.cpp
|
||||
hle/service/hid/controllers/npad.h
|
||||
hle/service/hid/controllers/palma.cpp
|
||||
hle/service/hid/controllers/palma.h
|
||||
hle/service/hid/controllers/stubbed.cpp
|
||||
hle/service/hid/controllers/stubbed.h
|
||||
hle/service/hid/controllers/touchscreen.cpp
|
||||
|
||||
@@ -660,6 +660,7 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing
|
||||
ASSERT(false);
|
||||
break;
|
||||
case Core::HID::NpadStyleIndex::ProController:
|
||||
case Core::HID::NpadStyleIndex::Pokeball:
|
||||
set_motion_state(sixaxis_fullkey_state, motion_state[0]);
|
||||
break;
|
||||
case Core::HID::NpadStyleIndex::Handheld:
|
||||
@@ -675,11 +676,6 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing
|
||||
case Core::HID::NpadStyleIndex::JoyconRight:
|
||||
set_motion_state(sixaxis_right_lifo_state, motion_state[1]);
|
||||
break;
|
||||
case Core::HID::NpadStyleIndex::Pokeball:
|
||||
using namespace std::literals::chrono_literals;
|
||||
set_motion_state(sixaxis_fullkey_state, motion_state[0]);
|
||||
sixaxis_fullkey_state.delta_time = std::chrono::nanoseconds(15ms).count();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1,229 +0,0 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "core/core_timing.h"
|
||||
#include "core/hid/emulated_controller.h"
|
||||
#include "core/hid/hid_core.h"
|
||||
#include "core/hid/hid_types.h"
|
||||
#include "core/hle/kernel/k_event.h"
|
||||
#include "core/hle/kernel/k_readable_event.h"
|
||||
#include "core/hle/service/hid/controllers/palma.h"
|
||||
#include "core/hle/service/kernel_helpers.h"
|
||||
|
||||
namespace Service::HID {
|
||||
|
||||
Controller_Palma::Controller_Palma(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_,
|
||||
KernelHelpers::ServiceContext& service_context_)
|
||||
: ControllerBase{hid_core_}, service_context{service_context_} {
|
||||
controller = hid_core.GetEmulatedController(Core::HID::NpadIdType::Other);
|
||||
operation_complete_event = service_context.CreateEvent("hid:PalmaOperationCompleteEvent");
|
||||
}
|
||||
|
||||
Controller_Palma::~Controller_Palma() = default;
|
||||
|
||||
void Controller_Palma::OnInit() {}
|
||||
|
||||
void Controller_Palma::OnRelease() {}
|
||||
|
||||
void Controller_Palma::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
|
||||
if (!IsControllerActivated()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Result Controller_Palma::GetPalmaConnectionHandle(Core::HID::NpadIdType npad_id,
|
||||
PalmaConnectionHandle& handle) {
|
||||
active_handle.npad_id = npad_id;
|
||||
handle = active_handle;
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
Result Controller_Palma::InitializePalma(const PalmaConnectionHandle& handle) {
|
||||
if (handle.npad_id != active_handle.npad_id) {
|
||||
return InvalidPalmaHandle;
|
||||
}
|
||||
ActivateController();
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
Kernel::KReadableEvent& Controller_Palma::AcquirePalmaOperationCompleteEvent(
|
||||
const PalmaConnectionHandle& handle) const {
|
||||
if (handle.npad_id != active_handle.npad_id) {
|
||||
LOG_ERROR(Service_HID, "Invalid npad id {}", handle.npad_id);
|
||||
}
|
||||
return operation_complete_event->GetReadableEvent();
|
||||
}
|
||||
|
||||
Result Controller_Palma::GetPalmaOperationInfo(const PalmaConnectionHandle& handle,
|
||||
PalmaOperationType& operation_type,
|
||||
PalmaOperationData& data) const {
|
||||
if (handle.npad_id != active_handle.npad_id) {
|
||||
return InvalidPalmaHandle;
|
||||
}
|
||||
operation_type = operation.operation;
|
||||
data = operation.data;
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
Result Controller_Palma::PlayPalmaActivity(const PalmaConnectionHandle& handle,
|
||||
u64 palma_activity) {
|
||||
if (handle.npad_id != active_handle.npad_id) {
|
||||
return InvalidPalmaHandle;
|
||||
}
|
||||
operation.operation = PalmaOperationType::PlayActivity;
|
||||
operation.result = PalmaResultSuccess;
|
||||
operation.data = {};
|
||||
operation_complete_event->GetWritableEvent().Signal();
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
Result Controller_Palma::SetPalmaFrModeType(const PalmaConnectionHandle& handle,
|
||||
PalmaFrModeType fr_mode_) {
|
||||
if (handle.npad_id != active_handle.npad_id) {
|
||||
return InvalidPalmaHandle;
|
||||
}
|
||||
fr_mode = fr_mode_;
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
Result Controller_Palma::ReadPalmaStep(const PalmaConnectionHandle& handle) {
|
||||
if (handle.npad_id != active_handle.npad_id) {
|
||||
return InvalidPalmaHandle;
|
||||
}
|
||||
operation.operation = PalmaOperationType::ReadStep;
|
||||
operation.result = PalmaResultSuccess;
|
||||
operation.data = {};
|
||||
operation_complete_event->GetWritableEvent().Signal();
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
Result Controller_Palma::EnablePalmaStep(const PalmaConnectionHandle& handle, bool is_enabled) {
|
||||
if (handle.npad_id != active_handle.npad_id) {
|
||||
return InvalidPalmaHandle;
|
||||
}
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
Result Controller_Palma::ResetPalmaStep(const PalmaConnectionHandle& handle) {
|
||||
if (handle.npad_id != active_handle.npad_id) {
|
||||
return InvalidPalmaHandle;
|
||||
}
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
void Controller_Palma::ReadPalmaApplicationSection() {}
|
||||
|
||||
void Controller_Palma::WritePalmaApplicationSection() {}
|
||||
|
||||
Result Controller_Palma::ReadPalmaUniqueCode(const PalmaConnectionHandle& handle) {
|
||||
if (handle.npad_id != active_handle.npad_id) {
|
||||
return InvalidPalmaHandle;
|
||||
}
|
||||
operation.operation = PalmaOperationType::ReadUniqueCode;
|
||||
operation.result = PalmaResultSuccess;
|
||||
operation.data = {};
|
||||
operation_complete_event->GetWritableEvent().Signal();
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
Result Controller_Palma::SetPalmaUniqueCodeInvalid(const PalmaConnectionHandle& handle) {
|
||||
if (handle.npad_id != active_handle.npad_id) {
|
||||
return InvalidPalmaHandle;
|
||||
}
|
||||
operation.operation = PalmaOperationType::SetUniqueCodeInvalid;
|
||||
operation.result = PalmaResultSuccess;
|
||||
operation.data = {};
|
||||
operation_complete_event->GetWritableEvent().Signal();
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
void Controller_Palma::WritePalmaActivityEntry() {}
|
||||
|
||||
Result Controller_Palma::WritePalmaRgbLedPatternEntry(const PalmaConnectionHandle& handle,
|
||||
u64 unknown) {
|
||||
if (handle.npad_id != active_handle.npad_id) {
|
||||
return InvalidPalmaHandle;
|
||||
}
|
||||
operation.operation = PalmaOperationType::WriteRgbLedPatternEntry;
|
||||
operation.result = PalmaResultSuccess;
|
||||
operation.data = {};
|
||||
operation_complete_event->GetWritableEvent().Signal();
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
Result Controller_Palma::WritePalmaWaveEntry(const PalmaConnectionHandle& handle, PalmaWaveSet wave,
|
||||
u8* t_mem, u64 size) {
|
||||
if (handle.npad_id != active_handle.npad_id) {
|
||||
return InvalidPalmaHandle;
|
||||
}
|
||||
operation.operation = PalmaOperationType::WriteWaveEntry;
|
||||
operation.result = PalmaResultSuccess;
|
||||
operation.data = {};
|
||||
operation_complete_event->GetWritableEvent().Signal();
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
Result Controller_Palma::SetPalmaDataBaseIdentificationVersion(const PalmaConnectionHandle& handle,
|
||||
s32 database_id_version_) {
|
||||
if (handle.npad_id != active_handle.npad_id) {
|
||||
return InvalidPalmaHandle;
|
||||
}
|
||||
database_id_version = database_id_version_;
|
||||
operation.operation = PalmaOperationType::ReadDataBaseIdentificationVersion;
|
||||
operation.result = PalmaResultSuccess;
|
||||
operation.data[0] = {};
|
||||
operation_complete_event->GetWritableEvent().Signal();
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
Result Controller_Palma::GetPalmaDataBaseIdentificationVersion(
|
||||
const PalmaConnectionHandle& handle) {
|
||||
if (handle.npad_id != active_handle.npad_id) {
|
||||
return InvalidPalmaHandle;
|
||||
}
|
||||
operation.operation = PalmaOperationType::ReadDataBaseIdentificationVersion;
|
||||
operation.result = PalmaResultSuccess;
|
||||
operation.data = {};
|
||||
operation.data[0] = static_cast<u8>(database_id_version);
|
||||
operation_complete_event->GetWritableEvent().Signal();
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
void Controller_Palma::SuspendPalmaFeature() {}
|
||||
|
||||
Result Controller_Palma::GetPalmaOperationResult(const PalmaConnectionHandle& handle) const {
|
||||
if (handle.npad_id != active_handle.npad_id) {
|
||||
return InvalidPalmaHandle;
|
||||
}
|
||||
return operation.result;
|
||||
}
|
||||
void Controller_Palma::ReadPalmaPlayLog() {}
|
||||
|
||||
void Controller_Palma::ResetPalmaPlayLog() {}
|
||||
|
||||
void Controller_Palma::SetIsPalmaAllConnectable(bool is_all_connectable) {
|
||||
// If true controllers are able to be paired
|
||||
is_connectable = is_all_connectable;
|
||||
}
|
||||
|
||||
void Controller_Palma::SetIsPalmaPairedConnectable() {}
|
||||
|
||||
Result Controller_Palma::PairPalma(const PalmaConnectionHandle& handle) {
|
||||
if (handle.npad_id != active_handle.npad_id) {
|
||||
return InvalidPalmaHandle;
|
||||
}
|
||||
// TODO: Do something
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
void Controller_Palma::SetPalmaBoostMode(bool boost_mode) {}
|
||||
|
||||
void Controller_Palma::CancelWritePalmaWaveEntry() {}
|
||||
|
||||
void Controller_Palma::EnablePalmaBoostMode() {}
|
||||
|
||||
void Controller_Palma::GetPalmaBluetoothAddress() {}
|
||||
|
||||
void Controller_Palma::SetDisallowedPalmaConnection() {}
|
||||
|
||||
} // namespace Service::HID
|
||||
@@ -1,163 +0,0 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include "common/common_funcs.h"
|
||||
#include "common/common_types.h"
|
||||
#include "core/hle/service/hid/controllers/controller_base.h"
|
||||
#include "core/hle/service/hid/errors.h"
|
||||
|
||||
namespace Kernel {
|
||||
class KEvent;
|
||||
class KReadableEvent;
|
||||
} // namespace Kernel
|
||||
|
||||
namespace Service::KernelHelpers {
|
||||
class ServiceContext;
|
||||
}
|
||||
|
||||
namespace Core::HID {
|
||||
class EmulatedController;
|
||||
} // namespace Core::HID
|
||||
|
||||
namespace Service::HID {
|
||||
class Controller_Palma final : public ControllerBase {
|
||||
public:
|
||||
using PalmaOperationData = std::array<u8, 0x140>;
|
||||
|
||||
// This is nn::hid::PalmaOperationType
|
||||
enum class PalmaOperationType {
|
||||
PlayActivity,
|
||||
SetFrModeType,
|
||||
ReadStep,
|
||||
EnableStep,
|
||||
ResetStep,
|
||||
ReadApplicationSection,
|
||||
WriteApplicationSection,
|
||||
ReadUniqueCode,
|
||||
SetUniqueCodeInvalid,
|
||||
WriteActivityEntry,
|
||||
WriteRgbLedPatternEntry,
|
||||
WriteWaveEntry,
|
||||
ReadDataBaseIdentificationVersion,
|
||||
WriteDataBaseIdentificationVersion,
|
||||
SuspendFeature,
|
||||
ReadPlayLog,
|
||||
ResetPlayLog,
|
||||
};
|
||||
|
||||
// This is nn::hid::PalmaWaveSet
|
||||
enum class PalmaWaveSet : u64 {
|
||||
Small,
|
||||
Medium,
|
||||
Large,
|
||||
};
|
||||
|
||||
// This is nn::hid::PalmaFrModeType
|
||||
enum class PalmaFrModeType : u64 {
|
||||
Off,
|
||||
B01,
|
||||
B02,
|
||||
B03,
|
||||
Downloaded,
|
||||
};
|
||||
|
||||
// This is nn::hid::PalmaFeature
|
||||
enum class PalmaFeature : u64 {
|
||||
FrMode,
|
||||
RumbleFeedback,
|
||||
Step,
|
||||
MuteSwitch,
|
||||
};
|
||||
|
||||
// This is nn::hid::PalmaOperationInfo
|
||||
struct PalmaOperationInfo {
|
||||
PalmaOperationType operation{};
|
||||
Result result{PalmaResultSuccess};
|
||||
PalmaOperationData data{};
|
||||
};
|
||||
static_assert(sizeof(PalmaOperationInfo) == 0x148, "PalmaOperationInfo is an invalid size");
|
||||
|
||||
// This is nn::hid::PalmaActivityEntry
|
||||
struct PalmaActivityEntry {
|
||||
u32 rgb_led_pattern_index;
|
||||
INSERT_PADDING_BYTES(2);
|
||||
PalmaWaveSet wave_set;
|
||||
u32 wave_index;
|
||||
INSERT_PADDING_BYTES(12);
|
||||
};
|
||||
static_assert(sizeof(PalmaActivityEntry) == 0x20, "PalmaActivityEntry is an invalid size");
|
||||
|
||||
struct PalmaConnectionHandle {
|
||||
Core::HID::NpadIdType npad_id;
|
||||
INSERT_PADDING_BYTES(4); // Unknown
|
||||
};
|
||||
static_assert(sizeof(PalmaConnectionHandle) == 0x8,
|
||||
"PalmaConnectionHandle has incorrect size.");
|
||||
|
||||
explicit Controller_Palma(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_,
|
||||
KernelHelpers::ServiceContext& service_context_);
|
||||
~Controller_Palma() override;
|
||||
|
||||
// Called when the controller is initialized
|
||||
void OnInit() override;
|
||||
|
||||
// When the controller is released
|
||||
void OnRelease() override;
|
||||
|
||||
// When the controller is requesting an update for the shared memory
|
||||
void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
|
||||
|
||||
Result GetPalmaConnectionHandle(Core::HID::NpadIdType npad_id, PalmaConnectionHandle& handle);
|
||||
Result InitializePalma(const PalmaConnectionHandle& handle);
|
||||
Kernel::KReadableEvent& AcquirePalmaOperationCompleteEvent(
|
||||
const PalmaConnectionHandle& handle) const;
|
||||
Result GetPalmaOperationInfo(const PalmaConnectionHandle& handle,
|
||||
PalmaOperationType& operation_type,
|
||||
PalmaOperationData& data) const;
|
||||
Result PlayPalmaActivity(const PalmaConnectionHandle& handle, u64 palma_activity);
|
||||
Result SetPalmaFrModeType(const PalmaConnectionHandle& handle, PalmaFrModeType fr_mode_);
|
||||
Result ReadPalmaStep(const PalmaConnectionHandle& handle);
|
||||
Result EnablePalmaStep(const PalmaConnectionHandle& handle, bool is_enabled);
|
||||
Result ResetPalmaStep(const PalmaConnectionHandle& handle);
|
||||
Result ReadPalmaUniqueCode(const PalmaConnectionHandle& handle);
|
||||
Result SetPalmaUniqueCodeInvalid(const PalmaConnectionHandle& handle);
|
||||
Result WritePalmaRgbLedPatternEntry(const PalmaConnectionHandle& handle, u64 unknown);
|
||||
Result WritePalmaWaveEntry(const PalmaConnectionHandle& handle, PalmaWaveSet wave, u8* t_mem,
|
||||
u64 size);
|
||||
Result SetPalmaDataBaseIdentificationVersion(const PalmaConnectionHandle& handle,
|
||||
s32 database_id_version_);
|
||||
Result GetPalmaDataBaseIdentificationVersion(const PalmaConnectionHandle& handle);
|
||||
Result GetPalmaOperationResult(const PalmaConnectionHandle& handle) const;
|
||||
void SetIsPalmaAllConnectable(bool is_all_connectable);
|
||||
Result PairPalma(const PalmaConnectionHandle& handle);
|
||||
void SetPalmaBoostMode(bool boost_mode);
|
||||
|
||||
private:
|
||||
void ReadPalmaApplicationSection();
|
||||
void WritePalmaApplicationSection();
|
||||
void WritePalmaActivityEntry();
|
||||
void SuspendPalmaFeature();
|
||||
void ReadPalmaPlayLog();
|
||||
void ResetPalmaPlayLog();
|
||||
void SetIsPalmaPairedConnectable();
|
||||
void CancelWritePalmaWaveEntry();
|
||||
void EnablePalmaBoostMode();
|
||||
void GetPalmaBluetoothAddress();
|
||||
void SetDisallowedPalmaConnection();
|
||||
|
||||
bool is_connectable{};
|
||||
s32 database_id_version{};
|
||||
PalmaOperationInfo operation{};
|
||||
PalmaFrModeType fr_mode{};
|
||||
PalmaConnectionHandle active_handle{};
|
||||
|
||||
Core::HID::EmulatedController* controller;
|
||||
|
||||
Kernel::KEvent* operation_complete_event;
|
||||
KernelHelpers::ServiceContext& service_context;
|
||||
};
|
||||
|
||||
} // namespace Service::HID
|
||||
@@ -7,7 +7,6 @@
|
||||
|
||||
namespace Service::HID {
|
||||
|
||||
constexpr Result PalmaResultSuccess{ErrorModule::HID, 0};
|
||||
constexpr Result NpadInvalidHandle{ErrorModule::HID, 100};
|
||||
constexpr Result NpadDeviceIndexOutOfRange{ErrorModule::HID, 107};
|
||||
constexpr Result VibrationInvalidStyleIndex{ErrorModule::HID, 122};
|
||||
@@ -18,7 +17,6 @@ constexpr Result NpadIsDualJoycon{ErrorModule::HID, 601};
|
||||
constexpr Result NpadIsSameType{ErrorModule::HID, 602};
|
||||
constexpr Result InvalidNpadId{ErrorModule::HID, 709};
|
||||
constexpr Result NpadNotConnected{ErrorModule::HID, 710};
|
||||
constexpr Result InvalidPalmaHandle{ErrorModule::HID, 3302};
|
||||
|
||||
} // namespace Service::HID
|
||||
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
#include "core/hle/service/hid/controllers/keyboard.h"
|
||||
#include "core/hle/service/hid/controllers/mouse.h"
|
||||
#include "core/hle/service/hid/controllers/npad.h"
|
||||
#include "core/hle/service/hid/controllers/palma.h"
|
||||
#include "core/hle/service/hid/controllers/stubbed.h"
|
||||
#include "core/hle/service/hid/controllers/touchscreen.h"
|
||||
#include "core/hle/service/hid/controllers/xpad.h"
|
||||
@@ -61,7 +60,6 @@ IAppletResource::IAppletResource(Core::System& system_,
|
||||
MakeControllerWithServiceContext<Controller_NPad>(HidController::NPad, shared_memory);
|
||||
MakeController<Controller_Gesture>(HidController::Gesture, shared_memory);
|
||||
MakeController<Controller_ConsoleSixAxis>(HidController::ConsoleSixAxisSensor, shared_memory);
|
||||
MakeControllerWithServiceContext<Controller_Palma>(HidController::Palma, shared_memory);
|
||||
|
||||
// Homebrew doesn't try to activate some controllers, so we activate them by default
|
||||
GetController<Controller_NPad>(HidController::NPad).ActivateController();
|
||||
@@ -312,36 +310,36 @@ Hid::Hid(Core::System& system_)
|
||||
{406, nullptr, "GetNpadLeftRightInterfaceType"},
|
||||
{407, nullptr, "GetNpadOfHighestBatteryLevel"},
|
||||
{408, nullptr, "GetNpadOfHighestBatteryLevelForJoyRight"},
|
||||
{500, &Hid::GetPalmaConnectionHandle, "GetPalmaConnectionHandle"},
|
||||
{501, &Hid::InitializePalma, "InitializePalma"},
|
||||
{502, &Hid::AcquirePalmaOperationCompleteEvent, "AcquirePalmaOperationCompleteEvent"},
|
||||
{503, &Hid::GetPalmaOperationInfo, "GetPalmaOperationInfo"},
|
||||
{504, &Hid::PlayPalmaActivity, "PlayPalmaActivity"},
|
||||
{505, &Hid::SetPalmaFrModeType, "SetPalmaFrModeType"},
|
||||
{506, &Hid::ReadPalmaStep, "ReadPalmaStep"},
|
||||
{507, &Hid::EnablePalmaStep, "EnablePalmaStep"},
|
||||
{508, &Hid::ResetPalmaStep, "ResetPalmaStep"},
|
||||
{509, &Hid::ReadPalmaApplicationSection, "ReadPalmaApplicationSection"},
|
||||
{510, &Hid::WritePalmaApplicationSection, "WritePalmaApplicationSection"},
|
||||
{511, &Hid::ReadPalmaUniqueCode, "ReadPalmaUniqueCode"},
|
||||
{512, &Hid::SetPalmaUniqueCodeInvalid, "SetPalmaUniqueCodeInvalid"},
|
||||
{513, &Hid::WritePalmaActivityEntry, "WritePalmaActivityEntry"},
|
||||
{514, &Hid::WritePalmaRgbLedPatternEntry, "WritePalmaRgbLedPatternEntry"},
|
||||
{515, &Hid::WritePalmaWaveEntry, "WritePalmaWaveEntry"},
|
||||
{516, &Hid::SetPalmaDataBaseIdentificationVersion, "SetPalmaDataBaseIdentificationVersion"},
|
||||
{517, &Hid::GetPalmaDataBaseIdentificationVersion, "GetPalmaDataBaseIdentificationVersion"},
|
||||
{518, &Hid::SuspendPalmaFeature, "SuspendPalmaFeature"},
|
||||
{519, &Hid::GetPalmaOperationResult, "GetPalmaOperationResult"},
|
||||
{520, &Hid::ReadPalmaPlayLog, "ReadPalmaPlayLog"},
|
||||
{521, &Hid::ResetPalmaPlayLog, "ResetPalmaPlayLog"},
|
||||
{500, nullptr, "GetPalmaConnectionHandle"},
|
||||
{501, nullptr, "InitializePalma"},
|
||||
{502, nullptr, "AcquirePalmaOperationCompleteEvent"},
|
||||
{503, nullptr, "GetPalmaOperationInfo"},
|
||||
{504, nullptr, "PlayPalmaActivity"},
|
||||
{505, nullptr, "SetPalmaFrModeType"},
|
||||
{506, nullptr, "ReadPalmaStep"},
|
||||
{507, nullptr, "EnablePalmaStep"},
|
||||
{508, nullptr, "ResetPalmaStep"},
|
||||
{509, nullptr, "ReadPalmaApplicationSection"},
|
||||
{510, nullptr, "WritePalmaApplicationSection"},
|
||||
{511, nullptr, "ReadPalmaUniqueCode"},
|
||||
{512, nullptr, "SetPalmaUniqueCodeInvalid"},
|
||||
{513, nullptr, "WritePalmaActivityEntry"},
|
||||
{514, nullptr, "WritePalmaRgbLedPatternEntry"},
|
||||
{515, nullptr, "WritePalmaWaveEntry"},
|
||||
{516, nullptr, "SetPalmaDataBaseIdentificationVersion"},
|
||||
{517, nullptr, "GetPalmaDataBaseIdentificationVersion"},
|
||||
{518, nullptr, "SuspendPalmaFeature"},
|
||||
{519, nullptr, "GetPalmaOperationResult"},
|
||||
{520, nullptr, "ReadPalmaPlayLog"},
|
||||
{521, nullptr, "ResetPalmaPlayLog"},
|
||||
{522, &Hid::SetIsPalmaAllConnectable, "SetIsPalmaAllConnectable"},
|
||||
{523, &Hid::SetIsPalmaPairedConnectable, "SetIsPalmaPairedConnectable"},
|
||||
{524, &Hid::PairPalma, "PairPalma"},
|
||||
{523, nullptr, "SetIsPalmaPairedConnectable"},
|
||||
{524, nullptr, "PairPalma"},
|
||||
{525, &Hid::SetPalmaBoostMode, "SetPalmaBoostMode"},
|
||||
{526, &Hid::CancelWritePalmaWaveEntry, "CancelWritePalmaWaveEntry"},
|
||||
{527, &Hid::EnablePalmaBoostMode, "EnablePalmaBoostMode"},
|
||||
{528, &Hid::GetPalmaBluetoothAddress, "GetPalmaBluetoothAddress"},
|
||||
{529, &Hid::SetDisallowedPalmaConnection, "SetDisallowedPalmaConnection"},
|
||||
{526, nullptr, "CancelWritePalmaWaveEntry"},
|
||||
{527, nullptr, "EnablePalmaBoostMode"},
|
||||
{528, nullptr, "GetPalmaBluetoothAddress"},
|
||||
{529, nullptr, "SetDisallowedPalmaConnection"},
|
||||
{1000, &Hid::SetNpadCommunicationMode, "SetNpadCommunicationMode"},
|
||||
{1001, &Hid::GetNpadCommunicationMode, "GetNpadCommunicationMode"},
|
||||
{1002, &Hid::SetTouchScreenConfiguration, "SetTouchScreenConfiguration"},
|
||||
@@ -1880,361 +1878,14 @@ void Hid::IsUsbFullKeyControllerEnabled(Kernel::HLERequestContext& ctx) {
|
||||
rb.Push(false);
|
||||
}
|
||||
|
||||
void Hid::GetPalmaConnectionHandle(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
struct Parameters {
|
||||
Core::HID::NpadIdType npad_id;
|
||||
INSERT_PADDING_WORDS_NOINIT(1);
|
||||
u64 applet_resource_user_id;
|
||||
};
|
||||
static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
|
||||
|
||||
const auto parameters{rp.PopRaw<Parameters>()};
|
||||
|
||||
LOG_WARNING(Service_HID, "(STUBBED) called, npad_id={}, applet_resource_user_id={}",
|
||||
parameters.npad_id, parameters.applet_resource_user_id);
|
||||
|
||||
Controller_Palma::PalmaConnectionHandle handle;
|
||||
auto& controller = GetAppletResource()->GetController<Controller_Palma>(HidController::Palma);
|
||||
const auto result = controller.GetPalmaConnectionHandle(parameters.npad_id, handle);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 4};
|
||||
rb.Push(result);
|
||||
rb.PushRaw(handle);
|
||||
}
|
||||
|
||||
void Hid::InitializePalma(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
|
||||
|
||||
LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id);
|
||||
|
||||
auto& controller = GetAppletResource()->GetController<Controller_Palma>(HidController::Palma);
|
||||
const auto result = controller.InitializePalma(connection_handle);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(result);
|
||||
}
|
||||
|
||||
void Hid::AcquirePalmaOperationCompleteEvent(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
|
||||
|
||||
LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id);
|
||||
|
||||
auto& controller = GetAppletResource()->GetController<Controller_Palma>(HidController::Palma);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2, 1};
|
||||
rb.Push(ResultSuccess);
|
||||
rb.PushCopyObjects(controller.AcquirePalmaOperationCompleteEvent(connection_handle));
|
||||
}
|
||||
|
||||
void Hid::GetPalmaOperationInfo(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
|
||||
|
||||
LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id);
|
||||
|
||||
Controller_Palma::PalmaOperationType operation_type;
|
||||
Controller_Palma::PalmaOperationData data;
|
||||
auto& controller = GetAppletResource()->GetController<Controller_Palma>(HidController::Palma);
|
||||
const auto result = controller.GetPalmaOperationInfo(connection_handle, operation_type, data);
|
||||
|
||||
if (result.IsError()) {
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(result);
|
||||
}
|
||||
|
||||
ctx.WriteBuffer(data);
|
||||
IPC::ResponseBuilder rb{ctx, 4};
|
||||
rb.Push(result);
|
||||
rb.Push(static_cast<u64>(operation_type));
|
||||
}
|
||||
|
||||
void Hid::PlayPalmaActivity(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
|
||||
const auto palma_activity{rp.Pop<u64>()};
|
||||
|
||||
LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}, palma_activity={}",
|
||||
connection_handle.npad_id, palma_activity);
|
||||
|
||||
auto& controller = GetAppletResource()->GetController<Controller_Palma>(HidController::Palma);
|
||||
const auto result = controller.PlayPalmaActivity(connection_handle, palma_activity);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(result);
|
||||
}
|
||||
|
||||
void Hid::SetPalmaFrModeType(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
|
||||
const auto fr_mode{rp.PopEnum<Controller_Palma::PalmaFrModeType>()};
|
||||
|
||||
LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}, fr_mode={}",
|
||||
connection_handle.npad_id, fr_mode);
|
||||
|
||||
auto& controller = GetAppletResource()->GetController<Controller_Palma>(HidController::Palma);
|
||||
const auto result = controller.SetPalmaFrModeType(connection_handle, fr_mode);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(result);
|
||||
}
|
||||
|
||||
void Hid::ReadPalmaStep(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
|
||||
|
||||
LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id);
|
||||
|
||||
auto& controller = GetAppletResource()->GetController<Controller_Palma>(HidController::Palma);
|
||||
const auto result = controller.ReadPalmaStep(connection_handle);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(result);
|
||||
}
|
||||
|
||||
void Hid::EnablePalmaStep(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
struct Parameters {
|
||||
bool is_enabled;
|
||||
INSERT_PADDING_WORDS_NOINIT(1);
|
||||
Controller_Palma::PalmaConnectionHandle connection_handle;
|
||||
};
|
||||
static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
|
||||
|
||||
const auto parameters{rp.PopRaw<Parameters>()};
|
||||
|
||||
LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}, is_enabled={}",
|
||||
parameters.connection_handle.npad_id, parameters.is_enabled);
|
||||
|
||||
auto& controller = GetAppletResource()->GetController<Controller_Palma>(HidController::Palma);
|
||||
const auto result =
|
||||
controller.EnablePalmaStep(parameters.connection_handle, parameters.is_enabled);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(result);
|
||||
}
|
||||
|
||||
void Hid::ResetPalmaStep(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
|
||||
|
||||
LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id);
|
||||
|
||||
auto& controller = GetAppletResource()->GetController<Controller_Palma>(HidController::Palma);
|
||||
const auto result = controller.ResetPalmaStep(connection_handle);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(result);
|
||||
}
|
||||
|
||||
void Hid::ReadPalmaApplicationSection(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_HID, "(STUBBED) called");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ResultSuccess);
|
||||
}
|
||||
|
||||
void Hid::WritePalmaApplicationSection(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_HID, "(STUBBED) called");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ResultSuccess);
|
||||
}
|
||||
|
||||
void Hid::ReadPalmaUniqueCode(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
|
||||
|
||||
LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id);
|
||||
|
||||
applet_resource->GetController<Controller_Palma>(HidController::Palma)
|
||||
.ReadPalmaUniqueCode(connection_handle);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ResultSuccess);
|
||||
}
|
||||
|
||||
void Hid::SetPalmaUniqueCodeInvalid(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
|
||||
|
||||
LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id);
|
||||
|
||||
applet_resource->GetController<Controller_Palma>(HidController::Palma)
|
||||
.SetPalmaUniqueCodeInvalid(connection_handle);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ResultSuccess);
|
||||
}
|
||||
|
||||
void Hid::WritePalmaActivityEntry(Kernel::HLERequestContext& ctx) {
|
||||
LOG_CRITICAL(Service_HID, "(STUBBED) called");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ResultSuccess);
|
||||
}
|
||||
|
||||
void Hid::WritePalmaRgbLedPatternEntry(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
|
||||
const auto unknown{rp.Pop<u64>()};
|
||||
|
||||
const auto buffer = ctx.ReadBuffer();
|
||||
|
||||
LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}, unknown={}",
|
||||
connection_handle.npad_id, unknown);
|
||||
|
||||
applet_resource->GetController<Controller_Palma>(HidController::Palma)
|
||||
.WritePalmaRgbLedPatternEntry(connection_handle, unknown);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ResultSuccess);
|
||||
}
|
||||
|
||||
void Hid::WritePalmaWaveEntry(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
|
||||
const auto wave_set{rp.PopEnum<Controller_Palma::PalmaWaveSet>()};
|
||||
const auto unknown{rp.Pop<u64>()};
|
||||
const auto t_mem_size{rp.Pop<u64>()};
|
||||
const auto t_mem_handle{ctx.GetCopyHandle(0)};
|
||||
const auto size{rp.Pop<u64>()};
|
||||
|
||||
ASSERT_MSG(t_mem_size == 0x3000, "t_mem_size is not 0x3000 bytes");
|
||||
|
||||
auto t_mem =
|
||||
system.CurrentProcess()->GetHandleTable().GetObject<Kernel::KTransferMemory>(t_mem_handle);
|
||||
|
||||
if (t_mem.IsNull()) {
|
||||
LOG_ERROR(Service_HID, "t_mem is a nullptr for handle=0x{:08X}", t_mem_handle);
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ResultUnknown);
|
||||
return;
|
||||
}
|
||||
|
||||
ASSERT_MSG(t_mem->GetSize() == 0x3000, "t_mem has incorrect size");
|
||||
|
||||
LOG_WARNING(Service_HID,
|
||||
"(STUBBED) called, connection_handle={}, wave_set={}, unkown={}, "
|
||||
"t_mem_handle=0x{:08X}, t_mem_size={}, size={}",
|
||||
connection_handle.npad_id, wave_set, unknown, t_mem_handle, t_mem_size, size);
|
||||
|
||||
applet_resource->GetController<Controller_Palma>(HidController::Palma)
|
||||
.WritePalmaWaveEntry(connection_handle, wave_set,
|
||||
system.Memory().GetPointer(t_mem->GetSourceAddress()), t_mem_size);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ResultSuccess);
|
||||
}
|
||||
|
||||
void Hid::SetPalmaDataBaseIdentificationVersion(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
struct Parameters {
|
||||
s32 database_id_version;
|
||||
INSERT_PADDING_WORDS_NOINIT(1);
|
||||
Controller_Palma::PalmaConnectionHandle connection_handle;
|
||||
};
|
||||
static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
|
||||
|
||||
const auto parameters{rp.PopRaw<Parameters>()};
|
||||
|
||||
LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}, database_id_version={}",
|
||||
parameters.connection_handle.npad_id, parameters.database_id_version);
|
||||
|
||||
applet_resource->GetController<Controller_Palma>(HidController::Palma)
|
||||
.SetPalmaDataBaseIdentificationVersion(parameters.connection_handle,
|
||||
parameters.database_id_version);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ResultSuccess);
|
||||
}
|
||||
|
||||
void Hid::GetPalmaDataBaseIdentificationVersion(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
|
||||
|
||||
LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id);
|
||||
|
||||
applet_resource->GetController<Controller_Palma>(HidController::Palma)
|
||||
.GetPalmaDataBaseIdentificationVersion(connection_handle);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ResultSuccess);
|
||||
}
|
||||
|
||||
void Hid::SuspendPalmaFeature(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_HID, "(STUBBED) called");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ResultSuccess);
|
||||
}
|
||||
|
||||
void Hid::GetPalmaOperationResult(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
|
||||
|
||||
LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id);
|
||||
|
||||
const auto result = applet_resource->GetController<Controller_Palma>(HidController::Palma)
|
||||
.GetPalmaOperationResult(connection_handle);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(result);
|
||||
}
|
||||
|
||||
void Hid::ReadPalmaPlayLog(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_HID, "(STUBBED) called");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ResultSuccess);
|
||||
}
|
||||
|
||||
void Hid::ResetPalmaPlayLog(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_HID, "(STUBBED) called");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ResultSuccess);
|
||||
}
|
||||
|
||||
void Hid::SetIsPalmaAllConnectable(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
struct Parameters {
|
||||
bool is_palma_all_connectable;
|
||||
INSERT_PADDING_BYTES_NOINIT(7);
|
||||
u64 applet_resource_user_id;
|
||||
};
|
||||
static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
|
||||
|
||||
const auto parameters{rp.PopRaw<Parameters>()};
|
||||
const auto applet_resource_user_id{rp.Pop<u64>()};
|
||||
const auto is_palma_all_connectable{rp.Pop<bool>()};
|
||||
|
||||
LOG_WARNING(Service_HID,
|
||||
"(STUBBED) called, is_palma_all_connectable={},applet_resource_user_id={}",
|
||||
parameters.is_palma_all_connectable, parameters.applet_resource_user_id);
|
||||
|
||||
applet_resource->GetController<Controller_Palma>(HidController::Palma)
|
||||
.SetIsPalmaAllConnectable(parameters.is_palma_all_connectable);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ResultSuccess);
|
||||
}
|
||||
|
||||
void Hid::SetIsPalmaPairedConnectable(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_HID, "(STUBBED) called");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ResultSuccess);
|
||||
}
|
||||
|
||||
void Hid::PairPalma(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
|
||||
|
||||
LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id);
|
||||
|
||||
applet_resource->GetController<Controller_Palma>(HidController::Palma)
|
||||
.PairPalma(connection_handle);
|
||||
"(STUBBED) called, applet_resource_user_id={}, is_palma_all_connectable={}",
|
||||
applet_resource_user_id, is_palma_all_connectable);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ResultSuccess);
|
||||
@@ -2246,37 +1897,6 @@ void Hid::SetPalmaBoostMode(Kernel::HLERequestContext& ctx) {
|
||||
|
||||
LOG_WARNING(Service_HID, "(STUBBED) called, palma_boost_mode={}", palma_boost_mode);
|
||||
|
||||
applet_resource->GetController<Controller_Palma>(HidController::Palma)
|
||||
.SetPalmaBoostMode(palma_boost_mode);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ResultSuccess);
|
||||
}
|
||||
|
||||
void Hid::CancelWritePalmaWaveEntry(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_HID, "(STUBBED) called");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ResultSuccess);
|
||||
}
|
||||
|
||||
void Hid::EnablePalmaBoostMode(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_HID, "(STUBBED) called");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ResultSuccess);
|
||||
}
|
||||
|
||||
void Hid::GetPalmaBluetoothAddress(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_HID, "(STUBBED) called");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ResultSuccess);
|
||||
}
|
||||
|
||||
void Hid::SetDisallowedPalmaConnection(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_HID, "(STUBBED) called");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ResultSuccess);
|
||||
}
|
||||
|
||||
@@ -33,7 +33,6 @@ enum class HidController : std::size_t {
|
||||
NPad,
|
||||
Gesture,
|
||||
ConsoleSixAxisSensor,
|
||||
Palma,
|
||||
|
||||
MaxControllers,
|
||||
};
|
||||
@@ -167,36 +166,8 @@ private:
|
||||
void FinalizeSevenSixAxisSensor(Kernel::HLERequestContext& ctx);
|
||||
void ResetSevenSixAxisSensorTimestamp(Kernel::HLERequestContext& ctx);
|
||||
void IsUsbFullKeyControllerEnabled(Kernel::HLERequestContext& ctx);
|
||||
void GetPalmaConnectionHandle(Kernel::HLERequestContext& ctx);
|
||||
void InitializePalma(Kernel::HLERequestContext& ctx);
|
||||
void AcquirePalmaOperationCompleteEvent(Kernel::HLERequestContext& ctx);
|
||||
void GetPalmaOperationInfo(Kernel::HLERequestContext& ctx);
|
||||
void PlayPalmaActivity(Kernel::HLERequestContext& ctx);
|
||||
void SetPalmaFrModeType(Kernel::HLERequestContext& ctx);
|
||||
void ReadPalmaStep(Kernel::HLERequestContext& ctx);
|
||||
void EnablePalmaStep(Kernel::HLERequestContext& ctx);
|
||||
void ResetPalmaStep(Kernel::HLERequestContext& ctx);
|
||||
void ReadPalmaApplicationSection(Kernel::HLERequestContext& ctx);
|
||||
void WritePalmaApplicationSection(Kernel::HLERequestContext& ctx);
|
||||
void ReadPalmaUniqueCode(Kernel::HLERequestContext& ctx);
|
||||
void SetPalmaUniqueCodeInvalid(Kernel::HLERequestContext& ctx);
|
||||
void WritePalmaActivityEntry(Kernel::HLERequestContext& ctx);
|
||||
void WritePalmaRgbLedPatternEntry(Kernel::HLERequestContext& ctx);
|
||||
void WritePalmaWaveEntry(Kernel::HLERequestContext& ctx);
|
||||
void SetPalmaDataBaseIdentificationVersion(Kernel::HLERequestContext& ctx);
|
||||
void GetPalmaDataBaseIdentificationVersion(Kernel::HLERequestContext& ctx);
|
||||
void SuspendPalmaFeature(Kernel::HLERequestContext& ctx);
|
||||
void GetPalmaOperationResult(Kernel::HLERequestContext& ctx);
|
||||
void ReadPalmaPlayLog(Kernel::HLERequestContext& ctx);
|
||||
void ResetPalmaPlayLog(Kernel::HLERequestContext& ctx);
|
||||
void SetIsPalmaAllConnectable(Kernel::HLERequestContext& ctx);
|
||||
void SetIsPalmaPairedConnectable(Kernel::HLERequestContext& ctx);
|
||||
void PairPalma(Kernel::HLERequestContext& ctx);
|
||||
void SetPalmaBoostMode(Kernel::HLERequestContext& ctx);
|
||||
void CancelWritePalmaWaveEntry(Kernel::HLERequestContext& ctx);
|
||||
void EnablePalmaBoostMode(Kernel::HLERequestContext& ctx);
|
||||
void GetPalmaBluetoothAddress(Kernel::HLERequestContext& ctx);
|
||||
void SetDisallowedPalmaConnection(Kernel::HLERequestContext& ctx);
|
||||
void SetNpadCommunicationMode(Kernel::HLERequestContext& ctx);
|
||||
void GetNpadCommunicationMode(Kernel::HLERequestContext& ctx);
|
||||
void SetTouchScreenConfiguration(Kernel::HLERequestContext& ctx);
|
||||
|
||||
@@ -542,8 +542,7 @@ Result IRS::IsIrCameraHandleValid(const Core::IrSensor::IrCameraHandle& camera_h
|
||||
|
||||
Core::IrSensor::DeviceFormat& IRS::GetIrCameraSharedMemoryDeviceEntry(
|
||||
const Core::IrSensor::IrCameraHandle& camera_handle) {
|
||||
const auto npad_id_max_index = static_cast<u8>(sizeof(StatusManager::device));
|
||||
ASSERT_MSG(camera_handle.npad_id < npad_id_max_index, "invalid npad_id");
|
||||
ASSERT_MSG(sizeof(StatusManager::device) > camera_handle.npad_id, "invalid npad_id");
|
||||
return shared_memory->device[camera_handle.npad_id];
|
||||
}
|
||||
|
||||
|
||||
@@ -800,12 +800,12 @@ Result Module::Interface::Flush() {
|
||||
|
||||
// Return to the start of the file
|
||||
if (!amiibo_file.Seek(0)) {
|
||||
LOG_ERROR(Service_NFP, "Error writing to file");
|
||||
LOG_ERROR(Service_NFP, "Error writting to file");
|
||||
return ErrCodes::WriteAmiiboFailed;
|
||||
}
|
||||
|
||||
if (!amiibo_file.Write(encrypted_tag_data)) {
|
||||
LOG_ERROR(Service_NFP, "Error writing to file");
|
||||
LOG_ERROR(Service_NFP, "Error writting to file");
|
||||
return ErrCodes::WriteAmiiboFailed;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "core/hle/service/nvflinger/ui/graphic_buffer.h"
|
||||
#include "core/hle/service/vi/display/vi_display.h"
|
||||
#include "core/hle/service/vi/layer/vi_layer.h"
|
||||
#include "core/hle/service/vi/vi_results.h"
|
||||
#include "video_core/gpu.h"
|
||||
|
||||
namespace Service::NVFlinger {
|
||||
@@ -163,15 +164,15 @@ std::optional<u32> NVFlinger::FindBufferQueueId(u64 display_id, u64 layer_id) {
|
||||
return layer->GetBinderId();
|
||||
}
|
||||
|
||||
Kernel::KReadableEvent* NVFlinger::FindVsyncEvent(u64 display_id) {
|
||||
ResultVal<Kernel::KReadableEvent*> NVFlinger::FindVsyncEvent(u64 display_id) {
|
||||
const auto lock_guard = Lock();
|
||||
auto* const display = FindDisplay(display_id);
|
||||
|
||||
if (display == nullptr) {
|
||||
return nullptr;
|
||||
return VI::ResultNotFound;
|
||||
}
|
||||
|
||||
return &display->GetVSyncEvent();
|
||||
return display->GetVSyncEvent();
|
||||
}
|
||||
|
||||
VI::Display* NVFlinger::FindDisplay(u64 display_id) {
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "common/common_types.h"
|
||||
#include "core/hle/result.h"
|
||||
#include "core/hle/service/kernel_helpers.h"
|
||||
|
||||
namespace Common {
|
||||
@@ -71,8 +72,9 @@ public:
|
||||
|
||||
/// Gets the vsync event for the specified display.
|
||||
///
|
||||
/// If an invalid display ID is provided, then nullptr is returned.
|
||||
[[nodiscard]] Kernel::KReadableEvent* FindVsyncEvent(u64 display_id);
|
||||
/// If an invalid display ID is provided, then VI::ResultNotFound is returned.
|
||||
/// If the vsync event has already been retrieved, then VI::ResultPermissionDenied is returned.
|
||||
[[nodiscard]] ResultVal<Kernel::KReadableEvent*> FindVsyncEvent(u64 display_id);
|
||||
|
||||
/// Performs a composition request to the emulated nvidia GPU and triggers the vsync events when
|
||||
/// finished.
|
||||
|
||||
@@ -929,7 +929,7 @@ BSD::BSD(Core::System& system_, const char* name)
|
||||
proxy_packet_received = room_member->BindOnProxyPacketReceived(
|
||||
[this](const Network::ProxyPacket& packet) { OnProxyPacketReceived(packet); });
|
||||
} else {
|
||||
LOG_ERROR(Service, "Network isn't initialized");
|
||||
LOG_ERROR(Service, "Network isn't initalized");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "core/hle/service/nvflinger/hos_binder_driver_server.h"
|
||||
#include "core/hle/service/vi/display/vi_display.h"
|
||||
#include "core/hle/service/vi/layer/vi_layer.h"
|
||||
#include "core/hle/service/vi/vi_results.h"
|
||||
|
||||
namespace Service::VI {
|
||||
|
||||
@@ -55,8 +56,18 @@ const Layer& Display::GetLayer(std::size_t index) const {
|
||||
return *layers.at(index);
|
||||
}
|
||||
|
||||
Kernel::KReadableEvent& Display::GetVSyncEvent() {
|
||||
return vsync_event->GetReadableEvent();
|
||||
ResultVal<Kernel::KReadableEvent*> Display::GetVSyncEvent() {
|
||||
if (got_vsync_event) {
|
||||
return ResultPermissionDenied;
|
||||
}
|
||||
|
||||
got_vsync_event = true;
|
||||
|
||||
return GetVSyncEventUnchecked();
|
||||
}
|
||||
|
||||
Kernel::KReadableEvent* Display::GetVSyncEventUnchecked() {
|
||||
return &vsync_event->GetReadableEvent();
|
||||
}
|
||||
|
||||
void Display::SignalVSyncEvent() {
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
#include "common/common_funcs.h"
|
||||
#include "common/common_types.h"
|
||||
#include "core/hle/result.h"
|
||||
|
||||
namespace Kernel {
|
||||
class KEvent;
|
||||
@@ -73,8 +74,16 @@ public:
|
||||
return layers.size();
|
||||
}
|
||||
|
||||
/// Gets the readable vsync event.
|
||||
Kernel::KReadableEvent& GetVSyncEvent();
|
||||
/**
|
||||
* Gets the internal vsync event.
|
||||
*
|
||||
* @returns The internal Vsync event if it has not yet been retrieved,
|
||||
* VI::ResultPermissionDenied otherwise.
|
||||
*/
|
||||
[[nodiscard]] ResultVal<Kernel::KReadableEvent*> GetVSyncEvent();
|
||||
|
||||
/// Gets the internal vsync event.
|
||||
Kernel::KReadableEvent* GetVSyncEventUnchecked();
|
||||
|
||||
/// Signals the internal vsync event.
|
||||
void SignalVSyncEvent();
|
||||
@@ -118,6 +127,7 @@ private:
|
||||
|
||||
std::vector<std::unique_ptr<Layer>> layers;
|
||||
Kernel::KEvent* vsync_event{};
|
||||
bool got_vsync_event{false};
|
||||
};
|
||||
|
||||
} // namespace Service::VI
|
||||
|
||||
@@ -29,16 +29,12 @@
|
||||
#include "core/hle/service/service.h"
|
||||
#include "core/hle/service/vi/vi.h"
|
||||
#include "core/hle/service/vi/vi_m.h"
|
||||
#include "core/hle/service/vi/vi_results.h"
|
||||
#include "core/hle/service/vi/vi_s.h"
|
||||
#include "core/hle/service/vi/vi_u.h"
|
||||
|
||||
namespace Service::VI {
|
||||
|
||||
constexpr Result ERR_OPERATION_FAILED{ErrorModule::VI, 1};
|
||||
constexpr Result ERR_PERMISSION_DENIED{ErrorModule::VI, 5};
|
||||
constexpr Result ERR_UNSUPPORTED{ErrorModule::VI, 6};
|
||||
constexpr Result ERR_NOT_FOUND{ErrorModule::VI, 7};
|
||||
|
||||
struct DisplayInfo {
|
||||
/// The name of this particular display.
|
||||
char display_name[0x40]{"Default"};
|
||||
@@ -348,7 +344,7 @@ private:
|
||||
if (!layer_id) {
|
||||
LOG_ERROR(Service_VI, "Layer not found! display=0x{:016X}", display);
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ERR_NOT_FOUND);
|
||||
rb.Push(ResultNotFound);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -498,7 +494,7 @@ private:
|
||||
if (!display_id) {
|
||||
LOG_ERROR(Service_VI, "Display not found! display_name={}", name);
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ERR_NOT_FOUND);
|
||||
rb.Push(ResultNotFound);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -554,14 +550,14 @@ private:
|
||||
|
||||
if (scaling_mode > NintendoScaleMode::PreserveAspectRatio) {
|
||||
LOG_ERROR(Service_VI, "Invalid scaling mode provided.");
|
||||
rb.Push(ERR_OPERATION_FAILED);
|
||||
rb.Push(ResultOperationFailed);
|
||||
return;
|
||||
}
|
||||
|
||||
if (scaling_mode != NintendoScaleMode::ScaleToWindow &&
|
||||
scaling_mode != NintendoScaleMode::PreserveAspectRatio) {
|
||||
LOG_ERROR(Service_VI, "Unsupported scaling mode supplied.");
|
||||
rb.Push(ERR_UNSUPPORTED);
|
||||
rb.Push(ResultNotSupported);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -594,7 +590,7 @@ private:
|
||||
if (!display_id) {
|
||||
LOG_ERROR(Service_VI, "Layer not found! layer_id={}", layer_id);
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ERR_NOT_FOUND);
|
||||
rb.Push(ResultNotFound);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -602,7 +598,7 @@ private:
|
||||
if (!buffer_queue_id) {
|
||||
LOG_ERROR(Service_VI, "Buffer queue id not found! display_id={}", *display_id);
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ERR_NOT_FOUND);
|
||||
rb.Push(ResultNotFound);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -640,7 +636,7 @@ private:
|
||||
if (!layer_id) {
|
||||
LOG_ERROR(Service_VI, "Layer not found! display_id={}", display_id);
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ERR_NOT_FOUND);
|
||||
rb.Push(ResultNotFound);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -648,7 +644,7 @@ private:
|
||||
if (!buffer_queue_id) {
|
||||
LOG_ERROR(Service_VI, "Buffer queue id not found! display_id={}", display_id);
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ERR_NOT_FOUND);
|
||||
rb.Push(ResultNotFound);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -675,19 +671,23 @@ private:
|
||||
IPC::RequestParser rp{ctx};
|
||||
const u64 display_id = rp.Pop<u64>();
|
||||
|
||||
LOG_WARNING(Service_VI, "(STUBBED) called. display_id=0x{:016X}", display_id);
|
||||
LOG_DEBUG(Service_VI, "called. display_id={}", display_id);
|
||||
|
||||
const auto vsync_event = nv_flinger.FindVsyncEvent(display_id);
|
||||
if (!vsync_event) {
|
||||
LOG_ERROR(Service_VI, "Vsync event was not found for display_id={}", display_id);
|
||||
if (vsync_event.Failed()) {
|
||||
const auto result = vsync_event.Code();
|
||||
if (result == ResultNotFound) {
|
||||
LOG_ERROR(Service_VI, "Vsync event was not found for display_id={}", display_id);
|
||||
}
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ERR_NOT_FOUND);
|
||||
rb.Push(result);
|
||||
return;
|
||||
}
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2, 1};
|
||||
rb.Push(ResultSuccess);
|
||||
rb.PushCopyObjects(vsync_event);
|
||||
rb.PushCopyObjects(*vsync_event);
|
||||
}
|
||||
|
||||
void ConvertScalingMode(Kernel::HLERequestContext& ctx) {
|
||||
@@ -764,7 +764,7 @@ private:
|
||||
return ConvertedScaleMode::PreserveAspectRatio;
|
||||
default:
|
||||
LOG_ERROR(Service_VI, "Invalid scaling mode specified, mode={}", mode);
|
||||
return ERR_OPERATION_FAILED;
|
||||
return ResultOperationFailed;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -794,7 +794,7 @@ void detail::GetDisplayServiceImpl(Kernel::HLERequestContext& ctx, Core::System&
|
||||
if (!IsValidServiceAccess(permission, policy)) {
|
||||
LOG_ERROR(Service_VI, "Permission denied for policy {}", policy);
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ERR_PERMISSION_DENIED);
|
||||
rb.Push(ResultPermissionDenied);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
13
src/core/hle/service/vi/vi_results.h
Normal file
13
src/core/hle/service/vi/vi_results.h
Normal file
@@ -0,0 +1,13 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "core/hle/result.h"
|
||||
|
||||
namespace Service::VI {
|
||||
|
||||
constexpr Result ResultOperationFailed{ErrorModule::VI, 1};
|
||||
constexpr Result ResultPermissionDenied{ErrorModule::VI, 5};
|
||||
constexpr Result ResultNotSupported{ErrorModule::VI, 6};
|
||||
constexpr Result ResultNotFound{ErrorModule::VI, 7};
|
||||
|
||||
} // namespace Service::VI
|
||||
@@ -364,7 +364,7 @@ std::pair<s32, Errno> Poll(std::vector<PollFD>& pollfds, s32 timeout) {
|
||||
std::vector<WSAPOLLFD> host_pollfds(pollfds.size());
|
||||
std::transform(pollfds.begin(), pollfds.end(), host_pollfds.begin(), [](PollFD fd) {
|
||||
WSAPOLLFD result;
|
||||
result.fd = fd.socket->GetFD();
|
||||
result.fd = fd.socket->fd;
|
||||
result.events = TranslatePollEvents(fd.events);
|
||||
result.revents = 0;
|
||||
return result;
|
||||
@@ -430,12 +430,12 @@ std::pair<SocketBase::AcceptResult, Errno> Socket::Accept() {
|
||||
return {AcceptResult{}, GetAndLogLastError()};
|
||||
}
|
||||
|
||||
ASSERT(addrlen == sizeof(sockaddr_in));
|
||||
AcceptResult result;
|
||||
result.socket = std::make_unique<Socket>();
|
||||
result.socket->fd = new_socket;
|
||||
|
||||
AcceptResult result{
|
||||
.socket = std::make_unique<Socket>(new_socket),
|
||||
.sockaddr_in = TranslateToSockAddrIn(addr),
|
||||
};
|
||||
ASSERT(addrlen == sizeof(sockaddr_in));
|
||||
result.sockaddr_in = TranslateToSockAddrIn(addr);
|
||||
|
||||
return {std::move(result), Errno::SUCCESS};
|
||||
}
|
||||
|
||||
@@ -32,10 +32,6 @@ public:
|
||||
std::unique_ptr<SocketBase> socket;
|
||||
SockAddrIn sockaddr_in;
|
||||
};
|
||||
|
||||
SocketBase() = default;
|
||||
explicit SocketBase(SOCKET fd_) : fd{fd_} {}
|
||||
|
||||
virtual ~SocketBase() = default;
|
||||
|
||||
virtual SocketBase& operator=(const SocketBase&) = delete;
|
||||
@@ -93,19 +89,12 @@ public:
|
||||
|
||||
virtual void HandleProxyPacket(const ProxyPacket& packet) = 0;
|
||||
|
||||
[[nodiscard]] SOCKET GetFD() const {
|
||||
return fd;
|
||||
}
|
||||
|
||||
protected:
|
||||
SOCKET fd = INVALID_SOCKET;
|
||||
};
|
||||
|
||||
class Socket : public SocketBase {
|
||||
public:
|
||||
Socket() = default;
|
||||
explicit Socket(SOCKET fd_) : SocketBase{fd_} {}
|
||||
|
||||
~Socket() override;
|
||||
|
||||
Socket(const Socket&) = delete;
|
||||
|
||||
@@ -244,10 +244,6 @@ static std::unique_ptr<AppLoader> GetFileLoader(Core::System& system, FileSys::V
|
||||
|
||||
std::unique_ptr<AppLoader> GetLoader(Core::System& system, FileSys::VirtualFile file,
|
||||
u64 program_id, std::size_t program_index) {
|
||||
if (!file) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
FileType type = IdentifyFile(file);
|
||||
const FileType filename_type = GuessFromFilename(file->GetName());
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ RoomNetwork::RoomNetwork() {
|
||||
|
||||
bool RoomNetwork::Init() {
|
||||
if (enet_initialize() != 0) {
|
||||
LOG_ERROR(Network, "Error initializing ENet");
|
||||
LOG_ERROR(Network, "Error initalizing ENet");
|
||||
return false;
|
||||
}
|
||||
m_room = std::make_shared<Room>();
|
||||
|
||||
@@ -175,7 +175,7 @@ bool IsReference(IR::Inst& inst) {
|
||||
}
|
||||
|
||||
void PrecolorInst(IR::Inst& phi) {
|
||||
// Insert phi moves before references to avoid overwriting other phis
|
||||
// Insert phi moves before references to avoid overwritting other phis
|
||||
const size_t num_args{phi.NumArgs()};
|
||||
for (size_t i = 0; i < num_args; ++i) {
|
||||
IR::Block& phi_block{*phi.PhiBlock(i)};
|
||||
|
||||
@@ -101,7 +101,7 @@ bool IsReference(IR::Inst& inst) {
|
||||
}
|
||||
|
||||
void PrecolorInst(IR::Inst& phi) {
|
||||
// Insert phi moves before references to avoid overwriting other phis
|
||||
// Insert phi moves before references to avoid overwritting other phis
|
||||
const size_t num_args{phi.NumArgs()};
|
||||
for (size_t i = 0; i < num_args; ++i) {
|
||||
IR::Block& phi_block{*phi.PhiBlock(i)};
|
||||
|
||||
@@ -1065,7 +1065,7 @@ TexelWeightParams DecodeBlockInfo() {
|
||||
void FillError(ivec3 coord) {
|
||||
for (uint j = 0; j < block_dims.y; j++) {
|
||||
for (uint i = 0; i < block_dims.x; i++) {
|
||||
imageStore(dest_image, coord + ivec3(i, j, 0), vec4(0.0, 0.0, 0.0, 0.0));
|
||||
imageStore(dest_image, coord + ivec3(i, j, 0), vec4(1.0, 1.0, 0.0, 1.0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -279,13 +279,28 @@ void MacroJITx64Impl::Compile_ExtractInsert(Macro::Opcode opcode) {
|
||||
auto dst = Compile_GetRegister(opcode.src_a, RESULT);
|
||||
auto src = Compile_GetRegister(opcode.src_b, eax);
|
||||
|
||||
const u32 mask = ~(opcode.GetBitfieldMask() << opcode.bf_dst_bit);
|
||||
and_(dst, mask);
|
||||
shr(src, opcode.bf_src_bit);
|
||||
and_(src, opcode.GetBitfieldMask());
|
||||
shl(src, opcode.bf_dst_bit);
|
||||
or_(dst, src);
|
||||
if (opcode.bf_src_bit != 0 && opcode.bf_src_bit != 31) {
|
||||
shr(src, opcode.bf_src_bit);
|
||||
} else if (opcode.bf_src_bit == 31) {
|
||||
xor_(src, src);
|
||||
}
|
||||
// Don't bother masking the whole register since we're using a 32 bit register
|
||||
if (opcode.bf_size != 31 && opcode.bf_size != 0) {
|
||||
and_(src, opcode.GetBitfieldMask());
|
||||
} else if (opcode.bf_size == 0) {
|
||||
xor_(src, src);
|
||||
}
|
||||
if (opcode.bf_dst_bit != 31 && opcode.bf_dst_bit != 0) {
|
||||
shl(src, opcode.bf_dst_bit);
|
||||
} else if (opcode.bf_dst_bit == 31) {
|
||||
xor_(src, src);
|
||||
}
|
||||
|
||||
const u32 mask = ~(opcode.GetBitfieldMask() << opcode.bf_dst_bit);
|
||||
if (mask != 0xffffffff) {
|
||||
and_(dst, mask);
|
||||
}
|
||||
or_(dst, src);
|
||||
Compile_ProcessResult(opcode.result_operation, opcode.dst);
|
||||
}
|
||||
|
||||
@@ -294,9 +309,17 @@ void MacroJITx64Impl::Compile_ExtractShiftLeftImmediate(Macro::Opcode opcode) {
|
||||
const auto src = Compile_GetRegister(opcode.src_b, RESULT);
|
||||
|
||||
shr(src, dst.cvt8());
|
||||
and_(src, opcode.GetBitfieldMask());
|
||||
shl(src, opcode.bf_dst_bit);
|
||||
if (opcode.bf_size != 0 && opcode.bf_size != 31) {
|
||||
and_(src, opcode.GetBitfieldMask());
|
||||
} else if (opcode.bf_size == 0) {
|
||||
xor_(src, src);
|
||||
}
|
||||
|
||||
if (opcode.bf_dst_bit != 0 && opcode.bf_dst_bit != 31) {
|
||||
shl(src, opcode.bf_dst_bit);
|
||||
} else if (opcode.bf_dst_bit == 31) {
|
||||
xor_(src, src);
|
||||
}
|
||||
Compile_ProcessResult(opcode.result_operation, opcode.dst);
|
||||
}
|
||||
|
||||
@@ -304,8 +327,13 @@ void MacroJITx64Impl::Compile_ExtractShiftLeftRegister(Macro::Opcode opcode) {
|
||||
const auto dst = Compile_GetRegister(opcode.src_a, ecx);
|
||||
const auto src = Compile_GetRegister(opcode.src_b, RESULT);
|
||||
|
||||
shr(src, opcode.bf_src_bit);
|
||||
and_(src, opcode.GetBitfieldMask());
|
||||
if (opcode.bf_src_bit != 0) {
|
||||
shr(src, opcode.bf_src_bit);
|
||||
}
|
||||
|
||||
if (opcode.bf_size != 31) {
|
||||
and_(src, opcode.GetBitfieldMask());
|
||||
}
|
||||
shl(src, dst.cvt8());
|
||||
|
||||
Compile_ProcessResult(opcode.result_operation, opcode.dst);
|
||||
|
||||
@@ -1413,7 +1413,7 @@ static void FillVoidExtentLDR(InputBitStream& strm, std::span<u32> outBuf, u32 b
|
||||
static void FillError(std::span<u32> outBuf, u32 blockWidth, u32 blockHeight) {
|
||||
for (u32 j = 0; j < blockHeight; j++) {
|
||||
for (u32 i = 0; i < blockWidth; i++) {
|
||||
outBuf[j * blockWidth + i] = 0x00000000;
|
||||
outBuf[j * blockWidth + i] = 0xFFFF00FF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -291,7 +291,7 @@ bool QtControllerSelectorDialog::CheckIfParametersMet() {
|
||||
// Here, we check and validate the current configuration against all applicable parameters.
|
||||
const auto num_connected_players = static_cast<int>(
|
||||
std::count_if(player_groupboxes.begin(), player_groupboxes.end(),
|
||||
[](const QGroupBox* player) { return player->isChecked(); }));
|
||||
[this](const QGroupBox* player) { return player->isChecked(); }));
|
||||
|
||||
const auto min_supported_players = parameters.enable_single_mode ? 1 : parameters.min_players;
|
||||
const auto max_supported_players = parameters.enable_single_mode ? 1 : parameters.max_players;
|
||||
|
||||
@@ -546,7 +546,6 @@ void Config::ReadDebuggingValues() {
|
||||
ReadBasicSetting(Settings::values.use_auto_stub);
|
||||
ReadBasicSetting(Settings::values.enable_all_controllers);
|
||||
ReadBasicSetting(Settings::values.create_crash_dumps);
|
||||
ReadBasicSetting(Settings::values.perform_vulkan_check);
|
||||
|
||||
qt_config->endGroup();
|
||||
}
|
||||
@@ -1163,7 +1162,6 @@ void Config::SaveDebuggingValues() {
|
||||
WriteBasicSetting(Settings::values.disable_macro_jit);
|
||||
WriteBasicSetting(Settings::values.enable_all_controllers);
|
||||
WriteBasicSetting(Settings::values.create_crash_dumps);
|
||||
WriteBasicSetting(Settings::values.perform_vulkan_check);
|
||||
|
||||
qt_config->endGroup();
|
||||
}
|
||||
|
||||
@@ -77,7 +77,6 @@ void ConfigureDebug::SetConfiguration() {
|
||||
ui->disable_loop_safety_checks->setChecked(
|
||||
Settings::values.disable_shader_loop_safety_checks.GetValue());
|
||||
ui->extended_logging->setChecked(Settings::values.extended_logging.GetValue());
|
||||
ui->perform_vulkan_check->setChecked(Settings::values.perform_vulkan_check.GetValue());
|
||||
|
||||
#ifdef YUZU_USE_QT_WEB_ENGINE
|
||||
ui->disable_web_applet->setChecked(UISettings::values.disable_web_applet.GetValue());
|
||||
@@ -118,7 +117,6 @@ void ConfigureDebug::ApplyConfiguration() {
|
||||
ui->disable_loop_safety_checks->isChecked();
|
||||
Settings::values.disable_macro_jit = ui->disable_macro_jit->isChecked();
|
||||
Settings::values.extended_logging = ui->extended_logging->isChecked();
|
||||
Settings::values.perform_vulkan_check = ui->perform_vulkan_check->isChecked();
|
||||
UISettings::values.disable_web_applet = ui->disable_web_applet->isChecked();
|
||||
Debugger::ToggleConsole();
|
||||
Common::Log::Filter filter;
|
||||
|
||||
@@ -313,16 +313,6 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QCheckBox" name="perform_vulkan_check">
|
||||
<property name="toolTip">
|
||||
<string>Enables yuzu to check for a working Vulkan environment when the program starts up. Disable this if this is causing issues with external programs seeing yuzu.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Perform Startup Vulkan Check</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
|
||||
@@ -163,9 +163,10 @@ void ConfigureInput::Initialize(InputCommon::InputSubsystem* input_subsystem,
|
||||
[this, input_subsystem, &hid_core] {
|
||||
CallConfigureDialog<ConfigureRingController>(*this, input_subsystem, hid_core);
|
||||
});
|
||||
connect(advanced, &ConfigureInputAdvanced::CallCameraDialog, [this, input_subsystem] {
|
||||
CallConfigureDialog<ConfigureCamera>(*this, input_subsystem);
|
||||
});
|
||||
connect(advanced, &ConfigureInputAdvanced::CallCameraDialog,
|
||||
[this, input_subsystem, &hid_core] {
|
||||
CallConfigureDialog<ConfigureCamera>(*this, input_subsystem);
|
||||
});
|
||||
|
||||
connect(ui->vibrationButton, &QPushButton::clicked,
|
||||
[this, &hid_core] { CallConfigureDialog<ConfigureVibration>(*this, hid_core); });
|
||||
|
||||
@@ -67,8 +67,6 @@ std::vector<std::string> InputProfiles::GetInputProfileNames() {
|
||||
profile_names.push_back(profile_name);
|
||||
}
|
||||
|
||||
std::stable_sort(profile_names.begin(), profile_names.end());
|
||||
|
||||
return profile_names;
|
||||
}
|
||||
|
||||
|
||||
@@ -2000,7 +2000,7 @@ static bool RomFSRawCopy(QProgressDialog& dialog, const FileSys::VirtualDir& src
|
||||
}
|
||||
|
||||
void GMainWindow::OnGameListRemoveInstalledEntry(u64 program_id, InstalledEntryType type) {
|
||||
const QString entry_type = [type] {
|
||||
const QString entry_type = [this, type] {
|
||||
switch (type) {
|
||||
case InstalledEntryType::Game:
|
||||
return tr("Contents");
|
||||
@@ -2097,7 +2097,7 @@ void GMainWindow::RemoveAddOnContent(u64 program_id, const QString& entry_type)
|
||||
|
||||
void GMainWindow::OnGameListRemoveFile(u64 program_id, GameListRemoveTarget target,
|
||||
const std::string& game_path) {
|
||||
const QString question = [target] {
|
||||
const QString question = [this, target] {
|
||||
switch (target) {
|
||||
case GameListRemoveTarget::GlShaderCache:
|
||||
return tr("Delete OpenGL Transferable Shader Cache?");
|
||||
@@ -4086,8 +4086,7 @@ int main(int argc, char* argv[]) {
|
||||
}
|
||||
#endif
|
||||
|
||||
if (StartupChecks(argv[0], &has_broken_vulkan,
|
||||
Settings::values.perform_vulkan_check.GetValue())) {
|
||||
if (StartupChecks(argv[0], &has_broken_vulkan)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ bool CheckEnvVars(bool* is_child) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool StartupChecks(const char* arg0, bool* has_broken_vulkan, bool perform_vulkan_check) {
|
||||
bool StartupChecks(const char* arg0, bool* has_broken_vulkan) {
|
||||
#ifdef _WIN32
|
||||
// Set the startup variable for child processes
|
||||
const bool env_var_set = SetEnvironmentVariableA(STARTUP_CHECK_ENV_VAR, ENV_VAR_ENABLED_TEXT);
|
||||
@@ -67,32 +67,29 @@ bool StartupChecks(const char* arg0, bool* has_broken_vulkan, bool perform_vulka
|
||||
return false;
|
||||
}
|
||||
|
||||
if (perform_vulkan_check) {
|
||||
// Spawn child process that performs Vulkan check
|
||||
PROCESS_INFORMATION process_info;
|
||||
std::memset(&process_info, '\0', sizeof(process_info));
|
||||
PROCESS_INFORMATION process_info;
|
||||
std::memset(&process_info, '\0', sizeof(process_info));
|
||||
|
||||
if (!SpawnChild(arg0, &process_info, 0)) {
|
||||
return false;
|
||||
}
|
||||
if (!SpawnChild(arg0, &process_info, 0)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Wait until the processs exits and get exit code from it
|
||||
WaitForSingleObject(process_info.hProcess, INFINITE);
|
||||
DWORD exit_code = STILL_ACTIVE;
|
||||
const int err = GetExitCodeProcess(process_info.hProcess, &exit_code);
|
||||
if (err == 0) {
|
||||
std::fprintf(stderr, "GetExitCodeProcess failed with error %d\n", GetLastError());
|
||||
}
|
||||
// Wait until the processs exits and get exit code from it
|
||||
WaitForSingleObject(process_info.hProcess, INFINITE);
|
||||
DWORD exit_code = STILL_ACTIVE;
|
||||
const int err = GetExitCodeProcess(process_info.hProcess, &exit_code);
|
||||
if (err == 0) {
|
||||
std::fprintf(stderr, "GetExitCodeProcess failed with error %d\n", GetLastError());
|
||||
}
|
||||
|
||||
// Vulkan is broken if the child crashed (return value is not zero)
|
||||
*has_broken_vulkan = (exit_code != 0);
|
||||
// Vulkan is broken if the child crashed (return value is not zero)
|
||||
*has_broken_vulkan = (exit_code != 0);
|
||||
|
||||
if (CloseHandle(process_info.hProcess) == 0) {
|
||||
std::fprintf(stderr, "CloseHandle failed with error %d\n", GetLastError());
|
||||
}
|
||||
if (CloseHandle(process_info.hThread) == 0) {
|
||||
std::fprintf(stderr, "CloseHandle failed with error %d\n", GetLastError());
|
||||
}
|
||||
if (CloseHandle(process_info.hProcess) == 0) {
|
||||
std::fprintf(stderr, "CloseHandle failed with error %d\n", GetLastError());
|
||||
}
|
||||
if (CloseHandle(process_info.hThread) == 0) {
|
||||
std::fprintf(stderr, "CloseHandle failed with error %d\n", GetLastError());
|
||||
}
|
||||
|
||||
if (!SetEnvironmentVariableA(STARTUP_CHECK_ENV_VAR, nullptr)) {
|
||||
@@ -101,28 +98,26 @@ bool StartupChecks(const char* arg0, bool* has_broken_vulkan, bool perform_vulka
|
||||
}
|
||||
|
||||
#elif defined(YUZU_UNIX)
|
||||
if (perform_vulkan_check) {
|
||||
const pid_t pid = fork();
|
||||
if (pid == 0) {
|
||||
CheckVulkan();
|
||||
return true;
|
||||
} else if (pid == -1) {
|
||||
const int err = errno;
|
||||
std::fprintf(stderr, "fork failed with error %d\n", err);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get exit code from child process
|
||||
int status;
|
||||
const int r_val = wait(&status);
|
||||
if (r_val == -1) {
|
||||
const int err = errno;
|
||||
std::fprintf(stderr, "wait failed with error %d\n", err);
|
||||
return false;
|
||||
}
|
||||
// Vulkan is broken if the child crashed (return value is not zero)
|
||||
*has_broken_vulkan = (status != 0);
|
||||
const pid_t pid = fork();
|
||||
if (pid == 0) {
|
||||
CheckVulkan();
|
||||
return true;
|
||||
} else if (pid == -1) {
|
||||
const int err = errno;
|
||||
std::fprintf(stderr, "fork failed with error %d\n", err);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get exit code from child process
|
||||
int status;
|
||||
const int r_val = wait(&status);
|
||||
if (r_val == -1) {
|
||||
const int err = errno;
|
||||
std::fprintf(stderr, "wait failed with error %d\n", err);
|
||||
return false;
|
||||
}
|
||||
// Vulkan is broken if the child crashed (return value is not zero)
|
||||
*has_broken_vulkan = (status != 0);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ constexpr char ENV_VAR_ENABLED_TEXT[] = "ON";
|
||||
|
||||
void CheckVulkan();
|
||||
bool CheckEnvVars(bool* is_child);
|
||||
bool StartupChecks(const char* arg0, bool* has_broken_vulkan, bool perform_vulkan_check);
|
||||
bool StartupChecks(const char* arg0, bool* has_broken_vulkan);
|
||||
|
||||
#ifdef _WIN32
|
||||
bool SpawnChild(const char* arg0, PROCESS_INFORMATION* pi, int flags);
|
||||
|
||||
Reference in New Issue
Block a user