Refactor to multiple files to comply with the Norm
authorLukas Jiriste <ljiriste@student.42prague.com>
Fri, 26 Apr 2024 09:09:41 +0000 (11:09 +0200)
committerLukas Jiriste <ljiriste@student.42prague.com>
Fri, 26 Apr 2024 09:09:41 +0000 (11:09 +0200)
Makefile
inc/fractol.h
src/cleanup.c [new file with mode: 0644]
src/drawing.c [new file with mode: 0644]
src/event_handling.c
src/init.c [new file with mode: 0644]
src/main.c
src/parsing.c [new file with mode: 0644]
src/trans_view.c [new file with mode: 0644]

index d252ab85c9cf789b79b70f2545229d9c24255598..3b4f9f766b3382d9187d935074e9be6dc679f838 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -22,6 +22,11 @@ SRCS := main.c                               \
                event_handling.c        \
                fractals.c                      \
                pixel.c                         \
+               cleanup.c                       \
+               drawing.c                       \
+               init.c                          \
+               parsing.c                       \
+               trans_view.c            \
 
 SRCS := $(addprefix $(SRCDIR)/, $(SRCS))
 
index 4187dcca0dfd8ce484ef8d9fee619ead82909276..1e7583f1a5e6c914c3b76e9fdfa79c761e9cdf49 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2023/11/11 18:51:29 by ljiriste          #+#    #+#             */
-/*   Updated: 2024/04/26 10:16:03 by ljiriste         ###   ########.fr       */
+/*   Updated: 2024/04/26 11:01:18 by ljiriste         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
@@ -71,17 +71,23 @@ struct s_session
 };
 typedef struct s_session       t_session;
 
-int    handle_key_press(int keycode, t_session *s);
-int    handle_mouse_press(int button, int x, int y, t_session *s);
-int    no_event_handle(t_session *s);
-void   process_pixel_group(t_session *s, int x, int y);
-void   calculate_base(t_session *s);
+int            handle_key_press(int keycode, t_session *s);
+int            handle_mouse_press(int button, int x, int y, t_session *s);
+int            no_event_handle(t_session *s);
+
+int            parse_args(int argc, char **argv, t_session *s);
+
 void   draw_fractal(t_session *s);
 void   pure_draw_fractal(t_session *s);
+void   erase_calced(t_mat *calced);
+
 void   change_zoom(t_session *s, t_vect2 invariant, double d_zoom);
+void   change_shift_speed(double *speed, double mult, double thresh);
 void   move_view(t_session *s, float move_amount_right, float move_amount_up);
-int    close_win(t_session *s);
 
-void   erase_calced(t_mat *calced);
+int            close_win(t_session *s);
+void   cleanup(t_session *s);
+
+void   init_session(t_session *s);
 
 #endif
diff --git a/src/cleanup.c b/src/cleanup.c
new file mode 100644 (file)
index 0000000..426686e
--- /dev/null
@@ -0,0 +1,39 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   cleanup.c                                          :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2024/04/26 10:51:11 by ljiriste          #+#    #+#             */
+/*   Updated: 2024/04/26 11:02:49 by ljiriste         ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#include "fractol.h"
+#include "libft.h"
+#include <mlx.h>
+#include <stdlib.h>
+
+int    close_win(t_session *s)
+{
+       mlx_destroy_window(s->mlx, s->win);
+       s->win = NULL;
+       return (0);
+}
+
+static void    free_session(t_session *s)
+{
+       mlx_destroy_display(s->mlx);
+       free(s->mlx);
+       return ;
+}
+
+void   cleanup(t_session *s)
+{
+       ft_mat_free(&s->img.calced, NULL);
+       ft_mat_free(&s->img.base, NULL);
+       mlx_destroy_image(s->mlx, s->img.img);
+       free_session(s);
+       return ;
+}
diff --git a/src/drawing.c b/src/drawing.c
new file mode 100644 (file)
index 0000000..0592ba7
--- /dev/null
@@ -0,0 +1,114 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   drawing.c                                          :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2024/04/26 10:44:28 by ljiriste          #+#    #+#             */
+/*   Updated: 2024/04/26 11:04:24 by ljiriste         ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#include "pixel.h"
+#include "fractol.h"
+#include "libft.h"
+#include <mlx.h>
+#include <stdbool.h>
+#include <math.h>
+
+static void    process_pixel_group(t_session *s, int x, int y)
+{
+       int             i;
+       int             j;
+       double  param;
+
+       if (!*(bool *)ft_mat_access(&s->img.calced, y, x))
+               param = s->view.fractal(&s->set,
+                               s->view.window_coord.x + s->view.pixel_size.x * x,
+                               s->view.window_coord.y - s->view.pixel_size.y * y);
+       else
+               param = *(double *)ft_mat_access(&s->img.base, y, x);
+       i = 0;
+       while (i < s->img.undersample && x + i < s->img.width)
+       {
+               j = 0;
+               while (j < s->img.undersample && y + j < s->img.height)
+               {
+                       if (!*(bool *)ft_mat_access(&s->img.calced, y + j, x + i))
+                               *(double *)ft_mat_access(&s->img.base, y + j, x + i) = param;
+                       ++j;
+               }
+               ++i;
+       }
+       *(bool *)ft_mat_access(&s->img.calced, y, x) = 1;
+       return ;
+}
+
+static void    calculate_base(t_session *s)
+{
+       int             x;
+       int             y;
+
+       x = 0;
+       while (x < s->img.width)
+       {
+               y = 0;
+               while (y < s->img.height)
+               {
+                       process_pixel_group(s, x, y);
+                       y += s->img.undersample;
+               }
+               x += s->img.undersample;
+       }
+}
+
+void   pure_draw_fractal(t_session *s)
+{
+       int             x;
+       int             y;
+       double  param;
+
+       x = 0;
+       while (x < s->img.width)
+       {
+               y = 0;
+               while (y < s->img.height)
+               {
+                       param = *(double *)ft_mat_access(&s->img.base, y, x);
+                       if (param >= 0)
+                               param = fmod(param + s->view.color_shift, 1.);
+                       ft_putpx_img(&s->img, x, y, s->view.palette(param));
+                       ++y;
+               }
+               ++x;
+       }
+       mlx_put_image_to_window(s->mlx, s->win, s->img.img, 0, 0);
+       return ;
+}
+
+void   draw_fractal(t_session *s)
+{
+       calculate_base(s);
+       pure_draw_fractal(s);
+       return ;
+}
+
+void   erase_calced(t_mat *calced)
+{
+       size_t  i;
+       size_t  j;
+
+       i = 0;
+       while (i < calced->rows)
+       {
+               j = 0;
+               while (j < calced->cols)
+               {
+                       *(bool *)ft_mat_access(calced, i, j) = false;
+                       ++j;
+               }
+               ++i;
+       }
+       return ;
+}
index 2612e53da2697e7d96d5ae48bfc7dd98dbaf8653..98f2aac561b4d64004d61c71a73c07ae3ff46528 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2023/12/05 19:35:01 by ljiriste          #+#    #+#             */
-/*   Updated: 2024/04/26 10:14:40 by ljiriste         ###   ########.fr       */
+/*   Updated: 2024/04/26 11:02:11 by ljiriste         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
 #define SHIFT_MULT 1.2
 #define SHIFT_THRESH 0.0001
 
-void   redraw(t_session *s)
+static void    set_for_redraw(t_session *s)
 {
        erase_calced(&s->img.calced);
        s->img.undersample = s->img.undersample_max;
        return ;
 }
 
-void   change_shift_speed(double *speed, double mult, double thresh)
-{
-       if (-thresh < *speed && *speed < thresh)
-       {
-               if (mult > 0)
-                       *speed = thresh;
-               else
-                       *speed = -thresh;
-               return ;
-       }
-       if (*speed > 0 && mult > 0)
-               *speed *= mult;
-       else if (*speed > 0 && mult < 0)
-               *speed /= -mult;
-       else if (*speed < 0 && mult < 0)
-               *speed *= -mult;
-       else if (*speed < 0 && mult > 0)
-               *speed /= mult;
-       if (-thresh < *speed && *speed < thresh)
-               *speed = 0;
-       return ;
-}
-
 static void    additional_keys(int keycode, t_session *s)
 {
        if (keycode == XK_KP_Multiply)
@@ -61,7 +38,7 @@ static void   additional_keys(int keycode, t_session *s)
                if (s->set.detail * DETAIL_MULT > s->set.detail)
                {
                        s->set.detail *= DETAIL_MULT;
-                       redraw(s);
+                       set_for_redraw(s);
                }
        }
        else if (keycode == XK_KP_Divide)
@@ -69,7 +46,7 @@ static void   additional_keys(int keycode, t_session *s)
                if (s->set.detail >= DETAIL_MULT)
                {
                        s->set.detail /= DETAIL_MULT;
-                       redraw(s);
+                       set_for_redraw(s);
                }
        }
        else if (keycode == XK_KP_Up)
@@ -99,7 +76,7 @@ int   handle_key_press(int keycode, t_session *s)
                change_zoom(s, (t_vect2){.x = s->img.width / 2,
                        .y = s->img.height / 2}, ZOOM_OUT);
        else if (keycode == XK_r)
-               redraw(s);
+               set_for_redraw(s);
        else
                additional_keys(keycode, s);
        if (keycode != XK_Escape)
@@ -121,7 +98,7 @@ int  handle_mouse_press(int button, int x, int y, t_session *s)
 /*     valgrind indicates an issue when the draw_fractal is in proccess
  *     while and ESC is pressed thus ending the program.
  *
- *     Setting the condition to less than 1 basically turns this redrawing
+ *     Setting the condition to less than 1 basically turns this set_for_redrawing
  *     off.
  */
 int    no_event_handle(t_session *s)
