mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-20 19:45:20 +00:00
update
This commit is contained in:
parent
9d8f3b7bc4
commit
dc2e45bc89
30 changed files with 177 additions and 79 deletions
3
3rdparty/wolfssl/CMakeLists.txt
vendored
3
3rdparty/wolfssl/CMakeLists.txt
vendored
|
@ -22,6 +22,5 @@ else()
|
|||
|
||||
add_subdirectory(wolfssl EXCLUDE_FROM_ALL)
|
||||
|
||||
target_compile_definitions(wolfssl PUBLIC WOLFSSL_DES_ECB HAVE_WRITE_DUP)
|
||||
target_compile_definitions(wolfssl PUBLIC FP_MAX_BITS=8192)
|
||||
target_compile_definitions(wolfssl PUBLIC WOLFSSL_DES_ECB HAVE_WRITE_DUP FP_MAX_BITS=8192 WOLFSSL_NO_OPTIONS_H)
|
||||
endif()
|
||||
|
|
|
@ -33,7 +33,8 @@ enum class thread_state : u32
|
|||
aborting = 1, // The thread has been joined in the destructor or explicitly aborted
|
||||
errored = 2, // Set after the emergency_exit call
|
||||
finished = 3, // Final state, always set at the end of thread execution
|
||||
mask = 3
|
||||
mask = 3,
|
||||
destroying_context = 7, // Special value assigned to destroy data explicitly before the destructor
|
||||
};
|
||||
|
||||
template <class Context>
|
||||
|
@ -702,14 +703,17 @@ public:
|
|||
thread::m_sync.notify_all();
|
||||
}
|
||||
|
||||
if (s == thread_state::finished)
|
||||
if (s == thread_state::finished || s == thread_state::destroying_context)
|
||||
{
|
||||
// This participates in emulation stopping, use destruction-alike semantics
|
||||
thread::join(true);
|
||||
}
|
||||
|
||||
if (s == thread_state::destroying_context)
|
||||
{
|
||||
if constexpr (std::is_assignable_v<Context&, thread_state>)
|
||||
{
|
||||
static_cast<Context&>(*this) = thread_state::finished;
|
||||
static_cast<Context&>(*this) = thread_state::destroying_context;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ enum class cheat_type : u8
|
|||
signed_16_cheat,
|
||||
signed_32_cheat,
|
||||
signed_64_cheat,
|
||||
float_32_cheat,
|
||||
max
|
||||
};
|
||||
|
||||
|
|
|
@ -164,7 +164,7 @@ elseif(WIN32)
|
|||
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/bin/GuiConfigs $<TARGET_FILE_DIR:rpcs3>/GuiConfigs
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/bin/git $<TARGET_FILE_DIR:rpcs3>/git
|
||||
COMMAND "${WINDEPLOYQT_EXECUTABLE}" --no-compiler-runtime --no-opengl-sw --no-patchqt
|
||||
--no-translations --no-quick --no-system-d3d-compiler --no-quick-import
|
||||
--no-translations --no-system-d3d-compiler --no-quick-import
|
||||
--plugindir "$<IF:$<CXX_COMPILER_ID:MSVC>,$<TARGET_FILE_DIR:rpcs3>/plugins,$<TARGET_FILE_DIR:rpcs3>/share/qt6/plugins>"
|
||||
--verbose 0 "$<TARGET_FILE:rpcs3>")
|
||||
endif()
|
||||
|
|
|
@ -71,7 +71,7 @@ CellError lv2_cond::on_id_create()
|
|||
|
||||
std::function<void(void*)> lv2_cond::load(utils::serial& ar)
|
||||
{
|
||||
return load_func(make_shared<lv2_cond>(ar));
|
||||
return load_func(make_shared<lv2_cond>(stx::exact_t<utils::serial&>(ar)));
|
||||
}
|
||||
|
||||
void lv2_cond::save(utils::serial& ar)
|
||||
|
|
|
@ -122,7 +122,7 @@ void lv2_config::remove_service_event(u32 id)
|
|||
|
||||
lv2_config_service_event& lv2_config_service_event::operator=(thread_state s) noexcept
|
||||
{
|
||||
if (s == thread_state::finished)
|
||||
if (s == thread_state::destroying_context && !m_destroyed.exchange(true))
|
||||
{
|
||||
if (auto global = g_fxo->try_get<lv2_config>())
|
||||
{
|
||||
|
@ -133,6 +133,23 @@ lv2_config_service_event& lv2_config_service_event::operator=(thread_state s) no
|
|||
return *this;
|
||||
}
|
||||
|
||||
lv2_config_service_event::~lv2_config_service_event() noexcept
|
||||
{
|
||||
operator=(thread_state::destroying_context);
|
||||
}
|
||||
|
||||
lv2_config::~lv2_config() noexcept
|
||||
{
|
||||
for (auto& [key, event] : events)
|
||||
{
|
||||
if (event)
|
||||
{
|
||||
// Avoid collision with lv2_config_service_event destructor
|
||||
event->m_destroyed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// LV2 Config Service Listener
|
||||
bool lv2_config_service_listener::check_service(const lv2_config_service& service) const
|
||||
{
|
||||
|
|
|
@ -161,6 +161,8 @@ public:
|
|||
|
||||
return null_ptr;
|
||||
}
|
||||
|
||||
~lv2_config() noexcept;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -276,7 +278,7 @@ public:
|
|||
|
||||
// Utilities
|
||||
usz get_size() const { return sizeof(sys_config_service_event_t)-1 + data.size(); }
|
||||
shared_ptr<lv2_config_service> get_shared_ptr () const { return idm::get_unlocked<lv2_config_service>(idm_id); }
|
||||
shared_ptr<lv2_config_service> get_shared_ptr () const { return stx::make_shared_from_this<lv2_config_service>(this); }
|
||||
u32 get_id() const { return idm_id; }
|
||||
};
|
||||
|
||||
|
@ -342,7 +344,7 @@ public:
|
|||
|
||||
// Utilities
|
||||
u32 get_id() const { return idm_id; }
|
||||
shared_ptr<lv2_config_service_listener> get_shared_ptr() const { return idm::get_unlocked<lv2_config_service_listener>(idm_id); }
|
||||
shared_ptr<lv2_config_service_listener> get_shared_ptr() const { return stx::make_shared_from_this<lv2_config_service_listener>(this); }
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -360,6 +362,10 @@ class lv2_config_service_event
|
|||
return g_fxo->get<service_event_id>().next_id++;
|
||||
}
|
||||
|
||||
atomic_t<bool> m_destroyed = false;
|
||||
|
||||
friend class lv2_config;
|
||||
|
||||
public:
|
||||
const u32 id;
|
||||
|
||||
|
@ -391,8 +397,7 @@ public:
|
|||
|
||||
// Destructor
|
||||
lv2_config_service_event& operator=(thread_state s) noexcept;
|
||||
|
||||
~lv2_config_service_event() noexcept = default;
|
||||
~lv2_config_service_event() noexcept;
|
||||
|
||||
// Notify queue that this event exists
|
||||
bool notify() const;
|
||||
|
|
|
@ -37,8 +37,8 @@ lv2_event_queue::lv2_event_queue(utils::serial& ar) noexcept
|
|||
|
||||
std::function<void(void*)> lv2_event_queue::load(utils::serial& ar)
|
||||
{
|
||||
auto queue = make_shared<lv2_event_queue>(ar);
|
||||
return [ptr = lv2_obj::load(queue->key, queue)](void* storage) { *static_cast<shared_ptr<lv2_obj>*>(storage) = ptr; };
|
||||
auto queue = make_shared<lv2_event_queue>(stx::exact_t<utils::serial&>(ar));
|
||||
return [ptr = lv2_obj::load(queue->key, queue)](void* storage) { *static_cast<atomic_ptr<lv2_obj>*>(storage) = ptr; };
|
||||
}
|
||||
|
||||
void lv2_event_queue::save(utils::serial& ar)
|
||||
|
|
|
@ -24,7 +24,7 @@ lv2_event_flag::lv2_event_flag(utils::serial& ar)
|
|||
|
||||
std::function<void(void*)> lv2_event_flag::load(utils::serial& ar)
|
||||
{
|
||||
return load_func(make_shared<lv2_event_flag>(ar));
|
||||
return load_func(make_shared<lv2_event_flag>(stx::exact_t<utils::serial&>(ar)));
|
||||
}
|
||||
|
||||
void lv2_event_flag::save(utils::serial& ar)
|
||||
|
|
|
@ -33,7 +33,7 @@ std::function<void(void*)> lv2_memory_container::load(utils::serial& ar)
|
|||
// Use idm::last_id() only for the instances at IDM
|
||||
return [ptr = make_shared<lv2_memory_container>(stx::exact_t<utils::serial&>(ar), true)](void* storage)
|
||||
{
|
||||
*static_cast<shared_ptr<lv2_memory_container>*>(storage) = ptr;
|
||||
*static_cast<atomic_ptr<lv2_memory_container>*>(storage) = ptr;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -84,7 +84,7 @@ CellError lv2_memory::on_id_create()
|
|||
|
||||
std::function<void(void*)> lv2_memory::load(utils::serial& ar)
|
||||
{
|
||||
auto mem = make_shared<lv2_memory>(ar);
|
||||
auto mem = make_shared<lv2_memory>(stx::exact_t<utils::serial&>(ar));
|
||||
mem->exists++; // Disable on_id_create()
|
||||
auto func = load_func(mem, +mem->pshared);
|
||||
mem->exists--;
|
||||
|
|
|
@ -27,7 +27,7 @@ lv2_mutex::lv2_mutex(utils::serial& ar)
|
|||
|
||||
std::function<void(void*)> lv2_mutex::load(utils::serial& ar)
|
||||
{
|
||||
return load_func(make_shared<lv2_mutex>(ar));
|
||||
return load_func(make_shared<lv2_mutex>(stx::exact_t<utils::serial&>(ar)));
|
||||
}
|
||||
|
||||
void lv2_mutex::save(utils::serial& ar)
|
||||
|
|
|
@ -293,7 +293,7 @@ std::function<void(void*)> lv2_socket::load(utils::serial& ar)
|
|||
sock_lv2->bind(sock_lv2->last_bound_addr);
|
||||
}
|
||||
|
||||
return [ptr = sock_lv2](void* storage) { *static_cast<shared_ptr<lv2_socket>*>(storage) = ptr; };;
|
||||
return [ptr = sock_lv2](void* storage) { *static_cast<atomic_ptr<lv2_socket>*>(storage) = ptr; };;
|
||||
}
|
||||
|
||||
void lv2_socket::save(utils::serial& ar, bool save_only_this_class)
|
||||
|
|
|
@ -178,7 +178,7 @@ void lv2_socket::queue_wake(ppu_thread* ppu)
|
|||
|
||||
lv2_socket& lv2_socket::operator=(thread_state s) noexcept
|
||||
{
|
||||
if (s == thread_state::finished)
|
||||
if (s == thread_state::destroying_context)
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
|
|
@ -112,7 +112,7 @@ std::function<void(void*)> lv2_overlay::load(utils::serial& ar)
|
|||
|
||||
return [ovlm](void* storage)
|
||||
{
|
||||
*static_cast<shared_ptr<lv2_obj>*>(storage) = ovlm;
|
||||
*static_cast<atomic_ptr<lv2_obj>*>(storage) = ovlm;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -372,7 +372,7 @@ std::function<void(void*)> lv2_prx::load(utils::serial& ar)
|
|||
|
||||
return [prx](void* storage)
|
||||
{
|
||||
*static_cast<shared_ptr<lv2_obj>*>(storage) = prx;
|
||||
*static_cast<atomic_ptr<lv2_obj>*>(storage) = prx;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -449,7 +449,7 @@ public:
|
|||
static std::function<void(void*)> load_func(shared_ptr<T> make, u64 pshared = umax)
|
||||
{
|
||||
const u64 key = make->key;
|
||||
return [ptr = load<T>(key, make, pshared)](void* storage) { *static_cast<shared_ptr<Storage>*>(storage) = ptr; };
|
||||
return [ptr = load<T>(key, make, pshared)](void* storage) { *static_cast<atomic_ptr<Storage>*>(storage) = ptr; };
|
||||
}
|
||||
|
||||
static bool wait_timeout(u64 usec, ppu_thread* cpu = {}, bool scale = true, bool is_usleep = false);
|
||||
|
|
|
@ -123,7 +123,7 @@ namespace id_manager
|
|||
ptr = stx::make_shared<T>(stx::exact_t<utils::serial&>(ar));
|
||||
}
|
||||
|
||||
return [ptr](void* storage) { *static_cast<stx::shared_ptr<T>*>(storage) = ptr; };
|
||||
return [ptr](void* storage) { *static_cast<stx::atomic_ptr<T>*>(storage) = ptr; };
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -805,8 +805,8 @@ public:
|
|||
{
|
||||
if (ptr)
|
||||
{
|
||||
constexpr thread_state finished{3};
|
||||
*static_cast<Get*>(ptr.get()) = finished;
|
||||
constexpr thread_state destroying_context{7};
|
||||
*static_cast<Get*>(ptr.get()) = destroying_context;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -837,8 +837,8 @@ public:
|
|||
{
|
||||
if (ptr)
|
||||
{
|
||||
constexpr thread_state finished{3};
|
||||
*static_cast<Get*>(ptr.get()) = finished;
|
||||
constexpr thread_state destroying_context{7};
|
||||
*static_cast<Get*>(ptr.get()) = destroying_context;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -78,6 +78,7 @@ namespace vk
|
|||
break;
|
||||
case vk::driver_vendor::LAVAPIPE:
|
||||
case vk::driver_vendor::V3DV:
|
||||
case vk::driver_vendor::PANVK:
|
||||
// TODO: Actually bench this. Using 32 for now to match other common configurations.
|
||||
case vk::driver_vendor::DOZEN:
|
||||
// Actual optimal size depends on the D3D device. Use 32 since it should work well on both AMD and NVIDIA
|
||||
|
|
|
@ -144,6 +144,9 @@ namespace vk
|
|||
case driver_vendor::HONEYKRISP:
|
||||
// Needs more testing
|
||||
break;
|
||||
case driver_vendor::PANVK:
|
||||
// Needs more testing
|
||||
break;
|
||||
default:
|
||||
rsx_log.warning("Unsupported device: %s", gpu_name);
|
||||
}
|
||||
|
|
|
@ -190,6 +190,7 @@ namespace vk
|
|||
case driver_vendor::LAVAPIPE:
|
||||
case driver_vendor::V3DV:
|
||||
case driver_vendor::HONEYKRISP:
|
||||
case driver_vendor::PANVK:
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -54,7 +54,8 @@ namespace vk
|
|||
LAVAPIPE,
|
||||
NVK,
|
||||
V3DV,
|
||||
HONEYKRISP
|
||||
HONEYKRISP,
|
||||
PANVK
|
||||
};
|
||||
|
||||
driver_vendor get_driver_vendor();
|
||||
|
|
|
@ -302,6 +302,11 @@ namespace vk
|
|||
return driver_vendor::HONEYKRISP;
|
||||
}
|
||||
|
||||
if (gpu_name.find("Panfrost") != umax)
|
||||
{
|
||||
return driver_vendor::PANVK;
|
||||
}
|
||||
|
||||
return driver_vendor::unknown;
|
||||
}
|
||||
else
|
||||
|
@ -329,6 +334,8 @@ namespace vk
|
|||
return driver_vendor::V3DV;
|
||||
case VK_DRIVER_ID_MESA_HONEYKRISP:
|
||||
return driver_vendor::HONEYKRISP;
|
||||
case VK_DRIVER_ID_MESA_PANVK:
|
||||
return driver_vendor::PANVK;
|
||||
default:
|
||||
// Mobile?
|
||||
return driver_vendor::unknown;
|
||||
|
@ -659,6 +666,12 @@ namespace vk
|
|||
enabled_features.textureCompressionBC = VK_FALSE;
|
||||
}
|
||||
|
||||
if (!pgpu->features.textureCompressionBC && pgpu->get_driver_vendor() == driver_vendor::PANVK)
|
||||
{
|
||||
rsx_log.error("Your GPU running on the PANVK driver does not support full texture block compression. Graphics may not render correctly.");
|
||||
enabled_features.textureCompressionBC = VK_FALSE;
|
||||
}
|
||||
|
||||
VkDeviceCreateInfo device = {};
|
||||
device.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
|
||||
device.pNext = nullptr;
|
||||
|
|
|
@ -41,6 +41,7 @@ void progress_dialog_server::operator()()
|
|||
{
|
||||
std::shared_ptr<rsx::overlays::progress_dialog> native_dlg;
|
||||
g_system_progress_stopping = false;
|
||||
g_system_progress_canceled = false;
|
||||
|
||||
const auto get_state = []()
|
||||
{
|
||||
|
|
|
@ -43,6 +43,7 @@ void fmt_class_string<cheat_type>::format(std::string& out, u64 arg)
|
|||
case cheat_type::signed_16_cheat: return "Signed 16 bits";
|
||||
case cheat_type::signed_32_cheat: return "Signed 32 bits";
|
||||
case cheat_type::signed_64_cheat: return "Signed 64 bits";
|
||||
case cheat_type::float_32_cheat: return "Float 32 bits";
|
||||
case cheat_type::max: break;
|
||||
}
|
||||
|
||||
|
@ -612,8 +613,9 @@ cheat_manager_dialog::cheat_manager_dialog(QWidget* parent)
|
|||
return;
|
||||
}
|
||||
|
||||
bool success;
|
||||
u64 result_value;
|
||||
bool success = false;
|
||||
u64 result_value {};
|
||||
f64 result_value_f {};
|
||||
|
||||
switch (cheat->type)
|
||||
{
|
||||
|
@ -625,6 +627,7 @@ cheat_manager_dialog::cheat_manager_dialog(QWidget* parent)
|
|||
case cheat_type::signed_16_cheat: result_value = cheat_engine::get_value<s16>(final_offset, success); break;
|
||||
case cheat_type::signed_32_cheat: result_value = cheat_engine::get_value<s32>(final_offset, success); break;
|
||||
case cheat_type::signed_64_cheat: result_value = cheat_engine::get_value<s64>(final_offset, success); break;
|
||||
case cheat_type::float_32_cheat: result_value_f = cheat_engine::get_value<f32>(final_offset, success); break;
|
||||
default: log_cheat.fatal("Unsupported cheat type"); return;
|
||||
}
|
||||
|
||||
|
@ -632,6 +635,8 @@ cheat_manager_dialog::cheat_manager_dialog(QWidget* parent)
|
|||
{
|
||||
if (cheat->type >= cheat_type::signed_8_cheat && cheat->type <= cheat_type::signed_64_cheat)
|
||||
edt_value_final->setText(tr("%1").arg(static_cast<s64>(result_value)));
|
||||
else if (cheat->type == cheat_type::float_32_cheat)
|
||||
edt_value_final->setText(tr("%1").arg(result_value_f));
|
||||
else
|
||||
edt_value_final->setText(tr("%1").arg(result_value));
|
||||
}
|
||||
|
@ -795,6 +800,7 @@ cheat_manager_dialog::cheat_manager_dialog(QWidget* parent)
|
|||
case cheat_type::signed_16_cheat: results = convert_and_set<s16>(final_offset); break;
|
||||
case cheat_type::signed_32_cheat: results = convert_and_set<s32>(final_offset); break;
|
||||
case cheat_type::signed_64_cheat: results = convert_and_set<s64>(final_offset); break;
|
||||
case cheat_type::float_32_cheat: results = convert_and_set<f32>(final_offset); break;
|
||||
default: log_cheat.fatal("Unsupported cheat type"); return;
|
||||
}
|
||||
|
||||
|
@ -888,8 +894,6 @@ cheat_manager_dialog* cheat_manager_dialog::get_dlg(QWidget* parent)
|
|||
template <typename T>
|
||||
T cheat_manager_dialog::convert_from_QString(const QString& str, bool& success)
|
||||
{
|
||||
T result;
|
||||
|
||||
if constexpr (std::is_same_v<T, u8>)
|
||||
{
|
||||
const u16 result_16 = str.toUShort(&success);
|
||||
|
@ -897,17 +901,17 @@ T cheat_manager_dialog::convert_from_QString(const QString& str, bool& success)
|
|||
if (result_16 > 0xFF)
|
||||
success = false;
|
||||
|
||||
result = static_cast<T>(result_16);
|
||||
return static_cast<T>(result_16);
|
||||
}
|
||||
|
||||
if constexpr (std::is_same_v<T, u16>)
|
||||
result = str.toUShort(&success);
|
||||
return str.toUShort(&success);
|
||||
|
||||
if constexpr (std::is_same_v<T, u32>)
|
||||
result = str.toUInt(&success);
|
||||
return str.toUInt(&success);
|
||||
|
||||
if constexpr (std::is_same_v<T, u64>)
|
||||
result = str.toULongLong(&success);
|
||||
return str.toULongLong(&success);
|
||||
|
||||
if constexpr (std::is_same_v<T, s8>)
|
||||
{
|
||||
|
@ -915,28 +919,31 @@ T cheat_manager_dialog::convert_from_QString(const QString& str, bool& success)
|
|||
if (result_16 < -128 || result_16 > 127)
|
||||
success = false;
|
||||
|
||||
result = static_cast<T>(result_16);
|
||||
return static_cast<T>(result_16);
|
||||
}
|
||||
|
||||
if constexpr (std::is_same_v<T, s16>)
|
||||
result = str.toShort(&success);
|
||||
return str.toShort(&success);
|
||||
|
||||
if constexpr (std::is_same_v<T, s32>)
|
||||
result = str.toInt(&success);
|
||||
return str.toInt(&success);
|
||||
|
||||
if constexpr (std::is_same_v<T, s64>)
|
||||
result = str.toLongLong(&success);
|
||||
return str.toLongLong(&success);
|
||||
|
||||
return result;
|
||||
if constexpr (std::is_same_v<T, f32>)
|
||||
return str.toFloat(&success);
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool cheat_manager_dialog::convert_and_search()
|
||||
{
|
||||
bool res_conv;
|
||||
bool res_conv = false;
|
||||
const QString to_search = edt_cheat_search_value->text();
|
||||
|
||||
T value = convert_from_QString<T>(to_search, res_conv);
|
||||
const T value = convert_from_QString<T>(to_search, res_conv);
|
||||
|
||||
if (!res_conv)
|
||||
return false;
|
||||
|
@ -948,10 +955,10 @@ bool cheat_manager_dialog::convert_and_search()
|
|||
template <typename T>
|
||||
std::pair<bool, bool> cheat_manager_dialog::convert_and_set(u32 offset)
|
||||
{
|
||||
bool res_conv;
|
||||
bool res_conv = false;
|
||||
const QString to_set = edt_value_final->text();
|
||||
|
||||
T value = convert_from_QString<T>(to_set, res_conv);
|
||||
const T value = convert_from_QString<T>(to_set, res_conv);
|
||||
|
||||
if (!res_conv)
|
||||
return {false, false};
|
||||
|
@ -974,6 +981,7 @@ void cheat_manager_dialog::do_the_search()
|
|||
case cheat_type::signed_16_cheat: res_conv = convert_and_search<s16>(); break;
|
||||
case cheat_type::signed_32_cheat: res_conv = convert_and_search<s32>(); break;
|
||||
case cheat_type::signed_64_cheat: res_conv = convert_and_search<s64>(); break;
|
||||
case cheat_type::float_32_cheat: res_conv = convert_and_search<f32>(); break;
|
||||
default: log_cheat.fatal("Unsupported cheat type"); break;
|
||||
}
|
||||
|
||||
|
@ -1065,6 +1073,7 @@ QString cheat_manager_dialog::get_localized_cheat_type(cheat_type type)
|
|||
case cheat_type::signed_16_cheat: return tr("Signed 16 bits");
|
||||
case cheat_type::signed_32_cheat: return tr("Signed 32 bits");
|
||||
case cheat_type::signed_64_cheat: return tr("Signed 64 bits");
|
||||
case cheat_type::float_32_cheat: return tr("Float 32 bits");
|
||||
case cheat_type::max: break;
|
||||
}
|
||||
std::string type_formatted;
|
||||
|
|
|
@ -2277,11 +2277,13 @@ void game_list_frame::RemoveHDD1Cache(const std::string& base_dir, const std::st
|
|||
game_list_log.fatal("Only %d/%d HDD1 cache directories could be removed in %s (%s)", dirs_removed, dirs_total, base_dir, title_id);
|
||||
}
|
||||
|
||||
void game_list_frame::BatchActionBySerials(progress_dialog* pdlg, const std::set<std::string>& serials, QString progressLabel, std::function<bool(const std::string&)> action, std::function<void(u32, u32)> cancel_log, bool refresh_on_finish, bool can_be_concurrent, std::function<bool()> should_wait_cb)
|
||||
void game_list_frame::BatchActionBySerials(progress_dialog* pdlg, const std::set<std::string>& serials, QString progressLabel, std::function<bool(const std::string&)> action, std::function<void(u32, u32)> cancel_log, bool refresh_on_finish, bool can_be_concurrent, std::function<bool()> should_wait_cb)
|
||||
{
|
||||
// Concurrent tasks should not wait (at least not in current implementation)
|
||||
ensure(!should_wait_cb || !can_be_concurrent);
|
||||
|
||||
g_system_progress_canceled = false;
|
||||
|
||||
const std::shared_ptr<std::function<bool(int)>> iterate_over_serial = std::make_shared<std::function<bool(int)>>();
|
||||
|
||||
const std::shared_ptr<atomic_t<int>> index = std::make_shared<atomic_t<int>>(0);
|
||||
|
@ -2297,12 +2299,16 @@ void game_list_frame::BatchActionBySerials(progress_dialog* pdlg, const std::set
|
|||
|
||||
const std::string& serial = *std::next(serials.begin(), index);
|
||||
|
||||
if (pdlg->wasCanceled() || g_system_progress_canceled)
|
||||
if (pdlg->wasCanceled() || g_system_progress_canceled.exchange(false))
|
||||
{
|
||||
cancel_log(index, serials_size);
|
||||
if (cancel_log)
|
||||
{
|
||||
cancel_log(index, serials_size);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else if (action(serial))
|
||||
|
||||
if (action(serial))
|
||||
{
|
||||
const int done = index_ptr->load();
|
||||
pdlg->setLabelText(progressLabel.arg(done + 1).arg(serials_size));
|
||||
|
@ -2360,19 +2366,17 @@ void game_list_frame::BatchActionBySerials(progress_dialog* pdlg, const std::set
|
|||
if ((*iterate_over_serial)(*index))
|
||||
{
|
||||
QTimer::singleShot(1, this, *periodic_func);
|
||||
return;
|
||||
}
|
||||
else
|
||||
|
||||
pdlg->setLabelText(progressLabel.arg(*index).arg(serials_size));
|
||||
pdlg->setCancelButtonText(tr("OK"));
|
||||
connect(pdlg, &progress_dialog::canceled, this, [pdlg](){ pdlg->deleteLater(); });
|
||||
QApplication::beep();
|
||||
|
||||
if (refresh_on_finish && index)
|
||||
{
|
||||
pdlg->setLabelText(progressLabel.arg(*index).arg(serials_size));
|
||||
pdlg->setCancelButtonText(tr("OK"));
|
||||
QApplication::beep();
|
||||
|
||||
if (refresh_on_finish && index)
|
||||
{
|
||||
Refresh(true);
|
||||
}
|
||||
|
||||
pdlg->deleteLater();
|
||||
Refresh(true);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -2414,6 +2418,14 @@ void game_list_frame::BatchCreateCPUCaches(const std::vector<game_info>& game_da
|
|||
pdlg->setAutoReset(false);
|
||||
pdlg->open();
|
||||
|
||||
connect(pdlg, &progress_dialog::canceled, this, []()
|
||||
{
|
||||
if (!Emu.IsStopped())
|
||||
{
|
||||
Emu.GracefulShutdown(false, true);
|
||||
}
|
||||
});
|
||||
|
||||
BatchActionBySerials(pdlg, serials, tr("%0\nProgress: %1/%2 caches compiled").arg(main_label),
|
||||
[&, game_data](const std::string& serial)
|
||||
{
|
||||
|
|
|
@ -394,7 +394,7 @@ void main_window::OnMissingFw()
|
|||
{
|
||||
const QString title = tr("Missing Firmware Detected!");
|
||||
const QString message = tr("Commercial games require the firmware (PS3UPDAT.PUP file) to be installed."
|
||||
"\n<br>For information about how to obtain the required firmware read the <a %0 href=\"https://rpcs3.net/quickstart\">quickstart guide</a>.").arg(gui::utils::get_link_style());
|
||||
"\n<br>For information about how to obtain the required firmware read the <a %0 href=\"https://rpcs3.net/quickstart\">quickstart guide</a>.").arg(gui::utils::get_link_style());
|
||||
|
||||
QMessageBox* mb = new QMessageBox(QMessageBox::Question, title, message, QMessageBox::Ok | QMessageBox::Cancel, this, Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint | Qt::WindowStaysOnTopHint);
|
||||
mb->setTextFormat(Qt::RichText);
|
||||
|
@ -2852,6 +2852,7 @@ void main_window::CreateConnects()
|
|||
connect(dlg, &settings_dialog::EmuSettingsApplied, this, &main_window::NotifyEmuSettingsChange);
|
||||
connect(dlg, &settings_dialog::EmuSettingsApplied, this, &main_window::update_gui_pad_thread);
|
||||
connect(dlg, &settings_dialog::EmuSettingsApplied, m_log_frame, &log_frame::LoadSettings);
|
||||
dlg->setAttribute(Qt::WA_DeleteOnClose);
|
||||
dlg->open();
|
||||
};
|
||||
|
||||
|
|
|
@ -1247,7 +1247,16 @@ bool patch_manager_dialog::handle_json(const QByteArray& data)
|
|||
if (patch_engine::load(patches, "From Download", content, true, &log_message))
|
||||
{
|
||||
patch_log.notice("Successfully validated downloaded patch file");
|
||||
const std::string path = patch_engine::get_patches_path() + "patch.yml";
|
||||
|
||||
const std::string patches_path = patch_engine::get_patches_path();
|
||||
|
||||
if (!fs::create_path(patches_path))
|
||||
{
|
||||
patch_log.fatal("Failed to create path: %s (%s)", patches_path, fs::g_tls_error);
|
||||
return false;
|
||||
}
|
||||
|
||||
const std::string path = patches_path + "patch.yml";
|
||||
|
||||
// Back up current patch file if possible
|
||||
if (fs::is_file(path))
|
||||
|
|
|
@ -347,6 +347,19 @@ namespace stx
|
|||
}
|
||||
}
|
||||
|
||||
// Order semi-destructors before the actual destructors
|
||||
// This allows to safely access data that may be deallocated or destroyed from other members of FXO regardless of their intialization time
|
||||
for (u32 i = 0; i < _max; i++)
|
||||
{
|
||||
const auto info = (*std::prev(m_info, i + 1));
|
||||
|
||||
if (auto op = info->thread_op)
|
||||
{
|
||||
constexpr thread_state destroying_context{7};
|
||||
op(*std::prev(m_order, i + 1), destroying_context);
|
||||
}
|
||||
}
|
||||
|
||||
// Destroy objects in reverse order
|
||||
for (; _max; _max--)
|
||||
{
|
||||
|
|
|
@ -361,13 +361,8 @@ namespace stx
|
|||
[[deprecated("Use null_ptr")]] shared_ptr(std::nullptr_t) = delete;
|
||||
|
||||
// Not-so-aliasing constructor: emulates std::enable_shared_from_this without its overhead
|
||||
explicit shared_ptr(T* _this) noexcept
|
||||
: m_ptr(_this)
|
||||
{
|
||||
// Random checks which may fail on invalid pointer
|
||||
ensure((reinterpret_cast<u64>(d()->destroy) - 0x10000) >> 47 == 0);
|
||||
ensure((d()->refs++ - 1) >> 58 == 0);
|
||||
}
|
||||
template <typename Type>
|
||||
friend shared_ptr<Type> make_shared_from_this(const Type* _this) noexcept;
|
||||
|
||||
template <typename U> requires same_ptr_implicit_v<T, U>
|
||||
shared_ptr(const shared_ptr<U>& r) noexcept
|
||||
|
@ -562,11 +557,29 @@ namespace stx
|
|||
|
||||
template <typename T>
|
||||
requires (std::is_constructible_v<std::remove_reference_t<T>, T&&>)
|
||||
static shared_ptr<std::remove_reference_t<T>> make_shared_value(T&& value)
|
||||
static shared_ptr<std::remove_reference_t<T>> make_shared_value(T&& value) noexcept
|
||||
{
|
||||
return make_single_value(std::forward<T>(value));
|
||||
}
|
||||
|
||||
// Not-so-aliasing constructor: emulates std::enable_shared_from_this without its overhead
|
||||
template <typename T>
|
||||
static shared_ptr<T> make_shared_from_this(const T* _this) noexcept
|
||||
{
|
||||
shared_ptr<T> r;
|
||||
r.m_ptr = const_cast<T*>(_this);
|
||||
|
||||
if (!_this) [[unlikely]]
|
||||
{
|
||||
return r;
|
||||
}
|
||||
|
||||
// Random checks which may fail on invalid pointer
|
||||
ensure((reinterpret_cast<u64>(r.d()->destroy.load()) - 0x10000) >> 47 == 0);
|
||||
ensure((r.d()->refs++ - 1) >> 58 == 0);
|
||||
return r;
|
||||
}
|
||||
|
||||
// Atomic simplified shared pointer
|
||||
template <typename T>
|
||||
class atomic_ptr
|
||||
|
@ -1059,9 +1072,9 @@ namespace stx
|
|||
do
|
||||
{
|
||||
// Update old head with current value
|
||||
next.m_ptr = reinterpret_cast<T*>(old.m_val.raw() >> c_ref_size);
|
||||
next.m_ptr = std::launder(ptr_to(old.m_val.raw()));
|
||||
|
||||
} while (!m_val.compare_exchange(old.m_val.raw(), reinterpret_cast<uptr>(exch.m_ptr) << c_ref_size));
|
||||
} while (!m_val.compare_exchange(old.m_val.raw(), to_val(exch.m_ptr)));
|
||||
|
||||
// This argument is consumed (moved from)
|
||||
exch.m_ptr = nullptr;
|
||||
|
@ -1076,7 +1089,7 @@ namespace stx
|
|||
// Simple atomic load is much more effective than load(), but it's a non-owning reference
|
||||
T* observe() const noexcept
|
||||
{
|
||||
return reinterpret_cast<T*>(m_val >> c_ref_size);
|
||||
return std::launder(ptr_to(m_val));
|
||||
}
|
||||
|
||||
explicit constexpr operator bool() const noexcept
|
||||
|
@ -1138,11 +1151,6 @@ namespace stx
|
|||
return false;
|
||||
}
|
||||
|
||||
constexpr std::nullptr_t get() const noexcept
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} null_ptr;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue