diff --git a/examples/Gravity/Gravity.ino b/examples/Gravity/Gravity.ino index 4c86bd9..78a18dc 100644 --- a/examples/Gravity/Gravity.ino +++ b/examples/Gravity/Gravity.ino @@ -43,6 +43,8 @@ enum ParamsChannelPage { PARAM_CH_PROB, PARAM_CH_DUTY, PARAM_CH_OFFSET, + PARAM_CH_CV_SRC, + PARAM_CH_CV_DEST, PARAM_CH_LAST, }; @@ -150,7 +152,7 @@ void HandleRotate(Direction dir, int val) { if (app.selected_channel == 0) { editMainParameter(val); } else { - editChannelParameter(dir, val); + editChannelParameter(val); } } app.refresh_screen = true; @@ -185,9 +187,9 @@ void editMainParameter(int val) { } } -void editChannelParameter(Direction dir, int val) { +void editChannelParameter(int val) { auto& ch = GetSelectedChannel(); - switch (static_cast(app.selected_param)) { + switch (app.selected_param) { case PARAM_CH_MOD: ch.setClockMod(ch.getClockModIndex() + val); break; @@ -200,6 +202,18 @@ void editChannelParameter(Direction dir, int val) { case PARAM_CH_OFFSET: ch.setOffset(ch.getOffset() + val); break; + case PARAM_CH_CV_SRC: { + int source = static_cast(ch.getCvSource()); + updateSelection(source, val, CV_LAST); + ch.setCvSource(static_cast(source)); + break; + } + case PARAM_CH_CV_DEST: { + int dest = static_cast(ch.getCvDestination()); + updateSelection(dest, val, CV_DEST_LAST); + ch.setCvDestination(static_cast(dest)); + break; + } } } @@ -311,7 +325,7 @@ void DisplayChannelPage() { const char* subText; switch (app.selected_param) { - case 0: { // Clock Mod + case PARAM_CH_MOD: { int mod_value = ch.getClockMod(); if (mod_value > 1) { sprintf(mainText, "/%d", mod_value); @@ -322,25 +336,63 @@ void DisplayChannelPage() { } break; } - case 1: // Probability + case PARAM_CH_PROB: sprintf(mainText, "%d%%", ch.getProbability()); subText = "Hit Chance"; break; - case 2: // Duty Cycle + case PARAM_CH_DUTY: sprintf(mainText, "%d%%", ch.getDutyCycle()); subText = "Pulse Width"; break; - case 3: // Offset + case PARAM_CH_OFFSET: sprintf(mainText, "%d%%", ch.getOffset()); subText = "Shift Hit"; break; + case PARAM_CH_CV_SRC: { + switch (ch.getCvSource()) { + case CV_NONE: + sprintf(mainText, "-"); + break; + case CV_1: + sprintf(mainText, "CV1"); + break; + case CV_2: + sprintf(mainText, "CV2"); + break; + } + subText = "CV Source"; + break; + } + case PARAM_CH_CV_DEST: { + switch (ch.getCvDestination()) { + case CV_DEST_NONE: + sprintf(mainText, "-"); + break; + case CV_DEST_MOD: + sprintf(mainText, "Mod"); + break; + case CV_DEST_PROB: + sprintf(mainText, "Prob"); + break; + case CV_DEST_DUTY: + sprintf(mainText, "Duty"); + break; + case CV_DEST_OFFSET: + sprintf(mainText, "Offs"); + break; + } + subText = "CV Dest"; + break; + } + } drawCenteredText(mainText, MAIN_TEXT_Y, LARGE_FONT); drawCenteredText(subText, SUB_TEXT_Y, TEXT_FONT); // Draw Channel Page menu items - const char* menu_items[PARAM_CH_LAST] = {"Mod", "Probability", "Duty Cycle", "Offset"}; + const char* menu_items[PARAM_CH_LAST] = { + "Mod", "Probability", "Duty", "Offset", "CV Source", "CV Dest"}; drawMenuItems(menu_items, PARAM_CH_LAST); } diff --git a/examples/Gravity/channel.h b/examples/Gravity/channel.h index 2d8d8d2..f550980 100644 --- a/examples/Gravity/channel.h +++ b/examples/Gravity/channel.h @@ -9,7 +9,7 @@ enum CvSource { CV_NONE, CV_1, CV_2, - CV_SOURCE_LAST, + CV_LAST, }; enum CvDestination { @@ -29,27 +29,26 @@ static const int clock_mod_pulses[MOD_CHOICE_SIZE] = {4, 8, 12, 16, 24, 32, 48, class Channel { public: - /** - * @brief Construct a new Channel object with default values. - */ Channel() { final_clock_mod_index = base_clock_mod_index; final_probability = base_probability; final_duty_cycle = base_duty_cycle; final_offset = base_offset; - updatePulses(); } - // --- Setters (They set the BASE value) --- + // Setters (Set the BASE value) void setClockMod(int index) { if (index >= 0 && index < MOD_CHOICE_SIZE) base_clock_mod_index = index; } void setProbability(int prob) { base_probability = constrain(prob, 0, 100); } - void setDutyCycle(int duty) { base_duty_cycle = constrain(duty, 0, 99); } - void setOffset(int off) { base_offset = constrain(off, 0, 99); } + void setDutyCycle(int duty) { base_duty_cycle = constrain(duty, 1, 99); } + void setOffset(int off) { base_offset = constrain(off, 1, 99); } + void setCvSource(CvSource source) { cv_source = source; } + void setCvDestination(CvDestination dest) { cv_destination = dest; } + + // Getters (Get the BASE value for the UI) - // --- Getters (They get the BASE value for the UI) --- int getProbability() const { return base_probability; } int getDutyCycle() const { return base_duty_cycle; } int getOffset() const { return base_offset; } @@ -57,9 +56,8 @@ class Channel { int getClockModIndex() const { return base_clock_mod_index; } uint32_t getDutyCyclePulses() const { return duty_cycle_pulses; } uint32_t getOffsetPulses() const { return offset_pulses; } - - CvSource getCvSource() const { return cv_source; } - CvDestination getCvDestination() const { return cv_destination; } + CvSource getCvSource() { return cv_source; } + CvDestination getCvDestination() { return cv_destination; } bool isCvActive() const { return cv_source != CV_NONE && cv_destination != CV_DEST_NONE; } /** @@ -68,7 +66,7 @@ class Channel { * @param output The output object (or a reference to its state) to be modified. */ void processClockTick(uint32_t tick, DigitalOutput& output) { - // --- Use pre-calculated final values --- + // Use pre-calculated final values const uint32_t mod_pulses = clock_mod_pulses[final_clock_mod_index]; const uint32_t duty_pulses = max((long)((mod_pulses * (100L - final_duty_cycle)) / 100L), 1L); const uint32_t offset_pulses = (long)((mod_pulses * (100L - final_offset)) / 100L); @@ -90,11 +88,6 @@ class Channel { } } - void setCvConfig(CvSource source, CvDestination dest) { - cv_source = source; - cv_destination = dest; - } - void updateFinalValues(int cv1_value, int cv2_value) { if (!isCvActive()) { // If CV is off, ensure final values match the base values. @@ -134,7 +127,7 @@ class Channel { * Should be called whenever mod, duty cycle, or offset changes. */ void updatePulses() { - uint32_t mod_pulses = clock_mod_pulses[final_clock_mod_index]; + const uint32_t mod_pulses = clock_mod_pulses[final_clock_mod_index]; duty_cycle_pulses = max((long)((mod_pulses * (100L - final_duty_cycle)) / 100L), 1L); offset_pulses = (long)((mod_pulses * (100L - final_offset)) / 100L); }