/* ************************************************************************** */ /* */ /* ::: :::::::: */ /* main.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: kcolin +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/07/17 14:14:30 by kcolin #+# #+# */ /* Updated: 2025/07/29 10:30:41 by kcolin ### ########.fr */ /* */ /* ************************************************************************** */ #include "../libft/includes/libft.h" #include "../mlx/mlx.h" #include "consts.h" #include "cub3d_data.h" #include "draw/drawutils.h" #include "map/map_checker.h" #include "draw/draw_map.h" #include "map/mapdata.h" #include "player/player.h" #include "utils/hooks.h" #include "utils/frees.h" #include #include #include #include #include #include #include // BAD void init_player(t_mapdata *mapdata, t_player *player) { player->health = 100; player->x = mapdata->startx * SIZE; player->y = mapdata->starty * SIZE; if (mapdata->map[mapdata->starty][mapdata->startx] == 'N') player->yaw = M_PI; else if (mapdata->map[mapdata->starty][mapdata->startx] == 'S') player->yaw = 0; else if (mapdata->map[mapdata->starty][mapdata->startx] == 'E') player->yaw = M_PI / 2; else if (mapdata->map[mapdata->starty][mapdata->startx] == 'W') player->yaw = 3 * M_PI / 2; } bool touch(float px, float py, t_mapdata *map) { int x; int y; x = px / SIZE; y = py / SIZE; if (map->map[y][x] == '1') return (true); return (false); } void draw_line(t_cub3d_data *data, float start_angle) { float cos_angle = cos(start_angle); float sin_angle = sin(start_angle); float ray_x = data->player.x; float ray_y = data->player.y; while(!touch(ray_x, ray_y, data->map)) { my_mlx_pixel_put(data->img_data, (int)(MAP_SIZE * (ray_x / SIZE)), (int)(MAP_SIZE * (ray_y / SIZE)), 0xcc241b); ray_x += sin_angle; ray_y += cos_angle; } } t_cardinal_dir angle_cardinal_dir(float angle) { if (angle >= g_southwest || (angle > g_south && angle < g_southeast)) return (SOUTH); if (angle >= g_southeast && angle < g_northeast) return (EAST); if (angle >= g_northeast && angle < g_northwest) return (NORTH); return (WEST); } t_cardinal_dir player_cardinal_dir(t_player player) { return (angle_cardinal_dir(player.yaw)); } t_intercardinal_dir angle_intercardinal_dir(float angle) { if (angle >= g_south && angle < g_east) return (SOUTHEAST); if (angle >= g_east && angle < g_north) return (NORTHEAST); if (angle >= g_north && angle < g_west) return (NORTHWEST); return (SOUTHWEST); } t_intercardinal_dir player_intercardinal_dir(t_player player) { return (angle_intercardinal_dir(player.yaw)); } /* ** Converts a coordinate from global map space to local tile space. ** ** input coordinate is in the full map ** output coordinate is in the current tile */ float coord_global_to_local(float coord) { return (coord - floor(coord / SIZE) * SIZE); } int game_loop(t_cub3d_data *data) { mlx_destroy_image(data->mlx, data->img_data->img); data->img_data->img = mlx_new_image(data->mlx, WIDTH, HEIGHT); if (player_intercardinal_dir(data->player) == SOUTHEAST) ft_printf("southeast "); if (player_intercardinal_dir(data->player) == SOUTHWEST) ft_printf("southwest "); if (player_intercardinal_dir(data->player) == NORTHEAST) ft_printf("northeast "); if (player_intercardinal_dir(data->player) == NORTHWEST) ft_printf("northwest "); if (player_cardinal_dir(data->player) == SOUTH) ft_printf("south\n"); if (player_cardinal_dir(data->player) == EAST) ft_printf("east\n"); if (player_cardinal_dir(data->player) == NORTH) ft_printf("north\n"); if (player_cardinal_dir(data->player) == WEST) ft_printf("west\n"); printf("local coord: %f, %f\n", coord_global_to_local(data->player.x), coord_global_to_local(data->player.y)); float ray_angle = data->player.yaw - M_PI / 6; float fraction = M_PI / 3 / WIDTH; int column = 0; while (column < WIDTH) { // hline check /* float ray_atan = atan(ray_angle); */ draw_line(data, ray_angle); column++; ray_angle += fraction; } draw_map(data->map, &data->player, data->img_data); mlx_put_image_to_window(data->mlx, data->mlx_win, data->img_data->img, 0, 0); mlx_string_put(data->mlx, data->mlx_win, 10, 10, 0x00FFFFFF, COMPILED_TEXT); return (0); } int main(int argc, char **argv) { t_cub3d_data data; if (argc < 2) return (ft_printf("Error: Missing cub3d file\n"), 1); data.map = ft_calloc(sizeof(t_mapdata), 1); if (!check_cubfile(argv[1], data.map)) return (ft_printf("Error: Wrong map file. Reason: %s\n", data.map->error), free_map(data.map), 1); data.mlx = mlx_init(); if (data.mlx == NULL) return (ft_printf("Error: Failed to initalize mlx\n"), free_map(data.map), 1); data.mlx_win = mlx_new_window(data.mlx, WIDTH, HEIGHT, "Cub3d"); data.img_data = ft_calloc(sizeof(t_img_data), 1); data.img_data->img = mlx_new_image(data.mlx, WIDTH, HEIGHT); data.img_data->addr = mlx_get_data_addr(data.img_data->img, &data.img_data->bits_per_pixel, &data.img_data->line_length, &data.img_data->endian); init_player(data.map, &(data.player)); mlx_hook(data.mlx_win, KeyPress, KeyPressMask, keypress_handler, &data); mlx_hook(data.mlx_win, KeyRelease, KeyReleaseMask, keyrelease_handler, &data); mlx_loop_hook(data.mlx, game_loop, &data); mlx_loop(data.mlx); }