Connected parsing to rest of the game

This commit is contained in:
Philippe BLAGOJEVIC
2022-04-23 20:12:13 +02:00
parent fac1f78230
commit f53e66556b
19 changed files with 1010 additions and 23 deletions

View File

@@ -26,8 +26,18 @@ int main(int ac, char **av)
{
t_game *game;
game = init_game();
init_parsing(ac, av, game);
if ((ac != 2 || check_extension(av[1], ".cub")) && \
write(2, "Error\nPlease use a valid .cub file as single argument.\n", 53))
return (EXIT_FAILURE);
game = init_struct();
if (init_parsing(game, av[1]) && write(2, "The .cub file is invalid.\n", 26))
return (EXIT_FAILURE);
if (check_map(&(game->map)) && write(2, "The map is invalid.\n", 20))
return (EXIT_FAILURE);
// init game variables
init_game(game);
mb_init(destroy_mlx, game);
// draw game a first time before it start

65
srcs/gnl/get_next_line.c Normal file
View File

@@ -0,0 +1,65 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* get_next_line.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: pblagoje <pblagoje@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2021/01/27 12:42:20 by pblagoje #+# #+# */
/* Updated: 2022/04/18 17:01:06 by pblagoje ### ########.fr */
/* */
/* ************************************************************************** */
#include "get_next_line.h"
void ft_free_gnl(char **s)
{
if (*s != NULL)
{
free(*s);
*s = NULL;
}
}
char *ft_strcpy(char *s1, char *s2)
{
int i;
i = 0;
while (s2[i])
{
s1[i] = s2[i];
i++;
}
s1[i] = '\0';
return (s1);
}
int get_next_line(int fd, char **line)
{
int ret;
static char *mem;
char *buf;
ret = 1;
buf = NULL;
if (BUFFER_SIZE <= 0 || !line || read(fd, buf, 0) == -1)
return (-1);
buf = malloc(sizeof(char) * (BUFFER_SIZE + 1));
while (!ft_is_newline(mem, '\n') && ret != 0)
{
ret = read(fd, buf, BUFFER_SIZE);
buf[ret] = '\0';
mem = ft_strjoin_gnl(mem, buf);
}
if (!ret)
{
ft_free_gnl(&mem);
ft_free_gnl(&buf);
return (0);
}
*line = ft_strtrim_gnl(mem);
mem = ft_strchr_gnl(mem, '\n');
ft_free_gnl(&buf);
return (1);
}

30
srcs/gnl/get_next_line.h Normal file
View File

@@ -0,0 +1,30 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* get_next_line.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: pblagoje <pblagoje@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2021/01/27 12:43:50 by pblagoje #+# #+# */
/* Updated: 2022/04/18 17:01:22 by pblagoje ### ########.fr */
/* */
/* ************************************************************************** */
#ifndef GET_NEXT_LINE_H
# define GET_NEXT_LINE_H
# define BUFFER_SIZE 100
# include <unistd.h>
# include <stdlib.h>
# include <stdio.h>
int get_next_line(int fd, char **line);
int ft_strlen_gnl(char *s);
char *ft_strchr_gnl(char *s, int c);
char *ft_strjoin_gnl(char *s1, char *s2);
char *ft_strtrim_gnl(char *s);
int ft_is_newline(char *s, int c);
char *ft_strcpy(char *s1, char *s2);
void ft_free_gnl(char **s);
#endif

View File

@@ -0,0 +1,115 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* get_next_line_utils.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: pblagoje <pblagoje@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2021/02/04 10:35:41 by pblagoje #+# #+# */
/* Updated: 2022/04/18 17:00:41 by pblagoje ### ########.fr */
/* */
/* ************************************************************************** */
#include "get_next_line.h"
int ft_strlen_gnl(char *s)
{
int i;
if (!s)
return (0);
i = 0;
while (s[i])
i++;
return (i);
}
char *ft_strjoin_gnl(char *s1, char *s2)
{
char *res;
int i;
int j;
if (!s1 && !s2)
return (NULL);
i = 0;
j = 0;
res = malloc(sizeof(char) * (ft_strlen_gnl(s1) + ft_strlen_gnl(s2) + 1));
if (!res)
return (NULL);
while (s1 != NULL && s1[i])
{
res[i] = s1[i];
i++;
}
while (s2[j])
{
res[i + j] = s2[j];
j++;
}
res[i + j] = '\0';
ft_free_gnl(&s1);
return (res);
}
int ft_is_newline(char *s, int c)
{
int i;
if (!s)
return (0);
i = 0;
while (s[i])
{
if (s[i] == (unsigned char)c)
return (1);
i++;
}
return (0);
}
char *ft_strchr_gnl(char *s, int c)
{
int i;
int is_newline;
char *tmp;
if (!s)
return (NULL);
i = 0;
is_newline = 0;
while (s[i] && is_newline == 0)
{
if (s[i] == (unsigned char)c)
is_newline = 1;
i++;
}
tmp = malloc(sizeof(char) * (ft_strlen_gnl(&s[i]) + 1));
if (!tmp)
return (NULL);
tmp = ft_strcpy(tmp, &s[i]);
ft_free_gnl(&s);
return (tmp);
}
char *ft_strtrim_gnl(char *s)
{
char *res;
int size;
int i;
size = 0;
i = 0;
while (s[size] != '\n')
size++;
res = malloc(sizeof(char) * (size + 1));
if (!res)
return (NULL);
while (s[i] != '\n')
{
res[i] = s[i];
i++;
}
res[i] = '\0';
return (res);
}

View File

@@ -1,8 +0,0 @@
#include "cube3d.h"
void init_parsing(int ac, char **av, t_game *game)
{
(void)*game;
(void)av;
(void)ac;
}

View File

@@ -10,7 +10,7 @@ static void init_img(t_img *img, t_game *game)
static void init_map(t_map *map)
{
map->size_x = 24;
/* map->size_x = 24;
map->size_y = 24;
// map
int tmp[24][24] = {
@@ -59,7 +59,21 @@ static void init_map(t_map *map)
j++;
}
i++;
}
} */
map->content = NULL;
map->tmp_str = NULL;
map->size_x = 0;
map->size_y = 0;
map->plr_x = 0;
map->plr_y = 0;
}
static void init_txt(t_txt *txt)
{
txt->txt_north = NULL;
txt->txt_south = NULL;
txt->txt_east = NULL;
txt->txt_west = NULL;
}
static void init_raycast(t_rcast *rcast)
@@ -81,11 +95,11 @@ static void init_raycast(t_rcast *rcast)
rcast->ray.end.y = -SCREEN_DIST;
}
static void init_plr(t_plr *plr)
void init_plr(t_plr *plr, t_map *map)
{
// player first position
plr->exact.x = 2 * CELL;
plr->exact.y = 2 * CELL;
plr->exact.x = map->plr_x * CELL;
plr->exact.y = map->plr_y * CELL;
plr->pos.x = plr->exact.x;
plr->pos.y = plr->exact.y;
// rotation
@@ -96,14 +110,16 @@ static void init_plr(t_plr *plr)
plr->sinj = 0;
}
t_game *init_game(void)
t_game *init_struct(void)
{
t_game *game;
game = mb_alloc(sizeof(t_game));
// map
init_map(&(game->map));
// plr
// init textures and floor/ceiling colors
init_txt(&(game->txt));
/* // plr
init_plr(&(game->plr));
// size window map
game->map_win.size_x = game->map.size_x * CELL;
@@ -119,6 +135,27 @@ t_game *init_game(void)
// raycasting
init_raycast(&(game->rcast));
// create image and get its data address
init_img(&(game->map_img), game);
init_img(&(game->map_img), game); */
return (game);
}
void init_game(t_game *game)
{
// plr
init_plr(&(game->plr), &(game->map));
// size window map
game->map_win.size_x = game->map.size_x * CELL;
game->map_win.size_y = game->map.size_y * CELL;
// init connexion to server
game->mlx_ptr = mlx_init();
mb_add(game->mlx_ptr);
// create the window
game->map_win.ptr = mlx_new_window(game->mlx_ptr, game->map_win.size_x,
game->map_win.size_y, "test");
// k(ey)_hook is the array containing the values of key press events
ft_bzero(&game->k_hook, sizeof(game->k_hook));
// raycasting
init_raycast(&(game->rcast));
// create image and get its data address
init_img(&(game->map_img), game);
}

