early-access version 1763
This commit is contained in:
parent
dc53b00cd9
commit
9612b12e5c
@ -1,7 +1,7 @@
|
|||||||
yuzu emulator early access
|
yuzu emulator early access
|
||||||
=============
|
=============
|
||||||
|
|
||||||
This is the source code for early-access 1761.
|
This is the source code for early-access 1763.
|
||||||
|
|
||||||
## Legal Notice
|
## Legal Notice
|
||||||
|
|
||||||
|
@ -41,6 +41,21 @@ SessionRequestManager::SessionRequestManager(KernelCore& kernel_) : kernel{kerne
|
|||||||
|
|
||||||
SessionRequestManager::~SessionRequestManager() = default;
|
SessionRequestManager::~SessionRequestManager() = default;
|
||||||
|
|
||||||
|
bool SessionRequestManager::HasSessionRequestHandler(const HLERequestContext& context) const {
|
||||||
|
if (IsDomain() && context.HasDomainMessageHeader()) {
|
||||||
|
const auto& message_header = context.GetDomainMessageHeader();
|
||||||
|
const auto object_id = message_header.object_id;
|
||||||
|
|
||||||
|
if (object_id > DomainHandlerCount()) {
|
||||||
|
LOG_CRITICAL(IPC, "object_id {} is too big!", object_id);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return DomainHandler(object_id - 1) != nullptr;
|
||||||
|
} else {
|
||||||
|
return session_handler != nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void SessionRequestHandler::ClientConnected(KServerSession* session) {
|
void SessionRequestHandler::ClientConnected(KServerSession* session) {
|
||||||
session->SetSessionHandler(shared_from_this());
|
session->SetSessionHandler(shared_from_this());
|
||||||
}
|
}
|
||||||
|
@ -85,8 +85,8 @@ public:
|
|||||||
*/
|
*/
|
||||||
void ClientDisconnected(KServerSession* session);
|
void ClientDisconnected(KServerSession* session);
|
||||||
|
|
||||||
std::shared_ptr<ServiceThread> GetServiceThread() const {
|
std::weak_ptr<ServiceThread> GetServiceThread() const {
|
||||||
return service_thread.lock();
|
return service_thread;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -152,10 +152,12 @@ public:
|
|||||||
session_handler = std::move(handler);
|
session_handler = std::move(handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<ServiceThread> GetServiceThread() const {
|
std::weak_ptr<ServiceThread> GetServiceThread() const {
|
||||||
return session_handler->GetServiceThread();
|
return session_handler->GetServiceThread();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool HasSessionRequestHandler(const HLERequestContext& context) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool is_domain{};
|
bool is_domain{};
|
||||||
SessionRequestHandlerPtr session_handler;
|
SessionRequestHandlerPtr session_handler;
|
||||||
@ -163,7 +165,6 @@ private:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
KernelCore& kernel;
|
KernelCore& kernel;
|
||||||
std::weak_ptr<ServiceThread> service_thread;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -119,11 +119,16 @@ ResultCode KServerSession::QueueSyncRequest(KThread* thread, Core::Memory::Memor
|
|||||||
|
|
||||||
context->PopulateFromIncomingCommandBuffer(kernel.CurrentProcess()->GetHandleTable(), cmd_buf);
|
context->PopulateFromIncomingCommandBuffer(kernel.CurrentProcess()->GetHandleTable(), cmd_buf);
|
||||||
|
|
||||||
if (auto strong_ptr = manager->GetServiceThread(); strong_ptr) {
|
// Ensure we have a session request handler
|
||||||
strong_ptr->QueueSyncRequest(*parent, std::move(context));
|
if (manager->HasSessionRequestHandler(*context)) {
|
||||||
return ResultSuccess;
|
if (auto strong_ptr = manager->GetServiceThread().lock()) {
|
||||||
|
strong_ptr->QueueSyncRequest(*parent, std::move(context));
|
||||||
|
return ResultSuccess;
|
||||||
|
} else {
|
||||||
|
ASSERT_MSG(false, "strong_ptr is nullptr!");
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
ASSERT_MSG(false, "strong_ptr was nullptr!");
|
ASSERT_MSG(false, "handler is invalid!");
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResultSuccess;
|
return ResultSuccess;
|
||||||
|
@ -63,8 +63,6 @@ struct KernelCore::Impl {
|
|||||||
global_scheduler_context = std::make_unique<Kernel::GlobalSchedulerContext>(kernel);
|
global_scheduler_context = std::make_unique<Kernel::GlobalSchedulerContext>(kernel);
|
||||||
global_handle_table = std::make_unique<Kernel::KHandleTable>(kernel);
|
global_handle_table = std::make_unique<Kernel::KHandleTable>(kernel);
|
||||||
|
|
||||||
service_thread_manager =
|
|
||||||
std::make_unique<Common::ThreadWorker>(1, "yuzu:ServiceThreadManager");
|
|
||||||
is_phantom_mode_for_singlecore = false;
|
is_phantom_mode_for_singlecore = false;
|
||||||
|
|
||||||
InitializePhysicalCores();
|
InitializePhysicalCores();
|
||||||
@ -96,7 +94,6 @@ struct KernelCore::Impl {
|
|||||||
process_list.clear();
|
process_list.clear();
|
||||||
|
|
||||||
// Ensures all service threads gracefully shutdown
|
// Ensures all service threads gracefully shutdown
|
||||||
service_thread_manager.reset();
|
|
||||||
service_threads.clear();
|
service_threads.clear();
|
||||||
|
|
||||||
next_object_id = 0;
|
next_object_id = 0;
|
||||||
@ -680,10 +677,6 @@ struct KernelCore::Impl {
|
|||||||
// Threads used for services
|
// Threads used for services
|
||||||
std::unordered_set<std::shared_ptr<Kernel::ServiceThread>> service_threads;
|
std::unordered_set<std::shared_ptr<Kernel::ServiceThread>> service_threads;
|
||||||
|
|
||||||
// Service threads are managed by a worker thread, so that a calling service thread can queue up
|
|
||||||
// the release of itself
|
|
||||||
std::unique_ptr<Common::ThreadWorker> service_thread_manager;
|
|
||||||
|
|
||||||
std::array<KThread*, Core::Hardware::NUM_CPU_CORES> suspend_threads;
|
std::array<KThread*, Core::Hardware::NUM_CPU_CORES> suspend_threads;
|
||||||
std::array<Core::CPUInterruptHandler, Core::Hardware::NUM_CPU_CORES> interrupts{};
|
std::array<Core::CPUInterruptHandler, Core::Hardware::NUM_CPU_CORES> interrupts{};
|
||||||
std::array<std::unique_ptr<Kernel::KScheduler>, Core::Hardware::NUM_CPU_CORES> schedulers{};
|
std::array<std::unique_ptr<Kernel::KScheduler>, Core::Hardware::NUM_CPU_CORES> schedulers{};
|
||||||
@ -986,17 +979,14 @@ void KernelCore::ExitSVCProfile() {
|
|||||||
|
|
||||||
std::weak_ptr<Kernel::ServiceThread> KernelCore::CreateServiceThread(const std::string& name) {
|
std::weak_ptr<Kernel::ServiceThread> KernelCore::CreateServiceThread(const std::string& name) {
|
||||||
auto service_thread = std::make_shared<Kernel::ServiceThread>(*this, 1, name);
|
auto service_thread = std::make_shared<Kernel::ServiceThread>(*this, 1, name);
|
||||||
impl->service_thread_manager->QueueWork(
|
impl->service_threads.emplace(service_thread);
|
||||||
[this, service_thread] { impl->service_threads.emplace(service_thread); });
|
|
||||||
return service_thread;
|
return service_thread;
|
||||||
}
|
}
|
||||||
|
|
||||||
void KernelCore::ReleaseServiceThread(std::weak_ptr<Kernel::ServiceThread> service_thread) {
|
void KernelCore::ReleaseServiceThread(std::weak_ptr<Kernel::ServiceThread> service_thread) {
|
||||||
impl->service_thread_manager->QueueWork([this, service_thread] {
|
if (auto strong_ptr = service_thread.lock()) {
|
||||||
if (auto strong_ptr = service_thread.lock()) {
|
impl->service_threads.erase(strong_ptr);
|
||||||
impl->service_threads.erase(strong_ptr);
|
}
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Init::KSlabResourceCounts& KernelCore::SlabResourceCounts() {
|
Init::KSlabResourceCounts& KernelCore::SlabResourceCounts() {
|
||||||
|
@ -505,6 +505,10 @@ void GameList::PopupContextMenu(const QPoint& menu_location) {
|
|||||||
void GameList::AddGamePopup(QMenu& context_menu, u64 program_id, const std::string& path) {
|
void GameList::AddGamePopup(QMenu& context_menu, u64 program_id, const std::string& path) {
|
||||||
QAction* favorite = context_menu.addAction(tr("Favorite"));
|
QAction* favorite = context_menu.addAction(tr("Favorite"));
|
||||||
context_menu.addSeparator();
|
context_menu.addSeparator();
|
||||||
|
QAction* start_game = context_menu.addAction(tr("Start Game"));
|
||||||
|
QAction* start_game_global =
|
||||||
|
context_menu.addAction(tr("Start Game without Custom Configuration"));
|
||||||
|
context_menu.addSeparator();
|
||||||
QAction* open_save_location = context_menu.addAction(tr("Open Save Data Location"));
|
QAction* open_save_location = context_menu.addAction(tr("Open Save Data Location"));
|
||||||
QAction* open_mod_location = context_menu.addAction(tr("Open Mod Data Location"));
|
QAction* open_mod_location = context_menu.addAction(tr("Open Mod Data Location"));
|
||||||
QAction* open_transferable_shader_cache =
|
QAction* open_transferable_shader_cache =
|
||||||
@ -540,6 +544,12 @@ void GameList::AddGamePopup(QMenu& context_menu, u64 program_id, const std::stri
|
|||||||
connect(open_save_location, &QAction::triggered, [this, program_id, path]() {
|
connect(open_save_location, &QAction::triggered, [this, program_id, path]() {
|
||||||
emit OpenFolderRequested(program_id, GameListOpenTarget::SaveData, path);
|
emit OpenFolderRequested(program_id, GameListOpenTarget::SaveData, path);
|
||||||
});
|
});
|
||||||
|
connect(start_game, &QAction::triggered, [this, path]() {
|
||||||
|
emit BootGame(QString::fromStdString(path), 0, StartGameType::Normal);
|
||||||
|
});
|
||||||
|
connect(start_game_global, &QAction::triggered, [this, path]() {
|
||||||
|
emit BootGame(QString::fromStdString(path), 0, StartGameType::Global);
|
||||||
|
});
|
||||||
connect(open_mod_location, &QAction::triggered, [this, program_id, path]() {
|
connect(open_mod_location, &QAction::triggered, [this, program_id, path]() {
|
||||||
emit OpenFolderRequested(program_id, GameListOpenTarget::ModData, path);
|
emit OpenFolderRequested(program_id, GameListOpenTarget::ModData, path);
|
||||||
});
|
});
|
||||||
|
@ -28,6 +28,7 @@ class GameListWorker;
|
|||||||
class GameListSearchField;
|
class GameListSearchField;
|
||||||
class GameListDir;
|
class GameListDir;
|
||||||
class GMainWindow;
|
class GMainWindow;
|
||||||
|
enum class StartGameType;
|
||||||
|
|
||||||
namespace FileSys {
|
namespace FileSys {
|
||||||
class ManualContentProvider;
|
class ManualContentProvider;
|
||||||
@ -82,6 +83,7 @@ public:
|
|||||||
static const QStringList supported_file_extensions;
|
static const QStringList supported_file_extensions;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
void BootGame(const QString& game_path, std::size_t program_index, StartGameType type);
|
||||||
void GameChosen(const QString& game_path);
|
void GameChosen(const QString& game_path);
|
||||||
void ShouldCancelWorker();
|
void ShouldCancelWorker();
|
||||||
void OpenFolderRequested(u64 program_id, GameListOpenTarget target,
|
void OpenFolderRequested(u64 program_id, GameListOpenTarget target,
|
||||||
|
@ -1094,6 +1094,7 @@ void GMainWindow::OnAppFocusStateChanged(Qt::ApplicationState state) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GMainWindow::ConnectWidgetEvents() {
|
void GMainWindow::ConnectWidgetEvents() {
|
||||||
|
connect(game_list, &GameList::BootGame, this, &GMainWindow::BootGame);
|
||||||
connect(game_list, &GameList::GameChosen, this, &GMainWindow::OnGameListLoadFile);
|
connect(game_list, &GameList::GameChosen, this, &GMainWindow::OnGameListLoadFile);
|
||||||
connect(game_list, &GameList::OpenDirectory, this, &GMainWindow::OnGameListOpenDirectory);
|
connect(game_list, &GameList::OpenDirectory, this, &GMainWindow::OnGameListOpenDirectory);
|
||||||
connect(game_list, &GameList::OpenFolderRequested, this, &GMainWindow::OnGameListOpenFolder);
|
connect(game_list, &GameList::OpenFolderRequested, this, &GMainWindow::OnGameListOpenFolder);
|
||||||
@ -1320,7 +1321,7 @@ void GMainWindow::SelectAndSetCurrentUser() {
|
|||||||
Settings::values.current_user = dialog.GetIndex();
|
Settings::values.current_user = dialog.GetIndex();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GMainWindow::BootGame(const QString& filename, std::size_t program_index) {
|
void GMainWindow::BootGame(const QString& filename, std::size_t program_index, StartGameType type) {
|
||||||
LOG_INFO(Frontend, "yuzu starting...");
|
LOG_INFO(Frontend, "yuzu starting...");
|
||||||
StoreRecentFile(filename); // Put the filename on top of the list
|
StoreRecentFile(filename); // Put the filename on top of the list
|
||||||
|
|
||||||
@ -1332,7 +1333,8 @@ void GMainWindow::BootGame(const QString& filename, std::size_t program_index) {
|
|||||||
const auto v_file = Core::GetGameFileFromPath(vfs, filename.toUtf8().constData());
|
const auto v_file = Core::GetGameFileFromPath(vfs, filename.toUtf8().constData());
|
||||||
const auto loader = Loader::GetLoader(system, v_file, program_index);
|
const auto loader = Loader::GetLoader(system, v_file, program_index);
|
||||||
|
|
||||||
if (!(loader == nullptr || loader->ReadProgramId(title_id) != Loader::ResultStatus::Success)) {
|
if (loader != nullptr && loader->ReadProgramId(title_id) == Loader::ResultStatus::Success &&
|
||||||
|
type == StartGameType::Normal) {
|
||||||
// Load per game settings
|
// Load per game settings
|
||||||
const auto file_path = std::filesystem::path{filename.toStdU16String()};
|
const auto file_path = std::filesystem::path{filename.toStdU16String()};
|
||||||
const auto config_file_name = title_id == 0
|
const auto config_file_name = title_id == 0
|
||||||
|
@ -39,6 +39,11 @@ class GameListPlaceholder;
|
|||||||
|
|
||||||
class QtSoftwareKeyboardDialog;
|
class QtSoftwareKeyboardDialog;
|
||||||
|
|
||||||
|
enum class StartGameType {
|
||||||
|
Normal, // Can use custom configuration
|
||||||
|
Global, // Only uses global configuration
|
||||||
|
};
|
||||||
|
|
||||||
namespace Core::Frontend {
|
namespace Core::Frontend {
|
||||||
struct ControllerParameters;
|
struct ControllerParameters;
|
||||||
struct InlineAppearParameters;
|
struct InlineAppearParameters;
|
||||||
@ -181,7 +186,8 @@ private:
|
|||||||
void AllowOSSleep();
|
void AllowOSSleep();
|
||||||
|
|
||||||
bool LoadROM(const QString& filename, std::size_t program_index);
|
bool LoadROM(const QString& filename, std::size_t program_index);
|
||||||
void BootGame(const QString& filename, std::size_t program_index = 0);
|
void BootGame(const QString& filename, std::size_t program_index = 0,
|
||||||
|
StartGameType with_config = StartGameType::Normal);
|
||||||
void ShutdownGame();
|
void ShutdownGame();
|
||||||
|
|
||||||
void ShowTelemetryCallout();
|
void ShowTelemetryCallout();
|
||||||
|
Loading…
Reference in New Issue
Block a user