Current OpenGL port status

This commit is contained in:
Cacodemon345
2025-03-09 01:39:07 +06:00
parent a4a521b345
commit 7572469988
13 changed files with 473 additions and 9 deletions

View File

@@ -77,6 +77,10 @@
#include <86box/snd_opl.h> #include <86box/snd_opl.h>
#include <86box/version.h> #include <86box/version.h>
/* Deliberate to not make the 86box.h header kitchen-sink. */
#include <86box/qt-glsl.h>
extern char gl3_shader_file[MAX_USER_SHADERS][512];
static int cx; static int cx;
static int cy; static int cy;
static int cw; static int cw;
@@ -1714,6 +1718,30 @@ load_other_peripherals(void)
ini_section_delete_var(cat, temp); ini_section_delete_var(cat, temp);
} }
/* Load OpenGL 3.0 renderer options. */
static void
load_gl3_shaders(void)
{
ini_section_t cat = ini_find_section(config, "GL3 Shaders");
char *p;
char temp[512];
int i = 0;
memset(temp, 0, sizeof(temp));
memset(gl3_shader_file, 0, sizeof(gl3_shader_file));
for (int i = 0; i < MAX_USER_SHADERS; i++) {
temp[0] = 0;
snprintf(temp, 512, "shader%d", i);
p = ini_section_get_string(cat, temp, "");
if (p[0]) {
strncpy(gl3_shader_file[i], p, 512);
} else {
gl3_shader_file[i][0] = 0;
break;
}
}
}
/* Load the specified or a default configuration file. */ /* Load the specified or a default configuration file. */
void void
config_load(void) config_load(void)
@@ -1810,6 +1838,7 @@ config_load(void)
load_floppy_and_cdrom_drives(); /* Floppy and CD-ROM drives */ load_floppy_and_cdrom_drives(); /* Floppy and CD-ROM drives */
load_other_removable_devices(); /* Other removable devices */ load_other_removable_devices(); /* Other removable devices */
load_other_peripherals(); /* Other peripherals */ load_other_peripherals(); /* Other peripherals */
load_gl3_shaders(); /* GL3 Shaders */
/* Migrate renamed device configurations. */ /* Migrate renamed device configurations. */
c = ini_find_section(config, "MDA"); c = ini_find_section(config, "MDA");
@@ -2632,6 +2661,34 @@ save_other_peripherals(void)
ini_delete_section_if_empty(config, cat); ini_delete_section_if_empty(config, cat);
} }
/* Save "GL3 Shaders" section. */
static void
save_gl3_shaders(void)
{
ini_section_t cat = ini_find_or_create_section(config, "GL3 Shaders");
char temp[512];
int shaders = 0, i = 0;
for (i = 0; i < MAX_USER_SHADERS; i++) {
if (gl3_shader_file[i][0] == 0)
break;
shaders++;
}
ini_section_set_int(cat, "shaders", shaders);
if (shaders == 0) {
ini_section_delete_var(cat, "shaders");
} else {
for (i = 0; i < shaders; i++) {
temp[0] = 0;
snprintf(temp, 512, "shader%d");
ini_section_set_string(cat, temp, gl3_shader_file[i]);
}
}
ini_delete_section_if_empty(config, cat);
}
/* Save "Hard Disks" section. */ /* Save "Hard Disks" section. */
static void static void
save_hard_disks(void) save_hard_disks(void)
@@ -2987,6 +3044,7 @@ config_save(void)
save_floppy_and_cdrom_drives(); /* Floppy and CD-ROM drives */ save_floppy_and_cdrom_drives(); /* Floppy and CD-ROM drives */
save_other_removable_devices(); /* Other removable devices */ save_other_removable_devices(); /* Other removable devices */
save_other_peripherals(); /* Other peripherals */ save_other_peripherals(); /* Other peripherals */
save_gl3_shaders(); /* GL3 Shaders */
ini_write(config, cfg_path); ini_write(config, cfg_path);
} }

