From 258372bf096721b9be013e26748714abeb68fc23 Mon Sep 17 00:00:00 2001 From: Theo Champion Date: Wed, 6 Aug 2025 14:06:15 +0200 Subject: [PATCH] feat: Added sprites --- Makefile | 1 + src/consts.h | 37 +++++----- src/cub3d_data.h | 5 +- src/main.c | 10 +-- src/sprites/sprite.h | 10 +-- src/sprites/sprite_caster.c | 138 ++++++++++++++++++++++++++++++++++++ src/sprites/sprite_caster.h | 20 ++++++ src/utils/inits.c | 3 +- src/utils/inits.h | 3 +- 9 files changed, 198 insertions(+), 29 deletions(-) create mode 100644 src/sprites/sprite_caster.c create mode 100644 src/sprites/sprite_caster.h diff --git a/Makefile b/Makefile index 695f727..d033447 100644 --- a/Makefile +++ b/Makefile @@ -28,6 +28,7 @@ SOURCEFILES = \ src/raycast/ray.c \ src/raycast/walls.c \ src/renderer/render.c \ + src/sprites/sprite_caster.c \ OBJECTS = $(SOURCEFILES:.c=.o) NAME = cub3d diff --git a/src/consts.h b/src/consts.h index 881abae..325c356 100644 --- a/src/consts.h +++ b/src/consts.h @@ -6,28 +6,31 @@ /* By: kcolin +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/07/17 14:54:36 by kcolin #+# #+# */ -/* Updated: 2025/08/05 15:22:09 by kcolin ### ########.fr */ +/* Updated: 2025/08/06 13:44:29 by tchampio ### ########.fr */ /* */ /* ************************************************************************** */ #ifndef CONSTS_H -# define CONSTS_H +#define CONSTS_H -# define HEIGHT 800 -# define WIDTH 800 +#define HEIGHT 800 +#define WIDTH 800 -# define SIZE 64 -# define MAP_SIZE 10 -# define PLAYER_SIZE 6 -# define RESSOURCE_DIR "ressources" -# define MOVEMENT_SPEED 0.000005 -# define ROTATION_SPEED 0.000002 -# define PLANE_VALUE 0.66 -# define TEXTURE_SIZE 64 -# ifdef BONUS -# define COMPILED_TEXT "Compiled with bonuses" -# else -# define COMPILED_TEXT " " -# endif +#define SIZE 64 +#define MAP_SIZE 10 +#define PLAYER_SIZE 6 +#define RESSOURCE_DIR "ressources" +#define MOVEMENT_SPEED 0.000005 +#define ROTATION_SPEED 0.000002 +#define PLANE_VALUE 0.6 +#define TEXTURE_SIZE 64 +// 4 static ones, 3 perks, the box and 25 zombies at max +#define SPRITE_TRANPARENCY_COLOR 0xff00dc +#define MAX_SPRITES 1 // FIXME: Change to 30 +#ifdef BONUS +#define COMPILED_TEXT "Compiled with bonuses" +#else +#define COMPILED_TEXT " " +#endif #endif diff --git a/src/cub3d_data.h b/src/cub3d_data.h index e6ba1e2..919b02e 100644 --- a/src/cub3d_data.h +++ b/src/cub3d_data.h @@ -6,7 +6,7 @@ /* By: kcolin +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/07/17 14:59:37 by kcolin #+# #+# */ -/* Updated: 2025/08/05 13:37:57 by tchampio ### ########.fr */ +/* Updated: 2025/08/05 15:44:27 by tchampio ### ########.fr */ /* */ /* ************************************************************************** */ @@ -37,6 +37,9 @@ typedef struct s_cub3d_data int delta; int last_tick; t_sprite static_sprite[4]; + double zbuffer[WIDTH]; + int sprite_order[MAX_SPRITES]; + double sprite_distances[MAX_SPRITES]; } t_cub3d_data; #endif // CUB3D_DATA_H diff --git a/src/main.c b/src/main.c index 9950274..7e84f68 100644 --- a/src/main.c +++ b/src/main.c @@ -6,7 +6,7 @@ /* By: kcolin +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/07/17 14:14:30 by kcolin #+# #+# */ -/* Updated: 2025/08/05 13:20:05 by tchampio ### ########.fr */ +/* Updated: 2025/08/06 13:36:07 by tchampio ### ########.fr */ /* */ /* ************************************************************************** */ @@ -19,6 +19,8 @@ #include "raycast/raycaster.h" #include "renderer/render.h" #include "raycast/ray.h" +#include "sprites/sprite_caster.h" +#include "utils/inits.h" #include "sprites/sprite.h" #include "utils/hooks.h" #include "utils/inits.h" @@ -30,9 +32,6 @@ #include #include "utils/time.h" -// for testing purposes -// TODO: Put all of that code in separated files - int game_loop(t_cub3d_data *data) { t_ray ray; @@ -43,6 +42,7 @@ int game_loop(t_cub3d_data *data) reset_matrix(data); raycaster(data, &ray); move_player(data); + sprite_caster(data); matrix_to_image(data); draw_map(data->map, &data->player, data->img_data); mlx_put_image_to_window(data->mlx, data->mlx_win, @@ -63,7 +63,7 @@ int main(int argc, char **argv) // placing a sprite next to player to ease debugging data.static_sprite[0].x = data.map->startx + 1; data.static_sprite[0].y = data.map->starty; - data.static_sprite[0].texture = mlx_xpm_file_to_image(&data.mlx, "ressources/box.xpm", &data.static_sprite[0].texture_width, &data.static_sprite[0].texture_height); + data.static_sprite[0].image = load_single_texture(&data, "ressources/box_no_transparent.xpm"); mlx_hook(data.mlx_win, KeyPress, KeyPressMask, keypress_handler, &data); mlx_hook(data.mlx_win, KeyRelease, KeyReleaseMask, keyrelease_handler, &data); diff --git a/src/sprites/sprite.h b/src/sprites/sprite.h index a11a686..ddd7e91 100644 --- a/src/sprites/sprite.h +++ b/src/sprites/sprite.h @@ -6,20 +6,22 @@ /* By: tchampio +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/08/05 12:59:44 by tchampio #+# #+# */ -/* Updated: 2025/08/05 13:19:30 by tchampio ### ########.fr */ +/* Updated: 2025/08/06 12:13:12 by tchampio ### ########.fr */ /* */ /* ************************************************************************** */ #ifndef SPRITE_H # define SPRITE_H +# include "../draw/img_data.h" + typedef struct s_sprite { double x; double y; - void *texture; - int texture_width; - int texture_height; + t_img_data *image; + int img_width; + int img_height; } t_sprite; #endif // SPRITE_H diff --git a/src/sprites/sprite_caster.c b/src/sprites/sprite_caster.c new file mode 100644 index 0000000..08f0f1b --- /dev/null +++ b/src/sprites/sprite_caster.c @@ -0,0 +1,138 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* sprite_caster.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: tchampio +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/08/05 15:51:01 by tchampio #+# #+# */ +/* Updated: 2025/08/06 13:46:34 by tchampio ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "../cub3d_data.h" +#include "../draw/drawutils.h" +#include "../renderer/render.h" +#include +#include +#include + +static void swap(int i, int j, int *spriteorder, double *spritedist) +{ + double tmp_dist; + int tmp_order; + + tmp_order = spriteorder[i]; + tmp_dist = spritedist[i]; + spriteorder[i] = spriteorder[j]; + spritedist[i] = spritedist[j]; + spriteorder[j] = tmp_order; + spritedist[j] = tmp_dist; +} + +// the sorting part is a readaptation of the std::sort function from c++ +// more info on here: https://stackoverflow.com/questions/23816797/how-does-stdsort-work-for-list-of-pairs +static void sort_sprites(int *spriteorder, double *spritedist, t_cub3d_data *data) +{ + int i; + int j; + int k; + int order[MAX_SPRITES]; + double dist[MAX_SPRITES]; + + i = 0; + while (i < MAX_SPRITES) + { + order[i] = i; + dist[i] = ((data->player.x - data->static_sprite[i].x) * (data->player.x - data->static_sprite[i].x) + (data->player.y - data->static_sprite[i].y) * (data->player.y - data->static_sprite[i].y)); + i++; + } + j = 0; + while (j < MAX_SPRITES) + { + k = 0; + while (j < MAX_SPRITES - j - 1) + { + if (dist[k] < dist[k + 1] && dist[k] != -1) + swap(k, k + 1, order, dist); + k++; + } + j++; + } + i = 0; + while (i < MAX_SPRITES) + { + spritedist[i] = dist[MAX_SPRITES - i - 1]; + spriteorder[i] = order[MAX_SPRITES - i - 1]; + i++; + } +} + +void sprite_caster(t_cub3d_data *data) +{ + int i; + double spriteX; + double spriteY; + double invDet; + double transformX; + double transformY; + int spriteScreenX; + int spriteHeight; + int spriteDrawStartY; + int spriteDrawEndY; + int spriteWidth; + int spriteDrawStartX; + int spriteDrawEndX; + int stripe; + int texX; + int d; + int texY; + int color; + int j; + + sort_sprites(data->sprite_order, data->sprite_distances, data); + i = 0; + while (i < MAX_SPRITES) + { + spriteX = data->static_sprite[i].x - data->player.x; + spriteY = data->static_sprite[i].y - data->player.y; + invDet = 1.0 / (data->player.plane_x * data->player.dir_y - data->player.dir_x * data->player.plane_y); + transformX = invDet * (data->player.dir_y * spriteX - data->player.dir_x * spriteY); + transformY = invDet * (-data->player.plane_y * spriteX + data->player.plane_x * spriteY); + spriteScreenX = (int)((WIDTH / 2) * (1 + transformX / transformY)); + spriteHeight = (int)fabs((HEIGHT / transformY)); + spriteDrawStartY = -spriteHeight / 2 + HEIGHT / 2; + if (spriteDrawStartY < 0) + spriteDrawStartY = 0; + spriteDrawEndY = spriteHeight / 2 + HEIGHT / 2; + if (spriteDrawEndY >= HEIGHT) + spriteDrawEndY = HEIGHT - 1; + spriteWidth = (int)fabs((HEIGHT / transformY)); + spriteDrawStartX = -spriteWidth / 2 + spriteScreenX; + if (spriteDrawStartX < 0) + spriteDrawStartX = 0; + spriteDrawEndX = spriteWidth / 2 + spriteScreenX; + if (spriteDrawEndX >= WIDTH) + spriteDrawEndX = WIDTH - 1; + stripe = spriteDrawStartX; + while (stripe < spriteDrawEndX) + { + texX = (int)(256 * (stripe - (-spriteWidth / 2 + spriteScreenX)) * SIZE / spriteWidth) / 256; + if (transformY > 0 && stripe > 0 && stripe < WIDTH && transformY < data->zbuffer[stripe]) + { + j = spriteDrawStartY; + while (j < spriteDrawEndY) + { + d = (j) * 256 - HEIGHT * 128 + spriteHeight * 128; + texY = ((d * SIZE) / spriteHeight) / 256; + color = my_mlx_pixel_get(data->static_sprite[0].image, texX, texY); // data->static_sprite[0].image->img[SIZE * texY + texX]; + if ((color & SPRITE_TRANPARENCY_COLOR) != 0) + matrix_set(data, stripe, j, color); + j++; + } + } + stripe++; + } + i++; + } +} diff --git a/src/sprites/sprite_caster.h b/src/sprites/sprite_caster.h new file mode 100644 index 0000000..d5302e9 --- /dev/null +++ b/src/sprites/sprite_caster.h @@ -0,0 +1,20 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* sprite_caster.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: tchampio +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/08/06 12:13:32 by tchampio #+# #+# */ +/* Updated: 2025/08/06 12:14:23 by tchampio ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef SPRITE_CASTER_H +# define SPRITE_CASTER_H + +# include "../cub3d_data.h" + +void sprite_caster(t_cub3d_data *data); + +#endif // SPRITE_CASTER_H diff --git a/src/utils/inits.c b/src/utils/inits.c index 0447da4..0943f23 100644 --- a/src/utils/inits.c +++ b/src/utils/inits.c @@ -6,7 +6,7 @@ /* By: kcolin +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/07/31 13:43:05 by kcolin #+# #+# */ -/* Updated: 2025/08/05 13:19:40 by kcolin ### ########.fr */ +/* Updated: 2025/08/05 15:45:01 by tchampio ### ########.fr */ /* */ /* ************************************************************************** */ @@ -72,4 +72,5 @@ void init_cub3d_data(t_cub3d_data *data, char **argv) init_player(&data->player, data->map); data->screen_matrix = ft_calloc(sizeof(int), WIDTH * HEIGHT); load_textures(data); + ft_memset(data->sprite_distances, -1, MAX_SPRITES); } diff --git a/src/utils/inits.h b/src/utils/inits.h index 37bbef3..121857d 100644 --- a/src/utils/inits.h +++ b/src/utils/inits.h @@ -6,7 +6,7 @@ /* By: tchampio