Browse Source

Added Davies knobs, added SVG renderer

tags/v0.3.0
Andrew Belt 7 years ago
parent
commit
58974d5530
21 changed files with 296 additions and 189 deletions
  1. +3
    -34
      Makefile
  2. +1
    -0
      Rack.rc
  3. +97
    -0
      include/components.hpp
  4. +2
    -0
      include/gui.hpp
  5. +1
    -8
      include/rack.hpp
  6. +10
    -44
      include/scene.hpp
  7. +1
    -1
      include/widgets.hpp
  8. +9
    -17
      src/core/AudioInterface.cpp
  9. +1
    -3
      src/core/MidiInterface.cpp
  10. +0
    -3
      src/core/core.cpp
  11. +2
    -2
      src/engine.cpp
  12. +82
    -3
      src/gui.cpp
  13. +1
    -1
      src/main.cpp
  14. +1
    -1
      src/scene.cpp
  15. +0
    -4
      src/widgets/Knob.cpp
  16. +7
    -3
      src/widgets/Panel.cpp
  17. +19
    -0
      src/widgets/RackScene.cpp
  18. +7
    -12
      src/widgets/RackWidget.cpp
  19. +5
    -5
      src/widgets/Screw.cpp
  20. +10
    -0
      src/widgets/SpriteKnob.cpp
  21. +37
    -48
      src/widgets/WireWidget.cpp

+ 3
- 34
Makefile View File

@@ -30,9 +30,6 @@ CFLAGS += -DNOC_FILE_DIALOG_OSX
CXXFLAGS += -DAPPLE -stdlib=libc++ -I$(HOME)/local/include CXXFLAGS += -DAPPLE -stdlib=libc++ -I$(HOME)/local/include
LDFLAGS += -stdlib=libc++ -L$(HOME)/local/lib -lpthread -lglew -lglfw3 -framework Cocoa -framework OpenGL -framework IOKit -framework CoreVideo -ldl -ljansson -lportaudio -lportmidi -lsamplerate LDFLAGS += -stdlib=libc++ -L$(HOME)/local/lib -lpthread -lglew -lglfw3 -framework Cocoa -framework OpenGL -framework IOKit -framework CoreVideo -ldl -ljansson -lportaudio -lportmidi -lsamplerate
TARGET = Rack TARGET = Rack

Rack.app: $(TARGET)
./bundle.sh
endif endif


# Windows # Windows
@@ -52,41 +49,13 @@ LDFLAGS += \
-L$(HOME)/pkg/portaudio-r1891-build/lib/x64/ReleaseMinDependency -lportaudio_x64 \ -L$(HOME)/pkg/portaudio-r1891-build/lib/x64/ReleaseMinDependency -lportaudio_x64 \
-Wl,--export-all-symbols,--out-implib,libRack.a -mwindows -Wl,--export-all-symbols,--out-implib,libRack.a -mwindows
TARGET = Rack.exe TARGET = Rack.exe
# OBJECTS = Rack.res

%.res: %.rc
windres $^ -O coff -o $@
endif

OBJECTS = Rack.res


all: $(TARGET) all: $(TARGET)


dist: $(TARGET)
# Rack
mkdir -p dist/Rack
cp LICENSE* dist/Rack/
ifeq ($(ARCH), linux)
cp Rack dist/Rack/
endif
ifeq ($(ARCH), apple)
./bundle.sh
cp -R Rack.app dist/Rack/
endif
ifeq ($(ARCH), windows)
cp Rack.exe dist/Rack/
./copy_dlls.sh
cp *.dll dist/Rack/
%.res: %.rc
windres $^ -O coff -o $@
endif endif
cp -R res dist/Rack/
mkdir -p dist/Rack/plugins
# Fundamental
$(MAKE) -C plugins/Fundamental dist
cp -R plugins/Fundamental/dist/Fundamental dist/Rack/plugins/
# zip
cd dist && zip -5 -r Rack.zip Rack

clean:
rm -rfv build $(TARGET) dist




include Makefile.inc include Makefile.inc

+ 1
- 0
Rack.rc View File

@@ -0,0 +1 @@
GLFW_ICON ICON res/icon.ico

+ 97
- 0
include/components.hpp View File

@@ -0,0 +1,97 @@
#pragma once
#include "scene.hpp"