@@ -131,9 +108,10 @@ int        no_event_handle(t_session *s)
                if (s->img.undersample > 1)
                {
                        --s->img.undersample;
-                       calculate_base(s);
+                       draw_fractal(s);
                }
-               pure_draw_fractal(s);
+               else
+                       pure_draw_fractal(s);
                s->view.color_shift
                        = fmod(s->view.color_shift + s->view.color_shift_speed, 1.);
                if (s->view.color_shift < 0)
diff --git a/src/init.c b/src/init.c
new file mode 100644 (file)
index 0000000..607519c
--- /dev/null
@@ -0,0 +1,38 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   init.c                                             :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2024/04/26 10:53:46 by ljiriste          #+#    #+#             */
+/*   Updated: 2024/04/26 11:05:51 by ljiriste         ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#include "fractol.h"
+#include "libft.h"
+#include <mlx.h>
+#include <stdbool.h>
+
+static void    init_view(t_session *s)
+{
+       s->view.window_coord.x = -s->img.width / 2 * s->view.pixel_size.x;
+       s->view.window_coord.y = s->img.height / 2 * s->view.pixel_size.y;
+       return ;
+}
+
+void   init_session(t_session *s)
+{
+       init_view(s);
+       s->mlx = mlx_init();
+       s->win = mlx_new_window(s->mlx, s->img.width, s->img.height, "Fract-ol");
+       s->img.img = mlx_new_image(s->mlx, s->img.width, s->img.height);
+       s->img.addr = mlx_get_data_addr(s->img.img,
+                       &s->img.bpp, &s->img.bpl, &s->img.endian);
+       ft_mat_init(&s->img.calced, sizeof(bool));
+       ft_mat_init(&s->img.base, sizeof(double));
+       ft_mat_zeros(&s->img.calced, s->img.height, s->img.width);
+       ft_mat_zeros(&s->img.base, s->img.height, s->img.width);
+       s->img.undersample = s->img.undersample_max;
+}
index b0b638281f9991747373ce0d34c6a50fd0277d31..75d7e31b9bcf5389f325b2af77d68d1602ae3bfb 100644 (file)
 /*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2023/10/27 14:29:26 by ljiriste          #+#    #+#             */
