From d66beb964dedbfd96037ad01c42c37dc29065d3f Mon Sep 17 00:00:00 2001 From: whaffman Date: Fri, 20 Dec 2024 12:28:29 +0100 Subject: [PATCH] Split files --- Makefile | 2 +- inc/fdf.h | 64 +++---- menu.png | Bin 18374 -> 55551 bytes scratch.txt | 33 ++++ src/{fdf_draw.c => draw/draw_line.c} | 31 ++-- src/draw/draw_menu.c | 25 +++ src/draw/get_gradient_color.c | 20 +++ src/draw/get_pixel_color.c | 23 +++ src/draw/get_z_color.c | 30 ++++ src/draw/interpolate_color.c | 34 ++++ src/draw/parse_color_string.c | 38 ++++ src/draw/prepare_draw.c | 10 ++ src/draw/put_pixel.c | 22 +++ src/{ => draw}/set_background.c | 2 +- src/fdf.c | 6 +- src/fdf_color.c | 99 ----------- src/fdf_hooks.c | 163 ------------------ src/fdf_rotations.c | 83 --------- src/hooks/close_hook.c | 26 +++ src/hooks/draw_hook.c | 39 +++++ src/hooks/fdf_hooks.c | 23 +++ src/hooks/key_hook.c | 22 +++ src/hooks/key_hook_options.c | 39 +++++ src/hooks/key_hook_transform.c | 37 ++++ src/hooks/resize_hook.c | 33 ++++ src/{ => parse}/get_map_sizes.c | 2 +- src/{ => parse}/get_z_max.c | 2 +- .../load_map_from_file.c} | 26 +-- src/{ => parse}/parse_map.c | 2 +- src/parse/set_map_point.c | 21 +++ src/transform/apply_rotation.c | 31 ++++ src/{ => transform}/deg2rad.c | 2 +- src/transform/project.c | 23 +++ src/{ => transform}/project_isometric.c | 54 +----- src/transform/project_parallel.c | 32 ++++ src/transform/project_trimetric.c | 36 ++++ src/transform/rotate_x.c | 28 +++ src/transform/rotate_y.c | 28 +++ src/transform/rotate_z.c | 30 ++++ src/util/check_filename.c | 25 +++ src/{ => util}/clean_fdf.c | 2 +- src/{ => util}/free_line_and_split.c | 2 +- src/{ => util}/handle_error.c | 2 +- src/{ => util}/init_mlx.c | 4 +- src/{ => util}/initialise_fdf.c | 27 +-- src/util/reset_fdf.c | 32 ++++ 46 files changed, 795 insertions(+), 520 deletions(-) create mode 100644 scratch.txt rename src/{fdf_draw.c => draw/draw_line.c} (72%) create mode 100644 src/draw/draw_menu.c create mode 100644 src/draw/get_gradient_color.c create mode 100644 src/draw/get_pixel_color.c create mode 100644 src/draw/get_z_color.c create mode 100644 src/draw/interpolate_color.c create mode 100644 src/draw/parse_color_string.c create mode 100644 src/draw/prepare_draw.c create mode 100644 src/draw/put_pixel.c rename src/{ => draw}/set_background.c (94%) delete mode 100644 src/fdf_color.c delete mode 100644 src/fdf_hooks.c delete mode 100644 src/fdf_rotations.c create mode 100644 src/hooks/close_hook.c create mode 100644 src/hooks/draw_hook.c create mode 100644 src/hooks/fdf_hooks.c create mode 100644 src/hooks/key_hook.c create mode 100644 src/hooks/key_hook_options.c create mode 100644 src/hooks/key_hook_transform.c create mode 100644 src/hooks/resize_hook.c rename src/{ => parse}/get_map_sizes.c (95%) rename src/{ => parse}/get_z_max.c (94%) rename src/{read_map_from_file.c => parse/load_map_from_file.c} (61%) rename src/{ => parse}/parse_map.c (95%) create mode 100644 src/parse/set_map_point.c create mode 100644 src/transform/apply_rotation.c rename src/{ => transform}/deg2rad.c (93%) create mode 100644 src/transform/project.c rename src/{ => transform}/project_isometric.c (50%) create mode 100644 src/transform/project_parallel.c create mode 100644 src/transform/project_trimetric.c create mode 100644 src/transform/rotate_x.c create mode 100644 src/transform/rotate_y.c create mode 100644 src/transform/rotate_z.c create mode 100644 src/util/check_filename.c rename src/{ => util}/clean_fdf.c (94%) rename src/{ => util}/free_line_and_split.c (94%) rename src/{ => util}/handle_error.c (94%) rename src/{ => util}/init_mlx.c (94%) rename src/{ => util}/initialise_fdf.c (73%) create mode 100644 src/util/reset_fdf.c diff --git a/Makefile b/Makefile index b9e74fb..a47d100 100644 --- a/Makefile +++ b/Makefile @@ -26,7 +26,7 @@ MLX42 = $(MLX42_PATH)/build/libmlx42.a OBJ_PATH = obj -VPATH = src +VPATH = src:src/parse:src/draw:src/hooks:src/util:src/transform SOURCES = $(shell basename -a $(shell find $(SRC_PATH) -type f -name "*.c")) OBJECTS = $(addprefix $(OBJ_PATH)/, $(SOURCES:.c=.o)) diff --git a/inc/fdf.h b/inc/fdf.h index c6743ef..56b37e4 100644 --- a/inc/fdf.h +++ b/inc/fdf.h @@ -18,10 +18,10 @@ # include # include # include -# include # include # include "libft.h" # include "MLX42.h" +# include # define SUCCESS 1 # define FAILURE 0 @@ -101,64 +101,48 @@ typedef struct s_fdf t_projection projection; } t_fdf; -int interpolate_color(t_point_2d start, - t_point_2d end, t_point_2d current); -int parse_color_string(char *str); -int get_map_sizes(char *filename, t_map *map); void free_line_and_split(char **line, char ***split); +int get_map_sizes(char *filename, t_map *map); int load_map_from_file(char *filename, t_fdf *fdf); int parse_map(char *filename, t_fdf *fdf); -void copy_map(t_fdf *fdf); -void fdf_apply_rotation(t_fdf *fdf); +void set_map_point(t_fdf *fdf, int x, int y, char **str); +int parse_color_string(char *str); +void get_z_max(t_fdf *fdf); void handle_error(t_fdf *fdf, char *error); +int fdf_hooks(t_fdf *fdf); +void resize_hook(int width, int height, void *param); +void draw_hook(void *param); +void key_hook(mlx_key_data_t keydata, void *param); + +mlx_image_t *draw_menu(t_fdf *fdf); +void apply_rotation(t_fdf *fdf); +int get_z_color(double z, int z_max); void rotate_x(t_point_3d **points, double angle, int size); void rotate_y(t_point_3d **points, double angle, int size); void rotate_z(t_point_3d **points, double angle, int size); -bool fdf_put_pixel(t_fdf *fdf, t_point_2d point); -void fdf_draw_line(t_fdf *fdf, t_point_2d start, - t_point_2d end); -int fdf_hooks(t_fdf *fdf); -void resize_hook(int width, int height, void *param); - -void draw_hook(void *param); -void key_hook(mlx_key_data_t keydata, void *param); -void fdf_set_background(mlx_image_t *img, int color); void project_isometric(t_fdf *fdf); +int interpolate_color(t_point_2d start, + t_point_2d end, t_point_2d current); +void draw_line(t_fdf *fdf, t_point_2d start, + t_point_2d end); +bool put_pixel(t_fdf *fdf, t_point_2d point); +void fdf_set_background(mlx_image_t *img, int color); double deg2rad(double deg); t_fdf *initialise_fdf(void); bool clean_fdf(t_fdf *fdf); -void get_z_max(t_fdf *fdf); int init_mlx(t_fdf *fdf); -void set_map_point(t_fdf *fdf, int x, int y, char **str); -mlx_image_t *draw_menu(t_fdf *fdf); -int get_z_color(double z, int z_max); void close_hook(void *param); int get_gradient_color(double z, int z_max); void project_parallel(t_fdf *fdf); +void project_trimetric(t_fdf *fdf); + void project(t_fdf *fdf); int check_filename(char *filename); void get_pixel_color(t_fdf *fdf, t_point_2d *point); void reset_fdf(t_fdf *fdf); - - +void prepare_draw(t_fdf *fdf); +void key_hook_options(mlx_key_data_t keydata, t_fdf *fdf); +void key_hook_transform(mlx_key_data_t keydata, t_fdf *fdf); #endif - -// FdF by whaffman -// ============================ - -// [?] Help menu -// [a] / [d] Rotate around Z-axis -// [w] / [s] Rotate around X-axis -// [q] / [e] Rotate around Y-axis -// [z] / [x] Change Z-scale -// [=] / [-] Change Zoom -// [UP] / [DOWN] Change X-offset -// [LEFT] / [RIGHT] Change Y-offset -// [[] / []] Change animation speed -// [c] Change colormode -// [p] Change projection mode -// [ESC] Close window - -// ============================ diff --git a/menu.png b/menu.png index bac62f45020c2d5d338c73e7954e9b286e8c9834..aaa512da0966bd00a3ba5605af971e65d607cc94 100644 GIT binary patch literal 55551 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, "[?] Help menu", x, y++ * line_height); + // mlx_put_string(fdf->mlx, "[a] / [d] Rotate around Z-axis", x, y++ * line_height); + // mlx_put_string(fdf->mlx, "[w] / [s] Rotate around X-axis", x, y++ * line_height); + // mlx_put_string(fdf->mlx, "[q] / [e] Rotate around Y-axis", x, y++ * line_height); + // mlx_put_string(fdf->mlx, "[z] / [x] Change Z-scale", x, y++ * line_height); + // mlx_put_string(fdf->mlx, "[=] / [-] Change Zoom", x, y++ * line_height); + // mlx_put_string(fdf->mlx, "[UP] / [DOWN] Change X-offset", x, y++ * line_height); + // mlx_put_string(fdf->mlx, "[LEFT] / [RIGHT] Change Y-offset", x, y++ * line_height); + // mlx_put_string(fdf->mlx, "[[] / []] Change animation speed", x, y++ * line_height); + // mlx_put_string(fdf->mlx, "[ESC] Close window", x, y++ * line_height); diff --git a/src/fdf_draw.c b/src/draw/draw_line.c similarity index 72% rename from src/fdf_draw.c rename to src/draw/draw_line.c index 30c2882..a45fbc7 100644 --- a/src/fdf_draw.c +++ b/src/draw/draw_line.c @@ -1,26 +1,17 @@ /* ************************************************************************** */ /* */ /* ::: o_ :::::: ::: */ -/* fdf_draw.c :+: / :+::+: :+: */ +/* draw_line.c :+: / :+::+: :+: */ /* +:+ > +:++:+ +:+ */ /* By: whaffman +#+ +:+ +#++#++:++#++ */ /* +#+ +#+#+ +#++#+ +#+ \o/ */ /* Created: 2024/12/08 11:45:12 by whaffman #+#+# #+#+# #+# #+# | */ -/* Updated: 2024/12/13 15:23:12 by whaffman ### ### ### ### / \ */ +/* Updated: 2024/12/20 11:21:15 by whaffman ### ### ### ### / \ */ /* */ /* ************************************************************************** */ #include "fdf.h" -bool fdf_put_pixel(t_fdf *fdf, t_point_2d point) -{ - if (point.x < 0 || point.x >= (int) fdf->img->width - || point.y < 0 || point.y >= (int) fdf->img->height) - return (false); - mlx_put_pixel(fdf->img, point.x, point.y, point.color); - return (true); -} - -void fdf_draw_line_low(t_fdf *fdf, t_point_2d start, t_point_2d end) +void draw_line_low(t_fdf *fdf, t_point_2d start, t_point_2d end) { int delta; int yi; @@ -37,7 +28,7 @@ void fdf_draw_line_low(t_fdf *fdf, t_point_2d start, t_point_2d end) while (current.x <= end.x) { current.color = interpolate_color(start, end, current); - fdf_put_pixel(fdf, current); + put_pixel(fdf, current); if (delta > 0) { current.y += yi; @@ -48,7 +39,7 @@ void fdf_draw_line_low(t_fdf *fdf, t_point_2d start, t_point_2d end) } } -void fdf_draw_line_high(t_fdf *fdf, t_point_2d start, t_point_2d end) +void draw_line_high(t_fdf *fdf, t_point_2d start, t_point_2d end) { int delta; int xi; @@ -65,7 +56,7 @@ void fdf_draw_line_high(t_fdf *fdf, t_point_2d start, t_point_2d end) while (current.y <= end.y) { current.color = interpolate_color(start, end, current); - fdf_put_pixel(fdf, current); + put_pixel(fdf, current); if (delta > 0) { current.x += xi; @@ -76,7 +67,7 @@ void fdf_draw_line_high(t_fdf *fdf, t_point_2d start, t_point_2d end) } } -void fdf_draw_line(t_fdf *fdf, t_point_2d start, t_point_2d end) +void draw_line(t_fdf *fdf, t_point_2d start, t_point_2d end) { if ((start.x < 0 || start.x >= (int) fdf->img->width || start.y < 0 || start.y >= (int) fdf->img->height) @@ -86,15 +77,15 @@ void fdf_draw_line(t_fdf *fdf, t_point_2d start, t_point_2d end) if (abs(end.y - start.y) < abs(end.x - start.x)) { if (start.x > end.x) - fdf_draw_line_low(fdf, end, start); + draw_line_low(fdf, end, start); else - fdf_draw_line_low(fdf, start, end); + draw_line_low(fdf, start, end); } else { if (start.y > end.y) - fdf_draw_line_high(fdf, end, start); + draw_line_high(fdf, end, start); else - fdf_draw_line_high(fdf, start, end); + draw_line_high(fdf, start, end); } } diff --git a/src/draw/draw_menu.c b/src/draw/draw_menu.c new file mode 100644 index 0000000..3486c2a --- /dev/null +++ b/src/draw/draw_menu.c @@ -0,0 +1,25 @@ +/* ************************************************************************** */ +/* */ +/* ::: o_ :::::: ::: */ +/* draw_menu.c :+: / :+::+: :+: */ +/* +:+ > +:++:+ +:+ */ +/* By: whaffman +#+ +:+ +#++#++:++#++ */ +/* +#+ +#+#+ +#++#+ +#+ \o/ */ +/* Created: 2024/12/20 11:21:20 by whaffman #+#+# #+#+# #+# #+# | */ +/* Updated: 2024/12/20 11:21:20 by whaffman ### ### ### ### / \ */ +/* */ +/* ************************************************************************** */ + +#include "fdf.h" + +mlx_image_t *draw_menu(t_fdf *fdf) +{ + mlx_texture_t *texture; + mlx_image_t *img; + + texture = mlx_load_png("menu.png"); + img = mlx_texture_to_image(fdf->mlx, texture); + mlx_delete_texture(texture); + mlx_image_to_window(fdf->mlx, img, 10, 10); + return (img); +} diff --git a/src/draw/get_gradient_color.c b/src/draw/get_gradient_color.c new file mode 100644 index 0000000..51cf4de --- /dev/null +++ b/src/draw/get_gradient_color.c @@ -0,0 +1,20 @@ +/* ************************************************************************** */ +/* */ +/* ::: o_ :::::: ::: */ +/* get_gradient_color.c :+: / :+::+: :+: */ +/* +:+ > +:++:+ +:+ */ +/* By: whaffman +#+ +:+ +#++#++:++#++ */ +/* +#+ +#+#+ +#++#+ +#+ \o/ */ +/* Created: 2024/12/20 11:21:22 by whaffman #+#+# #+#+# #+# #+# | */ +/* Updated: 2024/12/20 11:21:22 by whaffman ### ### ### ### / \ */ +/* */ +/* ************************************************************************** */ + +int get_gradient_color(double z, int z_max) +{ + const int colors[] = {0x0058fbff, 0x007efeff, 0x008fd7ff, 0x0098a3ff, + 0x009c7aff, 0x1fa46bff, 0x5eb13dff, 0x83c052ff, + 0xa5cf69ff, 0xc3de81ff, 0xeeffffff, 0xffffffff, 0xffffffff}; + + return (colors[(int)(z * 12 / z_max)]); +} diff --git a/src/draw/get_pixel_color.c b/src/draw/get_pixel_color.c new file mode 100644 index 0000000..4a147aa --- /dev/null +++ b/src/draw/get_pixel_color.c @@ -0,0 +1,23 @@ +/* ************************************************************************** */ +/* */ +/* ::: o_ :::::: ::: */ +/* get_pixel_color.c :+: / :+::+: :+: */ +/* +:+ > +:++:+ +:+ */ +/* By: whaffman +#+ +:+ +#++#++:++#++ */ +/* +#+ +#+#+ +#++#+ +#+ \o/ */ +/* Created: 2024/12/20 11:21:23 by whaffman #+#+# #+#+# #+# #+# | */ +/* Updated: 2024/12/20 11:21:23 by whaffman ### ### ### ### / \ */ +/* */ +/* ************************************************************************** */ + +#include "fdf.h" + +void get_pixel_color(t_fdf *fdf, t_point_2d *point) +{ + if (fdf->colormode == COLOR_MODE_DEFAULT) + point->color = point->color; + else if (fdf->colormode == COLOR_MODE_Z) + point->color = get_z_color(point->orig_z, fdf->map->z_max); + else if (fdf->colormode == COLOR_MODE_GRADIENT) + point->color = get_gradient_color(point->orig_z, fdf->map->z_max); +} diff --git a/src/draw/get_z_color.c b/src/draw/get_z_color.c new file mode 100644 index 0000000..d1a1e66 --- /dev/null +++ b/src/draw/get_z_color.c @@ -0,0 +1,30 @@ +/* ************************************************************************** */ +/* */ +/* ::: o_ :::::: ::: */ +/* get_z_color.c :+: / :+::+: :+: */ +/* +:+ > +:++:+ +:+ */ +/* By: whaffman +#+ +:+ +#++#++:++#++ */ +/* +#+ +#+#+ +#++#+ +#+ \o/ */ +/* Created: 2024/12/20 11:21:24 by whaffman #+#+# #+#+# #+# #+# | */ +/* Updated: 2024/12/20 11:21:24 by whaffman ### ### ### ### / \ */ +/* */ +/* ************************************************************************** */ + +int get_z_color(double z, int z_max) +{ + int red; + int green; + int blue; + + red = 0; + green = 0; + blue = 0; + if (z < 0) + blue = 127; + else + { + red = 255 * z / z_max; + green = 255 - red; + } + return (red << 24 | green << 16 | blue << 8 | 0x00FF); +} diff --git a/src/draw/interpolate_color.c b/src/draw/interpolate_color.c new file mode 100644 index 0000000..4e04a23 --- /dev/null +++ b/src/draw/interpolate_color.c @@ -0,0 +1,34 @@ +/* ************************************************************************** */ +/* */ +/* ::: o_ :::::: ::: */ +/* interpolate_color.c :+: / :+::+: :+: */ +/* +:+ > +:++:+ +:+ */ +/* By: whaffman +#+ +:+ +#++#++:++#++ */ +/* +#+ +#+#+ +#++#+ +#+ \o/ */ +/* Created: 2024/12/20 11:21:25 by whaffman #+#+# #+#+# #+# #+# | */ +/* Updated: 2024/12/20 11:21:25 by whaffman ### ### ### ### / \ */ +/* */ +/* ************************************************************************** */ + +#include "fdf.h" + +int interpolate_color(t_point_2d start, t_point_2d end, t_point_2d current) +{ + int dcur; + int dtotal; + int red; + int green; + int blue; + + dcur = fmax(abs(current.x - start.x), abs(current.y - start.y)); + dtotal = fmax(abs(end.x - start.x), abs(end.y - start.y)); + if (dtotal == 0) + return (start.color); + red = (int)((1 - (double) dcur / dtotal) * (start.color >> 24 & 0xFF) + + (double) dcur / dtotal * (end.color >> 24 & 0xFF)); + green = (int)((1 - (double) dcur / dtotal) * (start.color >> 16 & 0xFF) + + (double) dcur / dtotal * (end.color >> 16 & 0xFF)); + blue = (int)((1 - (double) dcur / dtotal) * (start.color >> 8 & 0xFF) + + (double) dcur / dtotal * (end.color >> 8 & 0xFF)); + return (red << 24 | green << 16 | blue << 8 | 0xFF); +} diff --git a/src/draw/parse_color_string.c b/src/draw/parse_color_string.c new file mode 100644 index 0000000..92e017b --- /dev/null +++ b/src/draw/parse_color_string.c @@ -0,0 +1,38 @@ +/* ************************************************************************** */ +/* */ +/* ::: o_ :::::: ::: */ +/* parse_color_string.c :+: / :+::+: :+: */ +/* +:+ > +:++:+ +:+ */ +/* By: whaffman +#+ +:+ +#++#++:++#++ */ +/* +#+ +#+#+ +#++#+ +#+ \o/ */ +/* Created: 2024/12/13 15:23:11 by whaffman #+#+# #+#+# #+# #+# | */ +/* Updated: 2024/12/20 11:21:25 by whaffman ### ### ### ### / \ */ +/* */ +/* ************************************************************************** */ + +#include "fdf.h" + +int parse_color_string(char *str) +{ + int color; + int i; + char *color_str; + + color = 0; + i = 1; + color_str = ft_strchr(str, ','); + if (!color_str || *++color_str != '0' || *++color_str != 'x') + return (0xFFFFFFFF); + while (color_str[i]) + { + if (ft_isdigit(color_str[i])) + color = color * 16 + color_str[i] - '0'; + else if (ft_tolower(color_str[i]) >= 'a' + && ft_tolower(color_str[i]) <= 'f') + color = color * 16 + ft_tolower(color_str[i]) - 'a' + 10; + else + break ; + i++; + } + return ((color << 8) + 0xFF); +} diff --git a/src/draw/prepare_draw.c b/src/draw/prepare_draw.c new file mode 100644 index 0000000..4fbd486 --- /dev/null +++ b/src/draw/prepare_draw.c @@ -0,0 +1,10 @@ +#include "fdf.h" + +void prepare_draw(t_fdf *fdf) +{ + fdf_set_background(fdf->img, 0x000000FF); + if (fdf->animate_z) + fdf->angle_z += deg2rad(fdf->animate_z); + apply_rotation(fdf); + project(fdf); +} diff --git a/src/draw/put_pixel.c b/src/draw/put_pixel.c new file mode 100644 index 0000000..ed28028 --- /dev/null +++ b/src/draw/put_pixel.c @@ -0,0 +1,22 @@ +/* ************************************************************************** */ +/* */ +/* ::: o_ :::::: ::: */ +/* put_pixel.c :+: / :+::+: :+: */ +/* +:+ > +:++:+ +:+ */ +/* By: whaffman +#+ +:+ +#++#++:++#++ */ +/* +#+ +#+#+ +#++#+ +#+ \o/ */ +/* Created: 2024/12/20 11:21:26 by whaffman #+#+# #+#+# #+# #+# | */ +/* Updated: 2024/12/20 11:21:26 by whaffman ### ### ### ### / \ */ +/* */ +/* ************************************************************************** */ + +#include "fdf.h" + +bool put_pixel(t_fdf *fdf, t_point_2d point) +{ + if (point.x < 0 || point.x >= (int) fdf->img->width + || point.y < 0 || point.y >= (int) fdf->img->height) + return (false); + mlx_put_pixel(fdf->img, point.x, point.y, point.color); + return (true); +} diff --git a/src/set_background.c b/src/draw/set_background.c similarity index 94% rename from src/set_background.c rename to src/draw/set_background.c index 371b5d0..ca7b0ad 100644 --- a/src/set_background.c +++ b/src/draw/set_background.c @@ -6,7 +6,7 @@ /* By: whaffman +#+ +:+ +#++#++:++#++ */ /* +#+ +#+#+ +#++#+ +#+ \o/ */ /* Created: 2024/12/13 15:23:20 by whaffman #+#+# #+#+# #+# #+# | */ -/* Updated: 2024/12/13 15:23:20 by whaffman ### ### ### ### / \ */ +/* Updated: 2024/12/20 11:21:27 by whaffman ### ### ### ### / \ */ /* */ /* ************************************************************************** */ diff --git a/src/fdf.c b/src/fdf.c index dacff2b..a01e304 100644 --- a/src/fdf.c +++ b/src/fdf.c @@ -6,7 +6,7 @@ /* By: whaffman +#+ +:+ +#++#++:++#++ */ /* +#+ +#+#+ +#++#+ +#+ \o/ */ /* Created: 2024/12/06 11:07:30 by whaffman #+#+# #+#+# #+# #+# | */ -/* Updated: 2024/12/13 15:23:10 by whaffman ### ### ### ### / \ */ +/* Updated: 2024/12/20 11:21:28 by whaffman ### ### ### ### / \ */ /* */ /* ************************************************************************** */ @@ -17,9 +17,9 @@ int main(int argc, char *argv[]) t_fdf *fdf; fdf = initialise_fdf(); - if (argc != 2 ) + if (argc != 2) handle_error(fdf, "Usage: ./fdf "); - if(!check_filename(argv[1])) + if (!check_filename(argv[1])) handle_error(fdf, "Error: wrong file extension"); if (!parse_map(argv[1], fdf)) handle_error(fdf, "Error: failed to parse map"); diff --git a/src/fdf_color.c b/src/fdf_color.c deleted file mode 100644 index f0e0727..0000000 --- a/src/fdf_color.c +++ /dev/null @@ -1,99 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: o_ :::::: ::: */ -/* fdf_color.c :+: / :+::+: :+: */ -/* +:+ > +:++:+ +:+ */ -/* By: whaffman +#+ +:+ +#++#++:++#++ */ -/* +#+ +#+#+ +#++#+ +#+ \o/ */ -/* Created: 2024/12/13 15:23:11 by whaffman #+#+# #+#+# #+# #+# | */ -/* Updated: 2024/12/13 15:23:11 by whaffman ### ### ### ### / \ */ -/* */ -/* ************************************************************************** */ - -#include "fdf.h" - -int parse_color_string(char *str) -{ - int color; - int i; - char *color_str; - - color = 0; - i = 1; - color_str = ft_strchr(str, ','); - if (!color_str || *++color_str != '0' || *++color_str != 'x') - return (0xFFFFFFFF); - while (color_str[i]) - { - if (ft_isdigit(color_str[i])) - color = color * 16 + color_str[i] - '0'; - else if (ft_tolower(color_str[i]) >= 'a' - && ft_tolower(color_str[i]) <= 'f') - color = color * 16 + ft_tolower(color_str[i]) - 'a' + 10; - else - break ; - i++; - } - return ((color << 8) + 0xFF); -} - -void get_pixel_color(t_fdf *fdf, t_point_2d *point) -{ - if (fdf->colormode == COLOR_MODE_DEFAULT) - point->color = point->color; - else if (fdf->colormode == COLOR_MODE_Z) - point->color = get_z_color(point->orig_z, fdf->map->z_max); - else if (fdf->colormode == COLOR_MODE_GRADIENT) - point->color = get_gradient_color(point->orig_z, fdf->map->z_max); - -} - -int interpolate_color(t_point_2d start, t_point_2d end, t_point_2d current) -{ - int dcur; - int dtotal; - int red; - int green; - int blue; - - dcur = fmax(abs(current.x - start.x), abs(current.y - start.y)); - dtotal = fmax(abs(end.x - start.x), abs(end.y - start.y)); - if (dtotal == 0) - return (start.color); - red = (int)((1 - (double) dcur / dtotal) * (start.color >> 24 & 0xFF) - + (double) dcur / dtotal * (end.color >> 24 & 0xFF)); - green = (int)((1 - (double) dcur / dtotal) * (start.color >> 16 & 0xFF) - + (double) dcur / dtotal * (end.color >> 16 & 0xFF)); - blue = (int)((1 - (double) dcur / dtotal) * (start.color >> 8 & 0xFF) - + (double) dcur / dtotal * (end.color >> 8 & 0xFF)); - return (red << 24 | green << 16 | blue << 8 | 0xFF); -} - -int get_z_color(double z, int z_max) -{ - int red; - int green; - int blue; - - red = 0; - green = 0; - blue = 0; - if(z < 0) - blue = 127; - else - { - red = 255 * z / z_max; - green = 255 - red; - } - return (red << 24 | green << 16 | blue << 8 | 0x00FF); -} - -int get_gradient_color(double z, int z_max) -{ - const int colors[] = {0x0058fbff, 0x007efeff, 0x008fd7ff, 0x0098a3ff, - 0x009c7aff, 0x1fa46bff, 0x5eb13dff, 0x83c052ff, - 0xa5cf69ff, 0xc3de81ff, 0xeeffffff, 0xffffffff,0xffffffff}; - - return (colors[(int)(z * 12 / z_max)]); -} - diff --git a/src/fdf_hooks.c b/src/fdf_hooks.c deleted file mode 100644 index 8c76e3f..0000000 --- a/src/fdf_hooks.c +++ /dev/null @@ -1,163 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: o_ :::::: ::: */ -/* fdf_hooks.c :+: / :+::+: :+: */ -/* +:+ > +:++:+ +:+ */ -/* By: whaffman +#+ +:+ +#++#++:++#++ */ -/* +#+ +#+#+ +#++#+ +#+ \o/ */ -/* Created: 2024/12/13 15:23:12 by whaffman #+#+# #+#+# #+# #+# | */ -/* Updated: 2024/12/13 15:23:12 by whaffman ### ### ### ### / \ */ -/* */ -/* ************************************************************************** */ - -#include "fdf.h" -#include "MLX42.h" - -int fdf_hooks(t_fdf *fdf) -{ - mlx_loop_hook(fdf->mlx, draw_hook, fdf); - mlx_key_hook(fdf->mlx, key_hook, fdf); - mlx_close_hook(fdf->mlx, close_hook, fdf); - mlx_resize_hook(fdf->mlx, resize_hook, fdf); - return (1); -} - -void resize_hook(int width, int height, void *param) -{ - t_fdf *fdf; - - (void)width; - (void)height; - fdf = (t_fdf *)param; - mlx_delete_image(fdf->mlx, fdf->img); - fdf->img = mlx_new_image(fdf->mlx, fdf->mlx->width, fdf->mlx->height); - if (!fdf->img - || (mlx_image_to_window(fdf->mlx, fdf->img, 0, 0) < 0) - || (mlx_image_to_window(fdf->mlx, fdf->menu, 10, 10) < 0)) - exit(1); - fdf->offset_x += (fdf->mlx->width - fdf->last_width) / 2 ; - fdf->offset_y += (fdf->mlx->height - fdf->last_height) / 2; - fdf->zoom = 0; - fdf->last_height = fdf->mlx->height; - fdf->last_width = fdf->mlx->width; -} - -void draw_hook(void *param) -{ - t_fdf *fdf; - int i; - - fdf = (t_fdf *)param; - if (fdf->last_width != fdf->mlx->width - || fdf->last_height != fdf->mlx->height) - { - resize_hook(fdf->mlx->width, fdf->mlx->height, fdf); - return ; - } - fdf_set_background(fdf->img, 0x000000FF); - if (fdf->animate_z) - fdf->angle_z += deg2rad(fdf->animate_z); - fdf_apply_rotation(fdf); - project(fdf); - i = 0; - while (i < fdf->map->width * fdf->map->height) - { - fdf_put_pixel(fdf, fdf->map->proj[i]); - if (i % fdf->map->width != fdf->map->width - 1) - fdf_draw_line(fdf, fdf->map->proj[i], fdf->map->proj[i + 1]); - if (i / fdf->map->width != fdf->map->height - 1) - fdf_draw_line(fdf, fdf->map->proj[i], fdf->map->proj[i + fdf->map->width]); - i++; - } - // draw_menu(fdf); -} -mlx_image_t *draw_menu(t_fdf *fdf) -{ - // const int x = 20; - // const int line_height = 25; - // int y; - mlx_texture_t *texture; - mlx_image_t *img; - - // y = 1; - - texture = mlx_load_png("menu.png"); - img = mlx_texture_to_image(fdf->mlx, texture); - mlx_delete_texture(texture); - mlx_image_to_window(fdf->mlx, img, 10, 10); - // mlx_put_string(fdf->mlx, "[?] Help menu", x, y++ * line_height); - // mlx_put_string(fdf->mlx, "[a] / [d] Rotate around Z-axis", x, y++ * line_height); - // mlx_put_string(fdf->mlx, "[w] / [s] Rotate around X-axis", x, y++ * line_height); - // mlx_put_string(fdf->mlx, "[q] / [e] Rotate around Y-axis", x, y++ * line_height); - // mlx_put_string(fdf->mlx, "[z] / [x] Change Z-scale", x, y++ * line_height); - // mlx_put_string(fdf->mlx, "[=] / [-] Change Zoom", x, y++ * line_height); - // mlx_put_string(fdf->mlx, "[UP] / [DOWN] Change X-offset", x, y++ * line_height); - // mlx_put_string(fdf->mlx, "[LEFT] / [RIGHT] Change Y-offset", x, y++ * line_height); - // mlx_put_string(fdf->mlx, "[[] / []] Change animation speed", x, y++ * line_height); - // mlx_put_string(fdf->mlx, "[ESC] Close window", x, y++ * line_height); - - return (img); -} - -void close_hook(void *param) -{ - t_fdf *fdf; - - fdf = (t_fdf *)param; - mlx_close_window(fdf->mlx); - mlx_delete_image(fdf->mlx, fdf->img); - mlx_delete_image(fdf->mlx, fdf->menu); - mlx_terminate(fdf->mlx); - clean_fdf(fdf); - exit(0); -} - -void key_hook(mlx_key_data_t keydata, void *param) -{ - t_fdf *fdf; - - fdf = (t_fdf *)param; - if (keydata.key == MLX_KEY_ESCAPE) - close_hook(fdf); - if (keydata.key == MLX_KEY_A && keydata.action != MLX_RELEASE) - fdf->angle_z -= deg2rad(5); - if (keydata.key == MLX_KEY_D && keydata.action != MLX_RELEASE) - fdf->angle_z += deg2rad(5); - if (keydata.key == MLX_KEY_W && keydata.action != MLX_RELEASE) - fdf->angle_x -= deg2rad(5); - if (keydata.key == MLX_KEY_S && keydata.action != MLX_RELEASE) - fdf->angle_x += deg2rad(5); - if (keydata.key == MLX_KEY_Q && keydata.action != MLX_RELEASE) - fdf->angle_y -= deg2rad(5); - if (keydata.key == MLX_KEY_E && keydata.action != MLX_RELEASE) - fdf->angle_y += deg2rad(5); - if (keydata.key == MLX_KEY_X && keydata.action != MLX_RELEASE) - fdf->z_scale *= 1.05; - if (keydata.key == MLX_KEY_Z && keydata.action != MLX_RELEASE) - fdf->z_scale /= 1.05; - if (keydata.key == MLX_KEY_UP && keydata.action != MLX_RELEASE) - fdf->offset_y -= 10; - if (keydata.key == MLX_KEY_DOWN && keydata.action != MLX_RELEASE) - fdf->offset_y += 10; - if (keydata.key == MLX_KEY_LEFT && keydata.action != MLX_RELEASE) - fdf->offset_x -= 10; - if (keydata.key == MLX_KEY_RIGHT && keydata.action != MLX_RELEASE) - fdf->offset_x += 10; - if (keydata.key == MLX_KEY_EQUAL && keydata.action != MLX_RELEASE) - fdf->zoom *= 1.1; - if (keydata.key == MLX_KEY_MINUS && keydata.action != MLX_RELEASE) - fdf->zoom /= 1.1; - if (keydata.key == MLX_KEY_LEFT_BRACKET && keydata.action == MLX_PRESS) - fdf->animate_z -= 0.5; - if (keydata.key == MLX_KEY_RIGHT_BRACKET && keydata.action == MLX_PRESS) - fdf->animate_z += 0.5; - if (keydata.key == MLX_KEY_SLASH && keydata.action == MLX_PRESS) - fdf->menu->enabled = !fdf->menu->enabled; - if (keydata.key == MLX_KEY_C && keydata.action == MLX_PRESS) - fdf->colormode = (fdf->colormode + 1) % 3; - if (keydata.key == MLX_KEY_P && keydata.action == MLX_PRESS) - fdf->projection = (fdf->projection + 1) % 3; - if (keydata.key == MLX_KEY_SPACE && keydata.action == MLX_PRESS) - reset_fdf(fdf); - -} diff --git a/src/fdf_rotations.c b/src/fdf_rotations.c deleted file mode 100644 index 683df8b..0000000 --- a/src/fdf_rotations.c +++ /dev/null @@ -1,83 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: o_ :::::: ::: */ -/* fdf_rotations.c :+: / :+::+: :+: */ -/* +:+ > +:++:+ +:+ */ -/* By: whaffman +#+ +:+ +#++#++:++#++ */ -/* +#+ +#+#+ +#++#+ +#+ \o/ */ -/* Created: 2024/12/13 15:23:13 by whaffman #+#+# #+#+# #+# #+# | */ -/* Updated: 2024/12/13 15:23:13 by whaffman ### ### ### ### / \ */ -/* */ -/* ************************************************************************** */ - -#include "fdf.h" - -void fdf_apply_rotation(t_fdf *fdf) -{ - copy_map(fdf); - rotate_x(&fdf->map->rot, fdf->angle_x, fdf->map->width * fdf->map->height); - rotate_y(&fdf->map->rot, fdf->angle_y, fdf->map->width * fdf->map->height); - rotate_z(&fdf->map->rot, fdf->angle_z, fdf->map->width * fdf->map->height); -} - -void copy_map(t_fdf *fdf) -{ - int i; - - i = 0; - while (i < fdf->map->width * fdf->map->height) - { - fdf->map->rot[i].x = fdf->map->orig[i].x; - fdf->map->rot[i].y = fdf->map->orig[i].y; - fdf->map->rot[i].z = fdf->map->orig[i].z * fdf->z_scale; - fdf->map->rot[i].color = fdf->map->orig[i].color; - i++; - } -} - -void rotate_x(t_point_3d **points, double angle, int size) -{ - int i; - double previous_y; - - i = 0; - while (i < size) - { - previous_y = (*points)[i].y; - (*points)[i].y = previous_y * cos(angle) + (*points)[i].z * sin(angle); - (*points)[i].z = -previous_y * sin(angle) + (*points)[i].z * cos(angle); - i++; - } -} - -void rotate_y(t_point_3d **points, double angle, int size) -{ - int i; - double previous_x; - - i = 0; - while (i < size) - { - previous_x = (*points)[i].x; - (*points)[i].x = previous_x * cos(angle) + (*points)[i].z * sin(angle); - (*points)[i].z = -previous_x * sin(angle) + (*points)[i].z * cos(angle); - i++; - } -} - -void rotate_z(t_point_3d **points, double angle, int size) -{ - int i; - double previous_x; - double previous_y; - - i = 0; - while (i < size) - { - previous_x = (*points)[i].x; - previous_y = (*points)[i].y; - (*points)[i].x = previous_x * cos(angle) - previous_y * sin(angle); - (*points)[i].y = previous_x * sin(angle) + previous_y * cos(angle); - i++; - } -} diff --git a/src/hooks/close_hook.c b/src/hooks/close_hook.c new file mode 100644 index 0000000..e6054dc --- /dev/null +++ b/src/hooks/close_hook.c @@ -0,0 +1,26 @@ +/* ************************************************************************** */ +/* */ +/* ::: o_ :::::: ::: */ +/* close_hook.c :+: / :+::+: :+: */ +/* +:+ > +:++:+ +:+ */ +/* By: whaffman +#+ +:+ +#++#++:++#++ */ +/* +#+ +#+#+ +#++#+ +#+ \o/ */ +/* Created: 2024/12/20 11:21:28 by whaffman #+#+# #+#+# #+# #+# | */ +/* Updated: 2024/12/20 11:21:28 by whaffman ### ### ### ### / \ */ +/* */ +/* ************************************************************************** */ + +#include "fdf.h" + +void close_hook(void *param) +{ + t_fdf *fdf; + + fdf = (t_fdf *)param; + mlx_close_window(fdf->mlx); + mlx_delete_image(fdf->mlx, fdf->img); + mlx_delete_image(fdf->mlx, fdf->menu); + mlx_terminate(fdf->mlx); + clean_fdf(fdf); + exit(0); +} diff --git a/src/hooks/draw_hook.c b/src/hooks/draw_hook.c new file mode 100644 index 0000000..5b9ac8a --- /dev/null +++ b/src/hooks/draw_hook.c @@ -0,0 +1,39 @@ +/* ************************************************************************** */ +/* */ +/* ::: o_ :::::: ::: */ +/* draw_hook.c :+: / :+::+: :+: */ +/* +:+ > +:++:+ +:+ */ +/* By: whaffman +#+ +:+ +#++#++:++#++ */ +/* +#+ +#+#+ +#++#+ +#+ \o/ */ +/* Created: 2024/12/20 11:21:29 by whaffman #+#+# #+#+# #+# #+# | */ +/* Updated: 2024/12/20 11:21:29 by whaffman ### ### ### ### / \ */ +/* */ +/* ************************************************************************** */ + +#include "fdf.h" + +void draw_hook(void *param) +{ + t_fdf *fdf; + int i; + + fdf = (t_fdf *)param; + if (fdf->last_width != fdf->mlx->width + || fdf->last_height != fdf->mlx->height) + { + resize_hook(fdf->mlx->width, fdf->mlx->height, fdf); + return ; + } + prepare_draw(fdf); + i = 0; + while (i < fdf->map->width * fdf->map->height) + { + put_pixel(fdf, fdf->map->proj[i]); + if (i % fdf->map->width != fdf->map->width - 1) + draw_line(fdf, fdf->map->proj[i], fdf->map->proj[i + 1]); + if (i / fdf->map->width != fdf->map->height - 1) + draw_line(fdf, fdf->map->proj[i], + fdf->map->proj[i + fdf->map->width]); + i++; + } +} diff --git a/src/hooks/fdf_hooks.c b/src/hooks/fdf_hooks.c new file mode 100644 index 0000000..13da142 --- /dev/null +++ b/src/hooks/fdf_hooks.c @@ -0,0 +1,23 @@ +/* ************************************************************************** */ +/* */ +/* ::: o_ :::::: ::: */ +/* fdf_hooks.c :+: / :+::+: :+: */ +/* +:+ > +:++:+ +:+ */ +/* By: whaffman +#+ +:+ +#++#++:++#++ */ +/* +#+ +#+#+ +#++#+ +#+ \o/ */ +/* Created: 2024/12/13 15:23:12 by whaffman #+#+# #+#+# #+# #+# | */ +/* Updated: 2024/12/20 11:21:30 by whaffman ### ### ### ### / \ */ +/* */ +/* ************************************************************************** */ + +#include "fdf.h" +#include "MLX42.h" + +int fdf_hooks(t_fdf *fdf) +{ + mlx_loop_hook(fdf->mlx, draw_hook, fdf); + mlx_key_hook(fdf->mlx, key_hook, fdf); + mlx_close_hook(fdf->mlx, close_hook, fdf); + mlx_resize_hook(fdf->mlx, resize_hook, fdf); + return (1); +} diff --git a/src/hooks/key_hook.c b/src/hooks/key_hook.c new file mode 100644 index 0000000..031a374 --- /dev/null +++ b/src/hooks/key_hook.c @@ -0,0 +1,22 @@ +/* ************************************************************************** */ +/* */ +/* ::: o_ :::::: ::: */ +/* key_hook.c :+: / :+::+: :+: */ +/* +:+ > +:++:+ +:+ */ +/* By: whaffman +#+ +:+ +#++#++:++#++ */ +/* +#+ +#+#+ +#++#+ +#+ \o/ */ +/* Created: 2024/12/20 11:21:30 by whaffman #+#+# #+#+# #+# #+# | */ +/* Updated: 2024/12/20 11:21:30 by whaffman ### ### ### ### / \ */ +/* */ +/* ************************************************************************** */ + +#include "fdf.h" + +void key_hook(mlx_key_data_t keydata, void *param) +{ + t_fdf *fdf; + + fdf = (t_fdf *)param; + key_hook_transform(keydata, fdf); + key_hook_options(keydata, fdf); +} diff --git a/src/hooks/key_hook_options.c b/src/hooks/key_hook_options.c new file mode 100644 index 0000000..9fb02fb --- /dev/null +++ b/src/hooks/key_hook_options.c @@ -0,0 +1,39 @@ +/* ************************************************************************** */ +/* */ +/* ::: o_ :::::: ::: */ +/* key_hook_options.c :+: / :+::+: :+: */ +/* +:+ > +:++:+ +:+ */ +/* By: whaffman +#+ +:+ +#++#++:++#++ */ +/* +#+ +#+#+ +#++#+ +#+ \o/ */ +/* Created: 2024/12/20 11:40:59 by whaffman #+#+# #+#+# #+# #+# | */ +/* Updated: 2024/12/20 11:40:59 by whaffman ### ### ### ### / \ */ +/* */ +/* ************************************************************************** */ + +#include "fdf.h" + +void key_hook_options(mlx_key_data_t keydata, t_fdf *fdf) +{ + if (keydata.key == MLX_KEY_X && keydata.action != MLX_RELEASE) + fdf->z_scale *= 1.05; + if (keydata.key == MLX_KEY_Z && keydata.action != MLX_RELEASE) + fdf->z_scale /= 1.05; + if (keydata.key == MLX_KEY_EQUAL && keydata.action != MLX_RELEASE) + fdf->zoom *= 1.1; + if (keydata.key == MLX_KEY_MINUS && keydata.action != MLX_RELEASE) + fdf->zoom /= 1.1; + if (keydata.key == MLX_KEY_SLASH && keydata.action == MLX_PRESS) + fdf->menu->enabled = !fdf->menu->enabled; + if (keydata.key == MLX_KEY_C && keydata.action == MLX_PRESS) + fdf->colormode = (fdf->colormode + 1) % 3; + if (keydata.key == MLX_KEY_P && keydata.action == MLX_PRESS) + fdf->projection = (fdf->projection + 1) % 3; + if (keydata.key == MLX_KEY_SPACE && keydata.action == MLX_PRESS) + reset_fdf(fdf); + if (keydata.key == MLX_KEY_LEFT_BRACKET && keydata.action == MLX_PRESS) + fdf->animate_z -= 0.5; + if (keydata.key == MLX_KEY_RIGHT_BRACKET && keydata.action == MLX_PRESS) + fdf->animate_z += 0.5; + if (keydata.key == MLX_KEY_ESCAPE) + close_hook(fdf); +} diff --git a/src/hooks/key_hook_transform.c b/src/hooks/key_hook_transform.c new file mode 100644 index 0000000..4da14ca --- /dev/null +++ b/src/hooks/key_hook_transform.c @@ -0,0 +1,37 @@ +/* ************************************************************************** */ +/* */ +/* ::: o_ :::::: ::: */ +/* key_hook_transform.c :+: / :+::+: :+: */ +/* +:+ > +:++:+ +:+ */ +/* By: whaffman +#+ +:+ +#++#++:++#++ */ +/* +#+ +#+#+ +#++#+ +#+ \o/ */ +/* Created: 2024/12/20 11:41:05 by whaffman #+#+# #+#+# #+# #+# | */ +/* Updated: 2024/12/20 11:41:05 by whaffman ### ### ### ### / \ */ +/* */ +/* ************************************************************************** */ + +#include "fdf.h" + +void key_hook_transform(mlx_key_data_t keydata, t_fdf *fdf) +{ + if (keydata.key == MLX_KEY_A && keydata.action != MLX_RELEASE) + fdf->angle_z -= deg2rad(5); + if (keydata.key == MLX_KEY_D && keydata.action != MLX_RELEASE) + fdf->angle_z += deg2rad(5); + if (keydata.key == MLX_KEY_W && keydata.action != MLX_RELEASE) + fdf->angle_x -= deg2rad(5); + if (keydata.key == MLX_KEY_S && keydata.action != MLX_RELEASE) + fdf->angle_x += deg2rad(5); + if (keydata.key == MLX_KEY_Q && keydata.action != MLX_RELEASE) + fdf->angle_y -= deg2rad(5); + if (keydata.key == MLX_KEY_E && keydata.action != MLX_RELEASE) + fdf->angle_y += deg2rad(5); + if (keydata.key == MLX_KEY_UP && keydata.action != MLX_RELEASE) + fdf->offset_y -= 10; + if (keydata.key == MLX_KEY_DOWN && keydata.action != MLX_RELEASE) + fdf->offset_y += 10; + if (keydata.key == MLX_KEY_LEFT && keydata.action != MLX_RELEASE) + fdf->offset_x -= 10; + if (keydata.key == MLX_KEY_RIGHT && keydata.action != MLX_RELEASE) + fdf->offset_x += 10; +} diff --git a/src/hooks/resize_hook.c b/src/hooks/resize_hook.c new file mode 100644 index 0000000..8a5f9a4 --- /dev/null +++ b/src/hooks/resize_hook.c @@ -0,0 +1,33 @@ +/* ************************************************************************** */ +/* */ +/* ::: o_ :::::: ::: */ +/* resize_hook.c :+: / :+::+: :+: */ +/* +:+ > +:++:+ +:+ */ +/* By: whaffman +#+ +:+ +#++#++:++#++ */ +/* +#+ +#+#+ +#++#+ +#+ \o/ */ +/* Created: 2024/12/20 11:21:31 by whaffman #+#+# #+#+# #+# #+# | */ +/* Updated: 2024/12/20 11:21:31 by whaffman ### ### ### ### / \ */ +/* */ +/* ************************************************************************** */ + +#include "fdf.h" + +void resize_hook(int width, int height, void *param) +{ + t_fdf *fdf; + + (void)width; + (void)height; + fdf = (t_fdf *)param; + mlx_delete_image(fdf->mlx, fdf->img); + fdf->img = mlx_new_image(fdf->mlx, fdf->mlx->width, fdf->mlx->height); + if (!fdf->img + || (mlx_image_to_window(fdf->mlx, fdf->img, 0, 0) < 0) + || (mlx_image_to_window(fdf->mlx, fdf->menu, 10, 10) < 0)) + exit(1); + fdf->offset_x += (fdf->mlx->width - fdf->last_width) / 2 ; + fdf->offset_y += (fdf->mlx->height - fdf->last_height) / 2; + fdf->zoom = 0; + fdf->last_height = fdf->mlx->height; + fdf->last_width = fdf->mlx->width; +} diff --git a/src/get_map_sizes.c b/src/parse/get_map_sizes.c similarity index 95% rename from src/get_map_sizes.c rename to src/parse/get_map_sizes.c index b7d70a8..f38bb95 100644 --- a/src/get_map_sizes.c +++ b/src/parse/get_map_sizes.c @@ -6,7 +6,7 @@ /* By: whaffman +#+ +:+ +#++#++:++#++ */ /* +#+ +#+#+ +#++#+ +#+ \o/ */ /* Created: 2024/12/13 15:23:14 by whaffman #+#+# #+#+# #+# #+# | */ -/* Updated: 2024/12/13 15:23:14 by whaffman ### ### ### ### / \ */ +/* Updated: 2024/12/20 11:21:32 by whaffman ### ### ### ### / \ */ /* */ /* ************************************************************************** */ diff --git a/src/get_z_max.c b/src/parse/get_z_max.c similarity index 94% rename from src/get_z_max.c rename to src/parse/get_z_max.c index 0143a48..d69900d 100644 --- a/src/get_z_max.c +++ b/src/parse/get_z_max.c @@ -6,7 +6,7 @@ /* By: whaffman +#+ +:+ +#++#++:++#++ */ /* +#+ +#+#+ +#++#+ +#+ \o/ */ /* Created: 2024/12/13 15:23:15 by whaffman #+#+# #+#+# #+# #+# | */ -/* Updated: 2024/12/13 15:23:15 by whaffman ### ### ### ### / \ */ +/* Updated: 2024/12/20 11:21:33 by whaffman ### ### ### ### / \ */ /* */ /* ************************************************************************** */ diff --git a/src/read_map_from_file.c b/src/parse/load_map_from_file.c similarity index 61% rename from src/read_map_from_file.c rename to src/parse/load_map_from_file.c index 451cd37..5208794 100644 --- a/src/read_map_from_file.c +++ b/src/parse/load_map_from_file.c @@ -1,29 +1,17 @@ /* ************************************************************************** */ /* */ /* ::: o_ :::::: ::: */ -/* load_map_from_file.c :+: / :+::+: :+: */ +/* load_map_from_file.c :+: / :+::+: :+: */ /* +:+ > +:++:+ +:+ */ /* By: whaffman +#+ +:+ +#++#++:++#++ */ /* +#+ +#+#+ +#++#+ +#+ \o/ */ -/* Created: 2024/12/13 15:23:19 by whaffman #+#+# #+#+# #+# #+# | */ -/* Updated: 2024/12/13 15:23:19 by whaffman ### ### ### ### / \ */ +/* Created: 2024/12/20 11:21:34 by whaffman #+#+# #+#+# #+# #+# | */ +/* Updated: 2024/12/20 11:21:34 by whaffman ### ### ### ### / \ */ /* */ /* ************************************************************************** */ #include "fdf.h" -int check_filename(char *filename) -{ - int i; - - i = 0; - while (filename[i]) - i++; - if (i < 5 || ft_strncmp(&filename[i - 4], ".fdf", 4)) - return (0); - return (1); -} - int load_map_from_file(char *filename, t_fdf *fdf) { int fd; @@ -51,11 +39,3 @@ int load_map_from_file(char *filename, t_fdf *fdf) close(fd); return (1); } - -void set_map_point(t_fdf *fdf, int x, int y, char **str) -{ - fdf->map->orig[y * fdf->map->width + x].x = x - fdf->map->width / 2; - fdf->map->orig[y * fdf->map->width + x].y = fdf->map->height / 2 - y; - fdf->map->orig[y * fdf->map->width + x].z = ft_atoi(str[x]); - fdf->map->orig[y * fdf->map->width + x].color = parse_color_string(str[x]); -} diff --git a/src/parse_map.c b/src/parse/parse_map.c similarity index 95% rename from src/parse_map.c rename to src/parse/parse_map.c index 3602b4c..c00201a 100644 --- a/src/parse_map.c +++ b/src/parse/parse_map.c @@ -6,7 +6,7 @@ /* By: whaffman +#+ +:+ +#++#++:++#++ */ /* +#+ +#+#+ +#++#+ +#+ \o/ */ /* Created: 2024/12/13 15:23:18 by whaffman #+#+# #+#+# #+# #+# | */ -/* Updated: 2024/12/13 15:23:18 by whaffman ### ### ### ### / \ */ +/* Updated: 2024/12/20 11:21:34 by whaffman ### ### ### ### / \ */ /* */ /* ************************************************************************** */ diff --git a/src/parse/set_map_point.c b/src/parse/set_map_point.c new file mode 100644 index 0000000..adb0a93 --- /dev/null +++ b/src/parse/set_map_point.c @@ -0,0 +1,21 @@ +/* ************************************************************************** */ +/* */ +/* ::: o_ :::::: ::: */ +/* set_map_point.c :+: / :+::+: :+: */ +/* +:+ > +:++:+ +:+ */ +/* By: whaffman +#+ +:+ +#++#++:++#++ */ +/* +#+ +#+#+ +#++#+ +#+ \o/ */ +/* Created: 2024/12/20 11:21:45 by whaffman #+#+# #+#+# #+# #+# | */ +/* Updated: 2024/12/20 11:21:45 by whaffman ### ### ### ### / \ */ +/* */ +/* ************************************************************************** */ + +#include "fdf.h" + +void set_map_point(t_fdf *fdf, int x, int y, char **str) +{ + fdf->map->orig[y * fdf->map->width + x].x = x - fdf->map->width / 2; + fdf->map->orig[y * fdf->map->width + x].y = fdf->map->height / 2 - y; + fdf->map->orig[y * fdf->map->width + x].z = ft_atoi(str[x]); + fdf->map->orig[y * fdf->map->width + x].color = parse_color_string(str[x]); +} diff --git a/src/transform/apply_rotation.c b/src/transform/apply_rotation.c new file mode 100644 index 0000000..6e78b68 --- /dev/null +++ b/src/transform/apply_rotation.c @@ -0,0 +1,31 @@ +/* ************************************************************************** */ +/* */ +/* ::: o_ :::::: ::: */ +/* apply_rotation.c :+: / :+::+: :+: */ +/* +:+ > +:++:+ +:+ */ +/* By: whaffman +#+ +:+ +#++#++:++#++ */ +/* +#+ +#+#+ +#++#+ +#+ \o/ */ +/* Created: 2024/12/20 11:21:46 by whaffman #+#+# #+#+# #+# #+# | */ +/* Updated: 2024/12/20 11:21:46 by whaffman ### ### ### ### / \ */ +/* */ +/* ************************************************************************** */ + +#include "fdf.h" + +void apply_rotation(t_fdf *fdf) +{ + int i; + + i = 0; + while (i < fdf->map->width * fdf->map->height) + { + fdf->map->rot[i].x = fdf->map->orig[i].x; + fdf->map->rot[i].y = fdf->map->orig[i].y; + fdf->map->rot[i].z = fdf->map->orig[i].z * fdf->z_scale; + fdf->map->rot[i].color = fdf->map->orig[i].color; + i++; + } + rotate_x(&fdf->map->rot, fdf->angle_x, fdf->map->width * fdf->map->height); + rotate_y(&fdf->map->rot, fdf->angle_y, fdf->map->width * fdf->map->height); + rotate_z(&fdf->map->rot, fdf->angle_z, fdf->map->width * fdf->map->height); +} diff --git a/src/deg2rad.c b/src/transform/deg2rad.c similarity index 93% rename from src/deg2rad.c rename to src/transform/deg2rad.c index b55debb..b56f781 100644 --- a/src/deg2rad.c +++ b/src/transform/deg2rad.c @@ -6,7 +6,7 @@ /* By: whaffman +#+ +:+ +#++#++:++#++ */ /* +#+ +#+#+ +#++#+ +#+ \o/ */ /* Created: 2024/12/13 15:23:10 by whaffman #+#+# #+#+# #+# #+# | */ -/* Updated: 2024/12/13 15:23:10 by whaffman ### ### ### ### / \ */ +/* Updated: 2024/12/20 11:21:47 by whaffman ### ### ### ### / \ */ /* */ /* ************************************************************************** */ diff --git a/src/transform/project.c b/src/transform/project.c new file mode 100644 index 0000000..ad775a1 --- /dev/null +++ b/src/transform/project.c @@ -0,0 +1,23 @@ +/* ************************************************************************** */ +/* */ +/* ::: o_ :::::: ::: */ +/* project.c :+: / :+::+: :+: */ +/* +:+ > +:++:+ +:+ */ +/* By: whaffman +#+ +:+ +#++#++:++#++ */ +/* +#+ +#+#+ +#++#+ +#+ \o/ */ +/* Created: 2024/12/20 11:21:47 by whaffman #+#+# #+#+# #+# #+# | */ +/* Updated: 2024/12/20 11:21:47 by whaffman ### ### ### ### / \ */ +/* */ +/* ************************************************************************** */ + +#include "fdf.h" + +void project(t_fdf *fdf) +{ + if (fdf->projection == PROJECTION_ISOMETRIC) + project_isometric(fdf); + else if (fdf->projection == PROJECTION_PARALLEL) + project_parallel(fdf); + else if (fdf->projection == PROJECTION_TRIMETRIC) + project_trimetric(fdf); +} diff --git a/src/project_isometric.c b/src/transform/project_isometric.c similarity index 50% rename from src/project_isometric.c rename to src/transform/project_isometric.c index a1e4ef4..2f50f0b 100644 --- a/src/project_isometric.c +++ b/src/transform/project_isometric.c @@ -6,54 +6,12 @@ /* By: whaffman +#+ +:+ +#++#++:++#++ */ /* +#+ +#+#+ +#++#+ +#+ \o/ */ /* Created: 2024/12/13 15:23:19 by whaffman #+#+# #+#+# #+# #+# | */ -/* Updated: 2024/12/13 15:23:19 by whaffman ### ### ### ### / \ */ +/* Updated: 2024/12/20 11:21:48 by whaffman ### ### ### ### / \ */ /* */ /* ************************************************************************** */ #include "fdf.h" -void project_trimetric(t_fdf *fdf) -{ - int i; - double x; - double y; - - i = 0; - if (fdf->zoom == 0) - fdf->zoom = fmin(fdf->mlx->width / fdf->map->width, - fdf->mlx->height / fdf->map->height) / 2; - while (i < fdf->map->width * fdf->map->height) - { - x = fdf->map->rot[i].x - fdf->map->rot[i].y; - y = fdf->map->rot[i].x + fdf->map->rot[i].y - fdf->map->rot[i].z; - fdf->map->proj[i].x = x * fdf->zoom + fdf->offset_x; - fdf->map->proj[i].y = y * fdf->zoom + fdf->offset_y; - fdf->map->proj[i].orig_z = fdf->map->orig[i].z; - fdf->map->proj[i].color = fdf->map->orig[i].color; - get_pixel_color(fdf, &fdf->map->proj[i]); - i++; - } -} - -void project_parallel(t_fdf *fdf) -{ - int i; - - i = 0; - if (fdf->zoom == 0) - fdf->zoom = fmin(fdf->mlx->width / fdf->map->width, - fdf->mlx->height / fdf->map->height) / 2; - while (i < fdf->map->width * fdf->map->height) - { - fdf->map->proj[i].x = fdf->map->rot[i].x * fdf->zoom + fdf->offset_x; - fdf->map->proj[i].y = fdf->map->rot[i].y * fdf->zoom + fdf->offset_y; - fdf->map->proj[i].orig_z = fdf->map->orig[i].z; - fdf->map->proj[i].color = fdf->map->orig[i].color; - get_pixel_color(fdf, &fdf->map->proj[i]); - i++; - } -} - void project_isometric(t_fdf *fdf) { int i; @@ -77,13 +35,3 @@ void project_isometric(t_fdf *fdf) i++; } } - -void project(t_fdf *fdf) -{ - if (fdf->projection == PROJECTION_ISOMETRIC) - project_isometric(fdf); - else if (fdf->projection == PROJECTION_PARALLEL) - project_parallel(fdf); - else if (fdf->projection == PROJECTION_TRIMETRIC) - project_trimetric(fdf); -} diff --git a/src/transform/project_parallel.c b/src/transform/project_parallel.c new file mode 100644 index 0000000..94820fe --- /dev/null +++ b/src/transform/project_parallel.c @@ -0,0 +1,32 @@ +/* ************************************************************************** */ +/* */ +/* ::: o_ :::::: ::: */ +/* project_parallel.c :+: / :+::+: :+: */ +/* +:+ > +:++:+ +:+ */ +/* By: whaffman +#+ +:+ +#++#++:++#++ */ +/* +#+ +#+#+ +#++#+ +#+ \o/ */ +/* Created: 2024/12/20 11:21:50 by whaffman #+#+# #+#+# #+# #+# | */ +/* Updated: 2024/12/20 11:21:50 by whaffman ### ### ### ### / \ */ +/* */ +/* ************************************************************************** */ + +#include "fdf.h" + +void project_parallel(t_fdf *fdf) +{ + int i; + + i = 0; + if (fdf->zoom == 0) + fdf->zoom = fmin(fdf->mlx->width / fdf->map->width, + fdf->mlx->height / fdf->map->height) / 2; + while (i < fdf->map->width * fdf->map->height) + { + fdf->map->proj[i].x = fdf->map->rot[i].x * fdf->zoom + fdf->offset_x; + fdf->map->proj[i].y = fdf->map->rot[i].y * fdf->zoom + fdf->offset_y; + fdf->map->proj[i].orig_z = fdf->map->orig[i].z; + fdf->map->proj[i].color = fdf->map->orig[i].color; + get_pixel_color(fdf, &fdf->map->proj[i]); + i++; + } +} diff --git a/src/transform/project_trimetric.c b/src/transform/project_trimetric.c new file mode 100644 index 0000000..3a2ad7a --- /dev/null +++ b/src/transform/project_trimetric.c @@ -0,0 +1,36 @@ +/* ************************************************************************** */ +/* */ +/* ::: o_ :::::: ::: */ +/* project_trimetric.c :+: / :+::+: :+: */ +/* +:+ > +:++:+ +:+ */ +/* By: whaffman +#+ +:+ +#++#++:++#++ */ +/* +#+ +#+#+ +#++#+ +#+ \o/ */ +/* Created: 2024/12/20 11:21:51 by whaffman #+#+# #+#+# #+# #+# | */ +/* Updated: 2024/12/20 11:21:51 by whaffman ### ### ### ### / \ */ +/* */ +/* ************************************************************************** */ + +#include "fdf.h" + +void project_trimetric(t_fdf *fdf) +{ + int i; + double x; + double y; + + i = 0; + if (fdf->zoom == 0) + fdf->zoom = fmin(fdf->mlx->width / fdf->map->width, + fdf->mlx->height / fdf->map->height) / 2; + while (i < fdf->map->width * fdf->map->height) + { + x = fdf->map->rot[i].x - fdf->map->rot[i].y; + y = fdf->map->rot[i].x + fdf->map->rot[i].y - fdf->map->rot[i].z; + fdf->map->proj[i].x = x * fdf->zoom + fdf->offset_x; + fdf->map->proj[i].y = y * fdf->zoom + fdf->offset_y; + fdf->map->proj[i].orig_z = fdf->map->orig[i].z; + fdf->map->proj[i].color = fdf->map->orig[i].color; + get_pixel_color(fdf, &fdf->map->proj[i]); + i++; + } +} diff --git a/src/transform/rotate_x.c b/src/transform/rotate_x.c new file mode 100644 index 0000000..ff703d7 --- /dev/null +++ b/src/transform/rotate_x.c @@ -0,0 +1,28 @@ +/* ************************************************************************** */ +/* */ +/* ::: o_ :::::: ::: */ +/* rotate_x.c :+: / :+::+: :+: */ +/* +:+ > +:++:+ +:+ */ +/* By: whaffman +#+ +:+ +#++#++:++#++ */ +/* +#+ +#+#+ +#++#+ +#+ \o/ */ +/* Created: 2024/12/20 11:21:52 by whaffman #+#+# #+#+# #+# #+# | */ +/* Updated: 2024/12/20 11:21:52 by whaffman ### ### ### ### / \ */ +/* */ +/* ************************************************************************** */ + +#include "fdf.h" + +void rotate_x(t_point_3d **points, double angle, int size) +{ + int i; + double previous_y; + + i = 0; + while (i < size) + { + previous_y = (*points)[i].y; + (*points)[i].y = previous_y * cos(angle) + (*points)[i].z * sin(angle); + (*points)[i].z = -previous_y * sin(angle) + (*points)[i].z * cos(angle); + i++; + } +} diff --git a/src/transform/rotate_y.c b/src/transform/rotate_y.c new file mode 100644 index 0000000..2472bd5 --- /dev/null +++ b/src/transform/rotate_y.c @@ -0,0 +1,28 @@ +/* ************************************************************************** */ +/* */ +/* ::: o_ :::::: ::: */ +/* rotate_y.c :+: / :+::+: :+: */ +/* +:+ > +:++:+ +:+ */ +/* By: whaffman +#+ +:+ +#++#++:++#++ */ +/* +#+ +#+#+ +#++#+ +#+ \o/ */ +/* Created: 2024/12/20 11:21:53 by whaffman #+#+# #+#+# #+# #+# | */ +/* Updated: 2024/12/20 11:21:53 by whaffman ### ### ### ### / \ */ +/* */ +/* ************************************************************************** */ + +#include "fdf.h" + +void rotate_y(t_point_3d **points, double angle, int size) +{ + int i; + double previous_x; + + i = 0; + while (i < size) + { + previous_x = (*points)[i].x; + (*points)[i].x = previous_x * cos(angle) + (*points)[i].z * sin(angle); + (*points)[i].z = -previous_x * sin(angle) + (*points)[i].z * cos(angle); + i++; + } +} diff --git a/src/transform/rotate_z.c b/src/transform/rotate_z.c new file mode 100644 index 0000000..8b71e8c --- /dev/null +++ b/src/transform/rotate_z.c @@ -0,0 +1,30 @@ +/* ************************************************************************** */ +/* */ +/* ::: o_ :::::: ::: */ +/* rotate_z.c :+: / :+::+: :+: */ +/* +:+ > +:++:+ +:+ */ +/* By: whaffman +#+ +:+ +#++#++:++#++ */ +/* +#+ +#+#+ +#++#+ +#+ \o/ */ +/* Created: 2024/12/20 11:21:55 by whaffman #+#+# #+#+# #+# #+# | */ +/* Updated: 2024/12/20 11:21:55 by whaffman ### ### ### ### / \ */ +/* */ +/* ************************************************************************** */ + +#include "fdf.h" + +void rotate_z(t_point_3d **points, double angle, int size) +{ + int i; + double previous_x; + double previous_y; + + i = 0; + while (i < size) + { + previous_x = (*points)[i].x; + previous_y = (*points)[i].y; + (*points)[i].x = previous_x * cos(angle) - previous_y * sin(angle); + (*points)[i].y = previous_x * sin(angle) + previous_y * cos(angle); + i++; + } +} diff --git a/src/util/check_filename.c b/src/util/check_filename.c new file mode 100644 index 0000000..ccf69ea --- /dev/null +++ b/src/util/check_filename.c @@ -0,0 +1,25 @@ +/* ************************************************************************** */ +/* */ +/* ::: o_ :::::: ::: */ +/* check_filename.c :+: / :+::+: :+: */ +/* +:+ > +:++:+ +:+ */ +/* By: whaffman +#+ +:+ +#++#++:++#++ */ +/* +#+ +#+#+ +#++#+ +#+ \o/ */ +/* Created: 2024/12/20 11:21:56 by whaffman #+#+# #+#+# #+# #+# | */ +/* Updated: 2024/12/20 11:21:56 by whaffman ### ### ### ### / \ */ +/* */ +/* ************************************************************************** */ + +#include "fdf.h" + +int check_filename(char *filename) +{ + int i; + + i = 0; + while (filename[i]) + i++; + if (i < 5 || ft_strncmp(&filename[i - 4], ".fdf", 4)) + return (0); + return (1); +} diff --git a/src/clean_fdf.c b/src/util/clean_fdf.c similarity index 94% rename from src/clean_fdf.c rename to src/util/clean_fdf.c index 3920881..0acf6ba 100644 --- a/src/clean_fdf.c +++ b/src/util/clean_fdf.c @@ -6,7 +6,7 @@ /* By: whaffman +#+ +:+ +#++#++:++#++ */ /* +#+ +#+#+ +#++#+ +#+ \o/ */ /* Created: 2024/12/13 15:15:51 by whaffman #+#+# #+#+# #+# #+# | */ -/* Updated: 2024/12/13 15:23:09 by whaffman ### ### ### ### / \ */ +/* Updated: 2024/12/20 11:21:57 by whaffman ### ### ### ### / \ */ /* */ /* ************************************************************************** */ diff --git a/src/free_line_and_split.c b/src/util/free_line_and_split.c similarity index 94% rename from src/free_line_and_split.c rename to src/util/free_line_and_split.c index 035e1c5..e0a3fc7 100644 --- a/src/free_line_and_split.c +++ b/src/util/free_line_and_split.c @@ -6,7 +6,7 @@ /* By: whaffman +#+ +:+ +#++#++:++#++ */ /* +#+ +#+#+ +#++#+ +#+ \o/ */ /* Created: 2024/12/13 15:23:14 by whaffman #+#+# #+#+# #+# #+# | */ -/* Updated: 2024/12/13 15:23:14 by whaffman ### ### ### ### / \ */ +/* Updated: 2024/12/20 11:21:58 by whaffman ### ### ### ### / \ */ /* */ /* ************************************************************************** */ diff --git a/src/handle_error.c b/src/util/handle_error.c similarity index 94% rename from src/handle_error.c rename to src/util/handle_error.c index 03fb15c..2ebfa54 100644 --- a/src/handle_error.c +++ b/src/util/handle_error.c @@ -6,7 +6,7 @@ /* By: whaffman +#+ +:+ +#++#++:++#++ */ /* +#+ +#+#+ +#++#+ +#+ \o/ */ /* Created: 2024/12/13 15:23:16 by whaffman #+#+# #+#+# #+# #+# | */ -/* Updated: 2024/12/13 15:23:16 by whaffman ### ### ### ### / \ */ +/* Updated: 2024/12/20 11:21:59 by whaffman ### ### ### ### / \ */ /* */ /* ************************************************************************** */ diff --git a/src/init_mlx.c b/src/util/init_mlx.c similarity index 94% rename from src/init_mlx.c rename to src/util/init_mlx.c index f257fcc..f67cb96 100644 --- a/src/init_mlx.c +++ b/src/util/init_mlx.c @@ -6,7 +6,7 @@ /* By: whaffman +#+ +:+ +#++#++:++#++ */ /* +#+ +#+#+ +#++#+ +#+ \o/ */ /* Created: 2024/12/13 15:23:17 by whaffman #+#+# #+#+# #+# #+# | */ -/* Updated: 2024/12/13 15:23:17 by whaffman ### ### ### ### / \ */ +/* Updated: 2024/12/20 11:22:00 by whaffman ### ### ### ### / \ */ /* */ /* ************************************************************************** */ @@ -15,7 +15,7 @@ int init_mlx(t_fdf *fdf) { mlx_t *mlx; - + mlx = mlx_init(WIDTH, HEIGHT, "FdF", true); if (!mlx) handle_error(fdf, "Error: failed to initialise MLX"); diff --git a/src/initialise_fdf.c b/src/util/initialise_fdf.c similarity index 73% rename from src/initialise_fdf.c rename to src/util/initialise_fdf.c index c1729d7..dd5d0cf 100644 --- a/src/initialise_fdf.c +++ b/src/util/initialise_fdf.c @@ -6,7 +6,7 @@ /* By: whaffman +#+ +:+ +#++#++:++#++ */ /* +#+ +#+#+ +#++#+ +#+ \o/ */ /* Created: 2024/12/13 15:23:17 by whaffman #+#+# #+#+# #+# #+# | */ -/* Updated: 2024/12/13 15:23:17 by whaffman ### ### ### ### / \ */ +/* Updated: 2024/12/20 11:22:00 by whaffman ### ### ### ### / \ */ /* */ /* ************************************************************************** */ @@ -26,7 +26,6 @@ t_fdf *initialise_fdf(void) fdf->map = map; fdf->mlx = NULL; fdf->img = NULL; - fdf->last_width = WIDTH; fdf->last_height = HEIGHT; fdf->map->orig = NULL; @@ -34,29 +33,7 @@ t_fdf *initialise_fdf(void) fdf->map->proj = NULL; fdf->map->width = 0; fdf->map->height = 0; - fdf->map->z_max = 0; - + fdf->map->z_max = 0; reset_fdf(fdf); return (fdf); } - -void reset_fdf(t_fdf *fdf) -{ - fdf->offset_x = WIDTH / 2; - fdf->offset_y = HEIGHT / 2; - if (fdf->mlx) - { - fdf->offset_x = fdf->mlx->width / 2; - fdf->offset_y = fdf->mlx->height / 2; - } - - - fdf->angle_x = 0; - fdf->angle_y = 0; - fdf->angle_z = 0; - fdf->zoom = 0; - fdf->z_scale = 0.1; - fdf->animate_z = 0; - fdf->colormode = COLOR_MODE_DEFAULT; - fdf->projection = PROJECTION_ISOMETRIC; -} diff --git a/src/util/reset_fdf.c b/src/util/reset_fdf.c new file mode 100644 index 0000000..b2d3371 --- /dev/null +++ b/src/util/reset_fdf.c @@ -0,0 +1,32 @@ +/* ************************************************************************** */ +/* */ +/* ::: o_ :::::: ::: */ +/* reset_fdf.c :+: / :+::+: :+: */ +/* +:+ > +:++:+ +:+ */ +/* By: whaffman +#+ +:+ +#++#++:++#++ */ +/* +#+ +#+#+ +#++#+ +#+ \o/ */ +/* Created: 2024/12/20 11:22:01 by whaffman #+#+# #+#+# #+# #+# | */ +/* Updated: 2024/12/20 11:22:01 by whaffman ### ### ### ### / \ */ +/* */ +/* ************************************************************************** */ + +#include "fdf.h" + +void reset_fdf(t_fdf *fdf) +{ + fdf->offset_x = WIDTH / 2; + fdf->offset_y = HEIGHT / 2; + if (fdf->mlx) + { + fdf->offset_x = fdf->mlx->width / 2; + fdf->offset_y = fdf->mlx->height / 2; + } + fdf->angle_x = 0; + fdf->angle_y = 0; + fdf->angle_z = 0; + fdf->zoom = 0; + fdf->z_scale = 0.1; + fdf->animate_z = 0; + fdf->colormode = COLOR_MODE_DEFAULT; + fdf->projection = PROJECTION_ISOMETRIC; +}