diff --git a/Makefile b/Makefile index 03930df..95c0af3 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ SRCS_GAME := main.c game/game.c game/init.c game/manage.c \ -game/manage_keys.c game/raycasting.c game/dda.c +game/manage_keys.c game/raycasting.c game/dda.c game/draw.c game/utils.c SRCS_MAP := parsing.c parsing_header.c parsing_header2.c parsing_meta.c parsing_body.c map.c SRCS_MAP := $(addprefix map/, $(SRCS_MAP)) diff --git a/game/dda.c b/game/dda.c index 296c096..c68051a 100644 --- a/game/dda.c +++ b/game/dda.c @@ -6,26 +6,14 @@ /* By: erey-bet +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/05/02 15:49:00 by erey-bet #+# #+# */ -/* Updated: 2023/05/05 15:54:46 by erey-bet ### ########.fr */ +/* Updated: 2023/05/11 16:22:58 by erey-bet ### ########.fr */ /* */ /* ************************************************************************** */ #include "game.h" -double ft_abs(double nb) +void init_dda(t_dda *dda, t_ply *ply, t_ray *ray) { - if (nb < 0) - return (-nb); - return (nb); -} - -void init_dda(t_game *game, t_dda *dda) -{ - t_ray *ray; - t_ply *ply; - - ray = &game->ray; - ply = &game->ply; dda->map_x = (int)ply->pos_x; dda->map_y = (int)ply->pos_y; if (ray->dir_x == 0) @@ -39,23 +27,21 @@ void init_dda(t_game *game, t_dda *dda) dda->step_x = 1; dda->step_y = 1; if (ray->dir_x < 0) - { dda->step_x = -1; + if (ray->dir_y < 0) + dda->step_y = -1; + if (ray->dir_x < 0) dda->side_dist_x = (ply->pos_x - dda->map_x) * dda->delta_dist_x; - } else dda->side_dist_x = (dda->map_x + 1.0 - ply->pos_x) * dda->delta_dist_x; if (ray->dir_y < 0) - { - dda->step_y = -1; dda->side_dist_y = (ply->pos_y - dda->map_y) * dda->delta_dist_y; - } else dda->side_dist_y = (dda->map_y + 1.0 - ply->pos_y) * dda->delta_dist_y; dda->hit = 0; } -void loop_dda(t_game *game, t_dda *dda) +void loop_dda(t_game *game, t_dda *dda) { while (dda->hit == 0) { @@ -71,88 +57,49 @@ void loop_dda(t_game *game, t_dda *dda) dda->map_y += dda->step_y; dda->side = 1; } - if (dda->map_x < 0 || dda->map_y < 0 - || dda->map_y >= (int)game->map.size_y + if (dda->map_x < 0 || dda->map_y < 0 || dda->map_y >= game->map.size_y || dda->map_x >= (int)ft_strlen(game->map.map[dda->map_y])) { dda->perp_wall_dist = 1e30; return ; } - if (game->map.map[dda->map_y][dda->map_x] == '1') + else + dda->perp_wall_dist = 0; + if (game->map.map[dda->map_y][dda->map_x] == '1') dda->hit = 1; - } - if(dda->side == 0) - dda->perp_wall_dist = dda->side_dist_x - dda->delta_dist_x; - else - dda->perp_wall_dist = dda->side_dist_y - dda->delta_dist_y; + } } void ray_dda(t_dda *dda) { - if (dda->perp_wall_dist == 0) - dda->perp_wall_dist = 1e30; + if (dda->perp_wall_dist != 1e30) + { + if (dda->side == 0) + dda->perp_wall_dist = dda->side_dist_x - dda->delta_dist_x; + else + dda->perp_wall_dist = dda->side_dist_y - dda->delta_dist_y; + if (dda->perp_wall_dist == 0) + dda->perp_wall_dist = 1e30; + } dda->line_height = (int)(HEIGHT / dda->perp_wall_dist); dda->draw_start = -(dda->line_height) / 2 + HEIGHT / 2; - if(dda->draw_start < 0) + if (dda->draw_start < 0) dda->draw_start = 0; dda->draw_end = dda->line_height / 2 + HEIGHT / 2; - if(dda->draw_end >= HEIGHT) + if (dda->draw_end >= HEIGHT) dda->draw_end = HEIGHT - 1; } -unsigned int get_rgba(int r, int g, int b, int a) -{ - return (r << 24 | g << 16 | b << 8 | a); -} - -void draw_line(t_game *game, t_dda *dda, unsigned int color, int x) -{ - int y; - - y = 0; - while (y < HEIGHT) - { - if (y < dda->draw_start) - { - mlx_put_pixel(game->window, x, y, game->map.color_bot); - } - else if (y >= dda->draw_start && y <= dda->draw_end) - { - mlx_put_pixel(game->window, x, y, color); - } - else if (y > dda->draw_end) - { - mlx_put_pixel(game->window, x, y, game->map.color_top); - } - y++; - } -} - - -void draw_dda(t_game *game, t_dda *dda, int x) -{ - unsigned int color; - - if (dda->step_x < 0 && dda->side == 0) // NORTH - color = get_rgba(0, 0, 200, 255); - else if (dda->step_x > 0 && dda->side == 0) // SOUTH - color = get_rgba(200, 0, 0, 255); - else if (dda->step_y < 0 && dda->side == 1) // EAST - color = get_rgba(0, 200, 0, 255); - else if (dda->step_y > 0 && dda->side == 1) // WEST - color = get_rgba(50, 100, 50, 255); - else - color = get_rgba(0, 0, 0, 255); - - draw_line(game, dda, color, x); -} - void dda(t_game *game, int x) { - t_dda dda; + t_dda dda; + t_ray *ray; + t_ply *ply; - init_dda(game, &dda); + ray = &game->ray; + ply = &game->ply; + init_dda(&dda, ply, ray); loop_dda(game, &dda); ray_dda(&dda); - draw_dda(game, &dda, x); + draw(game, &dda, x); } diff --git a/game/draw.c b/game/draw.c new file mode 100644 index 0000000..d7ad6aa --- /dev/null +++ b/game/draw.c @@ -0,0 +1,54 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* draw.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: erey-bet +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/05/11 14:41:48 by erey-bet #+# #+# */ +/* Updated: 2023/05/11 16:05:42 by erey-bet ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "game.h" + +void draw_texture(t_game *game, t_dda *dda, int x) +{ + t_texture_draw tex; + int y; + + tex.texture = game->textures[get_texture_side(dda)]; + if (dda->side == 0) + tex.wall_x = game->ply.pos_y + dda->perp_wall_dist * game->ray.dir_y; + else + tex.wall_x = game->ply.pos_x + dda->perp_wall_dist * game->ray.dir_x; + tex.wall_x -= floor(tex.wall_x); + tex.x = (int)(tex.wall_x * (double)tex.texture->width); + if ((dda->side == 0 && game->ray.dir_x > 0) + || (dda->side == 1 && game->ray.dir_y < 0)) + tex.x = tex.texture->width - tex.x - 1; + tex.step = 1.0 * tex.texture->height / dda->line_height; + tex.pos = (dda->draw_start - game->window->height + / 2 + dda->line_height / 2) * tex.step; + y = dda->draw_start; + while (y < dda->draw_end && y < HEIGHT) + { + tex.y = (int)tex.pos & (tex.texture->height - 1); + tex.pos += tex.step; + mlx_put_pixel(game->window, x, y++, + get_pixel_color(tex.texture, tex.x, tex.y)); + } +} + +void draw(t_game *game, t_dda *dda, int x) +{ + int y; + + y = -1; + while (++y < dda->draw_start) + mlx_put_pixel(game->window, x, y, game->map.color_bot); + draw_texture(game, dda, x); + y = dda->draw_end - 1; + while (++y < HEIGHT && y > 0) + mlx_put_pixel(game->window, x, y, game->map.color_top); +} diff --git a/game/game.c b/game/game.c index f61cfc5..7f136fa 100644 --- a/game/game.c +++ b/game/game.c @@ -6,35 +6,41 @@ /* By: erey-bet +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/04/26 12:59:53 by erey-bet #+# #+# */ -/* Updated: 2023/05/03 14:50:16 by erey-bet ### ########.fr */ +/* Updated: 2023/05/11 16:16:00 by erey-bet ### ########.fr */ /* */ /* ************************************************************************** */ #include "game.h" +void destroy(t_game *game) +{ + mlx_delete_texture(game->textures[0]); + mlx_delete_texture(game->textures[1]); + mlx_delete_texture(game->textures[2]); + mlx_delete_texture(game->textures[3]); + mlx_terminate(game->mlx); +} + int start_game(t_map map) { t_game game; - init(map, &game); - if (!game.mlx) + if (init(map, &game)) return (1); game.window = mlx_new_image(game.mlx, WIDTH, HEIGHT); if (!game.window) { mlx_terminate(game.mlx); - return(1); + return (1); } if (mlx_image_to_window(game.mlx, game.window, 0, 0) == -1) { mlx_terminate(game.mlx); - return(1); + return (1); } - raycasting(&game); mlx_key_hook(game.mlx, manage, &game); mlx_loop(game.mlx); - mlx_terminate(game.mlx); - + destroy(&game); return (0); } diff --git a/game/game.h b/game/game.h index e1c70b0..e44a1eb 100644 --- a/game/game.h +++ b/game/game.h @@ -6,7 +6,7 @@ /* By: erey-bet +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/04/26 15:29:34 by erey-bet #+# #+# */ -/* Updated: 2023/05/05 16:54:19 by erey-bet ### ########.fr */ +/* Updated: 2023/05/11 15:28:26 by erey-bet ### ########.fr */ /* */ /* ************************************************************************** */ @@ -56,28 +56,47 @@ typedef struct s_dda int draw_end; } t_dda; +typedef struct s_texture_draw +{ + mlx_texture_t *texture; + double wall_x; + int x; + int y; + double pos; + double step; +} t_texture_draw; + typedef struct s_game { - mlx_t *mlx; - mlx_image_t *window; - mlx_image_t textures[4]; - t_ply ply; - t_map map; - t_ray ray; + mlx_t *mlx; + mlx_image_t *window; + mlx_texture_t *textures[4]; + t_ply ply; + t_map map; + t_ray ray; } t_game; /* INIT */ -void init(t_map map, t_game *game); +int init(t_map map, t_game *game); /* MANAGE */ -void manage(mlx_key_data_t keydata, void *param); +void manage(mlx_key_data_t keydata, void *param); /* KEYS */ -int manage_keys(mlx_key_data_t keydata, t_game *game); +int manage_keys(mlx_key_data_t keydata, t_game *game); /* RAYCASTING */ -int raycasting(t_game *game); +int raycasting(t_game *game); /* DDA ALGO */ -void dda(t_game *game, int x); +void dda(t_game *game, int x); + +/* UTILS */ +double ft_abs(double nb); +unsigned int get_rgba(int r, int g, int b, int a); +uint32_t get_pixel_color(mlx_texture_t *texture, uint32_t x, uint32_t y); +int get_texture_side(t_dda *dda); + +/* DRAW */ +void draw(t_game *game, t_dda *dda, int x); #endif diff --git a/game/init.c b/game/init.c index 1c22bd9..eb7f9e6 100644 --- a/game/init.c +++ b/game/init.c @@ -6,7 +6,7 @@ /* By: erey-bet +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/04/27 14:50:22 by erey-bet #+# #+# */ -/* Updated: 2023/05/05 17:05:49 by erey-bet ### ########.fr */ +/* Updated: 2023/05/11 15:40:16 by erey-bet ### ########.fr */ /* */ /* ************************************************************************** */ @@ -14,18 +14,18 @@ void init_ply(t_map map, t_ply *ply) { - ply->pos_x = map.ply_x; - ply->pos_y = map.ply_y; - ply->dir_x = 0; - ply->dir_y = 0; + ply->pos_x = map.ply_x - 0.5; + ply->pos_y = map.ply_y - 0.5; + ply->dir_x = 0.0; + ply->dir_y = 0.0; if (map.direction == 'N') - ply->dir_y = -1; + ply->dir_y = -1.0; if (map.direction == 'S') - ply->dir_y = 1; + ply->dir_y = 1.0; if (map.direction == 'E') - ply->dir_x = 1; + ply->dir_x = 1.0; if (map.direction == 'W') - ply->dir_x = -1; + ply->dir_x = -1.0; ply->pla_x = -(ply->dir_y) * 0.66; ply->pla_y = (ply->dir_x) * 0.66; } @@ -36,30 +36,32 @@ void init_ray(t_ray *ray) ray->dir_y = 0; } -int init_textures(t_map map, mlx_image_t **textures) +int init_textures(t_map map, mlx_texture_t *textures[4]) { - (*textures)[0] = mlx_load_png(map.img_path[0]); + textures[0] = mlx_load_png(map.img_path[0]); if (!textures[0]) return (1); - (*textures)[1] = mlx_load_png(map.img_path[1]); + textures[1] = mlx_load_png(map.img_path[1]); if (!textures[1]) return (1); - (*textures)[2] = mlx_load_png(map.img_path[2]); + textures[2] = mlx_load_png(map.img_path[2]); if (!textures[2]) return (1); - (*textures)[3] = mlx_load_png(map.img_path[3]); + textures[3] = mlx_load_png(map.img_path[3]); if (!textures[3]) return (1); return (0); } -void init(t_map map, t_game *game) +int init(t_map map, t_game *game) { game->mlx = mlx_init(WIDTH, HEIGHT, "jan lili", true); if (!game->mlx) - return ; + return (1); game->map = map; init_ply(map, &game->ply); init_ray(&game->ray); - init_textures(map, &game->textures); + if (init_textures(map, game->textures)) + return (1); + return (0); } diff --git a/game/manage_keys.c b/game/manage_keys.c index 2c9c176..8dc44ca 100644 --- a/game/manage_keys.c +++ b/game/manage_keys.c @@ -14,11 +14,11 @@ void rotate(t_ply *ply, bool right) { - double old_dir_x; - double old_dir_y; - double old_plane_x; - double old_plane_y; - double speed; + double old_dir_x; + double old_dir_y; + double old_plane_x; + double old_plane_y; + double speed; old_dir_x = ply->dir_x; old_dir_y = ply->dir_y; @@ -33,30 +33,25 @@ void rotate(t_ply *ply, bool right) ply->pla_y = old_plane_x * sin(speed) + old_plane_y * cos(speed); } -void movement(t_game *game, t_ply *ply, double x, double y) +void movement(t_ply *ply, double x, double y) { - (void)game; - //if(game->map.map[(int)(ply->pos_x + x)][(int)ply->pos_y] == '0') - ply->pos_x += x; - //if(game->map.map[(int)ply->pos_x][(int)(ply->pos_y + y)] == '0') - ply->pos_y += y; + ply->pos_x += x; + ply->pos_y += y; } - int manage_movement(t_game *game, int key) { t_ply *ply; ply = &game->ply; - //printf("dir_x: %f, dir_y: %f\n", ply->dir_x, ply->dir_y); if (key == MLX_KEY_W) - movement(game, ply, (ply->dir_x * MOVESPEED), (ply->dir_y * MOVESPEED)); + movement(ply, (ply->dir_x * MOVESPEED), (ply->dir_y * MOVESPEED)); else if (key == MLX_KEY_S) - movement(game, ply, -(ply->dir_x * MOVESPEED), -(ply->dir_y * MOVESPEED)); + movement(ply, -(ply->dir_x * MOVESPEED), -(ply->dir_y * MOVESPEED)); else if (key == MLX_KEY_D) - movement(game, ply, (ply->pla_x * MOVESPEED), (ply->pla_y * MOVESPEED)); + movement(ply, (ply->pla_x * MOVESPEED), (ply->pla_y * MOVESPEED)); else if (key == MLX_KEY_A) - movement(game, ply, -(ply->pla_x * MOVESPEED), -(ply->pla_y * MOVESPEED)); + movement(ply, -(ply->pla_x * MOVESPEED), -(ply->pla_y * MOVESPEED)); else if (key == MLX_KEY_L) rotate(ply, true); else if (key == MLX_KEY_J) @@ -72,12 +67,12 @@ int manage_keys(mlx_key_data_t keys, t_game *game) if (keys.key == MLX_KEY_Q) mlx_close_window(game->mlx); else if (keys.key == MLX_KEY_W - || keys.key == MLX_KEY_S - || keys.key == MLX_KEY_D - || keys.key == MLX_KEY_A - || keys.key == MLX_KEY_ESCAPE - || keys.key == MLX_KEY_L - || keys.key == MLX_KEY_J ) + || keys.key == MLX_KEY_S + || keys.key == MLX_KEY_D + || keys.key == MLX_KEY_A + || keys.key == MLX_KEY_ESCAPE + || keys.key == MLX_KEY_L + || keys.key == MLX_KEY_J) is_moving = manage_movement(game, keys.key); if (is_moving) return (1); diff --git a/game/raycasting.c b/game/raycasting.c index 2f76916..791b31a 100644 --- a/game/raycasting.c +++ b/game/raycasting.c @@ -12,7 +12,7 @@ #include "game.h" -int ray(t_game *game) +int raycasting(t_game *game) { t_ply *p; t_ray *ray; @@ -21,7 +21,6 @@ int ray(t_game *game) x = 0; p = &game->ply; - ray = &game->ray; while (x < WIDTH) { @@ -31,11 +30,5 @@ int ray(t_game *game) dda(game, x); x++; } - return(0); -} - -int raycasting(t_game *game) -{ - ray(game); return (0); } diff --git a/game/utils.c b/game/utils.c new file mode 100644 index 0000000..9bfa181 --- /dev/null +++ b/game/utils.c @@ -0,0 +1,50 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* utils.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: erey-bet +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/05/11 14:19:16 by erey-bet #+# #+# */ +/* Updated: 2023/05/11 14:19:19 by erey-bet ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "game.h" + +double ft_abs(double nb) +{ + if (nb < 0) + return (-nb); + return (nb); +} + +unsigned int get_rgba(int r, int g, int b, int a) +{ + return (r << 24 | g << 16 | b << 8 | a); +} + +static uint32_t switch_color_bytes(uint32_t color) +{ + return (((color & 0xff) << 24) | (((color >> 8) & 0xff) << 16) + | (((color >> 16) & 0xff) << 8) | color >> 24); +} + +uint32_t get_pixel_color(mlx_texture_t *texture, uint32_t x, uint32_t y) +{ + return (switch_color_bytes(*(uint32_t *)(texture->pixels + + (y * texture->width + x) * texture->bytes_per_pixel))); +} + +int get_texture_side(t_dda *dda) +{ + if (dda->side == 0 && dda->step_x < 0) + return (0); + if (dda->side == 0 && dda->step_x > 0) + return (1); + if (dda->side == 1 && dda->step_y < 0) + return (2); + if (dda->side == 1 && dda->step_y > 0) + return (3); + return (0); +} diff --git a/map/map.h b/map/map.h index acd956c..620fc32 100644 --- a/map/map.h +++ b/map/map.h @@ -10,8 +10,8 @@ typedef struct s_map void *img_path[4]; long long color_bot; long long color_top; - size_t size_x; - size_t size_y; + int size_x; + int size_y; double ply_x; double ply_y; char direction; diff --git a/map/parsing_body.c b/map/parsing_body.c index 1fb4fce..cc223de 100644 --- a/map/parsing_body.c +++ b/map/parsing_body.c @@ -3,8 +3,8 @@ char **get_body(const char **file_content, size_t header_size) { char **body; - size_t i; - size_t len; + int i; + int len; len = 0; while (file_content[header_size + len] != NULL) @@ -29,8 +29,8 @@ char **get_body(const char **file_content, size_t header_size) int get_spawn_position(const char **body, double *spawn_x, double *spawn_y) { - size_t x; - size_t y; + int x; + int y; *spawn_x = -1; *spawn_y = -1; @@ -58,7 +58,7 @@ int get_spawn_position(const char **body, double *spawn_x, double *spawn_y) static int map_is_in_one_part(const char **body) { - size_t y; + int y; y = ft_tablen((const void **) body) - 1; while (body[y][0] == '\0' || ft_contain_only(body[y], ' ')) @@ -74,8 +74,8 @@ static int map_is_in_one_part(const char **body) static int map_surround(const char **body) { - size_t y; - size_t x; + int y; + int x; y = 0; while (body[y] != NULL) @@ -125,8 +125,8 @@ static int body_contain_normal_char(const char **body) void get_size(const char **body, t_map *map) { - size_t y; - size_t x; + int y; + int x; map->size_x = 0; y = 0; @@ -157,8 +157,8 @@ int body_is_valid(t_map *map) ft_eprintf("map: spawn position: not define"); return (0); } - map->direction = map->map[(size_t) map->ply_y][(size_t) map->ply_x]; - map->map[(size_t) map->ply_y][(size_t) map->ply_x] = '0'; + map->direction = map->map[(int) map->ply_y][(int) map->ply_x]; + map->map[(int) map->ply_y][(int) map->ply_x] = '0'; error = map_is_in_one_part((const char **)map->map); if (error) { diff --git a/maps/test1.cub b/maps/test1.cub index 59fab15..d6bd57b 100644 --- a/maps/test1.cub +++ b/maps/test1.cub @@ -1,4 +1,9 @@ -SO ./path_to_the_south_texture +NO ./assets/red.png +SO ./assets/blue.png +WE ./assets/green.png +EA ./assets/purple.png + +F 200,100,0 C 225,30,0 EA ./path_to_the_east_texture NO ./path_to_the_north_texture