ported joystick config to qt. sdl-joystick implementation from pcem

This commit is contained in:
Joakim L. Gilje
2021-12-13 22:45:37 +01:00
parent 777441ef0f
commit a39307d178
8 changed files with 555 additions and 14 deletions

View File

@@ -6,7 +6,13 @@ set(CMAKE_AUTORCC ON)
find_package(Threads REQUIRED)
add_library(plat STATIC qt.c qt_main.cpp qt_platform.cpp cpp11_thread.cpp)
add_library(plat STATIC
qt.c
qt_main.cpp
qt_platform.cpp
sdl_joystick.cpp
cpp11_thread.cpp
)
add_library(ui STATIC
qt_ui.cpp
qt_cdrom.c
@@ -69,6 +75,9 @@ add_library(ui STATIC
qt_deviceconfig.cpp
qt_deviceconfig.hpp
qt_deviceconfig.ui
qt_joystickconfiguration.cpp
qt_joystickconfiguration.hpp
qt_joystickconfiguration.ui
qt_filefield.cpp
qt_filefield.hpp

View File

@@ -0,0 +1,183 @@
#include "qt_joystickconfiguration.hpp"
#include "ui_qt_joystickconfiguration.h"
extern "C" {
#include <86box/device.h>
#include <86box/gameport.h>
}
#include <QLabel>
#include <QComboBox>
#include <QDialogButtonBox>
#include "qt_models_common.hpp"
JoystickConfiguration::JoystickConfiguration(int type, int joystick_nr, QWidget *parent) :
QDialog(parent),
ui(new Ui::JoystickConfiguration),
type(type),
joystick_nr(joystick_nr)
{
ui->setupUi(this);
auto model = ui->comboBoxDevice->model();
Models::AddEntry(model, "None", 0);
for (int c = 0; c < joysticks_present; c++) {
Models::AddEntry(model, plat_joystick_state[c].name, c+1);
}
ui->comboBoxDevice->setCurrentIndex(joystick_state[joystick_nr].plat_joystick_nr);
}
JoystickConfiguration::~JoystickConfiguration()
{
delete ui;
}
int JoystickConfiguration::selectedDevice() {
return ui->comboBoxDevice->currentIndex();
}
int JoystickConfiguration::selectedAxis(int axis) {
auto* cbox = findChild<QComboBox*>(QString("cboxAxis%1").arg(QString::number(axis)));
if (cbox == nullptr) {
return 0;
}
return cbox->currentIndex();
}
int JoystickConfiguration::selectedButton(int button) {
auto* cbox = findChild<QComboBox*>(QString("cboxButton%1").arg(QString::number(button)));
if (cbox == nullptr) {
return 0;
}
return cbox->currentIndex();
}
int JoystickConfiguration::selectedPov(int pov) {
auto* cbox = findChild<QComboBox*>(QString("cboxPov%1").arg(QString::number(pov)));
if (cbox == nullptr) {
return 0;
}
return cbox->currentIndex();
}
void JoystickConfiguration::on_comboBoxDevice_currentIndexChanged(int index) {
for (auto w : widgets) {
ui->ct->removeWidget(w);
}
if (index == 0) {
return;
}
int joystick = index - 1;
int row = 0;
for (int c = 0; c < joystick_get_axis_count(type); c++) {
/*Combo box*/
auto label = new QLabel(joystick_get_axis_name(type, c), this);
auto cbox = new QComboBox(this);
cbox->setObjectName(QString("cboxAxis%1").arg(QString::number(c)));
auto model = cbox->model();
for (int d = 0; d < plat_joystick_state[joystick].nr_axes; d++) {
Models::AddEntry(model, plat_joystick_state[joystick].axis[d].name, 0);
}
for (int d = 0; d < plat_joystick_state[joystick].nr_povs; d++) {
Models::AddEntry(model, QString("%1 (X axis)").arg(plat_joystick_state[joystick].pov[d].name), 0);
Models::AddEntry(model, QString("%1 (Y axis)").arg(plat_joystick_state[joystick].pov[d].name), 0);
}
for (int d = 0; d < plat_joystick_state[joystick].nr_sliders; d++) {
Models::AddEntry(model, plat_joystick_state[joystick].slider[d].name, 0);
}
int nr_axes = plat_joystick_state[joystick].nr_axes;
int nr_povs = plat_joystick_state[joystick].nr_povs;
int mapping = joystick_state[joystick_nr].axis_mapping[c];
if (mapping & POV_X)
cbox->setCurrentIndex(nr_axes + (mapping & 3) * 2);
else if (mapping & POV_Y)
cbox->setCurrentIndex(nr_axes + (mapping & 3) * 2 + 1);
else if (mapping & SLIDER)
cbox->setCurrentIndex(nr_axes + nr_povs * 2 + (mapping & 3));
else
cbox->setCurrentIndex(mapping);
ui->ct->addWidget(label, row, 0);
ui->ct->addWidget(cbox, row, 1);
widgets.append(label);
widgets.append(cbox);
++row;
}
for (int c = 0; c < joystick_get_button_count(type); c++) {
auto label = new QLabel(joystick_get_button_name(type, c), this);
auto cbox = new QComboBox(this);
cbox->setObjectName(QString("cboxButton%1").arg(QString::number(c)));
auto model = cbox->model();
for (int d = 0; d < plat_joystick_state[joystick].nr_buttons; d++) {
Models::AddEntry(model, plat_joystick_state[joystick].button[d].name, 0);
}
cbox->setCurrentIndex(joystick_state[joystick_nr].button_mapping[c]);
ui->ct->addWidget(label, row, 0);
ui->ct->addWidget(cbox, row, 1);
widgets.append(label);
widgets.append(cbox);
++row;
}
for (int c = 0; c < joystick_get_pov_count(type) * 2; c++) {
QLabel* label;
if (c & 1) {
label = new QLabel(QString("%1 (Y axis)").arg(joystick_get_pov_name(type, c/2)), this);
} else {
label = new QLabel(QString("%1 (X axis)").arg(joystick_get_pov_name(type, c/2)), this);
}
auto cbox = new QComboBox(this);
cbox->setObjectName(QString("cboxPov%1").arg(QString::number(c)));
auto model = cbox->model();
for (int d = 0; d < plat_joystick_state[joystick].nr_povs; d++) {
Models::AddEntry(model, QString("%1 (X axis)").arg(plat_joystick_state[joystick].pov[d].name), 0);
Models::AddEntry(model, QString("%1 (Y axis)").arg(plat_joystick_state[joystick].pov[d].name), 0);
}
for (int d = 0; d < plat_joystick_state[joystick].nr_axes; d++) {
Models::AddEntry(model, plat_joystick_state[joystick].axis[d].name, 0);
}
int mapping = joystick_state[joystick_nr].pov_mapping[c][0];
int nr_povs = plat_joystick_state[joystick].nr_povs;
if (mapping & POV_X)
cbox->setCurrentIndex((mapping & 3) * 2);
else if (mapping & POV_Y)
cbox->setCurrentIndex((mapping & 3)*2 + 1);
else
cbox->setCurrentIndex(mapping + nr_povs * 2);
mapping = joystick_state[joystick_nr].pov_mapping[c][1];
if (mapping & POV_X)
cbox->setCurrentIndex((mapping & 3)*2);
else if (mapping & POV_Y)
cbox->setCurrentIndex((mapping & 3)*2 + 1);
else
cbox->setCurrentIndex(mapping + nr_povs*2);
ui->ct->addWidget(label, row, 0);
ui->ct->addWidget(cbox, row, 1);
widgets.append(label);
widgets.append(cbox);
++row;
}
}

View File

@@ -0,0 +1,32 @@
#ifndef QT_JOYSTICKCONFIGURATION_HPP
#define QT_JOYSTICKCONFIGURATION_HPP
#include <QDialog>
namespace Ui {
class JoystickConfiguration;
}
class JoystickConfiguration : public QDialog
{
Q_OBJECT
public:
explicit JoystickConfiguration(int type, int joystick_nr, QWidget *parent = nullptr);
~JoystickConfiguration();
int selectedDevice();
int selectedAxis(int axis);
int selectedButton(int button);
int selectedPov(int pov);
private slots:
void on_comboBoxDevice_currentIndexChanged(int index);
private:
Ui::JoystickConfiguration *ui;
QList<QWidget*> widgets;
int type;
int joystick_nr;
};
#endif // QT_JOYSTICKCONFIGURATION_HPP

View File

@@ -0,0 +1,87 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>JoystickConfiguration</class>
<widget class="QDialog" name="JoystickConfiguration">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="1" column="0" colspan="2">
<layout class="QGridLayout" name="ct"/>
</item>
<item row="3" column="1">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="comboBoxDevice"/>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Device</string>
</property>
</widget>
</item>
<item row="2" column="1">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>JoystickConfiguration</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>223</x>
<y>278</y>
</hint>
<hint type="destinationlabel">
<x>199</x>
<y>149</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>JoystickConfiguration</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>223</x>
<y>278</y>
</hint>
<hint type="destinationlabel">
<x>199</x>
<y>149</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@@ -67,9 +67,6 @@ int kbd_req_capture = 0;
int hide_status_bar = 0;
uint32_t lang_id = 0x0409, lang_sys = 0x0409; // Multilangual UI variables, for now all set to LCID of en-US
plat_joystick_t plat_joystick_state[MAX_PLAT_JOYSTICKS];
joystick_t joystick_state[MAX_JOYSTICKS];
int stricmp(const char* s1, const char* s2)
{
return QByteArray(s1).compare(s2, Qt::CaseInsensitive);
@@ -380,9 +377,6 @@ void dynld_close(void *handle)
delete reinterpret_cast<QLibrary*>(handle);
}
void joystick_init(void) {}
void joystick_close(void) {}
void joystick_process(void) {}
void startblit()
{
blitmx_contention++;

View File

@@ -11,7 +11,9 @@ extern "C" {
#include <86box/gameport.h>
}
#include "qt_models_common.hpp"
#include "qt_deviceconfig.hpp"
#include "qt_joystickconfiguration.hpp"
SettingsInput::SettingsInput(QWidget *parent) :
QWidget(parent),
@@ -73,13 +75,7 @@ void SettingsInput::onCurrentMachineChanged(int machineId) {
removeRows = joystickModel->rowCount();
selectedRow = 0;
while (joyName) {
int row = joystickModel->rowCount();
joystickModel->insertRow(row);
auto idx = joystickModel->index(row, 0);
joystickModel->setData(idx, joyName, Qt::DisplayRole);
joystickModel->setData(idx, i, Qt::UserRole);
int row = Models::AddEntry(joystickModel, joyName, i);
if (i == joystick_type) {
selectedRow = row - removeRows;
}
@@ -112,3 +108,80 @@ void SettingsInput::on_pushButtonConfigureMouse_clicked() {
int mouseId = ui->comboBoxMouse->currentData().toInt();
DeviceConfig::ConfigureDevice(mouse_get_device(mouseId));
}
static int get_axis(JoystickConfiguration& jc, int axis, int joystick_nr) {
int axis_sel = jc.selectedAxis(axis);
int nr_axes = plat_joystick_state[joystick_state[joystick_nr].plat_joystick_nr - 1].nr_axes;
int nr_povs = plat_joystick_state[joystick_state[joystick_nr].plat_joystick_nr - 1].nr_povs;
if (axis_sel < nr_axes) {
return axis_sel;
}
axis_sel -= nr_axes;
if (axis_sel < nr_povs * 2) {
if (axis_sel & 1)
return POV_Y | (axis_sel >> 1);
else
return POV_X | (axis_sel >> 1);
}
axis_sel -= nr_povs;
return SLIDER | (axis_sel >> 1);
}
static int get_pov(JoystickConfiguration& jc, int pov, int joystick_nr) {
int pov_sel = jc.selectedPov(pov);
int nr_povs = plat_joystick_state[joystick_state[joystick_nr].plat_joystick_nr-1].nr_povs*2;
if (pov_sel < nr_povs)
{
if (pov_sel & 1)
return POV_Y | (pov_sel >> 1);
else
return POV_X | (pov_sel >> 1);
}
return pov_sel - nr_povs;
}
static void updateJoystickConfig(int type, int joystick_nr, QWidget* parent) {
JoystickConfiguration jc(type, joystick_nr, parent);
switch (jc.exec()) {
case QDialog::Rejected:
return;
case QDialog::Accepted:
break;
}
joystick_state[joystick_nr].plat_joystick_nr = jc.selectedDevice();
if (joystick_state[joystick_nr].plat_joystick_nr) {
for (int c = 0; c < joystick_get_axis_count(type); c++) {
joystick_state[joystick_nr].axis_mapping[c] = get_axis(jc, c, joystick_nr);
}
for (int c = 0; c < joystick_get_button_count(type); c++) {
joystick_state[joystick_nr].button_mapping[c] = jc.selectedButton(c);
}
for (int c = 0; c < joystick_get_button_count(type); c++) {
joystick_state[joystick_nr].pov_mapping[c][0] = get_pov(jc, c, joystick_nr);
joystick_state[joystick_nr].pov_mapping[c][1] = get_pov(jc, c, joystick_nr);
}
}
}
void SettingsInput::on_pushButtonJoystick1_clicked() {
updateJoystickConfig(ui->comboBoxJoystick->currentData().toInt(), 0, this);
}
void SettingsInput::on_pushButtonJoystick2_clicked() {
updateJoystickConfig(ui->comboBoxJoystick->currentData().toInt(), 1, this);
}
void SettingsInput::on_pushButtonJoystick3_clicked() {
updateJoystickConfig(ui->comboBoxJoystick->currentData().toInt(), 2, this);
}
void SettingsInput::on_pushButtonJoystick4_clicked() {
updateJoystickConfig(ui->comboBoxJoystick->currentData().toInt(), 3, this);
}

View File

@@ -24,6 +24,10 @@ private slots:
void on_pushButtonConfigureMouse_clicked();
void on_comboBoxJoystick_currentIndexChanged(int index);
void on_comboBoxMouse_currentIndexChanged(int index);
void on_pushButtonJoystick1_clicked();
void on_pushButtonJoystick2_clicked();
void on_pushButtonJoystick3_clicked();
void on_pushButtonJoystick4_clicked();
private:
Ui::SettingsInput *ui;

159
src/qt/sdl_joystick.cpp Normal file
View File

@@ -0,0 +1,159 @@
// Lifted from wx-sdl2-joystick.c in PCem
#include <SDL2/SDL.h>
extern "C" {
#include <86box/device.h>
#include <86box/gameport.h>
int joysticks_present;
joystick_t joystick_state[MAX_JOYSTICKS];
plat_joystick_t plat_joystick_state[MAX_PLAT_JOYSTICKS];
static SDL_Joystick *sdl_joy[MAX_PLAT_JOYSTICKS];
}
void joystick_init() {
if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) != 0) {
return;
}
joysticks_present = SDL_NumJoysticks();
memset(sdl_joy, 0, sizeof(sdl_joy));
for (int c = 0; c < joysticks_present; c++)
{
sdl_joy[c] = SDL_JoystickOpen(c);
if (sdl_joy[c])
{
int d;
strncpy(plat_joystick_state[c].name, SDL_JoystickNameForIndex(c), 64);
plat_joystick_state[c].nr_axes = SDL_JoystickNumAxes(sdl_joy[c]);
plat_joystick_state[c].nr_buttons = SDL_JoystickNumButtons(sdl_joy[c]);
plat_joystick_state[c].nr_povs = SDL_JoystickNumHats(sdl_joy[c]);
for (d = 0; d < std::min(plat_joystick_state[c].nr_axes, 8); d++)
{
sprintf(plat_joystick_state[c].axis[d].name, "Axis %i", d);
plat_joystick_state[c].axis[d].id = d;
}
for (d = 0; d < std::min(plat_joystick_state[c].nr_buttons, 8); d++)
{
sprintf(plat_joystick_state[c].button[d].name, "Button %i", d);
plat_joystick_state[c].button[d].id = d;
}
for (d = 0; d < std::min(plat_joystick_state[c].nr_povs, 4); d++)
{
sprintf(plat_joystick_state[c].pov[d].name, "POV %i", d);
plat_joystick_state[c].pov[d].id = d;
}
}
}
}
void joystick_close()
{
int c;
for (c = 0; c < joysticks_present; c++)
{
if (sdl_joy[c])
SDL_JoystickClose(sdl_joy[c]);
}
}
static int joystick_get_axis(int joystick_nr, int mapping)
{
if (mapping & POV_X)
{
switch (plat_joystick_state[joystick_nr].p[mapping & 3])
{
case SDL_HAT_LEFTUP: case SDL_HAT_LEFT: case SDL_HAT_LEFTDOWN:
return -32767;
case SDL_HAT_RIGHTUP: case SDL_HAT_RIGHT: case SDL_HAT_RIGHTDOWN:
return 32767;
default:
return 0;
}
}
else if (mapping & POV_Y)
{
switch (plat_joystick_state[joystick_nr].p[mapping & 3])
{
case SDL_HAT_LEFTUP: case SDL_HAT_UP: case SDL_HAT_RIGHTUP:
return -32767;
case SDL_HAT_LEFTDOWN: case SDL_HAT_DOWN: case SDL_HAT_RIGHTDOWN:
return 32767;
default:
return 0;
}
}
else
return plat_joystick_state[joystick_nr].a[plat_joystick_state[joystick_nr].axis[mapping].id];
}
void joystick_process()
{
int c, d;
SDL_JoystickUpdate();
for (c = 0; c < joysticks_present; c++)
{
int b;
plat_joystick_state[c].a[0] = SDL_JoystickGetAxis(sdl_joy[c], 0);
plat_joystick_state[c].a[1] = SDL_JoystickGetAxis(sdl_joy[c], 1);
plat_joystick_state[c].a[2] = SDL_JoystickGetAxis(sdl_joy[c], 2);
plat_joystick_state[c].a[3] = SDL_JoystickGetAxis(sdl_joy[c], 3);
plat_joystick_state[c].a[4] = SDL_JoystickGetAxis(sdl_joy[c], 4);
plat_joystick_state[c].a[5] = SDL_JoystickGetAxis(sdl_joy[c], 5);
for (b = 0; b < 16; b++)
plat_joystick_state[c].b[b] = SDL_JoystickGetButton(sdl_joy[c], b);
for (b = 0; b < 4; b++)
plat_joystick_state[c].p[b] = SDL_JoystickGetHat(sdl_joy[c], b);
// pclog("joystick %i - x=%i y=%i b[0]=%i b[1]=%i %i\n", c, joystick_state[c].x, joystick_state[c].y, joystick_state[c].b[0], joystick_state[c].b[1], joysticks_present);
}
for (c = 0; c < joystick_get_max_joysticks(joystick_type); c++)
{
if (joystick_state[c].plat_joystick_nr)
{
int joystick_nr = joystick_state[c].plat_joystick_nr - 1;
for (d = 0; d < joystick_get_axis_count(joystick_type); d++)
joystick_state[c].axis[d] = joystick_get_axis(joystick_nr, joystick_state[c].axis_mapping[d]);
for (d = 0; d < joystick_get_button_count(joystick_type); d++)
joystick_state[c].button[d] = plat_joystick_state[joystick_nr].b[joystick_state[c].button_mapping[d]];
for (d = 0; d < joystick_get_pov_count(joystick_type); d++)
{
int x, y;
double angle, magnitude;
x = joystick_get_axis(joystick_nr, joystick_state[c].pov_mapping[d][0]);
y = joystick_get_axis(joystick_nr, joystick_state[c].pov_mapping[d][1]);
angle = (atan2((double)y, (double)x) * 360.0) / (2*M_PI);
magnitude = sqrt((double)x*(double)x + (double)y*(double)y);
if (magnitude < 16384)
joystick_state[c].pov[d] = -1;
else
joystick_state[c].pov[d] = ((int)angle + 90 + 360) % 360;
}
}
else
{
for (d = 0; d < joystick_get_axis_count(joystick_type); d++)
joystick_state[c].axis[d] = 0;
for (d = 0; d < joystick_get_button_count(joystick_type); d++)
joystick_state[c].button[d] = 0;
for (d = 0; d < joystick_get_pov_count(joystick_type); d++)
joystick_state[c].pov[d] = -1;
}
}
}