diff --git a/Makefile b/Makefile index 9262555..27e6eee 100644 --- a/Makefile +++ b/Makefile @@ -27,16 +27,16 @@ SRCS += init_struct.c \ init_parsing.c # hook/ SRCS += keyhook.c \ - key_do_action.c \ - key_is_action_1.c \ - key_is_action_2.c + key_action_1.c \ + key_action_2.c # player/ SRCS += player_moves.c \ player_rotates.c \ player_limits.c # draw/ SRCS += draw.c \ - draw_window.c + ray_intersect.c \ + raycast.c # headers D_HEADERS = headers diff --git a/headers/cube3d_macro.h b/headers/cube3d_macro.h index 0acd529..9efe213 100644 --- a/headers/cube3d_macro.h +++ b/headers/cube3d_macro.h @@ -5,6 +5,8 @@ # define SCREEN_DIST 50 # define SCREEN_SIZE 100 # define SCREEN_DEF 50 +# define PLR_MV 5 +# define CELL 20 # define ARROW_LEFT 65361 # define ARROW_UP 65362 diff --git a/headers/cube3d_proto.h b/headers/cube3d_proto.h index 3fb72cb..2fcbe4a 100644 --- a/headers/cube3d_proto.h +++ b/headers/cube3d_proto.h @@ -27,17 +27,16 @@ void init_parsing(int ac, char **av, t_game *game); // SRC/HOOK // ------------------------------- // keyhook.c -int keypress(int keycode, t_game *game); -int keyrelease(int keycode, t_game *game); -// key_do_action.c -void keypress_do_action(t_game *game); -// key_is_action_1.c +int keypress(int keycode, t_game *game); +int keyrelease(int keycode, t_game *game); +int hook_action(t_game *game); +// key_action_1.c int is_esc(int *k_hook, int *is_action); int is_go_left(int *k_hook, int *is_action); int is_go_right(int *k_hook, int *is_action); int is_go_forward(int *k_hook, int *is_action); int is_go_backward(int *k_hook, int *is_action); -// key_is_action_2.c +// key_action_2.c int is_turn_left(int *k_hook, int *is_action); int is_turn_right(int *k_hook, int *is_action); @@ -46,13 +45,15 @@ int is_turn_right(int *k_hook, int *is_action); // SRC/PLAYER // ------------------------------- // player_moves.c -void plr_posx_decrement(t_game *game); -void plr_posy_decrement(t_game *game); -void plr_posx_increment(t_game *game); -void plr_posy_increment(t_game *game); +void plr_posx_decrement(t_game *game, t_plr *plr); +void plr_posy_decrement(t_game *game, t_plr *plr); +void plr_posx_increment(t_game *game, t_plr *plr); +void plr_posy_increment(t_game *game, t_plr *plr); // player_rotates.c -void plr_turn_right(t_game *game); -void plr_turn_left(t_game *game); +void rotate(t_plr *plr, t_coord *coord); +void rotate_double(t_plr *plr, t_d_coord *coord); +void plr_turn_right(t_plr *plr); +void plr_turn_left(t_plr *plr); // player_limits.c int plr_out_limits(t_game *game, int x, int y); int is_wall(t_game *game, int cell_x, int cell_y); @@ -62,12 +63,11 @@ int is_wall(t_game *game, int cell_x, int cell_y); // ------------------------------- // draw.c void draw_pixel(t_game *game, int x, int y, int color); -void rotate(t_game *game, int *x, int *y); -void rotate_double(t_game *game, double *x, double *y); -void draw_line(t_game *game, int start_x, int start_y, int end_x, int end_y, int color); +void draw_line(t_game *game, t_vec vec, int color); void draw(t_game *game); -// draw_window.c -void draw_rays(t_game *game); -void draw_map(t_game *game); +// raycast.c +void raycast(t_game *game, t_rcast *rcast); +// ray_intersect.c +void ray_intersect(t_game *game, t_rcast *rcast, t_vec *ray); #endif diff --git a/headers/cube3d_struct.h b/headers/cube3d_struct.h index 56d3237..a0b8e49 100644 --- a/headers/cube3d_struct.h +++ b/headers/cube3d_struct.h @@ -1,52 +1,129 @@ #ifndef CUBE3D_STRUCT_H # define CUBE3D_STRUCT_H +/* + * 3 structs with coordinates for + * - simple precision point + * - double precision point + * - vector (two points) + */ + +typedef struct s_d_coord +{ + double x; + double y; +} t_d_coord; + +typedef struct s_coord +{ + int x; + int y; +} t_coord; + typedef struct s_vec { - int start_x; - int start_y; - int end_x; - int end_y; + t_coord start; + t_coord end; } t_vec; -typedef struct s_game +/* + * struct with all elements for raycasting + */ + +typedef struct s_rcast { - // window - void *mlx_ptr; - void *win_ptr; - int win_size_x; - int win_size_y; - // rays t_vec screen_dist; t_vec screen_size; t_vec ray; - // tmp - int ray_highlight; - int ray_activ; - // map - int map_size_x; - int map_size_y; - char **map; - int cell; + int cell_x; + int cell_y; + int slope_x; + int slope_y; + int ray_sign_x; + int ray_sign_y; + int first_next_x; + int first_next_y; + int next_x; + int next_y; + int next_cell_x; + int next_cell_y; + int ray_step_x; + int ray_step_y; + int is_x; + int ray_nb; + int wall_height; + double ratio; +} t_rcast; + +/* + * structs for windows, and images associated + */ + +typedef struct s_win +{ + void *ptr; + int size_x; + int size_y; +} t_win; + +typedef struct s_img +{ + void *ptr; + char *data; + int bpp; + int sizel; + int endian; +} t_img; + +/* + * structs for the map + */ + +typedef struct s_map +{ + char **content; + int size_x; + int size_y; +} t_map; + +/* + * structs for the player and its moves + */ + +typedef struct s_plr +{ + // player + t_d_coord exact; + t_coord pos; // rot int rot; double cosi; double cosj; double sini; double sinj; +} t_plr; + +/* + * struct with all elements for the project + */ + +typedef struct s_game +{ + void *mlx_ptr; + // map window + t_win map_win; + t_img map_img; + // game window +// t_win win; +// t_img img; // player - double plr_exact_x; - double plr_exact_y; - int plr_x; - int plr_y; + t_plr plr; + // rays + t_rcast rcast; + // map + t_map map; // key hook int k_hook[MAX_NB_KEY]; - // image - void *img_ptr; - char *img_data; - int bpp; - int sizel; - int endian; } t_game; #endif diff --git a/srcs/cube3d.c b/srcs/cube3d.c index c5481e7..f343b41 100644 --- a/srcs/cube3d.c +++ b/srcs/cube3d.c @@ -5,12 +5,18 @@ void destroy_mlx(void *param) t_game *game; game = param; - mlx_destroy_image(game->mlx_ptr, game->img_ptr); - mlx_destroy_window(game->mlx_ptr, game->win_ptr); + + // tmp, to draw map + mlx_destroy_image(game->mlx_ptr, game->map_img.ptr); + mlx_destroy_window(game->mlx_ptr, game->map_win.ptr); + // tmp end + +// mlx_destroy_image(game->mlx_ptr, game->img.ptr); +// mlx_destroy_window(game->mlx_ptr, game->win.ptr); mlx_destroy_display(game->mlx_ptr); } -int shut_down() +int shut_down(void) { mb_exit(B_RED"close windows"RESET"\n"); return (0); @@ -26,13 +32,28 @@ int main(int ac, char **av) // draw game a first time before it start draw(game); + + // tmp, to draw map + // receive a keypress event + mlx_hook(game->map_win.ptr, 2, 1L << 0, keypress, game); + // receive a keyprelease event + mlx_hook(game->map_win.ptr, 3, 1L << 1, keyrelease, game); + // receive event when clicking the red button to close the window + mlx_hook(game->map_win.ptr, 17, 1L << 17, shut_down, NULL); + // infinite loop that waits for events to occurs + // tmp end + +/* // receive a keypress event - mlx_hook(game->win_ptr, 2, 1L << 0, keypress, game); + mlx_hook(game->win.ptr, 2, 1L << 0, keypress, game); // receive a keyprelease event - mlx_hook(game->win_ptr, 3, 1L << 1, keyrelease, game); + mlx_hook(game->win.ptr, 3, 1L << 1, keyrelease, game); // receive event when clicking the red button to close the window - mlx_hook(game->win_ptr, 17, 1L << 17, shut_down, NULL); + mlx_hook(game->win.ptr, 17, 1L << 17, shut_down, NULL); // infinite loop that waits for events to occurs +*/ + +// mlx_loop_hook(game->mlx_ptr, hook_action, game); mlx_loop(game->mlx_ptr); return (0); } diff --git a/srcs/draw/draw.c b/srcs/draw/draw.c index ae18167..4d0a486 100644 --- a/srcs/draw/draw.c +++ b/srcs/draw/draw.c @@ -5,8 +5,8 @@ static int pxl_out_limits(t_game *game, int x, int y) int xmax; int ymax; - xmax = game->sizel / (game->bpp / 8); - ymax = game->win_size_y; + xmax = game->map_img.sizel / (game->map_img.bpp / 8); + ymax = game->map_win.size_y; if (x < 0 || y < 0 || x > xmax || y > ymax) return (1); return (0); @@ -18,77 +18,122 @@ void draw_pixel(t_game *game, int x, int y, int color) if (pxl_out_limits(game, x, y)) return ; - position = y * game->sizel + x * (game->bpp / 8); - *(unsigned int*)(game->img_data + position) = color; + position = y * game->map_img.sizel + x * (game->map_img.bpp / 8); + *(unsigned int*)(game->map_img.data + position) = color; } -void rotate(t_game *game, int *x, int *y) +void draw_line(t_game *game, t_vec vec, int color) { - int old_x; - int tmp_x; - int tmp_y; + t_coord dist; + int i; + int j; - // do nothing if not rotating - if (game->rot == 0) - return ; - // offset center - tmp_x = *x - game->plr_x; - tmp_y = *y - game->plr_y; - // calculate new coordinates - old_x = tmp_x; - tmp_x = tmp_x * game->cosi + tmp_y * game->cosj; - tmp_y = old_x * game->sini + tmp_y * game->sinj; - // de-offset center - *x = tmp_x + game->plr_x; - *y = tmp_y + game->plr_y; -} - -void rotate_double(t_game *game, double *x, double *y) -{ - double old_x; - double tmp_x; - double tmp_y; - - // do nothing if not rotating - if (game->rot == 0) - return ; - // offset center - tmp_x = *x - game->plr_exact_x; - tmp_y = *y - game->plr_exact_y; - // calculate new coordinates - old_x = tmp_x; - tmp_x = tmp_x * game->cosi + tmp_y * game->cosj; - tmp_y = old_x * game->sini + tmp_y * game->sinj; - // de-offset center - *x = tmp_x + game->plr_exact_x; - *y = tmp_y + game->plr_exact_y; -} - -void draw_line(t_game *game, int start_x, int start_y, int end_x, int end_y, int color) -{ - int dx; - int dy; - int i; - int j; - - dx = end_x - start_x; - dy = end_y - start_y; + dist.x = vec.end.x - vec.start.x; + dist.y = vec.end.y - vec.start.y; i = 0; j = 0; - while (ft_abs(i) <= ft_abs(dx) && ft_abs(j) <= ft_abs(dy)) + while (ft_abs(i) <= ft_abs(dist.x) && ft_abs(j) <= ft_abs(dist.y)) { - draw_pixel(game, start_x + i, start_y + j, color); - if (!ft_abs(dx) || ft_abs(j) < ft_abs(i * dy / dx)) - j += ft_sign(dy); + draw_pixel(game, vec.start.x + i, vec.start.y + j, color); + if (!ft_abs(dist.x) || ft_abs(j) < ft_abs(i * dist.y / dist.x)) + j += ft_sign(dist.y); else - i += ft_sign(dx); + i += ft_sign(dist.x); } } +// tmp + static void draw_square(t_game *game, t_coord pos, int border, int fill, int size, int rotation) + { + int i; + int j; + t_coord new; + + i = 0; + while (i < size) + { + j = 0; + while (j < size) + { + new.x = pos.x + j; + new.y = pos.y + i; + if (rotation) + rotate(&(game->plr), &(new)); + if (!i || i == size - 1) + draw_pixel(game, new.x, new.y, border); + else if (!j || j == size - 1) + draw_pixel(game, new.x, new.y, border); + else + draw_pixel(game, new.x, new.y, fill); + j++; + } + i++; + } + } + + static void draw_map(t_game *game) + { + t_coord incr; + t_coord pos; + + incr.x = 0; + pos.x = 0; + pos.y = 0; + while ((game->map.content)[incr.x]) + { + incr.y = 0; + while ((game->map.content)[incr.x][incr.y]) + { + if ((game->map.content)[incr.x][incr.y] == '1' ) + draw_square(game, pos, 0x00999999, 0x00000000, CELL, 0); + else + draw_square(game, pos, 0x00555555, 0x00333333, CELL, 0); + (incr.y)++; + pos.x += CELL; + } + (incr.x)++; + pos.x = 0; + pos.y += CELL; + } + pos.x = game->plr.pos.x - CELL / 2; + pos.y = game->plr.pos.y - CELL / 2; + draw_square(game, pos, 0x00999900, 0x00330033, CELL, 1); + } + + static void draw_screen(t_game *game, t_rcast *rcast) + { + t_vec screen; + + // draw screen size + screen.start.x = rcast->screen_size.start.x + game->plr.pos.x; + screen.start.y = rcast->screen_size.start.y + game->plr.pos.y; + rotate(&(game->plr), &(screen.start)); + screen.end.x = rcast->screen_size.end.x + game->plr.pos.x; + screen.end.y = rcast->screen_size.end.y + game->plr.pos.y; + rotate(&(game->plr), &(screen.end)); + draw_line(game, screen, 0x00FFFFFF); + // draw screen dist + screen.start.x = rcast->screen_dist.start.x + game->plr.pos.x; + screen.start.y = rcast->screen_dist.start.y + game->plr.pos.y; + screen.end.x = rcast->screen_dist.end.x + game->plr.pos.x; + screen.end.y = rcast->screen_dist.end.y + game->plr.pos.y; + rotate(&(game->plr), &(screen.end)); + draw_line(game, screen, 0x00FFFFFF); + } +// tmp end + void draw(t_game *game) { - draw_map(game); - draw_rays(game); - //draw_view(game); - mlx_put_image_to_window(game->mlx_ptr, game->win_ptr, game->img_ptr, 0, 0); + // tmp, to draw map + draw_map(game); + // tmp end + + raycast(game, &(game->rcast)); + + // tmp, to draw map + draw_screen(game, &(game->rcast)); + mlx_put_image_to_window(game->mlx_ptr, game->map_win.ptr, game->map_img.ptr, 0, 0); + // tmp end + +// mlx_put_image_to_window(game->mlx_ptr, game->win.ptr, game->img.ptr, 0, 0); } diff --git a/srcs/draw/draw_window.c b/srcs/draw/draw_window.c deleted file mode 100644 index 31f3f8c..0000000 --- a/srcs/draw/draw_window.c +++ /dev/null @@ -1,202 +0,0 @@ -#include "cube3d.h" - -void ray_intersect(t_game *game, int start_x, int start_y, int *end_x, int *end_y) -{ - int cell_x; - int cell_y; - int slope_x; - int slope_y; - int ray_sign_x; - int ray_sign_y; - int first_next_x; - int first_next_y; - int next_x; - int next_y; - int next_cell_x; - int next_cell_y; - int ray_step_x; - int ray_step_y; - int is_x; - - is_x = 0; - // ray sign - ray_sign_x = 1; - if (start_x < *end_x) - ray_sign_x = -1; - ray_sign_y = 1; - if (start_y < *end_y) - ray_sign_y = -1; - // cell position of ray - cell_x = start_x / game->cell; - cell_y = start_y / game->cell; - // slope of ray - slope_x = *end_x - start_x; - slope_y = *end_y - start_y; - // direction of next cell - next_cell_x = -ray_sign_x; - next_cell_y = -ray_sign_y; - // ray steps in both axis - ray_step_x = ft_abs(game->cell * slope_y); - ray_step_y = ft_abs(game->cell * slope_x); - // first next time ray cross grid - first_next_x = start_x % game->cell; - if (first_next_x && ray_sign_x < 0) - first_next_x = game->cell - first_next_x; - if (!first_next_x && ray_sign_x < 0) - first_next_x = game->cell; - first_next_y = start_y % game->cell; - if (first_next_y && ray_sign_y < 0) - first_next_y = game->cell - first_next_y; - if (!first_next_y && ray_sign_y < 0) - first_next_y = game->cell; - next_x = ft_abs(first_next_x * slope_y); - next_y = ft_abs(first_next_y * slope_x); - // loop through grid -if (game->ray_activ == 1) printf("\ncell_x:%i, cell_y:%i, first_next_x:%i, first_next_y:%i\n", cell_x, cell_y, first_next_x, first_next_y); - while (!is_wall(game, cell_x, cell_y)) - { -if (game->ray_activ == 1) printf("next_x:%-4i, next_y:%-4i, ", next_x, next_y); - if (next_x > next_y) - { - cell_y += next_cell_y; - next_y += ray_step_y; - is_x = 0; - } - else - { - cell_x += next_cell_x; - next_x += ray_step_x; - is_x = 1; - } -if (game->ray_activ == 1) printf("cell_x:%-4i, cell_y:%-4i\n", cell_x, cell_y); - } - // end ray position - double ratio; - if (is_x) - { - *end_x = cell_x * game->cell; - if (ray_sign_x == 1) - *end_x += game->cell; - if (slope_x) - { - ratio = (double)(*end_x - start_x) / (double)slope_x; - *end_y = start_y + (double)slope_y * ratio; - } - } - else - { - *end_y = cell_y * game->cell; - if (ray_sign_y == 1) - *end_y += game->cell; - if (slope_y) - { - ratio = (double)(*end_y - start_y) / (double)slope_y; - *end_x = start_x + (double)slope_x * ratio; - } - } -} - -void draw_rays(t_game *game) -{ - int start_x; - int start_y; - int end_x; - int end_y; - int i; - - // draw screen size - start_x = game->screen_size.start_x + game->plr_x; - start_y = game->screen_size.start_y + game->plr_y; - rotate(game, &start_x, &start_y); - end_x = game->screen_size.end_x + game->plr_x; - end_y = game->screen_size.end_y + game->plr_y; - rotate(game, &end_x, &end_y); - draw_line(game, start_x, start_y, end_x, end_y, 0x00FFFFFF); - // draw rays - i = 0; - while (i <= SCREEN_DEF) - { - // tmp display one ray with infos - if (i == game->ray_highlight) - game->ray_activ = 1; - // tmp end - start_x = game->ray.start_x + game->plr_x; - start_y = game->ray.start_y + game->plr_y; - end_x = game->ray.end_x + game->plr_x + i * SCREEN_SIZE / SCREEN_DEF; - end_y = game->ray.end_y + game->plr_y; - rotate(game, &end_x, &end_y); - ray_intersect(game, start_x, start_y, &end_x, &end_y); - draw_line(game, start_x, start_y, end_x, end_y, 0x00FF00FF); - // tmp display one ray with infos - if (game->ray_activ == 1) - draw_line(game, start_x, start_y, end_x, end_y, 0x00FF0000); - // tmp end - i++; - game->ray_activ = 0; - } - // draw screen dist - start_x = game->screen_dist.start_x + game->plr_x; - start_y = game->screen_dist.start_y + game->plr_y; - end_x = game->screen_dist.end_x + game->plr_x; - end_y = game->screen_dist.end_y + game->plr_y; - rotate(game, &end_x, &end_y); - draw_line(game, start_x, start_y, end_x, end_y, 0x00FFFFFF); -} - -static void draw_square(t_game *game, int x, int y, int border, int fill, int size, int rotation) -{ - int i; - int j; - int new_x; - int new_y; - - i = 0; - while (i < size) - { - j = 0; - while (j < size) - { - new_x = x + j; - new_y = y + i; - if (rotation) - rotate(game, &new_x, &new_y); - if (!i || i == size - 1) - draw_pixel(game, new_x, new_y, border); - else if (!j || j == size - 1) - draw_pixel(game, new_x, new_y, border); - else - draw_pixel(game, new_x, new_y, fill); - j++; - } - i++; - } -} - -void draw_map(t_game *game) -{ - int i; - int j; - int x; - int y; - - i = 0; - x = 0; - y = 0; - while ((game->map)[i]) - { - j = 0; - while ((game->map)[i][j]) - { - if ((game->map)[i][j] == '1' ) - draw_square(game, x, y, 0x00999999, 0x00000000, game->cell, 0); - else - draw_square(game, x, y, 0x00555555, 0x00333333, game->cell, 0); - j++; - x += game->cell; - } - i++; - x = 0; - y += game->cell; - } - draw_square(game, game->plr_x - game->cell / 2, game->plr_y - game->cell / 2, 0x00999900, 0x00330033, game->cell, 1); -} diff --git a/srcs/draw/ray_intersect.c b/srcs/draw/ray_intersect.c new file mode 100644 index 0000000..6eeaa9a --- /dev/null +++ b/srcs/draw/ray_intersect.c @@ -0,0 +1,102 @@ +#include "cube3d.h" + +static void init_raycast(t_rcast *rcast, t_vec *ray) +{ + rcast->is_x = 0; + rcast->wall_height = 0; + // ray sign + rcast->ray_sign_x = 1; + if (ray->start.x < ray->end.x) + rcast->ray_sign_x = -1; + rcast->ray_sign_y = 1; + if (ray->start.y < ray->end.y) + rcast->ray_sign_y = -1; + // cell position of ray + rcast->cell_x = ray->start.x / CELL; + rcast->cell_y = ray->start.y / CELL; + // slope of ray + rcast->slope_x = ray->end.x - ray->start.x; + rcast->slope_y = ray->end.y - ray->start.y; + // direction of next cell + rcast->next_cell_x = -rcast->ray_sign_x; + rcast->next_cell_y = -rcast->ray_sign_y; + // ray steps in both axis + rcast->ray_step_x = ft_abs(CELL * rcast->slope_y); + rcast->ray_step_y = ft_abs(CELL * rcast->slope_x); +} + +static void init_first_step(t_rcast *rcast, t_vec *ray) +{ + // first next time ray cross grid + rcast->first_next_x = ray->start.x % CELL; + if (rcast->first_next_x && rcast->ray_sign_x < 0) + rcast->first_next_x = CELL - rcast->first_next_x; + if (!rcast->first_next_x && rcast->ray_sign_x < 0) + rcast->first_next_x = CELL; + rcast->first_next_y = ray->start.y % CELL; + if (rcast->first_next_y && rcast->ray_sign_y < 0) + rcast->first_next_y = CELL - rcast->first_next_y; + if (!rcast->first_next_y && rcast->ray_sign_y < 0) + rcast->first_next_y = CELL; + rcast->next_x = ft_abs(rcast->first_next_x * rcast->slope_y); + rcast->next_y = ft_abs(rcast->first_next_y * rcast->slope_x); +} + +static void next_cell(t_rcast *rcast) +{ + if (rcast->next_x > rcast->next_y) + { + rcast->cell_y += rcast->next_cell_y; + rcast->next_y += rcast->ray_step_y; + rcast->is_x = 0; + } + else + { + rcast->cell_x += rcast->next_cell_x; + rcast->next_x += rcast->ray_step_x; + rcast->is_x = 1; + } +} + +static void calcul_ray_end(t_rcast *rcast, t_vec *ray) +{ + if (rcast->is_x) + { + ray->end.x = rcast->cell_x * CELL; + if (rcast->ray_sign_x == 1) + ray->end.x += CELL; + if (rcast->slope_x) + { + rcast->ratio = (double)(ray->end.x - ray->start.x) / (double)rcast->slope_x; + ray->end.y = ray->start.y + (double)rcast->slope_y * rcast->ratio; + } + } + else + { + ray->end.y = rcast->cell_y * CELL; + if (rcast->ray_sign_y == 1) + ray->end.y += CELL; + if (rcast->slope_y) + { + rcast->ratio = (double)(ray->end.y - ray->start.y) / (double)rcast->slope_y; + ray->end.x = ray->start.x + (double)rcast->slope_x * rcast->ratio; + } + } +} + +void ray_intersect(t_game *game, t_rcast *rcast, t_vec *ray) +{ + ray->start.x = rcast->ray.start.x + game->plr.pos.x; + ray->start.y = rcast->ray.start.y + game->plr.pos.y; + ray->end.x = rcast->ray.end.x + game->plr.pos.x; + ray->end.x += rcast->ray_nb * SCREEN_SIZE / SCREEN_DEF; + ray->end.y = rcast->ray.end.y + game->plr.pos.y; + rotate(&(game->plr), &(ray->end)); + init_raycast(rcast, ray); + init_first_step(rcast, ray); + // loop through grid + while (!is_wall(game, rcast->cell_x, rcast->cell_y)) + next_cell(rcast); + // end ray position + calcul_ray_end(rcast, ray); +} diff --git a/srcs/draw/raycast.c b/srcs/draw/raycast.c new file mode 100644 index 0000000..99d05e4 --- /dev/null +++ b/srcs/draw/raycast.c @@ -0,0 +1,19 @@ +#include "cube3d.h" + +void raycast(t_game *game, t_rcast *rcast) +{ + t_vec ray; + + rcast->ray_nb = 0; + while (rcast->ray_nb <= SCREEN_DEF) + { + ray_intersect(game, rcast, &ray); + + // tmp, to draw the map + draw_line(game, ray, 0x00FF00FF); + // tmp end + + // draw_column(); + (rcast->ray_nb)++; + } +} diff --git a/srcs/hook/key_is_action_1.c b/srcs/hook/key_action_1.c similarity index 63% rename from srcs/hook/key_is_action_1.c rename to srcs/hook/key_action_1.c index 6f7d40a..f1a86dd 100644 --- a/srcs/hook/key_is_action_1.c +++ b/srcs/hook/key_action_1.c @@ -2,7 +2,7 @@ int is_esc(int *k_hook, int *is_action) { - if (!ft_arrintchr(k_hook, KEY_ESC, MAX_NB_KEY)) + if (!ft_arrint(k_hook, KEY_ESC, MAX_NB_KEY)) { *is_action = 1; return 1; @@ -12,12 +12,12 @@ int is_esc(int *k_hook, int *is_action) int is_go_left(int *k_hook, int *is_action) { - if (!ft_arrintchr(k_hook, KEY_A, MAX_NB_KEY)) + if (!ft_arrint(k_hook, KEY_A, MAX_NB_KEY)) { *is_action = 1; return 1; } - if (!ft_arrintchr(k_hook, KEY_Q, MAX_NB_KEY)) + if (!ft_arrint(k_hook, KEY_Q, MAX_NB_KEY)) { *is_action = 1; return 1; @@ -27,7 +27,7 @@ int is_go_left(int *k_hook, int *is_action) int is_go_right(int *k_hook, int *is_action) { - if (!ft_arrintchr(k_hook, KEY_D, MAX_NB_KEY)) + if (!ft_arrint(k_hook, KEY_D, MAX_NB_KEY)) { *is_action = 1; return 1; @@ -37,12 +37,12 @@ int is_go_right(int *k_hook, int *is_action) int is_go_forward(int *k_hook, int *is_action) { - if (!ft_arrintchr(k_hook, KEY_W, MAX_NB_KEY)) + if (!ft_arrint(k_hook, KEY_W, MAX_NB_KEY)) { *is_action = 1; return 1; } - if (!ft_arrintchr(k_hook, KEY_Z, MAX_NB_KEY)) + if (!ft_arrint(k_hook, KEY_Z, MAX_NB_KEY)) { *is_action = 1; return 1; @@ -52,7 +52,7 @@ int is_go_forward(int *k_hook, int *is_action) int is_go_backward(int *k_hook, int *is_action) { - if (!ft_arrintchr(k_hook, KEY_S, MAX_NB_KEY)) + if (!ft_arrint(k_hook, KEY_S, MAX_NB_KEY)) { *is_action = 1; return 1; diff --git a/srcs/hook/key_is_action_2.c b/srcs/hook/key_action_2.c similarity index 67% rename from srcs/hook/key_is_action_2.c rename to srcs/hook/key_action_2.c index f90888e..6f8cbab 100644 --- a/srcs/hook/key_is_action_2.c +++ b/srcs/hook/key_action_2.c @@ -2,7 +2,7 @@ int is_turn_left(int *k_hook, int *is_action) { - if (!ft_arrintchr(k_hook, ARROW_LEFT, MAX_NB_KEY)) + if (!ft_arrint(k_hook, ARROW_LEFT, MAX_NB_KEY)) { *is_action = 1; return 1; @@ -12,7 +12,7 @@ int is_turn_left(int *k_hook, int *is_action) int is_turn_right(int *k_hook, int *is_action) { - if (!ft_arrintchr(k_hook, ARROW_RIGHT, MAX_NB_KEY)) + if (!ft_arrint(k_hook, ARROW_RIGHT, MAX_NB_KEY)) { *is_action = 1; return 1; diff --git a/srcs/hook/key_do_action.c b/srcs/hook/key_do_action.c deleted file mode 100644 index f33aec3..0000000 --- a/srcs/hook/key_do_action.c +++ /dev/null @@ -1,43 +0,0 @@ -#include "cube3d.h" - -// temp, to test keypress hook -void keypress_do_action(t_game *game) -{ - int is_action; - - is_action = 0; - if (is_esc(game->k_hook, &is_action)) - shut_down(game); - if (is_go_left(game->k_hook, &is_action)) - plr_posx_decrement(game); - if (is_go_right(game->k_hook, &is_action)) - plr_posx_increment(game); - if (is_go_forward(game->k_hook, &is_action)) - plr_posy_decrement(game); - if (is_go_backward(game->k_hook, &is_action)) - plr_posy_increment(game); - if (is_turn_left(game->k_hook, &is_action)) - plr_turn_left(game); - if (is_turn_right(game->k_hook, &is_action)) - plr_turn_right(game); - // temp display one ray with infos - if (!ft_arrintchr(game->k_hook, 65364, MAX_NB_KEY)) - { - if (game->ray_highlight <= SCREEN_DEF) - game->ray_highlight++; - else - game->ray_highlight = -1; - is_action = 1; - } - if (!ft_arrintchr(game->k_hook, 65362, MAX_NB_KEY)) - { - if (game->ray_highlight >= 0) - game->ray_highlight--; - else - game->ray_highlight = SCREEN_DEF; - is_action = 1; - } - // temp end - if (is_action) - draw(game); -} diff --git a/srcs/hook/keyhook.c b/srcs/hook/keyhook.c index 5bfa312..f45e6d0 100644 --- a/srcs/hook/keyhook.c +++ b/srcs/hook/keyhook.c @@ -1,14 +1,38 @@ #include "cube3d.h" // temp, to map all the keys on linux and mac - static int print_keycode(int keycode) - { - ft_putnbr_fd(keycode, 1); - ft_putchar_fd('\n', 1); - return(0); - } +static int print_keycode(int keycode) +{ + ft_putnbr_fd(keycode, 1); + ft_putchar_fd('\n', 1); + return(0); +} // temp end +int hook_action(t_game *game) +{ + int is_action; + + is_action = 0; + if (is_esc(game->k_hook, &is_action)) + shut_down(); + if (is_go_left(game->k_hook, &is_action)) + plr_posx_decrement(game, &(game->plr)); + if (is_go_right(game->k_hook, &is_action)) + plr_posx_increment(game, &(game->plr)); + if (is_go_forward(game->k_hook, &is_action)) + plr_posy_decrement(game, &(game->plr)); + if (is_go_backward(game->k_hook, &is_action)) + plr_posy_increment(game, &(game->plr)); + if (is_turn_left(game->k_hook, &is_action)) + plr_turn_left(&(game->plr)); + if (is_turn_right(game->k_hook, &is_action)) + plr_turn_right(&(game->plr)); + if (is_action) + draw(game); + return(0); +} + int keypress(int keycode, t_game *game) { unsigned i; @@ -24,8 +48,7 @@ int keypress(int keycode, t_game *game) game->k_hook[i] = 0; else if (i < MAX_NB_KEY) game->k_hook[i] = keycode; - - keypress_do_action(game); + hook_action(game); return (0); } @@ -38,6 +61,5 @@ int keyrelease(int keycode, t_game *game) i++; if (i < MAX_NB_KEY) game->k_hook[i] = 0; - return (0); } diff --git a/srcs/init/init_struct.c b/srcs/init/init_struct.c index 3348d2a..b5d0307 100644 --- a/srcs/init/init_struct.c +++ b/srcs/init/init_struct.c @@ -1,36 +1,17 @@ #include "cube3d.h" -t_game *init_game(void) +static void init_img(t_img *img, t_game *game) { - t_game *game; + img->ptr = mlx_new_image(game->mlx_ptr, game->map_win.size_x, + game->map_win.size_y); + img->data = mlx_get_data_addr(img->ptr, &(img->bpp), + &(img->sizel), &(img->endian)); +} - game = mb_alloc(sizeof(t_game)); - game->cell = 20; - // player first position - game->plr_exact_x = 2 * game->cell; - game->plr_exact_y = 2 * game->cell; - game->plr_x = game->plr_exact_x; - game->plr_y = game->plr_exact_y; - // rotation - game->rot = 0; - game->cosi = 0; - game->cosj = 0; - game->sini = 0; - game->sinj = 0; - // map size - game->map_size_x = 24; - game->map_size_y = 24; - // size window - game->win_size_x = game->map_size_x * game->cell; - game->win_size_y = game->map_size_y * game->cell; - // init connexion to server - game->mlx_ptr = mlx_init(); - mb_add(game->mlx_ptr); - // create the window - game->win_ptr = mlx_new_window(game->mlx_ptr, game->win_size_x, - game->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)); +static void init_map(t_map *map) +{ + map->size_x = 24; + map->size_y = 24; // map int tmp[24][24] = { {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}, @@ -59,48 +40,85 @@ t_game *init_game(void) {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}, }; int i = 0; - game->map = mb_alloc(sizeof(char*) * (game->map_size_y + 1)); - (game->map)[game->map_size_y] = NULL; + map->content = mb_alloc(sizeof(char*) * (map->size_y + 1)); + (map->content)[map->size_y] = NULL; while (i < 24) { - (game->map)[i] = mb_alloc(sizeof(char) * (game->map_size_x + 1)); - (game->map)[i][game->map_size_x] = '\0'; + (map->content)[i] = mb_alloc(sizeof(char) * (map->size_x + 1)); + (map->content)[i][map->size_x] = '\0'; i++; } int j; i = 0; - while (i < game->map_size_y) + while (i < map->size_y) { j = 0; - while (j < game->map_size_x) + while (j < map->size_x) { - (game->map)[i][j] = tmp[i][j] + '0'; + (map->content)[i][j] = tmp[i][j] + '0'; j++; } i++; } +} + +static void init_raycast(t_rcast *rcast) +{ // draw screen dist - game->screen_dist.start_x = 0; - game->screen_dist.start_y = 0; - game->screen_dist.end_x = 0; - game->screen_dist.end_y = -SCREEN_DIST; + rcast->screen_dist.start.x = 0; + rcast->screen_dist.start.y = 0; + rcast->screen_dist.end.x = 0; + rcast->screen_dist.end.y = -SCREEN_DIST; // draw screen size - game->screen_size.start_x = -SCREEN_SIZE / 2; - game->screen_size.start_y = -SCREEN_DIST; - game->screen_size.end_x = SCREEN_SIZE / 2; - game->screen_size.end_y = -SCREEN_DIST; + rcast->screen_size.start.x = -SCREEN_SIZE / 2; + rcast->screen_size.start.y = -SCREEN_DIST; + rcast->screen_size.end.x = SCREEN_SIZE / 2; + rcast->screen_size.end.y = -SCREEN_DIST; // draw ray - game->ray.start_x = 0; - game->ray.start_y = 0; - game->ray.end_x = -SCREEN_SIZE / 2; - game->ray.end_y = -SCREEN_DIST; - // tmp - game->ray_highlight = -1; - game->ray_activ = 0; + rcast->ray.start.x = 0; + rcast->ray.start.y = 0; + rcast->ray.end.x = -SCREEN_SIZE / 2; + rcast->ray.end.y = -SCREEN_DIST; +} + +static void init_plr(t_plr *plr) +{ + // player first position + plr->exact.x = 2 * CELL; + plr->exact.y = 2 * CELL; + plr->pos.x = plr->exact.x; + plr->pos.y = plr->exact.y; + // rotation + plr->rot = 0; + plr->cosi = 0; + plr->cosj = 0; + plr->sini = 0; + plr->sinj = 0; +} + +t_game *init_game(void) +{ + t_game *game; + + game = mb_alloc(sizeof(t_game)); + // map + init_map(&(game->map)); + // plr + init_plr(&(game->plr)); + // 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 - game->img_ptr = mlx_new_image(game->mlx_ptr, game->win_size_x, - game->win_size_y); - game->img_data = mlx_get_data_addr(game->img_ptr, &(game->bpp), - &(game->sizel), &(game->endian)); + init_img(&(game->map_img), game); return (game); } diff --git a/srcs/player/player_limits.c b/srcs/player/player_limits.c index 4d6961e..7d9481a 100644 --- a/srcs/player/player_limits.c +++ b/srcs/player/player_limits.c @@ -4,9 +4,9 @@ int is_wall(t_game *game, int cell_x, int cell_y) { if (cell_x < 0 || cell_y < 0) return (1); - if (cell_x > game->map_size_x || cell_y > game->map_size_y) + if (cell_x > game->map.size_x || cell_y > game->map.size_y) return (1); - if (game->map[cell_y][cell_x] != '0') + if (game->map.content[cell_y][cell_x] != '0') return (1); return (0); } @@ -18,10 +18,10 @@ int plr_out_limits(t_game *game, int x, int y) int cell_x; int cell_y; - xmax = game->sizel / (game->bpp / 8); - ymax = game->win_size_y; - cell_x = x / game->cell; - cell_y = y / game->cell; + xmax = game->map_img.sizel / (game->map_img.bpp / 8); + ymax = game->map_win.size_y; + cell_x = x / CELL; + cell_y = y / CELL; if (is_wall(game, cell_x, cell_y)) return (1); if (x < 0 || y < 0 || x > xmax || y > ymax) diff --git a/srcs/player/player_moves.c b/srcs/player/player_moves.c index daf299c..1bf43d7 100644 --- a/srcs/player/player_moves.c +++ b/srcs/player/player_moves.c @@ -1,65 +1,61 @@ #include "cube3d.h" -void plr_posx_decrement(t_game *game) +void plr_posx_decrement(t_game *game, t_plr *plr) { - double pos_x; - double pos_y; + t_d_coord pos; - pos_x = game->plr_exact_x - 5; - pos_y = game->plr_exact_y; - rotate_double(game, &pos_x, &pos_y); - if (plr_out_limits(game, pos_x, pos_y)) + pos.x = plr->exact.x - PLR_MV; + pos.y = plr->exact.y; + rotate_double(plr, &pos); + if (plr_out_limits(game, pos.x, pos.y)) return ; - game->plr_exact_x = pos_x; - game->plr_exact_y = pos_y; - (game->plr_x) = (int)pos_x; - (game->plr_y) = (int)pos_y; + plr->exact.x = pos.x; + plr->exact.y = pos.y; + (plr->pos.x) = (int)(pos.x); + (plr->pos.y) = (int)(pos.y); } -void plr_posy_decrement(t_game *game) +void plr_posy_decrement(t_game *game, t_plr *plr) { - double pos_x; - double pos_y; + t_d_coord pos; - pos_x = game->plr_exact_x; - pos_y = game->plr_exact_y - 5; - rotate_double(game, &pos_x, &pos_y); - if (plr_out_limits(game, pos_x, pos_y)) + pos.x = plr->exact.x; + pos.y = plr->exact.y - PLR_MV; + rotate_double(plr, &(pos)); + if (plr_out_limits(game, pos.x, pos.y)) return ; - game->plr_exact_x = pos_x; - game->plr_exact_y = pos_y; - (game->plr_x) = (int)pos_x; - (game->plr_y) = (int)pos_y; + plr->exact.x = pos.x; + plr->exact.y = pos.y; + (plr->pos.x) = (int)(pos.x); + (plr->pos.y) = (int)(pos.y); } -void plr_posx_increment(t_game *game) +void plr_posx_increment(t_game *game, t_plr *plr) { - double pos_x; - double pos_y; + t_d_coord pos; - pos_x = game->plr_exact_x + 5; - pos_y = game->plr_exact_y; - rotate_double(game, &pos_x, &pos_y); - if (plr_out_limits(game, pos_x, pos_y)) + pos.x = plr->exact.x + PLR_MV; + pos.y = plr->exact.y; + rotate_double(plr, &(pos)); + if (plr_out_limits(game, pos.x, pos.y)) return ; - game->plr_exact_x = pos_x; - game->plr_exact_y = pos_y; - (game->plr_x) = (int)pos_x; - (game->plr_y) = (int)pos_y; + plr->exact.x = pos.x; + plr->exact.y = pos.y; + (plr->pos.x) = (int)(pos.x); + (plr->pos.y) = (int)(pos.y); } -void plr_posy_increment(t_game *game) +void plr_posy_increment(t_game *game, t_plr *plr) { - double pos_x; - double pos_y; + t_d_coord pos; - pos_x = game->plr_exact_x; - pos_y = game->plr_exact_y + 5; - rotate_double(game, &pos_x, &pos_y); - if (plr_out_limits(game, pos_x, pos_y)) + pos.x = plr->exact.x; + pos.y = plr->exact.y + PLR_MV; + rotate_double(plr, &(pos)); + if (plr_out_limits(game, pos.x, pos.y)) return ; - game->plr_exact_x = pos_x; - game->plr_exact_y = pos_y; - (game->plr_x) = (int)pos_x; - (game->plr_y) = (int)pos_y; + plr->exact.x = pos.x; + plr->exact.y = pos.y; + (plr->pos.x) = (int)(pos.x); + (plr->pos.y) = (int)(pos.y); } diff --git a/srcs/player/player_rotates.c b/srcs/player/player_rotates.c index d4d05a7..a0f3f55 100644 --- a/srcs/player/player_rotates.c +++ b/srcs/player/player_rotates.c @@ -1,35 +1,75 @@ #include "cube3d.h" -void plr_turn_left(t_game *game) +void rotate(t_plr *plr, t_coord *coord) +{ + int old_x; + t_coord tmp; + + // do nothing if not rotating + if (plr->rot == 0) + return ; + // offset center + tmp.x = coord->x - plr->pos.x; + tmp.y = coord->y - plr->pos.y; + // calculate new coordinates + old_x = tmp.x; + tmp.x = tmp.x * plr->cosi + tmp.y * plr->cosj; + tmp.y = old_x * plr->sini + tmp.y * plr->sinj; + // de-offset center + coord->x = tmp.x + plr->pos.x; + coord->y = tmp.y + plr->pos.y; +} + +void rotate_double(t_plr *plr, t_d_coord *coord) +{ + double old_x; + t_d_coord tmp; + + // do nothing if not rotating + if (plr->rot == 0) + return ; + // offset center + tmp.x = coord->x - plr->exact.x; + tmp.y = coord->y - plr->exact.y; + // calculate new coordinates + old_x = tmp.x; + tmp.x = tmp.x * plr->cosi + tmp.y * plr->cosj; + tmp.y = old_x * plr->sini + tmp.y * plr->sinj; + // de-offset center + coord->x = tmp.x + plr->exact.x; + coord->y = tmp.y + plr->exact.y; +} + +void plr_turn_left(t_plr *plr) { double radi; double radj; - if (game->rot == -180) - (game->rot) *= -1; - (game->rot)--; + if (plr->rot == -180) + (plr->rot) *= -1; + (plr->rot)--; // calculate trigo for rotations - radi = game->rot * M_PI / 180; + radi = plr->rot * M_PI / 180; radj = radi + (M_PI / 2); - game->cosi = cos(radi); - game->sini = sin(radi); - game->cosj = cos(radj); - game->sinj = sin(radj); + plr->cosi = cos(radi); + plr->sini = sin(radi); + plr->cosj = cos(radj); + plr->sinj = sin(radj); } -void plr_turn_right(t_game *game) +void plr_turn_right(t_plr *plr) { double radi; double radj; - if (game->rot == 180) - (game->rot) *= -1; - (game->rot)++; + if (plr->rot == 180) + (plr->rot) *= -1; + (plr->rot)++; // calculate trigo for rotations - radi = game->rot * M_PI / 180; + radi = plr->rot * M_PI / 180; radj = radi + (M_PI / 2); - game->cosi = cos(radi); - game->sini = sin(radi); - game->cosj = cos(radj); - game->sinj = sin(radj); + plr->cosi = cos(radi); + plr->sini = sin(radi); + plr->cosj = cos(radj); + plr->sinj = sin(radj); }