Browse Source

Use RELEASE=1 to build release version. VERSION is automatically set in the Makefile now.

Add detection code for legacy1 mode for patch files.
Initialize patch on launch if the last launch crashed after 15 seconds.
tags/v0.6.0
Andrew Belt 6 years ago
parent
commit
575e4df2fd
17 changed files with 110 additions and 83 deletions
  1. +6
    -3
      Makefile
  2. +13
    -2
      include/engine.hpp
  3. +3
    -0
      include/settings.hpp
  4. +3
    -2
      include/util.hpp
  5. +1
    -6
      src/app.cpp
  6. +2
    -2
      src/app/AddModuleWindow.cpp
  7. +5
    -5
      src/app/RackScene.cpp
  8. +12
    -6
      src/app/RackWidget.cpp
  9. +1
    -1
      src/app/Toolbar.cpp
  10. +6
    -6
      src/asset.cpp
  11. +5
    -12
      src/core/MidiToCV.cpp
  12. +1
    -1
      src/core/core.cpp
  13. +16
    -18
      src/core/core.hpp
  14. +1
    -4
      src/gui.cpp
  15. +12
    -7
      src/main.cpp
  16. +17
    -6
      src/settings.cpp
  17. +6
    -2
      src/util.cpp

+ 6
- 3
Makefile View File

@@ -1,7 +1,13 @@
VERSION = 0.6.0dev

FLAGS += \
-Iinclude \
-Idep/include -Idep/lib/libzip/include

ifdef RELEASE
FLAGS += -DRELEASE=$(RELEASE)
endif

SOURCES = $(wildcard src/*.cpp src/*/*.cpp) \
ext/nanovg/src/nanovg.c

@@ -87,9 +93,6 @@ include compile.mk


dist: all
ifndef VERSION
$(error VERSION must be defined when making distributables)
endif
rm -rf dist
$(MAKE) -C plugins/Fundamental dist



+ 13
- 2
include/engine.hpp View File

@@ -70,13 +70,24 @@ struct Module {
/** Called when user explicitly deletes the module, not when Rack is closed or a new patch is loaded */
virtual void onDelete() {}
/** Called when user clicks Initialize in the module context menu */
virtual void onReset() {}
virtual void onReset() {
// Call deprecated method
reset();
}
/** Called when user clicks Randomize in the module context menu */
virtual void onRandomize() {}
virtual void onRandomize() {
// Call deprecated method
randomize();
}

/** Override these to store extra internal data in the "data" property */
virtual json_t *toJson() { return NULL; }
virtual void fromJson(json_t *root) {}

/** Deprecated */
virtual void reset() {}
/** Deprecated */
virtual void randomize() {}
};

struct Wire {


+ 3
- 0
include/settings.hpp View File

@@ -10,4 +10,7 @@ void settingsSave(std::string filename);
void settingsLoad(std::string filename);


extern bool skipAutosaveOnLaunch;


} // namespace rack

+ 3
- 2
include/util.hpp View File

@@ -83,11 +83,12 @@ float randomNormal();

/** Converts a printf format string and optional arguments into a std::string */
std::string stringf(const char *format, ...);
std::string tolower(std::string s);
std::string toupper(std::string s);
std::string lowercase(std::string s);
std::string uppercase(std::string s);

/** Truncates and adds "..." to a string, not exceeding `len` characters */
std::string ellipsize(std::string s, size_t len);
bool startsWith(std::string str, std::string prefix);

std::string extractDirectory(std::string path);
std::string extractFilename(std::string path);


+ 1
- 6
src/app.cpp View File

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

std::string gApplicationName = "VCV Rack";
std::string gApplicationVersion =
#ifdef VERSION
TOSTRING(VERSION);
#else
"";
#endif
std::string gApplicationVersion = TOSTRING(VERSION);
std::string gApiHost = "https://api.vcvrack.com";
// std::string gApiHost = "http://localhost:8081";



+ 2
- 2
src/app/AddModuleWindow.cpp View File

@@ -98,8 +98,8 @@ static bool isModelMatch(Model *model, std::string search) {
str += " ";
str += gTagNames[tag];
}
str = tolower(str);
search = tolower(search);
str = lowercase(str);
search = lowercase(search);
return (str.find(search) != std::string::npos);
}



+ 5
- 5
src/app/RackScene.cpp View File

@@ -45,10 +45,10 @@ RackScene::RackScene() {
scrollWidget->box.pos.y = gToolbar->box.size.y;

// Check for new version
if (!gApplicationVersion.empty()) {
std::thread versionThread(checkVersion);
versionThread.detach();
}
#if defined(RELEASE)
std::thread versionThread(checkVersion);
versionThread.detach();
#endif
}

