early-access version 1763

This commit is contained in:
pineappleEA 2021-06-08 07:46:24 +02:00
parent dc53b00cd9
commit 9612b12e5c
9 changed files with 57 additions and 26 deletions

View file

@ -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

View file

@ -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());
} }

View file

@ -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;
}; };
/** /**

View file

@ -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
if (manager->HasSessionRequestHandler(*context)) {
if (auto strong_ptr = manager->GetServiceThread().lock()) {
strong_ptr->QueueSyncRequest(*parent, std::move(context)); strong_ptr->QueueSyncRequest(*parent, std::move(context));
return ResultSuccess; return ResultSuccess;
} else { } else {
ASSERT_MSG(false, "strong_ptr was nullptr!"); ASSERT_MSG(false, "strong_ptr is nullptr!");
}
} else {
ASSERT_MSG(false, "handler is invalid!");
} }
return ResultSuccess; return ResultSuccess;

View file

@ -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() {

View file

@ -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);
}); });

View file

@ -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,

View file

@ -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

View file

@ -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();