namespace rack {

////////////////////
// knobs
////////////////////

struct KnobDavies1900h : SpriteKnob {
KnobDavies1900h() {
box.size = Vec(36, 36);
spriteOffset = Vec(-8, -8);
spriteSize = Vec(64, 64);
minIndex = 44;
maxIndex = -46;
spriteCount = 120;
}
};

struct KnobDavies1900hWhite : KnobDavies1900h {
KnobDavies1900hWhite() {
spriteImage = Image::load("res/ComponentLibrary/Davies1900hWhite.png");
}
};

struct KnobDavies1900hBlack : KnobDavies1900h {
KnobDavies1900hBlack() {
spriteImage = Image::load("res/ComponentLibrary/Davies1900hBlack.png");
}
};

struct KnobDavies1900hRed : KnobDavies1900h {
KnobDavies1900hRed() {
spriteImage = Image::load("res/ComponentLibrary/Davies1900hRed.png");
}
};

////////////////////
// ports
////////////////////

struct PJ301M : SpriteWidget {
PJ301M() {
box.size = Vec(24, 24);
spriteOffset = Vec(-10, -10);
spriteSize = Vec(48, 48);
spriteImage = Image::load("res/ComponentLibrary/PJ301M.png");
}
};
struct InputPortPJ301M : InputPort, PJ301M {};
struct OutputPortPJ301M: OutputPort, PJ301M {};

struct PJ3410 : SpriteWidget {
PJ3410() {
box.size = Vec(31, 31);
spriteOffset = Vec(-9, -9);
spriteSize = Vec(54, 54);
spriteImage = Image::load("res/ComponentLibrary/PJ3410.png");
}
};
struct InputPortPJ3410 : InputPort, PJ3410 {};
struct OutputPortPJ3410: OutputPort, PJ3410 {};

struct CL1362 : SpriteWidget {
CL1362() {
box.size = Vec(33, 29);
spriteOffset = Vec(-10, -10);
spriteSize = Vec(57, 54);
spriteImage = Image::load("res/ComponentLibrary/CL1362.png");
}
};
struct InputPortCL1362 : InputPort, CL1362 {};
struct OutputPortCL1362 : OutputPort, CL1362 {};


////////////////////
// panels
////////////////////

struct LightPanel : Panel {
LightPanel() {
backgroundColor = nvgRGB(0xe8, 0xe8, 0xe8);
borderColor = nvgRGB(0xac, 0xac, 0xac);
}
};

struct DarkPanel : Panel {
DarkPanel() {
backgroundColor = nvgRGB(0x0f, 0x0f, 0x0f);
borderColor = nvgRGB(0x5e, 0x5e, 0x5e);
}
};


} // namespace rack

+ 2
- 0
include/gui.hpp View File

@@ -13,5 +13,7 @@ void guiCursorUnlock();
const char *guiSaveDialog(const char *filters, const char *filename); const char *guiSaveDialog(const char *filters, const char *filename);
const char *guiOpenDialog(const char *filters, const char *filename); const char *guiOpenDialog(const char *filters, const char *filename);


// TODO This should probably go in another file, like resources.hpp?
void drawSVG(NVGcontext *vg, NSVGimage *svg);


} // namespace rack } // namespace rack

+ 1
- 8
include/rack.hpp View File

@@ -2,6 +2,7 @@
#include "plugin.hpp" #include "plugin.hpp"
#include "engine.hpp" #include "engine.hpp"
#include "gui.hpp" #include "gui.hpp"
#include "components.hpp"




