rpcsx/rpcs3/main_application.cpp

202 lines
6.1 KiB
C++
Raw Normal View History

2020-12-05 13:08:24 +01:00
#include "main_application.h"
2019-06-18 04:02:06 +02:00
#include "util/types.hpp"
#include "util/logs.hpp"
2021-04-10 11:54:52 +02:00
#include "util/sysinfo.hpp"
2021-09-07 21:56:49 +02:00
#include "Utilities/Thread.h"
#include "Input/pad_thread.h"
#include "Emu/System.h"
#include "Emu/system_config.h"
#include "Emu/IdManager.h"
2019-06-18 04:02:06 +02:00
#include "Emu/Io/Null/NullKeyboardHandler.h"
#include "Emu/Io/Null/NullMouseHandler.h"
#include "Emu/Io/KeyboardHandler.h"
#include "Emu/Io/MouseHandler.h"
#include "Input/basic_keyboard_handler.h"
#include "Input/basic_mouse_handler.h"
2019-06-18 04:02:06 +02:00
#include "Emu/Audio/AudioBackend.h"
#include "Emu/Audio/Null/NullAudioBackend.h"
#include "Emu/Audio/Null/null_enumerator.h"
#include "Emu/Audio/Cubeb/CubebBackend.h"
#include "Emu/Audio/Cubeb/cubeb_enumerator.h"
2019-06-18 04:02:06 +02:00
#ifdef _WIN32
#include "Emu/Audio/XAudio2/XAudio2Backend.h"
#include "Emu/Audio/XAudio2/xaudio2_enumerator.h"
2019-06-18 04:02:06 +02:00
#endif
2019-10-24 21:26:29 +02:00
#ifdef HAVE_FAUDIO
#include "Emu/Audio/FAudio/FAudioBackend.h"
#include "Emu/Audio/FAudio/faudio_enumerator.h"
2019-10-24 21:26:29 +02:00
#endif
2019-06-18 04:02:06 +02:00
#include <QFileInfo> // This shouldn't be outside rpcs3qt...
#include <QImageReader> // This shouldn't be outside rpcs3qt...
#include <thread>
LOG_CHANNEL(sys_log, "SYS");
2021-04-02 00:54:32 +02:00
/** Emu.Init() wrapper for user management */
void main_application::InitializeEmulator(const std::string& user, bool show_gui)
2019-06-18 04:02:06 +02:00
{
Emu.SetHasGui(show_gui);
2021-04-02 00:54:32 +02:00
Emu.SetUsr(user);
Emu.Init();
2021-04-10 11:54:52 +02:00
// Log Firmware Version after Emu was initialized
const std::string firmware_version = utils::get_firmware_version();
const std::string firmware_string = firmware_version.empty() ? "Missing Firmware" : ("Firmware version: " + firmware_version);
sys_log.always()("%s", firmware_string);
2019-06-18 04:02:06 +02:00
}
/** RPCS3 emulator has functions it desires to call from the GUI at times. Initialize them in here. */
EmuCallbacks main_application::CreateCallbacks()
{
EmuCallbacks callbacks;
callbacks.init_kb_handler = [this]()
2019-06-18 04:02:06 +02:00
{
2021-04-07 23:05:18 +02:00
switch (g_cfg.io.keyboard.get())
2019-06-18 04:02:06 +02:00
{
case keyboard_handler::null:
{
g_fxo->init<KeyboardHandlerBase, NullKeyboardHandler>(Emu.DeserialManager());
break;
}
2019-06-18 04:02:06 +02:00
case keyboard_handler::basic:
{
basic_keyboard_handler* ret = g_fxo->init<KeyboardHandlerBase, basic_keyboard_handler>(Emu.DeserialManager());
2019-06-18 04:02:06 +02:00
ret->moveToThread(get_thread());
ret->SetTargetWindow(m_game_window);
break;
2019-06-18 04:02:06 +02:00
}
}
};
callbacks.init_mouse_handler = [this]()
2019-06-18 04:02:06 +02:00
{
2021-04-07 23:05:18 +02:00
switch (g_cfg.io.mouse.get())
2019-06-18 04:02:06 +02:00
{
case mouse_handler::null:
{
if (g_cfg.io.move == move_handler::mouse)
{
basic_mouse_handler* ret = g_fxo->init<MouseHandlerBase, basic_mouse_handler>(Emu.DeserialManager());
ret->moveToThread(get_thread());
ret->SetTargetWindow(m_game_window);
}
else
2022-07-06 14:35:50 +02:00
{
g_fxo->init<MouseHandlerBase, NullMouseHandler>(Emu.DeserialManager());
2022-07-06 14:35:50 +02:00
}
break;
}
2019-06-18 04:02:06 +02:00
case mouse_handler::basic:
{
basic_mouse_handler* ret = g_fxo->init<MouseHandlerBase, basic_mouse_handler>(Emu.DeserialManager());
2019-06-18 04:02:06 +02:00
ret->moveToThread(get_thread());
ret->SetTargetWindow(m_game_window);
break;
2019-06-18 04:02:06 +02:00
}
}
};
2019-09-18 01:44:06 +02:00
callbacks.init_pad_handler = [this](std::string_view title_id)
2019-06-18 04:02:06 +02:00
{
ensure(g_fxo->init<named_thread<pad_thread>>(get_thread(), m_game_window, title_id));
while (pad::g_reset) std::this_thread::yield();
2019-06-18 04:02:06 +02:00
};
callbacks.get_audio = []() -> std::shared_ptr<AudioBackend>
{
std::shared_ptr<AudioBackend> result;
2021-04-07 23:05:18 +02:00
switch (g_cfg.audio.renderer.get())
2019-06-18 04:02:06 +02:00
{
case audio_renderer::null: result = std::make_shared<NullAudioBackend>(); break;
2019-06-18 04:02:06 +02:00
#ifdef _WIN32
case audio_renderer::xaudio: result = std::make_shared<XAudio2Backend>(); break;
2019-06-18 04:02:06 +02:00
#endif
case audio_renderer::cubeb: result = std::make_shared<CubebBackend>(); break;
2019-10-24 21:26:29 +02:00
#ifdef HAVE_FAUDIO
case audio_renderer::faudio: result = std::make_shared<FAudioBackend>(); break;
2019-10-24 21:26:29 +02:00
#endif
2019-06-18 04:02:06 +02:00
}
if (!result->Initialized())
{
// Fall back to a null backend if something went wrong
sys_log.error("Audio renderer %s could not be initialized, using a Null renderer instead. Make sure that no other application is running that might block audio access (e.g. Netflix).", result->GetName());
result = std::make_shared<NullAudioBackend>();
}
return result;
2019-06-18 04:02:06 +02:00
};
callbacks.get_audio_enumerator = [](u64 renderer) -> std::shared_ptr<audio_device_enumerator>
{
switch (static_cast<audio_renderer>(renderer))
{
case audio_renderer::null: return std::make_shared<null_enumerator>();
#ifdef _WIN32
case audio_renderer::xaudio: return std::make_shared<xaudio2_enumerator>();
#endif
case audio_renderer::cubeb: return std::make_shared<cubeb_enumerator>();
#ifdef HAVE_FAUDIO
case audio_renderer::faudio: return std::make_shared<faudio_enumerator>();
#endif
default: fmt::throw_exception("Invalid renderer index %u", renderer);
}
};
callbacks.get_image_info = [](const std::string& filename, std::string& sub_type, s32& width, s32& height, s32& orientation) -> bool
{
sub_type.clear();
width = 0;
height = 0;
orientation = 0; // CELL_SEARCH_ORIENTATION_UNKNOWN
bool success = false;
Emu.BlockingCallFromMainThread([&]()
{
const QImageReader reader(QString::fromStdString(filename));
if (reader.canRead())
{
const QSize size = reader.size();
width = size.width();
height = size.height();
sub_type = reader.subType().toStdString();
switch (reader.transformation())
{
case QImageIOHandler::Transformation::TransformationNone:
orientation = 1; // CELL_SEARCH_ORIENTATION_TOP_LEFT = 0°
break;
case QImageIOHandler::Transformation::TransformationRotate90:
orientation = 2; // CELL_SEARCH_ORIENTATION_TOP_RIGHT = 90°
break;
case QImageIOHandler::Transformation::TransformationRotate180:
orientation = 3; // CELL_SEARCH_ORIENTATION_BOTTOM_RIGHT = 180°
break;
case QImageIOHandler::Transformation::TransformationRotate270:
orientation = 4; // CELL_SEARCH_ORIENTATION_BOTTOM_LEFT = 270°
break;
default:
// Ignore other transformations for now
break;
}
success = true;
sys_log.notice("get_image_info found image: filename='%s', sub_type='%s', width=%d, height=%d, orientation=%d", filename, sub_type, width, height, orientation);
}
});
return success;
};
callbacks.resolve_path = [](std::string_view sv)
{
return QFileInfo(QString::fromUtf8(sv.data(), static_cast<int>(sv.size()))).canonicalFilePath().toStdString();
};
2019-06-18 04:02:06 +02:00
return callbacks;
}