merge map parsing with expose

This commit is contained in:
mcolonna 2024-10-15 18:23:16 +02:00
commit d1f2136b13
35 changed files with 1364 additions and 152 deletions

View file

@ -1,45 +1,71 @@
# **************************************************************************** #
# #
# ::: :::::::: #
# Makefile :+: :+: :+: #
# +:+ +:+ +:+ #
# By: mcolonna <mcolonna@student.42.fr> +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
# Created: 2024/07/29 13:08:42 by greg #+# #+# #
# Updated: 2024/10/15 13:01:09 by mcolonna ### ########.fr #
# #
# **************************************************************************** #
NAME = cub3d
CPP = gcc $(FLAGS)
LIBRARIES_DIR = Libft Minilibx
LIBRARIES_A = Libft/libft.a Minilibx/libmlx.a
CPP_1 = $(CPP) -Wall -Wextra -Werror -I Libft -I Minilibx $(FLAGS_1)
CPP_2 = $(CPP) $(FLAGS_2)
SHARED = -lX11 -lXext -lm
C_FILES = $(wildcard **.c)
O_FILES = $(patsubst %.c,%.o,$(C_FILES))
SRC = $(wildcard *.c)
ECHO = echoo(){ \
if [ -t 1 ]; then \
echo "$$*"; \
else \
echo "$$*" | sed -E "s/\x1B[[][0-9;]+m//g"; \
fi; \
};echoo
OBJS = ${SRC:.c=.o}
all : $(NAME)
LIBFT = Libft
MLX = Minilibx
CC = gcc -g
CFLAGS = -Wall -Werror -Wextra
all: $(NAME)
obj : ${OBJS}
$(NAME): ${OBJS}
make -C ${LIBFT}
make -C ${MLX}
gcc ${OBJS} Libft/libft.a Minilibx/libmlx.a -lX11 -lXext -o cub3d -lm
$(LIBRARIES_DIR):
@$(ECHO)
@$(ECHO) "\e[30;47;1m $(NAME): making library $@... \e[0m"
$(MAKE) -C $@
clean :
rm -f ${OBJS}
@$(ECHO)
@$(ECHO) "\e[30;47;1m $(NAME): clean... \e[0m"
-rm -f $(O_FILES)
fclean : clean
rm -f $(NAME)
make fclean -C ${LIBFT}
make clean -C ${MLX}
fclean : clean
@$(ECHO)
@$(ECHO) "\e[30;47;1m $(NAME): fclean... \e[0m"
-rm -f $(NAME)
re : fclean all
$(NAME) : $(O_FILES) $(LIBRARIES_DIR)
@$(ECHO)
@$(ECHO) "\e[30;47;1m $(NAME): linking... \e[0m"
$(CPP_2) $(O_FILES) $(LIBRARIES_A) $(SHARED) -o $@
@$(ECHO)
@$(ECHO) "\t\t \e[0;92m\(^o^)/ \e[0;102;30;1m $(NAME) made! \e[0;92m \(^o^)/\e[0m"
@$(ECHO)
%.o : %.c
@$(ECHO)
@$(ECHO) "\e[30;47;1m $(NAME): making '$@'... \e[0m"
$(CPP_1) $(FLAGS_1) -c $< -o $@
check_headers :
@ERROR=0; \
for HEADER in $(wildcard *.h) $(wildcard **/*.h); \
do \
echo "check header $$HEADER..."; \
> __tmp_check_header.c echo "#include \"$$HEADER\""; \
>> __tmp_check_header.c echo "#include \"$$HEADER\""; \
>> __tmp_check_header.c echo "int main(void) {}"; \
$(CPP) -o __tmp_check_header.out __tmp_check_header.c; \
if [ $$? -ne 0 ]; \
then \
ERROR=1; \
echo " error \e[31m:(\e[0m"; \
fi; \
echo " good \e[32m:)\e[0m"; \
2> /dev/null rm -- "__tmp_check_header.out" "__tmp_check_header.c"; \
done; \
2> /dev/null rm __tmp_check_header.out __tmp_check_header.c; \
if [ $$ERROR -eq 0 ]; then true; else false; fi;
.PHONY : all clean fclean re check_headers $(LIBRARIES_DIR)

56
algo.c
View file

@ -6,52 +6,16 @@
/* By: mcolonna <mcolonna@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/10/01 16:24:58 by grobledo #+# #+# */
/* Updated: 2024/10/15 16:00:41 by mcolonna ### ########.fr */
/* Updated: 2024/10/15 16:38:31 by mcolonna ### ########.fr */
/* */
/* ************************************************************************** */
#include "algo.h"
void *g_mlx = NULL;
void *g_win = NULL;
t_ray g_ray;
int g_world_map[MAP_WIDTH][MAP_HEIGHT] = {
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1},
{1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1},
{1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1},
{1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
};
// TODO from map
static int initalgo(void)
{
g_ray.pos.x = 14;
g_ray.pos.y = 6.5;
g_ray.rot = 0;
return (0);
}
void *g_mlx = NULL;
void *g_win = NULL;
t_map g_map;
t_player g_player;
// TODO manage image format error better
@ -90,11 +54,17 @@ void load_textures(t_tex *tex)
&width, &height);
}
int main(void)
int main(int argc, char *argv[])
{
g_mlx = mlx_init();
if (argc != 2)
{
printf("Syntax: %s <map.cub>\n", argv[0]);
return (1);
}
if (!map_from_file(&g_map, argv[1]))
return (1);
g_win = mlx_new_window(g_mlx, SCREEN_WIDTH, SCREEN_HEIGHT, "cub3d");
initalgo();
mlx_hook(g_win, KeyPress, KeyPressMask, keypress, NULL);
draw_screen();
mlx_loop(g_mlx);

37
algo.h
View file

@ -6,7 +6,7 @@
/* By: mcolonna <mcolonna@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/09/30 15:45:59 by grobledo #+# #+# */
/* Updated: 2024/10/15 15:48:45 by mcolonna ### ########.fr */
/* Updated: 2024/10/15 16:57:48 by mcolonna ### ########.fr */
/* */
/* ************************************************************************** */
@ -15,11 +15,17 @@
# include <unistd.h>
# include <math.h>
# include <linux/types.h>
# include <stdbool.h>
# include "Minilibx/mlx.h"
# include "Minilibx/mlx_int.h"
# include "Libft/libft.h"
# include "stream.h"
# include "read_all_text.h"
# include "map.h"
# include "map_mapping.h"
# define MAP_WIDTH 24 // cases (TODO test)
# define MAP_HEIGHT 24 // cases (TODO test)
# define TEX_WIDTH 64
@ -34,30 +40,10 @@
# define SCREEN_HEIGHT 480 // px
# define FOV 0.66 // ? TODO unit
typedef struct s_point_double
{
double x;
double y;
} t_point_double;
typedef struct s_point_int
{
int x;
int y;
} t_point_int;
typedef struct s_ray
{
// pos player on map (cases)
t_point_double pos;
// player rotation (rad)
double rot;
} t_ray;
extern void *g_mlx;
extern void *g_win;
extern t_ray g_ray;
extern int g_world_map[MAP_WIDTH][MAP_HEIGHT];
extern t_player g_player;
extern t_map g_map;
typedef struct s_tex
{
@ -69,6 +55,11 @@ typedef struct s_tex
} t_tex;
/// @brief Write an error message on stderr.
///
/// @param str... All the strings to write. The last parameter MUST BE NULL.
void write_err(const char *str, ...);
void vector_from_rotation(t_point_double *vec, double angle, double norm);
int keypress(int keycode);

18
color.c Normal file
View file

@ -0,0 +1,18 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* color.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: mcolonna <mcolonna@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/10/01 17:04:56 by mcolonna #+# #+# */
/* Updated: 2024/10/15 16:26:52 by mcolonna ### ########.fr */
/* */
/* ************************************************************************** */
#include "map.h"
t_color color_from_rgb(int red, int green, int blue)
{
return (red << 16 | green << 8 | blue);
}

23
dev/cub.vim Normal file
View file

@ -0,0 +1,23 @@
# Vim plugin to edit .cub files
function! CubSyntax()
if expand('%:e') == 'cub'
highlight cubParameter ctermfg=blue
syntax match cubParameter /^(NO|SO|WE|EA|F|C) .$/
highlight cubDefault ctermfg=white
syntax match cubDefault /./
highlight cub0 ctermfg=grey
syntax match cub0 /0/
highlight cub1 cterm=bold ctermfg=white
syntax match cub1 /1/
highlight cubP cterm=bold ctermfg=blue
syntax match cubP /[NSWE]/
endif
endfunction
autocmd BufReadPost * call CubSyntax()

134
map.h Normal file
View file

@ -0,0 +1,134 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* map.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: mcolonna <mcolonna@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/10/01 13:59:04 by mcolonna #+# #+# */
/* Updated: 2024/10/15 18:22:32 by mcolonna ### ########.fr */
/* */
/* ************************************************************************** */
#ifndef MAP_H
# define MAP_H
# include <stdbool.h>
# include "utils.h"
/// @brief The type of a case.
typedef enum e_map_wall
{
/// @brief Empty case, for '0' and ' '.
EMPTY,
/// @brief A wall, for '1'.
WALL,
} t_map_wall;
/// @brief An object of the map (player, enemies?)
typedef struct s_object
{
/// @brief Function called when creating the object.
///
/// @param data Address of the s_object.data pointer.
void (*init)(void **data, t_point_int pos);
/// @brief Function called when destroying the object (to avoid leaks).
///
/// @param data Address of the s_object.data pointer.
void (*destroy)(void **data, t_point_int pos);
/// @brief Function called each tick.
///
/// @param data Address of the s_object.data pointer.
void (*tick)(void **data, t_point_int pos);
/// @brief Pointer the object can use to save data.
void *data;
} t_object;
/// @brief Represents a case of the map.
typedef struct s_map_case
{
/// @brief 'true' if the case is inside of the room (false with ' ' char)
bool inside;
/// @brief Is the case empty or a wall?
t_map_wall wall;
/// @brief The object that appears on this case. If there is none,
/// every pointer of the struct will be NULL.
t_object object;
} t_map_case;
typedef struct s_player
{
// pos player on map (cases)
t_point_double pos;
// player rotation (rad)
double rot;
} t_player;
/// @brief Represents a map.
typedef struct s_map
{
/// @brief Color of the floor.
t_color color_floor;
/// @brief Color of the ceiling.
t_color color_ceiling;
/// @brief Path to the image file for the wall face north.
const char *texture_north;
/// @brief Path to the image file for the wall face south.
const char *texture_south;
/// @brief Path to the image file for the wall face west.
const char *texture_west;
/// @brief Path to the image file for the wall face east.
const char *texture_east;
/// @brief Width of the map.
unsigned int width;
/// @brief Height of the map.
unsigned int height;
/// @brief An 2D array of all the cases.
///
/// Syntax to get a case: cases[y * width + x]
/// x is left to right, y is top to bottom.
t_map_case *cases;
/// @brief Represents the player in the map.
t_player player;
} t_map;
/// @brief Create a t_map from the content of a .cub file.
///
/// @param dest Pointer to the t_map to set.
/// @param file .cub file to use to create the t_map.
/// It must be destroyed with mapDestroy to avoid leaks.
/// @return false if an error occured, otherwise true.
bool map_from_file(t_map *dest, const char *file);
/// @brief Destroy the map to avoid leaks.
void map_destroy(t_map *map);
/// @brief Return true if the map is valid. Write an error message on stderr.
///
/// @param map The map to check.
/// @return true if the map is valid, false if not.
bool check_map(const t_map *map);
/// @brief Get a case of the map from its coordinates.
///
/// @param map Map to get the case from.
/// @param x x position of the case to return.
/// @param y y position of the case to return.
/// @return Wanted case.
const t_map_case *map_get_case(const t_map *map, int x, int y);
#endif

123
map1.c Normal file
View file

@ -0,0 +1,123 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* map1.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: mcolonna <mcolonna@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/10/01 17:12:58 by mcolonna #+# #+# */
/* Updated: 2024/10/15 17:22:53 by mcolonna ### ########.fr */
/* */
/* ************************************************************************** */
#include "map.h"
#include "map_utils.h"
#include "stream.h"
#include "read_all_text.h"
#include "libft.h"
#include <fcntl.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
static bool map_from_file2(t_map *dest, t_stream *stream, int fd)
{
bool success;
stream->i = 0;
success = read_map(dest, stream);
if (success)
{
success = check_map(dest);
if (!success)
map_destroy(dest);
}
close(fd);
free((void *)stream->str);
map_init_objects(dest);
return (success);
}
bool map_from_file(t_map *dest, const char *file)
{
int fd;
t_stream stream;
if (ft_strncmp(file + ft_strlen(file) - 4, ".cub", 5))
{
write_err("File extension must be .cub\n", NULL);
return (false);
}
fd = open(file, O_RDONLY);
if (fd < 0)
{
write_err("Can't open '", file, "': ", strerror(errno), "\n",
NULL);
return (false);
}
stream.str = read_all_text(fd);
if (!stream.str)
{
write_err("Can't read file.\n", NULL);
close(fd);
return (false);
}
return (map_from_file2(dest, &stream, fd));
}
void map_destroy(t_map *map)
{
free((void *)map->texture_east);
free((void *)map->texture_west);
free((void *)map->texture_north);
free((void *)map->texture_south);
free(map->cases);
}
static bool check_map2(const t_map *map, unsigned int x, unsigned int y)
{
unsigned int x2;
unsigned int y2;
const t_map_case *c;
c = &map->cases[y * map->width + x];
if (c->inside && c->wall != WALL)
{
if (x == 0 || x == map->width - 1
|| y == 0 || y == map->height - 1)
return (write_err("Map is not surrounded by walls\n", NULL), false);
x2 = x - 2;
while (++x2 < x + 2)
{
y2 = y - 2;
while (++y2 < y + 2)
{
if (x < map->width && y < map->height
&& !map->cases[y2 * map->width + x2].inside)
return (write_err("Map is not surrounded by walls\n", NULL),
false);
}
}
}
return (true);
}
// TODO check player
bool check_map(const t_map *map)
{
unsigned int x;
unsigned int y;
x = -1;
while (++x < map->width)
{
y = -1;
while (++y < map->height)
{
if (!check_map2(map, x, y))
return (false);
}
}
return (true);
}

27
map2.c Normal file
View file

@ -0,0 +1,27 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* map2.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: mcolonna <mcolonna@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/10/01 17:12:58 by mcolonna #+# #+# */
/* Updated: 2024/10/15 16:44:40 by mcolonna ### ########.fr */
/* */
/* ************************************************************************** */
#include "map.h"
#include "map_utils.h"
#include "stream.h"
#include "read_all_text.h"
#include "libft.h"
#include <fcntl.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
const t_map_case *map_get_case(const t_map *map, int x, int y)
{
return (&map->cases[y * map->width + x]);
}

25
map_mapping.c Normal file
View file

@ -0,0 +1,25 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* map_mapping.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: mcolonna <mcolonna@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/10/04 12:05:21 by mcolonna #+# #+# */
/* Updated: 2024/10/15 17:19:26 by mcolonna ### ########.fr */
/* */
/* ************************************************************************** */
#include "map_mapping.h"
#include "player.h"
#include <stdlib.h>
const t_map_mapping_element g_map_mapping[] = {
{' ', {false, EMPTY, {NULL, NULL, NULL, NULL}}},
{'0', {true, EMPTY, {NULL, NULL, NULL, NULL}}},
{'1', {true, WALL, {NULL, NULL, NULL, NULL}}},
{'N', {true, EMPTY, {init_player_n, NULL, NULL, NULL}}},
{'S', {true, EMPTY, {init_player_s, NULL, NULL, NULL}}},
{'E', {true, EMPTY, {init_player_e, NULL, NULL, NULL}}},
{'W', {true, EMPTY, {init_player_w, NULL, NULL, NULL}}},
{'\0', {true, EMPTY, {NULL, NULL, NULL, NULL}}}};

31
map_mapping.h Normal file
View file

@ -0,0 +1,31 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* map_mapping.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: mcolonna <mcolonna@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/10/04 12:00:07 by mcolonna #+# #+# */
/* Updated: 2024/10/04 15:24:14 by mcolonna ### ########.fr */
/* */
/* ************************************************************************** */
#ifndef MAP_MAPPING_H
# define MAP_MAPPING_H
# include "map.h"
/// @brief Each element of g_map_mapping. A case and its associated char.
typedef struct s_map_mapping_element
{
/// @brief char representing the case.
char name;
/// @brief associated case.
t_map_case value;
} t_map_mapping_element;
/// @brief List of each char and its according case.
/// Ended by an element with the name '\0'.
extern const t_map_mapping_element g_map_mapping[];
#endif

83
map_utils.h Normal file
View file

@ -0,0 +1,83 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* map_utils.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: mcolonna <mcolonna@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/10/03 15:05:13 by mc #+# #+# */
/* Updated: 2024/10/15 17:23:40 by mcolonna ### ########.fr */
/* */
/* ************************************************************************** */
#ifndef MAP_UTILS_H
# define MAP_UTILS_H
# include "stream.h"
# include "map.h"
# include <stdbool.h>
# include <stddef.h>
/// @brief Read a parameter of the map which has a color as an argument.
/// Color format: [0-255],[0-255],[0-255]
/// @param name Name of the parameter.
/// @param dest Will be set to the value of the parameter.
/// Unchanged if error.
/// If success but *dest is not 0xFF000000, throws an error.
/// @param stream Stream to use.
/// Unchanged if error.
/// @param redefined Set to true if the parameter was already defined.
/// @return true if success or redefined, false if non-fatal error.
bool read_color_parameter(const char *name, t_color *dest,
t_stream *stream, bool *redefined);
/// @brief Read a parameter of the map which has a string as an argument.
/// @param name Name of the parameter.
/// @param dest Will be set to an alloc'd pointer to the value of the parameter.
/// Unchanged if error.
/// If success but *dest is not null, throws an error.
/// @param stream Stream to use.
/// Unchanged if error.
/// @param redefined Set to true if the parameter was already defined.
/// @return true if success or redefined, false if non-fatal error.
bool read_string_parameter(const char *name, const char **dest,
t_stream *stream, bool *redefined);
/// @brief Set the map to initial values. Every texture becomes NULL
/// and every color becomes 0xFF000000.
/// @param dest Map to reset.
void reset_map(t_map *dest);
/// @brief Read a map-formatted string.
/// If an error occurs, write an error message on stderr.
/// @param dest Will be set to the map.
/// @param stream Stream to use.
/// @return true if success, false if error.
bool read_map(t_map *dest, t_stream *stream);
/// @brief Get the case associated with the char.
///
/// @param dest Will be set to the char.
/// @param name Name of the case.
/// @return true if success, false if error.
bool get_case(t_map_case *dest, char name);
/// @brief Fill the pointer with 'size' null bytes.
///
/// @param dest The pointer to set.
/// @param size The number of bytes.
void fill_zeros(void *dest, size_t size);
/// @brief Read the map description part of the map.
/// Read until the end of the file.
///
/// @param map The .width, .height and .cases members will be set.
/// @param stream Stream to use.
/// @return true if success, false if error.
bool read_map_description(t_map *map, t_stream *stream);
/// @brief Initialize all objects of the map.
/// @param map Map to use.
void map_init_objects(t_map *map);
#endif

135
map_utils1.c Normal file
View file

@ -0,0 +1,135 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* map_utils1.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: mcolonna <mcolonna@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/10/03 15:02:09 by mc #+# #+# */
/* Updated: 2024/10/15 17:43:29 by mcolonna ### ########.fr */
/* */
/* ************************************************************************** */
#include "map_utils.h"
#include "map.h"
#include "map_mapping.h"
#include <stdlib.h>
bool read_color_parameter(const char *name, t_color *dest,
t_stream *stream, bool *redefined)
{
unsigned int rgb[3];
bool err;
t_stream old;
old = *stream;
err = false;
read_expected_string(name, stream, &err);
read_expected_string(" ", stream, &err);
read_unsigned(&rgb[0], stream, &err);
read_expected_string(",", stream, &err);
read_unsigned(&rgb[1], stream, &err);
read_expected_string(",", stream, &err);
read_unsigned(&rgb[2], stream, &err);
read_expected_string("\n", stream, &err);
if (!err && *dest != 0xFF000000)
{
*redefined = true;
write_err("Parameter '", name, "' was defined several times\n",
NULL);
}
else if (!err)
*dest = color_from_rgb(rgb[0], rgb[1], rgb[2]);
else
*stream = old;
return (!err);
}
bool read_string_parameter(const char *name, const char **dest,
t_stream *stream, bool *redefined)
{
char *r;
bool err;
t_stream old;
old = *stream;
err = false;
r = NULL;
read_expected_string(name, stream, &err);
read_expected_string(" ", stream, &err);
read_until('\n', &r, stream, &err);
read_expected_string("\n", stream, &err);
if (!err && *dest)
{
*redefined = true;
write_err("Parameter '", name, "' was defined several times\n", NULL);
}
if (*redefined || err)
{
*stream = old;
free(r);
}
else
*dest = r;
return (!err);
}
void reset_map(t_map *dest)
{
dest->cases = NULL;
dest->color_ceiling = 0xFF000000;
dest->color_floor = 0xFF000000;
dest->texture_east = NULL;
dest->texture_west = NULL;
dest->texture_north = NULL;
dest->texture_south = NULL;
}
bool read_map(t_map *dest, t_stream *stream)
{
bool err;
bool rdf;
reset_map(dest);
err = false;
rdf = false;
while (!rdf && !err && stream->str[stream->i])
{
if ((read_expected_string("\n", stream, &err), err)
&& !read_string_parameter("NO", &dest->texture_north, stream, &rdf)
&& !read_string_parameter("SO", &dest->texture_south, stream, &rdf)
&& !read_string_parameter("WE", &dest->texture_west, stream, &rdf)
&& !read_string_parameter("EA", &dest->texture_east, stream, &rdf)
&& !read_color_parameter("F", &dest->color_floor, stream, &rdf)
&& !read_color_parameter("C", &dest->color_ceiling, stream, &rdf))
{
err = !read_map_description(dest, stream);
break ;
}
err = false;
}
if (!rdf && !dest->cases)
err = (write_err("Map description missing\n", NULL), true);
(rdf || err) && (map_destroy(dest), false);
return (!err && !rdf && dest->cases);
}
void map_init_objects(t_map *map)
{
t_point_int pos;
int i;
pos.x = 0;
while (pos.x < (int)map->width)
{
pos.y = 0;
while (pos.y < (int)map->height)
{
i = pos.y * map->width + pos.x;
if (map->cases[i].object.init)
map->cases[i].object.init(&map->cases[i].object.data, pos);
pos.y++;
}
pos.x++;
}
}

105
map_utils2.c Normal file
View file

@ -0,0 +1,105 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* map_utils2.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: mcolonna <mcolonna@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/10/04 15:12:08 by mcolonna #+# #+# */
/* Updated: 2024/10/15 16:27:41 by mcolonna ### ########.fr */
/* */
/* ************************************************************************** */
#include "map_utils.h"
#include "map_mapping.h"
#include "map.h"
#include <stdlib.h>
/// @brief Read the map description to get the dimensions.
/// The map must be at least 1x1.
///
/// @param map The .width and .height members will be set.
/// @param stream Stream to use.
/// @return true if success, false if error.
static bool get_map_dimensions(t_map *map, t_stream *stream)
{
unsigned int x;
unsigned int y;
map->width = 0;
map->height = 0;
y = 0;
while (stream->str[stream->i])
{
x = 0;
while (stream->str[stream->i] && stream->str[stream->i] != '\n')
{
stream->i++;
x++;
}
if (x > map->width)
map->width = x;
if (stream->str[stream->i] == '\n')
stream->i++;
y++;
}
map->height = y;
return (map->width > 0 && map->height > 0);
}
bool get_case(t_map_case *dest, char name)
{
int i;
char tmp[2];
i = -1;
while (g_map_mapping[++i].name)
{
if (name == g_map_mapping[i].name)
{
*dest = g_map_mapping[i].value;
return (true);
}
}
tmp[0] = name;
tmp[1] = '\0';
write_err("Character '", tmp, "' unexpected\n", NULL);
return (false);
}
void fill_zeros(void *dest, size_t size)
{
size_t i;
i = -1;
while (++i < size)
((char *)dest)[i] = '\0';
}
bool read_map_description(t_map *map, t_stream *stream)
{
t_stream stream2;
unsigned int x;
unsigned int y;
stream2 = *stream;
if (!get_map_dimensions(map, &stream2))
return (false);
map->cases = malloc((map->width * map->height) * sizeof(t_map_case));
y = -1;
fill_zeros(map->cases, (map->width * map->height) * sizeof(t_map_case));
while (++y < map->height)
{
x = 0;
while (stream->str[stream->i] && stream->str[stream->i] != '\n')
{
if (!get_case(&map->cases[y * map->width + x],
stream->str[stream->i]))
return (false);
stream->i++;
x++;
}
stream->i++;
}
return (true);
}

56
move.c
View file

@ -6,53 +6,35 @@
/* By: mcolonna <mcolonna@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/10/15 12:47:34 by mcolonna #+# #+# */
/* Updated: 2024/10/15 16:01:08 by mcolonna ### ########.fr */
/* Updated: 2024/10/15 18:22:58 by mcolonna ### ########.fr */
/* */
/* ************************************************************************** */
#include "algo.h"
static int move_forward(void)
static int move(int factor)
{
t_point_double dir;
vector_from_rotation(&dir, g_ray.rot, 1);
if (g_world_map[(int)((g_ray.pos.x + dir.x * MOVE_SPEED))]
[(int)(g_ray.pos.y)] != 1
vector_from_rotation(&dir, g_map.player.rot, 1);
if (map_get_case(&g_map,
(int)(g_map.player.pos.x + dir.x * MOVE_SPEED * factor),
(int)(g_map.player.pos.y)
)->wall == EMPTY
)
g_ray.pos.x += dir.x * MOVE_SPEED;
if (g_world_map[(int)(g_ray.pos.x)]
[(int)(g_ray.pos.y + dir.y * MOVE_SPEED)] != 1
g_map.player.pos.x += dir.x * MOVE_SPEED;
if (map_get_case(&g_map,
(int)(g_map.player.pos.x),
(int)(g_map.player.pos.y + dir.y * MOVE_SPEED * factor)
)->wall == EMPTY
)
g_ray.pos.y += dir.y * MOVE_SPEED;
g_map.player.pos.y += dir.y * MOVE_SPEED * factor;
return (0);
}
static int move_backward(void)
static int rotate(int factor)
{
t_point_double dir;
vector_from_rotation(&dir, g_ray.rot, 1);
if (g_world_map[(int)(g_ray.pos.x - dir.x * MOVE_SPEED)]
[(int)(g_ray.pos.y)] != 1
)
g_ray.pos.x -= dir.x * MOVE_SPEED;
if (g_world_map[(int)(g_ray.pos.x)]
[(int)(g_ray.pos.y - dir.y * MOVE_SPEED)] != 1
)
g_ray.pos.y -= dir.y * MOVE_SPEED;
return (0);
}
static int move_right(void)
{
g_ray.rot += PI / ROT_SPEED_DIVIDE_PI;
return (0);
}
static int move_left(void)
{
g_ray.rot -= PI / ROT_SPEED_DIVIDE_PI;
g_map.player.rot += PI / ROT_SPEED_DIVIDE_PI * factor;
return (0);
}
@ -61,13 +43,13 @@ static int move_left(void)
int keypress(int keycode)
{
if (keycode == XK_Up || keycode == XK_z || keycode == XK_w)
move_forward();
move(+1);
if (keycode == XK_Down || keycode == XK_s)
move_backward();
move(-1);
if (keycode == XK_Right || keycode == XK_d)
move_right();
rotate(+1);
if (keycode == XK_Left || keycode == XK_q || keycode == XK_a)
move_left();
rotate(-1);
if (keycode == XK_Escape)
{
mlx_destroy_window(g_mlx, g_win);

46
player.c Normal file
View file

@ -0,0 +1,46 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* player.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: mcolonna <mcolonna@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/10/15 17:33:11 by mcolonna #+# #+# */
/* Updated: 2024/10/15 17:38:27 by mcolonna ### ########.fr */
/* */
/* ************************************************************************** */
#include "player.h"
#include "utils.h"
#include "algo.h"
static void init_player(t_point_int pos, double rot)
{
g_map.player.pos.x = pos.x + 0.5;
g_map.player.pos.y = pos.y + 0.5;
g_map.player.rot = rot;
}
void init_player_n(void **data, t_point_int pos)
{
(void)data;
init_player(pos, 0);
}
void init_player_s(void **data, t_point_int pos)
{
(void)data;
init_player(pos, PI);
}
void init_player_w(void **data, t_point_int pos)
{
(void)data;
init_player(pos, 3 * PI / 2);
}
void init_player_e(void **data, t_point_int pos)
{
(void)data;
init_player(pos, PI / 2);
}

23
player.h Normal file
View file

@ -0,0 +1,23 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* player.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: mcolonna <mcolonna@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/10/15 17:31:35 by mcolonna #+# #+# */
/* Updated: 2024/10/15 17:43:52 by mcolonna ### ########.fr */
/* */
/* ************************************************************************** */
#ifndef PLAYER_H
# define PLAYER_H
# include "utils.h"
void init_player_n(void **data, t_point_int pos);
void init_player_s(void **data, t_point_int pos);
void init_player_w(void **data, t_point_int pos);
void init_player_e(void **data, t_point_int pos);
#endif

95
read_all_text.c Normal file
View file

@ -0,0 +1,95 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* read_all_text.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: mcolonna <mcolonna@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/10/02 16:18:35 by mcolonna #+# #+# */
/* Updated: 2024/10/15 16:28:22 by mcolonna ### ########.fr */
/* */
/* ************************************************************************** */
#include "read_all_text.h"
#include "map.h"
#include "libft.h"
#include <stdlib.h>
#include <stdbool.h>
#include <unistd.h>
/// @brief Concatenate *dest and src and put the result in *dest.
///
/// *dest is alloc'd to contain the result value.
///
/// the old *dest is freed only if the function succeds.
///
/// src doesn't have to be nul-terminated, instead n is the size of src.
///
/// @return true if success, false if error.
static bool strconcat(char **dest, char *src, int n)
{
const int len_dest = ft_strlen(*dest);
char *old_dest;
int i;
old_dest = *dest;
*dest = malloc((len_dest + n + 1) * sizeof(char));
if (!*dest)
return (false);
i = -1;
while (old_dest[++i])
(*dest)[i] = old_dest[i];
while (i < len_dest + n)
{
(*dest)[i] = src[i - len_dest];
i++;
}
(*dest)[i] = '\0';
free(old_dest);
return (true);
}
/// @brief If the string isn't empty and isn't ended by a '\\n', add one and
/// return the result.
///
/// str is either returned directly, or another freeable pointer is returned
/// and str is freed.
///
/// @return Return the result or NULL if error.
static char *add_endline_if_necessary(char *str)
{
char *endline;
if (str[0] == '\0' || str[ft_strlen(str) - 1] == '\n')
return (str);
endline = malloc(1 * sizeof(char));
if (!endline)
return (free(str), NULL);
endline[0] = '\n';
if (!strconcat(&str, endline, 1))
return (free(str), NULL);
return (str);
}
char *read_all_text(int fd)
{
char buf[BUFFER_SIZE];
int n;
char *r;
r = malloc(sizeof(char));
if (!r)
return (NULL);
r[0] = '\0';
n = 1;
while (n)
{
n = read(fd, buf, BUFFER_SIZE);
if (n < 0 || (n && !strconcat(&r, buf, n)))
{
free(r);
return (NULL);
}
}
return (add_endline_if_necessary(r));
}

29
read_all_text.h Normal file
View file

@ -0,0 +1,29 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* read_all_text.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: mcolonna <mcolonna@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/10/02 15:39:02 by mcolonna #+# #+# */
/* Updated: 2024/10/02 17:04:33 by mcolonna ### ########.fr */
/* */
/* ************************************************************************** */
#ifndef READ_ALL_TEXT_H
# define READ_ALL_TEXT_H
/// @brief Size of buffer used in read_all_text().
# define BUFFER_SIZE 1000
/// @brief Read all the text of the given file.
///
/// If the last line isn't ended by a '\\n', add one.
///
/// If error, returns NULL and set errno accordingly.
///
/// @param fd File descriptor of the file.
/// @return Alloc'd string of the file content. NULL if error.
char *read_all_text(int fd);
#endif

View file

@ -6,7 +6,7 @@
/* By: mcolonna <mcolonna@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/10/14 14:55:05 by greg #+# #+# */
/* Updated: 2024/10/15 15:59:55 by mcolonna ### ########.fr */
/* Updated: 2024/10/15 16:55:02 by mcolonna ### ########.fr */
/* */
/* ************************************************************************** */
@ -19,8 +19,8 @@ static void calculate_perpwalldist3(int x,
t_point_double plane;
t_point_double dir;
vector_from_rotation(&dir, g_ray.rot, 1);
vector_from_rotation(&plane, g_ray.rot + PI / 2, 1);
vector_from_rotation(&dir, g_map.player.rot, 1);
vector_from_rotation(&plane, g_map.player.rot + PI / 2, 1);
raydir->x = dir.x + plane.x * ray_direction;
raydir->y = dir.y + plane.y * ray_direction;
deltadist->x = 1e30;
@ -36,30 +36,30 @@ static void calculate_perpwalldist2(int x,
t_point_double *deltadist,
t_point_int *step)
{
const int map_x = (int)g_ray.pos.x;
const int map_y = (int)g_ray.pos.y;
const int map_x = (int)g_map.player.pos.x;
const int map_y = (int)g_map.player.pos.y;
t_point_double raydir;
calculate_perpwalldist3(x, &raydir, deltadist);
if (raydir.x < 0)
{
step->x = -1;
sidedist->x = (g_ray.pos.x - map_x) * deltadist->x;
sidedist->x = (g_map.player.pos.x - map_x) * deltadist->x;
}
else
{
step->x = 1;
sidedist->x = (map_x + 1.0 - g_ray.pos.x) * deltadist->x;
sidedist->x = (map_x + 1.0 - g_map.player.pos.x) * deltadist->x;
}
if (raydir.y < 0)
{
step->y = -1;
sidedist->y = (g_ray.pos.y - map_y) * deltadist->y;
sidedist->y = (g_map.player.pos.y - map_y) * deltadist->y;
}
else
{
step->y = 1;
sidedist->y = (map_y + 1.0 - g_ray.pos.y) * deltadist->y;
sidedist->y = (map_y + 1.0 - g_map.player.pos.y) * deltadist->y;
}
}
@ -76,10 +76,10 @@ static double calculate_perpwalldist(int x)
t_point_double deltadist;
t_point_int step;
map_pos.x = (int)g_ray.pos.x;
map_pos.y = (int)g_ray.pos.y;
map_pos.x = (int)g_map.player.pos.x;
map_pos.y = (int)g_map.player.pos.y;
calculate_perpwalldist2(x, &sidedist, &deltadist, &step);
while (g_world_map[map_pos.x][map_pos.y] != 1)
while (map_get_case(&g_map, map_pos.x, map_pos.y)->wall == EMPTY)
{
if (sidedist.x < sidedist.y)
{

89
stream.c Normal file
View file

@ -0,0 +1,89 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* stream.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: mcolonna <mcolonna@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/10/02 14:08:10 by mcolonna #+# #+# */
/* Updated: 2024/10/02 17:31:34 by mcolonna ### ########.fr */
/* */
/* ************************************************************************** */
#include "stream.h"
#include <stdlib.h>
void read_expected_string(const char *str, t_stream *stream, bool *err)
{
int i;
if (*err)
return ;
i = 0;
while (str[i])
{
if (str[i] != stream->str[stream->i])
{
*err = true;
return ;
}
i++;
stream->i++;
}
return ;
}
/// @brief Check if a character is a digit.
/// @param c Character to check.
/// @return true if the character is a digit, false if not.
/// false if the character is '\0'.
static bool is_digit(char c)
{
return (c >= '0' && c <= '9');
}
void read_unsigned(unsigned int *dest, t_stream *stream, bool *err)
{
int r;
if (*err)
return ;
if (!is_digit(stream->str[stream->i]))
{
*err = true;
return ;
}
r = 0;
while (is_digit(stream->str[stream->i]))
{
r = r * 10 + stream->str[stream->i] - '0';
stream->i++;
}
*dest = r;
}
void read_until(char c, char **dest, t_stream *stream, bool *err)
{
int len;
int i;
if (*err)
return ;
len = 0;
while (stream->str[stream->i + len] && stream->str[stream->i + len] != c)
len++;
*dest = malloc((len + 1) * sizeof(char));
if (!*dest)
{
*err = true;
return ;
}
i = 0;
while (stream->str[stream->i] && stream->str[stream->i] != c)
{
(*dest)[i] = stream->str[stream->i];
i++;
stream->i++;
}
(*dest)[i] = '\0';
}

54
stream.h Normal file
View file

@ -0,0 +1,54 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* stream.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: mcolonna <mcolonna@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/10/02 12:33:25 by mcolonna #+# #+# */
/* Updated: 2024/10/15 16:17:34 by mcolonna ### ########.fr */
/* */
/* ************************************************************************** */
#ifndef STREAM_H
# define STREAM_H
# include <stdbool.h>
/// @brief Represents a string and an associated cursor.
typedef struct s_stream
{
/// @brief Index of the cursor.
int i;
/// @brief Pointer to the string.
const char *str;
} t_stream;
/// @brief Read a specific string, error if it isn't the expected string.
///
/// @param str Expected string.
/// @param stream Stream to use.
/// @param err Set to true if an error occured.
/// If already true, the function won't do anything.
void read_expected_string(const char *str, t_stream *stream, bool *err);
/// @brief Read an unsigned int (which fits the pattern /[0-9]+/).
///
/// @param dest Will be set to the value of the unsigned integer.
/// @param stream Stream to use.
/// @param err Set to true if an error occured.
/// If already true, the function won't do anything.
void read_unsigned(unsigned int *dest, t_stream *stream, bool *err);
/// @brief Read a string until limit char or \0.
///
/// @param c Limit char.
/// @param dest Will be set to an alloc'd pointer to the read string.
/// NULL if alloc error.
/// @param stream Stream to use.
/// @param err Set to true if an error occured.
/// If already true, the function won't do anything.
void read_until(char c, char **dest, t_stream *stream, bool *err);
#endif

View file

@ -0,0 +1,12 @@
F 255,127,0
EA eastimage
NO theimageforthenorthwall
C 0,2,67
SO SOUTH!!!!!!1
WE weeeee
SO south2
11111
10N01
10001
11111

View file

@ -0,0 +1,11 @@
F 255,127,0
EA eastimage
NO theimageforthenorthwall
C 0,2,67
SO SOUTH!!!!!!1
WE weeeee
1111111
1000001
10W0001
1000001
1111111

View file

@ -0,0 +1,6 @@
F 255,127,0
EA eastimage
NO theimageforthenorthwall
C 0,2,67
SO SOUTH!!!!!!1
WE weeeee

View file

@ -0,0 +1,11 @@
F 255,127,0
EA eastimage
NO theimageforthenorthwall
C 0,2,67
SO SOUTH!!!!!!1
WE weeeee
1101111
1000001
10W0001
1000001
1111111

View file

@ -0,0 +1,11 @@
F 255,127,0
EA eastimage
NO theimageforthenorthwall
C 0,2,67
SO SOUTH!!!!!!1
WE weeeee
0111111
1000001
10W0001
1000001
1111111

View file

@ -0,0 +1,11 @@
F 255,127,0
EA eastimage
NO theimageforthenorthwall
C 0,2,67
SO SOUTH!!!!!!1
WE weeeee
111111
1000001
10W0001
1000001
1111111

View file

@ -0,0 +1,11 @@
F 255,127,0
EA eastimage
NO theimageforthenorthwall
C 0,2,67
SO SOUTH!!!!!!1
WE weeeee
1111111
1000001
10W0 01
1000001
1111111

11
testmaps/good.cub Normal file
View file

@ -0,0 +1,11 @@
F 255,127,0
EA eastimage
NO theimageforthenorthwall
C 0,2,67
SO SOUTH!!!!!!1
WE weeeee
1111111
1000001
10W0001
1000001
1111111

View file

@ -0,0 +1,13 @@
F 255,127,0
EA eastimage
NO theimageforthenorthwall
C 0,2,67
SO SOUTH!!!!!!1
WE weeeee
111
111110111
10000N001
111110111
101
101
111

9
testmaps/good_little.cub Normal file
View file

@ -0,0 +1,9 @@
F 255,127,0
EA eastimage
NO theimageforthenorthwall
C 0,2,67
SO SOUTH!!!!!!1
WE weeeee
111
1N1
111

View file

@ -0,0 +1,20 @@
F 255,127,0
EA eastimage
NO theimageforthenorthwall
C 0,2,67
SO SOUTH!!!!!!1
WE weeeee
1111111
1000001
10W0001
1000001
1111111

View file

@ -0,0 +1,19 @@
F 255,127,0
EA eastimage
NO theimageforthenorthwall
C 0,2,67
SO SOUTH!!!!!!1
WE weeeee
111
111 101
111 101111101
101111101100001
100001101101111
1111111111101100101
1000000000101110101
11011111110W00010101
1001 10000010101
1111 111111100000001111111
110000000000100000001
111111111111111111111

16
utils.c
View file

@ -6,14 +6,28 @@
/* By: mcolonna <mcolonna@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/10/15 12:38:40 by mcolonna #+# #+# */
/* Updated: 2024/10/15 15:18:43 by mcolonna ### ########.fr */
/* Updated: 2024/10/15 17:21:16 by mcolonna ### ########.fr */
/* */
/* ************************************************************************** */
#include "algo.h"
#include <stdarg.h>
void vector_from_rotation(t_point_double *vec, double angle, double norm)
{
vec->x = -cos(angle) * norm;
vec->y = sin(angle) * norm;
}
void write_err(const char *str, ...)
{
va_list args;
va_start(args, str);
write(2, "Error\n", 6);
while (str)
{
write(2, str, ft_strlen(str));
str = va_arg(args, const char *);
}
}

44
utils.h Normal file
View file

@ -0,0 +1,44 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* utils.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: mcolonna <mcolonna@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/10/15 16:56:47 by mcolonna #+# #+# */
/* Updated: 2024/10/15 17:21:10 by mcolonna ### ########.fr */
/* */
/* ************************************************************************** */
#ifndef UTILS_H
# define UTILS_H
# include <linux/types.h>
typedef struct s_point_double
{
double x;
double y;
} t_point_double;
typedef struct s_point_int
{
int x;
int y;
} t_point_int;
// TODO Must the transparency be 0 or 255?
/// @brief Represents an TRGB color in 0xTTRRGGBB format.
typedef __u32 t_color;
/// @brief Convert a color from each color value to a t_color.
///
/// @param red Level of red from 0 to 255.
/// @param green Level of green from 0 to 255.
/// @param blue Level of blue from 0 to 255.
/// @return The result.
t_color color_from_rgb(int red, int green, int blue);
void write_err(const char *str, ...);
#endif