View File

@@ -0,0 +1,27 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* check_extension.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: pblagoje <pblagoje@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/04/17 00:24:35 by pblagoje #+# #+# */
/* Updated: 2022/04/17 00:24:38 by pblagoje ### ########.fr */
/* */
/* ************************************************************************** */
#include "cube3d.h"
int check_extension(char *filename, char *ext)
{
char *str;
if (!filename || !ext)
return (1);
str = ft_strrchr(filename, '.');
if (!str)
return (2);
if (!ft_strcmp(str, ext))
return (0);
return (3);
}

122
srcs/parsing/check_map.c Normal file
View File

@@ -0,0 +1,122 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* check_map.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: pblagoje <pblagoje@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/04/18 12:37:48 by pblagoje #+# #+# */
/* Updated: 2022/04/23 19:18:16 by pblagoje ### ########.fr */
/* */
/* ************************************************************************** */
#include "cube3d.h"
int set_player(t_map *map, int y, int x)
{
map->plr_x = x;
map->plr_y = y;
map->content[y][x] = '0';
return (1);
}
void set_points(int *y, int *x, int row, int col)
{
y[0] = row - 1;
y[1] = row;
y[2] = row + 1;
x[0] = col - 1;
x[1] = col;
x[2] = col + 1;
}
int check_spaces(t_map *map, int row, int col)
{
int y[3];
int x[3];
int i;
int j;
set_points(y, x, row, col);
i = 0;
while (i < 3)
{
j = 0;
while (j < 3)
{
if (y[i] > 0 && y[i] < map->size_y - 1 \
&& x[j] > 0 && x[j] < map->size_x - 1)
{
if (map->content[y[i]][x[j]] != '1' \
&& map->content[y[i]][x[j]] != ' ')
return (EXIT_FAILURE);
}
j++;
}
i++;
}
return (EXIT_SUCCESS);
}
int check_content(t_map *map)
{
int x;
int y;
int count;
count = 0;
y = 0;
while (map->content[y] != NULL)
{
x = 0;
while (map->content[y][x] != '\0' && map->content[y][x] != '\n')
{
if (map->content[y][x] == ' ' && check_spaces(map, y, x))
return (EXIT_FAILURE);
else if (!ft_strchr(" 01SNWE", map->content[y][x]))
return (EXIT_FAILURE);
else if (ft_strchr("SNWE", map->content[y][x]) \
&& set_player(map, y, x))
count++;
x++;
}
y++;
}
if (count != 1)
return (EXIT_FAILURE);
return (EXIT_SUCCESS);
}
int check_borders(t_map *map)
{
int x;
int y;
y = 0;
while (map->content[y] != NULL)
{
x = 0;
while (map->content[y][x] != '\0' && map->content[y][x] != '\n')
{
if (y == 0 || y == map->size_y - 1)
if (map->content[y][x] != '1' && map->content[y][x] != ' ')
return (EXIT_FAILURE);
if (x == 0 || x == map->size_x - 1)
if (map->content[y][x] != '1' && map->content[y][x] != ' ')
return (EXIT_FAILURE);
x++;
}
y++;
}
return (EXIT_SUCCESS);
}
int check_map(t_map *map)
{
if (check_borders(map) || check_content(map))
{
ft_putstr_fd("Error\nThe map characters are invalid.\n", 2);
return (EXIT_FAILURE);
}
return (EXIT_SUCCESS);
}