View File

@@ -91,13 +91,16 @@ extern ini_section_t ini_find_or_create_section(ini_t ini, const char *name);
extern void ini_rename_section(ini_section_t section, const char *name); extern void ini_rename_section(ini_section_t section, const char *name);
extern void ini_delete_section_if_empty(ini_t ini, ini_section_t section); extern void ini_delete_section_if_empty(ini_t ini, ini_section_t section);
static inline void *wx_config_load(const char *path) { return (void*) ini_read(path); }; static inline void *wx_config_load(const char *path) { return (void*) ini_read(path); }
static inline int wx_config_get_string(void *config, const char *name, char *dst, int size, const char *defVal) { static inline int wx_config_get_string(void *config, const char *name, char *dst, int size, const char *defVal) {
int res = ini_has_entry(ini_find_or_create_section((ini_t)config, ""), name); int res = ini_has_entry(ini_find_or_create_section((ini_t)config, ""), name);
char* str = ini_get_string((ini_t)config, "", name, (char*)defVal); char* str = ini_get_string((ini_t)config, "", name, (char*)defVal);
if (size == 0) if (size == 0)
return res; return res;
strncpy(dst, str, size); if (str != NULL)
strncpy(dst, str, size - 1);
else
dst[0] = 0;
return res; return res;
} }
static inline int wx_config_get_int(void *config, const char *name, int *dst, int defVal) { static inline int wx_config_get_int(void *config, const char *name, int *dst, int defVal) {

View File

@@ -53,4 +53,7 @@ void get_glslp_name(const char *f, char *s, int size);
glslp_t *glslp_parse(const char *f); glslp_t *glslp_parse(const char *f);
void glslp_free(glslp_t *p); void glslp_free(glslp_t *p);
#endif /* SRC_WX_GLSLP_PARSER_H_ */ void glslp_read_shader_config(glslp_t *shader);
void glslp_write_shader_config(glslp_t *shader);
#endif /* SRC_WX_GLSLP_PARSER_H_ */

View File

@@ -193,6 +193,10 @@ add_library(ui STATIC
../qt_resources.qrc ../qt_resources.qrc
./qdarkstyle/dark/darkstyle.qrc ./qdarkstyle/dark/darkstyle.qrc
qt_openglshadermanagerdialog.hpp
qt_openglshadermanagerdialog.cpp
qt_openglshadermanagerdialog.ui
) )
if(RTMIDI) if(RTMIDI)

View File

@@ -7,8 +7,12 @@ extern "C"
{ {
#include <86box/86box.h> #include <86box/86box.h>
#include <86box/ini.h> #include <86box/ini.h>
#include <86box/config.h>
#include <86box/qt-glslp-parser.h> #include <86box/qt-glslp-parser.h>
#include <86box/path.h> #include <86box/path.h>
extern void startblit();
extern void endblit();
} }
#define safe_strncpy(a, b, n) \ #define safe_strncpy(a, b, n) \
@@ -305,4 +309,29 @@ void glslp_free(glslp_t *p) {
free(p); free(p);
} }
} void glslp_read_shader_config(glslp_t *shader) {
char s[512];
int i;
char *name = shader->name;
sprintf(s, "GL3 Shaders - %s", name);
for (i = 0; i < shader->num_parameters; ++i) {
struct parameter *param = &shader->parameters[i];
param->value = config_get_double(s, param->id, param->default_value);
}
}
void glslp_write_shader_config(glslp_t *shader) {
char s[512];
int i;
char *name = shader->name;
startblit();
sprintf(s, "GL3 Shaders - %s", name);
for (i = 0; i < shader->num_parameters; ++i) {
struct parameter *param = &shader->parameters[i];
config_set_double(s, param->id, param->value);
}
endblit();
}
}

View File

