diff --git a/src/Scope.cpp b/src/Scope.cpp index 7b32d4a..3f85c05 100644 --- a/src/Scope.cpp +++ b/src/Scope.cpp @@ -217,8 +217,11 @@ struct ScopeDisplay : LedDisplay { } void calculateStats(Stats& stats, int wave, int channels) { - if (!module) + if (!module) { + stats.min = -5.f; + stats.max = 5.f; return; + } stats = Stats(); for (int i = 0; i < BUFFER_SIZE; i++) { @@ -234,13 +237,21 @@ struct ScopeDisplay : LedDisplay { } void drawWave(const DrawArgs& args, int wave, int channel, float offset, float gain) { - if (!module) - return; - // Copy point buffer to stack to prevent min/max values being different phase. // This is currently only 256*4*16*4 = 64 kiB. Scope::Point pointBuffer[BUFFER_SIZE]; - std::copy(std::begin(module->pointBuffer), std::end(module->pointBuffer), std::begin(pointBuffer)); + if (module) { + std::copy(std::begin(module->pointBuffer), std::end(module->pointBuffer), std::begin(pointBuffer)); + } + else { + for (size_t i = 0; i < BUFFER_SIZE; i++) { + float phase = float(i) / BUFFER_SIZE; + Scope::Point point; + point.minX[0] = point.maxX[0] = 4.f * std::sin(2 * M_PI * phase * 2.f) + 5.f; + point.minY[0] = point.maxY[0] = 4.f * std::sin(2 * M_PI * phase * 2.f) - 5.f; + pointBuffer[i] = point; + } + } nvgSave(args.vg); Rect b = box.zeroPos().shrink(Vec(0, 15)); @@ -415,26 +426,27 @@ struct ScopeDisplay : LedDisplay { // Background lines drawBackground(args); - if (!module) - return; - - float gainX = std::pow(2.f, std::round(module->params[Scope::X_SCALE_PARAM].getValue())) / 10.f; - float gainY = std::pow(2.f, std::round(module->params[Scope::Y_SCALE_PARAM].getValue())) / 10.f; - float offsetX = module->params[Scope::X_POS_PARAM].getValue(); - float offsetY = module->params[Scope::Y_POS_PARAM].getValue(); + float gainX = module ? module->params[Scope::X_SCALE_PARAM].getValue() : 0.f; + gainX = std::pow(2.f, std::round(gainX)) / 10.f; + float gainY = module ? module->params[Scope::Y_SCALE_PARAM].getValue() : 0.f; + gainY = std::pow(2.f, std::round(gainY)) / 10.f; + float offsetX = module ? module->params[Scope::X_POS_PARAM].getValue() : 0.f; + float offsetY = module ? module->params[Scope::Y_POS_PARAM].getValue() : 0.f; // Get input colors PortWidget* inputX = moduleWidget->getInput(Scope::X_INPUT); PortWidget* inputY = moduleWidget->getInput(Scope::Y_INPUT); CableWidget* inputXCable = APP->scene->rack->getTopCable(inputX); CableWidget* inputYCable = APP->scene->rack->getTopCable(inputY); - NVGcolor inputXColor = inputXCable ? inputXCable->color : color::WHITE; - NVGcolor inputYColor = inputYCable ? inputYCable->color : color::WHITE; + NVGcolor inputXColor = inputXCable ? inputXCable->color : SCHEME_YELLOW; + NVGcolor inputYColor = inputYCable ? inputYCable->color : SCHEME_YELLOW; // Draw waveforms - if (module->isLissajous()) { + int channelsY = module ? module->channelsY : 1; + int channelsX = module ? module->channelsX : 1; + if (module && module->isLissajous()) { // X x Y - int lissajousChannels = std::min(module->channelsX, module->channelsY); + int lissajousChannels = std::min(channelsX, channelsY); for (int c = 0; c < lissajousChannels; c++) { nvgStrokeColor(args.vg, SCHEME_YELLOW); drawLissajous(args, c, offsetX, gainX, offsetY, gainY); @@ -442,29 +454,30 @@ struct ScopeDisplay : LedDisplay { } else { // Y - for (int c = 0; c < module->channelsY; c++) { + for (int c = 0; c < channelsY; c++) { nvgFillColor(args.vg, inputYColor); drawWave(args, 1, c, offsetY, gainY); } // X - for (int c = 0; c < module->channelsX; c++) { + for (int c = 0; c < channelsX; c++) { nvgFillColor(args.vg, inputXColor); drawWave(args, 0, c, offsetX, gainX); } // Trigger - float trigThreshold = module->params[Scope::THRESH_PARAM].getValue(); + float trigThreshold = module ? module->params[Scope::THRESH_PARAM].getValue() : 0.f; trigThreshold = (trigThreshold + offsetX) * gainX; drawTrig(args, trigThreshold); } // Calculate and draw stats - if (++statsFrame >= 4) { - statsFrame = 0; - calculateStats(statsX, 0, module->channelsX); - calculateStats(statsY, 1, module->channelsY); + if (statsFrame == 0) { + calculateStats(statsX, 0, channelsX); + calculateStats(statsY, 1, channelsY); } + statsFrame = (statsFrame + 1) % 4; + drawStats(args, Vec(0, 0 + 1), "1", statsX); drawStats(args, Vec(0, box.size.y - 15 - 1), "2", statsY); }