Merge branch 'master' of ssh://github.com/86Box/86Box into cleanup30
# Conflicts: # .ci/build.sh # .ci/dependencies_msys.txt # src/sound/snd_audiopci.c
This commit is contained in:
@@ -141,6 +141,11 @@ add_library(ui STATIC
|
||||
)
|
||||
|
||||
|
||||
if(RTMIDI)
|
||||
target_compile_definitions(ui PRIVATE USE_RTMIDI)
|
||||
endif()
|
||||
|
||||
|
||||
if(WIN32)
|
||||
enable_language(RC)
|
||||
target_sources(86Box PUBLIC ../win/86Box-qt.rc)
|
||||
@@ -259,7 +264,7 @@ if (APPLE AND CMAKE_MACOSX_BUNDLE)
|
||||
fixup_bundle(\"\${CMAKE_INSTALL_PREFIX_ABSOLUTE}/86Box.app\" \"${QT_PLUGINS}\" \"${DIRS}\")")
|
||||
endif()
|
||||
|
||||
if (UNIX AND NOT APPLE)
|
||||
if (UNIX AND NOT APPLE AND NOT HAIKU)
|
||||
find_package(X11 REQUIRED)
|
||||
target_link_libraries(ui PRIVATE X11::X11 X11::Xi)
|
||||
target_sources(ui PRIVATE xinput2_mouse.cpp)
|
||||
|
||||
@@ -29,7 +29,7 @@ msgid "&Hide status bar"
|
||||
msgstr "&Piilota tilapalkki"
|
||||
|
||||
msgid "Hide &toolbar"
|
||||
msgstr "Hide &toolbar"
|
||||
msgstr "Piilota &työkalupalkki"
|
||||
|
||||
msgid "&Resizeable window"
|
||||
msgstr "&Salli koon muuttaminen"
|
||||
@@ -59,7 +59,7 @@ msgid "Specify dimensions..."
|
||||
msgstr "&Määritä koko..."
|
||||
|
||||
msgid "F&orce 4:3 display ratio"
|
||||
msgstr "Pakota 4:3 näyttösuhde"
|
||||
msgstr "Pakota 4:3-näyttösuhde"
|
||||
|
||||
msgid "&Window scale factor"
|
||||
msgstr "&Ikkunan kokokerroin"
|
||||
@@ -107,19 +107,19 @@ msgid "&Integer scale"
|
||||
msgstr "&Kokonaislukuskaalaus"
|
||||
|
||||
msgid "E&GA/(S)VGA settings"
|
||||
msgstr "&EGA/(S)VGA asetukset"
|
||||
msgstr "&EGA/(S)VGA-asetukset"
|
||||
|
||||
msgid "&Inverted VGA monitor"
|
||||
msgstr "&VGA näyttö käänteisillä väreillä"
|
||||
|
||||
msgid "VGA screen &type"
|
||||
msgstr "VGA näytön &tyyppi"
|
||||
msgstr "VGA-näytön &tyyppi"
|
||||
|
||||
msgid "RGB &Color"
|
||||
msgstr "RGB &värit"
|
||||
msgstr "RGB, &värit"
|
||||
|
||||
msgid "&RGB Grayscale"
|
||||
msgstr "&RGB harmaasävyinen"
|
||||
msgstr "&RGB, harmaasävy"
|
||||
|
||||
msgid "&Amber monitor"
|
||||
msgstr "&Meripihkanvärinen"
|
||||
@@ -143,7 +143,7 @@ msgid "&Average"
|
||||
msgstr "&Keskiarvo"
|
||||
|
||||
msgid "CGA/PCjr/Tandy/E&GA/(S)VGA overscan"
|
||||
msgstr "CGA/PCjr/Tandy/E&GA/(S)VGA &yliskannaus"
|
||||
msgstr "CGA/PCjr/Tandy/E&GA/(S)VGA-&yliskannaus"
|
||||
|
||||
msgid "Change contrast for &monochrome display"
|
||||
msgstr "&Muuta harmaavärinäytön kontrastia"
|
||||
@@ -152,7 +152,7 @@ msgid "&Media"
|
||||
msgstr "&Media"
|
||||
|
||||
msgid "&Tools"
|
||||
msgstr "&Työkalut"
|
||||
msgstr "Työ&kalut"
|
||||
|
||||
msgid "&Settings..."
|
||||
msgstr "&Kokoonpano..."
|
||||
@@ -167,10 +167,10 @@ msgid "&Preferences..."
|
||||
msgstr "&Sovellusasetukset..."
|
||||
|
||||
msgid "Enable &Discord integration"
|
||||
msgstr "Käytä &Discord integraatiota"
|
||||
msgstr "Käytä &Discord-integraatiota"
|
||||
|
||||
msgid "Sound &gain..."
|
||||
msgstr "&Äänen tulotaso..."
|
||||
msgstr "&Äänitasot..."
|
||||
|
||||
msgid "Begin trace\tCtrl+T"
|
||||
msgstr "Aloita jäljitys\tCtrl+T"
|
||||
@@ -182,19 +182,19 @@ msgid "&Help"
|
||||
msgstr "&Ohje"
|
||||
|
||||
msgid "&Documentation..."
|
||||
msgstr "&Dokumentaatio..."
|
||||
msgstr "&Ohjekirja..."
|
||||
|
||||
msgid "&About 86Box..."
|
||||
msgstr "&Tietoja 86Box:sta..."
|
||||
msgstr "&Tietoja 86Boxista..."
|
||||
|
||||
msgid "&New image..."
|
||||
msgstr "&Uusi kasettikuva..."
|
||||
msgstr "&Uusi levykuva..."
|
||||
|
||||
msgid "&Existing image..."
|
||||
msgstr "&Olemassaoleva kasettikuva..."
|
||||
msgstr "&Olemassaoleva levykuva..."
|
||||
|
||||
msgid "Existing image (&Write-protected)..."
|
||||
msgstr "Olemassaoleva kasettikuva (&kirjoitussuojattu)..."
|
||||
msgstr "Olemassaoleva levykuva (&kirjoitussuojattu)..."
|
||||
|
||||
msgid "&Record"
|
||||
msgstr "&Nauhoita"
|
||||
@@ -209,7 +209,7 @@ msgid "&Fast forward to the end"
|
||||
msgstr "Kelaa &loppuun"
|
||||
|
||||
msgid "E&ject"
|
||||
msgstr "&Poista kasettipesästä"
|
||||
msgstr "&Poista asemasta"
|
||||
|
||||
msgid "&Image..."
|
||||
msgstr "&ROM-moduulikuva..."
|
||||
@@ -263,7 +263,7 @@ msgid "Preferences"
|
||||
msgstr "Sovellusasetukset"
|
||||
|
||||
msgid "Sound Gain"
|
||||
msgstr "Äänen tulotaso"
|
||||
msgstr "Äänen taso"
|
||||
|
||||
msgid "New Image"
|
||||
msgstr "Uusi levykuva"
|
||||
@@ -302,7 +302,7 @@ msgid "Disk size:"
|
||||
msgstr "Levyn koko:"
|
||||
|
||||
msgid "RPM mode:"
|
||||
msgstr "RPM tila:"
|
||||
msgstr "Kierroslukutila:"
|
||||
|
||||
msgid "Progress:"
|
||||
msgstr "Edistyminen:"
|
||||
@@ -470,10 +470,10 @@ msgid "FD Controller:"
|
||||
msgstr "Levykeohjain:"
|
||||
|
||||
msgid "Tertiary IDE Controller"
|
||||
msgstr "Tertinäärinen IDE-ohjain"
|
||||
msgstr "Kolmas IDE-ohjain"
|
||||
|
||||
msgid "Quaternary IDE Controller"
|
||||
msgstr "Kvaternaarinen IDE-ohjain"
|
||||
msgstr "Neljäs IDE-ohjain"
|
||||
|
||||
msgid "SCSI"
|
||||
msgstr "SCSI"
|
||||
@@ -521,7 +521,7 @@ msgid "Sectors:"
|
||||
msgstr "Sektorit:"
|
||||
|
||||
msgid "Heads:"
|
||||
msgstr "Päät:"
|
||||
msgstr "Lukupäät:"
|
||||
|
||||
msgid "Cylinders:"
|
||||
msgstr "Sylinterit:"
|
||||
@@ -599,7 +599,7 @@ msgid "Fatal error"
|
||||
msgstr "Vakava virhe"
|
||||
|
||||
msgid " - PAUSED"
|
||||
msgstr " - PAUSED"
|
||||
msgstr " - TAUKO"
|
||||
|
||||
msgid "Press Ctrl+Alt+PgDn to return to windowed mode."
|
||||
msgstr "Paina Ctrl+Alt+PgDn palataksesi ikkunoituun tilaan."
|
||||
@@ -614,7 +614,7 @@ msgid "ZIP images"
|
||||
msgstr "ZIP-levykuvat"
|
||||
|
||||
msgid "86Box could not find any usable ROM images.\n\nPlease <a href=\"https://github.com/86Box/roms/releases/latest\">download</a> a ROM set and extract it into the \"roms\" directory."
|
||||
msgstr "86Box ei löytänyt käyttökelpoisia ROM-tiedostoja.\n\nVoit <a href=\"https://github.com/86Box/roms/releases/latest\">ladata</a> ROM-paketin ja purkaa sen \"roms\" hakemistoon."
|
||||
msgstr "86Box ei löytänyt käyttökelpoisia ROM-tiedostoja.\n\nVoit <a href=\"https://github.com/86Box/roms/releases/latest\">ladata</a> ROM-paketin ja purkaa sen \"roms\"-hakemistoon."
|
||||
|
||||
msgid "(empty)"
|
||||
msgstr "(tyhjä)"
|
||||
@@ -689,7 +689,7 @@ msgid "Press F8+F12 or middle button to release mouse"
|
||||
msgstr "Paina F8+F12 tai keskipainiketta vapauttaaksesi hiiren"
|
||||
|
||||
msgid "Unable to initialize FluidSynth"
|
||||
msgstr "FluidSynth:in alustus epäonnistui"
|
||||
msgstr "FluidSynthin alustus epäonnistui"
|
||||
|
||||
msgid "Bus"
|
||||
msgstr "Väylä"
|
||||
@@ -710,7 +710,7 @@ msgid "KB"
|
||||
msgstr "kt"
|
||||
|
||||
msgid "Could not initialize the video renderer."
|
||||
msgstr "Video-renderöijän alustus epäonnistui"
|
||||
msgstr "Videorenderöijän alustus epäonnistui"
|
||||
|
||||
msgid "Default"
|
||||
msgstr "Oletus"
|
||||
@@ -782,13 +782,13 @@ msgid "Unable to initialize SDL, SDL2.dll is required"
|
||||
msgstr "SDL:n alustus epäonnistui. Tarvitaan SDL2.dll"
|
||||
|
||||
msgid "Are you sure you want to hard reset the emulated machine?"
|
||||
msgstr "Oletko varma, että haluat käynnistää emuloidun tietokoneen uudelleen?"
|
||||
msgstr "Haluatko varmasti käynnistää emuloidun tietokoneen uudelleen?"
|
||||
|
||||
msgid "Are you sure you want to exit 86Box?"
|
||||
msgstr "Haluatko varmasti sulkea 86Box:in?"
|
||||
msgstr "Haluatko varmasti sulkea 86Boxin?"
|
||||
|
||||
msgid "Unable to initialize Ghostscript"
|
||||
msgstr "Ghostscript:in alustus epäonnistui"
|
||||
msgstr "Ghostscriptin alustus epäonnistui"
|
||||
|
||||
msgid "MO %i (%ls): %ls"
|
||||
msgstr "MO %i (%ls): %ls"
|
||||
@@ -797,7 +797,7 @@ msgid "MO images"
|
||||
msgstr "MO-levykuvat"
|
||||
|
||||
msgid "Welcome to 86Box!"
|
||||
msgstr "Tervetuloa 86Box:iin!"
|
||||
msgstr "Tervetuloa 86Boxiin!"
|
||||
|
||||
msgid "Internal controller"
|
||||
msgstr "Sisäinen ohjain"
|
||||
@@ -911,7 +911,7 @@ msgid "Cassette: %s"
|
||||
msgstr "Kasetti: %s"
|
||||
|
||||
msgid "Cassette images"
|
||||
msgstr "Kasetti-tiedostot"
|
||||
msgstr "Kasettitiedostot"
|
||||
|
||||
msgid "Cartridge %i: %ls"
|
||||
msgstr "ROM-moduuli %i: %ls"
|
||||
@@ -923,25 +923,25 @@ msgid "Error initializing renderer"
|
||||
msgstr "Virhe renderöijän alustuksessa"
|
||||
|
||||
msgid "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer."
|
||||
msgstr "OpenGL (3.0 Core) renderöijän alustus epäonnistui. Käytä toista renderöijää."
|
||||
msgstr "OpenGL (3.0 Core) -renderöijän alustus epäonnistui. Käytä toista renderöijää."
|
||||
|
||||
msgid "Resume execution"
|
||||
msgstr "Resume execution"
|
||||
msgstr "Jatka suoritusta"
|
||||
|
||||
msgid "Pause execution"
|
||||
msgstr "Pause execution"
|
||||
msgstr "Pysäytä suoritus"
|
||||
|
||||
msgid "Press Ctrl+Alt+Del"
|
||||
msgstr "Press Ctrl+Alt+Del"
|
||||
msgstr "Paina Ctrl+Alt+Del"
|
||||
|
||||
msgid "Press Ctrl+Alt+Esc"
|
||||
msgstr "Press Ctrl+Alt+Esc"
|
||||
msgstr "Paina Ctrl+Alt+Esc"
|
||||
|
||||
msgid "Hard reset"
|
||||
msgstr "Hard reset"
|
||||
msgstr "Kylmä uudelleenkäynnistys"
|
||||
|
||||
msgid "ACPI shutdown"
|
||||
msgstr "ACPI shutdown"
|
||||
msgstr "ACPI-sammutus"
|
||||
|
||||
msgid "Hard disk (%s)"
|
||||
msgstr "Kiintolevy (%s)"
|
||||
@@ -953,7 +953,7 @@ msgid "%01i"
|
||||
msgstr "%01i"
|
||||
|
||||
msgid "MFM/RLL or ESDI CD-ROM drives never existed"
|
||||
msgstr "MFM/RLL tai ESDI CD-ROM asemia ei ole koskaan ollut olemassa"
|
||||
msgstr "MFM/RLL- tai ESDI-CD-ROM-asemia ei ole koskaan ollut olemassa"
|
||||
|
||||
msgid "Custom..."
|
||||
msgstr "Mukautettu..."
|
||||
@@ -968,7 +968,7 @@ msgid "Add Existing Hard Disk"
|
||||
msgstr "Lisää olemassaoleva kiintolevy"
|
||||
|
||||
msgid "HDI disk images cannot be larger than 4 GB."
|
||||
msgstr "HDI levykuvan suurin mahdollinen koko on 4 Gt."
|
||||
msgstr "HDI-levykuvan suurin mahdollinen koko on 4 Gt."
|
||||
|
||||
msgid "Disk images cannot be larger than 127 GB."
|
||||
msgstr "Levykuvien suurin mahdollinen koko on 127 Gt."
|
||||
@@ -1010,16 +1010,16 @@ msgid "Remember to partition and format the newly-created drive."
|
||||
msgstr "Muista osioida ja alustaa juuri luomasi asema."
|
||||
|
||||
msgid "The selected file will be overwritten. Are you sure you want to use it?"
|
||||
msgstr "Valittu tiedosto ylikirjoitetaan. Oletko varma, että haluat käyttää sitä?"
|
||||
msgstr "Valittu tiedosto korvataan. Oletko varma, että haluat käyttää sitä?"
|
||||
|
||||
msgid "Unsupported disk image"
|
||||
msgstr "Levynkuvaa ei tueta"
|
||||
msgstr "Levykuvaa ei tueta"
|
||||
|
||||
msgid "Overwrite"
|
||||
msgstr "Ylikirjoita"
|
||||
msgstr "Korvaa"
|
||||
|
||||
msgid "Don't overwrite"
|
||||
msgstr "Älä ylikirjoita"
|
||||
msgstr "Älä korvaa"
|
||||
|
||||
msgid "Raw image (.img)"
|
||||
msgstr "Raaka levykuva (.img)"
|
||||
@@ -1169,16 +1169,16 @@ msgid "5.25\" 1.3 GB"
|
||||
msgstr "5.25\" 1.3 Gt"
|
||||
|
||||
msgid "Perfect RPM"
|
||||
msgstr "Täydellinen RPM"
|
||||
msgstr "Täydellinen kierrosluku"
|
||||
|
||||
msgid "1% below perfect RPM"
|
||||
msgstr "1% alle täydellisen RPM:n"
|
||||
msgstr "1% alle täydellisen kierrosluvun"
|
||||
|
||||
msgid "1.5% below perfect RPM"
|
||||
msgstr "1.5% alle täydellisen RPM:n"
|
||||
msgstr "1.5% alle täydellisen kierrosluvun"
|
||||
|
||||
msgid "2% below perfect RPM"
|
||||
msgstr "2% alle täydellisen RPM:n"
|
||||
msgstr "2% alle täydellisen kierrosluvun"
|
||||
|
||||
msgid "(System Default)"
|
||||
msgstr "(Järjestelmän oletus)"
|
||||
|
||||
@@ -67,6 +67,7 @@ void DeviceConfig::ConfigureDevice(const _device_* device, int instance, Setting
|
||||
dc.ui->formLayout->addRow(config->description, cbox);
|
||||
break;
|
||||
}
|
||||
#ifdef USE_RTMIDI
|
||||
case CONFIG_MIDI_OUT:
|
||||
{
|
||||
auto* cbox = new QComboBox();
|
||||
@@ -74,9 +75,9 @@ void DeviceConfig::ConfigureDevice(const _device_* device, int instance, Setting
|
||||
auto* model = cbox->model();
|
||||
int currentIndex = -1;
|
||||
int selected = config_get_int(device_context.name, const_cast<char*>(config->name), config->default_int);
|
||||
for (int i = 0; i < rtmidi_get_num_devs(); i++) {
|
||||
for (int i = 0; i < rtmidi_out_get_num_devs(); i++) {
|
||||
char midiName[512] = { 0 };
|
||||
rtmidi_get_dev_name(i, midiName);
|
||||
rtmidi_out_get_dev_name(i, midiName);
|
||||
|
||||
Models::AddEntry(model, midiName, i);
|
||||
if (selected == i) {
|
||||
@@ -107,6 +108,7 @@ void DeviceConfig::ConfigureDevice(const _device_* device, int instance, Setting
|
||||
cbox->setCurrentIndex(currentIndex);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
case CONFIG_SELECTION:
|
||||
case CONFIG_HEX16:
|
||||
case CONFIG_HEX20:
|
||||
|
||||
@@ -38,6 +38,7 @@ extern "C" {
|
||||
#include <QProgressDialog>
|
||||
#include <QPushButton>
|
||||
#include <QStringBuilder>
|
||||
#include <QStringList>
|
||||
|
||||
#include "qt_harddrive_common.hpp"
|
||||
#include "qt_settings_bus_tracking.hpp"
|
||||
@@ -50,8 +51,9 @@ HarddiskDialog::HarddiskDialog(bool existing, QWidget *parent) :
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
ui->fileField->setFilter(tr("Hard disk images") % util::DlgFilter({ "hd?","im?","vhd" }) % tr("All files") % util::DlgFilter({ "*" }, true));
|
||||
if (existing) {
|
||||
ui->fileField->setFilter(tr("Hard disk images") % util::DlgFilter({ "hd?", "im?", "vhd" }) % tr("All files") % util::DlgFilter({ "*" }, true));
|
||||
|
||||
setWindowTitle(tr("Add Existing Hard Disk"));
|
||||
ui->lineEditCylinders->setEnabled(false);
|
||||
ui->lineEditHeads->setEnabled(false);
|
||||
@@ -64,8 +66,24 @@ HarddiskDialog::HarddiskDialog(bool existing, QWidget *parent) :
|
||||
|
||||
connect(ui->fileField, &FileField::fileSelected, this, &HarddiskDialog::onExistingFileSelected);
|
||||
} else {
|
||||
QStringList filters({ tr("Raw image") % util::DlgFilter({ "img" }, true),
|
||||
tr("HDI image") % util::DlgFilter({ "hdi" }, true),
|
||||
tr("HDX image") % util::DlgFilter({ "hdx" }, true),
|
||||
tr("Fixed-size VHD") % util::DlgFilter({ "vhd" }, true),
|
||||
tr("Dynamic-size VHD") % util::DlgFilter({ "vhd" }, true),
|
||||
tr("Differencing VHD") % util::DlgFilter({ "vhd" }, true) });
|
||||
|
||||
ui->fileField->setFilter(filters.join(";;"));
|
||||
|
||||
setWindowTitle(tr("Add New Hard Disk"));
|
||||
ui->fileField->setCreateFile(true);
|
||||
|
||||
connect(ui->fileField, &FileField::fileSelected, this, [this, filters] {
|
||||
int filter = filters.indexOf(ui->fileField->selectedFilter());
|
||||
if (filter > -1)
|
||||
ui->comboBoxFormat->setCurrentIndex(filter);
|
||||
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true);
|
||||
});
|
||||
}
|
||||
|
||||
auto* model = ui->comboBoxFormat->model();
|
||||
@@ -101,9 +119,6 @@ HarddiskDialog::HarddiskDialog(bool existing, QWidget *parent) :
|
||||
|
||||
ui->lineEditSize->setValidator(new QIntValidator());
|
||||
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
|
||||
if (!existing) connect(ui->fileField, &FileField::fileSelected, this, [this] {
|
||||
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true);
|
||||
});
|
||||
}
|
||||
|
||||
HarddiskDialog::~HarddiskDialog()
|
||||
@@ -705,6 +720,7 @@ void HarddiskDialog::on_comboBoxBus_currentIndexChanged(int index) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (chanIdx == 0xFF) chanIdx = 0;
|
||||
ui->comboBoxChannel->setCurrentIndex(chanIdx);
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ void Harddrives::populateBuses(QAbstractItemModel *model) {
|
||||
model->removeRows(0, model->rowCount());
|
||||
model->insertRows(0, 6);
|
||||
model->setData(model->index(0, 0), "MFM/RLL");
|
||||
model->setData(model->index(1, 0), "XT IDE");
|
||||
model->setData(model->index(1, 0), "XTA");
|
||||
model->setData(model->index(2, 0), "ESDI");
|
||||
model->setData(model->index(3, 0), "IDE");
|
||||
model->setData(model->index(4, 0), "ATAPI");
|
||||
@@ -97,7 +97,7 @@ QString Harddrives::BusChannelName(uint8_t bus, uint8_t channel) {
|
||||
busName = QString("MFM/RLL (%1:%2)").arg(channel >> 1).arg(channel & 1);
|
||||
break;
|
||||
case HDD_BUS_XTA:
|
||||
busName = QString("XT IDE (%1:%2)").arg(channel >> 1).arg(channel & 1);
|
||||
busName = QString("XTA (%1:%2)").arg(channel >> 1).arg(channel & 1);
|
||||
break;
|
||||
case HDD_BUS_ESDI:
|
||||
busName = QString("ESDI (%1:%2)").arg(channel >> 1).arg(channel & 1);
|
||||
|
||||
@@ -43,7 +43,7 @@ JoystickConfiguration::JoystickConfiguration(int type, int joystick_nr, QWidget
|
||||
}
|
||||
|
||||
ui->comboBoxDevice->setCurrentIndex(joystick_state[joystick_nr].plat_joystick_nr);
|
||||
setFixedSize(minimumSizeHint());
|
||||
layout()->setSizeConstraint(QLayout::SetFixedSize);
|
||||
}
|
||||
|
||||
JoystickConfiguration::~JoystickConfiguration()
|
||||
@@ -82,7 +82,9 @@ int JoystickConfiguration::selectedPov(int pov) {
|
||||
void JoystickConfiguration::on_comboBoxDevice_currentIndexChanged(int index) {
|
||||
for (auto w : widgets) {
|
||||
ui->ct->removeWidget(w);
|
||||
w->deleteLater();
|
||||
}
|
||||
widgets.clear();
|
||||
|
||||
if (index == 0) {
|
||||
return;
|
||||
@@ -197,6 +199,4 @@ void JoystickConfiguration::on_comboBoxDevice_currentIndexChanged(int index) {
|
||||
|
||||
++row;
|
||||
}
|
||||
|
||||
setFixedSize(minimumSizeHint());
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Dialog</string>
|
||||
<string>Joystick configuration</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="1" column="0" colspan="2">
|
||||
|
||||
@@ -358,7 +358,7 @@ void MachineStatus::refresh(QStatusBar* sbar) {
|
||||
if (cassette_enable) {
|
||||
d->cassette.label = std::make_unique<ClickableLabel>();
|
||||
d->cassette.setEmpty(QString(cassette_fname).isEmpty());
|
||||
connect((ClickableLabel*)d->cassette.label.get(), &ClickableLabel::clicked, [this](QPoint pos) {
|
||||
connect((ClickableLabel*)d->cassette.label.get(), &ClickableLabel::clicked, [](QPoint pos) {
|
||||
MediaMenu::ptr->cassetteMenu->popup(pos - QPoint(0, MediaMenu::ptr->cassetteMenu->sizeHint().height()));
|
||||
});
|
||||
d->cassette.label->setToolTip(MediaMenu::ptr->cassetteMenu->title());
|
||||
@@ -369,7 +369,7 @@ void MachineStatus::refresh(QStatusBar* sbar) {
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
d->cartridge[i].label = std::make_unique<ClickableLabel>();
|
||||
d->cartridge[i].setEmpty(QString(cart_fns[i]).isEmpty());
|
||||
connect((ClickableLabel*)d->cartridge[i].label.get(), &ClickableLabel::clicked, [this, i](QPoint pos) {
|
||||
connect((ClickableLabel*)d->cartridge[i].label.get(), &ClickableLabel::clicked, [i](QPoint pos) {
|
||||
MediaMenu::ptr->cartridgeMenus[i]->popup(pos - QPoint(0, MediaMenu::ptr->cartridgeMenus[i]->sizeHint().height()));
|
||||
});
|
||||
d->cartridge[i].label->setToolTip(MediaMenu::ptr->cartridgeMenus[i]->title());
|
||||
@@ -389,7 +389,7 @@ void MachineStatus::refresh(QStatusBar* sbar) {
|
||||
d->fdd[i].label = std::make_unique<ClickableLabel>();
|
||||
d->fdd[i].setEmpty(QString(floppyfns[i]).isEmpty());
|
||||
d->fdd[i].setActive(false);
|
||||
connect((ClickableLabel*)d->fdd[i].label.get(), &ClickableLabel::clicked, [this, i](QPoint pos) {
|
||||
connect((ClickableLabel*)d->fdd[i].label.get(), &ClickableLabel::clicked, [i](QPoint pos) {
|
||||
MediaMenu::ptr->floppyMenus[i]->popup(pos - QPoint(0, MediaMenu::ptr->floppyMenus[i]->sizeHint().height()));
|
||||
});
|
||||
d->fdd[i].label->setToolTip(MediaMenu::ptr->floppyMenus[i]->title());
|
||||
@@ -400,7 +400,7 @@ void MachineStatus::refresh(QStatusBar* sbar) {
|
||||
d->cdrom[i].label = std::make_unique<ClickableLabel>();
|
||||
d->cdrom[i].setEmpty(cdrom[i].host_drive != 200 || QString(cdrom[i].image_path).isEmpty());
|
||||
d->cdrom[i].setActive(false);
|
||||
connect((ClickableLabel*)d->cdrom[i].label.get(), &ClickableLabel::clicked, [this, i](QPoint pos) {
|
||||
connect((ClickableLabel*)d->cdrom[i].label.get(), &ClickableLabel::clicked, [i](QPoint pos) {
|
||||
MediaMenu::ptr->cdromMenus[i]->popup(pos - QPoint(0, MediaMenu::ptr->cdromMenus[i]->sizeHint().height()));
|
||||
});
|
||||
d->cdrom[i].label->setToolTip(MediaMenu::ptr->cdromMenus[i]->title());
|
||||
@@ -411,7 +411,7 @@ void MachineStatus::refresh(QStatusBar* sbar) {
|
||||
d->zip[i].label = std::make_unique<ClickableLabel>();
|
||||
d->zip[i].setEmpty(QString(zip_drives[i].image_path).isEmpty());
|
||||
d->zip[i].setActive(false);
|
||||
connect((ClickableLabel*)d->zip[i].label.get(), &ClickableLabel::clicked, [this, i](QPoint pos) {
|
||||
connect((ClickableLabel*)d->zip[i].label.get(), &ClickableLabel::clicked, [i](QPoint pos) {
|
||||
MediaMenu::ptr->zipMenus[i]->popup(pos - QPoint(0, MediaMenu::ptr->zipMenus[i]->sizeHint().height()));
|
||||
});
|
||||
d->zip[i].label->setToolTip(MediaMenu::ptr->zipMenus[i]->title());
|
||||
@@ -422,7 +422,7 @@ void MachineStatus::refresh(QStatusBar* sbar) {
|
||||
d->mo[i].label = std::make_unique<ClickableLabel>();
|
||||
d->mo[i].setEmpty(QString(mo_drives[i].image_path).isEmpty());
|
||||
d->mo[i].setActive(false);
|
||||
connect((ClickableLabel*)d->mo[i].label.get(), &ClickableLabel::clicked, [this, i](QPoint pos) {
|
||||
connect((ClickableLabel*)d->mo[i].label.get(), &ClickableLabel::clicked, [i](QPoint pos) {
|
||||
MediaMenu::ptr->moMenus[i]->popup(pos - QPoint(0, MediaMenu::ptr->moMenus[i]->sizeHint().height()));
|
||||
});
|
||||
d->mo[i].label->setToolTip(MediaMenu::ptr->moMenus[i]->title());
|
||||
@@ -471,7 +471,7 @@ void MachineStatus::refresh(QStatusBar* sbar) {
|
||||
d->sound = std::make_unique<ClickableLabel>();
|
||||
d->sound->setPixmap(d->pixmaps.sound);
|
||||
|
||||
connect(d->sound.get(), &ClickableLabel::doubleClicked, d->sound.get(), [this](QPoint pos) {
|
||||
connect(d->sound.get(), &ClickableLabel::doubleClicked, d->sound.get(), [](QPoint pos) {
|
||||
SoundGain gain(main_window);
|
||||
gain.exec();
|
||||
});
|
||||
|
||||
@@ -168,6 +168,8 @@ int main(int argc, char* argv[]) {
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
fprintf(stderr, "Qt: version %s, platform \"%s\"\n", qVersion(), QApplication::platformName().toUtf8().data());
|
||||
ProgSettings::loadTranslators(&app);
|
||||
#ifdef Q_OS_WINDOWS
|
||||
auto font_name = QObject::tr("FONT_NAME");
|
||||
@@ -249,7 +251,7 @@ int main(int argc, char* argv[]) {
|
||||
{
|
||||
QObject::connect(&socket, &UnixManagerSocket::showsettings, main_window, &MainWindow::showSettings);
|
||||
QObject::connect(&socket, &UnixManagerSocket::pause, main_window, &MainWindow::togglePause);
|
||||
QObject::connect(&socket, &UnixManagerSocket::reset, main_window, &MainWindow::hardReset);
|
||||
QObject::connect(&socket, &UnixManagerSocket::resetVM, main_window, &MainWindow::hardReset);
|
||||
QObject::connect(&socket, &UnixManagerSocket::request_shutdown, main_window, &MainWindow::close);
|
||||
QObject::connect(&socket, &UnixManagerSocket::force_shutdown, [](){
|
||||
do_stop();
|
||||
|
||||
@@ -72,7 +72,7 @@ extern "C" {
|
||||
#include "qt_mediamenu.hpp"
|
||||
#include "qt_util.hpp"
|
||||
|
||||
#ifdef __unix__
|
||||
#if defined __unix__ && !defined __HAIKU__
|
||||
#ifdef WAYLAND
|
||||
#include "wl_mouse.hpp"
|
||||
#endif
|
||||
@@ -82,6 +82,32 @@ extern "C" {
|
||||
#undef KeyRelease
|
||||
#endif
|
||||
|
||||
#ifdef __HAIKU__
|
||||
#include <os/AppKit.h>
|
||||
#include <os/InterfaceKit.h>
|
||||
|
||||
extern MainWindow* main_window;
|
||||
|
||||
filter_result keyb_filter(BMessage *message, BHandler **target, BMessageFilter *filter)
|
||||
{
|
||||
if (message->what == B_KEY_DOWN || message->what == B_KEY_UP
|
||||
|| message->what == B_UNMAPPED_KEY_DOWN || message->what == B_UNMAPPED_KEY_UP)
|
||||
{
|
||||
int key_state = 0, key_scancode = 0;
|
||||
key_state = message->what == B_KEY_DOWN || message->what == B_UNMAPPED_KEY_DOWN;
|
||||
message->FindInt32("key", &key_scancode);
|
||||
QGuiApplication::postEvent(main_window, new QKeyEvent(key_state ? QEvent::KeyPress : QEvent::KeyRelease, 0, QGuiApplication::keyboardModifiers(), key_scancode, 0, 0));
|
||||
if (key_scancode == 0x68 && key_state)
|
||||
{
|
||||
QGuiApplication::postEvent(main_window, new QKeyEvent(QEvent::KeyRelease, 0, QGuiApplication::keyboardModifiers(), key_scancode, 0, 0));
|
||||
}
|
||||
}
|
||||
return B_DISPATCH_MESSAGE;
|
||||
}
|
||||
|
||||
static BMessageFilter* filter;
|
||||
#endif
|
||||
|
||||
extern void qt_mouse_capture(int);
|
||||
extern "C" void qt_blit(int x, int y, int w, int h);
|
||||
|
||||
@@ -93,6 +119,10 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||
MediaMenu::ptr = mm;
|
||||
status = std::make_unique<MachineStatus>(this);
|
||||
|
||||
#ifdef __HAIKU__
|
||||
filter = new BMessageFilter(B_PROGRAMMED_DELIVERY, B_ANY_SOURCE, keyb_filter);
|
||||
((BWindow*)this->winId())->AddFilter(filter);
|
||||
#endif
|
||||
setUnifiedTitleAndToolBarOnMac(true);
|
||||
ui->setupUi(this);
|
||||
ui->stackedWidget->setMouseTracking(true);
|
||||
@@ -234,9 +264,12 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||
ui->actionHardware_Renderer_OpenGL->setVisible(QOpenGLContext::openGLModuleType() != QOpenGLContext::LibGLES);
|
||||
if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGLES && vid_api == 1) vid_api = 0;
|
||||
|
||||
if (QApplication::platformName().contains("eglfs") && vid_api >= 1) {
|
||||
fprintf(stderr, "OpenGL renderers are unsupported on EGLFS.\n");
|
||||
if ((QApplication::platformName().contains("eglfs") || QApplication::platformName() == "haiku")) {
|
||||
if (vid_api >= 1) fprintf(stderr, "OpenGL renderers are unsupported on %s.\n", QApplication::platformName().toUtf8().data());
|
||||
vid_api = 0;
|
||||
ui->actionHardware_Renderer_OpenGL->setVisible(false);
|
||||
ui->actionHardware_Renderer_OpenGL_ES->setVisible(false);
|
||||
ui->actionOpenGL_3_0_Core->setVisible(false);
|
||||
}
|
||||
|
||||
QActionGroup* actGroup = nullptr;
|
||||
@@ -437,6 +470,11 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||
}
|
||||
|
||||
void MainWindow::closeEvent(QCloseEvent *event) {
|
||||
if (mouse_capture) {
|
||||
event->ignore();
|
||||
return;
|
||||
}
|
||||
|
||||
if (confirm_exit && confirm_exit_cmdl && cpu_thread_run)
|
||||
{
|
||||
QMessageBox questionbox(QMessageBox::Icon::Question, "86Box", tr("Are you sure you want to exit 86Box?"), QMessageBox::Yes | QMessageBox::No, this);
|
||||
@@ -464,7 +502,7 @@ void MainWindow::closeEvent(QCloseEvent *event) {
|
||||
}
|
||||
qt_nvr_save();
|
||||
config_save();
|
||||
#ifdef __unix__
|
||||
#if defined __unix__ && !defined __HAIKU__
|
||||
extern void xinput2_exit();
|
||||
if (QApplication::platformName() == "xcb") xinput2_exit();
|
||||
#endif
|
||||
@@ -1054,6 +1092,117 @@ static std::unordered_map<uint32_t, uint16_t> evdev_to_xt =
|
||||
{111, 0x153}
|
||||
};
|
||||
|
||||
#ifdef __HAIKU__
|
||||
static std::unordered_map<uint8_t, uint16_t> be_to_xt =
|
||||
{
|
||||
{0x01, 0x01},
|
||||
{B_F1_KEY, 0x3B},
|
||||
{B_F2_KEY, 0x3C},
|
||||
{B_F3_KEY, 0x3D},
|
||||
{B_F4_KEY, 0x3E},
|
||||
{B_F5_KEY, 0x3F},
|
||||
{B_F6_KEY, 0x40},
|
||||
{B_F7_KEY, 0x41},
|
||||
{B_F8_KEY, 0x42},
|
||||
{B_F9_KEY, 0x43},
|
||||
{B_F10_KEY, 0x44},
|
||||
{B_F11_KEY, 0x57},
|
||||
{B_F12_KEY, 0x58},
|
||||
{0x11, 0x29},
|
||||
{0x12, 0x02},
|
||||
{0x13, 0x03},
|
||||
{0x14, 0x04},
|
||||
{0x15, 0x05},
|
||||
{0x16, 0x06},
|
||||
{0x17, 0x07},
|
||||
{0x18, 0x08},
|
||||
{0x19, 0x09},
|
||||
{0x1A, 0x0A},
|
||||
{0x1B, 0x0B},
|
||||
{0x1C, 0x0C},
|
||||
{0x1D, 0x0D},
|
||||
{0x1E, 0x0E},
|
||||
{0x1F, 0x152},
|
||||
{0x20, 0x147},
|
||||
{0x21, 0x149},
|
||||
{0x22, 0x45},
|
||||
{0x23, 0x135},
|
||||
{0x24, 0x37},
|
||||
{0x25, 0x4A},
|
||||
{0x26, 0x0F},
|
||||
{0x27, 0x10},
|
||||
{0x28, 0x11},
|
||||
{0x29, 0x12},
|
||||
{0x2A, 0x13},
|
||||
{0x2B, 0x14},
|
||||
{0x2C, 0x15},
|
||||
{0x2D, 0x16},
|
||||
{0x2E, 0x17},
|
||||
{0x2F, 0x18},
|
||||
{0x30, 0x19},
|
||||
{0x31, 0x1A},
|
||||
{0x32, 0x1B},
|
||||
{0x33, 0x2B},
|
||||
{0x34, 0x153},
|
||||
{0x35, 0x14F},
|
||||
{0x36, 0x151},
|
||||
{0x37, 0x47},
|
||||
{0x38, 0x48},
|
||||
{0x39, 0x49},
|
||||
{0x3A, 0x4E},
|
||||
{0x3B, 0x3A},
|
||||
{0x3C, 0x1E},
|
||||
{0x3D, 0x1F},
|
||||
{0x3E, 0x20},
|
||||
{0x3F, 0x21},
|
||||
{0x40, 0x22},
|
||||
{0x41, 0x23},
|
||||
{0x42, 0x24},
|
||||
{0x43, 0x25},
|
||||
{0x44, 0x26},
|
||||
{0x45, 0x27},
|
||||
{0x46, 0x28},
|
||||
{0x47, 0x1C},
|
||||
{0x48, 0x4B},
|
||||
{0x49, 0x4C},
|
||||
{0x4A, 0x4D},
|
||||
{0x4B, 0x2A},
|
||||
{0x4C, 0x2C},
|
||||
{0x4D, 0x2D},
|
||||
{0x4E, 0x2E},
|
||||
{0x4F, 0x2F},
|
||||
{0x50, 0x30},
|
||||
{0x51, 0x31},
|
||||
{0x52, 0x32},
|
||||
{0x53, 0x33},
|
||||
{0x54, 0x34},
|
||||
{0x55, 0x35},
|
||||
{0x56, 0x36},
|
||||
{0x57, 0x148},
|
||||
{0x58, 0x51},
|
||||
{0x59, 0x50},
|
||||
{0x5A, 0x4F},
|
||||
{0x5B, 0x11C},
|
||||
{0x5C, 0x1D},
|
||||
{0x5D, 0x38},
|
||||
{0x5E, 0x39},
|
||||
{0x5F, 0x138},
|
||||
{0x60, 0x11D},
|
||||
{0x61, 0x14B},
|
||||
{0x62, 0x150},
|
||||
{0x63, 0x14D},
|
||||
{0x64, 0x52},
|
||||
{0x65, 0x53},
|
||||
|
||||
{0x0e, 0x137},
|
||||
{0x0f, 0x46},
|
||||
{0x66, 0x15B},
|
||||
{0x67, 0x15C},
|
||||
{0x68, 0x15D},
|
||||
{0x69, 0x56}
|
||||
};
|
||||
#endif
|
||||
|
||||
static std::array<uint32_t, 256>& selected_keycode = x11_to_xt_base;
|
||||
|
||||
uint16_t x11_keycode_to_keysym(uint32_t keycode)
|
||||
@@ -1063,6 +1212,8 @@ uint16_t x11_keycode_to_keysym(uint32_t keycode)
|
||||
finalkeycode = (keycode & 0xFFFF);
|
||||
#elif defined(__APPLE__)
|
||||
finalkeycode = darwin_to_xt[keycode];
|
||||
#elif defined(__HAIKU__)
|
||||
finalkeycode = be_to_xt[keycode];
|
||||
#else
|
||||
static Display* x11display = nullptr;
|
||||
if (QApplication::platformName().contains("wayland"))
|
||||
|
||||
@@ -339,6 +339,11 @@ bool NewFloppyDialog::create86f(const QString& filename, const disk_size_t& disk
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Ignore false positive warning caused by a bug on gcc */
|
||||
#if __GNUC__ >= 11
|
||||
#pragma GCC diagnostic ignored "-Wstringop-overflow"
|
||||
#endif
|
||||
|
||||
bool NewFloppyDialog::createSectorImage(const QString &filename, const disk_size_t& disk_size, FileType type)
|
||||
{
|
||||
uint32_t total_size = 0;
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
* Copyright 2022 Teemu Korhonen
|
||||
*/
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QFile>
|
||||
#include <QRegularExpression>
|
||||
#include <QStringBuilder>
|
||||
@@ -45,9 +46,14 @@ void main() {\n\
|
||||
color = texture(texsampler, tex);\n\
|
||||
}\n";
|
||||
|
||||
OpenGLOptions::OpenGLOptions(QObject *parent, bool loadConfig)
|
||||
OpenGLOptions::OpenGLOptions(QObject *parent, bool loadConfig, const QString &glslVersion)
|
||||
: QObject(parent)
|
||||
, m_glslVersion(glslVersion)
|
||||
{
|
||||
m_filter = video_filter_method == 0
|
||||
? FilterType::Nearest
|
||||
: FilterType::Linear;
|
||||
|
||||
if (!loadConfig)
|
||||
return;
|
||||
|
||||
@@ -59,10 +65,6 @@ OpenGLOptions::OpenGLOptions(QObject *parent, bool loadConfig)
|
||||
? RenderBehaviorType::SyncWithVideo
|
||||
: RenderBehaviorType::TargetFramerate;
|
||||
|
||||
m_filter = video_filter_method == 0
|
||||
? FilterType::Nearest
|
||||
: FilterType::Linear;
|
||||
|
||||
QString shaderPath(video_shader);
|
||||
|
||||
if (shaderPath.isEmpty()) {
|
||||
@@ -88,7 +90,7 @@ OpenGLOptions::save() const
|
||||
auto path = m_shaders.first().path().toLocal8Bit();
|
||||
|
||||
if (!path.isEmpty())
|
||||
strcpy(video_shader, path.constData());
|
||||
qstrncpy(video_shader, path.constData(), sizeof(video_shader));
|
||||
else
|
||||
video_shader[0] = '\0';
|
||||
}
|
||||
@@ -143,11 +145,14 @@ OpenGLOptions::addShader(const QString &path)
|
||||
|
||||
shader_file.close();
|
||||
|
||||
/* Remove parameter lines */
|
||||
shader_text.remove(QRegularExpression("^\\s*#pragma parameter.*?\\n", QRegularExpression::MultilineOption));
|
||||
|
||||
QRegularExpression version("^\\s*(#version\\s+\\w+)", QRegularExpression::MultilineOption);
|
||||
|
||||
auto match = version.match(shader_text);
|
||||
|
||||
QString version_line("#version 130");
|
||||
QString version_line(m_glslVersion);
|
||||
|
||||
if (match.hasMatch()) {
|
||||
/* Extract existing version and remove it. */
|
||||
@@ -155,10 +160,6 @@ OpenGLOptions::addShader(const QString &path)
|
||||
shader_text.remove(version);
|
||||
}
|
||||
|
||||
if (QOpenGLContext::currentContext() && QOpenGLContext::currentContext()->isOpenGLES()) {
|
||||
/* Force #version 300 es (the default of #version 100 es is too old and too limited) */
|
||||
version_line = "#version 300 es";
|
||||
}
|
||||
auto shader = new QOpenGLShaderProgram(this);
|
||||
|
||||
auto throw_shader_error = [path, shader](const QString &what) {
|
||||
@@ -169,10 +170,12 @@ OpenGLOptions::addShader(const QString &path)
|
||||
.toStdString());
|
||||
};
|
||||
|
||||
if (!shader->addShaderFromSourceCode(QOpenGLShader::Vertex, version_line % "\n#extension GL_ARB_shading_language_420pack : enable\n" % "\n#define VERTEX\n" % shader_text))
|
||||
static const char *extension = "\n#extension GL_ARB_shading_language_420pack : enable\n";
|
||||
|
||||
if (!shader->addShaderFromSourceCode(QOpenGLShader::Vertex, version_line % extension % "\n#define VERTEX\n#line 1\n" % shader_text))
|
||||
throw_shader_error(tr("Error compiling vertex shader in file \"%1\""));
|
||||
|
||||
if (!shader->addShaderFromSourceCode(QOpenGLShader::Fragment, version_line % "\n#extension GL_ARB_shading_language_420pack : enable\n" "\n#define FRAGMENT\n" % shader_text))
|
||||
if (!shader->addShaderFromSourceCode(QOpenGLShader::Fragment, version_line % extension % "\n#define FRAGMENT\n#line 1\n" % shader_text))
|
||||
throw_shader_error(tr("Error compiling fragment shader in file \"%1\""));
|
||||
|
||||
if (!shader->link())
|
||||
@@ -184,13 +187,9 @@ OpenGLOptions::addShader(const QString &path)
|
||||
void
|
||||
OpenGLOptions::addDefaultShader()
|
||||
{
|
||||
QString version = QOpenGLContext::currentContext() && QOpenGLContext::currentContext()->isOpenGLES()
|
||||
? "#version 300 es\n"
|
||||
: "#version 130\n";
|
||||
|
||||
auto shader = new QOpenGLShaderProgram(this);
|
||||
shader->addShaderFromSourceCode(QOpenGLShader::Vertex, version % vertex_shader);
|
||||
shader->addShaderFromSourceCode(QOpenGLShader::Fragment, version % fragment_shader);
|
||||
shader->addShaderFromSourceCode(QOpenGLShader::Vertex, m_glslVersion % "\n" % vertex_shader);
|
||||
shader->addShaderFromSourceCode(QOpenGLShader::Fragment, m_glslVersion % "\n" % fragment_shader);
|
||||
shader->link();
|
||||
m_shaders << OpenGLShaderPass(shader, QString());
|
||||
}
|
||||
|
||||
@@ -72,14 +72,14 @@ public:
|
||||
enum FilterType { Nearest,
|
||||
Linear };
|
||||
|
||||
OpenGLOptions(QObject *parent = nullptr, bool loadConfig = false);
|
||||
OpenGLOptions(QObject *parent, bool loadConfig, const QString &glslVersion);
|
||||
|
||||
RenderBehaviorType renderBehavior() const { return m_renderBehavior; }
|
||||
int framerate() const { return m_framerate; }
|
||||
bool vSync() const { return m_vsync; }
|
||||
FilterType filter() const;
|
||||
|
||||
const QList<OpenGLShaderPass> &shaders() const { return m_shaders; };
|
||||
const QList<OpenGLShaderPass> &shaders() const { return m_shaders; }
|
||||
|
||||
void setRenderBehavior(RenderBehaviorType value);
|
||||
void setFrameRate(int value);
|
||||
@@ -95,6 +95,7 @@ private:
|
||||
bool m_vsync = false;
|
||||
FilterType m_filter = Nearest;
|
||||
QList<OpenGLShaderPass> m_shaders;
|
||||
QString m_glslVersion;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -24,9 +24,10 @@
|
||||
#include "qt_util.hpp"
|
||||
#include "ui_qt_opengloptionsdialog.h"
|
||||
|
||||
OpenGLOptionsDialog::OpenGLOptionsDialog(QWidget *parent, const OpenGLOptions &options)
|
||||
OpenGLOptionsDialog::OpenGLOptionsDialog(QWidget *parent, const OpenGLOptions &options, std::function<OpenGLOptions *()> optionsFactory)
|
||||
: QDialog(parent)
|
||||
, ui(new Ui::OpenGLOptionsDialog)
|
||||
, createOptions(optionsFactory)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
@@ -54,7 +55,7 @@ OpenGLOptionsDialog::~OpenGLOptionsDialog()
|
||||
void
|
||||
OpenGLOptionsDialog::accept()
|
||||
{
|
||||
auto options = new OpenGLOptions();
|
||||
auto options = createOptions();
|
||||
|
||||
options->setRenderBehavior(
|
||||
ui->syncWithVideo->isChecked()
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
#include <functional>
|
||||
|
||||
#include "qt_opengloptions.hpp"
|
||||
|
||||
namespace Ui {
|
||||
@@ -29,7 +31,7 @@ class OpenGLOptionsDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit OpenGLOptionsDialog(QWidget *parent, const OpenGLOptions &options);
|
||||
explicit OpenGLOptionsDialog(QWidget *parent, const OpenGLOptions &options, std::function<OpenGLOptions *()> optionsFactory);
|
||||
~OpenGLOptionsDialog();
|
||||
|
||||
signals:
|
||||
@@ -41,6 +43,8 @@ public slots:
|
||||
private:
|
||||
Ui::OpenGLOptionsDialog *ui;
|
||||
|
||||
std::function<OpenGLOptions *()> createOptions;
|
||||
|
||||
private slots:
|
||||
void on_addShader_clicked();
|
||||
};
|
||||
|
||||
@@ -18,8 +18,8 @@
|
||||
#include <QMessageBox>
|
||||
#include <QOpenGLShaderProgram>
|
||||
#include <QOpenGLTexture>
|
||||
#include <QStringBuilder>
|
||||
#include <QSurfaceFormat>
|
||||
#include <QOpenGLTexture>
|
||||
|
||||
#include <cmath>
|
||||
|
||||
@@ -42,20 +42,18 @@ OpenGLRenderer::OpenGLRenderer(QWidget *parent)
|
||||
|
||||
QSurfaceFormat format;
|
||||
|
||||
#ifdef Q_OS_MACOS
|
||||
format.setVersion(4, 1);
|
||||
#else
|
||||
format.setVersion(3, 2);
|
||||
#endif
|
||||
format.setProfile(QSurfaceFormat::OpenGLContextProfile::CoreProfile);
|
||||
format.setMajorVersion(3);
|
||||
format.setMinorVersion(0);
|
||||
|
||||
if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGLES)
|
||||
format.setRenderableType(QSurfaceFormat::OpenGLES);
|
||||
|
||||
setFormat(format);
|
||||
|
||||
context = new QOpenGLContext(this);
|
||||
|
||||
context->setFormat(format);
|
||||
|
||||
context->create();
|
||||
|
||||
parentWidget = parent;
|
||||
|
||||
source.setRect(0, 0, INIT_WIDTH, INIT_HEIGHT);
|
||||
@@ -108,64 +106,98 @@ OpenGLRenderer::event(QEvent *event)
|
||||
void
|
||||
OpenGLRenderer::initialize()
|
||||
{
|
||||
if (!context->makeCurrent(this)) {
|
||||
/* TODO: This could be done much better */
|
||||
QMessageBox::critical((QWidget *) qApp->findChild<QWindow *>(), tr("Error initializing OpenGL"), tr("Error setting OpenGL context. Falling back to software rendering."));
|
||||
try {
|
||||
context = new QOpenGLContext(this);
|
||||
|
||||
context->setFormat(format());
|
||||
|
||||
if (!context->create())
|
||||
throw opengl_init_error(tr("Couldn't create OpenGL context."));
|
||||
|
||||
if (!context->makeCurrent(this))
|
||||
throw opengl_init_error(tr("Couldn't switch to OpenGL context."));
|
||||
|
||||
auto version = context->format().version();
|
||||
|
||||
if (version.first < 3)
|
||||
throw opengl_init_error(tr("OpenGL version 3.0 or greater is required. Current version is %1.%2").arg(version.first).arg(version.second));
|
||||
|
||||
initializeOpenGLFunctions();
|
||||
|
||||
/* Prepare the shader version string */
|
||||
glslVersion = reinterpret_cast<const char *>(glGetString(GL_SHADING_LANGUAGE_VERSION));
|
||||
glslVersion.truncate(4);
|
||||
glslVersion.remove('.');
|
||||
glslVersion.prepend("#version ");
|
||||
if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGLES)
|
||||
glslVersion.append(" es");
|
||||
else if (context->format().profile() == QSurfaceFormat::CoreProfile)
|
||||
glslVersion.append(" core");
|
||||
|
||||
initializeExtensions();
|
||||
|
||||
initializeBuffers();
|
||||
|
||||
/* Vertex, texture 2d coordinates and color (white) making a quad as triangle strip */
|
||||
const GLfloat surface[] = {
|
||||
-1.f, 1.f, 0.f, 0.f, 1.f, 1.f, 1.f, 1.f,
|
||||
1.f, 1.f, 1.f, 0.f, 1.f, 1.f, 1.f, 1.f,
|
||||
-1.f, -1.f, 0.f, 1.f, 1.f, 1.f, 1.f, 1.f,
|
||||
1.f, -1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f
|
||||
};
|
||||
|
||||
glGenVertexArrays(1, &vertexArrayID);
|
||||
|
||||
glBindVertexArray(vertexArrayID);
|
||||
|
||||
glGenBuffers(1, &vertexBufferID);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferID);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(surface), surface, GL_STATIC_DRAW);
|
||||
|
||||
glGenTextures(1, &textureID);
|
||||
glBindTexture(GL_TEXTURE_2D, textureID);
|
||||
|
||||
const GLfloat border_color[] = { 0.f, 0.f, 0.f, 1.f };
|
||||
|
||||
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, border_color);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, QOpenGLTexture::RGBA8_UNorm, INIT_WIDTH, INIT_HEIGHT, 0, QOpenGLTexture::BGRA, QOpenGLTexture::UInt32_RGBA8_Rev, NULL);
|
||||
|
||||
options = new OpenGLOptions(this, true, glslVersion);
|
||||
|
||||
applyOptions();
|
||||
|
||||
glClearColor(0.f, 0.f, 0.f, 1.f);
|
||||
|
||||
glViewport(
|
||||
destination.x(),
|
||||
destination.y(),
|
||||
destination.width() * devicePixelRatio(),
|
||||
destination.height() * devicePixelRatio());
|
||||
|
||||
GLenum error = glGetError();
|
||||
if (error != GL_NO_ERROR)
|
||||
throw opengl_init_error(tr("OpenGL initialization failed. Error %1.").arg(error));
|
||||
|
||||
isInitialized = true;
|
||||
|
||||
emit initialized();
|
||||
|
||||
} catch (const opengl_init_error &e) {
|
||||
/* Mark all buffers as in use */
|
||||
for (auto &flag : buf_usage)
|
||||
flag.test_and_set();
|
||||
|
||||
QMessageBox::critical((QWidget *) qApp->findChild<QWindow *>(), tr("Error initializing OpenGL"), e.what() % tr("\nFalling back to software rendering."));
|
||||
|
||||
context->doneCurrent();
|
||||
isFinalized = true;
|
||||
isInitialized = true;
|
||||
|
||||
emit errorInitializing();
|
||||
return;
|
||||
}
|
||||
|
||||
initializeOpenGLFunctions();
|
||||
|
||||
setupExtensions();
|
||||
|
||||
setupBuffers();
|
||||
|
||||
/* Vertex, texture 2d coordinates and color (white) making a quad as triangle strip */
|
||||
const GLfloat surface[] = {
|
||||
-1.f, 1.f, 0.f, 0.f, 1.f, 1.f, 1.f, 1.f,
|
||||
1.f, 1.f, 1.f, 0.f, 1.f, 1.f, 1.f, 1.f,
|
||||
-1.f, -1.f, 0.f, 1.f, 1.f, 1.f, 1.f, 1.f,
|
||||
1.f, -1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f
|
||||
};
|
||||
|
||||
glGenVertexArrays(1, &vertexArrayID);
|
||||
|
||||
glBindVertexArray(vertexArrayID);
|
||||
|
||||
glGenBuffers(1, &vertexBufferID);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferID);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(surface), surface, GL_STATIC_DRAW);
|
||||
|
||||
glGenTextures(1, &textureID);
|
||||
glBindTexture(GL_TEXTURE_2D, textureID);
|
||||
|
||||
const GLfloat border_color[] = { 0.f, 0.f, 0.f, 1.f };
|
||||
|
||||
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, border_color);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, QOpenGLTexture::RGBA8_UNorm, INIT_WIDTH, INIT_HEIGHT, 0, QOpenGLTexture::BGRA, QOpenGLTexture::UInt32_RGBA8_Rev, NULL);
|
||||
|
||||
options = new OpenGLOptions(this, true);
|
||||
|
||||
applyOptions();
|
||||
|
||||
glClearColor(0.f, 0.f, 0.f, 1.f);
|
||||
|
||||
glViewport(
|
||||
destination.x(),
|
||||
destination.y(),
|
||||
destination.width(),
|
||||
destination.height());
|
||||
|
||||
isInitialized = true;
|
||||
|
||||
emit initialized();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -174,6 +206,8 @@ OpenGLRenderer::finalize()
|
||||
if (isFinalized)
|
||||
return;
|
||||
|
||||
renderTimer->stop();
|
||||
|
||||
context->makeCurrent(this);
|
||||
|
||||
if (hasBufferStorage)
|
||||
@@ -195,7 +229,7 @@ OpenGLRenderer::finalize()
|
||||
QDialog *
|
||||
OpenGLRenderer::getOptions(QWidget *parent)
|
||||
{
|
||||
auto dialog = new OpenGLOptionsDialog(parent, *options);
|
||||
auto dialog = new OpenGLOptionsDialog(parent, *options, [this]() { return new OpenGLOptions(this, false, glslVersion); });
|
||||
|
||||
connect(dialog, &OpenGLOptionsDialog::optionsChanged, this, &OpenGLRenderer::updateOptions);
|
||||
|
||||
@@ -203,7 +237,7 @@ OpenGLRenderer::getOptions(QWidget *parent)
|
||||
}
|
||||
|
||||
void
|
||||
OpenGLRenderer::setupExtensions()
|
||||
OpenGLRenderer::initializeExtensions()
|
||||
{
|
||||
#ifndef NO_BUFFER_STORAGE
|
||||
if (context->hasExtension("GL_ARB_buffer_storage")) {
|
||||
@@ -215,7 +249,7 @@ OpenGLRenderer::setupExtensions()
|
||||
}
|
||||
|
||||
void
|
||||
OpenGLRenderer::setupBuffers()
|
||||
OpenGLRenderer::initializeBuffers()
|
||||
{
|
||||
glGenBuffers(1, &unpackBufferID);
|
||||
|
||||
@@ -232,6 +266,9 @@ OpenGLRenderer::setupBuffers()
|
||||
/* Fallback; create our own buffer. */
|
||||
unpackBuffer = malloc(BUFFERBYTES * BUFFERCOUNT);
|
||||
|
||||
if (unpackBuffer == nullptr)
|
||||
throw opengl_init_error(tr("Allocating memory for unpack buffer failed."));
|
||||
|
||||
glBufferData(GL_PIXEL_UNPACK_BUFFER, BUFFERBYTES * BUFFERCOUNT, NULL, GL_STREAM_DRAW);
|
||||
}
|
||||
}
|
||||
@@ -375,7 +412,7 @@ OpenGLRenderer::onBlit(int buf_idx, int x, int y, int w, int h)
|
||||
|
||||
/* Resize the texture */
|
||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, (GLenum)QOpenGLTexture::RGBA8_UNorm, source.width(), source.height(), 0, (GLenum)QOpenGLTexture::BGRA, (GLenum)QOpenGLTexture::UInt32_RGBA8_Rev, NULL);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, (GLenum) QOpenGLTexture::RGBA8_UNorm, source.width(), source.height(), 0, (GLenum) QOpenGLTexture::BGRA, (GLenum) QOpenGLTexture::UInt32_RGBA8_Rev, NULL);
|
||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, unpackBufferID);
|
||||
}
|
||||
|
||||
@@ -384,7 +421,7 @@ OpenGLRenderer::onBlit(int buf_idx, int x, int y, int w, int h)
|
||||
|
||||
glPixelStorei(GL_UNPACK_SKIP_PIXELS, BUFFERPIXELS * buf_idx + y * ROW_LENGTH + x);
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, ROW_LENGTH);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, (GLenum)QOpenGLTexture::BGRA, (GLenum)QOpenGLTexture::UInt32_RGBA8_Rev, NULL);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, (GLenum) QOpenGLTexture::BGRA, (GLenum) QOpenGLTexture::UInt32_RGBA8_Rev, NULL);
|
||||
|
||||
/* TODO: check if fence sync is implementable here and still has any benefit. */
|
||||
glFinish();
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#endif
|
||||
|
||||
#include <atomic>
|
||||
#include <stdexcept>
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
|
||||
@@ -76,6 +77,8 @@ private:
|
||||
OpenGLOptions *options;
|
||||
QTimer *renderTimer;
|
||||
|
||||
QString glslVersion;
|
||||
|
||||
bool isInitialized = false;
|
||||
bool isFinalized = false;
|
||||
|
||||
@@ -90,8 +93,8 @@ private:
|
||||
void *unpackBuffer = nullptr;
|
||||
|
||||
void initialize();
|
||||
void setupExtensions();
|
||||
void setupBuffers();
|
||||
void initializeExtensions();
|
||||
void initializeBuffers();
|
||||
void applyOptions();
|
||||
void applyShader(const OpenGLShaderPass &shader);
|
||||
bool notReady() const { return !isInitialized || isFinalized; }
|
||||
@@ -107,4 +110,12 @@ private slots:
|
||||
void updateOptions(OpenGLOptions *newOptions);
|
||||
};
|
||||
|
||||
class opengl_init_error : public std::runtime_error {
|
||||
public:
|
||||
opengl_init_error(const QString &what)
|
||||
: std::runtime_error(what.toStdString())
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -74,11 +74,13 @@ private:
|
||||
|
||||
extern "C" {
|
||||
#ifdef Q_OS_WINDOWS
|
||||
#define NOMINMAX
|
||||
#include <windows.h>
|
||||
#include <86box/win.h>
|
||||
# ifndef NOMINMAX
|
||||
# define NOMINMAX
|
||||
# endif
|
||||
# include <windows.h>
|
||||
# include <86box/win.h>
|
||||
#else
|
||||
#include <strings.h>
|
||||
# include <strings.h>
|
||||
#endif
|
||||
#include <86box/86box.h>
|
||||
#include <86box/device.h>
|
||||
@@ -238,10 +240,12 @@ plat_path_abs(char *path)
|
||||
void
|
||||
plat_path_normalize(char* path)
|
||||
{
|
||||
#ifdef Q_OS_WINDOWS
|
||||
while (*path++ != 0)
|
||||
{
|
||||
if (*path == '\\') *path = '/';
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
@@ -529,9 +533,11 @@ void ProgSettings::reloadStrings()
|
||||
translatedstrings[IDS_2078] = QCoreApplication::translate("", "Press F8+F12 to release mouse").replace("F8+F12", MOUSE_CAPTURE_KEYSEQ).replace("CTRL-END", QLocale::system().name() == "de_DE" ? "Strg+Ende" : "CTRL-END").toStdWString();
|
||||
translatedstrings[IDS_2079] = QCoreApplication::translate("", "Press F8+F12 or middle button to release mouse").replace("F8+F12", MOUSE_CAPTURE_KEYSEQ).replace("CTRL-END", QLocale::system().name() == "de_DE" ? "Strg+Ende" : "CTRL-END").toStdWString();
|
||||
translatedstrings[IDS_2080] = QCoreApplication::translate("", "Failed to initialize FluidSynth").toStdWString();
|
||||
translatedstrings[IDS_2130] = QCoreApplication::translate("", "Invalid configuration").toStdWString();
|
||||
translatedstrings[IDS_4099] = QCoreApplication::translate("", "MFM/RLL or ESDI CD-ROM drives never existed").toStdWString();
|
||||
translatedstrings[IDS_2093] = QCoreApplication::translate("", "Failed to set up PCap").toStdWString();
|
||||
translatedstrings[IDS_2094] = QCoreApplication::translate("", "No PCap devices found").toStdWString();
|
||||
translatedstrings[IDS_2095] = QCoreApplication::translate("", "Invalid PCap device").toStdWString();
|
||||
translatedstrings[IDS_2110] = QCoreApplication::translate("", "Unable to initialize FreeType").toStdWString();
|
||||
translatedstrings[IDS_2111] = QCoreApplication::translate("", "Unable to initialize SDL, libsdl2 is required").toStdWString();
|
||||
translatedstrings[IDS_2129] = QCoreApplication::translate("", "Make sure libpcap is installed and that you are on a libpcap-compatible network connection.").toStdWString();
|
||||
@@ -539,6 +545,7 @@ void ProgSettings::reloadStrings()
|
||||
translatedstrings[IDS_2063] = QCoreApplication::translate("", "Machine \"%hs\" is not available due to missing ROMs in the roms/machines directory. Switching to an available machine.").toStdWString();
|
||||
translatedstrings[IDS_2064] = QCoreApplication::translate("", "Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card.").toStdWString();
|
||||
translatedstrings[IDS_2128] = QCoreApplication::translate("", "Hardware not available").toStdWString();
|
||||
translatedstrings[IDS_2142] = QCoreApplication::translate("", "Monitor in sleep mode").toStdWString();
|
||||
translatedstrings[IDS_2120] = QCoreApplication::translate("", "No ROMs found").toStdWString();
|
||||
translatedstrings[IDS_2056] = QCoreApplication::translate("", "86Box could not find any usable ROM images.\n\nPlease <a href=\"https://github.com/86Box/roms/releases/latest\">download</a> a ROM set and extract it into the \"roms\" directory.").replace("roms", ROMDIR).toStdWString();
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ RendererStack::RendererStack(QWidget *parent)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
#ifdef __unix__
|
||||
#if defined __unix__ && !defined __HAIKU__
|
||||
# ifdef WAYLAND
|
||||
if (QApplication::platformName().contains("wayland")) {
|
||||
wl_init();
|
||||
@@ -104,7 +104,7 @@ RendererStack::mousePoll()
|
||||
mousedata.deltax = mousedata.deltay = mousedata.deltaz = 0;
|
||||
mouse_buttons = mousedata.mousebuttons;
|
||||
|
||||
# ifdef __unix__
|
||||
# if defined __unix__ && !defined __HAIKU__
|
||||
# ifdef WAYLAND
|
||||
if (QApplication::platformName().contains("wayland"))
|
||||
wl_mouse_poll();
|
||||
@@ -206,6 +206,7 @@ RendererStack::leaveEvent(QEvent *event)
|
||||
}
|
||||
if (!mouse_capture)
|
||||
return;
|
||||
QCursor::setPos(mapToGlobal(QPoint(width() / 2, height() / 2)));
|
||||
ignoreNextMouseEvent = 2;
|
||||
event->accept();
|
||||
}
|
||||
@@ -237,7 +238,11 @@ RendererStack::createRenderer(Renderer renderer)
|
||||
auto sw = new SoftwareRenderer(this);
|
||||
rendererWindow = sw;
|
||||
connect(this, &RendererStack::blitToRenderer, sw, &SoftwareRenderer::onBlit, Qt::QueuedConnection);
|
||||
#ifdef __HAIKU__
|
||||
current.reset(sw);
|
||||
#else
|
||||
current.reset(this->createWindowContainer(sw, this));
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
case Renderer::OpenGL:
|
||||
@@ -272,6 +277,7 @@ RendererStack::createRenderer(Renderer renderer)
|
||||
});
|
||||
connect(hw, &OpenGLRenderer::errorInitializing, [=]() {
|
||||
/* Renderer could initialize, fallback to software. */
|
||||
imagebufs = {};
|
||||
endblit();
|
||||
QTimer::singleShot(0, this, [this]() { switchRenderer(Renderer::Software); });
|
||||
});
|
||||
@@ -299,7 +305,7 @@ RendererStack::createRenderer(Renderer renderer)
|
||||
void
|
||||
RendererStack::blit(int x, int y, int w, int h)
|
||||
{
|
||||
if ((w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (buffer32 == NULL) || std::get<std::atomic_flag *>(imagebufs[currentBuf])->test_and_set()) {
|
||||
if ((w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (buffer32 == NULL) || imagebufs.empty() || std::get<std::atomic_flag *>(imagebufs[currentBuf])->test_and_set()) {
|
||||
video_blit_complete();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -218,9 +218,8 @@ SettingsBusTracking::scsi_bus_full()
|
||||
void
|
||||
SettingsBusTracking::device_track(int set, uint8_t dev_type, int bus, int channel)
|
||||
{
|
||||
int i, element;
|
||||
int element;
|
||||
uint64_t mask;
|
||||
uint8_t count = 0;
|
||||
|
||||
switch (bus) {
|
||||
case HDD_BUS_MFM:
|
||||
|
||||
@@ -54,7 +54,6 @@ void SettingsInput::onCurrentMachineChanged(int machineId) {
|
||||
// win_settings_video_proc, WM_INITDIALOG
|
||||
this->machineId = machineId;
|
||||
|
||||
const auto* machine = &machines[machineId];
|
||||
auto* mouseModel = ui->comboBoxMouse->model();
|
||||
auto removeRows = mouseModel->rowCount();
|
||||
|
||||
|
||||
@@ -80,7 +80,6 @@ void SettingsNetwork::save() {
|
||||
|
||||
void SettingsNetwork::onCurrentMachineChanged(int machineId) {
|
||||
this->machineId = machineId;
|
||||
auto* machine = &machines[machineId];
|
||||
|
||||
auto* model = ui->comboBoxAdapter->model();
|
||||
auto removeRows = model->rowCount();
|
||||
|
||||
@@ -45,7 +45,7 @@ SettingsSound::~SettingsSound()
|
||||
|
||||
void SettingsSound::save() {
|
||||
sound_card_current = ui->comboBoxSoundCard->currentData().toInt();
|
||||
midi_device_current = ui->comboBoxMidiOut->currentData().toInt();
|
||||
midi_output_device_current = ui->comboBoxMidiOut->currentData().toInt();
|
||||
midi_input_device_current = ui->comboBoxMidiIn->currentData().toInt();
|
||||
mpu401_standalone_enable = ui->checkBoxMPU401->isChecked() ? 1 : 0;
|
||||
SSI2001 = ui->checkBoxSSI2001->isChecked() ? 1 : 0;;
|
||||
@@ -95,14 +95,14 @@ void SettingsSound::onCurrentMachineChanged(int machineId) {
|
||||
c = 0;
|
||||
selectedRow = 0;
|
||||
while (true) {
|
||||
QString name = DeviceConfig::DeviceName(midi_device_getdevice(c), midi_device_get_internal_name(c), 0);
|
||||
QString name = DeviceConfig::DeviceName(midi_out_device_getdevice(c), midi_out_device_get_internal_name(c), 0);
|
||||
if (name.isEmpty()) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (midi_device_available(c)) {
|
||||
if (midi_out_device_available(c)) {
|
||||
int row = Models::AddEntry(model, name, c);
|
||||
if (c == midi_device_current) {
|
||||
if (c == midi_output_device_current) {
|
||||
selectedRow = row - removeRows;
|
||||
}
|
||||
}
|
||||
@@ -118,7 +118,7 @@ void SettingsSound::onCurrentMachineChanged(int machineId) {
|
||||
c = 0;
|
||||
selectedRow = 0;
|
||||
while (true) {
|
||||
QString name = DeviceConfig::DeviceName(midi_in_device_getdevice(c), midi_device_get_internal_name(c), 0);
|
||||
QString name = DeviceConfig::DeviceName(midi_in_device_getdevice(c), midi_in_device_get_internal_name(c), 0);
|
||||
if (name.isEmpty()) {
|
||||
break;
|
||||
}
|
||||
@@ -154,7 +154,7 @@ void SettingsSound::onCurrentMachineChanged(int machineId) {
|
||||
}
|
||||
|
||||
static bool allowMpu401(Ui::SettingsSound *ui) {
|
||||
QString midiOut = midi_device_get_internal_name(ui->comboBoxMidiOut->currentData().toInt());
|
||||
QString midiOut = midi_out_device_get_internal_name(ui->comboBoxMidiOut->currentData().toInt());
|
||||
QString midiIn = midi_in_device_get_internal_name(ui->comboBoxMidiIn->currentData().toInt());
|
||||
|
||||
if (midiOut.isEmpty()) {
|
||||
@@ -184,13 +184,13 @@ void SettingsSound::on_comboBoxMidiOut_currentIndexChanged(int index) {
|
||||
if (index < 0) {
|
||||
return;
|
||||
}
|
||||
ui->pushButtonConfigureMidiOut->setEnabled(midi_device_has_config(ui->comboBoxMidiOut->currentData().toInt()));
|
||||
ui->pushButtonConfigureMidiOut->setEnabled(midi_out_device_has_config(ui->comboBoxMidiOut->currentData().toInt()));
|
||||
ui->checkBoxMPU401->setEnabled(allowMpu401(ui) && (machine_has_bus(machineId, MACHINE_BUS_ISA) || machine_has_bus(machineId, MACHINE_BUS_MCA)));
|
||||
ui->pushButtonConfigureMPU401->setEnabled(allowMpu401(ui) && ui->checkBoxMPU401->isChecked());
|
||||
}
|
||||
|
||||
void SettingsSound::on_pushButtonConfigureMidiOut_clicked() {
|
||||
DeviceConfig::ConfigureDevice(midi_device_getdevice(ui->comboBoxMidiOut->currentData().toInt()), 0, qobject_cast<Settings*>(Settings::settings));
|
||||
DeviceConfig::ConfigureDevice(midi_out_device_getdevice(ui->comboBoxMidiOut->currentData().toInt()), 0, qobject_cast<Settings*>(Settings::settings));
|
||||
}
|
||||
|
||||
void SettingsSound::on_comboBoxMidiIn_currentIndexChanged(int index) {
|
||||
|
||||
@@ -64,7 +64,6 @@ void SettingsStorageControllers::save() {
|
||||
|
||||
void SettingsStorageControllers::onCurrentMachineChanged(int machineId) {
|
||||
this->machineId = machineId;
|
||||
auto* machine = &machines[machineId];
|
||||
|
||||
/*HD controller config*/
|
||||
auto* model = ui->comboBoxHD->model();
|
||||
|
||||
@@ -28,9 +28,13 @@ extern "C" {
|
||||
}
|
||||
|
||||
SoftwareRenderer::SoftwareRenderer(QWidget *parent)
|
||||
#ifdef __HAIKU__
|
||||
: QWidget(parent)
|
||||
#else
|
||||
: QRasterWindow(parent->windowHandle())
|
||||
#endif
|
||||
{
|
||||
parentWidget = parent;
|
||||
RendererCommon::parentWidget = parent;
|
||||
|
||||
images[0] = std::make_unique<QImage>(QSize(2048, 2048), QImage::Format_RGB32);
|
||||
images[1] = std::make_unique<QImage>(QSize(2048, 2048), QImage::Format_RGB32);
|
||||
@@ -38,6 +42,9 @@ SoftwareRenderer::SoftwareRenderer(QWidget *parent)
|
||||
buf_usage = std::vector<std::atomic_flag>(2);
|
||||
buf_usage[0].clear();
|
||||
buf_usage[1].clear();
|
||||
#ifdef __HAIKU__
|
||||
this->setMouseTracking(true);
|
||||
#endif
|
||||
}
|
||||
|
||||
void SoftwareRenderer::paintEvent(QPaintEvent* event) {
|
||||
@@ -60,13 +67,22 @@ void SoftwareRenderer::onBlit(int buf_idx, int x, int y, int w, int h) {
|
||||
|
||||
void SoftwareRenderer::resizeEvent(QResizeEvent *event) {
|
||||
onResize(width(), height());
|
||||
#ifdef __HAIKU__
|
||||
QWidget::resizeEvent(event);
|
||||
#else
|
||||
QRasterWindow::resizeEvent(event);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool SoftwareRenderer::event(QEvent *event)
|
||||
{
|
||||
bool res = false;
|
||||
if (!eventDelegate(event, res)) return QRasterWindow::event(event);
|
||||
if (!eventDelegate(event, res))
|
||||
#ifdef __HAIKU__
|
||||
return QWidget::event(event);
|
||||
#else
|
||||
return QRasterWindow::event(event);
|
||||
#endif
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,13 @@
|
||||
#include <atomic>
|
||||
#include "qt_renderercommon.hpp"
|
||||
|
||||
class SoftwareRenderer : public QRasterWindow, public RendererCommon
|
||||
class SoftwareRenderer :
|
||||
#ifdef __HAIKU__
|
||||
public QWidget,
|
||||
#else
|
||||
public QRasterWindow,
|
||||
#endif
|
||||
public RendererCommon
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
@@ -34,6 +34,7 @@ extern "C" {
|
||||
|
||||
#include <86box/plat.h>
|
||||
#include <86box/ui.h>
|
||||
#include <86box/mouse.h>
|
||||
|
||||
void
|
||||
plat_delay_ms(uint32_t count)
|
||||
@@ -72,6 +73,9 @@ void plat_setfullscreen(int on) {
|
||||
}
|
||||
|
||||
void plat_mouse_capture(int on) {
|
||||
if (!kbd_req_capture && (mouse_type == MOUSE_TYPE_NONE))
|
||||
return;
|
||||
|
||||
main_window->setMouseCapture(on > 0 ? true : false);
|
||||
}
|
||||
|
||||
|
||||
@@ -31,8 +31,7 @@ void UnixManagerSocket::readyToRead()
|
||||
QByteArray line = readLine();
|
||||
if (line.size())
|
||||
{
|
||||
line.resize(line.size() - 2);
|
||||
line.push_back('\0');
|
||||
line.resize(line.size() - 1);
|
||||
if (line == "showsettings")
|
||||
{
|
||||
emit showsettings();
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
#include <Windows.h>
|
||||
#include <86box/win.h>
|
||||
|
||||
bool WindowsManagerFilter::nativeEventFilter(const QByteArray &eventType, void *message, long *result)
|
||||
bool WindowsManagerFilter::nativeEventFilter(const QByteArray &eventType, void *message, result_t *result)
|
||||
{
|
||||
if (eventType == "windows_generic_MSG")
|
||||
{
|
||||
|
||||
@@ -110,19 +110,25 @@ WindowsRawInputFilter::~WindowsRawInputFilter()
|
||||
RegisterRawInputDevices(rid, 2, sizeof(rid[0]));
|
||||
}
|
||||
|
||||
bool WindowsRawInputFilter::nativeEventFilter(const QByteArray &eventType, void *message, long *result)
|
||||
bool WindowsRawInputFilter::nativeEventFilter(const QByteArray &eventType, void *message, result_t *result)
|
||||
{
|
||||
if (eventType == "windows_generic_MSG")
|
||||
{
|
||||
MSG *msg = static_cast<MSG *>(message);
|
||||
|
||||
if (msg->message == WM_INPUT)
|
||||
{
|
||||
if (msg->message == WM_INPUT) {
|
||||
if (window->isActiveWindow() && menus_open == 0)
|
||||
handle_input((HRAWINPUT)msg->lParam);
|
||||
handle_input((HRAWINPUT) msg->lParam);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Stop processing of Alt-F4 */
|
||||
if (msg->message == WM_SYSKEYDOWN) {
|
||||
if (msg->wParam == 0x73) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -312,9 +318,9 @@ void WindowsRawInputFilter::keyboard_getkeymap()
|
||||
/* Get the scan code remappings from:
|
||||
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout */
|
||||
bufSize = 32768;
|
||||
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyName, 0, 1, &hKey) == ERROR_SUCCESS)
|
||||
if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, keyName, 0, 1, &hKey) == ERROR_SUCCESS)
|
||||
{
|
||||
if (RegQueryValueEx(hKey, valueName, NULL, NULL, buf, &bufSize) == ERROR_SUCCESS)
|
||||
if (RegQueryValueExA(hKey, valueName, NULL, NULL, buf, &bufSize) == ERROR_SUCCESS)
|
||||
{
|
||||
bufEx2 = (UINT32 *)buf;
|
||||
scMapCount = bufEx2[2];
|
||||
|
||||
@@ -40,13 +40,12 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
#if QT_VERSION_MAJOR >= 6
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
#define result_t qintptr
|
||||
#else
|
||||
#define result_t long
|
||||
#endif
|
||||
|
||||
|
||||
class WindowsRawInputFilter : public QObject, public QAbstractNativeEventFilter
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Reference in New Issue
Block a user