You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

336 lines
12KB

  1. #include "alikins.hpp"
  2. #include "dsp/digital.hpp"
  3. #include "window.hpp"
  4. #include <global_pre.hpp>
  5. #include <global_ui.hpp>
  6. namespace rack_plugin_Alikins {
  7. struct ShiftPedal : Module {
  8. enum ParamIds {
  9. LEFT_SHIFT_PARAM,
  10. RIGHT_SHIFT_PARAM,
  11. LEFT_CTRL_PARAM,
  12. RIGHT_CTRL_PARAM,
  13. LEFT_ALT_PARAM,
  14. RIGHT_ALT_PARAM,
  15. LEFT_SUPER_PARAM,
  16. RIGHT_SUPER_PARAM,
  17. NUM_PARAMS
  18. };
  19. enum InputIds {
  20. NUM_INPUTS
  21. };
  22. enum OutputIds {
  23. LEFT_SHIFT_GATE_OUTPUT,
  24. RIGHT_SHIFT_GATE_OUTPUT,
  25. EITHER_SHIFT_GATE_OUTPUT,
  26. LEFT_CTRL_GATE_OUTPUT,
  27. RIGHT_CTRL_GATE_OUTPUT,
  28. EITHER_CTRL_GATE_OUTPUT,
  29. LEFT_ALT_GATE_OUTPUT,
  30. RIGHT_ALT_GATE_OUTPUT,
  31. EITHER_ALT_GATE_OUTPUT,
  32. LEFT_SUPER_GATE_OUTPUT,
  33. RIGHT_SUPER_GATE_OUTPUT,
  34. EITHER_SUPER_GATE_OUTPUT,
  35. NUM_OUTPUTS
  36. };
  37. enum LightIds {
  38. NUM_LIGHTS
  39. };
  40. ShiftPedal() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {}
  41. void step() override;
  42. // TODO: should probably setup a pulse generator for the gate outs
  43. };
  44. void ShiftPedal::step() {
  45. // TODO: should probably setup a pulse generator for the gate outs
  46. outputs[LEFT_SHIFT_GATE_OUTPUT].value = params[LEFT_SHIFT_PARAM].value;
  47. outputs[RIGHT_SHIFT_GATE_OUTPUT].value = params[RIGHT_SHIFT_PARAM].value;
  48. outputs[EITHER_SHIFT_GATE_OUTPUT].value = params[LEFT_SHIFT_PARAM].value +
  49. params[RIGHT_SHIFT_PARAM].value >= 10.0f ? 10.0f : 0.0f;
  50. outputs[LEFT_CTRL_GATE_OUTPUT].value = params[LEFT_CTRL_PARAM].value;
  51. outputs[RIGHT_CTRL_GATE_OUTPUT].value = params[RIGHT_CTRL_PARAM].value;
  52. outputs[EITHER_CTRL_GATE_OUTPUT].value = params[LEFT_CTRL_PARAM].value +
  53. params[RIGHT_CTRL_PARAM].value >= 10.0f ? 10.0f : 0.0f;
  54. outputs[LEFT_ALT_GATE_OUTPUT].value = params[LEFT_ALT_PARAM].value;
  55. outputs[RIGHT_ALT_GATE_OUTPUT].value = params[RIGHT_ALT_PARAM].value;
  56. outputs[EITHER_ALT_GATE_OUTPUT].value = params[LEFT_ALT_PARAM].value +
  57. params[RIGHT_ALT_PARAM].value >= 10.0f ? 10.0f : 0.0f;
  58. outputs[LEFT_SUPER_GATE_OUTPUT].value = params[LEFT_SUPER_PARAM].value;
  59. outputs[RIGHT_SUPER_GATE_OUTPUT].value = params[RIGHT_SUPER_PARAM].value;
  60. outputs[EITHER_SUPER_GATE_OUTPUT].value = params[LEFT_SUPER_PARAM].value +
  61. params[RIGHT_SUPER_PARAM].value >= 10.0f ? 10.0f : 0.0f;
  62. }
  63. struct ShiftSwitch : SVGSwitch, ToggleSwitch {
  64. ShiftSwitch() {
  65. addFrame(SVG::load(assetPlugin(plugin, "res/ShiftIsOff.svg")));
  66. addFrame(SVG::load(assetPlugin(plugin, "res/ShiftIsOn.svg")));
  67. }
  68. };
  69. struct CtrlSwitch : SVGSwitch, ToggleSwitch {
  70. CtrlSwitch() {
  71. addFrame(SVG::load(assetPlugin(plugin, "res/CtrlIsOff.svg")));
  72. addFrame(SVG::load(assetPlugin(plugin, "res/CtrlIsOn.svg")));
  73. }
  74. };
  75. struct AltSwitch : SVGSwitch, ToggleSwitch {
  76. AltSwitch() {
  77. addFrame(SVG::load(assetPlugin(plugin, "res/AltIsOff.svg")));
  78. addFrame(SVG::load(assetPlugin(plugin, "res/AltIsOn.svg")));
  79. }
  80. };
  81. struct SuperSwitch : SVGSwitch, ToggleSwitch {
  82. SuperSwitch() {
  83. addFrame(SVG::load(assetPlugin(plugin, "res/SuperIsOff.svg")));
  84. addFrame(SVG::load(assetPlugin(plugin, "res/SuperIsOn.svg")));
  85. }
  86. };
  87. struct PurplePort : SVGPort {
  88. PurplePort() {
  89. setSVG(SVG::load(assetPlugin(plugin, "res/PurplePort.svg")));
  90. }
  91. };
  92. struct ShiftPedalWidget : ModuleWidget {
  93. ShiftPedalWidget(ShiftPedal *module);
  94. ParamWidget *leftShiftButtonSwitch;
  95. ParamWidget *rightShiftButtonSwitch;
  96. ParamWidget *leftCtrlButtonSwitch;
  97. ParamWidget *rightCtrlButtonSwitch;
  98. ParamWidget *leftAltButtonSwitch;
  99. ParamWidget *rightAltButtonSwitch;
  100. ParamWidget *leftSuperButtonSwitch;
  101. ParamWidget *rightSuperButtonSwitch;
  102. void step() override;
  103. };
  104. ShiftPedalWidget::ShiftPedalWidget(ShiftPedal *module) : ModuleWidget(module) {
  105. box.size = Vec(4 * RACK_GRID_WIDTH, RACK_GRID_HEIGHT);
  106. setPanel(SVG::load(assetPlugin(plugin, "res/ShiftPedal.svg")));
  107. // FIXME: change to #defines
  108. float buttonWidth = 30.0f;
  109. float buttonHeight = 55.5f;
  110. float y_start = 25.0f;
  111. float y_spacing = 1.5f;
  112. float y_row_spacing = 6.5f;
  113. float y_baseline = y_start;
  114. float port_x_start = 3.0f;
  115. float middle = box.size.x / 2.0f;
  116. // first row, shift
  117. leftShiftButtonSwitch = ParamWidget::create<ShiftSwitch>(Vec(0.0f, y_baseline),
  118. module,
  119. ShiftPedal::LEFT_SHIFT_PARAM,
  120. 0.0f, 10.0f, 0.0f);
  121. addParam(leftShiftButtonSwitch);
  122. buttonHeight = leftShiftButtonSwitch->box.size.y;
  123. Port *leftShiftButtonPort =
  124. Port::create<PurplePort>(Vec(port_x_start, y_baseline + buttonHeight + y_spacing),
  125. Port::OUTPUT,
  126. module,
  127. ShiftPedal::LEFT_SHIFT_GATE_OUTPUT);
  128. addOutput(leftShiftButtonPort);
  129. float portHeight = leftShiftButtonPort->box.size.y;
  130. float portWidth = leftShiftButtonPort->box.size.x;
  131. // Add the 'either' port
  132. Port *eitherShiftPort =
  133. Port::create<PurplePort>(Vec(middle - (portWidth/2.0f), y_baseline + buttonHeight + y_spacing),
  134. Port::OUTPUT,
  135. module,
  136. ShiftPedal::EITHER_SHIFT_GATE_OUTPUT);
  137. addOutput(eitherShiftPort);
  138. rightShiftButtonSwitch = ParamWidget::create<ShiftSwitch>(Vec(buttonWidth, y_start),
  139. module,
  140. ShiftPedal::RIGHT_SHIFT_PARAM,
  141. 0.0f, 10.0f, 0.0f);
  142. addParam(rightShiftButtonSwitch);
  143. addOutput(Port::create<PurplePort>(Vec(box.size.x - portWidth - port_x_start, y_start + buttonHeight + y_spacing),
  144. Port::OUTPUT,
  145. module,
  146. ShiftPedal::RIGHT_SHIFT_GATE_OUTPUT));
  147. // next row
  148. y_baseline = y_baseline + buttonHeight + y_spacing + portHeight + y_row_spacing;
  149. leftCtrlButtonSwitch = ParamWidget::create<CtrlSwitch>(Vec(0.0f, y_baseline),
  150. module,
  151. ShiftPedal::LEFT_CTRL_PARAM,
  152. 0.0f, 10.0f, 0.0f);
  153. addParam(leftCtrlButtonSwitch);
  154. // update for this row, although ended up making all the buttons the same size for now
  155. buttonHeight = leftCtrlButtonSwitch->box.size.y;
  156. addOutput(Port::create<PurplePort>(Vec(port_x_start, y_baseline + buttonHeight + y_spacing),
  157. Port::OUTPUT,
  158. module,
  159. ShiftPedal::LEFT_CTRL_GATE_OUTPUT));
  160. //either
  161. Port *eitherCtrlPort =
  162. Port::create<PurplePort>(Vec(middle - (portWidth / 2.0f), y_baseline + buttonHeight + y_spacing),
  163. Port::OUTPUT,
  164. module,
  165. ShiftPedal::EITHER_CTRL_GATE_OUTPUT);
  166. addOutput(eitherCtrlPort);
  167. rightCtrlButtonSwitch = ParamWidget::create<CtrlSwitch>(Vec(buttonWidth, y_baseline),
  168. module,
  169. ShiftPedal::RIGHT_CTRL_PARAM,
  170. 0.0f, 10.0f, 0.0f);
  171. addParam(rightCtrlButtonSwitch);
  172. addOutput(Port::create<PurplePort>(Vec(box.size.x - portWidth - port_x_start,
  173. y_baseline + buttonHeight + y_spacing),
  174. Port::OUTPUT,
  175. module,
  176. ShiftPedal::RIGHT_CTRL_GATE_OUTPUT));
  177. // third row Alt
  178. y_baseline = y_baseline + buttonHeight + y_spacing + portHeight + y_row_spacing;
  179. leftAltButtonSwitch = ParamWidget::create<AltSwitch>(Vec(0.0f, y_baseline),
  180. module,
  181. ShiftPedal::LEFT_ALT_PARAM,
  182. 0.0f, 10.0f, 0.0f);
  183. addParam(leftAltButtonSwitch);
  184. float altButtonHeight = leftAltButtonSwitch->box.size.y;
  185. addOutput(Port::create<PurplePort>(Vec(2.0f, y_baseline + altButtonHeight + y_spacing),
  186. Port::OUTPUT,
  187. module,
  188. ShiftPedal::LEFT_ALT_GATE_OUTPUT));
  189. //either
  190. Port *eitherAltPort =
  191. Port::create<PurplePort>(Vec(middle - (portWidth / 2.0f), y_baseline + altButtonHeight + y_spacing),
  192. Port::OUTPUT,
  193. module,
  194. ShiftPedal::EITHER_ALT_GATE_OUTPUT);
  195. addOutput(eitherAltPort);
  196. rightAltButtonSwitch = ParamWidget::create<AltSwitch>(Vec(buttonWidth, y_baseline),
  197. module,
  198. ShiftPedal::RIGHT_ALT_PARAM,
  199. 0.0f, 10.0f, 0.0f);
  200. addParam(rightAltButtonSwitch);
  201. addOutput(Port::create<PurplePort>(Vec(box.size.x - portWidth - port_x_start, y_baseline + altButtonHeight + y_spacing),
  202. Port::OUTPUT,
  203. module,
  204. ShiftPedal::RIGHT_ALT_GATE_OUTPUT));
  205. // fourth row, super
  206. y_baseline = y_baseline + altButtonHeight + y_spacing + portHeight + y_row_spacing;
  207. leftSuperButtonSwitch = ParamWidget::create<SuperSwitch>(Vec(0.0f, y_baseline),
  208. module,
  209. ShiftPedal::LEFT_SUPER_PARAM,
  210. 0.0f, 10.0f, 0.0f);
  211. addParam(leftSuperButtonSwitch);
  212. float superButtonHeight = leftSuperButtonSwitch->box.size.y;
  213. addOutput(Port::create<PurplePort>(Vec(2.0f, y_baseline + superButtonHeight + y_spacing),
  214. Port::OUTPUT,
  215. module,
  216. ShiftPedal::LEFT_SUPER_GATE_OUTPUT));
  217. //either
  218. Port *eitherSuperPort =
  219. Port::create<PurplePort>(Vec(middle - (portWidth / 2.0f), y_baseline + superButtonHeight + y_spacing),
  220. Port::OUTPUT,
  221. module,
  222. ShiftPedal::EITHER_SUPER_GATE_OUTPUT);
  223. addOutput(eitherSuperPort);
  224. rightSuperButtonSwitch = ParamWidget::create<SuperSwitch>(Vec(buttonWidth, y_baseline),
  225. module,
  226. ShiftPedal::RIGHT_SUPER_PARAM,
  227. 0.0f, 10.0f, 0.0f);
  228. addParam(rightSuperButtonSwitch);
  229. addOutput(Port::create<PurplePort>(Vec(box.size.x - portWidth - port_x_start, y_baseline + superButtonHeight + y_spacing),
  230. Port::OUTPUT,
  231. module,
  232. ShiftPedal::RIGHT_SUPER_GATE_OUTPUT));
  233. addChild(Widget::create<ScrewSilver>(Vec(0.0, 0)));
  234. addChild(Widget::create<ScrewSilver>(Vec(box.size.x-15, 0)));
  235. addChild(Widget::create<ScrewSilver>(Vec(0.0f, 365.0f)));
  236. }
  237. void ShiftPedalWidget::step() {
  238. #if 1
  239. // LGLW (VSVR)
  240. uint32_t mod = lglw_keyboard_get_modifiers(rack::global_ui->window.lglw);
  241. leftShiftButtonSwitch->setValue((0 != (mod & LGLW_KMOD_LSHIFT)) ? 10.0f : 0.0f);
  242. rightShiftButtonSwitch->setValue((0 != (mod & LGLW_KMOD_RSHIFT)) ? 10.0f : 0.0f);
  243. leftCtrlButtonSwitch->setValue((0 != (mod & LGLW_KMOD_LCTRL)) ? 10.0f : 0.0f);
  244. rightCtrlButtonSwitch->setValue((0 != (mod & LGLW_KMOD_RCTRL)) ? 10.0f : 0.0f);
  245. leftAltButtonSwitch->setValue((0 != (mod & LGLW_KMOD_LALT)) ? 10.0f : 0.0f);
  246. rightAltButtonSwitch->setValue((0 != (mod & LGLW_KMOD_RALT)) ? 10.0f : 0.0f);
  247. leftSuperButtonSwitch->setValue((0 != (mod & LGLW_KMOD_LSUPER)) ? 10.0f : 0.0f); // unreachable (windows key)
  248. rightSuperButtonSwitch->setValue((0 != (mod & LGLW_KMOD_RSUPER)) ? 10.0f : 0.0f); // menu key
  249. #else
  250. // GLFW (VCV)
  251. leftShiftButtonSwitch->setValue(glfwGetKey(gWindow, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS ? 10.0f : 0.0f);
  252. rightShiftButtonSwitch->setValue(glfwGetKey(gWindow, GLFW_KEY_RIGHT_SHIFT) == GLFW_PRESS ? 10.0f : 0.0f);
  253. leftCtrlButtonSwitch->setValue(glfwGetKey(gWindow, GLFW_KEY_LEFT_CONTROL) == GLFW_PRESS ? 10.0f : 0.0f);
  254. rightCtrlButtonSwitch->setValue(glfwGetKey(gWindow, GLFW_KEY_RIGHT_CONTROL) == GLFW_PRESS ? 10.0f : 0.0f);
  255. leftAltButtonSwitch->setValue(glfwGetKey(gWindow, GLFW_KEY_LEFT_ALT) == GLFW_PRESS ? 10.0f : 0.0f);
  256. rightAltButtonSwitch->setValue(glfwGetKey(gWindow, GLFW_KEY_RIGHT_ALT) == GLFW_PRESS ? 10.0f : 0.0f);
  257. leftSuperButtonSwitch->setValue(glfwGetKey(gWindow, GLFW_KEY_LEFT_SUPER) == GLFW_PRESS ? 10.0f : 0.0f);
  258. rightSuperButtonSwitch->setValue(glfwGetKey(gWindow, GLFW_KEY_RIGHT_SUPER) == GLFW_PRESS ? 10.0f : 0.0f);
  259. #endif
  260. ModuleWidget::step();
  261. }
  262. } // namespace rack_plugin_Alikins
  263. using namespace rack_plugin_Alikins;
  264. RACK_PLUGIN_MODEL_INIT(Alikins, ShiftPedal) {
  265. Model *modelShiftPedal = Model::create<ShiftPedal, ShiftPedalWidget>(
  266. "Alikins", "ShiftPedal", "Shift Pedal - Gen gates on mod key presses", UTILITY_TAG);
  267. return modelShiftPedal;
  268. }