42_cub3d/src/minimap.c
2024-11-19 14:08:10 +01:00

139 lines
4.1 KiB
C

/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* minimap.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: mcolonna <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/11/15 11:41:15 by grobledo #+# #+# */
/* Updated: 2024/11/19 13:59:36 by mcolonna ### ########.fr */
/* */
/* ************************************************************************** */
#include "minimap.h"
#include "minimap_inline.h"
#include "const.h"
#include "map.h"
#include "global.h"
static void draw_minimap_wall(uint32_t *img_data, int map_y, int map_x,
double scale);
static void draw_minimap_player(u_int32_t *img_data, double scale);
static void draw_minimap_player_fov(u_int32_t *img_data, double scale);
static double scale_calcul(void)
{
const int minimap_width = SCREEN_WIDTH / MINIMAP_SIZE_INVERT;
const int minimap_height = SCREEN_HEIGHT / MINIMAP_SIZE_INVERT;
const double scale_x = (double)minimap_width / g_map.width;
const double scale_y = (double)minimap_height / g_map.height;
if (scale_x < scale_y)
return (scale_x);
else
return (scale_y);
}
void draw_minimap(u_int32_t *img_data)
{
unsigned int map_x;
unsigned int map_y;
const double scale = scale_calcul();
map_x = 0;
map_y = 0;
while (map_y < g_map.width)
{
map_x = 0;
while (map_x < g_map.height)
{
draw_minimap_wall(img_data, map_x, map_y, scale);
map_x++;
}
map_y++;
}
draw_minimap_player(img_data, scale);
}
static void draw_minimap_wall(uint32_t *img_data, int map_y, int map_x,
double scale)
{
const int map_case = map_y * g_map.width + map_x;
int pixel_x;
int pixel_y;
int pixel;
pixel_y = map_y * scale;
while (pixel_y < (map_y + 1) * scale)
{
pixel_x = map_x * scale;
while (pixel_x < (map_x + 1) * scale)
{
if (pixel_x < SCREEN_WIDTH && pixel_y < SCREEN_HEIGHT)
{
pixel = pixel_y * SCREEN_WIDTH + pixel_x;
if (g_map.cases[map_case].wall == WALL)
img_data[pixel] = MINIMAP_COLOR_WALL;
else if (g_map.cases[map_case].wall == EMPTY
&& g_map.cases[map_case].inside)
img_data[pixel] = MINIMAP_COLOR_EMPTY;
}
pixel_x++;
}
pixel_y++;
}
}
static void draw_minimap_player(u_int32_t *img_data, double scale)
{
const t_point_int player = {
g_map.player.pos.x * scale,
g_map.player.pos.y * scale,
};
t_point_int pixel;
int pixel_i;
draw_minimap_player_fov(img_data, scale);
pixel.x = player.x - HITBOX * scale;
while (++pixel.x < player.x + HITBOX * scale)
{
pixel.y = player.y - HITBOX * scale;
while (++pixel.y < player.y + HITBOX * scale)
{
pixel_i = pixel.y * SCREEN_WIDTH + pixel.x;
if (pixel.x < SCREEN_WIDTH && pixel.y < SCREEN_HEIGHT
&& distance_between_int(player, pixel) < HITBOX * scale)
img_data[pixel_i] = MINIMAP_COLOR_PLAYER;
}
}
}
static void draw_minimap_player_fov(u_int32_t *img_data, double scale)
{
const double fov_angle = atan(FOV);
const t_point_int player = {
g_map.player.pos.x * scale,
g_map.player.pos.y * scale,
};
t_point_int p;
int p_i;
p.x = player.x - MINIMAP_DISTANCE_FOV * scale - 1;
while (++p.x < player.x + MINIMAP_DISTANCE_FOV * scale)
{
p.y = player.y - MINIMAP_DISTANCE_FOV * scale - 1;
while (++p.y < player.y + MINIMAP_DISTANCE_FOV * 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, scale),
g_map.player.pos)
/ MINIMAP_DISTANCE_FOV * MINIMAP_OPACITY_FOV));
}
}
}