]> git.mcshandy.xyz Git - picker/commitdiff
Proper HSV->RGB conversion, HSL slider, preview window, and some controls
authorrandy <randy@mcshandy.xyz>
Thu, 21 Sep 2023 17:35:17 +0000 (12:35 -0500)
committerrandy <randy@mcshandy.xyz>
Thu, 21 Sep 2023 17:35:17 +0000 (12:35 -0500)
source/main.c
source/sdl/SDL_Utils.c
source/sdl/SDL_Utils.h
source/structs.h

index 6440aad8bd9aa376883762b37262c25419e666db..c9df6ae795d83c7c9455274a00a840d7fd7814df 100644 (file)
@@ -18,33 +18,25 @@ int init()
        signal(SIGKILL, killterm_handler);
        signal(SIGTERM, killterm_handler);
 
-       gi.window = (Rect){.x = 0.0f, .y = 0.0f, .w = 512.0f, .h = 512.0f};
+       gi.window = (Rect){.x = 0.0f, .y = 0.0f, .w = 2*512.0f, .h = 2*512.0f};
+
        // satisfying rel.[xy]*2 == .[wh] centers axis in parent container
        gi.rgb_square.rel = (Rect){.x = 0.05, .y = 0.05, .w = 0.5, .h = 0.5};
        gi.hue_slider.rel = (Rect){.x = 0.65, .y = 0.05, .w = .08, .h = 0.5};
        gi.final_sample.rel = (Rect){.x = 0.05, .y = .65, .w = 0.20, .h = 0.20};
-
        gi.info_container.rel = (Rect){.x = 0.05, .y = .65, .w = .9, .h = .30};
        gi.info_boxes.rel = (Rect){.x = .25, .y = 0.00, .w = 0.75, .h = 1.00};
-
        gi.rgb_info.rel = (Rect){.x = 0.00, .y = 0.00, .w = 1.00, .h = 0.50};
        gi.red.rel = (Rect){.x = 0.00, .y = 0.00, .w = 0.30, .h = 1.00};
        gi.green.rel = (Rect){.x = 0.35, .y = 0.00, .w = 0.30, .h = 1.00};
        gi.blue.rel = (Rect){.x = 0.70, .y = 0.00, .w = 0.30, .h = 1.00};
-
        gi.hsl_info.rel = (Rect){.x = 0.00, .y = 0.50, .w = 1.00, .h = 0.50};
        gi.hue.rel = (Rect){.x = 0.00, .y = 0.00, .w = 0.30, .h = 1.00};
        gi.saturation.rel = (Rect){.x = 0.35, .y = 0.00, .w = 0.30, .h = 1.00};
        gi.luminence.rel = (Rect){.x = 0.70, .y = 0.00, .w = 0.30, .h = 1.00};
 
-       // lime (120 100 50) - > (0 255 0)
-       gi.active_hsv = (HSL_Color){.h = 120, .s = 100, .l = 50};
-
-       // silver (0 0 75) - > (0 255 0)
-       gi.active_hsv = (HSL_Color){.h = 0, .s = 0, .l = 75};
-
-       Color rgb = hsl_to_rgb(gi.active_hsv);
-       printf("%d %d %d\n", rgb.r, rgb.g, rgb.b);
+       gi.active_hsl = (HSL_Color){.h = 0, .s = 100, .l = 50};
+       gi.active_rgb = hsl_to_rgb(gi.active_hsl);
 
        init_renderer(&gi);
 
@@ -53,16 +45,6 @@ int init()
        return 0;
 };
 
-int handle_collisions(Game_Info* gi)
-{
-}
-
-int game_loop(Game_Info* gi, float time_step)
-{
-
-       return 0;
-}
-
 int main(void)
 {
        int quit = 0;
@@ -80,7 +62,6 @@ int main(void)
                clock_gettime(CLOCK_MONOTONIC_RAW, &ts_start);
 
                check_inputs(&gi);
-               game_loop(&gi, time_step);
                display(&gi);
 
                clock_gettime(CLOCK_MONOTONIC_RAW, &ts_end);
index 9083746574568dc80089598a4341e282ff8316a2..11335fda6ed8091d25df98a27e6bac502b19de9a 100644 (file)
@@ -7,6 +7,13 @@
 #define unroll_sdl_color(color) color.r, color.g, color.b, color.a
 #define lineColorFPoints(r, a, b, c) lineColor(r, a.x - camera_offset.x, a.y - camera_offset.y, b.x - camera_offset.x, b.y - camera_offset.y, c)
 
+SDL_Color red = {255, 0, 0, 255};
+SDL_Color green = {0, 255, 0, 255};
+SDL_Color blue = {0, 0, 255, 255};
+SDL_Color black = {0, 0, 0, 255};
+SDL_Color white = {255, 255, 255, 255};
+SDL_Color magenta = {255, 0, 255, 255};
+
 sdl_group mgr;
 const int keypress_delta = 4;
 
@@ -66,15 +73,42 @@ int32_t render_rgb_square(Game_Info* gi)
        return 0;
 }
 
