From 57867bbbdc24b734d85f8d3569c7ad27dcd9504d Mon Sep 17 00:00:00 2001 From: Charles Date: Thu, 30 Jan 2020 15:52:16 +0100 Subject: files restructuration --- Makefile | 54 +++++---- capture.c | 25 ---- cub3d.h | 267 ------------------------------------------- error.c | 48 -------- event.c | 45 -------- helper.c | 60 ---------- include/cub3d.h | 267 +++++++++++++++++++++++++++++++++++++++++++ main.c | 77 ------------- minimalist.cub | 4 +- parse/parse.c | 142 ----------------------- parse/parse_check.c | 46 -------- parse/parse_color.c | 55 --------- parse/parse_resolution.c | 24 ---- parse/parse_textures.c | 48 -------- render.c | 107 ----------------- render_state.c | 205 --------------------------------- src/capture.c | 25 ++++ src/error.c | 48 ++++++++ src/event.c | 45 ++++++++ src/helper.c | 60 ++++++++++ src/main.c | 77 +++++++++++++ src/parse/parse.c | 142 +++++++++++++++++++++++ src/parse/parse_check.c | 46 ++++++++ src/parse/parse_color.c | 55 +++++++++ src/parse/parse_resolution.c | 24 ++++ src/parse/parse_textures.c | 48 ++++++++ src/render.c | 107 +++++++++++++++++ src/render_state.c | 205 +++++++++++++++++++++++++++++++++ src/state.c | 128 +++++++++++++++++++++ src/vector.c | 62 ++++++++++ state.c | 128 --------------------- textures/mossy.xpm | 95 +++++++++++++++ vector.c | 62 ---------- 33 files changed, 1469 insertions(+), 1362 deletions(-) delete mode 100644 capture.c delete mode 100644 cub3d.h delete mode 100644 error.c delete mode 100644 event.c delete mode 100644 helper.c create mode 100644 include/cub3d.h delete mode 100644 main.c delete mode 100644 parse/parse.c delete mode 100644 parse/parse_check.c delete mode 100644 parse/parse_color.c delete mode 100644 parse/parse_resolution.c delete mode 100644 parse/parse_textures.c delete mode 100644 render.c delete mode 100644 render_state.c create mode 100644 src/capture.c create mode 100644 src/error.c create mode 100644 src/event.c create mode 100644 src/helper.c create mode 100644 src/main.c create mode 100644 src/parse/parse.c create mode 100644 src/parse/parse_check.c create mode 100644 src/parse/parse_color.c create mode 100644 src/parse/parse_resolution.c create mode 100644 src/parse/parse_textures.c create mode 100644 src/render.c create mode 100644 src/render_state.c create mode 100644 src/state.c create mode 100644 src/vector.c delete mode 100644 state.c create mode 100644 textures/mossy.xpm delete mode 100644 vector.c diff --git a/Makefile b/Makefile index 0f9454c..5b4222e 100644 --- a/Makefile +++ b/Makefile @@ -1,36 +1,48 @@ LIBFT_PATH = ./libft MINILIBX_PATH = ./miniLibX +SRCDIR = src +INCLUDEDIR = include +OBJDIR = obj + CC = gcc -CCFLAGS = -I$(LIBFT_PATH) -I$(MINILIBX_PATH) -I. -Wall -Wextra -g #-Werror +CCFLAGS = -I$(LIBFT_PATH) -I$(MINILIBX_PATH) -I$(INCLUDEDIR) \ + -Wall -Wextra #-Werror LDFLAGS = -L$(LIBFT_PATH) -lft \ -L$(MINILIBX_PATH) -lmlx \ -framework OpenGL -framework AppKit -lm NAME = cub3D -SRC = main.c \ - parse/parse.c \ - parse/parse_textures.c \ - parse/parse_color.c \ - parse/parse_resolution.c \ - parse/parse_check.c \ - event.c \ - state.c \ - vector.c \ - render.c \ - render_state.c \ - helper.c \ - error.c \ - capture.c -OBJ = $(SRC:.c=.o) -INCLUDE = cub3d.h - -all: libft_all minilibx_all $(NAME) +SRCFILES = main.c \ + parse/parse.c \ + parse/parse_textures.c \ + parse/parse_color.c \ + parse/parse_resolution.c \ + parse/parse_check.c \ + event.c \ + state.c \ + vector.c \ + render.c \ + render_state.c \ + helper.c \ + error.c \ + capture.c +SRC = $(addprefix $(SRCDIR)/,$(SRCFILES)) +$(info $(SRC)) +OBJ = $(SRC:$(SRCDIR)/%.c=$(OBJDIR)/%.o) +$(info $(OBJ)) +INCLUDE = $(addprefix $(INCLUDEDIR), cub3d.h) + +all: make_obj_dir libft_all minilibx_all $(NAME) + +make_obj_dir: + @if [ ! -d $(OBJDIR) ]; then mkdir $(OBJDIR); fi + @if [ ! -d $(OBJDIR)/parse ]; then mkdir $(OBJDIR)/parse; fi $(NAME): $(OBJ) - $(CC) $(LDFLAGS) -o $@ $(OBJ) + $(CC) -o $@ $(OBJ) $(LDFLAGS) -%.o: %.c $(INCLUDE) +$(OBJDIR)/%.o: $(SRCDIR)/%.c $(CC) $(CCFLAGS) -c -o $@ $< clean: libft_clean minilibx_clean diff --git a/capture.c b/capture.c deleted file mode 100644 index 521774a..0000000 --- a/capture.c +++ /dev/null @@ -1,25 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* capture.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: cacharle +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2020/01/11 13:15:11 by cacharle #+# #+# */ -/* Updated: 2020/01/16 07:49:17 by cacharle ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#include "cub3d.h" - -int capture(t_state *state) -{ - printf("capture\n"); - /* render_update_window(state); */ - /* write_bmp(&state->window); */ - return (0); -} - -void write_bmp(t_image *image) -{ -} diff --git a/cub3d.h b/cub3d.h deleted file mode 100644 index 2c5d0c3..0000000 --- a/cub3d.h +++ /dev/null @@ -1,267 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* cub3d.h :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: cacharle +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2019/11/15 06:40:37 by cacharle #+# #+# */ -/* Updated: 2020/01/30 15:05:20 by cacharle ### ########.fr */ -/* */ -/* ************************************************************************** */ -#include - -#ifndef CUB3D_H -# define CUB3D_H - -# include -# include -# include -# include -# include "mlx.h" -# include "libft.h" - -# define CUB3D_BUFFER_SIZE 64 - -# define WINDOW_TITLE "cub3D" -# define MLXK_ESC 53 -# define MLXK_W 13 -# define MLXK_A 0 -# define MLXK_S 1 -# define MLXK_D 2 -# define MLXK_LEFT 123 -# define MLXK_RIGHT 124 - -# define MLX_LITTLE_ENDIAN 0 -# define MLX_BIG_ENDIAN 1 - -# define TRUE 1 -# define FALSE 0 - -# define SQUARE(x) ((x) * (x)) - -typedef int t_bool; - -typedef struct -{ - double x; - double y; -} t_vector; - -typedef union -{ - unsigned int hexcode; - struct - { - t_byte b; - t_byte g; - t_byte r; - t_byte empty; - } rgb; -} t_color; - -typedef enum -{ - CELL_EMPTY = 0, - CELL_WALL = 1, - CELL_ITEM = 2, - CELL_LOOK_NORTH, - CELL_LOOK_SOUTH, - CELL_LOOK_WEST, - CELL_LOOK_EAST -} t_cell; - -typedef t_cell** t_map; - -enum -{ - TEX_NORTH, - TEX_SOUTH, - TEX_WEST, - TEX_EAST, - TEX_SPRITE -}; - -# define TEXTURES_NUM (TEX_SPRITE - TEX_NORTH + 1) - -typedef struct -{ - int width; - int height; - void *id; - char *data; - int depth; - int size_line; - int endian; -} t_image; - -typedef struct s_state -{ - t_bool running; - void *mlx_ptr; - void *window_ptr; - t_vector pos; - t_vector dir; - t_vector plane; - t_map map; - int map_width; - int map_height; - t_color ceilling_color; - t_color floor_color; - t_image window; - char *textures_path[TEXTURES_NUM]; - t_image textures[TEXTURES_NUM]; -} t_state; - -typedef enum -{ - SIDE_NS, - SIDE_WE -} t_side; - -typedef struct s_render_state -{ - int x; - t_vector ray; - t_vector map_pos; - t_vector delta; - t_side side; - double perp_dist; - int line_height; - t_vector probe; - t_vector map_step; - int draw_start; - int draw_end; -} t_render_state; - -typedef t_bool (*t_option_parser_func)(t_state *state, char *line); - -typedef struct s_option_parser -{ - char *id; - t_option_parser_func func; -} t_option_parser; - -/* -** parse/parse.c -*/ - -t_state *parse(char *filename); -char **get_file_lines(char *filename); -t_bool parse_line(t_state *state, char *line); -t_state *parse_map(t_state *state, char **lines); -t_cell *create_map_row(char *line); - -/* -** parse/parse_check.c -*/ - -t_state *parse_check(t_state *state); - -/* -** parse/parse_resolution.c -*/ - -t_bool parse_resolution(t_state *state, char *line); - -/* -** parse/parse_textures.c -*/ - -t_bool parse_north_texture(t_state *state, char *line); -t_bool parse_south_texture(t_state *state, char *line); -t_bool parse_west_texture(t_state *state, char *line); -t_bool parse_east_texture(t_state *state, char *line); -t_bool parse_sprite_texture(t_state *state, char *line); - -/* -** parse/parse_color.c -*/ - -t_bool parse_floor_color(t_state *state, char *line); -t_bool parse_ceilling_color(t_state *state, char *line); - -/* -** event.c -*/ - -int event_keydown(int key, t_state *state); -int event_quit(t_state *state); - -/* -** state.c -*/ - -t_state *state_new(t_state *state); -void state_init_player(t_state *state); -t_state *state_new_empty(void); -void *state_destroy(t_state *state); -void load_texture(void *mlx_ptr, t_image *image, char *path); - -/* -** render.c -*/ - -int render_update(void *param); -void render_update_window(t_state *state); -void render_column(t_state *state, int x); -void render_window_column(t_state *state, t_render_state *rstate); -void render_texture(t_state *state, t_render_state *rstate); - -/* -** vector.c -*/ - -# define VECTOR_MINUS(v) vector_scale(v, -1.0) -# define VECTOR_SUB(v, w) vector_add(v, VECTOR_MINUS(w)) -# define VECTOR_ADD_CONST(v, c) vector_add(v, vector_new(c, c)) - -t_vector vector_add(t_vector a, t_vector b); -t_vector vector_scale(t_vector v, double scalar); -t_vector vector_rotate(t_vector v, double angle); -double vector_norm(t_vector v); -t_vector vector_new(double x, double y); -t_vector vector_apply(t_vector v, double (*f)(double)); - -/* -** error.c -*/ - -void error_put_usage_exit(char *name); -void error_put(char *message); -void *error_put_return(char *message); -void *error_put_return_state_destroy(char *message, t_state *state); -void *error_put_return_lines_state_destroy( - char *message, t_state *state, char **lines); - -/* -** helper.c -*/ - -t_bool helper_is_player_cell(t_cell cell); -void helper_free_splited(char **splited); -void helper_rotate_player(t_state *state, double rotation); -void helper_init_dir_plane(t_state *state, int y, int x); -// int get_tex_x() - -/* -** render_state.c -*/ - -void rstate_ray(t_state *state, t_render_state *rstate); -void rstate_delta(t_render_state *rstate); -void rstate_init_probe(t_state *state, t_render_state *rstate); -void rstate_perp_dist(t_state *state, t_render_state *rstate); -void rstate_line_height(t_state *state, t_render_state *rstate); -void rstate_next_probe(t_render_state *rstate); -t_image *get_tex(t_state *state, t_render_state *rstate); -int get_tex_x(t_state *state, t_render_state *rstate, t_image *texture); - -/* -** capture.c -*/ - -int capture(t_state *state); -void write_bmp(t_image *image); - -#endif diff --git a/error.c b/error.c deleted file mode 100644 index eb94c9f..0000000 --- a/error.c +++ /dev/null @@ -1,48 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* error.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: cacharle +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2020/01/11 13:33:14 by cacharle #+# #+# */ -/* Updated: 2020/01/11 13:34:18 by cacharle ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#include "cub3d.h" - -void error_put_usage_exit(char *name) -{ - ft_putstr_fd(name, STDERR_FILENO); - ft_putendl_fd(": missing file operand", STDERR_FILENO); - ft_putstr_fd("Usage: ", STDERR_FILENO); - ft_putstr_fd(name, STDERR_FILENO); - ft_putendl_fd(" [.cub file] [--save]", STDERR_FILENO); - exit(EXIT_FAILURE); -} - -void error_put(char *message) -{ - ft_putstr("Error\nCouldnt "); - ft_putendl(message); -} - -void *error_put_return(char *message) -{ - error_put(message); - return (NULL); -} - -void *error_put_return_state_destroy(char *message, t_state *state) -{ - state_destroy(state); - return (error_put_return(message)); -} - -void *error_put_return_lines_state_destroy( - char *message, t_state *state, char **lines) -{ - helper_free_splited(lines); - return (error_put_return_state_destroy(message, state)); -} diff --git a/event.c b/event.c deleted file mode 100644 index 9dcaa75..0000000 --- a/event.c +++ /dev/null @@ -1,45 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* event.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: cacharle +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2019/11/15 06:39:37 by cacharle #+# #+# */ -/* Updated: 2020/01/30 15:20:18 by cacharle ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#include "cub3d.h" - -#define ROTATE_STEP (M_PI / 40.0) -#define MOVE_SPEED 0.25 - -int event_keydown(int key, t_state *state) -{ - if (key == MLXK_ESC) - state->running = FALSE; - else if (key == MLXK_A) - state->pos = vector_add(state->pos, - vector_scale(vector_rotate(state->dir, -M_PI_2), MOVE_SPEED)); - else if (key == MLXK_D) - state->pos = vector_add(state->pos, - vector_scale(vector_rotate(state->dir, M_PI_2), MOVE_SPEED)); - else if (key == MLXK_W) - state->pos = vector_add(state->pos, - vector_scale(state->dir, MOVE_SPEED)); - else if (key == MLXK_S) - state->pos = vector_add(state->pos, - vector_scale(state->dir, -MOVE_SPEED)); - else if (key == MLXK_LEFT) - helper_rotate_player(state, -ROTATE_STEP); - else if (key == MLXK_RIGHT) - helper_rotate_player(state, ROTATE_STEP); - return (0); -} - -int event_quit(t_state *state) -{ - state->running = FALSE; - return (0); -} diff --git a/helper.c b/helper.c deleted file mode 100644 index 9940848..0000000 --- a/helper.c +++ /dev/null @@ -1,60 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* helper.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: cacharle +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2020/01/11 07:32:20 by cacharle #+# #+# */ -/* Updated: 2020/01/16 08:57:01 by cacharle ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#include "cub3d.h" - -t_bool helper_is_player_cell(t_cell cell) -{ - return (cell == CELL_LOOK_NORTH || cell == CELL_LOOK_SOUTH || - cell == CELL_LOOK_WEST || cell == CELL_LOOK_EAST); -} - -void helper_free_splited(char **splited) -{ - int i; - - if (splited == NULL) - return ; - i = -1; - while (splited[++i] != NULL) - free(splited[i]); - free(splited); -} - -void helper_rotate_player(t_state *state, double rotation) -{ - state->dir = vector_rotate(state->dir, rotation); - state->plane = vector_rotate(state->plane, rotation); -} - -/* -** Initial player direction vector -** Since the map [0 0] is in the top left corner the north/south direction are slipped. -** The camera plane has to stay perpendicular to the direction and -** create a camera with a 66 degree angle (which is a recommended angle for fps) -*/ - -void helper_init_dir_plane(t_state *state, int y, int x) -{ - if (state->map[y][x] == CELL_LOOK_NORTH) - state->dir.y = -1.0; - else if (state->map[y][x] == CELL_LOOK_SOUTH) - state->dir.y = 1.0; - else if (state->map[y][x] == CELL_LOOK_WEST) - state->dir.x = -1.0; - else if (state->map[y][x] == CELL_LOOK_EAST) - state->dir.x = 1.0; - state->plane = vector_rotate(state->dir, M_PI_2); - state->plane = vector_scale(state->plane, 1.0 / vector_norm(state->plane)); - state->plane = vector_scale(state->plane, 0.66); - state->plane = vector_apply(state->plane, &fabs); -} diff --git a/include/cub3d.h b/include/cub3d.h new file mode 100644 index 0000000..2c5d0c3 --- /dev/null +++ b/include/cub3d.h @@ -0,0 +1,267 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* cub3d.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cacharle +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2019/11/15 06:40:37 by cacharle #+# #+# */ +/* Updated: 2020/01/30 15:05:20 by cacharle ### ########.fr */ +/* */ +/* ************************************************************************** */ +#include + +#ifndef CUB3D_H +# define CUB3D_H + +# include +# include +# include +# include +# include "mlx.h" +# include "libft.h" + +# define CUB3D_BUFFER_SIZE 64 + +# define WINDOW_TITLE "cub3D" +# define MLXK_ESC 53 +# define MLXK_W 13 +# define MLXK_A 0 +# define MLXK_S 1 +# define MLXK_D 2 +# define MLXK_LEFT 123 +# define MLXK_RIGHT 124 + +# define MLX_LITTLE_ENDIAN 0 +# define MLX_BIG_ENDIAN 1 + +# define TRUE 1 +# define FALSE 0 + +# define SQUARE(x) ((x) * (x)) + +typedef int t_bool; + +typedef struct +{ + double x; + double y; +} t_vector; + +typedef union +{ + unsigned int hexcode; + struct + { + t_byte b; + t_byte g; + t_byte r; + t_byte empty; + } rgb; +} t_color; + +typedef enum +{ + CELL_EMPTY = 0, + CELL_WALL = 1, + CELL_ITEM = 2, + CELL_LOOK_NORTH, + CELL_LOOK_SOUTH, + CELL_LOOK_WEST, + CELL_LOOK_EAST +} t_cell; + +typedef t_cell** t_map; + +enum +{ + TEX_NORTH, + TEX_SOUTH, + TEX_WEST, + TEX_EAST, + TEX_SPRITE +}; + +# define TEXTURES_NUM (TEX_SPRITE - TEX_NORTH + 1) + +typedef struct +{ + int width; + int height; + void *id; + char *data; + int depth; + int size_line; + int endian; +} t_image; + +typedef struct s_state +{ + t_bool running; + void *mlx_ptr; + void *window_ptr; + t_vector pos; + t_vector dir; + t_vector plane; + t_map map; + int map_width; + int map_height; + t_color ceilling_color; + t_color floor_color; + t_image window; + char *textures_path[TEXTURES_NUM]; + t_image textures[TEXTURES_NUM]; +} t_state; + +typedef enum +{ + SIDE_NS, + SIDE_WE +} t_side; + +typedef struct s_render_state +{ + int x; + t_vector ray; + t_vector map_pos; + t_vector delta; + t_side side; + double perp_dist; + int line_height; + t_vector probe; + t_vector map_step; + int draw_start; + int draw_end; +} t_render_state; + +typedef t_bool (*t_option_parser_func)(t_state *state, char *line); + +typedef struct s_option_parser +{ + char *id; + t_option_parser_func func; +} t_option_parser; + +/* +** parse/parse.c +*/ + +t_state *parse(char *filename); +char **get_file_lines(char *filename); +t_bool parse_line(t_state *state, char *line); +t_state *parse_map(t_state *state, char **lines); +t_cell *create_map_row(char *line); + +/* +** parse/parse_check.c +*/ + +t_state *parse_check(t_state *state); + +/* +** parse/parse_resolution.c +*/ + +t_bool parse_resolution(t_state *state, char *line); + +/* +** parse/parse_textures.c +*/ + +t_bool parse_north_texture(t_state *state, char *line); +t_bool parse_south_texture(t_state *state, char *line); +t_bool parse_west_texture(t_state *state, char *line); +t_bool parse_east_texture(t_state *state, char *line); +t_bool parse_sprite_texture(t_state *state, char *line); + +/* +** parse/parse_color.c +*/ + +t_bool parse_floor_color(t_state *state, char *line); +t_bool parse_ceilling_color(t_state *state, char *line); + +/* +** event.c +*/ + +int event_keydown(int key, t_state *state); +int event_quit(t_state *state); + +/* +** state.c +*/ + +t_state *state_new(t_state *state); +void state_init_player(t_state *state); +t_state *state_new_empty(void); +void *state_destroy(t_state *state); +void load_texture(void *mlx_ptr, t_image *image, char *path); + +/* +** render.c +*/ + +int render_update(void *param); +void render_update_window(t_state *state); +void render_column(t_state *state, int x); +void render_window_column(t_state *state, t_render_state *rstate); +void render_texture(t_state *state, t_render_state *rstate); + +/* +** vector.c +*/ + +# define VECTOR_MINUS(v) vector_scale(v, -1.0) +# define VECTOR_SUB(v, w) vector_add(v, VECTOR_MINUS(w)) +# define VECTOR_ADD_CONST(v, c) vector_add(v, vector_new(c, c)) + +t_vector vector_add(t_vector a, t_vector b); +t_vector vector_scale(t_vector v, double scalar); +t_vector vector_rotate(t_vector v, double angle); +double vector_norm(t_vector v); +t_vector vector_new(double x, double y); +t_vector vector_apply(t_vector v, double (*f)(double)); + +/* +** error.c +*/ + +void error_put_usage_exit(char *name); +void error_put(char *message); +void *error_put_return(char *message); +void *error_put_return_state_destroy(char *message, t_state *state); +void *error_put_return_lines_state_destroy( + char *message, t_state *state, char **lines); + +/* +** helper.c +*/ + +t_bool helper_is_player_cell(t_cell cell); +void helper_free_splited(char **splited); +void helper_rotate_player(t_state *state, double rotation); +void helper_init_dir_plane(t_state *state, int y, int x); +// int get_tex_x() + +/* +** render_state.c +*/ + +void rstate_ray(t_state *state, t_render_state *rstate); +void rstate_delta(t_render_state *rstate); +void rstate_init_probe(t_state *state, t_render_state *rstate); +void rstate_perp_dist(t_state *state, t_render_state *rstate); +void rstate_line_height(t_state *state, t_render_state *rstate); +void rstate_next_probe(t_render_state *rstate); +t_image *get_tex(t_state *state, t_render_state *rstate); +int get_tex_x(t_state *state, t_render_state *rstate, t_image *texture); + +/* +** capture.c +*/ + +int capture(t_state *state); +void write_bmp(t_image *image); + +#endif diff --git a/main.c b/main.c deleted file mode 100644 index 00a041d..0000000 --- a/main.c +++ /dev/null @@ -1,77 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* main.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: cacharle +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2019/11/15 06:39:39 by cacharle #+# #+# */ -/* Updated: 2020/01/30 14:02:58 by cacharle ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#include "cub3d.h" - -int main(int argc, char **argv) -{ - t_state *state; - - if (argc != 2 && !(argc == 3 && ft_strcmp(argv[2], "--save") == 0)) - error_put_usage_exit(argv[0]); - if ((state = state_new(parse_check(parse(argv[1])))) == NULL) - return (1); - if (argc == 3) - return (capture(state)); - /* printf("%d\n", state->window.size_line); */ - mlx_hook(state->window_ptr, 2, (1L << 1), event_keydown, (void*)state); - mlx_hook(state->window_ptr, 17L, 0, event_quit, (void*)state); - mlx_loop_hook(state->mlx_ptr, render_update, (void*)state); - mlx_loop(state->mlx_ptr); - /* while (1) */ - /* render_update(state); */ - return (0); -} - -/* -int main(int argc, char **argv) -{ - (void)argc; - t_state *s = parse_check(parse(argv[1])); - if (s == NULL) - return (1); - printf("R %d %d\n", s->window.width, s->window.height); - printf("NO %s\n", s->textures_path[TEX_NORTH]); - printf("SO %s\n", s->textures_path[TEX_SOUTH]); - printf("WE %s\n", s->textures_path[TEX_WEST]); - printf("EA %s\n\n", s->textures_path[TEX_EAST]); - printf("S %s\n", s->textures_path[TEX_SPRITE]); - printf("F %d,%d,%d\n", s->floor_color.rgb.r, s->floor_color.rgb.g, s->floor_color.rgb.b); - printf("C %d,%d,%d\n\n", s->ceilling_color.rgb.r, s->ceilling_color.rgb.g, s->ceilling_color.rgb.b); - - printf("%dx%d\n", s->map_height, s->map_width); - for (int i = 0; i < s->map_height; i++) - { - for (int j = 0; j < s->map_width; j++) - { - if (s->map[i][j] == CELL_WALL) - printf("#"); - else if (s->map[i][j] == CELL_EMPTY) - printf(" "); - else - printf("%d", s->map[i][j]); - if (j != s->map_width - 1) - printf(" "); - } - printf("\n"); - } - printf("post state_new\n"); - if ((s = state_new(s)) == NULL) - { - printf("Error: state new"); - return 1; - } - printf("state->pos [%f %f]\n", s->pos.x, s->pos.y); - state_destroy(s); - return 0; -} -*/ diff --git a/minimalist.cub b/minimalist.cub index 9974bb2..a1d6433 100644 --- a/minimalist.cub +++ b/minimalist.cub @@ -1,7 +1,7 @@ R 700 500 -NO ./textures/brick.xpm +NO ./textures/wood.xpm SO ./textures/wood.xpm -WE ./textures/wood.xpm +WE ./textures/brick.xpm EA ./textures/stone.xpm S ./textures/brick.xpm diff --git a/parse/parse.c b/parse/parse.c deleted file mode 100644 index f4b5b66..0000000 --- a/parse/parse.c +++ /dev/null @@ -1,142 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* parse.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: cacharle +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2019/11/15 09:29:21 by cacharle #+# #+# */ -/* Updated: 2020/01/30 12:03:54 by cacharle ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#include "cub3d.h" - -t_state *parse(char *filename) -{ - int i; - char **lines; - t_state *state; - - if ((state = state_new_empty()) == NULL) - return (error_put_return("create empty state")); - if ((lines = get_file_lines(filename)) == NULL) - return (error_put_return_state_destroy("read .cub file", state)); - i = -1; - while (lines[++i] != NULL) - { - if (*lines[i] == '1') - break ; - if (!parse_line(state, lines[i])) - return (error_put_return_lines_state_destroy( - "parse configuration", state, lines)); - } - if ((state = parse_map(state, lines + i)) == NULL) - return (error_put_return_lines_state_destroy( - "parse map", state, lines)); - helper_free_splited(lines); - return (state); -} - -char **get_file_lines(char *filename) -{ - int fd; - int ret; - char buf[CUB3D_BUFFER_SIZE + 1]; - char *file; - - if ((fd = open(filename, O_RDONLY)) < 0) - return (NULL); - if ((file = ft_strdup("")) == NULL) - return (NULL); - while ((ret = read(fd, buf, CUB3D_BUFFER_SIZE)) > 0) - { - buf[ret] = '\0'; - if ((file = ft_strjoin(file, buf)) == NULL) - return (NULL); - } - if (ret == -1) - return (NULL); - close(fd); - return (ft_split(file, '\n')); -} - -static t_option_parser g_option_parsers[] = -{ - {"R", parse_resolution}, - {"NO", parse_north_texture}, - {"SO", parse_south_texture}, - {"WE", parse_west_texture}, - {"EA", parse_east_texture}, - {"S", parse_sprite_texture}, - {"F", parse_floor_color}, - {"C", parse_ceilling_color} -}; - -#define OPTIONS_PARSERS_SIZE (sizeof(g_option_parsers) / sizeof(t_option_parser)) - -t_bool parse_line(t_state *state, char *line) -{ - int i; - - if (!*line) - return (TRUE); - i = -1; - while (++i < (int)OPTIONS_PARSERS_SIZE) - if (ft_strncmp(g_option_parsers[i].id, line, - ft_strlen(g_option_parsers[i].id)) == 0) - return (g_option_parsers[i].func( - state, line + ft_strlen(g_option_parsers[i].id) + 1)); - return (FALSE); -} - -t_state *parse_map(t_state *state, char **lines) -{ - int i; - - i = -1; - while (lines[++i] != NULL) - if (*lines[i] != '1') - return (NULL); - state->map_height = i; - if ((state->map = (t_map)malloc(sizeof(t_cell*) * i)) == NULL) - return (NULL); - state->map_width = ft_strcount(*lines, '1'); - i = -1; - while (lines[++i] != NULL) - if ((state->map[i] = create_map_row(lines[i])) == NULL) - return (NULL); - return (state); -} - -t_cell *create_map_row(char *line) -{ - int i; - t_cell *row; - - if ((row = (t_cell*)malloc(sizeof(t_cell) * ft_strlen(line))) == NULL) - return (NULL); - i = 0; - while (*line) - { - if (*line == '0' || *line == '1' || *line == '2') - row[i++] = *line - '0'; - else if (*line == 'N') - row[i++] = CELL_LOOK_NORTH; - else if (*line == 'S') - row[i++] = CELL_LOOK_SOUTH; - else if (*line == 'W') - row[i++] = CELL_LOOK_WEST; - else if (*line == 'E') - row[i++] = CELL_LOOK_EAST; - else - { - free(row); - return (NULL); - } - line++; - while (*line == ' ') - line++; - } - return (row); -} diff --git a/parse/parse_check.c b/parse/parse_check.c deleted file mode 100644 index a65d74a..0000000 --- a/parse/parse_check.c +++ /dev/null @@ -1,46 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* check.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: cacharle +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2020/01/11 10:59:15 by cacharle #+# #+# */ -/* Updated: 2020/01/11 13:03:33 by cacharle ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#include "cub3d.h" - -t_state *parse_check(t_state *state) -{ - int i; - /* int j; */ - /* int player_count; */ - - i = -1; - while (++i < state->map_width) - if (state->map[0][i] != CELL_WALL - || state->map[state->map_height - 1][i] != CELL_WALL) - return (error_put_return_state_destroy( - "validate map without borders", state)); - i = -1; - while (++i < state->map_height) - if (state->map[i][0] != CELL_WALL - || state->map[i][state->map_width - 1] != CELL_WALL) - return (error_put_return_state_destroy( - "validate map without borders", state)); - // maybe not necessary - /* player_count = 0; */ - /* i = -1; */ - /* while (++i < state->map_height) */ - /* { */ - /* j = -1; */ - /* while (++j < state->map_width) */ - /* if (helper_is_player_cell(state->map[i][j])) */ - /* player_count++; */ - /* } */ - /* if (player_count != 1) */ - /* return (state_destroy(state)); */ - return (state); -} diff --git a/parse/parse_color.c b/parse/parse_color.c deleted file mode 100644 index fd482e5..0000000 --- a/parse/parse_color.c +++ /dev/null @@ -1,55 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* parse_color.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: cacharle +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2020/01/11 09:52:34 by cacharle #+# #+# */ -/* Updated: 2020/01/30 14:17:37 by cacharle ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#include "cub3d.h" - -t_bool parse_ceilling_color(t_state *state, char *line) -{ - int tmp; - - state->ceilling_color.hexcode = 0x0; - if ((tmp = ft_atoi(line)) > 255 || tmp < 0) // cant do atoi due to overflow stuff, use ft_strtol - return (FALSE); - state->ceilling_color.rgb.r = (t_byte)tmp; - if ((line = ft_strchr(line, ',') + 1) == NULL) - return (FALSE); - if ((tmp = ft_atoi(line)) > 255 || tmp < 0) - return (FALSE); - state->ceilling_color.rgb.g = (t_byte)tmp; - if ((line = ft_strchr(line, ',') + 1) == NULL) - return (FALSE); - if ((tmp = ft_atoi(line)) > 255 || tmp < 0) - return (FALSE); - state->ceilling_color.rgb.b = (t_byte)tmp; - return (TRUE); -} - -t_bool parse_floor_color(t_state *state, char *line) -{ - int tmp; - - state->floor_color.hexcode = 0x0; - if ((tmp = ft_atoi(line)) > 255 || tmp < 0) - return (FALSE); - state->floor_color.rgb.r = (t_byte)tmp; - if ((line = ft_strchr(line, ',') + 1) == NULL) - return (FALSE); - if ((tmp = ft_atoi(line)) > 255 || tmp < 0) - return (FALSE); - state->floor_color.rgb.g = (t_byte)tmp; - if ((line = ft_strchr(line, ',') + 1) == NULL) - return (FALSE); - if ((tmp = ft_atoi(line)) > 255 || tmp < 0) - return (FALSE); - state->floor_color.rgb.b = (t_byte)tmp; - return (TRUE); -} diff --git a/parse/parse_resolution.c b/parse/parse_resolution.c deleted file mode 100644 index d6c5759..0000000 --- a/parse/parse_resolution.c +++ /dev/null @@ -1,24 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* parse_resolution.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: cacharle +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2019/11/15 09:29:27 by cacharle #+# #+# */ -/* Updated: 2020/01/11 09:44:18 by cacharle ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#include "cub3d.h" - -t_bool parse_resolution(t_state *state, char *line) -{ - if ((state->window.width = ft_atoi(line)) < 0) - return (FALSE); - if ((line = ft_strrchr(line, ' ') + 1) == NULL) - return (FALSE); - if ((state->window.height = ft_atoi(line)) < 0) - return (FALSE); - return (TRUE); -} diff --git a/parse/parse_textures.c b/parse/parse_textures.c deleted file mode 100644 index a0fb8f6..0000000 --- a/parse/parse_textures.c +++ /dev/null @@ -1,48 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* parse_textures.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: cacharle +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2020/01/11 09:47:53 by cacharle #+# #+# */ -/* Updated: 2020/01/11 09:51:03 by cacharle ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#include "cub3d.h" - -t_bool parse_north_texture(t_state *state, char *line) -{ - if ((state->textures_path[TEX_NORTH] = ft_strdup(line)) == NULL) - return (FALSE); - return (TRUE); -} - -t_bool parse_south_texture(t_state *state, char *line) -{ - if ((state->textures_path[TEX_SOUTH] = ft_strdup(line)) == NULL) - return (FALSE); - return (TRUE); -} - -t_bool parse_west_texture(t_state *state, char *line) -{ - if ((state->textures_path[TEX_WEST] = ft_strdup(line)) == NULL) - return (FALSE); - return (TRUE); -} - -t_bool parse_east_texture(t_state *state, char *line) -{ - if ((state->textures_path[TEX_EAST] = ft_strdup(line)) == NULL) - return (FALSE); - return (TRUE); -} - -t_bool parse_sprite_texture(t_state *state, char *line) -{ - if ((state->textures_path[TEX_SPRITE] = ft_strdup(line)) == NULL) - return (FALSE); - return (TRUE); -} diff --git a/render.c b/render.c deleted file mode 100644 index 88b0cae..0000000 --- a/render.c +++ /dev/null @@ -1,107 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* render.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: cacharle +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2020/01/11 13:37:17 by cacharle #+# #+# */ -/* Updated: 2020/01/30 15:17:49 by cacharle ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#include "cub3d.h" - -int render_update(void *param) -{ - t_state *state; - - state = param; - if (!state->running) - { - state_destroy(state); - exit(EXIT_SUCCESS); - return (0); - } - render_update_window(state); - mlx_put_image_to_window(state->mlx_ptr, state->window_ptr, state->window.id, 0, 0); - return (0); -} - -void render_update_window(t_state *state) -{ - int x; - - x = -1; - while (++x < state->window.width) - render_column(state, x); -} - -void render_column(t_state *state, int x) -{ - t_render_state rstate; - - rstate.x = x; - rstate_ray(state, &rstate); - rstate.map_pos = vector_new((double)((int)state->pos.x), (double)((int)state->pos.y)); //floor? - rstate_delta(&rstate); - rstate_init_probe(state, &rstate); - rstate.map_step = vector_new(rstate.ray.x < 0.0 ? -1.0 : 1.0, rstate.ray.y < 0.0 ? -1.0 : 1.0); - while (TRUE) - { - rstate.side = rstate.probe.x < rstate.probe.y ? SIDE_WE : SIDE_NS; - rstate_next_probe(&rstate); - if (state->map[(int)rstate.map_pos.y][(int)rstate.map_pos.x] == CELL_WALL) - break ; - } - rstate_perp_dist(state, &rstate); - rstate_line_height(state, &rstate); - rstate.draw_start = state->window.height / 2 - rstate.line_height / 2; - rstate.draw_end = state->window.height / 2 + rstate.line_height / 2; - if (rstate.draw_start < 0) - rstate.draw_start = 0; - if (rstate.draw_end > state->window.height - 1) - rstate.draw_end = state->window.height - 1; - render_window_column(state, &rstate); -} - -void render_window_column(t_state *state, t_render_state *rstate) -{ - int i; - t_color white; - - white.hexcode = 0x00ffffff; - i = 0; - while (i < rstate->draw_start) - ((t_color*)state->window.data)[i++ * state->window.width + rstate->x] = state->ceilling_color; - while (i < rstate->draw_end) - ((t_color*)state->window.data)[i++ * state->window.width + rstate->x] = white; - render_texture(state, rstate); - i = rstate->draw_end; - while (i < state->window.height) - ((t_color*)state->window.data)[i++ * state->window.width + rstate->x] = state->floor_color; - -} - -void render_texture(t_state *state, t_render_state *rstate) -{ - int i; - double step; - double tex_pos; - int tex_y; - int tex_x; - t_image *texture; - - texture = get_tex(state, rstate); - tex_x = get_tex_x(state, rstate, texture); - step = 1.0 * texture->height / rstate->line_height; - tex_pos = (rstate->draw_start - state->window.height / 2 + rstate->line_height / 2) * step; - i = rstate->draw_start - 1; - while (++i < rstate->draw_end) - { - tex_y = (int)tex_pos & (texture->height - 1); - tex_pos += step; - ((t_color*)state->window.data)[i * state->window.width + rstate->x] = - ((t_color*)texture->data)[texture->height * tex_y + tex_x]; - } -} diff --git a/render_state.c b/render_state.c deleted file mode 100644 index 5fcc6ed..0000000 --- a/render_state.c +++ /dev/null @@ -1,205 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* render_state.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: cacharle +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2020/01/15 14:40:14 by cacharle #+# #+# */ -/* Updated: 2020/01/30 15:14:39 by cacharle ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#include "cub3d.h" - -/* -** -1 0 1 <-- camera_x -** v v v -** ################ -** # | # <-- screen -** # | # -** ################ -** -** camera_x is the x column from the camera percpective -** scaling the plane vector and adding it to the direction vector -** to create a vector in the *direction* of the column x. -*/ - -void rstate_ray(t_state *state, t_render_state *rstate) -{ - double camera_x; - - camera_x = 2.0 * (double)rstate->x / (double)state->window.width - 1.0; - rstate->ray = vector_add(state->dir, vector_scale(state->plane, camera_x)); -} - -/* -** delta between each grid unit form the vector percpective -** -** if we have a vector v = [2 3]: -** dx = |v| / v_1 -** = sqrt(v_1^2 + v_2^2) / v_1 -** = (v_1^2 + v_2^2) / v_1^2 -** = 1 + v_2^2 / v_1^2 -** Same thing for dy -** dy = |v| / v_2 -** = sqrt(v_1^2 + v_2^2) / v_1 -** = (v_1^2 + v_2^2) / v_2^2 -** = v_1^2 / v_2^2 + 1 -** -** This can be simplified (for some obscure reason): -** dx = |1 / v_1| -** dy = |1 / v_2| -*/ - -void rstate_delta(t_render_state *rstate) -{ - rstate->delta.x = fabs(1 / rstate->ray.x); //vector_norm(rstate->ray) / rstate->ray.x; - rstate->delta.y = fabs(1 / rstate->ray.y); // vector_norm(rstate->ray) / rstate->ray.y; -} - -/* -** first delta between player position and first grid unit -** -** current x and y are the perpendicular distance to the nearest wall, -** we multiply them by their corresponding delta. -** 0 <= perpendicular distance <= 1 is a ratio, how much of the full delta we need to take. -** -** if (rstate->ray.x < 0) -** rstate->probe.x = state->pos.x - rstate->map_pos.x; -** else -** rstate->probe.x = fabs(state->pos.x - rstate->map_pos.x + 1.0); -** if (rstate->ray.y < 0) -** rstate->probe.y = state->pos.y - rstate->map_pos.y; -** else -** rstate->probe.y = fabs(state->pos.y - rstate->map_pos.y + 1.0); -** rstate->probe.x *= rstate->delta.x; -** rstate->probe.y *= rstate->delta.y; -*/ - -void rstate_init_probe(t_state *state, t_render_state *rstate) -{ - if (rstate->ray.x < 0) - rstate->probe.x = (state->pos.x - rstate->map_pos.x) * rstate->delta.x; - else - rstate->probe.x = (rstate->map_pos.x + 1.0 - state->pos.x) * rstate->delta.x; - if (rstate->ray.y < 0) - rstate->probe.y = (state->pos.y - rstate->map_pos.y) * rstate->delta.y; - else - rstate->probe.y = (rstate->map_pos.y + 1.0 - state->pos.y) * rstate->delta.y; - /* rstate->probe = VECTOR_SUB(state->pos, rstate->map_pos); */ - /* if (rstate->ray.x > 0) */ - /* rstate->probe.x += 1.0; */ - /* if (rstate->ray.y > 0) */ - /* rstate->probe.y += 1.0; */ - /* rstate->probe.x *= rstate->delta.x; */ - /* rstate->probe.y *= rstate->delta.y; */ -} - -/* -** Move the probe to it's next iteration by advancing to the nearest square unit -** in the x or y direction. -** This advance is represented both with the -** player/ray percpective and the map pecpective. -*/ - -void rstate_next_probe(t_render_state *rstate) -{ - if (rstate->probe.x < rstate->probe.y) - { - rstate->probe.x += rstate->delta.x; - rstate->map_pos.x += rstate->map_step.x; - } - else - { - rstate->probe.y += rstate->delta.y; - rstate->map_pos.y += rstate->map_step.y; - } -} - -/* -** perpendicular distance between the wall hit and the camera plane. -** We don't use euclidean distance because it would cause a fisheye effect. -** -** ====================X========== wall -** | /| -** | <------ / | -----+ -** | / | | -** plane | / | <- perpendicular distance -** | | / | -** v | / | -** <-------^----/----------------- camera plane -** | / -** dir -> | / -** | / <- euclidean distance -** |/ -** x <- pos -** -** In this case the perpendicular distance (p) is the difference -** of the y-coord of the hit point and the y-coord of the pos + dir vector. -** We use the y component because we hit the wall -** from a south/north percepective, -** if we had hit it form west/east, we would use the x component instead. -*/ - -void rstate_perp_dist(t_state *state, t_render_state *rstate) -{ - if (rstate->side == SIDE_WE) - rstate->perp_dist = (rstate->map_pos.x - state->pos.x + (1 - rstate->map_step.x) / 2) / rstate->ray.x; - else - rstate->perp_dist = (rstate->map_pos.y - state->pos.y + (1 - rstate->map_step.y) / 2) / rstate->ray.y; -} - -/* -** 0 <= 1 / perp_dist <= 1 -** height * (1 / perp_dist) is how much of the screen height do we take -*/ - -void rstate_line_height(t_state *state, t_render_state *rstate) -{ - rstate->line_height = (int)((double)state->window.height / rstate->perp_dist); -} - -t_image *get_tex(t_state *state, t_render_state *rstate) -{ - if (rstate->side == SIDE_NS) - { - if (rstate->probe.y < state->pos.y) - return (state->textures + TEX_NORTH); - else - return (state->textures + TEX_SOUTH); - } - else if (rstate->side == SIDE_WE) - { - if (rstate->probe.x < state->pos.x) - return (state->textures + TEX_WEST); - else - return (state->textures + TEX_EAST); - } - return (NULL); -} - -/* -** Since we're drawing each column, all the texels we want to draw on the window -** are on a single column of the texture. -** First we find the x-coord relative to the wall we hit -*/ - -int get_tex_x(t_state *state, t_render_state *rstate, t_image *texture) -{ - int tex_x; - double wall_x; - - if (rstate->side == SIDE_WE) - wall_x = state->pos.y + rstate->perp_dist * rstate->ray.y; - else - wall_x = state->pos.x + rstate->perp_dist * rstate->ray.x; - wall_x -= floor(wall_x); - - tex_x = (int)(wall_x * (double)texture->width); - if (rstate->side == 0 && rstate->ray.x > 0) - tex_x = texture->width - tex_x - 1; - if (rstate->side == 1 && rstate->ray.y < 0) - tex_x = texture->width - tex_x - 1; - return (tex_x); -} diff --git a/src/capture.c b/src/capture.c new file mode 100644 index 0000000..521774a --- /dev/null +++ b/src/capture.c @@ -0,0 +1,25 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* capture.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cacharle +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2020/01/11 13:15:11 by cacharle #+# #+# */ +/* Updated: 2020/01/16 07:49:17 by cacharle ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "cub3d.h" + +int capture(t_state *state) +{ + printf("capture\n"); + /* render_update_window(state); */ + /* write_bmp(&state->window); */ + return (0); +} + +void write_bmp(t_image *image) +{ +} diff --git a/src/error.c b/src/error.c new file mode 100644 index 0000000..eb94c9f --- /dev/null +++ b/src/error.c @@ -0,0 +1,48 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* error.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cacharle +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2020/01/11 13:33:14 by cacharle #+# #+# */ +/* Updated: 2020/01/11 13:34:18 by cacharle ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "cub3d.h" + +void error_put_usage_exit(char *name) +{ + ft_putstr_fd(name, STDERR_FILENO); + ft_putendl_fd(": missing file operand", STDERR_FILENO); + ft_putstr_fd("Usage: ", STDERR_FILENO); + ft_putstr_fd(name, STDERR_FILENO); + ft_putendl_fd(" [.cub file] [--save]", STDERR_FILENO); + exit(EXIT_FAILURE); +} + +void error_put(char *message) +{ + ft_putstr("Error\nCouldnt "); + ft_putendl(message); +} + +void *error_put_return(char *message) +{ + error_put(message); + return (NULL); +} + +void *error_put_return_state_destroy(char *message, t_state *state) +{ + state_destroy(state); + return (error_put_return(message)); +} + +void *error_put_return_lines_state_destroy( + char *message, t_state *state, char **lines) +{ + helper_free_splited(lines); + return (error_put_return_state_destroy(message, state)); +} diff --git a/src/event.c b/src/event.c new file mode 100644 index 0000000..9dcaa75 --- /dev/null +++ b/src/event.c @@ -0,0 +1,45 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* event.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cacharle +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2019/11/15 06:39:37 by cacharle #+# #+# */ +/* Updated: 2020/01/30 15:20:18 by cacharle ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "cub3d.h" + +#define ROTATE_STEP (M_PI / 40.0) +#define MOVE_SPEED 0.25 + +int event_keydown(int key, t_state *state) +{ + if (key == MLXK_ESC) + state->running = FALSE; + else if (key == MLXK_A) + state->pos = vector_add(state->pos, + vector_scale(vector_rotate(state->dir, -M_PI_2), MOVE_SPEED)); + else if (key == MLXK_D) + state->pos = vector_add(state->pos, + vector_scale(vector_rotate(state->dir, M_PI_2), MOVE_SPEED)); + else if (key == MLXK_W) + state->pos = vector_add(state->pos, + vector_scale(state->dir, MOVE_SPEED)); + else if (key == MLXK_S) + state->pos = vector_add(state->pos, + vector_scale(state->dir, -MOVE_SPEED)); + else if (key == MLXK_LEFT) + helper_rotate_player(state, -ROTATE_STEP); + else if (key == MLXK_RIGHT) + helper_rotate_player(state, ROTATE_STEP); + return (0); +} + +int event_quit(t_state *state) +{ + state->running = FALSE; + return (0); +} diff --git a/src/helper.c b/src/helper.c new file mode 100644 index 0000000..9940848 --- /dev/null +++ b/src/helper.c @@ -0,0 +1,60 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* helper.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cacharle +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2020/01/11 07:32:20 by cacharle #+# #+# */ +/* Updated: 2020/01/16 08:57:01 by cacharle ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "cub3d.h" + +t_bool helper_is_player_cell(t_cell cell) +{ + return (cell == CELL_LOOK_NORTH || cell == CELL_LOOK_SOUTH || + cell == CELL_LOOK_WEST || cell == CELL_LOOK_EAST); +} + +void helper_free_splited(char **splited) +{ + int i; + + if (splited == NULL) + return ; + i = -1; + while (splited[++i] != NULL) + free(splited[i]); + free(splited); +} + +void helper_rotate_player(t_state *state, double rotation) +{ + state->dir = vector_rotate(state->dir, rotation); + state->plane = vector_rotate(state->plane, rotation); +} + +/* +** Initial player direction vector +** Since the map [0 0] is in the top left corner the north/south direction are slipped. +** The camera plane has to stay perpendicular to the direction and +** create a camera with a 66 degree angle (which is a recommended angle for fps) +*/ + +void helper_init_dir_plane(t_state *state, int y, int x) +{ + if (state->map[y][x] == CELL_LOOK_NORTH) + state->dir.y = -1.0; + else if (state->map[y][x] == CELL_LOOK_SOUTH) + state->dir.y = 1.0; + else if (state->map[y][x] == CELL_LOOK_WEST) + state->dir.x = -1.0; + else if (state->map[y][x] == CELL_LOOK_EAST) + state->dir.x = 1.0; + state->plane = vector_rotate(state->dir, M_PI_2); + state->plane = vector_scale(state->plane, 1.0 / vector_norm(state->plane)); + state->plane = vector_scale(state->plane, 0.66); + state->plane = vector_apply(state->plane, &fabs); +} diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..00a041d --- /dev/null +++ b/src/main.c @@ -0,0 +1,77 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* main.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cacharle +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2019/11/15 06:39:39 by cacharle #+# #+# */ +/* Updated: 2020/01/30 14:02:58 by cacharle ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "cub3d.h" + +int main(int argc, char **argv) +{ + t_state *state; + + if (argc != 2 && !(argc == 3 && ft_strcmp(argv[2], "--save") == 0)) + error_put_usage_exit(argv[0]); + if ((state = state_new(parse_check(parse(argv[1])))) == NULL) + return (1); + if (argc == 3) + return (capture(state)); + /* printf("%d\n", state->window.size_line); */ + mlx_hook(state->window_ptr, 2, (1L << 1), event_keydown, (void*)state); + mlx_hook(state->window_ptr, 17L, 0, event_quit, (void*)state); + mlx_loop_hook(state->mlx_ptr, render_update, (void*)state); + mlx_loop(state->mlx_ptr); + /* while (1) */ + /* render_update(state); */ + return (0); +} + +/* +int main(int argc, char **argv) +{ + (void)argc; + t_state *s = parse_check(parse(argv[1])); + if (s == NULL) + return (1); + printf("R %d %d\n", s->window.width, s->window.height); + printf("NO %s\n", s->textures_path[TEX_NORTH]); + printf("SO %s\n", s->textures_path[TEX_SOUTH]); + printf("WE %s\n", s->textures_path[TEX_WEST]); + printf("EA %s\n\n", s->textures_path[TEX_EAST]); + printf("S %s\n", s->textures_path[TEX_SPRITE]); + printf("F %d,%d,%d\n", s->floor_color.rgb.r, s->floor_color.rgb.g, s->floor_color.rgb.b); + printf("C %d,%d,%d\n\n", s->ceilling_color.rgb.r, s->ceilling_color.rgb.g, s->ceilling_color.rgb.b); + + printf("%dx%d\n", s->map_height, s->map_width); + for (int i = 0; i < s->map_height; i++) + { + for (int j = 0; j < s->map_width; j++) + { + if (s->map[i][j] == CELL_WALL) + printf("#"); + else if (s->map[i][j] == CELL_EMPTY) + printf(" "); + else + printf("%d", s->map[i][j]); + if (j != s->map_width - 1) + printf(" "); + } + printf("\n"); + } + printf("post state_new\n"); + if ((s = state_new(s)) == NULL) + { + printf("Error: state new"); + return 1; + } + printf("state->pos [%f %f]\n", s->pos.x, s->pos.y); + state_destroy(s); + return 0; +} +*/ diff --git a/src/parse/parse.c b/src/parse/parse.c new file mode 100644 index 0000000..f4b5b66 --- /dev/null +++ b/src/parse/parse.c @@ -0,0 +1,142 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* parse.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cacharle +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2019/11/15 09:29:21 by cacharle #+# #+# */ +/* Updated: 2020/01/30 12:03:54 by cacharle ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "cub3d.h" + +t_state *parse(char *filename) +{ + int i; + char **lines; + t_state *state; + + if ((state = state_new_empty()) == NULL) + return (error_put_return("create empty state")); + if ((lines = get_file_lines(filename)) == NULL) + return (error_put_return_state_destroy("read .cub file", state)); + i = -1; + while (lines[++i] != NULL) + { + if (*lines[i] == '1') + break ; + if (!parse_line(state, lines[i])) + return (error_put_return_lines_state_destroy( + "parse configuration", state, lines)); + } + if ((state = parse_map(state, lines + i)) == NULL) + return (error_put_return_lines_state_destroy( + "parse map", state, lines)); + helper_free_splited(lines); + return (state); +} + +char **get_file_lines(char *filename) +{ + int fd; + int ret; + char buf[CUB3D_BUFFER_SIZE + 1]; + char *file; + + if ((fd = open(filename, O_RDONLY)) < 0) + return (NULL); + if ((file = ft_strdup("")) == NULL) + return (NULL); + while ((ret = read(fd, buf, CUB3D_BUFFER_SIZE)) > 0) + { + buf[ret] = '\0'; + if ((file = ft_strjoin(file, buf)) == NULL) + return (NULL); + } + if (ret == -1) + return (NULL); + close(fd); + return (ft_split(file, '\n')); +} + +static t_option_parser g_option_parsers[] = +{ + {"R", parse_resolution}, + {"NO", parse_north_texture}, + {"SO", parse_south_texture}, + {"WE", parse_west_texture}, + {"EA", parse_east_texture}, + {"S", parse_sprite_texture}, + {"F", parse_floor_color}, + {"C", parse_ceilling_color} +}; + +#define OPTIONS_PARSERS_SIZE (sizeof(g_option_parsers) / sizeof(t_option_parser)) + +t_bool parse_line(t_state *state, char *line) +{ + int i; + + if (!*line) + return (TRUE); + i = -1; + while (++i < (int)OPTIONS_PARSERS_SIZE) + if (ft_strncmp(g_option_parsers[i].id, line, + ft_strlen(g_option_parsers[i].id)) == 0) + return (g_option_parsers[i].func( + state, line + ft_strlen(g_option_parsers[i].id) + 1)); + return (FALSE); +} + +t_state *parse_map(t_state *state, char **lines) +{ + int i; + + i = -1; + while (lines[++i] != NULL) + if (*lines[i] != '1') + return (NULL); + state->map_height = i; + if ((state->map = (t_map)malloc(sizeof(t_cell*) * i)) == NULL) + return (NULL); + state->map_width = ft_strcount(*lines, '1'); + i = -1; + while (lines[++i] != NULL) + if ((state->map[i] = create_map_row(lines[i])) == NULL) + return (NULL); + return (state); +} + +t_cell *create_map_row(char *line) +{ + int i; + t_cell *row; + + if ((row = (t_cell*)malloc(sizeof(t_cell) * ft_strlen(line))) == NULL) + return (NULL); + i = 0; + while (*line) + { + if (*line == '0' || *line == '1' || *line == '2') + row[i++] = *line - '0'; + else if (*line == 'N') + row[i++] = CELL_LOOK_NORTH; + else if (*line == 'S') + row[i++] = CELL_LOOK_SOUTH; + else if (*line == 'W') + row[i++] = CELL_LOOK_WEST; + else if (*line == 'E') + row[i++] = CELL_LOOK_EAST; + else + { + free(row); + return (NULL); + } + line++; + while (*line == ' ') + line++; + } + return (row); +} diff --git a/src/parse/parse_check.c b/src/parse/parse_check.c new file mode 100644 index 0000000..a65d74a --- /dev/null +++ b/src/parse/parse_check.c @@ -0,0 +1,46 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* check.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cacharle +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2020/01/11 10:59:15 by cacharle #+# #+# */ +/* Updated: 2020/01/11 13:03:33 by cacharle ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "cub3d.h" + +t_state *parse_check(t_state *state) +{ + int i; + /* int j; */ + /* int player_count; */ + + i = -1; + while (++i < state->map_width) + if (state->map[0][i] != CELL_WALL + || state->map[state->map_height - 1][i] != CELL_WALL) + return (error_put_return_state_destroy( + "validate map without borders", state)); + i = -1; + while (++i < state->map_height) + if (state->map[i][0] != CELL_WALL + || state->map[i][state->map_width - 1] != CELL_WALL) + return (error_put_return_state_destroy( + "validate map without borders", state)); + // maybe not necessary + /* player_count = 0; */ + /* i = -1; */ + /* while (++i < state->map_height) */ + /* { */ + /* j = -1; */ + /* while (++j < state->map_width) */ + /* if (helper_is_player_cell(state->map[i][j])) */ + /* player_count++; */ + /* } */ + /* if (player_count != 1) */ + /* return (state_destroy(state)); */ + return (state); +} diff --git a/src/parse/parse_color.c b/src/parse/parse_color.c new file mode 100644 index 0000000..fd482e5 --- /dev/null +++ b/src/parse/parse_color.c @@ -0,0 +1,55 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* parse_color.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cacharle +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2020/01/11 09:52:34 by cacharle #+# #+# */ +/* Updated: 2020/01/30 14:17:37 by cacharle ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "cub3d.h" + +t_bool parse_ceilling_color(t_state *state, char *line) +{ + int tmp; + + state->ceilling_color.hexcode = 0x0; + if ((tmp = ft_atoi(line)) > 255 || tmp < 0) // cant do atoi due to overflow stuff, use ft_strtol + return (FALSE); + state->ceilling_color.rgb.r = (t_byte)tmp; + if ((line = ft_strchr(line, ',') + 1) == NULL) + return (FALSE); + if ((tmp = ft_atoi(line)) > 255 || tmp < 0) + return (FALSE); + state->ceilling_color.rgb.g = (t_byte)tmp; + if ((line = ft_strchr(line, ',') + 1) == NULL) + return (FALSE); + if ((tmp = ft_atoi(line)) > 255 || tmp < 0) + return (FALSE); + state->ceilling_color.rgb.b = (t_byte)tmp; + return (TRUE); +} + +t_bool parse_floor_color(t_state *state, char *line) +{ + int tmp; + + state->floor_color.hexcode = 0x0; + if ((tmp = ft_atoi(line)) > 255 || tmp < 0) + return (FALSE); + state->floor_color.rgb.r = (t_byte)tmp; + if ((line = ft_strchr(line, ',') + 1) == NULL) + return (FALSE); + if ((tmp = ft_atoi(line)) > 255 || tmp < 0) + return (FALSE); + state->floor_color.rgb.g = (t_byte)tmp; + if ((line = ft_strchr(line, ',') + 1) == NULL) + return (FALSE); + if ((tmp = ft_atoi(line)) > 255 || tmp < 0) + return (FALSE); + state->floor_color.rgb.b = (t_byte)tmp; + return (TRUE); +} diff --git a/src/parse/parse_resolution.c b/src/parse/parse_resolution.c new file mode 100644 index 0000000..d6c5759 --- /dev/null +++ b/src/parse/parse_resolution.c @@ -0,0 +1,24 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* parse_resolution.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cacharle +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2019/11/15 09:29:27 by cacharle #+# #+# */ +/* Updated: 2020/01/11 09:44:18 by cacharle ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "cub3d.h" + +t_bool parse_resolution(t_state *state, char *line) +{ + if ((state->window.width = ft_atoi(line)) < 0) + return (FALSE); + if ((line = ft_strrchr(line, ' ') + 1) == NULL) + return (FALSE); + if ((state->window.height = ft_atoi(line)) < 0) + return (FALSE); + return (TRUE); +} diff --git a/src/parse/parse_textures.c b/src/parse/parse_textures.c new file mode 100644 index 0000000..a0fb8f6 --- /dev/null +++ b/src/parse/parse_textures.c @@ -0,0 +1,48 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* parse_textures.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cacharle +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2020/01/11 09:47:53 by cacharle #+# #+# */ +/* Updated: 2020/01/11 09:51:03 by cacharle ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "cub3d.h" + +t_bool parse_north_texture(t_state *state, char *line) +{ + if ((state->textures_path[TEX_NORTH] = ft_strdup(line)) == NULL) + return (FALSE); + return (TRUE); +} + +t_bool parse_south_texture(t_state *state, char *line) +{ + if ((state->textures_path[TEX_SOUTH] = ft_strdup(line)) == NULL) + return (FALSE); + return (TRUE); +} + +t_bool parse_west_texture(t_state *state, char *line) +{ + if ((state->textures_path[TEX_WEST] = ft_strdup(line)) == NULL) + return (FALSE); + return (TRUE); +} + +t_bool parse_east_texture(t_state *state, char *line) +{ + if ((state->textures_path[TEX_EAST] = ft_strdup(line)) == NULL) + return (FALSE); + return (TRUE); +} + +t_bool parse_sprite_texture(t_state *state, char *line) +{ + if ((state->textures_path[TEX_SPRITE] = ft_strdup(line)) == NULL) + return (FALSE); + return (TRUE); +} diff --git a/src/render.c b/src/render.c new file mode 100644 index 0000000..88b0cae --- /dev/null +++ b/src/render.c @@ -0,0 +1,107 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* render.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cacharle +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2020/01/11 13:37:17 by cacharle #+# #+# */ +/* Updated: 2020/01/30 15:17:49 by cacharle ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "cub3d.h" + +int render_update(void *param) +{ + t_state *state; + + state = param; + if (!state->running) + { + state_destroy(state); + exit(EXIT_SUCCESS); + return (0); + } + render_update_window(state); + mlx_put_image_to_window(state->mlx_ptr, state->window_ptr, state->window.id, 0, 0); + return (0); +} + +void render_update_window(t_state *state) +{ + int x; + + x = -1; + while (++x < state->window.width) + render_column(state, x); +} + +void render_column(t_state *state, int x) +{ + t_render_state rstate; + + rstate.x = x; + rstate_ray(state, &rstate); + rstate.map_pos = vector_new((double)((int)state->pos.x), (double)((int)state->pos.y)); //floor? + rstate_delta(&rstate); + rstate_init_probe(state, &rstate); + rstate.map_step = vector_new(rstate.ray.x < 0.0 ? -1.0 : 1.0, rstate.ray.y < 0.0 ? -1.0 : 1.0); + while (TRUE) + { + rstate.side = rstate.probe.x < rstate.probe.y ? SIDE_WE : SIDE_NS; + rstate_next_probe(&rstate); + if (state->map[(int)rstate.map_pos.y][(int)rstate.map_pos.x] == CELL_WALL) + break ; + } + rstate_perp_dist(state, &rstate); + rstate_line_height(state, &rstate); + rstate.draw_start = state->window.height / 2 - rstate.line_height / 2; + rstate.draw_end = state->window.height / 2 + rstate.line_height / 2; + if (rstate.draw_start < 0) + rstate.draw_start = 0; + if (rstate.draw_end > state->window.height - 1) + rstate.draw_end = state->window.height - 1; + render_window_column(state, &rstate); +} + +void render_window_column(t_state *state, t_render_state *rstate) +{ + int i; + t_color white; + + white.hexcode = 0x00ffffff; + i = 0; + while (i < rstate->draw_start) + ((t_color*)state->window.data)[i++ * state->window.width + rstate->x] = state->ceilling_color; + while (i < rstate->draw_end) + ((t_color*)state->window.data)[i++ * state->window.width + rstate->x] = white; + render_texture(state, rstate); + i = rstate->draw_end; + while (i < state->window.height) + ((t_color*)state->window.data)[i++ * state->window.width + rstate->x] = state->floor_color; + +} + +void render_texture(t_state *state, t_render_state *rstate) +{ + int i; + double step; + double tex_pos; + int tex_y; + int tex_x; + t_image *texture; + + texture = get_tex(state, rstate); + tex_x = get_tex_x(state, rstate, texture); + step = 1.0 * texture->height / rstate->line_height; + tex_pos = (rstate->draw_start - state->window.height / 2 + rstate->line_height / 2) * step; + i = rstate->draw_start - 1; + while (++i < rstate->draw_end) + { + tex_y = (int)tex_pos & (texture->height - 1); + tex_pos += step; + ((t_color*)state->window.data)[i * state->window.width + rstate->x] = + ((t_color*)texture->data)[texture->height * tex_y + tex_x]; + } +} diff --git a/src/render_state.c b/src/render_state.c new file mode 100644 index 0000000..46fc7c5 --- /dev/null +++ b/src/render_state.c @@ -0,0 +1,205 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* render_state.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cacharle +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2020/01/15 14:40:14 by cacharle #+# #+# */ +/* Updated: 2020/01/30 15:50:48 by cacharle ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "cub3d.h" + +/* +** -1 0 1 <-- camera_x +** v v v +** ################ +** # | # <-- screen +** # | # +** ################ +** +** camera_x is the x column from the camera percpective +** scaling the plane vector and adding it to the direction vector +** to create a vector in the *direction* of the column x. +*/ + +void rstate_ray(t_state *state, t_render_state *rstate) +{ + double camera_x; + + camera_x = 2.0 * (double)rstate->x / (double)state->window.width - 1.0; + rstate->ray = vector_add(state->dir, vector_scale(state->plane, camera_x)); +} + +/* +** delta between each grid unit form the vector percpective +** +** if we have a vector v = [2 3]: +** dx = |v| / v_1 +** = sqrt(v_1^2 + v_2^2) / v_1 +** = (v_1^2 + v_2^2) / v_1^2 +** = 1 + v_2^2 / v_1^2 +** Same thing for dy +** dy = |v| / v_2 +** = sqrt(v_1^2 + v_2^2) / v_1 +** = (v_1^2 + v_2^2) / v_2^2 +** = v_1^2 / v_2^2 + 1 +** +** This can be simplified (for some obscure reason): +** dx = |1 / v_1| +** dy = |1 / v_2| +*/ + +void rstate_delta(t_render_state *rstate) +{ + rstate->delta.x = fabs(1 / rstate->ray.x); //vector_norm(rstate->ray) / rstate->ray.x; + rstate->delta.y = fabs(1 / rstate->ray.y); // vector_norm(rstate->ray) / rstate->ray.y; +} + +/* +** first delta between player position and first grid unit +** +** current x and y are the perpendicular distance to the nearest wall, +** we multiply them by their corresponding delta. +** 0 <= perpendicular distance <= 1 is a ratio, how much of the full delta we need to take. +** +** if (rstate->ray.x < 0) +** rstate->probe.x = state->pos.x - rstate->map_pos.x; +** else +** rstate->probe.x = fabs(state->pos.x - rstate->map_pos.x + 1.0); +** if (rstate->ray.y < 0) +** rstate->probe.y = state->pos.y - rstate->map_pos.y; +** else +** rstate->probe.y = fabs(state->pos.y - rstate->map_pos.y + 1.0); +** rstate->probe.x *= rstate->delta.x; +** rstate->probe.y *= rstate->delta.y; +*/ + +void rstate_init_probe(t_state *state, t_render_state *rstate) +{ + if (rstate->ray.x < 0) + rstate->probe.x = (state->pos.x - rstate->map_pos.x) * rstate->delta.x; + else + rstate->probe.x = (rstate->map_pos.x + 1.0 - state->pos.x) * rstate->delta.x; + if (rstate->ray.y < 0) + rstate->probe.y = (state->pos.y - rstate->map_pos.y) * rstate->delta.y; + else + rstate->probe.y = (rstate->map_pos.y + 1.0 - state->pos.y) * rstate->delta.y; + /* rstate->probe = VECTOR_SUB(state->pos, rstate->map_pos); */ + /* if (rstate->ray.x > 0) */ + /* rstate->probe.x += 1.0; */ + /* if (rstate->ray.y > 0) */ + /* rstate->probe.y += 1.0; */ + /* rstate->probe.x *= rstate->delta.x; */ + /* rstate->probe.y *= rstate->delta.y; */ +} + +/* +** Move the probe to it's next iteration by advancing to the nearest square unit +** in the x or y direction. +** This advance is represented both with the +** player/ray percpective and the map pecpective. +*/ + +void rstate_next_probe(t_render_state *rstate) +{ + if (rstate->probe.x < rstate->probe.y) + { + rstate->probe.x += rstate->delta.x; + rstate->map_pos.x += rstate->map_step.x; + } + else + { + rstate->probe.y += rstate->delta.y; + rstate->map_pos.y += rstate->map_step.y; + } +} + +/* +** perpendicular distance between the wall hit and the camera plane. +** We don't use euclidean distance because it would cause a fisheye effect. +** +** ====================X========== wall +** | /| +** | <------ / | -----+ +** | / | | +** plane | / | <- perpendicular distance +** | | / | +** v | / | +** <-------^----/----------------- camera plane +** | / +** dir -> | / +** | / <- euclidean distance +** |/ +** x <- pos +** +** In this case the perpendicular distance (p) is the difference +** of the y-coord of the hit point and the y-coord of the pos + dir vector. +** We use the y component because we hit the wall +** from a south/north percepective, +** if we had hit it form west/east, we would use the x component instead. +*/ + +void rstate_perp_dist(t_state *state, t_render_state *rstate) +{ + if (rstate->side == SIDE_WE) + rstate->perp_dist = (rstate->map_pos.x - state->pos.x + (1 - rstate->map_step.x) / 2) / rstate->ray.x; + else + rstate->perp_dist = (rstate->map_pos.y - state->pos.y + (1 - rstate->map_step.y) / 2) / rstate->ray.y; +} + +/* +** 0 <= 1 / perp_dist <= 1 +** height * (1 / perp_dist) is how much of the screen height do we take +*/ + +void rstate_line_height(t_state *state, t_render_state *rstate) +{ + rstate->line_height = (int)((double)state->window.height / rstate->perp_dist); +} + +t_image *get_tex(t_state *state, t_render_state *rstate) +{ + if (rstate->side == SIDE_NS) + { + if (rstate->probe.y < state->pos.y) + return (state->textures + TEX_NORTH); + else + return (state->textures + TEX_SOUTH); + } + else if (rstate->side == SIDE_WE) + { + if (rstate->probe.x > state->pos.x) + return (state->textures + TEX_WEST); + else + return (state->textures + TEX_EAST); + } + return (NULL); +} + +/* +** Since we're drawing each column, all the texels we want to draw on the window +** are on a single column of the texture. +** First we find the x-coord relative to the wall we hit +*/ + +int get_tex_x(t_state *state, t_render_state *rstate, t_image *texture) +{ + int tex_x; + double wall_x; + + if (rstate->side == SIDE_WE) + wall_x = state->pos.y + rstate->perp_dist * rstate->ray.y; + else + wall_x = state->pos.x + rstate->perp_dist * rstate->ray.x; + wall_x -= floor(wall_x); + + tex_x = (int)(wall_x * (double)texture->width); + if (rstate->side == 0 && rstate->ray.x > 0) + tex_x = texture->width - tex_x - 1; + if (rstate->side == 1 && rstate->ray.y < 0) + tex_x = texture->width - tex_x - 1; + return (tex_x); +} diff --git a/src/state.c b/src/state.c new file mode 100644 index 0000000..11e1c65 --- /dev/null +++ b/src/state.c @@ -0,0 +1,128 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* graphics.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cacharle +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2019/11/19 16:39:57 by cacharle #+# #+# */ +/* Updated: 2020/01/30 15:13:42 by cacharle ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "cub3d.h" + +/* +** Initialize the state attributes that weren't already filled by the parsing +*/ + +t_state *state_new(t_state *state) +{ + int i; + + state->running = TRUE; + if ((state->mlx_ptr = mlx_init()) == NULL) + return (state_destroy(state)); + if ((state->window_ptr = mlx_new_window(state->mlx_ptr, + state->window.width, state->window.height, WINDOW_TITLE)) == NULL) + return (state_destroy(state)); + printf("init mlx and mlx window\n"); + i = -1; + while (++i < TEXTURES_NUM) + { + load_texture(state->mlx_ptr, &state->textures[i], + state->textures_path[i]); + if (state->textures[i].id == NULL) + return (error_put_return_state_destroy("load texture", state)); + } + if ((state->window.id = mlx_new_image(state->mlx_ptr, + state->window.width, state->window.height)) == NULL) + return (state_destroy(state)); + state->window.data = mlx_get_data_addr(state->window.id, + &state->window.depth, &state->window.size_line, + &state->window.endian); + printf("init mlx window image\n"); + state_init_player(state); + printf("init player\n"); + return (state); +} + +void state_init_player(t_state *state) +{ + int i; + int j; + + i = -1; + while (++i < state->map_height) + { + j = -1; + while (++j < state->map_width) + if (helper_is_player_cell(state->map[i][j])) + { + state->pos.x = (double)j + 0.5; + state->pos.y = (double)i + 0.5; + } + } + helper_init_dir_plane(state, (int)state->pos.y, (int)state->pos.x); +} + +t_state *state_new_empty(void) +{ + int i; + t_state *state; + + if ((state = (t_state*)malloc(sizeof(t_state))) == NULL) + return (NULL); + state->mlx_ptr = NULL; + state->window_ptr = NULL; + i = -1; + while (++i < TEXTURES_NUM) + { + state->textures_path[i] = NULL; + state->textures[i].id = NULL; + } + state->dir.x = 0.0; + state->dir.y = 0.0; + state->map = NULL; + state->ceilling_color.hexcode = 0x0; + state->floor_color.hexcode = 0x0; + return (state); +} + +void *state_destroy(t_state *state) +{ + int i; + + if (state == NULL) + return (NULL); + i = -1; + while (++i < TEXTURES_NUM) + { + free(state->textures_path[i]); + if (state->mlx_ptr != NULL && state->textures[i].id != NULL) + mlx_destroy_image(state->mlx_ptr, state->textures[i].id); + } + printf("free window image\n"); + if (state->mlx_ptr != NULL && state->window.id != NULL) + mlx_destroy_image(state->mlx_ptr, state->window.id); + printf("free window\n"); + if (state->mlx_ptr && state->window_ptr) + mlx_destroy_window(state->mlx_ptr, state->window_ptr); + printf("free map\n"); + if (state->map != NULL) + while (state->map_height-- > 0 && state->map[state->map_height] != NULL) + free(state->map[state->map_height]); + free(state->map); + printf("free state\n"); + free(state); + return (NULL); +} + +void load_texture(void *mlx_ptr, t_image *image, char *path) +{ + if ((image->id = mlx_xpm_file_to_image( + mlx_ptr, path, &image->width, &image->height)) == NULL) + return ; + image->data = mlx_get_data_addr(image->id, &image->depth, + &image->size_line, &image->endian); +} diff --git a/src/vector.c b/src/vector.c new file mode 100644 index 0000000..44f784b --- /dev/null +++ b/src/vector.c @@ -0,0 +1,62 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* linear_algebra.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cacharle +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2019/11/18 01:28:01 by cacharle #+# #+# */ +/* Updated: 2020/01/16 08:43:09 by cacharle ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "cub3d.h" + +t_vector vector_add(t_vector a, t_vector b) +{ + a.x += b.x; + a.y += b.y; + return (a); +} + +t_vector vector_scale(t_vector v, double scalar) +{ + v.x *= scalar; + v.y *= scalar; + return (v); +} + +/* +** rotate counter clockwise +*/ + +t_vector vector_rotate(t_vector v, double angle) +{ + t_vector rotated; + + rotated.x = cos(angle) * v.x - sin(angle) * v.y; + rotated.y = sin(angle) * v.x + cos(angle) * v.y; + return (rotated); +} + +double vector_norm(t_vector v) +{ + /* return (sqrt(SQUARE(v.x) + SQUARE(v.y))); */ + return (hypot(v.x, v.y)); +} + +t_vector vector_new(double x, double y) +{ + t_vector v; + + v.x = x; + v.y = y; + return (v); +} + +t_vector vector_apply(t_vector v, double (*f)(double)) +{ + v.x = f(v.x); + v.y = f(v.y); + return (v); +} diff --git a/state.c b/state.c deleted file mode 100644 index 11e1c65..0000000 --- a/state.c +++ /dev/null @@ -1,128 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* graphics.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: cacharle +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2019/11/19 16:39:57 by cacharle #+# #+# */ -/* Updated: 2020/01/30 15:13:42 by cacharle ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#include "cub3d.h" - -/* -** Initialize the state attributes that weren't already filled by the parsing -*/ - -t_state *state_new(t_state *state) -{ - int i; - - state->running = TRUE; - if ((state->mlx_ptr = mlx_init()) == NULL) - return (state_destroy(state)); - if ((state->window_ptr = mlx_new_window(state->mlx_ptr, - state->window.width, state->window.height, WINDOW_TITLE)) == NULL) - return (state_destroy(state)); - printf("init mlx and mlx window\n"); - i = -1; - while (++i < TEXTURES_NUM) - { - load_texture(state->mlx_ptr, &state->textures[i], - state->textures_path[i]); - if (state->textures[i].id == NULL) - return (error_put_return_state_destroy("load texture", state)); - } - if ((state->window.id = mlx_new_image(state->mlx_ptr, - state->window.width, state->window.height)) == NULL) - return (state_destroy(state)); - state->window.data = mlx_get_data_addr(state->window.id, - &state->window.depth, &state->window.size_line, - &state->window.endian); - printf("init mlx window image\n"); - state_init_player(state); - printf("init player\n"); - return (state); -} - -void state_init_player(t_state *state) -{ - int i; - int j; - - i = -1; - while (++i < state->map_height) - { - j = -1; - while (++j < state->map_width) - if (helper_is_player_cell(state->map[i][j])) - { - state->pos.x = (double)j + 0.5; - state->pos.y = (double)i + 0.5; - } - } - helper_init_dir_plane(state, (int)state->pos.y, (int)state->pos.x); -} - -t_state *state_new_empty(void) -{ - int i; - t_state *state; - - if ((state = (t_state*)malloc(sizeof(t_state))) == NULL) - return (NULL); - state->mlx_ptr = NULL; - state->window_ptr = NULL; - i = -1; - while (++i < TEXTURES_NUM) - { - state->textures_path[i] = NULL; - state->textures[i].id = NULL; - } - state->dir.x = 0.0; - state->dir.y = 0.0; - state->map = NULL; - state->ceilling_color.hexcode = 0x0; - state->floor_color.hexcode = 0x0; - return (state); -} - -void *state_destroy(t_state *state) -{ - int i; - - if (state == NULL) - return (NULL); - i = -1; - while (++i < TEXTURES_NUM) - { - free(state->textures_path[i]); - if (state->mlx_ptr != NULL && state->textures[i].id != NULL) - mlx_destroy_image(state->mlx_ptr, state->textures[i].id); - } - printf("free window image\n"); - if (state->mlx_ptr != NULL && state->window.id != NULL) - mlx_destroy_image(state->mlx_ptr, state->window.id); - printf("free window\n"); - if (state->mlx_ptr && state->window_ptr) - mlx_destroy_window(state->mlx_ptr, state->window_ptr); - printf("free map\n"); - if (state->map != NULL) - while (state->map_height-- > 0 && state->map[state->map_height] != NULL) - free(state->map[state->map_height]); - free(state->map); - printf("free state\n"); - free(state); - return (NULL); -} - -void load_texture(void *mlx_ptr, t_image *image, char *path) -{ - if ((image->id = mlx_xpm_file_to_image( - mlx_ptr, path, &image->width, &image->height)) == NULL) - return ; - image->data = mlx_get_data_addr(image->id, &image->depth, - &image->size_line, &image->endian); -} diff --git a/textures/mossy.xpm b/textures/mossy.xpm new file mode 100644 index 0000000..7e9d798 --- /dev/null +++ b/textures/mossy.xpm @@ -0,0 +1,95 @@ +/* XPM */ +static char *mossy[] = { +/* columns rows colors chars-per-pixel */ +"64 64 25 1", +" c #202020", +". c #2C2C2C", +"X c #383838", +"o c #404000", +"O c #585400", +"+ c #706C00", +"@ c #484848", +"# c #545454", +"$ c #646464", +"% c #707070", +"& c #7C7C7C", +"* c #848400", +"= c #9C9C00", +"- c #B4AC00", +"; c #CCC400", +": c #E4D800", +"> c #FCF420", +", c #8C8C8C", +"< c #989898", +"1 c #A8A8A8", +"2 c #B4B4B4", +"3 c #C0C0C0", +"4 c #D0D0D0", +"5 c #DCDCDC", +"6 c #ECECEC", +/* pixels */ +"................................................................", +"##########@5;;;;;555555---5 X,155555;;;%,,# @@@@@@@@@@##########", +"##########@54----<1;;433;;, X,32,;&;===+##X X%====&&&%$@@@@@@@@@", +",,,,,,,, #@54---+<;;=333*-$ X151,&;&+*+#&#X X=;:=+,23;;;$$;;,,,,", +"42-221,, #@54==*+<;=11<,,=# X,3,,,11$*+#%#X X=:-+$&25;::@$;;*&44", +"11--#%&% #@53=*+%&<1<=,%,*# X@1;=1,,&O#%##X X=:+$,2:;&==@$=*+@,<", +"2<+#,,,% @@54=++&1<<<=,<%,# X@&=*-,11%$%XXX X*=+$&;;;&+=@%$@@$-&", +"22&,1,%# X@54,&&<1<4&*<1,,# X@%,1,1,,,1%XXX.X*+$,,&;&&++@%&,%&*$", +"<11%%,@@ .@531<&<;<<,<,,1,# @#%%##XXXXXXX XX&$,&11&,1&@%,<,,1&$", +",,,,%#@@ .@561&<&;-%,,,1,,#. @@XXXXXXXXX XXX&22,=&<&&<$%<,<,,1,", +"%%%%#@XX .@55,&<<;=%1,1,1,#. X@X.. ..XXXX&2&=@,1:&,%,%<$%,$$", +"##@@@ .@151<&;-=%<,,&,%$X X@@@@%111155+XXX%2,&$$&=X##$@@@@@@@", +" ....X#,54,&,=%,,1&,=,#X X@%1>>555445;+XX#,%$$#@OXXXXXX.....", +".........X#%14,1,,,1,,<,$$#X .X1>;=,,1,1=%O XXXXXXXXXXX.. ", +"XXXXXXXXXX#@,41,1<%<,&,1*##X .@1;*&1,::,=#+XX..........XXXXXXXXX", +"#@XXXXXXXX#@%3,1<;=%1,1,+#%@ .@1:*&,;:&,*#OX@@#### @@@@@@@@@@@@@", +"<<<<<<<<<. #@33*,=*1%,,,%$## @::&&1::%,+#XX@:--$#@#&<<<<<<<<<<<", +"4;-55;=%%X #@,3+$<$,%%1,%,%@ @:&,&,=+$1,#XXX--*$.@&3;;;5-11;;;5", +";-*--=+#%X #@%<$$,,%,#,%#%#@ @&,&,:$$$###X X=*#$ @<;;;&:=&1;=*%", +"-*1-=*+#%X @#@<<%,$%%%%#%#@. .1,%,%#XXXXXX $=*%# @<;;&<==&<;=*%", +"*1,-=++##X @#@$##XXXXXX. .,%XXX $,*,# @<1&,<=&&1;=*<", +"1,1-+##,#X @#@.... .X#X ......,1,1# @,1<1<1&1&1=+%", +",1&&#%,%#X X##@X @@@@@@@,,<=====&#.X$3513$ @,,1:<,1<11&&<", +",;=&,,,$@X X,;;-=,222$X@$=;;;-4666;;;;-=* X&5351% @&<1<,1<:<&1<1", +",=*1,,,$@X X;--=&&&&&X#@=;-%<11<1<=&=*=*+ X,5113: @:1<1<::&1<<1<", +"<*,,,,%#XX X-=*$$$$$$ #@<6<<=<;1<<&1*&=+O X,:,,1= @=O%$:-*+O%%#%", +"$$$$$#@XXX X-*$$<*=+$ @@<6:1<;*<;;1<*1*$O X,-%,1+ @OXX@OOOO@@###", +"#@@XXX .X-*$<<&*+$ @@<6;1;=&<;*<1<<&$o X,%,15O @.. XX@", +" ...@@@6$<1*,*+$ X@<6-<;+&1<1<&-*&$o X:6151# @XXXX... ", +"@$$%,<,,,,@ 6<<1*,$&$o @<6-1=+&<&<1<-*&#o X-6331# @XXXXXXXXXXXXX", +"$,2--,1111$ 614,+1,&$o @<61;=+&<11<1-*,#o +=511-# @+===--**@@@@#", +"$2--*$1111@ 61<1&,&,$o @&<;=+%&1<<&<-*$#o X=55-=# @%=+===---* +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2019/11/18 01:28:01 by cacharle #+# #+# */ -/* Updated: 2020/01/16 08:43:09 by cacharle ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#include "cub3d.h" - -t_vector vector_add(t_vector a, t_vector b) -{ - a.x += b.x; - a.y += b.y; - return (a); -} - -t_vector vector_scale(t_vector v, double scalar) -{ - v.x *= scalar; - v.y *= scalar; - return (v); -} - -/* -** rotate counter clockwise -*/ - -t_vector vector_rotate(t_vector v, double angle) -{ - t_vector rotated; - - rotated.x = cos(angle) * v.x - sin(angle) * v.y; - rotated.y = sin(angle) * v.x + cos(angle) * v.y; - return (rotated); -} - -double vector_norm(t_vector v) -{ - /* return (sqrt(SQUARE(v.x) + SQUARE(v.y))); */ - return (hypot(v.x, v.y)); -} - -t_vector vector_new(double x, double y) -{ - t_vector v; - - v.x = x; - v.y = y; - return (v); -} - -t_vector vector_apply(t_vector v, double (*f)(double)) -{ - v.x = f(v.x); - v.y = f(v.y); - return (v); -} -- cgit