You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

282 lines
7.6KB

  1. #include "global_pre.hpp"
  2. #include "settings.hpp"
  3. #include "app.hpp"
  4. #include "window.hpp"
  5. #include "engine.hpp"
  6. #include "plugin.hpp"
  7. #include <jansson.h>
  8. #include "global.hpp"
  9. #include "global_ui.hpp"
  10. extern void vst2_window_size_set (int _width, int _height);
  11. extern void vst2_refresh_rate_set (float _hz);
  12. #ifdef RACK_HOST
  13. extern void vst2_oversample_set (int _factor, int _quality);
  14. #endif // RACK_HOST
  15. namespace rack {
  16. extern bool b_touchkeyboard_enable;
  17. static json_t *settingsToJson() {
  18. // root
  19. json_t *rootJ = json_object();
  20. // token
  21. json_t *tokenJ = json_string(global->plugin.gToken.c_str());
  22. json_object_set_new(rootJ, "token", tokenJ);
  23. if (!windowIsMaximized()) {
  24. // windowSize
  25. Vec windowSize = windowGetWindowSize();
  26. json_t *windowSizeJ = json_pack("[f, f]", windowSize.x, windowSize.y);
  27. json_object_set_new(rootJ, "windowSize", windowSizeJ);
  28. // windowPos
  29. Vec windowPos = windowGetWindowPos();
  30. json_t *windowPosJ = json_pack("[f, f]", windowPos.x, windowPos.y);
  31. json_object_set_new(rootJ, "windowPos", windowPosJ);
  32. }
  33. // opacity
  34. float opacity = global_ui->app.gToolbar->wireOpacitySlider->value;
  35. json_t *opacityJ = json_real(opacity);
  36. json_object_set_new(rootJ, "wireOpacity", opacityJ);
  37. // tension
  38. float tension = global_ui->app.gToolbar->wireTensionSlider->value;
  39. json_t *tensionJ = json_real(tension);
  40. json_object_set_new(rootJ, "wireTension", tensionJ);
  41. // zoom
  42. float zoom = global_ui->app.gRackScene->zoomWidget->zoom;
  43. json_t *zoomJ = json_real(zoom);
  44. json_object_set_new(rootJ, "zoom", zoomJ);
  45. // allowCursorLock
  46. json_t *allowCursorLockJ = json_boolean(global_ui->window.gAllowCursorLock);
  47. json_object_set_new(rootJ, "allowCursorLock", allowCursorLockJ);
  48. // sampleRate
  49. json_t *sampleRateJ = json_real(engineGetSampleRate());
  50. json_object_set_new(rootJ, "sampleRate", sampleRateJ);
  51. // lastPath
  52. json_t *lastPathJ = json_string(global_ui->app.gRackWidget->lastPath.c_str());
  53. json_object_set_new(rootJ, "lastPath", lastPathJ);
  54. // skipAutosaveOnLaunch
  55. if (global->settings.gSkipAutosaveOnLaunch) {
  56. json_object_set_new(rootJ, "skipAutosaveOnLaunch", json_true());
  57. }
  58. // moduleBrowser
  59. json_object_set_new(rootJ, "moduleBrowser", appModuleBrowserToJson());
  60. // powerMeter
  61. json_object_set_new(rootJ, "powerMeter", json_boolean(global->gPowerMeter));
  62. // checkVersion
  63. json_object_set_new(rootJ, "checkVersion", json_boolean(global_ui->app.gCheckVersion));
  64. return rootJ;
  65. }
  66. static void settingsFromJson(json_t *rootJ, bool bWindowSizeOnly) {
  67. // token
  68. json_t *tokenJ = json_object_get(rootJ, "token");
  69. if (tokenJ)
  70. global->plugin.gToken = json_string_value(tokenJ);
  71. // windowSize
  72. json_t *windowSizeJ = json_object_get(rootJ, "windowSize");
  73. if (windowSizeJ) {
  74. double width, height;
  75. json_unpack(windowSizeJ, "[F, F]", &width, &height);
  76. #ifdef USE_VST2
  77. // (note) calling windowSetWindowSize() causes the window to be not resizable initially, and when it is moved, it reverts to a default size (TBI)
  78. if(bWindowSizeOnly)
  79. {
  80. global_ui->window.windowWidth = int(width);
  81. global_ui->window.windowHeight = int(height);
  82. vst2_window_size_set((int)width, (int)height);
  83. return;
  84. }
  85. #else
  86. windowSetWindowSize(Vec(width, height));
  87. #endif // USE_VST2
  88. }
  89. // windowPos
  90. json_t *windowPosJ = json_object_get(rootJ, "windowPos");
  91. if (windowPosJ) {
  92. double x, y;
  93. json_unpack(windowPosJ, "[F, F]", &x, &y);
  94. #ifndef USE_VST2
  95. windowSetWindowPos(Vec(x, y));
  96. #endif // USE_VST2
  97. }
  98. // opacity
  99. json_t *opacityJ = json_object_get(rootJ, "wireOpacity");
  100. if (opacityJ)
  101. global_ui->app.gToolbar->wireOpacitySlider->value = json_number_value(opacityJ);
  102. // tension
  103. json_t *tensionJ = json_object_get(rootJ, "wireTension");
  104. if (tensionJ)
  105. global_ui->app.gToolbar->wireTensionSlider->value = json_number_value(tensionJ);
  106. // zoom
  107. json_t *zoomJ = json_object_get(rootJ, "zoom");
  108. if (zoomJ) {
  109. global_ui->app.gRackScene->zoomWidget->setZoom(clamp((float) json_number_value(zoomJ), 0.25f, 4.0f));
  110. global_ui->app.gToolbar->zoomSlider->setValue(json_number_value(zoomJ) * 100.0);
  111. }
  112. // refresh rate (Hz)
  113. // (note) <15: use DAW timer (effEditIdle)
  114. json_t *refreshJ = json_object_get(rootJ, "refreshRate");
  115. if (refreshJ) {
  116. vst2_refresh_rate_set(clamp((float) json_number_value(refreshJ), 0.0f, 200.0f));
  117. }
  118. // vsync
  119. if(!bWindowSizeOnly)
  120. {
  121. json_t *vsyncJ = json_object_get(rootJ, "vsync");
  122. if (vsyncJ)
  123. {
  124. lglw_glcontext_push(global_ui->window.lglw);
  125. lglw_swap_interval(global_ui->window.lglw, json_is_true(vsyncJ));
  126. lglw_glcontext_pop(global_ui->window.lglw);
  127. }
  128. }
  129. // allowCursorLock
  130. json_t *allowCursorLockJ = json_object_get(rootJ, "allowCursorLock");
  131. if (allowCursorLockJ)
  132. {
  133. global_ui->window.gAllowCursorLock = json_is_true(allowCursorLockJ);
  134. }
  135. // touchInput
  136. if(!bWindowSizeOnly)
  137. {
  138. json_t *touchJ = json_object_get(rootJ, "touchInput");
  139. if (touchJ)
  140. {
  141. if(json_is_true(touchJ))
  142. {
  143. lglw_touchinput_set(global_ui->window.lglw, LGLW_TRUE);
  144. }
  145. }
  146. }
  147. // touchKbd
  148. if(!bWindowSizeOnly)
  149. {
  150. json_t *touchJ = json_object_get(rootJ, "touchKbd");
  151. if (touchJ)
  152. {
  153. b_touchkeyboard_enable = json_is_true(touchJ);
  154. }
  155. }
  156. #ifndef USE_VST2
  157. // sampleRate
  158. json_t *sampleRateJ = json_object_get(rootJ, "sampleRate");
  159. if (sampleRateJ) {
  160. float sampleRate = json_number_value(sampleRateJ);
  161. engineSetSampleRate(sampleRate);
  162. }
  163. #endif // USE_VST2
  164. #ifdef RACK_HOST
  165. int oversampleFactor = -1;
  166. int oversampleQuality = -1;
  167. // Oversample factor
  168. {
  169. json_t *oversampleJ = json_object_get(rootJ, "oversampleFactor");
  170. if (oversampleJ) {
  171. oversampleFactor = int(json_number_value(oversampleJ));
  172. }
  173. }
  174. // Oversample quality (0..10)
  175. {
  176. json_t *oversampleJ = json_object_get(rootJ, "oversampleQuality");
  177. if (oversampleJ) {
  178. oversampleQuality = int(json_number_value(oversampleJ));
  179. }
  180. }
  181. vst2_oversample_set(oversampleFactor, oversampleQuality);
  182. #endif // RACK_HOST
  183. // lastPath
  184. json_t *lastPathJ = json_object_get(rootJ, "lastPath");
  185. if (lastPathJ)
  186. global_ui->app.gRackWidget->lastPath = json_string_value(lastPathJ);
  187. // skipAutosaveOnLaunch
  188. json_t *skipAutosaveOnLaunchJ = json_object_get(rootJ, "skipAutosaveOnLaunch");
  189. if (skipAutosaveOnLaunchJ)
  190. global->settings.gSkipAutosaveOnLaunch = json_boolean_value(skipAutosaveOnLaunchJ);
  191. // moduleBrowser
  192. json_t *moduleBrowserJ = json_object_get(rootJ, "moduleBrowser");
  193. if (moduleBrowserJ)
  194. appModuleBrowserFromJson(moduleBrowserJ);
  195. // powerMeter
  196. json_t *powerMeterJ = json_object_get(rootJ, "powerMeter");
  197. if (powerMeterJ)
  198. global->gPowerMeter = json_boolean_value(powerMeterJ);
  199. // checkVersion
  200. json_t *checkVersionJ = json_object_get(rootJ, "checkVersion");
  201. if (checkVersionJ)
  202. global_ui->app.gCheckVersion = json_boolean_value(checkVersionJ);
  203. }
  204. void settingsSave(std::string filename) {
  205. info("Saving settings %s", filename.c_str());
  206. json_t *rootJ = settingsToJson();
  207. if (rootJ) {
  208. FILE *file = fopen(filename.c_str(), "w");
  209. if (!file)
  210. return;
  211. json_dumpf(rootJ, file, JSON_INDENT(2) | JSON_REAL_PRECISION(9));
  212. json_decref(rootJ);
  213. fclose(file);
  214. }
  215. }
  216. void settingsLoad(std::string filename, bool bWindowSizeOnly) {
  217. info("Loading settings %s", filename.c_str());
  218. FILE *file = fopen(filename.c_str(), "r");
  219. if (!file)
  220. return;
  221. json_error_t error;
  222. json_t *rootJ = json_loadf(file, 0, &error);
  223. if (rootJ) {
  224. settingsFromJson(rootJ, bWindowSizeOnly);
  225. json_decref(rootJ);
  226. }
  227. else {
  228. warn("JSON parsing error at %s %d:%d %s", error.source, error.line, error.column, error.text);
  229. }
  230. fclose(file);
  231. }
  232. } // namespace rack