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.

134 lines
3.9KB

  1. #include "common.hpp"
  2. #include "boole.hpp"
  3. namespace rack_plugin_TheXOR {
  4. void Boole::step()
  5. {
  6. for(int k = 0; k < NUM_BOOL_OP; k++)
  7. {
  8. int index = 2 * k;
  9. if(inputs[IN_1 + index].active && (k == 0 || inputs[IN_1 + index - 1].active))
  10. {
  11. bool o = process(k, index);
  12. if(k > 0 && params[INVERT_1 + k - 1].value > 0)
  13. o = !o;
  14. lights[LED_1+k+ 2 * NUM_BOOL_OP-1].value = o ? 5.0 : 0.0;
  15. outputs[OUT_1 + k].value = o ? LVL_ON : LVL_OFF;
  16. } else
  17. {
  18. outputs[OUT_1 + k].value = lights[LED_1 + k + 2 * NUM_BOOL_OP - 1].value = LVL_OFF;
  19. }
  20. }
  21. }
  22. bool Boole::process(int num_op, int index)
  23. {
  24. bool x;
  25. if(num_op == 0) // not?
  26. {
  27. x = inputs[IN_1].normalize(0.0) > params[THRESH_1 ].value;
  28. lights[LED_1].value = x ? 5.0 : 0.0;
  29. return !x;
  30. } else
  31. {
  32. x = inputs[IN_1 + index-1].normalize(0.0) > params[THRESH_1 + index-1].value;
  33. lights[LED_1 + index - 1].value = x ? 5.0 : 0.0;
  34. }
  35. bool y = inputs[IN_1 + index].normalize(0.0) > params[THRESH_1 + index].value;
  36. lights[LED_1 + index].value = y ? 5.0 : 0.0;
  37. switch(num_op)
  38. {
  39. case 1: return x && y; //and
  40. case 2: return x || y; //or
  41. case 3: return x ^ y; //the xor
  42. case 4: return !x || y; // implication
  43. }
  44. return false;
  45. }
  46. BooleWidget::BooleWidget(Boole *module) : ModuleWidget(module)
  47. {
  48. box.size = Vec(14* RACK_GRID_WIDTH, RACK_GRID_HEIGHT);
  49. {
  50. SVGPanel *panel = new SVGPanel();
  51. panel->box.size = box.size;
  52. panel->setBackground(SVG::load(assetPlugin(plugin, "res/modules/boole.svg")));
  53. addChild(panel);
  54. }
  55. addChild(Widget::create<ScrewBlack>(Vec(RACK_GRID_WIDTH, 0)));
  56. addChild(Widget::create<ScrewBlack>(Vec(box.size.x - 2 * RACK_GRID_WIDTH, 0)));
  57. addChild(Widget::create<ScrewBlack>(Vec(RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH)));
  58. addChild(Widget::create<ScrewBlack>(Vec(box.size.x - 2 * RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH)));
  59. float in_x = mm2px(5.170);
  60. float in_led_x = mm2px(15.778);
  61. float out_led_x = mm2px(53.878);
  62. float pot_x = mm2px(20.561);
  63. float out_x = mm2px(58.091);
  64. float y = 112.349;
  65. float yout = 112.349;
  66. float ypot = 112.477;
  67. float yled = 115.389;
  68. float yinv = 97.892;
  69. float yled_out = 115.389;
  70. float delta_y =- 14.771;
  71. float sub_dy = -11.92;
  72. float out_dy = -26.691;
  73. for(int k = 0; k < NUM_BOOL_OP; k++)
  74. {
  75. int index = 2 * k;
  76. if(k > 0)
  77. index--;
  78. // X
  79. addInput(Port::create<PJ301GRPort>(Vec(in_x, yncscape(y, 8.255)), Port::INPUT, module, Boole::IN_1 + index));
  80. addParam(ParamWidget::create<Davies1900hFixWhiteKnobSmall>(Vec(pot_x, yncscape(ypot, 8.0)), module, Boole::THRESH_1 + index, 0.0, 10.0, 0.0));
  81. addChild(ModuleLightWidget::create<SmallLight<RedLight>>(Vec(in_led_x, yncscape(yled, 2.176)), module, Boole::LED_1+index));
  82. // Y
  83. if(k > 0)
  84. {
  85. index++;
  86. y += sub_dy;
  87. ypot += sub_dy;
  88. yled += sub_dy;
  89. addInput(Port::create<PJ301GRPort>(Vec(in_x, yncscape(y, 8.255)), Port::INPUT, module, Boole::IN_1 + index));
  90. addParam(ParamWidget::create<Davies1900hFixWhiteKnobSmall>(Vec(pot_x, yncscape(ypot, 8.0) ), module, Boole::THRESH_1 + index, 0.0, 10.0, 0.0));
  91. addChild(ModuleLightWidget::create<SmallLight<RedLight>>(Vec(in_led_x, yncscape(yled, 2.176)), module, Boole::LED_1 + index ));
  92. }
  93. // OUT
  94. addOutput(Port::create<PJ301WPort>(Vec(out_x, yncscape(yout, 8.255)), Port::OUTPUT, module, Boole::OUT_1+k));
  95. addChild(ModuleLightWidget::create<SmallLight<WhiteLight>>(Vec(out_led_x, yncscape(yled_out, 2.176)), module, Boole::LED_1 + k+ 2 * NUM_BOOL_OP-1));
  96. if(k == 0)
  97. {
  98. yled_out -= 20.731;
  99. yout -= 20.731;
  100. } else
  101. {
  102. addParam(ParamWidget::create<CKSSFix>(Vec(mm2px(53.116), yncscape(yinv, 5.460)), module, Boole::INVERT_1 + k - 1, 0.0, 1.0, 0.0));
  103. yled_out += out_dy;
  104. yout += out_dy;
  105. yinv += out_dy;
  106. }
  107. y += delta_y;
  108. ypot += delta_y;
  109. yled += delta_y;
  110. }
  111. }
  112. } // namespace rack_plugin_TheXOR
  113. using namespace rack_plugin_TheXOR;
  114. RACK_PLUGIN_MODEL_INIT(TheXOR, Boole) {
  115. return Model::create<Boole, BooleWidget>("TheXOR", "Boole", "Boole", LOGIC_TAG);
  116. }