Compare commits
34 Commits
__refs_pul
...
__refs_pul
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5035df27c3 | ||
|
|
3ca3254b9f | ||
|
|
f7908eebb9 | ||
|
|
ffd3afcf2f | ||
|
|
5808e76fae | ||
|
|
5c20373db3 | ||
|
|
f981e90af3 | ||
|
|
55b0dda57c | ||
|
|
0b9ef3c0b8 | ||
|
|
2fb6df3fe9 | ||
|
|
dca63391b6 | ||
|
|
c2b583c911 | ||
|
|
e7ba9fd7e1 | ||
|
|
e158951695 | ||
|
|
f345ffdc0f | ||
|
|
26e5bc6082 | ||
|
|
2123594ce2 | ||
|
|
5562ae9cc5 | ||
|
|
4087f1d10f | ||
|
|
7fe5004f90 | ||
|
|
b317f54f22 | ||
|
|
4f1a2c2562 | ||
|
|
babd580c64 | ||
|
|
7eb0992d2c | ||
|
|
18a0c2e9db | ||
|
|
4559112651 | ||
|
|
f3f3f1b7d9 | ||
|
|
b06f9f2606 | ||
|
|
8037f2eae8 | ||
|
|
d00464bd25 | ||
|
|
9398521006 | ||
|
|
f72f4377f4 | ||
|
|
17ce54d7f2 | ||
|
|
d2388a2ca8 |
1223
dist/languages/ca.ts
vendored
1223
dist/languages/ca.ts
vendored
File diff suppressed because it is too large
Load Diff
1233
dist/languages/cs.ts
vendored
1233
dist/languages/cs.ts
vendored
File diff suppressed because it is too large
Load Diff
1223
dist/languages/da.ts
vendored
1223
dist/languages/da.ts
vendored
File diff suppressed because it is too large
Load Diff
1237
dist/languages/de.ts
vendored
1237
dist/languages/de.ts
vendored
File diff suppressed because it is too large
Load Diff
1335
dist/languages/el.ts
vendored
1335
dist/languages/el.ts
vendored
File diff suppressed because it is too large
Load Diff
1223
dist/languages/es.ts
vendored
1223
dist/languages/es.ts
vendored
File diff suppressed because it is too large
Load Diff
1228
dist/languages/fr.ts
vendored
1228
dist/languages/fr.ts
vendored
File diff suppressed because it is too large
Load Diff
1254
dist/languages/id.ts
vendored
1254
dist/languages/id.ts
vendored
File diff suppressed because it is too large
Load Diff
1233
dist/languages/it.ts
vendored
1233
dist/languages/it.ts
vendored
File diff suppressed because it is too large
Load Diff
1229
dist/languages/ja_JP.ts
vendored
1229
dist/languages/ja_JP.ts
vendored
File diff suppressed because it is too large
Load Diff
1290
dist/languages/ko_KR.ts
vendored
1290
dist/languages/ko_KR.ts
vendored
File diff suppressed because it is too large
Load Diff
1235
dist/languages/nb.ts
vendored
1235
dist/languages/nb.ts
vendored
File diff suppressed because it is too large
Load Diff
1231
dist/languages/nl.ts
vendored
1231
dist/languages/nl.ts
vendored
File diff suppressed because it is too large
Load Diff
1229
dist/languages/pl.ts
vendored
1229
dist/languages/pl.ts
vendored
File diff suppressed because it is too large
Load Diff
1213
dist/languages/pt_BR.ts
vendored
1213
dist/languages/pt_BR.ts
vendored
File diff suppressed because it is too large
Load Diff
1221
dist/languages/pt_PT.ts
vendored
1221
dist/languages/pt_PT.ts
vendored
File diff suppressed because it is too large
Load Diff
1825
dist/languages/ru_RU.ts
vendored
1825
dist/languages/ru_RU.ts
vendored
File diff suppressed because it is too large
Load Diff
1229
dist/languages/sv.ts
vendored
1229
dist/languages/sv.ts
vendored
File diff suppressed because it is too large
Load Diff
1227
dist/languages/tr_TR.ts
vendored
1227
dist/languages/tr_TR.ts
vendored
File diff suppressed because it is too large
Load Diff
1229
dist/languages/vi.ts
vendored
1229
dist/languages/vi.ts
vendored
File diff suppressed because it is too large
Load Diff
1229
dist/languages/vi_VN.ts
vendored
1229
dist/languages/vi_VN.ts
vendored
File diff suppressed because it is too large
Load Diff
1225
dist/languages/zh_CN.ts
vendored
1225
dist/languages/zh_CN.ts
vendored
File diff suppressed because it is too large
Load Diff
1221
dist/languages/zh_TW.ts
vendored
1221
dist/languages/zh_TW.ts
vendored
File diff suppressed because it is too large
Load Diff
2
externals/sirit
vendored
2
externals/sirit
vendored
Submodule externals/sirit updated: b8f133bf63...aa292d5665
@@ -606,6 +606,7 @@ struct Values {
|
||||
BasicSetting<bool> dump_exefs{false, "dump_exefs"};
|
||||
BasicSetting<bool> dump_nso{false, "dump_nso"};
|
||||
BasicSetting<bool> dump_shaders{false, "dump_shaders"};
|
||||
BasicSetting<bool> dump_macros{false, "dump_macros"};
|
||||
BasicSetting<bool> enable_fs_access_log{false, "enable_fs_access_log"};
|
||||
BasicSetting<bool> reporting_services{false, "reporting_services"};
|
||||
BasicSetting<bool> quest_flag{false, "quest_flag"};
|
||||
|
||||
@@ -178,6 +178,10 @@ std::wstring UTF8ToUTF16W(const std::string& input) {
|
||||
|
||||
#endif
|
||||
|
||||
std::u16string U16StringFromBuffer(const u16* input, std::size_t length) {
|
||||
return std::u16string(reinterpret_cast<const char16_t*>(input), length);
|
||||
}
|
||||
|
||||
std::string StringFromFixedZeroTerminatedBuffer(std::string_view buffer, std::size_t max_len) {
|
||||
std::size_t len = 0;
|
||||
while (len < buffer.length() && len < max_len && buffer[len] != '\0') {
|
||||
|
||||
@@ -44,6 +44,8 @@ bool SplitPath(const std::string& full_path, std::string* _pPath, std::string* _
|
||||
|
||||
#endif
|
||||
|
||||
[[nodiscard]] std::u16string U16StringFromBuffer(const u16* input, std::size_t length);
|
||||
|
||||
/**
|
||||
* Compares the string defined by the range [`begin`, `end`) to the null-terminated C-string
|
||||
* `other` for equality.
|
||||
|
||||
@@ -20,7 +20,7 @@ struct fmt::formatter<Dynarmic::A32::CoprocReg> {
|
||||
}
|
||||
template <typename FormatContext>
|
||||
auto format(const Dynarmic::A32::CoprocReg& reg, FormatContext& ctx) {
|
||||
return format_to(ctx.out(), "cp{}", static_cast<size_t>(reg));
|
||||
return fmt::format_to(ctx.out(), "cp{}", static_cast<size_t>(reg));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -327,7 +327,7 @@ void SanitizeStick(Common::Input::AnalogStatus& analog_x, Common::Input::AnalogS
|
||||
raw_y += properties_y.offset;
|
||||
|
||||
// Apply X scale correction from offset
|
||||
if (std::abs(properties_x.offset) < 0.5f) {
|
||||
if (std::abs(properties_x.offset) < 0.75f) {
|
||||
if (raw_x > 0) {
|
||||
raw_x /= 1 + properties_x.offset;
|
||||
} else {
|
||||
@@ -336,7 +336,7 @@ void SanitizeStick(Common::Input::AnalogStatus& analog_x, Common::Input::AnalogS
|
||||
}
|
||||
|
||||
// Apply Y scale correction from offset
|
||||
if (std::abs(properties_y.offset) < 0.5f) {
|
||||
if (std::abs(properties_y.offset) < 0.75f) {
|
||||
if (raw_y > 0) {
|
||||
raw_y /= 1 + properties_y.offset;
|
||||
} else {
|
||||
|
||||
@@ -181,7 +181,7 @@ public:
|
||||
consteval ResultRange(ErrorModule module, u32 description_start, u32 description_end_)
|
||||
: code{module, description_start}, description_end{description_end_} {}
|
||||
|
||||
[[nodiscard]] consteval operator ResultCode() const {
|
||||
[[nodiscard]] constexpr operator ResultCode() const {
|
||||
return code;
|
||||
}
|
||||
|
||||
@@ -232,6 +232,8 @@ public:
|
||||
|
||||
constexpr ResultVal(ResultCode code) : expected{Common::Unexpected(code)} {}
|
||||
|
||||
constexpr ResultVal(ResultRange range) : expected{Common::Unexpected(range)} {}
|
||||
|
||||
template <typename U>
|
||||
constexpr ResultVal(U&& val) : expected{std::forward<U>(val)} {}
|
||||
|
||||
@@ -317,7 +319,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
// TODO: Replace this with std::expected once it is standardized in the STL.
|
||||
// TODO (Morph): Replace this with C++23 std::expected.
|
||||
Common::Expected<T, ResultCode> expected;
|
||||
};
|
||||
|
||||
|
||||
@@ -3,7 +3,9 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <chrono>
|
||||
#include <cstring>
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "common/bit_field.h"
|
||||
#include "common/common_types.h"
|
||||
@@ -529,6 +531,14 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing
|
||||
auto& sixaxis_left_lifo_state = controller.sixaxis_left_lifo_state;
|
||||
auto& sixaxis_right_lifo_state = controller.sixaxis_right_lifo_state;
|
||||
|
||||
// Clear previous state
|
||||
sixaxis_fullkey_state = {};
|
||||
sixaxis_handheld_state = {};
|
||||
sixaxis_dual_left_state = {};
|
||||
sixaxis_dual_right_state = {};
|
||||
sixaxis_left_lifo_state = {};
|
||||
sixaxis_right_lifo_state = {};
|
||||
|
||||
if (controller.sixaxis_sensor_enabled && Settings::values.motion_enabled.GetValue()) {
|
||||
controller.sixaxis_at_rest = true;
|
||||
for (std::size_t e = 0; e < motion_state.size(); ++e) {
|
||||
@@ -537,69 +547,55 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing
|
||||
}
|
||||
}
|
||||
|
||||
const auto set_motion_state = [&](SixAxisSensorState& state,
|
||||
const Core::HID::ControllerMotion& hid_state) {
|
||||
using namespace std::literals::chrono_literals;
|
||||
static constexpr SixAxisSensorState default_motion_state = {
|
||||
.delta_time = std::chrono::nanoseconds(5ms).count(),
|
||||
.accel = {0, 0, -1.0f},
|
||||
.orientation =
|
||||
{
|
||||
Common::Vec3f{1.0f, 0, 0},
|
||||
Common::Vec3f{0, 1.0f, 0},
|
||||
Common::Vec3f{0, 0, 1.0f},
|
||||
},
|
||||
.attribute = {1},
|
||||
};
|
||||
if (!controller.sixaxis_sensor_enabled) {
|
||||
state = default_motion_state;
|
||||
return;
|
||||
}
|
||||
if (!Settings::values.motion_enabled.GetValue()) {
|
||||
state = default_motion_state;
|
||||
return;
|
||||
}
|
||||
state.attribute.is_connected.Assign(1);
|
||||
state.delta_time = std::chrono::nanoseconds(5ms).count();
|
||||
state.accel = hid_state.accel;
|
||||
state.gyro = hid_state.gyro;
|
||||
state.rotation = hid_state.rotation;
|
||||
state.orientation = hid_state.orientation;
|
||||
};
|
||||
|
||||
switch (controller_type) {
|
||||
case Core::HID::NpadStyleIndex::None:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
case Core::HID::NpadStyleIndex::ProController:
|
||||
sixaxis_fullkey_state.attribute.raw = 0;
|
||||
if (controller.sixaxis_sensor_enabled) {
|
||||
sixaxis_fullkey_state.attribute.is_connected.Assign(1);
|
||||
sixaxis_fullkey_state.accel = motion_state[0].accel;
|
||||
sixaxis_fullkey_state.gyro = motion_state[0].gyro;
|
||||
sixaxis_fullkey_state.rotation = motion_state[0].rotation;
|
||||
sixaxis_fullkey_state.orientation = motion_state[0].orientation;
|
||||
}
|
||||
set_motion_state(sixaxis_fullkey_state, motion_state[0]);
|
||||
break;
|
||||
case Core::HID::NpadStyleIndex::Handheld:
|
||||
sixaxis_handheld_state.attribute.raw = 0;
|
||||
if (controller.sixaxis_sensor_enabled) {
|
||||
sixaxis_handheld_state.attribute.is_connected.Assign(1);
|
||||
sixaxis_handheld_state.accel = motion_state[0].accel;
|
||||
sixaxis_handheld_state.gyro = motion_state[0].gyro;
|
||||
sixaxis_handheld_state.rotation = motion_state[0].rotation;
|
||||
sixaxis_handheld_state.orientation = motion_state[0].orientation;
|
||||
}
|
||||
set_motion_state(sixaxis_handheld_state, motion_state[0]);
|
||||
break;
|
||||
case Core::HID::NpadStyleIndex::JoyconDual:
|
||||
sixaxis_dual_left_state.attribute.raw = 0;
|
||||
sixaxis_dual_right_state.attribute.raw = 0;
|
||||
if (controller.sixaxis_sensor_enabled) {
|
||||
// Set motion for the left joycon
|
||||
sixaxis_dual_left_state.attribute.is_connected.Assign(1);
|
||||
sixaxis_dual_left_state.accel = motion_state[0].accel;
|
||||
sixaxis_dual_left_state.gyro = motion_state[0].gyro;
|
||||
sixaxis_dual_left_state.rotation = motion_state[0].rotation;
|
||||
sixaxis_dual_left_state.orientation = motion_state[0].orientation;
|
||||
}
|
||||
if (controller.sixaxis_sensor_enabled) {
|
||||
// Set motion for the right joycon
|
||||
sixaxis_dual_right_state.attribute.is_connected.Assign(1);
|
||||
sixaxis_dual_right_state.accel = motion_state[1].accel;
|
||||
sixaxis_dual_right_state.gyro = motion_state[1].gyro;
|
||||
sixaxis_dual_right_state.rotation = motion_state[1].rotation;
|
||||
sixaxis_dual_right_state.orientation = motion_state[1].orientation;
|
||||
}
|
||||
set_motion_state(sixaxis_dual_left_state, motion_state[0]);
|
||||
set_motion_state(sixaxis_dual_right_state, motion_state[1]);
|
||||
break;
|
||||
case Core::HID::NpadStyleIndex::JoyconLeft:
|
||||
sixaxis_left_lifo_state.attribute.raw = 0;
|
||||
if (controller.sixaxis_sensor_enabled) {
|
||||
sixaxis_left_lifo_state.attribute.is_connected.Assign(1);
|
||||
sixaxis_left_lifo_state.accel = motion_state[0].accel;
|
||||
sixaxis_left_lifo_state.gyro = motion_state[0].gyro;
|
||||
sixaxis_left_lifo_state.rotation = motion_state[0].rotation;
|
||||
sixaxis_left_lifo_state.orientation = motion_state[0].orientation;
|
||||
}
|
||||
set_motion_state(sixaxis_left_lifo_state, motion_state[0]);
|
||||
break;
|
||||
case Core::HID::NpadStyleIndex::JoyconRight:
|
||||
sixaxis_right_lifo_state.attribute.raw = 0;
|
||||
if (controller.sixaxis_sensor_enabled) {
|
||||
sixaxis_right_lifo_state.attribute.is_connected.Assign(1);
|
||||
sixaxis_right_lifo_state.accel = motion_state[1].accel;
|
||||
sixaxis_right_lifo_state.gyro = motion_state[1].gyro;
|
||||
sixaxis_right_lifo_state.rotation = motion_state[1].rotation;
|
||||
sixaxis_right_lifo_state.orientation = motion_state[1].orientation;
|
||||
}
|
||||
set_motion_state(sixaxis_right_lifo_state, motion_state[1]);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
@@ -37,8 +37,7 @@ namespace Service::HID {
|
||||
// Period time is obtained by measuring the number of samples in a second on HW using a homebrew
|
||||
constexpr auto pad_update_ns = std::chrono::nanoseconds{4 * 1000 * 1000}; // (4ms, 250Hz)
|
||||
constexpr auto mouse_keyboard_update_ns = std::chrono::nanoseconds{8 * 1000 * 1000}; // (8ms, 125Hz)
|
||||
// TODO: Correct update rate for motion is 5ms. Check why some games don't behave at that speed
|
||||
constexpr auto motion_update_ns = std::chrono::nanoseconds{10 * 1000 * 1000}; // (10ms, 100Hz)
|
||||
constexpr auto motion_update_ns = std::chrono::nanoseconds{5 * 1000 * 1000}; // (5ms, 200Hz)
|
||||
|
||||
IAppletResource::IAppletResource(Core::System& system_,
|
||||
KernelHelpers::ServiceContext& service_context_)
|
||||
|
||||
@@ -732,7 +732,7 @@ std::unique_ptr<Common::Input::InputDevice> InputFactory::CreateHatButtonDevice(
|
||||
std::unique_ptr<Common::Input::InputDevice> InputFactory::CreateStickDevice(
|
||||
const Common::ParamPackage& params) {
|
||||
const auto deadzone = std::clamp(params.Get("deadzone", 0.15f), 0.0f, 1.0f);
|
||||
const auto range = std::clamp(params.Get("range", 1.0f), 0.25f, 1.50f);
|
||||
const auto range = std::clamp(params.Get("range", 0.95f), 0.25f, 1.50f);
|
||||
const auto threshold = std::clamp(params.Get("threshold", 0.5f), 0.0f, 1.0f);
|
||||
const PadIdentifier identifier = {
|
||||
.guid = Common::UUID{params.Get("guid", "")},
|
||||
|
||||
@@ -103,6 +103,6 @@ struct fmt::formatter<Shader::IR::Opcode> {
|
||||
}
|
||||
template <typename FormatContext>
|
||||
auto format(const Shader::IR::Opcode& op, FormatContext& ctx) {
|
||||
return format_to(ctx.out(), "{}", Shader::IR::NameOf(op));
|
||||
return fmt::format_to(ctx.out(), "{}", Shader::IR::NameOf(op));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -24,6 +24,6 @@ struct fmt::formatter<Shader::Maxwell::Opcode> {
|
||||
}
|
||||
template <typename FormatContext>
|
||||
auto format(const Shader::Maxwell::Opcode& opcode, FormatContext& ctx) {
|
||||
return format_to(ctx.out(), "{}", NameOf(opcode));
|
||||
return fmt::format_to(ctx.out(), "{}", NameOf(opcode));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -173,6 +173,8 @@ void Maxwell3D::ProcessMethodCall(u32 method, u32 argument, u32 nonshadow_argume
|
||||
case MAXWELL3D_REG_INDEX(shadow_ram_control):
|
||||
shadow_state.shadow_ram_control = static_cast<Regs::ShadowRamControl>(nonshadow_argument);
|
||||
return;
|
||||
case MAXWELL3D_REG_INDEX(macros.upload_address):
|
||||
return macro_engine->ClearCode(regs.macros.upload_address);
|
||||
case MAXWELL3D_REG_INDEX(macros.data):
|
||||
return macro_engine->AddCode(regs.macros.upload_address, argument);
|
||||
case MAXWELL3D_REG_INDEX(macros.bind):
|
||||
|
||||
@@ -134,7 +134,8 @@ void MaxwellDMA::CopyBlockLinearToPitch() {
|
||||
|
||||
// Deswizzle the input and copy it over.
|
||||
UNIMPLEMENTED_IF(regs.launch_dma.remap_enable != 0);
|
||||
const u32 bytes_per_pixel = regs.pitch_out / regs.line_length_in;
|
||||
const u32 bytes_per_pixel =
|
||||
regs.launch_dma.remap_enable ? regs.pitch_out / regs.line_length_in : 1;
|
||||
const Parameters& src_params = regs.src_params;
|
||||
const u32 width = src_params.width;
|
||||
const u32 height = src_params.height;
|
||||
@@ -166,7 +167,8 @@ void MaxwellDMA::CopyPitchToBlockLinear() {
|
||||
UNIMPLEMENTED_IF(regs.launch_dma.remap_enable != 0);
|
||||
|
||||
const auto& dst_params = regs.dst_params;
|
||||
const u32 bytes_per_pixel = regs.pitch_in / regs.line_length_in;
|
||||
const u32 bytes_per_pixel =
|
||||
regs.launch_dma.remap_enable ? regs.pitch_in / regs.line_length_in : 1;
|
||||
const u32 width = dst_params.width;
|
||||
const u32 height = dst_params.height;
|
||||
const u32 depth = dst_params.depth;
|
||||
@@ -210,7 +212,8 @@ void MaxwellDMA::CopyPitchToBlockLinear() {
|
||||
}
|
||||
|
||||
void MaxwellDMA::FastCopyBlockLinearToPitch() {
|
||||
const u32 bytes_per_pixel = regs.pitch_out / regs.line_length_in;
|
||||
const u32 bytes_per_pixel =
|
||||
regs.launch_dma.remap_enable ? regs.pitch_out / regs.line_length_in : 1;
|
||||
const size_t src_size = GOB_SIZE;
|
||||
const size_t dst_size = static_cast<size_t>(regs.pitch_out) * regs.line_count;
|
||||
u32 pos_x = regs.src_params.origin.x;
|
||||
|
||||
@@ -2,11 +2,15 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <cstring>
|
||||
#include <fstream>
|
||||
#include <optional>
|
||||
#include <span>
|
||||
|
||||
#include <boost/container_hash/hash.hpp>
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "common/fs/fs.h"
|
||||
#include "common/fs/path_util.h"
|
||||
#include "common/settings.h"
|
||||
#include "video_core/macro/macro.h"
|
||||
#include "video_core/macro/macro_hle.h"
|
||||
@@ -15,6 +19,23 @@
|
||||
|
||||
namespace Tegra {
|
||||
|
||||
static void Dump(u64 hash, std::span<const u32> code) {
|
||||
const auto base_dir{Common::FS::GetYuzuPath(Common::FS::YuzuPath::DumpDir)};
|
||||
const auto macro_dir{base_dir / "macros"};
|
||||
if (!Common::FS::CreateDir(base_dir) || !Common::FS::CreateDir(macro_dir)) {
|
||||
LOG_ERROR(Common_Filesystem, "Failed to create macro dump directories");
|
||||
return;
|
||||
}
|
||||
const auto name{macro_dir / fmt::format("{:016x}.macro", hash)};
|
||||
std::fstream macro_file(name, std::ios::out | std::ios::binary);
|
||||
if (!macro_file) {
|
||||
LOG_ERROR(Common_Filesystem, "Unable to open or create file at {}",
|
||||
Common::FS::PathToUTF8String(name));
|
||||
return;
|
||||
}
|
||||
macro_file.write(reinterpret_cast<const char*>(code.data()), code.size_bytes());
|
||||
}
|
||||
|
||||
MacroEngine::MacroEngine(Engines::Maxwell3D& maxwell3d)
|
||||
: hle_macros{std::make_unique<Tegra::HLEMacro>(maxwell3d)} {}
|
||||
|
||||
@@ -24,6 +45,11 @@ void MacroEngine::AddCode(u32 method, u32 data) {
|
||||
uploaded_macro_code[method].push_back(data);
|
||||
}
|
||||
|
||||
void MacroEngine::ClearCode(u32 method) {
|
||||
macro_cache.erase(method);
|
||||
uploaded_macro_code.erase(method);
|
||||
}
|
||||
|
||||
void MacroEngine::Execute(u32 method, const std::vector<u32>& parameters) {
|
||||
auto compiled_macro = macro_cache.find(method);
|
||||
if (compiled_macro != macro_cache.end()) {
|
||||
@@ -54,6 +80,9 @@ void MacroEngine::Execute(u32 method, const std::vector<u32>& parameters) {
|
||||
if (!mid_method.has_value()) {
|
||||
cache_info.lle_program = Compile(macro_code->second);
|
||||
cache_info.hash = boost::hash_value(macro_code->second);
|
||||
if (Settings::values.dump_macros) {
|
||||
Dump(cache_info.hash, macro_code->second);
|
||||
}
|
||||
} else {
|
||||
const auto& macro_cached = uploaded_macro_code[mid_method.value()];
|
||||
const auto rebased_method = method - mid_method.value();
|
||||
@@ -63,6 +92,9 @@ void MacroEngine::Execute(u32 method, const std::vector<u32>& parameters) {
|
||||
code.size() * sizeof(u32));
|
||||
cache_info.hash = boost::hash_value(code);
|
||||
cache_info.lle_program = Compile(code);
|
||||
if (Settings::values.dump_macros) {
|
||||
Dump(cache_info.hash, code);
|
||||
}
|
||||
}
|
||||
|
||||
if (auto hle_program = hle_macros->GetHLEProgram(cache_info.hash)) {
|
||||
|
||||
@@ -117,6 +117,9 @@ public:
|
||||
// Store the uploaded macro code to compile them when they're called.
|
||||
void AddCode(u32 method, u32 data);
|
||||
|
||||
// Clear the code associated with a method.
|
||||
void ClearCode(u32 method);
|
||||
|
||||
// Compiles the macro if its not in the cache, and executes the compiled macro
|
||||
void Execute(u32 method, const std::vector<u32>& parameters);
|
||||
|
||||
|
||||
@@ -23,7 +23,8 @@ MICROPROFILE_DEFINE(MacroJitExecute, "GPU", "Execute macro JIT", MP_RGB(255, 255
|
||||
namespace Tegra {
|
||||
namespace {
|
||||
constexpr Xbyak::Reg64 STATE = Xbyak::util::rbx;
|
||||
constexpr Xbyak::Reg32 RESULT = Xbyak::util::ebp;
|
||||
constexpr Xbyak::Reg32 RESULT = Xbyak::util::r10d;
|
||||
constexpr Xbyak::Reg64 MAX_PARAMETER = Xbyak::util::r11;
|
||||
constexpr Xbyak::Reg64 PARAMETERS = Xbyak::util::r12;
|
||||
constexpr Xbyak::Reg32 METHOD_ADDRESS = Xbyak::util::r14d;
|
||||
constexpr Xbyak::Reg64 BRANCH_HOLDER = Xbyak::util::r15;
|
||||
@@ -31,6 +32,7 @@ constexpr Xbyak::Reg64 BRANCH_HOLDER = Xbyak::util::r15;
|
||||
constexpr std::bitset<32> PERSISTENT_REGISTERS = Common::X64::BuildRegSet({
|
||||
STATE,
|
||||
RESULT,
|
||||
MAX_PARAMETER,
|
||||
PARAMETERS,
|
||||
METHOD_ADDRESS,
|
||||
BRANCH_HOLDER,
|
||||
@@ -80,7 +82,7 @@ private:
|
||||
u32 carry_flag{};
|
||||
};
|
||||
static_assert(offsetof(JITState, maxwell3d) == 0, "Maxwell3D is not at 0x0");
|
||||
using ProgramType = void (*)(JITState*, const u32*);
|
||||
using ProgramType = void (*)(JITState*, const u32*, const u32*);
|
||||
|
||||
struct OptimizerState {
|
||||
bool can_skip_carry{};
|
||||
@@ -112,7 +114,7 @@ void MacroJITx64Impl::Execute(const std::vector<u32>& parameters, u32 method) {
|
||||
JITState state{};
|
||||
state.maxwell3d = &maxwell3d;
|
||||
state.registers = {};
|
||||
program(&state, parameters.data());
|
||||
program(&state, parameters.data(), parameters.data() + parameters.size());
|
||||
}
|
||||
|
||||
void MacroJITx64Impl::Compile_ALU(Macro::Opcode opcode) {
|
||||
@@ -488,6 +490,7 @@ void MacroJITx64Impl::Compile() {
|
||||
// JIT state
|
||||
mov(STATE, Common::X64::ABI_PARAM1);
|
||||
mov(PARAMETERS, Common::X64::ABI_PARAM2);
|
||||
mov(MAX_PARAMETER, Common::X64::ABI_PARAM3);
|
||||
xor_(RESULT, RESULT);
|
||||
xor_(METHOD_ADDRESS, METHOD_ADDRESS);
|
||||
xor_(BRANCH_HOLDER, BRANCH_HOLDER);
|
||||
@@ -598,7 +601,22 @@ bool MacroJITx64Impl::Compile_NextInstruction() {
|
||||
return true;
|
||||
}
|
||||
|
||||
static void WarnInvalidParameter(uintptr_t parameter, uintptr_t max_parameter) {
|
||||
LOG_CRITICAL(HW_GPU,
|
||||
"Macro JIT: invalid parameter access 0x{:x} (0x{:x} is the last parameter)",
|
||||
parameter, max_parameter - sizeof(u32));
|
||||
}
|
||||
|
||||
Xbyak::Reg32 MacroJITx64Impl::Compile_FetchParameter() {
|
||||
Xbyak::Label parameter_ok{};
|
||||
cmp(PARAMETERS, MAX_PARAMETER);
|
||||
jb(parameter_ok, T_NEAR);
|
||||
Common::X64::ABI_PushRegistersAndAdjustStack(*this, PersistentCallerSavedRegs(), 0);
|
||||
mov(Common::X64::ABI_PARAM1, PARAMETERS);
|
||||
mov(Common::X64::ABI_PARAM2, MAX_PARAMETER);
|
||||
Common::X64::CallFarFunction(*this, &WarnInvalidParameter);
|
||||
Common::X64::ABI_PopRegistersAndAdjustStack(*this, PersistentCallerSavedRegs(), 0);
|
||||
L(parameter_ok);
|
||||
mov(eax, dword[PARAMETERS]);
|
||||
add(PARAMETERS, sizeof(u32));
|
||||
return eax;
|
||||
|
||||
@@ -563,12 +563,11 @@ void RasterizerOpenGL::SyncViewport() {
|
||||
flags[Dirty::FrontFace] = false;
|
||||
|
||||
GLenum mode = MaxwellToGL::FrontFace(regs.front_face);
|
||||
bool flip_faces = false;
|
||||
if (regs.screen_y_control.triangle_rast_flip != 0 &&
|
||||
regs.viewport_transform[0].scale_y < 0.0f) {
|
||||
bool flip_faces = true;
|
||||
if (regs.screen_y_control.triangle_rast_flip != 0) {
|
||||
flip_faces = !flip_faces;
|
||||
}
|
||||
if (regs.viewport_transform[0].scale_z < 0.0f) {
|
||||
if (regs.viewport_transform[0].scale_y < 0.0f) {
|
||||
flip_faces = !flip_faces;
|
||||
}
|
||||
if (flip_faces) {
|
||||
|
||||
@@ -411,11 +411,11 @@ void QtSoftwareKeyboardDialog::ShowTextCheckDialog(
|
||||
break;
|
||||
}
|
||||
|
||||
auto text = ui->topOSK->currentIndex() == 1
|
||||
? ui->text_edit_osk->toPlainText().toStdU16String()
|
||||
: ui->line_edit_osk->text().toStdU16String();
|
||||
const auto text = ui->topOSK->currentIndex() == 1 ? ui->text_edit_osk->toPlainText()
|
||||
: ui->line_edit_osk->text();
|
||||
auto text_str = Common::U16StringFromBuffer(text.utf16(), text.size());
|
||||
|
||||
emit SubmitNormalText(SwkbdResult::Ok, std::move(text), true);
|
||||
emit SubmitNormalText(SwkbdResult::Ok, std::move(text_str), true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -562,7 +562,7 @@ void QtSoftwareKeyboardDialog::keyPressEvent(QKeyEvent* event) {
|
||||
return;
|
||||
}
|
||||
|
||||
InlineTextInsertString(entered_text.toStdU16String());
|
||||
InlineTextInsertString(Common::U16StringFromBuffer(entered_text.utf16(), entered_text.size()));
|
||||
}
|
||||
|
||||
void QtSoftwareKeyboardDialog::MoveAndResizeWindow(QPoint pos, QSize size) {
|
||||
@@ -1119,11 +1119,11 @@ void QtSoftwareKeyboardDialog::NormalKeyboardButtonClicked(QPushButton* button)
|
||||
}
|
||||
|
||||
if (button == ui->button_ok || button == ui->button_ok_shift || button == ui->button_ok_num) {
|
||||
auto text = ui->topOSK->currentIndex() == 1
|
||||
? ui->text_edit_osk->toPlainText().toStdU16String()
|
||||
: ui->line_edit_osk->text().toStdU16String();
|
||||
const auto text = ui->topOSK->currentIndex() == 1 ? ui->text_edit_osk->toPlainText()
|
||||
: ui->line_edit_osk->text();
|
||||
auto text_str = Common::U16StringFromBuffer(text.utf16(), text.size());
|
||||
|
||||
emit SubmitNormalText(SwkbdResult::Ok, std::move(text));
|
||||
emit SubmitNormalText(SwkbdResult::Ok, std::move(text_str));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1189,7 +1189,8 @@ void QtSoftwareKeyboardDialog::InlineKeyboardButtonClicked(QPushButton* button)
|
||||
return;
|
||||
}
|
||||
|
||||
InlineTextInsertString(button->text().toStdU16String());
|
||||
const auto button_text = button->text();
|
||||
InlineTextInsertString(Common::U16StringFromBuffer(button_text.utf16(), button_text.size()));
|
||||
|
||||
// Revert the keyboard to lowercase if the shift key is active.
|
||||
if (bottom_osk_index == BottomOSKIndex::UpperCase && !caps_lock_enabled) {
|
||||
@@ -1282,11 +1283,11 @@ void QtSoftwareKeyboardDialog::TranslateButtonPress(Core::HID::NpadButton button
|
||||
if (is_inline) {
|
||||
emit SubmitInlineText(SwkbdReplyType::DecidedCancel, current_text, cursor_position);
|
||||
} else {
|
||||
auto text = ui->topOSK->currentIndex() == 1
|
||||
? ui->text_edit_osk->toPlainText().toStdU16String()
|
||||
: ui->line_edit_osk->text().toStdU16String();
|
||||
const auto text = ui->topOSK->currentIndex() == 1 ? ui->text_edit_osk->toPlainText()
|
||||
: ui->line_edit_osk->text();
|
||||
auto text_str = Common::U16StringFromBuffer(text.utf16(), text.size());
|
||||
|
||||
emit SubmitNormalText(SwkbdResult::Cancel, std::move(text));
|
||||
emit SubmitNormalText(SwkbdResult::Cancel, std::move(text_str));
|
||||
}
|
||||
break;
|
||||
case Core::HID::NpadButton::Y:
|
||||
|
||||
@@ -53,6 +53,8 @@ void ConfigureDebug::SetConfiguration() {
|
||||
ui->enable_nsight_aftermath->setChecked(Settings::values.enable_nsight_aftermath.GetValue());
|
||||
ui->dump_shaders->setEnabled(runtime_lock);
|
||||
ui->dump_shaders->setChecked(Settings::values.dump_shaders.GetValue());
|
||||
ui->dump_macros->setEnabled(runtime_lock);
|
||||
ui->dump_macros->setChecked(Settings::values.dump_macros.GetValue());
|
||||
ui->disable_macro_jit->setEnabled(runtime_lock);
|
||||
ui->disable_macro_jit->setChecked(Settings::values.disable_macro_jit.GetValue());
|
||||
ui->disable_loop_safety_checks->setEnabled(runtime_lock);
|
||||
@@ -83,6 +85,7 @@ void ConfigureDebug::ApplyConfiguration() {
|
||||
Settings::values.cpu_debug_mode = ui->enable_cpu_debugging->isChecked();
|
||||
Settings::values.enable_nsight_aftermath = ui->enable_nsight_aftermath->isChecked();
|
||||
Settings::values.dump_shaders = ui->dump_shaders->isChecked();
|
||||
Settings::values.dump_macros = ui->dump_macros->isChecked();
|
||||
Settings::values.disable_shader_loop_safety_checks =
|
||||
ui->disable_loop_safety_checks->isChecked();
|
||||
Settings::values.disable_macro_jit = ui->disable_macro_jit->isChecked();
|
||||
|
||||
@@ -118,6 +118,19 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QCheckBox" name="dump_macros">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>When checked, it will dump all the macro programs of the GPU</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Dump Maxwell Macros</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QCheckBox" name="disable_macro_jit">
|
||||
<property name="enabled">
|
||||
|
||||
@@ -520,7 +520,28 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i
|
||||
QMenu context_menu;
|
||||
Common::ParamPackage param = emulated_controller->GetStickParam(analog_id);
|
||||
context_menu.addAction(tr("Clear"), [&] {
|
||||
emulated_controller->SetStickParam(analog_id, {});
|
||||
if (param.Get("engine", "") != "analog_from_button") {
|
||||
emulated_controller->SetStickParam(analog_id, {});
|
||||
for (auto button : analog_map_buttons[analog_id]) {
|
||||
button->setText(tr("[not set]"));
|
||||
}
|
||||
return;
|
||||
}
|
||||
switch (sub_button_id) {
|
||||
case 0:
|
||||
param.Erase("up");
|
||||
break;
|
||||
case 1:
|
||||
param.Erase("down");
|
||||
break;
|
||||
case 2:
|
||||
param.Erase("left");
|
||||
break;
|
||||
case 3:
|
||||
param.Erase("right");
|
||||
break;
|
||||
}
|
||||
emulated_controller->SetStickParam(analog_id, param);
|
||||
analog_map_buttons[analog_id][sub_button_id]->setText(tr("[not set]"));
|
||||
});
|
||||
context_menu.addAction(tr("Center axis"), [&] {
|
||||
@@ -988,7 +1009,7 @@ void ConfigureInputPlayer::UpdateUI() {
|
||||
slider_value = static_cast<int>(param.Get("deadzone", 0.15f) * 100);
|
||||
deadzone_label->setText(tr("Deadzone: %1%").arg(slider_value));
|
||||
deadzone_slider->setValue(slider_value);
|
||||
range_spinbox->setValue(static_cast<int>(param.Get("range", 1.0f) * 100));
|
||||
range_spinbox->setValue(static_cast<int>(param.Get("range", 0.95f) * 100));
|
||||
} else {
|
||||
slider_value = static_cast<int>(param.Get("modifier_scale", 0.5f) * 100);
|
||||
modifier_label->setText(tr("Modifier Range: %1%").arg(slider_value));
|
||||
|
||||
@@ -754,13 +754,13 @@
|
||||
<string>%</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>50</number>
|
||||
<number>25</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>150</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>100</number>
|
||||
<number>95</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -2985,13 +2985,13 @@
|
||||
<string>%</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>50</number>
|
||||
<number>25</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>150</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>100</number>
|
||||
<number>95</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
||||
@@ -1401,7 +1401,8 @@ void GMainWindow::BootGame(const QString& filename, u64 program_id, std::size_t
|
||||
if (loader != nullptr && loader->ReadProgramId(title_id) == Loader::ResultStatus::Success &&
|
||||
type == StartGameType::Normal) {
|
||||
// Load per game settings
|
||||
const auto file_path = std::filesystem::path{filename.toStdU16String()};
|
||||
const auto file_path =
|
||||
std::filesystem::path{Common::U16StringFromBuffer(filename.utf16(), filename.size())};
|
||||
const auto config_file_name = title_id == 0
|
||||
? Common::FS::PathToUTF8String(file_path.filename())
|
||||
: fmt::format("{:016X}", title_id);
|
||||
@@ -1482,7 +1483,8 @@ void GMainWindow::BootGame(const QString& filename, u64 program_id, std::size_t
|
||||
}
|
||||
if (res != Loader::ResultStatus::Success || title_name.empty()) {
|
||||
title_name = Common::FS::PathToUTF8String(
|
||||
std::filesystem::path{filename.toStdU16String()}.filename());
|
||||
std::filesystem::path{Common::U16StringFromBuffer(filename.utf16(), filename.size())}
|
||||
.filename());
|
||||
}
|
||||
const bool is_64bit = system->Kernel().CurrentProcess()->Is64BitProcess();
|
||||
const auto instruction_set_suffix = is_64bit ? tr("(64-bit)") : tr("(32-bit)");
|
||||
|
||||
Reference in New Issue
Block a user