From e0315979e0af0013331af0ab7fe9e5f7b58cb0f2 Mon Sep 17 00:00:00 2001 From: Lukas Jiriste Date: Fri, 26 Apr 2024 11:09:41 +0200 Subject: [PATCH] Refactor to multiple files to comply with the Norm --- Makefile | 5 + inc/fractol.h | 22 +-- src/cleanup.c | 39 ++++++ src/drawing.c | 114 ++++++++++++++++ src/event_handling.c | 40 ++---- src/init.c | 38 ++++++ src/main.c | 314 +------------------------------------------ src/parsing.c | 110 +++++++++++++++ src/trans_view.c | 107 +++++++++++++++ 9 files changed, 438 insertions(+), 351 deletions(-) create mode 100644 src/cleanup.c create mode 100644 src/drawing.c create mode 100644 src/init.c create mode 100644 src/parsing.c create mode 100644 src/trans_view.c diff --git a/Makefile b/Makefile index d252ab8..3b4f9f7 100644 --- 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)) diff --git a/inc/fractol.h b/inc/fractol.h index 4187dcc..1e7583f 100644 --- a/inc/fractol.h +++ b/inc/fractol.h @@ -6,7 +6,7 @@ /* By: ljiriste +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* 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 index 0000000..426686e --- /dev/null +++ b/src/cleanup.c @@ -0,0 +1,39 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* cleanup.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ljiriste +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* 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 +#include + +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 index 0000000..0592ba7 --- /dev/null +++ b/src/drawing.c @@ -0,0 +1,114 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* drawing.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ljiriste +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* 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 +#include +#include + +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 ; +} diff --git a/src/event_handling.c b/src/event_handling.c index 2612e53..98f2aac 100644 --- a/src/event_handling.c +++ b/src/event_handling.c @@ -6,7 +6,7 @@ /* By: ljiriste +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* 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 */ /* */ /* ************************************************************************** */ @@ -24,36 +24,13 @@ #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 index 0000000..607519c --- /dev/null +++ b/src/init.c @@ -0,0 +1,38 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* init.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ljiriste +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* 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 +#include + +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; +} diff --git a/src/main.c b/src/main.c index b0b6382..75d7e31 100644 --- a/src/main.c +++ b/src/main.c @@ -6,223 +6,18 @@ /* By: ljiriste +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* 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 #include -#include #include #include #include -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 index 0000000..69789bb --- /dev/null +++ b/src/parsing.c @@ -0,0 +1,110 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* parsing.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ljiriste +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* 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 index 0000000..d813ff1 --- /dev/null +++ b/src/trans_view.c @@ -0,0 +1,107 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* trans_view.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ljiriste +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* 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 +#include + +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 ; +} -- 2.30.2