feat: raycasting functionnal

This commit is contained in:
Raphael 2024-11-27 16:10:31 +01:00
parent a3b0d266bb
commit 9ae3eb011f
19 changed files with 1183 additions and 101 deletions

BIN
Cub3D 2 Executable file

Binary file not shown.

View file

@ -6,7 +6,7 @@
# By: rparodi <rparodi@student.42.fr> +#+ +:+ +#+ # # By: rparodi <rparodi@student.42.fr> +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ # # +#+#+#+#+#+ +#+ #
# Created: 2023/11/12 11:05:05 by rparodi #+# #+# # # Created: 2023/11/12 11:05:05 by rparodi #+# #+# #
# Updated: 2024/11/23 12:41:29 by rparodi ### ########.fr # # Updated: 2024/11/27 16:05:42 by rparodi ### ########.fr #
# # # #
# **************************************************************************** # # **************************************************************************** #
@ -26,8 +26,8 @@ CFLAGS += -g3 -MMD
# CFLAGS += -fsanitize=address # CFLAGS += -fsanitize=address
# CFLAGS += -fsanitize=thread # CFLAGS += -fsanitize=thread
# INCLUDES += -I /opt/X11/include INCLUDES += -I /opt/X11/include
INCLUDES = -I /usr/include -I ./includes -I ./includes/include -I ./minilibx-linux INCLUDES = -I ./includes -I ./includes/include -I ./minilibx-linux
# Paths # Paths
LIBFT_DIR = ./libft LIBFT_DIR = ./libft
@ -37,8 +37,8 @@ MLX_DIR = ./minilibx-linux
LDFLAGS = -L./build -lft -lm LDFLAGS = -L./build -lft -lm
# MiniLibX flags for macOS with XQuartz # MiniLibX flags for macOS with XQuartz
MLXFLAGS = -L$(MLX_DIR) -lmlx -lX11 -lXext -lXrender -lXrandr -lXi MLXFLAGS = -L$(MLX_DIR) -lmlx -lX11 -lXext
#MLXFLAGS += -L/opt/X11/lib MLXFLAGS += -L/opt/X11/lib
# Add MLXFLAGS to the linker flags # Add MLXFLAGS to the linker flags
LDFLAGS += $(MLXFLAGS) LDFLAGS += $(MLXFLAGS)

1
Makefile.gen Normal file
View file

@ -0,0 +1 @@
INC=/usr/X11/include

View file

@ -6,7 +6,7 @@
/* By: rparodi <rparodi@student.42.fr> +#+ +:+ +#+ */ /* By: rparodi <rparodi@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2024/10/30 16:30:26 by rparodi #+# #+# */ /* Created: 2024/10/30 16:30:26 by rparodi #+# #+# */
/* Updated: 2024/11/20 13:55:10 by rparodi ### ########.fr */ /* Updated: 2024/11/26 13:37:20 by rparodi ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@ -38,5 +38,6 @@ void parse_map(t_info *info);
void parse_args(char *arg, t_info *inf); void parse_args(char *arg, t_info *inf);
int main(int argc, char *argv[]); int main(int argc, char *argv[]);
void shelves_launch(t_info *info);
#endif /* CUB3D_H */ #endif /* CUB3D_H */

View file

@ -6,7 +6,7 @@
/* By: bgoulard <bgoulard@student.42.fr> +#+ +:+ +#+ */ /* By: bgoulard <bgoulard@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2024/11/08 23:55:29 by bgoulard #+# #+# */ /* Created: 2024/11/08 23:55:29 by bgoulard #+# #+# */
/* Updated: 2024/11/20 15:13:28 by rparodi ### ########.fr */ /* Updated: 2024/11/26 13:35:13 by rparodi ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@ -19,6 +19,8 @@
# define FILE_EXTENSION ".cub" # define FILE_EXTENSION ".cub"
# define FILE_EXTENSION_LEN 4 # define FILE_EXTENSION_LEN 4
#define FOV 65
#define TILE_SIZE 64
// -- graphic utils // -- graphic utils
typedef struct s_color typedef struct s_color

View file

@ -1,4 +0,0 @@
src/ft_string/ft_chr/ft_putchar_fd.c:17:2: error: ignoring return value of function declared with 'warn_unused_result' attribute [-Werror,-Wunused-result]
17 | write(fd, &c, 1);
|  ^~~~~ ~~~~~~~~~
1 error generated.

View file

@ -6,7 +6,7 @@
/* By: rparodi <rparodi@student.42.fr> +#+ +:+ +#+ */ /* By: rparodi <rparodi@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2024/11/11 19:53:42 by rparodi #+# #+# */ /* Created: 2024/11/11 19:53:42 by rparodi #+# #+# */
/* Updated: 2024/11/22 15:17:07 by rparodi ### ########.fr */ /* Updated: 2024/11/26 13:40:17 by rparodi ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@ -32,17 +32,17 @@ int c3_redcross(t_info *info)
{ {
return (mlx_loop_end(info->mlx_ptr), EXIT_SUCCESS); return (mlx_loop_end(info->mlx_ptr), EXIT_SUCCESS);
} }
t_win_list *c3_init_mlx_window(t_info *info);
/*t_win_list *c3_init_mlx_window(t_info *info)*/ t_win_list *c3_init_mlx_window(t_info *info)
/*{*/ {
/* int x;*/ int x;
/* int y;*/ int y;
/**/
/* x = 0;*/ x = 0;
/* y = 0;*/ y = 0;
/* mlx_get_screen_size(info->mlx_ptr, &x, &y);*/ mlx_get_screen_size(info->mlx_ptr, &x, &y);
/* return (mlx_new_window(info->mlx_ptr, x, y, "C3D"));*/ return (mlx_new_window(info->mlx_ptr, x, y, "C3D"));
/*}*/ }
int init_mlx_env(t_info *info) int init_mlx_env(t_info *info)
{ {
@ -54,6 +54,7 @@ int init_mlx_env(t_info *info)
return (ERROR_MLX); return (ERROR_MLX);
mlx_hook(info->win_ptr, KeyPress, KeyPressMask, c3_keyhook, info); mlx_hook(info->win_ptr, KeyPress, KeyPressMask, c3_keyhook, info);
mlx_hook(info->win_ptr, DestroyNotify, StructureNotifyMask, c3_redcross, info); mlx_hook(info->win_ptr, DestroyNotify, StructureNotifyMask, c3_redcross, info);
mlx_loop_hook(info->mlx_ptr, c3_frame_update, info); mlx_loop_hook(info->mlx_ptr, (int (*)())shelves_launch, &info);
/*mlx_loop_hook(info->mlx_ptr, c3_frame_update, info);*/
return (NO_ERROR); return (NO_ERROR);
} }

