fdf/src/fdf.c

209 lines
4.5 KiB
C

/* ************************************************************************** */
/* */
/* ::: o_ :::::: ::: */
/* fdf.c :+: / :+::+: :+: */
/* +:+ > +:++:+ +:+ */
/* By: whaffman <whaffman@student.codam.nl> +#+ +:+ +#++#++:++#++ */
/* +#+ +#+#+ +#++#+ +#+ \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_map *map)
{
int fd;
char *line;
int y;
int x;
char **split;
fd = open(filename, O_RDONLY);
if (fd < 0)
return (ft_printf(FILE_ERROR, filename), 0);
y = map->height - 1;
while (true)
{
x = 0;
line = get_next_line(fd);
if (!line)
break ;
split = ft_split(line, ' ');
while (split[x])
{
map->points[y * map->width + x].x = x - map->width / 2;
map->points[y * map->width + x].y = map->height / 2 - y;
map->points[y * map->width + x].z = ft_atoi(split[x]) * 0.08;
map->points[y * map->width + x].color = 0xFFFFFFFF;
x++;
}
free_line_and_split(&line, &split);
y--;
}
close(fd);
return (1);
}
void print_map(t_map *map)
{
int x;
int y;
y = 0;
while (y < map->height)
{
x = 0;
while (x < map->width)
{
printf("(%.2f, %.2f, %.2f)\n",
map->points[y * map->width + x].x,
map->points[y * map->width + x].y,
map->points[y * map->width + x].z);
x++;
}
ft_printf("\n");
y++;
}
}
int parse_map(char *filename, t_fdf *fdf)
{
t_map *map;
map = malloc(sizeof(t_map));
if (!map)
return (ft_printf(MALLOC_ERROR), FAILURE);
if (!get_map_sizes(filename, map))
return (free(map), FAILURE);
map->points = malloc(map->width * map->height * sizeof(t_point_3d));
if (!map->points)
return (free(map), ft_printf(MALLOC_ERROR), FAILURE);
if (!read_map(filename, map))
return (free(map->points), free(map), FAILURE);
fdf->map = 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_map *map)
{
int i;
double x;
double y;
const int scale = fmax(map->height, map->width) * SQRT2;
i = 0;
map->projected = malloc(map->width * map->height * sizeof(t_point_2d));
if (!map->projected)
return ;
while (i < map->width * map->height)
{
x = (map->points[i].x - map->points[i].y) / SQRT2;
y = (map->points[i].x + map->points[i].y - 2 * map->points[i].z) / SQRT6;
map->projected[i].x = x * WIDTH / scale + WIDTH / 2;
map->projected[i].y = y * HEIGHT / scale + HEIGHT / 2;
map->projected[i].color = map->points[i].color;
i++;
}
}
double deg2rad(double deg)
{
return (deg / 180.0 * M_PI);
}
int init_mlx(t_fdf *fdf)
{
fdf->mlx = mlx_init(WIDTH, HEIGHT, "FdF", false);
if (!fdf->mlx)
return (FAILURE);
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))
return (FAILURE);
fdf_hooks(fdf);
mlx_loop(fdf->mlx);
mlx_terminate(fdf->mlx);
return (SUCCESS);
}
int main(int argc, char *argv[])
{
t_fdf fdf;
if (argc != 2)
{
ft_printf(USAGE_ERROR, argv[0]);
return (EXIT_FAILURE);
}
if (!parse_map(argv[1], &fdf))
return (EXIT_FAILURE);
init_mlx(&fdf);
return (EXIT_SUCCESS);
}