-/*   Updated: 2024/04/26 10:15:44 by ljiriste         ###   ########.fr       */
+/*   Updated: 2024/04/26 11:08:47 by ljiriste         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
-#include "complex.h"
-#include "color.h"
-#include "vect2.h"
-#include "fractals.h"
-#include "pixel.h"
 #include "fractol.h"
 #include "libft.h"
 #include <mlx.h>
 #include <math.h>
-#include <stdbool.h>
 #include <stdlib.h>
 #include <X11/keysym.h>
 #include <X11/X.h>
 
-int    close_win(t_session *s)
-{
-       mlx_destroy_window(s->mlx, s->win);
-       s->win = NULL;
-       return (0);
-}
-
-void   free_session(t_session *s)
-{
-       mlx_destroy_display(s->mlx);
-       free(s->mlx);
-       return ;
-}
-
-void   process_pixel_group(t_session *s, int x, int y)
-{
-       int             i;
-       int             j;
-       double  param;
-
-       if (!*(bool *)ft_mat_access(&s->img.calced, y, x))
-               param = s->view.fractal(&s->set,
-                               s->view.window_coord.x + s->view.pixel_size.x * x,
-                               s->view.window_coord.y - s->view.pixel_size.y * y);
-       else
-               param = *(double *)ft_mat_access(&s->img.base, y, x);
-       i = 0;
-       while (i < s->img.undersample && x + i < s->img.width)
-       {
-               j = 0;
-               while (j < s->img.undersample && y + j < s->img.height)
-               {
-                       if (!*(bool *)ft_mat_access(&s->img.calced, y + j, x + i))
-                               *(double *)ft_mat_access(&s->img.base, y + j, x + i) = param;
-                       ++j;
-               }
-               ++i;
-       }
-       *(bool *)ft_mat_access(&s->img.calced, y, x) = 1;
-       return ;
-}
-
-void   calculate_base(t_session *s)
-{
-       int             x;
-       int             y;
-
-       x = 0;
-       while (x < s->img.width)
-       {
-               y = 0;
-               while (y < s->img.height)
-               {
-                       process_pixel_group(s, x, y);
-                       y += s->img.undersample;
-               }
-               x += s->img.undersample;
-       }
-}
-
-void   pure_draw_fractal(t_session *s)
-{
-       int             x;
-       int             y;
-       double  param;
-
-       x = 0;
-       while (x < s->img.width)
-       {
-               y = 0;
-               while (y < s->img.height)
-               {
-                       param = *(double *)ft_mat_access(&s->img.base, y, x);
-                       if (param >= 0)
-                               param = fmod(param + s->view.color_shift, 1.);
-                       ft_putpx_img(&s->img, x, y, s->view.palette(param));
-                       ++y;
-               }
-               ++x;
-       }
-       mlx_put_image_to_window(s->mlx, s->win, s->img.img, 0, 0);
-       return ;
-}
-
-void   draw_fractal(t_session *s)
-{
-       calculate_base(s);
-       pure_draw_fractal(s);
-       return ;
-}
-
-void   erase_calced(t_mat *calced)
-{
-       size_t  i;
-       size_t  j;
-
-       i = 0;
-       while (i < calced->rows)
-       {
-               j = 0;
-               while (j < calced->cols)
-               {
-                       *(bool *)ft_mat_access(calced, i, j) = false;
-                       ++j;
-               }
-               ++i;
-       }
-       return ;
-}
-
-void   change_zoom(t_session *s, t_vect2 invariant, double d_zoom)
-{
-       s->view.pixel_size.x /= d_zoom;
-       s->view.pixel_size.y /= d_zoom;
-       s->view.window_coord.x += s->view.pixel_size.x * invariant.x * (d_zoom - 1);
-       s->view.window_coord.y -= s->view.pixel_size.y * invariant.y * (d_zoom - 1);
-       erase_calced(&s->img.calced);
-       s->img.undersample = s->img.undersample_max;
-       return ;
-}
-
-void   move_pixel(t_img *img, t_vect2 old, t_vect2 new)
-{
-       *(double *)ft_mat_access(&img->base, new.y, new.x)
-               = *(double *)ft_mat_access(&img->base, old.y, old.x);
-       *(bool *)ft_mat_access(&img->calced, new.y, new.x)
-               = *(bool *)ft_mat_access(&img->calced, old.y, old.x);
-       return ;
-}
-
-void   move_img(t_img *img, int delta_x, int delta_y)
-{
-       int             x;
-       int             y;
-
-       x = 0;
-       if (delta_x < 0)
-               x = img->width - 1;
-       while (0 <= x && x < img->width)
-       {
-               y = 0;
-               if (delta_y < 0)
-                       y = img->height - 1;
-               while (0 <= y && y < img->height)
-               {
-                       if (0 <= x - delta_x && x - delta_x < img->width
-                               && 0 <= y - delta_y && y - delta_y < img->height)
-                               move_pixel(img, (t_vect2){.x = x, .y = y},
-                                       (t_vect2){.x = x - delta_x, .y = y - delta_y});
-                       if (!(0 <= x + delta_x && x + delta_x < img->width
-                                       && 0 <= y + delta_y && y + delta_y < img->height))
-                               *(bool *)ft_mat_access(&img->calced, y, x) = false;
-                       y += 1 - 2 * (delta_y < 0);
-               }
-               x += 1 - 2 * (delta_x < 0);
-       }
-       return ;
-}
-
-// move_amount is ratio of move distance to length one can see
-void   move_view(t_session *s, float move_amount_right, float move_amount_up)
-{
-       int     x_pix_change;
-       int     y_pix_change;
-
-       x_pix_change = round(move_amount_right * s->img.height);
-       if (x_pix_change == 0)
-               x_pix_change = (move_amount_right > 0) - (move_amount_right < 0);
-       y_pix_change = -round(move_amount_up * s->img.height);
-       if (y_pix_change == 0)
-               y_pix_change = -((move_amount_up > 0) - (move_amount_up < 0));
-       s->view.window_coord.x += x_pix_change * s->view.pixel_size.x;
-       s->view.window_coord.y -= y_pix_change * s->view.pixel_size.y;
-       move_img(&s->img, x_pix_change, y_pix_change);
-       s->img.undersample = s->img.undersample_max;
-       return ;
-}
-
-void   init_session(t_session *s)
-{
-       s->mlx = mlx_init();
-       s->win = mlx_new_window(s->mlx, s->img.width, s->img.height, "Fract-ol");
-       s->img.img = mlx_new_image(s->mlx, s->img.width, s->img.height);
-       s->img.addr = mlx_get_data_addr(s->img.img,
-                       &s->img.bpp, &s->img.bpl, &s->img.endian);
-       ft_mat_init(&s->img.calced, sizeof(bool));
-       ft_mat_init(&s->img.base, sizeof(double));
-       ft_mat_zeros(&s->img.calced, s->img.height, s->img.width);
-       ft_mat_zeros(&s->img.base, s->img.height, s->img.width);
-       s->img.undersample = s->img.undersample_max;
-}
-
-static void    init_view(t_session *s)
-{
-       s->view.window_coord.x = -s->img.width / 2 * s->view.pixel_size.x;
-       s->view.window_coord.y = s->img.height / 2 * s->view.pixel_size.y;
-       return ;
-}
-
 void   set_default(t_session *s)
 {
        s->img.width = 1920;
@@ -240,103 +35,6 @@ void       set_default(t_session *s)
        return ;
 }
 
-t_fractal      to_fractal(const char *name)
-{
-       if (!ft_strcmp(name, "man") || !ft_strcmp(name, "mandelbrot"))
-               return (mandelbrot);
-       else if (!ft_strcmp(name, "tri") || !ft_strcmp(name, "tricorn"))
-               return (tricorn);
-       else if (!ft_strcmp(name, "ju") || !ft_strcmp(name, "julia"))
-               return (julia);
-       else
-               return (NULL);
-}
-
-// The input has to be a single string of the form i1,i2,... without whitespace
-// There has to be correct number of inputs for the chosen fractal
-// The input has to be composed of integers
-int    is_correct_input(const char *str, t_fractal fractal)
-{
-       int     count;
-
-       count = 0;
-       while (*str)
-       {
-               ++count;
-               while (ft_isdigit(*str) || *str == '-')
-                       ++str;
-               if (*str == ',')
-                       ++str;
-               else if (*str != '\0')
-                       return (0);
-       }
-       if (fractal == julia && count != 2)
-               return (0);
-       return (1);
-}
-
-t_input        parse_input(const char *str, t_fractal fractal)
-{
-       t_input res;
-
-       if (fractal == julia)
-       {
-               res.cpx.r = ft_atoi(str) / 1000.;
-               while (ft_isdigit(*str) || *str == '-')
-                       ++str;
-               ++str;
-               res.cpx.i = ft_atoi(str) / 1000.;
-       }
-       return (res);
-}
-
-int    parse_arg(char **argv, t_session *s, int *i)
-{
-       if (!ft_strcmp(argv[*i], "-w")
-               && ft_isint(argv[*i + 1]) && ft_atoi(argv[*i + 1]) > 0)
-               s->img.width = ft_atoi(argv[++*i]);
-       else if (!ft_strcmp(argv[*i], "-h")
-               && ft_isint(argv[*i + 1]) && ft_atoi(argv[*i + 1]) > 0)
-               s->img.height = ft_atoi(argv[++*i]);
-       else if (!ft_strcmp(argv[*i], "-u")
-               && ft_isint(argv[*i + 1]) && ft_atoi(argv[*i + 1]) >= 0)
-               s->img.undersample_max = ft_atoi(argv[++*i]);
-       else if (!ft_strcmp(argv[*i], "-d") && ft_isint(argv[*i + 1]))
-               s->set.detail = ft_atoi(argv[++*i]);
-       else if (!ft_strcmp(argv[*i], "-f") && to_fractal(argv[*i + 1]) != NULL)
-               s->view.fractal = to_fractal(argv[++*i]);
-       else if (!ft_strcmp(argv[*i], "-s") && ft_isint(argv[*i + 1]))
-               s->view.color_shift_speed = ft_atoi(argv[++*i]) / 1000.;
-       else if (!ft_strcmp(argv[*i], "-c") && ft_isint(argv[*i + 1]))
-               s->set.color_stability = 10000 / ft_atoi(argv[++*i]);
-       else if (!ft_strcmp(argv[*i], "-i")
-               && is_correct_input(argv[*i + 1], s->view.fractal))
-               s->set.input = parse_input(argv[++*i], s->view.fractal);
-       else
-               return (1);
-       return (0);
-}
-
-int    parse_args(int argc, char **argv, t_session *s)
-{
-       int                     i;
-
-       if (argc % 2 == 0)
-               return (1);
-       set_default(s);
-       i = 1;
-       while (i + 1 < argc)
-       {
-               if (parse_arg(argv, s, &i))
-                       return (1);
-               ++i;
-       }
-       if (!s->view.fractal)
-               return (1);
-       init_view(s);
-       return (0);
-}
-
 void   print_help(void)
 {
        ft_printf("This is the help for fractol by Lukáš Jiřiště\n"
@@ -366,19 +64,11 @@ void       print_help(void)
                "\tThe color change can be sped up and down with 8 and 2 keys.\n");
 }
 
-void   cleanup(t_session *s)
-{
-       ft_mat_free(&s->img.calced, NULL);
-       ft_mat_free(&s->img.base, NULL);
-       mlx_destroy_image(s->mlx, s->img.img);
-       free_session(s);
-       return ;
-}
-
 int    main(int argc, char **argv)
 {
        t_session       s;
 
+       set_default(&s);
        if (parse_args(argc, argv, &s))
        {
                print_help();
diff --git a/src/parsing.c b/src/parsing.c
new file mode 100644 (file)
index 0000000..69789bb
--- /dev/null
@@ -0,0 +1,110 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   parsing.c                                          :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2024/04/26 10:47:46 by ljiriste          #+#    #+#             */
+/*   Updated: 2024/04/26 11:06:32 by ljiriste         ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#include "fractals.h"
+#include "fractol.h"
+#include "libft.h"
+
+static t_fractal       to_fractal(const char *name)
+{
+       if (!ft_strcmp(name, "man") || !ft_strcmp(name, "mandelbrot"))
+               return (mandelbrot);
+       else if (!ft_strcmp(name, "tri") || !ft_strcmp(name, "tricorn"))
+               return (tricorn);
+       else if (!ft_strcmp(name, "ju") || !ft_strcmp(name, "julia"))
+               return (julia);
+       else
+               return (NULL);
+}
+
+// The input has to be a single string of the form i1,i2,... without whitespace
+// There has to be correct number of inputs for the chosen fractal
+// The input has to be composed of integers
+static int     is_correct_input(const char *str, t_fractal fractal)
+{
+       int     count;
+
+       count = 0;
+       while (*str)
+       {
+               ++count;
+               while (ft_isdigit(*str) || *str == '-')
+                       ++str;
+               if (*str == ',')
+                       ++str;
+               else if (*str != '\0')
+                       return (0);
+       }
+       if (fractal == julia && count != 2)
+               return (0);
+       return (1);
+}
+
+static t_input parse_input(const char *str, t_fractal fractal)
+{
+       t_input res;
+
+       if (fractal == julia)
+       {
+               res.cpx.r = ft_atoi(str) / 1000.;
+               while (ft_isdigit(*str) || *str == '-')
+                       ++str;
+               ++str;
+               res.cpx.i = ft_atoi(str) / 1000.;
+       }
+       return (res);
+}
+
+static int     parse_arg(char **argv, t_session *s, int *i)
+{
+       if (!ft_strcmp(argv[*i], "-w")
+               && ft_isint(argv[*i + 1]) && ft_atoi(argv[*i + 1]) > 0)
+               s->img.width = ft_atoi(argv[++*i]);
+       else if (!ft_strcmp(argv[*i], "-h")
+               && ft_isint(argv[*i + 1]) && ft_atoi(argv[*i + 1]) > 0)
+               s->img.height = ft_atoi(argv[++*i]);
+       else if (!ft_strcmp(argv[*i], "-u")
+               && ft_isint(argv[*i + 1]) && ft_atoi(argv[*i + 1]) >= 0)
+               s->img.undersample_max = ft_atoi(argv[++*i]);
+       else if (!ft_strcmp(argv[*i], "-d") && ft_isint(argv[*i + 1]))
+               s->set.detail = ft_atoi(argv[++*i]);
+       else if (!ft_strcmp(argv[*i], "-f") && to_fractal(argv[*i + 1]) != NULL)
+               s->view.fractal = to_fractal(argv[++*i]);
+       else if (!ft_strcmp(argv[*i], "-s") && ft_isint(argv[*i + 1]))
+               s->view.color_shift_speed = ft_atoi(argv[++*i]) / 1000.;
+       else if (!ft_strcmp(argv[*i], "-c") && ft_isint(argv[*i + 1]))
+               s->set.color_stability = 10000 / ft_atoi(argv[++*i]);
+       else if (!ft_strcmp(argv[*i], "-i")
+               && is_correct_input(argv[*i + 1], s->view.fractal))
+               s->set.input = parse_input(argv[++*i], s->view.fractal);
+       else
+               return (1);
+       return (0);
+}
+
+int    parse_args(int argc, char **argv, t_session *s)
+{
+       int                     i;
+
+       if (argc % 2 == 0)
+               return (1);
+       i = 1;
+       while (i + 1 < argc)
+       {
+               if (parse_arg(argv, s, &i))
+                       return (1);
+               ++i;
+       }
+       if (!s->view.fractal)
+               return (1);
+       return (0);
+}
diff --git a/src/trans_view.c b/src/trans_view.c
new file mode 100644 (file)
index 0000000..d813ff1
--- /dev/null
@@ -0,0 +1,107 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   trans_view.c                                       :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2024/04/26 10:40:31 by ljiriste          #+#    #+#             */
+/*   Updated: 2024/04/26 11:06:57 by ljiriste         ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#include "fractol.h"
+#include "libft.h"
+#include <math.h>
+#include <stdbool.h>
+
+void   change_zoom(t_session *s, t_vect2 invariant, double d_zoom)
+{
+       s->view.pixel_size.x /= d_zoom;
+       s->view.pixel_size.y /= d_zoom;
+       s->view.window_coord.x += s->view.pixel_size.x * invariant.x * (d_zoom - 1);
+       s->view.window_coord.y -= s->view.pixel_size.y * invariant.y * (d_zoom - 1);
+       erase_calced(&s->img.calced);
+       s->img.undersample = s->img.undersample_max;
+       return ;
+}
+
+static void    move_pixel(t_img *img, t_vect2 old, t_vect2 new)
+{
+       *(double *)ft_mat_access(&img->base, new.y, new.x)
+               = *(double *)ft_mat_access(&img->base, old.y, old.x);
+       *(bool *)ft_mat_access(&img->calced, new.y, new.x)
+               = *(bool *)ft_mat_access(&img->calced, old.y, old.x);
+       return ;
+}
+
+static void    move_img(t_img *img, int delta_x, int delta_y)
+{
+       int             x;
+       int             y;
+
+       x = 0;
+       if (delta_x < 0)
+               x = img->width - 1;
+       while (0 <= x && x < img->width)
+       {
+               y = 0;
+               if (delta_y < 0)
+                       y = img->height - 1;
+               while (0 <= y && y < img->height)
+               {
+                       if (0 <= x - delta_x && x - delta_x < img->width
+                               && 0 <= y - delta_y && y - delta_y < img->height)
+                               move_pixel(img, (t_vect2){.x = x, .y = y},
+                                       (t_vect2){.x = x - delta_x, .y = y - delta_y});
+                       if (!(0 <= x + delta_x && x + delta_x < img->width
+                                       && 0 <= y + delta_y && y + delta_y < img->height))
+                               *(bool *)ft_mat_access(&img->calced, y, x) = false;
+                       y += 1 - 2 * (delta_y < 0);
+               }
+               x += 1 - 2 * (delta_x < 0);
+       }
+       return ;
+}
+
+// move_amount is ratio of move distance to length one can see
+void   move_view(t_session *s, float move_amount_right, float move_amount_up)
+{
+       int     x_pix_change;
+       int     y_pix_change;
+
+       x_pix_change = round(move_amount_right * s->img.height);
+       if (x_pix_change == 0)
+               x_pix_change = (move_amount_right > 0) - (move_amount_right < 0);
+       y_pix_change = -round(move_amount_up * s->img.height);
+       if (y_pix_change == 0)
+               y_pix_change = -((move_amount_up > 0) - (move_amount_up < 0));
+       s->view.window_coord.x += x_pix_change * s->view.pixel_size.x;
+       s->view.window_coord.y -= y_pix_change * s->view.pixel_size.y;
+       move_img(&s->img, x_pix_change, y_pix_change);
+       s->img.undersample = s->img.undersample_max;
+       return ;
+}
+
+void   change_shift_speed(double *speed, double mult, double thresh)
+{
+       if (-thresh < *speed && *speed < thresh)
+       {
+               if (mult > 0)
+                       *speed = thresh;
+               else
+                       *speed = -thresh;
+               return ;
+       }
+       if (*speed > 0 && mult > 0)
+               *speed *= mult;
+       else if (*speed > 0 && mult < 0)
+               *speed /= -mult;
+       else if (*speed < 0 && mult < 0)
+               *speed *= -mult;
+       else if (*speed < 0 && mult > 0)
+               *speed /= mult;
+       if (-thresh < *speed && *speed < thresh)
+               *speed = 0;
+       return ;
+}