@@ -58,6 +58,7 @@ T *construct(F f, V v, Args... args) { | |||||
// RNG | // RNG | ||||
//////////////////// | //////////////////// | ||||
/** Seeds the RNG with the current time */ | |||||
void randomSeedTime(); | void randomSeedTime(); | ||||
uint32_t randomu32(); | uint32_t randomu32(); | ||||
uint64_t randomu64(); | uint64_t randomu64(); | ||||
@@ -126,5 +127,18 @@ struct VIPLock { | |||||
} | } | ||||
}; | }; | ||||
//////////////////// | |||||
// logger | |||||
//////////////////// | |||||
enum LogLevel { | |||||
INFO, | |||||
WARN, | |||||
ERROR, | |||||
}; | |||||
extern FILE *gLogFile; | |||||
void log(LogLevel level, const char *format, ...); | |||||
} // namespace rack | } // namespace rack |
@@ -83,7 +83,7 @@ void RackWidget::saveAsDialog() { | |||||
void RackWidget::savePatch(std::string path) { | void RackWidget::savePatch(std::string path) { | ||||
printf("Saving patch %s\n", path.c_str()); | |||||
log(INFO, "Saving patch %s", path.c_str()); | |||||
FILE *file = fopen(path.c_str(), "w"); | FILE *file = fopen(path.c_str(), "w"); | ||||
if (!file) | if (!file) | ||||
return; | return; | ||||
@@ -98,7 +98,7 @@ void RackWidget::savePatch(std::string path) { | |||||
} | } | ||||
void RackWidget::loadPatch(std::string path) { | void RackWidget::loadPatch(std::string path) { | ||||
printf("Loading patch %s\n", path.c_str()); | |||||
log(INFO, "Loading patch %s", path.c_str()); | |||||
FILE *file = fopen(path.c_str(), "r"); | FILE *file = fopen(path.c_str(), "r"); | ||||
if (!file) { | if (!file) { | ||||
// Exit silently | // Exit silently | ||||
@@ -17,7 +17,7 @@ void audioInit() { | |||||
PaError err = Pa_Initialize(); | PaError err = Pa_Initialize(); | ||||
if (err) { | if (err) { | ||||
fprintf(stderr, "Failed to initialize PortAudio: %s\n", Pa_GetErrorText(err)); | |||||
log(WARN, "Failed to initialize PortAudio: %s", Pa_GetErrorText(err)); | |||||
return; | return; | ||||
} | } | ||||
initialized = true; | initialized = true; | ||||
@@ -244,7 +244,7 @@ void AudioInterface::openDevice(int deviceId, float sampleRate, int blockSize) { | |||||
PaError err; | PaError err; | ||||
const PaDeviceInfo *deviceInfo = Pa_GetDeviceInfo(deviceId); | const PaDeviceInfo *deviceInfo = Pa_GetDeviceInfo(deviceId); | ||||
if (!deviceInfo) { | if (!deviceInfo) { | ||||
fprintf(stderr, "Failed to query audio device\n"); | |||||
log(WARN, "Failed to query audio device"); | |||||
return; | return; | ||||
} | } | ||||
@@ -271,13 +271,13 @@ void AudioInterface::openDevice(int deviceId, float sampleRate, int blockSize) { | |||||
numOutputs == 0 ? NULL : &outputParameters, | numOutputs == 0 ? NULL : &outputParameters, | ||||
sampleRate, blockSize, paNoFlag, paCallback, this); | sampleRate, blockSize, paNoFlag, paCallback, this); | ||||
if (err) { | if (err) { | ||||
fprintf(stderr, "Failed to open audio stream: %s\n", Pa_GetErrorText(err)); | |||||
log(WARN, "Failed to open audio stream: %s", Pa_GetErrorText(err)); | |||||
return; | return; | ||||
} | } | ||||
err = Pa_StartStream(stream); | err = Pa_StartStream(stream); | ||||
if (err) { | if (err) { | ||||
fprintf(stderr, "Failed to start audio stream: %s\n", Pa_GetErrorText(err)); | |||||
log(WARN, "Failed to start audio stream: %s", Pa_GetErrorText(err)); | |||||
return; | return; | ||||
} | } | ||||
// This should go after Pa_StartStream because sometimes it will call the callback once synchronously, and that time it should return early | // This should go after Pa_StartStream because sometimes it will call the callback once synchronously, and that time it should return early | ||||
@@ -299,12 +299,12 @@ void AudioInterface::closeDevice() { | |||||
err = Pa_AbortStream(stream); | err = Pa_AbortStream(stream); | ||||
// err = Pa_StopStream(stream); | // err = Pa_StopStream(stream); | ||||
if (err) { | if (err) { | ||||
fprintf(stderr, "Failed to stop audio stream: %s\n", Pa_GetErrorText(err)); | |||||
log(WARN, "Failed to stop audio stream: %s", Pa_GetErrorText(err)); | |||||
} | } | ||||
err = Pa_CloseStream(stream); | err = Pa_CloseStream(stream); | ||||
if (err) { | if (err) { | ||||
fprintf(stderr, "Failed to close audio stream: %s\n", Pa_GetErrorText(err)); | |||||
log(WARN, "Failed to close audio stream: %s", Pa_GetErrorText(err)); | |||||
} | } | ||||
} | } | ||||
@@ -17,9 +17,9 @@ MidiIO::MidiIO(bool isOut) { | |||||
channel = -1; | channel = -1; | ||||
this->isOut = isOut; | this->isOut = isOut; | ||||
if (isOut) { | |||||
fprintf(stderr, "Midi Out is currently not supported (will be added soon)"); | |||||
} | |||||
// TODO | |||||
// Support MIDI out | |||||
assert(!isOut); | |||||
}; | }; | ||||
void MidiIO::setChannel(int channel) { | void MidiIO::setChannel(int channel) { | ||||
@@ -60,7 +60,7 @@ std::vector<std::string> MidiIO::getDevices() { | |||||
try { | try { | ||||
m = new RtMidiIn(); | m = new RtMidiIn(); | ||||
} catch (RtMidiError &error) { | } catch (RtMidiError &error) { | ||||
fprintf(stderr, "Failed to create RtMidiIn: %s\n", error.getMessage().c_str()); | |||||
log(WARN, "Failed to create RtMidiIn: %s", error.getMessage().c_str()); | |||||
return names; | return names; | ||||
} | } | ||||
@@ -96,14 +96,14 @@ void MidiIO::openDevice(std::string deviceName) { | |||||
} | } | ||||
if (!mw->isPortOpen()) { | if (!mw->isPortOpen()) { | ||||
fprintf(stderr, "Failed to create RtMidiIn: No such device %s\n", deviceName.c_str()); | |||||
log(WARN, "Failed to create RtMidiIn: No such device %s", deviceName.c_str()); | |||||
this->deviceName = ""; | this->deviceName = ""; | ||||
this->id = -1; | this->id = -1; | ||||
return; | return; | ||||
} | } | ||||
} | } | ||||
catch (RtMidiError &error) { | catch (RtMidiError &error) { | ||||
fprintf(stderr, "Failed to create RtMidiIn: %s\n", error.getMessage().c_str()); | |||||
log(WARN, "Failed to create RtMidiIn: %s", error.getMessage().c_str()); | |||||
this->deviceName = ""; | this->deviceName = ""; | ||||
this->id = -1; | this->id = -1; | ||||
return; | return; | ||||
@@ -144,7 +144,7 @@ double MidiIO::getMessage(std::vector<unsigned char> *msg) { | |||||
MidiInWrapper *mw = midiInMap[deviceName]; | MidiInWrapper *mw = midiInMap[deviceName]; | ||||
if (!mw) { | if (!mw) { | ||||
fprintf(stderr, "Device not opened!: %s\n", deviceName.c_str()); | |||||
log(WARN, "Device not opened!: %s", deviceName.c_str()); | |||||
return 0; | return 0; | ||||
} | } | ||||
@@ -176,7 +176,7 @@ void MidiIO::close() { | |||||
MidiInWrapper *mw = midiInMap[deviceName]; | MidiInWrapper *mw = midiInMap[deviceName]; | ||||
if (!mw || id < 0) { | if (!mw || id < 0) { | ||||
//fprintf(stderr, "Trying to close already closed device!\n"); | |||||
//log(WARN, "Trying to close already closed device!"); | |||||
return; | return; | ||||
} | } | ||||
@@ -279,7 +279,7 @@ void dropCallback(GLFWwindow *window, int count, const char **paths) { | |||||
} | } | ||||
void errorCallback(int error, const char *description) { | void errorCallback(int error, const char *description) { | ||||
fprintf(stderr, "GLFW error %d: %s\n", error, description); | |||||
log(WARN, "GLFW error %d: %s", error, description); | |||||
} | } | ||||
void renderGui() { | void renderGui() { | ||||
@@ -446,7 +446,7 @@ void guiRun() { | |||||
std::this_thread::sleep_for(std::chrono::duration<double>(minTime - frameTime)); | std::this_thread::sleep_for(std::chrono::duration<double>(minTime - frameTime)); | ||||
} | } | ||||
endTime = glfwGetTime(); | endTime = glfwGetTime(); | ||||
// printf("%lf fps\n", 1.0 / (endTime - startTime)); | |||||
// log(INFO, "%lf fps", 1.0 / (endTime - startTime)); | |||||
} | } | ||||
} | } | ||||
@@ -519,10 +519,10 @@ bool guiIsMaximized() { | |||||
Font::Font(const std::string &filename) { | Font::Font(const std::string &filename) { | ||||
handle = nvgCreateFont(gVg, filename.c_str(), filename.c_str()); | handle = nvgCreateFont(gVg, filename.c_str(), filename.c_str()); | ||||
if (handle >= 0) { | if (handle >= 0) { | ||||
fprintf(stderr, "Loaded font %s\n", filename.c_str()); | |||||
log(INFO, "Loaded font %s", filename.c_str()); | |||||
} | } | ||||
else { | else { | ||||
fprintf(stderr, "Failed to load font %s\n", filename.c_str()); | |||||
log(WARN, "Failed to load font %s", filename.c_str()); | |||||
} | } | ||||
} | } | ||||
@@ -545,10 +545,10 @@ std::shared_ptr<Font> Font::load(const std::string &filename) { | |||||
Image::Image(const std::string &filename) { | Image::Image(const std::string &filename) { | ||||
handle = nvgCreateImage(gVg, filename.c_str(), NVG_IMAGE_REPEATX | NVG_IMAGE_REPEATY); | handle = nvgCreateImage(gVg, filename.c_str(), NVG_IMAGE_REPEATX | NVG_IMAGE_REPEATY); | ||||
if (handle > 0) { | if (handle > 0) { | ||||
fprintf(stderr, "Loaded image %s\n", filename.c_str()); | |||||
log(INFO, "Loaded image %s", filename.c_str()); | |||||
} | } | ||||
else { | else { | ||||
fprintf(stderr, "Failed to load image %s\n", filename.c_str()); | |||||
log(WARN, "Failed to load image %s", filename.c_str()); | |||||
} | } | ||||
} | } | ||||
@@ -572,10 +572,10 @@ std::shared_ptr<Image> Image::load(const std::string &filename) { | |||||
SVG::SVG(const std::string &filename) { | SVG::SVG(const std::string &filename) { | ||||
handle = nsvgParseFromFile(filename.c_str(), "px", SVG_DPI); | handle = nsvgParseFromFile(filename.c_str(), "px", SVG_DPI); | ||||
if (handle) { | if (handle) { | ||||
fprintf(stderr, "Loaded SVG %s\n", filename.c_str()); | |||||
log(INFO, "Loaded SVG %s", filename.c_str()); | |||||
} | } | ||||
else { | else { | ||||
fprintf(stderr, "Failed to load SVG %s\n", filename.c_str()); | |||||
log(WARN, "Failed to load SVG %s", filename.c_str()); | |||||
} | } | ||||
} | } | ||||
@@ -12,18 +12,23 @@ using namespace rack; | |||||
int main(int argc, char* argv[]) { | int main(int argc, char* argv[]) { | ||||
randomSeedTime(); | randomSeedTime(); | ||||
#ifdef VERSION | |||||
std::string logFilename = assetLocal("log.txt"); | |||||
gLogFile = fopen(logFilename.c_str()); | |||||
#endif | |||||
if (!gApplicationVersion.empty()) { | if (!gApplicationVersion.empty()) { | ||||
printf("Rack v%s\n", gApplicationVersion.c_str()); | |||||
log(INFO, "Rack v%s", gApplicationVersion.c_str()); | |||||
} | } | ||||
{ | { | ||||
char *cwd = getcwd(NULL, 0); | char *cwd = getcwd(NULL, 0); | ||||
printf("Current working directory: %s\n", cwd); | |||||
log(INFO, "Current working directory: %s", cwd); | |||||
free(cwd); | free(cwd); | ||||
std::string globalDir = assetGlobal(""); | std::string globalDir = assetGlobal(""); | ||||
std::string localDir = assetLocal(""); | std::string localDir = assetLocal(""); | ||||
printf("Global directory: %s\n", globalDir.c_str()); | |||||
printf("Local directory: %s\n", localDir.c_str()); | |||||
log(INFO, "Global directory: %s", globalDir.c_str()); | |||||
log(INFO, "Local directory: %s", localDir.c_str()); | |||||
} | } | ||||
pluginInit(); | pluginInit(); | ||||
@@ -49,5 +54,10 @@ int main(int argc, char* argv[]) { | |||||
guiDestroy(); | guiDestroy(); | ||||
engineDestroy(); | engineDestroy(); | ||||
pluginDestroy(); | pluginDestroy(); | ||||
#ifdef VERSION | |||||
fclose(gLogFile); | |||||
#endif | |||||
return 0; | return 0; | ||||
} | } |
@@ -112,13 +112,13 @@ static int loadPlugin(std::string path) { | |||||
HINSTANCE handle = LoadLibrary(libraryFilename.c_str()); | HINSTANCE handle = LoadLibrary(libraryFilename.c_str()); | ||||
if (!handle) { | if (!handle) { | ||||
int error = GetLastError(); | int error = GetLastError(); | ||||
fprintf(stderr, "Failed to load library %s: %d\n", libraryFilename.c_str(), error); | |||||
log(WARN, "Failed to load library %s: %d", libraryFilename.c_str(), error); | |||||
return -1; | return -1; | ||||
} | } | ||||
#elif ARCH_LIN || ARCH_MAC | #elif ARCH_LIN || ARCH_MAC | ||||
void *handle = dlopen(libraryFilename.c_str(), RTLD_NOW); | void *handle = dlopen(libraryFilename.c_str(), RTLD_NOW); | ||||
if (!handle) { | if (!handle) { | ||||
fprintf(stderr, "Failed to load library %s: %s\n", libraryFilename.c_str(), dlerror()); | |||||
log(WARN, "Failed to load library %s: %s", libraryFilename.c_str(), dlerror()); | |||||
return -1; | return -1; | ||||
} | } | ||||
#endif | #endif | ||||
@@ -132,7 +132,7 @@ static int loadPlugin(std::string path) { | |||||
initCallback = (InitCallback) dlsym(handle, "init"); | initCallback = (InitCallback) dlsym(handle, "init"); | ||||
#endif | #endif | ||||
if (!initCallback) { | if (!initCallback) { | ||||
fprintf(stderr, "Failed to read init() symbol in %s\n", libraryFilename.c_str()); | |||||
log(WARN, "Failed to read init() symbol in %s", libraryFilename.c_str()); | |||||
return -2; | return -2; | ||||
} | } | ||||
@@ -144,7 +144,7 @@ static int loadPlugin(std::string path) { | |||||
// Add plugin to list | // Add plugin to list | ||||
gPlugins.push_back(plugin); | gPlugins.push_back(plugin); | ||||
fprintf(stderr, "Loaded plugin %s\n", libraryFilename.c_str()); | |||||
log(INFO, "Loaded plugin %s", libraryFilename.c_str()); | |||||
return 0; | return 0; | ||||
} | } | ||||
@@ -277,14 +277,14 @@ void pluginInit() { | |||||
// Load plugins from global directory | // Load plugins from global directory | ||||
std::string globalPlugins = assetGlobal("plugins"); | std::string globalPlugins = assetGlobal("plugins"); | ||||
printf("Loading plugins from %s\n", globalPlugins.c_str()); | |||||
log(INFO, "Loading plugins from %s", globalPlugins.c_str()); | |||||
loadPlugins(globalPlugins); | loadPlugins(globalPlugins); | ||||
// Load plugins from local directory | // Load plugins from local directory | ||||
std::string localPlugins = assetLocal("plugins"); | std::string localPlugins = assetLocal("plugins"); | ||||
if (globalPlugins != localPlugins) { | if (globalPlugins != localPlugins) { | ||||
mkdir(localPlugins.c_str(), 0755); | mkdir(localPlugins.c_str(), 0755); | ||||
printf("Loading plugins from %s\n", localPlugins.c_str()); | |||||
log(INFO, "Loading plugins from %s", localPlugins.c_str()); | |||||
loadPlugins(localPlugins); | loadPlugins(localPlugins); | ||||
} | } | ||||
} | } | ||||
@@ -353,7 +353,7 @@ void pluginRefresh() { | |||||
json_t *errorJ = json_object_get(resJ, "error"); | json_t *errorJ = json_object_get(resJ, "error"); | ||||
if (errorJ) { | if (errorJ) { | ||||
const char *errorStr = json_string_value(errorJ); | const char *errorStr = json_string_value(errorJ); | ||||
fprintf(stderr, "Plugin refresh error: %s\n", errorStr); | |||||
log(WARN, "Plugin refresh error: %s", errorStr); | |||||
} | } | ||||
else { | else { | ||||
json_t *purchasesJ = json_object_get(resJ, "purchases"); | json_t *purchasesJ = json_object_get(resJ, "purchases"); | ||||
@@ -127,7 +127,7 @@ static void settingsFromJson(json_t *rootJ) { | |||||
void settingsSave(std::string filename) { | void settingsSave(std::string filename) { | ||||
printf("Saving settings %s\n", filename.c_str()); | |||||
log(INFO, "Saving settings %s", filename.c_str()); | |||||
FILE *file = fopen(filename.c_str(), "w"); | FILE *file = fopen(filename.c_str(), "w"); | ||||
if (!file) | if (!file) | ||||
return; | return; | ||||
@@ -142,7 +142,7 @@ void settingsSave(std::string filename) { | |||||
} | } | ||||
void settingsLoad(std::string filename) { | void settingsLoad(std::string filename) { | ||||
printf("Loading settings %s\n", filename.c_str()); | |||||
log(INFO, "Loading settings %s", filename.c_str()); | |||||
FILE *file = fopen(filename.c_str(), "r"); | FILE *file = fopen(filename.c_str(), "r"); | ||||
if (!file) | if (!file) | ||||
return; | return; | ||||
@@ -154,7 +154,7 @@ void settingsLoad(std::string filename) { | |||||
json_decref(rootJ); | json_decref(rootJ); | ||||
} | } | ||||
else { | else { | ||||
printf("JSON parsing error at %s %d:%d %s\n", error.source, error.line, error.column, error.text); | |||||
log(WARN, "JSON parsing error at %s %d:%d %s", error.source, error.line, error.column, error.text); | |||||
} | } | ||||
fclose(file); | fclose(file); | ||||
@@ -1,5 +1,4 @@ | |||||
#include "util.hpp" | #include "util.hpp" | ||||
#include <stdio.h> | |||||
#include <stdarg.h> | #include <stdarg.h> | ||||
#include <string.h> | #include <string.h> | ||||
#include <random> | #include <random> | ||||
@@ -15,6 +14,10 @@ | |||||
namespace rack { | namespace rack { | ||||
//////////////////// | |||||
// RNG | |||||
//////////////////// | |||||
// xoroshiro128+ | // xoroshiro128+ | ||||
// from http://xoroshiro.di.unimi.it/xoroshiro128plus.c | // from http://xoroshiro.di.unimi.it/xoroshiro128plus.c | ||||
@@ -36,11 +39,6 @@ static uint64_t xoroshiro128plus_next(void) { | |||||
return result; | return result; | ||||
} | } | ||||
static std::random_device rd; | |||||
static std::mt19937 rng(rd()); | |||||
static std::normal_distribution<float> normalDist; | |||||
void randomSeedTime() { | void randomSeedTime() { | ||||
struct timeval tv; | struct timeval tv; | ||||
gettimeofday(&tv, NULL); | gettimeofday(&tv, NULL); | ||||
@@ -80,6 +78,9 @@ float randomNormal() { | |||||
// return (sum - n / 2.f) / sqrtf(n / 12.f); | // return (sum - n / 2.f) / sqrtf(n / 12.f); | ||||
} | } | ||||
//////////////////// | |||||
// String functions | |||||
//////////////////// | |||||
std::string stringf(const char *format, ...) { | std::string stringf(const char *format, ...) { | ||||
va_list args; | va_list args; | ||||
@@ -136,6 +137,10 @@ std::string extractExtension(std::string path) { | |||||
return ext + 1; | return ext + 1; | ||||
} | } | ||||
//////////////////// | |||||
// Operating system functions | |||||
//////////////////// | |||||
void openBrowser(std::string url) { | void openBrowser(std::string url) { | ||||
#if ARCH_LIN | #if ARCH_LIN | ||||
std::string command = "xdg-open " + url; | std::string command = "xdg-open " + url; | ||||
@@ -150,5 +155,32 @@ void openBrowser(std::string url) { | |||||
#endif | #endif | ||||
} | } | ||||
//////////////////// | |||||
// logger | |||||
//////////////////// | |||||
FILE *gLogFile = stderr; | |||||
void log(LogLevel level, const char *format, ...) { | |||||
va_list args; | |||||
va_start(args, format); | |||||
switch (level) { | |||||
case INFO: | |||||
fprintf(gLogFile, "[info] "); | |||||
break; | |||||
case WARN: | |||||
fprintf(gLogFile, "[warning] "); | |||||
break; | |||||
case ERROR: | |||||
fprintf(gLogFile, "[error] "); | |||||
break; | |||||
default: | |||||
break; | |||||
} | |||||
vfprintf(gLogFile, format, args); | |||||
fprintf(gLogFile, "\n"); | |||||
va_end(args); | |||||
} | |||||
} // namespace rack | } // namespace rack |
@@ -1,4 +1,5 @@ | |||||
#include "util/request.hpp" | #include "util/request.hpp" | ||||
#include "util.hpp" | |||||
#include <assert.h> | #include <assert.h> | ||||
#include <stdio.h> | #include <stdio.h> | ||||
#include <string.h> | #include <string.h> | ||||
@@ -82,7 +83,7 @@ json_t *requestJson(RequestMethod method, std::string url, json_t *dataJ) { | |||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &resText); | curl_easy_setopt(curl, CURLOPT_WRITEDATA, &resText); | ||||
// Perform request | // Perform request | ||||
printf("Requesting %s\n", url.c_str()); | |||||
log(INFO, "Requesting %s", url.c_str()); | |||||
// curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); | // curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); | ||||
CURLcode res = curl_easy_perform(curl); | CURLcode res = curl_easy_perform(curl); | ||||
@@ -130,7 +131,7 @@ bool requestDownload(std::string url, std::string filename, float *progress) { | |||||
curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, xferInfoCallback); | curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, xferInfoCallback); | ||||
curl_easy_setopt(curl, CURLOPT_XFERINFODATA, progress); | curl_easy_setopt(curl, CURLOPT_XFERINFODATA, progress); | ||||
printf("Downloading %s\n", url.c_str()); | |||||
log(INFO, "Downloading %s", url.c_str()); | |||||
CURLcode res = curl_easy_perform(curl); | CURLcode res = curl_easy_perform(curl); | ||||
curl_easy_cleanup(curl); | curl_easy_cleanup(curl); | ||||
@@ -64,7 +64,7 @@ void FramebufferWidget::draw(NVGcontext *vg) { | |||||
if (fbSize.isZero()) | if (fbSize.isZero()) | ||||
return; | return; | ||||
// printf("rendering framebuffer %f %f\n", fbSize.x, fbSize.y); | |||||
// log(INFO, "rendering framebuffer %f %f", fbSize.x, fbSize.y); | |||||
// Delete old one first to free up GPU memory | // Delete old one first to free up GPU memory | ||||
internal->setFramebuffer(NULL); | internal->setFramebuffer(NULL); | ||||
// Create a framebuffer from the main nanovg context. We will draw to this in the secondary nanovg context. | // Create a framebuffer from the main nanovg context. We will draw to this in the secondary nanovg context. | ||||
@@ -8,7 +8,7 @@ void SpriteWidget::draw(NVGcontext *vg) { | |||||
nvgImageSize(vg, spriteImage->handle, &width, &height); | nvgImageSize(vg, spriteImage->handle, &width, &height); | ||||
int stride = width / spriteSize.x; | int stride = width / spriteSize.x; | ||||
if (stride == 0) { | if (stride == 0) { | ||||
printf("Size of SpriteWidget is %d, %d but spriteSize is %f, %f\n", width, height, spriteSize.x, spriteSize.y); | |||||
log(WARN, "Size of SpriteWidget is %d, %d but spriteSize is %f, %f", width, height, spriteSize.x, spriteSize.y); | |||||
return; | return; | ||||
} | } | ||||
Vec offset = Vec((index % stride) * spriteSize.x, (index / stride) * spriteSize.y); | Vec offset = Vec((index % stride) * spriteSize.x, (index / stride) * spriteSize.y); | ||||
@@ -14,7 +14,6 @@ Rect TransformWidget::getChildrenBoundingBox() { | |||||
Vec bottomRight = bound.getBottomRight(); | Vec bottomRight = bound.getBottomRight(); | ||||
nvgTransformPoint(&topLeft.x, &topLeft.y, transform, topLeft.x, topLeft.y); | nvgTransformPoint(&topLeft.x, &topLeft.y, transform, topLeft.x, topLeft.y); | ||||
nvgTransformPoint(&bottomRight.x, &bottomRight.y, transform, bottomRight.x, bottomRight.y); | nvgTransformPoint(&bottomRight.x, &bottomRight.y, transform, bottomRight.x, bottomRight.y); | ||||
printf("%f\n", 42.1); | |||||
return Rect(topLeft, bottomRight.minus(topLeft)); | return Rect(topLeft, bottomRight.minus(topLeft)); | ||||
} | } | ||||