113
srcs/parsing/check_path.c Normal file
View File

@@ -0,0 +1,113 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* check_path.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: pblagoje <pblagoje@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/04/16 20:54:37 by pblagoje #+# #+# */
/* Updated: 2022/04/23 18:38:15 by pblagoje ### ########.fr */
/* */
/* ************************************************************************** */
#include "cube3d.h"
int set_path(t_txt *txt, char *path, char identifier)
{
if (identifier == 'N' && txt->txt_north == NULL)
{
txt->txt_north = ft_strdup(path);
return (EXIT_SUCCESS);
}
else if (identifier == 'S' && txt->txt_south == NULL)
{
txt->txt_south = ft_strdup(path);
return (EXIT_SUCCESS);
}
else if (identifier == 'W' && txt->txt_west == NULL)
{
txt->txt_west = ft_strdup(path);
return (EXIT_SUCCESS);
}
else if (identifier == 'E' && txt->txt_east == NULL)
{
txt->txt_east = ft_strdup(path);
return (EXIT_SUCCESS);
}
return (EXIT_FAILURE);
}
int check_path(t_txt *txt, char *element, char identifier)
{
char *path;
int fd;
while (element && *element && ft_strchr(" \t\r", *element))
element++;
path = ft_substr(element, 0, ft_strlen(element));
fd = open(path, O_RDONLY);
if (fd == -1 || check_extension(path, ".xpm"))
{
ft_putstr_fd("Error\nInvalid texture file.\n", 2);
free(path);
close(fd);
return (EXIT_FAILURE);
}
if (set_path(txt, path, identifier) == EXIT_FAILURE)
{
free(path);
close(fd);
return (EXIT_FAILURE);
}
free(path);
close(fd);
return (EXIT_SUCCESS);
}
int check_element(t_game *game, char *element)
{
char identifier[3];
while (element && *element && ft_strchr(" \t\r", *element))
element++;
if (element == NULL || *element == '\0' || ft_strlen(element) < 2)
return (1);
identifier[0] = *element++;
identifier[1] = *element++;
identifier[2] = '\0';
if ((*element == ' ') && ft_strnstr("NOSOWEEA", identifier, 9) \
&& !check_path(&(game->txt), element, identifier[0]))
return (EXIT_SUCCESS);
if (ft_strnstr("F C ", identifier, 5) && \
!check_rgb(&(game->txt), element, identifier[0]))
return (EXIT_SUCCESS);
return (EXIT_FAILURE);
}
int check_elements(t_game *game, char *file)
{
int fd;
char *line;
int count;
line = NULL;
count = 0;
fd = open(file, O_RDONLY);
if (fd == -1)
return (-1);
while (count < TOTAL_ELEMENTS)
{
get_next_line(fd, &line);
if (line && *line != '\n' && !check_element(game, line))
count++;
else if (!line || (*line != '\n' && *line != '\0'))
{
free(line);
close(fd);
return (-1);
}
free(line);
line = NULL;
}
return (fd);
}