View file

@ -6,7 +6,7 @@
/* By: rparodi <rparodi@student.42.fr> +#+ +:+ +#+ */ /* By: rparodi <rparodi@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2024/11/12 12:24:35 by rparodi #+# #+# */ /* Created: 2024/11/12 12:24:35 by rparodi #+# #+# */
/* Updated: 2024/11/23 12:33:39 by rparodi ### ########.fr */ /* Updated: 2024/11/26 13:39:56 by rparodi ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@ -27,91 +27,76 @@ double cub_convert_deg_to_rad(double degrees)
} }
/** /**
* @brief Launches a ray for raycasting to determine the distance to the first wall. * @brief Launches a ray for raycasting to determine the distance to the first wall.
* *
* This function calculates the distance of a ray cast in a specified angle * This function calculates the distance of a ray cast in a specified angle
* until it either hits a wall or reaches the maximum range. * until it either hits a wall or reaches the maximum range.
* *
* @param info A pointer to the `t_info` structure containing the map and other relevant data.
* @param info A pointer to the `t_info` structure containing the map and other relevant data.
* @param angle The angle of the ray being cast, in radians. * @param angle The angle of the ray being cast, in radians.
* *
* @return The distance from the starting position to the first wall hit. * @return The distance from the starting position to the first wall hit.
* If no wall is hit within `MAX_RANGE`, the function returns `MAX_RANGE`. * If no wall is hit within `MAX_RANGE`,
the function returns `MAX_RANGE`.
*/ */
double rc_launch(t_info *info, double angle) double rc_launch(t_info *info, double angle)
{
double distance;
t_dpoint direction;
t_dpoint rayon;
distance = 0;
direction.x = cos(angle);
direction.y = sin(angle);
rayon.x = 0;
rayon.y = 0;
while (distance < MAX_RANGE)
{
rayon.x = direction.x * distance;
rayon.y = direction.y * distance;
if (info->map.map[(int)info->map.fraw[(int)rayon.x][(int)rayon.y]] == '1')
return (distance);
distance += STEP_SIZE;
}
return (MAX_RANGE);
}
/**
* @brief Launches algorithm over a specified width with angle adjustments.
*
* @param info The structure of the game (for the view)
* @param spacing The spacing between rays.
* @param focal The focal length affecting the angle adjustment.
* @param width The total width (number of columns) to iterate over.
*
* @note The function assumes `rc_launch` is defined elsewhere to handle the angle.
*/
void shelves_launch(t_info *info, double spacing, double focal, int width)
{
int x;
double angle;
x = 0;
while (x < width)
{
angle = info->player.view + atan(\
(spacing / 2 - x * spacing / (width - 1)) / focal);
rc_launch(info, angle);
x++;
}
}
t_win_list *c3_init_mlx_window(t_info *info)
{ {
void *window; double distance = 0;
int i; t_dpoint direction = { cos(angle), sin(angle) };
int j; t_dpoint rayon = { 0, 0 };
int x;
int y;
x = 0; while (distance < MAX_RANGE)
y = 0;
mlx_get_screen_size(info->mlx_ptr, &x, &y);
i = 0;
window = mlx_new_window(info->mlx_ptr, x, y, "Raycasting");
while (i < x)
{ {
j = 0; rayon.x = info->player.pos.x + direction.x * distance;
while (j < y) rayon.y = info->player.pos.y + direction.y * distance;
{ if (info->map.fraw[(int)(rayon.y)][(int)(rayon.x)] == '1')
if (info->map.fraw[i / info->map.size.x][j / info->map.size.y] == '1') return (distance);
mlx_pixel_put(info->mlx_ptr, window, i, j, 0xFFFFFF); distance += STEP_SIZE;
else
mlx_pixel_put(info->mlx_ptr, window, i, j, 0x000000);
j++;
}
i++;
} }
mlx_loop(info->mlx_ptr); return (MAX_RANGE);
return (window); }
}
/**
* @brief Launches algorithm over a specified width with angle adjustments.
*
* @param info The structure of the game (for the view)
* @param spacing The spacing between rays.
* @param focal The focal length affecting the angle adjustment.
* @param width The total width (number of columns) to iterate over.
*
* @note The function assumes `rc_launch` is defined elsewhere to handle the angle.
*/
void draw_line(t_info *info, int x, int start, int end, unsigned int color)
{
while (start <= end)
{
mlx_pixel_put(info->mlx_ptr, info->win_ptr, x, start, color);
start++;
}
}
void shelves_launch(t_info *info)
{
info->player.pos = (t_dpoint){ 4.5, 4.5 }; // Starting in the middle of the map
info->player.view = 0; int x;
double angle;
double distance;
double projection_plane = info->map.size.x / (2.0 * tan(M_PI / 6.0));
for (x = 0; x < info->map.size.x; x++)
{
angle = info->player.view + atan((x - info->map.size.x / 2.0) / projection_plane);
distance = rc_launch(info, angle);
int line_height = (int)(TILE_SIZE / distance * projection_plane);
int start = (info->map.size.y / 2) - (line_height / 2);
int end = (info->map.size.y / 2) + (line_height / 2);
if (start < 0) start = 0;
if (end >= info->map.size.y) end = info->map.size.y - 1;
draw_line(info, x, start, end, 0xFFFFFF);
}
}

1
test/.envrc Normal file
View file

@ -0,0 +1 @@
use flake