@@ -1987,7 +1987,16 @@ MainWindow::on_actionRenderer_options_triggered()
{ {
if (const auto dlg = ui->stackedWidget->getOptions(this)) { if (const auto dlg = ui->stackedWidget->getOptions(this)) {
if (dlg->exec() == QDialog::Accepted) { if (dlg->exec() == QDialog::Accepted) {
for (int i = 1; i < MONITORS_NUM; i++) { if (ui->stackedWidget->reloadRendererOption()) {
ui->stackedWidget->switchRenderer(static_cast<RendererStack::Renderer>(vid_api));
if (show_second_monitors) {
for (int i = 1; i < MONITORS_NUM; i++) {
if (renderers[i] && renderers[i]->reloadRendererOption() && renderers[i]->hasOptions()) {
ui->stackedWidget->switchRenderer(static_cast<RendererStack::Renderer>(vid_api));
}
}
}
} else for (int i = 1; i < MONITORS_NUM; i++) {
if (renderers[i] && renderers[i]->hasOptions()) if (renderers[i] && renderers[i]->hasOptions())
renderers[i]->reloadOptions(); renderers[i]->reloadOptions();
} }

View File

@@ -20,6 +20,7 @@
#include <cmath> #include <cmath>
#include "qt_openglrenderer_pcem.hpp" #include "qt_openglrenderer_pcem.hpp"
#include "qt_openglshadermanagerdialog.hpp"
extern "C" { extern "C" {
#include <86box/86box.h> #include <86box/86box.h>
@@ -1286,6 +1287,12 @@ OpenGLRendererPCem::event(QEvent *event)
return res; return res;
} }
QDialog*
OpenGLRendererPCem::getOptions(QWidget *parent)
{
return new OpenGLShaderManagerDialog(parent);
}
void void
OpenGLRendererPCem::render() OpenGLRendererPCem::render()
{ {
@@ -1659,4 +1666,4 @@ OpenGLRendererPCem::render()
frameCounter++; frameCounter++;
context->swapBuffers(this); context->swapBuffers(this);
} }

View File

@@ -67,9 +67,9 @@ public:
std::vector<std::tuple<uint8_t *, std::atomic_flag *>> getBuffers() override; std::vector<std::tuple<uint8_t *, std::atomic_flag *>> getBuffers() override;
void finalize() override final; void finalize() override final;
//bool hasOptions() const override { return true; } bool hasOptions() const override { return true; }
//QDialog *getOptions(QWidget *parent) override; QDialog *getOptions(QWidget *parent) override;
//void reloadOptions() override; bool reloadRendererOption() { return true; }
signals: signals:
void initialized(); void initialized();

View File

@@ -0,0 +1,159 @@
#include "qt_openglshadermanagerdialog.hpp"
#include "ui_qt_openglshadermanagerdialog.h"
#include <QListWidgetItem>
#include <QFileDialog>
#include <QMessageBox>
extern "C" {
#include <86box/86box.h>
#include <86box/plat.h>
#include <86box/video.h>
#include <86box/path.h>
#include <86box/ini.h>
#include <86box/config.h>
#include <86box/qt-glslp-parser.h>
extern char gl3_shader_file[MAX_USER_SHADERS][512];
}
OpenGLShaderManagerDialog::OpenGLShaderManagerDialog(QWidget *parent)
: QDialog(parent)
, ui(new Ui::OpenGLShaderManagerDialog)
{
ui->setupUi(this);
for (int i = 0; i < MAX_USER_SHADERS; i++) {
if (gl3_shader_file[i][0] != 0) {
char* filename = path_get_filename(gl3_shader_file[i]);
if (filename[0] != 0) {
glslp_t* shaderfile = glslp_parse(gl3_shader_file[i]);
if (shaderfile) {
QListWidgetItem* item = new QListWidgetItem(ui->shaderListWidget);
item->setText(filename);
item->setData(Qt::UserRole + 1, QString(gl3_shader_file[i]));
item->setData(Qt::UserRole + 2, (uintptr_t)shaderfile);
}
}
}
}
if (ui->shaderListWidget->count()) {
ui->shaderListWidget->setCurrentRow(ui->shaderListWidget->count() - 1);
} else {
ui->buttonRemove->setDisabled(true);
ui->buttonMoveUp->setDisabled(true);
ui->buttonMoveDown->setDisabled(true);
}
}
OpenGLShaderManagerDialog::~OpenGLShaderManagerDialog()
{
for (int i = 0; i < ui->shaderListWidget->count(); i++) {
if (ui->shaderListWidget->item(i) && ui->shaderListWidget->item(i)->data(Qt::UserRole + 2).toULongLong()) {
glslp_free((glslp_t*)ui->shaderListWidget->item(i)->data(Qt::UserRole + 2).toULongLong());
}
}
delete ui;
}
void OpenGLShaderManagerDialog::on_buttonBox_clicked(QAbstractButton *button)
{
if (ui->buttonBox->buttonRole(button) == QDialogButtonBox::AcceptRole) {
accept();
} else if (ui->buttonBox->buttonRole(button) == QDialogButtonBox::RejectRole) {
reject();
}
}
void OpenGLShaderManagerDialog::on_buttonMoveUp_clicked()
{
if (ui->shaderListWidget->currentRow() == 0)
return;
int row = ui->shaderListWidget->currentRow();
auto item = ui->shaderListWidget->takeItem(row);
ui->shaderListWidget->insertItem(row - 1, item);
ui->shaderListWidget->setCurrentItem(item);
}
void OpenGLShaderManagerDialog::on_shaderListWidget_currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous)
{
if (current == nullptr) {
ui->buttonRemove->setDisabled(true);
ui->buttonMoveUp->setDisabled(true);
ui->buttonMoveDown->setDisabled(true);
return;
} else {
ui->buttonRemove->setDisabled(false);
}
ui->buttonMoveUp->setDisabled(ui->shaderListWidget->currentRow() == 0);
ui->buttonMoveDown->setDisabled(ui->shaderListWidget->currentRow() == (ui->shaderListWidget->count() - 1));
}
void OpenGLShaderManagerDialog::on_shaderListWidget_currentRowChanged(int currentRow)
{
ui->buttonMoveUp->setDisabled(ui->shaderListWidget->currentRow() == 0);
ui->buttonMoveDown->setDisabled(ui->shaderListWidget->currentRow() == (ui->shaderListWidget->count() - 1));
}
void OpenGLShaderManagerDialog::on_buttonMoveDown_clicked()
{
if (ui->shaderListWidget->currentRow() == (ui->shaderListWidget->count() - 1))
return;
int row = ui->shaderListWidget->currentRow();
auto item = ui->shaderListWidget->takeItem(row);
ui->shaderListWidget->insertItem(row + 1, item);
ui->shaderListWidget->setCurrentItem(item);
}
void OpenGLShaderManagerDialog::on_buttonAdd_clicked()
{
auto res = QFileDialog::getOpenFileName(this, QString(), QString(), "GLSL Shaders (*.glslp *.glsl);;All files (*.*)");
if (!res.isEmpty()) {
auto glslp_file = res.toUtf8();
glslp_t* shaderfile = glslp_parse(glslp_file.data());
if (shaderfile) {
auto filename = path_get_filename(glslp_file.data());
QListWidgetItem* item = new QListWidgetItem(ui->shaderListWidget);
item->setText(filename);
item->setData(Qt::UserRole + 1, res);
item->setData(Qt::UserRole + 2, (uintptr_t)shaderfile);
if (ui->shaderListWidget->count()) {
ui->shaderListWidget->setCurrentRow(ui->shaderListWidget->count() - 1);
}
} else {
QMessageBox::critical(this, tr("GLSL error"), tr("Could not load filename %1").arg(res));
}
}
}
void OpenGLShaderManagerDialog::on_buttonRemove_clicked()
{
if (ui->shaderListWidget->currentItem()) {
auto item = ui->shaderListWidget->takeItem(ui->shaderListWidget->currentRow());
if (item->data(Qt::UserRole + 2).toULongLong()) {
glslp_free((glslp_t*)item->data(Qt::UserRole + 2).toULongLong());
}
delete item;
}
}
void OpenGLShaderManagerDialog::on_OpenGLShaderManagerDialog_accepted()
{
memset(gl3_shader_file, 0, sizeof(gl3_shader_file));
for (int i = 0; i < ui->shaderListWidget->count(); i++) {
strncpy(gl3_shader_file[i], ui->shaderListWidget->item(i)->data(Qt::UserRole + 1).toString().toUtf8(), 512);
}
startblit();
config_save();
endblit();
}

View File

@@ -0,0 +1,40 @@
#ifndef QT_OPENGLSHADERMANAGERDIALOG_H
#define QT_OPENGLSHADERMANAGERDIALOG_H
#include <QDialog>
#include <QAbstractButton>
#include <QListWidgetItem>
namespace Ui {
class OpenGLShaderManagerDialog;
}
class OpenGLShaderManagerDialog : public QDialog {
Q_OBJECT
public:
explicit OpenGLShaderManagerDialog(QWidget *parent = nullptr);
~OpenGLShaderManagerDialog();
private slots:
void on_buttonBox_clicked(QAbstractButton *button);
void on_buttonMoveUp_clicked();
void on_shaderListWidget_currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous);
void on_shaderListWidget_currentRowChanged(int currentRow);
void on_buttonMoveDown_clicked();
void on_buttonAdd_clicked();
void on_buttonRemove_clicked();
void on_OpenGLShaderManagerDialog_accepted();
private:
Ui::OpenGLShaderManagerDialog *ui;
};
#endif // QT_OPENGLSHADERMANAGERDIALOG_H

View File

@@ -0,0 +1,148 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>OpenGLShaderManagerDialog</class>
<widget class="QDialog" name="OpenGLShaderManagerDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>465</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="sizeConstraint">
<enum>QLayout::SizeConstraint::SetFixedSize</enum>
</property>
<item>
<widget class="QListWidget" name="shaderListWidget">
<property name="dragDropMode">
<enum>QAbstractItemView::DragDropMode::InternalMove</enum>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectionBehavior::SelectItems</enum>
</property>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QPushButton" name="buttonAdd">
<property name="text">
<string>Add</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="buttonRemove">
<property name="text">
<string>Remove</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Orientation::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="buttonConfigure">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Configure</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="buttonMoveUp">
<property name="text">
<string>Move up</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="buttonMoveDown">
<property name="text">
<string>Move down</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Orientation::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Orientation::Vertical</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Ok</set>
</property>
<property name="centerButtons">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>OpenGLShaderManagerDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>OpenGLShaderManagerDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@@ -34,6 +34,8 @@ public:
virtual QDialog *getOptions(QWidget *parent) { return nullptr; } virtual QDialog *getOptions(QWidget *parent) { return nullptr; }
/* Reloads options of renderer */ /* Reloads options of renderer */
virtual void reloadOptions() { } virtual void reloadOptions() { }
/* Make the renderer reload itself */
virtual bool reloadRendererOption() { return false; }
int r_monitor_index = 0; int r_monitor_index = 0;

View File

@@ -70,6 +70,8 @@ public:
void reloadOptions() const { return rendererWindow->reloadOptions(); } void reloadOptions() const { return rendererWindow->reloadOptions(); }
/* Returns options dialog for current renderer */ /* Returns options dialog for current renderer */
QDialog *getOptions(QWidget *parent) { return rendererWindow ? rendererWindow->getOptions(parent) : nullptr; } QDialog *getOptions(QWidget *parent) { return rendererWindow ? rendererWindow->getOptions(parent) : nullptr; }
/* Reload the renderer itself */
bool reloadRendererOption() { return rendererWindow ? rendererWindow->reloadRendererOption() : false; }
void setFocusRenderer(); void setFocusRenderer();
void onResize(int width, int height); void onResize(int width, int height);