103
srcs/parsing/check_rgb.c Normal file
View File

@@ -0,0 +1,103 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* check_rgb.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: pblagoje <pblagoje@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/04/15 16:11:24 by pblagoje #+# #+# */
/* Updated: 2022/04/23 18:40:13 by pblagoje ### ########.fr */
/* */
/* ************************************************************************** */
#include "cube3d.h"
int check_colors(char **str)
{
int i;
int num;
i = 0;
num = 0;
while (str && str[i])
{
num = ft_atoi(str[i]);
if (num < 0 || num > 255)
return (EXIT_FAILURE);
i++;
}
return (EXIT_SUCCESS);
}
int ft_strlen_2d(char **str)
{
int i;
i = 0;
while (str && str[i])
i++;
return (i);
}
void set_floor_rgb(t_txt *txt, char **rgb)
{
int i;
i = 0;
while (i < 3)
{
txt->rgb_floor[i] = ft_atoi(rgb[i]);
i++;
}
}
void set_ceiling_rgb(t_txt *txt, char **rgb)
{
int i;
i = 0;
while (i < 3)
{
txt->rgb_ceiling[i] = ft_atoi(rgb[i]);
i++;
}
}
void ft_free_2d(char **str)
{
int i;
i = 0;
while (str && str[i])
{
free(str[i]);
i++;
}
free(str);
}
int check_rgb(t_txt *txt, char *element, char identifier)
{
char **rgb;
rgb = ft_split(element, ',');
if (!rgb || ft_strlen_2d(rgb) != 3 || \
element[ft_strlen(element) - 1] == ',')
{
ft_free_2d(rgb);
ft_putstr_fd("Error\nInvalid RGB code.\n", 2);
return (EXIT_FAILURE);
}
if ((identifier != 'F' && identifier != 'C') || check_colors(rgb))
{
ft_free_2d(rgb);
ft_putstr_fd("Error\nInvalid RGB code.\n", 2);
return (EXIT_FAILURE);
}
if (identifier == 'F')
set_floor_rgb(txt, rgb);
else
set_ceiling_rgb(txt, rgb);
ft_free_2d(rgb);
return (EXIT_SUCCESS);
}

