From e3fd1ef8139b7fb89dc14612349d56da157f4cef Mon Sep 17 00:00:00 2001 From: jszczerbinsky Date: Fri, 3 May 2024 17:55:24 +0000 Subject: [PATCH] Target point comeback --- src/common.h | 1 + src/common/config.c | 26 +++++++++++---- src/core/main.c | 36 +++++++++++--------- src/core/main.h | 2 +- src/core/windowHandlers.c | 10 ++++++ src/window_templates/main.glade | 28 +++++++++++++++- src/wlp/main.c | 58 +++++++++++++++++++++++++-------- src/wlp/main.h | 27 +++++++-------- src/wlp/render.c | 57 +++++++++++++++++++++++--------- 9 files changed, 180 insertions(+), 65 deletions(-) diff --git a/src/common.h b/src/common.h index 477a790..c228b1e 100644 --- a/src/common.h +++ b/src/common.h @@ -64,6 +64,7 @@ typedef struct { int targetFps; char renderQuality[8]; + int unfocusedComeback; } AppConfig; // diff --git a/src/common/config.c b/src/common/config.c index 94bea6f..c5becb9 100644 --- a/src/common/config.c +++ b/src/common/config.c @@ -91,6 +91,7 @@ static void useDefaultAppCfg(AppConfig *ac) { ac->targetFps = 60; strcpy(ac->renderQuality, "best"); + ac->unfocusedComeback = 1; } void saveAppConfig(AppConfig *ac) @@ -105,6 +106,8 @@ void saveAppConfig(AppConfig *ac) config_setting_set_int(setting, ac->targetFps); setting = config_setting_add(root, "render_quality", CONFIG_TYPE_STRING); config_setting_set_string(setting, ac->renderQuality); + setting = config_setting_add(root, "unfocused_comeback", CONFIG_TYPE_INT); + config_setting_set_int(setting, ac->unfocusedComeback); char path[PATH_MAX]; getAppCfgPath(path); @@ -134,12 +137,23 @@ int loadAppConfig(AppConfig *ac) } root = config_root_setting(&cfg); - setting = config_setting_get_member(root, "target_fps"); - ac->targetFps = config_setting_get_int(setting); - setting = config_setting_get_member(root, "render_quality"); - strcpy(ac->renderQuality, config_setting_get_string(setting)); - - config_destroy(&cfg); + setting = config_setting_get_member(root, "target_fps"); + if (setting == NULL) + ac->targetFps = 60; + else + ac->targetFps = config_setting_get_int(setting); + + setting = config_setting_get_member(root, "render_quality"); + if (setting == NULL) + strcpy(ac->renderQuality, "best"); + else + strcpy(ac->renderQuality, config_setting_get_string(setting)); + + setting = config_setting_get_member(root, "unfocused_comeback"); + if (setting == NULL) + ac->unfocusedComeback = 1; + else + ac->unfocusedComeback = config_setting_get_int(setting); return 1; } diff --git a/src/core/main.c b/src/core/main.c index ea68c80..208a8a4 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -5,22 +5,23 @@ GtkApplication *app = NULL; GtkBuilder *builder = NULL; -GtkWidget *mainWnd = NULL; -GtkWidget *exitDialog = NULL; -GtkWidget *wallpaperMgrWnd = NULL; -GtkWidget *monitorWnd = NULL; -GtkWidget *monitorListBox = NULL; -GtkWidget *wallpaperListBox = NULL; -GtkWidget *wallpaperComboBox = NULL; -GtkWidget *xPosSpinBtn = NULL; -GtkWidget *yPosSpinBtn = NULL; -GtkWidget *widthSpinBtn = NULL; -GtkWidget *heightSpinBtn = NULL; -GtkWidget *monitorNameLabel = NULL; -GtkWidget *versionLabel = NULL; -GtkWidget *appSettingsWnd = NULL; -GtkWidget *targetFpsComboBox = NULL; -GtkWidget *renderQualityComboBox = NULL; +GtkWidget *mainWnd = NULL; +GtkWidget *exitDialog = NULL; +GtkWidget *wallpaperMgrWnd = NULL; +GtkWidget *monitorWnd = NULL; +GtkWidget *monitorListBox = NULL; +GtkWidget *wallpaperListBox = NULL; +GtkWidget *wallpaperComboBox = NULL; +GtkWidget *xPosSpinBtn = NULL; +GtkWidget *yPosSpinBtn = NULL; +GtkWidget *widthSpinBtn = NULL; +GtkWidget *heightSpinBtn = NULL; +GtkWidget *monitorNameLabel = NULL; +GtkWidget *versionLabel = NULL; +GtkWidget *appSettingsWnd = NULL; +GtkWidget *targetFpsComboBox = NULL; +GtkWidget *renderQualityComboBox = NULL; +GtkWidget *unfocusedComebackComboBox = NULL; static void reloadMonitorListBox() { @@ -156,6 +157,9 @@ static void activate(GtkApplication *app, gpointer userdata) renderQualityComboBox = (GtkWidget *)gtk_builder_get_object( builder, "SettingsWindow_TexFilteringComboBox" ); + unfocusedComebackComboBox = (GtkWidget *)gtk_builder_get_object( + builder, "SettingsWindow_UnfocusedCombackComboBox" + ); gtk_window_set_application(GTK_WINDOW(mainWnd), GTK_APPLICATION(app)); gtk_window_set_application(GTK_WINDOW(exitDialog), GTK_APPLICATION(app)); diff --git a/src/core/main.h b/src/core/main.h index b775e33..c982a3e 100644 --- a/src/core/main.h +++ b/src/core/main.h @@ -22,7 +22,7 @@ extern GtkWidget *monitorNameLabel; extern GtkWidget *appSettingsWnd; extern GtkWidget *targetFpsComboBox; extern GtkWidget *renderQualityComboBox; -extern GtkWidget *drawOnRootWndComboBox; +extern GtkWidget *unfocusedComebackComboBox; void runWlp(); void killWlp(); diff --git a/src/core/windowHandlers.c b/src/core/windowHandlers.c index f506c2e..1537707 100644 --- a/src/core/windowHandlers.c +++ b/src/core/windowHandlers.c @@ -173,10 +173,16 @@ G_MODULE_EXPORT void SettingsWindowShow() char targetFpsStr[4]; sprintf(targetFpsStr, "%d", ac.targetFps); + char unfocusedComebackStr[2]; + sprintf(unfocusedComebackStr, "%d", ac.unfocusedComeback); + gtk_combo_box_set_active_id( GTK_COMBO_BOX(renderQualityComboBox), ac.renderQuality ); gtk_combo_box_set_active_id(GTK_COMBO_BOX(targetFpsComboBox), targetFpsStr); + gtk_combo_box_set_active_id( + GTK_COMBO_BOX(unfocusedComebackComboBox), unfocusedComebackStr + ); } G_MODULE_EXPORT void SettingsWindowClose() @@ -194,6 +200,10 @@ G_MODULE_EXPORT void SettingsWindow_ApplyBtnClick() ac.targetFps = atoi(gtk_combo_box_get_active_id(GTK_COMBO_BOX(targetFpsComboBox))); + ac.unfocusedComeback = + atoi(gtk_combo_box_get_active_id(GTK_COMBO_BOX(unfocusedComebackComboBox)) + ); + saveAppConfig(&ac); killWlp(); diff --git a/src/window_templates/main.glade b/src/window_templates/main.glade index ba18481..9b46e0b 100644 --- a/src/window_templates/main.glade +++ b/src/window_templates/main.glade @@ -625,7 +625,7 @@ Layered WallPaper - + True False @@ -690,6 +690,32 @@ Layered WallPaper 0 + + + True + False + start + Unfocused monitor behaviour + + + 0 + 2 + + + + + True + False + + Come back + Clamp + + + + 1 + 2 + + False diff --git a/src/wlp/main.c b/src/wlp/main.c index bb616ac..d0c6bda 100644 --- a/src/wlp/main.c +++ b/src/wlp/main.c @@ -21,7 +21,7 @@ static void atExit() m++; } - + free(app.monitors); SDL_Quit(); @@ -33,7 +33,9 @@ void exitSignalHandler(int s) exit(0); } -void initWallpaper(App *app, Monitor *m, WallpaperInfo *wallpapers, int wallpapersCount) +void initWallpaper( + App *app, Monitor *m, WallpaperInfo *wallpapers, int wallpapersCount +) { MonitorInfo *mi = &m->info; @@ -54,7 +56,9 @@ void initWallpaper(App *app, Monitor *m, WallpaperInfo *wallpapers, int wallpape Wallpaper *wallpaper = &m->wlp; lwpLog(LOG_INFO, "Initializing wallpaper %s...", wallpaper->info.name); - lwpLog(LOG_INFO, "Layers count: %d", wallpaper->info.config.layersCount); + lwpLog( + LOG_INFO, "Layers count: %d", wallpaper->info.config.layersCount + ); lwpLog( LOG_INFO, "Repeat X Y: %d %d", @@ -70,10 +74,15 @@ void initWallpaper(App *app, Monitor *m, WallpaperInfo *wallpapers, int wallpape mi->clientBounds.h ); if (m->tex == NULL) - lwpLog(LOG_ERROR, "Failed creating a texture for the monitor: %s", SDL_GetError()); - - wallpaper->layers = malloc(sizeof(Layer) * wallpaper->info.config.layersCount); - wallpaper->tex = SDL_CreateTexture( + lwpLog( + LOG_ERROR, + "Failed creating a texture for the monitor: %s", + SDL_GetError() + ); + + wallpaper->layers = + malloc(sizeof(Layer) * wallpaper->info.config.layersCount); + wallpaper->tex = SDL_CreateTexture( m->renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, @@ -81,7 +90,11 @@ void initWallpaper(App *app, Monitor *m, WallpaperInfo *wallpapers, int wallpape mi->config.wlpBounds.h ); if (wallpaper->tex == NULL) - lwpLog(LOG_ERROR, "Failed creating a texture for the monitor: %s", SDL_GetError()); + lwpLog( + LOG_ERROR, + "Failed creating a texture for the monitor: %s", + SDL_GetError() + ); for (int l = 0; l < wallpaper->info.config.layersCount; l++) { @@ -97,9 +110,15 @@ void initWallpaper(App *app, Monitor *m, WallpaperInfo *wallpapers, int wallpape wallpaper->originalH = surf->h; } - wallpaper->layers[l].tex = SDL_CreateTextureFromSurface(m->renderer, surf); + wallpaper->layers[l].tex = + SDL_CreateTextureFromSurface(m->renderer, surf); if (wallpaper->tex == NULL) - lwpLog(LOG_ERROR, "Failed creating a texture for the layer %d: %s", l, SDL_GetError()); + lwpLog( + LOG_ERROR, + "Failed creating a texture for the layer %d: %s", + l, + SDL_GetError() + ); SDL_FreeSurface(surf); } @@ -109,7 +128,8 @@ void initWallpaper(App *app, Monitor *m, WallpaperInfo *wallpapers, int wallpape break; } } - if (!foundWlp) lwpLog(LOG_WARNING, "Couldn't find the wallpaper. Ignoring..."); + if (!foundWlp) + lwpLog(LOG_WARNING, "Couldn't find the wallpaper. Ignoring..."); } int initMonitors(App *app) @@ -129,16 +149,28 @@ int initMonitors(App *app) MonitorInfo *mi = &app->monitors[i].info; + app->monitors[i].currentPoint.x = 0; + app->monitors[i].currentPoint.y = 0; + if (!loadMonitorConfig(mi->name, &mi->config)) { - lwpLog(LOG_WARNING, "Couldn't find config file for monitor %s. Ignoring...", mi->name); + lwpLog( + LOG_WARNING, + "Couldn't find config file for monitor %s. Ignoring...", + mi->name + ); } else { lwpLog(LOG_INFO, "Initializing monitor %d...", i); lwpLog(LOG_INFO, "Wallpaper: %s", mi->config.wlpName); lwpLog( - LOG_INFO, "Bounds: %d %d %dx%d", mi->clientBounds.x, mi->clientBounds.y, mi->clientBounds.w, mi->clientBounds.h + LOG_INFO, + "Bounds: %d %d %dx%d", + mi->clientBounds.x, + mi->clientBounds.y, + mi->clientBounds.w, + mi->clientBounds.h ); lwpLog( LOG_INFO, diff --git a/src/wlp/main.h b/src/wlp/main.h index 983eb6e..5138d82 100644 --- a/src/wlp/main.h +++ b/src/wlp/main.h @@ -27,6 +27,12 @@ #define LOG_INFO 1 #define LOG_WARNING 2 +typedef struct +{ + float x; + float y; +} Point; + typedef struct { SDL_Texture *tex; @@ -43,27 +49,22 @@ typedef struct typedef struct { - MonitorInfo info; - SDL_Texture *tex; - Wallpaper wlp; + MonitorInfo info; + SDL_Texture *tex; + Wallpaper wlp; SDL_Window *window; SDL_Renderer *renderer; - int aborted; + Point currentPoint; + int aborted; } Monitor; typedef struct { - AppConfig config; - int monitorsCount; - Monitor *monitors; + AppConfig config; + int monitorsCount; + Monitor *monitors; } App; -typedef struct -{ - float x; - float y; -} Point; - void lwpLog(int type, const char *str, ...); void initWindow(App *app, Monitor *monitor); diff --git a/src/wlp/render.c b/src/wlp/render.c index f1fea90..078d521 100644 --- a/src/wlp/render.c +++ b/src/wlp/render.c @@ -15,24 +15,59 @@ static float clamp(float a, float min, float max) return a; } +static void lerpTargetPoint(Point *p, Point *target, float dT) +{ + p->x = lerp(p->x, target->x, dT * 4); // 4: smooth + p->y = lerp(p->y, target->y, dT * 4); +} + static void getRelativeTargetPoint( - Point *dest, Point *globalTargetPoint, Monitor *m + Point *dest, const Point *globalTargetPoint, const Monitor *m ) { dest->x = globalTargetPoint->x - m->info.clientBounds.x; dest->y = globalTargetPoint->y - m->info.clientBounds.y; +} + +static void clampTargetPoint(Point *p, Monitor *m) +{ + p->x = clamp(p->x, 0, m->info.clientBounds.w); + p->y = clamp(p->y, 0, m->info.clientBounds.h); +} + +static void comeBackTargetPoint(Point *p, Monitor *m) +{ + if (p->x < 0 || p->x > m->info.clientBounds.w || p->y < 0 || + p->y > m->info.clientBounds.h) + { + p->x = m->info.clientBounds.w / 2; + p->y = m->info.clientBounds.h / 2; + } +} - dest->x = clamp(dest->x, 0, m->info.clientBounds.w); - dest->y = clamp(dest->y, 0, m->info.clientBounds.h); +static float distanceSquared(const Point *p, const Point *q) +{ + return (p->x - q->x) * (p->x - q->x) + (p->y - q->y) * (p->y - q->y); } -static void renderMonitor(App *app, Monitor *monitor, Point *globalTargetPoint) +static void renderMonitor( + App *app, Monitor *monitor, const Point *globalTargetPoint, float dT +) { if (!monitor->info.config.loaded || !monitor->wlp.info.config.loaded) return; Point targetPoint; getRelativeTargetPoint(&targetPoint, globalTargetPoint, monitor); + if (app->config.unfocusedComeback) + comeBackTargetPoint(&targetPoint, monitor); + else + clampTargetPoint(&targetPoint, monitor); + + lerpTargetPoint(&monitor->currentPoint, &targetPoint, dT); + + if (distanceSquared(&monitor->currentPoint, &targetPoint) < 1) return; + if (SDL_SetRenderTarget(monitor->renderer, monitor->wlp.tex) != 0) { lwpLog(LOG_ERROR, "Error setting the renderer target: %s", SDL_GetError()); @@ -51,10 +86,10 @@ static void renderMonitor(App *app, Monitor *monitor, Point *globalTargetPoint) }; int x = - -((targetPoint.x - monitor->info.clientBounds.w / 2) * + -((monitor->currentPoint.x - monitor->info.clientBounds.w / 2) * monitor->wlp.info.config.layerConfigs[i].sensitivityX); int y = - -((targetPoint.y - monitor->info.clientBounds.h / 2) * + -((monitor->currentPoint.y - monitor->info.clientBounds.h / 2) * monitor->wlp.info.config.layerConfigs[i].sensitivityY); for (int k = -monitor->wlp.info.config.repeatY; @@ -144,16 +179,9 @@ static void getTargetPoint(Point *p) #endif } -static void lerpTargetPoint(Point *p, Point *target, float dT) -{ - p->x = lerp(p->x, target->x, dT * 4); // 4: smooth - p->y = lerp(p->y, target->y, dT * 4); -} - void runWallpaperLoop(App *app) { Point targetPoint; - Point point; int quit = 0; while (!quit) @@ -167,10 +195,9 @@ void runWallpaperLoop(App *app) getInput(&quit); getTargetPoint(&targetPoint); - lerpTargetPoint(&point, &targetPoint, dT); for (int m = 0; m < app->monitorsCount; m++) if (!app->monitors[m].aborted) - renderMonitor(app, app->monitors + m, &point); + renderMonitor(app, app->monitors + m, &targetPoint, dT); } }