[TIL] 210118 - cub3d description 파일 파싱하기 3 (42 과제)

seomoon·2021년 1월 18일
0

TIL (Today I Learned)

목록 보기
6/12

Cub3d description 파일 파싱하기

config_resolution() : 화면해상도 설정

int			config_resolution(char *line)
{
	int		i;
	int		x;
	int		y;

	i = 0;
	x = 0;
	y = 0;
	while (is_space(line[i]))
		i++;
	while (ft_isdigit(line[i]))
	{
		x = (x * 10) + (line[i] - '0');
		i++;
	}
	while (is_space(line[i]))
		i++;
	while (ft_isdigit(line[i]))
	{
		y = (y * 10) + (line[i] - '0');
		i++;
	}
	if (line[i] != '\0')
		return (-1);
	else
	{
		info->window->width = x;
		info->window->height = y;
	}
	return (1);
}
  • type identifier R을 만난 경우, config_resolution() 함수가 호출된다.

  • line[i]가 공백인 경우 : 건너뛰기

  • line[i]가 숫자인 동안 x에 10 곱하고 line[i] - '0' 더해 문자열 -> 숫자로 전환하기 (width 구하기)

  • i 값 1 증가시켜 width와 height 사이의 , 건너뛰기

  • line[i]가 숫자인 동안 y에 10 곱하고 line[i] - '0' 더해 문자열 -> 숫자로 전환하기 (height 구하기)

  • 만약 line[i]가 널 문자가 아닌 경우, resolution 형식이 잘못된 것으로 보고 에러(-1) 리턴

  • line[i]가 널 문자가 맞다면, 구한 x값과 y값을 info->window 구조체의 width, height 값을 저장한 뒤
    (+1) 리턴


config_path()

int			config_path(int index, char *line)
{
	int		start;
	int		end;
	char	*path;

	start = 0;
	while (is_space(line[start]))
		start++;
	end = ft_strlen(line);
	path = ft_substr(line, start, end - start);
	if (!path || !file_exists(path))
		return (print_error("Invalid Path"));
	info->path[index] = path;
	return (1);
}
  • sprite / texture path를 설정하는 함수

  • line을 파싱하다가 S 또는 NO, SO, WE, EA type identifier를 만난 경우 실행된다.

  • 매개변수로 받는 indexNO, SO, WE, EA가 각각 인덱스 0, 1, 2, 3 / S가 인덱스 4이다.

  • libft의 ft_substr() 함수로 path 부분만 잘라낸다.

  • path가 NULL이거나 path에 해당하는 파일이 존재하지 않으면 에러를 출력하고 (-1)을 리턴한다.

  • info 구조체의 path 배열에 파싱한 path를 저장한다.


file_exists()

int			file_exists(char *file_name)
{
	int		fd;
	int		len;

	len = ft_strlen(file_name);
	if (!file_name || len == 0)
		return (-1);
	fd = open(file_name, O_RDONLY);
	if (fd == -1)
	{
		close(fd);
		return (-1);
	}
	if (!(file_name[len - 4] == '.' && file_name[len - 3] == 'x' && file_name[len - 2] == 'p' && file_name[len - 1] == 'm'))
		return (-1);
	return (1);
}
  • config_path() 함수에서 path에 해당하는 파일이 존재하는지 여부를 확인하기 위해 호출하는 함수이다.

  • 파일이 존재하지 않거나 파일이름, 형식이 잘못된 경우 -1을 리턴하고 정상적인 파일이라면 1을 리턴한다.

  • file_name이 NULL이거나 길이가 0이면 -1을 리턴한다.

  • open() 함수로 파일을 열고, 파일이 열리지 않고 에러가 발생하면 -1을 리턴한다.

  • 파일 이름이 .xmp로 끝나지 않으면 -1을 리턴한다.


config_color()

int					config_color(char location, char *line)
{
	int				i;
	int				r;
	int				g;
	int				b;
	unsigned int	*color;

	i = 0;
	while (is_space(line[i]))
		i++;
	while (line[i] && ft_isdigit(line[i]))
	{
		r = r * 10 + (line[i] - '0');
		i++;
	}
	i++;
	while (line[i] && ft_isdigit(line[i]))
	{
		g = g * 10 + (line[i] - '0');
		i++;
	}
	i++;
	while (line[i] && ft_isdigit(line[i]))
	{
		b = b * 10 + (line[i] - '0');
		i++;
	}
	color = (r * 256 * 256) + (g * 256) + b;
	if (location == 'F')
		info->floor_colr = color;
	else if (location == 'C')
		info->ceiling_color = color;
	return (1);
}
  • color description 파일 형식 :

    • F 220,100,0
    • C 225,30,0
  • type identifier가 F 또는 C인 경우 config_color() 함수가 호출된다.

  • type identifier 뒤의 공백은 건너뛴다.

  • 숫자 세 개를 순서대로 r, g, b 변수에 저장한다. (문자열 -> int 타입으로 전환)

  • color 값을 계산한다 : (r * 256 * 256) + (g * 256) + b

  • 매개변수로 받은 location(=type identifier)이 F인 경우 floor_color에 저장하고
    C인 경우 ceiling_color에 저장한다.


코드 개선점

  • config_resolution()과 config_color()에서 반복되는 문자열->숫자 전환 부분은 ft_atoi()등의 함수를 만들어서 대체할 수 있을 것 같다. (코드 중복 줄이기)

  • 에러/성공 여부 리턴은 헤더 파일에 따로 SUCCESS 또는 ERROR 값을 상수로 정의해두면 가독성이 더 좋아질 것 같다.

  • 컴파일 되는지 아직 확인을 못해봤다. + 만들어둔 단위테스트가 없어서 전체 프로그램을 완성해야 테스트를 할 수 있다.

profile
안녕하세요

관심 있을 만한 포스트

0개의 댓글