mirror of https://github.com/bsnes-emu/bsnes.git
Update to v094r19 release.
byuu says: The input port menu was hooked up. Alternate input support was added, although I wasn't able to test rumble support because SDL doesn't support that, and I don't have XInput or udev drivers on FreeBSD. This one's going to be tricky. Maybe I can test via cross-compiling on Windows/GTK. Added mouse capture hotkey, and auto capture/release on toggling fullscreen (as a bonus it hides the mouse cursor.) Added all possible video and input drivers to ruby for BSD systems. Remaining issues before we can release v095: - add slotted cart loader (SGB, BSX, ST) - add DIP switch selection window (NSS) - add timing configuration (video/audio sync) - hide inapplicable options from system menu (eg controller ports and reset button from handheld systems)
This commit is contained in:
parent
fc8eba133d
commit
458775a481
|
@ -49,8 +49,6 @@ else ifeq ($(platform),linux)
|
||||||
link += -lX11 -lXext -ldl
|
link += -lX11 -lXext -ldl
|
||||||
else ifeq ($(platform),bsd)
|
else ifeq ($(platform),bsd)
|
||||||
flags += -march=native
|
flags += -march=native
|
||||||
link += -Wl,-rpath=/usr/local/lib
|
|
||||||
link += -Wl,-rpath=/usr/local/lib/gcc49
|
|
||||||
link += -Wl,-export-dynamic
|
link += -Wl,-export-dynamic
|
||||||
link += -lX11 -lXext
|
link += -lX11 -lXext
|
||||||
else
|
else
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
namespace Emulator {
|
namespace Emulator {
|
||||||
static const char Name[] = "higan";
|
static const char Name[] = "higan";
|
||||||
static const char Version[] = "094.18";
|
static const char Version[] = "094.19";
|
||||||
static const char Author[] = "byuu";
|
static const char Author[] = "byuu";
|
||||||
static const char License[] = "GPLv3";
|
static const char License[] = "GPLv3";
|
||||||
static const char Website[] = "http://byuu.org/";
|
static const char Website[] = "http://byuu.org/";
|
||||||
|
|
|
@ -73,6 +73,8 @@ endif
|
||||||
# bsd settings
|
# bsd settings
|
||||||
ifeq ($(platform),bsd)
|
ifeq ($(platform),bsd)
|
||||||
flags += -I/usr/local/include
|
flags += -I/usr/local/include
|
||||||
|
link += -Wl,-rpath=/usr/local/lib
|
||||||
|
link += -Wl,-rpath=/usr/local/lib/gcc49
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# cross-compilation support
|
# cross-compilation support
|
||||||
|
|
|
@ -26,9 +26,9 @@ else ifeq ($(platform),linux)
|
||||||
ruby += audio.alsa audio.openal audio.oss audio.pulseaudio audio.pulseaudiosimple audio.ao
|
ruby += audio.alsa audio.openal audio.oss audio.pulseaudio audio.pulseaudiosimple audio.ao
|
||||||
ruby += input.udev input.sdl input.xlib
|
ruby += input.udev input.sdl input.xlib
|
||||||
else ifeq ($(platform),bsd)
|
else ifeq ($(platform),bsd)
|
||||||
ruby := video.glx video.xshm
|
ruby := video.glx video.xv video.xshm video.sdl
|
||||||
ruby += audio.openal audio.oss
|
ruby += audio.openal audio.oss
|
||||||
ruby += input.xlib
|
ruby += input.sdl input.xlib
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# ruby
|
# ruby
|
||||||
|
|
|
@ -7,6 +7,14 @@ auto InputManager::appendHotkeys() -> void {
|
||||||
hotkeys.append(hotkey);
|
hotkeys.append(hotkey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{ auto hotkey = new InputHotkey;
|
||||||
|
hotkey->name = "Toggle Mouse Capture";
|
||||||
|
hotkey->action = [] {
|
||||||
|
input.acquired() ? input.unacquire() : input.acquire();
|
||||||
|
};
|
||||||
|
hotkeys.append(hotkey);
|
||||||
|
}
|
||||||
|
|
||||||
{ auto hotkey = new InputHotkey;
|
{ auto hotkey = new InputHotkey;
|
||||||
hotkey->name = "Save State";
|
hotkey->name = "Save State";
|
||||||
hotkey->action = [] {
|
hotkey->action = [] {
|
||||||
|
|
|
@ -4,10 +4,11 @@ InputManager* inputManager = nullptr;
|
||||||
|
|
||||||
auto InputMapping::bind() -> void {
|
auto InputMapping::bind() -> void {
|
||||||
auto token = assignment.split("/");
|
auto token = assignment.split("/");
|
||||||
if(token.size() < 3) return;
|
if(token.size() < 3) return unbind();
|
||||||
uint64_t id = token[0].hex();
|
uint64_t id = token[0].hex();
|
||||||
unsigned group = token[1].decimal();
|
unsigned group = token[1].decimal();
|
||||||
unsigned input = token[2].decimal();
|
unsigned input = token[2].decimal();
|
||||||
|
string qualifier = token(3, "None");
|
||||||
|
|
||||||
for(auto& device : inputManager->devices) {
|
for(auto& device : inputManager->devices) {
|
||||||
if(id != device->id) continue;
|
if(id != device->id) continue;
|
||||||
|
@ -15,22 +16,89 @@ auto InputMapping::bind() -> void {
|
||||||
this->device = device;
|
this->device = device;
|
||||||
this->group = group;
|
this->group = group;
|
||||||
this->input = input;
|
this->input = input;
|
||||||
|
this->qualifier = Qualifier::None;
|
||||||
|
if(qualifier == "Lo") this->qualifier = Qualifier::Lo;
|
||||||
|
if(qualifier == "Hi") this->qualifier = Qualifier::Hi;
|
||||||
|
if(qualifier == "Rumble") this->qualifier = Qualifier::Rumble;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto InputMapping::bind(HID::Device& device, unsigned group, unsigned input, int16 oldValue, int16 newValue) -> bool {
|
auto InputMapping::bind(HID::Device& device, unsigned group, unsigned input, int16 oldValue, int16 newValue) -> bool {
|
||||||
if(device.group[group].input[input].name == "Escape") return unbind(), true;
|
if(device.isNull() || (device.isKeyboard() && device.group[group].input[input].name == "Escape")) {
|
||||||
|
return unbind(), true;
|
||||||
|
}
|
||||||
|
|
||||||
this->assignment = {hex(device.id), "/", group, "/", input, "/", device.group[group].input[input].name};
|
string encoding = {hex(device.id), "/", group, "/", input};
|
||||||
this->device = &device;
|
|
||||||
this->group = group;
|
if(isDigital()) {
|
||||||
this->input = input;
|
if((device.isKeyboard() && group == HID::Keyboard::GroupID::Button)
|
||||||
return true;
|
|| (device.isMouse() && group == HID::Mouse::GroupID::Button)
|
||||||
|
|| (device.isJoypad() && group == HID::Joypad::GroupID::Button)) {
|
||||||
|
if(newValue) {
|
||||||
|
this->assignment = encoding;
|
||||||
|
return bind(), true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if((device.isJoypad() && group == HID::Joypad::GroupID::Axis)
|
||||||
|
|| (device.isJoypad() && group == HID::Joypad::GroupID::Hat)) {
|
||||||
|
if(newValue < -16384) {
|
||||||
|
this->assignment = {encoding, "/Lo"};
|
||||||
|
return bind(), true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(newValue > +16384) {
|
||||||
|
this->assignment = {encoding, "/Hi"};
|
||||||
|
return bind(), true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(isAnalog()) {
|
||||||
|
if((device.isMouse() && group == HID::Mouse::GroupID::Axis)
|
||||||
|
|| (device.isJoypad() && group == HID::Joypad::GroupID::Axis)
|
||||||
|
|| (device.isJoypad() && group == HID::Joypad::GroupID::Hat)) {
|
||||||
|
if(newValue < -16384 || newValue > +16384) {
|
||||||
|
this->assignment = encoding;
|
||||||
|
return bind(), true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(isRumble()) {
|
||||||
|
if(device.isJoypad() && group == HID::Joypad::GroupID::Button) {
|
||||||
|
if(newValue) {
|
||||||
|
encoding = {this->assignment, "/Rumble"};
|
||||||
|
return bind(), true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto InputMapping::poll() -> int16 {
|
auto InputMapping::poll() -> int16 {
|
||||||
if(device) return device->group[group].input[input].value;
|
if(!device) return 0;
|
||||||
|
auto value = device->group[group].input[input].value;
|
||||||
|
|
||||||
|
if(isDigital()) {
|
||||||
|
if(device->isKeyboard() && group == HID::Keyboard::GroupID::Button) return value != 0;
|
||||||
|
if(device->isMouse() && group == HID::Mouse::GroupID::Button) return value != 0;
|
||||||
|
if(device->isJoypad() && group == HID::Joypad::GroupID::Button) return value != 0;
|
||||||
|
if((device->isJoypad() && group == HID::Joypad::GroupID::Axis)
|
||||||
|
|| (device->isJoypad() && group == HID::Joypad::GroupID::Hat)) {
|
||||||
|
if(qualifier == Qualifier::Lo) return value < -16384;
|
||||||
|
if(qualifier == Qualifier::Hi) return value > +16384;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(isAnalog()) {
|
||||||
|
if(device->isMouse() && group == HID::Mouse::GroupID::Axis) return value;
|
||||||
|
if(device->isJoypad() && group == HID::Joypad::GroupID::Axis) return value >> 8;
|
||||||
|
if(device->isJoypad() && group == HID::Joypad::GroupID::Hat) return value < 0 ? -1 : value > 0 ? +1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,6 +107,24 @@ auto InputMapping::unbind() -> void {
|
||||||
this->device = nullptr;
|
this->device = nullptr;
|
||||||
this->group = 0;
|
this->group = 0;
|
||||||
this->input = 0;
|
this->input = 0;
|
||||||
|
this->qualifier = Qualifier::None;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto InputMapping::assignmentName() const -> string {
|
||||||
|
if(!device) return "None";
|
||||||
|
string path;
|
||||||
|
path.append(device->name);
|
||||||
|
path.append(".", device->group[group].name);
|
||||||
|
path.append(".", device->group[group].input[input].name);
|
||||||
|
if(qualifier == Qualifier::Lo) path.append(".Lo");
|
||||||
|
if(qualifier == Qualifier::Hi) path.append(".Hi");
|
||||||
|
if(qualifier == Qualifier::Rumble) path.append(".Rumble");
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto InputMapping::deviceName() const -> string {
|
||||||
|
if(!device) return "";
|
||||||
|
return device->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -137,3 +223,10 @@ auto InputManager::quit() -> void {
|
||||||
emulators.reset();
|
emulators.reset();
|
||||||
hotkeys.reset();
|
hotkeys.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto InputManager::findMouse() -> HID::Device* {
|
||||||
|
for(auto device : devices) {
|
||||||
|
if(device->isMouse()) return device;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
|
@ -4,12 +4,20 @@ struct InputMapping {
|
||||||
auto poll() -> int16;
|
auto poll() -> int16;
|
||||||
auto unbind() -> void;
|
auto unbind() -> void;
|
||||||
|
|
||||||
|
auto isDigital() const -> bool { return !link || link->type == 0; }
|
||||||
|
auto isAnalog() const -> bool { return link && link->type == 1; }
|
||||||
|
auto isRumble() const -> bool { return link && link->type == 2; }
|
||||||
|
|
||||||
|
auto assignmentName() const -> string;
|
||||||
|
auto deviceName() const -> string;
|
||||||
|
|
||||||
string name;
|
string name;
|
||||||
string assignment = "None";
|
string assignment = "None";
|
||||||
Emulator::Interface::Device::Input* link = nullptr;
|
Emulator::Interface::Device::Input* link = nullptr;
|
||||||
HID::Device* device = nullptr;
|
HID::Device* device = nullptr;
|
||||||
unsigned group = 0;
|
unsigned group = 0;
|
||||||
unsigned input = 0;
|
unsigned input = 0;
|
||||||
|
enum class Qualifier : unsigned { None, Lo, Hi, Rumble } qualifier = Qualifier::None;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct InputHotkey : InputMapping {
|
struct InputHotkey : InputMapping {
|
||||||
|
@ -40,6 +48,8 @@ struct InputManager {
|
||||||
auto onChange(HID::Device& device, unsigned group, unsigned input, int16 oldValue, int16 newValue) -> void;
|
auto onChange(HID::Device& device, unsigned group, unsigned input, int16 oldValue, int16 newValue) -> void;
|
||||||
auto quit() -> void;
|
auto quit() -> void;
|
||||||
|
|
||||||
|
auto findMouse() -> HID::Device*;
|
||||||
|
|
||||||
//hotkeys.cpp
|
//hotkeys.cpp
|
||||||
auto appendHotkeys() -> void;
|
auto appendHotkeys() -> void;
|
||||||
auto pollHotkeys() -> void;
|
auto pollHotkeys() -> void;
|
||||||
|
|
|
@ -102,6 +102,29 @@ Presentation::Presentation() {
|
||||||
resizeViewport();
|
resizeViewport();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto Presentation::updateEmulator() -> void {
|
||||||
|
inputPort1.reset();
|
||||||
|
inputPort2.reset();
|
||||||
|
if(!emulator) return;
|
||||||
|
|
||||||
|
for(auto n : range(emulator->port)) {
|
||||||
|
if(n >= 2) break;
|
||||||
|
auto& port = emulator->port[n];
|
||||||
|
auto& menu = (n == 0 ? inputPort1 : inputPort2);
|
||||||
|
menu.setText(port.name);
|
||||||
|
|
||||||
|
vector<wMenuRadioItem> items;
|
||||||
|
for(auto& device : port.device) {
|
||||||
|
MenuRadioItem item{&menu};
|
||||||
|
item.setText(device.name).onActivate([=] {
|
||||||
|
emulator->connect(port.id, device.id);
|
||||||
|
});
|
||||||
|
items.append(item);
|
||||||
|
}
|
||||||
|
MenuRadioItem::group(items);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
auto Presentation::resizeViewport() -> void {
|
auto Presentation::resizeViewport() -> void {
|
||||||
signed width = 256;
|
signed width = 256;
|
||||||
signed height = 240;
|
signed height = 240;
|
||||||
|
@ -154,7 +177,9 @@ auto Presentation::toggleFullScreen() -> void {
|
||||||
statusBar.setVisible(false);
|
statusBar.setVisible(false);
|
||||||
setResizable(true);
|
setResizable(true);
|
||||||
setFullScreen(true);
|
setFullScreen(true);
|
||||||
|
if(!input.acquired()) input.acquire();
|
||||||
} else {
|
} else {
|
||||||
|
if(input.acquired()) input.unacquire();
|
||||||
setFullScreen(false);
|
setFullScreen(false);
|
||||||
setResizable(false);
|
setResizable(false);
|
||||||
menuBar.setVisible(true);
|
menuBar.setVisible(true);
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
struct Presentation : Window {
|
struct Presentation : Window {
|
||||||
Presentation();
|
Presentation();
|
||||||
|
auto updateEmulator() -> void;
|
||||||
auto resizeViewport() -> void;
|
auto resizeViewport() -> void;
|
||||||
auto toggleFullScreen() -> void;
|
auto toggleFullScreen() -> void;
|
||||||
auto drawSplashScreen() -> void;
|
auto drawSplashScreen() -> void;
|
||||||
|
@ -10,7 +11,10 @@ struct Presentation : Window {
|
||||||
Menu systemMenu{&menuBar};
|
Menu systemMenu{&menuBar};
|
||||||
MenuItem powerSystem{&systemMenu};
|
MenuItem powerSystem{&systemMenu};
|
||||||
MenuItem resetSystem{&systemMenu};
|
MenuItem resetSystem{&systemMenu};
|
||||||
MenuSeparator systemMenuSeparator{&systemMenu};
|
MenuSeparator systemMenuSeparatorPorts{&systemMenu};
|
||||||
|
Menu inputPort1{&systemMenu};
|
||||||
|
Menu inputPort2{&systemMenu};
|
||||||
|
MenuSeparator systemMenuSeparatorUnload{&systemMenu};
|
||||||
MenuItem unloadSystem{&systemMenu};
|
MenuItem unloadSystem{&systemMenu};
|
||||||
Menu settingsMenu{&menuBar};
|
Menu settingsMenu{&menuBar};
|
||||||
Menu videoScaleMenu{&settingsMenu};
|
Menu videoScaleMenu{&settingsMenu};
|
||||||
|
|
|
@ -29,6 +29,7 @@ auto Program::loadMedia(Emulator::Interface& _emulator, Emulator::Interface::Med
|
||||||
presentation->setTitle(emulator->title());
|
presentation->setTitle(emulator->title());
|
||||||
presentation->systemMenu.setVisible(true);
|
presentation->systemMenu.setVisible(true);
|
||||||
presentation->toolsMenu.setVisible(true);
|
presentation->toolsMenu.setVisible(true);
|
||||||
|
presentation->updateEmulator();
|
||||||
toolsManager->cheatEditor.loadCheats();
|
toolsManager->cheatEditor.loadCheats();
|
||||||
toolsManager->stateManager.doRefresh();
|
toolsManager->stateManager.doRefresh();
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,10 +33,7 @@ auto HotkeySettings::reloadMappings() -> void {
|
||||||
auto HotkeySettings::refreshMappings() -> void {
|
auto HotkeySettings::refreshMappings() -> void {
|
||||||
unsigned position = 0;
|
unsigned position = 0;
|
||||||
for(auto& hotkey : inputManager->hotkeys) {
|
for(auto& hotkey : inputManager->hotkeys) {
|
||||||
auto path = hotkey->assignment.split("/");
|
mappingList.item(position++)->setText(1, hotkey->assignmentName()).setText(2, hotkey->deviceName());
|
||||||
string assignment = path.takeLast();
|
|
||||||
string device = path(0);
|
|
||||||
mappingList.item(position++)->setText(1, assignment).setText(2, device);
|
|
||||||
}
|
}
|
||||||
mappingList.resizeColumns();
|
mappingList.resizeColumns();
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,9 +11,10 @@ InputSettings::InputSettings(TabFrame* parent) : TabFrameItem(parent) {
|
||||||
deviceList.onChange([&] { reloadMappings(); });
|
deviceList.onChange([&] { reloadMappings(); });
|
||||||
mappingList.setHeaderVisible();
|
mappingList.setHeaderVisible();
|
||||||
mappingList.onActivate([&] { assignMapping(); });
|
mappingList.onActivate([&] { assignMapping(); });
|
||||||
mappingList.onChange([&] {
|
mappingList.onChange([&] { updateControls(); });
|
||||||
eraseButton.setEnabled((bool)mappingList.selected());
|
assignMouse1.setVisible(false).onActivate([&] { assignMouseInput(0); });
|
||||||
});
|
assignMouse2.setVisible(false).onActivate([&] { assignMouseInput(1); });
|
||||||
|
assignMouse3.setVisible(false).onActivate([&] { assignMouseInput(2); });
|
||||||
resetButton.setText("Reset").onActivate([&] {
|
resetButton.setText("Reset").onActivate([&] {
|
||||||
if(MessageDialog("Are you sure you want to erase all mappings for this device?").setParent(*settingsManager).question() == 0) {
|
if(MessageDialog("Are you sure you want to erase all mappings for this device?").setParent(*settingsManager).question() == 0) {
|
||||||
for(auto& mapping : activeDevice().mappings) mapping->unbind();
|
for(auto& mapping : activeDevice().mappings) mapping->unbind();
|
||||||
|
@ -30,6 +31,26 @@ InputSettings::InputSettings(TabFrame* parent) : TabFrameItem(parent) {
|
||||||
reloadPorts();
|
reloadPorts();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto InputSettings::updateControls() -> void {
|
||||||
|
eraseButton.setEnabled((bool)mappingList.selected());
|
||||||
|
assignMouse1.setVisible(false);
|
||||||
|
assignMouse2.setVisible(false);
|
||||||
|
assignMouse3.setVisible(false);
|
||||||
|
|
||||||
|
if(auto mapping = mappingList.selected()) {
|
||||||
|
auto input = activeDevice().mappings[mapping->offset()];
|
||||||
|
|
||||||
|
if(input->isDigital()) {
|
||||||
|
assignMouse1.setVisible().setText("Mouse Left");
|
||||||
|
assignMouse2.setVisible().setText("Mouse Middle");
|
||||||
|
assignMouse3.setVisible().setText("Mouse Right");
|
||||||
|
} else if(input->isAnalog()) {
|
||||||
|
assignMouse1.setVisible().setText("Mouse X-axis");
|
||||||
|
assignMouse2.setVisible().setText("Mouse Y-axis");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
auto InputSettings::activeEmulator() -> InputEmulator& {
|
auto InputSettings::activeEmulator() -> InputEmulator& {
|
||||||
return inputManager->emulators[emulatorList.selected()->offset()];
|
return inputManager->emulators[emulatorList.selected()->offset()];
|
||||||
}
|
}
|
||||||
|
@ -73,10 +94,7 @@ auto InputSettings::reloadMappings() -> void {
|
||||||
auto InputSettings::refreshMappings() -> void {
|
auto InputSettings::refreshMappings() -> void {
|
||||||
unsigned position = 0;
|
unsigned position = 0;
|
||||||
for(auto& mapping : activeDevice().mappings) {
|
for(auto& mapping : activeDevice().mappings) {
|
||||||
auto path = mapping->assignment.split("/");
|
mappingList.item(position++)->setText(1, mapping->assignmentName()).setText(2, mapping->deviceName());
|
||||||
string assignment = path.takeLast();
|
|
||||||
string device = path(0);
|
|
||||||
mappingList.item(position++)->setText(1, assignment).setText(2, device);
|
|
||||||
}
|
}
|
||||||
mappingList.resizeColumns();
|
mappingList.resizeColumns();
|
||||||
}
|
}
|
||||||
|
@ -84,16 +102,30 @@ auto InputSettings::refreshMappings() -> void {
|
||||||
auto InputSettings::assignMapping() -> void {
|
auto InputSettings::assignMapping() -> void {
|
||||||
inputManager->poll(); //clear any pending events first
|
inputManager->poll(); //clear any pending events first
|
||||||
|
|
||||||
auto item = mappingList.selected();
|
auto mapping = mappingList.selected();
|
||||||
activeMapping = activeDevice().mappings[item->offset()];
|
activeMapping = activeDevice().mappings[mapping->offset()];
|
||||||
|
|
||||||
//settingsManager->layout.setEnabled(false);
|
//settingsManager->layout.setEnabled(false);
|
||||||
settingsManager->statusBar.setText({"Press a key or button to map [", activeMapping->name, "] ..."});
|
settingsManager->statusBar.setText({"Press a key or button to map [", activeMapping->name, "] ..."});
|
||||||
}
|
}
|
||||||
|
|
||||||
auto InputSettings::inputEvent(HID::Device& device, unsigned group, unsigned input, int16 oldValue, int16 newValue) -> void {
|
auto InputSettings::assignMouseInput(unsigned id) -> void {
|
||||||
|
if(auto mouse = inputManager->findMouse()) {
|
||||||
|
if(auto mapping = mappingList.selected()) {
|
||||||
|
activeMapping = activeDevice().mappings[mapping->offset()];
|
||||||
|
|
||||||
|
if(activeMapping->isDigital()) {
|
||||||
|
return inputEvent(*mouse, HID::Mouse::GroupID::Button, id, 0, 1, true);
|
||||||
|
} else if(activeMapping->isAnalog()) {
|
||||||
|
return inputEvent(*mouse, HID::Mouse::GroupID::Axis, id, 0, +32767, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto InputSettings::inputEvent(HID::Device& device, unsigned group, unsigned input, int16 oldValue, int16 newValue, bool allowMouseInput) -> void {
|
||||||
if(!activeMapping) return;
|
if(!activeMapping) return;
|
||||||
if(!device.isKeyboard() || oldValue != 0 || newValue != 1) return;
|
if(device.isMouse() && !allowMouseInput) return;
|
||||||
|
|
||||||
if(activeMapping->bind(device, group, input, oldValue, newValue)) {
|
if(activeMapping->bind(device, group, input, oldValue, newValue)) {
|
||||||
activeMapping = nullptr;
|
activeMapping = nullptr;
|
||||||
|
|
|
@ -20,6 +20,15 @@ SettingsManager::SettingsManager() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto SettingsManager::setVisible(bool visible) -> SettingsManager& {
|
||||||
|
if(visible) {
|
||||||
|
input.refreshMappings();
|
||||||
|
hotkeys.refreshMappings();
|
||||||
|
}
|
||||||
|
Window::setVisible(visible);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
auto SettingsManager::show(unsigned setting) -> void {
|
auto SettingsManager::show(unsigned setting) -> void {
|
||||||
panel.item(setting)->setSelected();
|
panel.item(setting)->setSelected();
|
||||||
setVisible();
|
setVisible();
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
struct InputSettings : TabFrameItem {
|
struct InputSettings : TabFrameItem {
|
||||||
InputSettings(TabFrame*);
|
InputSettings(TabFrame*);
|
||||||
|
auto updateControls() -> void;
|
||||||
auto activeEmulator() -> InputEmulator&;
|
auto activeEmulator() -> InputEmulator&;
|
||||||
auto activePort() -> InputPort&;
|
auto activePort() -> InputPort&;
|
||||||
auto activeDevice() -> InputDevice&;
|
auto activeDevice() -> InputDevice&;
|
||||||
|
@ -8,7 +9,8 @@ struct InputSettings : TabFrameItem {
|
||||||
auto reloadMappings() -> void;
|
auto reloadMappings() -> void;
|
||||||
auto refreshMappings() -> void;
|
auto refreshMappings() -> void;
|
||||||
auto assignMapping() -> void;
|
auto assignMapping() -> void;
|
||||||
auto inputEvent(HID::Device& device, unsigned group, unsigned input, int16 oldValue, int16 newValue) -> void;
|
auto assignMouseInput(unsigned id) -> void;
|
||||||
|
auto inputEvent(HID::Device& device, unsigned group, unsigned input, int16 oldValue, int16 newValue, bool allowMouseInput = false) -> void;
|
||||||
|
|
||||||
InputMapping* activeMapping = nullptr;
|
InputMapping* activeMapping = nullptr;
|
||||||
|
|
||||||
|
@ -19,6 +21,9 @@ struct InputSettings : TabFrameItem {
|
||||||
ComboButton deviceList{&selectionLayout, Size{~0, 0}};
|
ComboButton deviceList{&selectionLayout, Size{~0, 0}};
|
||||||
ListView mappingList{&layout, Size{~0, ~0}};
|
ListView mappingList{&layout, Size{~0, ~0}};
|
||||||
HorizontalLayout controlLayout{&layout, Size{~0, 0}};
|
HorizontalLayout controlLayout{&layout, Size{~0, 0}};
|
||||||
|
Button assignMouse1{&controlLayout, Size{100, 0}};
|
||||||
|
Button assignMouse2{&controlLayout, Size{100, 0}};
|
||||||
|
Button assignMouse3{&controlLayout, Size{100, 0}};
|
||||||
Widget spacer{&controlLayout, Size{~0, 0}};
|
Widget spacer{&controlLayout, Size{~0, 0}};
|
||||||
Button resetButton{&controlLayout, Size{80, 0}};
|
Button resetButton{&controlLayout, Size{80, 0}};
|
||||||
Button eraseButton{&controlLayout, Size{80, 0}};
|
Button eraseButton{&controlLayout, Size{80, 0}};
|
||||||
|
@ -61,6 +66,7 @@ struct AdvancedSettings : TabFrameItem {
|
||||||
|
|
||||||
struct SettingsManager : Window {
|
struct SettingsManager : Window {
|
||||||
SettingsManager();
|
SettingsManager();
|
||||||
|
auto setVisible(bool visible = true) -> SettingsManager&;
|
||||||
auto show(unsigned setting) -> void;
|
auto show(unsigned setting) -> void;
|
||||||
|
|
||||||
VerticalLayout layout{this};
|
VerticalLayout layout{this};
|
||||||
|
|
Loading…
Reference in New Issue