Compare commits

...

24 Commits

Author SHA1 Message Date
Lioncash
0ab7bfdfce core: Add boxcat sources with target_sources
Same behavior, minus a script variable.
2020-10-18 08:09:06 -04:00
bunnei
2190f1a2b7 Merge pull request #4801 from lioncash/missing-bound
mii/manager: Make use of unused lower bound in GetRandomValue()
2020-10-17 23:32:40 -07:00
bunnei
743fe1aea3 Merge pull request #4782 from ReinUsesLisp/remove-dyn-primitive
vk_graphics_pipeline: Manage primitive topology as fixed state
2020-10-17 22:14:17 -07:00
Lioncash
c1577f3448 mii/manager: Make use of unused lower bound in GetRandomValue()
Previously, the lower bound wasn't being used and zero was being used as
the lower bound every time this function was called.

This affects the outcome of some of the randomized entries a little bit,
for example, the lower-bound for beard and mustache flags was supposed
to be 1, not 0.

Aside from these cases, the bug didn't affect anything else.
2020-10-17 09:50:04 -04:00
bunnei
1eb908bc88 Merge pull request #4797 from bunnei/bcat-errors
service: bcat: Check client connection before interacting with socket.
2020-10-16 23:28:40 -07:00
bunnei
cb708631b6 Merge pull request #4798 from lioncash/input-copy
udp/client: Take std::function by const reference with TestCommunication()
2020-10-16 21:20:01 -07:00
bunnei
363c644730 service: bcat: Check client connection before interacting with socket.
- Fixes a crash when BCAT service is offline.
2020-10-16 21:16:56 -07:00
Lioncash
30b1e71066 udp/client: Make use of designated initializers in TestCommunication()
Same behavior, but makes the callback list nicer to look at.
2020-10-16 06:23:51 -04:00
Lioncash
36cfb234d5 udp/client: Take std::function by const reference with TestCommunication()
Avoids redundant copies.
2020-10-16 06:22:29 -04:00
bunnei
64f967fd49 Merge pull request #4790 from lioncash/input-common
input_common/CMakeLists: Make some warnings errors
2020-10-15 20:59:34 -07:00
bunnei
dbd1662ae2 Merge pull request #4784 from bunnei/cancelbuffer
hle: service: vi: Implement BufferQueue::CancelBuffer.
2020-10-15 19:57:27 -07:00
Lioncash
046c0c91a3 input_common/CMakeLists: Make some warnings errors
Makes the input_common code warnings consistent with the rest of the
codebase.
2020-10-15 19:37:51 -04:00
bunnei
046cc81938 Merge pull request #4793 from bunnei/storeopencontext
service: acc: Stub IManagerForApplication::StoreOpenContext.
2020-10-14 20:42:18 -07:00
bunnei
1d714c8c7f service: acc: Stub IManagerForApplication::StoreOpenContext.
- Used by Super Mario 3D All-Stars.
2020-10-14 20:06:33 -07:00
bunnei
d47ac3ce09 Merge pull request #4772 from goldenx86/block-rdna
vk_device: Block VK_EXT_extended_dynamic_state for RDNA devices
2020-10-14 17:51:39 -07:00
bunnei
1f186f34a2 hle: service: vi: Implement BufferQueue::CancelBuffer.
- This is used by Super Mario 3D All-Stars.
2020-10-13 22:11:52 -07:00
bunnei
ca416a0fb8 Merge pull request #4787 from lioncash/conversion
audio_core/CMakeLists: Make warnings consistent with core
2020-10-13 15:30:30 -07:00
Lioncash
9f9b64d280 audio_core/CMakeLists: Make warnings consistent with core
Normalizes the warnings shared between audio_core and core.
2020-10-13 16:36:58 -04:00
Rodrigo Locatti
c5b3c8d06b Merge pull request #4786 from lioncash/flags
core/CMakeLists: Make some warnings errors
2020-10-13 16:20:44 -03:00
Lioncash
39c8d18feb core/CMakeLists: Make some warnings errors
Makes our error coverage a little more consistent across the board by
applying it to Linux side of things as well. This also makes it more
consistent with the warning settings in other libraries in the project.

This also updates httplib to 0.7.9, as there are several warning
cleanups made that allow us to enable several warnings as errors.
2020-10-13 13:16:49 -04:00
ReinUsesLisp
e4e0abc418 vk_graphics_pipeline: Manage primitive topology as fixed state
Vulkan has requirements for primitive topologies that don't play nicely
with yuzu's. Since it's only 4 bits, we can move it to fixed state
without changing the size of the pipeline key.

- Fixes a regression on recent Nvidia drivers on Fire Emblem: Three
  Houses.
2020-10-13 04:08:33 -03:00
bunnei
d291fc1a51 Merge pull request #3929 from FearlessTobi/ticket-keys
file_sys/nsp: Make SetTicketKeys actually do something
2020-10-12 17:58:36 -07:00
goldenx86
0120e5b1d9 vk_device: Block VK_EXT_extended_dynamic_state for RDNA devices
RDNA devices seem to crash when using VK_EXT_extended_dynamic_state in
the latest 20.9.2 proprietary Windows drivers. As a workaround, for now
we block device names corresponding to current RDNA released products.
2020-10-08 21:27:49 -03:00
FearlessTobi
4d4bbe756f file_sys/nsp: Make SetTicketKeys actually do something
Previously, the method wasn't modifying any class state and therefore not having any effects when called.
Since this has been the case for a very long time now, I'm not sure if we couldn't just remove this method altogether.
2020-07-18 02:02:39 +02:00
69 changed files with 3715 additions and 1838 deletions

View File

@@ -90,6 +90,9 @@ if (ENABLE_WEB_SERVICE)
target_include_directories(httplib INTERFACE ./httplib)
target_compile_definitions(httplib INTERFACE -DCPPHTTPLIB_OPENSSL_SUPPORT)
target_link_libraries(httplib INTERFACE ${OPENSSL_LIBRARIES})
if (WIN32)
target_link_libraries(httplib INTERFACE crypt32 cryptui ws2_32)
endif()
endif()
# Opus

File diff suppressed because it is too large Load Diff

View File

@@ -46,10 +46,13 @@ create_target_directory_groups(audio_core)
if (NOT MSVC)
target_compile_options(audio_core PRIVATE
-Werror=conversion
-Werror=ignored-qualifiers
-Werror=implicit-fallthrough
-Werror=reorder
-Werror=sign-compare
-Werror=unused-but-set-parameter
-Werror=unused-but-set-variable
-Werror=unused-variable
)
endif()

View File

