early-access version 3153
This commit is contained in:
parent
ef99adf450
commit
00b79da15f
15 changed files with 88 additions and 73 deletions
|
@ -1,7 +1,7 @@
|
|||
yuzu emulator early access
|
||||
=============
|
||||
|
||||
This is the source code for early-access 3150.
|
||||
This is the source code for early-access 3153.
|
||||
|
||||
## Legal Notice
|
||||
|
||||
|
|
|
@ -199,7 +199,7 @@ public:
|
|||
~HLERequestContext();
|
||||
|
||||
/// Returns a pointer to the IPC command buffer for this request.
|
||||
u32* CommandBuffer() {
|
||||
[[nodiscard]] u32* CommandBuffer() {
|
||||
return cmd_buf.data();
|
||||
}
|
||||
|
||||
|
@ -207,7 +207,7 @@ public:
|
|||
* Returns the session through which this request was made. This can be used as a map key to
|
||||
* access per-client data on services.
|
||||
*/
|
||||
Kernel::KServerSession* Session() {
|
||||
[[nodiscard]] Kernel::KServerSession* Session() {
|
||||
return server_session;
|
||||
}
|
||||
|
||||
|
@ -217,61 +217,61 @@ public:
|
|||
/// Writes data from this context back to the requesting process/thread.
|
||||
Result WriteToOutgoingCommandBuffer(KThread& requesting_thread);
|
||||
|
||||
u32_le GetHipcCommand() const {
|
||||
[[nodiscard]] u32_le GetHipcCommand() const {
|
||||
return command;
|
||||
}
|
||||
|
||||
u32_le GetTipcCommand() const {
|
||||
[[nodiscard]] u32_le GetTipcCommand() const {
|
||||
return static_cast<u32_le>(command_header->type.Value()) -
|
||||
static_cast<u32_le>(IPC::CommandType::TIPC_CommandRegion);
|
||||
}
|
||||
|
||||
u32_le GetCommand() const {
|
||||
[[nodiscard]] u32_le GetCommand() const {
|
||||
return command_header->IsTipc() ? GetTipcCommand() : GetHipcCommand();
|
||||
}
|
||||
|
||||
bool IsTipc() const {
|
||||
[[nodiscard]] bool IsTipc() const {
|
||||
return command_header->IsTipc();
|
||||
}
|
||||
|
||||
IPC::CommandType GetCommandType() const {
|
||||
[[nodiscard]] IPC::CommandType GetCommandType() const {
|
||||
return command_header->type;
|
||||
}
|
||||
|
||||
u64 GetPID() const {
|
||||
[[nodiscard]] u64 GetPID() const {
|
||||
return pid;
|
||||
}
|
||||
|
||||
u32 GetDataPayloadOffset() const {
|
||||
[[nodiscard]] u32 GetDataPayloadOffset() const {
|
||||
return data_payload_offset;
|
||||
}
|
||||
|
||||
const std::vector<IPC::BufferDescriptorX>& BufferDescriptorX() const {
|
||||
[[nodiscard]] const std::vector<IPC::BufferDescriptorX>& BufferDescriptorX() const {
|
||||
return buffer_x_desciptors;
|
||||
}
|
||||
|
||||
const std::vector<IPC::BufferDescriptorABW>& BufferDescriptorA() const {
|
||||
[[nodiscard]] const std::vector<IPC::BufferDescriptorABW>& BufferDescriptorA() const {
|
||||
return buffer_a_desciptors;
|
||||
}
|
||||
|
||||
const std::vector<IPC::BufferDescriptorABW>& BufferDescriptorB() const {
|
||||
[[nodiscard]] const std::vector<IPC::BufferDescriptorABW>& BufferDescriptorB() const {
|
||||
return buffer_b_desciptors;
|
||||
}
|
||||
|
||||
const std::vector<IPC::BufferDescriptorC>& BufferDescriptorC() const {
|
||||
[[nodiscard]] const std::vector<IPC::BufferDescriptorC>& BufferDescriptorC() const {
|
||||
return buffer_c_desciptors;
|
||||
}
|
||||
|
||||
const IPC::DomainMessageHeader& GetDomainMessageHeader() const {
|
||||
[[nodiscard]] const IPC::DomainMessageHeader& GetDomainMessageHeader() const {
|
||||
return domain_message_header.value();
|
||||
}
|
||||
|
||||
bool HasDomainMessageHeader() const {
|
||||
[[nodiscard]] bool HasDomainMessageHeader() const {
|
||||
return domain_message_header.has_value();
|
||||
}
|
||||
|
||||
/// Helper function to read a buffer using the appropriate buffer descriptor
|
||||
std::vector<u8> ReadBuffer(std::size_t buffer_index = 0) const;
|
||||
[[nodiscard]] std::vector<u8> ReadBuffer(std::size_t buffer_index = 0) const;
|
||||
|
||||
/// Helper function to write a buffer using the appropriate buffer descriptor
|
||||
std::size_t WriteBuffer(const void* buffer, std::size_t size,
|
||||
|
@ -308,22 +308,34 @@ public:
|
|||
}
|
||||
|
||||
/// Helper function to get the size of the input buffer
|
||||
std::size_t GetReadBufferSize(std::size_t buffer_index = 0) const;
|
||||
[[nodiscard]] std::size_t GetReadBufferSize(std::size_t buffer_index = 0) const;
|
||||
|
||||
/// Helper function to get the size of the output buffer
|
||||
std::size_t GetWriteBufferSize(std::size_t buffer_index = 0) const;
|
||||
[[nodiscard]] std::size_t GetWriteBufferSize(std::size_t buffer_index = 0) const;
|
||||
|
||||
/// Helper function to derive the number of elements able to be contained in the read buffer
|
||||
template <typename T>
|
||||
[[nodiscard]] std::size_t GetReadBufferNumElements(std::size_t buffer_index = 0) const {
|
||||
return GetReadBufferSize(buffer_index) / sizeof(T);
|
||||
}
|
||||
|
||||
/// Helper function to derive the number of elements able to be contained in the write buffer
|
||||
template <typename T>
|
||||
[[nodiscard]] std::size_t GetWriteBufferNumElements(std::size_t buffer_index = 0) const {
|
||||
return GetWriteBufferSize(buffer_index) / sizeof(T);
|
||||
}
|
||||
|
||||
/// Helper function to test whether the input buffer at buffer_index can be read
|
||||
bool CanReadBuffer(std::size_t buffer_index = 0) const;
|
||||
[[nodiscard]] bool CanReadBuffer(std::size_t buffer_index = 0) const;
|
||||
|
||||
/// Helper function to test whether the output buffer at buffer_index can be written
|
||||
bool CanWriteBuffer(std::size_t buffer_index = 0) const;
|
||||
[[nodiscard]] bool CanWriteBuffer(std::size_t buffer_index = 0) const;
|
||||
|
||||
Handle GetCopyHandle(std::size_t index) const {
|
||||
[[nodiscard]] Handle GetCopyHandle(std::size_t index) const {
|
||||
return incoming_copy_handles.at(index);
|
||||
}
|
||||
|
||||
Handle GetMoveHandle(std::size_t index) const {
|
||||
[[nodiscard]] Handle GetMoveHandle(std::size_t index) const {
|
||||
return incoming_move_handles.at(index);
|
||||
}
|
||||
|
||||
|
@ -348,13 +360,13 @@ public:
|
|||
manager = manager_;
|
||||
}
|
||||
|
||||
std::string Description() const;
|
||||
[[nodiscard]] std::string Description() const;
|
||||
|
||||
KThread& GetThread() {
|
||||
[[nodiscard]] KThread& GetThread() {
|
||||
return *thread;
|
||||
}
|
||||
|
||||
std::shared_ptr<SessionRequestManager> GetManager() const {
|
||||
[[nodiscard]] std::shared_ptr<SessionRequestManager> GetManager() const {
|
||||
return manager.lock();
|
||||
}
|
||||
|
||||
|
|
|
@ -122,10 +122,10 @@ private:
|
|||
}
|
||||
|
||||
void GetReleasedAudioInBuffer(Kernel::HLERequestContext& ctx) {
|
||||
auto write_buffer_size = ctx.GetWriteBufferSize() / sizeof(u64);
|
||||
std::vector<u64> released_buffers(write_buffer_size, 0);
|
||||
const auto write_buffer_size = ctx.GetWriteBufferNumElements<u64>();
|
||||
std::vector<u64> released_buffers(write_buffer_size);
|
||||
|
||||
auto count = impl->GetReleasedBuffers(released_buffers);
|
||||
const auto count = impl->GetReleasedBuffers(released_buffers);
|
||||
|
||||
[[maybe_unused]] std::string tags{};
|
||||
for (u32 i = 0; i < count; i++) {
|
||||
|
@ -227,7 +227,7 @@ void AudInU::ListAudioIns(Kernel::HLERequestContext& ctx) {
|
|||
LOG_DEBUG(Service_Audio, "called");
|
||||
|
||||
const auto write_count =
|
||||
static_cast<u32>(ctx.GetWriteBufferSize() / sizeof(AudioDevice::AudioDeviceName));
|
||||
static_cast<u32>(ctx.GetWriteBufferNumElements<AudioDevice::AudioDeviceName>());
|
||||
std::vector<AudioDevice::AudioDeviceName> device_names{};
|
||||
|
||||
u32 out_count{0};
|
||||
|
@ -247,7 +247,7 @@ void AudInU::ListAudioInsAutoFiltered(Kernel::HLERequestContext& ctx) {
|
|||
LOG_DEBUG(Service_Audio, "called");
|
||||
|
||||
const auto write_count =
|
||||
static_cast<u32>(ctx.GetWriteBufferSize() / sizeof(AudioDevice::AudioDeviceName));
|
||||
static_cast<u32>(ctx.GetWriteBufferNumElements<AudioDevice::AudioDeviceName>());
|
||||
std::vector<AudioDevice::AudioDeviceName> device_names{};
|
||||
|
||||
u32 out_count{0};
|
||||
|
|
|
@ -128,16 +128,16 @@ private:
|
|||
}
|
||||
|
||||
void GetReleasedAudioOutBuffers(Kernel::HLERequestContext& ctx) {
|
||||
auto write_buffer_size = ctx.GetWriteBufferSize() / sizeof(u64);
|
||||
std::vector<u64> released_buffers(write_buffer_size, 0);
|
||||
const auto write_buffer_size = ctx.GetWriteBufferNumElements<u64>();
|
||||
std::vector<u64> released_buffers(write_buffer_size);
|
||||
|
||||
auto count = impl->GetReleasedBuffers(released_buffers);
|
||||
const auto count = impl->GetReleasedBuffers(released_buffers);
|
||||
|
||||
[[maybe_unused]] std::string tags{};
|
||||
for (u32 i = 0; i < count; i++) {
|
||||
tags += fmt::format("{:08X}, ", released_buffers[i]);
|
||||
}
|
||||
[[maybe_unused]] auto sessionid{impl->GetSystem().GetSessionId()};
|
||||
[[maybe_unused]] const auto sessionid{impl->GetSystem().GetSessionId()};
|
||||
LOG_TRACE(Service_Audio, "called. Session {} released {} buffers: {}", sessionid, count,
|
||||
tags);
|
||||
|
||||
|
@ -242,7 +242,7 @@ void AudOutU::ListAudioOuts(Kernel::HLERequestContext& ctx) {
|
|||
std::scoped_lock l{impl->mutex};
|
||||
|
||||
const auto write_count =
|
||||
static_cast<u32>(ctx.GetWriteBufferSize() / sizeof(AudioDevice::AudioDeviceName));
|
||||
static_cast<u32>(ctx.GetWriteBufferNumElements<AudioDevice::AudioDeviceName>());
|
||||
std::vector<AudioDevice::AudioDeviceName> device_names{};
|
||||
if (write_count > 0) {
|
||||
device_names.emplace_back("DeviceOut");
|
||||
|
|
|
@ -272,7 +272,7 @@ public:
|
|||
|
||||
private:
|
||||
void ListAudioDeviceName(Kernel::HLERequestContext& ctx) {
|
||||
const size_t in_count = ctx.GetWriteBufferSize() / sizeof(AudioDevice::AudioDeviceName);
|
||||
const size_t in_count = ctx.GetWriteBufferNumElements<AudioDevice::AudioDeviceName>();
|
||||
|
||||
std::vector<AudioDevice::AudioDeviceName> out_names{};
|
||||
|
||||
|
@ -333,7 +333,7 @@ private:
|
|||
}
|
||||
|
||||
void GetActiveAudioDeviceName(Kernel::HLERequestContext& ctx) {
|
||||
const auto write_size = ctx.GetWriteBufferSize() / sizeof(char);
|
||||
const auto write_size = ctx.GetWriteBufferSize();
|
||||
std::string out_name{"AudioTvOutput"};
|
||||
|
||||
LOG_DEBUG(Service_Audio, "(STUBBED) called. Name={}", out_name);
|
||||
|
@ -385,7 +385,7 @@ private:
|
|||
}
|
||||
|
||||
void ListAudioOutputDeviceName(Kernel::HLERequestContext& ctx) {
|
||||
const size_t in_count = ctx.GetWriteBufferSize() / sizeof(AudioDevice::AudioDeviceName);
|
||||
const size_t in_count = ctx.GetWriteBufferNumElements<AudioDevice::AudioDeviceName>();
|
||||
|
||||
std::vector<AudioDevice::AudioDeviceName> out_names{};
|
||||
|
||||
|
|
|
@ -68,7 +68,7 @@ private:
|
|||
ExtraBehavior extra_behavior) {
|
||||
u32 consumed = 0;
|
||||
u32 sample_count = 0;
|
||||
std::vector<opus_int16> samples(ctx.GetWriteBufferSize() / sizeof(opus_int16));
|
||||
std::vector<opus_int16> samples(ctx.GetWriteBufferNumElements<opus_int16>());
|
||||
|
||||
if (extra_behavior == ExtraBehavior::ResetContext) {
|
||||
ResetDecoderContext();
|
||||
|
|
|
@ -443,7 +443,7 @@ private:
|
|||
}
|
||||
|
||||
void Read(Kernel::HLERequestContext& ctx) {
|
||||
auto write_size = ctx.GetWriteBufferSize() / sizeof(DeliveryCacheDirectoryEntry);
|
||||
auto write_size = ctx.GetWriteBufferNumElements<DeliveryCacheDirectoryEntry>();
|
||||
|
||||
LOG_DEBUG(Service_BCAT, "called, write_size={:016X}", write_size);
|
||||
|
||||
|
@ -533,7 +533,7 @@ private:
|
|||
}
|
||||
|
||||
void EnumerateDeliveryCacheDirectory(Kernel::HLERequestContext& ctx) {
|
||||
auto size = ctx.GetWriteBufferSize() / sizeof(DirectoryName);
|
||||
auto size = ctx.GetWriteBufferNumElements<DirectoryName>();
|
||||
|
||||
LOG_DEBUG(Service_BCAT, "called, size={:016X}", size);
|
||||
|
||||
|
|
|
@ -192,12 +192,10 @@ private:
|
|||
}
|
||||
|
||||
void ListCommonTicketRightsIds(Kernel::HLERequestContext& ctx) {
|
||||
u32 out_entries;
|
||||
if (keys.GetCommonTickets().empty())
|
||||
out_entries = 0;
|
||||
else
|
||||
out_entries = static_cast<u32>(ctx.GetWriteBufferSize() / sizeof(u128));
|
||||
|
||||
size_t out_entries = 0;
|
||||
if (!keys.GetCommonTickets().empty()) {
|
||||
out_entries = ctx.GetWriteBufferNumElements<u128>();
|
||||
}
|
||||
LOG_DEBUG(Service_ETicket, "called, entries={:016X}", out_entries);
|
||||
|
||||
keys.PopulateTickets();
|
||||
|
@ -206,20 +204,19 @@ private:
|
|||
std::transform(tickets.begin(), tickets.end(), std::back_inserter(ids),
|
||||
[](const auto& pair) { return pair.first; });
|
||||
|
||||
out_entries = static_cast<u32>(std::min<std::size_t>(ids.size(), out_entries));
|
||||
out_entries = std::min(ids.size(), out_entries);
|
||||
ctx.WriteBuffer(ids.data(), out_entries * sizeof(u128));
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 3};
|
||||
rb.Push(ResultSuccess);
|
||||
rb.Push<u32>(out_entries);
|
||||
rb.Push<u32>(static_cast<u32>(out_entries));
|
||||
}
|
||||
|
||||
void ListPersonalizedTicketRightsIds(Kernel::HLERequestContext& ctx) {
|
||||
u32 out_entries;
|
||||
if (keys.GetPersonalizedTickets().empty())
|
||||
out_entries = 0;
|
||||
else
|
||||
out_entries = static_cast<u32>(ctx.GetWriteBufferSize() / sizeof(u128));
|
||||
size_t out_entries = 0;
|
||||
if (!keys.GetPersonalizedTickets().empty()) {
|
||||
out_entries = ctx.GetWriteBufferNumElements<u128>();
|
||||
}
|
||||
|
||||
LOG_DEBUG(Service_ETicket, "called, entries={:016X}", out_entries);
|
||||
|
||||
|
@ -229,12 +226,12 @@ private:
|
|||
std::transform(tickets.begin(), tickets.end(), std::back_inserter(ids),
|
||||
[](const auto& pair) { return pair.first; });
|
||||
|
||||
out_entries = static_cast<u32>(std::min<std::size_t>(ids.size(), out_entries));
|
||||
out_entries = std::min(ids.size(), out_entries);
|
||||
ctx.WriteBuffer(ids.data(), out_entries * sizeof(u128));
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 3};
|
||||
rb.Push(ResultSuccess);
|
||||
rb.Push<u32>(out_entries);
|
||||
rb.Push<u32>(static_cast<u32>(out_entries));
|
||||
}
|
||||
|
||||
void GetCommonTicketSize(Kernel::HLERequestContext& ctx) {
|
||||
|
|
|
@ -277,7 +277,7 @@ private:
|
|||
LOG_DEBUG(Service_FS, "called.");
|
||||
|
||||
// Calculate how many entries we can fit in the output buffer
|
||||
const u64 count_entries = ctx.GetWriteBufferSize() / sizeof(FileSys::Entry);
|
||||
const u64 count_entries = ctx.GetWriteBufferNumElements<FileSys::Entry>();
|
||||
|
||||
// Cap at total number of entries.
|
||||
const u64 actual_entries = std::min(count_entries, entries.size() - next_entry_index);
|
||||
|
@ -543,7 +543,7 @@ public:
|
|||
LOG_DEBUG(Service_FS, "called");
|
||||
|
||||
// Calculate how many entries we can fit in the output buffer
|
||||
const u64 count_entries = ctx.GetWriteBufferSize() / sizeof(SaveDataInfo);
|
||||
const u64 count_entries = ctx.GetWriteBufferNumElements<SaveDataInfo>();
|
||||
|
||||
// Cap at total number of entries.
|
||||
const u64 actual_entries = std::min(count_entries, info.size() - next_entry_index);
|
||||
|
|
|
@ -300,7 +300,7 @@ public:
|
|||
|
||||
void GetNetworkInfoLatestUpdate(Kernel::HLERequestContext& ctx) {
|
||||
const std::size_t network_buffer_size = ctx.GetWriteBufferSize(0);
|
||||
const std::size_t node_buffer_count = ctx.GetWriteBufferSize(1) / sizeof(NodeLatestUpdate);
|
||||
const std::size_t node_buffer_count = ctx.GetWriteBufferNumElements<NodeLatestUpdate>(1);
|
||||
|
||||
if (node_buffer_count == 0 || network_buffer_size != sizeof(NetworkInfo)) {
|
||||
LOG_ERROR(Service_LDN, "Invalid buffer, size = {}, count = {}", network_buffer_size,
|
||||
|
@ -341,7 +341,7 @@ public:
|
|||
const auto channel{rp.PopEnum<WifiChannel>()};
|
||||
const auto scan_filter{rp.PopRaw<ScanFilter>()};
|
||||
|
||||
const std::size_t network_info_size = ctx.GetWriteBufferSize() / sizeof(NetworkInfo);
|
||||
const std::size_t network_info_size = ctx.GetWriteBufferNumElements<NetworkInfo>();
|
||||
|
||||
if (network_info_size == 0) {
|
||||
LOG_ERROR(Service_LDN, "Invalid buffer size {}", network_info_size);
|
||||
|
|
|
@ -118,7 +118,7 @@ void IUser::ListDevices(Kernel::HLERequestContext& ctx) {
|
|||
}
|
||||
|
||||
std::vector<u64> nfp_devices;
|
||||
const std::size_t max_allowed_devices = ctx.GetWriteBufferSize() / sizeof(u64);
|
||||
const std::size_t max_allowed_devices = ctx.GetWriteBufferNumElements<u64>();
|
||||
|
||||
for (auto& device : devices) {
|
||||
if (nfp_devices.size() >= max_allowed_devices) {
|
||||
|
|
|
@ -104,9 +104,9 @@ void IUser::ListDevices(Kernel::HLERequestContext& ctx) {
|
|||
}
|
||||
|
||||
std::vector<u64> nfp_devices;
|
||||
const std::size_t max_allowed_devices = ctx.GetWriteBufferSize() / sizeof(u64);
|
||||
const std::size_t max_allowed_devices = ctx.GetWriteBufferNumElements<u64>();
|
||||
|
||||
for (auto& device : devices) {
|
||||
for (const auto& device : devices) {
|
||||
if (nfp_devices.size() >= max_allowed_devices) {
|
||||
continue;
|
||||
}
|
||||
|
@ -115,7 +115,7 @@ void IUser::ListDevices(Kernel::HLERequestContext& ctx) {
|
|||
}
|
||||
}
|
||||
|
||||
if (nfp_devices.size() == 0) {
|
||||
if (nfp_devices.empty()) {
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(DeviceNotFound);
|
||||
return;
|
||||
|
|
|
@ -279,13 +279,10 @@ void IPlatformServiceManager::GetSharedFontInOrderOfPriority(Kernel::HLERequestC
|
|||
font_sizes.push_back(region.size);
|
||||
}
|
||||
|
||||
// Resize buffers if game requests smaller size output.
|
||||
font_codes.resize(
|
||||
std::min<std::size_t>(font_codes.size(), ctx.GetWriteBufferSize(0) / sizeof(u32)));
|
||||
font_offsets.resize(
|
||||
std::min<std::size_t>(font_offsets.size(), ctx.GetWriteBufferSize(1) / sizeof(u32)));
|
||||
font_sizes.resize(
|
||||
std::min<std::size_t>(font_sizes.size(), ctx.GetWriteBufferSize(2) / sizeof(u32)));
|
||||
// Resize buffers if game requests smaller size output
|
||||
font_codes.resize(std::min(font_codes.size(), ctx.GetWriteBufferNumElements<u32>(0)));
|
||||
font_offsets.resize(std::min(font_offsets.size(), ctx.GetWriteBufferNumElements<u32>(1)));
|
||||
font_sizes.resize(std::min(font_sizes.size(), ctx.GetWriteBufferNumElements<u32>(2)));
|
||||
|
||||
ctx.WriteBuffer(font_codes, 0);
|
||||
ctx.WriteBuffer(font_offsets, 1);
|
||||
|
|
|
@ -83,7 +83,7 @@ void PushResponseLanguageCode(Kernel::HLERequestContext& ctx, std::size_t num_la
|
|||
}
|
||||
|
||||
void GetAvailableLanguageCodesImpl(Kernel::HLERequestContext& ctx, std::size_t max_entries) {
|
||||
const std::size_t requested_amount = ctx.GetWriteBufferSize() / sizeof(LanguageCode);
|
||||
const std::size_t requested_amount = ctx.GetWriteBufferNumElements<LanguageCode>();
|
||||
const std::size_t max_amount = std::min(requested_amount, max_entries);
|
||||
const std::size_t copy_amount = std::min(available_language_codes.size(), max_amount);
|
||||
const std::size_t copy_size = copy_amount * sizeof(LanguageCode);
|
||||
|
|
|
@ -231,6 +231,9 @@
|
|||
<property name="text">
|
||||
<string>Con&figure...</string>
|
||||
</property>
|
||||
<property name="menuRole">
|
||||
<enum>QAction::PreferencesRole</enum>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_Display_Dock_Widget_Headers">
|
||||
<property name="checkable">
|
||||
|
@ -363,6 +366,9 @@
|
|||
<property name="text">
|
||||
<string>&Configure TAS...</string>
|
||||
</property>
|
||||
<property name="menuRole">
|
||||
<enum>QAction::NoRole</enum>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_Configure_Current_Game">
|
||||
<property name="enabled">
|
||||
|
@ -371,6 +377,9 @@
|
|||
<property name="text">
|
||||
<string>Configure C&urrent Game...</string>
|
||||
</property>
|
||||
<property name="menuRole">
|
||||
<enum>QAction::NoRole</enum>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_TAS_Start">
|
||||
<property name="enabled">
|
||||
|
|
Loading…
Reference in a new issue