146
test/Makefile Normal file
View file

@ -0,0 +1,146 @@
# **************************************************************************** #
# #
# ::: :::::::: #
# Makefile :+: :+: :+: #
# +:+ +:+ +:+ #
# By: rparodi <rparodi@student.42.fr> +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
# Created: 2023/11/12 11:05:05 by rparodi #+# #+# #
# Updated: 2024/11/26 14:41:12 by rparodi ### ########.fr #
# #
# **************************************************************************** #
# Variables
# Name
NAME = Cub3D
NAME_BONUS = Cub3D_bonus
# Commands
CC = cc
RM = rm -rf
# Flags
CFLAGS = -Werror -Wextra -Wall
CFLAGS += -g3 -MMD
# CFLAGS += -fsanitize=address
# CFLAGS += -fsanitize=thread
# INCLUDES += -I /opt/X11/include
INCLUDES = -I /usr/include -I ./includes -I ./includes/include -I ./minilibx-linux
# Paths
MLX_DIR = ./minilibx-linux
# Library flags
LDFLAGS = -L./build -lm
# MiniLibX flags for macOS with XQuartz
MLXFLAGS = -L$(MLX_DIR) -lmlx -lX11 -lXext
#MLXFLAGS += -L/opt/X11/lib
# Add MLXFLAGS to the linker flags
LDFLAGS += $(MLXFLAGS)
SRC = test2.c
# Objects
OBJDIRNAME = ./build
OBJ = $(addprefix $(OBJDIRNAME)/,$(SRC:.c=.o))
# Colors
GREEN = \033[32m
GREY = \033[0;90m
RED = \033[0;31m
GOLD = \033[38;5;220m
END = \033[0m
# Rules
#
# All (make all)
all: header $(NAME) footer
# Bonus (make bonus)
bonus: header $(OBJ) footer
@mkdir -p $(OBJDIRNAME)
@printf '$(GREY) Creating $(END)$(GREEN)$(OBJDIRNAME)$(END)\n'
@$(CC) $(CFLAGS) -D BONUS=1 -o $(NAME_BONUS) $(OBJ) $(LDFLAGS)
# Clean (make clean)
clean:
@printf '$(GREY) Removing $(END)$(RED)Objects$(END)\n'
@printf '$(GREY) Removing $(END)$(RED)Objects Folder$(END)\n'
@$(RM) $(OBJDIRNAME)
# Clean (make fclean)
fclean: clean
@printf '$(GREY) Removing $(END)$(RED)Program$(END)\n'
@$(RM) $(NAME)
@$(RM) $(NAME_BONUS)
@echo ""
# Restart (make re)
re: header fclean all
# Compile external libraries
build/libmlx.a:
@make --no-print-directory -C $(MLX_DIR)
# Dependences for all
$(NAME): $(OBJ) build/libmlx.a
@mkdir -p $(OBJDIRNAME)
@printf '$(GREY) Creating $(END)$(GREEN)$(OBJDIRNAME)$(END)\n'
@$(CC) $(CFLAGS) $(OBJ) $(LDFLAGS) -o $(NAME)
# Creating the objects
$(OBJDIRNAME)/%.o: %.c
@mkdir -p $(dir $@)
@printf '$(GREY) Compiling $(END)$(GREEN)$<$(END)\n'
@$(CC) $(CFLAGS) $(INCLUDES) -o $@ -c $<
# Header
header:
@clear
@printf '\n\n'
@printf '$(GOLD) ******* ****** ******* $(END)\n'
@printf '$(GOLD) ****** *** ******* $(END)\n'
@printf '$(GOLD) ******* * ******* $(END)\n'
@printf '$(GOLD) ****** ******* $(END)\n'
@printf '$(GOLD) ******* ******* $(END)\n'
@printf '$(GOLD) ******************* ******* * $(END)\n'
@printf '$(GOLD) ******************* ******* *** $(END)\n'
@printf '$(GOLD) ****** ******* ****** $(END)\n'
@printf '$(GOLD) ****** $(END)\n'
@printf '$(GOLD) ****** $(END)\n'
@printf '$(GREY) Made by rparodi$(END)\n\n'
# Footer
footer:
@printf "\n"
@printf "$(GOLD) ,_ _,$(END)\n"
@printf "$(GOLD) | \\___//|$(END)\n"
@printf "$(GOLD) |=6 6=|$(END)\n"
@printf "$(GOLD) \\=._Y_.=/$(END)\n"
@printf "$(GOLD) ) \` ( ,$(END)\n"
@printf "$(GOLD) / \\ (('$(END)\n"
@printf "$(GOLD) | | ))$(END)\n"
@printf "$(GOLD) /| | | |\\_//$(END)\n"
@printf "$(GOLD) \\| |._.| |/-\`$(END)\n"
@printf "$(GOLD) '\"' '\"'$(END)\n"
@printf ' $(GREY)The compilation is$(END) $(GOLD)finish$(END)\n $(GREY)Have a good $(END)$(GOLD)correction !$(END)\n'
clangd:
@echo -en \
"CompileFlags:\n" \
" Add:\n" \
" - \"-Wall -Wextra -Werror\"\n" \
" - \"-I/opt/X11/include\"\n" \
" - \"-I"$(shell pwd)"/includes\"\n" \
" - \"-I"$(shell pwd)"/includes/include\"\n" \
" - \"-xc\"\n" \
> .clangd
# Phony targets
.PHONY: all bonus clean fclean re
-include ${OBJ:.o=.d}

1
test/Makefile.gen Normal file
View file

@ -0,0 +1 @@
INC=/usr/X11/include

143
test/flake.lock generated Normal file
View file

@ -0,0 +1,143 @@
{
"nodes": {
"c_formatter_42": {
"inputs": {
"c_formatter_42_src": "c_formatter_42_src",
"flake-utils": "flake-utils",
"nixpkgs": "nixpkgs"
},
"locked": {
"lastModified": 1731759938,
"narHash": "sha256-3cVAExF4GFXXMd72AUUNgBn3p6W/8HIpYpeXvczK3Bo=",
"owner": "maix0",
"repo": "c_formatter_42-flake",
"rev": "26b2a2b774669d10bc50ab624ef58ed48ca2e9ec",
"type": "github"
},
"original": {
"owner": "maix0",
"repo": "c_formatter_42-flake",
"type": "github"
}
},
"c_formatter_42_src": {
"flake": false,
"locked": {
"lastModified": 1727700580,
"narHash": "sha256-GFnYVipVE6G1GFUqAzRkBSg7GgPgcLWX48GZtmM4i2Q=",
"owner": "dawnbeen",
"repo": "c_formatter_42",
"rev": "a255930b4be508a94bf6d8523d96556bdb4660ad",
"type": "github"
},
"original": {
"owner": "dawnbeen",
"repo": "c_formatter_42",
"type": "github"
}
},
"flake-utils": {
"inputs": {
"systems": "systems"
},
"locked": {
"lastModified": 1731533236,
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"flake-utils_2": {
"inputs": {
"systems": "systems_2"
},
"locked": {
"lastModified": 1731533236,
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 0,
"narHash": "sha256-Dqg6si5CqIzm87sp57j5nTaeBbWhHFaVyG7V6L8k3lY=",
"path": "/nix/store/zq2axpgzd5kykk1v446rkffj3bxa2m2h-source",
"type": "path"
},
"original": {
"id": "nixpkgs",
"type": "indirect"
}
},
"nixpkgs_2": {
"locked": {
"lastModified": 1732014248,
"narHash": "sha256-y/MEyuJ5oBWrWAic/14LaIr/u5E0wRVzyYsouYY3W6w=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "23e89b7da85c3640bbc2173fe04f4bd114342367",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"c_formatter_42": "c_formatter_42",
"flake-utils": "flake-utils_2",
"nixpkgs": "nixpkgs_2"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"systems_2": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
}
},
"root": "root",
"version": 7
}

31
test/flake.nix Normal file
View file

@ -0,0 +1,31 @@
{
description = "Flake utils demo";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
flake-utils.url = "github:numtide/flake-utils";
c_formatter_42.url = "github:maix0/c_formatter_42-flake";
};
outputs = {
self,
nixpkgs,
flake-utils,
c_formatter_42,
}:
flake-utils.lib.eachDefaultSystem (
system: let
pkgs = nixpkgs.legacyPackages.${system};
in {
devShell = pkgs.mkShell {
packages = [
pkgs.xorg.libX11
pkgs.xorg.libXext
pkgs.clang
pkgs.clang-tools
pkgs.norminette
c_formatter_42.packages.${system}.default
];
};
}
);
}

1
test/minilibx-linux Submodule

@ -0,0 +1 @@
Subproject commit 7dc53a411a7d4ae286c60c6229bd1e395b0efb82

263
test/test.c Normal file
View file

@ -0,0 +1,263 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* test.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: rparodi <rparodi@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/11/27 12:09:00 by rparodi #+# #+# */
/* Updated: 2024/11/27 15:59:53 by rparodi ### ########.fr */
/* */
/* ************************************************************************** */
#include "test.h"
int worldMap[MAP_WIDTH][MAP_HEIGHT] = {\
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}, \
{1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, \
{1,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, \
{1,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, \
{1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, \
{1,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, \
{1,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, \
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, \
{1,1,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, \
{1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, \
{1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, \
{1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, \
{1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, \
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, \
{1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, \
{1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, \
{1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, \
{1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, \
{1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, \
{1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, \
{1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, \
{1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, \
{1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, \
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} \
};
void my_mlx_pixel_put(t_data *data, int x, int y, int color)
{
char *dst;
dst = data->addr + (y * data->line_length + x * (data->bits_per_pixel / 8));
*(unsigned int *)dst = color;
}
void move_straight(t_data *data)
{
if (!worldMap[\
(int)(data->pos_x + data->dir_x * MOVE_SPEED)][(int)data->pos_y])
data->pos_x += data->dir_x * MOVE_SPEED;
if (!worldMap[\
(int)data->pos_x][(int)(data->pos_y + data->dir_y * MOVE_SPEED)])
data->pos_y += data->dir_y * MOVE_SPEED;
}
void move_backward(t_data *data)
{
if (!worldMap[\
(int)(data->pos_x - data->dir_x * MOVE_SPEED)][(int)data->pos_y])
data->pos_x -= data->dir_x * MOVE_SPEED;
if (!worldMap[\
(int)data->pos_x][(int)(data->pos_y - data->dir_y * MOVE_SPEED)])
data->pos_y -= data->dir_y * MOVE_SPEED;
}
void move_left(t_data *data)
{
double perp_dir_x;
double perp_dir_y;
perp_dir_x = -data->dir_y;
perp_dir_y = data->dir_x;
if (!worldMap[\
(int)(data->pos_x + perp_dir_x * MOVE_SPEED)][(int)data->pos_y])
data->pos_x -= perp_dir_x * MOVE_SPEED;
if (!worldMap[\
(int)data->pos_x][(int)(data->pos_y - perp_dir_y * MOVE_SPEED)])
data->pos_y -= perp_dir_y * MOVE_SPEED;
}
void move_right(t_data *data)
{
double perp_dir_x;
double perp_dir_y;
perp_dir_x = -data->dir_y;
perp_dir_y = data->dir_x;
if (!worldMap[\
(int)(data->pos_x - perp_dir_x * MOVE_SPEED)][(int)data->pos_y])
data->pos_x += perp_dir_x * MOVE_SPEED;
if (!worldMap[\
(int)data->pos_x][(int)(data->pos_y + perp_dir_y * MOVE_SPEED)])
data->pos_y += perp_dir_y * MOVE_SPEED;
}
void look_left(t_data *data)
{
double old_dir_x;
double old_plane_x;
old_dir_x = data->dir_x;
old_plane_x = data->plane_x;
data->dir_x = data->dir_x * cos(ROT_SPEED) - data->dir_y * sin(ROT_SPEED);
data->dir_y = old_dir_x * sin(ROT_SPEED) + data->dir_y * cos(ROT_SPEED);
data->plane_x = data->plane_x * cos(ROT_SPEED) \
- data->plane_y * sin(ROT_SPEED);
data->plane_y = old_plane_x * sin(ROT_SPEED) \
+ data->plane_y * cos(ROT_SPEED);
}
void look_right(t_data *data)
{
double old_dir_x;
double old_plane_x;
old_dir_x = data->dir_x;
old_plane_x = data->plane_x;
data->dir_x = data->dir_x * cos(-ROT_SPEED) - data->dir_y * sin(-ROT_SPEED);
data->dir_y = old_dir_x * sin(-ROT_SPEED) + data->dir_y * cos(-ROT_SPEED);
data->plane_x = data->plane_x * cos(-ROT_SPEED) \
- data->plane_y * sin(-ROT_SPEED);
data->plane_y = old_plane_x * sin(-ROT_SPEED) \
+ data->plane_y * cos(-ROT_SPEED);
}
int key_hook(int keycode, t_data *data)
{
if (keycode == 65307)
exit(0);
if (keycode == 119)
move_straight(data);
if (keycode == 115)
move_backward(data);
if (keycode == 97)
move_right(data);
if (keycode == 100)
move_left(data);
if (keycode == 65361)
look_left(data);
if (keycode == 65363)
look_right(data);
return (0);
}
int render_frame(t_data *data)
{
int y;
int x;
y = 0;
while (y < WINDOW_HEIGHT)
{
x = 0;
while (x < WINDOW_WIDTH)
{
my_mlx_pixel_put(data, x, y, 0x00000000);
x++;
}
y++;
}
for(int x = 0; x < WINDOW_WIDTH; x++)
{
double cameraX = 2 * x / (double)WINDOW_WIDTH - 1;
double rayDirX = data->dir_x + data->plane_x * cameraX;
double rayDirY = data->dir_y + data->plane_y * cameraX;
int mapX = (int)data->pos_x;
int mapY = (int)data->pos_y;
double sideDistX, sideDistY;
double deltaDistX = fabs(1 / rayDirX);
double deltaDistY = fabs(1 / rayDirY);
double perpWallDist;
int stepX, stepY;
int hit = 0;
int side;
if (rayDirX < 0) {
stepX = -1;
sideDistX = (data->pos_x - mapX) * deltaDistX;
} else {
stepX = 1;
sideDistX = (mapX + 1.0 - data->pos_x) * deltaDistX;
}
if (rayDirY < 0) {
stepY = -1;
sideDistY = (data->pos_y - mapY) * deltaDistY;
} else {
stepY = 1;
sideDistY = (mapY + 1.0 - data->pos_y) * deltaDistY;
}
while (hit == 0) {
if (sideDistX < sideDistY) {
sideDistX += deltaDistX;
mapX += stepX;
side = 0;
} else {
sideDistY += deltaDistY;
mapY += stepY;
side = 1;
}
if (worldMap[mapX][mapY] > 0)
hit = 1;
}
if (side == 0)
perpWallDist = (mapX - data->pos_x + (1 - stepX) / 2) / rayDirX;
else
perpWallDist = (mapY - data->pos_y + (1 - stepY) / 2) / rayDirY;
int lineHeight = (int)(WINDOW_HEIGHT / perpWallDist);
int drawStart = -lineHeight / 2 + WINDOW_HEIGHT / 2;
if(drawStart < 0) drawStart = 0;
int drawEnd = lineHeight / 2 + WINDOW_HEIGHT / 2;
if(drawEnd >= WINDOW_HEIGHT) drawEnd = WINDOW_HEIGHT - 1;
int color;
if (side == 0 && stepX > 0)
color = 0x00FF0000;
else if (side == 0 && stepX < 0)
color = 0x0000FF00;
else if (side == 1 && stepY > 0)
color = 0x000000FF;
else
color = 0x00FFFF00;
if (side == 1) color = (color >> 1) & 8355711; // Make sides darker
for(int y = drawStart; y < drawEnd; y++)
my_mlx_pixel_put(data, x, y, color);
}
mlx_put_image_to_window(data->mlx, data->win, data->img, 0, 0);
return (0);
}
int main(void)
{
t_data data;
data.mlx = mlx_init();
data.win = mlx_new_window(data.mlx, WINDOW_WIDTH, WINDOW_HEIGHT, "Raycaster");
data.img = mlx_new_image(data.mlx, WINDOW_WIDTH, WINDOW_HEIGHT);
data.addr = mlx_get_data_addr(data.img, &data.bits_per_pixel, &data.line_length, &data.endian);
data.pos_x = 22;
data.pos_y = 12;
data.dir_x = -1;
data.dir_y = 0;
data.plane_x = 0;
data.plane_y = 0.66;
mlx_hook(data.win, 2, 1L<<0, key_hook, &data);
mlx_loop_hook(data.mlx, render_frame, &data);
mlx_loop(data.mlx);
return (0);
}

45
test/test.h Normal file
View file

@ -0,0 +1,45 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* test.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: rparodi <rparodi@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/11/27 12:07:20 by rparodi #+# #+# */
/* Updated: 2024/11/27 12:08:19 by rparodi ### ########.fr */
/* */
/* ************************************************************************** */
#ifndef TEST_H
# define TEST_H
# include "minilibx-linux/mlx.h"
# include <math.h>
# include <stdio.h>
# include <stdlib.h>
# define WINDOW_WIDTH 1024
# define WINDOW_HEIGHT 768
# define MAP_WIDTH 24
# define MAP_HEIGHT 24
# define MOVE_SPEED 0.5
# define ROT_SPEED 0.5
typedef struct s_data
{
void *mlx;
void *win;
void *img;
char *addr;
int bits_per_pixel;
int line_length;
int endian;
double pos_x;
double pos_y;
double dir_x;
double dir_y;
double plane_x;
double plane_y;
} t_data;
#endif

262
test/test2.c Normal file
View file

@ -0,0 +1,262 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* test2.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: rparodi <rparodi@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/11/27 12:09:00 by rparodi #+# #+# */
/* Updated: 2024/11/27 16:00:23 by rparodi ### ########.fr */
/* */
/* ************************************************************************** */
#include "minilibx-linux/mlx.h"
#include "test.h"
int worldMap[MAP_WIDTH][MAP_HEIGHT] = {\
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}, \
{1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, \
{1,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, \
{1,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, \
{1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, \
{1,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, \
{1,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, \
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, \
{1,1,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, \
{1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, \
{1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, \
{1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, \
{1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, \
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, \
{1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, \
{1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, \
{1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, \
{1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, \
{1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, \
{1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, \
{1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, \
{1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, \
{1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, \
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} \
};
void my_mlx_pixel_put(t_data *data, int x, int y, int color)
{
char *dst;
dst = data->addr + (y * data->line_length + x * (data->bits_per_pixel / 8));
*(unsigned int *)dst = color;
}
void move_straight(t_data *data)
{
if (!worldMap[\
(int)(data->pos_x + data->dir_x * MOVE_SPEED)][(int)data->pos_y])
data->pos_x += data->dir_x * MOVE_SPEED;
if (!worldMap[\
(int)data->pos_x][(int)(data->pos_y + data->dir_y * MOVE_SPEED)])
data->pos_y += data->dir_y * MOVE_SPEED;
}
void move_backward(t_data *data)
{
if (!worldMap[\
(int)(data->pos_x - data->dir_x * MOVE_SPEED)][(int)data->pos_y])
data->pos_x -= data->dir_x * MOVE_SPEED;
if (!worldMap[\
(int)data->pos_x][(int)(data->pos_y - data->dir_y * MOVE_SPEED)])
data->pos_y -= data->dir_y * MOVE_SPEED;
}
void move_left(t_data *data)
{
double perp_dir_x;
double perp_dir_y;
perp_dir_x = -data->dir_y;
perp_dir_y = data->dir_x;
if (!worldMap[\
(int)(data->pos_x + perp_dir_x * MOVE_SPEED)][(int)data->pos_y])
data->pos_x -= perp_dir_x * MOVE_SPEED;
if (!worldMap[\
(int)data->pos_x][(int)(data->pos_y - perp_dir_y * MOVE_SPEED)])
data->pos_y -= perp_dir_y * MOVE_SPEED;
}
void move_right(t_data *data)
{
double perp_dir_x;
double perp_dir_y;
perp_dir_x = -data->dir_y;
perp_dir_y = data->dir_x;
if (!worldMap[\
(int)(data->pos_x - perp_dir_x * MOVE_SPEED)][(int)data->pos_y])
data->pos_x += perp_dir_x * MOVE_SPEED;
if (!worldMap[\
(int)data->pos_x][(int)(data->pos_y + perp_dir_y * MOVE_SPEED)])
data->pos_y += perp_dir_y * MOVE_SPEED;
}
void look_left(t_data *data)
{
double old_dir_x;
double old_plane_x;
old_dir_x = data->dir_x;
old_plane_x = data->plane_x;
data->dir_x = data->dir_x * cos(ROT_SPEED) - data->dir_y * sin(ROT_SPEED);
data->dir_y = old_dir_x * sin(ROT_SPEED) + data->dir_y * cos(ROT_SPEED);
data->plane_x = data->plane_x * cos(ROT_SPEED) \
- data->plane_y * sin(ROT_SPEED);
data->plane_y = old_plane_x * sin(ROT_SPEED) \
+ data->plane_y * cos(ROT_SPEED);
}
void look_right(t_data *data)
{
double old_dir_x;
double old_plane_x;
old_dir_x = data->dir_x;
old_plane_x = data->plane_x;
data->dir_x = data->dir_x * cos(-ROT_SPEED) - data->dir_y * sin(-ROT_SPEED);
data->dir_y = old_dir_x * sin(-ROT_SPEED) + data->dir_y * cos(-ROT_SPEED);
data->plane_x = data->plane_x * cos(-ROT_SPEED) \
- data->plane_y * sin(-ROT_SPEED);
data->plane_y = old_plane_x * sin(-ROT_SPEED) \
+ data->plane_y * cos(-ROT_SPEED);
}
int key_hook(int keycode, t_data *data)
{
if (keycode == 65307)
exit(0);
if (keycode == 119)
move_straight(data);
if (keycode == 115)
move_backward(data);
if (keycode == 97)
move_right(data);
if (keycode == 100)
move_left(data);
if (keycode == 65361)
look_left(data);
if (keycode == 65363)
look_right(data);
return (0);
}
int render_frame(t_data *data)
{
int y;
int x;
y = 0;
while (y < WINDOW_HEIGHT)
{
x = 0;
while (x < WINDOW_WIDTH)
{
my_mlx_pixel_put(data, x, y, 0x00000000);
x++;
}
y++;
}
for(int x = 0; x < WINDOW_WIDTH; x++)
{
double cameraX = 2 * x / (double)WINDOW_WIDTH - 1;
double rayDirX = data->dir_x + data->plane_x * cameraX;
double rayDirY = data->dir_y + data->plane_y * cameraX;
int mapX = (int)data->pos_x;
int mapY = (int)data->pos_y;
double sideDistX, sideDistY;
double deltaDistX = fabs(1 / rayDirX);
double deltaDistY = fabs(1 / rayDirY);
double perpWallDist;
int stepX, stepY;
int hit = 0;
int side;
if (rayDirX < 0) {
stepX = -1;
sideDistX = (data->pos_x - mapX) * deltaDistX;
} else {
stepX = 1;
sideDistX = (mapX + 1.0 - data->pos_x) * deltaDistX;
}
if (rayDirY < 0) {
stepY = -1;
sideDistY = (data->pos_y - mapY) * deltaDistY;
} else {
stepY = 1;
sideDistY = (mapY + 1.0 - data->pos_y) * deltaDistY;
}
while (hit == 0) {
if (sideDistX < sideDistY) {
sideDistX += deltaDistX;
mapX += stepX;
side = 0;
} else {
sideDistY += deltaDistY;
mapY += stepY;
side = 1;
}
if (worldMap[mapX][mapY] > 0)
hit = 1;
}
if (side == 0)
perpWallDist = (mapX - data->pos_x + (1 - stepX) / 2) / rayDirX;
else
perpWallDist = (mapY - data->pos_y + (1 - stepY) / 2) / rayDirY;
int lineHeight = (int)(WINDOW_HEIGHT / perpWallDist);
int drawStart = -lineHeight / 2 + WINDOW_HEIGHT / 2;
if(drawStart < 0) drawStart = 0;
int drawEnd = lineHeight / 2 + WINDOW_HEIGHT / 2;
if(drawEnd >= WINDOW_HEIGHT) drawEnd = WINDOW_HEIGHT - 1;
int color;
if (side == 0 && stepX > 0)
color = 0x00FF0000;
else if (side == 0 && stepX < 0)
color = 0x0000FF00;
else if (side == 1 && stepY > 0)
color = 0x000000FF;
else
color = 0x00FFFF00;
for(int y = drawStart; y < drawEnd; y++)
my_mlx_pixel_put(data, x, y, color);
}
mlx_put_image_to_window(data->mlx, data->win, data->img, 0, 0);
return (0);
}
int main(void)
{
t_data data;
data.mlx = mlx_init();
data.win = mlx_new_window(data.mlx, WINDOW_WIDTH, WINDOW_HEIGHT, "Raycaster");
data.img = mlx_new_image(data.mlx, WINDOW_WIDTH, WINDOW_HEIGHT);
data.addr = mlx_get_data_addr(data.img, &data.bits_per_pixel, &data.line_length, &data.endian);
data.pos_x = 22;
data.pos_y = 12;
data.dir_x = -1;
data.dir_y = 0;
data.plane_x = 0;
data.plane_y = 0.66;
mlx_hook(data.win, 2, 1L<<0, key_hook, &data);
mlx_loop_hook(data.mlx, render_frame, &data);
mlx_loop(data.mlx);
return (0);
}

154
test/textures/a.xpm Normal file
View file

@ -0,0 +1,154 @@
/* XPM */
static char *_cb59dce4f574e3bd6a1e2f025c0312agi1mGDihwOOx8j7A[] = {
/* columns rows colors chars-per-pixel */
"32 32 116 2 ",
" c #100F10",
". c #161515",
"X c #191717",
"o c #191718",
"O c #1E1C1C",
"+ c #211E1E",
"@ c #252222",
"# c #292626",
"$ c #2D2B2B",
"% c #322E2E",
"& c #3A2F2E",
"* c #36302F",
"= c #3C312E",
"- c #342F30",
"; c #353131",
": c #3A3434",
"> c #3D3836",
", c #3C3738",
"< c #3E3A3A",
"1 c #43332F",
"2 c #433534",
"3 c #4C3633",
"4 c #433A36",
"5 c #4C3937",
"6 c #433C3B",
"7 c #4B3D3B",
"8 c #503835",
"9 c #523D3C",
"0 c #46413E",
"q c #4B433D",
"w c #524433",
"e c #55443B",
"r c #453F41",
"t c #563D40",
"y c #474141",
"u c #4B4442",
"i c #4E4845",
"p c #4F4949",
"a c #544442",
"s c #584644",
"d c #534A42",
"f c #5A4A46",
"g c #554D4B",
"h c #5C4D4C",
"j c #545146",
"k c #56514C",
"l c #5B524D",
"z c #5D5552",
"x c #5F5A53",
"c c #614D46",
"v c #61534D",
"b c #625D4C",
"n c #625553",
"m c #635A53",
"M c #655B59",
"N c #695D5A",
"B c #636052",
"V c #696354",
"C c #6E6852",
"Z c #66615A",
"A c #6B625D",
"S c #6D695B",
"D c #70675F",
"F c #736A5D",
"G c #6C6360",
"H c #6B6463",
"J c #6F6563",
"K c #6D6865",
"L c #706763",
"P c #726766",
"I c #716A62",
"U c #726A63",
"Y c #756D63",
"T c #746A64",
"R c #786B66",
"E c #786D66",
"W c #716A68",
"Q c #746B69",
"! c #776E6C",
"~ c #7B6F69",
"^ c #796E6A",
"/ c #786E6C",
"( c #767161",
") c #7B7366",
"_ c #7C7367",
"` c #7E7A66",
"' c #767069",
"] c #79706B",
"[ c #7C716B",
"{ c #7F7868",
"} c #7F796C",
"| c #7E7572",
" . c #807D6D",
".. c #807776",
"X. c #837B70",
"o. c #847972",
"O. c #857C72",
"+. c #847B79",
"@. c #8A7F78",
"#. c #868172",
"$. c #898171",
"%. c #8C8673",
"&. c #8A8174",
"*. c #8D8870",
"=. c #8D867B",
"-. c #928B7C",
";. c #938C7D",
":. c #968F7F",
">. c #96907B",
",. c #98907F",
"<. c #8D8681",
"1. c #938C80",
"2. c #948C88",
"3. c #979081",
"4. c #999087",
"5. c #A29C81",
/* pixels */
"V : H + Z m % - $ $ ' ! # -.$ k g x $ $ 2 &.$ % % 2 >.g ; z $ A ",
"&.d % $ 1 F 5.@ X.1 f [ % % % : z Y % ; O.L ] # @ N a T ; % , :.",
"A ; $ 6 = C $ , % , ; a $ I %.% 7 % o + 1 Z = 1 O % $ < @ & v L ",
"O ; T # 3 X @ 2 l z % % % g p % $ % A l $ ; : M t % = f G % # # ",
"e ; ; 6 > k $ & $ % @ % % : 4 % 0 % > T 4 $ % a % @ % $ 9 N $ -.",
"J % / z ~ 3.k , , f Z k e 3 # % O.d % % % } 6 : ; I | l $ , $ l ",
"N 8 2 2 3 O.m 6 , % E % = % 5 L E S % % 7 N J k = > u [ & D $ R ",
"= % + # ; % 2 % $ 7 l $ % : % : > $ $ $ , 2 q 4 % % % , , 4 % * ",
"$ h Z A $ % % 7 % : : $ A z q ; ; : ] I % ; $ ; D N 0 $ | Z z p ",
"M l g X.< 7 7 W u < % ; n { m , > > i > ; j % m q d g O 7 g g $ ",
"6 , n @ $ z : 2 % m .d % 9 % , l > ; ; m M @ : % , x @ $ % $ ; ",
"L 4 $ ; I <.u ; # A P A $ % # x 0 , % # z X.x < $ m P 9 = _ < g ",
"A 7 , + @.M & 9 % ; $ : % > % ; # ; % : n N n ; k % $ % G H % u ",
"$ % O.; $ $ . ` l % # $ # $ =.I 7 <.2.A ; % $ $ 6 x : , V Y > 6 ",
"2 ] [ s $ 9 @ E { m A O ] f A ; l s +.@ F I $ | / O.% % 2 0 $ : ",
"% % f a % $ ; A E = % # 3 i > $ $ , ..+ O g ; ~ N $ : : % $ 4 k ",
"$.j , < & #.% 6 : $ ;.a % 2 % g *.; g ; c v , $ : 6 T ~ % u ; ( ",
"g Z # : O.L ] # 6 N a T # % , D p d % % = F ` ; Z = f [ , % $ u ",
"v % @ # 1 Z = 1 $ % $ ; 6 % v l A @ @ ; & j $ ; # $ ; a . I S : ",
"# $ g l $ $ , M t % = f G , ; $ ; # z , 2 6 # 7 L ~ ; 7 % u 6 ; ",
") % 0 z e , # a % ; % # 9 N $ -.n , < 6 > k $ & $ % $ # % < 4 $ ",
": : ; $ % } b d , I | l $ $ # l W % / z ~ 3.S ; * f #.S e 3 ; * ",
"0 6 % p s N J k = > J [ & D @ R N 8 3 9 3 O.m ; # % E % 2 % 9 A ",
"v $ $ $ , : 4 : % * ; % 6 4 % % % % O < % % 2 % % > D @ ; q % z ",
"# 2 ] z % , % # l N 0 # | +.4.p % q O.A $ r # a ; w = , A g m o ",
"( i 0 c 7 j % ] l 6 , % 2 G N % > J A o.# 7 a W Q A + n k [ % ",
"k M 9 @ S M # 2 $ 6 ] , # % % % % % n # # Q * 2 % d .d < 9 % ; ",
"u u # $ Z 1.Z % % m P 9 = _ @ A x % $ ; I <.L $ $ g P ~ % % y [ ",
"p $ % : u g a $ D % $ % G H % A y : ; % @.M 2 9 $ % # 3 @ f ; $ ",
"7 K z y % # ; % 6 ] 7 , V ,.d 6 % % O.% $ ; % B ; % y ; ; $ =.I ",
"J 7 g < u I $ M x O.% # 7 Z ; 1 9 ] [ s $ 2 # 6 { i q O ] f A , ",
"u ; .., ; A u ~ N $ ; $ + $ 1 l % % f a , % # A z % % $ 3 n 9 % "
};

49
test/textures/b.xpm Normal file
View file

@ -0,0 +1,49 @@
/* XPM */
static char *_947bb94b4e04fd3d8b6e97faaaaa774DMhsGHANfMg9UIKL[] = {
/* columns rows colors chars-per-pixel */
"32 32 11 1 ",
" c #422816",
". c #4E371C",
"X c #584529",
"o c #655131",
"O c #665232",
"+ c #655339",
"@ c #705C41",
"# c #756349",
"$ c #796442",
"% c #816D54",
"& c #948066",
/* pixels */
"##++XX#@###%@%%O@X++.X#@@XX+++++",
"#@o+X #%##@O+X@@++XX+++@+@@++#%",
"#%#OO.+XXo+%#&%##.X.X##%@@@++##O",
"oooXXXX. +@@OX#.X##+X+..+#@O@X++",
"+OX@O@%%##@XX++OooXXX.X+XXX+@OXX",
"$X#O@.X@XXX.+.XX..+XX+XX+@+X....",
"#+%%++X+@@@X++#+X..+@+#####%#$#@",
"+X+X...XX@#.+#X@@+.++#&%@@@#+.++",
"X+XXX+XXXX@#%.@##@@.@++++#X.X.@%",
".+XX..X+@@++..#@++...X.XXX+@+XX+",
"X+X@#%+X.X++#+X XX++++...++X+X+",
"X..++@.XXXXOO@@@&##%@@+...++.++X",
"+@+X...#@#%@+@@+@#+X@#++@X.+@#++",
"X.XXX++&+@++X+.X+++X+XX###@@@X+X",
" .#++###+%#@+X#oXX+@@#@+@##+##..",
".%@##XOX%#@.@@X..X.X@@+@@@@@XX++",
"#@#X.XXXX+++.XX@#+++X XXX#+X+X+&",
"X@#%+X@XX.XX++O##@+..X++@#@%%++@",
"##@##.@+XXXX.XX@XX+X..+XX@#%%#@X",
"..X##.+X+@XX++@++X++.+X++++X+++.",
"+#+.XX+XX#+%&#@@@#X XX@XX.XX# .+",
"XX+X.+%%%%@@XX++%+%&%#++.X+X@.XX",
"# ++@+@#+XX.+X##+X##+@++@+@@#%",
"##X+X+@oX@....XXXX+o+#@@@++ X#X@",
"%+@XX..XX.X#..@X+X++#+XX+.@X+X%@",
"+X.X.X+++#XX+XX@@@@#+++.+++@+%OX",
"XOX+@X+@+@@+++X+++X+@X+++@X@X+X ",
"@##&@#++++@+++@X+. ..++@@.X++X+%",
"@#@#X+@++X@+XXXX++@+@XXX.X+@@@@%",
"XXOXXX...+@@#@@X@@#@#@&...X@#@.X",
"XX@...+@%&#XX@XX++@ .@@#@@+@X.X+",
"%@.@%@@+++@o++++X+X+@++XXO@@@%#&"
};