From 7975e624eebf35416d86b5ece1f27b1b9b920929 Mon Sep 17 00:00:00 2001 From: NoxyMe Date: Fri, 8 Dec 2023 21:39:11 +0000 Subject: [PATCH] ColecoVision - Added "Super Action Controller" support Added support for the "Super Action Controller". I an unsure how exactly the best setup for the controls when it comes to that binding thing. Unsure exacty how its ment to be layed out, but this works and works in the controller test roms. This is kinda a hack job with copied and modified code (controllers are nearly identical electronically to the original sock version just with two extra keys added). Also note the keys for this controller are typically listed from F1 to F4 renaming the L and R buttons... though that said cant find meeny first hand docs nameing those buttons on the oringal controller other than button 1 and button 2... so maybe they should be renamed in the emulator?.. idk, up to you lot. Let me know of any problems --- ares/cv/controller/controller.cpp | 1 + ares/cv/controller/controller.hpp | 1 + ares/cv/controller/port.cpp | 3 +- .../controller/super_action/super_action.cpp | 92 +++++++++++++++++++ .../controller/super_action/super_action.hpp | 38 ++++++++ desktop-ui/emulator/colecovision.cpp | 26 +++++- 6 files changed, 158 insertions(+), 3 deletions(-) create mode 100644 ares/cv/controller/super_action/super_action.cpp create mode 100644 ares/cv/controller/super_action/super_action.hpp diff --git a/ares/cv/controller/controller.cpp b/ares/cv/controller/controller.cpp index 337bf8f362..6fee45e68e 100644 --- a/ares/cv/controller/controller.cpp +++ b/ares/cv/controller/controller.cpp @@ -4,5 +4,6 @@ namespace ares::ColecoVision { #include "port.cpp" #include "gamepad/gamepad.cpp" +#include "super_action/super_action.cpp" } diff --git a/ares/cv/controller/controller.hpp b/ares/cv/controller/controller.hpp index 71b70bae2f..6237f21dfb 100644 --- a/ares/cv/controller/controller.hpp +++ b/ares/cv/controller/controller.hpp @@ -9,3 +9,4 @@ struct Controller : Thread { #include "port.hpp" #include "gamepad/gamepad.hpp" +#include "super_action/super_action.hpp" diff --git a/ares/cv/controller/port.cpp b/ares/cv/controller/port.cpp index 1514c4a440..b71744a854 100644 --- a/ares/cv/controller/port.cpp +++ b/ares/cv/controller/port.cpp @@ -11,7 +11,7 @@ auto ControllerPort::load(Node::Object parent) -> void { port->setHotSwappable(true); port->setAllocate([&](auto name) { return allocate(name); }); port->setDisconnect([&] { device.reset(); }); - port->setSupported({"Gamepad"}); + port->setSupported({"Gamepad","SuperActionController"}); } auto ControllerPort::unload() -> void { @@ -21,6 +21,7 @@ auto ControllerPort::unload() -> void { auto ControllerPort::allocate(string name) -> Node::Peripheral { if(name == "Gamepad") device = new Gamepad(port); + if(name == "SuperActionController") device = new SuperActionController(port); if(device) return device->node; return {}; } diff --git a/ares/cv/controller/super_action/super_action.cpp b/ares/cv/controller/super_action/super_action.cpp new file mode 100644 index 0000000000..685e77987e --- /dev/null +++ b/ares/cv/controller/super_action/super_action.cpp @@ -0,0 +1,92 @@ +SuperActionController::SuperActionController(Node::Port parent) { + node = parent->append("SuperActionController"); + + up = node->append("Up"); + down = node->append("Down"); + left = node->append("Left"); + right = node->append("Right"); + l = node->append("L"); + r = node->append("R"); + one = node->append("1"); + two = node->append("2"); + three = node->append("3"); + four = node->append("4"); + five = node->append("5"); + six = node->append("6"); + seven = node->append("7"); + eight = node->append("8"); + nine = node->append("9"); + star = node->append("*"); + zero = node->append("0"); + pound = node->append("#"); + + y = node->append("Y"); + x = node->append("X"); +} + +auto SuperActionController::read() -> n8 { + platform->input(up); + platform->input(down); + platform->input(left); + platform->input(right); + platform->input(l); + platform->input(r); + platform->input(one); + platform->input(two); + platform->input(three); + platform->input(four); + platform->input(five); + platform->input(six); + platform->input(seven); + platform->input(eight); + platform->input(nine); + platform->input(star); + platform->input(zero); + platform->input(pound); + + platform->input(x); + platform->input(y); + + if(!(up->value() & down->value())) { + yHold = 0, upLatch = up->value(), downLatch = down->value(); + } else if(!yHold) { + yHold = 1, swap(upLatch, downLatch); + } + + if(!(left->value() & right->value())) { + xHold = 0, leftLatch = left->value(), rightLatch = right->value(); + } else if(!xHold) { + xHold = 1, swap(leftLatch, rightLatch); + } + + n8 data = 0x7f; + if(select == 0) { + if(one->value ()) data.bit(0,3) = 0b1101; + else if(two->value ()) data.bit(0,3) = 0b0111; + else if(three->value()) data.bit(0,3) = 0b1100; + else if(four->value ()) data.bit(0,3) = 0b0010; + else if(five->value ()) data.bit(0,3) = 0b0011; + else if(six->value ()) data.bit(0,3) = 0b1110; + else if(seven->value()) data.bit(0,3) = 0b0101; + else if(eight->value()) data.bit(0,3) = 0b0001; + else if(nine->value ()) data.bit(0,3) = 0b1011; + else if(star->value ()) data.bit(0,3) = 0b1001; + else if(zero->value ()) data.bit(0,3) = 0b1010; + else if(pound->value()) data.bit(0,3) = 0b0110; + + else if(x->value ()) data.bit(0,3) = 0x04; + else if(y->value()) data.bit(0,3) = 0x08; + data.bit(6) = !r->value(); + } else { + data.bit(0) = !upLatch; + data.bit(1) = !rightLatch; + data.bit(2) = !downLatch; + data.bit(3) = !leftLatch; + data.bit(6) = !l->value(); + } + return data; +} + +auto SuperActionController::write(n8 data) -> void { + select = data.bit(0); +} diff --git a/ares/cv/controller/super_action/super_action.hpp b/ares/cv/controller/super_action/super_action.hpp new file mode 100644 index 0000000000..992f309075 --- /dev/null +++ b/ares/cv/controller/super_action/super_action.hpp @@ -0,0 +1,38 @@ +struct SuperActionController : Controller { + Node::Input::Button up; + Node::Input::Button down; + Node::Input::Button left; + Node::Input::Button right; + Node::Input::Button l; + Node::Input::Button r; + Node::Input::Button one; + Node::Input::Button two; + Node::Input::Button three; + Node::Input::Button four; + Node::Input::Button five; + Node::Input::Button six; + Node::Input::Button seven; + Node::Input::Button eight; + Node::Input::Button nine; + Node::Input::Button star; + Node::Input::Button zero; + Node::Input::Button pound; + + Node::Input::Button x; + Node::Input::Button y; + + SuperActionController(Node::Port); + + auto read() -> n8 override; + auto write(n8 data) -> void override; + + n1 select; + +private: + b1 yHold; + b1 upLatch; + b1 downLatch; + b1 xHold; + b1 leftLatch; + b1 rightLatch; +}; diff --git a/desktop-ui/emulator/colecovision.cpp b/desktop-ui/emulator/colecovision.cpp index 223c5e9b53..0ac6a2c244 100644 --- a/desktop-ui/emulator/colecovision.cpp +++ b/desktop-ui/emulator/colecovision.cpp @@ -19,8 +19,8 @@ ColecoVision::ColecoVision() { device.digital("Down", virtualPorts[id].pad.down); device.digital("Left", virtualPorts[id].pad.left); device.digital("Right", virtualPorts[id].pad.right); - device.digital("L", virtualPorts[id].pad.south); - device.digital("R", virtualPorts[id].pad.east); + device.digital("L", virtualPorts[id].pad.south); // F1 + device.digital("R", virtualPorts[id].pad.east); // F2 device.digital("1", virtualPorts[id].pad.west); device.digital("2", virtualPorts[id].pad.north); device.digital("3", virtualPorts[id].pad.l_bumper); @@ -34,6 +34,28 @@ ColecoVision::ColecoVision() { device.digital("*", virtualPorts[id].pad.select); device.digital("#", virtualPorts[id].pad.start); port.append(device); } + + { InputDevice device{"SuperActionController"}; + device.digital("Up", virtualPorts[id].pad.up); + device.digital("Down", virtualPorts[id].pad.down); + device.digital("Left", virtualPorts[id].pad.left); + device.digital("Right", virtualPorts[id].pad.right); + device.digital("L", virtualPorts[id].pad.south); // F1 + device.digital("R", virtualPorts[id].pad.east); // F2 + device.digital("Y", virtualPorts[id].pad.lstick_down); // F3 + device.digital("X", virtualPorts[id].pad.lstick_up); // F4 + device.digital("2", virtualPorts[id].pad.north); + device.digital("3", virtualPorts[id].pad.l_bumper); + device.digital("4", virtualPorts[id].pad.l_trigger); + device.digital("5", virtualPorts[id].pad.r_bumper); + device.digital("6", virtualPorts[id].pad.r_trigger); + device.digital("7", virtualPorts[id].pad.lstick_click); + device.digital("8", virtualPorts[id].pad.rstick_click); + device.digital("9", virtualPorts[id].pad.rstick_down); + device.digital("0", virtualPorts[id].pad.rstick_right); + device.digital("*", virtualPorts[id].pad.select); + device.digital("#", virtualPorts[id].pad.start); + port.append(device); } ports.append(port); }