@@ -12,7 +12,7 @@ struct MultiLightWidget : LightWidget { | |||||
std::vector<NVGcolor> baseColors; | std::vector<NVGcolor> baseColors; | ||||
void addBaseColor(NVGcolor baseColor); | void addBaseColor(NVGcolor baseColor); | ||||
/** Sets the color to a linear combination of the baseColors with the given weights */ | /** Sets the color to a linear combination of the baseColors with the given weights */ | ||||
void setValues(const std::vector<float> &values); | |||||
void setBrightnesses(const std::vector<float> &brightnesses); | |||||
}; | }; | ||||
@@ -9,7 +9,7 @@ namespace rack { | |||||
static const char APP_NAME[] = "VCV Rack"; | static const char APP_NAME[] = "VCV Rack"; | ||||
static const char APP_VERSION[] = TOSTRING(VERSION); | static const char APP_VERSION[] = TOSTRING(VERSION); | ||||
static const char API_HOST[] = "https://api.vcvrack.com"; | |||||
static const char APP_API_URL[] = "https://api.vcvrack.com"; | |||||
static const float APP_SVG_DPI = 75.0; | static const float APP_SVG_DPI = 75.0; | ||||
static const float MM_PER_IN = 25.4; | static const float MM_PER_IN = 25.4; | ||||
@@ -20,7 +20,7 @@ static const NVGcolor MAGENTA = nvgRGB(0xff, 0x00, 0xff); | |||||
static const NVGcolor YELLOW = nvgRGB(0xff, 0xff, 0x00); | static const NVGcolor YELLOW = nvgRGB(0xff, 0xff, 0x00); | ||||
NVGcolor clip(NVGcolor a); | |||||
NVGcolor clamp(NVGcolor a); | |||||
NVGcolor minus(NVGcolor a, NVGcolor b); | NVGcolor minus(NVGcolor a, NVGcolor b); | ||||
NVGcolor plus(NVGcolor a, NVGcolor b); | NVGcolor plus(NVGcolor a, NVGcolor b); | ||||
NVGcolor mult(NVGcolor a, NVGcolor b); | NVGcolor mult(NVGcolor a, NVGcolor b); | ||||
@@ -28,7 +28,7 @@ struct Light { | |||||
// Fade out light with lambda = framerate | // Fade out light with lambda = framerate | ||||
// Use 44.1k here to avoid the call to Engine::getSampleRate(). | // Use 44.1k here to avoid the call to Engine::getSampleRate(). | ||||
// This is close enough to look okay up to 96k | // This is close enough to look okay up to 96k | ||||
value += (v - value) * frames * 60.f / 44100.f; | |||||
value += (v - value) * frames * 120.f / 44100.f; | |||||
} | } | ||||
else { | else { | ||||
// Immediately illuminate light | // Immediately illuminate light | ||||
@@ -225,7 +225,7 @@ void CableWidget::draw(NVGcontext *vg) { | |||||
Output *output = &cable->outputModule->outputs[cable->outputId]; | Output *output = &cable->outputModule->outputs[cable->outputId]; | ||||
if (output->channels > 1) { | if (output->channels > 1) { | ||||
// Increase thickness if output port is polyphonic | // Increase thickness if output port is polyphonic | ||||
thickness = 7; | |||||
thickness = 8; | |||||
} | } | ||||
// else if (output->channels == 0) { | // else if (output->channels == 0) { | ||||
// // Draw translucent cable if not active (i.e. 0 channels) | // // Draw translucent cable if not active (i.e. 0 channels) | ||||
@@ -9,7 +9,7 @@ void ModuleLightWidget::step() { | |||||
return; | return; | ||||
assert(module->lights.size() >= firstLightId + baseColors.size()); | assert(module->lights.size() >= firstLightId + baseColors.size()); | ||||
std::vector<float> values(baseColors.size()); | |||||
std::vector<float> brightnesses(baseColors.size()); | |||||
for (size_t i = 0; i < baseColors.size(); i++) { | for (size_t i = 0; i < baseColors.size(); i++) { | ||||
float brightness = module->lights[firstLightId + i].getBrightness(); | float brightness = module->lights[firstLightId + i].getBrightness(); | ||||
@@ -18,9 +18,9 @@ void ModuleLightWidget::step() { | |||||
// Because LEDs are nonlinear, this seems to look more natural. | // Because LEDs are nonlinear, this seems to look more natural. | ||||
brightness = std::sqrt(brightness); | brightness = std::sqrt(brightness); | ||||
brightness = math::clamp(brightness, 0.f, 1.f); | brightness = math::clamp(brightness, 0.f, 1.f); | ||||
values[i] = brightness; | |||||
brightnesses[i] = brightness; | |||||
} | } | ||||
setValues(values); | |||||
setBrightnesses(brightnesses); | |||||
} | } | ||||
@@ -9,15 +9,15 @@ void MultiLightWidget::addBaseColor(NVGcolor baseColor) { | |||||
baseColors.push_back(baseColor); | baseColors.push_back(baseColor); | ||||
} | } | ||||
void MultiLightWidget::setValues(const std::vector<float> &values) { | |||||
assert(values.size() == baseColors.size()); | |||||
void MultiLightWidget::setBrightnesses(const std::vector<float> &brightnesses) { | |||||
assert(brightnesses.size() == baseColors.size()); | |||||
color = nvgRGBAf(0, 0, 0, 0); | color = nvgRGBAf(0, 0, 0, 0); | ||||
for (size_t i = 0; i < baseColors.size(); i++) { | for (size_t i = 0; i < baseColors.size(); i++) { | ||||
NVGcolor c = baseColors[i]; | NVGcolor c = baseColors[i]; | ||||
c.a *= math::clamp(values[i], 0.f, 1.f); | |||||
c.a *= math::clamp(brightnesses[i], 0.f, 1.f); | |||||
color = color::screen(color, c); | color = color::screen(color, c); | ||||
} | } | ||||
color = color::clip(color); | |||||
color = color::clamp(color); | |||||
} | } | ||||
@@ -48,7 +48,7 @@ void PortWidget::step() { | |||||
values[1] = module->inputs[portId].plugLights[1].getBrightness(); | values[1] = module->inputs[portId].plugLights[1].getBrightness(); | ||||
values[2] = module->inputs[portId].plugLights[2].getBrightness(); | values[2] = module->inputs[portId].plugLights[2].getBrightness(); | ||||
} | } | ||||
plugLight->setValues(values); | |||||
plugLight->setBrightnesses(values); | |||||
} | } | ||||
void PortWidget::draw(NVGcontext *vg) { | void PortWidget::draw(NVGcontext *vg) { | ||||
@@ -164,7 +164,7 @@ void Scene::onPathDrop(const event::PathDrop &e) { | |||||
} | } | ||||
void Scene::runCheckVersion() { | void Scene::runCheckVersion() { | ||||
std::string versionUrl = API_HOST; | |||||
std::string versionUrl = APP_API_URL; | |||||
versionUrl += "/version"; | versionUrl += "/version"; | ||||
json_t *versionResJ = network::requestJson(network::METHOD_GET, versionUrl, NULL); | json_t *versionResJ = network::requestJson(network::METHOD_GET, versionUrl, NULL); | ||||
@@ -6,7 +6,7 @@ namespace rack { | |||||
namespace color { | namespace color { | ||||
NVGcolor clip(NVGcolor a) { | |||||
NVGcolor clamp(NVGcolor a) { | |||||
for (int i = 0; i < 4; i++) | for (int i = 0; i < 4; i++) | ||||
a.rgba[i] = math::clamp(a.rgba[i], 0.f, 1.f); | a.rgba[i] = math::clamp(a.rgba[i], 0.f, 1.f); | ||||
return a; | return a; | ||||
@@ -48,7 +48,7 @@ NVGcolor screen(NVGcolor a, NVGcolor b) { | |||||
NVGcolor c = minus(plus(a, b), mult(a, b)); | NVGcolor c = minus(plus(a, b), mult(a, b)); | ||||
c.a = a.a + b.a - a.a * b.a; | c.a = a.a + b.a - a.a * b.a; | ||||
c = mult(c, 1.f / c.a); | c = mult(c, 1.f / c.a); | ||||
c = clip(c); | |||||
c = clamp(c); | |||||
return c; | return c; | ||||
} | } | ||||
@@ -62,6 +62,7 @@ NVGcolor fromHexString(std::string s) { | |||||
uint8_t g = 0; | uint8_t g = 0; | ||||
uint8_t b = 0; | uint8_t b = 0; | ||||
uint8_t a = 255; | uint8_t a = 255; | ||||
// If only three hex pairs are given, this will leave `a` unset. | |||||
sscanf(s.c_str(), "#%2hhx%2hhx%2hhx%2hhx", &r, &g, &b, &a); | sscanf(s.c_str(), "#%2hhx%2hhx%2hhx%2hhx", &r, &g, &b, &a); | ||||
return nvgRGBA(r, g, b, a); | return nvgRGBA(r, g, b, a); | ||||
} | } | ||||
@@ -179,7 +179,7 @@ static bool syncPlugin(std::string slug, json_t *manifestJ, bool dryRun) { | |||||
#endif | #endif | ||||
std::string downloadUrl; | std::string downloadUrl; | ||||
downloadUrl = API_HOST; | |||||
downloadUrl = APP_API_URL; | |||||
downloadUrl += "/download"; | downloadUrl += "/download"; | ||||
if (dryRun) { | if (dryRun) { | ||||
downloadUrl += "/available"; | downloadUrl += "/available"; | ||||
@@ -378,7 +378,7 @@ void logIn(std::string email, std::string password) { | |||||
json_t *reqJ = json_object(); | json_t *reqJ = json_object(); | ||||
json_object_set(reqJ, "email", json_string(email.c_str())); | json_object_set(reqJ, "email", json_string(email.c_str())); | ||||
json_object_set(reqJ, "password", json_string(password.c_str())); | json_object_set(reqJ, "password", json_string(password.c_str())); | ||||
std::string tokenUrl = API_HOST; | |||||
std::string tokenUrl = APP_API_URL; | |||||
tokenUrl += "/token"; | tokenUrl += "/token"; | ||||
json_t *resJ = network::requestJson(network::METHOD_POST, tokenUrl, reqJ); | json_t *resJ = network::requestJson(network::METHOD_POST, tokenUrl, reqJ); | ||||
json_decref(reqJ); | json_decref(reqJ); | ||||
@@ -423,7 +423,7 @@ bool sync(bool dryRun) { | |||||
// Get user's plugins list | // Get user's plugins list | ||||
json_t *pluginsReqJ = json_object(); | json_t *pluginsReqJ = json_object(); | ||||
json_object_set(pluginsReqJ, "token", json_string(token.c_str())); | json_object_set(pluginsReqJ, "token", json_string(token.c_str())); | ||||
std::string pluginsUrl = API_HOST; | |||||
std::string pluginsUrl = APP_API_URL; | |||||
pluginsUrl += "/plugins"; | pluginsUrl += "/plugins"; | ||||
json_t *pluginsResJ = network::requestJson(network::METHOD_GET, pluginsUrl, pluginsReqJ); | json_t *pluginsResJ = network::requestJson(network::METHOD_GET, pluginsUrl, pluginsReqJ); | ||||
json_decref(pluginsReqJ); | json_decref(pluginsReqJ); | ||||
@@ -442,7 +442,7 @@ bool sync(bool dryRun) { | |||||
} | } | ||||
// Get community manifests | // Get community manifests | ||||
std::string manifestsUrl = API_HOST; | |||||
std::string manifestsUrl = APP_API_URL; | |||||
manifestsUrl += "/community/manifests"; | manifestsUrl += "/community/manifests"; | ||||
json_t *manifestsResJ = network::requestJson(network::METHOD_GET, manifestsUrl, NULL); | json_t *manifestsResJ = network::requestJson(network::METHOD_GET, manifestsUrl, NULL); | ||||
if (!manifestsResJ) { | if (!manifestsResJ) { | ||||