diff --git a/Cub3D 2 b/Cub3D 2 new file mode 100755 index 0000000..b4309a9 Binary files /dev/null and b/Cub3D 2 differ diff --git a/Makefile b/Makefile index 4affe38..10d3cb7 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ # 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=thread -# INCLUDES += -I /opt/X11/include -INCLUDES = -I /usr/include -I ./includes -I ./includes/include -I ./minilibx-linux +INCLUDES += -I /opt/X11/include +INCLUDES = -I ./includes -I ./includes/include -I ./minilibx-linux # Paths LIBFT_DIR = ./libft @@ -37,8 +37,8 @@ MLX_DIR = ./minilibx-linux LDFLAGS = -L./build -lft -lm # MiniLibX flags for macOS with XQuartz -MLXFLAGS = -L$(MLX_DIR) -lmlx -lX11 -lXext -lXrender -lXrandr -lXi -#MLXFLAGS += -L/opt/X11/lib +MLXFLAGS = -L$(MLX_DIR) -lmlx -lX11 -lXext +MLXFLAGS += -L/opt/X11/lib # Add MLXFLAGS to the linker flags LDFLAGS += $(MLXFLAGS) diff --git a/Makefile.gen b/Makefile.gen new file mode 100644 index 0000000..60181d4 --- /dev/null +++ b/Makefile.gen @@ -0,0 +1 @@ +INC=/usr/X11/include diff --git a/includes/cub3d.h b/includes/cub3d.h index b07c25c..43386a5 100644 --- a/includes/cub3d.h +++ b/includes/cub3d.h @@ -6,7 +6,7 @@ /* 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); int main(int argc, char *argv[]); +void shelves_launch(t_info *info); #endif /* CUB3D_H */ diff --git a/includes/cub3d_struct.h b/includes/cub3d_struct.h index 8516dd2..211541f 100644 --- a/includes/cub3d_struct.h +++ b/includes/cub3d_struct.h @@ -6,7 +6,7 @@ /* 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_LEN 4 +#define FOV 65 +#define TILE_SIZE 64 // -- graphic utils typedef struct s_color diff --git a/libft/compilation.log b/libft/compilation.log deleted file mode 100644 index 707331c..0000000 --- a/libft/compilation.log +++ /dev/null @@ -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. diff --git a/mlx_layer/mlx_init.c b/mlx_layer/mlx_init.c index df0abcc..db5c801 100644 --- a/mlx_layer/mlx_init.c +++ b/mlx_layer/mlx_init.c @@ -6,7 +6,7 @@ /* 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); } -t_win_list *c3_init_mlx_window(t_info *info); -/*t_win_list *c3_init_mlx_window(t_info *info)*/ -/*{*/ -/* int x;*/ -/* int y;*/ -/**/ -/* x = 0;*/ -/* y = 0;*/ -/* mlx_get_screen_size(info->mlx_ptr, &x, &y);*/ -/* return (mlx_new_window(info->mlx_ptr, x, y, "C3D"));*/ -/*}*/ + +t_win_list *c3_init_mlx_window(t_info *info) +{ + int x; + int y; + + x = 0; + y = 0; + mlx_get_screen_size(info->mlx_ptr, &x, &y); + return (mlx_new_window(info->mlx_ptr, x, y, "C3D")); +} int init_mlx_env(t_info *info) { @@ -54,6 +54,7 @@ int init_mlx_env(t_info *info) return (ERROR_MLX); mlx_hook(info->win_ptr, KeyPress, KeyPressMask, c3_keyhook, 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); } diff --git a/raycast/rc_utils.c b/raycast/rc_utils.c index c6bca11..971edf6 100644 --- a/raycast/rc_utils.c +++ b/raycast/rc_utils.c @@ -6,7 +6,7 @@ /* 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 * 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. * * @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 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) +double rc_launch(t_info *info, double angle) { - void *window; - int i; - int j; - int x; - int y; + double distance = 0; + t_dpoint direction = { cos(angle), sin(angle) }; + t_dpoint rayon = { 0, 0 }; - x = 0; - 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) + while (distance < MAX_RANGE) { - j = 0; - while (j < y) - { - if (info->map.fraw[i / info->map.size.x][j / info->map.size.y] == '1') - mlx_pixel_put(info->mlx_ptr, window, i, j, 0xFFFFFF); - else - mlx_pixel_put(info->mlx_ptr, window, i, j, 0x000000); - j++; - } - i++; + rayon.x = info->player.pos.x + direction.x * distance; + rayon.y = info->player.pos.y + direction.y * distance; + if (info->map.fraw[(int)(rayon.y)][(int)(rayon.x)] == '1') + return (distance); + distance += STEP_SIZE; } - mlx_loop(info->mlx_ptr); - return (window); - } + 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 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); + } +} diff --git a/test/.envrc b/test/.envrc new file mode 100644 index 0000000..3550a30 --- /dev/null +++ b/test/.envrc @@ -0,0 +1 @@ +use flake diff --git a/test/Makefile b/test/Makefile new file mode 100644 index 0000000..854d6d2 --- /dev/null +++ b/test/Makefile @@ -0,0 +1,146 @@ +# **************************************************************************** # +# # +# ::: :::::::: # +# Makefile :+: :+: :+: # +# +:+ +:+ +:+ # +# By: rparodi +#+ +:+ +#+ # +# +#+#+#+#+#+ +#+ # +# 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} diff --git a/test/Makefile.gen b/test/Makefile.gen new file mode 100644 index 0000000..60181d4 --- /dev/null +++ b/test/Makefile.gen @@ -0,0 +1 @@ +INC=/usr/X11/include diff --git a/test/flake.lock b/test/flake.lock new file mode 100644 index 0000000..6db3dfb --- /dev/null +++ b/test/flake.lock @@ -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 +} diff --git a/test/flake.nix b/test/flake.nix new file mode 100644 index 0000000..b62b26c --- /dev/null +++ b/test/flake.nix @@ -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 + ]; + }; + } + ); +} diff --git a/test/minilibx-linux b/test/minilibx-linux new file mode 160000 index 0000000..7dc53a4 --- /dev/null +++ b/test/minilibx-linux @@ -0,0 +1 @@ +Subproject commit 7dc53a411a7d4ae286c60c6229bd1e395b0efb82 diff --git a/test/test.c b/test/test.c new file mode 100644 index 0000000..f5fa61b --- /dev/null +++ b/test/test.c @@ -0,0 +1,263 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* test.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: rparodi +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* 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); +} diff --git a/test/test.h b/test/test.h new file mode 100644 index 0000000..f5ede6b --- /dev/null +++ b/test/test.h @@ -0,0 +1,45 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* test.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: rparodi +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* 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 +# include +# include + +# 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 diff --git a/test/test2.c b/test/test2.c new file mode 100644 index 0000000..8992bd2 --- /dev/null +++ b/test/test2.c @@ -0,0 +1,262 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* test2.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: rparodi +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* 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); +} diff --git a/test/textures/a.xpm b/test/textures/a.xpm new file mode 100644 index 0000000..5d7ac8c --- /dev/null +++ b/test/textures/a.xpm @@ -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 % " +}; diff --git a/test/textures/b.xpm b/test/textures/b.xpm new file mode 100644 index 0000000..99258e6 --- /dev/null +++ b/test/textures/b.xpm @@ -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@@@%#&" +};