@@ -55,7 +55,8 @@ void Filter::Process(std::vector<s16>& signal) {
/// @param total_count The total number of biquads to be cascaded.
/// @param index 0-index of the biquad to calculate the Q value for.
static double CascadingBiquadQ(std::size_t total_count, std::size_t index) {
const double pole = M_PI * (2 * index + 1) / (4.0 * total_count);
const auto pole =
M_PI * static_cast<double>(2 * index + 1) / (4.0 * static_cast<double>(total_count));
return 1.0 / (2.0 * std::cos(pole));
}

View File

@@ -146,7 +146,7 @@ std::vector<s16> Interpolate(InterpolationState& state, std::vector<s16> input,
return {};
if (ratio <= 0) {
LOG_CRITICAL(Audio, "Nonsensical interpolation ratio {}", ratio);
LOG_ERROR(Audio, "Nonsensical interpolation ratio {}", ratio);
return input;
}
@@ -164,7 +164,8 @@ std::vector<s16> Interpolate(InterpolationState& state, std::vector<s16> input,
const std::size_t num_frames{input.size() / 2};
std::vector<s16> output;
output.reserve(static_cast<std::size_t>(input.size() / ratio + InterpolationState::taps));
output.reserve(static_cast<std::size_t>(static_cast<double>(input.size()) / ratio +
InterpolationState::taps));
for (std::size_t frame{}; frame < num_frames; ++frame) {
const std::size_t lut_index{(state.fraction >> 8) * InterpolationState::taps};

View File

@@ -793,7 +793,6 @@ s32 CommandGenerator::DecodeAdpcm(ServerVoiceInfo& voice_info, VoiceState& dsp_s
// Decode entire frame
if (remaining_samples >= static_cast<int>(SAMPLES_PER_FRAME)) {
for (std::size_t i = 0; i < SAMPLES_PER_FRAME / 2; i++) {
// Sample 1
const s32 s0 = SIGNED_NIBBLES[buffer[buffer_offset] >> 4];
const s32 s1 = SIGNED_NIBBLES[buffer[buffer_offset++] & 0xf];
@@ -802,7 +801,7 @@ s32 CommandGenerator::DecodeAdpcm(ServerVoiceInfo& voice_info, VoiceState& dsp_s
sample_buffer[cur_mix_offset++] = sample_1;
sample_buffer[cur_mix_offset++] = sample_2;
}
remaining_samples -= SAMPLES_PER_FRAME;
remaining_samples -= static_cast<int>(SAMPLES_PER_FRAME);
position_in_frame += SAMPLES_PER_FRAME;
continue;
}

View File

@@ -93,8 +93,10 @@ public:
constexpr s32 clev{707}; // center mixing level coefficient
constexpr s32 slev{707}; // surround mixing level coefficient
buf.push_back(left + (clev * center / 1000) + (slev * surround_left / 1000));
buf.push_back(right + (clev * center / 1000) + (slev * surround_right / 1000));
buf.push_back(static_cast<s16>(left + (clev * center / 1000) +
(slev * surround_left / 1000)));
buf.push_back(static_cast<s16>(right + (clev * center / 1000) +
(slev * surround_right / 1000)));
}
queue.Push(buf);
return;

View File

@@ -128,7 +128,10 @@ void ServerVoiceInfo::UpdateParameters(const VoiceInfo::InParams& voice_in,
in_params.wave_buffer_count = voice_in.wave_buffer_count;
in_params.wave_bufffer_head = voice_in.wave_buffer_head;
if (behavior_info.IsFlushVoiceWaveBuffersSupported()) {
in_params.wave_buffer_flush_request_count += voice_in.wave_buffer_flush_request_count;
const auto in_request_count = in_params.wave_buffer_flush_request_count;
const auto voice_request_count = voice_in.wave_buffer_flush_request_count;
in_params.wave_buffer_flush_request_count =
static_cast<u8>(in_request_count + voice_request_count);
}
in_params.mix_id = voice_in.mix_id;
if (behavior_info.IsSplitterSupported()) {

View File

@@ -16,14 +16,14 @@ namespace Common {
[[nodiscard]] constexpr u8 ToHexNibble(char c) {
if (c >= 65 && c <= 70) {
return c - 55;
return static_cast<u8>(c - 55);
}
if (c >= 97 && c <= 102) {
return c - 87;
return static_cast<u8>(c - 87);
}
return c - 48;
return static_cast<u8>(c - 48);
}
[[nodiscard]] std::vector<u8> HexStringToVector(std::string_view str, bool little_endian);
@@ -33,11 +33,11 @@ template <std::size_t Size, bool le = false>
std::array<u8, Size> out{};
if constexpr (le) {
for (std::size_t i = 2 * Size - 2; i <= 2 * Size; i -= 2) {
out[i / 2] = (ToHexNibble(str[i]) << 4) | ToHexNibble(str[i + 1]);
out[i / 2] = static_cast<u8>((ToHexNibble(str[i]) << 4) | ToHexNibble(str[i + 1]));
}
} else {
for (std::size_t i = 0; i < 2 * Size; i += 2) {
out[i / 2] = (ToHexNibble(str[i]) << 4) | ToHexNibble(str[i + 1]);
out[i / 2] = static_cast<u8>((ToHexNibble(str[i]) << 4) | ToHexNibble(str[i + 1]));
}
}
return out;

View File

@@ -20,8 +20,8 @@ struct Rectangle {
constexpr Rectangle() = default;
constexpr Rectangle(T left, T top, T right, T bottom)
: left(left), top(top), right(right), bottom(bottom) {}
constexpr Rectangle(T left_, T top_, T right_, T bottom_)
: left(left_), top(top_), right(right_), bottom(bottom_) {}
[[nodiscard]] T GetWidth() const {
if constexpr (std::is_floating_point_v<T>) {

View File

@@ -87,7 +87,13 @@ public:
template <typename V>
[[nodiscard]] constexpr Vec2<decltype(T{} * V{})> operator*(const V& f) const {
return {x * f, y * f};
using TV = decltype(T{} * V{});
using C = std::common_type_t<T, V>;
return {
static_cast<TV>(static_cast<C>(x) * static_cast<C>(f)),
static_cast<TV>(static_cast<C>(y) * static_cast<C>(f)),
};
}
template <typename V>
@@ -98,7 +104,13 @@ public:
template <typename V>
[[nodiscard]] constexpr Vec2<decltype(T{} / V{})> operator/(const V& f) const {
return {x / f, y / f};
using TV = decltype(T{} / V{});
using C = std::common_type_t<T, V>;
return {
static_cast<TV>(static_cast<C>(x) / static_cast<C>(f)),
static_cast<TV>(static_cast<C>(y) / static_cast<C>(f)),
};
}
template <typename V>
@@ -168,7 +180,10 @@ public:
template <typename T, typename V>
[[nodiscard]] constexpr Vec2<T> operator*(const V& f, const Vec2<T>& vec) {
return Vec2<T>(f * vec.x, f * vec.y);
using C = std::common_type_t<T, V>;
return Vec2<T>(static_cast<T>(static_cast<C>(f) * static_cast<C>(vec.x)),
static_cast<T>(static_cast<C>(f) * static_cast<C>(vec.y)));
}
using Vec2f = Vec2<float>;
@@ -237,7 +252,14 @@ public:
template <typename V>
[[nodiscard]] constexpr Vec3<decltype(T{} * V{})> operator*(const V& f) const {
return {x * f, y * f, z * f};
using TV = decltype(T{} * V{});
using C = std::common_type_t<T, V>;
return {
static_cast<TV>(static_cast<C>(x) * static_cast<C>(f)),
static_cast<TV>(static_cast<C>(y) * static_cast<C>(f)),
static_cast<TV>(static_cast<C>(z) * static_cast<C>(f)),
};
}
template <typename V>
@@ -247,7 +269,14 @@ public:
}
template <typename V>
[[nodiscard]] constexpr Vec3<decltype(T{} / V{})> operator/(const V& f) const {
return {x / f, y / f, z / f};
using TV = decltype(T{} / V{});
using C = std::common_type_t<T, V>;
return {
static_cast<TV>(static_cast<C>(x) / static_cast<C>(f)),
static_cast<TV>(static_cast<C>(y) / static_cast<C>(f)),
static_cast<TV>(static_cast<C>(z) / static_cast<C>(f)),
};
}
template <typename V>
@@ -367,7 +396,11 @@ public:
template <typename T, typename V>
[[nodiscard]] constexpr Vec3<T> operator*(const V& f, const Vec3<T>& vec) {
return Vec3<T>(f * vec.x, f * vec.y, f * vec.z);
using C = std::common_type_t<T, V>;
return Vec3<T>(static_cast<T>(static_cast<C>(f) * static_cast<C>(vec.x)),
static_cast<T>(static_cast<C>(f) * static_cast<C>(vec.y)),
static_cast<T>(static_cast<C>(f) * static_cast<C>(vec.z)));
}
template <>
@@ -446,7 +479,15 @@ public:
template <typename V>
[[nodiscard]] constexpr Vec4<decltype(T{} * V{})> operator*(const V& f) const {
return {x * f, y * f, z * f, w * f};
using TV = decltype(T{} * V{});
using C = std::common_type_t<T, V>;
return {
static_cast<TV>(static_cast<C>(x) * static_cast<C>(f)),
static_cast<TV>(static_cast<C>(y) * static_cast<C>(f)),
static_cast<TV>(static_cast<C>(z) * static_cast<C>(f)),
static_cast<TV>(static_cast<C>(w) * static_cast<C>(f)),
};
}
template <typename V>
@@ -457,7 +498,15 @@ public:
template <typename V>
[[nodiscard]] constexpr Vec4<decltype(T{} / V{})> operator/(const V& f) const {
return {x / f, y / f, z / f, w / f};
using TV = decltype(T{} / V{});
using C = std::common_type_t<T, V>;
return {
static_cast<TV>(static_cast<C>(x) / static_cast<C>(f)),
static_cast<TV>(static_cast<C>(y) / static_cast<C>(f)),
static_cast<TV>(static_cast<C>(z) / static_cast<C>(f)),
static_cast<TV>(static_cast<C>(w) / static_cast<C>(f)),
};
}
template <typename V>
@@ -582,7 +631,15 @@ public:
template <typename T, typename V>
[[nodiscard]] constexpr Vec4<decltype(V{} * T{})> operator*(const V& f, const Vec4<T>& vec) {
return {f * vec.x, f * vec.y, f * vec.z, f * vec.w};
using TV = decltype(V{} * T{});
using C = std::common_type_t<T, V>;
return {
static_cast<TV>(static_cast<C>(f) * static_cast<C>(vec.x)),
static_cast<TV>(static_cast<C>(f) * static_cast<C>(vec.y)),
static_cast<TV>(static_cast<C>(f) * static_cast<C>(vec.z)),
static_cast<TV>(static_cast<C>(f) * static_cast<C>(vec.w)),
};
}
using Vec4f = Vec4<float>;

View File

@@ -1,9 +1,3 @@
if (YUZU_ENABLE_BOXCAT)
set(BCAT_BOXCAT_ADDITIONAL_SOURCES hle/service/bcat/backend/boxcat.cpp hle/service/bcat/backend/boxcat.h)
else()
set(BCAT_BOXCAT_ADDITIONAL_SOURCES)
endif()
add_library(core STATIC
arm/arm_interface.h
arm/arm_interface.cpp
@@ -303,7 +297,6 @@ add_library(core STATIC
hle/service/audio/hwopus.h
hle/service/bcat/backend/backend.cpp
hle/service/bcat/backend/backend.h
${BCAT_BOXCAT_ADDITIONAL_SOURCES}
hle/service/bcat/bcat.cpp
hle/service/bcat/bcat.h
hle/service/bcat/module.cpp
@@ -608,6 +601,13 @@ add_library(core STATIC
tools/freezer.h
)
if (YUZU_ENABLE_BOXCAT)
target_sources(core PRIVATE
hle/service/bcat/backend/boxcat.cpp
hle/service/bcat/backend/boxcat.h
)
endif()
if (MSVC)
target_compile_options(core PRIVATE
# 'expression' : signed/unsigned mismatch
@@ -623,6 +623,17 @@ if (MSVC)
# 'context' : truncation from 'type1' to 'type2'
/we4305
)
else()
target_compile_options(core PRIVATE
-Werror=conversion
-Werror=ignored-qualifiers
-Werror=implicit-fallthrough
-Werror=reorder
-Werror=sign-compare
-Werror=unused-but-set-parameter
-Werror=unused-but-set-variable
-Werror=unused-variable
)
endif()
create_target_directory_groups(core)

View File

@@ -411,7 +411,7 @@ Loader::ResultStatus DeriveSDKeys(std::array<Key256, 2>& sd_keys, KeyManager& ke
// Combine sources and seed
for (auto& source : sd_key_sources) {
for (std::size_t i = 0; i < source.size(); ++i) {
source[i] ^= sd_seed[i & 0xF];
source[i] = static_cast<u8>(source[i] ^ sd_seed[i & 0xF]);
}
}

View File

@@ -266,8 +266,9 @@ std::multimap<u64, VirtualFile> RomFSBuildContext::Build() {
cur_file->offset = file_partition_size;
file_partition_size += cur_file->size;
cur_file->entry_offset = entry_offset;
entry_offset += sizeof(RomFSFileEntry) +
Common::AlignUp(cur_file->path_len - cur_file->cur_path_ofs, 4);
entry_offset +=
static_cast<u32>(sizeof(RomFSFileEntry) +
Common::AlignUp(cur_file->path_len - cur_file->cur_path_ofs, 4));
prev_file = cur_file;
}
// Assign deferred parent/sibling ownership.
@@ -284,8 +285,9 @@ std::multimap<u64, VirtualFile> RomFSBuildContext::Build() {
for (const auto& it : directories) {
cur_dir = it.second;
cur_dir->entry_offset = entry_offset;
entry_offset += sizeof(RomFSDirectoryEntry) +
Common::AlignUp(cur_dir->path_len - cur_dir->cur_path_ofs, 4);
entry_offset +=
static_cast<u32>(sizeof(RomFSDirectoryEntry) +
Common::AlignUp(cur_dir->path_len - cur_dir->cur_path_ofs, 4));
}
// Assign deferred parent/sibling ownership.
for (auto it = directories.rbegin(); it->second != root; ++it) {

View File

@@ -299,7 +299,7 @@ void IPSwitchCompiler::Parse() {
patch_text->GetName(), offset, Common::HexToString(replace));
}
patch.records.insert_or_assign(offset, std::move(replace));
patch.records.insert_or_assign(static_cast<u32>(offset), std::move(replace));
}
patches.push_back(std::move(patch));

View File

@@ -108,7 +108,7 @@ std::vector<u8> CNMT::Serialize() const {
memcpy(out.data() + sizeof(CNMTHeader), &opt_header, sizeof(OptionalHeader));
}
auto offset = header.table_offset;
u64_le offset = header.table_offset;
for (const auto& rec : content_records) {
memcpy(out.data() + offset + sizeof(CNMTHeader), &rec, sizeof(ContentRecord));

View File

@@ -29,7 +29,7 @@
namespace FileSys {
namespace {
constexpr u64 SINGLE_BYTE_MODULUS = 0x100;
constexpr u32 SINGLE_BYTE_MODULUS = 0x100;
constexpr u64 DLC_BASE_TITLE_ID_MASK = 0xFFFFFFFFFFFFE000;
constexpr std::array<const char*, 14> EXEFS_FILE_NAMES{

View File

@@ -19,38 +19,6 @@
#include "core/loader/loader.h"
namespace FileSys {
namespace {
void SetTicketKeys(const std::vector<VirtualFile>& files) {
auto& keys = Core::Crypto::KeyManager::Instance();
for (const auto& ticket_file : files) {
if (ticket_file == nullptr) {
continue;
}
if (ticket_file->GetExtension() != "tik") {
continue;
}
if (ticket_file->GetSize() <
Core::Crypto::TICKET_FILE_TITLEKEY_OFFSET + sizeof(Core::Crypto::Key128)) {
continue;
}
Core::Crypto::Key128 key{};
ticket_file->Read(key.data(), key.size(), Core::Crypto::TICKET_FILE_TITLEKEY_OFFSET);
// We get the name without the extension in order to create the rights ID.
std::string name_only(ticket_file->GetName());
name_only.erase(name_only.size() - 4);
const auto rights_id_raw = Common::HexStringToArray<16>(name_only);
u128 rights_id;
std::memcpy(rights_id.data(), rights_id_raw.data(), sizeof(u128));
keys.SetKey(Core::Crypto::S128KeyType::Titlekey, key, rights_id[1], rights_id[0]);
}
}
} // Anonymous namespace
NSP::NSP(VirtualFile file_)
: file(std::move(file_)), status{Loader::ResultStatus::Success},
@@ -232,6 +200,35 @@ VirtualDir NSP::GetParentDirectory() const {
return file->GetContainingDirectory();
}
void NSP::SetTicketKeys(const std::vector<VirtualFile>& files) {
for (const auto& ticket_file : files) {
if (ticket_file == nullptr) {
continue;
}
if (ticket_file->GetExtension() != "tik") {
continue;
}
if (ticket_file->GetSize() <
Core::Crypto::TICKET_FILE_TITLEKEY_OFFSET + sizeof(Core::Crypto::Key128)) {
continue;
}
Core::Crypto::Key128 key{};
ticket_file->Read(key.data(), key.size(), Core::Crypto::TICKET_FILE_TITLEKEY_OFFSET);
// We get the name without the extension in order to create the rights ID.
std::string name_only(ticket_file->GetName());
name_only.erase(name_only.size() - 4);
const auto rights_id_raw = Common::HexStringToArray<16>(name_only);
u128 rights_id;
std::memcpy(rights_id.data(), rights_id_raw.data(), sizeof(u128));
keys.SetKey(Core::Crypto::S128KeyType::Titlekey, key, rights_id[1], rights_id[0]);
}
}
void NSP::InitializeExeFSAndRomFS(const std::vector<VirtualFile>& files) {
exefs = pfs;

View File

@@ -63,6 +63,7 @@ public:
VirtualDir GetParentDirectory() const override;
private:
void SetTicketKeys(const std::vector<VirtualFile>& files);
void InitializeExeFSAndRomFS(const std::vector<VirtualFile>& files);
void ReadNCAs(const std::vector<VirtualFile>& files);

View File

@@ -84,10 +84,12 @@ void EmuWindow::TouchPressed(unsigned framebuffer_x, unsigned framebuffer_y) {
return;
std::lock_guard guard{touch_state->mutex};
touch_state->touch_x = static_cast<float>(framebuffer_x - framebuffer_layout.screen.left) /
(framebuffer_layout.screen.right - framebuffer_layout.screen.left);
touch_state->touch_y = static_cast<float>(framebuffer_y - framebuffer_layout.screen.top) /
(framebuffer_layout.screen.bottom - framebuffer_layout.screen.top);
touch_state->touch_x =
static_cast<float>(framebuffer_x - framebuffer_layout.screen.left) /
static_cast<float>(framebuffer_layout.screen.right - framebuffer_layout.screen.left);
touch_state->touch_y =
static_cast<float>(framebuffer_y - framebuffer_layout.screen.top) /
static_cast<float>(framebuffer_layout.screen.bottom - framebuffer_layout.screen.top);
touch_state->touch_pressed = true;
}

View File

@@ -14,8 +14,8 @@ namespace Layout {
template <class T>
static Common::Rectangle<T> MaxRectangle(Common::Rectangle<T> window_area,
float screen_aspect_ratio) {
float scale = std::min(static_cast<float>(window_area.GetWidth()),
window_area.GetHeight() / screen_aspect_ratio);
const float scale = std::min(static_cast<float>(window_area.GetWidth()),
static_cast<float>(window_area.GetHeight()) / screen_aspect_ratio);
return Common::Rectangle<T>{0, 0, static_cast<T>(std::round(scale)),
static_cast<T>(std::round(scale * screen_aspect_ratio))};
}
@@ -27,7 +27,7 @@ FramebufferLayout DefaultFrameLayout(u32 width, u32 height) {
// so just calculate them both even if the other isn't showing.
FramebufferLayout res{width, height, false, {}};
const float window_aspect_ratio = static_cast<float>(height) / width;
const float window_aspect_ratio = static_cast<float>(height) / static_cast<float>(width);
const float emulation_aspect_ratio = EmulationAspectRatio(
static_cast<AspectRatio>(Settings::values.aspect_ratio.GetValue()), window_aspect_ratio);

View File

@@ -291,11 +291,11 @@ static void FpuWrite(std::size_t id, u128 val, Kernel::Thread* thread = nullptr)
*/
static u8 HexCharToValue(u8 hex) {
if (hex >= '0' && hex <= '9') {
return hex - '0';
return static_cast<u8>(hex - '0');
} else if (hex >= 'a' && hex <= 'f') {
return hex - 'a' + 0xA;
return static_cast<u8>(hex - 'a' + 0xA);
} else if (hex >= 'A' && hex <= 'F') {
return hex - 'A' + 0xA;
return static_cast<u8>(hex - 'A' + 0xA);
}
LOG_ERROR(Debug_GDBStub, "Invalid nibble: {} ({:02X})", hex, hex);
@@ -310,9 +310,9 @@ static u8 HexCharToValue(u8 hex) {
static u8 NibbleToHex(u8 n) {
n &= 0xF;
if (n < 0xA) {
return '0' + n;
return static_cast<u8>('0' + n);
} else {
return 'a' + n - 0xA;
return static_cast<u8>('a' + n - 0xA);
}
}
@@ -355,8 +355,8 @@ static u64 HexToLong(const u8* src, std::size_t len) {
*/
static void MemToGdbHex(u8* dest, const u8* src, std::size_t len) {
while (len-- > 0) {
u8 tmp = *src++;
*dest++ = NibbleToHex(tmp >> 4);
const u8 tmp = *src++;
*dest++ = NibbleToHex(static_cast<u8>(tmp >> 4));
*dest++ = NibbleToHex(tmp);
}
}
@@ -370,7 +370,7 @@ static void MemToGdbHex(u8* dest, const u8* src, std::size_t len) {
*/
static void GdbHexToMem(u8* dest, const u8* src, std::size_t len) {
while (len-- > 0) {
*dest++ = (HexCharToValue(src[0]) << 4) | HexCharToValue(src[1]);
*dest++ = static_cast<u8>((HexCharToValue(src[0]) << 4) | HexCharToValue(src[1]));
src += 2;
}
}
@@ -602,22 +602,22 @@ static void SendReply(const char* reply) {
memcpy(command_buffer + 1, reply, command_length);
u8 checksum = CalculateChecksum(command_buffer, command_length + 1);
const u8 checksum = CalculateChecksum(command_buffer, command_length + 1);
command_buffer[0] = GDB_STUB_START;
command_buffer[command_length + 1] = GDB_STUB_END;
command_buffer[command_length + 2] = NibbleToHex(checksum >> 4);
command_buffer[command_length + 2] = NibbleToHex(static_cast<u8>(checksum >> 4));
command_buffer[command_length + 3] = NibbleToHex(checksum);
u8* ptr = command_buffer;
u32 left = command_length + 4;
while (left > 0) {
int sent_size = send(gdbserver_socket, reinterpret_cast<char*>(ptr), left, 0);
const auto sent_size = send(gdbserver_socket, reinterpret_cast<char*>(ptr), left, 0);
if (sent_size < 0) {
LOG_ERROR(Debug_GDBStub, "gdb: send failed");
return Shutdown();
}
left -= sent_size;
left -= static_cast<u32>(sent_size);
ptr += sent_size;
}
}
@@ -777,10 +777,10 @@ static void ReadCommand() {
command_buffer[command_length++] = c;
}
u8 checksum_received = HexCharToValue(ReadByte()) << 4;
checksum_received |= HexCharToValue(ReadByte());
auto checksum_received = static_cast<u32>(HexCharToValue(ReadByte()) << 4);
checksum_received |= static_cast<u32>(HexCharToValue(ReadByte()));
u8 checksum_calculated = CalculateChecksum(command_buffer, command_length);
const u32 checksum_calculated = CalculateChecksum(command_buffer, command_length);
if (checksum_received != checksum_calculated) {
LOG_ERROR(Debug_GDBStub,

View File

@@ -38,10 +38,11 @@ public:
explicit RequestHelperBase(Kernel::HLERequestContext& context)
: context(&context), cmdbuf(context.CommandBuffer()) {}
void Skip(unsigned size_in_words, bool set_to_null) {
if (set_to_null)
void Skip(u32 size_in_words, bool set_to_null) {
if (set_to_null) {
memset(cmdbuf + index, 0, size_in_words * sizeof(u32));
index += size_in_words;
}
index += static_cast<ptrdiff_t>(size_in_words);
}
/**
@@ -49,15 +50,15 @@ public:
*/
void AlignWithPadding() {
if (index & 3) {
Skip(4 - (index & 3), true);
Skip(static_cast<u32>(4 - (index & 3)), true);
}
}
unsigned GetCurrentOffset() const {
return static_cast<unsigned>(index);
u32 GetCurrentOffset() const {
return static_cast<u32>(index);
}
void SetCurrentOffset(unsigned offset) {
void SetCurrentOffset(u32 offset) {
index = static_cast<ptrdiff_t>(offset);
}
};
@@ -89,7 +90,7 @@ public:
// The entire size of the raw data section in u32 units, including the 16 bytes of mandatory
// padding.
u32 raw_data_size = sizeof(IPC::DataPayloadHeader) / 4 + 4 + normal_params_size;
u64 raw_data_size = sizeof(IPC::DataPayloadHeader) / 4 + 4 + normal_params_size;
u32 num_handles_to_move{};
u32 num_domain_objects{};
@@ -105,7 +106,7 @@ public:
raw_data_size += sizeof(DomainMessageHeader) / 4 + num_domain_objects;
}
header.data_size.Assign(raw_data_size);
header.data_size.Assign(static_cast<u32>(raw_data_size));
if (num_handles_to_copy || num_handles_to_move) {
header.enable_handle_descriptor.Assign(1);
}

View File

@@ -118,7 +118,7 @@ std::shared_ptr<Object> HandleTable::GetGeneric(Handle handle) const {
void HandleTable::Clear() {
for (u16 i = 0; i < table_size; ++i) {
generations[i] = i + 1;
generations[i] = static_cast<u16>(i + 1);
objects[i] = nullptr;
}
next_free_slot = 0;

View File

@@ -72,7 +72,7 @@ u32 GlobalScheduler::SelectThreads() {
if (top_thread != nullptr) {
// TODO(Blinkhawk): Implement Thread Pinning
} else {
idle_cores |= (1ul << core);
idle_cores |= (1U << core);
}
top_threads[core] = top_thread;
}
@@ -126,7 +126,7 @@ u32 GlobalScheduler::SelectThreads() {
top_threads[core_id] = suggested;
}
idle_cores &= ~(1ul << core_id);
idle_cores &= ~(1U << core_id);
}
u32 cores_needing_context_switch{};
for (u32 core = 0; core < Core::Hardware::NUM_CPU_CORES; core++) {
@@ -134,7 +134,7 @@ u32 GlobalScheduler::SelectThreads() {
ASSERT(top_threads[core] == nullptr ||
static_cast<u32>(top_threads[core]->GetProcessorID()) == core);
if (update_thread(top_threads[core], sched)) {
cores_needing_context_switch |= (1ul << core);
cores_needing_context_switch |= (1U << core);
}
}
return cores_needing_context_switch;
@@ -364,7 +364,7 @@ void GlobalScheduler::EnableInterruptAndSchedule(u32 cores_pending_reschedule,
} else {
must_context_switch = true;
}
cores_pending_reschedule &= ~(1ul << core);
cores_pending_reschedule &= ~(1U << core);
}
if (must_context_switch) {
auto& core_scheduler = kernel.CurrentScheduler();
@@ -767,7 +767,7 @@ void Scheduler::SwitchToCurrent() {
current_thread->context_guard.unlock();
break;
}
if (current_thread->GetProcessorID() != core_id) {
if (static_cast<u32>(current_thread->GetProcessorID()) != core_id) {
current_thread->context_guard.unlock();
break;
}

View File

@@ -496,7 +496,7 @@ public:
{3, nullptr, "LoadIdTokenCache"},
{130, nullptr, "GetNintendoAccountUserResourceCacheForApplication"},
{150, nullptr, "CreateAuthorizationRequest"},
{160, nullptr, "StoreOpenContext"},
{160, &IManagerForApplication::StoreOpenContext, "StoreOpenContext"},
{170, nullptr, "LoadNetworkServiceLicenseKindAsync"},
};
// clang-format on
@@ -520,6 +520,12 @@ private:
rb.PushRaw<u64>(user_id.GetNintendoID());
}
void StoreOpenContext(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_ACC, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
Common::UUID user_id;
};

View File

@@ -196,7 +196,9 @@ private:
const std::string& content_type_name) {
if (client == nullptr) {
client = std::make_unique<httplib::SSLClient>(BOXCAT_HOSTNAME, PORT);
client->set_timeout_sec(timeout_seconds);
client->set_connection_timeout(timeout_seconds);
client->set_read_timeout(timeout_seconds);
client->set_write_timeout(timeout_seconds);
}
httplib::Headers headers{
@@ -255,7 +257,7 @@ private:
return out;
}
std::unique_ptr<httplib::Client> client;
std::unique_ptr<httplib::SSLClient> client;
std::string path;
u64 title_id;
u64 build_id;
@@ -443,13 +445,25 @@ std::optional<std::vector<u8>> Boxcat::GetLaunchParameter(TitleIDVersion title)
Boxcat::StatusResult Boxcat::GetStatus(std::optional<std::string>& global,
std::map<std::string, EventStatus>& games) {
httplib::SSLClient client{BOXCAT_HOSTNAME, static_cast<int>(PORT)};
client.set_timeout_sec(static_cast<int>(TIMEOUT_SECONDS));
client.set_connection_timeout(static_cast<int>(TIMEOUT_SECONDS));
client.set_read_timeout(static_cast<int>(TIMEOUT_SECONDS));
client.set_write_timeout(static_cast<int>(TIMEOUT_SECONDS));
httplib::Headers headers{
{std::string("Game-Assets-API-Version"), std::string(BOXCAT_API_VERSION)},
{std::string("Boxcat-Client-Type"), std::string(BOXCAT_CLIENT_TYPE)},
};
if (!client.is_valid()) {
LOG_ERROR(Service_BCAT, "Client is invalid, going offline!");
return StatusResult::Offline;
}
if (!client.is_socket_open()) {
LOG_ERROR(Service_BCAT, "Failed to open socket, going offline!");
return StatusResult::Offline;
}
const auto response = client.Get(BOXCAT_PATHNAME_EVENTS, headers);
if (response == nullptr)
return StatusResult::Offline;

View File

@@ -42,8 +42,8 @@ void Controller_Keyboard::OnUpdate(const Core::Timing::CoreTiming& core_timing,
cur_entry.modifier = 0;
if (Settings::values.keyboard_enabled) {
for (std::size_t i = 0; i < keyboard_keys.size(); ++i) {
cur_entry.key[i / KEYS_PER_BYTE] |=
(keyboard_keys[i]->GetStatus() << (i % KEYS_PER_BYTE));
auto& entry = cur_entry.key[i / KEYS_PER_BYTE];
entry = static_cast<u8>(entry | (keyboard_keys[i]->GetStatus() << (i % KEYS_PER_BYTE)));
}
for (std::size_t i = 0; i < keyboard_mods.size(); ++i) {

View File

@@ -269,7 +269,6 @@ void Controller_NPad::RequestPadStateUpdate(u32 npad_id) {
auto& rstick_entry = npad_pad_states[controller_idx].r_stick;
const auto& button_state = buttons[controller_idx];
const auto& analog_state = sticks[controller_idx];
const auto& motion_state = motions[controller_idx];
const auto [stick_l_x_f, stick_l_y_f] =
analog_state[static_cast<std::size_t>(JoystickId::Joystick_Left)]->GetStatus();
const auto [stick_r_x_f, stick_r_y_f] =
@@ -391,18 +390,6 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
libnx_entry.connection_status.raw = 0;
libnx_entry.connection_status.IsConnected.Assign(1);
auto& full_sixaxis_entry =
npad.sixaxis_full.sixaxis[npad.sixaxis_full.common.last_entry_index];
auto& handheld_sixaxis_entry =
npad.sixaxis_handheld.sixaxis[npad.sixaxis_handheld.common.last_entry_index];
auto& dual_left_sixaxis_entry =
npad.sixaxis_dual_left.sixaxis[npad.sixaxis_dual_left.common.last_entry_index];
auto& dual_right_sixaxis_entry =
npad.sixaxis_dual_right.sixaxis[npad.sixaxis_dual_right.common.last_entry_index];
auto& left_sixaxis_entry =
npad.sixaxis_left.sixaxis[npad.sixaxis_left.common.last_entry_index];
auto& right_sixaxis_entry =
npad.sixaxis_right.sixaxis[npad.sixaxis_right.common.last_entry_index];
switch (controller_type) {
case NPadControllerType::None:
@@ -541,18 +528,6 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing
}
}
auto& main_controller =
npad.main_controller_states.npad[npad.main_controller_states.common.last_entry_index];
auto& handheld_entry =
npad.handheld_states.npad[npad.handheld_states.common.last_entry_index];
auto& dual_entry = npad.dual_states.npad[npad.dual_states.common.last_entry_index];
auto& left_entry = npad.left_joy_states.npad[npad.left_joy_states.common.last_entry_index];
auto& right_entry =
npad.right_joy_states.npad[npad.right_joy_states.common.last_entry_index];
auto& pokeball_entry =
npad.pokeball_states.npad[npad.pokeball_states.common.last_entry_index];
auto& libnx_entry = npad.libnx.npad[npad.libnx.common.last_entry_index];
auto& full_sixaxis_entry =
npad.sixaxis_full.sixaxis[npad.sixaxis_full.common.last_entry_index];
auto& handheld_sixaxis_entry =

View File

@@ -475,7 +475,7 @@ void Hid::StopSixAxisSensor(Kernel::HLERequestContext& ctx) {
void Hid::EnableSixAxisSensorFusion(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto enable{rp.Pop<bool>()};
[[maybe_unused]] const auto enable{rp.Pop<bool>()};
const auto handle{rp.Pop<u32>()};
const auto applet_resource_user_id{rp.Pop<u64>()};

View File

@@ -131,7 +131,7 @@ template <typename T>
T GetRandomValue(T min, T max) {
std::random_device device;
std::mt19937 gen(device());
std::uniform_int_distribution<u64> distribution(0, static_cast<u64>(max));
std::uniform_int_distribution<u64> distribution(static_cast<u64>(min), static_cast<u64>(max));
return static_cast<T>(distribution(gen));
}
@@ -428,7 +428,7 @@ bool MiiManager::IsFullDatabase() const {
}
u32 MiiManager::GetCount(SourceFlag source_flag) const {
u32 count{};
std::size_t count{};
if ((source_flag & SourceFlag::Database) != SourceFlag::None) {
// TODO(bunnei): We don't implement the Mii database, but when we do, update this
count += 0;
@@ -436,7 +436,7 @@ u32 MiiManager::GetCount(SourceFlag source_flag) const {
if ((source_flag & SourceFlag::Default) != SourceFlag::None) {
count += DefaultMiiCount;
}
return count;
return static_cast<u32>(count);
}
ResultVal<MiiInfo> MiiManager::UpdateLatest([[maybe_unused]] const MiiInfo& info,

View File

@@ -99,6 +99,20 @@ void BufferQueue::QueueBuffer(u32 slot, BufferTransformFlags transform,
queue_sequence.push_back(slot);
}
void BufferQueue::CancelBuffer(u32 slot, const Service::Nvidia::MultiFence& multi_fence) {
const auto itr = std::find_if(queue.begin(), queue.end(),
[slot](const Buffer& buffer) { return buffer.slot == slot; });
ASSERT(itr != queue.end());
ASSERT(itr->status != Buffer::Status::Free);
itr->status = Buffer::Status::Free;
itr->multi_fence = multi_fence;
itr->swap_interval = 0;
free_buffers.push_back(slot);
buffer_wait_event.writable->Signal();
}
std::optional<std::reference_wrapper<const BufferQueue::Buffer>> BufferQueue::AcquireBuffer() {
auto itr = queue.end();
// Iterate to find a queued buffer matching the requested slot.

View File

@@ -95,6 +95,7 @@ public:
void QueueBuffer(u32 slot, BufferTransformFlags transform,
const Common::Rectangle<int>& crop_rect, u32 swap_interval,
Service::Nvidia::MultiFence& multi_fence);
void CancelBuffer(u32 slot, const Service::Nvidia::MultiFence& multi_fence);
std::optional<std::reference_wrapper<const Buffer>> AcquireBuffer();
void ReleaseBuffer(u32 slot);
void Disconnect();

View File

@@ -89,9 +89,9 @@ Network::Protocol Translate(Type type, Protocol protocol) {
}
}
u16 TranslatePollEventsToHost(u16 flags) {
u16 result = 0;
const auto translate = [&result, &flags](u16 from, u16 to) {
u16 TranslatePollEventsToHost(u32 flags) {
u32 result = 0;
const auto translate = [&result, &flags](u32 from, u32 to) {
if ((flags & from) != 0) {
flags &= ~from;
result |= to;
@@ -105,12 +105,12 @@ u16 TranslatePollEventsToHost(u16 flags) {
translate(POLL_NVAL, Network::POLL_NVAL);
UNIMPLEMENTED_IF_MSG(flags != 0, "Unimplemented flags={}", flags);
return result;
return static_cast<u16>(result);
}
u16 TranslatePollEventsToGuest(u16 flags) {
u16 result = 0;
const auto translate = [&result, &flags](u16 from, u16 to) {
u16 TranslatePollEventsToGuest(u32 flags) {
u32 result = 0;
const auto translate = [&result, &flags](u32 from, u32 to) {
if ((flags & from) != 0) {
flags &= ~from;
result |= to;
@@ -125,7 +125,7 @@ u16 TranslatePollEventsToGuest(u16 flags) {
translate(Network::POLL_NVAL, POLL_NVAL);
UNIMPLEMENTED_IF_MSG(flags != 0, "Unimplemented flags={}", flags);
return result;
return static_cast<u16>(result);
}
Network::SockAddrIn Translate(SockAddrIn value) {

View File

@@ -31,10 +31,10 @@ Network::Type Translate(Type type);
Network::Protocol Translate(Type type, Protocol protocol);
/// Translate abstract poll event flags to guest poll event flags
u16 TranslatePollEventsToHost(u16 flags);
u16 TranslatePollEventsToHost(u32 flags);
/// Translate guest poll event flags to abstract poll event flags
u16 TranslatePollEventsToGuest(u16 flags);
u16 TranslatePollEventsToGuest(u32 flags);
/// Translate guest socket address structure to abstract socket address structure
Network::SockAddrIn Translate(SockAddrIn value);

View File

@@ -820,7 +820,10 @@ static ResultCode ToCalendarTimeImpl(const TimeZoneRule& rules, s64 time, Calend
const ResultCode result{
ToCalendarTimeInternal(rules, time, calendar_time, calendar.additiona_info)};
calendar.time.year = static_cast<s16>(calendar_time.year);
calendar.time.month = calendar_time.month + 1; // Internal impl. uses 0-indexed month
// Internal impl. uses 0-indexed month
calendar.time.month = static_cast<s8>(calendar_time.month + 1);
calendar.time.day = calendar_time.day;
calendar.time.hour = calendar_time.hour;
calendar.time.minute = calendar_time.minute;
@@ -872,13 +875,15 @@ ResultCode TimeZoneManager::ToPosixTime(const TimeZoneRule& rules,
const CalendarTime& calendar_time, s64& posix_time) const {
posix_time = 0;
CalendarTimeInternal internal_time{};
internal_time.year = calendar_time.year;
internal_time.month = calendar_time.month - 1; // Internal impl. uses 0-indexed month
internal_time.day = calendar_time.day;
internal_time.hour = calendar_time.hour;
internal_time.minute = calendar_time.minute;
internal_time.second = calendar_time.second;
CalendarTimeInternal internal_time{
.year = calendar_time.year,
// Internal impl. uses 0-indexed month
.month = static_cast<s8>(calendar_time.month - 1),
.day = calendar_time.day,
.hour = calendar_time.hour,
.minute = calendar_time.minute,
.second = calendar_time.second,
};
s32 hour{internal_time.hour};
s32 minute{internal_time.minute};

View File

@@ -159,7 +159,7 @@ public:
header.data_size = static_cast<u32_le>(write_index - sizeof(Header));
header.data_offset = sizeof(Header);
header.objects_size = 4;
header.objects_offset = sizeof(Header) + header.data_size;
header.objects_offset = static_cast<u32>(sizeof(Header) + header.data_size);
std::memcpy(buffer.data(), &header, sizeof(Header));
return buffer;
@@ -215,10 +215,9 @@ public:
explicit IGBPConnectRequestParcel(std::vector<u8> buffer) : Parcel(std::move(buffer)) {
Deserialize();
}
~IGBPConnectRequestParcel() override = default;
void DeserializeData() override {
std::u16string token = ReadInterfaceToken();
[[maybe_unused]] const std::u16string token = ReadInterfaceToken();
data = Read<Data>();
}
@@ -279,10 +278,9 @@ public:
: Parcel(std::move(buffer)) {
Deserialize();
}
~IGBPSetPreallocatedBufferRequestParcel() override = default;
void DeserializeData() override {
std::u16string token = ReadInterfaceToken();
[[maybe_unused]] const std::u16string token = ReadInterfaceToken();
data = Read<Data>();
buffer = Read<NVFlinger::IGBPBuffer>();
}
@@ -306,15 +304,40 @@ protected:
}
};
class IGBPCancelBufferRequestParcel : public Parcel {
public:
explicit IGBPCancelBufferRequestParcel(std::vector<u8> buffer) : Parcel(std::move(buffer)) {
Deserialize();
}
void DeserializeData() override {
[[maybe_unused]] const std::u16string token = ReadInterfaceToken();
data = Read<Data>();
}
struct Data {
u32_le slot;
Service::Nvidia::MultiFence multi_fence;
};
Data data;
};
class IGBPCancelBufferResponseParcel : public Parcel {
protected:
void SerializeData() override {
Write<u32>(0); // Success
}
};
class IGBPDequeueBufferRequestParcel : public Parcel {
public:
explicit IGBPDequeueBufferRequestParcel(std::vector<u8> buffer) : Parcel(std::move(buffer)) {
Deserialize();
}
~IGBPDequeueBufferRequestParcel() override = default;
void DeserializeData() override {
std::u16string token = ReadInterfaceToken();
[[maybe_unused]] const std::u16string token = ReadInterfaceToken();
data = Read<Data>();
}
@@ -333,7 +356,6 @@ class IGBPDequeueBufferResponseParcel : public Parcel {
public:
explicit IGBPDequeueBufferResponseParcel(u32 slot, Service::Nvidia::MultiFence& multi_fence)
: slot(slot), multi_fence(multi_fence) {}
~IGBPDequeueBufferResponseParcel() override = default;
protected:
void SerializeData() override {
@@ -352,10 +374,9 @@ public:
explicit IGBPRequestBufferRequestParcel(std::vector<u8> buffer) : Parcel(std::move(buffer)) {
Deserialize();
}
~IGBPRequestBufferRequestParcel() override = default;
void DeserializeData() override {
std::u16string token = ReadInterfaceToken();
[[maybe_unused]] const std::u16string token = ReadInterfaceToken();
slot = Read<u32_le>();
}
@@ -384,10 +405,9 @@ public:
explicit IGBPQueueBufferRequestParcel(std::vector<u8> buffer) : Parcel(std::move(buffer)) {
Deserialize();
}
~IGBPQueueBufferRequestParcel() override = default;
void DeserializeData() override {
std::u16string token = ReadInterfaceToken();
[[maybe_unused]] const std::u16string token = ReadInterfaceToken();
data = Read<Data>();
}
@@ -447,10 +467,9 @@ public:
explicit IGBPQueryRequestParcel(std::vector<u8> buffer) : Parcel(std::move(buffer)) {
Deserialize();
}
~IGBPQueryRequestParcel() override = default;
void DeserializeData() override {
std::u16string token = ReadInterfaceToken();
[[maybe_unused]] const std::u16string token = ReadInterfaceToken();
type = Read<u32_le>();
}
@@ -596,7 +615,12 @@ private:
break;
}
case TransactionId::CancelBuffer: {
LOG_CRITICAL(Service_VI, "(STUBBED) called, transaction=CancelBuffer");
IGBPCancelBufferRequestParcel request{ctx.ReadBuffer()};
buffer_queue.CancelBuffer(request.data.slot, request.data.multi_fence);
IGBPCancelBufferResponseParcel response{};
ctx.WriteBuffer(response.Serialize());
break;
}
case TransactionId::Disconnect: {

View File

@@ -16,7 +16,7 @@ namespace Loader {
namespace {
constexpr u32 PageAlignSize(u32 size) {
return (size + Core::Memory::PAGE_MASK) & ~Core::Memory::PAGE_MASK;
return static_cast<u32>((size + Core::Memory::PAGE_MASK) & ~Core::Memory::PAGE_MASK);
}
} // Anonymous namespace

View File

@@ -127,7 +127,7 @@ FileType AppLoader_NRO::IdentifyType(const FileSys::VirtualFile& file) {
}
static constexpr u32 PageAlignSize(u32 size) {
return (size + Core::Memory::PAGE_MASK) & ~Core::Memory::PAGE_MASK;
return static_cast<u32>((size + Core::Memory::PAGE_MASK) & ~Core::Memory::PAGE_MASK);
}
static bool LoadNroImpl(Kernel::Process& process, const std::vector<u8>& data,

View File

@@ -47,7 +47,7 @@ std::vector<u8> DecompressSegment(const std::vector<u8>& compressed_data,
}
constexpr u32 PageAlignSize(u32 size) {
return (size + Core::Memory::PAGE_MASK) & ~Core::Memory::PAGE_MASK;
return static_cast<u32>((size + Core::Memory::PAGE_MASK) & ~Core::Memory::PAGE_MASK);
}
} // Anonymous namespace

View File

@@ -59,7 +59,7 @@ struct NSOHeader {
static_assert(sizeof(NSOHeader) == 0x100, "NSOHeader has incorrect size.");
static_assert(std::is_trivially_copyable_v<NSOHeader>, "NSOHeader must be trivially copyable.");
constexpr u64 NSO_ARGUMENT_DATA_ALLOCATION_SIZE = 0x9000;
constexpr u32 NSO_ARGUMENT_DATA_ALLOCATION_SIZE = 0x9000;
struct NSOArgumentHeader {
u32_le allocated_size;

View File

@@ -120,9 +120,9 @@ struct Memory::Impl {
if ((addr & 1) == 0) {
return Read<u16_le>(addr);
} else {
const u8 a{Read<u8>(addr)};
const u8 b{Read<u8>(addr + sizeof(u8))};
return (static_cast<u16>(b) << 8) | a;
const u32 a{Read<u8>(addr)};
const u32 b{Read<u8>(addr + sizeof(u8))};
return static_cast<u16>((b << 8) | a);
}
}
@@ -130,9 +130,9 @@ struct Memory::Impl {
if ((addr & 3) == 0) {
return Read<u32_le>(addr);
} else {
const u16 a{Read16(addr)};
const u16 b{Read16(addr + sizeof(u16))};
return (static_cast<u32>(b) << 16) | a;
const u32 a{Read16(addr)};
const u32 b{Read16(addr + sizeof(u16))};
return (b << 16) | a;
}
}

View File

@@ -153,8 +153,9 @@ std::vector<CheatEntry> TextCheatParser::Parse(std::string_view data) const {
return {};
}
const auto value = static_cast<u32>(std::stoul(hex, nullptr, 0x10));
out[*current_entry].definition.opcodes[out[*current_entry].definition.num_opcodes++] =
std::stoul(hex, nullptr, 0x10);
value;
i += 8;
} else {

View File

@@ -238,14 +238,14 @@ SockAddrIn TranslateToSockAddrIn(sockaddr input_) {
return result;
}
u16 TranslatePollEvents(u16 events) {
u16 result = 0;
u16 TranslatePollEvents(u32 events) {
u32 result = 0;
if (events & POLL_IN) {
if ((events & POLL_IN) != 0) {
events &= ~POLL_IN;
result |= POLLIN;
}
if (events & POLL_PRI) {
if ((events & POLL_PRI) != 0) {
events &= ~POLL_PRI;
#ifdef _WIN32
LOG_WARNING(Service, "Winsock doesn't support POLLPRI");
@@ -253,20 +253,20 @@ u16 TranslatePollEvents(u16 events) {
result |= POLL_PRI;
#endif
}
if (events & POLL_OUT) {
if ((events & POLL_OUT) != 0) {
events &= ~POLL_OUT;
result |= POLLOUT;
}
UNIMPLEMENTED_IF_MSG(events != 0, "Unhandled guest events=0x{:x}", events);
return result;
return static_cast<u16>(result);
}
u16 TranslatePollRevents(u16 revents) {
u16 result = 0;
const auto translate = [&result, &revents](int host, unsigned guest) {
if (revents & host) {
u16 TranslatePollRevents(u32 revents) {
u32 result = 0;
const auto translate = [&result, &revents](u32 host, u32 guest) {
if ((revents & host) != 0) {
revents &= ~host;
result |= guest;
}
@@ -280,7 +280,7 @@ u16 TranslatePollRevents(u16 revents) {
UNIMPLEMENTED_IF_MSG(revents != 0, "Unhandled host revents=0x{:x}", revents);
return result;
return static_cast<u16>(result);
}
template <typename T>
@@ -350,7 +350,7 @@ std::pair<s32, Errno> Poll(std::vector<PollFD>& pollfds, s32 timeout) {
}
for (size_t i = 0; i < num; ++i) {
pollfds[i].revents = TranslatePollRevents(host_pollfds[i].revents);
pollfds[i].revents = TranslatePollRevents(static_cast<u32>(host_pollfds[i].revents));
}
if (result > 0) {
@@ -408,7 +408,7 @@ std::pair<Socket::AcceptResult, Errno> Socket::Accept() {
Errno Socket::Connect(SockAddrIn addr_in) {
const sockaddr host_addr_in = TranslateFromSockAddrIn(addr_in);
if (connect(fd, &host_addr_in, sizeof(host_addr_in)) != INVALID_SOCKET) {
if (connect(fd, &host_addr_in, sizeof(host_addr_in)) != SOCKET_ERROR) {
return Errno::SUCCESS;
}
@@ -503,10 +503,10 @@ std::pair<s32, Errno> Socket::Recv(int flags, std::vector<u8>& message) {
ASSERT(flags == 0);
ASSERT(message.size() < static_cast<size_t>(std::numeric_limits<int>::max()));
const int result =
const auto result =
recv(fd, reinterpret_cast<char*>(message.data()), static_cast<int>(message.size()), 0);
if (result != SOCKET_ERROR) {
return {result, Errno::SUCCESS};
return {static_cast<s32>(result), Errno::SUCCESS};
}
switch (const int ec = LastError()) {
@@ -531,14 +531,14 @@ std::pair<s32, Errno> Socket::RecvFrom(int flags, std::vector<u8>& message, Sock
socklen_t* const p_addrlen = addr ? &addrlen : nullptr;
sockaddr* const p_addr_in = addr ? &addr_in : nullptr;
const int result = recvfrom(fd, reinterpret_cast<char*>(message.data()),
static_cast<int>(message.size()), 0, p_addr_in, p_addrlen);
const auto result = recvfrom(fd, reinterpret_cast<char*>(message.data()),
static_cast<int>(message.size()), 0, p_addr_in, p_addrlen);
if (result != SOCKET_ERROR) {
if (addr) {
ASSERT(addrlen == sizeof(addr_in));
*addr = TranslateToSockAddrIn(addr_in);
}
return {result, Errno::SUCCESS};
return {static_cast<s32>(result), Errno::SUCCESS};
}
switch (const int ec = LastError()) {
@@ -558,10 +558,10 @@ std::pair<s32, Errno> Socket::Send(const std::vector<u8>& message, int flags) {
ASSERT(message.size() < static_cast<size_t>(std::numeric_limits<int>::max()));
ASSERT(flags == 0);
const int result = send(fd, reinterpret_cast<const char*>(message.data()),
static_cast<int>(message.size()), 0);
const auto result = send(fd, reinterpret_cast<const char*>(message.data()),
static_cast<int>(message.size()), 0);
if (result != SOCKET_ERROR) {
return {result, Errno::SUCCESS};
return {static_cast<s32>(result), Errno::SUCCESS};
}
const int ec = LastError();
@@ -591,10 +591,10 @@ std::pair<s32, Errno> Socket::SendTo(u32 flags, const std::vector<u8>& message,
to = &host_addr_in;
}
const int result = sendto(fd, reinterpret_cast<const char*>(message.data()),
static_cast<int>(message.size()), 0, to, tolen);
const auto result = sendto(fd, reinterpret_cast<const char*>(message.data()),
static_cast<int>(message.size()), 0, to, tolen);
if (result != SOCKET_ERROR) {
return {result, Errno::SUCCESS};
return {static_cast<s32>(result), Errno::SUCCESS};
}
const int ec = LastError();

View File

@@ -29,6 +29,35 @@ add_library(input_common STATIC
udp/udp.h
)
if (MSVC)
target_compile_options(input_common PRIVATE
# 'expression' : signed/unsigned mismatch
/we4018
# 'argument' : conversion from 'type1' to 'type2', possible loss of data (floating-point)
/we4244
# 'conversion' : conversion from 'type1' to 'type2', signed/unsigned mismatch
/we4245
# 'operator': conversion from 'type1:field_bits' to 'type2:field_bits', possible loss of data
/we4254
# 'var' : conversion from 'size_t' to 'type', possible loss of data
/we4267
# 'context' : truncation from 'type1' to 'type2'
/we4305
)
else()
target_compile_options(input_common PRIVATE
-Werror=conversion
-Werror=ignored-qualifiers
-Werror=implicit-fallthrough
-Werror=reorder
-Werror=shadow
-Werror=sign-compare
-Werror=unused-but-set-parameter
-Werror=unused-but-set-variable
-Werror=unused-variable
)
endif()
if(SDL2_FOUND)
target_sources(input_common PRIVATE
sdl/sdl_impl.cpp

View File

@@ -20,18 +20,22 @@ public:
constexpr float SQRT_HALF = 0.707106781f;
int x = 0, y = 0;
if (right->GetStatus())
if (right->GetStatus()) {
++x;
if (left->GetStatus())
}
if (left->GetStatus()) {
--x;
if (up->GetStatus())
}
if (up->GetStatus()) {
++y;
if (down->GetStatus())
}
if (down->GetStatus()) {
--y;
}
float coef = modifier->GetStatus() ? modifier_scale : 1.0f;
return std::make_tuple(x * coef * (y == 0 ? 1.0f : SQRT_HALF),
y * coef * (x == 0 ? 1.0f : SQRT_HALF));
const float coef = modifier->GetStatus() ? modifier_scale : 1.0f;
return std::make_tuple(static_cast<float>(x) * coef * (y == 0 ? 1.0f : SQRT_HALF),
static_cast<float>(y) * coef * (x == 0 ? 1.0f : SQRT_HALF));
}
bool GetAnalogDirectionStatus(Input::AnalogDirection direction) const override {

View File

@@ -21,7 +21,7 @@
namespace GCAdapter {
/// Used to loop through and assign button in poller
// Used to loop through and assign button in poller
constexpr std::array<PadButton, 12> PadButtonArray{
PadButton::PAD_BUTTON_LEFT, PadButton::PAD_BUTTON_RIGHT, PadButton::PAD_BUTTON_DOWN,
PadButton::PAD_BUTTON_UP, PadButton::PAD_TRIGGER_Z, PadButton::PAD_TRIGGER_R,
@@ -29,6 +29,18 @@ constexpr std::array<PadButton, 12> PadButtonArray{
PadButton::PAD_BUTTON_X, PadButton::PAD_BUTTON_Y, PadButton::PAD_BUTTON_START,
};
static void PadToState(const GCPadStatus& pad, GCState& out_state) {
for (const auto& button : PadButtonArray) {
const auto button_key = static_cast<u16>(button);
const auto button_value = (pad.button & button_key) != 0;
out_state.buttons.insert_or_assign(static_cast<s32>(button_key), button_value);
}
for (std::size_t i = 0; i < pad.axis_values.size(); ++i) {
out_state.axes.insert_or_assign(static_cast<u32>(i), pad.axis_values[i]);
}
}
Adapter::Adapter() {
if (usb_adapter_handle != nullptr) {
return;
@@ -78,17 +90,17 @@ GCPadStatus Adapter::GetPadStatus(std::size_t port, const std::array<u8, 37>& ad
for (std::size_t i = 0; i < b1_buttons.size(); ++i) {
if ((b1 & (1U << i)) != 0) {
pad.button |= static_cast<u16>(b1_buttons[i]);
pad.button = static_cast<u16>(pad.button | static_cast<u16>(b1_buttons[i]));
}
}
for (std::size_t j = 0; j < b2_buttons.size(); ++j) {
if ((b2 & (1U << j)) != 0) {
pad.button |= static_cast<u16>(b2_buttons[j]);
pad.button = static_cast<u16>(pad.button | static_cast<u16>(b2_buttons[j]));
}
}
for (PadAxes axis : axes) {
const std::size_t index = static_cast<std::size_t>(axis);
const auto index = static_cast<std::size_t>(axis);
pad.axis_values[index] = adapter_payload[offset + 3 + index];
}
@@ -100,17 +112,6 @@ GCPadStatus Adapter::GetPadStatus(std::size_t port, const std::array<u8, 37>& ad
return pad;
}
void Adapter::PadToState(const GCPadStatus& pad, GCState& state) {
for (const auto& button : PadButtonArray) {
const u16 button_value = static_cast<u16>(button);
state.buttons.insert_or_assign(button_value, pad.button & button_value);
}
for (size_t i = 0; i < pad.axis_values.size(); ++i) {
state.axes.insert_or_assign(static_cast<u8>(i), pad.axis_values[i]);
}
}
void Adapter::Read() {
LOG_DEBUG(Input, "GC Adapter Read() thread started");
@@ -250,7 +251,7 @@ void Adapter::GetGCEndpoint(libusb_device* device) {
const libusb_interface_descriptor* interface = &interfaceContainer->altsetting[i];
for (u8 e = 0; e < interface->bNumEndpoints; e++) {
const libusb_endpoint_descriptor* endpoint = &interface->endpoint[e];
if (endpoint->bEndpointAddress & LIBUSB_ENDPOINT_IN) {
if ((endpoint->bEndpointAddress & LIBUSB_ENDPOINT_IN) != 0) {
input_endpoint = endpoint->bEndpointAddress;
} else {
output_endpoint = endpoint->bEndpointAddress;
@@ -419,7 +420,7 @@ const std::array<GCState, 4>& Adapter::GetPadState() const {
return state;
}
int Adapter::GetOriginValue(int port, int axis) const {
int Adapter::GetOriginValue(u32 port, u32 axis) const {
return origin_status[port].axis_values[axis];
}

View File

@@ -60,7 +60,7 @@ struct GCPadStatus {
struct GCState {
std::unordered_map<int, bool> buttons;
std::unordered_map<int, u16> axes;
std::unordered_map<u32, u16> axes;
};
enum class ControllerTypes { None, Wired, Wireless };
@@ -89,13 +89,11 @@ public:
std::array<GCState, 4>& GetPadState();
const std::array<GCState, 4>& GetPadState() const;
int GetOriginValue(int port, int axis) const;
int GetOriginValue(u32 port, u32 axis) const;
private:
GCPadStatus GetPadStatus(std::size_t port, const std::array<u8, 37>& adapter_payload);
void PadToState(const GCPadStatus& pad, GCState& state);
void Read();
/// Resets status of device connected to port

View File

@@ -15,7 +15,7 @@ namespace InputCommon {
class GCButton final : public Input::ButtonDevice {
public:
explicit GCButton(int port_, int button_, const GCAdapter::Adapter* adapter)
explicit GCButton(u32 port_, int button_, const GCAdapter::Adapter* adapter)
: port(port_), button(button_), gcadapter(adapter) {}
~GCButton() override;
@@ -28,14 +28,14 @@ public:
}
private:
const int port;
const u32 port;
const int button;
const GCAdapter::Adapter* gcadapter;
};
class GCAxisButton final : public Input::ButtonDevice {
public:
explicit GCAxisButton(int port_, int axis_, float threshold_, bool trigger_if_greater_,
explicit GCAxisButton(u32 port_, u32 axis_, float threshold_, bool trigger_if_greater_,
const GCAdapter::Adapter* adapter)
: port(port_), axis(axis_), threshold(threshold_), trigger_if_greater(trigger_if_greater_),
gcadapter(adapter),
@@ -56,8 +56,8 @@ public:
}
private:
const int port;
const int axis;
const u32 port;
const u32 axis;
float threshold;
bool trigger_if_greater;
const GCAdapter::Adapter* gcadapter;
@@ -70,8 +70,8 @@ GCButtonFactory::GCButtonFactory(std::shared_ptr<GCAdapter::Adapter> adapter_)
GCButton::~GCButton() = default;
std::unique_ptr<Input::ButtonDevice> GCButtonFactory::Create(const Common::ParamPackage& params) {
const int button_id = params.Get("button", 0);
const int port = params.Get("port", 0);
const auto button_id = params.Get("button", 0);
const auto port = static_cast<u32>(params.Get("port", 0));
constexpr int PAD_STICK_ID = static_cast<u16>(GCAdapter::PadButton::PAD_STICK);
@@ -149,25 +149,27 @@ void GCButtonFactory::EndConfiguration() {
class GCAnalog final : public Input::AnalogDevice {
public:
GCAnalog(int port_, int axis_x_, int axis_y_, float deadzone_,
const GCAdapter::Adapter* adapter, float range_)
explicit GCAnalog(u32 port_, u32 axis_x_, u32 axis_y_, float deadzone_,
const GCAdapter::Adapter* adapter, float range_)
: port(port_), axis_x(axis_x_), axis_y(axis_y_), deadzone(deadzone_), gcadapter(adapter),
origin_value_x(static_cast<float>(adapter->GetOriginValue(port_, axis_x_))),
origin_value_y(static_cast<float>(adapter->GetOriginValue(port_, axis_y_))),
range(range_) {}
float GetAxis(int axis) const {
float GetAxis(u32 axis) const {
if (gcadapter->DeviceConnected(port)) {
std::lock_guard lock{mutex};
const auto origin_value = axis % 2 == 0 ? origin_value_x : origin_value_y;
return (gcadapter->GetPadState()[port].axes.at(axis) - origin_value) / (100.0f * range);
const auto axis_value =
static_cast<float>(gcadapter->GetPadState()[port].axes.at(axis));
return (axis_value - origin_value) / (100.0f * range);
}
return 0.0f;
}
std::pair<float, float> GetAnalog(int axis_x, int axis_y) const {
float x = GetAxis(axis_x);
float y = GetAxis(axis_y);
std::pair<float, float> GetAnalog(u32 analog_axis_x, u32 analog_axis_y) const {
float x = GetAxis(analog_axis_x);
float y = GetAxis(analog_axis_y);
// Make sure the coordinates are in the unit circle,
// otherwise normalize it.
@@ -208,9 +210,9 @@ public:
}
private:
const int port;
const int axis_x;
const int axis_y;
const u32 port;
const u32 axis_x;
const u32 axis_y;
const float deadzone;
const GCAdapter::Adapter* gcadapter;
const float origin_value_x;
@@ -231,11 +233,11 @@ GCAnalogFactory::GCAnalogFactory(std::shared_ptr<GCAdapter::Adapter> adapter_)
* - "axis_y": the index of the axis to be bind as y-axis
*/
std::unique_ptr<Input::AnalogDevice> GCAnalogFactory::Create(const Common::ParamPackage& params) {
const int port = params.Get("port", 0);
const int axis_x = params.Get("axis_x", 0);
const int axis_y = params.Get("axis_y", 1);
const float deadzone = std::clamp(params.Get("deadzone", 0.0f), 0.0f, 1.0f);
const float range = std::clamp(params.Get("range", 1.0f), 0.50f, 1.50f);
const auto port = static_cast<u32>(params.Get("port", 0));
const auto axis_x = static_cast<u32>(params.Get("axis_x", 0));
const auto axis_y = static_cast<u32>(params.Get("axis_y", 1));
const auto deadzone = std::clamp(params.Get("deadzone", 0.0f), 0.0f, 1.0f);
const auto range = std::clamp(params.Get("range", 1.0f), 0.50f, 1.50f);
return std::make_unique<GCAnalog>(port, axis_x, axis_y, deadzone, adapter.get(), range);
}
@@ -256,7 +258,7 @@ Common::ParamPackage GCAnalogFactory::GetNextInput() {
for (std::size_t port = 0; port < queue.size(); ++port) {
while (queue[port].Pop(pad)) {
if (pad.axis == GCAdapter::PadAxes::Undefined ||
std::abs((pad.axis_value - 128.0f) / 128.0f) < 0.1) {
std::abs((static_cast<float>(pad.axis_value) - 128.0f) / 128.0f) < 0.1f) {
continue;
}
// An analog device needs two axes, so we need to store the axis for later and wait for

View File

@@ -49,8 +49,9 @@ public:
void ChangeKeyStatus(int key_code, bool pressed) {
std::lock_guard guard{mutex};
for (const KeyButtonPair& pair : list) {
if (pair.key_code == key_code)
if (pair.key_code == key_code) {
pair.key_button->status.store(pressed);
}
}
}
@@ -73,7 +74,7 @@ KeyButton::~KeyButton() {
}
std::unique_ptr<Input::ButtonDevice> Keyboard::Create(const Common::ParamPackage& params) {
int key_code = params.Get("code", 0);
const int key_code = params.Get("code", 0);
std::unique_ptr<KeyButton> button = std::make_unique<KeyButton>(key_button_list);
key_button_list->AddKeyButton(key_code, button.get());
return button;

View File

@@ -196,6 +196,10 @@ ButtonMapping InputSubsystem::GetButtonMappingForDevice(const Common::ParamPacka
return impl->GetButtonMappingForDevice(device);
}
MotionMapping InputSubsystem::GetMotionMappingForDevice(const Common::ParamPackage& device) const {
return impl->GetMotionMappingForDevice(device);
}
GCAnalogFactory* InputSubsystem::GetGCAnalogs() {
return impl->gcanalog.get();
}

View File

@@ -18,11 +18,11 @@ namespace InputCommon {
// Implementation class of the motion emulation device
class MotionEmuDevice {
public:
MotionEmuDevice(int update_millisecond, float sensitivity)
: update_millisecond(update_millisecond),
explicit MotionEmuDevice(int update_millisecond_, float sensitivity_)
: update_millisecond(update_millisecond_),
update_duration(std::chrono::duration_cast<std::chrono::steady_clock::duration>(
std::chrono::milliseconds(update_millisecond))),
sensitivity(sensitivity), motion_emu_thread(&MotionEmuDevice::MotionEmuThread, this) {}
sensitivity(sensitivity_), motion_emu_thread(&MotionEmuDevice::MotionEmuThread, this) {}
~MotionEmuDevice() {
if (motion_emu_thread.joinable()) {
@@ -37,16 +37,18 @@ public:
}
void Tilt(int x, int y) {
auto mouse_move = Common::MakeVec(x, y) - mouse_origin;
if (is_tilting) {
std::lock_guard guard{tilt_mutex};
if (mouse_move.x == 0 && mouse_move.y == 0) {
tilt_angle = 0;
} else {
tilt_direction = mouse_move.Cast<float>();
tilt_angle =
std::clamp(tilt_direction.Normalize() * sensitivity, 0.0f, Common::PI * 0.5f);
}
if (!is_tilting) {
return;
}
std::lock_guard guard{tilt_mutex};
const auto mouse_move = Common::MakeVec(x, y) - mouse_origin;
if (mouse_move.x == 0 && mouse_move.y == 0) {
tilt_angle = 0;
} else {
tilt_direction = mouse_move.Cast<float>();
tilt_angle =
std::clamp(tilt_direction.Normalize() * sensitivity, 0.0f, Common::PI * 0.5f);
}
}
@@ -86,11 +88,10 @@ private:
void MotionEmuThread() {
auto update_time = std::chrono::steady_clock::now();
Common::Quaternion<float> q = Common::MakeQuaternion(Common::Vec3<float>(), 0);
Common::Quaternion<float> old_q;
while (!shutdown_event.WaitUntil(update_time)) {
update_time += update_duration;
old_q = q;
const Common::Quaternion<float> old_q = q;
{
std::lock_guard guard{tilt_mutex};
@@ -100,14 +101,14 @@ private:
Common::MakeVec(-tilt_direction.y, 0.0f, tilt_direction.x), tilt_angle);
}
auto inv_q = q.Inverse();
const auto inv_q = q.Inverse();
// Set the gravity vector in world space
auto gravity = Common::MakeVec(0.0f, -1.0f, 0.0f);
// Find the angular rate vector in world space
auto angular_rate = ((q - old_q) * inv_q).xyz * 2;
angular_rate *= 1000 / update_millisecond / Common::PI * 180;
angular_rate *= static_cast<float>(1000 / update_millisecond) / Common::PI * 180.0f;
// Transform the two vectors from world space to 3DS space
gravity = QuaternionRotate(inv_q, gravity);
@@ -136,7 +137,7 @@ private:
// can forward all the inputs to the implementation only when it is valid.
class MotionEmuDeviceWrapper : public Input::MotionDevice {
public:
MotionEmuDeviceWrapper(int update_millisecond, float sensitivity) {
explicit MotionEmuDeviceWrapper(int update_millisecond, float sensitivity) {
device = std::make_shared<MotionEmuDevice>(update_millisecond, sensitivity);
}
@@ -148,8 +149,8 @@ public:
};
std::unique_ptr<Input::MotionDevice> MotionEmu::Create(const Common::ParamPackage& params) {
int update_period = params.Get("update_period", 100);
float sensitivity = params.Get("sensitivity", 0.01f);
const int update_period = params.Get("update_period", 100);
const float sensitivity = params.Get("sensitivity", 0.01f);
auto device_wrapper = std::make_unique<MotionEmuDeviceWrapper>(update_period, sensitivity);
// Previously created device is disconnected here. Having two motion devices for 3DS is not
// expected.

View File

@@ -11,7 +11,7 @@ class MotionKey final : public Input::MotionDevice {
public:
using Button = std::unique_ptr<Input::ButtonDevice>;
MotionKey(Button key_) : key(std::move(key_)) {}
explicit MotionKey(Button key_) : key(std::move(key_)) {}
Input::MotionStatus GetStatus() const override {

View File

@@ -8,8 +8,7 @@
namespace InputCommon {
MotionInput::MotionInput(f32 new_kp, f32 new_ki, f32 new_kd)
: kp(new_kp), ki(new_ki), kd(new_kd), quat{{0, 0, -1}, 0} {}
MotionInput::MotionInput(f32 new_kp, f32 new_ki, f32 new_kd) : kp(new_kp), ki(new_ki), kd(new_kd) {}
void MotionInput::SetAcceleration(const Common::Vec3f& acceleration) {
accel = acceleration;
@@ -59,7 +58,7 @@ bool MotionInput::IsCalibrated(f32 sensitivity) const {
}
void MotionInput::UpdateRotation(u64 elapsed_time) {
const f32 sample_period = elapsed_time / 1000000.0f;
const auto sample_period = static_cast<f32>(elapsed_time) / 1000000.0f;
if (sample_period > 0.1f) {
return;
}
@@ -75,7 +74,7 @@ void MotionInput::UpdateOrientation(u64 elapsed_time) {
f32 q2 = quat.xyz[0];
f32 q3 = quat.xyz[1];
f32 q4 = quat.xyz[2];
const f32 sample_period = elapsed_time / 1000000.0f;
const auto sample_period = static_cast<f32>(elapsed_time) / 1000000.0f;
// Ignore invalid elapsed time
if (sample_period > 0.1f) {
@@ -203,21 +202,21 @@ Input::MotionStatus MotionInput::GetRandomMotion(int accel_magnitude, int gyro_m
std::random_device device;
std::mt19937 gen(device());
std::uniform_int_distribution<s16> distribution(-1000, 1000);
const Common::Vec3f gyroscope = {
distribution(gen) * 0.001f,
distribution(gen) * 0.001f,
distribution(gen) * 0.001f,
const Common::Vec3f gyroscope{
static_cast<f32>(distribution(gen)) * 0.001f,
static_cast<f32>(distribution(gen)) * 0.001f,
static_cast<f32>(distribution(gen)) * 0.001f,
};
const Common::Vec3f accelerometer = {
distribution(gen) * 0.001f,
distribution(gen) * 0.001f,
distribution(gen) * 0.001f,
const Common::Vec3f accelerometer{
static_cast<f32>(distribution(gen)) * 0.001f,
static_cast<f32>(distribution(gen)) * 0.001f,
static_cast<f32>(distribution(gen)) * 0.001f,
};
const Common::Vec3f rotation = {};
const std::array<Common::Vec3f, 3> orientation = {
Common::Vec3f{1.0f, 0, 0},
Common::Vec3f{0, 1.0f, 0},
Common::Vec3f{0, 0, 1.0f},
constexpr Common::Vec3f rotation;
constexpr std::array orientation{
Common::Vec3f{1.0f, 0.0f, 0.0f},
Common::Vec3f{0.0f, 1.0f, 0.0f},
Common::Vec3f{0.0f, 0.0f, 1.0f},
};
return {accelerometer * accel_magnitude, gyroscope * gyro_magnitude, rotation, orientation};
}
@@ -247,9 +246,6 @@ void MotionInput::SetOrientationFromAccelerometer() {
const f32 sample_period = 0.015f;
const auto normal_accel = accel.Normalized();
const f32 ax = -normal_accel.x;
const f32 ay = normal_accel.y;
const f32 az = -normal_accel.z;
while (!IsCalibrated(0.01f) && ++iterations < 100) {
// Short name local variable for readability
@@ -258,7 +254,7 @@ void MotionInput::SetOrientationFromAccelerometer() {
f32 q3 = quat.xyz[1];
f32 q4 = quat.xyz[2];
Common::Vec3f rad_gyro = {};
Common::Vec3f rad_gyro;
const f32 ax = -normal_accel.x;
const f32 ay = normal_accel.y;
const f32 az = -normal_accel.z;

View File

@@ -22,7 +22,7 @@ public:
MotionInput& operator=(MotionInput&&) = default;
void SetAcceleration(const Common::Vec3f& acceleration);
void SetGyroscope(const Common::Vec3f& acceleration);
void SetGyroscope(const Common::Vec3f& gyroscope);
void SetQuaternion(const Common::Quaternion<f32>& quaternion);
void SetGyroDrift(const Common::Vec3f& drift);
void SetGyroThreshold(f32 threshold);
@@ -49,16 +49,16 @@ private:
void SetOrientationFromAccelerometer();
// PID constants
const f32 kp;
const f32 ki;
const f32 kd;
f32 kp;
f32 ki;
f32 kd;
// PID errors
Common::Vec3f real_error;
Common::Vec3f integral_error;
Common::Vec3f derivative_error;
Common::Quaternion<f32> quat;
Common::Quaternion<f32> quat{{0.0f, 0.0f, -1.0f}, 0.0f};
Common::Vec3f rotations;
Common::Vec3f accel;
Common::Vec3f gyro;

View File

@@ -56,9 +56,9 @@ static int SDLEventWatcher(void* user_data, SDL_Event* event) {
class SDLJoystick {
public:
SDLJoystick(std::string guid_, int port_, SDL_Joystick* joystick,
SDL_GameController* gamecontroller)
SDL_GameController* game_controller)
: guid{std::move(guid_)}, port{port_}, sdl_joystick{joystick, &SDL_JoystickClose},
sdl_controller{gamecontroller, &SDL_GameControllerClose} {}
sdl_controller{game_controller, &SDL_GameControllerClose} {}
void SetButton(int button, bool value) {
std::lock_guard lock{mutex};
@@ -77,10 +77,10 @@ public:
float GetAxis(int axis, float range) const {
std::lock_guard lock{mutex};
return state.axes.at(axis) / (32767.0f * range);
return static_cast<float>(state.axes.at(axis)) / (32767.0f * range);
}
bool RumblePlay(f32 amp_low, f32 amp_high, int time) {
bool RumblePlay(f32 amp_low, f32 amp_high, u32 time) {
const u16 raw_amp_low = static_cast<u16>(amp_low * 0xFFFF);
const u16 raw_amp_high = static_cast<u16>(amp_high * 0xFFFF);
// Lower drastically the number of state changes
@@ -124,7 +124,7 @@ public:
return std::make_tuple(x, y);
}
const InputCommon::MotionInput& GetMotion() const {
const MotionInput& GetMotion() const {
return motion;
}
@@ -172,15 +172,15 @@ private:
} state;
std::string guid;
int port;
u16 last_state_rumble_high;
u16 last_state_rumble_low;
u16 last_state_rumble_high = 0;
u16 last_state_rumble_low = 0;
std::chrono::time_point<std::chrono::system_clock> last_vibration;
std::unique_ptr<SDL_Joystick, decltype(&SDL_JoystickClose)> sdl_joystick;
std::unique_ptr<SDL_GameController, decltype(&SDL_GameControllerClose)> sdl_controller;
mutable std::mutex mutex;
// motion is initalized without PID values as motion input is not aviable for SDL2
InputCommon::MotionInput motion{0.0f, 0.0f, 0.0f};
// Motion is initialized without PID values as motion input is not aviable for SDL2
MotionInput motion{0.0f, 0.0f, 0.0f};
};
std::shared_ptr<SDLJoystick> SDLState::GetSDLJoystickByGUID(const std::string& guid, int port) {
@@ -192,7 +192,7 @@ std::shared_ptr<SDLJoystick> SDLState::GetSDLJoystickByGUID(const std::string& g
nullptr, nullptr);
it->second.emplace_back(std::move(joystick));
}
return it->second[port];
return it->second[static_cast<std::size_t>(port)];
}
auto joystick = std::make_shared<SDLJoystick>(guid, 0, nullptr, nullptr);
return joystick_map[guid].emplace_back(std::move(joystick));
@@ -212,7 +212,7 @@ std::shared_ptr<SDLJoystick> SDLState::GetSDLJoystickBySDLID(SDL_JoystickID sdl_
return sdl_joystick == joystick->GetSDLJoystick();
});
if (vec_it != map_it->second.end()) {
// This is the common case: There is already an existing SDL_Joystick maped to a
// This is the common case: There is already an existing SDL_Joystick mapped to a
// SDLJoystick. return the SDLJoystick
return *vec_it;
}
@@ -220,7 +220,7 @@ std::shared_ptr<SDLJoystick> SDLState::GetSDLJoystickBySDLID(SDL_JoystickID sdl_
// Search for a SDLJoystick without a mapped SDL_Joystick...
const auto nullptr_it = std::find_if(map_it->second.begin(), map_it->second.end(),
[](const std::shared_ptr<SDLJoystick>& joystick) {
return !joystick->GetSDLJoystick();
return joystick->GetSDLJoystick() == nullptr;
});
if (nullptr_it != map_it->second.end()) {
// ... and map it
@@ -273,22 +273,21 @@ void SDLState::InitJoystick(int joystick_index) {
void SDLState::CloseJoystick(SDL_Joystick* sdl_joystick) {
const std::string guid = GetGUID(sdl_joystick);
std::shared_ptr<SDLJoystick> joystick;
std::shared_ptr<SDLJoystick> found_joystick;
{
std::lock_guard lock{joystick_map_mutex};
// This call to guid is safe since the joystick is guaranteed to be in the map
const auto& joystick_guid_list = joystick_map[guid];
const auto joystick_it =
std::find_if(joystick_guid_list.begin(), joystick_guid_list.end(),
[&sdl_joystick](const std::shared_ptr<SDLJoystick>& joystick) {
return joystick->GetSDLJoystick() == sdl_joystick;
});
joystick = *joystick_it;
const auto joystick_it = std::find_if(joystick_guid_list.begin(), joystick_guid_list.end(),
[&sdl_joystick](const auto& joystick) {
return joystick->GetSDLJoystick() == sdl_joystick;
});
found_joystick = *joystick_it;
}
// Destruct SDL_Joystick outside the lock guard because SDL can internally call the
// event callback which locks the mutex again.
joystick->SetSDLJoystick(nullptr, nullptr);
found_joystick->SetSDLJoystick(nullptr, nullptr);
}
void SDLState::HandleGameControllerEvent(const SDL_Event& event) {
@@ -392,8 +391,8 @@ private:
class SDLAnalog final : public Input::AnalogDevice {
public:
SDLAnalog(std::shared_ptr<SDLJoystick> joystick_, int axis_x_, int axis_y_, float deadzone_,
float range_)
explicit SDLAnalog(std::shared_ptr<SDLJoystick> joystick_, int axis_x_, int axis_y_,
float deadzone_, float range_)
: joystick(std::move(joystick_)), axis_x(axis_x_), axis_y(axis_y_), deadzone(deadzone_),
range(range_) {}
@@ -672,13 +671,13 @@ SDLState::SDLState() {
RegisterFactory<ButtonDevice>("sdl", button_factory);
RegisterFactory<MotionDevice>("sdl", motion_factory);
// If the frontend is going to manage the event loop, then we dont start one here
start_thread = !SDL_WasInit(SDL_INIT_JOYSTICK);
// If the frontend is going to manage the event loop, then we don't start one here
start_thread = SDL_WasInit(SDL_INIT_JOYSTICK) == 0;
if (start_thread && SDL_Init(SDL_INIT_JOYSTICK) < 0) {
LOG_CRITICAL(Input, "SDL_Init(SDL_INIT_JOYSTICK) failed with: {}", SDL_GetError());
return;
}
has_gamecontroller = SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER);
has_gamecontroller = SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER) != 0;
if (SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1") == SDL_FALSE) {
LOG_ERROR(Input, "Failed to set hint for background events with: {}", SDL_GetError());
}
@@ -723,8 +722,8 @@ std::vector<Common::ParamPackage> SDLState::GetInputDevices() {
std::vector<Common::ParamPackage> devices;
for (const auto& [key, value] : joystick_map) {
for (const auto& joystick : value) {
auto joy = joystick->GetSDLJoystick();
if (auto controller = joystick->GetSDLGameController()) {
auto* joy = joystick->GetSDLJoystick();
if (auto* controller = joystick->GetSDLGameController()) {
std::string name =
fmt::format("{} {}", SDL_GameControllerName(controller), joystick->GetPort());
devices.emplace_back(Common::ParamPackage{
@@ -748,7 +747,7 @@ std::vector<Common::ParamPackage> SDLState::GetInputDevices() {
}
namespace {
Common::ParamPackage BuildAnalogParamPackageForButton(int port, std::string guid, u8 axis,
Common::ParamPackage BuildAnalogParamPackageForButton(int port, std::string guid, s32 axis,
float value = 0.1f) {
Common::ParamPackage params({{"engine", "sdl"}});
params.Set("port", port);
@@ -764,7 +763,7 @@ Common::ParamPackage BuildAnalogParamPackageForButton(int port, std::string guid
return params;
}
Common::ParamPackage BuildButtonParamPackageForButton(int port, std::string guid, u8 button) {
Common::ParamPackage BuildButtonParamPackageForButton(int port, std::string guid, s32 button) {
Common::ParamPackage params({{"engine", "sdl"}});
params.Set("port", port);
params.Set("guid", std::move(guid));
@@ -772,7 +771,7 @@ Common::ParamPackage BuildButtonParamPackageForButton(int port, std::string guid
return params;
}
Common::ParamPackage BuildHatParamPackageForButton(int port, std::string guid, u8 hat, u8 value) {
Common::ParamPackage BuildHatParamPackageForButton(int port, std::string guid, s32 hat, s32 value) {
Common::ParamPackage params({{"engine", "sdl"}});
params.Set("port", port);
@@ -802,17 +801,19 @@ Common::ParamPackage SDLEventToButtonParamPackage(SDLState& state, const SDL_Eve
case SDL_JOYAXISMOTION: {
const auto joystick = state.GetSDLJoystickBySDLID(event.jaxis.which);
return BuildAnalogParamPackageForButton(joystick->GetPort(), joystick->GetGUID(),
event.jaxis.axis, event.jaxis.value);
static_cast<s32>(event.jaxis.axis),
event.jaxis.value);
}
case SDL_JOYBUTTONUP: {
const auto joystick = state.GetSDLJoystickBySDLID(event.jbutton.which);
return BuildButtonParamPackageForButton(joystick->GetPort(), joystick->GetGUID(),
event.jbutton.button);
static_cast<s32>(event.jbutton.button));
}
case SDL_JOYHATMOTION: {
const auto joystick = state.GetSDLJoystickBySDLID(event.jhat.which);
return BuildHatParamPackageForButton(joystick->GetPort(), joystick->GetGUID(),
event.jhat.hat, event.jhat.value);
static_cast<s32>(event.jhat.hat),
static_cast<s32>(event.jhat.value));
}
}
return {};
@@ -823,17 +824,19 @@ Common::ParamPackage SDLEventToMotionParamPackage(SDLState& state, const SDL_Eve
case SDL_JOYAXISMOTION: {
const auto joystick = state.GetSDLJoystickBySDLID(event.jaxis.which);
return BuildAnalogParamPackageForButton(joystick->GetPort(), joystick->GetGUID(),
event.jaxis.axis, event.jaxis.value);
static_cast<s32>(event.jaxis.axis),
event.jaxis.value);
}
case SDL_JOYBUTTONUP: {
const auto joystick = state.GetSDLJoystickBySDLID(event.jbutton.which);
return BuildButtonParamPackageForButton(joystick->GetPort(), joystick->GetGUID(),
event.jbutton.button);
static_cast<s32>(event.jbutton.button));
}
case SDL_JOYHATMOTION: {
const auto joystick = state.GetSDLJoystickBySDLID(event.jhat.which);
return BuildHatParamPackageForButton(joystick->GetPort(), joystick->GetGUID(),
event.jhat.hat, event.jhat.value);
static_cast<s32>(event.jhat.hat),
static_cast<s32>(event.jhat.value));
}
}
return {};
@@ -1062,7 +1065,7 @@ public:
if (event.type == SDL_JOYAXISMOTION) {
const auto axis = event.jaxis.axis;
const auto joystick = state.GetSDLJoystickBySDLID(event.jaxis.which);
const auto controller = joystick->GetSDLGameController();
auto* const controller = joystick->GetSDLGameController();
if (controller) {
const auto axis_left_x =
SDL_GameControllerGetBindForAxis(controller, SDL_CONTROLLER_AXIS_LEFTX)

View File

@@ -11,9 +11,11 @@ namespace InputCommon {
class TouchFromButtonDevice final : public Input::TouchDevice {
public:
TouchFromButtonDevice() {
for (const auto& config_entry :
Settings::values.touch_from_button_maps[Settings::values.touch_from_button_map_index]
.buttons) {
const auto button_index =
static_cast<std::size_t>(Settings::values.touch_from_button_map_index);
const auto& buttons = Settings::values.touch_from_button_maps[button_index].buttons;
for (const auto& config_entry : buttons) {
const Common::ParamPackage package{config_entry};
map.emplace_back(
Input::CreateDevice<Input::ButtonDevice>(config_entry),

View File

@@ -26,11 +26,11 @@ class Socket {
public:
using clock = std::chrono::system_clock;
explicit Socket(const std::string& host, u16 port, u8 pad_index, u32 client_id,
SocketCallback callback)
: callback(std::move(callback)), timer(io_service),
socket(io_service, udp::endpoint(udp::v4(), 0)), client_id(client_id),
pad_index(pad_index) {
explicit Socket(const std::string& host, u16 port, std::size_t pad_index_, u32 client_id_,
SocketCallback callback_)
: callback(std::move(callback_)), timer(io_service),
socket(io_service, udp::endpoint(udp::v4(), 0)), client_id(client_id_),
pad_index(pad_index_) {
boost::system::error_code ec{};
auto ipv4 = boost::asio::ip::make_address_v4(host, ec);
if (ec.value() != boost::system::errc::success) {
@@ -93,13 +93,17 @@ private:
void HandleSend(const boost::system::error_code& error) {
boost::system::error_code _ignored{};
// Send a request for getting port info for the pad
Request::PortInfo port_info{1, {pad_index, 0, 0, 0}};
const Request::PortInfo port_info{1, {static_cast<u8>(pad_index), 0, 0, 0}};
const auto port_message = Request::Create(port_info, client_id);
std::memcpy(&send_buffer1, &port_message, PORT_INFO_SIZE);
socket.send_to(boost::asio::buffer(send_buffer1), send_endpoint, {}, _ignored);
// Send a request for getting pad data for the pad
Request::PadData pad_data{Request::PadData::Flags::Id, pad_index, EMPTY_MAC_ADDRESS};
const Request::PadData pad_data{
Request::PadData::Flags::Id,
static_cast<u8>(pad_index),
EMPTY_MAC_ADDRESS,
};
const auto pad_message = Request::Create(pad_data, client_id);
std::memcpy(send_buffer2.data(), &pad_message, PAD_DATA_SIZE);
socket.send_to(boost::asio::buffer(send_buffer2), send_endpoint, {}, _ignored);
@@ -112,7 +116,7 @@ private:
udp::socket socket;
u32 client_id{};
u8 pad_index{};
std::size_t pad_index{};
static constexpr std::size_t PORT_INFO_SIZE = sizeof(Message<Request::PortInfo>);
static constexpr std::size_t PAD_DATA_SIZE = sizeof(Message<Request::PadData>);
@@ -133,7 +137,7 @@ static void SocketLoop(Socket* socket) {
Client::Client() {
LOG_INFO(Input, "Udp Initialization started");
for (std::size_t client = 0; client < clients.size(); client++) {
u8 pad = client % 4;
const auto pad = client % 4;
StartCommunication(client, Settings::values.udp_input_address,
Settings::values.udp_input_port, pad, 24872);
// Set motion parameters
@@ -166,9 +170,9 @@ std::vector<Common::ParamPackage> Client::GetInputDevices() const {
bool Client::DeviceConnected(std::size_t pad) const {
// Use last timestamp to detect if the socket has stopped sending data
const auto now = std::chrono::system_clock::now();
u64 time_difference =
const auto time_difference = static_cast<u64>(
std::chrono::duration_cast<std::chrono::milliseconds>(now - clients[pad].last_motion_update)
.count();
.count());
return time_difference < 1000 && clients[pad].active == 1;
}
@@ -177,9 +181,9 @@ void Client::ReloadUDPClient() {
ReloadSocket(Settings::values.udp_input_address, Settings::values.udp_input_port, client);
}
}
void Client::ReloadSocket(const std::string& host, u16 port, u8 pad_index, u32 client_id) {
void Client::ReloadSocket(const std::string& host, u16 port, std::size_t pad_index, u32 client_id) {
// client number must be determined from host / port and pad index
std::size_t client = pad_index;
const std::size_t client = pad_index;
clients[client].socket->Stop();
clients[client].thread.join();
StartCommunication(client, host, port, pad_index, client_id);
@@ -194,8 +198,8 @@ void Client::OnPortInfo(Response::PortInfo data) {
}
void Client::OnPadData(Response::PadData data) {
// client number must be determined from host / port and pad index
std::size_t client = data.info.id;
// Client number must be determined from host / port and pad index
const std::size_t client = data.info.id;
LOG_TRACE(Input, "PadData packet received");
if (data.packet_counter == clients[client].packet_sequence) {
LOG_WARNING(
@@ -207,11 +211,12 @@ void Client::OnPadData(Response::PadData data) {
clients[client].active = data.info.is_pad_active;
clients[client].packet_sequence = data.packet_counter;
const auto now = std::chrono::system_clock::now();
u64 time_difference = std::chrono::duration_cast<std::chrono::microseconds>(
now - clients[client].last_motion_update)
.count();
const auto time_difference =
static_cast<u64>(std::chrono::duration_cast<std::chrono::microseconds>(
now - clients[client].last_motion_update)
.count());
clients[client].last_motion_update = now;
Common::Vec3f raw_gyroscope = {data.gyro.pitch, data.gyro.roll, -data.gyro.yaw};
const Common::Vec3f raw_gyroscope = {data.gyro.pitch, data.gyro.roll, -data.gyro.yaw};
clients[client].motion.SetAcceleration({data.accel.x, -data.accel.z, data.accel.y});
// Gyroscope values are not it the correct scale from better joy.
// Dividing by 312 allows us to make one full turn = 1 turn
@@ -237,9 +242,11 @@ void Client::OnPadData(Response::PadData data) {
const u16 min_y = clients[client].status.touch_calibration->min_y;
const u16 max_y = clients[client].status.touch_calibration->max_y;
x = (std::clamp(static_cast<u16>(data.touch_1.x), min_x, max_x) - min_x) /
x = static_cast<float>(std::clamp(static_cast<u16>(data.touch_1.x), min_x, max_x) -
min_x) /
static_cast<float>(max_x - min_x);
y = (std::clamp(static_cast<u16>(data.touch_1.y), min_y, max_y) - min_y) /
y = static_cast<float>(std::clamp(static_cast<u16>(data.touch_1.y), min_y, max_y) -
min_y) /
static_cast<float>(max_y - min_y);
}
@@ -253,8 +260,8 @@ void Client::OnPadData(Response::PadData data) {
}
}
void Client::StartCommunication(std::size_t client, const std::string& host, u16 port, u8 pad_index,
u32 client_id) {
void Client::StartCommunication(std::size_t client, const std::string& host, u16 port,
std::size_t pad_index, u32 client_id) {
SocketCallback callback{[this](Response::Version version) { OnVersion(version); },
[this](Response::PortInfo info) { OnPortInfo(info); },
[this](Response::PadData data) { OnPadData(data); }};
@@ -264,9 +271,9 @@ void Client::StartCommunication(std::size_t client, const std::string& host, u16
}
void Client::Reset() {
for (std::size_t client = 0; client < clients.size(); client++) {
clients[client].socket->Stop();
clients[client].thread.join();
for (auto& client : clients) {
client.socket->Stop();
client.thread.join();
}
}
@@ -325,16 +332,19 @@ const std::array<Common::SPSCQueue<UDPPadStatus>, 4>& Client::GetPadQueue() cons
return pad_queue;
}
void TestCommunication(const std::string& host, u16 port, u8 pad_index, u32 client_id,
std::function<void()> success_callback,
std::function<void()> failure_callback) {
void TestCommunication(const std::string& host, u16 port, std::size_t pad_index, u32 client_id,
const std::function<void()>& success_callback,
const std::function<void()>& failure_callback) {
std::thread([=] {
Common::Event success_event;
SocketCallback callback{[](Response::Version version) {}, [](Response::PortInfo info) {},
[&](Response::PadData data) { success_event.Set(); }};
SocketCallback callback{
.version = [](Response::Version) {},
.port_info = [](Response::PortInfo) {},
.pad_data = [&](Response::PadData) { success_event.Set(); },
};
Socket socket{host, port, pad_index, client_id, std::move(callback)};
std::thread worker_thread{SocketLoop, &socket};
bool result = success_event.WaitFor(std::chrono::seconds(8));
const bool result = success_event.WaitFor(std::chrono::seconds(8));
socket.Stop();
worker_thread.join();
if (result) {
@@ -346,7 +356,7 @@ void TestCommunication(const std::string& host, u16 port, u8 pad_index, u32 clie
}
CalibrationConfigurationJob::CalibrationConfigurationJob(
const std::string& host, u16 port, u8 pad_index, u32 client_id,
const std::string& host, u16 port, std::size_t pad_index, u32 client_id,
std::function<void(Status)> status_callback,
std::function<void(u16, u16, u16, u16)> data_callback) {
@@ -366,7 +376,7 @@ CalibrationConfigurationJob::CalibrationConfigurationJob(
current_status = Status::Ready;
status_callback(current_status);
}
if (!data.touch_1.is_active) {
if (data.touch_1.is_active == 0) {
return;
}
LOG_DEBUG(Input, "Current touch: {} {}", data.touch_1.x,

View File

@@ -84,8 +84,8 @@ public:
bool DeviceConnected(std::size_t pad) const;
void ReloadUDPClient();
void ReloadSocket(const std::string& host = "127.0.0.1", u16 port = 26760, u8 pad_index = 0,
u32 client_id = 24872);
void ReloadSocket(const std::string& host = "127.0.0.1", u16 port = 26760,
std::size_t pad_index = 0, u32 client_id = 24872);
std::array<Common::SPSCQueue<UDPPadStatus>, 4>& GetPadQueue();
const std::array<Common::SPSCQueue<UDPPadStatus>, 4>& GetPadQueue() const;
@@ -99,7 +99,7 @@ private:
DeviceStatus status;
std::thread thread;
u64 packet_sequence = 0;
u8 active;
u8 active = 0;
// Realtime values
// motion is initalized with PID values for drift correction on joycons
@@ -113,8 +113,8 @@ private:
void OnVersion(Response::Version);
void OnPortInfo(Response::PortInfo);
void OnPadData(Response::PadData);
void StartCommunication(std::size_t client, const std::string& host, u16 port, u8 pad_index,
u32 client_id);
void StartCommunication(std::size_t client, const std::string& host, u16 port,
std::size_t pad_index, u32 client_id);
void UpdateYuzuSettings(std::size_t client, const Common::Vec3<float>& acc,
const Common::Vec3<float>& gyro, bool touch);
@@ -139,7 +139,7 @@ public:
* @param status_callback Callback for job status updates
* @param data_callback Called when calibration data is ready
*/
explicit CalibrationConfigurationJob(const std::string& host, u16 port, u8 pad_index,
explicit CalibrationConfigurationJob(const std::string& host, u16 port, std::size_t pad_index,
u32 client_id, std::function<void(Status)> status_callback,
std::function<void(u16, u16, u16, u16)> data_callback);
~CalibrationConfigurationJob();
@@ -149,8 +149,8 @@ private:
Common::Event complete_event;
};
void TestCommunication(const std::string& host, u16 port, u8 pad_index, u32 client_id,
std::function<void()> success_callback,
std::function<void()> failure_callback);
void TestCommunication(const std::string& host, u16 port, std::size_t pad_index, u32 client_id,
const std::function<void()>& success_callback,
const std::function<void()>& failure_callback);
} // namespace InputCommon::CemuhookUDP

View File

@@ -2,8 +2,6 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include <atomic>
#include <list>
#include <mutex>
#include <utility>
#include "common/assert.h"
@@ -15,8 +13,8 @@ namespace InputCommon {
class UDPMotion final : public Input::MotionDevice {
public:
UDPMotion(std::string ip_, int port_, int pad_, CemuhookUDP::Client* client_)
: ip(ip_), port(port_), pad(pad_), client(client_) {}
explicit UDPMotion(std::string ip_, int port_, u32 pad_, CemuhookUDP::Client* client_)
: ip(std::move(ip_)), port(port_), pad(pad_), client(client_) {}
Input::MotionStatus GetStatus() const override {
return client->GetPadState(pad).motion_status;
@@ -25,7 +23,7 @@ public:
private:
const std::string ip;
const int port;
const int pad;
const u32 pad;
CemuhookUDP::Client* client;
mutable std::mutex mutex;
};
@@ -40,11 +38,11 @@ UDPMotionFactory::UDPMotionFactory(std::shared_ptr<CemuhookUDP::Client> client_)
* - "port": the nth jcpad on the adapter
*/
std::unique_ptr<Input::MotionDevice> UDPMotionFactory::Create(const Common::ParamPackage& params) {
const std::string ip = params.Get("ip", "127.0.0.1");
const int port = params.Get("port", 26760);
const int pad = params.Get("pad_index", 0);
auto ip = params.Get("ip", "127.0.0.1");
const auto port = params.Get("port", 26760);
const auto pad = static_cast<u32>(params.Get("pad_index", 0));
return std::make_unique<UDPMotion>(ip, port, pad, client.get());
return std::make_unique<UDPMotion>(std::move(ip), port, pad, client.get());
}
void UDPMotionFactory::BeginConfiguration() {
@@ -79,7 +77,7 @@ Common::ParamPackage UDPMotionFactory::GetNextInput() {
class UDPTouch final : public Input::TouchDevice {
public:
UDPTouch(std::string ip_, int port_, int pad_, CemuhookUDP::Client* client_)
explicit UDPTouch(std::string ip_, int port_, u32 pad_, CemuhookUDP::Client* client_)
: ip(std::move(ip_)), port(port_), pad(pad_), client(client_) {}
std::tuple<float, float, bool> GetStatus() const override {
@@ -89,7 +87,7 @@ public:
private:
const std::string ip;
const int port;
const int pad;
const u32 pad;
CemuhookUDP::Client* client;
mutable std::mutex mutex;
};
@@ -104,11 +102,11 @@ UDPTouchFactory::UDPTouchFactory(std::shared_ptr<CemuhookUDP::Client> client_)
* - "port": the nth jcpad on the adapter
*/
std::unique_ptr<Input::TouchDevice> UDPTouchFactory::Create(const Common::ParamPackage& params) {
const std::string ip = params.Get("ip", "127.0.0.1");
const int port = params.Get("port", 26760);
const int pad = params.Get("pad_index", 0);
auto ip = params.Get("ip", "127.0.0.1");
const auto port = params.Get("port", 26760);
const auto pad = static_cast<u32>(params.Get("pad_index", 0));
return std::make_unique<UDPTouch>(ip, port, pad, client.get());
return std::make_unique<UDPTouch>(std::move(ip), port, pad, client.get());
}
void UDPTouchFactory::BeginConfiguration() {

View File

@@ -58,6 +58,7 @@ void FixedPipelineState::Fill(const Maxwell& regs, bool has_extended_dynamic_sta
logic_op_enable.Assign(regs.logic_op.enable != 0 ? 1 : 0);
logic_op.Assign(PackLogicOp(regs.logic_op.operation));
rasterize_enable.Assign(regs.rasterize_enable != 0 ? 1 : 0);
topology.Assign(regs.draw.topology);
std::memcpy(&point_size, &regs.point_size, sizeof(point_size)); // TODO: C++20 std::bit_cast
@@ -131,7 +132,6 @@ void FixedPipelineState::BlendingAttachment::Fill(const Maxwell& regs, std::size
}
void FixedPipelineState::DynamicState::Fill(const Maxwell& regs) {
const u32 topology_index = static_cast<u32>(regs.draw.topology.Value());
u32 packed_front_face = PackFrontFace(regs.front_face);
if (regs.screen_y_control.triangle_rast_flip != 0) {
// Flip front face
@@ -161,7 +161,6 @@ void FixedPipelineState::DynamicState::Fill(const Maxwell& regs) {
depth_test_enable.Assign(regs.depth_test_enable);
front_face.Assign(packed_front_face);
depth_test_func.Assign(PackComparisonOp(regs.depth_test_func));
topology.Assign(topology_index);
cull_face.Assign(PackCullFace(regs.cull_face));
cull_enable.Assign(regs.cull_test_enabled != 0 ? 1 : 0);

View File

@@ -150,9 +150,8 @@ struct FixedPipelineState {
};
union {
u32 raw2;
BitField<0, 4, u32> topology;
BitField<4, 2, u32> cull_face;
BitField<6, 1, u32> cull_enable;
BitField<0, 2, u32> cull_face;
BitField<2, 1, u32> cull_enable;
};
std::array<VertexBinding, Maxwell::NumVertexArrays> vertex_bindings;
@@ -169,10 +168,6 @@ struct FixedPipelineState {
Maxwell::FrontFace FrontFace() const noexcept {
return UnpackFrontFace(front_face.Value());
}
constexpr Maxwell::PrimitiveTopology Topology() const noexcept {
return static_cast<Maxwell::PrimitiveTopology>(topology.Value());
}
};
union {
@@ -190,6 +185,7 @@ struct FixedPipelineState {
BitField<18, 1, u32> logic_op_enable;
BitField<19, 4, u32> logic_op;
BitField<23, 1, u32> rasterize_enable;
BitField<24, 4, Maxwell::PrimitiveTopology> topology;
};
u32 point_size;
std::array<u32, Maxwell::NumVertexArrays> binding_divisors;

View File

@@ -79,6 +79,21 @@ VkFormatFeatureFlags GetFormatFeatures(VkFormatProperties properties, FormatType
}
}
[[nodiscard]] bool IsRDNA(std::string_view device_name, VkDriverIdKHR driver_id) {
static constexpr std::array RDNA_DEVICES{
"5700",
"5600",
"5500",
"5300",
};
if (driver_id != VK_DRIVER_ID_AMD_PROPRIETARY_KHR) {
return false;
}
return std::any_of(RDNA_DEVICES.begin(), RDNA_DEVICES.end(), [device_name](const char* name) {
return device_name.find(name) != std::string_view::npos;
});
}
std::unordered_map<VkFormat, VkFormatProperties> GetFormatProperties(
vk::PhysicalDevice physical, const vk::InstanceDispatch& dld) {
static constexpr std::array formats{
@@ -388,6 +403,15 @@ bool VKDevice::Create() {
CollectTelemetryParameters();
if (ext_extended_dynamic_state && IsRDNA(properties.deviceName, driver_id)) {
// AMD's proprietary driver supports VK_EXT_extended_dynamic_state but on RDNA devices it
// seems to cause stability issues
LOG_WARNING(
Render_Vulkan,
"Blacklisting AMD proprietary on RDNA devices from VK_EXT_extended_dynamic_state");
ext_extended_dynamic_state = false;
}
graphics_queue = logical.GetQueue(graphics_family);
present_queue = logical.GetQueue(present_family);

View File

@@ -261,12 +261,12 @@ vk::Pipeline VKGraphicsPipeline::CreatePipeline(const RenderPassParams& renderpa
vertex_input_ci.pNext = &input_divisor_ci;
}
const auto input_assembly_topology = MaxwellToVK::PrimitiveTopology(device, dynamic.Topology());
const auto input_assembly_topology = MaxwellToVK::PrimitiveTopology(device, state.topology);
const VkPipelineInputAssemblyStateCreateInfo input_assembly_ci{
.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
.pNext = nullptr,
.flags = 0,
.topology = MaxwellToVK::PrimitiveTopology(device, dynamic.Topology()),
.topology = MaxwellToVK::PrimitiveTopology(device, state.topology),
.primitiveRestartEnable = state.primitive_restart_enable != 0 &&
SupportsPrimitiveRestart(input_assembly_topology),
};
@@ -400,7 +400,6 @@ vk::Pipeline VKGraphicsPipeline::CreatePipeline(const RenderPassParams& renderpa
static constexpr std::array extended{
VK_DYNAMIC_STATE_CULL_MODE_EXT,
VK_DYNAMIC_STATE_FRONT_FACE_EXT,
VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY_EXT,
VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT,
VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE_EXT,
VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE_EXT,

View File

@@ -331,8 +331,7 @@ void VKPipelineCache::OnShaderRemoval(Shader* shader) {
std::pair<SPIRVProgram, std::vector<VkDescriptorSetLayoutBinding>>
VKPipelineCache::DecompileShaders(const FixedPipelineState& fixed_state) {
Specialization specialization;
if (fixed_state.dynamic_state.Topology() == Maxwell::PrimitiveTopology::Points ||
device.IsExtExtendedDynamicStateSupported()) {
if (fixed_state.topology == Maxwell::PrimitiveTopology::Points) {
float point_size;
std::memcpy(&point_size, &fixed_state.point_size, sizeof(float));
specialization.point_size = point_size;

View File

@@ -948,7 +948,6 @@ void RasterizerVulkan::UpdateDynamicStates() {
UpdateDepthWriteEnable(regs);
UpdateDepthCompareOp(regs);
UpdateFrontFace(regs);
UpdatePrimitiveTopology(regs);
UpdateStencilOp(regs);
UpdateStencilTestEnable(regs);
}
@@ -1418,16 +1417,6 @@ void RasterizerVulkan::UpdateFrontFace(Tegra::Engines::Maxwell3D::Regs& regs) {
[front_face](vk::CommandBuffer cmdbuf) { cmdbuf.SetFrontFaceEXT(front_face); });
}
void RasterizerVulkan::UpdatePrimitiveTopology(Tegra::Engines::Maxwell3D::Regs& regs) {
const Maxwell::PrimitiveTopology primitive_topology = regs.draw.topology.Value();
if (!state_tracker.ChangePrimitiveTopology(primitive_topology)) {
return;
}
scheduler.Record([this, primitive_topology](vk::CommandBuffer cmdbuf) {
cmdbuf.SetPrimitiveTopologyEXT(MaxwellToVK::PrimitiveTopology(device, primitive_topology));
});
}
void RasterizerVulkan::UpdateStencilOp(Tegra::Engines::Maxwell3D::Regs& regs) {
if (!state_tracker.TouchStencilOp()) {
return;

View File

@@ -259,7 +259,6 @@ private:
void UpdateDepthWriteEnable(Tegra::Engines::Maxwell3D::Regs& regs);
void UpdateDepthCompareOp(Tegra::Engines::Maxwell3D::Regs& regs);
void UpdateFrontFace(Tegra::Engines::Maxwell3D::Regs& regs);
void UpdatePrimitiveTopology(Tegra::Engines::Maxwell3D::Regs& regs);
void UpdateStencilOp(Tegra::Engines::Maxwell3D::Regs& regs);
void UpdateStencilTestEnable(Tegra::Engines::Maxwell3D::Regs& regs);

View File

@@ -67,28 +67,25 @@ struct Client::Impl {
const std::string& jwt = "", const std::string& username = "",
const std::string& token = "") {
if (cli == nullptr) {
auto parsedUrl = LUrlParser::clParseURL::ParseURL(host);
int port;
const auto parsedUrl = LUrlParser::clParseURL::ParseURL(host);
int port{};
if (parsedUrl.m_Scheme == "http") {
if (!parsedUrl.GetPort(&port)) {
port = HTTP_PORT;
}
cli = std::make_unique<httplib::Client>(parsedUrl.m_Host.c_str(), port);
} else if (parsedUrl.m_Scheme == "https") {
if (!parsedUrl.GetPort(&port)) {
port = HTTPS_PORT;
}
cli = std::make_unique<httplib::SSLClient>(parsedUrl.m_Host.c_str(), port);
} else {
LOG_ERROR(WebService, "Bad URL scheme {}", parsedUrl.m_Scheme);
return WebResult{WebResult::Code::InvalidURL, "Bad URL scheme", ""};
}
cli = std::make_unique<httplib::Client>(parsedUrl.m_Host.c_str(), port);
}
if (cli == nullptr) {
LOG_ERROR(WebService, "Invalid URL {}", host + path);
return WebResult{WebResult::Code::InvalidURL, "Invalid URL", ""};
}
cli->set_timeout_sec(TIMEOUT_SECONDS);
cli->set_connection_timeout(TIMEOUT_SECONDS);
cli->set_read_timeout(TIMEOUT_SECONDS);
cli->set_write_timeout(TIMEOUT_SECONDS);
httplib::Headers params;
if (!jwt.empty()) {

View File

@@ -193,7 +193,7 @@ void ConfigureMotionTouch::OnCemuhookUDPTest() {
udp_test_in_progress = true;
InputCommon::CemuhookUDP::TestCommunication(
ui->udp_server->text().toStdString(), static_cast<u16>(ui->udp_port->text().toInt()),
static_cast<u8>(ui->udp_pad_index->currentIndex()), 24872,
static_cast<u32>(ui->udp_pad_index->currentIndex()), 24872,
[this] {
LOG_INFO(Frontend, "UDP input test success");
QMetaObject::invokeMethod(this, "ShowUDPTestResult", Q_ARG(bool, true));