Fixed formatting
This commit is contained in:
parent
8a1f3b7c41
commit
c793a9c95c
3 changed files with 368 additions and 376 deletions
|
@ -246,8 +246,7 @@ void Config::ReadValues() {
|
||||||
|
|
||||||
// Network
|
// Network
|
||||||
|
|
||||||
Settings::values.network_route =
|
Settings::values.network_route = config->GetString("Network", "network_route", "");
|
||||||
config->GetString("Network", "network_route", "");
|
|
||||||
|
|
||||||
// Miscellaneous
|
// Miscellaneous
|
||||||
// log_filter has a different default here than from common
|
// log_filter has a different default here than from common
|
||||||
|
|
|
@ -13,9 +13,9 @@
|
||||||
|
|
||||||
#include <android/api-level.h>
|
#include <android/api-level.h>
|
||||||
#include <android/native_window_jni.h>
|
#include <android/native_window_jni.h>
|
||||||
#include <network/room_member.h>
|
|
||||||
#include <network/network.h>
|
|
||||||
#include <core/loader/nro.h>
|
#include <core/loader/nro.h>
|
||||||
|
#include <network/network.h>
|
||||||
|
#include <network/room_member.h>
|
||||||
|
|
||||||
#include "common/detached_tasks.h"
|
#include "common/detached_tasks.h"
|
||||||
#include "common/dynamic_library.h"
|
#include "common/dynamic_library.h"
|
||||||
|
@ -60,384 +60,385 @@
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
class EmulationSession final {
|
class EmulationSession final {
|
||||||
public:
|
public:
|
||||||
EmulationSession() {
|
EmulationSession() {
|
||||||
m_vfs = std::make_shared<FileSys::RealVfsFilesystem>();
|
m_vfs = std::make_shared<FileSys::RealVfsFilesystem>();
|
||||||
}
|
}
|
||||||
|
|
||||||
~EmulationSession() = default;
|
~EmulationSession() = default;
|
||||||
|
|
||||||
static EmulationSession& GetInstance() {
|
static EmulationSession& GetInstance() {
|
||||||
return s_instance;
|
return s_instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Core::System& System() const {
|
const Core::System& System() const {
|
||||||
return m_system;
|
return m_system;
|
||||||
}
|
}
|
||||||
|
|
||||||
Core::System& System() {
|
Core::System& System() {
|
||||||
return m_system;
|
return m_system;
|
||||||
}
|
}
|
||||||
|
|
||||||
const EmuWindow_Android& Window() const {
|
const EmuWindow_Android& Window() const {
|
||||||
return *m_window;
|
return *m_window;
|
||||||
}
|
}
|
||||||
|
|
||||||
EmuWindow_Android& Window() {
|
EmuWindow_Android& Window() {
|
||||||
return *m_window;
|
return *m_window;
|
||||||
}
|
}
|
||||||
|
|
||||||
ANativeWindow* NativeWindow() const {
|
ANativeWindow* NativeWindow() const {
|
||||||
return m_native_window;
|
return m_native_window;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetNativeWindow(ANativeWindow* native_window) {
|
void SetNativeWindow(ANativeWindow* native_window) {
|
||||||
m_native_window = native_window;
|
m_native_window = native_window;
|
||||||
}
|
}
|
||||||
|
|
||||||
void InitializeGpuDriver(const std::string& hook_lib_dir, const std::string& custom_driver_dir,
|
void InitializeGpuDriver(const std::string& hook_lib_dir, const std::string& custom_driver_dir,
|
||||||
const std::string& custom_driver_name,
|
const std::string& custom_driver_name,
|
||||||
const std::string& file_redirect_dir) {
|
const std::string& file_redirect_dir) {
|
||||||
#ifdef ARCHITECTURE_arm64
|
#ifdef ARCHITECTURE_arm64
|
||||||
void* handle{};
|
void* handle{};
|
||||||
const char* file_redirect_dir_{};
|
const char* file_redirect_dir_{};
|
||||||
int featureFlags{};
|
int featureFlags{};
|
||||||
|
|
||||||
// Enable driver file redirection when renderer debugging is enabled.
|
// Enable driver file redirection when renderer debugging is enabled.
|
||||||
if (Settings::values.renderer_debug && file_redirect_dir.size()) {
|
if (Settings::values.renderer_debug && file_redirect_dir.size()) {
|
||||||
featureFlags |= ADRENOTOOLS_DRIVER_FILE_REDIRECT;
|
featureFlags |= ADRENOTOOLS_DRIVER_FILE_REDIRECT;
|
||||||
file_redirect_dir_ = file_redirect_dir.c_str();
|
file_redirect_dir_ = file_redirect_dir.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to load a custom driver.
|
// Try to load a custom driver.
|
||||||
if (custom_driver_name.size()) {
|
if (custom_driver_name.size()) {
|
||||||
handle = adrenotools_open_libvulkan(
|
handle = adrenotools_open_libvulkan(
|
||||||
RTLD_NOW, featureFlags | ADRENOTOOLS_DRIVER_CUSTOM, nullptr, hook_lib_dir.c_str(),
|
RTLD_NOW, featureFlags | ADRENOTOOLS_DRIVER_CUSTOM, nullptr, hook_lib_dir.c_str(),
|
||||||
custom_driver_dir.c_str(), custom_driver_name.c_str(), file_redirect_dir_, nullptr);
|
custom_driver_dir.c_str(), custom_driver_name.c_str(), file_redirect_dir_, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to load the system driver.
|
// Try to load the system driver.
|
||||||
if (!handle) {
|
if (!handle) {
|
||||||
handle =
|
handle =
|
||||||
adrenotools_open_libvulkan(RTLD_NOW, featureFlags, nullptr, hook_lib_dir.c_str(),
|
adrenotools_open_libvulkan(RTLD_NOW, featureFlags, nullptr, hook_lib_dir.c_str(),
|
||||||
nullptr, nullptr, file_redirect_dir_, nullptr);
|
nullptr, nullptr, file_redirect_dir_, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_vulkan_library = std::make_shared<Common::DynamicLibrary>(handle);
|
m_vulkan_library = std::make_shared<Common::DynamicLibrary>(handle);
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsRunning() const {
|
||||||
|
std::scoped_lock lock(m_mutex);
|
||||||
|
return m_is_running;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Core::PerfStatsResults& PerfStats() const {
|
||||||
|
std::scoped_lock m_perf_stats_lock(m_perf_stats_mutex);
|
||||||
|
return m_perf_stats;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SurfaceChanged() {
|
||||||
|
if (!IsRunning()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_window->OnSurfaceChanged(m_native_window);
|
||||||
|
m_system.Renderer().NotifySurfaceChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
Core::SystemResultStatus InitializeEmulation(const std::string& filepath) {
|
||||||
|
std::scoped_lock lock(m_mutex);
|
||||||
|
|
||||||
|
// Loads the configuration.
|
||||||
|
Config{};
|
||||||
|
|
||||||
|
// Create the render window.
|
||||||
|
m_window = std::make_unique<EmuWindow_Android>(&m_input_subsystem, m_native_window,
|
||||||
|
m_vulkan_library);
|
||||||
|
|
||||||
|
// Initialize system.
|
||||||
|
auto android_keyboard = std::make_unique<SoftwareKeyboard::AndroidKeyboard>();
|
||||||
|
m_software_keyboard = android_keyboard.get();
|
||||||
|
m_system.SetShuttingDown(false);
|
||||||
|
m_system.ApplySettings();
|
||||||
|
m_system.HIDCore().ReloadInputDevices();
|
||||||
|
m_system.SetContentProvider(std::make_unique<FileSys::ContentProviderUnion>());
|
||||||
|
m_system.SetFilesystem(std::make_shared<FileSys::RealVfsFilesystem>());
|
||||||
|
m_system.SetAppletFrontendSet({
|
||||||
|
nullptr, // Amiibo Settings
|
||||||
|
nullptr, // Controller Selector
|
||||||
|
nullptr, // Error Display
|
||||||
|
nullptr, // Mii Editor
|
||||||
|
nullptr, // Parental Controls
|
||||||
|
nullptr, // Photo Viewer
|
||||||
|
nullptr, // Profile Selector
|
||||||
|
std::move(android_keyboard), // Software Keyboard
|
||||||
|
nullptr, // Web Browser
|
||||||
|
});
|
||||||
|
m_system.GetFileSystemController().CreateFactories(*m_system.GetFilesystem());
|
||||||
|
|
||||||
|
// Initialize account manager
|
||||||
|
m_profile_manager = std::make_unique<Service::Account::ProfileManager>();
|
||||||
|
|
||||||
|
// Load the ROM.
|
||||||
|
m_load_result = m_system.Load(EmulationSession::GetInstance().Window(), filepath);
|
||||||
|
if (m_load_result != Core::SystemResultStatus::Success) {
|
||||||
|
return m_load_result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsRunning() const {
|
// Complete initialization.
|
||||||
|
m_system.GPU().Start();
|
||||||
|
m_system.GetCpuManager().OnGpuReady();
|
||||||
|
m_system.RegisterExitCallback([&] { HaltEmulation(); });
|
||||||
|
|
||||||
|
return Core::SystemResultStatus::Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShutdownEmulation() {
|
||||||
|
std::scoped_lock lock(m_mutex);
|
||||||
|
|
||||||
|
m_is_running = false;
|
||||||
|
|
||||||
|
// Unload user input.
|
||||||
|
m_system.HIDCore().UnloadInputDevices();
|
||||||
|
|
||||||
|
// Shutdown the main emulated process
|
||||||
|
if (m_load_result == Core::SystemResultStatus::Success) {
|
||||||
|
m_system.DetachDebugger();
|
||||||
|
m_system.ShutdownMainProcess();
|
||||||
|
m_detached_tasks.WaitForAllTasks();
|
||||||
|
m_load_result = Core::SystemResultStatus::ErrorNotInitialized;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tear down the render window.
|
||||||
|
m_window.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PauseEmulation() {
|
||||||
|
std::scoped_lock lock(m_mutex);
|
||||||
|
m_system.Pause();
|
||||||
|
}
|
||||||
|
|
||||||
|
void UnPauseEmulation() {
|
||||||
|
std::scoped_lock lock(m_mutex);
|
||||||
|
m_system.Run();
|
||||||
|
}
|
||||||
|
|
||||||
|
void HaltEmulation() {
|
||||||
|
std::scoped_lock lock(m_mutex);
|
||||||
|
m_is_running = false;
|
||||||
|
m_cv.notify_one();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RunEmulation() {
|
||||||
|
{
|
||||||
std::scoped_lock lock(m_mutex);
|
std::scoped_lock lock(m_mutex);
|
||||||
return m_is_running;
|
m_is_running = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Core::PerfStatsResults& PerfStats() const {
|
// Load the disk shader cache.
|
||||||
std::scoped_lock m_perf_stats_lock(m_perf_stats_mutex);
|
if (Settings::values.use_disk_shader_cache.GetValue()) {
|
||||||
return m_perf_stats;
|
LoadDiskCacheProgress(VideoCore::LoadCallbackStage::Prepare, 0, 0);
|
||||||
|
m_system.Renderer().ReadRasterizer()->LoadDiskResources(
|
||||||
|
m_system.GetApplicationProcessProgramID(), std::stop_token{},
|
||||||
|
LoadDiskCacheProgress);
|
||||||
|
LoadDiskCacheProgress(VideoCore::LoadCallbackStage::Complete, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SurfaceChanged() {
|
void(m_system.Run());
|
||||||
if (!IsRunning()) {
|
|
||||||
return;
|
if (m_system.DebuggerEnabled()) {
|
||||||
}
|
m_system.InitializeDebugger();
|
||||||
m_window->OnSurfaceChanged(m_native_window);
|
|
||||||
m_system.Renderer().NotifySurfaceChanged();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Core::SystemResultStatus InitializeEmulation(const std::string& filepath) {
|
while (true) {
|
||||||
std::scoped_lock lock(m_mutex);
|
|
||||||
|
|
||||||
// Loads the configuration.
|
|
||||||
Config{};
|
|
||||||
|
|
||||||
// Create the render window.
|
|
||||||
m_window = std::make_unique<EmuWindow_Android>(&m_input_subsystem, m_native_window,
|
|
||||||
m_vulkan_library);
|
|
||||||
|
|
||||||
// Initialize system.
|
|
||||||
auto android_keyboard = std::make_unique<SoftwareKeyboard::AndroidKeyboard>();
|
|
||||||
m_software_keyboard = android_keyboard.get();
|
|
||||||
m_system.SetShuttingDown(false);
|
|
||||||
m_system.ApplySettings();
|
|
||||||
m_system.HIDCore().ReloadInputDevices();
|
|
||||||
m_system.SetContentProvider(std::make_unique<FileSys::ContentProviderUnion>());
|
|
||||||
m_system.SetFilesystem(std::make_shared<FileSys::RealVfsFilesystem>());
|
|
||||||
m_system.SetAppletFrontendSet({
|
|
||||||
nullptr, // Amiibo Settings
|
|
||||||
nullptr, // Controller Selector
|
|
||||||
nullptr, // Error Display
|
|
||||||
nullptr, // Mii Editor
|
|
||||||
nullptr, // Parental Controls
|
|
||||||
nullptr, // Photo Viewer
|
|
||||||
nullptr, // Profile Selector
|
|
||||||
std::move(android_keyboard), // Software Keyboard
|
|
||||||
nullptr, // Web Browser
|
|
||||||
});
|
|
||||||
m_system.GetFileSystemController().CreateFactories(*m_system.GetFilesystem());
|
|
||||||
|
|
||||||
// Initialize account manager
|
|
||||||
m_profile_manager = std::make_unique<Service::Account::ProfileManager>();
|
|
||||||
|
|
||||||
// Load the ROM.
|
|
||||||
m_load_result = m_system.Load(EmulationSession::GetInstance().Window(), filepath);
|
|
||||||
if (m_load_result != Core::SystemResultStatus::Success) {
|
|
||||||
return m_load_result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Complete initialization.
|
|
||||||
m_system.GPU().Start();
|
|
||||||
m_system.GetCpuManager().OnGpuReady();
|
|
||||||
m_system.RegisterExitCallback([&] { HaltEmulation(); });
|
|
||||||
|
|
||||||
return Core::SystemResultStatus::Success;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ShutdownEmulation() {
|
|
||||||
std::scoped_lock lock(m_mutex);
|
|
||||||
|
|
||||||
m_is_running = false;
|
|
||||||
|
|
||||||
// Unload user input.
|
|
||||||
m_system.HIDCore().UnloadInputDevices();
|
|
||||||
|
|
||||||
// Shutdown the main emulated process
|
|
||||||
if (m_load_result == Core::SystemResultStatus::Success) {
|
|
||||||
m_system.DetachDebugger();
|
|
||||||
m_system.ShutdownMainProcess();
|
|
||||||
m_detached_tasks.WaitForAllTasks();
|
|
||||||
m_load_result = Core::SystemResultStatus::ErrorNotInitialized;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tear down the render window.
|
|
||||||
m_window.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PauseEmulation() {
|
|
||||||
std::scoped_lock lock(m_mutex);
|
|
||||||
m_system.Pause();
|
|
||||||
}
|
|
||||||
|
|
||||||
void UnPauseEmulation() {
|
|
||||||
std::scoped_lock lock(m_mutex);
|
|
||||||
m_system.Run();
|
|
||||||
}
|
|
||||||
|
|
||||||
void HaltEmulation() {
|
|
||||||
std::scoped_lock lock(m_mutex);
|
|
||||||
m_is_running = false;
|
|
||||||
m_cv.notify_one();
|
|
||||||
}
|
|
||||||
|
|
||||||
void RunEmulation() {
|
|
||||||
{
|
{
|
||||||
std::scoped_lock lock(m_mutex);
|
std::unique_lock lock(m_mutex);
|
||||||
m_is_running = true;
|
if (m_cv.wait_for(lock, std::chrono::milliseconds(800),
|
||||||
}
|
[&]() { return !m_is_running; })) {
|
||||||
|
// Emulation halted.
|
||||||
// Load the disk shader cache.
|
break;
|
||||||
if (Settings::values.use_disk_shader_cache.GetValue()) {
|
|
||||||
LoadDiskCacheProgress(VideoCore::LoadCallbackStage::Prepare, 0, 0);
|
|
||||||
m_system.Renderer().ReadRasterizer()->LoadDiskResources(
|
|
||||||
m_system.GetApplicationProcessProgramID(), std::stop_token{},
|
|
||||||
LoadDiskCacheProgress);
|
|
||||||
LoadDiskCacheProgress(VideoCore::LoadCallbackStage::Complete, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void(m_system.Run());
|
|
||||||
|
|
||||||
if (m_system.DebuggerEnabled()) {
|
|
||||||
m_system.InitializeDebugger();
|
|
||||||
}
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
{
|
|
||||||
std::unique_lock lock(m_mutex);
|
|
||||||
if (m_cv.wait_for(lock, std::chrono::milliseconds(800),
|
|
||||||
[&]() { return !m_is_running; })) {
|
|
||||||
// Emulation halted.
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
{
|
|
||||||
// Refresh performance stats.
|
|
||||||
std::scoped_lock m_perf_stats_lock(m_perf_stats_mutex);
|
|
||||||
m_perf_stats = m_system.GetAndResetPerfStats();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
{
|
||||||
|
// Refresh performance stats.
|
||||||
std::string GetRomTitle(const std::string& path) {
|
std::scoped_lock m_perf_stats_lock(m_perf_stats_mutex);
|
||||||
return GetRomMetadata(path).title;
|
m_perf_stats = m_system.GetAndResetPerfStats();
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<u8> GetRomIcon(const std::string& path) {
|
|
||||||
return GetRomMetadata(path).icon;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GetIsHomebrew(const std::string& path) {
|
|
||||||
return GetRomMetadata(path).isHomebrew;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ResetRomMetadata() {
|
|
||||||
m_rom_metadata_cache.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsHandheldOnly() {
|
|
||||||
const auto npad_style_set = m_system.HIDCore().GetSupportedStyleTag();
|
|
||||||
|
|
||||||
if (npad_style_set.fullkey == 1) {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (npad_style_set.handheld == 0) {
|
std::string GetRomTitle(const std::string& path) {
|
||||||
return false;
|
return GetRomMetadata(path).title;
|
||||||
}
|
}
|
||||||
|
|
||||||
return !Settings::values.use_docked_mode.GetValue();
|
std::vector<u8> GetRomIcon(const std::string& path) {
|
||||||
|
return GetRomMetadata(path).icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GetIsHomebrew(const std::string& path) {
|
||||||
|
return GetRomMetadata(path).isHomebrew;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResetRomMetadata() {
|
||||||
|
m_rom_metadata_cache.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsHandheldOnly() {
|
||||||
|
const auto npad_style_set = m_system.HIDCore().GetSupportedStyleTag();
|
||||||
|
|
||||||
|
if (npad_style_set.fullkey == 1) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetDeviceType(int index, int type) {
|
if (npad_style_set.handheld == 0) {
|
||||||
auto controller = m_system.HIDCore().GetEmulatedControllerByIndex(index);
|
return false;
|
||||||
controller->SetNpadStyleIndex(static_cast<Core::HID::NpadStyleIndex>(type));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnGamepadConnectEvent(int index) {
|
return !Settings::values.use_docked_mode.GetValue();
|
||||||
auto controller = m_system.HIDCore().GetEmulatedControllerByIndex(index);
|
}
|
||||||
|
|
||||||
// Ensure that player1 is configured correctly and handheld disconnected
|
void SetDeviceType(int index, int type) {
|
||||||
if (controller->GetNpadIdType() == Core::HID::NpadIdType::Player1) {
|
auto controller = m_system.HIDCore().GetEmulatedControllerByIndex(index);
|
||||||
auto handheld =
|
controller->SetNpadStyleIndex(static_cast<Core::HID::NpadStyleIndex>(type));
|
||||||
m_system.HIDCore().GetEmulatedController(Core::HID::NpadIdType::Handheld);
|
}
|
||||||
|
|
||||||
if (controller->GetNpadStyleIndex() == Core::HID::NpadStyleIndex::Handheld) {
|
void OnGamepadConnectEvent(int index) {
|
||||||
handheld->SetNpadStyleIndex(Core::HID::NpadStyleIndex::ProController);
|
auto controller = m_system.HIDCore().GetEmulatedControllerByIndex(index);
|
||||||
controller->SetNpadStyleIndex(Core::HID::NpadStyleIndex::ProController);
|
|
||||||
handheld->Disconnect();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure that handheld is configured correctly and player 1 disconnected
|
// Ensure that player1 is configured correctly and handheld disconnected
|
||||||
if (controller->GetNpadIdType() == Core::HID::NpadIdType::Handheld) {
|
if (controller->GetNpadIdType() == Core::HID::NpadIdType::Player1) {
|
||||||
auto player1 = m_system.HIDCore().GetEmulatedController(Core::HID::NpadIdType::Player1);
|
auto handheld =
|
||||||
|
m_system.HIDCore().GetEmulatedController(Core::HID::NpadIdType::Handheld);
|
||||||
|
|
||||||
if (controller->GetNpadStyleIndex() != Core::HID::NpadStyleIndex::Handheld) {
|
if (controller->GetNpadStyleIndex() == Core::HID::NpadStyleIndex::Handheld) {
|
||||||
player1->SetNpadStyleIndex(Core::HID::NpadStyleIndex::Handheld);
|
handheld->SetNpadStyleIndex(Core::HID::NpadStyleIndex::ProController);
|
||||||
controller->SetNpadStyleIndex(Core::HID::NpadStyleIndex::Handheld);
|
controller->SetNpadStyleIndex(Core::HID::NpadStyleIndex::ProController);
|
||||||
player1->Disconnect();
|
handheld->Disconnect();
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!controller->IsConnected()) {
|
|
||||||
controller->Connect();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnGamepadDisconnectEvent(int index) {
|
// Ensure that handheld is configured correctly and player 1 disconnected
|
||||||
auto controller = m_system.HIDCore().GetEmulatedControllerByIndex(index);
|
if (controller->GetNpadIdType() == Core::HID::NpadIdType::Handheld) {
|
||||||
controller->Disconnect();
|
auto player1 = m_system.HIDCore().GetEmulatedController(Core::HID::NpadIdType::Player1);
|
||||||
}
|
|
||||||
|
|
||||||
SoftwareKeyboard::AndroidKeyboard* SoftwareKeyboard() {
|
if (controller->GetNpadStyleIndex() != Core::HID::NpadStyleIndex::Handheld) {
|
||||||
return m_software_keyboard;
|
player1->SetNpadStyleIndex(Core::HID::NpadStyleIndex::Handheld);
|
||||||
}
|
controller->SetNpadStyleIndex(Core::HID::NpadStyleIndex::Handheld);
|
||||||
|
player1->Disconnect();
|
||||||
void DirectConnectToRoom(const std::string& nickname, const char* server_addr = "127.0.0.1",
|
|
||||||
u16 server_port = Network::DefaultRoomPort,
|
|
||||||
const std::string& password = "") {
|
|
||||||
auto room_network = m_system.GetRoomNetwork();
|
|
||||||
|
|
||||||
if (const auto member = room_network.GetRoomMember().lock()) {
|
|
||||||
// Prevent the user from trying to join a room while they are already joining.
|
|
||||||
if (member->GetState() == Network::RoomMember::State::Joining || member->IsConnected()) {
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
member->Join(nickname, server_addr, server_port);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Network::RoomMember::State GetRoomMemberState() {
|
if (!controller->IsConnected()) {
|
||||||
if (const auto member = m_system.GetRoomNetwork().GetRoomMember().lock()) {
|
controller->Connect();
|
||||||
return member->GetState();
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnGamepadDisconnectEvent(int index) {
|
||||||
|
auto controller = m_system.HIDCore().GetEmulatedControllerByIndex(index);
|
||||||
|
controller->Disconnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
SoftwareKeyboard::AndroidKeyboard* SoftwareKeyboard() {
|
||||||
|
return m_software_keyboard;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DirectConnectToRoom(const std::string& nickname, const char* server_addr = "127.0.0.1",
|
||||||
|
u16 server_port = Network::DefaultRoomPort,
|
||||||
|
const std::string& password = "") {
|
||||||
|
auto room_network = m_system.GetRoomNetwork();
|
||||||
|
|
||||||
|
if (const auto member = room_network.GetRoomMember().lock()) {
|
||||||
|
// Prevent the user from trying to join a room while they are already joining.
|
||||||
|
if (member->GetState() == Network::RoomMember::State::Joining ||
|
||||||
|
member->IsConnected()) {
|
||||||
|
return;
|
||||||
} else {
|
} else {
|
||||||
return Network::RoomMember::State::Idle;
|
member->Join(nickname, server_addr, server_port);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
Network::RoomMember::State GetRoomMemberState() {
|
||||||
struct RomMetadata {
|
if (const auto member = m_system.GetRoomNetwork().GetRoomMember().lock()) {
|
||||||
std::string title;
|
return member->GetState();
|
||||||
std::vector<u8> icon;
|
} else {
|
||||||
bool isHomebrew;
|
return Network::RoomMember::State::Idle;
|
||||||
};
|
|
||||||
|
|
||||||
RomMetadata GetRomMetadata(const std::string& path) {
|
|
||||||
if (auto search = m_rom_metadata_cache.find(path); search != m_rom_metadata_cache.end()) {
|
|
||||||
return search->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
return CacheRomMetadata(path);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
RomMetadata CacheRomMetadata(const std::string& path) {
|
private:
|
||||||
const auto file = Core::GetGameFileFromPath(m_vfs, path);
|
struct RomMetadata {
|
||||||
auto loader = Loader::GetLoader(EmulationSession::GetInstance().System(), file, 0, 0);
|
std::string title;
|
||||||
|
std::vector<u8> icon;
|
||||||
RomMetadata entry;
|
bool isHomebrew;
|
||||||
loader->ReadTitle(entry.title);
|
|
||||||
loader->ReadIcon(entry.icon);
|
|
||||||
if (loader->GetFileType() == Loader::FileType::NRO) {
|
|
||||||
auto loader_nro = dynamic_cast<Loader::AppLoader_NRO*>(loader.get());
|
|
||||||
entry.isHomebrew = loader_nro->IsHomebrew();
|
|
||||||
} else {
|
|
||||||
entry.isHomebrew = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_rom_metadata_cache[path] = entry;
|
|
||||||
|
|
||||||
return entry;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
static void LoadDiskCacheProgress(VideoCore::LoadCallbackStage stage, int progress, int max) {
|
|
||||||
JNIEnv* env = IDCache::GetEnvForThread();
|
|
||||||
env->CallStaticVoidMethod(IDCache::GetDiskCacheProgressClass(),
|
|
||||||
IDCache::GetDiskCacheLoadProgress(), static_cast<jint>(stage),
|
|
||||||
static_cast<jint>(progress), static_cast<jint>(max));
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
static EmulationSession s_instance;
|
|
||||||
|
|
||||||
// Frontend management
|
|
||||||
std::unordered_map<std::string, RomMetadata> m_rom_metadata_cache;
|
|
||||||
|
|
||||||
// Window management
|
|
||||||
std::unique_ptr<EmuWindow_Android> m_window;
|
|
||||||
ANativeWindow* m_native_window{};
|
|
||||||
|
|
||||||
// Core emulation
|
|
||||||
Core::System m_system;
|
|
||||||
InputCommon::InputSubsystem m_input_subsystem;
|
|
||||||
Common::DetachedTasks m_detached_tasks;
|
|
||||||
Core::PerfStatsResults m_perf_stats{};
|
|
||||||
std::shared_ptr<FileSys::RealVfsFilesystem> m_vfs;
|
|
||||||
Core::SystemResultStatus m_load_result{Core::SystemResultStatus::ErrorNotInitialized};
|
|
||||||
bool m_is_running{};
|
|
||||||
SoftwareKeyboard::AndroidKeyboard* m_software_keyboard{};
|
|
||||||
std::unique_ptr<Service::Account::ProfileManager> m_profile_manager;
|
|
||||||
|
|
||||||
// GPU driver parameters
|
|
||||||
std::shared_ptr<Common::DynamicLibrary> m_vulkan_library;
|
|
||||||
|
|
||||||
// Synchronization
|
|
||||||
std::condition_variable_any m_cv;
|
|
||||||
mutable std::mutex m_perf_stats_mutex;
|
|
||||||
mutable std::mutex m_mutex;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
RomMetadata GetRomMetadata(const std::string& path) {
|
||||||
|
if (auto search = m_rom_metadata_cache.find(path); search != m_rom_metadata_cache.end()) {
|
||||||
|
return search->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
return CacheRomMetadata(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
RomMetadata CacheRomMetadata(const std::string& path) {
|
||||||
|
const auto file = Core::GetGameFileFromPath(m_vfs, path);
|
||||||
|
auto loader = Loader::GetLoader(EmulationSession::GetInstance().System(), file, 0, 0);
|
||||||
|
|
||||||
|
RomMetadata entry;
|
||||||
|
loader->ReadTitle(entry.title);
|
||||||
|
loader->ReadIcon(entry.icon);
|
||||||
|
if (loader->GetFileType() == Loader::FileType::NRO) {
|
||||||
|
auto loader_nro = dynamic_cast<Loader::AppLoader_NRO*>(loader.get());
|
||||||
|
entry.isHomebrew = loader_nro->IsHomebrew();
|
||||||
|
} else {
|
||||||
|
entry.isHomebrew = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_rom_metadata_cache[path] = entry;
|
||||||
|
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
static void LoadDiskCacheProgress(VideoCore::LoadCallbackStage stage, int progress, int max) {
|
||||||
|
JNIEnv* env = IDCache::GetEnvForThread();
|
||||||
|
env->CallStaticVoidMethod(IDCache::GetDiskCacheProgressClass(),
|
||||||
|
IDCache::GetDiskCacheLoadProgress(), static_cast<jint>(stage),
|
||||||
|
static_cast<jint>(progress), static_cast<jint>(max));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
static EmulationSession s_instance;
|
||||||
|
|
||||||
|
// Frontend management
|
||||||
|
std::unordered_map<std::string, RomMetadata> m_rom_metadata_cache;
|
||||||
|
|
||||||
|
// Window management
|
||||||
|
std::unique_ptr<EmuWindow_Android> m_window;
|
||||||
|
ANativeWindow* m_native_window{};
|
||||||
|
|
||||||
|
// Core emulation
|
||||||
|
Core::System m_system;
|
||||||
|
InputCommon::InputSubsystem m_input_subsystem;
|
||||||
|
Common::DetachedTasks m_detached_tasks;
|
||||||
|
Core::PerfStatsResults m_perf_stats{};
|
||||||
|
std::shared_ptr<FileSys::RealVfsFilesystem> m_vfs;
|
||||||
|
Core::SystemResultStatus m_load_result{Core::SystemResultStatus::ErrorNotInitialized};
|
||||||
|
bool m_is_running{};
|
||||||
|
SoftwareKeyboard::AndroidKeyboard* m_software_keyboard{};
|
||||||
|
std::unique_ptr<Service::Account::ProfileManager> m_profile_manager;
|
||||||
|
|
||||||
|
// GPU driver parameters
|
||||||
|
std::shared_ptr<Common::DynamicLibrary> m_vulkan_library;
|
||||||
|
|
||||||
|
// Synchronization
|
||||||
|
std::condition_variable_any m_cv;
|
||||||
|
mutable std::mutex m_perf_stats_mutex;
|
||||||
|
mutable std::mutex m_mutex;
|
||||||
|
};
|
||||||
|
|
||||||
/*static*/ EmulationSession EmulationSession::s_instance;
|
/*static*/ EmulationSession EmulationSession::s_instance;
|
||||||
|
|
||||||
} // Anonymous namespace
|
} // Anonymous namespace
|
||||||
|
@ -492,11 +493,11 @@ void Java_org_yuzu_yuzu_1emu_NativeLibrary_setAppDirectory(JNIEnv* env,
|
||||||
}
|
}
|
||||||
|
|
||||||
void JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_initializeGpuDriver(
|
void JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_initializeGpuDriver(
|
||||||
JNIEnv* env, [[maybe_unused]] jclass clazz, jstring hook_lib_dir, jstring custom_driver_dir,
|
JNIEnv* env, [[maybe_unused]] jclass clazz, jstring hook_lib_dir, jstring custom_driver_dir,
|
||||||
jstring custom_driver_name, jstring file_redirect_dir) {
|
jstring custom_driver_name, jstring file_redirect_dir) {
|
||||||
EmulationSession::GetInstance().InitializeGpuDriver(
|
EmulationSession::GetInstance().InitializeGpuDriver(
|
||||||
GetJString(env, hook_lib_dir), GetJString(env, custom_driver_dir),
|
GetJString(env, hook_lib_dir), GetJString(env, custom_driver_dir),
|
||||||
GetJString(env, custom_driver_name), GetJString(env, file_redirect_dir));
|
GetJString(env, custom_driver_name), GetJString(env, file_redirect_dir));
|
||||||
}
|
}
|
||||||
|
|
||||||
jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_reloadKeys(JNIEnv* env,
|
jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_reloadKeys(JNIEnv* env,
|
||||||
|
@ -554,7 +555,7 @@ jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_onGamePadConnectEvent([[maybe_unu
|
||||||
}
|
}
|
||||||
|
|
||||||
jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_onGamePadDisconnectEvent(
|
jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_onGamePadDisconnectEvent(
|
||||||
[[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jint j_device) {
|
[[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jint j_device) {
|
||||||
if (EmulationSession::GetInstance().IsRunning()) {
|
if (EmulationSession::GetInstance().IsRunning()) {
|
||||||
EmulationSession::GetInstance().OnGamepadDisconnectEvent(j_device);
|
EmulationSession::GetInstance().OnGamepadDisconnectEvent(j_device);
|
||||||
}
|
}
|
||||||
|
@ -584,12 +585,12 @@ jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_onGamePadJoystickEvent([[maybe_un
|
||||||
}
|
}
|
||||||
|
|
||||||
jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_onGamePadMotionEvent(
|
jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_onGamePadMotionEvent(
|
||||||
[[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jint j_device,
|
[[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jint j_device,
|
||||||
jlong delta_timestamp, jfloat gyro_x, jfloat gyro_y, jfloat gyro_z, jfloat accel_x,
|
jlong delta_timestamp, jfloat gyro_x, jfloat gyro_y, jfloat gyro_z, jfloat accel_x,
|
||||||
jfloat accel_y, jfloat accel_z) {
|
jfloat accel_y, jfloat accel_z) {
|
||||||
if (EmulationSession::GetInstance().IsRunning()) {
|
if (EmulationSession::GetInstance().IsRunning()) {
|
||||||
EmulationSession::GetInstance().Window().OnGamepadMotionEvent(
|
EmulationSession::GetInstance().Window().OnGamepadMotionEvent(
|
||||||
j_device, delta_timestamp, gyro_x, gyro_y, gyro_z, accel_x, accel_y, accel_z);
|
j_device, delta_timestamp, gyro_x, gyro_y, gyro_z, accel_x, accel_y, accel_z);
|
||||||
}
|
}
|
||||||
return static_cast<jboolean>(true);
|
return static_cast<jboolean>(true);
|
||||||
}
|
}
|
||||||
|
@ -686,7 +687,7 @@ jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_isHomebrew([[maybe_unused]] JNIEn
|
||||||
}
|
}
|
||||||
|
|
||||||
void Java_org_yuzu_yuzu_1emu_NativeLibrary_initializeEmulation
|
void Java_org_yuzu_yuzu_1emu_NativeLibrary_initializeEmulation
|
||||||
[[maybe_unused]] (JNIEnv* env, [[maybe_unused]] jclass clazz) {
|
[[maybe_unused]] (JNIEnv* env, [[maybe_unused]] jclass clazz) {
|
||||||
// Create the default config.ini.
|
// Create the default config.ini.
|
||||||
Config{};
|
Config{};
|
||||||
// Initialize the emulated system.
|
// Initialize the emulated system.
|
||||||
|
@ -699,8 +700,8 @@ jint Java_org_yuzu_yuzu_1emu_NativeLibrary_defaultCPUCore([[maybe_unused]] JNIEn
|
||||||
}
|
}
|
||||||
|
|
||||||
void Java_org_yuzu_yuzu_1emu_NativeLibrary_run__Ljava_lang_String_2Ljava_lang_String_2Z(
|
void Java_org_yuzu_yuzu_1emu_NativeLibrary_run__Ljava_lang_String_2Ljava_lang_String_2Z(
|
||||||
[[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, [[maybe_unused]] jstring j_file,
|
[[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, [[maybe_unused]] jstring j_file,
|
||||||
[[maybe_unused]] jstring j_savestate, [[maybe_unused]] jboolean j_delete_savestate) {}
|
[[maybe_unused]] jstring j_savestate, [[maybe_unused]] jboolean j_delete_savestate) {}
|
||||||
|
|
||||||
void Java_org_yuzu_yuzu_1emu_NativeLibrary_reloadSettings([[maybe_unused]] JNIEnv* env,
|
void Java_org_yuzu_yuzu_1emu_NativeLibrary_reloadSettings([[maybe_unused]] JNIEnv* env,
|
||||||
[[maybe_unused]] jclass clazz) {
|
[[maybe_unused]] jclass clazz) {
|
||||||
|
@ -763,7 +764,7 @@ jdoubleArray Java_org_yuzu_yuzu_1emu_NativeLibrary_getPerfStats([[maybe_unused]]
|
||||||
}
|
}
|
||||||
|
|
||||||
void Java_org_yuzu_yuzu_1emu_utils_DirectoryInitialization_setSysDirectory(
|
void Java_org_yuzu_yuzu_1emu_utils_DirectoryInitialization_setSysDirectory(
|
||||||
[[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jstring j_path) {}
|
[[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jstring j_path) {}
|
||||||
|
|
||||||
void Java_org_yuzu_yuzu_1emu_NativeLibrary_run__Ljava_lang_String_2([[maybe_unused]] JNIEnv* env,
|
void Java_org_yuzu_yuzu_1emu_NativeLibrary_run__Ljava_lang_String_2([[maybe_unused]] JNIEnv* env,
|
||||||
[[maybe_unused]] jclass clazz,
|
[[maybe_unused]] jclass clazz,
|
||||||
|
@ -795,16 +796,11 @@ void Java_org_yuzu_yuzu_1emu_NativeLibrary_submitInlineKeyboardInput(JNIEnv* env
|
||||||
}
|
}
|
||||||
|
|
||||||
void Java_org_yuzu_yuzu_1emu_NativeLibrary_connectToRoom(JNIEnv* env, jclass clazz,
|
void Java_org_yuzu_yuzu_1emu_NativeLibrary_connectToRoom(JNIEnv* env, jclass clazz,
|
||||||
jstring nickname,
|
jstring nickname, jstring server_addr,
|
||||||
jstring server_addr,
|
jint server_port, jstring password) {
|
||||||
jint server_port,
|
EmulationSession::GetInstance().DirectConnectToRoom(GetJString(env, nickname),
|
||||||
jstring password) {
|
GetJString(env, server_addr).c_str(),
|
||||||
EmulationSession::GetInstance().DirectConnectToRoom(
|
server_port, GetJString(env, password));
|
||||||
GetJString(env, nickname),
|
|
||||||
GetJString(env, server_addr).c_str(),
|
|
||||||
server_port,
|
|
||||||
GetJString(env, password)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getRoomMemberState(JNIEnv* env, jclass clazz) {
|
jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getRoomMemberState(JNIEnv* env, jclass clazz) {
|
||||||
|
@ -812,24 +808,24 @@ jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getRoomMemberState(JNIEnv* env, jc
|
||||||
|
|
||||||
std::string state_str{};
|
std::string state_str{};
|
||||||
|
|
||||||
switch(state) {
|
switch (state) {
|
||||||
using State = Network::RoomMember::State;
|
using State = Network::RoomMember::State;
|
||||||
|
|
||||||
case State::Uninitialized:
|
case State::Uninitialized:
|
||||||
state_str = "Uninitialized";
|
state_str = "Uninitialized";
|
||||||
break;
|
break;
|
||||||
case State::Idle:
|
case State::Idle:
|
||||||
state_str = "Idle";
|
state_str = "Idle";
|
||||||
break;
|
break;
|
||||||
case State::Joining:
|
case State::Joining:
|
||||||
state_str = "Joining";
|
state_str = "Joining";
|
||||||
break;
|
break;
|
||||||
case State::Joined:
|
case State::Joined:
|
||||||
state_str = "Joined";
|
state_str = "Joined";
|
||||||
break;
|
break;
|
||||||
case State::Moderator:
|
case State::Moderator:
|
||||||
state_str = "Moderator";
|
state_str = "Moderator";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return env->NewStringUTF(state_str.c_str());
|
return env->NewStringUTF(state_str.c_str());
|
||||||
|
|
|
@ -20,9 +20,9 @@
|
||||||
#include <iphlpapi.h>
|
#include <iphlpapi.h>
|
||||||
#else
|
#else
|
||||||
#include <cerrno>
|
#include <cerrno>
|
||||||
|
#include <arpa/inet.h>
|
||||||
#include <ifaddrs.h>
|
#include <ifaddrs.h>
|
||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
#include <arpa/inet.h>
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -103,18 +103,15 @@ std::vector<NetworkInterface> GetAvailableNetworkInterfaces() {
|
||||||
|
|
||||||
boost::split(route_parts, Settings::values.network_route.GetValue(), boost::is_any_of(";"));
|
boost::split(route_parts, Settings::values.network_route.GetValue(), boost::is_any_of(";"));
|
||||||
|
|
||||||
struct in_addr ip{}, sm{}, gw{};
|
struct in_addr ip {
|
||||||
|
}, sm{}, gw{};
|
||||||
|
|
||||||
inet_pton(AF_INET, route_parts[1].c_str(), &ip);
|
inet_pton(AF_INET, route_parts[1].c_str(), &ip);
|
||||||
inet_pton(AF_INET, route_parts[2].c_str(), &sm);
|
inet_pton(AF_INET, route_parts[2].c_str(), &sm);
|
||||||
inet_pton(AF_INET, route_parts[3].c_str(), &gw);
|
inet_pton(AF_INET, route_parts[3].c_str(), &gw);
|
||||||
|
|
||||||
result.emplace_back(NetworkInterface{
|
result.emplace_back(
|
||||||
.name{route_parts[0]},
|
NetworkInterface{.name{route_parts[0]}, .ip_address{ip}, .subnet_mask{sm}, .gateway{gw}});
|
||||||
.ip_address{ip},
|
|
||||||
.subnet_mask{sm},
|
|
||||||
.gateway{gw}
|
|
||||||
});
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue