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.

164 lines
4.3KB

  1. #include "JWModules.hpp"
  2. #include "dsp/digital.hpp"
  3. namespace rack_plugin_JW_Modules {
  4. struct WavHead : Module {
  5. enum ParamIds {
  6. NUM_PARAMS
  7. };
  8. enum InputIds {
  9. VOLT_INPUT,
  10. NUM_INPUTS
  11. };
  12. enum OutputIds {
  13. NUM_OUTPUTS
  14. };
  15. enum LightIds {
  16. NUM_LIGHTS
  17. };
  18. bool invert = true;
  19. bool neg5ToPos5 = false;
  20. bool snowMode = false;
  21. WavHead() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {}
  22. json_t *toJson() override {
  23. json_t *rootJ = json_object();
  24. json_object_set_new(rootJ, "invert", json_boolean(invert));
  25. json_object_set_new(rootJ, "neg5ToPos5", json_boolean(neg5ToPos5));
  26. json_object_set_new(rootJ, "snowMode", json_boolean(snowMode));
  27. return rootJ;
  28. }
  29. void fromJson(json_t *rootJ) override {
  30. json_t *invertJ = json_object_get(rootJ, "invert");
  31. if (invertJ){ invert = json_is_true(invertJ); }
  32. json_t *neg5ToPos5J = json_object_get(rootJ, "neg5ToPos5");
  33. if (neg5ToPos5J){ neg5ToPos5 = json_is_true(neg5ToPos5J); }
  34. json_t *snowModeJ = json_object_get(rootJ, "snowMode");
  35. if (snowModeJ){ snowMode = json_is_true(snowModeJ); }
  36. }
  37. };
  38. struct WavHeadWidget : ModuleWidget {
  39. WavHeadWidget(WavHead *module);
  40. void step() override;
  41. Widget* widgetToMove;
  42. Widget* snowflakesArr[10];
  43. Menu *createContextMenu() override;
  44. };
  45. void WavHeadWidget::step() {
  46. WavHead *wavHead = dynamic_cast<WavHead*>(module);
  47. float minVolts = wavHead->neg5ToPos5 ? -5 : 0;
  48. float maxVolts = minVolts + 10;
  49. float clamped = clampfjw(module->inputs[WavHead::VOLT_INPUT].value, minVolts, maxVolts);
  50. float minY = wavHead->invert ? 250 : 15;
  51. float maxY = wavHead->invert ? 15 : 250;
  52. widgetToMove->box.pos.y = rescalefjw(clamped, minVolts, maxVolts, minY, maxY);
  53. if(wavHead->snowMode){
  54. for(int i=0; i<10; i++){
  55. if(snowflakesArr[i]->box.pos.y > box.size.y){
  56. snowflakesArr[i]->box.pos.y = -randomUniform()*200-30;
  57. } else {
  58. snowflakesArr[i]->box.pos.y += randomUniform();
  59. }
  60. }
  61. } else {
  62. for(int i=0; i<10; i++){
  63. snowflakesArr[i]->box.pos.y = -randomUniform()*200-30;
  64. }
  65. }
  66. };
  67. WavHeadWidget::WavHeadWidget(WavHead *module) : ModuleWidget(module) {
  68. box.size = Vec(RACK_GRID_WIDTH*4, RACK_GRID_HEIGHT);
  69. LightPanel *panel = new LightPanel();
  70. panel->box.size = box.size;
  71. addChild(panel);
  72. widgetToMove = Widget::create<WavHeadLogo>(Vec(5, 250));
  73. addChild(widgetToMove);
  74. addChild(Widget::create<Screw_J>(Vec(16, 1)));
  75. addChild(Widget::create<Screw_J>(Vec(16, 365)));
  76. addChild(Widget::create<Screw_W>(Vec(box.size.x-29, 1)));
  77. addChild(Widget::create<Screw_W>(Vec(box.size.x-29, 365)));
  78. for(int i=0; i<10; i++){
  79. snowflakesArr[i] = Widget::create<Snowflake>(Vec(randomUniform()*box.size.x, -randomUniform()*200-30));
  80. addChild(snowflakesArr[i]);
  81. }
  82. addInput(Port::create<PJ301MPort>(Vec(18, 330), Port::INPUT, module, WavHead::VOLT_INPUT));
  83. }
  84. struct InvertMenuItem : MenuItem {
  85. WavHead *wavHead;
  86. void onAction(EventAction &e) override {
  87. wavHead->invert = !wavHead->invert;
  88. }
  89. void step() override {
  90. rightText = wavHead->invert ? "✔" : "";
  91. }
  92. };
  93. struct Neg5MenuItem : MenuItem {
  94. WavHead *wavHead;
  95. void onAction(EventAction &e) override {
  96. wavHead->neg5ToPos5 = !wavHead->neg5ToPos5;
  97. }
  98. void step() override {
  99. rightText = wavHead->neg5ToPos5 ? "✔" : "";
  100. }
  101. };
  102. struct SnowModeMenuItem : MenuItem {
  103. WavHead *wavHead;
  104. void onAction(EventAction &e) override {
  105. wavHead->snowMode = !wavHead->snowMode;
  106. }
  107. void step() override {
  108. rightText = wavHead->snowMode ? "✔" : "";
  109. }
  110. };
  111. Menu *WavHeadWidget::createContextMenu() {
  112. Menu *menu = ModuleWidget::createContextMenu();
  113. WavHead *wavHead = dynamic_cast<WavHead*>(module);
  114. MenuLabel *spacerLabel = new MenuLabel();
  115. menu->addChild(spacerLabel);
  116. InvertMenuItem *invertMenuItem = new InvertMenuItem();
  117. invertMenuItem->text = "Invert";
  118. invertMenuItem->wavHead = wavHead;
  119. menu->addChild(invertMenuItem);
  120. Neg5MenuItem *neg5MenuItem = new Neg5MenuItem();
  121. neg5MenuItem->text = "-5 to +5";
  122. neg5MenuItem->wavHead = wavHead;
  123. menu->addChild(neg5MenuItem);
  124. SnowModeMenuItem *snowModeMenuItem = new SnowModeMenuItem();
  125. snowModeMenuItem->text = "Snow Mode";
  126. snowModeMenuItem->wavHead = wavHead;
  127. menu->addChild(snowModeMenuItem);
  128. return menu;
  129. }
  130. } // namespace rack_plugin_JW_Modules
  131. using namespace rack_plugin_JW_Modules;
  132. RACK_PLUGIN_MODEL_INIT(JW_Modules, WavHead) {
  133. Model *modelWavHead = Model::create<WavHead, WavHeadWidget>("JW-Modules", "WavHead", "Wav Head", VISUAL_TAG);
  134. return modelWavHead;
  135. }