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.

176 lines
5.6KB

  1. #include "plugin.hpp"
  2. struct Logic : Module {
  3. enum ParamId {
  4. B_PARAM,
  5. PARAMS_LEN
  6. };
  7. enum InputId {
  8. A_INPUT,
  9. B_INPUT,
  10. INPUTS_LEN
  11. };
  12. enum OutputId {
  13. NOTA_OUTPUT,
  14. NOTB_OUTPUT,
  15. OR_OUTPUT,
  16. NOR_OUTPUT,
  17. AND_OUTPUT,
  18. NAND_OUTPUT,
  19. XOR_OUTPUT,
  20. XNOR_OUTPUT,
  21. OUTPUTS_LEN
  22. };
  23. enum LightId {
  24. B_BUTTON_LIGHT,
  25. ENUMS(NOTA_LIGHT, 2),
  26. ENUMS(NOTB_LIGHT, 2),
  27. ENUMS(OR_LIGHT, 2),
  28. ENUMS(NOR_LIGHT, 2),
  29. ENUMS(AND_LIGHT, 2),
  30. ENUMS(NAND_LIGHT, 2),
  31. ENUMS(XOR_LIGHT, 2),
  32. ENUMS(XNOR_LIGHT, 2),
  33. LIGHTS_LEN
  34. };
  35. dsp::ClockDivider lightDivider;
  36. Logic() {
  37. config(PARAMS_LEN, INPUTS_LEN, OUTPUTS_LEN, LIGHTS_LEN);
  38. configButton(B_PARAM, "B");
  39. configInput(A_INPUT, "A");
  40. configInput(B_INPUT, "B");
  41. configOutput(NOTA_OUTPUT, "NOT A");
  42. configOutput(NOTB_OUTPUT, "NOT B");
  43. configOutput(OR_OUTPUT, "OR");
  44. configOutput(NOR_OUTPUT, "NOR");
  45. configOutput(AND_OUTPUT, "AND");
  46. configOutput(NAND_OUTPUT, "NAND");
  47. configOutput(XOR_OUTPUT, "XOR");
  48. configOutput(XNOR_OUTPUT, "XNOR");
  49. lightDivider.setDivision(32);
  50. }
  51. void process(const ProcessArgs& args) override {
  52. int channels = std::max(inputs[A_INPUT].getChannels(), inputs[B_INPUT].getChannels());
  53. bool bPush = params[B_PARAM].getValue() > 0.f;
  54. bool anyState[8] = {};
  55. for (int c = 0; c < channels; c++) {
  56. bool a = inputs[A_INPUT].getPolyVoltage(c) >= 1.f;
  57. bool b = bPush || inputs[B_INPUT].getPolyVoltage(c) >= 1.f;
  58. bool states[8] = {
  59. !a, // NOTA
  60. !b, // NOTB
  61. a || b, // OR
  62. !(a || b), // NOR
  63. a && b, // AND
  64. !(a && b), // NAND
  65. a != b, // XOR
  66. a == b, // XNOR
  67. };
  68. for (int i = 0; i < 8; i++) {
  69. outputs[NOTA_OUTPUT + i].setVoltage(states[i] ? 10.f : 0.f);
  70. if (states[i])
  71. anyState[i] = true;
  72. }
  73. }
  74. for (int i = 0; i < 8; i++) {
  75. outputs[NOTA_OUTPUT + i].setChannels(channels);
  76. }
  77. // Set lights
  78. if (lightDivider.process()) {
  79. float lightTime = args.sampleTime * lightDivider.getDivision();
  80. lights[B_BUTTON_LIGHT].setBrightness(bPush);
  81. for (int i = 0; i < 8; i++) {
  82. lights[NOTA_LIGHT + 2 * i + 0].setBrightnessSmooth(anyState[i] && channels == 1, lightTime);
  83. lights[NOTA_LIGHT + 2 * i + 1].setBrightnessSmooth(anyState[i] && channels > 1, lightTime);
  84. }
  85. }
  86. }
  87. };
  88. struct VCVBezelBig : app::SvgSwitch {
  89. VCVBezelBig() {
  90. momentary = true;
  91. addFrame(Svg::load(asset::plugin(pluginInstance, "res/VCVBezelBig.svg")));
  92. }
  93. };
  94. template <typename TBase>
  95. struct VCVBezelLightBig : TBase {
  96. VCVBezelLightBig() {
  97. this->borderColor = color::BLACK_TRANSPARENT;
  98. this->bgColor = color::BLACK_TRANSPARENT;
  99. this->box.size = mm2px(math::Vec(9.53, 9.53));
  100. }
  101. };
  102. template <typename TBase, typename TLight = WhiteLight>
  103. struct LightButton : TBase {
  104. app::ModuleLightWidget* light;
  105. LightButton() {
  106. light = new TLight;
  107. // Move center of light to center of box
  108. light->box.pos = this->box.size.div(2).minus(light->box.size.div(2));
  109. this->addChild(light);
  110. }
  111. app::ModuleLightWidget* getLight() {
  112. return light;
  113. }
  114. };
  115. using VCVBezelLightBigWhite = LightButton<VCVBezelBig, VCVBezelLightBig<WhiteLight>>;
  116. struct LogicWidget : ModuleWidget {
  117. LogicWidget(Logic* module) {
  118. setModule(module);
  119. setPanel(createPanel(asset::plugin(pluginInstance, "res/Logic.svg")));
  120. addChild(createWidget<ScrewSilver>(Vec(RACK_GRID_WIDTH, 0)));
  121. addChild(createWidget<ScrewSilver>(Vec(box.size.x - 2 * RACK_GRID_WIDTH, 0)));
  122. addChild(createWidget<ScrewSilver>(Vec(RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH)));
  123. addChild(createWidget<ScrewSilver>(Vec(box.size.x - 2 * RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH)));
  124. addParam(createLightParamCentered<VCVBezelLightBigWhite>(mm2px(Vec(12.7, 26.755)), module, Logic::B_PARAM, Logic::B_BUTTON_LIGHT));
  125. addInput(createInputCentered<PJ301MPort>(mm2px(Vec(7.299, 52.31)), module, Logic::A_INPUT));
  126. addInput(createInputCentered<PJ301MPort>(mm2px(Vec(18.136, 52.31)), module, Logic::B_INPUT));
  127. addOutput(createOutputCentered<PJ301MPort>(mm2px(Vec(7.297, 67.53)), module, Logic::NOTA_OUTPUT));
  128. addOutput(createOutputCentered<PJ301MPort>(mm2px(Vec(18.134, 67.53)), module, Logic::NOTB_OUTPUT));
  129. addOutput(createOutputCentered<PJ301MPort>(mm2px(Vec(7.297, 82.732)), module, Logic::OR_OUTPUT));
  130. addOutput(createOutputCentered<PJ301MPort>(mm2px(Vec(18.134, 82.732)), module, Logic::NOR_OUTPUT));
  131. addOutput(createOutputCentered<PJ301MPort>(mm2px(Vec(7.297, 97.958)), module, Logic::AND_OUTPUT));
  132. addOutput(createOutputCentered<PJ301MPort>(mm2px(Vec(18.134, 97.958)), module, Logic::NAND_OUTPUT));
  133. addOutput(createOutputCentered<PJ301MPort>(mm2px(Vec(7.297, 113.115)), module, Logic::XOR_OUTPUT));
  134. addOutput(createOutputCentered<PJ301MPort>(mm2px(Vec(18.134, 113.115)), module, Logic::XNOR_OUTPUT));
  135. addChild(createLightCentered<TinyLight<YellowBlueLight<>>>(mm2px(Vec(11.027, 63.805)), module, Logic::NOTA_LIGHT));
  136. addChild(createLightCentered<TinyLight<YellowBlueLight<>>>(mm2px(Vec(21.864, 63.805)), module, Logic::NOTB_LIGHT));
  137. addChild(createLightCentered<TinyLight<YellowBlueLight<>>>(mm2px(Vec(11.027, 79.007)), module, Logic::OR_LIGHT));
  138. addChild(createLightCentered<TinyLight<YellowBlueLight<>>>(mm2px(Vec(21.864, 79.007)), module, Logic::NOR_LIGHT));
  139. addChild(createLightCentered<TinyLight<YellowBlueLight<>>>(mm2px(Vec(11.027, 94.233)), module, Logic::AND_LIGHT));
  140. addChild(createLightCentered<TinyLight<YellowBlueLight<>>>(mm2px(Vec(21.864, 94.233)), module, Logic::NAND_LIGHT));
  141. addChild(createLightCentered<TinyLight<YellowBlueLight<>>>(mm2px(Vec(11.027, 109.393)), module, Logic::XOR_LIGHT));
  142. addChild(createLightCentered<TinyLight<YellowBlueLight<>>>(mm2px(Vec(21.864, 109.393)), module, Logic::XNOR_LIGHT));
  143. }
  144. };
  145. Model* modelLogic = createModel<Logic, LogicWidget>("Logic");