+int32_t render_solid_color(Game_Info* gi, SDL_FRect* container, SDL_Color color)
+{
+       SDL_SetRenderDrawColor(mgr.rend, unroll_sdl_color(color));
+       SDL_RenderFillRectF(mgr.rend, container);
+
+       return 0;
+}
+
+int32_t render_vertical_hue_spectrum(Game_Info* gi, SDL_FRect* container)
+{
+
+       int hue_slice_scale = container->h;
+       float hue_slice_height = hue_slice_scale/360.0f;
+
+       int bar_y = gi->active_hsl.h/360.0f*container->h + container->y;
+       SDL_SetRenderDrawColor(mgr.rend, unroll_sdl_color(black));
+       SDL_RenderDrawLine(mgr.rend, container->x-16, bar_y, container->w+container->x+16, bar_y);
+
+       for (int n = 0; n < (int)container->h; n++)
+       {
+               HSL_Color slice_hsl = {((float)n/(float)container->h) * 360, 100, 50};
+               SDL_Color slice_color = hsl_to_rgb (slice_hsl);
+
+               SDL_SetRenderDrawColor(mgr.rend, unroll_sdl_color(slice_color));
+               SDL_RenderDrawLine(mgr.rend, container->x, container->y + n, container->w+container->x, container->y+n);
+       }
+
+       return 0;
+}
+
 // REALLY this should be "generate layout", and not a true rendering step
