/* ************************************************************************** */ /* */ /* ::: o_ :::::: ::: */ /* fdf.c :+: / :+::+: :+: */ /* +:+ > +:++:+ +:+ */ /* By: whaffman +#+ +:+ +#++#++:++#++ */ /* +#+ +#+#+ +#++#+ +#+ \o/ */ /* Created: 2024/12/06 11:07:30 by whaffman #+#+# #+#+# #+# #+# | */ /* Updated: 2024/12/06 11:19:30 by whaffman ### ### ### ### / \ */ /* */ /* ************************************************************************** */ #include "fdf.h" int get_map_sizes(char *filename, t_map *map) { const int fd = open(filename, O_RDONLY); char *line; int width; if (fd < 0) return (ft_printf(FILE_ERROR, filename), 0); width = 0; while (true) { line = get_next_line(fd); if (!line) break ; width = ft_count_words(line, ' '); free(line); if (map->width != 0 && map->width != width) return (ft_printf(WRONG_LINE_LENGTH, map->width, width, map->height), 0); else if (map->width == 0) map->width = width; map->height++; } return (close(fd), 1); } void free_line_and_split(char **line, char ***split) { char **split_start; split_start = *split; free(*line); *line = NULL; while (**split) { free(**split); **split = NULL; (*split)++; } free(split_start); *split = NULL; } int read_map(char *filename, t_fdf *fdf) { int fd; char *line; int y; int x; char **split; fd = open(filename, O_RDONLY); if (fd < 0) handle_error(NULL, FILE_ERROR); y = fdf->map->height - 1; while (true) { x = 0; line = get_next_line(fd); if (!line) break ; split = ft_split(line, ' '); while (split[x]) { fdf->map->original[y * fdf->map->width + x].x = x - fdf->map->width / 2; fdf->map->original[y * fdf->map->width + x].y = fdf->map->height / 2 - y; fdf->map->original[y * fdf->map->width + x].z = ft_atoi(split[x]); fdf->map->original[y * fdf->map->width + x].color = get_color(split[x]); x++; } free_line_and_split(&line, &split); y--; } close(fd); return (1); } int parse_map(char *filename, t_fdf *fdf) { if (!get_map_sizes(filename, fdf->map)) handle_error(fdf, "Error: failed to get map sizes"); fdf->map->original = malloc(fdf->map->width * fdf->map->height * sizeof(t_point_3d)); fdf->map->rotated = malloc(fdf->map->width * fdf->map->height * sizeof(t_point_3d)); fdf->map->projected = malloc(fdf->map->width * fdf->map->height * sizeof(t_point_2d)); if (!fdf->map->original || !fdf->map->rotated || !fdf->map->projected) handle_error(fdf, MALLOC_ERROR); if (!read_map(filename, fdf)) handle_error(fdf, "Error: failed to read map"); return (SUCCESS); } void fdf_set_background(mlx_image_t *img, int color) { int x; int y; y = 0; while (y < (int) img->height) { x = 0; while (x < (int) img->width) { mlx_put_pixel(img, x, y, color); x++; } y++; } } void fdf_project_isometric(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) / SQRT2; while (i < fdf->map->width * fdf->map->height) { x = (fdf->map->rotated[i].x - fdf->map->rotated[i].y) / SQRT2; y = (fdf->map->rotated[i].x + fdf->map->rotated[i].y - 2 * fdf->map->rotated[i].z) / SQRT6; fdf->map->projected[i].x = x * fdf->zoom + fdf->offset_x; fdf->map->projected[i].y = y * fdf->zoom + fdf->offset_y; fdf->map->projected[i].color = fdf->map->rotated[i].color; i++; } } double deg2rad(double deg) { return (deg / 180.0 * M_PI); } int init_mlx(t_fdf *fdf) { mlx_t *mlx; printf("init_mlx\n"); mlx = mlx_init(WIDTH, HEIGHT, "FdF", true); if (!mlx) handle_error(fdf, "Error: failed to initialise MLX"); fdf->mlx = mlx; 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)) handle_error(fdf, "Error: failed to create image"); fdf_hooks(fdf); return (SUCCESS); } t_fdf *initialise_fdf() { t_map *map; t_fdf *fdf; fdf = malloc(sizeof(t_fdf)); if (!fdf) handle_error(fdf, MALLOC_ERROR); map = malloc(sizeof(t_map)); if (!map) handle_error(fdf, MALLOC_ERROR); fdf->map = map; fdf->mlx = NULL; fdf->img = NULL; fdf->angle_x = 0; fdf->angle_y = 0; fdf->angle_z = 0; fdf->zoom = 0; fdf->offset_x = WIDTH / 2; fdf->offset_y = HEIGHT / 2; fdf->z_scale = 0.1; fdf->last_width = WIDTH; fdf->last_height = HEIGHT; fdf->map->original = NULL; fdf->map->rotated = NULL; fdf->map->projected = NULL; fdf->map->width = 0; fdf->map->height = 0; fdf->map->z_max = 0; return (fdf); } bool clean_fdf(t_fdf *fdf) { if (fdf->map) { free(fdf->map->original); free(fdf->map->rotated); free(fdf->map->projected); free(fdf->map); } free(fdf); return (true); } void handle_error(t_fdf *fdf, char *error) { if (errno) perror(error); if (mlx_errno) ft_putendl_fd(mlx_strerror(mlx_errno), 2); ft_putendl_fd(error , 2); clean_fdf(fdf); exit(1); } int main(int argc, char *argv[]) { t_fdf *fdf; fdf = initialise_fdf(); if (argc != 2) handle_error(fdf, "Usage: ./fdf "); if (!parse_map(argv[1], fdf)) handle_error(fdf, "Error: failed to parse map"); init_mlx(fdf); mlx_loop(fdf->mlx); mlx_terminate(fdf->mlx); clean_fdf(fdf); return (EXIT_SUCCESS); }