From d91a3ef90ba3975b7c3bd47b69ce7febda2a77a7 Mon Sep 17 00:00:00 2001
From: Rudy Bousset <rbousset@z3r8p1.le-101.fr>
Date: Thu, 13 Feb 2020 18:30:37 +0100
Subject: Smooth

---
 Makefile              |  5 +++-
 inc/cub3d.h           |  5 ++++
 inc/cub3d_structs.h   | 23 ++++++++++++++++++
 src/ft_detect.c       | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++
 src/ft_draw_verline.c | 28 +++++++++++++++++++++
 src/ft_drawmap.c      |  1 +
 src/ft_init_lists.c   |  8 ++++++
 src/ft_init_s_ray.c   | 25 +++++++++++++++++++
 src/ft_raycasting.c   | 41 ++++++++++++++++++++++++++-----
 9 files changed, 196 insertions(+), 7 deletions(-)
 create mode 100644 src/ft_detect.c
 create mode 100644 src/ft_draw_verline.c
 create mode 100644 src/ft_init_s_ray.c

diff --git a/Makefile b/Makefile
index 4e90778..ffe8446 100644
--- a/Makefile
+++ b/Makefile
@@ -23,7 +23,6 @@ SRCS_NAME	+= ft_hooks_and_loops.c
 SRCS_NAME	+= ft_key_events.c
 SRCS_NAME	+= ft_click_close.c
 SRCS_NAME	+= ft_exit.c
-SRCS_NAME	+= ft_drawsquare.c
 SRCS_NAME	+= ft_parse_map.c
 SRCS_NAME	+= ft_select_get.c
 SRCS_NAME	+= ft_get_screen_size.c
@@ -39,10 +38,14 @@ SRCS_NAME	+= ft_check_map_line.c
 SRCS_NAME	+= ft_free_words.c
 SRCS_NAME	+= ft_map_error.c
 SRCS_NAME	+= ft_init_winlx.c
+SRCS_NAME	+= ft_drawsquare.c
 SRCS_NAME	+= ft_drawmap.c
+SRCS_NAME	+= ft_draw_verline.c
 SRCS_NAME	+= ft_print_list.c
 SRCS_NAME	+= ft_rgb_to_hex.c
 SRCS_NAME	+= ft_raycasting.c
+SRCS_NAME	+= ft_init_s_ray.c
+SRCS_NAME	+= ft_detect.c
 #------------------------------------------------------------------------------#
 SRCS		= $(addprefix ${SRCS_DIR},${SRCS_NAME})
 #------------------------------------------------------------------------------#
diff --git a/inc/cub3d.h b/inc/cub3d.h
index 777360b..f0dbf61 100644
--- a/inc/cub3d.h
+++ b/inc/cub3d.h
@@ -85,5 +85,10 @@ int					ft_init_winlx(t_cub *clist);
 void				ft_drawmap(t_cub *clist);
 void				ft_print_list(t_cub *clist);
 uint32_t			ft_rgb_to_hex(t_rgb rgb);
+t_ray				ft_init_s_ray(void);
+void				ft_detect(t_cub *cl);
+int8_t				ft_draw_verline(t_cub *cl, int32_t x, int32_t y1,
+									int32_t y2, int32_t color);
+void				ft_castray(t_cub *cl);
 
 #	endif
diff --git a/inc/cub3d_structs.h b/inc/cub3d_structs.h
index cc5d805..0c3cb7c 100644
--- a/inc/cub3d_structs.h
+++ b/inc/cub3d_structs.h
@@ -41,6 +41,11 @@ typedef struct		s_player
 	float			pos_x;
 	float			pos_y;
 	float			view_side;
+	float			dir_x;
+	float			dir_y;
+	float			cam_x;
+	float			plane_x;
+	float			plane_y;
 }					t_player;
 
 /* typedef struct		s_ray */
@@ -61,6 +66,21 @@ typedef struct		s_player
 typedef struct		s_ray
 {
 	uint16_t		line_h;
+	float			wall_dist;
+	float			x_ray_pos;
+	float			y_ray_pos;
+	float			x_ray_dir;
+	float			y_ray_dir;
+	float			x_side_dist;
+	float			y_side_dist;
+	float			x_delta_dist;
+	float			y_delta_dist;
+	int16_t			wall_t;
+	int16_t			wall_b;
+	uint8_t			side;
+	size_t			sqx;
+	size_t			sqy;
+	uint8_t			hit;
 }					t_ray;
 
 typedef struct		s_cub
@@ -72,6 +92,8 @@ typedef struct		s_cub
 	char			*sprite_path;
 	char			*mapl;
 	char			**map;
+	int8_t			x_step;
+	int8_t			y_step;
 	size_t			map_w;
 	size_t			map_h;
 	size_t			line_chk;
