early-access version 3344

main
pineappleEA 2023-01-29 05:56:02 +01:00
parent 6198ef28c6
commit 19de7fc82d
9 changed files with 135 additions and 30 deletions

View File

@ -1,7 +1,7 @@
yuzu emulator early access
=============
This is the source code for early-access 3343.
This is the source code for early-access 3344.
## Legal Notice

View File

@ -130,6 +130,8 @@ struct ButtonStatus {
bool inverted{};
// Press once to activate, press again to release
bool toggle{};
// Spams the button when active
bool turbo{};
// Internal lock for the toggle status
bool locked{};
};

View File

@ -687,6 +687,7 @@ void EmulatedController::SetButton(const Common::Input::CallbackStatus& callback
}
current_status.toggle = new_status.toggle;
current_status.turbo = new_status.turbo;
current_status.uuid = uuid;
// Update button status with current
@ -1548,7 +1549,7 @@ NpadButtonState EmulatedController::GetNpadButtons() const {
if (is_configuring) {
return {};
}
return controller.npad_button_state;
return {controller.npad_button_state.raw & GetTurboButtonMask()};
}
DebugPadButton EmulatedController::GetDebugPadButtons() const {
@ -1656,4 +1657,74 @@ void EmulatedController::DeleteCallback(int key) {
}
callback_list.erase(iterator);
}
void EmulatedController::TurboButtonUpdate() {
turbo_button_state = !turbo_button_state;
}
NpadButton EmulatedController::GetTurboButtonMask() const {
// Apply no mask when disabled
if (!turbo_button_state) {
return {NpadButton::All};
}
NpadButtonState button_mask{};
for (std::size_t index = 0; index < controller.button_values.size(); ++index) {
if (!controller.button_values[index].turbo) {
continue;
}
switch (index) {
case Settings::NativeButton::A:
button_mask.a.Assign(1);
break;
case Settings::NativeButton::B:
button_mask.b.Assign(1);
break;
case Settings::NativeButton::X:
button_mask.x.Assign(1);
break;
case Settings::NativeButton::Y:
button_mask.y.Assign(1);
break;
case Settings::NativeButton::L:
button_mask.l.Assign(1);
break;
case Settings::NativeButton::R:
button_mask.r.Assign(1);
break;
case Settings::NativeButton::ZL:
button_mask.zl.Assign(1);
break;
case Settings::NativeButton::ZR:
button_mask.zr.Assign(1);
break;
case Settings::NativeButton::DLeft:
button_mask.left.Assign(1);
break;
case Settings::NativeButton::DUp:
button_mask.up.Assign(1);
break;
case Settings::NativeButton::DRight:
button_mask.right.Assign(1);
break;
case Settings::NativeButton::DDown:
button_mask.down.Assign(1);
break;
case Settings::NativeButton::SL:
button_mask.left_sl.Assign(1);
button_mask.right_sl.Assign(1);
break;
case Settings::NativeButton::SR:
button_mask.left_sr.Assign(1);
button_mask.right_sr.Assign(1);
break;
default:
break;
}
}
return static_cast<NpadButton>(~button_mask.raw);
}
} // namespace Core::HID

View File

@ -411,6 +411,9 @@ public:
*/
void DeleteCallback(int key);
/// Swaps the state of the turbo buttons
void TurboButtonUpdate();
private:
/// creates input devices from params
void LoadDevices();
@ -511,6 +514,8 @@ private:
*/
void TriggerOnChange(ControllerTriggerType type, bool is_service_update);
NpadButton GetTurboButtonMask() const;
const NpadIdType npad_id_type;
NpadStyleIndex npad_type{NpadStyleIndex::None};
NpadStyleIndex original_npad_type{NpadStyleIndex::None};
@ -520,6 +525,7 @@ private:
bool system_buttons_enabled{true};
f32 motion_sensitivity{0.01f};
bool force_update_motion{false};
bool turbo_button_state{false};
// Temporary values to avoid doing changes while the controller is in configuring mode
NpadStyleIndex tmp_npad_type{NpadStyleIndex::None};

