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.

161 lines
4.5KB

  1. #include <string.h>
  2. #include "JWModules.hpp"
  3. #include "dsp/digital.hpp"
  4. namespace rack_plugin_JW_Modules {
  5. struct ThingThingBall {
  6. NVGcolor color;
  7. };
  8. struct ThingThing : Module {
  9. enum ParamIds {
  10. BALL_RAD_PARAM,
  11. ZOOM_MULT_PARAM,
  12. NUM_PARAMS
  13. };
  14. enum InputIds {
  15. BALL_RAD_INPUT,
  16. ZOOM_MULT_INPUT,
  17. ANG_INPUT,
  18. NUM_INPUTS = ANG_INPUT + 5
  19. };
  20. enum OutputIds {
  21. NUM_OUTPUTS
  22. };
  23. enum LightIds {
  24. NUM_LIGHTS
  25. };
  26. ThingThingBall *balls = new ThingThingBall[5];
  27. float atten[5] = {1, 1, 1, 1, 1};
  28. // float atten[5] = {0.0, 0.25, 0.5, 0.75, 1};
  29. ThingThing() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {
  30. balls[0].color = nvgRGB(255, 255, 255);//white
  31. balls[1].color = nvgRGB(255, 151, 9);//orange
  32. balls[2].color = nvgRGB(255, 243, 9);//yellow
  33. balls[3].color = nvgRGB(144, 26, 252);//purple
  34. balls[4].color = nvgRGB(25, 150, 252);//blue
  35. }
  36. ~ThingThing() {
  37. delete [] balls;
  38. }
  39. void step() override {};
  40. void reset() override {}
  41. json_t *toJson() override {
  42. json_t *rootJ = json_object();
  43. return rootJ;
  44. }
  45. void fromJson(json_t *rootJ) override {}
  46. };
  47. struct ThingThingDisplay : Widget {
  48. ThingThing *module;
  49. ThingThingDisplay(){}
  50. void draw(NVGcontext *vg) override {
  51. //background
  52. nvgFillColor(vg, nvgRGB(20, 30, 33));
  53. nvgBeginPath(vg);
  54. nvgRect(vg, 0, 0, box.size.x, box.size.y);
  55. nvgFill(vg);
  56. float ballRadius = module->params[ThingThing::BALL_RAD_PARAM].value;
  57. if(module->inputs[ThingThing::BALL_RAD_INPUT].active){
  58. ballRadius += rescalefjw(module->inputs[ThingThing::BALL_RAD_INPUT].value, -5.0, 5.0, 0.0, 30.0);
  59. }
  60. float zoom = module->params[ThingThing::ZOOM_MULT_PARAM].value;
  61. if(module->inputs[ThingThing::ZOOM_MULT_INPUT].active){
  62. ballRadius += rescalefjw(module->inputs[ThingThing::ZOOM_MULT_INPUT].value, -5.0, 5.0, 1.0, 50.0);
  63. }
  64. float x[5];
  65. float y[5];
  66. float angle[5];
  67. for(int i=0; i<5; i++){
  68. angle[i] = i==0 ? 0 : (module->inputs[ThingThing::ANG_INPUT+i].value + angle[i-1]) * module->atten[i];
  69. x[i] = i==0 ? 0 : sinf(rescalefjw(angle[i], -5, 5, -2*M_PI + M_PI/2.0f, 2*M_PI + M_PI/2.0f)) * zoom;
  70. y[i] = i==0 ? 0 : cosf(rescalefjw(angle[i], -5, 5, -2*M_PI + M_PI/2.0f, 2*M_PI + M_PI/2.0f)) * zoom;
  71. }
  72. /////////////////////// LINES ///////////////////////
  73. nvgSave(vg);
  74. nvgTranslate(vg, box.size.x * 0.5, box.size.y * 0.5);
  75. for(int i=0; i<5; i++){
  76. nvgTranslate(vg, x[i], y[i]);
  77. nvgStrokeColor(vg, nvgRGB(255, 255, 255));
  78. if(i>0){
  79. nvgStrokeWidth(vg, 1);
  80. nvgBeginPath(vg);
  81. nvgMoveTo(vg, 0, 0);
  82. nvgLineTo(vg, -x[i], -y[i]);
  83. nvgStroke(vg);
  84. }
  85. }
  86. nvgRestore(vg);
  87. /////////////////////// BALLS ///////////////////////
  88. nvgSave(vg);
  89. nvgTranslate(vg, box.size.x * 0.5, box.size.y * 0.5);
  90. for(int i=0; i<5; i++){
  91. nvgTranslate(vg, x[i], y[i]);
  92. nvgStrokeColor(vg, module->balls[i].color);
  93. nvgFillColor(vg, module->balls[i].color);
  94. nvgStrokeWidth(vg, 2);
  95. nvgBeginPath(vg);
  96. nvgCircle(vg, 0, 0, ballRadius);
  97. nvgFill(vg);
  98. nvgStroke(vg);
  99. }
  100. nvgRestore(vg);
  101. }
  102. };
  103. struct ThingThingWidget : ModuleWidget {
  104. ThingThingWidget(ThingThing *module);
  105. };
  106. ThingThingWidget::ThingThingWidget(ThingThing *module) : ModuleWidget(module) {
  107. box.size = Vec(RACK_GRID_WIDTH*20, RACK_GRID_HEIGHT);
  108. SVGPanel *panel = new SVGPanel();
  109. panel->box.size = box.size;
  110. panel->setBackground(SVG::load(assetPlugin(plugin, "res/ThingThing.svg")));
  111. addChild(panel);
  112. ThingThingDisplay *display = new ThingThingDisplay();
  113. display->module = module;
  114. display->box.pos = Vec(0, 0);
  115. display->box.size = Vec(box.size.x, RACK_GRID_HEIGHT);
  116. addChild(display);
  117. addChild(Widget::create<Screw_J>(Vec(265, 365)));
  118. addChild(Widget::create<Screw_W>(Vec(280, 365)));
  119. for(int i=0; i<4; i++){
  120. addInput(Port::create<TinyPJ301MPort>(Vec(5+(20*i), 360), Port::INPUT, module, ThingThing::ANG_INPUT+i+1));
  121. }
  122. addInput(Port::create<TinyPJ301MPort>(Vec(140, 360), Port::INPUT, module, ThingThing::BALL_RAD_INPUT));
  123. addParam(ParamWidget::create<JwTinyKnob>(Vec(155, 360), module, ThingThing::BALL_RAD_PARAM, 0.0, 30.0, 10.0));
  124. addInput(Port::create<TinyPJ301MPort>(Vec(190, 360), Port::INPUT, module, ThingThing::ZOOM_MULT_INPUT));
  125. addParam(ParamWidget::create<JwTinyKnob>(Vec(205, 360), module, ThingThing::ZOOM_MULT_PARAM, 1.0, 200.0, 20.0));
  126. }
  127. } // namespace rack_plugin_JW_Modules
  128. using namespace rack_plugin_JW_Modules;
  129. RACK_PLUGIN_MODEL_INIT(JW_Modules, ThingThing) {
  130. Model *modelThingThing = Model::create<ThingThing, ThingThingWidget>("JW-Modules", "ThingThing", "Thing Thing", VISUAL_TAG);
  131. return modelThingThing;
  132. }