void RackScene::step() {
@@ -68,7 +68,7 @@ void RackScene::step() {

// Version popup message
if (!newVersion.empty()) {
std::string versionMessage = stringf("Rack %s is available.\n\nYou have Rack %s.\n\nWould you like to download the new version on the website?", newVersion.c_str(), gApplicationVersion.c_str());
std::string versionMessage = stringf("Rack v%s is available.\n\nYou have Rack v%s.\n\nWould you like to download the new version on the website?", newVersion.c_str(), gApplicationVersion.c_str());
if (osdialog_message(OSDIALOG_INFO, OSDIALOG_YES_NO, versionMessage.c_str())) {
std::thread t(openBrowser, "https://vcvrack.com/");
t.detach();


+ 12
- 6
src/app/RackWidget.cpp View File

@@ -145,10 +145,8 @@ json_t *RackWidget::toJson() {
json_t *rootJ = json_object();

// version
if (!gApplicationVersion.empty()) {
json_t *versionJ = json_string(gApplicationVersion.c_str());
json_object_set_new(rootJ, "version", versionJ);
}
json_t *versionJ = json_string(gApplicationVersion.c_str());
json_object_set_new(rootJ, "version", versionJ);

// modules
json_t *modulesJ = json_array();
@@ -210,11 +208,19 @@ void RackWidget::fromJson(json_t *rootJ) {
std::string message;

// version
std::string version;
json_t *versionJ = json_object_get(rootJ, "version");
if (versionJ) {
std::string version = json_string_value(versionJ);
version = json_string_value(versionJ);
if (!version.empty() && gApplicationVersion != version)
message += stringf("This patch was created with Rack %s. Saving it will convert it to a Rack %s patch.\n\n", version.c_str(), gApplicationVersion.empty() ? "dev" : gApplicationVersion.c_str());
message += stringf("This patch was created with Rack %s. Saving it will convert it to a Rack %s patch.\n\n", version.c_str(), gApplicationVersion.c_str());
}

// Detect old patches with ModuleWidget::params/inputs/outputs indices.
// (We now use Module::params/inputs/outputs indices.)
bool legacy1 = (startsWith(version, "0.3.") || startsWith(version, "0.4.") || startsWith(version, "0.5.") || version == "" || version == "dev");
if (legacy1) {
info("Converting patch using legacy1 loader");
}

// modules


+ 1
- 1
src/app/Toolbar.cpp View File

@@ -178,7 +178,7 @@ Toolbar::Toolbar() {
xPos += margin;
*/

#ifdef VERSION
#if defined(RELEASE)
{
Widget *pluginManager = new PluginManagerWidget();
pluginManager->box.pos = Vec(xPos, margin);


+ 6
- 6
src/asset.cpp View File

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

std::string assetGlobal(std::string filename) {
std::string dir;
#ifdef VERSION
#if defined(RELEASE)
#if ARCH_MAC
CFBundleRef bundle = CFBundleGetMainBundle();
assert(bundle);
@@ -45,16 +45,16 @@ std::string assetGlobal(std::string filename) {
// TODO For now, users should launch Rack from their terminal in the global directory
dir = ".";
#endif
#else // VERSION
#else // RELEASE
dir = ".";
#endif // VERSION
#endif // RELEASE
return dir + "/" + filename;
}


std::string assetLocal(std::string filename) {
std::string dir;
#ifdef VERSION
#if defined(RELEASE)
#if ARCH_MAC
// Get home directory
struct passwd *pw = getpwuid(getuid());
@@ -83,9 +83,9 @@ std::string assetLocal(std::string filename) {
dir += "/.Rack";
mkdir(dir.c_str(), 0755);
#endif
#else // VERSION
#else // RELEASE
dir = ".";
#endif // VERSION
#endif // RELEASE
return dir + "/" + filename;
}



+ 5
- 12
src/core/MidiToCV.cpp View File

@@ -2,7 +2,7 @@
#include <list>
#include <algorithm>
#include "core.hpp"
#include "MidiIO.hpp"
#include "midi.hpp"
#include "dsp/digital.hpp"


@@ -16,7 +16,7 @@ struct MidiValue {
bool changed = false; // Value has been changed by midi message (only if it is in sync!)
};

struct MIDIToCVInterface : MidiIO, Module {
struct MIDIToCVInterface : Module {
enum ParamIds {
RESET_PARAM,
NUM_PARAMS
@@ -49,7 +49,7 @@ struct MIDIToCVInterface : MidiIO, Module {

SchmittTrigger resetTrigger;

MIDIToCVInterface() : MidiIO(), Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {
MIDIToCVInterface() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {
pitchWheel.val = 64;
pitchWheel.tSmooth.set(0, 0);
}
@@ -253,8 +253,7 @@ MidiToCVWidget::MidiToCVWidget() {
}

addParam(createParam<LEDButton>(Vec(7 * 15, labelHeight), module, MIDIToCVInterface::RESET_PARAM, 0.0, 1.0, 0.0));
addChild(createLight<SmallLight<RedLight>>(Vec(7 * 15 + 5, labelHeight + 5), module,
MIDIToCVInterface::RESET_LIGHT));
addChild(createLight<SmallLight<RedLight>>(Vec(7 * 15 + 5, labelHeight + 5), module, MIDIToCVInterface::RESET_LIGHT));
{
Label *label = new Label();
label->box.pos = Vec(margin, yPos);
@@ -285,8 +284,7 @@ MidiToCVWidget::MidiToCVWidget() {
yPos += channelChoice->box.size.y + margin + 15;
}

std::string labels[MIDIToCVInterface::NUM_OUTPUTS] = {"1V/oct", "Gate", "Velocity", "Mod Wheel", "Pitch Wheel",
"Aftertouch"};
std::string labels[MIDIToCVInterface::NUM_OUTPUTS] = {"1V/oct", "Gate", "Velocity", "Mod Wheel", "Pitch Wheel", "Aftertouch"};

for (int i = 0; i < MIDIToCVInterface::NUM_OUTPUTS; i++) {
Label *label = new Label();
@@ -299,9 +297,4 @@ MidiToCVWidget::MidiToCVWidget() {
yPos += yGap + margin;
}
}

void MidiToCVWidget::step() {

ModuleWidget::step();
}
#endif

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

@@ -8,8 +8,8 @@ void init(rack::Plugin *p) {
#endif

p->addModel(createModel<AudioInterfaceWidget>("Core", "AudioInterface", "Audio Interface", EXTERNAL_TAG));
// p->addModel(createModel<MidiToCVWidget>("Core", "MIDIToCVInterface", "MIDI-to-CV Interface", MIDI_TAG, EXTERNAL_TAG));

// p->addModel(createModel<MidiToCVWidget>("Core", "MIDIToCVInterface", "MIDI-to-CV Interface", MIDI_TAG, EXTERNAL_TAG));
// p->addModel(createModel<MIDICCToCVWidget>("Core", "MIDICCToCVInterface", "MIDI CC-to-CV Interface", MIDI_TAG, EXTERNAL_TAG));
// p->addModel(createModel<MIDIClockToCVWidget>("Core", "MIDIClockToCVInterface", "MIDI Clock-to-CV Interface", MIDI_TAG, EXTERNAL_TAG, CLOCK_TAG));
// p->addModel(createModel<MIDITriggerToCVWidget>("Core", "MIDITriggerToCVInterface", "MIDI Trigger-to-CV Interface", MIDI_TAG, EXTERNAL_TAG));


+ 16
- 18
src/core/core.hpp View File

@@ -14,29 +14,27 @@ struct AudioInterfaceWidget : ModuleWidget {

struct MidiToCVWidget : ModuleWidget {
MidiToCVWidget();
void step() override;
};

struct MIDICCToCVWidget : ModuleWidget {
MIDICCToCVWidget();
void step() override;
};

struct MIDIClockToCVWidget : ModuleWidget {
MIDIClockToCVWidget();
void step() override;
};
// struct MIDICCToCVWidget : ModuleWidget {
// MIDICCToCVWidget();
// void step() override;
// };

struct MIDITriggerToCVWidget : ModuleWidget {
MIDITriggerToCVWidget();
void step() override;
};
// struct MIDIClockToCVWidget : ModuleWidget {
// MIDIClockToCVWidget();
// void step() override;
// };

struct QuadMidiToCVWidget : ModuleWidget {
QuadMidiToCVWidget();
void step() override;
};
// struct MIDITriggerToCVWidget : ModuleWidget {
// MIDITriggerToCVWidget();
// void step() override;
// };

// struct QuadMidiToCVWidget : ModuleWidget {
// QuadMidiToCVWidget();
// void step() override;
// };

struct BridgeWidget : ModuleWidget {
BridgeWidget();


+ 1
- 4
src/gui.cpp View File

@@ -432,10 +432,7 @@ void guiRun() {
mouseButtonStickyPop();

// Set window title
std::string windowTitle = gApplicationName;
if (!gApplicationVersion.empty()) {
windowTitle += " v" + gApplicationVersion;
}
std::string windowTitle = gApplicationName + " v" + gApplicationVersion;
if (!gRackWidget->lastPath.empty()) {
windowTitle += " - ";
windowTitle += extractFilename(gRackWidget->lastPath);


+ 12
- 7
src/main.cpp View File

@@ -12,14 +12,12 @@ using namespace rack;
int main(int argc, char* argv[]) {
randomSeedTime();

#ifdef VERSION
#ifdef RELEASE
std::string logFilename = assetLocal("log.txt");
gLogFile = fopen(logFilename.c_str(), "w");
#endif

if (!gApplicationVersion.empty()) {
info("Rack v%s", gApplicationVersion.c_str());
}
info("Rack v%s", gApplicationVersion.c_str());

{
char *cwd = getcwd(NULL, 0);
@@ -35,21 +33,28 @@ int main(int argc, char* argv[]) {
engineInit();
guiInit();
sceneInit();
gRackWidget->loadPatch(assetLocal("autosave.vcv"));
settingsLoad(assetLocal("settings.json"));

// To prevent launch crashes, if Rack crashes between now and 15 seconds from now, the "skipAutosaveOnLaunch" property will remain in settings.json, so that in the next launch, the broken autosave will not be loaded.
bool oldSkipAutosaveOnLaunch = skipAutosaveOnLaunch;
skipAutosaveOnLaunch = true;
settingsSave(assetLocal("settings.json"));
skipAutosaveOnLaunch = false;
if (!oldSkipAutosaveOnLaunch)
gRackWidget->loadPatch(assetLocal("autosave.vcv"));

engineStart();
guiRun();
engineStop();

settingsSave(assetLocal("settings.json"));
gRackWidget->savePatch(assetLocal("autosave.vcv"));
settingsSave(assetLocal("settings.json"));
sceneDestroy();
guiDestroy();
engineDestroy();
pluginDestroy();

#ifdef VERSION
#ifdef RELEASE
fclose(gLogFile);
#endif



+ 17
- 6
src/settings.cpp View File

@@ -9,6 +9,9 @@
namespace rack {


bool skipAutosaveOnLaunch = false;


static json_t *settingsToJson() {
// root
json_t *rootJ = json_object();
@@ -56,6 +59,11 @@ static json_t *settingsToJson() {
json_t *lastPathJ = json_string(gRackWidget->lastPath.c_str());
json_object_set_new(rootJ, "lastPath", lastPathJ);

// skipAutosaveOnLaunch
if (skipAutosaveOnLaunch) {
json_object_set_new(rootJ, "skipAutosaveOnLaunch", json_true());
}

return rootJ;
}

@@ -114,22 +122,25 @@ static void settingsFromJson(json_t *rootJ) {
json_t *lastPathJ = json_object_get(rootJ, "lastPath");
if (lastPathJ)
gRackWidget->lastPath = json_string_value(lastPathJ);

json_t *skipAutosaveOnLaunchJ = json_object_get(rootJ, "skipAutosaveOnLaunch");
if (skipAutosaveOnLaunchJ)
skipAutosaveOnLaunch = json_boolean_value(skipAutosaveOnLaunchJ);
}


void settingsSave(std::string filename) {
info("Saving settings %s", filename.c_str());
FILE *file = fopen(filename.c_str(), "w");
if (!file)
return;

json_t *rootJ = settingsToJson();
if (rootJ) {
FILE *file = fopen(filename.c_str(), "w");
if (!file)
return;

json_dumpf(rootJ, file, JSON_INDENT(2));
json_decref(rootJ);
fclose(file);
}

fclose(file);
}

void settingsLoad(std::string filename) {


+ 6
- 2
src/util.cpp View File

@@ -99,12 +99,12 @@ std::string stringf(const char *format, ...) {
return s;
}

std::string tolower(std::string s) {
std::string lowercase(std::string s) {
std::transform(s.begin(), s.end(), s.begin(), ::tolower);
return s;
}

std::string toupper(std::string s) {
std::string uppercase(std::string s) {
std::transform(s.begin(), s.end(), s.begin(), ::toupper);
return s;
}
@@ -116,6 +116,10 @@ std::string ellipsize(std::string s, size_t len) {
return s.substr(0, len - 3) + "...";
}

bool startsWith(std::string str, std::string prefix) {
return str.substr(0, prefix.size()) == prefix;
}

std::string extractDirectory(std::string path) {
char *pathDup = strdup(path.c_str());
std::string directory = dirname(pathDup);


Loading…
Cancel
Save