@@ -80,6 +102,7 @@ typedef struct		s_cub
 	uint8_t			scale;
 	struct s_win	*wlist;
 	struct s_player	*plist;
+	struct s_ray	rlist;
 	struct s_img	img;
 	struct s_rgb	f_rgb;
 	struct s_rgb	c_rgb;
diff --git a/src/ft_detect.c b/src/ft_detect.c
new file mode 100644
index 0000000..b83c9f1
--- /dev/null
+++ b/src/ft_detect.c
@@ -0,0 +1,67 @@
+#include <cub3d.h>
+#include <math.h>
+
+static void
+ft_detection_init_y(t_cub *cl)
+{
+	cl->rlist.y_delta_dist = sqrt(1 + (cl->rlist.x_ray_dir *
+		cl->rlist.x_ray_dir) / (cl->rlist.y_ray_dir *
+		cl->rlist.y_ray_dir));
+	if (cl->rlist.y_ray_dir < 0)
+	{
+		cl->y_step = -1;
+		cl->rlist.y_side_dist = (cl->rlist.y_ray_pos -
+			cl->rlist.sqy) * cl->rlist.y_delta_dist;
+	}
+	else
+	{
+		cl->y_step = 1;
+		cl->rlist.y_side_dist = (cl->rlist.sqy + 1.0 -
+			cl->rlist.y_ray_pos) * cl->rlist.y_delta_dist;
+	}
+}
+
+static void
+ft_detection_init_x(t_cub *cl)
+{
+	cl->rlist.x_delta_dist = sqrt(1 + (cl->rlist.y_ray_dir *
+		cl->rlist.y_ray_dir) / (cl->rlist.x_ray_dir *
+		cl->rlist.x_ray_dir));
+	if (cl->rlist.x_ray_dir < 0)
+	{
+		cl->x_step = -1;
+		cl->rlist.x_side_dist = (cl->rlist.x_ray_pos -
+			cl->rlist.sqx) * cl->rlist.x_delta_dist;
+	}
+	else
+	{
+		cl->x_step = 1;
+		cl->rlist.x_side_dist = (cl->rlist.sqx + 1.0 -
+			cl->rlist.x_ray_pos) * cl->rlist.x_delta_dist;
+	}
+	ft_detection_init_y(cl);
+}
+
+void
+ft_detect(t_cub *cl)
+{
+	ft_detection_init_x(cl);
+	cl->rlist.hit = 0;	
+	while (cl->rlist.hit == 0)
+	{
+		if (cl->rlist.x_side_dist < cl->rlist.y_side_dist)
+		{
+			cl->rlist.x_side_dist += cl->rlist.x_delta_dist;
+			cl->rlist.sqx += cl->x_step;
+			cl->rlist.side = 0;
+		}
+		else
+		{
+			cl->rlist.y_side_dist += cl->rlist.y_delta_dist;
+			cl->rlist.sqy += cl->y_step;
+			cl->rlist.side = 1;
+		}
+		if (cl->map[cl->rlist.sqx][cl->rlist.sqy] == '1')
+			cl->rlist.hit = 1;
+	}
+}
diff --git a/src/ft_draw_verline.c b/src/ft_draw_verline.c
new file mode 100644
index 0000000..4544aa0
--- /dev/null
+++ b/src/ft_draw_verline.c
@@ -0,0 +1,28 @@
+#include <cub3d.h>
+
+int8_t
+ft_draw_verline(t_cub *cl, int32_t x, int32_t y1, int32_t y2, int32_t color)
+{
+	int32_t y;
+	int32_t t;
+
+	if (y1 < 0)
+		y1 = 0;
+	if (y2 < 0)
+		y2 = 0;
+	if (y2 >= cl->wlist->y_size)
+		y2 = cl->wlist->x_size - 1;
+	if (y1 > y2)
+	{
+		t = y1;
+		y1 = y2;
+		y2 = t;
+	}
+	y = y1;
+	while (y <= y2)
+	{
+		*(int*)(cl->img.ptr + (x * 4 + (y * cl->img.sizeline))) = color;
+		y++;
+	}
+	return (0);
+}
diff --git a/src/ft_drawmap.c b/src/ft_drawmap.c
index ce5c0fc..1526ae6 100644
--- a/src/ft_drawmap.c
+++ b/src/ft_drawmap.c
@@ -70,6 +70,7 @@ void
 						&clist->img.sizeline, &clist->img.endian);
 	ft_draw_core_map(clist->map, clist);
 	ft_draw_player(clist->plist, clist);
+	ft_castray(clist);
 	mlx_put_image_to_window(clist->wlist->wlx,
 						clist->wlist->winptr, clist->img.img, 0, 0);
 	mlx_destroy_image(clist->wlist->wlx, clist->img.img);
