diff --git a/src/base.hpp b/src/base.hpp index 3cdbc645..da5afb39 100644 --- a/src/base.hpp +++ b/src/base.hpp @@ -1,4 +1,4 @@ -#define BSNES_VERSION "0.040" +#define BSNES_VERSION "0.041" #define BSNES_TITLE "bsnes v" BSNES_VERSION #define BUSCORE sBus diff --git a/src/data/joypad.png b/src/data/joypad.png index 3bd2638d..43d7c7d9 100644 Binary files a/src/data/joypad.png and b/src/data/joypad.png differ diff --git a/src/data/logo.png b/src/data/logo.png index eaa33cd0..e78ef27f 100644 Binary files a/src/data/logo.png and b/src/data/logo.png differ diff --git a/src/ui_qt/config.cpp b/src/ui_qt/config.cpp index 0cd53833..d75e099e 100644 --- a/src/ui_qt/config.cpp +++ b/src/ui_qt/config.cpp @@ -71,13 +71,13 @@ public: //external //======== - attach(snes.config.controller_port1 = SNES::Input::DeviceJoypad, "snes.controller_port1"); - attach(snes.config.controller_port2 = SNES::Input::DeviceJoypad, "snes.controller_port2"); - attach(snes.config.expansion_port = SNES::ExpansionBSX, "snes.expansion_port"); + attach(snes.config.controller_port1 = SNES::Input::DeviceJoypad, "snes.controllerPort1"); + attach(snes.config.controller_port2 = SNES::Input::DeviceJoypad, "snes.controllerPort2"); + attach(snes.config.expansion_port = SNES::ExpansionBSX, "snes.expansionPort"); attach(snes.config.region = SNES::Autodetect, "snes.region"); - attach(snes.config.file.autodetect_type = false, "file.autodetect_type"); - attach(snes.config.file.bypass_patch_crc32 = false, "file.bypass_patch_crc32"); + attach(snes.config.file.autodetect_type = false, "file.autodetectType"); + attach(snes.config.file.bypass_patch_crc32 = false, "file.bypassPatchCrc32"); attach(snes.config.path.rom = "", "path.rom"); attach(snes.config.path.save = "", "path.save"); @@ -88,14 +88,14 @@ public: attach(snes.config.path.st = "", "path.st"); attach(snes.config.cpu.version = 2, "cpu.version", "Valid version(s) are: 1, 2"); - attach(snes.config.cpu.ntsc_clock_rate = 21477272, "cpu.ntsc_clock_rate"); - attach(snes.config.cpu.pal_clock_rate = 21281370, "cpu.pal_clock_rate"); - attach(snes.config.cpu.alu_mul_delay = 2, "cpu.alu_mul_delay"); - attach(snes.config.cpu.alu_div_delay = 2, "cpu.alu_div_delay"); - attach(snes.config.cpu.wram_init_value = 0x55, "cpu.wram_init_value"); + attach(snes.config.cpu.ntsc_clock_rate = 21477272, "cpu.ntscClockRate"); + attach(snes.config.cpu.pal_clock_rate = 21281370, "cpu.palClockRate"); + attach(snes.config.cpu.alu_mul_delay = 2, "cpu.aluMulDelay"); + attach(snes.config.cpu.alu_div_delay = 2, "cpu.aluDivDelay"); + attach(snes.config.cpu.wram_init_value = 0x55, "cpu.wramInitValue"); - attach(snes.config.smp.ntsc_clock_rate = 32041 * 768, "smp.ntsc_clock_rate"); - attach(snes.config.smp.pal_clock_rate = 32041 * 768, "smp.pal_clock_rate"); + attach(snes.config.smp.ntsc_clock_rate = 32041 * 768, "smp.ntscClockRate"); + attach(snes.config.smp.pal_clock_rate = 32041 * 768, "smp.palClockRate"); attach(snes.config.ppu1.version = 1, "ppu1.version", "Valid version(s) are: 1"); attach(snes.config.ppu2.version = 3, "ppu2.version", "Valid version(s) are: 1, 2, 3"); diff --git a/src/ui_qt/input/input.cpp b/src/ui_qt/input/input.cpp index db4d139c..9ba40b43 100644 --- a/src/ui_qt/input/input.cpp +++ b/src/ui_qt/input/input.cpp @@ -47,8 +47,8 @@ void InputManager::refresh() { input.poll(stateTable[next]); for(unsigned i = 0; i < nall::input_limit; i++) { - //call on_input() whenever button is pressed down; ignore axes - if(!stateTable[last][i] && stateTable[next][i] && InputCode::isButton(i) && onInput) onInput(i); + //alert via callback whenever input state changes for any ID ... + if(onInput && stateTable[last][i] != stateTable[next][i]) onInput(i); } } diff --git a/src/ui_qt/settings/input.cpp b/src/ui_qt/settings/input.cpp index 5eb2e721..7f231757 100644 --- a/src/ui_qt/settings/input.cpp +++ b/src/ui_qt/settings/input.cpp @@ -31,10 +31,10 @@ void InputSettingsWindow::setup() { layout->addSpacing(Style::WidgetSpacing); controls = new QHBoxLayout; { - assign = new QPushButton("Assign Key ..."); + assign = new QPushButton("Assign ..."); controls->addWidget(assign); - unassign = new QPushButton("Unassign Key"); + unassign = new QPushButton("Unassign"); controls->addWidget(unassign); } controls->setSpacing(Style::WidgetSpacing); diff --git a/src/ui_qt/settings/utility/inputcapture.cpp b/src/ui_qt/settings/utility/inputcapture.cpp index 92810067..b917e7b7 100644 --- a/src/ui_qt/settings/utility/inputcapture.cpp +++ b/src/ui_qt/settings/utility/inputcapture.cpp @@ -7,52 +7,41 @@ void InputCaptureWindow::setup() { layout->setMargin(Style::WindowMargin); layout->setSpacing(0); - title = new QLabel; - layout->addWidget(title); + hlayout = new QHBoxLayout; + hlayout->setSpacing(Style::WidgetSpacing); { + title = new QLabel; + hlayout->addWidget(title, 0, Qt::AlignTop); - axisGroup = new QGroupBox("Mouse axes"); { - axisLayout = new QHBoxLayout; - axisLayout->setSpacing(Style::WidgetSpacing); { - mouseAxisX = new QPushButton("X-axis"); - axisLayout->addWidget(mouseAxisX); + mouseAxes = new QPushButton(" Assign Mouse Axis "); + mouseAxes->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + mouseAxisMenu = new QMenu; + mouseAxisX = mouseAxisMenu->addAction("X-axis"); + mouseAxisY = mouseAxisMenu->addAction("Y-axis"); + mouseAxes->setMenu(mouseAxisMenu); + hlayout->addWidget(mouseAxes, 0, Qt::AlignTop); - mouseAxisY = new QPushButton("Y-axis"); - axisLayout->addWidget(mouseAxisY); - } - axisGroup->setLayout(axisLayout); + mouseButtons = new QPushButton(" Assign Mouse Button "); + mouseButtons->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + mouseButtonMenu = new QMenu; + mouseButton[0] = mouseButtonMenu->addAction("Button 0 (left)"); + mouseButton[1] = mouseButtonMenu->addAction("Button 1 (middle)"); + mouseButton[2] = mouseButtonMenu->addAction("Button 2 (right)"); + mouseButtonMenu->addSeparator(); + mouseButton[3] = mouseButtonMenu->addAction("Button 3"); + mouseButton[4] = mouseButtonMenu->addAction("Button 4"); + mouseButton[5] = mouseButtonMenu->addAction("Button 5"); + mouseButton[6] = mouseButtonMenu->addAction("Button 6"); + mouseButton[7] = mouseButtonMenu->addAction("Button 7"); + mouseButtons->setMenu(mouseButtonMenu); + hlayout->addWidget(mouseButtons, 0, Qt::AlignTop); } - layout->addWidget(axisGroup); - - buttonGroup = new QGroupBox("Mouse buttons"); { - buttonLayout = new QGridLayout; - buttonLayout->setSpacing(Style::WidgetSpacing); { - mouseButton[0] = new QPushButton("Left"); - buttonLayout->addWidget(mouseButton[0], 0, 0); - - mouseButton[1] = new QPushButton("Middle"); - buttonLayout->addWidget(mouseButton[1], 0, 1); - - mouseButton[2] = new QPushButton("Right"); - buttonLayout->addWidget(mouseButton[2], 0, 2); - - mouseButton[3] = new QPushButton("Extra 1"); - buttonLayout->addWidget(mouseButton[3], 1, 0); - - mouseButton[4] = new QPushButton("Extra 2"); - buttonLayout->addWidget(mouseButton[4], 1, 1); - - mouseButton[5] = new QPushButton("Extra 3"); - buttonLayout->addWidget(mouseButton[5], 1, 2); - } - buttonGroup->setLayout(buttonLayout); - } - layout->addWidget(buttonGroup); + layout->addLayout(hlayout); imageSpacer = new QWidget; imageSpacer->setFixedSize(Style::WidgetSpacing, Style::WidgetSpacing); layout->addWidget(imageSpacer); - imageWidget = new InputImage; + imageWidget = new ImageWidget; layout->addWidget(imageWidget, 0, Qt::AlignHCenter); spacer = new QWidget; @@ -60,14 +49,16 @@ void InputCaptureWindow::setup() { layout->addWidget(spacer); window->setLayout(layout); - connect(mouseAxisX, SIGNAL(released()), this, SLOT(assignMouseX())); - connect(mouseAxisY, SIGNAL(released()), this, SLOT(assignMouseY())); - connect(mouseButton[0], SIGNAL(released()), this, SLOT(assignMouse0())); - connect(mouseButton[1], SIGNAL(released()), this, SLOT(assignMouse1())); - connect(mouseButton[2], SIGNAL(released()), this, SLOT(assignMouse2())); - connect(mouseButton[3], SIGNAL(released()), this, SLOT(assignMouse3())); - connect(mouseButton[4], SIGNAL(released()), this, SLOT(assignMouse4())); - connect(mouseButton[5], SIGNAL(released()), this, SLOT(assignMouse5())); + connect(mouseAxisX, SIGNAL(triggered()), this, SLOT(assignMouseX())); + connect(mouseAxisY, SIGNAL(triggered()), this, SLOT(assignMouseY())); + connect(mouseButton[0], SIGNAL(triggered()), this, SLOT(assignMouse0())); + connect(mouseButton[1], SIGNAL(triggered()), this, SLOT(assignMouse1())); + connect(mouseButton[2], SIGNAL(triggered()), this, SLOT(assignMouse2())); + connect(mouseButton[3], SIGNAL(triggered()), this, SLOT(assignMouse3())); + connect(mouseButton[4], SIGNAL(triggered()), this, SLOT(assignMouse4())); + connect(mouseButton[5], SIGNAL(triggered()), this, SLOT(assignMouse5())); + connect(mouseButton[6], SIGNAL(triggered()), this, SLOT(assignMouse6())); + connect(mouseButton[7], SIGNAL(triggered()), this, SLOT(assignMouse7())); } void InputCaptureWindow::activate(InputObject *object) { @@ -85,20 +76,20 @@ void InputCaptureWindow::activate(InputObject *object) { activeObject = object; if(activeObject->type == InputObject::Button) { - axisGroup->hide(); - buttonGroup->show(); + mouseAxes->hide(); + mouseButtons->show(); - info << "Press any keyboard key / joypad button, or click the desired mouse button below to set assignment."; + info << "Press any key or button to assign to this ID."; } else /*(activeObject->type == InputObject::Axis)*/ { - axisGroup->show(); - buttonGroup->hide(); + mouseAxes->show(); + mouseButtons->hide(); - info << "Move any joypad axis, or click the desired mouse axis below to set assignment."; + info << "Move any axis to assign to this ID."; } if(dynamic_cast(activeObject->parent)) { imageSpacer->show(); - imageWidget->setFixedSize(600, 300); + imageWidget->setFixedSize(480, 210); imageWidget->show(); } else { imageSpacer->hide(); @@ -121,25 +112,34 @@ void InputCaptureWindow::activate(InputObject *object) { window->raise(); } -void InputCaptureWindow::inputEvent(uint16_t code, bool forceAssign) { +void InputCaptureWindow::inputEvent(uint16_t code, bool forceAssign /* = false */) { if(!activeObject) return; //input polling is global, need to block mouse actions that may be UI interactions. //custom controls on window allow mouse assignment instead. if(forceAssign == false) { InputCode::type_t type = InputCode::type(code); + int16_t state = inputManager.state(code); + + if(activeObject->type == InputObject::Axis) { + if(type == InputCode::KeyboardButton + || type == InputCode::MouseAxis + || type == InputCode::MouseButton + || type == InputCode::JoypadButton + ) return; + + //only capture when axis is positioned at least 50% toward a given direction + if(abs(state) < 16384) return; + } if(activeObject->type == InputObject::Button) { if(type == InputCode::MouseAxis || type == InputCode::MouseButton || type == InputCode::JoypadAxis ) return; - } else /*(activeObject->type == InputObject::Axis)*/ { - if(type == InputCode::KeyboardButton - || type == InputCode::MouseAxis - || type == InputCode::MouseButton - || type == InputCode::JoypadButton - ) return; + + //only capture on button press, not release + if(state == false) return; } } @@ -160,6 +160,8 @@ void InputCaptureWindow::assignMouse2() { inputEvent(mouse::button + 2, true); } void InputCaptureWindow::assignMouse3() { inputEvent(mouse::button + 3, true); } void InputCaptureWindow::assignMouse4() { inputEvent(mouse::button + 4, true); } void InputCaptureWindow::assignMouse5() { inputEvent(mouse::button + 5, true); } +void InputCaptureWindow::assignMouse6() { inputEvent(mouse::button + 6, true); } +void InputCaptureWindow::assignMouse7() { inputEvent(mouse::button + 7, true); } InputCaptureWindow::InputCaptureWindow() { activeObject = 0; @@ -170,7 +172,7 @@ void InputCaptureWindow::Window::closeEvent(QCloseEvent*) { winInputCapture->activeObject = 0; } -void InputCaptureWindow::InputImage::paintEvent(QPaintEvent*) { +void InputCaptureWindow::ImageWidget::paintEvent(QPaintEvent*) { //currently, there is only an image available for the joypad. //in the future, this routine should determine which type of //image to draw via activeObject->parent's derived class type. diff --git a/src/ui_qt/settings/utility/inputcapture.hpp b/src/ui_qt/settings/utility/inputcapture.hpp index 3ae607a3..72fae3e3 100644 --- a/src/ui_qt/settings/utility/inputcapture.hpp +++ b/src/ui_qt/settings/utility/inputcapture.hpp @@ -8,16 +8,17 @@ public: void closeEvent(QCloseEvent*); } *window; QVBoxLayout *layout; - QLabel *title; - QGroupBox *axisGroup; - QHBoxLayout *axisLayout; - QPushButton *mouseAxisX; - QPushButton *mouseAxisY; - QGroupBox *buttonGroup; - QGridLayout *buttonLayout; - QPushButton *mouseButton[6]; + QHBoxLayout *hlayout; + QLabel *title; + QPushButton *mouseAxes; + QMenu *mouseAxisMenu; + QAction *mouseAxisX; + QAction *mouseAxisY; + QPushButton *mouseButtons; + QMenu *mouseButtonMenu; + QAction *mouseButton[8]; QWidget *imageSpacer; - struct InputImage : public QWidget { + struct ImageWidget : public QWidget { void paintEvent(QPaintEvent*); } *imageWidget; QWidget *spacer; @@ -36,4 +37,6 @@ public slots: void assignMouse3(); void assignMouse4(); void assignMouse5(); + void assignMouse6(); + void assignMouse7(); } *winInputCapture; diff --git a/src/ui_qt/ui.cpp b/src/ui_qt/ui.cpp index 927d7072..fb3fac77 100644 --- a/src/ui_qt/ui.cpp +++ b/src/ui_qt/ui.cpp @@ -108,6 +108,8 @@ void Application::init() { config.save(configFilename); inputManager.bind(); + inputManager.refresh(); + inputManager.refresh(); inputManager.onInput = bind(&Utility::inputEvent, &utility); utility.updateAvSync(); diff --git a/src/ui_qt/utility/utility.cpp b/src/ui_qt/utility/utility.cpp index dba8cc8a..faa014e2 100644 --- a/src/ui_qt/utility/utility.cpp +++ b/src/ui_qt/utility/utility.cpp @@ -5,6 +5,10 @@ void Utility::inputEvent(uint16_t code) { //if input capture assignment window is currently active, forward key-press event if(winInputCapture->activeObject) winInputCapture->inputEvent(code); + //only match buttons being pressed down ... + if(InputCode::isButton(code) == false) return; + if(inputManager.state(code) == false) return; + if(code == keyboard::escape && input.acquired()) { input.unacquire(); return; //do not trigger other UI actions that may be bound to escape key