View File

@ -428,6 +428,9 @@ void Controller_NPad::RequestPadStateUpdate(Core::HID::NpadIdType npad_id) {
return;
}
// This function is unique to yuzu for the turbo buttons to work properly
controller.device->TurboButtonUpdate();
auto& pad_entry = controller.npad_pad_state;
auto& trigger_entry = controller.npad_trigger_state;
const auto button_state = controller.device->GetNpadButtons();

View File

@ -16,10 +16,10 @@ public:
class InputFromButton final : public Common::Input::InputDevice {
public:
explicit InputFromButton(PadIdentifier identifier_, int button_, bool toggle_, bool inverted_,
InputEngine* input_engine_)
: identifier(identifier_), button(button_), toggle(toggle_), inverted(inverted_),
input_engine(input_engine_) {
explicit InputFromButton(PadIdentifier identifier_, int button_, bool turbo_, bool toggle_,
bool inverted_, InputEngine* input_engine_)
: identifier(identifier_), button(button_), turbo(turbo_), toggle(toggle_),
inverted(inverted_), input_engine(input_engine_) {
UpdateCallback engine_callback{[this]() { OnChange(); }};
const InputIdentifier input_identifier{
.identifier = identifier,
@ -40,6 +40,7 @@ public:
.value = input_engine->GetButton(identifier, button),
.inverted = inverted,
.toggle = toggle,
.turbo = turbo,
};
}
@ -68,6 +69,7 @@ public:
private:
const PadIdentifier identifier;
const int button;
const bool turbo;
const bool toggle;
const bool inverted;
int callback_key;
@ -77,10 +79,10 @@ private:
class InputFromHatButton final : public Common::Input::InputDevice {
public:
explicit InputFromHatButton(PadIdentifier identifier_, int button_, u8 direction_, bool toggle_,
bool inverted_, InputEngine* input_engine_)
: identifier(identifier_), button(button_), direction(direction_), toggle(toggle_),
inverted(inverted_), input_engine(input_engine_) {
explicit InputFromHatButton(PadIdentifier identifier_, int button_, u8 direction_, bool turbo_,
bool toggle_, bool inverted_, InputEngine* input_engine_)
: identifier(identifier_), button(button_), direction(direction_), turbo(turbo_),
toggle(toggle_), inverted(inverted_), input_engine(input_engine_) {
UpdateCallback engine_callback{[this]() { OnChange(); }};
const InputIdentifier input_identifier{
.identifier = identifier,
@ -101,6 +103,7 @@ public:
.value = input_engine->GetHatButton(identifier, button, direction),
.inverted = inverted,
.toggle = toggle,
.turbo = turbo,
};
}
@ -130,6 +133,7 @@ private:
const PadIdentifier identifier;
const int button;
const u8 direction;
const bool turbo;
const bool toggle;
const bool inverted;
int callback_key;
@ -853,14 +857,15 @@ std::unique_ptr<Common::Input::InputDevice> InputFactory::CreateButtonDevice(
const auto keyboard_key = params.Get("code", 0);
const auto toggle = params.Get("toggle", false) != 0;
const auto inverted = params.Get("inverted", false) != 0;
const auto turbo = params.Get("turbo", false) != 0;
input_engine->PreSetController(identifier);
input_engine->PreSetButton(identifier, button_id);
input_engine->PreSetButton(identifier, keyboard_key);
if (keyboard_key != 0) {
return std::make_unique<InputFromButton>(identifier, keyboard_key, toggle, inverted,
return std::make_unique<InputFromButton>(identifier, keyboard_key, turbo, toggle, inverted,
input_engine.get());
}
return std::make_unique<InputFromButton>(identifier, button_id, toggle, inverted,
return std::make_unique<InputFromButton>(identifier, button_id, turbo, toggle, inverted,
input_engine.get());
}
@ -876,11 +881,12 @@ std::unique_ptr<Common::Input::InputDevice> InputFactory::CreateHatButtonDevice(
const auto direction = input_engine->GetHatButtonId(params.Get("direction", ""));
const auto toggle = params.Get("toggle", false) != 0;
const auto inverted = params.Get("inverted", false) != 0;
const auto turbo = params.Get("turbo", false) != 0;
input_engine->PreSetController(identifier);
input_engine->PreSetHatButton(identifier, button_id);
return std::make_unique<InputFromHatButton>(identifier, button_id, direction, toggle, inverted,
input_engine.get());
return std::make_unique<InputFromHatButton>(identifier, button_id, direction, turbo, toggle,
inverted, input_engine.get());
}
std::unique_ptr<Common::Input::InputDevice> InputFactory::CreateStickDevice(

View File

@ -355,21 +355,21 @@ TextureInst MakeInst(Environment& env, IR::Block* block, IR::Inst& inst) {
};
}
TextureType ReadTextureType(Environment& env, const ConstBufferAddr& cbuf) {
u32 GetTextureHandle(Environment& env, const ConstBufferAddr& cbuf) {
const u32 secondary_index{cbuf.has_secondary ? cbuf.secondary_index : cbuf.index};
const u32 secondary_offset{cbuf.has_secondary ? cbuf.secondary_offset : cbuf.offset};
const u32 lhs_raw{env.ReadCbufValue(cbuf.index, cbuf.offset) << cbuf.shift_left};
const u32 rhs_raw{env.ReadCbufValue(secondary_index, secondary_offset)
<< cbuf.secondary_shift_left};
return env.ReadTextureType(lhs_raw | rhs_raw);
return lhs_raw | rhs_raw;
}
TextureType ReadTextureType(Environment& env, const ConstBufferAddr& cbuf) {
return env.ReadTextureType(GetTextureHandle(env, cbuf));
}
TexturePixelFormat ReadTexturePixelFormat(Environment& env, const ConstBufferAddr& cbuf) {
const u32 secondary_index{cbuf.has_secondary ? cbuf.secondary_index : cbuf.index};
const u32 secondary_offset{cbuf.has_secondary ? cbuf.secondary_offset : cbuf.offset};
const u32 lhs_raw{env.ReadCbufValue(cbuf.index, cbuf.offset)};
const u32 rhs_raw{env.ReadCbufValue(secondary_index, secondary_offset)};
return env.ReadTexturePixelFormat(lhs_raw | rhs_raw);
return env.ReadTexturePixelFormat(GetTextureHandle(env, cbuf));
}
class Descriptors {
@ -386,8 +386,10 @@ public:
return Add(texture_buffer_descriptors, desc, [&desc](const auto& existing) {
return desc.cbuf_index == existing.cbuf_index &&
desc.cbuf_offset == existing.cbuf_offset &&
desc.shift_left == existing.shift_left &&
desc.secondary_cbuf_index == existing.secondary_cbuf_index &&
desc.secondary_cbuf_offset == existing.secondary_cbuf_offset &&
desc.secondary_shift_left == existing.secondary_shift_left &&
desc.count == existing.count && desc.size_shift == existing.size_shift &&
desc.has_secondary == existing.has_secondary;
});
@ -405,15 +407,20 @@ public:
}
u32 Add(const TextureDescriptor& desc) {
return Add(texture_descriptors, desc, [&desc](const auto& existing) {
const u32 index{Add(texture_descriptors, desc, [&desc](const auto& existing) {
return desc.type == existing.type && desc.is_depth == existing.is_depth &&
desc.has_secondary == existing.has_secondary &&
desc.cbuf_index == existing.cbuf_index &&
desc.cbuf_offset == existing.cbuf_offset &&
desc.shift_left == existing.shift_left &&
desc.secondary_cbuf_index == existing.secondary_cbuf_index &&
desc.secondary_cbuf_offset == existing.secondary_cbuf_offset &&
desc.secondary_shift_left == existing.secondary_shift_left &&
desc.count == existing.count && desc.size_shift == existing.size_shift;
});
})};
// TODO: Read this from TIC
texture_descriptors[index].is_multisample |= desc.is_multisample;
return index;
}
u32 Add(const ImageDescriptor& desc) {

View File

@ -182,12 +182,13 @@ QString ConfigureInputPlayer::ButtonToText(const Common::ParamPackage& param) {
const QString toggle = QString::fromStdString(param.Get("toggle", false) ? "~" : "");
const QString inverted = QString::fromStdString(param.Get("inverted", false) ? "!" : "");
const QString invert = QString::fromStdString(param.Get("invert", "+") == "-" ? "-" : "");
const QString turbo = QString::fromStdString(param.Get("turbo", false) ? "$" : "");
const auto common_button_name = input_subsystem->GetButtonName(param);
// Retrieve the names from Qt
if (param.Get("engine", "") == "keyboard") {
const QString button_str = GetKeyName(param.Get("code", 0));
return QObject::tr("%1%2%3").arg(toggle, inverted, button_str);
return QObject::tr("%1%2%3%4").arg(turbo, toggle, inverted, button_str);
}
if (common_button_name == Common::Input::ButtonNames::Invalid) {
@ -201,7 +202,7 @@ QString ConfigureInputPlayer::ButtonToText(const Common::ParamPackage& param) {
if (common_button_name == Common::Input::ButtonNames::Value) {
if (param.Has("hat")) {
const QString hat = GetDirectionName(param.Get("direction", ""));
return QObject::tr("%1%2Hat %3").arg(toggle, inverted, hat);
return QObject::tr("%1%2%3Hat %4").arg(turbo, toggle, inverted, hat);
}
if (param.Has("axis")) {
const QString axis = QString::fromStdString(param.Get("axis", ""));
@ -219,13 +220,13 @@ QString ConfigureInputPlayer::ButtonToText(const Common::ParamPackage& param) {
}
if (param.Has("button")) {
const QString button = QString::fromStdString(param.Get("button", ""));
return QObject::tr("%1%2Button %3").arg(toggle, inverted, button);
return QObject::tr("%1%2%3Button %4").arg(turbo, toggle, inverted, button);
}
}
QString button_name = GetButtonName(common_button_name);
if (param.Has("hat")) {
return QObject::tr("%1%2Hat %3").arg(toggle, inverted, button_name);
return QObject::tr("%1%2%3Hat %4").arg(turbo, toggle, inverted, button_name);
}
if (param.Has("axis")) {
return QObject::tr("%1%2Axis %3").arg(toggle, inverted, button_name);
@ -234,7 +235,7 @@ QString ConfigureInputPlayer::ButtonToText(const Common::ParamPackage& param) {
return QObject::tr("%1%2Axis %3").arg(toggle, inverted, button_name);
}
if (param.Has("button")) {
return QObject::tr("%1%2Button %3").arg(toggle, inverted, button_name);
return QObject::tr("%1%2%3Button %4").arg(turbo, toggle, inverted, button_name);
}
return QObject::tr("[unknown]");
@ -395,6 +396,12 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i
button_map[button_id]->setText(ButtonToText(param));
emulated_controller->SetButtonParam(button_id, param);
});
context_menu.addAction(tr("Turbo button"), [&] {
const bool turbo_value = !param.Get("turbo", false);
param.Set("turbo", turbo_value);
button_map[button_id]->setText(ButtonToText(param));
emulated_controller->SetButtonParam(button_id, param);
});
}
if (param.Has("axis")) {
context_menu.addAction(tr("Invert axis"), [&] {

View File

@ -58,13 +58,16 @@ std::vector<std::string> InputProfiles::GetInputProfileNames() {
std::vector<std::string> profile_names;
profile_names.reserve(map_profiles.size());
for (const auto& [profile_name, config] : map_profiles) {
auto it = map_profiles.cbegin();
while (it != map_profiles.cend()) {
const auto& [profile_name, config] = *it;
if (!ProfileExistsInFilesystem(profile_name)) {
DeleteProfile(profile_name);
it = map_profiles.erase(it);
continue;
}
profile_names.push_back(profile_name);
++it;
}
std::stable_sort(profile_names.begin(), profile_names.end());