diff --git a/src/ft_init_lists.c b/src/ft_init_lists.c
index a30e166..1233eaa 100644
--- a/src/ft_init_lists.c
+++ b/src/ft_init_lists.c
@@ -39,6 +39,11 @@ static t_player
 	plist->pos_x = 0;
 	plist->pos_y = 0;
 	plist->view_side = 0;
+	plist->cam_x = 0;
+	plist->dir_x = -1;
+	plist->dir_y = 0;
+	plist->plane_x = 0;
+	plist->plane_y = 0.50;
 	return (plist);
 }
 
@@ -80,11 +85,14 @@ static t_cub
 	clist->map[1] = 0;
 	clist->map_w = 0;
 	clist->map_h = 0;
+	clist->x_step = 0;
+	clist->y_step = 0;
 	clist->line_chk = 0;
 	clist->map_start = 0;
 	clist->isspawn = 0;
 	clist->f_rgb = ft_init_rgb();
 	clist->c_rgb = ft_init_rgb();
+	clist->rlist = ft_init_s_ray();
 	return (clist);
 }
 
diff --git a/src/ft_init_s_ray.c b/src/ft_init_s_ray.c
new file mode 100644
index 0000000..5dd0a01
--- /dev/null
+++ b/src/ft_init_s_ray.c
@@ -0,0 +1,25 @@
+#include <cub3d.h>
+
+t_ray
+ft_init_s_ray(void)
+{
+	t_ray	rl;
+
+	rl.line_h = 0;
+	rl.wall_dist = 0;
+	rl.wall_t = 0;
+	rl.wall_b = 0;
+	rl.x_ray_pos = 0;
+	rl.y_ray_pos = 0;
+	rl.x_ray_dir = 0;
+	rl.y_ray_dir = 0;
+	rl.x_side_dist = 0;
+	rl.y_side_dist = 0;
+	rl.x_delta_dist = 0;
+	rl.y_delta_dist = 0;
+	rl.side = 0;
+	rl.sqx = 0;
+	rl.sqy = 0;
+	rl.hit = 0;
+	return (rl);
+}
diff --git a/src/ft_raycasting.c b/src/ft_raycasting.c
index d36eacf..8aa4dbe 100644
--- a/src/ft_raycasting.c
+++ b/src/ft_raycasting.c
@@ -2,21 +2,50 @@
 #include <stdint.h>
 
 static void
-ft_initray(t_cub *clist, uint16_t i)
+ft_initray(t_cub *cl, uint16_t i)
 {
-	(void)clist;
-	(void)i;
+	t_win		*wl;
+	t_player	*pl;
+
+	wl = cl->wlist;
+	pl = cl->plist;
+	pl->cam_x = 2 * i / (float)(wl->x_size) - 1;
+	cl->rlist.x_ray_pos = pl->pos_y;
+	cl->rlist.y_ray_pos = pl->pos_x;
+	cl->rlist.x_ray_dir = pl->dir_x + pl->plane_x *
+		pl->cam_x;
+	cl->rlist.y_ray_dir = pl->dir_y + pl->plane_y *
+		pl->cam_x;
+	cl->rlist.sqx = (int16_t)cl->rlist.x_ray_pos;
+	cl->rlist.sqy = (int16_t)cl->rlist.y_ray_pos;
+	ft_detect(cl);
+	if (cl->rlist.side == 0)
+		cl->rlist.wall_dist = (cl->rlist.sqx - cl->rlist.x_ray_pos +
+		(1 - cl->x_step) / 2) / cl->rlist.x_ray_dir;
+	else
+		cl->rlist.wall_dist = (cl->rlist.sqy - cl->rlist.y_ray_pos +
+		(1 - cl->y_step) / 2) / cl->rlist.y_ray_dir;
 }
 
 void
-ft_castray(t_cub *clist)
+ft_castray(t_cub *cl)
 {
 	uint16_t	i;
+	t_win		*wl;
 
 	i = 0;
-	while (i < clist->wlist->y_size)
+	wl = cl->wlist;
+	while (i < wl->x_size)
 	{
-		ft_initray(clist, i);
+		ft_initray(cl, i);
+		cl->rlist.line_h = (int16_t)(wl->y_size / cl->rlist.wall_dist);
+		cl->rlist.wall_t = -cl->rlist.line_h / 2 + wl->y_size / 2;
+		if (cl->rlist.wall_t < 0)
+			cl->rlist.wall_t = 0;
+		cl->rlist.wall_b = cl->rlist.line_h / 2 + wl->y_size / 2;
+		if (cl->rlist.wall_b >= wl->y_size)\
+			cl->rlist.wall_b = wl->y_size - 1;
+		ft_draw_verline(cl, i, cl->rlist.wall_t - 1, cl->rlist.wall_b, 0x0000ffaa);
 		i++;
 	}
 }
-- 
cgit v1.2.3