From 2ec9ce4f8ee4936de51f31e89d5a9307988ca27f Mon Sep 17 00:00:00 2001 From: mcolonna Date: Tue, 19 Nov 2024 13:30:01 +0100 Subject: [PATCH] change: minimap: pretty player with fov --- include/const.h | 5 ++- src/minimap.c | 59 +++++++++++++++++++++++++++-------- src/minimap_inline.h | 72 +++++++++++++++++++++++++++++++++++++++++++ src/minimap_inline2.h | 46 +++++++++++++++++++++++++++ 4 files changed, 168 insertions(+), 14 deletions(-) create mode 100644 src/minimap_inline.h create mode 100644 src/minimap_inline2.h diff --git a/include/const.h b/include/const.h index 9d5a34d..6a34c4b 100644 --- a/include/const.h +++ b/include/const.h @@ -6,7 +6,7 @@ /* By: mcolonna +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/10/31 17:00:59 by mcolonna #+# #+# */ -/* Updated: 2024/11/18 13:40:04 by mcolonna ### ########.fr */ +/* Updated: 2024/11/19 13:05:50 by mcolonna ### ########.fr */ /* */ /* ************************************************************************** */ @@ -31,5 +31,8 @@ # define MINIMAP_COLOR_WALL 0xFFAF33 // Color of the walls on the minimap # define MINIMAP_COLOR_EMPTY 0xFFFC33 // Color of the empty cases on the minimap # define MINIMAP_COLOR_PLAYER 0xFF0000 // Color of the player on the minimap +// Distance from the player until where the FOV is drawn (unit: cases). +# define MINIMAP_DISTANCE_FOV 3 // Size of the FOV on the minimap +# define MINIMAP_OPACITY_FOV 0.8 // Opacity of the FOV on the minimap #endif diff --git a/src/minimap.c b/src/minimap.c index 10a667f..e9834e8 100644 --- a/src/minimap.c +++ b/src/minimap.c @@ -6,11 +6,12 @@ /* By: mcolonna +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/11/15 11:41:15 by grobledo #+# #+# */ -/* Updated: 2024/11/18 14:19:40 by mcolonna ### ########.fr */ +/* Updated: 2024/11/19 13:20:54 by mcolonna ### ########.fr */ /* */ /* ************************************************************************** */ #include "minimap.h" +#include "minimap_inline.h" #include "const.h" #include "map.h" @@ -18,6 +19,7 @@ static void draw_minimap_wall(uint32_t *img_data, int map_y, int map_x); static void draw_minimap_player(u_int32_t *img_data); +static void draw_minimap_player_fov(u_int32_t *img_data); void draw_minimap(u_int32_t *img_data) { @@ -69,21 +71,52 @@ static void draw_minimap_wall(uint32_t *img_data, int map_y, int map_x) static void draw_minimap_player(u_int32_t *img_data) { - const int player_x = g_map.player.pos.x * MINIMAP_SCALE; - const int player_y = g_map.player.pos.y * MINIMAP_SCALE; - int pixel_x; - int pixel_y; - int pixel; + const t_point_int player = { + g_map.player.pos.x * MINIMAP_SCALE, + g_map.player.pos.y * MINIMAP_SCALE, + }; + t_point_int pixel; + int pixel_i; - pixel_x = player_x - 2; - while (++pixel_x < player_x + 2) + draw_minimap_player_fov(img_data); + pixel.x = player.x - HITBOX * MINIMAP_SCALE; + while (++pixel.x < player.x + HITBOX * MINIMAP_SCALE) { - pixel_y = player_y - 2; - while (++pixel_y < player_y + 2) + pixel.y = player.y - HITBOX * MINIMAP_SCALE; + while (++pixel.y < player.y + HITBOX * MINIMAP_SCALE) { - pixel = pixel_y * SCREEN_WIDTH + pixel_x; - if (pixel_x < SCREEN_WIDTH && pixel_y < SCREEN_HEIGHT) - img_data[pixel] = MINIMAP_COLOR_PLAYER; + pixel_i = pixel.y * SCREEN_WIDTH + pixel.x; + if (pixel.x < SCREEN_WIDTH && pixel.y < SCREEN_HEIGHT + && distance_between_int(player, pixel) < HITBOX * MINIMAP_SCALE) + img_data[pixel_i] = MINIMAP_COLOR_PLAYER; + } + } +} + +static void draw_minimap_player_fov(u_int32_t *img_data) +{ + const double fov_angle = atan(FOV); + const t_point_int player = { + g_map.player.pos.x * MINIMAP_SCALE, + g_map.player.pos.y * MINIMAP_SCALE, + }; + t_point_int p; + int p_i; + + p.x = player.x - MINIMAP_DISTANCE_FOV * MINIMAP_SCALE - 1; + while (++p.x < player.x + MINIMAP_DISTANCE_FOV * MINIMAP_SCALE) + { + p.y = player.y - MINIMAP_DISTANCE_FOV * MINIMAP_SCALE - 1; + while (++p.y < player.y + MINIMAP_DISTANCE_FOV * MINIMAP_SCALE) + { + p_i = p.y * SCREEN_WIDTH + p.x; + if (p_i >= 0 && p_i < SCREEN_HEIGHT * SCREEN_WIDTH) + if (angle_in_between(get_angle(player, p), g_map.player.rot + - fov_angle, g_map.player.rot + fov_angle)) + draw_transparent_pixel(&img_data[p_i], + MINIMAP_COLOR_PLAYER, MINIMAP_OPACITY_FOV + - (distance_between(pixel_to_pos(p), g_map.player.pos) + / MINIMAP_DISTANCE_FOV * MINIMAP_OPACITY_FOV)); } } } diff --git a/src/minimap_inline.h b/src/minimap_inline.h new file mode 100644 index 0000000..8c4a22c --- /dev/null +++ b/src/minimap_inline.h @@ -0,0 +1,72 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* minimap_inline.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: mcolonna +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/11/19 13:01:34 by mcolonna #+# #+# */ +/* Updated: 2024/11/19 13:26:01 by mcolonna ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef MINIMAP_INLINE_H +# define MINIMAP_INLINE_H + +# include "minimap.h" +# include "minimap_inline2.h" + +# include "const.h" + +static inline double distance_between(t_point_double a, t_point_double b) +{ + return (sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y))); +} + +static inline double distance_between_int(t_point_int a, t_point_int b) +{ + return (sqrt((double)( + (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y) + ))); +} + +static inline t_point_double pixel_to_pos(t_point_int pixel) +{ + return ((t_point_double){ + (double)pixel.x / MINIMAP_SCALE, + (double)pixel.y / MINIMAP_SCALE, + }); +} + +static inline double get_angle(t_point_int base, t_point_int vector) +{ + double r; + + vector.x -= base.x; + vector.y -= base.y; + if (!vector.y) + { + if (vector.x > 0) + return (PI / 2); + else + return (3 * PI / 2); + } + r = atan((double)vector.x / -(double)vector.y); + if (vector.y > 0) + return (r + PI); + else + return (r); +} + +static inline bool angle_in_between(double angle, double min, double max) +{ + while (max < min) + max += 2 * PI; + while (angle < min) + angle += 2 * PI; + while (angle >= max) + angle -= 2 * PI; + return (angle >= min); +} + +#endif diff --git a/src/minimap_inline2.h b/src/minimap_inline2.h new file mode 100644 index 0000000..a69f535 --- /dev/null +++ b/src/minimap_inline2.h @@ -0,0 +1,46 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* minimap_inline2.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: mcolonna +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/11/19 13:07:02 by mcolonna #+# #+# */ +/* Updated: 2024/11/19 13:12:31 by mcolonna ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef MINIMAP_INLINE2_H +# define MINIMAP_INLINE2_H + +# include "minimap.h" + +static inline double srgb_to_gamma(u_int8_t value) +{ + return (pow((double)value / 0xFF, 2.2)); +} + +static inline u_int8_t gamma_to_srgb(double value) +{ + return (pow((double)value, 1 / 2.2) * 0xFF); +} + +static inline void draw_transparent_pixel(u_int32_t *pixel, u_int32_t color, + double opacity) +{ + if (opacity <= 0) + return ; + if (opacity >= 1) + *pixel = color; + ((u_int8_t *)pixel)[0] = gamma_to_srgb( + (1 - opacity) * srgb_to_gamma(((u_int8_t *)pixel)[0]) + + opacity * srgb_to_gamma(((u_int8_t *)&color)[0])); + ((u_int8_t *)pixel)[1] = gamma_to_srgb( + (1 - opacity) * srgb_to_gamma(((u_int8_t *)pixel)[1]) + + opacity * srgb_to_gamma(((u_int8_t *)&color)[1])); + ((u_int8_t *)pixel)[2] = gamma_to_srgb( + (1 - opacity) * srgb_to_gamma(((u_int8_t *)pixel)[2]) + + opacity * srgb_to_gamma(((u_int8_t *)&color)[2])); +} + +#endif