Skip to content

Commit

Permalink
feat(scene): add file validation and scene loading to complete stage
Browse files Browse the repository at this point in the history
  • Loading branch information
mendes-jv committed Dec 19, 2024
1 parent d934303 commit 32ea533
Show file tree
Hide file tree
Showing 5 changed files with 243 additions and 93 deletions.
15 changes: 11 additions & 4 deletions includes/cub3d.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,18 @@
# define MSG_INV_FILE_DIR "File: Specified file is actually a directory.\n"
# define MSG_INV_FILE_OPEN "File: Could not open specified file.\n"
# define MSG_INV_FILE_EXT_CUB "File: Invalid file extension. Must be '.cub'.\n"
# define MSG_INV_FILE_ELEMENTS "File: Invalid elements or players in file.\n"
# define MSG_INV_FILE_MAP "Map: Map is not playable.\n"
# define MSG_INV_MLX_INIT "MLX: Could not initialize MLX.\n"
# define MSG_INV_TEXTURES "Invalid texture configurations.\n"
# define MSG_INV_COLORS "Invalid RGB colors configurations.\n"
# define MSG_INV_ARG "Invalid arguments.\n"

# define MSG_ERROR_EXIT "\033[0m\n"
# define MSG_ERROR_EXIT "\033[0m"
# define MSG_LEN_ERROR_EXIT 5

#define BLANK_CHARS " \t\v"

# define FALSE 0
# define TRUE 1

Expand Down Expand Up @@ -142,14 +146,17 @@ void handle_error(const char *message);
void check_file(char *file);
void load_scene(char *file, t_cub3d *scene);
mlx_texture_t *get_texture(char *line);
char *get_color(char *line);
char *get_rgb(char *line);
void get_map(char *line, t_cub3d *scene, int fd);
void get_player_elements(t_cub3d *scene);
void check_elements(t_cub3d *scene);
void flood_fill(char **map, int rows, t_coordinates c);
bool is_valid_png(char *file);
bool is_valid_color_tag(char *line);
bool is_valid_map(char *line);
bool is_valid_map(t_list *lines);
bool is_empty_line(char* line);
void run_scene(t_cub3d *scene);
void clean_scene(t_cub3d *scene);
void clean_scene(t_cub3d *scene, char *message);
int handle_mlx(mlx_t **mlx, mlx_image_t **image);
void handle_key_hooks(t_cub3d *s_cub3d);
int algorithm(t_cub3d *s_cub3d);
Expand Down
20 changes: 18 additions & 2 deletions sources/check_file.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,23 @@ bool is_valid_color_tag(char *line)
return (true);
}

void check_elements(t_cub3d *scene)
bool is_valid_map(t_list *list)
{
(void)scene;
t_list *lines;

lines = list;
while (lines)
{
if (is_empty_line(lines->content))
return (false);
lines = lines->next;
}
return (true);
}

bool is_empty_line(char *line)
{
while (*line && ft_strchr(BLANK_CHARS, *line))
line++;
return (!*line);
}
86 changes: 79 additions & 7 deletions sources/getters.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,31 +12,103 @@

#include "../includes/cub3d.h"

static void fill_map(char **map, t_list *lines);
static void fill_player_coordinates(t_cub3d *scene, int x, int y);

mlx_texture_t *get_texture(char *line)
{
char *trimmed_line;
mlx_texture_t *texture;

trimmed_line = ft_strtrim(line, " ");
trimmed_line = ft_strtrim(line + 3, " \n");
texture = NULL;
if (is_valid_png(trimmed_line))
texture = mlx_load_png(trimmed_line);
return (texture);
}

char *get_color(char *line)
char *get_rgb(char *line)
{
char *trimmed_line;

trimmed_line = ft_strtrim(line, " ");
trimmed_line = ft_strtrim(line + 2, " \n");
if (is_valid_color_tag(trimmed_line))
return (trimmed_line);
free(trimmed_line);
return (NULL);
}

void get_map(char *line, t_cub3d *scene)
void get_map(char *line, t_cub3d *scene, int fd)
{
t_list *lines;

lines = NULL;
while (line)
{
ft_lstadd_back(&lines, ft_lstnew(line));
free(line);
line = ft_get_next_line(fd);
}
if (is_valid_map(lines))
fill_map(scene->map, lines);
ft_lstclear(&lines, free);
}

static void fill_map(char **map, t_list *list)
{
t_list *lines;
int index;
int size;

lines = list;
size = ft_lstsize(lines);
index = 0;
map = ft_calloc(size + 1, sizeof(char *));
while (lines && size > index)
{
map[index] = ft_strtrim(lines->content, "\n");
lines = lines->next;
index++;
}
}

void get_player_elements(t_cub3d *scene)
{
(void)line;
(void)scene;
}
int x;
int y;
int player_count;

x = 0;
player_count = 0;
while (scene->map[x])
{
y = 0;
while (scene->map[x][y])
{
if (ft_strchr("NSWE", scene->map[x][y]))
{
fill_player_coordinates(scene, x, y);
player_count++;
}
y++;
}
x++;
}
if (player_count != 1)
scene->player_pos.x = -1;
}