+// For now just do the math and color the full space of the child
 int32_t render_container(Game_Info* gi, SDL_FRect* parent, Layout_Rect* child, SDL_Color color)
 {
        SDL_SetRenderDrawColor(mgr.rend, unroll_sdl_color(color));
        child->real = fr_margin_adjust(*parent, child->rel);
-
-       // replace this with corresponding item's callback
-       // hmm maybe that can be wedged into the layout_rect?
-       // nahhhh
        SDL_RenderFillRectF(mgr.rend, &child->real);
 
        return 0;
@@ -82,35 +116,32 @@ int32_t render_container(Game_Info* gi, SDL_FRect* parent, Layout_Rect* child, S
 
 int32_t display(Game_Info* gi)
 {
-       SDL_Color red = {255, 0, 0, 255};
-       SDL_Color green = {0, 255, 0, 255};
-       SDL_Color blue = {0, 0, 255, 255};
-       SDL_Color black = {0, 0, 0, 255};
-       SDL_Color white = {255, 255, 255, 255};
-       SDL_Color magenta = {255, 0, 255, 255};
-
-       // This is kinda the important stuff
-       SDL_RenderPresent(mgr.rend);
        SDL_SetRenderDrawColor(mgr.rend, 0xCB, 0xCB, 0xCB, 0xCB);
        SDL_RenderClear(mgr.rend);
 
+       gi->active_rgb = hsl_to_rgb(gi->active_hsl);
+
        // this would be really cool to turn into some stack-based type of thing
+       // Also, if resizing is disabled, this can be moved to a static initialization section
        render_container(gi, &gi->window, &gi->rgb_square, green);
        render_container(gi, &gi->window, &gi->hue_slider, green);
        render_container(gi, &gi->window, &gi->info_container, blue);
-       render_container(gi, &gi->window, &gi->final_sample, green);
-
-       render_container(gi, &gi->info_container.real, &gi->info_boxes, green);
-       render_container(gi, &gi->info_boxes.real, &gi->rgb_info, black);
-       render_container(gi, &gi->info_boxes.real, &gi->hsl_info, white);
+               render_container(gi, &gi->window, &gi->final_sample, green);
+               render_container(gi, &gi->info_container.real, &gi->info_boxes, green);
+               render_container(gi, &gi->info_boxes.real, &gi->rgb_info, black);
+                       render_container(gi, &gi->rgb_info.real, &gi->red, red);
+                       render_container(gi, &gi->rgb_info.real, &gi->green, green);
+                       render_container(gi, &gi->rgb_info.real, &gi->blue, blue);
+               render_container(gi, &gi->info_boxes.real, &gi->hsl_info, white);
+                       render_container(gi, &gi->hsl_info.real, &gi->hue, green);
+                       render_container(gi, &gi->hsl_info.real, &gi->saturation, blue);
+                       render_container(gi, &gi->hsl_info.real, &gi->luminence, red);
+
+       render_solid_color(gi, &gi->final_sample.real, gi->active_rgb);
+       render_vertical_hue_spectrum(gi, &gi->hue_slider.real);
 
-       render_container(gi, &gi->rgb_info.real, &gi->red, red);
-       render_container(gi, &gi->rgb_info.real, &gi->green, green);
-       render_container(gi, &gi->rgb_info.real, &gi->blue, blue);
-
-       render_container(gi, &gi->hsl_info.real, &gi->hue, green);
-       render_container(gi, &gi->hsl_info.real, &gi->saturation, blue);
-       render_container(gi, &gi->hsl_info.real, &gi->luminence, red);
+       // This is kinda the important stuff
+       SDL_RenderPresent(mgr.rend);
        return 0;
 }
 
@@ -118,11 +149,23 @@ int32_t check_inputs(Game_Info* gi)
 {
        while(SDL_PollEvent(&(mgr.event)))
        {
-               // wasd movement and quitting
+               if (mgr.event.type == SDL_KEYDOWN)
                {
-                       if (mgr.event.type == SDL_KEYDOWN && mgr.event.key.keysym.sym == SDLK_q)
+                       switch(mgr.event.key.keysym.sym)
                        {
-                               gi->game_alive = 0;
+                               case SDLK_q:
+                                       gi->game_alive = 0;
+                                       break;
+                               case SDLK_j:
+                                       gi->active_hsl.h += 1;
+                                       if(gi->active_hsl.h > 360)
+                                               gi->active_hsl.h -= 360;
+                                       break;
+                               case SDLK_k:
+                                       gi->active_hsl.h -= 1;
+                                       if(gi->active_hsl.h < 0)
+                                               gi->active_hsl.h += 360;
+                                       break;
                        }
                }
        }
@@ -182,61 +225,23 @@ SDL_FRect fr_margin_adjust(const SDL_FRect parent, const Relative_Rect child)
        };
 }
 
-// https://www.rapidtables.com/convert/color/hsl-to-rgb.html
-SDL_Color hsl_to_rgb (const HSL_Color hsl)
+float hsl_to_rgb_alt_internal(const HSL_Color hsl, int n)
 {
-       float C, X, m;
-       float rP, gP, bP;
-
-       float h = fmod(hsl.h, 360.0);
-       float s = hsl.s/100.0f;
-       float l = hsl.l/100.0f;
-
-       C = (1 - abs((2*(l)) - 1)) * s;
-       X = C * (1 - abs(fmod(h/60, 2.0f) -1));
-       m = l - (C/2.0);
-
-
-       if (h >= 0 && h <= 60)
-       {
-               rP = C;
-               gP = X;
-               bP = 0;
-       }
-       else if (h >= 60 && h <= 120)
-       {
-               rP = X;
-               gP = C;
-               bP = 0;
-       }
-       else if (h >= 120 && h <= 180)
-       {
-               rP = 0;
-               gP = C;
-               bP = X;
-       }
-       else if (h >= 180 && h <= 240)
-       {
-               rP = 0;
-               gP = X;
-               bP = C;
-       }
-       else if (h >= 240 && h <= 300)
-       {
-               rP = X;
-               gP = 0;
-               bP = C;
-       }
-       else if (h >= 300 && h <= 360)
-       {
-               rP = C;
-               gP = 0;
-               bP = X;
-       }
+       float H = (float)hsl.h;
+       float L = (float)hsl.l/100.0f;
+       float S = (float)hsl.s/100.0f;
+       float a = S * MIN(L, 1-L);
+       float k = fmod((n + (H/30.0)), 12.0);
+       return L - a * MAX(-1, MIN(k-3, MIN(9-k, 1)));
+}
 
+// https://www.wikiwand.com/en/HSL_and_HSV#To_RGB
+SDL_Color hsl_to_rgb (const HSL_Color hsl)
+{
        return (SDL_Color){
-               (rP + m) * 255,
-               (gP + m) * 255,
-               (bP + m) * 255};
+               .r = (uint8_t)(hsl_to_rgb_alt_internal(hsl, 0) * 255),
+               .g = (uint8_t)(hsl_to_rgb_alt_internal(hsl, 8) * 255),
+               .b = (uint8_t)(hsl_to_rgb_alt_internal(hsl, 4) * 255),
+               .a = 0xFF}; // Opaque
 }
 
index ddd252089efaf3c4d1f116a2eefa0cc2e8df671c..7631c08604f66570ad322f40b3a7db1e42f7ceba 100644 (file)
@@ -24,5 +24,6 @@ SDL_FRect fr_subtract(const SDL_FRect left, const SDL_FRect right);
 SDL_FRect fr_mult(const SDL_FRect left, const SDL_FRect right);
 SDL_FRect fr_margin_adjust(const SDL_FRect parent, const Relative_Rect child);
 SDL_Color hsl_to_rgb (const HSL_Color hsl);
+SDL_Color wikipedia_hsl_to_rgb (const HSL_Color hsl);
 #endif // SDL_Utils__
 
index 894ed70045b2d3d9be7fcf773ef645ebeb07fa45..367ccc2bdd5407212febb6bddf6e8d79c1e4a1b7 100644 (file)
@@ -32,7 +32,7 @@ typedef struct
 {
        // Internet says hue likes to go 0-360
        // Saturation and luminence are 0-100
-       uint16_t h;
+       int16_t h;
        uint8_t s;
        uint8_t l;
        uint8_t a;
@@ -67,7 +67,7 @@ typedef struct
        Color active_rgb;
 
        // Hue value should correspond to value on HSV slider
-       HSL_Color active_hsv;
+       HSL_Color active_hsl;
 
        int game_alive;