/* ************************************************************************** */ /* */ /* ::: :::::::: */ /* dda.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: erey-bet +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/05/02 15:49:00 by erey-bet #+# #+# */ /* Updated: 2023/05/03 17:37:31 by erey-bet ### ########.fr */ /* */ /* ************************************************************************** */ #include "game.h" double ft_abs(double nb) { if (nb < 0) return (-nb); return (nb); } void init_dda(t_game *game, t_dda *dda) { t_ray *ray; t_ply *ply; ray = &game->ray; ply = &game->ply; dda->map_x = (int)ply->pos_x; dda->map_y = (int)ply->pos_y; if (ray->dir_x == 0) dda->delta_dist_x = 1e30; else dda->delta_dist_x = ft_abs(1 / ray->dir_x); if (ray->dir_y == 0) dda->delta_dist_y = 1e30; else dda->delta_dist_y = ft_abs(1 / ray->dir_y); dda->step_x = 1; dda->step_y = 1; if (ray->dir_x < 0) { dda->step_x = -1; dda->side_dist_x = (ply->pos_x - dda->map_x) * dda->delta_dist_x; } else dda->side_dist_x = (dda->map_x + 1.0 - ply->pos_x) * dda->delta_dist_x; if (ray->dir_y < 0) { dda->step_y = -1; dda->side_dist_y = (ply->pos_y - dda->map_y) * dda->delta_dist_y; } else dda->side_dist_y = (dda->map_y + 1.0 - ply->pos_y) * dda->delta_dist_y; dda->hit = 0; } void loop_dda(t_game *game, t_dda *dda) { while (dda->hit == 0) { if (dda->side_dist_x < dda->side_dist_y) { dda->side_dist_x += dda->delta_dist_x; dda->map_x += dda->step_x; dda->side = 0; } else { dda->side_dist_y += dda->delta_dist_y; dda->map_y += dda->step_y; dda->side = 1; } if (dda->map_x >= 0 && dda->map_y >= 0 && game->map.map[dda->map_y][dda->map_x] == '1') dda->hit = 1; } } void ray_dda(t_dda *dda) { if(dda->side == 0) dda->perp_wall_dist = dda->side_dist_x - dda->delta_dist_x; else dda->perp_wall_dist = dda->side_dist_y - dda->delta_dist_y; if (dda->perp_wall_dist == 0) dda->perp_wall_dist = 1e30; dda->line_height = (int)(HEIGHT / dda->perp_wall_dist); dda->draw_start = -(dda->line_height) / 2 + HEIGHT / 2; if(dda->draw_start < 0) dda->draw_start = 0; dda->draw_end = dda->line_height / 2 + HEIGHT / 2; if(dda->draw_end >= HEIGHT) dda->draw_end = HEIGHT - 1; } unsigned int get_rgba(int r, int g, int b, int a) { return (a << 24 | r << 16 | g << 8 | b); } void draw_line(t_game *game, t_dda *dda, unsigned int color, int x) { int y; unsigned int white; white = 0xFFFFFFFF; y = 0; while (y < HEIGHT) { if (y < dda->draw_start) { mlx_put_pixel(game->window, x, y, white); } else if (y >= dda->draw_start && y <= dda->draw_end) { mlx_put_pixel(game->window, x, y, color); } else if (y > dda->draw_end) { mlx_put_pixel(game->window, x, y, white); } y ++; } } void draw_dda(t_game *game, t_dda *dda, int x) { unsigned int color; if (dda->step_x == -1 && dda->side == 0) // EAST color = get_rgba(255, 0, 0, 255); else if (dda->step_x == 1 && dda->side == 0) // WEST color = get_rgba(0, 255, 0, 255); else if (dda->step_y == 1 && dda->side == 1) // NORTH color = get_rgba(0, 0, 255, 255); else // SOUTH color = get_rgba(100, 100, 100, 255); draw_line(game, dda, color, x); } void dda(t_game *game, int x) { t_dda dda; init_dda(game, &dda); loop_dda(game, &dda); ray_dda(&dda); draw_dda(game, &dda, x); }