136
srcs/parsing/init_parsing.c Normal file
View File

@@ -0,0 +1,136 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* init_parsing.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: pblagoje <pblagoje@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/04/15 16:03:50 by pblagoje #+# #+# */
/* Updated: 2022/04/23 18:57:37 by pblagoje ### ########.fr */
/* */
/* ************************************************************************** */
#include "cube3d.h"
int size_map(t_map *map, int fd)
{
char *line;
get_next_line(fd, &line);
while (line)
{
if ((*line == '\n' || *line == '\0') && map->size_x)
{
free(line);
return (EXIT_FAILURE);
}
else if (*line != '\n' && (int)ft_strlen(line) > map->size_x)
{
map->size_x = ft_strlen(line);
if (line[map->size_x - 1] != '\n')
map->size_x++;
}
if (*line != '\n' && *line != '\0')
map->size_y++;
free(line);
line = NULL;
get_next_line(fd, &line);
}
return (EXIT_SUCCESS);
}
int find_map(t_map *map, char *file)
{
int fd;
int count;
fd = open(file, O_RDONLY);
count = 0;
if (fd == -1)
return (-1);
while (count < TOTAL_ELEMENTS + 1)
{
free(map->tmp_str);
get_next_line(fd, &map->tmp_str);
if (!map->tmp_str)
{
close(fd);
return (-1);
}
if (map->tmp_str[0] != '\n' && map->tmp_str[0] != '\0')
count++;
}
return (fd);
}
void fill_row(char *row, char *line, int width)
{
int i;
i = 0;
while (line != NULL && line[i] != '\0' && line[i] != '\n')
{
row[i] = line[i];
i++;
}
while (i < width - 1)
{
row[i] = ' ';
i++;
}
row[i] = '\0';
}
int fill_map(t_map *map, int fd)
{
int i;
map->content = (char **)mb_alloc((map->size_y + 1) * sizeof(char *));
if (!map->content)
{
free(map->tmp_str);
return (EXIT_FAILURE);
}
i = -1;
while (++i < map->size_y)
{
if (i > 0)
get_next_line(fd, &map->tmp_str);
map->content[i] = (char *)mb_alloc((map->size_x + 1) * sizeof(char));
if (!map->content[i])
{
free(map->tmp_str);
return (EXIT_FAILURE);
}
fill_row(map->content[i], map->tmp_str, map->size_x);
free(map->tmp_str);
map->tmp_str = NULL;
}
map->content[i] = NULL;
return (EXIT_SUCCESS);
}
int init_parsing(t_game *game, char *file)
{
int fd;
fd = check_elements(game, file);
if (fd == -1)
return (EXIT_FAILURE);
if (size_map(&(game->map), fd))
{
close(fd);
return (EXIT_FAILURE);
}
close(fd);
fd = find_map(&(game->map), file);
if (fd == -1)
return (EXIT_FAILURE);
if (fill_map(&(game->map), fd) == EXIT_FAILURE)
{
close(fd);
return (EXIT_FAILURE);
}
close(fd);
return (EXIT_SUCCESS);
}