static void fill_player_coordinates(t_cub3d *scene, int x, int y)
{
scene->player_pos.x = x;
scene->player_pos.y = y;
if (scene->map[x][y] == 'N')
scene->player_dir.y = 1;
else if (scene->map[x][y] == 'S')
scene->player_dir.y = -1;
else if (scene->map[x][y] == 'W')
scene->player_dir.x = -1;
else if (scene->map[x][y] == 'E')
scene->player_dir.x = 1;
scene->camera_plane.y = 0.66;
}
86 changes: 71 additions & 15 deletions sources/load_scene.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,15 @@
#include "../includes/cub3d.h"

static void process_file(t_cub3d *scene);
static void check_identifiers(char *line, t_cub3d *scene);
static void set_aditionals(t_cub3d *scene);
static void check_identifiers(char *line, t_cub3d *scene, int fd);
static bool is_map_playable(char **map);

void load_scene(char *file, t_cub3d *scene)
{
ft_bzero(scene, sizeof(t_cub3d));
scene->file = file;
process_file(scene);
check_elements(scene);
set_aditionals(scene);
}

static void process_file(t_cub3d *scene)
Expand All @@ -34,34 +33,91 @@ static void process_file(t_cub3d *scene)
if (fd < 0)
handle_error(MSG_INV_FILE_OPEN);
line = ft_get_next_line(fd);
while (*line && !ft_strchr(line, '1'))
while (line && *line)
{
check_identifiers(line, scene);
check_identifiers(line, scene, fd);
free(line);
line = ft_get_next_line(fd);
}
get_map(line, scene, fd);
free(line);
get_player_elements(scene);
close(fd);
}

static void check_identifiers(char *line, t_cub3d *scene)
static void check_identifiers(char *line, t_cub3d *scene, int fd)
{
if (*line == '\n')
return ;
if (ft_strnstr(line, "NO ", 3))
scene->textures.loaded_textures.no = get_texture(line);
else if (ft_strnstr(line, "SO ", 3))
scene->textures.loaded_textures.so = get_texture(line);
scene->textures.loaded_textures.so = get_texture(line);
else if (ft_strnstr(line, "WE ", 3))
scene->textures.loaded_textures.we = get_texture(line);
scene->textures.loaded_textures.we = get_texture(line);
else if (ft_strnstr(line, "EA ", 3))
scene->textures.loaded_textures.ea = get_texture(line);
scene->textures.loaded_textures.ea = get_texture(line);
else if (ft_strnstr(line, "F ", 2))
scene->rgb_colors.floor_color = get_color(line);
scene->rgb_colors.floor_color = get_rgb(line);
else if (ft_strnstr(line, "C ", 2))
scene->rgb_colors.ceiling_color = get_color(line);
scene->rgb_colors.ceiling_color = get_rgb(line);
else
get_map(line, scene, fd);
}

static void set_aditionals(t_cub3d *scene)
void check_elements(t_cub3d *scene)
{
(void)scene;
if (scene->player_pos.x == -1
|| scene->player_pos.y == -1
|| scene->player_dir.x == -1
|| scene->player_dir.y == -1
|| scene->camera_plane.x == -1
|| scene->camera_plane.y == -1
|| !scene->textures.loaded_textures.no
|| !scene->textures.loaded_textures.so
|| !scene->textures.loaded_textures.we
|| !scene->textures.loaded_textures.ea
|| !scene->rgb_colors.floor_color
|| !scene->rgb_colors.ceiling_color
|| !scene->map)
clean_scene(scene, MSG_INV_FILE_MAP);
flood_fill(scene->map, ft_arr_len(scene->map), scene->player_pos);
if (!is_map_playable(scene->map))
clean_scene(scene, MSG_INV_FILE_ELEMENTS);
}

void flood_fill(char **map, int x, t_coordinates c)
{
if (c.y < 0 || c.y >= x || c.x < 0
|| (int) c.x >= (int) ft_strlen(map[(int)c.y])
|| map[(int) c.y][(int) c.x] == '1'
|| map[(int) c.y][(int) c.x] == '#')
return ;
if (map[(int)c.y][(int)c.x] == '0'
|| ft_strrchr(BLANK_CHARS, map[(int) c.y][(int) c.x]))
map[(int) c.y][(int) c.x] = '#';
flood_fill(map, x, (t_coordinates){c.x - 1, c.y});
flood_fill(map, x, (t_coordinates){c.x + 1, c.y});
flood_fill(map, x, (t_coordinates){c.x, c.y - 1});
flood_fill(map, x, (t_coordinates){c.x, c.y + 1});
}

static bool is_map_playable(char **map)
{
int i;
int map_size;

i = -1;
map_size = (int)ft_arr_len(map);
while (map[0][++i])
if (map[0][i] == '#')
return (false);
i = -1;
while (map[map_size - 1][++i])
if (map[map_size - 1][i] == '#')
return (false);
i = 0;
while(++i < map_size)
if (map[i][0] == '#'
|| map[i][ft_strlen(map[i]) - 1] == '#')
return (false);
return (true);
}
Loading

0 comments on commit 32ea533

Please sign in to comment.