diff --git a/command.c b/command.c index 18ca322b53..4ccc4f5f6f 100644 --- a/command.c +++ b/command.c @@ -1336,8 +1336,8 @@ static void command_event_restore_default_shader_preset(void) static void command_event_restore_remaps(void) { - if (rarch_ctl(RARCH_CTL_IS_REMAPS_CORE_ACTIVE, NULL) || - rarch_ctl(RARCH_CTL_IS_REMAPS_CONTENT_DIR_ACTIVE, NULL) || + if (rarch_ctl(RARCH_CTL_IS_REMAPS_CORE_ACTIVE, NULL) || + rarch_ctl(RARCH_CTL_IS_REMAPS_CONTENT_DIR_ACTIVE, NULL) || rarch_ctl(RARCH_CTL_IS_REMAPS_GAME_ACTIVE, NULL)) input_remapping_set_defaults(true); } @@ -2441,10 +2441,14 @@ TODO: Add a setting for these tweaks */ if (!command_event_save_core_config()) return false; break; + case CMD_EVENT_SHADER_PRESET_LOADED: + ui_companion_event_command(cmd); + break; case CMD_EVENT_SHADERS_APPLY_CHANGES: #ifdef HAVE_MENU menu_shader_manager_apply_changes(); #endif + ui_companion_event_command(cmd); break; case CMD_EVENT_PAUSE_CHECKS: { diff --git a/command.h b/command.h index 6b50d6f3eb..1a7e84fac7 100644 --- a/command.h +++ b/command.h @@ -158,6 +158,8 @@ enum event_command CMD_EVENT_MENU_REFRESH, /* Applies shader changes. */ CMD_EVENT_SHADERS_APPLY_CHANGES, + /* A new shader preset has been loaded */ + CMD_EVENT_SHADER_PRESET_LOADED, /* Initializes shader directory. */ CMD_EVENT_SHADER_DIR_INIT, /* Deinitializes shader directory. */ diff --git a/gfx/video_driver.c b/gfx/video_driver.c index 3a38c46eed..3fa843eefa 100644 --- a/gfx/video_driver.c +++ b/gfx/video_driver.c @@ -1641,7 +1641,7 @@ bool video_driver_is_stub_frame(void) bool video_driver_supports_recording(void) { settings_t *settings = config_get_ptr(); - return settings->bools.video_gpu_record + return settings->bools.video_gpu_record && current_video->read_viewport; } @@ -1668,7 +1668,7 @@ void video_driver_set_viewport_config(void) { struct retro_game_geometry *geom = &video_driver_av_info.geometry; - if (geom->aspect_ratio > 0.0f && + if (geom->aspect_ratio > 0.0f && settings->bools.video_aspect_ratio_auto) aspectratio_lut[ASPECT_RATIO_CONFIG].value = geom->aspect_ratio; else @@ -1898,7 +1898,7 @@ void video_driver_update_viewport(struct video_viewport* vp, bool force_full, bo } else if (device_aspect > desired_aspect) { - delta = (desired_aspect / device_aspect - 1.0f) + delta = (desired_aspect / device_aspect - 1.0f) / 2.0f + 0.5f; vp->x = (int)roundf(vp->full_width * (0.5f - delta)); vp->width = (unsigned)roundf(2.0f * vp->full_width * delta); @@ -1909,7 +1909,7 @@ void video_driver_update_viewport(struct video_viewport* vp, bool force_full, bo { vp->x = 0; vp->width = vp->full_width; - delta = (device_aspect / desired_aspect - 1.0f) + delta = (device_aspect / desired_aspect - 1.0f) / 2.0f + 0.5f; vp->y = (int)roundf(vp->full_height * (0.5f - delta)); vp->height = (unsigned)roundf(2.0f * vp->full_height * delta); @@ -2324,7 +2324,7 @@ void video_viewport_get_scaled_integer(struct video_viewport *vp, unsigned base_width; /* Use system reported sizes as these define the * geometry for the "normal" case. */ - unsigned base_height = + unsigned base_height = video_driver_av_info.geometry.base_height; if (base_height == 0) @@ -2631,9 +2631,9 @@ void video_driver_frame(const void *data, unsigned width, /* Display the FPS, with a higher priority. */ if (video_info.fps_show) runloop_msg_queue_push(video_info.fps_text, 2, 1, true); - - /* trigger set resolution*/ - if (video_info.crt_switch_resolution) + + /* trigger set resolution*/ + if (video_info.crt_switch_resolution) { video_driver_crt_switching_active = true; @@ -2646,9 +2646,9 @@ void video_driver_frame(const void *data, unsigned width, crt_switch_res_core(width, height, video_driver_core_hz); } else if (!video_info.crt_switch_resolution) - video_driver_crt_switching_active = false; - - /* trigger set resolution*/ + video_driver_crt_switching_active = false; + + /* trigger set resolution*/ } void video_driver_display_type_set(enum rarch_display_type type) @@ -2741,8 +2741,8 @@ void video_driver_build_info(video_frame_info_t *video_info) settings = config_get_ptr(); custom_vp = &settings->video_viewport_custom; video_info->refresh_rate = settings->floats.video_refresh_rate; - video_info->crt_switch_resolution = settings->bools.crt_switch_resolution; - video_info->crt_switch_resolution_super = settings->uints.crt_switch_resolution_super; + video_info->crt_switch_resolution = settings->bools.crt_switch_resolution; + video_info->crt_switch_resolution_super = settings->uints.crt_switch_resolution_super; video_info->black_frame_insertion = settings->bools.video_black_frame_insertion; video_info->hard_sync = settings->bools.video_hard_sync; video_info->hard_sync_frames = settings->uints.video_hard_sync_frames; @@ -2873,13 +2873,13 @@ bool video_driver_translate_coord_viewport( return false; if (mouse_x >= 0 && mouse_x <= norm_full_vp_width) - scaled_screen_x = ((2 * mouse_x * 0x7fff) + scaled_screen_x = ((2 * mouse_x * 0x7fff) / norm_full_vp_width) - 0x7fff; else scaled_screen_x = -0x8000; /* OOB */ if (mouse_y >= 0 && mouse_y <= norm_full_vp_height) - scaled_screen_y = ((2 * mouse_y * 0x7fff) + scaled_screen_y = ((2 * mouse_y * 0x7fff) / norm_full_vp_height) - 0x7fff; else scaled_screen_y = -0x8000; /* OOB */ @@ -2888,13 +2888,13 @@ bool video_driver_translate_coord_viewport( mouse_y -= vp->y; if (mouse_x >= 0 && mouse_x <= norm_vp_width) - scaled_x = ((2 * mouse_x * 0x7fff) + scaled_x = ((2 * mouse_x * 0x7fff) / norm_vp_width) - 0x7fff; else scaled_x = -0x8000; /* OOB */ if (mouse_y >= 0 && mouse_y <= norm_vp_height) - scaled_y = ((2 * mouse_y * 0x7fff) + scaled_y = ((2 * mouse_y * 0x7fff) / norm_vp_height) - 0x7fff; else scaled_y = -0x8000; /* OOB */ @@ -2920,7 +2920,7 @@ void video_driver_get_status(uint64_t *frame_count, bool * is_alive, bool *is_focused) { *frame_count = video_driver_frame_count; - *is_alive = current_video ? + *is_alive = current_video ? current_video->alive(video_driver_data) : true; *is_focused = video_driver_cb_has_focus(); } @@ -3002,7 +3002,7 @@ bool video_context_driver_find_next_driver(void) * * Initialize graphics context driver. * - * Returns: graphics context driver if successfully initialized, + * Returns: graphics context driver if successfully initialized, * otherwise NULL. **/ static const gfx_ctx_driver_t *video_context_driver_init( @@ -3238,7 +3238,7 @@ bool video_context_driver_get_refresh_rate(float *refresh_rate) return false; if (refresh_rate) - *refresh_rate = + *refresh_rate = current_video_context.get_refresh_rate(video_context_data); return true; @@ -3247,7 +3247,7 @@ bool video_context_driver_get_refresh_rate(float *refresh_rate) bool video_context_driver_input_driver(gfx_ctx_input_t *inp) { settings_t *settings = config_get_ptr(); - const char *joypad_name = settings ? + const char *joypad_name = settings ? settings->arrays.input_joypad_driver : NULL; if (!current_video_context.input_driver) @@ -3518,6 +3518,9 @@ bool video_shader_driver_get_current_shader(video_shader_ctx_t *shader) bool video_shader_driver_direct_get_current_shader( video_shader_ctx_t *shader) { + if (!current_shader) + return false; + shader->data = current_shader->get_current_shader(current_shader_data); return true; diff --git a/gfx/video_shader_parse.c b/gfx/video_shader_parse.c index 001f8ba055..005a9d64fb 100644 --- a/gfx/video_shader_parse.c +++ b/gfx/video_shader_parse.c @@ -35,6 +35,7 @@ #include "../verbosity.h" #include "../configuration.h" #include "../frontend/frontend_driver.h" +#include "../command.h" #include "video_driver.h" #include "video_shader_parse.h" @@ -785,6 +786,8 @@ bool video_shader_read_conf_cgp(config_file_t *conf, string_list_free(file_list); } + command_event(CMD_EVENT_SHADER_PRESET_LOADED, NULL); + if (!video_shader_parse_textures(conf, shader)) return false; diff --git a/griffin/griffin_cpp.cpp b/griffin/griffin_cpp.cpp index 970ac5cffe..17aae41d3d 100644 --- a/griffin/griffin_cpp.cpp +++ b/griffin/griffin_cpp.cpp @@ -41,6 +41,7 @@ UI #include "../ui/drivers/qt/ui_qt_browser_window.cpp" #include "../ui/drivers/qt/ui_qt_msg_window.cpp" #include "../ui/drivers/qt/ui_qt_application.cpp" +#include "../ui/drivers/qt/flowlayout.cpp" #endif /*============================================================ diff --git a/ui/drivers/qt/ui_qt_window.cpp b/ui/drivers/qt/ui_qt_window.cpp index 0cd1a7b4ce..6c2b63156a 100644 --- a/ui/drivers/qt/ui_qt_window.cpp +++ b/ui/drivers/qt/ui_qt_window.cpp @@ -203,6 +203,22 @@ static void setElidedText(QLabel *label, QWidget *clipWidget, int padding, const const QPixmap getInvader(); +ShaderParamsDialog::ShaderParamsDialog(QWidget *parent) : + QDialog(parent) +{ +} + +ShaderParamsDialog::~ShaderParamsDialog() +{ +} + +void ShaderParamsDialog::closeEvent(QCloseEvent *event) +{ + QDialog::closeEvent(event); + + emit closed(); +} + GridItem::GridItem() : QObject() ,widget(NULL) @@ -928,7 +944,7 @@ MainWindow::MainWindow(QWidget *parent) : ,m_allPlaylistsGridMaxCount(0) ,m_playlistEntryDialog(NULL) ,m_statusMessageElapsedTimer() - ,m_shaderParamsDialog(NULL) + ,m_shaderParamsDialog() ,m_networkManager(new QNetworkAccessManager(this)) ,m_updateProgressDialog(new QProgressDialog()) ,m_updateFile() @@ -1152,7 +1168,10 @@ MainWindow::MainWindow(QWidget *parent) : /* make sure these use an auto connection so it will be queued if called from a different thread (some facilities in RA log messages from other threads) */ connect(this, SIGNAL(gotLogMessage(const QString&)), this, SLOT(onGotLogMessage(const QString&)), Qt::AutoConnection); connect(this, SIGNAL(gotStatusMessage(QString,unsigned,unsigned,bool)), this, SLOT(onGotStatusMessage(QString,unsigned,unsigned,bool)), Qt::AutoConnection); - connect(this, SIGNAL(gotReloadPlaylists()), this, SLOT(onGotReloadPlaylists())); + connect(this, SIGNAL(gotReloadPlaylists()), this, SLOT(onGotReloadPlaylists()), Qt::AutoConnection); + connect(this, SIGNAL(gotReloadShaderParams()), this, SLOT(onGotReloadShaderParams()), Qt::AutoConnection); + + /* these are always queued */ connect(this, SIGNAL(showErrorMessageDeferred(QString)), this, SLOT(onShowErrorMessage(QString)), Qt::QueuedConnection); connect(this, SIGNAL(extractArchiveDeferred(QString)), this, SLOT(onExtractArchive(QString)), Qt::QueuedConnection); @@ -1218,9 +1237,11 @@ void MainWindow::removeUpdateTempFiles() void MainWindow::onShaderParamsClicked() { - QFormLayout *form = new QFormLayout(); video_shader_ctx_t shader_info; unsigned i; + int last_pass = -1; + QFormLayout *last_form = NULL; + QGroupBox *last_group = NULL; video_shader_driver_get_current_shader(&shader_info); @@ -1231,77 +1252,109 @@ void MainWindow::onShaderParamsClicked() if (m_shaderParamsDialog) delete m_shaderParamsDialog; - m_shaderParamsDialog = new QDialog(); - m_shaderParamsDialog->setLayout(form); + m_shaderParamsDialog = new ShaderParamsDialog(); + m_shaderParamsDialog->setLayout(new QVBoxLayout()); m_shaderParamsDialog->setWindowTitle(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PARAMETERS)); - for (i = 0; i < shader_info.data->num_parameters; i++) + connect(m_shaderParamsDialog, SIGNAL(closed()), m_shaderParamsDialog, SLOT(deleteLater())); + + if (shader_info.data->num_parameters == 0) { - struct video_shader_parameter *param = &shader_info.data->parameters[i]; - QString desc = param->desc; + QLabel *label = new QLabel(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NO_SHADER_PARAMETERS), m_shaderParamsDialog); + label->setAlignment(Qt::AlignCenter); - if ((param->minimum == 0.0) - && (param->maximum - == (param->minimum - + param->step))) + m_shaderParamsDialog->layout()->addWidget(label); + } + else + { + /* NOTE: We assume that parameters are always grouped in order by the pass number, e.g., all parameters for pass 0 come first, then params for pass 1, etc. */ + for (i = 0; i < shader_info.data->num_parameters; i++) { - /* option is basically a bool, so use a checkbox */ - QCheckBox *checkBox = new QCheckBox(m_shaderParamsDialog); - checkBox->setChecked(param->current == param->maximum ? true : false); - checkBox->setProperty("param", QVariant::fromValue(param)); + struct video_shader_parameter *param = &shader_info.data->parameters[i]; + QString desc = param->desc; + QFormLayout *form = last_form; - connect(checkBox, SIGNAL(clicked()), this, SLOT(onShaderParamCheckBoxClicked())); - - form->addRow(desc, checkBox); - } - else - { - QDoubleSpinBox *doubleSpinBox = NULL; - QSpinBox *spinBox = NULL; - QHBoxLayout *box = new QHBoxLayout(); - QSlider *slider = new QSlider(Qt::Horizontal, m_shaderParamsDialog); - double value = lerp(param->minimum, param->maximum, 0, 100, param->current); - double intpart = 0; - bool stepIsFractional = modf(param->step, &intpart); - - slider->setRange(0, 100); - slider->setSingleStep(1); - slider->setValue(value); - slider->setProperty("param", QVariant::fromValue(param)); - - connect(slider, SIGNAL(valueChanged(int)), this, SLOT(onShaderParamSliderValueChanged(int))); - - box->addWidget(slider); - - if (stepIsFractional) + if (param->pass > last_pass) { - doubleSpinBox = new QDoubleSpinBox(m_shaderParamsDialog); - doubleSpinBox->setRange(param->minimum, param->maximum); - doubleSpinBox->setSingleStep(param->step); - doubleSpinBox->setValue(param->current); - doubleSpinBox->setProperty("slider", QVariant::fromValue(slider)); - slider->setProperty("doubleSpinBox", QVariant::fromValue(doubleSpinBox)); + QGroupBox *groupBox = NULL; + QFileInfo fileInfo(shader_info.data->pass[param->pass].source.path); + QString shaderBasename = fileInfo.completeBaseName(); - connect(doubleSpinBox, SIGNAL(valueChanged(double)), this, SLOT(onShaderParamDoubleSpinBoxValueChanged(double))); + form = new QFormLayout(); + groupBox = new QGroupBox(shaderBasename); + groupBox->setLayout(form); - box->addWidget(doubleSpinBox); + m_shaderParamsDialog->layout()->addWidget(groupBox); + + last_form = form; + last_pass = param->pass; + } + + if ((param->minimum == 0.0) + && (param->maximum + == (param->minimum + + param->step))) + { + /* option is basically a bool, so use a checkbox */ + QCheckBox *checkBox = new QCheckBox(m_shaderParamsDialog); + checkBox->setChecked(param->current == param->maximum ? true : false); + checkBox->setProperty("param", QVariant::fromValue(param)); + + connect(checkBox, SIGNAL(clicked()), this, SLOT(onShaderParamCheckBoxClicked())); + + form->addRow(desc, checkBox); } else { - spinBox = new QSpinBox(m_shaderParamsDialog); - spinBox->setRange(param->minimum, param->maximum); - spinBox->setSingleStep(param->step); - spinBox->setValue(param->current); - spinBox->setProperty("slider", QVariant::fromValue(slider)); - slider->setProperty("spinBox", QVariant::fromValue(spinBox)); + QDoubleSpinBox *doubleSpinBox = NULL; + QSpinBox *spinBox = NULL; + QHBoxLayout *box = new QHBoxLayout(); + QSlider *slider = new QSlider(Qt::Horizontal, m_shaderParamsDialog); + double value = lerp(param->minimum, param->maximum, 0, 100, param->current); + double intpart = 0; + bool stepIsFractional = modf(param->step, &intpart); - connect(spinBox, SIGNAL(valueChanged(int)), this, SLOT(onShaderParamSpinBoxValueChanged(int))); + slider->setRange(0, 100); + slider->setSingleStep(1); + slider->setValue(value); + slider->setProperty("param", QVariant::fromValue(param)); - box->addWidget(spinBox); + connect(slider, SIGNAL(valueChanged(int)), this, SLOT(onShaderParamSliderValueChanged(int))); + + box->addWidget(slider); + + if (stepIsFractional) + { + doubleSpinBox = new QDoubleSpinBox(m_shaderParamsDialog); + doubleSpinBox->setRange(param->minimum, param->maximum); + doubleSpinBox->setSingleStep(param->step); + doubleSpinBox->setValue(param->current); + doubleSpinBox->setProperty("slider", QVariant::fromValue(slider)); + slider->setProperty("doubleSpinBox", QVariant::fromValue(doubleSpinBox)); + + connect(doubleSpinBox, SIGNAL(valueChanged(double)), this, SLOT(onShaderParamDoubleSpinBoxValueChanged(double))); + + box->addWidget(doubleSpinBox); + } + else + { + spinBox = new QSpinBox(m_shaderParamsDialog); + spinBox->setRange(param->minimum, param->maximum); + spinBox->setSingleStep(param->step); + spinBox->setValue(param->current); + spinBox->setProperty("slider", QVariant::fromValue(slider)); + slider->setProperty("spinBox", QVariant::fromValue(spinBox)); + + connect(spinBox, SIGNAL(valueChanged(int)), this, SLOT(onShaderParamSpinBoxValueChanged(int))); + + box->addWidget(spinBox); + } + + form->addRow(desc, box); } - - form->addRow(desc, box); } + + m_shaderParamsDialog->layout()->addItem(new QSpacerItem(20, 20, QSizePolicy::Minimum, QSizePolicy::Expanding)); } m_shaderParamsDialog->resize(720, 480); @@ -2456,6 +2509,17 @@ void MainWindow::onGotStatusMessage(QString msg, unsigned priority, unsigned dur } } +void MainWindow::deferReloadShaderParams() +{ + emit gotReloadShaderParams(); +} + +void MainWindow::onGotReloadShaderParams() +{ + if (m_shaderParamsDialog && m_shaderParamsDialog->isVisible()) + onShaderParamsClicked(); +} + void MainWindow::deferReloadPlaylists() { emit gotReloadPlaylists(); diff --git a/ui/drivers/ui_qt.cpp b/ui/drivers/ui_qt.cpp index 7fcace03e0..4e679cfeae 100644 --- a/ui/drivers/ui_qt.cpp +++ b/ui/drivers/ui_qt.cpp @@ -623,11 +623,23 @@ static void ui_companion_qt_toggle(void *data, bool force) static void ui_companion_qt_event_command(void *data, enum event_command cmd) { ui_companion_qt_t *handle = (ui_companion_qt_t*)data; - - (void)cmd; + ui_window_qt_t *win_handle = (ui_window_qt_t*)handle->window; if (!handle) return; + + switch (cmd) + { + case CMD_EVENT_SHADERS_APPLY_CHANGES: + /* PRESET_LOADED already fires in more situations than APPLY_CHANGES, use that for reloading the params window */ + break; + case CMD_EVENT_SHADER_PRESET_LOADED: + RARCH_LOG("[Qt]: Reloading shader parameters.\n"); + win_handle->qtWindow->deferReloadShaderParams(); + break; + default: + break; + } } static void ui_companion_qt_notify_list_pushed(void *data, file_list_t *list, diff --git a/ui/drivers/ui_qt.h b/ui/drivers/ui_qt.h index 50943d2a6c..98519dcdf8 100644 --- a/ui/drivers/ui_qt.h +++ b/ui/drivers/ui_qt.h @@ -250,6 +250,18 @@ private: QSpinBox *m_allPlaylistsGridMaxCountSpinBox; }; +class ShaderParamsDialog : public QDialog +{ + Q_OBJECT +public: + ShaderParamsDialog(QWidget *parent = 0); + ~ShaderParamsDialog(); +signals: + void closed(); +protected: + void closeEvent(QCloseEvent *event); +}; + class CoreInfoLabel : public QLabel { Q_OBJECT @@ -365,6 +377,7 @@ signals: void gotLogMessage(const QString &msg); void gotStatusMessage(QString msg, unsigned priority, unsigned duration, bool flush); void gotReloadPlaylists(); + void gotReloadShaderParams(); void showErrorMessageDeferred(QString msg); void extractArchiveDeferred(QString path); @@ -393,6 +406,7 @@ public slots: void reloadPlaylists(); void deferReloadPlaylists(); void onGotReloadPlaylists(); + void onGotReloadShaderParams(); void showWelcomeScreen(); void onIconViewClicked(); void onListViewClicked(); @@ -403,6 +417,7 @@ public slots: void showDocs(); void updateRetroArchNightly(); void onUpdateRetroArchFinished(bool success); + void deferReloadShaderParams(); private slots: void onLoadCoreClicked(const QStringList &extensionFilters = QStringList()); @@ -520,7 +535,7 @@ private: int m_allPlaylistsGridMaxCount; PlaylistEntryDialog *m_playlistEntryDialog; QElapsedTimer m_statusMessageElapsedTimer; - QDialog *m_shaderParamsDialog; + QPointer m_shaderParamsDialog; QNetworkAccessManager *m_networkManager; QProgressDialog *m_updateProgressDialog; QFile m_updateFile; diff --git a/ui/ui_companion_driver.c b/ui/ui_companion_driver.c index 0133e1a56a..a866b6749b 100644 --- a/ui/ui_companion_driver.c +++ b/ui/ui_companion_driver.c @@ -103,6 +103,10 @@ void ui_companion_event_command(enum event_command action) if (ui && ui->event_command) ui->event_command(ui_companion_data, action); +#ifdef HAVE_QT + if (ui_companion_qt.toggle && qt_is_inited) + ui_companion_qt.event_command(ui_companion_qt_data, action); +#endif } void ui_companion_driver_deinit(void)