add map parsing and other things
This commit is contained in:
parent
f04587cd62
commit
5bad24dcee
24 changed files with 974 additions and 15 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -35,6 +35,7 @@
|
|||
*.i*86
|
||||
*.x86_64
|
||||
*.hex
|
||||
/cub3D
|
||||
|
||||
# Debug files
|
||||
*.dSYM/
|
||||
|
|
17
.vscode/c_cpp_properties.json
vendored
Normal file
17
.vscode/c_cpp_properties.json
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Linux",
|
||||
"includePath": [
|
||||
"${workspaceFolder}/**"
|
||||
],
|
||||
"defines": [],
|
||||
"compilerPath": "/usr/bin/clang",
|
||||
"cStandard": "c17",
|
||||
"cppStandard": "c++14",
|
||||
"intelliSenseMode": "linux-clang-x64",
|
||||
"configurationProvider": "ms-vscode.makefile-tools"
|
||||
}
|
||||
],
|
||||
"version": 4
|
||||
}
|
5
.vscode/settings.json
vendored
Normal file
5
.vscode/settings.json
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"files.associations": {
|
||||
"util.h": "c"
|
||||
}
|
||||
}
|
14
Makefile
14
Makefile
|
@ -1,6 +1,6 @@
|
|||
NAME = cub3D
|
||||
CPP = gcc -Wall -Wextra -Werror $(FLAGS)
|
||||
C_FILES = $(wildcard *.c)
|
||||
CPP = gcc -Wall -Wextra -Werror -I include $(FLAGS)
|
||||
C_FILES = $(wildcard **/*.c)
|
||||
O_FILES = $(patsubst %.c,%.o,$(C_FILES))
|
||||
|
||||
ECHO = echoo(){ \
|
||||
|
@ -33,14 +33,13 @@ $(NAME) : $(O_FILES)
|
|||
@$(ECHO) "\t\t \e[0;92m\(^o^)/ \e[0;102;30;1m $(NAME) made! \e[0;92m \(^o^)/\e[0m"
|
||||
@$(ECHO)
|
||||
|
||||
%.o : %.cpp
|
||||
%.o : %.c
|
||||
@$(ECHO)
|
||||
@$(ECHO) "\e[30;47;1m $(NAME): making '$@'... \e[0m"
|
||||
$(CPP) $(FLAGS_1) -c $< -o $@
|
||||
|
||||
check_headers :
|
||||
@ERROR=0; \
|
||||
echo $(wildcard **/*.h); \
|
||||
for HEADER in $(wildcard **/*.h); \
|
||||
do \
|
||||
echo "check header $$HEADER..."; \
|
||||
|
@ -51,13 +50,12 @@ check_headers :
|
|||
if [ $$? -ne 0 ]; \
|
||||
then \
|
||||
ERROR=1; \
|
||||
echo error \
|
||||
break; \
|
||||
echo " error \e[31m:(\e[0m"; \
|
||||
fi; \
|
||||
echo "good :)"; \
|
||||
echo " good \e[32m:)\e[0m"; \
|
||||
2> /dev/null rm -- "__tmp_check_header.out" "__tmp_check_header.c"; \
|
||||
done; \
|
||||
2> /dev/null rm __tmp_check_header.out __tmp_check_header.c; \
|
||||
if [ $$ERROR -eq 0 ]; then true; else false; fi;
|
||||
|
||||
.PHONY : all clean fclean re check_headers
|
||||
.PHONY : all clean fclean re check_headers
|
||||
|
|
21
dev/cub.vim
Normal file
21
dev/cub.vim
Normal file
|
@ -0,0 +1,21 @@
|
|||
function! CubSyntax()
|
||||
if expand('%:e') == 'cub'
|
||||
|
||||
highlight cubParameter ctermfg=blue
|
||||
syntax match cubParameter /^(NO|SO|WE|EA|F|C) .$/
|
||||
|
||||
highlight cubDefault ctermfg=white
|
||||
syntax match cubDefault /./
|
||||
|
||||
highlight cub0 ctermfg=grey
|
||||
syntax match cub0 /0/
|
||||
|
||||
highlight cub1 cterm=bold ctermfg=white
|
||||
syntax match cub1 /1/
|
||||
|
||||
highlight cubP cterm=bold ctermfg=blue
|
||||
syntax match cubP /[NSWE]/
|
||||
|
||||
endif
|
||||
endfunction
|
||||
autocmd BufReadPost * call CubSyntax()
|
30
include/color.h
Normal file
30
include/color.h
Normal file
|
@ -0,0 +1,30 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* color.h :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: mcolonna <mcolonna@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/10/01 16:25:50 by mcolonna #+# #+# */
|
||||
/* Updated: 2024/10/02 15:41:43 by mcolonna ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#ifndef COLOR_H
|
||||
# define COLOR_H
|
||||
|
||||
# include <linux/types.h>
|
||||
|
||||
// TODO Must the transparency be 0 or 255?
|
||||
/// @brief Represents an TRGB color in 0xTTRRGGBB format.
|
||||
typedef __u32 t_color;
|
||||
|
||||
/// @brief Convert a color from each color value to a t_color.
|
||||
///
|
||||
/// @param red Level of red from 0 to 255.
|
||||
/// @param green Level of green from 0 to 255.
|
||||
/// @param blue Level of blue from 0 to 255.
|
||||
/// @return The result.
|
||||
t_color color_from_rgb(int red, int green, int blue);
|
||||
|
||||
#endif
|
|
@ -6,13 +6,16 @@
|
|||
/* By: mcolonna <mcolonna@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/10/01 13:59:04 by mcolonna #+# #+# */
|
||||
/* Updated: 2024/10/01 14:00:40 by mcolonna ### ########.fr */
|
||||
/* Updated: 2024/10/04 13:13:04 by mcolonna ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#ifndef MAP_H
|
||||
# define MAP_H
|
||||
|
||||
# include <stdbool.h>
|
||||
# include "color.h"
|
||||
|
||||
/// @brief The type of a case.
|
||||
typedef enum e_map_wall
|
||||
{
|
||||
|
@ -26,14 +29,20 @@ typedef enum e_map_wall
|
|||
typedef struct s_object
|
||||
{
|
||||
/// @brief Function called when creating the object.
|
||||
///
|
||||
/// @param data Address of the s_object.data pointer.
|
||||
void (*init)(void **data);
|
||||
/// @brief Function called when destroying the object (to free everything).
|
||||
|
||||
/// @brief Function called when destroying the object (to avoid leaks).
|
||||
///
|
||||
/// @param data Address of the s_object.data pointer.
|
||||
void (*destroy)(void **data);
|
||||
|
||||
/// @brief Function called each tick.
|
||||
///
|
||||
/// @param data Address of the s_object.data pointer.
|
||||
void (*tick)(void **data);
|
||||
|
||||
/// @brief Pointer the object can use to save data.
|
||||
void *data;
|
||||
} t_object;
|
||||
|
@ -43,6 +52,7 @@ typedef struct s_map_case
|
|||
{
|
||||
/// @brief Is the case empty or a wall?
|
||||
t_map_wall wall;
|
||||
|
||||
/// @brief The object that appears on this case. If there is none,
|
||||
/// every pointer of the struct will be NULL.
|
||||
t_object object;
|
||||
|
@ -51,14 +61,46 @@ typedef struct s_map_case
|
|||
/// @brief Represents a map.
|
||||
typedef struct s_map
|
||||
{
|
||||
/// @brief Color of the floor.
|
||||
t_color color_floor;
|
||||
|
||||
/// @brief Color of the ceiling.
|
||||
t_color color_ceiling;
|
||||
|
||||
/// @brief Path to the image file for the wall face north.
|
||||
const char *texture_north;
|
||||
|
||||
/// @brief Path to the image file for the wall face south.
|
||||
const char *texture_south;
|
||||
|
||||
/// @brief Path to the image file for the wall face west.
|
||||
const char *texture_west;
|
||||
|
||||
/// @brief Path to the image file for the wall face east.
|
||||
const char *texture_east;
|
||||
|
||||
/// @brief Width of the map.
|
||||
int width;
|
||||
unsigned int width;
|
||||
|
||||
/// @brief Height of the map.
|
||||
int height;
|
||||
unsigned int height;
|
||||
|
||||
/// @brief An 2D array of all the cases.
|
||||
/// Syntax to get a case: cases[y][x]
|
||||
///
|
||||
/// Syntax to get a case: cases[y * width + x]
|
||||
/// x is left to right, y is top to bottom.
|
||||
t_map_case **cases;
|
||||
t_map_case *cases;
|
||||
} t_map;
|
||||
|
||||
#endif
|
||||
/// @brief Create a t_map from the content of a .cub file.
|
||||
///
|
||||
/// @param dest Pointer to the t_map to set.
|
||||
/// @param file .cub file to use to create the t_map.
|
||||
/// It must be destroyed with mapDestroy to avoid leaks.
|
||||
/// @return false if an error occured, otherwise true.
|
||||
bool map_from_file(t_map *dest, const char *file);
|
||||
|
||||
/// @brief Destroy the map to avoid leaks.
|
||||
void map_destroy(t_map *map);
|
||||
|
||||
#endif
|
||||
|
|
31
include/map_mapping.h
Normal file
31
include/map_mapping.h
Normal file
|
@ -0,0 +1,31 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* map_mapping.h :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: mcolonna <mcolonna@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/10/04 12:00:07 by mcolonna #+# #+# */
|
||||
/* Updated: 2024/10/04 15:24:14 by mcolonna ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#ifndef MAP_MAPPING_H
|
||||
# define MAP_MAPPING_H
|
||||
|
||||
# include "map.h"
|
||||
|
||||
/// @brief Each element of g_map_mapping. A case and its associated char.
|
||||
typedef struct s_map_mapping_element
|
||||
{
|
||||
/// @brief char representing the case.
|
||||
char name;
|
||||
/// @brief associated case.
|
||||
t_map_case value;
|
||||
} t_map_mapping_element;
|
||||
|
||||
/// @brief List of each char and its according case.
|
||||
/// Ended by an element with the name '\0'.
|
||||
extern const t_map_mapping_element g_map_mapping[];
|
||||
|
||||
#endif
|
29
include/read_all_text.h
Normal file
29
include/read_all_text.h
Normal file
|
@ -0,0 +1,29 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* read_all_text.h :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: mcolonna <mcolonna@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/10/02 15:39:02 by mcolonna #+# #+# */
|
||||
/* Updated: 2024/10/02 17:04:33 by mcolonna ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#ifndef READ_ALL_TEXT_H
|
||||
# define READ_ALL_TEXT_H
|
||||
|
||||
/// @brief Size of buffer used in read_all_text().
|
||||
# define BUFFER_SIZE 1000
|
||||
|
||||
/// @brief Read all the text of the given file.
|
||||
///
|
||||
/// If the last line isn't ended by a '\\n', add one.
|
||||
///
|
||||
/// If error, returns NULL and set errno accordingly.
|
||||
///
|
||||
/// @param fd File descriptor of the file.
|
||||
/// @return Alloc'd string of the file content. NULL if error.
|
||||
char *read_all_text(int fd);
|
||||
|
||||
#endif
|
54
include/stream.h
Normal file
54
include/stream.h
Normal file
|
@ -0,0 +1,54 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* stream.h :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: mcolonna <mcolonna@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/10/02 12:33:25 by mcolonna #+# #+# */
|
||||
/* Updated: 2024/10/02 16:14:23 by mcolonna ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#ifndef STREAM_H
|
||||
# define STREAM_H
|
||||
|
||||
# include <stdbool.h>
|
||||
|
||||
/// @brief Represents a string and an associated cursor.
|
||||
typedef struct s_stream
|
||||
{
|
||||
/// @brief Index of the cursor.
|
||||
int i;
|
||||
|
||||
/// @brief Pointer to the string.
|
||||
const char *str;
|
||||
} t_stream;
|
||||
|
||||
/// @brief Read a specific string, error if it isn't the expected string.
|
||||
///
|
||||
/// @param str Expected string.
|
||||
/// @param stream Stream to use.
|
||||
/// @param err Set to true if an error occured.
|
||||
/// If already true, the function won't do anything.
|
||||
void read_expected_string(const char *str, t_stream *stream, bool *err);
|
||||
|
||||
/// @brief Read an unsigned int (which fits the pattern /[0-9]+/).
|
||||
///
|
||||
/// @param dest Will be set to the value of the unsigned integer.
|
||||
/// @param stream Stream to use.
|
||||
/// @param err Set to true if an error occured.
|
||||
/// If already true, the function won't do anything.
|
||||
void read_unsigned(unsigned int *dest, t_stream *stream, bool *err);
|
||||
|
||||
/// @brief Read a string until limit char or \0.
|
||||
///
|
||||
/// @param c Limit char.
|
||||
/// @param dest Will be set to an alloc'd pointer to the read string.
|
||||
/// NULL if alloc error.
|
||||
/// @param stream Stream to use.
|
||||
/// @param err Set to true if an error occured.
|
||||
/// If already true, the function won't do anything.
|
||||
void read_until(char c, char **dest, t_stream *stream, bool *err);
|
||||
|
||||
#endif
|
24
include/util.h
Normal file
24
include/util.h
Normal file
|
@ -0,0 +1,24 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* util.h :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: mcolonna <mcolonna@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/10/03 14:19:03 by mc #+# #+# */
|
||||
/* Updated: 2024/10/04 15:27:07 by mcolonna ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#ifndef UTIL_H
|
||||
# define UTIL_H
|
||||
|
||||
/// @brief Get the length of a string.
|
||||
int getlen(const char *str);
|
||||
|
||||
/// @brief Write an error message on stderr.
|
||||
///
|
||||
/// @param str... All the strings to write. The last parameter MUST BE NULL.
|
||||
void write_err(const char *str, ...);
|
||||
|
||||
#endif
|
18
src/color.c
Normal file
18
src/color.c
Normal file
|
@ -0,0 +1,18 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* color.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: mcolonna <mcolonna@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/10/01 17:04:56 by mcolonna #+# #+# */
|
||||
/* Updated: 2024/10/02 14:27:53 by mcolonna ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "color.h"
|
||||
|
||||
t_color color_from_rgb(int red, int green, int blue)
|
||||
{
|
||||
return (red << 16 | green << 8 | blue);
|
||||
}
|
34
src/main.c
Normal file
34
src/main.c
Normal file
|
@ -0,0 +1,34 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* main.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: mcolonna <mcolonna@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/10/02 15:45:49 by mcolonna #+# #+# */
|
||||
/* Updated: 2024/10/04 15:10:50 by mcolonna ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "map.h"
|
||||
#include <stdio.h>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
t_map map;
|
||||
bool success;
|
||||
|
||||
if (argc != 2)
|
||||
{
|
||||
printf(":(\n");
|
||||
return (1);
|
||||
}
|
||||
success = map_from_file(&map, argv[1]);
|
||||
printf("--> Success: %i <--\n", success);
|
||||
if (success)
|
||||
printf("C 0x%08x\nF 0x%08x\nEA %s\nWE %s\nNO %s\nSO %s\n",
|
||||
map.color_ceiling, map.color_floor,
|
||||
map.texture_east, map.texture_west,
|
||||
map.texture_north, map.texture_south);
|
||||
map_destroy(&map);
|
||||
}
|
55
src/map.c
Normal file
55
src/map.c
Normal file
|
@ -0,0 +1,55 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* map.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: mcolonna <mcolonna@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/10/01 17:12:58 by mcolonna #+# #+# */
|
||||
/* Updated: 2024/10/04 15:25:32 by mcolonna ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "map.h"
|
||||
#include "map_utils.h"
|
||||
#include "stream.h"
|
||||
#include "read_all_text.h"
|
||||
#include <util.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
bool map_from_file(t_map *dest, const char *file)
|
||||
{
|
||||
int fd;
|
||||
t_stream stream;
|
||||
bool err;
|
||||
|
||||
fd = open(file, O_RDONLY);
|
||||
if (fd < 0)
|
||||
{
|
||||
write_err("Can't open '", file, "': ", strerror(errno), "\n",
|
||||
NULL);
|
||||
return (false);
|
||||
}
|
||||
stream.str = read_all_text(fd);
|
||||
if (!stream.str)
|
||||
{
|
||||
write_err("Can't read file.\n", NULL);
|
||||
return (false);
|
||||
}
|
||||
stream.i = 0;
|
||||
err = read_map(dest, &stream);
|
||||
free((void *)stream.str);
|
||||
return (err);
|
||||
}
|
||||
|
||||
void map_destroy(t_map *map)
|
||||
{
|
||||
free((void *)map->texture_east);
|
||||
free((void *)map->texture_west);
|
||||
free((void *)map->texture_north);
|
||||
free((void *)map->texture_south);
|
||||
free(map->cases);
|
||||
}
|
24
src/map_mapping.c
Normal file
24
src/map_mapping.c
Normal file
|
@ -0,0 +1,24 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* map_mapping.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: mcolonna <mcolonna@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/10/04 12:05:21 by mcolonna #+# #+# */
|
||||
/* Updated: 2024/10/04 15:23:28 by mcolonna ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "map_mapping.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
const t_map_mapping_element g_map_mapping[] = {
|
||||
{' ', {EMPTY, {NULL, NULL, NULL, NULL}}},
|
||||
{'0', {EMPTY, {NULL, NULL, NULL, NULL}}},
|
||||
{'1', {WALL, {NULL, NULL, NULL, NULL}}},
|
||||
{'N', {EMPTY, {NULL, NULL, NULL, NULL}}}, // TODO add player object
|
||||
{'S', {EMPTY, {NULL, NULL, NULL, NULL}}}, // --
|
||||
{'E', {EMPTY, {NULL, NULL, NULL, NULL}}}, // --
|
||||
{'W', {EMPTY, {NULL, NULL, NULL, NULL}}}, // --
|
||||
{'\0', {EMPTY, {NULL, NULL, NULL, NULL}}}};
|
80
src/map_utils.h
Normal file
80
src/map_utils.h
Normal file
|
@ -0,0 +1,80 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* map_utils.h :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: mcolonna <mcolonna@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/10/03 15:05:13 by mc #+# #+# */
|
||||
/* Updated: 2024/10/04 15:30:03 by mcolonna ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#ifndef MAP_UTILS_H
|
||||
# define MAP_UTILS_H
|
||||
|
||||
# include "color.h"
|
||||
# include "stream.h"
|
||||
# include "map.h"
|
||||
# include <stdbool.h>
|
||||
# include <stddef.h>
|
||||
|
||||
/// @brief Read a parameter of the map which has a color as an argument.
|
||||
/// Color format: [0-255],[0-255],[0-255]
|
||||
/// @param name Name of the parameter.
|
||||
/// @param dest Will be set to the value of the parameter.
|
||||
/// Unchanged if error.
|
||||
/// If success but *dest is not 0xFF000000, throws an error.
|
||||
/// @param stream Stream to use.
|
||||
/// Unchanged if error.
|
||||
/// @param redefined Set to true if the parameter was already defined.
|
||||
/// @return true if success or redefined, false if non-fatal error.
|
||||
bool read_color_parameter(const char *name, t_color *dest,
|
||||
t_stream *stream, bool *redefined);
|
||||
|
||||
/// @brief Read a parameter of the map which has a string as an argument.
|
||||
/// @param name Name of the parameter.
|
||||
/// @param dest Will be set to an alloc'd pointer to the value of the parameter.
|
||||
/// Unchanged if error.
|
||||
/// If success but *dest is not null, throws an error.
|
||||
/// @param stream Stream to use.
|
||||
/// Unchanged if error.
|
||||
/// @param redefined Set to true if the parameter was already defined.
|
||||
/// @return true if success or redefined, false if non-fatal error.
|
||||
bool read_string_parameter(const char *name, const char **dest,
|
||||
t_stream *stream, bool *redefined);
|
||||
|
||||
/// @brief Set the map to initial values. Every texture becomes NULL
|
||||
/// and every color becomes 0xFF000000.
|
||||
/// @param dest Map to reset.
|
||||
void reset_map(t_map *dest);
|
||||
|
||||
/// @brief Read a map-formatted string.
|
||||
/// If an error occurs, write an error message on stderr.
|
||||
/// @param dest Will be set to the map.
|
||||
/// @param stream Stream to use.
|
||||
/// @return true if success, false if error.
|
||||
bool read_map(t_map *dest, t_stream *stream);
|
||||
|
||||
/// @brief Get the case associated with the char.
|
||||
///
|
||||
/// @param dest Will be set to the char.
|
||||
/// @param name Name of the case.
|
||||
/// @return true if success, false if error.
|
||||
bool get_case(t_map_case *dest, char name);
|
||||
|
||||
/// @brief Fill the pointer with 'size' null bytes.
|
||||
///
|
||||
/// @param dest The pointer to set.
|
||||
/// @param size The number of bytes.
|
||||
void fill_zeros(void *dest, size_t size);
|
||||
|
||||
/// @brief Read the map description part of the map.
|
||||
/// Read until the end of the file.
|
||||
///
|
||||
/// @param map The .width, .height and .cases members will be set.
|
||||
/// @param stream Stream to use.
|
||||
/// @return true if success, false if error.
|
||||
bool read_map_description(t_map *map, t_stream *stream);
|
||||
|
||||
#endif
|
116
src/map_utils1.c
Normal file
116
src/map_utils1.c
Normal file
|
@ -0,0 +1,116 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* map_utils1.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: mcolonna <mcolonna@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/10/03 15:02:09 by mc #+# #+# */
|
||||
/* Updated: 2024/10/04 15:28:06 by mcolonna ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "map_utils.h"
|
||||
#include "util.h"
|
||||
#include "map_mapping.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
bool read_color_parameter(const char *name, t_color *dest,
|
||||
t_stream *stream, bool *redefined)
|
||||
{
|
||||
unsigned int rgb[3];
|
||||
bool err;
|
||||
t_stream old;
|
||||
|
||||
old = *stream;
|
||||
err = false;
|
||||
read_expected_string(name, stream, &err);
|
||||
read_expected_string(" ", stream, &err);
|
||||
read_unsigned(&rgb[0], stream, &err);
|
||||
read_expected_string(",", stream, &err);
|
||||
read_unsigned(&rgb[1], stream, &err);
|
||||
read_expected_string(",", stream, &err);
|
||||
read_unsigned(&rgb[2], stream, &err);
|
||||
read_expected_string("\n", stream, &err);
|
||||
if (!err && *dest != 0xFF000000)
|
||||
{
|
||||
*redefined = true;
|
||||
write_err("Parameter '", name, "' was defined several times\n",
|
||||
NULL);
|
||||
}
|
||||
else if (!err)
|
||||
*dest = color_from_rgb(rgb[0], rgb[1], rgb[2]);
|
||||
else
|
||||
*stream = old;
|
||||
return (!err);
|
||||
}
|
||||
|
||||
bool read_string_parameter(const char *name, const char **dest,
|
||||
t_stream *stream, bool *redefined)
|
||||
{
|
||||
char *r;
|
||||
bool err;
|
||||
t_stream old;
|
||||
|
||||
old = *stream;
|
||||
err = false;
|
||||
r = NULL;
|
||||
read_expected_string(name, stream, &err);
|
||||
read_expected_string(" ", stream, &err);
|
||||
read_until('\n', &r, stream, &err);
|
||||
read_expected_string("\n", stream, &err);
|
||||
if (!err && *dest)
|
||||
{
|
||||
*redefined = true;
|
||||
write_err("Parameter '", name, "' was defined several times\n",
|
||||
NULL);
|
||||
}
|
||||
if (err || (!err && *dest))
|
||||
{
|
||||
*stream = old;
|
||||
free(r);
|
||||
}
|
||||
else
|
||||
*dest = r;
|
||||
return (!err);
|
||||
}
|
||||
|
||||
void reset_map(t_map *dest)
|
||||
{
|
||||
dest->cases = NULL;
|
||||
dest->color_ceiling = 0xFF000000;
|
||||
dest->color_floor = 0xFF000000;
|
||||
dest->texture_east = NULL;
|
||||
dest->texture_west = NULL;
|
||||
dest->texture_north = NULL;
|
||||
dest->texture_south = NULL;
|
||||
}
|
||||
|
||||
bool read_map(t_map *dest, t_stream *stream)
|
||||
{
|
||||
bool err;
|
||||
bool rdf;
|
||||
|
||||
reset_map(dest);
|
||||
err = false;
|
||||
rdf = false;
|
||||
while (!rdf && !err && stream->str[stream->i])
|
||||
{
|
||||
if (true
|
||||
&& (read_expected_string("\n", stream, &err), err)
|
||||
&& !read_string_parameter("NO", &dest->texture_north, stream, &rdf)
|
||||
&& !read_string_parameter("SO", &dest->texture_south, stream, &rdf)
|
||||
&& !read_string_parameter("WE", &dest->texture_west, stream, &rdf)
|
||||
&& !read_string_parameter("EA", &dest->texture_east, stream, &rdf)
|
||||
&& !read_color_parameter("F", &dest->color_floor, stream, &rdf)
|
||||
&& !read_color_parameter("C", &dest->color_ceiling, stream, &rdf))
|
||||
{
|
||||
err = !read_map_description(dest, stream);
|
||||
return (!err);
|
||||
}
|
||||
err = false;
|
||||
}
|
||||
if (!rdf && !dest->cases)
|
||||
write_err("Map description missing\n", NULL);
|
||||
return (!err && !rdf && dest->cases);
|
||||
}
|
105
src/map_utils2.c
Normal file
105
src/map_utils2.c
Normal file
|
@ -0,0 +1,105 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* map_utils2.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: mcolonna <mcolonna@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/10/04 15:12:08 by mcolonna #+# #+# */
|
||||
/* Updated: 2024/10/04 15:25:52 by mcolonna ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "map_utils.h"
|
||||
#include "map_mapping.h"
|
||||
#include "util.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
/// @brief Read the map description to get the dimensions.
|
||||
/// The map must be at least 1x1.
|
||||
///
|
||||
/// @param map The .width and .height members will be set.
|
||||
/// @param stream Stream to use.
|
||||
/// @return true if success, false if error.
|
||||
static bool get_map_dimensions(t_map *map, t_stream *stream)
|
||||
{
|
||||
unsigned int x;
|
||||
unsigned int y;
|
||||
|
||||
map->width = 0;
|
||||
map->height = 0;
|
||||
y = 0;
|
||||
while (stream->str[stream->i])
|
||||
{
|
||||
x = 0;
|
||||
while (stream->str[stream->i] && stream->str[stream->i] != '\n')
|
||||
{
|
||||
stream->i++;
|
||||
x++;
|
||||
}
|
||||
if (x > map->width)
|
||||
map->width = x;
|
||||
if (stream->str[stream->i] == '\n')
|
||||
stream->i++;
|
||||
y++;
|
||||
}
|
||||
map->height = y;
|
||||
return (map->width > 0 && map->height > 0);
|
||||
}
|
||||
|
||||
bool get_case(t_map_case *dest, char name)
|
||||
{
|
||||
int i;
|
||||
char tmp[2];
|
||||
|
||||
i = -1;
|
||||
while (g_map_mapping[++i].name)
|
||||
{
|
||||
if (name == g_map_mapping[i].name)
|
||||
{
|
||||
*dest = g_map_mapping[i].value;
|
||||
return (true);
|
||||
}
|
||||
}
|
||||
tmp[0] = name;
|
||||
tmp[1] = '\0';
|
||||
write_err("Character '", tmp, "' unexpected\n", NULL);
|
||||
return (false);
|
||||
}
|
||||
|
||||
void fill_zeros(void *dest, size_t size)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
i = -1;
|
||||
while (++i < size)
|
||||
((char *)dest)[i] = '\0';
|
||||
}
|
||||
|
||||
bool read_map_description(t_map *map, t_stream *stream)
|
||||
{
|
||||
t_stream stream2;
|
||||
unsigned int x;
|
||||
unsigned int y;
|
||||
|
||||
stream2 = *stream;
|
||||
if (!get_map_dimensions(map, &stream2))
|
||||
return (false);
|
||||
map->cases = malloc((map->width * map->height) * sizeof(t_map_case));
|
||||
y = -1;
|
||||
fill_zeros(map->cases, (map->width * map->height) * sizeof(t_map_case));
|
||||
while (++y < map->height)
|
||||
{
|
||||
x = 0;
|
||||
while (stream->str[stream->i] && stream->str[stream->i] != '\n')
|
||||
{
|
||||
if (!get_case(&map->cases[y * map->width + x],
|
||||
stream->str[stream->i]))
|
||||
return (false);
|
||||
stream->i++;
|
||||
x++;
|
||||
}
|
||||
stream->i++;
|
||||
}
|
||||
return (true);
|
||||
}
|
94
src/read_all_text.c
Normal file
94
src/read_all_text.c
Normal file
|
@ -0,0 +1,94 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* read_all_text.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: mc <mc@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/10/02 16:18:35 by mcolonna #+# #+# */
|
||||
/* Updated: 2024/10/03 14:20:37 by mc ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "read_all_text.h"
|
||||
#include "util.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/// @brief Concatenate *dest and src and put the result in *dest.
|
||||
///
|
||||
/// *dest is alloc'd to contain the result value.
|
||||
///
|
||||
/// the old *dest is freed only if the function succeds.
|
||||
///
|
||||
/// src doesn't have to be nul-terminated, instead n is the size of src.
|
||||
///
|
||||
/// @return true if success, false if error.
|
||||
static bool strconcat(char **dest, char *src, int n)
|
||||
{
|
||||
const int len_dest = getlen(*dest);
|
||||
char *old_dest;
|
||||
int i;
|
||||
|
||||
old_dest = *dest;
|
||||
*dest = malloc((len_dest + n + 1) * sizeof(char));
|
||||
if (!*dest)
|
||||
return (false);
|
||||
i = -1;
|
||||
while (old_dest[++i])
|
||||
(*dest)[i] = old_dest[i];
|
||||
while (i < len_dest + n)
|
||||
{
|
||||
(*dest)[i] = src[i - len_dest];
|
||||
i++;
|
||||
}
|
||||
(*dest)[i] = '\0';
|
||||
free(old_dest);
|
||||
return (true);
|
||||
}
|
||||
|
||||
/// @brief If the string isn't empty and isn't ended by a '\\n', add one and
|
||||
/// return the result.
|
||||
///
|
||||
/// str is either returned directly, or another freeable pointer is returned
|
||||
/// and str is freed.
|
||||
///
|
||||
/// @return Return the result or NULL if error.
|
||||
static char *add_endline_if_necessary(char *str)
|
||||
{
|
||||
char *endline;
|
||||
|
||||
if (str[0] == '\0' || str[getlen(str) - 1] == '\n')
|
||||
return (str);
|
||||
endline = malloc(1 * sizeof(char));
|
||||
if (!endline)
|
||||
return (free(str), NULL);
|
||||
endline[0] = '\n';
|
||||
if (!strconcat(&str, endline, 1))
|
||||
return (free(str), NULL);
|
||||
return (str);
|
||||
}
|
||||
|
||||
char *read_all_text(int fd)
|
||||
{
|
||||
char buf[BUFFER_SIZE];
|
||||
int n;
|
||||
char *r;
|
||||
|
||||
r = malloc(sizeof(char));
|
||||
if (!r)
|
||||
return (NULL);
|
||||
r[0] = '\0';
|
||||
n = 1;
|
||||
while (n)
|
||||
{
|
||||
n = read(fd, buf, BUFFER_SIZE);
|
||||
if (n < 0 || (n && !strconcat(&r, buf, n)))
|
||||
{
|
||||
free(r);
|
||||
return (NULL);
|
||||
}
|
||||
}
|
||||
return (add_endline_if_necessary(r));
|
||||
}
|
89
src/stream.c
Normal file
89
src/stream.c
Normal file
|
@ -0,0 +1,89 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* stream.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: mcolonna <mcolonna@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/10/02 14:08:10 by mcolonna #+# #+# */
|
||||
/* Updated: 2024/10/02 17:31:34 by mcolonna ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "stream.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
void read_expected_string(const char *str, t_stream *stream, bool *err)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (*err)
|
||||
return ;
|
||||
i = 0;
|
||||
while (str[i])
|
||||
{
|
||||
if (str[i] != stream->str[stream->i])
|
||||
{
|
||||
*err = true;
|
||||
return ;
|
||||
}
|
||||
i++;
|
||||
stream->i++;
|
||||
}
|
||||
return ;
|
||||
}
|
||||
|
||||
/// @brief Check if a character is a digit.
|
||||
/// @param c Character to check.
|
||||
/// @return true if the character is a digit, false if not.
|
||||
/// false if the character is '\0'.
|
||||
static bool is_digit(char c)
|
||||
{
|
||||
return (c >= '0' && c <= '9');
|
||||
}
|
||||
|
||||
void read_unsigned(unsigned int *dest, t_stream *stream, bool *err)
|
||||
{
|
||||
int r;
|
||||
|
||||
if (*err)
|
||||
return ;
|
||||
if (!is_digit(stream->str[stream->i]))
|
||||
{
|
||||
*err = true;
|
||||
return ;
|
||||
}
|
||||
r = 0;
|
||||
while (is_digit(stream->str[stream->i]))
|
||||
{
|
||||
r = r * 10 + stream->str[stream->i] - '0';
|
||||
stream->i++;
|
||||
}
|
||||
*dest = r;
|
||||
}
|
||||
|
||||
void read_until(char c, char **dest, t_stream *stream, bool *err)
|
||||
{
|
||||
int len;
|
||||
int i;
|
||||
|
||||
if (*err)
|
||||
return ;
|
||||
len = 0;
|
||||
while (stream->str[stream->i + len] && stream->str[stream->i + len] != c)
|
||||
len++;
|
||||
*dest = malloc((len + 1) * sizeof(char));
|
||||
if (!*dest)
|
||||
{
|
||||
*err = true;
|
||||
return ;
|
||||
}
|
||||
i = 0;
|
||||
while (stream->str[stream->i] && stream->str[stream->i] != c)
|
||||
{
|
||||
(*dest)[i] = stream->str[stream->i];
|
||||
i++;
|
||||
stream->i++;
|
||||
}
|
||||
(*dest)[i] = '\0';
|
||||
}
|
38
src/util.c
Normal file
38
src/util.c
Normal file
|
@ -0,0 +1,38 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* util.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: mcolonna <mcolonna@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/10/03 14:19:38 by mc #+# #+# */
|
||||
/* Updated: 2024/10/04 15:26:32 by mcolonna ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "util.h"
|
||||
#include <stdarg.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int getlen(const char *str)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = 0;
|
||||
while (str[i])
|
||||
i++;
|
||||
return (i);
|
||||
}
|
||||
|
||||
void write_err(const char *str, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start(args, str);
|
||||
write(2, "Error\n", 6);
|
||||
while (str)
|
||||
{
|
||||
write(2, str, getlen(str));
|
||||
str = va_arg(args, const char *);
|
||||
}
|
||||
}
|
19
testmaps/hdhd.cub
Normal file
19
testmaps/hdhd.cub
Normal file
|
@ -0,0 +1,19 @@
|
|||
|
||||
|
||||
F 255,127,0
|
||||
|
||||
EA eastimage
|
||||
|
||||
|
||||
|
||||
NO theimageforthenorthwall
|
||||
C 0,2,67
|
||||
|
||||
SO SOUTH!!!!!!1
|
||||
SO jde:
|
||||
|
||||
WE weeeee
|
||||
|
||||
|
||||
|
||||
SO south2
|
15
testmaps/idid.cub
Normal file
15
testmaps/idid.cub
Normal file
|
@ -0,0 +1,15 @@
|
|||
F 255,127,0
|
||||
|
||||
EA eastimage
|
||||
|
||||
NO theimageforthenorthwall
|
||||
C 0,2,67
|
||||
|
||||
SO SOUTH!!!!!!1
|
||||
|
||||
WE weeeee
|
||||
|
||||
|
||||
|
||||
|
||||
|
20
testmaps/jdjd.cub
Normal file
20
testmaps/jdjd.cub
Normal file
|
@ -0,0 +1,20 @@
|
|||
F 255,127,0
|
||||
|
||||
EA eastimage
|
||||
|
||||
NO theimageforthenorthwall
|
||||
C 0,2,67
|
||||
|
||||
SO SOUTH!!!!!!1
|
||||
|
||||
WE weeeee
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
1111111
|
||||
1000001
|
||||
10W0001
|
||||
1000001
|
||||
1111111
|
Loading…
Add table
Reference in a new issue