1397 lines
33 KiB
Plaintext
1397 lines
33 KiB
Plaintext
/* ************************************************************************** */
|
|
/* */
|
|
/* ::: :::::::: */
|
|
/* cub3d.h :+: :+: :+: */
|
|
/* +:+ +:+ +:+ */
|
|
/* By: ezafra-r <ezafra-r@student.42.fr> +#+ +:+ +#+ */
|
|
/* +#+#+#+#+#+ +#+ */
|
|
/* Created: 2024/02/08 18:17:00 by ezafra-r #+# #+# */
|
|
/* Updated: 2024/02/08 18:43:52 by ezafra-r ### ########.fr */
|
|
/* */
|
|
/* ************************************************************************** */
|
|
|
|
#ifndef CUB3D_H
|
|
# define CUB3D_H
|
|
|
|
/*═════════════════════════════ [ LIBS ] ═══════════════════════════════════*/
|
|
|
|
// personal libs
|
|
# include "../lib/libft/inc/libft.h"
|
|
# include "../lib/libmlx/include/MLX42/MLX42.h"
|
|
// global libs
|
|
# include <dirent.h>
|
|
# include <errno.h>
|
|
# include <fcntl.h>
|
|
# include <libgen.h>
|
|
# include <limits.h>
|
|
# include <math.h>
|
|
# include <memory.h>
|
|
# include <signal.h>
|
|
# include <stdarg.h>
|
|
# include <stdbool.h>
|
|
# include <stdio.h>
|
|
# include <stdlib.h>
|
|
# include <string.h>
|
|
# include <sys/ioctl.h>
|
|
# include <sys/stat.h>
|
|
# include <sys/types.h>
|
|
# include <sys/wait.h>
|
|
# include <termios.h>
|
|
# include <unistd.h>
|
|
|
|
/*═══════════════════════════ [ MACROS ] ═══════════════════════════════════*/
|
|
|
|
// MLX - GAME
|
|
|
|
# define S_W 1900 // screen width
|
|
# define S_H 1000 // screen height
|
|
# define WALL_SIZE 30 // wall size
|
|
# define FOV 60 // field of view
|
|
# define ROTATION_SPEED 0.045 // rotation speed
|
|
# define PLAYER_SPEED 4 // player speed
|
|
|
|
// ERROR
|
|
|
|
# define ERR_INV_COP "Error: invalid argument\n"
|
|
# define ERR_INV_FILE "Error: invalid file\n"
|
|
# define ERR_EMPTY_FILE "Error: empty file\n"
|
|
|
|
# define ERR_MAP_INV "Error: invalid map element\n"
|
|
# define ERR_MAP_EMPTY "Error: empty ligne in the map\n"
|
|
# define ERR_MAP_DUP "Error: duplicate map element\n"
|
|
# define ERR_MAP_RGB "Error: invalid color map [RGB]\n"
|
|
|
|
/*══════════════════════════ [ STRUCTS ] ═══════════════════════════════════*/
|
|
|
|
typedef struct s_tex
|
|
{
|
|
mlx_texture_t *no;
|
|
mlx_texture_t *so;
|
|
mlx_texture_t *we;
|
|
mlx_texture_t *ea;
|
|
} t_tex;
|
|
|
|
typedef struct s_turelist
|
|
{
|
|
char *name;
|
|
char *value;
|
|
struct s_turelist *next;
|
|
} t_turelist;
|
|
|
|
typedef struct s_player
|
|
{
|
|
int plyr_x; // player x position in pixels
|
|
int plyr_y; // player y position in pixels
|
|
double angle; // player angle
|
|
float fov_rd; // field of view in radians
|
|
int rot; // rotation flag
|
|
int l_r; // left right flag
|
|
int u_d; // up down flag
|
|
} t_player;
|
|
|
|
typedef struct s_ray
|
|
{
|
|
int index;
|
|
double ray_ngl;
|
|
double horiz_x;
|
|
double horiz_y;
|
|
double vert_x;
|
|
double vert_y;
|
|
double distance;
|
|
int flag;
|
|
} t_ray;
|
|
|
|
typedef struct s_data
|
|
{
|
|
int p_x; // player x position in the map
|
|
int p_y; // player y position in the map
|
|
int w_map; // map width
|
|
int h_map; // map height
|
|
int fd;
|
|
char *line;
|
|
char *ture;
|
|
char **ture2d;
|
|
char *map;
|
|
char **map2d;
|
|
char **sq_map;
|
|
char **cc;
|
|
char **ff;
|
|
t_turelist *t_list;
|
|
} t_data;
|
|
|
|
typedef struct s_mlx
|
|
{
|
|
mlx_image_t *img; // the image
|
|
mlx_t *mlx_ptr; // the mlx pointer
|
|
t_ray *ray; // the ray structure
|
|
t_data *dt; // the data structure
|
|
t_player *ply; // the player structure
|
|
t_tex *tex;
|
|
t_turelist *l_ture;
|
|
} t_mlx;
|
|
|
|
/*═════════════════════════ [ FUNCTIONS ] ══════════════════════════════════*/
|
|
/*-------------------------- [ parsing ] -----------------------------------*/
|
|
|
|
// p_frees.c
|
|
void freetl(char *ture, char *line, int fd);
|
|
void free_map(t_data *m);
|
|
void free_m(t_mlx *mlx);
|
|
void freelist(t_turelist **head);
|
|
|
|
// p_lst_ture.c
|
|
int get_index(char *line, int i);
|
|
t_turelist *new_texture(char *line);
|
|
void lst_back_ture(t_turelist **l_ture, t_turelist *new);
|
|
int lst_ture(t_data *m, t_turelist **l_ture);
|
|
|
|
// p_read_map_utils.c
|
|
int check_tures_space_tab(char **ture2d, int count);
|
|
int parse_rgb(char **ture2d);
|
|
int check_dup(t_data *m);
|
|
int check_first_last_line(char **map);
|
|
int surounded_by_one(char **map);
|
|
|
|
// p_read_map.c
|
|
int is_surrounded(char *line);
|
|
int is_validmap(char *line, int *flag);
|
|
char *getmap(t_data *m);
|
|
int read_map_(t_data *m, int count);
|
|
void process_map(t_data *map, int *count);
|
|
|
|
// p_texture_utils.c
|
|
int is_valid_texture(char *line);
|
|
int count_comma(char *rgb);
|
|
int check_pos_cf(char *line);
|
|
int line_arond_one(char *line);
|
|
char *getlastline(char **map);
|
|
|
|
// p_texture.c
|
|
int check_color_values(char **rgb);
|
|
void ft_process_rgb_color(t_turelist *tmp, t_data *m);
|
|
int color_ture(t_data *m, t_turelist *l_ture);
|
|
int check_color_textures(char *line);
|
|
int check_count_textures(t_data *m, int count);
|
|
|
|
// p_valid_map.c
|
|
int h_map(char **map);
|
|
int v_map(char **map);
|
|
char *fixline(char *line, int maxlen);
|
|
int getsize_line(char **map);
|
|
int valid_map(t_data *m);
|
|
|
|
// parsing.c
|
|
int read_map(char *av, t_data *data, int *count);
|
|
void get_x_y_player(t_data *m);
|
|
int parsing(int ac, char **av, t_data *data);
|
|
int check_extension_map(char *fname);
|
|
|
|
/*------------------------ [ execution ] -----------------------------------*/
|
|
// execfree.c
|
|
void ft_delete_tex(t_tex *tex);
|
|
void ft_exit(t_mlx *mlx);
|
|
|
|
// mouvement.c
|
|
void rotate_player(t_mlx *mlx, int i);
|
|
void move_player(t_mlx *mlx, double move_x, double move_y);
|
|
void cub_hook(t_mlx *mlx, double move_x, double move_y);
|
|
void ft_reset_move(mlx_key_data_t keydata, t_mlx *mlx);
|
|
void key_press(mlx_key_data_t keydata, void *ml);
|
|
|
|
// execution.c
|
|
void get_angle(t_mlx *mlx);
|
|
void drow_map_pixel(void *mlxl);
|
|
int check_load_ture(t_turelist *list);
|
|
int load_texture(t_tex *tex, t_turelist *l_ture);
|
|
int execution(t_data *dt);
|
|
|
|
// raycasting.c
|
|
int inter_check(float angle, float *inter, float *step,
|
|
int is_horizon);
|
|
int wall_hit(float x, float y, t_mlx *mlx);
|
|
float get_h_inter(t_mlx *mlx, float angl);
|
|
float get_v_inter(t_mlx *mlx, float angl);
|
|
void cast_rays(t_mlx *mlx);
|
|
|
|
// render2.c
|
|
int get_rgba(int r, int g, int b, int a);
|
|
int reverse_bytes(int c);
|
|
void my_mlx_pixel_put(t_mlx *mlx, int x, int y, int color);
|
|
float nor_angle(float angle);
|
|
int unit_circle(float angle, char c);
|
|
|
|
// render.c
|
|
double get_x_o(mlx_texture_t *texture, t_mlx *mlx);
|
|
void draw_floor_ceiling(t_mlx *mlx, int ray, int t_pix,
|
|
int b_pix);
|
|
void draw_wall(t_mlx *mlx, int t_pix, int b_pix,
|
|
double wall_h);
|
|
void render_wall(t_mlx *mlx, int ray);
|
|
#endif
|
|
|
|
# **************************************************************************** #
|
|
# #
|
|
# ::: :::::::: #
|
|
# e_frees.c :+: :+: :+: #
|
|
# +:+ +:+ +:+ #
|
|
# By: aortigos <aortigos@student.42malaga.com +#+ +:+ +#+ #
|
|
# +#+#+#+#+#+ +#+ #
|
|
# Created: 2024/02/08 18:32:59 by ezafra-r #+# #+# #
|
|
# Updated: 2025/11/14 09:25:29 by aortigos ### ########.fr #
|
|
# #
|
|
# **************************************************************************** #
|
|
|
|
#include "cub3d.h"
|
|
|
|
void ft_delete_tex(t_tex *tex)
|
|
{
|
|
if (tex->no)
|
|
mlx_delete_texture(tex->no);
|
|
if (tex->so)
|
|
mlx_delete_texture(tex->so);
|
|
if (tex->we)
|
|
mlx_delete_texture(tex->we);
|
|
if (tex->ea)
|
|
mlx_delete_texture(tex->ea);
|
|
}
|
|
|
|
void ft_exit(t_mlx *mlx)
|
|
{
|
|
mlx_delete_image(mlx->mlx_ptr, mlx->img);
|
|
mlx_close_window(mlx->mlx_ptr);
|
|
freelist(&mlx->dt->t_list);
|
|
free_map(mlx->dt);
|
|
ft_delete_tex(mlx->tex);
|
|
ft_memfree(mlx->tex);
|
|
ft_memfree(mlx->ply);
|
|
ft_memfree(mlx->ray);
|
|
mlx_terminate(mlx->mlx_ptr);
|
|
ft_putstr_fd("END GAME\n", 1);
|
|
exit(0);
|
|
}
|
|
/* ************************************************************************** */
|
|
/* e_mouvement.c :+: :+: :+: */
|
|
/* ************************************************************************** */
|
|
|
|
#include "cub3d.h"
|
|
|
|
void rotate_player(t_mlx *mlx, int i)
|
|
{
|
|
if (i == 1)
|
|
{
|
|
mlx->ply->angle += ROTATION_SPEED;
|
|
if (mlx->ply->angle > 2 * M_PI)
|
|
mlx->ply->angle -= 2 * M_PI;
|
|
}
|
|
else
|
|
{
|
|
mlx->ply->angle -= ROTATION_SPEED;
|
|
if (mlx->ply->angle < 0)
|
|
mlx->ply->angle += 2 * M_PI;
|
|
}
|
|
}
|
|
|
|
void move_player(t_mlx *mlx, double move_x, double move_y)
|
|
{
|
|
int map_grid_y;
|
|
int map_grid_x;
|
|
int new_x;
|
|
int new_y;
|
|
|
|
new_x = roundf(mlx->ply->plyr_x + move_x);
|
|
new_y = roundf(mlx->ply->plyr_y + move_y);
|
|
map_grid_x = (new_x / WALL_SIZE);
|
|
map_grid_y = (new_y / WALL_SIZE);
|
|
if (mlx->dt->sq_map[map_grid_y][map_grid_x] != '1'
|
|
&& (mlx->dt->sq_map[map_grid_y][mlx->ply->plyr_x / WALL_SIZE] != '1'
|
|
&& mlx->dt->sq_map[mlx->ply->plyr_y
|
|
/ WALL_SIZE][map_grid_x] != '1'))
|
|
{
|
|
mlx->ply->plyr_x = new_x;
|
|
mlx->ply->plyr_y = new_y;
|
|
}
|
|
}
|
|
|
|
void cub_hook(t_mlx *mlx, double move_x, double move_y)
|
|
{
|
|
if (mlx->ply->rot == 1)
|
|
rotate_player(mlx, 1);
|
|
if (mlx->ply->rot == -1)
|
|
rotate_player(mlx, 0);
|
|
if (mlx->ply->l_r == 1)
|
|
{
|
|
move_x = -sin(mlx->ply->angle) * PLAYER_SPEED;
|
|
move_y = cos(mlx->ply->angle) * PLAYER_SPEED;
|
|
}
|
|
if (mlx->ply->l_r == -1)
|
|
{
|
|
move_x = sin(mlx->ply->angle) * PLAYER_SPEED;
|
|
move_y = -cos(mlx->ply->angle) * PLAYER_SPEED;
|
|
}
|
|
if (mlx->ply->u_d == 1)
|
|
{
|
|
move_x = cos(mlx->ply->angle) * PLAYER_SPEED;
|
|
move_y = sin(mlx->ply->angle) * PLAYER_SPEED;
|
|
}
|
|
if (mlx->ply->u_d == -1)
|
|
{
|
|
move_x = -cos(mlx->ply->angle) * PLAYER_SPEED;
|
|
move_y = -sin(mlx->ply->angle) * PLAYER_SPEED;
|
|
}
|
|
move_player(mlx, move_x, move_y);
|
|
}
|
|
|
|
void ft_reset_move(mlx_key_data_t keydata, t_mlx *mlx)
|
|
{
|
|
if (keydata.key == MLX_KEY_D && (keydata.action == MLX_RELEASE))
|
|
mlx->ply->l_r = 0;
|
|
else if (keydata.key == MLX_KEY_A && (keydata.action == MLX_RELEASE))
|
|
mlx->ply->l_r = 0;
|
|
else if (keydata.key == MLX_KEY_S && (keydata.action == MLX_RELEASE))
|
|
mlx->ply->u_d = 0;
|
|
else if (keydata.key == MLX_KEY_W && (keydata.action == MLX_RELEASE))
|
|
mlx->ply->u_d = 0;
|
|
else if (keydata.key == MLX_KEY_LEFT && keydata.action == MLX_RELEASE)
|
|
mlx->ply->rot = 0;
|
|
else if (keydata.key == MLX_KEY_RIGHT && keydata.action == MLX_RELEASE)
|
|
mlx->ply->rot = 0;
|
|
}
|
|
|
|
void key_press(mlx_key_data_t keydata, void *ml)
|
|
{
|
|
t_mlx *mlx;
|
|
|
|
mlx = ml;
|
|
if (keydata.key == MLX_KEY_ESCAPE && (keydata.action == MLX_PRESS
|
|
|| keydata.action == MLX_REPEAT))
|
|
{
|
|
ft_exit(mlx);
|
|
}
|
|
else if (keydata.key == MLX_KEY_A && (keydata.action == MLX_PRESS))
|
|
mlx->ply->l_r = -1;
|
|
else if (keydata.key == MLX_KEY_D && (keydata.action == MLX_PRESS))
|
|
mlx->ply->l_r = 1;
|
|
else if (keydata.key == MLX_KEY_S && (keydata.action == MLX_PRESS))
|
|
mlx->ply->u_d = -1;
|
|
else if (keydata.key == MLX_KEY_W && keydata.action == MLX_PRESS)
|
|
mlx->ply->u_d = 1;
|
|
else if (keydata.key == MLX_KEY_LEFT && keydata.action == MLX_PRESS)
|
|
mlx->ply->rot = -1;
|
|
else if (keydata.key == MLX_KEY_RIGHT && keydata.action == MLX_PRESS)
|
|
mlx->ply->rot = 1;
|
|
ft_reset_move(keydata, mlx);
|
|
}
|
|
/* ************************************************************************** */
|
|
/* e_raycasting.c :+: :+: :+: */
|
|
/* ************************************************************************** */
|
|
|
|
#include "cub3d.h"
|
|
|
|
int inter_check(float angle, float *inter, float *step, int is_horizon)
|
|
{
|
|
if (is_horizon)
|
|
{
|
|
if (angle > 0 && angle < M_PI)
|
|
{
|
|
*inter += WALL_SIZE;
|
|
return (-1);
|
|
}
|
|
*step *= -1;
|
|
}
|
|
else
|
|
{
|
|
if (!(angle > M_PI / 2 && angle < 3 * M_PI / 2))
|
|
{
|
|
*inter += WALL_SIZE;
|
|
return (-1);
|
|
}
|
|
*step *= -1;
|
|
}
|
|
return (1);
|
|
}
|
|
|
|
int wall_hit(float x, float y, t_mlx *mlx)
|
|
{
|
|
int x_m;
|
|
int y_m;
|
|
|
|
if (x < 0 || y < 0)
|
|
return (0);
|
|
x_m = floor(x / WALL_SIZE);
|
|
y_m = floor(y / WALL_SIZE);
|
|
if ((y_m >= mlx->dt->h_map || x_m >= mlx->dt->w_map))
|
|
return (0);
|
|
if (mlx->dt->map2d[y_m] && x_m <= (int)ft_strlen(mlx->dt->map2d[y_m]))
|
|
if (mlx->dt->map2d[y_m][x_m] == '1')
|
|
return (0);
|
|
return (1);
|
|
}
|
|
|
|
float get_h_inter(t_mlx *mlx, float angl)
|
|
{
|
|
float h_x;
|
|
float h_y;
|
|
float x_step;
|
|
float y_step;
|
|
int pixel;
|
|
|
|
y_step = WALL_SIZE;
|
|
x_step = WALL_SIZE / tan(angl);
|
|
h_y = floor(mlx->ply->plyr_y / WALL_SIZE) * WALL_SIZE;
|
|
pixel = inter_check(angl, &h_y, &y_step, 1);
|
|
h_x = mlx->ply->plyr_x + (h_y - mlx->ply->plyr_y) / tan(angl);
|
|
if ((unit_circle(angl, 'y') && x_step > 0) || (!unit_circle(angl, 'y')
|
|
&& x_step < 0))
|
|
x_step *= -1;
|
|
while (wall_hit(h_x, h_y - pixel, mlx))
|
|
{
|
|
h_x += x_step;
|
|
h_y += y_step;
|
|
}
|
|
mlx->ray->horiz_x = h_x;
|
|
mlx->ray->horiz_y = h_y;
|
|
return (sqrt(pow(h_x - mlx->ply->plyr_x, 2) + pow(h_y - mlx->ply->plyr_y,
|
|
2)));
|
|
}
|
|
|
|
float get_v_inter(t_mlx *mlx, float angl)
|
|
{
|
|
float v_x;
|
|
float v_y;
|
|
float x_step;
|
|
float y_step;
|
|
int pixel;
|
|
|
|
x_step = WALL_SIZE;
|
|
y_step = WALL_SIZE * tan(angl);
|
|
v_x = floor(mlx->ply->plyr_x / WALL_SIZE) * WALL_SIZE;
|
|
pixel = inter_check(angl, &v_x, &x_step, 0);
|
|
v_y = mlx->ply->plyr_y + (v_x - mlx->ply->plyr_x) * tan(angl);
|
|
if ((unit_circle(angl, 'x') && y_step < 0) || (!unit_circle(angl, 'x')
|
|
&& y_step > 0))
|
|
y_step *= -1;
|
|
while (wall_hit(v_x - pixel, v_y, mlx))
|
|
{
|
|
v_x += x_step;
|
|
v_y += y_step;
|
|
}
|
|
mlx->ray->vert_x = v_x;
|
|
mlx->ray->vert_y = v_y;
|
|
return (sqrt(pow(v_x - mlx->ply->plyr_x, 2) + pow(v_y - mlx->ply->plyr_y,
|
|
2)));
|
|
}
|
|
|
|
void cast_rays(t_mlx *mlx)
|
|
{
|
|
double h_inter;
|
|
double v_inter;
|
|
int ray;
|
|
|
|
ray = 0;
|
|
mlx->ray->ray_ngl = mlx->ply->angle - (mlx->ply->fov_rd / 2);
|
|
while (ray < S_W)
|
|
{
|
|
mlx->ray->flag = 0;
|
|
h_inter = get_h_inter(mlx, nor_angle(mlx->ray->ray_ngl));
|
|
v_inter = get_v_inter(mlx, nor_angle(mlx->ray->ray_ngl));
|
|
if (v_inter <= h_inter)
|
|
mlx->ray->distance = v_inter;
|
|
else
|
|
{
|
|
mlx->ray->distance = h_inter;
|
|
mlx->ray->flag = 1;
|
|
}
|
|
render_wall(mlx, ray);
|
|
ray++;
|
|
mlx->ray->ray_ngl += (mlx->ply->fov_rd / S_W);
|
|
}
|
|
}
|
|
/* ************************************************************************** */
|
|
/* e_render.c :+: :+: :+: */
|
|
/* ************************************************************************** */
|
|
|
|
#include "cub3d.h"
|
|
|
|
void draw_floor_ceiling(t_mlx *mlx, int ray, int t_pix, int b_pix)
|
|
{
|
|
int i;
|
|
int c;
|
|
|
|
i = b_pix;
|
|
c = get_rgba(ft_atoi(mlx->dt->ff[0]), ft_atoi(mlx->dt->ff[1]),
|
|
ft_atoi(mlx->dt->ff[2]), 255);
|
|
while (i < S_H)
|
|
my_mlx_pixel_put(mlx, ray, i++, c);
|
|
c = get_rgba(ft_atoi(mlx->dt->cc[0]), ft_atoi(mlx->dt->cc[1]),
|
|
ft_atoi(mlx->dt->cc[2]), 255);
|
|
i = 0;
|
|
while (i < t_pix)
|
|
my_mlx_pixel_put(mlx, ray, i++, c);
|
|
}
|
|
|
|
mlx_texture_t *get_texture(t_mlx *mlx, int flag)
|
|
{
|
|
mlx->ray->ray_ngl = nor_angle(mlx->ray->ray_ngl);
|
|
if (flag == 0)
|
|
{
|
|
if (mlx->ray->ray_ngl > M_PI / 2 && mlx->ray->ray_ngl < 3 * (M_PI / 2))
|
|
return (mlx->tex->ea);
|
|
else
|
|
return (mlx->tex->we);
|
|
}
|
|
else
|
|
{
|
|
if (mlx->ray->ray_ngl > 0 && mlx->ray->ray_ngl < M_PI)
|
|
return (mlx->tex->so);
|
|
else
|
|
return (mlx->tex->no);
|
|
}
|
|
}
|
|
|
|
double get_x_o(mlx_texture_t *texture, t_mlx *mlx)
|
|
{
|
|
double x_o;
|
|
|
|
if (mlx->ray->flag == 1)
|
|
x_o = (int)fmodf((mlx->ray->horiz_x * (texture->width / WALL_SIZE)),
|
|
texture->width);
|
|
else
|
|
x_o = (int)fmodf((mlx->ray->vert_y * (texture->width / WALL_SIZE)),
|
|
texture->width);
|
|
return (x_o);
|
|
}
|
|
|
|
void draw_wall(t_mlx *mlx, int t_pix, int b_pix, double wall_h)
|
|
{
|
|
double x_o;
|
|
double y_o;
|
|
mlx_texture_t *texture;
|
|
uint32_t *arr;
|
|
double factor;
|
|
|
|
texture = get_texture(mlx, mlx->ray->flag);
|
|
arr = (uint32_t *)texture->pixels;
|
|
factor = (double)texture->height / wall_h;
|
|
x_o = get_x_o(texture, mlx);
|
|
y_o = (t_pix - (S_H / 2) + (wall_h / 2)) * factor;
|
|
if (y_o < 0)
|
|
y_o = 0;
|
|
while (t_pix < b_pix)
|
|
{
|
|
my_mlx_pixel_put(mlx, mlx->ray->index, t_pix, reverse_bytes(arr[(int)y_o
|
|
* texture->width + (int)x_o]));
|
|
y_o += factor;
|
|
t_pix++;
|
|
}
|
|
}
|
|
|
|
void render_wall(t_mlx *mlx, int ray)
|
|
{
|
|
double wall_h;
|
|
double b_pix;
|
|
double t_pix;
|
|
|
|
mlx->ray->distance *= cos(nor_angle(mlx->ray->ray_ngl - mlx->ply->angle));
|
|
wall_h = (WALL_SIZE / mlx->ray->distance) * ((S_W / 2)
|
|
/ tan(mlx->ply->fov_rd / 2));
|
|
b_pix = (S_H / 2) + (wall_h / 2);
|
|
t_pix = (S_H / 2) - (wall_h / 2);
|
|
if (b_pix > S_H)
|
|
b_pix = S_H;
|
|
if (t_pix < 0)
|
|
t_pix = 0;
|
|
mlx->ray->index = ray;
|
|
draw_wall(mlx, t_pix, b_pix, wall_h);
|
|
draw_floor_ceiling(mlx, ray, t_pix, b_pix);
|
|
}
|
|
/* ************************************************************************** */
|
|
/* e_render2.c :+: :+: :+: */
|
|
/* ************************************************************************** */
|
|
|
|
#include "cub3d.h"
|
|
|
|
int get_rgba(int r, int g, int b, int a)
|
|
{
|
|
return (r << 24 | g << 16 | b << 8 | a << 0);
|
|
}
|
|
|
|
int reverse_bytes(int c)
|
|
{
|
|
unsigned int b;
|
|
|
|
b = 0;
|
|
b |= (c & 0xFF) << 24;
|
|
b |= (c & 0xFF00) << 8;
|
|
b |= (c & 0xFF0000) >> 8;
|
|
b |= (c & 0xFF000000) >> 24;
|
|
return (b);
|
|
}
|
|
|
|
void my_mlx_pixel_put(t_mlx *mlx, int x, int y, int color)
|
|
{
|
|
if (x < 0)
|
|
return ;
|
|
else if (x >= S_W)
|
|
return ;
|
|
if (y < 0)
|
|
return ;
|
|
else if (y >= S_H)
|
|
return ;
|
|
mlx_put_pixel(mlx->img, x, y, color);
|
|
}
|
|
|
|
float nor_angle(float angle)
|
|
{
|
|
if (angle < 0)
|
|
angle += (2 * M_PI);
|
|
if (angle > (2 * M_PI))
|
|
angle -= (2 * M_PI);
|
|
return (angle);
|
|
}
|
|
|
|
int unit_circle(float angle, char c)
|
|
{
|
|
if (c == 'x')
|
|
{
|
|
if (angle > 0 && angle < M_PI)
|
|
return (1);
|
|
}
|
|
else if (c == 'y')
|
|
{
|
|
if (angle > (M_PI / 2) && angle < (3 * M_PI) / 2)
|
|
return (1);
|
|
}
|
|
return (0);
|
|
}
|
|
/* ************************************************************************** */
|
|
/* execution.c :+: :+: :+: */
|
|
/* ************************************************************************** */
|
|
|
|
#include "cub3d.h"
|
|
|
|
void drow_map_pixel(void *mlxl)
|
|
{
|
|
t_mlx *mlx;
|
|
|
|
mlx = mlxl;
|
|
mlx_delete_image(mlx->mlx_ptr, mlx->img);
|
|
mlx->img = mlx_new_image(mlx->mlx_ptr, S_W, S_H);
|
|
cub_hook(mlx, 0, 0);
|
|
cast_rays(mlx);
|
|
mlx_image_to_window(mlx->mlx_ptr, mlx->img, 0, 0);
|
|
}
|
|
|
|
int check_load_ture(t_turelist *list)
|
|
{
|
|
t_turelist *tmp;
|
|
mlx_texture_t *texture;
|
|
|
|
tmp = list;
|
|
while (tmp)
|
|
{
|
|
if (!ft_strncmp(tmp->name, "NO", 2) || !ft_strncmp(tmp->name, "SO", 2)
|
|
|| !ft_strncmp(tmp->name, "WE", 2) || !ft_strncmp(tmp->name, "EA",
|
|
2))
|
|
{
|
|
texture = mlx_load_png(tmp->value);
|
|
if (!texture)
|
|
return (0);
|
|
mlx_delete_texture(texture);
|
|
}
|
|
tmp = tmp->next;
|
|
}
|
|
return (1);
|
|
}
|
|
|
|
int load_texture(t_tex *tex, t_turelist *l_ture)
|
|
{
|
|
t_turelist *tmp;
|
|
|
|
tmp = l_ture;
|
|
if (!check_load_ture(l_ture))
|
|
return (0);
|
|
while (tmp)
|
|
{
|
|
if (!ft_strncmp(tmp->name, "NO", 2))
|
|
tex->no = mlx_load_png(tmp->value);
|
|
else if (!ft_strncmp(tmp->name, "SO", 2))
|
|
tex->so = mlx_load_png(tmp->value);
|
|
else if (!ft_strncmp(tmp->name, "WE", 2))
|
|
tex->we = mlx_load_png(tmp->value);
|
|
else if (!ft_strncmp(tmp->name, "EA", 2))
|
|
tex->ea = mlx_load_png(tmp->value);
|
|
tmp = tmp->next;
|
|
}
|
|
return (1);
|
|
}
|
|
|
|
void get_angle(t_mlx *mlx)
|
|
{
|
|
char c;
|
|
|
|
c = mlx->dt->sq_map[mlx->dt->p_y][mlx->dt->p_x];
|
|
if (c == 'N')
|
|
mlx->ply->angle = 3 * M_PI / 2;
|
|
if (c == 'S')
|
|
mlx->ply->angle = M_PI / 2;
|
|
if (c == 'E')
|
|
mlx->ply->angle = 0;
|
|
if (c == 'W')
|
|
mlx->ply->angle = M_PI;
|
|
mlx->ply->plyr_x = (mlx->dt->p_x * WALL_SIZE) + WALL_SIZE / 2;
|
|
mlx->ply->plyr_y = (mlx->dt->p_y * WALL_SIZE) + WALL_SIZE / 2;
|
|
mlx->ply->fov_rd = (FOV * M_PI / 180);
|
|
}
|
|
|
|
int execution(t_data *dt)
|
|
{
|
|
t_mlx mlx;
|
|
|
|
if (S_H > 1440 || S_W > 2560 || FOV >= 180 || FOV <= 0)
|
|
return (freelist(&dt->t_list), free_map(dt), 0);
|
|
mlx.ply = (t_player *)ft_calloc(sizeof(t_player), 1);
|
|
mlx.ray = (t_ray *)ft_calloc(sizeof(t_ray), 1);
|
|
mlx.tex = (t_tex *)ft_calloc(sizeof(t_tex), 1);
|
|
mlx.dt = dt;
|
|
mlx.mlx_ptr = mlx_init(S_W, S_H, "cub3D", false);
|
|
if (!mlx.mlx_ptr)
|
|
return (ft_exit(&mlx), 0);
|
|
if (!load_texture(mlx.tex, dt->t_list))
|
|
return (ft_exit(&mlx), 0);
|
|
get_angle(&mlx);
|
|
mlx_key_hook(mlx.mlx_ptr, &key_press, &mlx);
|
|
mlx_loop_hook(mlx.mlx_ptr, &drow_map_pixel, &mlx);
|
|
mlx_loop(mlx.mlx_ptr);
|
|
ft_exit(&mlx);
|
|
return (0);
|
|
}
|
|
/* ************************************************************************** */
|
|
/* main.c :+: :+: :+: */
|
|
/* ************************************************************************** */
|
|
|
|
#include "cub3d.h"
|
|
|
|
int main(int ac, char **av)
|
|
{
|
|
t_data dt;
|
|
|
|
if (!parsing(ac, av, &dt))
|
|
return (1);
|
|
execution(&dt);
|
|
return (0);
|
|
}
|
|
/* ************************************************************************** */
|
|
/* p_frees.c :+: :+: :+: */
|
|
/* ************************************************************************** */
|
|
|
|
#include "cub3d.h"
|
|
|
|
void freetl(char *ture, char *line, int fd)
|
|
{
|
|
if (ture)
|
|
ft_memfree(ture);
|
|
if (line)
|
|
ft_memfree(line);
|
|
if (fd >= 0)
|
|
close(fd);
|
|
}
|
|
|
|
void free_map(t_data *m)
|
|
{
|
|
free2d(m->sq_map);
|
|
free2d(m->map2d);
|
|
free2d(m->ture2d);
|
|
if (m->ff)
|
|
free2d(m->ff);
|
|
if (m->cc)
|
|
free2d(m->cc);
|
|
}
|
|
|
|
void free_m(t_mlx *mlx)
|
|
{
|
|
if (mlx->dt->sq_map)
|
|
free2d(mlx->dt->sq_map);
|
|
if (mlx->dt->map2d)
|
|
free2d(mlx->dt->map2d);
|
|
if (mlx->dt->ture2d)
|
|
free2d(mlx->dt->ture2d);
|
|
if (mlx->dt->ff)
|
|
free2d(mlx->dt->ff);
|
|
if (mlx->dt->cc)
|
|
free2d(mlx->dt->cc);
|
|
}
|
|
|
|
void freelist(t_turelist **head)
|
|
{
|
|
t_turelist *tmp;
|
|
|
|
tmp = *head;
|
|
while (tmp)
|
|
{
|
|
*head = tmp->next;
|
|
ft_memfree(tmp->name);
|
|
ft_memfree(tmp->value);
|
|
ft_memfree(tmp);
|
|
tmp = *head;
|
|
}
|
|
ft_memfree(*head);
|
|
}
|
|
/* ************************************************************************** */
|
|
/* p_lst_ture.c :+: :+: :+: */
|
|
/* ************************************************************************** */
|
|
|
|
#include "cub3d.h"
|
|
|
|
int get_index(char *line, int i)
|
|
{
|
|
while (ft_isspace(line[i]))
|
|
i++;
|
|
return (i);
|
|
}
|
|
|
|
t_turelist *new_texture(char *line)
|
|
{
|
|
t_turelist *list;
|
|
|
|
list = (t_turelist *)ft_calloc(sizeof(t_turelist), 1);
|
|
if (!list)
|
|
return (NULL);
|
|
while (ft_isspace(*line))
|
|
line++;
|
|
if ((!ft_strncmp(line, "NO", 2) || !ft_strncmp(line, "SO", 2)
|
|
|| !ft_strncmp(line, "WE", 2) || !ft_strncmp(line, "EA", 2)))
|
|
{
|
|
list->name = ft_substr(line, 0, 2);
|
|
list->value = ft_substr(line, get_index(line, 2), ft_strlen(line));
|
|
}
|
|
else if ((!ft_strncmp(line, "F", 1) || !ft_strncmp(line, "C", 1)))
|
|
{
|
|
list->name = ft_substr(line, 0, 1);
|
|
list->value = ft_substr(line, get_index(line, 1), ft_strlen(line));
|
|
}
|
|
list->next = NULL;
|
|
return (list);
|
|
}
|
|
|
|
void lst_back_ture(t_turelist **l_ture, t_turelist *new)
|
|
{
|
|
t_turelist *tmp;
|
|
|
|
if (!*l_ture)
|
|
{
|
|
(*l_ture) = new;
|
|
return ;
|
|
}
|
|
tmp = *l_ture;
|
|
while (tmp->next)
|
|
tmp = tmp->next;
|
|
tmp->next = new;
|
|
}
|
|
|
|
int lst_ture(t_data *m, t_turelist **l_ture)
|
|
{
|
|
int i;
|
|
t_turelist *tmp;
|
|
|
|
i = 0;
|
|
while (m->ture2d[i])
|
|
{
|
|
tmp = new_texture(m->ture2d[i++]);
|
|
if (!tmp)
|
|
return (0);
|
|
lst_back_ture(l_ture, tmp);
|
|
}
|
|
return (1);
|
|
}
|
|
/* ************************************************************************** */
|
|
/* p_read_map.c :+: :+: :+: */
|
|
/* ************************************************************************** */
|
|
|
|
#include "cub3d.h"
|
|
|
|
int is_surrounded(char *line)
|
|
{
|
|
while (ft_isspace(*line))
|
|
line++;
|
|
return (*line == '1' && line[ft_strlen(line) - 1] == '1');
|
|
}
|
|
|
|
int is_validmap(char *line, int *flag)
|
|
{
|
|
int i;
|
|
|
|
i = -1;
|
|
while (line[++i])
|
|
{
|
|
if ((line[i] != '1' && line[i] != 32 && line[i] != '0'
|
|
&& line[i] != '\n') && !(line[i] == 'W' || line[i] == 'E'
|
|
|| line[i] == 'N' || line[i] == 'S'))
|
|
return (0);
|
|
else if (line[i] == 'W' || line[i] == 'E' || line[i] == 'N'
|
|
|| line[i] == 'S')
|
|
(*flag)++;
|
|
}
|
|
return (1);
|
|
}
|
|
|
|
char *getmap(t_data *map)
|
|
{
|
|
char *temp;
|
|
|
|
map->map = ft_strdup("");
|
|
while (map->line)
|
|
{
|
|
if (map->line[0] == '\n')
|
|
return (ft_putstr_fd(ERR_MAP_EMPTY, 2), freetl(map->map, map->line,
|
|
-1), NULL);
|
|
temp = ft_strjoin(map->map, map->line);
|
|
ft_memfree(map->map);
|
|
ft_memfree(map->line);
|
|
map->map = ft_strdup(temp);
|
|
ft_memfree(temp);
|
|
map->line = get_next_line(map->fd);
|
|
}
|
|
return (map->map);
|
|
}
|
|
|
|
int read_map_(t_data *map, int count)
|
|
{
|
|
map->map = getmap(map);
|
|
if (!map->map)
|
|
return (0);
|
|
map->map2d = ft_split(map->map, '\n');
|
|
if (!map->map2d)
|
|
return (ft_memfree(map->map), 0);
|
|
ft_memfree(map->map);
|
|
if (!check_tures_space_tab(map->ture2d, count) || !parse_rgb(map->ture2d)
|
|
|| !check_dup(map) || !check_first_last_line(map->map2d)
|
|
|| !surounded_by_one(map->map2d))
|
|
return (free2d(map->map2d), 0);
|
|
return (1);
|
|
}
|
|
|
|
void process_map(t_data *map, int *count)
|
|
{
|
|
char *temp_ture;
|
|
|
|
while (map->line && map->line[0] != '1' && map->line[0] != 32)
|
|
{
|
|
if (check_color_textures(map->line))
|
|
{
|
|
temp_ture = ft_strjoin(map->ture, map->line);
|
|
ft_memfree(map->ture);
|
|
map->ture = strdup(temp_ture);
|
|
ft_memfree(temp_ture);
|
|
(*count)++;
|
|
}
|
|
ft_memfree(map->line);
|
|
map->line = get_next_line(map->fd);
|
|
}
|
|
}
|
|
/* ************************************************************************** */
|
|
/* p_read_map_utils.c :+: :+: :+: */
|
|
/* ************************************************************************** */
|
|
|
|
#include "cub3d.h"
|
|
|
|
int check_tures_space_tab(char **ture2d, int count)
|
|
{
|
|
int i;
|
|
|
|
i = -1;
|
|
if (count != 6)
|
|
return (0);
|
|
while (++i < count)
|
|
if (!is_valid_texture(ture2d[i]))
|
|
return (ft_putstr_fd("texture mal\n", 2), 0);
|
|
return (1);
|
|
}
|
|
|
|
int parse_rgb(char **ture2d)
|
|
{
|
|
int i;
|
|
char *ptr;
|
|
|
|
i = 0;
|
|
while (ture2d[i])
|
|
{
|
|
ptr = ture2d[i];
|
|
while (ft_isspace(*ptr))
|
|
ptr++;
|
|
if (ptr[0] == 'F' || ptr[0] == 'C')
|
|
if (count_comma(ptr) != 2 || !check_pos_cf(ptr))
|
|
return (ft_putstr_fd("color mal\n", 2), 0);
|
|
i++;
|
|
}
|
|
return (1);
|
|
}
|
|
|
|
int check_dup(t_data *m)
|
|
{
|
|
int i;
|
|
int j;
|
|
|
|
i = 0;
|
|
while (m->ture2d[i])
|
|
{
|
|
j = i + 1;
|
|
while (m->ture2d[j])
|
|
{
|
|
if (!ft_strncmp(m->ture2d[i], m->ture2d[j], 2))
|
|
return (ft_putstr_fd(ERR_MAP_DUP, 2), 0);
|
|
j++;
|
|
}
|
|
i++;
|
|
}
|
|
return (1);
|
|
}
|
|
|
|
int check_first_last_line(char **map)
|
|
{
|
|
if (!map[0])
|
|
return (ft_putstr_fd(ERR_MAP_INV, 2), 0);
|
|
if (!line_arond_one(map[0]) || !line_arond_one(map[ft_arraylen(map) - 1]))
|
|
return (ft_putstr_fd("one Y\n", 2), 0);
|
|
return (1);
|
|
}
|
|
|
|
int surounded_by_one(char **map)
|
|
{
|
|
int i;
|
|
int flag;
|
|
|
|
flag = 0;
|
|
i = -1;
|
|
while (map[++i])
|
|
if (!is_surrounded(map[i]) || !is_validmap(map[i], &flag) || flag > 1)
|
|
return (ft_putstr_fd("one X\n", 2), 0);
|
|
if (flag == 0)
|
|
return (ft_putstr_fd("no position map\n", 2), 0);
|
|
return (1);
|
|
}
|
|
/* ************************************************************************** */
|
|
/* p_textures.c :+: :+: :+: */
|
|
/* ************************************************************************** */
|
|
|
|
#include "cub3d.h"
|
|
|
|
int check_color_values(char **rgb)
|
|
{
|
|
int i;
|
|
|
|
i = -1;
|
|
while (rgb[++i])
|
|
if (ft_atoi(rgb[i]) > 255 || ft_atoi(rgb[i]) < 0)
|
|
return (free2d(rgb), 0);
|
|
return (free2d(rgb), 1);
|
|
}
|
|
|
|
void ft_process_rgb_color(t_turelist *tmp, t_data *m)
|
|
{
|
|
if (!ft_strncmp(tmp->name, "F", 2))
|
|
m->ff = ft_split(tmp->value, ',');
|
|
else if (!ft_strncmp(tmp->name, "C", 2))
|
|
m->cc = ft_split(tmp->value, ',');
|
|
return ;
|
|
}
|
|
|
|
int color_ture(t_data *m, t_turelist *l_ture)
|
|
{
|
|
t_turelist *tmp;
|
|
|
|
m->cc = NULL;
|
|
m->ff = NULL;
|
|
tmp = l_ture;
|
|
while (tmp)
|
|
{
|
|
if (!ft_strncmp(tmp->name, "F", 1) || !ft_strncmp(tmp->name, "C", 1))
|
|
{
|
|
if (!check_color_values(ft_split(tmp->value, ',')))
|
|
return (ft_putstr_fd(ERR_MAP_RGB, 2), 0);
|
|
ft_process_rgb_color(tmp, m);
|
|
}
|
|
tmp = tmp->next;
|
|
}
|
|
return (1);
|
|
}
|
|
|
|
int check_color_textures(char *line)
|
|
{
|
|
while (ft_isspace(*line))
|
|
line++;
|
|
return ((!ft_strncmp(line, "EA", 2) || !ft_strncmp(line, "NO", 2)
|
|
|| !ft_strncmp(line, "SO", 2) || !ft_strncmp(line, "WE", 2))
|
|
|| (!ft_strncmp(line, "F", 1) || !ft_strncmp(line, "C", 1)));
|
|
}
|
|
|
|
int check_count_textures(t_data *m, int count)
|
|
{
|
|
(void)m;
|
|
if (count != 6)
|
|
return (ft_putstr_fd(ERR_MAP_INV, 2), 0);
|
|
return (1);
|
|
}
|
|
/* ************************************************************************** */
|
|
/* p_textures_utils.c :+: :+: :+: */
|
|
/* ************************************************************************** */
|
|
|
|
#include "cub3d.h"
|
|
|
|
int is_valid_texture(char *line)
|
|
{
|
|
while (ft_isspace(*line))
|
|
line++;
|
|
if ((!ft_strncmp(line, "NO", 2) || !ft_strncmp(line, "SO", 2)
|
|
|| !ft_strncmp(line, "WE", 2) || !ft_strncmp(line, "EA", 2))
|
|
&& ft_isspace(line[2]))
|
|
return (1);
|
|
else if ((!ft_strncmp(line, "F", 1) || !ft_strncmp(line, "C", 1))
|
|
&& ft_isspace(line[1]))
|
|
return (1);
|
|
return (0);
|
|
}
|
|
|
|
int count_comma(char *rgb)
|
|
{
|
|
int i;
|
|
int count;
|
|
|
|
i = 0;
|
|
count = 0;
|
|
while (rgb[i])
|
|
if (rgb[i++] == ',')
|
|
count++;
|
|
return (count);
|
|
}
|
|
|
|
int check_pos_cf(char *l)
|
|
{
|
|
int i;
|
|
int flag;
|
|
|
|
flag = 0;
|
|
i = 0;
|
|
while (ft_isspace(*l) || *l == 'C' || *l == 'F')
|
|
{
|
|
if (*l == 'C' || *l == 'F')
|
|
flag++;
|
|
l++;
|
|
}
|
|
if (flag != 1)
|
|
return (0);
|
|
if (!ft_isdigit(l[i]) || !ft_isdigit(l[(ft_strlen(l) - 1)]))
|
|
return (0);
|
|
while (l[i])
|
|
{
|
|
if ((!ft_isdigit(l[i]) && l[i] != ',') || (l[i] == ',' && l[i + 1]
|
|
&& l[i + 1] == ','))
|
|
return (0);
|
|
i++;
|
|
}
|
|
return (1);
|
|
}
|
|
|
|
int line_arond_one(char *line)
|
|
{
|
|
int i;
|
|
|
|
i = -1;
|
|
while (line[++i])
|
|
if (line[i] != '1' && line[i] != 32)
|
|
return (0);
|
|
return (1);
|
|
}
|
|
|
|
char *getlastline(char **map)
|
|
{
|
|
int i;
|
|
|
|
i = 0;
|
|
while (map[i + 1])
|
|
i++;
|
|
return (map[i]);
|
|
}
|
|
/* ************************************************************************** */
|
|
/* p_valid_map.c :+: :+: :+: */
|
|
/* ************************************************************************** */
|
|
|
|
#include "cub3d.h"
|
|
|
|
int h_map(char **map)
|
|
{
|
|
int i;
|
|
int j;
|
|
|
|
i = 0;
|
|
while (map[i])
|
|
{
|
|
j = 0;
|
|
while (map[i][j])
|
|
{
|
|
if (map[i][j] != '1' && map[i][j] != ' ')
|
|
if (map[i][j - 1] == ' ' || map[i][j + 1] == ' ')
|
|
return (ft_putstr_fd(ERR_MAP_INV, 2), 0);
|
|
j++;
|
|
}
|
|
i++;
|
|
}
|
|
return (1);
|
|
}
|
|
|
|
int v_map(char **map)
|
|
{
|
|
int i;
|
|
int j;
|
|
|
|
i = 0;
|
|
while (map[i])
|
|
{
|
|
j = 0;
|
|
while (map[i][j])
|
|
{
|
|
if (map[i][j] != '1' && map[i][j] != ' ')
|
|
if (map[i - 1][j] == ' ' || map[i + 1][j] == ' ')
|
|
return (ft_putstr_fd(ERR_MAP_INV, 2), 0);
|
|
j++;
|
|
}
|
|
i++;
|
|
}
|
|
return (1);
|
|
}
|
|
|
|
char *fixline(char *line, int maxlen)
|
|
{
|
|
char *new;
|
|
int i;
|
|
|
|
i = 0;
|
|
new = ft_calloc(sizeof(char), (maxlen + 1));
|
|
if (!new)
|
|
return (NULL);
|
|
while (line[i])
|
|
{
|
|
new[i] = line[i];
|
|
i++;
|
|
}
|
|
while (i < maxlen)
|
|
{
|
|
new[i] = ' ';
|
|
i++;
|
|
}
|
|
return (new);
|
|
}
|
|
|
|
int getsize_line(char **map)
|
|
{
|
|
int i;
|
|
int max;
|
|
|
|
i = -1;
|
|
max = ft_strlen(map[0]);
|
|
while (map[++i])
|
|
if ((int)ft_strlen(map[i]) > max)
|
|
max = ft_strlen(map[i]);
|
|
return (max);
|
|
}
|
|
|
|
int valid_map(t_data *m)
|
|
{
|
|
int i;
|
|
int maxlen;
|
|
|
|
maxlen = getsize_line(m->map2d);
|
|
m->sq_map = ft_calloc(sizeof(char *), (ft_arraylen(m->map2d) + 1));
|
|
if (!m->sq_map)
|
|
return (0);
|
|
i = -1;
|
|
while (m->map2d[++i])
|
|
{
|
|
if (maxlen == (int)ft_strlen(m->map2d[i]))
|
|
m->sq_map[i] = ft_strdup(m->map2d[i]);
|
|
else
|
|
m->sq_map[i] = fixline(m->map2d[i], maxlen);
|
|
}
|
|
m->h_map = ft_arraylen(m->sq_map);
|
|
m->w_map = ft_strlen(m->sq_map[0]);
|
|
if (!h_map(m->sq_map) || !v_map(m->sq_map))
|
|
return (free2d(m->sq_map), free2d(m->map2d), free2d(m->ture2d), 0);
|
|
return (1);
|
|
}
|
|
/* ************************************************************************** */
|
|
/* parsing.c :+: :+: :+: */
|
|
/* ************************************************************************** */
|
|
|
|
#include "cub3d.h"
|
|
|
|
int read_map(char *av, t_data *map, int *count)
|
|
{
|
|
map->fd = open(av, O_RDONLY);
|
|
if (map->fd == -1)
|
|
return (ft_putstr_fd(ERR_INV_FILE, 2), 0);
|
|
map->line = get_next_line(map->fd);
|
|
if (map->line == NULL)
|
|
return (ft_putstr_fd(ERR_EMPTY_FILE, 2), 0);
|
|
map->ture = ft_strdup("");
|
|
process_map(map, count);
|
|
if (!check_count_textures(map, *count))
|
|
return (freetl(map->ture, map->line, map->fd), 0);
|
|
map->ture2d = ft_split(map->ture, '\n');
|
|
if (!map->ture2d)
|
|
return (freetl(map->ture, map->line, map->fd), 0);
|
|
if (!read_map_(map, *count))
|
|
return (freetl(map->ture, map->line, map->fd), free2d(map->ture2d), 0);
|
|
return (freetl(map->ture, map->line, map->fd), 1);
|
|
}
|
|
|
|
void get_x_y_player(t_data *m)
|
|
{
|
|
int i;
|
|
int j;
|
|
|
|
i = 0;
|
|
while (m->sq_map[i])
|
|
{
|
|
j = 0;
|
|
while (m->sq_map[i][j])
|
|
{
|
|
if (m->sq_map[i][j] == 'N' || m->sq_map[i][j] == 'S'
|
|
|| m->sq_map[i][j] == 'W' || m->sq_map[i][j] == 'E')
|
|
{
|
|
m->p_x = j;
|
|
m->p_y = i;
|
|
return ;
|
|
}
|
|
j++;
|
|
}
|
|
i++;
|
|
}
|
|
}
|
|
|
|
int check_extension_map(char *file_name)
|
|
{
|
|
char *dot;
|
|
|
|
dot = ft_strrchr(file_name, '.');
|
|
return (dot && !ft_strcmp(dot, ".cub"));
|
|
}
|
|
|
|
int parsing(int ac, char **av, t_data *data)
|
|
{
|
|
int count;
|
|
|
|
if (ac != 2 || !check_extension_map(av[1]))
|
|
return (ft_putstr_fd(ERR_INV_COP, 2), 0);
|
|
count = 0;
|
|
if (!read_map(av[1], data, &count))
|
|
return (0);
|
|
if (!valid_map(data))
|
|
return (0);
|
|
data->t_list = NULL;
|
|
if (!lst_ture(data, &data->t_list))
|
|
return (free_map(data), freelist(&data->t_list), 0);
|
|
if (!color_ture(data, data->t_list))
|
|
return (free_map(data), freelist(&data->t_list), 0);
|
|
get_x_y_player(data);
|
|
return (1);
|
|
}
|