/* ************************************************************************** */ /* */ /* ::: :::::::: */ /* ft_raycasting.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: rbousset +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/02/14 17:22:57 by rbousset #+# #+# */ /* Updated: 2020/02/14 17:23:42 by rbousset ### ########lyon.fr */ /* */ /* ************************************************************************** */ #include #include #include #include #include #include static void ft_calc_tex(t_cub *cl) { if (cl->rlist.side == 0) cl->rlist.wall_hit_x = (cl->plist.pos_x) + cl->rlist.wall_dist * cl->rlist.y_ray_dir; else cl->rlist.wall_hit_x = (cl->plist.pos_y) + cl->rlist.wall_dist * cl->rlist.x_ray_dir; cl->rlist.wall_hit_x -= floor(cl->rlist.wall_hit_x); cl->tlist[cl->w_side].tex_x = (int)(cl->rlist.wall_hit_x * (double)cl->tlist[cl->w_side].img_w); if (cl->rlist.side == 0 && cl->rlist.x_ray_dir > 0) cl->tlist[cl->w_side].tex_x = cl->tlist[cl->w_side].img_w - cl->tlist[cl->w_side].tex_x - 1; else if (cl->rlist.side == 1 && cl->rlist.y_ray_dir < 0) cl->tlist[cl->w_side].tex_x = cl->tlist[cl->w_side].img_w - cl->tlist[cl->w_side].tex_x - 1; } static void ft_initray(uint16_t i, t_cub *cl) { 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->mlist.x_step) / 2) / cl->rlist.x_ray_dir; } else { cl->rlist.wall_dist = (cl->rlist.sqy - cl->rlist.y_ray_pos + (1 - cl->mlist.y_step) / 2) / cl->rlist.y_ray_dir; } } static void ft_castray_loop(uint16_t i, t_win *wl, t_cub *cl) { ft_initray(i, cl); 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 >= (int16_t)wl->y_size) cl->rlist.wall_b = wl->y_size - 1; ft_choose_tex(i, cl); ft_calc_tex(cl); cl->rlist.tex_x_tab[i] = cl->tlist[cl->w_side].tex_x; cl->rlist.line_h_tab[i] = cl->rlist.line_h; cl->rlist.wall_t_tab[i] = cl->rlist.wall_t; cl->rlist.wall_bz[i] = cl->rlist.wall_b; cl->rlist.wall_dist_tab[i] = cl->rlist.wall_dist; } static void ft_set_fc_tex_xy(uint8_t tid, uint16_t x, uint16_t y, t_cub *cl) { const int32_t x_cell = (int32_t)(cl->rlist.x_floor); const int32_t y_cell = (int32_t)(cl->rlist.y_floor); cl->tlist[tid].tex_x = (int32_t)(cl->tlist[tid].img_h * (cl->rlist.y_floor - y_cell)); cl->tlist[tid].tex_y = (int32_t)(cl->tlist[tid].img_w * (cl->rlist.x_floor - x_cell)); cl->rlist.fc_tex_x_tab[tid - 6][y][x] = cl->tlist[tid].tex_x; cl->rlist.fc_tex_y_tab[tid - 6][y][x] = cl->tlist[tid].tex_y; } void ft_castray(t_cub *cl) { pthread_t tid[2]; uint16_t y; uint16_t x; if (!(cl->rlist.wall_dist_tab = (float*)malloc(cl->wlist.x_size * sizeof(float))) || !(cl->rlist.wall_bz = (int16_t*)malloc(cl->wlist.x_size * sizeof(int16_t))) || !(cl->rlist.w_side_tab = (uint8_t*)malloc(cl->wlist.x_size * sizeof(uint8_t))) || !(cl->rlist.line_h_tab = (uint16_t*)malloc(cl->wlist.x_size * sizeof(uint16_t))) || !(cl->rlist.wall_t_tab = (int16_t*)malloc(cl->wlist.x_size * sizeof(int16_t))) || !(cl->rlist.tex_x_tab = (int32_t*)malloc(cl->wlist.x_size * sizeof(int32_t))) || !(cl->rlist.fc_tex_x_tab = (int32_t***)malloc(2 * sizeof(int32_t**))) || !(cl->rlist.fc_tex_y_tab = (int32_t***)malloc(2 * sizeof(int32_t**))) || !(cl->rlist.row_dist_tab = (float*)malloc(cl->wlist.y_size * sizeof(float)))) ft_error(FT_RET_ALLOC_ERR, FT_ERR_ALLOCATE, cl); x = 0; while (x < 2) { if (!(cl->rlist.fc_tex_x_tab[x] = (int**)malloc(cl->wlist.y_size * sizeof(int*))) || !(cl->rlist.fc_tex_y_tab[x] = (int**)malloc(cl->wlist.y_size * sizeof(int*)))) ft_error(FT_RET_ALLOC_ERR, FT_ERR_ALLOCATE, cl); y = 0; while (y < cl->wlist.y_size) { if (!(cl->rlist.fc_tex_x_tab[x][y] = (int*)malloc(cl->wlist.x_size * sizeof(int))) || !(cl->rlist.fc_tex_y_tab[x][y] = (int*)malloc(cl->wlist.x_size * sizeof(int)))) ft_error(FT_RET_ALLOC_ERR, FT_ERR_ALLOCATE, cl); y++; } x++; } x = 0; while (x < cl->wlist.x_size) { ft_castray_loop(x, &cl->wlist, cl); x++; } y = cl->wlist.y_size / 2; while (y < cl->wlist.y_size) { x = 0; ft_floor_cast_inits(y, &cl->rlist, cl); while (x < cl->wlist.x_size) { if (cl->rlist.wall_bz[x] <= y) { if (cl->mlist.isftex) ft_set_fc_tex_xy(6, x, y, cl); if (cl->mlist.isctex && !cl->mlist.isskybox) ft_set_fc_tex_xy(7, x, cl->wlist.y_size - y - 1, cl); } cl->rlist.x_floor += cl->mlist.x_floor_step; cl->rlist.y_floor += cl->mlist.y_floor_step; x++; } cl->rlist.row_dist_tab[y] = cl->rlist.row_dist; cl->rlist.row_dist_tab[cl->wlist.y_size - y] = cl->rlist.row_dist; y++; } pthread_create(&tid[0], 0x0, ft_wall_cast, (void*)cl); pthread_create(&tid[1], 0x0, ft_floor_cast, (void*)cl); pthread_join(tid[0], 0x0); pthread_join(tid[1], 0x0); x = 0; while (x < 2) { y = 0; while (y < cl->wlist.y_size) { ft_memdel((void*)&cl->rlist.fc_tex_x_tab[x][y]); ft_memdel((void*)&cl->rlist.fc_tex_y_tab[x][y]); y++; } ft_memdel((void*)&cl->rlist.fc_tex_x_tab[x]); ft_memdel((void*)&cl->rlist.fc_tex_y_tab[x]); x++; } ft_memdel((void*)&cl->rlist.fc_tex_x_tab); ft_memdel((void*)&cl->rlist.fc_tex_y_tab); ft_memdel((void*)&cl->rlist.tex_x_tab); ft_memdel((void*)&cl->rlist.row_dist_tab); ft_memdel((void*)&cl->rlist.wall_t_tab); ft_memdel((void*)&cl->rlist.w_side_tab); ft_memdel((void*)&cl->rlist.line_h_tab); ft_memdel((void*)&cl->rlist.wall_bz); ft_calc_sprite(cl); ft_calc_heal(cl); ft_calc_trap(cl); ft_calc_weaps(cl); if (cl->plist.handles_weapon > -1) ft_draw_handweap(cl); ft_memdel((void*)&cl->rlist.wall_dist_tab); }