1
0
mirror of https://github.com/RPCS3/rpcs3.git synced 2024-11-22 18:53:28 +01:00

cellCamera: Implement dynamic camera selection

This commit is contained in:
Megamouse 2021-10-21 01:47:59 +02:00
parent 77f6db2543
commit f66b29f043
7 changed files with 161 additions and 72 deletions

View File

@ -244,6 +244,7 @@ struct cfg_root : cfg::node
cfg::_enum<camera_handler> camera{ this, "Camera", camera_handler::null };
cfg::_enum<fake_camera_type> camera_type{ this, "Camera type", fake_camera_type::unknown };
cfg::_enum<camera_flip> camera_flip{ this, "Camera flip", camera_flip::none, true };
cfg::string camera_id{ this, "Camera ID", "Default", true };
cfg::_enum<move_handler> move{ this, "Move", move_handler::null };
cfg::_enum<buzz_handler> buzz{ this, "Buzz emulated controller", buzz_handler::null };
cfg::_enum<turntable_handler> turntable{this, "Turntable emulated controller", turntable_handler::null};

View File

@ -126,6 +126,7 @@ enum class emu_settings_type
Camera,
CameraType,
CameraFlip,
CameraID,
Move,
Buzz,
Turntable,
@ -281,6 +282,7 @@ inline static const QMap<emu_settings_type, cfg_location> settings_location =
{ emu_settings_type::Camera, { "Input/Output", "Camera"}},
{ emu_settings_type::CameraType, { "Input/Output", "Camera type"}},
{ emu_settings_type::CameraFlip, { "Input/Output", "Camera flip"}},
{ emu_settings_type::CameraID, { "Input/Output", "Camera ID"}},
{ emu_settings_type::Move, { "Input/Output", "Move" }},
{ emu_settings_type::Buzz, { "Input/Output", "Buzz emulated controller" }},
{ emu_settings_type::Turntable, { "Input/Output", "Turntable emulated controller" }},

View File

