Merge remote-tracking branch 'origin/master' into obattler

This commit is contained in:
OBattler
2025-08-23 18:58:06 +02:00
33 changed files with 552 additions and 253 deletions

View File

@@ -234,29 +234,46 @@ struct accelKey acc_keys[NUM_ACCELS];
// Default accelerator key values // Default accelerator key values
struct accelKey def_acc_keys[NUM_ACCELS] = { struct accelKey def_acc_keys[NUM_ACCELS] = {
{ .name="send_ctrl_alt_del", .desc="Send Control+Alt+Del", {
.seq="Ctrl+F12" }, .name="send_ctrl_alt_del",
.desc="Send Control+Alt+Del",
{ .name="send_ctrl_alt_esc", .desc="Send Control+Alt+Escape", .seq="Ctrl+F12"
.seq="Ctrl+F10" }, },
{
{ .name="fullscreen", .desc="Toggle fullscreen", .name="send_ctrl_alt_esc",
.seq="Ctrl+Alt+PgUp" }, .desc="Send Control+Alt+Escape",
.seq="Ctrl+F10"
{ .name="screenshot", .desc="Screenshot", },
.seq="Ctrl+F11" }, {
.name="fullscreen",
{ .name="release_mouse", .desc="Release mouse pointer", .desc="Toggle fullscreen",
.seq="Ctrl+End" }, .seq="Ctrl+Alt+PgUp"
},
{ .name="hard_reset", .desc="Hard reset", {
.seq="Ctrl+Alt+F12" }, .name="screenshot",
.desc="Screenshot",
{ .name="pause", .desc="Toggle pause", .seq="Ctrl+F11"
.seq="Ctrl+Alt+F1" }, },
{
{ .name="mute", .desc="Toggle mute", .name="release_mouse",
.seq="Ctrl+Alt+M" } .desc="Release mouse pointer",
.seq="Ctrl+End"
},
{
.name="hard_reset",
.desc="Hard reset",
.seq="Ctrl+Alt+F12"
},
{
.name="pause",
.desc="Toggle pause",
.seq="Ctrl+Alt+F1"
},
{
.name="mute",
.desc="Toggle mute",
.seq="Ctrl+Alt+M"
}
}; };
char vmm_path[1024] = { '\0' }; /* VM manager path to scan for VMs */ char vmm_path[1024] = { '\0' }; /* VM manager path to scan for VMs */
@@ -1593,8 +1610,9 @@ pc_reset_hard_init(void)
the chances of the SCSI controller ending up on the bridge. */ the chances of the SCSI controller ending up on the bridge. */
video_voodoo_init(); video_voodoo_init();
if (joystick_type) /* installs first game port if no device provides one, must be late */
gameport_update_joystick_type(); /* installs game port if no device provides one, must be late */ if (joystick_type[0])
gameport_update_joystick_type(0);
ui_sb_update_panes(); ui_sb_update_panes();
@@ -1802,7 +1820,7 @@ pc_run(void)
#ifdef USE_GDBSTUB /* avoid a KBC FIFO overflow when CPU emulation is stalled */ #ifdef USE_GDBSTUB /* avoid a KBC FIFO overflow when CPU emulation is stalled */
} }
#endif #endif
joystick_process(); joystick_process(0); // Gameport 0
endblit(); endblit();
/* Done with this frame, update statistics. */ /* Done with this frame, update statistics. */
@@ -2007,13 +2025,11 @@ do_pause(int p)
// Helper to find an accelerator key and return it's index in acc_keys // Helper to find an accelerator key and return it's index in acc_keys
int FindAccelerator(const char *name) { int FindAccelerator(const char *name) {
for(int x=0;x<NUM_ACCELS;x++) for (int x = 0; x < NUM_ACCELS; x++) {
{ if(strcmp(acc_keys[x].name, name) == 0)
if(strcmp(acc_keys[x].name, name) == 0) return(x);
{ }
return(x);
} // No key was found
} return -1;
// No key was found
return -1;
} }

View File

