refactor: code cleaning

This commit is contained in:
2026-04-11 14:24:35 +02:00
parent f38108d3fa
commit 6bd8d48846
16 changed files with 70 additions and 100 deletions

View File

@@ -1,10 +1,10 @@
all: wallpaper distance_field_generator all: wallpaper distance_field_generator
wallpaper: src/wallpaper.c wallpaper: src/wallpaper.c
gcc -O3 -Werror -Wall -Wextra -I./vendor/raylib-5.5_linux_amd64/include/ -o wallpaper src/wallpaper.c -L./vendor/raylib-5.5_linux_amd64/lib -l:libraylib.a -lm gcc -O3 -Werror -Wall -Wextra -pedantic -I./vendor/raylib-5.5_linux_amd64/include/ -o wallpaper src/wallpaper.c -L./vendor/raylib-5.5_linux_amd64/lib -l:libraylib.a -lm
distance_field_generator: src/distance_field_generator.c distance_field_generator: src/distance_field_generator.c
gcc -Werror -Wall -Wextra -fopenmp -I./vendor/raylib-5.5_linux_amd64/include/ -o distance_field_generator src/distance_field_generator.c -L./vendor/raylib-5.5_linux_amd64/lib -l:libraylib.a -lm gcc -Werror -Wall -Wextra -pedantic -fopenmp -I./vendor/raylib-5.5_linux_amd64/include/ -o distance_field_generator src/distance_field_generator.c -L./vendor/raylib-5.5_linux_amd64/lib -l:libraylib.a -lm
install: wallpaper install: wallpaper
sudo install -D -m 755 wallpaper /usr/bin/wallpaper sudo install -D -m 755 wallpaper /usr/bin/wallpaper

View File

Before

Width:  |  Height:  |  Size: 211 KiB

After

Width:  |  Height:  |  Size: 211 KiB

View File

Before

Width:  |  Height:  |  Size: 193 KiB

After

Width:  |  Height:  |  Size: 193 KiB

View File

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.9 MiB

After

Width:  |  Height:  |  Size: 7.9 MiB

View File

Before

Width:  |  Height:  |  Size: 386 KiB

After

Width:  |  Height:  |  Size: 386 KiB

View File

Before

Width:  |  Height:  |  Size: 97 KiB

After

Width:  |  Height:  |  Size: 97 KiB

View File

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

Before

Width:  |  Height:  |  Size: 386 KiB

After

Width:  |  Height:  |  Size: 386 KiB

View File

Before

Width:  |  Height:  |  Size: 67 KiB

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.9 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

View File