@ -1,6 +1,6 @@
#include "stdafx.h"
#include "qt_camera_handler.h"
#include "Emu/System.h"
#include "Emu/system_config.h"
#include <QMediaService>
#include <QCameraInfo>
@ -21,22 +21,24 @@ qt_camera_handler::~qt_camera_handler()
close_camera();
}
void qt_camera_handler::set_camera(const QCameraInfo& cameraInfo)
void qt_camera_handler::set_camera(const QCameraInfo& camera_info)
{
if (cameraInfo.isNull())
if (camera_info.isNull())
{
camera_log.warning("No camera present");
m_surface.reset();
m_camera.reset();
m_error_handler.reset();
return;
}
// Determine if the camera is front facing, in which case we will need to flip the image horizontally.
const bool front_facing = cameraInfo.position() == QCamera::Position::FrontFace;
const bool front_facing = camera_info.position() == QCamera::Position::FrontFace;
camera_log.success("Using camera: name=\"%s\", description=\"%s\", front_facing=%d", cameraInfo.deviceName().toStdString(), cameraInfo.description().toStdString(), front_facing);
camera_log.success("Using camera: name=\"%s\", description=\"%s\", front_facing=%d", camera_info.deviceName().toStdString(), camera_info.description().toStdString(), front_facing);
// Create camera and video surface
m_surface.reset(new qt_camera_video_surface(front_facing, nullptr));
m_camera.reset(new QCamera(cameraInfo));
m_camera.reset(new QCamera(camera_info));
m_error_handler.reset(new qt_camera_error_handler(m_camera,
[this](QCamera::Status status)
{
@ -72,14 +74,42 @@ void qt_camera_handler::set_camera(const QCameraInfo& cameraInfo)
void qt_camera_handler::open_camera()
{
// Let's use the default camera for now
set_camera(QCameraInfo::defaultCamera());
camera_log.notice("Loading camera");
if (const std::string camera_id = g_cfg.io.camera_id.to_string();
m_camera_id != camera_id)
{
camera_log.notice("Switching camera from %s to %s", camera_id, m_camera_id);
camera_log.notice("Unloading old camera...");
if (m_camera) m_camera->unload();
m_camera_id = camera_id;
}
QCameraInfo selected_camera;
if (m_camera_id == g_cfg.io.camera_id.def)
{
selected_camera = QCameraInfo::defaultCamera();
}
else if (!m_camera_id.empty())
{
const QString camera_id = QString::fromStdString(m_camera_id);
for (const QCameraInfo& camera_info : QCameraInfo::availableCameras())
{
if (camera_id == camera_info.deviceName())
{
selected_camera = camera_info;
break;
}
}
}
set_camera(selected_camera);
if (!m_camera)
{
camera_log.error("No camera found");
if (m_camera_id.empty()) camera_log.notice("Camera disabled");
else camera_log.error("No camera found");
m_state = camera_handler_state::not_available;
return;
}
@ -117,7 +147,8 @@ void qt_camera_handler::close_camera()
if (!m_camera)
{
camera_log.error("No camera found");
if (m_camera_id.empty()) camera_log.notice("Camera disabled");
else camera_log.error("No camera found");
m_state = camera_handler_state::not_available;
return;
}
@ -138,7 +169,8 @@ void qt_camera_handler::start_camera()
if (!m_camera)
{
camera_log.error("No camera found");
if (m_camera_id.empty()) camera_log.notice("Camera disabled");
else camera_log.error("No camera found");
m_state = camera_handler_state::not_available;
return;
}
@ -165,7 +197,8 @@ void qt_camera_handler::stop_camera()
if (!m_camera)
{
camera_log.error("No camera found");
if (m_camera_id.empty()) camera_log.notice("Camera disabled");
else camera_log.error("No camera found");
m_state = camera_handler_state::not_available;
return;
}
@ -222,6 +255,21 @@ camera_handler_base::camera_handler_state qt_camera_handler::get_image(u8* buf,
frame_number = 0;
bytes_read = 0;
if (const std::string camera_id = g_cfg.io.camera_id.to_string();
m_camera_id != camera_id)
{
camera_log.notice("Switching cameras");
m_state = camera_handler_state::not_available;
return camera_handler_state::not_available;
}
if (m_camera_id.empty())
{
camera_log.notice("Camera disabled");
m_state = camera_handler_state::not_available;
return camera_handler_state::not_available;
}
if (!m_camera || !m_surface)
{
camera_log.fatal("Error: camera invalid");

View File

@ -14,7 +14,7 @@ public:
qt_camera_handler();
virtual ~qt_camera_handler();
void set_camera(const QCameraInfo& cameraInfo);
void set_camera(const QCameraInfo& camera_info);
void open_camera() override;
void close_camera() override;
@ -30,6 +30,7 @@ public:
private:
void update_camera_settings();
std::string m_camera_id;
std::shared_ptr<QCamera> m_camera;
std::unique_ptr<qt_camera_video_surface> m_surface;
std::unique_ptr<qt_camera_error_handler> m_error_handler;

View File

@ -1,4 +1,5 @@
#include <QButtonGroup>
#include <QCameraInfo>
#include <QDialogButtonBox>
#include <QFontMetrics>
#include <QPushButton>
@ -958,6 +959,37 @@ settings_dialog::settings_dialog(std::shared_ptr<gui_settings> gui_settings, std
m_emu_settings->EnhanceComboBox(ui->cameraFlipBox, emu_settings_type::CameraFlip);
SubscribeTooltip(ui->gb_camera_flip, tooltips.settings.camera_flip);
{
const std::string default_camera = m_emu_settings->GetSettingDefault(emu_settings_type::CameraID);
const std::string selected_camera = m_emu_settings->GetSetting(emu_settings_type::CameraID);
ui->cameraIdBox->addItem(tr("None", "Camera Device"), "");
ui->cameraIdBox->addItem(tr("Default", "Camera Device"), qstr(default_camera));
for (const QCameraInfo& camera_info : QCameraInfo::availableCameras())
{
if (!camera_info.isNull())
ui->cameraIdBox->addItem(camera_info.description(), camera_info.deviceName());
}
if (const int index = ui->cameraIdBox->findData(qstr(selected_camera)); index >= 0)
{
ui->cameraIdBox->setCurrentIndex(index);
}
else
{
cfg_log.error("The selected camera was not found. Selecting default camera as fallback.");
ui->cameraIdBox->setCurrentIndex(ui->cameraIdBox->findData(qstr(default_camera)));
}
connect(ui->cameraIdBox, QOverload<int>::of(&QComboBox::currentIndexChanged), [this](int index)
{
if (index >= 0) m_emu_settings->SetSetting(emu_settings_type::CameraID, ui->cameraIdBox->itemData(index).toString().toStdString());
});
connect(m_emu_settings.get(), &emu_settings::RestoreDefaultsSignal, [this, default_camera]()
{
m_emu_settings->SetSetting(emu_settings_type::CameraID, default_camera);
ui->cameraIdBox->setCurrentIndex(ui->cameraIdBox->findData(qstr(default_camera)));
});
SubscribeTooltip(ui->gb_camera_id, tooltips.settings.camera_id);
}
m_emu_settings->EnhanceComboBox(ui->moveBox, emu_settings_type::Move);
SubscribeTooltip(ui->gb_move_handler, tooltips.settings.move);
@ -1134,7 +1166,7 @@ settings_dialog::settings_dialog(std::shared_ptr<gui_settings> gui_settings, std
SnapSlider(ui->clockScale, 10);
ui->clockScale->setPageStep(50);
const int clocks_scale_def = stoi(m_emu_settings->GetSettingDefault(emu_settings_type::ClocksScale));
connect(ui->clockScaleReset, &QAbstractButton::clicked, [=, this]()
connect(ui->clockScaleReset, &QAbstractButton::clicked, [clocks_scale_def, this]()
{
ui->clockScale->setValue(clocks_scale_def);
});

View File

@ -1412,10 +1412,10 @@
<attribute name="title">
<string>I/O</string>
</attribute>
<layout class="QVBoxLayout" name="inputTab_layout" stretch="0,0,0,1,0">
<layout class="QVBoxLayout" name="inputTab_layout">
<item>
<layout class="QHBoxLayout" name="inputTabLayout1" stretch="1,1,1">
<item>
<layout class="QGridLayout" name="ioGridLayout">
<item row="0" column="0">
<widget class="QGroupBox" name="gb_keyboard_handler">
<property name="title">
<string>Keyboard Handler</string>
@ -1427,35 +1427,7 @@
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="gb_camera_type">
<property name="title">
<string>Camera Input</string>
</property>
<layout class="QVBoxLayout" name="gb_camera_type_layout">
<item>
<widget class="QComboBox" name="cameraTypeBox"/>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="gb_move_handler">
<property name="title">
<string>Move Handler</string>
</property>
<layout class="QVBoxLayout" name="gb_move_handler_layout">
<item>
<widget class="QComboBox" name="moveBox"/>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="inputTabLayout2" stretch="1,1,1">
<item>
<item row="1" column="0">
<widget class="QGroupBox" name="gb_mouse_handler">
<property name="title">
<string>Mouse Handler</string>
@ -1467,19 +1439,7 @@
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="gb_camera_setting">
<property name="title">
<string>Camera Settings</string>
</property>
<layout class="QVBoxLayout" name="gb_camera_setting_layout">
<item>
<widget class="QComboBox" name="cameraBox"/>
</item>
</layout>
</widget>
</item>
<item>
<item row="0" column="2">
<widget class="QGroupBox" name="gb_buzz_emulated">
<property name="title">
<string>Buzz! emulated controller</string>
@ -1491,11 +1451,7 @@
</layout>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="inputTabLayout3">
<item>
<item row="1" column="2">
<widget class="QGroupBox" name="gb_turntable_emulated">
<property name="title">
<string>DJ Hero emulated turntable</string>
@ -1507,7 +1463,43 @@
</layout>
</widget>
</item>
<item>
<item row="0" column="1">
<widget class="QGroupBox" name="gb_camera_type">
<property name="title">
<string>Camera Input</string>
</property>
<layout class="QVBoxLayout" name="gb_camera_type_layout">
<item>
<widget class="QComboBox" name="cameraTypeBox"/>
</item>
</layout>
</widget>
</item>
<item row="1" column="1">
<widget class="QGroupBox" name="gb_camera_flip">
<property name="title">
<string>Camera Flip</string>
</property>
<layout class="QVBoxLayout" name="gb_camera_flip_layout">
<item>
<widget class="QComboBox" name="cameraFlipBox"/>
</item>
</layout>
</widget>
</item>
<item row="2" column="1">
<widget class="QGroupBox" name="gb_camera_setting">
<property name="title">
<string>Camera Handler</string>
</property>
<layout class="QVBoxLayout" name="gb_camera_setting_layout">
<item>
<widget class="QComboBox" name="cameraBox"/>
</item>
</layout>
</widget>
</item>
<item row="2" column="2">
<widget class="QGroupBox" name="gb_ghltar_emulated">
<property name="title">
<string>Guitar Hero Live emulated guitar</string>
@ -1519,14 +1511,26 @@
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="gb_camera_flip">
<item row="2" column="0">
<widget class="QGroupBox" name="gb_move_handler">
<property name="title">
<string>Camera Flip</string>
<string>Move Handler</string>
</property>
<layout class="QVBoxLayout" name="gb_camera_flip_layout">
<layout class="QVBoxLayout" name="gb_move_handler_layout">
<item>
<widget class="QComboBox" name="cameraFlipBox"/>
<widget class="QComboBox" name="moveBox"/>
</item>
</layout>
</widget>
</item>
<item row="2" column="2">
<widget class="QGroupBox" name="gb_camera_id">
<property name="title">
<string>Camera</string>
</property>
<layout class="QVBoxLayout" name="camera_id_layout">
<item>
<widget class="QComboBox" name="cameraIdBox"/>
</item>
</layout>
</widget>

View File

@ -195,6 +195,7 @@ public:
const QString camera = tr("Select Qt Camera to use the default camera device of your operating system.");
const QString camera_type = tr("Depending on the game, you may need to select a specific camera type.");
const QString camera_flip = tr("Flips the camera image either horizontally, vertically, or on both axis.");
const QString camera_id = tr("Select the camera that you want to use during gameplay.");
const QString move = tr("PlayStation Move support.\nFake: Experimental! This maps Move controls to DS3 controller mappings.\nMouse: Emulate PSMove with Mouse handler.");
const QString buzz = tr("Buzz! support.\nSelect 1 or 2 controllers if the game requires Buzz! controllers and you don't have real controllers.\nSelect Null if the game has support for DualShock or if you have real Buzz! controllers.");
const QString turntable = tr("DJ Hero Turntable controller support.\nSelect 1 or 2 controllers if the game requires DJ Hero Turntable controllers and you don't have real turntable controllers.\nSelect Null if the game has support for DualShock or if you have real turntable controllers.\nA real turntable controller can be used at the same time as an emulated turntable controller.");