@@ -529,62 +529,63 @@ load_input_devices(void)
else else
mouse_type = 0; mouse_type = 0;
uint8_t joy_insn = 0;
p = ini_section_get_string(cat, "joystick_type", NULL); p = ini_section_get_string(cat, "joystick_type", NULL);
if (p != NULL) { if (p != NULL) {
joystick_type = joystick_get_from_internal_name(p); joystick_type[joy_insn] = joystick_get_from_internal_name(p);
if (!joystick_type) { if (!joystick_type[joy_insn]) {
/* Try to read an integer for backwards compatibility with old configs */ /* Try to read an integer for backwards compatibility with old configs */
if (!strcmp(p, "0")) if (!strcmp(p, "0"))
/* Workaround for ini_section_get_int returning 0 on non-integer data */ /* Workaround for ini_section_get_int returning 0 on non-integer data */
joystick_type = joystick_get_from_internal_name("2axis_2button"); joystick_type[joy_insn] = joystick_get_from_internal_name("2axis_2button");
else { else {
int js = ini_section_get_int(cat, "joystick_type", 8); int js = ini_section_get_int(cat, "joystick_type", 8);
switch (js) { switch (js) {
case JS_TYPE_2AXIS_4BUTTON: case JS_TYPE_2AXIS_4BUTTON:
joystick_type = joystick_get_from_internal_name("2axis_4button"); joystick_type[joy_insn] = joystick_get_from_internal_name("2axis_4button");
break; break;
case JS_TYPE_2AXIS_6BUTTON: case JS_TYPE_2AXIS_6BUTTON:
joystick_type = joystick_get_from_internal_name("2axis_6button"); joystick_type[joy_insn] = joystick_get_from_internal_name("2axis_6button");
break; break;
case JS_TYPE_2AXIS_8BUTTON: case JS_TYPE_2AXIS_8BUTTON:
joystick_type = joystick_get_from_internal_name("2axis_8button"); joystick_type[joy_insn] = joystick_get_from_internal_name("2axis_8button");
break; break;
case JS_TYPE_4AXIS_4BUTTON: case JS_TYPE_4AXIS_4BUTTON:
joystick_type = joystick_get_from_internal_name("4axis_4button"); joystick_type[joy_insn] = joystick_get_from_internal_name("4axis_4button");
break; break;
case JS_TYPE_CH_FLIGHTSTICK_PRO: case JS_TYPE_CH_FLIGHTSTICK_PRO:
joystick_type = joystick_get_from_internal_name("ch_flightstick_pro"); joystick_type[joy_insn] = joystick_get_from_internal_name("ch_flightstick_pro");
break; break;
case JS_TYPE_SIDEWINDER_PAD: case JS_TYPE_SIDEWINDER_PAD:
joystick_type = joystick_get_from_internal_name("sidewinder_pad"); joystick_type[joy_insn] = joystick_get_from_internal_name("sidewinder_pad");
break; break;
case JS_TYPE_THRUSTMASTER_FCS: case JS_TYPE_THRUSTMASTER_FCS:
joystick_type = joystick_get_from_internal_name("thrustmaster_fcs"); joystick_type[joy_insn] = joystick_get_from_internal_name("thrustmaster_fcs");
break; break;
default: default:
joystick_type = JS_TYPE_NONE; joystick_type[joy_insn] = JS_TYPE_NONE;
break; break;
} }
} }
} }
} else } else
joystick_type = JS_TYPE_NONE; joystick_type[joy_insn] = JS_TYPE_NONE;
for (int js = 0; js < joystick_get_max_joysticks(joystick_type); js++) { for (int js = 0; js < joystick_get_max_joysticks(joystick_type[joy_insn]); js++) {
sprintf(temp, "joystick_%i_nr", js); sprintf(temp, "joystick_%i_nr", js);
joystick_state[0][js].plat_joystick_nr = ini_section_get_int(cat, temp, 0); joystick_state[0][js].plat_joystick_nr = ini_section_get_int(cat, temp, 0);
if (joystick_state[0][js].plat_joystick_nr) { if (joystick_state[0][js].plat_joystick_nr) {
for (int axis_nr = 0; axis_nr < joystick_get_axis_count(joystick_type); axis_nr++) { for (int axis_nr = 0; axis_nr < joystick_get_axis_count(joystick_type[joy_insn]); axis_nr++) {
sprintf(temp, "joystick_%i_axis_%i", js, axis_nr); sprintf(temp, "joystick_%i_axis_%i", js, axis_nr);
joystick_state[0][js].axis_mapping[axis_nr] = ini_section_get_int(cat, temp, axis_nr); joystick_state[0][js].axis_mapping[axis_nr] = ini_section_get_int(cat, temp, axis_nr);
} }
for (int button_nr = 0; button_nr < joystick_get_button_count(joystick_type); button_nr++) { for (int button_nr = 0; button_nr < joystick_get_button_count(joystick_type[joy_insn]); button_nr++) {
sprintf(temp, "joystick_%i_button_%i", js, button_nr); sprintf(temp, "joystick_%i_button_%i", js, button_nr);
joystick_state[0][js].button_mapping[button_nr] = ini_section_get_int(cat, temp, button_nr); joystick_state[0][js].button_mapping[button_nr] = ini_section_get_int(cat, temp, button_nr);
} }
for (int pov_nr = 0; pov_nr < joystick_get_pov_count(joystick_type); pov_nr++) { for (int pov_nr = 0; pov_nr < joystick_get_pov_count(joystick_type[joy_insn]); pov_nr++) {
sprintf(temp, "joystick_%i_pov_%i", js, pov_nr); sprintf(temp, "joystick_%i_pov_%i", js, pov_nr);
p = ini_section_get_string(cat, temp, "0, 0"); p = ini_section_get_string(cat, temp, "0, 0");
joystick_state[0][js].pov_mapping[pov_nr][0] = joystick_state[0][js].pov_mapping[pov_nr][1] = 0; joystick_state[0][js].pov_mapping[pov_nr][0] = joystick_state[0][js].pov_mapping[pov_nr][1] = 0;
@@ -2552,7 +2553,8 @@ save_input_devices(void)
ini_section_set_string(cat, "mouse_type", mouse_get_internal_name(mouse_type)); ini_section_set_string(cat, "mouse_type", mouse_get_internal_name(mouse_type));
if (!joystick_type) { uint8_t joy_insn = 0;
if (!joystick_type[joy_insn]) {
ini_section_delete_var(cat, "joystick_type"); ini_section_delete_var(cat, "joystick_type");
for (int js = 0; js < MAX_PLAT_JOYSTICKS; js++) { for (int js = 0; js < MAX_PLAT_JOYSTICKS; js++) {
@@ -2573,22 +2575,22 @@ save_input_devices(void)
} }
} }
} else { } else {
ini_section_set_string(cat, "joystick_type", joystick_get_internal_name(joystick_type)); ini_section_set_string(cat, "joystick_type", joystick_get_internal_name(joystick_type[joy_insn]));
for (int js = 0; js < joystick_get_max_joysticks(joystick_type); js++) { for (int js = 0; js < joystick_get_max_joysticks(joystick_type[joy_insn]); js++) {
sprintf(tmp2, "joystick_%i_nr", js); sprintf(tmp2, "joystick_%i_nr", js);
ini_section_set_int(cat, tmp2, joystick_state[0][js].plat_joystick_nr); ini_section_set_int(cat, tmp2, joystick_state[0][js].plat_joystick_nr);
if (joystick_state[0][js].plat_joystick_nr) { if (joystick_state[0][js].plat_joystick_nr) {
for (int axis_nr = 0; axis_nr < joystick_get_axis_count(joystick_type); axis_nr++) { for (int axis_nr = 0; axis_nr < joystick_get_axis_count(joystick_type[joy_insn]); axis_nr++) {
sprintf(tmp2, "joystick_%i_axis_%i", js, axis_nr); sprintf(tmp2, "joystick_%i_axis_%i", js, axis_nr);
ini_section_set_int(cat, tmp2, joystick_state[0][js].axis_mapping[axis_nr]); ini_section_set_int(cat, tmp2, joystick_state[0][js].axis_mapping[axis_nr]);
} }
for (int button_nr = 0; button_nr < joystick_get_button_count(joystick_type); button_nr++) { for (int button_nr = 0; button_nr < joystick_get_button_count(joystick_type[joy_insn]); button_nr++) {
sprintf(tmp2, "joystick_%i_button_%i", js, button_nr); sprintf(tmp2, "joystick_%i_button_%i", js, button_nr);
ini_section_set_int(cat, tmp2, joystick_state[0][js].button_mapping[button_nr]); ini_section_set_int(cat, tmp2, joystick_state[0][js].button_mapping[button_nr]);
} }
for (int pov_nr = 0; pov_nr < joystick_get_pov_count(joystick_type); pov_nr++) { for (int pov_nr = 0; pov_nr < joystick_get_pov_count(joystick_type[joy_insn]); pov_nr++) {
sprintf(tmp2, "joystick_%i_pov_%i", js, pov_nr); sprintf(tmp2, "joystick_%i_pov_%i", js, pov_nr);
sprintf(temp, "%i, %i", joystick_state[0][js].pov_mapping[pov_nr][0], sprintf(temp, "%i, %i", joystick_state[0][js].pov_mapping[pov_nr][0],
joystick_state[0][js].pov_mapping[pov_nr][1]); joystick_state[0][js].pov_mapping[pov_nr][1]);

View File

@@ -65,7 +65,7 @@ typedef struct _joystick_instance_ {
void *dat; void *dat;
} joystick_instance_t; } joystick_instance_t;
int joystick_type = JS_TYPE_NONE; int joystick_type[GAMEPORT_MAX] = { JS_TYPE_NONE, JS_TYPE_NONE };
static const joystick_t joystick_none = { static const joystick_t joystick_none = {
.name = "None", .name = "None",
@@ -299,17 +299,17 @@ timer_over(void *priv)
} }
void void
gameport_update_joystick_type(void) gameport_update_joystick_type(uint8_t gp)
{ {
/* Add a standalone game port if a joystick is enabled but no other game ports exist. */ /* Add a standalone game port if a joystick is enabled but no other game ports exist. */
if (standalone_gameport_type) if (standalone_gameport_type)
gameport_add(standalone_gameport_type); gameport_add(standalone_gameport_type);
/* Reset the joystick interface. */ /* Reset the joystick interface. */
if (joystick_instance[0]) { if (joystick_instance[gp]) {
joystick_instance[0]->intf->close(joystick_instance[0]->dat); joystick_instance[gp]->intf->close(joystick_instance[gp]->dat);
joystick_instance[0]->intf = joysticks[joystick_type].joystick; joystick_instance[gp]->intf = joysticks[joystick_type[gp]].joystick;
joystick_instance[0]->dat = joystick_instance[0]->intf->init(); joystick_instance[gp]->dat = joystick_instance[gp]->intf->init();
} }
} }
@@ -393,24 +393,27 @@ gameport_init(const device_t *info)
{ {
gameport_t *dev = calloc(1, sizeof(gameport_t)); gameport_t *dev = calloc(1, sizeof(gameport_t));
// TODO: Later we'll actually support more than one gameport
uint8_t joy_insn = 0;
/* Allocate global instance. */ /* Allocate global instance. */
if (!joystick_instance[0] && joystick_type) { if (!joystick_instance[joy_insn] && joystick_type[joy_insn]) {
joystick_instance[0] = calloc(1, sizeof(joystick_instance_t)); joystick_instance[joy_insn] = calloc(1, sizeof(joystick_instance_t));
// For each analog joystick axis // For each analog joystick axis
for (uint8_t i = 0; i < 4; i++) { for (uint8_t i = 0; i < 4; i++) {
joystick_instance[0]->axis[i].joystick = joystick_instance[0]; joystick_instance[joy_insn]->axis[i].joystick = joystick_instance[joy_insn];
joystick_instance[0]->axis[i].axis_nr = i; joystick_instance[joy_insn]->axis[i].axis_nr = i;
timer_add(&joystick_instance[0]->axis[i].timer, timer_over, &joystick_instance[0]->axis[i], 0); timer_add(&joystick_instance[joy_insn]->axis[i].timer, timer_over, &joystick_instance[joy_insn]->axis[i], 0);
} }
joystick_instance[0]->intf = joysticks[joystick_type].joystick; joystick_instance[joy_insn]->intf = joysticks[joystick_type[joy_insn]].joystick;
joystick_instance[0]->dat = joystick_instance[0]->intf->init(); joystick_instance[joy_insn]->dat = joystick_instance[joy_insn]->intf->init();
} }
dev->joystick = joystick_instance[0]; dev->joystick = joystick_instance[joy_insn];
/* Map game port to the default address. Not applicable on PnP-only ports. */ /* Map game port to the default address. Not applicable on PnP-only ports. */
dev->len = (info->local >> 16) & 0xff; dev->len = (info->local >> 16) & 0xff;
@@ -475,15 +478,18 @@ gameport_close(void *priv)
{ {
gameport_t *dev = (gameport_t *) priv; gameport_t *dev = (gameport_t *) priv;
// TODO: Later we'll actually support more than one gameport
uint8_t joy_insn = 0;
/* If this port was active, remove it from the active ports list. */ /* If this port was active, remove it from the active ports list. */
gameport_remap(dev, 0); gameport_remap(dev, 0);
/* Free the global instance here, if it wasn't already freed. */ /* Free the global instance here, if it wasn't already freed. */
if (joystick_instance[0]) { if (joystick_instance[joy_insn]) {
joystick_instance[0]->intf->close(joystick_instance[0]->dat); joystick_instance[joy_insn]->intf->close(joystick_instance[joy_insn]->dat);
free(joystick_instance[0]); free(joystick_instance[joy_insn]);
joystick_instance[0] = NULL; joystick_instance[joy_insn] = NULL;
} }
free(dev); free(dev);
@@ -793,7 +799,7 @@ gameport_available(int port)
/* UI */ /* UI */
const device_t * const device_t *
gameport_getdevice(int port) gameport_get_device(int port)
{ {
return (gameports[port].device); return (gameports[port].device);
} }

View File

@@ -119,7 +119,7 @@ extern "C" {
extern int gameport_available(int port); extern int gameport_available(int port);
#ifdef EMU_DEVICE_H #ifdef EMU_DEVICE_H
extern const device_t *gameport_getdevice(int port); extern const device_t *gameport_get_device(int port);
#endif #endif
extern int gameport_has_config(int port); extern int gameport_has_config(int port);
extern const char *gameport_get_internal_name(int port); extern const char *gameport_get_internal_name(int port);
@@ -151,11 +151,11 @@ extern plat_joystick_state_t plat_joystick_state[MAX_PLAT_JOYSTICKS];
extern joystick_state_t joystick_state[GAMEPORT_MAX][MAX_JOYSTICKS]; extern joystick_state_t joystick_state[GAMEPORT_MAX][MAX_JOYSTICKS];
extern int joysticks_present; extern int joysticks_present;
extern int joystick_type; extern int joystick_type[GAMEPORT_MAX];
extern void joystick_init(void); extern void joystick_init(void);
extern void joystick_close(void); extern void joystick_close(void);
extern void joystick_process(void); extern void joystick_process(uint8_t gp);
extern const char *joystick_get_name(int js); extern const char *joystick_get_name(int js);
extern const char *joystick_get_internal_name(int js); extern const char *joystick_get_internal_name(int js);
@@ -168,7 +168,7 @@ extern const char *joystick_get_axis_name(int js, int id);
extern const char *joystick_get_button_name(int js, int id); extern const char *joystick_get_button_name(int js, int id);
extern const char *joystick_get_pov_name(int js, int id); extern const char *joystick_get_pov_name(int js, int id);
extern void gameport_update_joystick_type(void); extern void gameport_update_joystick_type(uint8_t gp);
extern void gameport_remap(void *priv, uint16_t address); extern void gameport_remap(void *priv, uint16_t address);
extern void *gameport_add(const device_t *gameport_type); extern void *gameport_add(const device_t *gameport_type);

View File

@@ -625,7 +625,7 @@ europc_boot(UNUSED(const device_t *info))
mouse_bus_set_irq(sys->mouse, 2); mouse_bus_set_irq(sys->mouse, 2);
/* Configure the port for (Bus Mouse Compatible) Mouse. */ /* Configure the port for (Bus Mouse Compatible) Mouse. */
b |= 0x01; b |= 0x01;
} else if (joystick_type) } else if (joystick_type[0])
b |= 0x02; /* enable port as joysticks */ b |= 0x02; /* enable port as joysticks */
sys->nvr.regs[MRTC_CONF_C] = b; sys->nvr.regs[MRTC_CONF_C] = b;

View File

@@ -2397,7 +2397,7 @@ machine_xt_m240_init(const machine_t *model)
if (fdc_current[0] == FDC_INTERNAL) if (fdc_current[0] == FDC_INTERNAL)
device_add(&fdc_at_device); /* io.c logs clearly show it using port 3F7 */ device_add(&fdc_at_device); /* io.c logs clearly show it using port 3F7 */
if (joystick_type) if (joystick_type[0])
device_add(&gameport_200_device); device_add(&gameport_200_device);
nmi_init(); nmi_init();

View File

@@ -374,6 +374,8 @@ if (WIN32)
target_sources(ui PRIVATE target_sources(ui PRIVATE
qt_winrawinputfilter.hpp qt_winrawinputfilter.hpp
qt_winrawinputfilter.cpp qt_winrawinputfilter.cpp
qt_vmmanager_windarkmodefilter.hpp
qt_vmmanager_windarkmodefilter.cpp
qt_winmanagerfilter.hpp qt_winmanagerfilter.hpp
qt_winmanagerfilter.cpp qt_winmanagerfilter.cpp
) )

View File

@@ -247,7 +247,7 @@ msgid "&Rewind to the beginning"
msgstr "Ri&avvolgi all'inizio" msgstr "Ri&avvolgi all'inizio"
msgid "&Fast forward to the end" msgid "&Fast forward to the end"
msgstr "A&vanti veloce alla fine" msgstr "A&vanti veloce fino alla fine"
msgid "E&ject" msgid "E&ject"
msgstr "&Espelli" msgstr "&Espelli"
@@ -1075,7 +1075,7 @@ msgid "Start"
msgstr "Avvia" msgstr "Avvia"
msgid "Not running" msgid "Not running"
msgstr "Sospeso" msgstr "Inattivo"
msgid "Running" msgid "Running"
msgstr "In esecuzione" msgstr "In esecuzione"
@@ -1141,7 +1141,7 @@ msgid "New configuration"
msgstr "Nuova configurazione" msgstr "Nuova configurazione"
msgid "Complete" msgid "Complete"
msgstr "Completare" msgstr "Completamento"
msgid "The wizard will now launch the configuration for the new system." msgid "The wizard will now launch the configuration for the new system."
msgstr "La procedura guidata avvierà ora la configurazione del nuovo sistema." msgstr "La procedura guidata avvierà ora la configurazione del nuovo sistema."
@@ -2932,7 +2932,7 @@ msgid "The system will not be added."
msgstr "Il sistema non verrà aggiunto." msgstr "Il sistema non verrà aggiunto."
msgid "&Update mouse every CPU frame" msgid "&Update mouse every CPU frame"
msgstr "&Aggiorano stato mouse ad ogni blocco CPU" msgstr "&Aggiorna stato del mouse ad ogni blocco della CPU"
msgid "Hue" msgid "Hue"
msgstr "Tinta" msgstr "Tinta"
@@ -2950,7 +2950,7 @@ msgid "Sharpness"
msgstr "Nitidezza" msgstr "Nitidezza"
msgid "&CGA composite settings..." msgid "&CGA composite settings..."
msgstr "Impostazioni del modo composito &CGA..." msgstr "Impostazioni video composito &CGA..."
msgid "CGA composite settings" msgid "CGA composite settings"
msgstr "Impostazioni del modo composito CGA" msgstr "Impostazioni video composito CGA"

View File

@@ -27,10 +27,11 @@ extern "C" {
#include <QDialogButtonBox> #include <QDialogButtonBox>
#include "qt_models_common.hpp" #include "qt_models_common.hpp"
JoystickConfiguration::JoystickConfiguration(int type, int joystick_nr, QWidget *parent) JoystickConfiguration::JoystickConfiguration(int type, uint8_t gameport_nr, int joystick_nr, QWidget *parent)
: QDialog(parent) : QDialog(parent)
, ui(new Ui::JoystickConfiguration) , ui(new Ui::JoystickConfiguration)
, type(type) , type(type)
, gameport_nr(gameport_nr)
, joystick_nr(joystick_nr) , joystick_nr(joystick_nr)
{ {
ui->setupUi(this); ui->setupUi(this);
@@ -41,7 +42,7 @@ JoystickConfiguration::JoystickConfiguration(int type, int joystick_nr, QWidget
Models::AddEntry(model, plat_joystick_state[c].name, c + 1); Models::AddEntry(model, plat_joystick_state[c].name, c + 1);
} }
ui->comboBoxDevice->setCurrentIndex(joystick_state[0][joystick_nr].plat_joystick_nr); ui->comboBoxDevice->setCurrentIndex(joystick_state[gameport_nr][joystick_nr].plat_joystick_nr);
layout()->setSizeConstraint(QLayout::SetFixedSize); layout()->setSizeConstraint(QLayout::SetFixedSize);
} }
@@ -119,7 +120,7 @@ JoystickConfiguration::on_comboBoxDevice_currentIndexChanged(int index)
} }
int nr_axes = plat_joystick_state[joystick].nr_axes; int nr_axes = plat_joystick_state[joystick].nr_axes;
int mapping = joystick_state[0][joystick_nr].axis_mapping[c]; int mapping = joystick_state[gameport_nr][joystick_nr].axis_mapping[c];
if (mapping & POV_X) if (mapping & POV_X)
cbox->setCurrentIndex(nr_axes + (mapping & 3) * 2); cbox->setCurrentIndex(nr_axes + (mapping & 3) * 2);
else if (mapping & POV_Y) else if (mapping & POV_Y)
@@ -147,7 +148,7 @@ JoystickConfiguration::on_comboBoxDevice_currentIndexChanged(int index)
Models::AddEntry(model, plat_joystick_state[joystick].button[d].name, 0); Models::AddEntry(model, plat_joystick_state[joystick].button[d].name, 0);
} }
cbox->setCurrentIndex(joystick_state[0][joystick_nr].button_mapping[c]); cbox->setCurrentIndex(joystick_state[gameport_nr][joystick_nr].button_mapping[c]);
ui->ct->addWidget(label, row, 0); ui->ct->addWidget(label, row, 0);
ui->ct->addWidget(cbox, row, 1); ui->ct->addWidget(cbox, row, 1);
@@ -179,7 +180,7 @@ JoystickConfiguration::on_comboBoxDevice_currentIndexChanged(int index)
Models::AddEntry(model, plat_joystick_state[joystick].axis[d].name, 0); Models::AddEntry(model, plat_joystick_state[joystick].axis[d].name, 0);
} }
int mapping = joystick_state[0][joystick_nr].pov_mapping[c / 2][c & 1]; int mapping = joystick_state[gameport_nr][joystick_nr].pov_mapping[c / 2][c & 1];
int nr_povs = plat_joystick_state[joystick].nr_povs; int nr_povs = plat_joystick_state[joystick].nr_povs;
if (mapping & POV_X) if (mapping & POV_X)
cbox->setCurrentIndex((mapping & 3) * 2); cbox->setCurrentIndex((mapping & 3) * 2);

View File

@@ -11,7 +11,7 @@ class JoystickConfiguration : public QDialog {
Q_OBJECT Q_OBJECT
public: public:
explicit JoystickConfiguration(int type, int joystick_nr, QWidget *parent = nullptr); explicit JoystickConfiguration(int type, uint8_t gameport_nr, int joystick_nr, QWidget *parent = nullptr);
~JoystickConfiguration(); ~JoystickConfiguration();
int selectedDevice(); int selectedDevice();
@@ -25,6 +25,7 @@ private:
Ui::JoystickConfiguration *ui; Ui::JoystickConfiguration *ui;
QList<QWidget *> widgets; QList<QWidget *> widgets;
int type; int type;
int gameport_nr;
int joystick_nr; int joystick_nr;
}; };

View File

@@ -66,6 +66,7 @@ extern "C" {
# include "qt_rendererstack.hpp" # include "qt_rendererstack.hpp"
# include "qt_winrawinputfilter.hpp" # include "qt_winrawinputfilter.hpp"
# include "qt_winmanagerfilter.hpp" # include "qt_winmanagerfilter.hpp"
# include "qt_vmmanager_windarkmodefilter.hpp"
# include <86box/win.h> # include <86box/win.h>
# include <shobjidl.h> # include <shobjidl.h>
# include <windows.h> # include <windows.h>
@@ -514,10 +515,6 @@ main_thread_fn()
static std::thread *main_thread; static std::thread *main_thread;
#ifdef Q_OS_WINDOWS
extern bool windows_is_light_theme();
#endif
int int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
@@ -548,7 +545,7 @@ main(int argc, char *argv[])
} }
QApplication::setAttribute(Qt::AA_NativeWindows); QApplication::setAttribute(Qt::AA_NativeWindows);
if (!windows_is_light_theme()) { if (!util::isWindowsLightTheme()) {
QFile f(":qdarkstyle/dark/darkstyle.qss"); QFile f(":qdarkstyle/dark/darkstyle.qss");
if (!f.exists()) { if (!f.exists()) {
@@ -558,6 +555,10 @@ main(int argc, char *argv[])
QTextStream ts(&f); QTextStream ts(&f);
qApp->setStyleSheet(ts.readAll()); qApp->setStyleSheet(ts.readAll());
} }
QPalette palette(qApp->palette());
palette.setColor(QPalette::Link, Qt::white);
palette.setColor(QPalette::LinkVisited, Qt::lightGray);
qApp->setPalette(palette);
} }
#endif #endif
@@ -632,8 +633,19 @@ main(int argc, char *argv[])
// QApplication::setApplicationDisplayName("86Box VM Manager"); // QApplication::setApplicationDisplayName("86Box VM Manager");
// vmm.show(); // vmm.show();
// vmm.exec(); // vmm.exec();
#ifdef Q_OS_WINDOWS
auto darkModeFilter = std::unique_ptr<WindowsDarkModeFilter>(new WindowsDarkModeFilter());
if (darkModeFilter) {
qApp->installNativeEventFilter(darkModeFilter.get());
}
QTimer::singleShot(0, [&darkModeFilter] {
#else
QTimer::singleShot(0, [] { QTimer::singleShot(0, [] {
#endif
const auto vmm_main_window = new VMManagerMainWindow(); const auto vmm_main_window = new VMManagerMainWindow();
#ifdef Q_OS_WINDOWS
darkModeFilter.get()->setWindow(vmm_main_window);
#endif
vmm_main_window->show(); vmm_main_window->show();
}); });
QApplication::exec(); QApplication::exec();

View File

@@ -8,8 +8,6 @@
* *
* Mouse/Joystick configuration UI module. * Mouse/Joystick configuration UI module.
* *
*
*
* Authors: Joakim L. Gilje <jgilje@jgilje.net> * Authors: Joakim L. Gilje <jgilje@jgilje.net>
* *
* Copyright 2021 Joakim L. Gilje * Copyright 2021 Joakim L. Gilje
@@ -95,7 +93,7 @@ SettingsInput::save()
keyboard_type = ui->comboBoxKeyboard->currentData().toInt(); keyboard_type = ui->comboBoxKeyboard->currentData().toInt();
mouse_type = ui->comboBoxMouse->currentData().toInt(); mouse_type = ui->comboBoxMouse->currentData().toInt();
joystick_type = ui->comboBoxJoystick->currentData().toInt(); joystick_type[0] = ui->comboBoxJoystick0->currentData().toInt();
// Copy accelerators from working set to global set // Copy accelerators from working set to global set
for(int x = 0; x < NUM_ACCELS; x++) { for(int x = 0; x < NUM_ACCELS; x++) {
@@ -179,21 +177,22 @@ SettingsInput::onCurrentMachineChanged(int machineId)
ui->comboBoxMouse->setCurrentIndex(-1); ui->comboBoxMouse->setCurrentIndex(-1);
ui->comboBoxMouse->setCurrentIndex(selectedRow); ui->comboBoxMouse->setCurrentIndex(selectedRow);
// Joysticks
int i = 0; int i = 0;
const char *joyName = joystick_get_name(i); const char *joyName = joystick_get_name(i);
auto *joystickModel = ui->comboBoxJoystick->model(); auto *joystickModel = ui->comboBoxJoystick0->model();
removeRows = joystickModel->rowCount(); removeRows = joystickModel->rowCount();
selectedRow = 0; selectedRow = 0;
while (joyName) { while (joyName) {
int row = Models::AddEntry(joystickModel, tr(joyName).toUtf8().data(), i); int row = Models::AddEntry(joystickModel, tr(joyName).toUtf8().data(), i);
if (i == joystick_type) if (i == joystick_type[0])
selectedRow = row - removeRows; selectedRow = row - removeRows;
++i; ++i;
joyName = joystick_get_name(i); joyName = joystick_get_name(i);
} }
joystickModel->removeRows(0, removeRows); joystickModel->removeRows(0, removeRows);
ui->comboBoxJoystick->setCurrentIndex(selectedRow); ui->comboBoxJoystick0->setCurrentIndex(selectedRow);
} }
void void
@@ -309,11 +308,11 @@ SettingsInput::on_comboBoxMouse_currentIndexChanged(int index)
} }
void void
SettingsInput::on_comboBoxJoystick_currentIndexChanged(int index) SettingsInput::on_comboBoxJoystick0_currentIndexChanged(int index)
{ {
int joystickId = ui->comboBoxJoystick->currentData().toInt(); int joystickId = ui->comboBoxJoystick0->currentData().toInt();
for (int i = 0; i < MAX_JOYSTICKS; ++i) { for (int i = 0; i < MAX_JOYSTICKS; ++i) {
auto *btn = findChild<QPushButton *>(QString("pushButtonJoystick%1").arg(i + 1)); auto *btn = findChild<QPushButton *>(QString("pushButtonJoystick0%1").arg(i + 1));
if (btn == nullptr) if (btn == nullptr)
continue; continue;
@@ -336,10 +335,10 @@ SettingsInput::on_pushButtonConfigureMouse_clicked()
} }
static int static int
get_axis(JoystickConfiguration &jc, int axis, int joystick_nr) get_axis(JoystickConfiguration &jc, int axis, uint8_t gameport_nr, int joystick_nr)
{ {
int axis_sel = jc.selectedAxis(axis); int axis_sel = jc.selectedAxis(axis);
int nr_axes = plat_joystick_state[joystick_state[0][joystick_nr].plat_joystick_nr - 1].nr_axes; int nr_axes = plat_joystick_state[joystick_state[gameport_nr][joystick_nr].plat_joystick_nr - 1].nr_axes;
if (axis_sel < nr_axes) if (axis_sel < nr_axes)
return axis_sel; return axis_sel;
@@ -352,10 +351,10 @@ get_axis(JoystickConfiguration &jc, int axis, int joystick_nr)
} }
static int static int
get_pov(JoystickConfiguration &jc, int pov, int joystick_nr) get_pov(JoystickConfiguration &jc, int pov, uint8_t gameport_nr, int joystick_nr)
{ {
int pov_sel = jc.selectedPov(pov); int pov_sel = jc.selectedPov(pov);
int nr_povs = plat_joystick_state[joystick_state[0][joystick_nr].plat_joystick_nr - 1].nr_povs * 2; int nr_povs = plat_joystick_state[joystick_state[gameport_nr][joystick_nr].plat_joystick_nr - 1].nr_povs * 2;
if (pov_sel < nr_povs) { if (pov_sel < nr_povs) {
if (pov_sel & 1) if (pov_sel & 1)
@@ -368,9 +367,9 @@ get_pov(JoystickConfiguration &jc, int pov, int joystick_nr)
} }
static void static void
updateJoystickConfig(int type, int joystick_nr, QWidget *parent) updateJoystickConfig(int type, uint8_t gameport_nr, int joystick_nr, QWidget *parent)
{ {
JoystickConfiguration jc(type, joystick_nr, parent); JoystickConfiguration jc(type, gameport_nr, joystick_nr, parent);
switch (jc.exec()) { switch (jc.exec()) {
case QDialog::Rejected: case QDialog::Rejected:
return; return;
@@ -378,43 +377,43 @@ updateJoystickConfig(int type, int joystick_nr, QWidget *parent)
break; break;
} }
joystick_state[0][joystick_nr].plat_joystick_nr = jc.selectedDevice(); joystick_state[gameport_nr][joystick_nr].plat_joystick_nr = jc.selectedDevice();
if (joystick_state[0][joystick_nr].plat_joystick_nr) { if (joystick_state[gameport_nr][joystick_nr].plat_joystick_nr) {
for (int axis_nr = 0; axis_nr < joystick_get_axis_count(type); axis_nr++) { for (int axis_nr = 0; axis_nr < joystick_get_axis_count(type); axis_nr++) {
joystick_state[0][joystick_nr].axis_mapping[axis_nr] = get_axis(jc, axis_nr, joystick_nr); joystick_state[gameport_nr][joystick_nr].axis_mapping[axis_nr] = get_axis(jc, axis_nr, gameport_nr, joystick_nr);
} }
for (int button_nr = 0; button_nr < joystick_get_button_count(type); button_nr++) { for (int button_nr = 0; button_nr < joystick_get_button_count(type); button_nr++) {
joystick_state[0][joystick_nr].button_mapping[button_nr] = jc.selectedButton(button_nr); joystick_state[gameport_nr][joystick_nr].button_mapping[button_nr] = jc.selectedButton(button_nr);
} }
for (int pov_nr = 0; pov_nr < joystick_get_pov_count(type) * 2; pov_nr += 2) { for (int pov_nr = 0; pov_nr < joystick_get_pov_count(type) * 2; pov_nr += 2) {
joystick_state[0][joystick_nr].pov_mapping[pov_nr][0] = get_pov(jc, pov_nr, joystick_nr); joystick_state[gameport_nr][joystick_nr].pov_mapping[pov_nr][0] = get_pov(jc, pov_nr, gameport_nr, joystick_nr);
joystick_state[0][joystick_nr].pov_mapping[pov_nr][1] = get_pov(jc, pov_nr + 1, joystick_nr); joystick_state[gameport_nr][joystick_nr].pov_mapping[pov_nr][1] = get_pov(jc, pov_nr + 1, gameport_nr, joystick_nr);
} }
} }
} }
void void
SettingsInput::on_pushButtonJoystick1_clicked() SettingsInput::on_pushButtonJoystick01_clicked()
{ {
updateJoystickConfig(ui->comboBoxJoystick->currentData().toInt(), 0, this); updateJoystickConfig(ui->comboBoxJoystick0->currentData().toInt(), 0, 0, this);
} }
void void
SettingsInput::on_pushButtonJoystick2_clicked() SettingsInput::on_pushButtonJoystick02_clicked()
{ {
updateJoystickConfig(ui->comboBoxJoystick->currentData().toInt(), 1, this); updateJoystickConfig(ui->comboBoxJoystick0->currentData().toInt(), 0, 1, this);
} }
void void
SettingsInput::on_pushButtonJoystick3_clicked() SettingsInput::on_pushButtonJoystick03_clicked()
{ {
updateJoystickConfig(ui->comboBoxJoystick->currentData().toInt(), 2, this); updateJoystickConfig(ui->comboBoxJoystick0->currentData().toInt(), 0, 2, this);
} }
void void
SettingsInput::on_pushButtonJoystick4_clicked() SettingsInput::on_pushButtonJoystick04_clicked()
{ {
updateJoystickConfig(ui->comboBoxJoystick->currentData().toInt(), 3, this); updateJoystickConfig(ui->comboBoxJoystick0->currentData().toInt(), 0, 3, this);
} }

View File

@@ -32,22 +32,22 @@ private slots:
void on_comboBoxMouse_currentIndexChanged(int index); void on_comboBoxMouse_currentIndexChanged(int index);
void on_pushButtonConfigureMouse_clicked(); void on_pushButtonConfigureMouse_clicked();
void on_comboBoxJoystick_currentIndexChanged(int index); void on_comboBoxJoystick0_currentIndexChanged(int index);
void on_pushButtonJoystick1_clicked(); void on_pushButtonJoystick01_clicked();
void on_pushButtonJoystick2_clicked(); void on_pushButtonJoystick02_clicked();
void on_pushButtonJoystick3_clicked(); void on_pushButtonJoystick03_clicked();
void on_pushButtonJoystick4_clicked(); void on_pushButtonJoystick04_clicked();
void on_tableKeys_cellDoubleClicked(int row, int col); void on_tableKeys_cellDoubleClicked(int row, int col);
void on_tableKeys_currentCellChanged(int currentRow, int currentColumn, int previousRow, int previousColumn); void on_tableKeys_currentCellChanged(int currentRow, int currentColumn, int previousRow, int previousColumn);
void on_pushButtonClearBind_clicked(); void on_pushButtonClearBind_clicked();
void on_pushButtonBind_clicked(); void on_pushButtonBind_clicked();
private: private:
Ui::SettingsInput *ui; Ui::SettingsInput *ui;
int machineId = 0; int machineId = 0;
void refreshInputList(); void refreshInputList();
}; };
#endif // QT_SETTINGSINPUT_HPP #endif // QT_SETTINGSINPUT_HPP

View File

@@ -90,42 +90,42 @@
</widget> </widget>
</item> </item>
<item row="2" column="0"> <item row="2" column="0">
<widget class="QLabel" name="labelJoystick"> <widget class="QLabel" name="labelJoystick0">
<property name="text"> <property name="text">
<string>Joystick:</string> <string>Joystick:</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="1" colspan="2"> <item row="2" column="1" colspan="2">
<widget class="QComboBox" name="comboBoxJoystick"> <widget class="QComboBox" name="comboBoxJoystick0">
<property name="maxVisibleItems"> <property name="maxVisibleItems">
<number>30</number> <number>30</number>
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="0"> <item row="3" column="0">
<widget class="QPushButton" name="pushButtonJoystick1"> <widget class="QPushButton" name="pushButtonJoystick01">
<property name="text"> <property name="text">
<string>Joystick 1...</string> <string>Joystick 1...</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="1"> <item row="3" column="1">
<widget class="QPushButton" name="pushButtonJoystick2"> <widget class="QPushButton" name="pushButtonJoystick02">
<property name="text"> <property name="text">
<string>Joystick 2...</string> <string>Joystick 2...</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="2"> <item row="3" column="2">
<widget class="QPushButton" name="pushButtonJoystick3"> <widget class="QPushButton" name="pushButtonJoystick03">
<property name="text"> <property name="text">
<string>Joystick 3...</string> <string>Joystick 3...</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="3"> <item row="3" column="3">
<widget class="QPushButton" name="pushButtonJoystick4"> <widget class="QPushButton" name="pushButtonJoystick04">
<property name="text"> <property name="text">
<string>Joystick 4...</string> <string>Joystick 4...</string>
</property> </property>

View File

@@ -15,6 +15,7 @@
* Copyright 2022 Teemu Korhonen * Copyright 2022 Teemu Korhonen
*/ */
#include "qt_styleoverride.hpp" #include "qt_styleoverride.hpp"
#include "qt_util.hpp"
#include <QComboBox> #include <QComboBox>
#include <QAbstractItemView> #include <QAbstractItemView>
@@ -64,8 +65,7 @@ StyleOverride::polish(QWidget *widget)
} }
widget->setWindowFlag(Qt::WindowContextHelpButtonHint, false); widget->setWindowFlag(Qt::WindowContextHelpButtonHint, false);
#ifdef Q_OS_WINDOWS #ifdef Q_OS_WINDOWS
extern bool windows_is_light_theme(); BOOL DarkMode = !util::isWindowsLightTheme();
BOOL DarkMode = !windows_is_light_theme();
DwmSetWindowAttribute((HWND)widget->winId(), DWMWA_USE_IMMERSIVE_DARK_MODE, (LPCVOID)&DarkMode, sizeof(DarkMode)); DwmSetWindowAttribute((HWND)widget->winId(), DWMWA_USE_IMMERSIVE_DARK_MODE, (LPCVOID)&DarkMode, sizeof(DarkMode));
#endif #endif
} }

View File

@@ -27,6 +27,7 @@
#include "qt_util.hpp" #include "qt_util.hpp"
#ifdef Q_OS_WINDOWS #ifdef Q_OS_WINDOWS
# include <windows.h>
# include <dwmapi.h> # include <dwmapi.h>
# ifndef DWMWA_WINDOW_CORNER_PREFERENCE # ifndef DWMWA_WINDOW_CORNER_PREFERENCE
# define DWMWA_WINDOW_CORNER_PREFERENCE 33 # define DWMWA_WINDOW_CORNER_PREFERENCE 33
@@ -62,6 +63,36 @@ screenOfWidget(QWidget *widget)
} }
#ifdef Q_OS_WINDOWS #ifdef Q_OS_WINDOWS
bool
isWindowsLightTheme(void) {
// based on https://stackoverflow.com/questions/51334674/how-to-detect-windows-10-light-dark-mode-in-win32-application
// The value is expected to be a REG_DWORD, which is a signed 32-bit little-endian
auto buffer = std::vector<char>(4);
auto cbData = static_cast<DWORD>(buffer.size() * sizeof(char));
auto res = RegGetValueW(
HKEY_CURRENT_USER,
L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize",
L"AppsUseLightTheme",
RRF_RT_REG_DWORD, // expected value type
nullptr,
buffer.data(),
&cbData);
if (res != ERROR_SUCCESS) {
return 1;
}
// convert bytes written to our buffer to an int, assuming little-endian
auto i = int(buffer[3] << 24 |
buffer[2] << 16 |
buffer[1] << 8 |
buffer[0]);
return i == 1;
}
void void
setWin11RoundedCorners(WId hwnd, bool enable) setWin11RoundedCorners(WId hwnd, bool enable)
{ {

View File

@@ -15,6 +15,7 @@ QString DlgFilter(QStringList extensions, bool last = false);
/* Returns screen the widget is on */ /* Returns screen the widget is on */
QScreen *screenOfWidget(QWidget *widget); QScreen *screenOfWidget(QWidget *widget);
#ifdef Q_OS_WINDOWS #ifdef Q_OS_WINDOWS
bool isWindowsLightTheme(void);
void setWin11RoundedCorners(WId hwnd, bool enable); void setWin11RoundedCorners(WId hwnd, bool enable);
#endif #endif
QString currentUuid(); QString currentUuid();

View File

@@ -19,12 +19,19 @@
#include <QDebug> #include <QDebug>
#include <QStyle> #include <QStyle>
#include "qt_util.hpp"
#include "qt_vmmanager_details.hpp" #include "qt_vmmanager_details.hpp"
#include "ui_qt_vmmanager_details.h" #include "ui_qt_vmmanager_details.h"
#define TOOLBUTTON_STYLESHEET_LIGHT "QToolButton {background: transparent; border: none; padding: 5px} QToolButton:hover {background: palette(midlight)} QToolButton:pressed {background: palette(mid)}"
#ifdef Q_OS_WINDOWS #ifdef Q_OS_WINDOWS
extern bool windows_is_light_theme(); # define TOOLBUTTON_STYLESHEET_DARK "QToolButton {padding: 5px}"
# define SCREENSHOTBORDER_STYLESHEET_DARK "QLabel { border: 1px solid gray }"
#else
# define TOOLBUTTON_STYLESHEET_DARK "QToolButton {background: transparent; border: none; padding: 5px} QToolButton:hover {background: palette(dark)} QToolButton:pressed {background: palette(mid)}"
#endif #endif
#define SCROLLAREA_STYLESHEET_LIGHT "QWidget {background-color: palette(light)} QScrollBar{ background-color: none }"
#define SYSTEMLABEL_STYLESHEET_LIGHT "background-color: palette(midlight);"
using namespace VMManager; using namespace VMManager;
@@ -100,18 +107,14 @@ VMManagerDetails::VMManagerDetails(QWidget *parent) :
QString toolButtonStyleSheet; QString toolButtonStyleSheet;
// Simple method to try and determine if light mode is enabled // Simple method to try and determine if light mode is enabled
#ifdef Q_OS_WINDOWS #ifdef Q_OS_WINDOWS
const bool lightMode = windows_is_light_theme(); const bool lightMode = util::isWindowsLightTheme();
#else #else
const bool lightMode = QApplication::palette().window().color().value() > QApplication::palette().windowText().color().value(); const bool lightMode = QApplication::palette().window().color().value() > QApplication::palette().windowText().color().value();
#endif #endif
if (lightMode) { if (lightMode) {
toolButtonStyleSheet = "QToolButton {background: transparent; border: none; padding: 5px} QToolButton:hover {background: palette(midlight)} QToolButton:pressed {background: palette(mid)}"; toolButtonStyleSheet = TOOLBUTTON_STYLESHEET_LIGHT;
} else { } else {
#ifndef Q_OS_WINDOWS toolButtonStyleSheet = TOOLBUTTON_STYLESHEET_DARK;
toolButtonStyleSheet = "QToolButton {background: transparent; border: none; padding: 5px} QToolButton:hover {background: palette(dark)} QToolButton:pressed {background: palette(mid)}";
#else
toolButtonStyleSheet = "QToolButton {padding: 5px}";
#endif
} }
ui->ssNavTBHolder->setStyleSheet(toolButtonStyleSheet); ui->ssNavTBHolder->setStyleSheet(toolButtonStyleSheet);
@@ -150,6 +153,17 @@ VMManagerDetails::VMManagerDetails(QWidget *parent) :
ui->notesTextEdit->setEnabled(false); ui->notesTextEdit->setEnabled(false);
#ifdef Q_OS_WINDOWS
connect(this, &VMManagerDetails::styleUpdated, systemSection, &VMManagerDetailSection::updateStyle);
connect(this, &VMManagerDetails::styleUpdated, videoSection, &VMManagerDetailSection::updateStyle);
connect(this, &VMManagerDetails::styleUpdated, storageSection, &VMManagerDetailSection::updateStyle);
connect(this, &VMManagerDetails::styleUpdated, audioSection, &VMManagerDetailSection::updateStyle);
connect(this, &VMManagerDetails::styleUpdated, networkSection, &VMManagerDetailSection::updateStyle);
connect(this, &VMManagerDetails::styleUpdated, inputSection, &VMManagerDetailSection::updateStyle);
connect(this, &VMManagerDetails::styleUpdated, portsSection, &VMManagerDetailSection::updateStyle);
connect(this, &VMManagerDetails::styleUpdated, otherSection, &VMManagerDetailSection::updateStyle);
#endif
sysconfig = new VMManagerSystem(); sysconfig = new VMManagerSystem();
} }
@@ -163,12 +177,11 @@ VMManagerDetails::updateData(VMManagerSystem *passed_sysconfig) {
// Set the scrollarea background but also set the scroll bar to none. Otherwise it will also // Set the scrollarea background but also set the scroll bar to none. Otherwise it will also
// set the scrollbar background to the same. // set the scrollbar background to the same.
#ifdef Q_OS_WINDOWS #ifdef Q_OS_WINDOWS
extern bool windows_is_light_theme(); if (util::isWindowsLightTheme())
if (windows_is_light_theme())
#endif #endif
{ {
ui->scrollArea->setStyleSheet("QWidget {background-color: palette(light)} QScrollBar{ background-color: none }"); ui->scrollArea->setStyleSheet(SCROLLAREA_STYLESHEET_LIGHT);
ui->systemLabel->setStyleSheet("background-color: palette(midlight);"); ui->systemLabel->setStyleSheet(SYSTEMLABEL_STYLESHEET_LIGHT);
} }
// Margins are a little different on macos // Margins are a little different on macos
#ifdef Q_OS_MACOS #ifdef Q_OS_MACOS
@@ -331,8 +344,8 @@ VMManagerDetails::updateScreenshots(VMManagerSystem *passed_sysconfig) {
ui->screenshot->setEnabled(false); ui->screenshot->setEnabled(false);
ui->screenshot->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter); ui->screenshot->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
#ifdef Q_OS_WINDOWS #ifdef Q_OS_WINDOWS
if (!windows_is_light_theme()) { if (!util::isWindowsLightTheme()) {
ui->screenshot->setStyleSheet("QLabel { border: 1px solid gray }"); ui->screenshot->setStyleSheet(SCREENSHOTBORDER_STYLESHEET_DARK);
} else { } else {
ui->screenshot->setStyleSheet(""); ui->screenshot->setStyleSheet("");
} }
@@ -390,6 +403,32 @@ VMManagerDetails::updateWindowStatus()
updateProcessStatus(); updateProcessStatus();
} }
#ifdef Q_OS_WINDOWS
void
VMManagerDetails::updateStyle()
{
QString toolButtonStyleSheet;
const bool lightMode = util::isWindowsLightTheme();
if (lightMode) {
toolButtonStyleSheet = TOOLBUTTON_STYLESHEET_LIGHT;
ui->scrollArea->setStyleSheet(SCROLLAREA_STYLESHEET_LIGHT);
ui->systemLabel->setStyleSheet(SYSTEMLABEL_STYLESHEET_LIGHT);
if (!ui->screenshot->isEnabled())
ui->screenshot->setStyleSheet("");
} else {
toolButtonStyleSheet = TOOLBUTTON_STYLESHEET_DARK;
ui->scrollArea->setStyleSheet("");
ui->systemLabel->setStyleSheet("");
if (!ui->screenshot->isEnabled())
ui->screenshot->setStyleSheet(SCREENSHOTBORDER_STYLESHEET_DARK);
}
ui->ssNavTBHolder->setStyleSheet(toolButtonStyleSheet);
ui->toolButtonHolder->setStyleSheet(toolButtonStyleSheet);
emit styleUpdated();
}
#endif
QWidget * QWidget *
VMManagerDetails::createHorizontalLine(const int leftSpacing, const int rightSpacing) VMManagerDetails::createHorizontalLine(const int leftSpacing, const int rightSpacing)
{ {

View File

@@ -42,8 +42,18 @@ public:
void updateProcessStatus(); void updateProcessStatus();
void updateWindowStatus(); void updateWindowStatus();
#ifdef Q_OS_WINDOWS
void updateStyle();
#endif
// CollapseButton *systemCollapseButton; // CollapseButton *systemCollapseButton;
#ifdef Q_OS_WINDOWS
signals:
void styleUpdated();
#endif
private: private:
Ui::VMManagerDetails *ui; Ui::VMManagerDetails *ui;
VMManagerSystem *sysconfig; VMManagerSystem *sysconfig;

View File

@@ -19,6 +19,15 @@
#include "ui_qt_vmmanager_detailsection.h" #include "ui_qt_vmmanager_detailsection.h"
#include <QPushButton> #include <QPushButton>
#include "qt_util.hpp"
#define HEADER_STYLESHEET_LIGHT "background-color: palette(midlight);"
#ifdef Q_OS_WINDOWS
# define HEADER_STYLESHEET_DARK "background-color: #616161;"
# define BACKGROUND_STYLESHEET_DARK "background-color: #272727;"
#else
# define HEADER_STYLESHEET_DARK "background-color: palette(mid);"
#endif
const QString VMManagerDetailSection::sectionSeparator = ";"; const QString VMManagerDetailSection::sectionSeparator = ";";
using namespace VMManager; using namespace VMManager;
@@ -40,21 +49,18 @@ VMManagerDetailSection(const QString &sectionName)
// Simple method to try and determine if light mode is enabled on the host // Simple method to try and determine if light mode is enabled on the host
#ifdef Q_OS_WINDOWS #ifdef Q_OS_WINDOWS
extern bool windows_is_light_theme(); const bool lightMode = util::isWindowsLightTheme();
const bool lightMode = windows_is_light_theme();
#else #else
const bool lightMode = QApplication::palette().window().color().value() > QApplication::palette().windowText().color().value(); const bool lightMode = QApplication::palette().window().color().value() > QApplication::palette().windowText().color().value();
#endif #endif
// Alternate layout // Alternate layout
if ( lightMode) { if (lightMode) {
ui->collapseButtonHolder->setStyleSheet("background-color: palette(midlight);"); ui->collapseButtonHolder->setStyleSheet(HEADER_STYLESHEET_LIGHT);
} else { } else {
#ifdef Q_OS_WINDOWS #ifdef Q_OS_WINDOWS
ui->outerFrame->setStyleSheet("background-color: #272727;"); ui->outerFrame->setStyleSheet(BACKGROUND_STYLESHEET_DARK);
ui->collapseButtonHolder->setStyleSheet("background-color: #616161;");
#else
ui->collapseButtonHolder->setStyleSheet("background-color: palette(mid);");
#endif #endif
ui->collapseButtonHolder->setStyleSheet(HEADER_STYLESHEET_DARK);
} }
const auto sectionLabel = new QLabel(sectionName); const auto sectionLabel = new QLabel(sectionName);
sectionLabel->setStyleSheet(sectionLabel->styleSheet().append("font-weight: bold;")); sectionLabel->setStyleSheet(sectionLabel->styleSheet().append("font-weight: bold;"));
@@ -214,6 +220,21 @@ VMManagerDetailSection::clear()
ui->detailFrame->setLayout(frameGridLayout); ui->detailFrame->setLayout(frameGridLayout);
} }
#ifdef Q_OS_WINDOWS
void
VMManagerDetailSection::updateStyle()
{
const bool lightMode = util::isWindowsLightTheme();
if (lightMode) {
ui->outerFrame->setStyleSheet("");
ui->collapseButtonHolder->setStyleSheet(HEADER_STYLESHEET_LIGHT);
} else {
ui->outerFrame->setStyleSheet(BACKGROUND_STYLESHEET_DARK);
ui->collapseButtonHolder->setStyleSheet(HEADER_STYLESHEET_DARK);
}
}
#endif
// QT for Linux and Windows doesn't have the same default margins as QT on MacOS. // QT for Linux and Windows doesn't have the same default margins as QT on MacOS.
// For consistency in appearance we'll have to return the margins on a per-OS basis // For consistency in appearance we'll have to return the margins on a per-OS basis
QMargins QMargins

View File

@@ -74,6 +74,10 @@ public:
static const QString sectionSeparator; static const QString sectionSeparator;
#ifdef Q_OS_WINDOWS
public slots:
void updateStyle();
#endif
private: private:
enum class MarginSection { enum class MarginSection {

View File

@@ -18,13 +18,10 @@
#include <QApplication> #include <QApplication>
#include "qt_util.hpp"
#include "qt_vmmanager_listviewdelegate.hpp" #include "qt_vmmanager_listviewdelegate.hpp"
#include "qt_vmmanager_model.hpp" #include "qt_vmmanager_model.hpp"
#ifdef Q_OS_WINDOWS
extern bool windows_is_light_theme();
#endif
// Thanks to scopchanov https://github.com/scopchanov/SO-MessageLog // Thanks to scopchanov https://github.com/scopchanov/SO-MessageLog
// from https://stackoverflow.com/questions/53105343/is-it-possible-to-add-a-custom-widget-into-a-qlistview // from https://stackoverflow.com/questions/53105343/is-it-possible-to-add-a-custom-widget-into-a-qlistview
@@ -52,7 +49,7 @@ void VMManagerListViewDelegate::paint(QPainter *painter, const QStyleOptionViewI
const QModelIndex &index) const { const QModelIndex &index) const {
bool windows_light_mode = true; bool windows_light_mode = true;
#ifdef Q_OS_WINDOWS #ifdef Q_OS_WINDOWS
windows_light_mode = windows_is_light_theme(); windows_light_mode = util::isWindowsLightTheme();
#endif #endif
QStyleOptionViewItem opt(option); QStyleOptionViewItem opt(option);
initStyleOption(&opt, index); initStyleOption(&opt, index);

View File

@@ -349,7 +349,7 @@ illegal_chars:
}); });
// Initial default details view // Initial default details view
vm_details = new VMManagerDetails(); vm_details = new VMManagerDetails(ui->detailsArea);
ui->detailsArea->layout()->addWidget(vm_details); ui->detailsArea->layout()->addWidget(vm_details);
const QItemSelectionModel *selection_model = ui->listView->selectionModel(); const QItemSelectionModel *selection_model = ui->listView->selectionModel();
@@ -785,6 +785,14 @@ VMManagerMain::onLanguageUpdated()
vm_details->updateData(selected_sysconfig); vm_details->updateData(selected_sysconfig);
} }
#ifdef Q_OS_WINDOWS
void
VMManagerMain::onDarkModeUpdated()
{
vm_details->updateStyle();
}
#endif
int int
VMManagerMain::getActiveMachineCount() VMManagerMain::getActiveMachineCount()
{ {

View File

@@ -80,6 +80,9 @@ public slots:
void modelDataChange(); void modelDataChange();
void onPreferencesUpdated(); void onPreferencesUpdated();
void onLanguageUpdated(); void onLanguageUpdated();
#ifdef Q_OS_WINDOWS
void onDarkModeUpdated();
#endif
void onConfigUpdated(const QString &uuid); void onConfigUpdated(const QString &uuid);
int getActiveMachineCount(); int getActiveMachineCount();

View File

@@ -116,6 +116,9 @@ VMManagerMainWindow(QWidget *parent)
// Inform the main view when preferences are updated // Inform the main view when preferences are updated
connect(this, &VMManagerMainWindow::preferencesUpdated, vmm, &VMManagerMain::onPreferencesUpdated); connect(this, &VMManagerMainWindow::preferencesUpdated, vmm, &VMManagerMain::onPreferencesUpdated);
connect(this, &VMManagerMainWindow::languageUpdated, vmm, &VMManagerMain::onLanguageUpdated); connect(this, &VMManagerMainWindow::languageUpdated, vmm, &VMManagerMain::onLanguageUpdated);
#ifdef Q_OS_WINDOWS
connect(this, &VMManagerMainWindow::darkModeUpdated, vmm, &VMManagerMain::onDarkModeUpdated);
#endif
} }
@@ -178,6 +181,15 @@ VMManagerMainWindow::updateLanguage()
emit languageUpdated(); emit languageUpdated();
} }
#ifdef Q_OS_WINDOWS
void
VMManagerMainWindow::updateDarkMode()
{
emit darkModeUpdated();
}
#endif
void void
VMManagerMainWindow::changeEvent(QEvent *event) VMManagerMainWindow::changeEvent(QEvent *event)
{ {

View File

@@ -37,6 +37,9 @@ public:
signals: signals:
void preferencesUpdated(); void preferencesUpdated();
void languageUpdated(); void languageUpdated();
#ifdef Q_OS_WINDOWS
void darkModeUpdated();
#endif
private: private:
Ui::VMManagerMainWindow *ui; Ui::VMManagerMainWindow *ui;
@@ -48,6 +51,9 @@ public slots:
void setStatusLeft(const QString &text) const; void setStatusLeft(const QString &text) const;
void setStatusRight(const QString &text) const; void setStatusRight(const QString &text) const;
void updateLanguage(); void updateLanguage();
#ifdef Q_OS_WINDOWS
void updateDarkMode();
#endif
private slots: private slots:
void vmmSelectionChanged(const QModelIndex &currentSelection, QProcess::ProcessState processState) const; void vmmSelectionChanged(const QModelIndex &currentSelection, QProcess::ProcessState processState) const;

View File

@@ -78,7 +78,8 @@ void
VMManagerPreferences::chooseDirectoryLocation() VMManagerPreferences::chooseDirectoryLocation()
{ {
const auto directory = QFileDialog::getExistingDirectory(this, tr("Choose directory"), ui->systemDirectory->text()); const auto directory = QFileDialog::getExistingDirectory(this, tr("Choose directory"), ui->systemDirectory->text());
ui->systemDirectory->setText(QDir::toNativeSeparators(directory)); if (!directory.isEmpty())
ui->systemDirectory->setText(QDir::toNativeSeparators(directory));
} }
void void

View File

@@ -0,0 +1,99 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* Generic Windows native event filter for dark mode handling
*
*
*
* Authors: Teemu Korhonen
* Cacodemon345
*
* Copyright 2021 Teemu Korhonen
* Copyright 2024-2025 Cacodemon345.
*/
#include "qt_vmmanager_windarkmodefilter.hpp"
#include <QDebug>
#include <QTextStream>
#include <QFile>
#include <QApplication>
#include <QTimer>
#include <windows.h>
#include <dwmapi.h>
#ifndef DWMWA_USE_IMMERSIVE_DARK_MODE
#define DWMWA_USE_IMMERSIVE_DARK_MODE 20
#endif
#include <86box/86box.h>
#include <86box/plat.h>
#include "qt_util.hpp"
static bool NewDarkMode = FALSE;
void
WindowsDarkModeFilter::setWindow(VMManagerMainWindow *window)
{
this->window = window;
}
bool
WindowsDarkModeFilter::nativeEventFilter(const QByteArray &eventType, void *message, result_t *result)
{
if ((window != nullptr) && (eventType == "windows_generic_MSG")) {
MSG *msg = static_cast<MSG *>(message);
if ((msg != nullptr) && (msg->message == WM_SETTINGCHANGE)) {
if ((((void *) msg->lParam) != nullptr) &&
(wcscmp(L"ImmersiveColorSet", (wchar_t*)msg->lParam) == 0)) {
bool OldDarkMode = NewDarkMode;
if (!util::isWindowsLightTheme()) {
QFile f(":qdarkstyle/dark/darkstyle.qss");
if (!f.exists())
printf("Unable to set stylesheet, file not found\n");
else {
f.open(QFile::ReadOnly | QFile::Text);
QTextStream ts(&f);
qApp->setStyleSheet(ts.readAll());
}
QPalette palette(qApp->palette());
palette.setColor(QPalette::Link, Qt::white);
palette.setColor(QPalette::LinkVisited, Qt::lightGray);
qApp->setPalette(palette);
window->resize(window->size());
NewDarkMode = TRUE;
} else {
qApp->setStyleSheet("");
QPalette palette(qApp->palette());
palette.setColor(QPalette::Link, Qt::blue);
palette.setColor(QPalette::LinkVisited, Qt::magenta);
qApp->setPalette(palette);
window->resize(window->size());
NewDarkMode = FALSE;
}
window->updateDarkMode();
if (NewDarkMode != OldDarkMode) QTimer::singleShot(1000, [this] () {
BOOL DarkMode = NewDarkMode;
DwmSetWindowAttribute((HWND) window->winId(),
DWMWA_USE_IMMERSIVE_DARK_MODE,
(LPCVOID) &DarkMode,
sizeof(DarkMode));
});
}
}
}
return false;
}

View File

@@ -0,0 +1,47 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* Header file for Windows dark mode native messages filter
*
*
*
* Authors: Teemu Korhonen
*
* Copyright 2022 Teemu Korhonen
*/
#ifndef QT_WINDOWSDARKMODEEVENTFILTER_HPP
#define QT_WINDOWSDARKMODEEVENTFILTER_HPP
#include <QObject>
#include <QAbstractNativeEventFilter>
#include <QByteArray>
#include <QEvent>
#include <QWindow>
#include "qt_vmmanager_mainwindow.hpp"
#if QT_VERSION_MAJOR >= 6
# define result_t qintptr
#else
# define result_t long
#endif
class WindowsDarkModeFilter : public QObject, public QAbstractNativeEventFilter {
Q_OBJECT
public:
WindowsDarkModeFilter() = default;
void setWindow(VMManagerMainWindow *window);
bool nativeEventFilter(const QByteArray &eventType, void *message, result_t *result) override;
private:
VMManagerMainWindow *window;
};
#endif // QT_WINDOWSDARKMODEEVENTFILTER_HPP

View File

@@ -71,38 +71,11 @@ extern void win_keyboard_handle(uint32_t scancode, int up, int e0, int e1);
#include <memory> #include <memory>
#include "qt_rendererstack.hpp" #include "qt_rendererstack.hpp"
#include "qt_util.hpp"
#include "ui_qt_mainwindow.h" #include "ui_qt_mainwindow.h"
static bool NewDarkMode = FALSE; static bool NewDarkMode = FALSE;
bool windows_is_light_theme() {
// based on https://stackoverflow.com/questions/51334674/how-to-detect-windows-10-light-dark-mode-in-win32-application
// The value is expected to be a REG_DWORD, which is a signed 32-bit little-endian
auto buffer = std::vector<char>(4);
auto cbData = static_cast<DWORD>(buffer.size() * sizeof(char));
auto res = RegGetValueW(
HKEY_CURRENT_USER,
L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize",
L"AppsUseLightTheme",
RRF_RT_REG_DWORD, // expected value type
nullptr,
buffer.data(),
&cbData);
if (res != ERROR_SUCCESS) {
return 1;
}
// convert bytes written to our buffer to an int, assuming little-endian
auto i = int(buffer[3] << 24 |
buffer[2] << 16 |
buffer[1] << 8 |
buffer[0]);
return i == 1;
}
struct struct
{ {
HANDLE done_event = 0, ready_event = 0; HANDLE done_event = 0, ready_event = 0;
@@ -365,7 +338,7 @@ WindowsRawInputFilter::nativeEventFilter(const QByteArray &eventType, void *mess
} }
#endif #endif
if (!windows_is_light_theme()) { if (!util::isWindowsLightTheme()) {
QFile f(":qdarkstyle/dark/darkstyle.qss"); QFile f(":qdarkstyle/dark/darkstyle.qss");
if (!f.exists()) if (!f.exists())
@@ -375,9 +348,17 @@ WindowsRawInputFilter::nativeEventFilter(const QByteArray &eventType, void *mess
QTextStream ts(&f); QTextStream ts(&f);
qApp->setStyleSheet(ts.readAll()); qApp->setStyleSheet(ts.readAll());
} }
QPalette palette(qApp->palette());
palette.setColor(QPalette::Link, Qt::white);
palette.setColor(QPalette::LinkVisited, Qt::lightGray);
qApp->setPalette(palette);
NewDarkMode = TRUE; NewDarkMode = TRUE;
} else { } else {
qApp->setStyleSheet(""); qApp->setStyleSheet("");
QPalette palette(qApp->palette());
palette.setColor(QPalette::Link, Qt::blue);
palette.setColor(QPalette::LinkVisited, Qt::magenta);
qApp->setPalette(palette);
NewDarkMode = FALSE; NewDarkMode = FALSE;
} }

View File

@@ -91,7 +91,7 @@ joystick_close(void)
} }
static int static int
joystick_get_axis(int gameport, int joystick_nr, int mapping) joystick_get_axis(int joystick_nr, int mapping)
{ {
if (mapping & POV_X) { if (mapping & POV_X) {
switch (plat_joystick_state[joystick_nr].p[mapping & 3]) { switch (plat_joystick_state[joystick_nr].p[mapping & 3]) {
@@ -128,9 +128,9 @@ joystick_get_axis(int gameport, int joystick_nr, int mapping)
} }
void void
joystick_process(void) joystick_process(uint8_t gp)
{ {
if (!joystick_type) if (!joystick_type[gp])
return; return;
SDL_JoystickUpdate(); SDL_JoystickUpdate();
@@ -146,44 +146,44 @@ joystick_process(void)
#if 0 #if 0
pclog("joystick %i - x=%i y=%i b[0]=%i b[1]=%i %i\n", js, pclog("joystick %i - x=%i y=%i b[0]=%i b[1]=%i %i\n", js,
joystick_state[0][js].x, joystick_state[gp][js].x,
joystick_state[0][js].y, joystick_state[gp][js].y,
joystick_state[0][js].b[0], joystick_state[gp][js].b[0],
joystick_state[0][js].b[1], joystick_state[gp][js].b[1],
joysticks_present); joysticks_present[gp]);
#endif #endif
} }
for (int js = 0; js < joystick_get_max_joysticks(joystick_type); js++) { for (int js = 0; js < joystick_get_max_joysticks(joystick_type[gp]); js++) {
if (joystick_state[0][js].plat_joystick_nr) { if (joystick_state[gp][js].plat_joystick_nr) {
int joystick_nr = joystick_state[0][js].plat_joystick_nr - 1; int joystick_nr = joystick_state[gp][js].plat_joystick_nr - 1;
for (int axis_nr = 0; axis_nr < joystick_get_axis_count(joystick_type); axis_nr++) for (int axis_nr = 0; axis_nr < joystick_get_axis_count(joystick_type[gp]); axis_nr++)
joystick_state[0][js].axis[axis_nr] = joystick_get_axis(0, joystick_nr, joystick_state[0][js].axis_mapping[axis_nr]); joystick_state[gp][js].axis[axis_nr] = joystick_get_axis(joystick_nr, joystick_state[gp][js].axis_mapping[axis_nr]);
for (int button_nr = 0; button_nr < joystick_get_button_count(joystick_type); button_nr++) for (int button_nr = 0; button_nr < joystick_get_button_count(joystick_type[gp]); button_nr++)
joystick_state[0][js].button[button_nr] = plat_joystick_state[joystick_nr].b[joystick_state[0][js].button_mapping[button_nr]]; joystick_state[gp][js].button[button_nr] = plat_joystick_state[joystick_nr].b[joystick_state[gp][js].button_mapping[button_nr]];
for (int pov_nr = 0; pov_nr < joystick_get_pov_count(joystick_type); pov_nr++) { for (int pov_nr = 0; pov_nr < joystick_get_pov_count(joystick_type[gp]); pov_nr++) {
int x = joystick_get_axis(0, joystick_nr, joystick_state[0][js].pov_mapping[pov_nr][0]); int x = joystick_get_axis(joystick_nr, joystick_state[gp][js].pov_mapping[pov_nr][0]);
int y = joystick_get_axis(0, joystick_nr, joystick_state[0][js].pov_mapping[pov_nr][1]); int y = joystick_get_axis(joystick_nr, joystick_state[gp][js].pov_mapping[pov_nr][1]);
double angle = (atan2((double) y, (double) x) * 360.0) / (2 * M_PI); double angle = (atan2((double) y, (double) x) * 360.0) / (2 * M_PI);
double magnitude = sqrt((double) x * (double) x + (double) y * (double) y); double magnitude = sqrt((double) x * (double) x + (double) y * (double) y);
if (magnitude < 16384) if (magnitude < 16384)
joystick_state[0][js].pov[pov_nr] = -1; joystick_state[gp][js].pov[pov_nr] = -1;
else else
joystick_state[0][js].pov[pov_nr] = ((int) angle + 90 + 360) % 360; joystick_state[gp][js].pov[pov_nr] = ((int) angle + 90 + 360) % 360;
} }
} else { } else {
for (int axis_nr = 0; axis_nr < joystick_get_axis_count(joystick_type); axis_nr++) for (int axis_nr = 0; axis_nr < joystick_get_axis_count(joystick_type[gp]); axis_nr++)
joystick_state[0][js].axis[axis_nr] = 0; joystick_state[gp][js].axis[axis_nr] = 0;
for (int button_nr = 0; button_nr < joystick_get_button_count(joystick_type); button_nr++) for (int button_nr = 0; button_nr < joystick_get_button_count(joystick_type[gp]); button_nr++)
joystick_state[0][js].button[button_nr] = 0; joystick_state[gp][js].button[button_nr] = 0;
for (int pov_nr = 0; pov_nr < joystick_get_pov_count(joystick_type); pov_nr++) for (int pov_nr = 0; pov_nr < joystick_get_pov_count(joystick_type[gp]); pov_nr++)
joystick_state[0][js].pov[pov_nr] = -1; joystick_state[gp][js].pov[pov_nr] = -1;
} }
} }
} }

View File

@@ -454,7 +454,7 @@ win_joystick_handle(PRAWINPUT raw)
plat_joystick_state[j].a[axis_nr] = value; plat_joystick_state[j].a[axis_nr] = value;
#if 0 #if 0
joystick_log("%s %-06d ", plat_joystick_state[0][j].axis[axis_nr].name, plat_joystick_state[j].a[axis_nr]); joystick_log("%s %-06d ", plat_joystick_state[j].axis[axis_nr].name, plat_joystick_state[j].a[axis_nr]);
#endif #endif
} }
@@ -476,7 +476,7 @@ win_joystick_handle(PRAWINPUT raw)
plat_joystick_state[j].p[pov_nr] = value; plat_joystick_state[j].p[pov_nr] = value;
#if 0 #if 0
joystick_log("%s %-3d ", plat_joystick_state[0][j].pov[pov_nr].name, plat_joystick_state[j].p[pov_nr]); joystick_log("%s %-3d ", plat_joystick_state[j].pov[pov_nr].name, plat_joystick_state[j].p[pov_nr]);
#endif #endif
} }
#if 0 #if 0
@@ -505,41 +505,41 @@ joystick_get_axis(int joystick_nr, int mapping)
} }
void void
joystick_process(void) joystick_process(uint8_t gp)
{ {
if (joystick_type == JS_TYPE_NONE) if (joystick_type[gp] == JS_TYPE_NONE)
return; return;
for (int js = 0; js < joystick_get_max_joysticks(joystick_type); js++) { for (int js = 0; js < joystick_get_max_joysticks(joystick_type[gp]); js++) {
if (joystick_state[0][js].plat_joystick_nr) { if (joystick_state[gp][js].plat_joystick_nr) {
int joystick_nr = joystick_state[0][js].plat_joystick_nr - 1; int joystick_nr = joystick_state[gp][js].plat_joystick_nr - 1;
for (int axis_nr = 0; axis_nr < joystick_get_axis_count(joystick_type); axis_nr++) for (int axis_nr = 0; axis_nr < joystick_get_axis_count(joystick_type[gp]); axis_nr++)
joystick_state[0][js].axis[axis_nr] = joystick_get_axis(joystick_nr, joystick_state[0][js].axis_mapping[axis_nr]); joystick_state[gp][js].axis[axis_nr] = joystick_get_axis(joystick_nr, joystick_state[gp][js].axis_mapping[axis_nr]);
for (int button_nr = 0; button_nr < joystick_get_button_count(joystick_type); button_nr++) for (int button_nr = 0; button_nr < joystick_get_button_count(joystick_type[gp]); button_nr++)
joystick_state[0][js].button[button_nr] = plat_joystick_state[joystick_nr].b[joystick_state[0][js].button_mapping[button_nr]]; joystick_state[gp][js].button[button_nr] = plat_joystick_state[joystick_nr].b[joystick_state[gp][js].button_mapping[button_nr]];
for (int pov_nr = 0; pov_nr < joystick_get_pov_count(joystick_type); pov_nr++) { for (int pov_nr = 0; pov_nr < joystick_get_pov_count(joystick_type[gp]); pov_nr++) {
int x = joystick_get_axis(joystick_nr, joystick_state[0][js].pov_mapping[pov_nr][0]); int x = joystick_get_axis(joystick_nr, joystick_state[gp][js].pov_mapping[pov_nr][0]);
int y = joystick_get_axis(joystick_nr, joystick_state[0][js].pov_mapping[pov_nr][1]); int y = joystick_get_axis(joystick_nr, joystick_state[gp][js].pov_mapping[pov_nr][1]);
double angle = (atan2((double) y, (double) x) * 360.0) / (2 * M_PI); double angle = (atan2((double) y, (double) x) * 360.0) / (2 * M_PI);
double magnitude = sqrt((double) x * (double) x + (double) y * (double) y); double magnitude = sqrt((double) x * (double) x + (double) y * (double) y);
if (magnitude < 16384) if (magnitude < 16384)
joystick_state[0][js].pov[pov_nr] = -1; joystick_state[gp][js].pov[pov_nr] = -1;
else else
joystick_state[0][js].pov[pov_nr] = ((int) angle + 90 + 360) % 360; joystick_state[gp][js].pov[pov_nr] = ((int) angle + 90 + 360) % 360;
} }
} else { } else {
for (int axis_nr = 0; axis_nr < joystick_get_axis_count(joystick_type); axis_nr++) for (int axis_nr = 0; axis_nr < joystick_get_axis_count(joystick_type[gp]); axis_nr++)
joystick_state[0][js].axis[axis_nr] = 0; joystick_state[gp][js].axis[axis_nr] = 0;
for (int button_nr = 0; button_nr < joystick_get_button_count(joystick_type); button_nr++) for (int button_nr = 0; button_nr < joystick_get_button_count(joystick_type[gp]); button_nr++)
joystick_state[0][js].button[button_nr] = 0; joystick_state[gp][js].button[button_nr] = 0;
for (int pov_nr = 0; pov_nr < joystick_get_pov_count(joystick_type); pov_nr++) for (int pov_nr = 0; pov_nr < joystick_get_pov_count(joystick_type[gp]); pov_nr++)
joystick_state[0][js].pov[pov_nr] = -1; joystick_state[gp][js].pov[pov_nr] = -1;
} }
} }
} }

View File

@@ -1484,7 +1484,7 @@ joystick_close(void)
} }
void void
joystick_process(void) joystick_process(uint8_t gp)
{ {
/* No-op. */ /* No-op. */
} }