diff --git a/CHANGES b/CHANGES index 1333e91c0..118799f87 100644 --- a/CHANGES +++ b/CHANGES @@ -15,6 +15,7 @@ Other fixes: - Qt: Fix crash when switching from high-resolution OpenGL renderer to software - Qt: Fix OpenGL renderer lagging behind when fast-forwarding (fixes mgba.io/i/2094) - Qt: Fix smudged window icon on Windows + - Qt: Fix saving settings enabling camera when camera name changes (fixes mgba.io/i/2125) Misc: - Core: Truncate preloading ROMs that slightly exceed max size (fixes mgba.io/i/2093) - GBA: Default-enable VBA bug compat for Ruby and Emerald ROM hacks diff --git a/src/platform/qt/InputController.cpp b/src/platform/qt/InputController.cpp index e58580138..2e3ba0a9a 100644 --- a/src/platform/qt/InputController.cpp +++ b/src/platform/qt/InputController.cpp @@ -94,23 +94,23 @@ InputController::InputController(int playerId, QWidget* topLevel, QObject* paren InputControllerImage* image = static_cast(context); image->w = w; image->h = h; + image->p->m_cameraActive = true; if (image->image.isNull()) { image->image.load(":/res/no-cam.png"); } #ifdef BUILD_QT_MULTIMEDIA - if (image->p->m_config->getQtOption("cameraDriver").toInt() == static_cast(CameraDriver::QT_MULTIMEDIA)) { - QByteArray camera = image->p->m_config->getQtOption("camera").toByteArray(); - if (!camera.isNull()) { - QMetaObject::invokeMethod(image->p, "setCamera", Q_ARG(QByteArray, camera)); - } - QMetaObject::invokeMethod(image->p, "setupCam"); + QByteArray camera = image->p->m_config->getQtOption("camera").toByteArray(); + if (!camera.isNull()) { + image->p->m_cameraDevice = camera; } + QMetaObject::invokeMethod(image->p, "setupCam"); #endif }; m_image.stopRequestImage = [](mImageSource* context) { InputControllerImage* image = static_cast(context); #ifdef BUILD_QT_MULTIMEDIA + image->p->m_cameraActive = false; QMetaObject::invokeMethod(image->p, "teardownCam"); #endif }; @@ -766,10 +766,18 @@ void InputController::setLuminanceValue(uint8_t value) { void InputController::setupCam() { #ifdef BUILD_QT_MULTIMEDIA + if (m_config->getQtOption("cameraDriver").toInt() != static_cast(CameraDriver::QT_MULTIMEDIA)) { + return; + } + if (!m_camera) { - m_camera = std::make_unique(); + m_camera = std::make_unique(m_cameraDevice); connect(m_camera.get(), &QCamera::statusChanged, this, &InputController::prepareCamSettings, Qt::QueuedConnection); } + if (m_camera->status() == QCamera::UnavailableStatus) { + m_camera.reset(); + return; + } m_camera->setCaptureMode(QCamera::CaptureVideo); m_camera->setViewfinder(&m_videoDumper); m_camera->load(); @@ -820,20 +828,22 @@ void InputController::prepareCamSettings(QCamera::Status status) { void InputController::teardownCam() { #ifdef BUILD_QT_MULTIMEDIA if (m_camera) { - m_camera->stop(); + m_camera->unload(); + m_camera.reset(); } #endif } void InputController::setCamera(const QByteArray& name) { #ifdef BUILD_QT_MULTIMEDIA - bool needsRestart = false; - if (m_camera) { - needsRestart = m_camera->state() == QCamera::ActiveState; + if (m_cameraDevice == name) { + return; } - m_camera = std::make_unique(name); - connect(m_camera.get(), &QCamera::statusChanged, this, &InputController::prepareCamSettings, Qt::QueuedConnection); - if (needsRestart) { + m_cameraDevice = name; + if (m_camera && m_camera->state() == QCamera::ActiveState) { + teardownCam(); + } + if (m_cameraActive) { setupCam(); } #endif diff --git a/src/platform/qt/InputController.h b/src/platform/qt/InputController.h index a056b1b38..93f77091f 100644 --- a/src/platform/qt/InputController.h +++ b/src/platform/qt/InputController.h @@ -158,6 +158,8 @@ private: } m_image; #ifdef BUILD_QT_MULTIMEDIA + bool m_cameraActive = false; + QByteArray m_cameraDevice; std::unique_ptr m_camera; VideoDumper m_videoDumper; #endif diff --git a/src/platform/qt/SettingsView.cpp b/src/platform/qt/SettingsView.cpp index c750efb4e..be100fc07 100644 --- a/src/platform/qt/SettingsView.cpp +++ b/src/platform/qt/SettingsView.cpp @@ -503,9 +503,12 @@ void SettingsView::updateConfig() { } QVariant camera = m_ui.camera->itemData(m_ui.camera->currentIndex()); - if (camera != m_controller->getQtOption("camera")) { + QVariant oldCamera = m_controller->getQtOption("camera"); + if (camera != oldCamera) { m_controller->setQtOption("camera", camera); - emit cameraChanged(camera.toByteArray()); + if (!oldCamera.isNull()) { + emit cameraChanged(camera.toByteArray()); + } } QLocale language = m_ui.languages->itemData(m_ui.languages->currentIndex()).toLocale();