@@ -3,13 +3,11 @@
#include <math.h> #include <math.h>
#include <omp.h> #include <omp.h>
bool is_inside_shape(Color pixel) static bool is_inside_shape(Color pixel) {
{
return pixel.r == 255 && pixel.g == 255 && pixel.b == 255; return pixel.r == 255 && pixel.g == 255 && pixel.b == 255;
} }
Image generate_distance_field(Image input_texture, int search_radius) static Image generate_distance_field(Image input_texture, int search_radius) {
{
int width = input_texture.width; int width = input_texture.width;
int height = input_texture.height; int height = input_texture.height;
@@ -20,25 +18,20 @@ Image generate_distance_field(Image input_texture, int search_radius)
TraceLog(LOG_INFO, "Using %d threads for parallel processing", omp_get_max_threads()); TraceLog(LOG_INFO, "Using %d threads for parallel processing", omp_get_max_threads());
#pragma omp parallel for schedule(dynamic, 64) #pragma omp parallel for schedule(dynamic, 64)
for (int y = 0; y < height; y++) for (int y = 0; y < height; y += 1) {
{ if (omp_get_thread_num() == 0 && y % (height / 10) == 0) {
if (omp_get_thread_num() == 0 && y % (height / 10) == 0)
{
TraceLog(LOG_INFO, "Progress: %d%%", (y * 100) / height); TraceLog(LOG_INFO, "Progress: %d%%", (y * 100) / height);
} }
for (int x = 0; x < width; x++) for (int x = 0; x < width; x += 1) {
{
int index = y * width + x; int index = y * width + x;
bool is_inside = is_inside_shape(input_pixels[index]); bool is_inside = is_inside_shape(input_pixels[index]);
float min_distance_sq = search_radius * search_radius; float min_distance_sq = search_radius * search_radius;
bool found_boundary = false; bool found_boundary = false;
for (int dy = -search_radius; dy <= search_radius; dy += 1) for (int dy = -search_radius; dy <= search_radius; dy += 1) {
{ for (int dx = -search_radius; dx <= search_radius; dx += 1) {
for (int dx = -search_radius; dx <= search_radius; dx += 1)
{
int sample_x = x + dx; int sample_x = x + dx;
int sample_y = y + dy; int sample_y = y + dy;
@@ -47,11 +40,9 @@ Image generate_distance_field(Image input_texture, int search_radius)
int sample_index = sample_y * width + sample_x; int sample_index = sample_y * width + sample_x;
bool sample_is_inside = is_inside_shape(input_pixels[sample_index]); bool sample_is_inside = is_inside_shape(input_pixels[sample_index]);
if (sample_is_inside != is_inside) if (sample_is_inside != is_inside) {
{
float distance_sq = dx * dx + dy * dy; float distance_sq = dx * dx + dy * dy;
if (distance_sq < min_distance_sq) if (distance_sq < min_distance_sq) {
{
min_distance_sq = distance_sq; min_distance_sq = distance_sq;
found_boundary = true; found_boundary = true;
} }
@@ -62,22 +53,15 @@ Image generate_distance_field(Image input_texture, int search_radius)
float distance = found_boundary ? sqrtf(min_distance_sq) : (float)search_radius; float distance = found_boundary ? sqrtf(min_distance_sq) : (float)search_radius;
float normalized_distance = distance / (float)search_radius; float normalized_distance = distance / (float)search_radius;
unsigned char distance_value; unsigned char distance_value = is_inside ?
if (is_inside) (unsigned char)(127.0f - 127.0f * normalized_distance) :
{ (unsigned char)(128.0f + 127.0f * normalized_distance);
distance_value = (unsigned char)(127.0f - 127.0f * normalized_distance);
}
else
{
distance_value = (unsigned char)(128.0f + 127.0f * normalized_distance);
}
output_pixels[index] = (Color){distance_value, distance_value, distance_value, 255}; output_pixels[index] = (Color){distance_value, distance_value, distance_value, 255};
} }
} }
for (int i = 0; i < width * height; i++) for (int i = 0; i < width * height; i += 1) {
{
ImageDrawPixel(&distance_field, i % width, i / width, output_pixels[i]); ImageDrawPixel(&distance_field, i % width, i / width, output_pixels[i]);
} }
@@ -89,8 +73,7 @@ Image generate_distance_field(Image input_texture, int search_radius)
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
if (argc < 3) if (argc < 3) {
{
TraceLog(LOG_ERROR, "Usage: %s <input_image> <output_image> [search_radius]", argv[0]); TraceLog(LOG_ERROR, "Usage: %s <input_image> <output_image> [search_radius]", argv[0]);
return 1; return 1;
} }
@@ -100,15 +83,13 @@ int main(int argc, char *argv[])
int search_radius = (argc >= 4) ? atoi(argv[3]) : 100; int search_radius = (argc >= 4) ? atoi(argv[3]) : 100;
Image input_image = LoadImage(input_path); Image input_image = LoadImage(input_path);
if (input_image.data == NULL) if (input_image.data == NULL) {
{
TraceLog(LOG_ERROR, "Error: Failed to load input image '%s'", input_path); TraceLog(LOG_ERROR, "Error: Failed to load input image '%s'", input_path);
return 1; return 1;
} }
Image distance_field_image = generate_distance_field(input_image, search_radius); Image distance_field_image = generate_distance_field(input_image, search_radius);
if (!ExportImage(distance_field_image, output_path)) if (!ExportImage(distance_field_image, output_path)) {
{
TraceLog(LOG_ERROR, "Failed to save output image '%s'", output_path); TraceLog(LOG_ERROR, "Failed to save output image '%s'", output_path);
UnloadImage(input_image); UnloadImage(input_image);
UnloadImage(distance_field_image); UnloadImage(distance_field_image);

View File

@@ -6,41 +6,41 @@
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/un.h> #include <sys/un.h>
#include <unistd.h> #include <unistd.h>
#include <time.h> #include <errno.h>
#include <string.h>
#include <math.h> #include <math.h>
#define WIDTH 1920 #define WIDTH 1920
#define HEIGHT 1080 #define HEIGHT 1080
#define BALL_RADIUS 100.0f
#define INFLUENCE 200.0f
typedef struct { typedef struct {
const char* name; const char* name;
int x; Vector2 pos;
int y; Vector2 origin;
int cx;
int cy;
float angle; float angle;
float angle_step; float angle_step;
} Star; } Star;
static Star stars[] = { static Star stars[] = {
{ .name = "star_1.png", .x = 4, .y = 528, .cx = 165, .cy = 166, .angle = 90.0, .angle_step = -0.025 }, { .name = "star_1.png", .pos = { 4, 528 }, .origin = {165, 166}, .angle = 90.0, .angle_step = -0.025 },
{ .name = "star_2.png", .x = 215, .y = 809, .cx = 82, .cy = 83, .angle = 90.0, .angle_step = 0.05 }, { .name = "star_2.png", .pos = { 215, 809 }, .origin = {82, 83}, .angle = 90.0, .angle_step = 0.05 },
{ .name = "star_3.png", .x = 333, .y = 781, .cx = 25, .cy = 31, .angle = 90.0, .angle_step = 0.15 }, { .name = "star_3.png", .pos = { 333, 781 }, .origin = {25, 31}, .angle = 90.0, .angle_step = 0.15 },
{ .name = "star_4.png", .x = 956, .y = 405, .cx = 166, .cy = 167, .angle = 90.0, .angle_step = -0.1 }, { .name = "star_4.png", .pos = { 956, 405 }, .origin = {166, 167}, .angle = 90.0, .angle_step = -0.1 },
{ .name = "star_5.png", .x = 1164, .y = 570, .cx = 66, .cy = 70, .angle = 90.0, .angle_step = 0.075 }, { .name = "star_5.png", .pos = { 1164, 570 }, .origin = {66, 70}, .angle = 90.0, .angle_step = 0.075 },
}; };
#define STARS_COUNT (int)(sizeof(stars) / sizeof(stars[0])) #define STARS_COUNT (int)(sizeof(stars) / sizeof(stars[0]))
char *hyprland_socket_path; static char *hyprland_socket_path;
Vector2 hyprland_get_cursor_position() { static Vector2 hyprland_get_cursor_position() {
Vector2 pos = {0}; Vector2 pos = {0, 0};
int sock_fd = socket(AF_UNIX, SOCK_STREAM, 0); int sock_fd = socket(AF_UNIX, SOCK_STREAM, 0);
if (sock_fd == -1) { if (sock_fd == -1) {
perror("socket"); TraceLog(LOG_ERROR, "socket: %s", strerror(errno));
return pos; return pos;
} }
@@ -49,15 +49,14 @@ Vector2 hyprland_get_cursor_position() {
strncpy(addr.sun_path, hyprland_socket_path, sizeof(addr.sun_path) - 1); strncpy(addr.sun_path, hyprland_socket_path, sizeof(addr.sun_path) - 1);
if (connect(sock_fd, (struct sockaddr *)&addr, sizeof(addr)) == -1) { if (connect(sock_fd, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
printf("Using hyprland socket: %s\n", hyprland_socket_path); TraceLog(LOG_ERROR, "connect %s: %s", hyprland_socket_path, strerror(errno));
perror("connect");
close(sock_fd); close(sock_fd);
return pos; return pos;
} }
const char *message = "/cursorpos"; const char *message = "/cursorpos";
if (send(sock_fd, message, strlen(message), 0) == -1) { if (send(sock_fd, message, strlen(message), 0) == -1) {
perror("send"); TraceLog(LOG_ERROR, "send: %s", strerror(errno));
close(sock_fd); close(sock_fd);
return pos; return pos;
} }
@@ -65,7 +64,7 @@ Vector2 hyprland_get_cursor_position() {
char buffer[256] = {0}; char buffer[256] = {0};
ssize_t bytes_received = recv(sock_fd, buffer, sizeof(buffer) - 1, 0); ssize_t bytes_received = recv(sock_fd, buffer, sizeof(buffer) - 1, 0);
if (bytes_received == -1) { if (bytes_received == -1) {
perror("recv"); TraceLog(LOG_ERROR, "recv: %s", strerror(errno));
close(sock_fd); close(sock_fd);
return pos; return pos;
} }
@@ -74,76 +73,66 @@ Vector2 hyprland_get_cursor_position() {
buffer[bytes_received] = '\0'; buffer[bytes_received] = '\0';
if (sscanf(buffer, "%f, %f", &pos.x, &pos.y) != 2) { if (sscanf(buffer, "%f, %f", &pos.x, &pos.y) != 2) {
fprintf(stderr, "Failed to parse cursor position\n"); TraceLog(LOG_ERROR, "Failed to parse cursor position");
} }
close(sock_fd); close(sock_fd);
return pos; return pos;
} }
Texture2D load_texture_from_file(const char *file_path) { static const char *resolve_asset_path(const char *path) {
Texture2D texture = {0}; if (FileExists(path)) return path;
const char *system_path = TextFormat("/usr/share/wallpaper/%s", path);
if (FileExists(file_path)) { if (FileExists(system_path)) return system_path;
texture = LoadTexture(file_path); return path;
} }
else {
const char *system_path = TextFormat("/usr/share/wallpaper/%s", file_path);
if (FileExists(system_path)) {
texture = LoadTexture(system_path);
}
}
static Texture2D load_texture_from_file(const char *file_path) {
Texture2D texture = LoadTexture(resolve_asset_path(file_path));
if (texture.id == 0) { if (texture.id == 0) {
TraceLog(LOG_ERROR, "Failed to load texture from file: %s", file_path); TraceLog(LOG_ERROR, "Failed to load texture from file: %s", file_path);
abort();
} }
return texture; return texture;
} }
Shader load_shader_from_file(const char *vs_path, const char *fs_path) { static Shader load_shader_from_file(const char *vs_path, const char *fs_path) {
Shader shader = {0}; Shader shader = LoadShader(resolve_asset_path(vs_path), resolve_asset_path(fs_path));
if (FileExists(vs_path) && FileExists(fs_path)) {
shader = LoadShader(vs_path, fs_path);
}
else {
const char *system_vs_path = TextFormat("/usr/share/wallpaper/%s", vs_path);
const char *system_fs_path = TextFormat("/usr/share/wallpaper/%s", fs_path);
if (FileExists(system_vs_path) && FileExists(system_fs_path)) {
shader = LoadShader(system_vs_path, system_fs_path);
}
}
if (shader.id == 0) { if (shader.id == 0) {
TraceLog(LOG_ERROR, "Failed to load shader from files: %s, %s", vs_path, fs_path); TraceLog(LOG_ERROR, "Failed to load shader from files: %s, %s", vs_path, fs_path);
abort();
} }
return shader; return shader;
} }
const char* get_window_title() { static const char* get_window_title() {
return getenv("DEBUG") != NULL ? "pihkaal-wallpaper-debug" : "pihkaal-wallpaper"; return getenv("DEBUG") != NULL ? "pihkaal-wallpaper-debug" : "pihkaal-wallpaper";
} }
static char* get_hyprland_socket_path() {
return strdup(TextFormat("%s/hypr/%s/.socket.sock", getenv("XDG_RUNTIME_DIR"), getenv("HYPRLAND_INSTANCE_SIGNATURE")));
}
int main(void) { int main(void) {
InitWindow(WIDTH, HEIGHT, get_window_title()); InitWindow(WIDTH, HEIGHT, get_window_title());
SetWindowState(FLAG_WINDOW_RESIZABLE); SetWindowState(FLAG_WINDOW_RESIZABLE);
SetTargetFPS(60); SetTargetFPS(60);
// initialize hyprland socket path // initialize hyprland socket path
hyprland_socket_path = strdup(TextFormat("%s/hypr/%s/.socket.sock", getenv("XDG_RUNTIME_DIR"), getenv("HYPRLAND_INSTANCE_SIGNATURE"))); hyprland_socket_path = get_hyprland_socket_path();
// initialize textures // initialize textures
Texture2D distanceFieldTex = load_texture_from_file("resources/textures/background_distance_field.png"); Texture2D distanceFieldTex = load_texture_from_file("assets/textures/background_distance_field.png");
Texture2D backgroundTex = load_texture_from_file("resources/textures/background_no_stars.png"); Texture2D backgroundTex = load_texture_from_file("assets/textures/background_transparent.png");
RenderTexture2D target = LoadRenderTexture(WIDTH, HEIGHT); Texture2D starTextures[STARS_COUNT] = {0};
Texture2D starTextures[STARS_COUNT];
for (int i = 0; i < STARS_COUNT; i++) { for (int i = 0; i < STARS_COUNT; i++) {
starTextures[i] = load_texture_from_file(TextFormat("resources/textures/%s", stars[i].name)); starTextures[i] = load_texture_from_file(TextFormat("assets/textures/%s", stars[i].name));
} }
RenderTexture2D target = LoadRenderTexture(WIDTH, HEIGHT);
// initialize shader // initialize shader
Shader shader = load_shader_from_file("resources/shaders/basic.vs", "resources/shaders/distance_field.fs"); Shader shader = load_shader_from_file("assets/shaders/basic.vs", "assets/shaders/distance_field.fs");
int resolutionLoc = GetShaderLocation(shader, "resolution"); int resolutionLoc = GetShaderLocation(shader, "resolution");
int mousePosLoc = GetShaderLocation(shader, "mousePos"); int mousePosLoc = GetShaderLocation(shader, "mousePos");
@@ -154,10 +143,10 @@ int main(void) {
Vector2 resolution = {WIDTH, HEIGHT}; Vector2 resolution = {WIDTH, HEIGHT};
SetShaderValue(shader, resolutionLoc, &resolution, SHADER_UNIFORM_VEC2); SetShaderValue(shader, resolutionLoc, &resolution, SHADER_UNIFORM_VEC2);
float ballRadius = 100.0f; float ballRadius = BALL_RADIUS;
SetShaderValue(shader, ballRadiusLoc, &ballRadius, SHADER_UNIFORM_FLOAT); SetShaderValue(shader, ballRadiusLoc, &ballRadius, SHADER_UNIFORM_FLOAT);
float shapeInfluence = 200.0f; float shapeInfluence = INFLUENCE;
SetShaderValue(shader, shapeInfluenceLoc, &shapeInfluence, SHADER_UNIFORM_FLOAT); SetShaderValue(shader, shapeInfluenceLoc, &shapeInfluence, SHADER_UNIFORM_FLOAT);
int textureUnit = 1; int textureUnit = 1;
@@ -192,13 +181,13 @@ int main(void) {
DrawTextureRec(backgroundTex, (Rectangle){0, 0, screenWidth, screenHeight}, (Vector2){0, 0}, WHITE); DrawTextureRec(backgroundTex, (Rectangle){0, 0, screenWidth, screenHeight}, (Vector2){0, 0}, WHITE);
for (int i = 0; i < STARS_COUNT; i++) { for (int i = 0; i < STARS_COUNT; i++) {
stars[i].angle = fmodf(stars[i].angle + stars[i].angle_step, 360.0f); Star* star = &stars[i];
star->angle = fmodf(star->angle + star->angle_step, 360.0f);
Texture2D tex = starTextures[i]; Texture2D tex = starTextures[i];
Rectangle source = {0, 0, (float)tex.width, (float)tex.height}; Rectangle source = {0, 0, (float)tex.width, (float)tex.height};
Rectangle dest = {stars[i].x, stars[i].y, (float)tex.width, (float)tex.height}; Rectangle dest = {star->pos.x, star->pos.y, (float)tex.width, (float)tex.height};
Vector2 origin = {stars[i].cx, stars[i].cy}; DrawTexturePro(tex, source, dest, star->origin, star->angle, WHITE);
DrawTexturePro(tex, source, dest, origin, stars[i].angle, WHITE);
} }
EndDrawing(); EndDrawing();