aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCharles <sircharlesaze@gmail.com>2020-02-05 01:29:44 +0100
committerCharles <sircharlesaze@gmail.com>2020-02-05 01:29:44 +0100
commitaf747497060d8a311204ec58b3ac87cc585462fc (patch)
tree2022e10ac93243772f22f281071a4e0fd5c55f1d
parent3b224458a5d539bbe00318d939c9a099f3f158e1 (diff)
downloadcub3d-af747497060d8a311204ec58b3ac87cc585462fc.tar.gz
cub3d-af747497060d8a311204ec58b3ac87cc585462fc.tar.bz2
cub3d-af747497060d8a311204ec58b3ac87cc585462fc.zip
better parsing
-rw-r--r--include/cub3d.h19
m---------libft0
-rw-r--r--minimalist.cub40
-rw-r--r--src/error.c2
-rw-r--r--src/event.c21
-rw-r--r--src/helper.c2
-rw-r--r--src/main.c44
-rw-r--r--src/parse/parse.c48
-rw-r--r--src/parse/parse_check.c14
-rw-r--r--src/parse/parse_color.c8
-rw-r--r--src/parse/parse_file.c38
-rw-r--r--src/parse/parse_resolution.c5
-rw-r--r--src/parse/parse_textures.c17
-rw-r--r--src/render.c2
-rw-r--r--src/render_sprite.c94
-rw-r--r--src/render_state.c2
-rw-r--r--src/sprite_sort.c2
-rw-r--r--src/state.c43
-rw-r--r--src/texture.c8
-rw-r--r--test.cub21
20 files changed, 243 insertions, 187 deletions
diff --git a/include/cub3d.h b/include/cub3d.h
index eed376c..bd696fb 100644
--- a/include/cub3d.h
+++ b/include/cub3d.h
@@ -6,7 +6,7 @@
/* By: cacharle <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2019/11/15 06:40:37 by cacharle #+# #+# */
-/* Updated: 2020/02/04 04:09:56 by cacharle ### ########.fr */
+/* Updated: 2020/02/05 01:19:02 by cacharle ### ########.fr */
/* */
/* ************************************************************************** */
#include <stdio.h>
@@ -103,8 +103,19 @@ typedef struct
double dist;
} t_sprite;
+typedef unsigned short t_pflags;
+# define PFLAGS_R (1 << 0)
+# define PFLAGS_NO (1 << 1)
+# define PFLAGS_SO (1 << 2)
+# define PFLAGS_WE (1 << 3)
+# define PFLAGS_EA (1 << 4)
+# define PFLAGS_S (1 << 5)
+# define PFLAGS_F (1 << 6)
+# define PFLAGS_C (1 << 7)
+
typedef struct s_state
{
+ t_pflags pflags;
t_bool running;
void *mlx_ptr;
void *window_ptr;
@@ -175,13 +186,15 @@ typedef struct s_option_parser
t_state *parse(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);
+t_cell *create_map_row(t_state *state, char *line);
/*
** parse/parse_file.c
*/
char **get_file_lines(char *filename);
+int parse_premap(t_state *state, char **lines);
+t_bool create_map_row_char(char c, t_cell *row, int i);
/*
** parse/parse_check.c
@@ -227,7 +240,7 @@ 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);
+t_bool state_init_textures(t_state *state);
/*
** render.c
diff --git a/libft b/libft
-Subproject f078f191515d0fc65340a8722fad14f3de679d7
+Subproject 19964c7a382bcc5c0f09b1233b54b559c44e3a2
diff --git a/minimalist.cub b/minimalist.cub
index 24a1db0..03690a5 100644
--- a/minimalist.cub
+++ b/minimalist.cub
@@ -1,45 +1,23 @@
-
-
-
-R 200 200
-
-NO ./textures/greystone.xpm
-
-
-
+R 1600 1200
+NO ./textures/eagle.xpm
SO ./textures/greystone.xpm
-
-
-
-
-WE ./textures/greystone.xpm
-
-
+WE ./textures/wood.xpm
EA ./textures/greystone.xpm
-
-
-
-
-S ./textures/cacharle.xpm
-
-
-
-
-F 10,10,10
-C 40,40,40
+S ./textures/cheese.xpm
+F 10,10,10
+C 40,40,40
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 1 1 1 1
1 0 0 0 0 0 2 0 0 0 1 1 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 1 1 1 0 0 0 0 0 0 2 0 0 0 0 0 1 0 0 0 1
-
-1 2 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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 0 1 0 0 0 1
1 0 1 1 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1
1 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 1 1 1 0 1 1 1 1 0 2 0 1
1 1 1 1 0 1 1 1 1 1 1 1 1 1 0 1 1 1 0 0 0 0 0 0 1 0 0 0 1
1 1 1 1 0 1 1 1 1 1 1 1 1 1 0 1 1 1 0 1 0 1 0 0 1 0 0 0 1
1 1 0 0 0 0 0 0 1 1 0 1 0 1 0 1 1 1 0 0 0 0 0 0 1 0 0 0 1
1 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 0 0 0 1
-1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 0 1 0 0 1 0 N 0 1
-1 1 0 0 0 0 0 0 1 1 0 1 0 1 0 1 1 1 1 1 0 1 1 1 1 0 0 0 1
+1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 0 1 0 0 1 0 0 0 1
+1 1 0 0 0 0 0 0 1 1 0 1 0 1 0 1 1 1 1 1 0 1 1 1 1 0 N 0 1
1 1 1 1 0 1 1 1 1 1 1 1 0 1 0 1 1 1 1 1 0 1 1 1 1 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 1 1 1 1 1
diff --git a/src/error.c b/src/error.c
index 03352e1..7d280d5 100644
--- a/src/error.c
+++ b/src/error.c
@@ -6,7 +6,7 @@
/* By: cacharle <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2020/01/11 13:33:14 by cacharle #+# #+# */
-/* Updated: 2020/02/04 02:17:53 by cacharle ### ########.fr */
+/* Updated: 2020/02/05 00:58:08 by cacharle ### ########.fr */
/* */
/* ************************************************************************** */
diff --git a/src/event.c b/src/event.c
index 5a5b3e1..c91b204 100644
--- a/src/event.c
+++ b/src/event.c
@@ -6,16 +6,25 @@
/* By: cacharle <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2019/11/15 06:39:37 by cacharle #+# #+# */
-/* Updated: 2020/02/03 00:44:39 by cacharle ### ########.fr */
+/* Updated: 2020/02/04 23:50:51 by cacharle ### ########.fr */
/* */
/* ************************************************************************** */
#include "cub3d.h"
-#define ROTATE_STEP (M_PI / 20.0)
-#define MOVE_SPEED 0.24
+#define ROTATE_STEP (M_PI / 12.0)
+#define MOVE_SPEED 0.40
-int event_keydown(int key, t_state *state)
+static t_bool valid_pos(t_state *state)
+{
+ return (state->pos.x > 0 && state->pos.y > 0
+ && state->pos.x < (double)(state->map_width - 1)
+ && state->pos.y < (double)(state->map_height - 1)
+ && state->map[(int)state->pos.y][(int)state->pos.x] != CELL_WALL
+ && state->map[(int)state->pos.y][(int)state->pos.x] != CELL_ITEM);
+}
+
+int event_keydown(int key, t_state *state)
{
t_vector saved_pos;
@@ -38,12 +47,12 @@ int event_keydown(int key, t_state *state)
helper_rotate_player(state, -ROTATE_STEP);
else if (key == MLXK_RIGHT)
helper_rotate_player(state, ROTATE_STEP);
- if (state->map[(int)state->pos.y][(int)state->pos.x] == CELL_WALL)
+ if (!valid_pos(state))
state->pos = saved_pos;
return (0);
}
-int event_quit(t_state *state)
+int event_quit(t_state *state)
{
state->running = FALSE;
return (0);
diff --git a/src/helper.c b/src/helper.c
index ca0f879..1197f03 100644
--- a/src/helper.c
+++ b/src/helper.c
@@ -6,7 +6,7 @@
/* By: cacharle <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2020/01/11 07:32:20 by cacharle #+# #+# */
-/* Updated: 2020/02/04 02:17:38 by cacharle ### ########.fr */
+/* Updated: 2020/02/04 20:00:23 by cacharle ### ########.fr */
/* */
/* ************************************************************************** */
diff --git a/src/main.c b/src/main.c
index f1d4f20..b935b52 100644
--- a/src/main.c
+++ b/src/main.c
@@ -6,7 +6,7 @@
/* By: cacharle <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2019/11/15 06:39:39 by cacharle #+# #+# */
-/* Updated: 2020/02/04 05:29:40 by cacharle ### ########.fr */
+/* Updated: 2020/02/05 00:14:18 by cacharle ### ########.fr */
/* */
/* ************************************************************************** */
@@ -28,45 +28,3 @@ int main(int argc, char **argv)
mlx_loop(state->mlx_ptr);
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
index 4c51945..c1f1a5f 100644
--- a/src/parse/parse.c
+++ b/src/parse/parse.c
@@ -6,7 +6,7 @@
/* By: cacharle <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2019/11/15 09:29:21 by cacharle #+# #+# */
-/* Updated: 2020/02/04 04:41:26 by cacharle ### ########.fr */
+/* Updated: 2020/02/05 01:27:22 by cacharle ### ########.fr */
/* */
/* ************************************************************************** */
@@ -22,19 +22,15 @@ t_state *parse(char *filename)
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 ((i = parse_premap(state, lines)) == -1)
{
- if (*lines[i] == '1')
- break ;
- if (!parse_line(state, lines[i]))
- return (error_put_return_lines_state_destroy(
- "parse configuration", state, lines));
+ return (error_put_return_lines_state_destroy(
+ "parse option", state, lines));
}
- if ((state = parse_map(state, lines + i)) == NULL)
+ if (state->pflags != 0xFF || (state = parse_map(state, lines + i)) == NULL)
{
- return (error_put_return_lines_state_destroy("parse map",
- state, lines));
+ return (error_put_return_lines_state_destroy(state == NULL ?
+ "parse map" : "parse options", state, lines));
}
helper_free_splited(lines);
return (state);
@@ -54,15 +50,14 @@ static t_option_parser g_option_parsers[] =
t_bool parse_line(t_state *state, char *line)
{
- int i;
- char *tmp;
+ int i;
+ char *tmp;
if (!*line)
return (TRUE);
i = -1;
while (++i < (int)(sizeof(g_option_parsers) / sizeof(t_option_parser)))
{
-
if (ft_strncmp(g_option_parsers[i].id, line,
ft_strlen(g_option_parsers[i].id)) == 0)
{
@@ -84,37 +79,27 @@ t_state *parse_map(t_state *state, char **lines)
if (*lines[i] != '1')
return (NULL);
state->map_height = i;
- if ((state->map = (t_map)malloc(sizeof(t_cell*) * i)) == NULL)
+ if ((state->map = (t_map)ft_calloc(i, sizeof(t_cell*))) == 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)
+ if ((state->map[i] = create_map_row(state, lines[i])) == NULL)
return (NULL);
return (state);
}
-t_cell *create_map_row(char *line)
+t_cell *create_map_row(t_state *state, char *line)
{
int i;
t_cell *row;
- if ((row = (t_cell*)malloc(sizeof(t_cell) * ft_strlen(line))) == NULL)
+ if ((row = (t_cell*)malloc(sizeof(t_cell) * state->map_width)) == 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
+ if (!create_map_row_char(*line, row, i++))
{
free(row);
return (NULL);
@@ -123,5 +108,10 @@ t_cell *create_map_row(char *line)
while (*line == ' ')
line++;
}
+ if (i != state->map_width)
+ {
+ free(row);
+ return (NULL);
+ }
return (row);
}
diff --git a/src/parse/parse_check.c b/src/parse/parse_check.c
index 976020b..09a2429 100644
--- a/src/parse/parse_check.c
+++ b/src/parse/parse_check.c
@@ -6,7 +6,7 @@
/* By: cacharle <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2020/01/11 10:59:15 by cacharle #+# #+# */
-/* Updated: 2020/02/04 05:07:22 by cacharle ### ########.fr */
+/* Updated: 2020/02/04 18:49:49 by cacharle ### ########.fr */
/* */
/* ************************************************************************** */
@@ -27,7 +27,12 @@ static t_bool check_player_count(t_state *state)
if (helper_is_player_cell(state->map[i][j]))
player_count++;
}
- return (player_count == 1);
+ if (player_count != 1)
+ {
+ error_put("validate map with other than one player");
+ return (FALSE);
+ }
+ return (TRUE);
}
t_state *parse_check(t_state *state)
@@ -53,9 +58,6 @@ t_state *parse_check(t_state *state)
"validate map without borders", state));
}
if (!check_player_count(state))
- {
- return (error_put_return_state_destroy(
- "validate map with other than one player", state));
- }
+ return (state_destroy(state));
return (state);
}
diff --git a/src/parse/parse_color.c b/src/parse/parse_color.c
index d3cee05..b939076 100644
--- a/src/parse/parse_color.c
+++ b/src/parse/parse_color.c
@@ -6,7 +6,7 @@
/* By: cacharle <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2020/01/11 09:52:34 by cacharle #+# #+# */
-/* Updated: 2020/02/04 05:12:42 by cacharle ### ########.fr */
+/* Updated: 2020/02/05 00:04:53 by cacharle ### ########.fr */
/* */
/* ************************************************************************** */
@@ -16,6 +16,8 @@ t_bool parse_ceilling_color(t_state *state, char *line)
{
long tmp;
+ if (state->pflags & PFLAGS_C)
+ return (FALSE);
errno = 0;
state->ceilling_color.hexcode = 0x0;
if ((tmp = ft_strtol(line, &line, 10)) > 255 || tmp < 0)
@@ -33,6 +35,7 @@ t_bool parse_ceilling_color(t_state *state, char *line)
state->ceilling_color.rgb.b = (t_byte)tmp;
if (errno != 0)
return (FALSE);
+ state->pflags |= PFLAGS_C;
return (TRUE);
}
@@ -40,6 +43,8 @@ t_bool parse_floor_color(t_state *state, char *line)
{
long tmp;
+ if (state->pflags & PFLAGS_F)
+ return (FALSE);
errno = 0;
state->floor_color.hexcode = 0x0;
if ((tmp = ft_strtol(line, &line, 10)) > 255 || tmp < 0)
@@ -57,5 +62,6 @@ t_bool parse_floor_color(t_state *state, char *line)
state->floor_color.rgb.b = (t_byte)tmp;
if (errno != 0)
return (FALSE);
+ state->pflags |= PFLAGS_F;
return (TRUE);
}
diff --git a/src/parse/parse_file.c b/src/parse/parse_file.c
index 443a1b5..8c6ef5e 100644
--- a/src/parse/parse_file.c
+++ b/src/parse/parse_file.c
@@ -6,7 +6,7 @@
/* By: cacharle <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2020/02/04 03:50:53 by cacharle #+# #+# */
-/* Updated: 2020/02/04 04:28:41 by cacharle ### ########.fr */
+/* Updated: 2020/02/05 01:27:26 by cacharle ### ########.fr */
/* */
/* ************************************************************************** */
@@ -49,5 +49,39 @@ char **get_file_lines(char *filename)
if (ret == -1)
return (NULL);
close(fd);
- return (trim_file_lines(ft_split(file, '\n')));
+ return (trim_file_lines(ft_split_strict(file, '\n')));
+}
+
+int parse_premap(t_state *state, char **lines)
+{
+ int i;
+
+ i = -1;
+ while (lines[++i] != NULL)
+ {
+ if (*lines[i] == '\n')
+ continue ;
+ if (*lines[i] == '1')
+ break ;
+ if (!parse_line(state, lines[i]))
+ return (-1);
+ }
+ return (i);
+}
+
+t_bool create_map_row_char(char c, t_cell *row, int i)
+{
+ if (c == '0' || c == '1' || c == '2')
+ row[i] = c - '0';
+ else if (c == 'N')
+ row[i] = CELL_LOOK_NORTH;
+ else if (c == 'S')
+ row[i] = CELL_LOOK_SOUTH;
+ else if (c == 'W')
+ row[i] = CELL_LOOK_WEST;
+ else if (c == 'E')
+ row[i] = CELL_LOOK_EAST;
+ else
+ return (FALSE);
+ return (TRUE);
}
diff --git a/src/parse/parse_resolution.c b/src/parse/parse_resolution.c
index 300b461..b863c94 100644
--- a/src/parse/parse_resolution.c
+++ b/src/parse/parse_resolution.c
@@ -6,7 +6,7 @@
/* By: cacharle <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2019/11/15 09:29:27 by cacharle #+# #+# */
-/* Updated: 2020/02/04 04:40:35 by cacharle ### ########.fr */
+/* Updated: 2020/02/05 00:04:03 by cacharle ### ########.fr */
/* */
/* ************************************************************************** */
@@ -20,6 +20,8 @@ t_bool parse_resolution(t_state *state, char *line)
{
long tmp;
+ if (state->pflags & PFLAGS_R)
+ return (FALSE);
errno = 0;
if ((tmp = ft_strtol(line, &line, 10)) < MIN_RES)
return (FALSE);
@@ -37,5 +39,6 @@ t_bool parse_resolution(t_state *state, char *line)
state->window.height = tmp;
if (*line != '\0' || errno != 0 || state->window.height > 2160)
return (FALSE);
+ state->pflags |= PFLAGS_R;
return (TRUE);
}
diff --git a/src/parse/parse_textures.c b/src/parse/parse_textures.c
index f6ba1a0..e048bd5 100644
--- a/src/parse/parse_textures.c
+++ b/src/parse/parse_textures.c
@@ -6,7 +6,7 @@
/* By: cacharle <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2020/01/11 09:47:53 by cacharle #+# #+# */
-/* Updated: 2020/02/02 19:21:39 by cacharle ### ########.fr */
+/* Updated: 2020/02/05 00:06:18 by cacharle ### ########.fr */
/* */
/* ************************************************************************** */
@@ -14,35 +14,50 @@
t_bool parse_north_texture(t_state *state, char *line)
{
+ if (state->pflags & PFLAGS_NO)
+ return (FALSE);
if ((state->textures_path[TEX_NORTH] = ft_strdup(line)) == NULL)
return (FALSE);
+ state->pflags |= PFLAGS_NO;
return (TRUE);
}
t_bool parse_south_texture(t_state *state, char *line)
{
+ if (state->pflags & PFLAGS_SO)
+ return (FALSE);
if ((state->textures_path[TEX_SOUTH] = ft_strdup(line)) == NULL)
return (FALSE);
+ state->pflags |= PFLAGS_SO;
return (TRUE);
}
t_bool parse_west_texture(t_state *state, char *line)
{
+ if (state->pflags & PFLAGS_WE)
+ return (FALSE);
if ((state->textures_path[TEX_WEST] = ft_strdup(line)) == NULL)
return (FALSE);
+ state->pflags |= PFLAGS_WE;
return (TRUE);
}
t_bool parse_east_texture(t_state *state, char *line)
{
+ if (state->pflags & PFLAGS_EA)
+ return (FALSE);
if ((state->textures_path[TEX_EAST] = ft_strdup(line)) == NULL)
return (FALSE);
+ state->pflags |= PFLAGS_EA;
return (TRUE);
}
t_bool parse_sprite_texture(t_state *state, char *line)
{
+ if (state->pflags & PFLAGS_S)
+ return (FALSE);
if ((state->textures_path[TEX_SPRITE] = ft_strdup(line)) == NULL)
return (FALSE);
+ state->pflags |= PFLAGS_S;
return (TRUE);
}
diff --git a/src/render.c b/src/render.c
index de7e843..e6c7eeb 100644
--- a/src/render.c
+++ b/src/render.c
@@ -6,7 +6,7 @@
/* By: cacharle <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2020/01/11 13:37:17 by cacharle #+# #+# */
-/* Updated: 2020/02/04 02:31:57 by cacharle ### ########.fr */
+/* Updated: 2020/02/04 23:16:38 by cacharle ### ########.fr */
/* */
/* ************************************************************************** */
diff --git a/src/render_sprite.c b/src/render_sprite.c
index 379f67a..2ca34c0 100644
--- a/src/render_sprite.c
+++ b/src/render_sprite.c
@@ -6,47 +6,80 @@
/* By: cacharle <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2020/02/02 17:39:07 by cacharle #+# #+# */
-/* Updated: 2020/02/04 03:38:53 by cacharle ### ########.fr */
+/* Updated: 2020/02/04 23:25:21 by cacharle ### ########.fr */
/* */
/* ************************************************************************** */
#include "cub3d.h"
+/*
+** 1: While raycasting the walls, store the perpendicular distance
+** of each vertical stripe in a 1D ZBuffer
+** 2: Calculate the distance of each sprite to the player
+** 3: Use this distance to sort the sprites, from furthest away
+** to closest to the camera
+** 4: Project the sprite on the camera plane (in 2D):
+** subtract the player position from the sprite position,
+** then multiply the result with the inverse of the 2x2 camera matrix
+** 5: Calculate the size of the sprite on the screen
+** (both in x and y direction) by using the perpendicular distance
+** 6: Draw the sprites vertical stripe by vertical stripe,
+** don't draw the vertical stripe if the distance is further away
+** than the 1D ZBuffer of the walls of the current stripe
+** 7: Draw the vertical stripe pixel by pixel, make sure there's
+** an invisible color or all sprites would be rectangles
+*/
+
+static void draw_stripe_pixels(t_state *state, t_sprite_state *sstate,
+ int stripe, int tex_x)
+{
+ int y;
+ int d;
+ int tex_y;
+ t_color color;
+
+ y = sstate->draw_start - 1;
+ while (++y < sstate->draw_end_y)
+ {
+ d = y * 256 - state->window.height * 128 + sstate->sprite_height * 128;
+ tex_y = (d * state->textures[TEX_SPRITE].height)
+ / (sstate->sprite_height * 256);
+ color = ((t_color*)state->textures[TEX_SPRITE].data)
+ [state->textures[TEX_SPRITE].width * tex_y + tex_x];
+ if ((color.hexcode & 0x00FFFFFF) != 0)
+ ((t_color*)state->window.data)[y * state->window.width + stripe] =
+ color;
+ }
+}
+
static void draw_stripe(t_state *state, t_sprite_state *sstate, int stripe)
{
int tex_width;
int tex_height;
int tex_x;
- int y;
tex_width = state->textures[TEX_SPRITE].width;
tex_height = state->textures[TEX_SPRITE].height;
- tex_x = (int)(256 * (stripe - (-sstate->sprite_width / 2 + sstate->sprite_window_x))
- * tex_width / sstate->sprite_width) / 256;
- if (!(sstate->transform.y > 0 && stripe > 0 && stripe < state->window.width && sstate->transform.y < state->z_buffer[stripe]))
+ tex_x = (int)(256 * (stripe - (-sstate->sprite_width / 2
+ + sstate->sprite_window_x))
+ * tex_width / sstate->sprite_width) / 256;
+ if (!(sstate->transform.y > 0 && stripe > 0 && stripe < state->window.width
+ && sstate->transform.y < state->z_buffer[stripe]))
return ;
- y = sstate->draw_start - 1;
- while (++y < sstate->draw_end_y)
- {
- int d = y * 256 - state->window.height * 128 + sstate->sprite_height * 128;
- int tex_y = ((d * tex_height) / sstate->sprite_height) / 256;
- t_color color = ((t_color*)state->textures[TEX_SPRITE].data)[tex_width * tex_y + tex_x];
- if ((color.hexcode & 0x00FFFFFF) != 0)
- ((t_color*)state->window.data)[y * state->window.width + stripe] = color;
- }
+ draw_stripe_pixels(state, sstate, stripe, tex_x);
}
-static void sprite_boundary(t_state *state, t_sprite_state *sstate)
+static void sprite_boundary(t_state *state, t_sprite_state *sstate)
{
sstate->sprite_height = ft_abs((int)(state->window.height
/ (sstate->transform.y)));
sstate->draw_start = -sstate->sprite_height / 2 + state->window.height / 2;
- if(sstate->draw_start < 0)
+ if (sstate->draw_start < 0)
sstate->draw_start = 0;
sstate->draw_end_y = sstate->sprite_height / 2 + state->window.height / 2;
- if(sstate->draw_end_y >= state->window.height)
+ if (sstate->draw_end_y >= state->window.height)
sstate->draw_end_y = state->window.height - 1;
- sstate->sprite_width = ft_abs( (int) (state->window.height
+ sstate->sprite_width = ft_abs((int)(state->window.height
/ (sstate->transform.y)));
sstate->draw_start_x = -sstate->sprite_width / 2 + sstate->sprite_window_x;
if (sstate->draw_start_x < 0)
@@ -56,28 +89,29 @@ static void sprite_boundary(t_state *state, t_sprite_state *sstate)
sstate->draw_end_x = state->window.width - 1;
}
-static void render_sprite(t_state *state, int i)
+static void render_sprite(t_state *state, int i)
{
int stripe;
t_sprite_state sstate;
+ double inverse_det;
+ t_vector sprite;
- sstate.sprite.x = state->sprites[i].pos.x - state->pos.x;
- sstate.sprite.y = state->sprites[i].pos.y - state->pos.y;
- sstate.inverse_det = 1.0 / (state->plane.x
- * state->dir.y - state->dir.x * state->plane.y);
- sstate.transform.x = sstate.inverse_det
- * (state->dir.y * sstate.sprite.x - state->dir.x * sstate.sprite.y);
- sstate.transform.y = sstate.inverse_det * (-state->plane.y
- * sstate.sprite.x + state->plane.x * sstate.sprite.y);
- sstate.sprite_window_x = (int)((state->window.width / 2)
- * (1 + sstate.transform.x / sstate.transform.y));
+ sprite = vector_add(state->sprites[i].pos, vector_scale(state->pos, -1.0));
+ inverse_det = 1.0 / (state->plane.x * state->dir.y
+ - state->dir.x * state->plane.y);
+ sstate.transform.x = state->dir.y * sprite.x - state->dir.x * sprite.y;
+ sstate.transform.y =
+ -state->plane.y * sprite.x + state->plane.x * sprite.y;
+ sstate.transform = vector_scale(sstate.transform, inverse_det);
+ sstate.sprite_window_x = (int)((state->window.width / 2.0)
+ * (1.0 + sstate.transform.x / sstate.transform.y));
sprite_boundary(state, &sstate);
stripe = sstate.draw_start_x - 1;
while (++stripe < sstate.draw_end_x)
draw_stripe(state, &sstate, stripe);
}
-void render_update_sprite(t_state *state)
+void render_update_sprite(t_state *state)
{
int i;
diff --git a/src/render_state.c b/src/render_state.c
index 09f6f0c..5d535d2 100644
--- a/src/render_state.c
+++ b/src/render_state.c
@@ -6,7 +6,7 @@
/* By: cacharle <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2020/01/15 14:40:14 by cacharle #+# #+# */
-/* Updated: 2020/02/04 02:09:43 by cacharle ### ########.fr */
+/* Updated: 2020/02/04 18:30:10 by cacharle ### ########.fr */
/* */
/* ************************************************************************** */
diff --git a/src/sprite_sort.c b/src/sprite_sort.c
index 4227743..553df43 100644
--- a/src/sprite_sort.c
+++ b/src/sprite_sort.c
@@ -6,7 +6,7 @@
/* By: cacharle <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2020/02/04 02:35:05 by cacharle #+# #+# */
-/* Updated: 2020/02/04 03:38:15 by cacharle ### ########.fr */
+/* Updated: 2020/02/04 23:20:37 by cacharle ### ########.fr */
/* */
/* ************************************************************************** */
diff --git a/src/state.c b/src/state.c
index 414c2f1..ba46647 100644
--- a/src/state.c
+++ b/src/state.c
@@ -6,7 +6,7 @@
/* By: cacharle <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2019/11/19 16:39:57 by cacharle #+# #+# */
-/* Updated: 2020/02/04 03:37:21 by cacharle ### ########.fr */
+/* Updated: 2020/02/05 01:28:31 by cacharle ### ########.fr */
/* */
/* ************************************************************************** */
@@ -18,8 +18,6 @@
t_state *state_new(t_state *state)
{
- int i;
-
if (state == NULL)
return (NULL);
state->running = TRUE;
@@ -28,15 +26,8 @@ t_state *state_new(t_state *state)
if ((state->window_ptr = mlx_new_window(state->mlx_ptr,
state->window.width, state->window.height, WINDOW_TITLE)) == NULL)
return (state_destroy(state));
- i = -1;
- while (++i < TEXTURES_NUM)
- {
- puts(state->textures_path[i]);
- 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_init_textures(state))
+ 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));
@@ -44,7 +35,8 @@ t_state *state_new(t_state *state)
&state->window.depth, &state->window.size_line,
&state->window.endian);
state_init_player(state);
- if ((state->z_buffer = malloc(sizeof(double) * state->window.width)) == NULL)
+ if ((state->z_buffer = malloc(sizeof(double)
+ * state->window.width)) == NULL)
return (error_put_return_state_destroy("create z buffer", state));
if (!state_init_sprites(state))
return (error_put_return_state_destroy("create sprites pos", state));
@@ -119,16 +111,27 @@ void *state_destroy(t_state *state)
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)
+t_bool state_init_textures(t_state *state)
{
- 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);
+ int i;
+ t_image *tex;
+
+ i = -1;
+ while (++i < TEXTURES_NUM)
+ {
+ tex = &state->textures[i];
+ if ((tex->id = mlx_xpm_file_to_image(state->mlx_ptr,
+ state->textures_path[i], &tex->width, &tex->height))
+ == NULL)
+ return (FALSE);
+ tex->data = mlx_get_data_addr(tex->id, &tex->depth,
+ &tex->size_line, &tex->endian);
+ if (tex->id == NULL)
+ return (FALSE);
+ }
+ return (TRUE);
}
diff --git a/src/texture.c b/src/texture.c
index a5bf611..afeae92 100644
--- a/src/texture.c
+++ b/src/texture.c
@@ -6,7 +6,7 @@
/* By: cacharle <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2020/02/01 11:38:43 by cacharle #+# #+# */
-/* Updated: 2020/02/04 03:34:54 by cacharle ### ########.fr */
+/* Updated: 2020/02/04 23:16:02 by cacharle ### ########.fr */
/* */
/* ************************************************************************** */
@@ -45,7 +45,7 @@ t_image *texture_select(t_state *state, t_render_state *rstate)
}
else if (rstate->side == SIDE_WE)
{
- if (rstate->map_pos.x > state->pos.x)
+ if (rstate->map_pos.x < state->pos.x)
return (state->textures + TEX_WEST);
else
return (state->textures + TEX_EAST);
@@ -70,8 +70,8 @@ int texture_x(t_state *state, t_render_state *rstate, t_image *texture)
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 == SIDE_NS && rstate->ray.x > 0) ||
- (rstate->side == SIDE_WE && rstate->ray.y < 0))
+ if ((rstate->side == SIDE_NS && rstate->ray.y > 0) ||
+ (rstate->side == SIDE_WE && rstate->ray.x < 0))
tex_x = texture->width - tex_x - 1;
return (tex_x);
}
diff --git a/test.cub b/test.cub
index 6324582..ffeda25 100644
--- a/test.cub
+++ b/test.cub
@@ -1,5 +1,16 @@
-11111
-10001
-10001
-10001
-11111
+R 1600 1200
+NO ./textures/eagle.xpm
+SO ./textures/greystone.xpm
+WE ./textures/wood.xpm
+EA ./textures/greystone.xpm
+S ./textures/cheese.xpm
+F 10,10,10
+C 40,40,40
+
+11 1 1 1 1 1 1 1
+10 0 0 1 0 0 0 1
+10 0 0 0 0 0 0 1
+10 0 0 N 0 0 0 1
+10 0 0 0 0 0 0 1
+10 0 0 0 0 0 0 1
+11 1 1 1 1 1 1 1