namespace rack { namespace rack {
@@ -11,14 +12,6 @@ namespace rack {
// helpers // helpers
//////////////////// ////////////////////


inline
Plugin *createPlugin(std::string slug, std::string name) {
Plugin *plugin = new Plugin();
plugin->slug = slug;
plugin->name = name;
return plugin;
}

template <class TModuleWidget> template <class TModuleWidget>
Model *createModel(Plugin *plugin, std::string slug, std::string name) { Model *createModel(Plugin *plugin, std::string slug, std::string name) {
struct TModel : Model { struct TModel : Model {


+ 10
- 44
include/scene.hpp View File

@@ -93,8 +93,9 @@ struct RackWidget : OpaqueWidget {
void onMouseDown(int button); void onMouseDown(int button);
}; };


struct ModulePanel : TransparentWidget {
struct Panel : TransparentWidget {
NVGcolor backgroundColor; NVGcolor backgroundColor;
NVGcolor borderColor;
std::shared_ptr<Image> backgroundImage; std::shared_ptr<Image> backgroundImage;
void draw(NVGcontext *vg); void draw(NVGcontext *vg);
}; };
@@ -109,7 +110,7 @@ struct Light : TransparentWidget, SpriteWidget {
}; };


// If you don't add these to your ModuleWidget, it will fall out of the RackWidget // If you don't add these to your ModuleWidget, it will fall out of the RackWidget
struct Screw : TransparentWidget, SpriteWidget {
struct Screw : TransparentWidget {
Screw(); Screw();
}; };


@@ -123,14 +124,17 @@ struct ParamWidget : OpaqueWidget, QuantityWidget {
void onChange(); void onChange();
}; };


struct Knob : ParamWidget, SpriteWidget {
int minIndex, maxIndex, spriteCount;
void step();
struct Knob : ParamWidget {
void onDragStart(); void onDragStart();
void onDragMove(Vec mouseRel); void onDragMove(Vec mouseRel);
void onDragEnd(); void onDragEnd();
}; };


struct SpriteKnob : Knob, SpriteWidget {
int minIndex, maxIndex, spriteCount;
void step();
};

struct Switch : ParamWidget, SpriteWidget { struct Switch : ParamWidget, SpriteWidget {
}; };


@@ -212,47 +216,9 @@ struct RackScene : Scene {


RackScene(); RackScene();
void step(); void step();
void draw(NVGcontext *vg);
}; };



////////////////////
// Component Library
////////////////////

struct PJ301M : SpriteWidget {
PJ301M() {
box.size = Vec(24, 24);
spriteOffset = Vec(-10, -10);
spriteSize = Vec(48, 48);
spriteImage = Image::load("res/ComponentLibrary/PJ301M.png");
}
};
struct InputPortPJ301M : InputPort, PJ301M {};
struct OutputPortPJ301M: OutputPort, PJ301M {};

struct PJ3410 : SpriteWidget {
PJ3410() {
box.size = Vec(31, 31);
spriteOffset = Vec(-9, -9);
spriteSize = Vec(54, 54);
spriteImage = Image::load("res/ComponentLibrary/PJ3410.png");
}
};
struct InputPortPJ3410 : InputPort, PJ3410 {};
struct OutputPortPJ3410: OutputPort, PJ3410 {};

struct CL1362 : SpriteWidget {
CL1362() {
box.size = Vec(33, 29);
spriteOffset = Vec(-10, -10);
spriteSize = Vec(57, 54);
spriteImage = Image::load("res/ComponentLibrary/CL1362.png");
}
};
struct InputPortCL1362 : InputPort, CL1362 {};
struct OutputPortCL1362 : OutputPort, CL1362 {};


//////////////////// ////////////////////
// globals // globals
//////////////////// ////////////////////


+ 1
- 1
include/widgets.hpp View File

@@ -35,7 +35,7 @@ struct Image {
}; };


struct SVG { struct SVG {
NSVGimage *image;
NSVGimage *handle;
SVG(const std::string &filename); SVG(const std::string &filename);
~SVG(); ~SVG();
static std::shared_ptr<SVG> load(const std::string &filename); static std::shared_ptr<SVG> load(const std::string &filename);


+ 9
- 17
src/core/AudioInterface.cpp View File

@@ -46,7 +46,7 @@ struct AudioInterface : Module {
SampleRateConverter<2> outputSrc; SampleRateConverter<2> outputSrc;


// in rack's sample rate // in rack's sample rate
DoubleRingBuffer<Frame<2>, 32> inputBuffer;
DoubleRingBuffer<Frame<2>, 16> inputBuffer;
DoubleRingBuffer<Frame<2>, (1<<15)> outputBuffer; DoubleRingBuffer<Frame<2>, (1<<15)> outputBuffer;
// in device's sample rate // in device's sample rate
DoubleRingBuffer<Frame<2>, (1<<15)> inputSrcBuffer; DoubleRingBuffer<Frame<2>, (1<<15)> inputSrcBuffer;
@@ -121,7 +121,7 @@ void AudioInterface::step() {
err = Pa_ReadStream(stream, (float*) buf, blockSize); err = Pa_ReadStream(stream, (float*) buf, blockSize);
if (err) { if (err) {
// Ignore buffer underflows // Ignore buffer underflows
if (err != paInputOverflowed) {
if (err == paInputOverflowed) {
fprintf(stderr, "Audio input buffer underflow\n"); fprintf(stderr, "Audio input buffer underflow\n");
} }
} }
@@ -143,7 +143,7 @@ void AudioInterface::step() {
inputSrcBuffer.startIncr(blockSize); inputSrcBuffer.startIncr(blockSize);
if (err) { if (err) {
// Ignore buffer underflows // Ignore buffer underflows
if (err != paOutputUnderflowed) {
if (err == paOutputUnderflowed) {
fprintf(stderr, "Audio output buffer underflow\n"); fprintf(stderr, "Audio output buffer underflow\n");
} }
} }
@@ -308,7 +308,8 @@ struct SampleRateChoice : ChoiceButton {
menu->box.pos = getAbsolutePos().plus(Vec(0, box.size.y)); menu->box.pos = getAbsolutePos().plus(Vec(0, box.size.y));


const float sampleRates[6] = {44100, 48000, 88200, 96000, 176400, 192000}; const float sampleRates[6] = {44100, 48000, 88200, 96000, 176400, 192000};
for (int i = 0; i < 6; i++) {
int sampleRatesLen = sizeof(sampleRates) / sizeof(sampleRates[0]);
for (int i = 0; i < sampleRatesLen; i++) {
SampleRateItem *item = new SampleRateItem(); SampleRateItem *item = new SampleRateItem();
item->audioInterface = audioInterface; item->audioInterface = audioInterface;
item->sampleRate = sampleRates[i]; item->sampleRate = sampleRates[i];
@@ -340,8 +341,9 @@ struct BlockSizeChoice : ChoiceButton {
Menu *menu = new Menu(); Menu *menu = new Menu();
menu->box.pos = getAbsolutePos().plus(Vec(0, box.size.y)); menu->box.pos = getAbsolutePos().plus(Vec(0, box.size.y));


const int blockSizes[6] = {128, 256, 512, 1024, 2048, 4096};
for (int i = 0; i < 6; i++) {
const int blockSizes[] = {64, 128, 256, 512, 1024, 2048, 4096};
int blockSizesLen = sizeof(blockSizes) / sizeof(blockSizes[0]);
for (int i = 0; i < blockSizesLen; i++) {
BlockSizeItem *item = new BlockSizeItem(); BlockSizeItem *item = new BlockSizeItem();
item->audioInterface = audioInterface; item->audioInterface = audioInterface;
item->blockSize = blockSizes[i]; item->blockSize = blockSizes[i];
@@ -362,24 +364,14 @@ AudioInterfaceWidget::AudioInterfaceWidget() : ModuleWidget(new AudioInterface()
box.size = Vec(15*8, 380); box.size = Vec(15*8, 380);


{ {
ModulePanel *panel = new ModulePanel();
Panel *panel = new LightPanel();
panel->box.size = box.size; panel->box.size = box.size;
panel->backgroundColor = nvgRGBf(0.90, 0.90, 0.90);
// panel->imageFilename = "";
addChild(panel); addChild(panel);
} }


float margin = 5; float margin = 5;
float yPos = margin; float yPos = margin;


{
Label *label = new Label();
label->box.pos = Vec(margin, yPos);
label->text = "Audio Interface";
addChild(label);
yPos += label->box.size.y + margin;
}

{ {
Label *label = new Label(); Label *label = new Label();
label->box.pos = Vec(margin, yPos); label->box.pos = Vec(margin, yPos);


+ 1
- 3
src/core/MidiInterface.cpp View File

@@ -225,10 +225,8 @@ MidiInterfaceWidget::MidiInterfaceWidget() : ModuleWidget(new MidiInterface()) {
box.size = Vec(15*8, 380); box.size = Vec(15*8, 380);


{ {
ModulePanel *panel = new ModulePanel();
Panel *panel = new LightPanel();
panel->box.size = box.size; panel->box.size = box.size;
panel->backgroundColor = nvgRGBf(0.90, 0.90, 0.90);
// panel->imageFilename = "";
addChild(panel); addChild(panel);
} }




+ 0
- 3
src/core/core.cpp View File

@@ -1,9 +1,6 @@
#include "core.hpp" #include "core.hpp"




using namespace rack;


struct CorePlugin : Plugin { struct CorePlugin : Plugin {
CorePlugin() { CorePlugin() {
slug = "Core"; slug = "Core";


+ 2
- 2
src/engine.cpp View File

@@ -129,9 +129,9 @@ static void engineRun() {
} }
} }
auto end = std::chrono::high_resolution_clock::now(); auto end = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::nanoseconds((long) (0.9 * 1e9 * stepSize / gSampleRate)) - (end - start);
auto duration = std::chrono::nanoseconds((long) (0.5 * 1e9 * stepSize / gSampleRate)) - (end - start);
// Avoid pegging the CPU at 100% when there are no "blocking" modules like AudioInterface, but still step audio at a reasonable rate // Avoid pegging the CPU at 100% when there are no "blocking" modules like AudioInterface, but still step audio at a reasonable rate
std::this_thread::sleep_for(duration);
// std::this_thread::sleep_for(duration);
} }
} }




+ 82
- 3
src/gui.cpp View File

@@ -314,8 +314,8 @@ std::shared_ptr<Image> Image::load(const std::string &filename) {
//////////////////// ////////////////////


SVG::SVG(const std::string &filename) { SVG::SVG(const std::string &filename) {
image = nsvgParseFromFile(filename.c_str(), "px", 96.0);
if (image) {
handle = nsvgParseFromFile(filename.c_str(), "px", 96.0);
if (handle) {
fprintf(stderr, "Loaded SVG %s\n", filename.c_str()); fprintf(stderr, "Loaded SVG %s\n", filename.c_str());
} }
else { else {
@@ -324,7 +324,7 @@ SVG::SVG(const std::string &filename) {
} }


SVG::~SVG() { SVG::~SVG() {
nsvgDelete(image);
nsvgDelete(handle);
} }


std::shared_ptr<SVG> SVG::load(const std::string &filename) { std::shared_ptr<SVG> SVG::load(const std::string &filename) {
@@ -336,4 +336,83 @@ std::shared_ptr<SVG> SVG::load(const std::string &filename) {
} }




////////////////////
// drawSVG
////////////////////

NVGcolor getNVGColor(int color) {
return nvgRGBA((color >> 0) & 0xff, (color >> 8) & 0xff, (color >> 16) & 0xff, (color >> 24) & 0xff);
// return nvgRGBA((color >> 24) & 0xff, (color >> 16) & 0xff, (color >> 8) & 0xff, (color) & 0xff);
}

void drawSVG(NVGcontext *vg, NSVGimage *svg) {
for (NSVGshape *shape = svg->shapes; shape; shape = shape->next) {
// printf(" new shape: id \"%s\", fillrule %d\n", shape->id, shape->fillRule);

if (!(shape->flags & NSVG_FLAGS_VISIBLE))
continue;

nvgSave(vg);
nvgGlobalAlpha(vg, shape->opacity);
nvgStrokeWidth(vg, shape->strokeWidth);
// strokeDashOffset, strokeDashArray, strokeDashCount not supported
// strokeLineJoin, strokeLineCap not supported

// Build path
nvgBeginPath(vg);
for (NSVGpath *path = shape->paths; path; path = path->next) {
// printf(" new path: %d points, %s\n", path->npts, path->closed ? "closed" : "notclosed");

nvgMoveTo(vg, path->pts[0], path->pts[1]);
for (int i = 1; i < path->npts; i += 3) {
float *p = &path->pts[2*i];
nvgBezierTo(vg, p[0], p[1], p[2], p[3], p[4], p[5]);
// nvgLineTo(vg, p[4], p[5]);
}

if (path->closed)
nvgClosePath(vg);


if (path->next)
nvgPathWinding(vg, NVG_HOLE);
}

// Fill shape
if (shape->fill.type) {
switch (shape->fill.type) {
case NSVG_PAINT_COLOR: {
NVGcolor color = getNVGColor(shape->fill.color);
nvgFillColor(vg, color);
// printf(" fill color (%f %f %f %f)\n", color.r, color.g, color.b, color.a);
} break;
case NSVG_PAINT_LINEAR_GRADIENT: {
NSVGgradient *g = shape->fill.gradient;
// printf(" lin grad: %f\t%f\n", g->fx, g->fy);
} break;
}
nvgFill(vg);
}

// Stroke shape
if (shape->stroke.type) {
switch (shape->stroke.type) {
case NSVG_PAINT_COLOR: {
NVGcolor color = getNVGColor(shape->stroke.color);
nvgFillColor(vg, color);
// printf(" stroke color (%f %f %f %f)\n", color.r, color.g, color.b, color.a);
} break;
case NSVG_PAINT_LINEAR_GRADIENT: {
NSVGgradient *g = shape->stroke.gradient;
// printf(" lin grad: %f\t%f\n", g->fx, g->fy);
} break;
}
nvgStroke(vg);
}

nvgRestore(vg);
}
}


} // namespace rack } // namespace rack

+ 1
- 1
src/main.cpp View File

@@ -20,7 +20,7 @@ int main() {
assert(success); assert(success);
CFRelease(bundleURL); CFRelease(bundleURL);


chdir(dirname(path));
// chdir(dirname(path));
} }
#endif #endif




+ 1
- 1
src/scene.cpp View File

@@ -4,7 +4,7 @@
namespace rack { namespace rack {


std::string gApplicationName = "VCV Rack"; std::string gApplicationName = "VCV Rack";
std::string gApplicationVersion = "v0.1.0 alpha";
std::string gApplicationVersion = "v0.2.0 alpha";


RackWidget *gRackWidget = NULL; RackWidget *gRackWidget = NULL;




+ 0
- 4
src/widgets/Knob.cpp View File

@@ -7,10 +7,6 @@ namespace rack {
#define KNOB_SENSITIVITY 0.001 #define KNOB_SENSITIVITY 0.001




void Knob::step() {
index = eucmod((int) roundf(mapf(value, minValue, maxValue, minIndex, maxIndex)), spriteCount);
}

void Knob::onDragStart() { void Knob::onDragStart() {
guiCursorLock(); guiCursorLock();
} }


src/widgets/ModulePanel.cpp → src/widgets/Panel.cpp View File

@@ -3,10 +3,9 @@


namespace rack { namespace rack {


void ModulePanel::draw(NVGcontext *vg) {
void Panel::draw(NVGcontext *vg) {
nvgBeginPath(vg); nvgBeginPath(vg);
nvgRect(vg, box.pos.x, box.pos.y, box.size.x, box.size.y); nvgRect(vg, box.pos.x, box.pos.y, box.size.x, box.size.y);
NVGpaint paint;


// Background color // Background color
nvgFillColor(vg, backgroundColor); nvgFillColor(vg, backgroundColor);
@@ -16,10 +15,15 @@ void ModulePanel::draw(NVGcontext *vg) {
if (backgroundImage) { if (backgroundImage) {
int width, height; int width, height;
nvgImageSize(vg, backgroundImage->handle, &width, &height); nvgImageSize(vg, backgroundImage->handle, &width, &height);
paint = nvgImagePattern(vg, box.pos.x, box.pos.y, width, height, 0.0, backgroundImage->handle, 1.0);
NVGpaint paint = nvgImagePattern(vg, box.pos.x, box.pos.y, width, height, 0.0, backgroundImage->handle, 1.0);
nvgFillPaint(vg, paint); nvgFillPaint(vg, paint);
nvgFill(vg); nvgFill(vg);
} }

// Border color
nvgStrokeColor(vg, borderColor);
nvgStrokeWidth(vg, 0.5);
nvgStroke(vg);
} }


} // namespace rack } // namespace rack

+ 19
- 0
src/widgets/RackScene.cpp View File

@@ -1,4 +1,5 @@
#include "scene.hpp" #include "scene.hpp"
#include "gui.hpp"




namespace rack { namespace rack {
@@ -24,5 +25,23 @@ void RackScene::step() {
Scene::step(); Scene::step();
} }


void RackScene::draw(NVGcontext *vg) {
Scene::draw(vg);

// // Draw custom stuff here
// static std::shared_ptr<SVG> svg;
// if (!svg)
// svg = SVG::load("res/ComponentLibrary/CL1362.svg");

// for (float y = 0.0; y < 1000.0; y += 200.0)
// for (float x = 0.0; x < 1000.0; x += 200.0) {
// nvgSave(vg);
// nvgTranslate(vg, x, y);
// drawSVG(vg, svg->handle);
// nvgRestore(vg);
// }
}




} // namespace rack } // namespace rack

+ 7
- 12
src/widgets/RackWidget.cpp View File

@@ -288,23 +288,18 @@ void RackWidget::step() {
} }


void RackWidget::draw(NVGcontext *vg) { void RackWidget::draw(NVGcontext *vg) {
// Draw background
nvgBeginPath(vg); nvgBeginPath(vg);
nvgRect(vg, box.pos.x, box.pos.y, box.size.x, box.size.y); nvgRect(vg, box.pos.x, box.pos.y, box.size.x, box.size.y);
NVGpaint paint;
{
// int imageId = loadImage("res/background.png");
// int imageWidth, imageHeight;
// nvgImageSize(vg, imageId, &imageWidth, &imageHeight);
// paint = nvgImagePattern(vg, box.pos.x, box.pos.y, imageWidth, imageHeight, 0.0, imageId, 1.0);
// nvgFillPaint(vg, paint);
nvgFillColor(vg, nvgRGBf(0.25, 0.25, 0.25));
nvgFill(vg);
}

// Background color
nvgFillColor(vg, nvgRGBf(0.2, 0.2, 0.2));
nvgFill(vg);

// Rails image
{ {
int imageWidth, imageHeight; int imageWidth, imageHeight;
nvgImageSize(vg, railsImage->handle, &imageWidth, &imageHeight); nvgImageSize(vg, railsImage->handle, &imageWidth, &imageHeight);
paint = nvgImagePattern(vg, box.pos.x, box.pos.y, imageWidth, imageHeight, 0.0, railsImage->handle, 1.0);
NVGpaint paint = nvgImagePattern(vg, box.pos.x, box.pos.y, imageWidth, imageHeight, 0.0, railsImage->handle, 1.0);
nvgFillPaint(vg, paint); nvgFillPaint(vg, paint);
nvgFill(vg); nvgFill(vg);
} }


+ 5
- 5
src/widgets/Screw.cpp View File

@@ -4,12 +4,12 @@
namespace rack { namespace rack {


Screw::Screw() { Screw::Screw() {
box.size = Vec(15, 15);
spriteOffset = Vec(-7, -7);
spriteSize = Vec(29, 29);
spriteImage = Image::load("res/screw.png");
// box.size = Vec(15, 15);
// spriteOffset = Vec(-7, -7);
// spriteSize = Vec(29, 29);
// spriteImage = Image::load("res/screw.png");


index = randomu32() % 5;
// index = randomu32() % 5;
} }






+ 10
- 0
src/widgets/SpriteKnob.cpp View File

@@ -0,0 +1,10 @@
#include "scene.hpp"


namespace rack {

void SpriteKnob::step() {
index = eucmod((int) roundf(mapf(value, minValue, maxValue, minIndex, maxIndex)), spriteCount);
}

} // namespace rack

+ 37
- 48
src/widgets/WireWidget.cpp View File

@@ -4,10 +4,28 @@


namespace rack { namespace rack {


void drawWire(NVGcontext *vg, Vec pos1, Vec pos2, float tension, NVGcolor color, float opacity) {
NVGcolor colorShadow = nvgRGBAf(0, 0, 0, 0.08);
static void drawPlug(NVGcontext *vg, Vec pos, NVGcolor color) {
NVGcolor colorOutline = nvgLerpRGBA(color, nvgRGBf(0.0, 0.0, 0.0), 0.5); NVGcolor colorOutline = nvgLerpRGBA(color, nvgRGBf(0.0, 0.0, 0.0), 0.5);


nvgBeginPath(vg);
nvgCircle(vg, pos.x, pos.y, 10.5);
nvgFillColor(vg, colorOutline);
nvgFill(vg);

nvgBeginPath(vg);
nvgCircle(vg, pos.x, pos.y, 9.5);
nvgFillColor(vg, color);
nvgFill(vg);

nvgBeginPath(vg);
nvgCircle(vg, pos.x, pos.y, 5.5);
nvgFillColor(vg, nvgRGBf(0.0, 0.0, 0.0));
nvgFill(vg);
}

static void drawWire(NVGcontext *vg, Vec pos1, Vec pos2, NVGcolor color, float tension, float opacity) {
NVGcolor colorShadow = nvgRGBAf(0, 0, 0, 0.08);
NVGcolor colorOutline = nvgLerpRGBA(color, nvgRGBf(0.0, 0.0, 0.0), 0.5);


// Wire // Wire
if (opacity > 0.0) { if (opacity > 0.0) {
@@ -35,68 +53,36 @@ void drawWire(NVGcontext *vg, Vec pos1, Vec pos2, float tension, NVGcolor color,
nvgMoveTo(vg, pos1.x, pos1.y); nvgMoveTo(vg, pos1.x, pos1.y);
nvgQuadTo(vg, pos3.x, pos3.y, pos2.x, pos2.y); nvgQuadTo(vg, pos3.x, pos3.y, pos2.x, pos2.y);
nvgStrokeColor(vg, colorOutline); nvgStrokeColor(vg, colorOutline);
nvgStrokeWidth(vg, 6);
nvgStrokeWidth(vg, 5);
nvgStroke(vg); nvgStroke(vg);


// Wire solid // Wire solid
nvgStrokeColor(vg, color); nvgStrokeColor(vg, color);
nvgStrokeWidth(vg, 4);
nvgStrokeWidth(vg, 3);
nvgStroke(vg); nvgStroke(vg);


nvgRestore(vg); nvgRestore(vg);
} }

// First plug
nvgBeginPath(vg);
nvgCircle(vg, pos1.x, pos1.y, 21/2.0);
nvgFillColor(vg, colorOutline);
nvgFill(vg);

nvgBeginPath(vg);
nvgCircle(vg, pos1.x, pos1.y, 19/2.0);
nvgFillColor(vg, color);
nvgFill(vg);

nvgBeginPath(vg);
nvgCircle(vg, pos1.x, pos1.y, 11/2.0);
nvgFillColor(vg, nvgRGBf(0.0, 0.0, 0.0));
nvgFill(vg);

// Second plug
nvgBeginPath(vg);
nvgCircle(vg, pos2.x, pos2.y, 21/2.0);
nvgFillColor(vg, colorOutline);
nvgFill(vg);

nvgBeginPath(vg);
nvgCircle(vg, pos2.x, pos2.y, 19/2.0);
nvgFillColor(vg, color);
nvgFill(vg);

nvgBeginPath(vg);
nvgCircle(vg, pos2.x, pos2.y, 11/2.0);
nvgFillColor(vg, nvgRGBf(0.0, 0.0, 0.0));
nvgFill(vg);
} }




static NVGcolor wireColors[8] = { static NVGcolor wireColors[8] = {
nvgRGB(0x50, 0x50, 0x50),
nvgRGB(0xac, 0x41, 0x42),
nvgRGB(0x90, 0xa9, 0x59),
nvgRGB(0xf4, 0xbf, 0x75),
nvgRGB(0x6a, 0x9f, 0xb5),
nvgRGB(0xaa, 0x75, 0x9f),
nvgRGB(0x75, 0xb5, 0xaa),
nvgRGB(0xf5, 0xf5, 0xf5),
nvgRGB(0xc9, 0xb7, 0x0e), // yellow
nvgRGB(0xc9, 0x18, 0x47), // red
nvgRGB(0x0c, 0x8e, 0x15), // green
nvgRGB(0x09, 0x86, 0xad), // blue
nvgRGB(0x44, 0x44, 0x44), // black
nvgRGB(0x66, 0x66, 0x66), // gray
nvgRGB(0x88, 0x88, 0x88), // light gray
nvgRGB(0xaa, 0xaa, 0xaa), // white
}; };
static int wireColorId = 1;
static int nextWireColorId = 1;






WireWidget::WireWidget() { WireWidget::WireWidget() {
wireColorId = (wireColorId + 1) % 8;
color = wireColors[wireColorId];
color = wireColors[nextWireColorId];
nextWireColorId = (nextWireColorId + 1) % 8;
} }


WireWidget::~WireWidget() { WireWidget::~WireWidget() {
@@ -152,8 +138,11 @@ void WireWidget::draw(NVGcontext *vg) {
outputPos = outputPos.minus(absolutePos); outputPos = outputPos.minus(absolutePos);
inputPos = inputPos.minus(absolutePos); inputPos = inputPos.minus(absolutePos);


drawWire(vg, outputPos, inputPos, tension, color, opacity);
drawWire(vg, outputPos, inputPos, color, tension, opacity);
drawPlug(vg, outputPos, color);
drawPlug(vg, inputPos, color);
} }





} // namespace rack } // namespace rack

Loading…
Cancel
Save