Compare commits

..

11 commits

Author SHA1 Message Date
Theo Champion
258372bf09 feat: Added sprites 2025-08-06 14:06:52 +02:00
Theo Champion
7a1e8c18df dev: moved my_mlx_get_pixel function in draw utils for easier access 2025-08-06 14:05:40 +02:00
Theo Champion
aed03e79c3 fix: changed transparency color for the texture 2025-08-06 14:03:27 +02:00
Theo Champion
134a6e14f0 wip: trying to render sprites 2025-08-06 14:01:29 +02:00
Theo Champion
d3ba05a36d feat: Made a sprite structure and added a static sprite field in data
A static sprite is a sprite that is not supposed to move, it'll be
placed at the parsing part. The sprite struct is prone to change as I am
testing it
2025-08-06 14:01:29 +02:00
Theo Champion
07dc80ba6a feat: added a poorly drawn mystery box texture 2025-08-06 14:01:29 +02:00
a18c115ef1
fix: prevent crash due to out-of-bounds when game lags 2025-08-06 11:49:48 +02:00
1d6d97ef25
feat: enhance minimap rendering
- add heading indicator
- center of player icon is player position
- player size is independent of map tile size
- reduce minimap size
2025-08-05 15:23:31 +02:00
a46fdff49a
fix: correct error exit code when texture has error 2025-08-05 15:12:29 +02:00
a4d85c3cbb
tests: add test for detecting wrong texture size 2025-08-05 15:08:28 +02:00
c4bb3efe3e
feat: floor and ceiling colors 2025-08-05 15:01:35 +02:00
25 changed files with 450 additions and 77 deletions

View file

@ -15,6 +15,7 @@ SOURCEFILES = \
src/draw/drawutils.c \
src/main.c \
src/map/checkers.c \
src/map/collision.c \
src/map/forbidden_characters.c \
src/map/populate_map.c \
src/map/setters.c \
@ -27,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

View file

@ -0,0 +1,22 @@
NO ressources/north.xpm
SO ressources/south.xpm
WE ressources/west.xpm
EA ressources/bad_size.xpm
F 220,100,100
C 20,30,0
1111111111111111111111111
1000000000110000000000001
1011000001110000000000001
1001000000000000000000001
111111111011000001110000000000001
100000000011000001110111110111111
11110111111111011100000010001
11110111111111011101010010001
11000000110101011100000010001
10000000000000001100000010001
10000000000000001101010010001
11000001110101011111011110N0111
11110111 1110101 101111010001
11111111 1111111 111111111111

70
ressources/bad_size.xpm Normal file
View file

@ -0,0 +1,70 @@
/* XPM */
static char *dummy[]={
"65 64 3 1",
"# c #67502e",
"a c #833e4b",
". c #d6a459",
".................................................................",
".................................................................",
".................................................................",
".................................................................",
".................................................................",
".................................................................",
".................................................................",
".................................................................",
".................................................................",
"............................####.................................",
".........................###....##...............................",
"......................###........................................",
".....................#...........................................",
"....................#............................................",
"...................#.............................................",
"..................#..............................................",
"..................#..............................................",
"..................#..............................................",
"..................#..............................................",
"...................##............................................",
".....................##..........................................",
".......................#.........................................",
"........................##.......................................",
"..........................##.....................................",
"............................##...................................",
"..............................###................................",
".................................#...............................",
"..................................#..............................",
"..................................#..............................",
"..................................#..............................",
"..................................#..............................",
"..................................#..............................",
".................................#...............................",
"................................#................................",
"..............................##.................................",
"............................##...................................",
"....................########.....................................",
".................................................................",
".................................................................",
"........aa.......................................................",
"........aaa......................................................",
"........a.a......................................................",
".......a..a......................................................",
".......a..a.......aa.....................aaa.....................",
".......a..a.......aa....................a.......a................",
".......aaaa......a.a......aaaa..........a.......a.a..............",
".......aa........aaaa......a..a.........aaa.....a..aaa...........",
".......aa.......a...a......a..aa..........a.....a....a....aaa....",
".......a.a.....a....a......a....a........aa....a...aaa...aa......",
".......a.a.....a....a......a....a................aa......a.......",
".......a.a.....a....a......a....a................aaa.....aaa.....",
".......a.aa................a..aa....................aaa..aa......",
".......aaa.................a..a.......................a..a.......",
".......a...................aaa...........................aaa.....",
"...........................aa....................................",
".................................................................",
".................................................................",
".................................................................",
".................................................................",
".................................................................",
".................................................................",
".................................................................",
".................................................................",
"................................................................."};

View file

@ -1,7 +1,7 @@
/* XPM */
static char * box_xpm[] = {
"64 64 15 1",
" c None",
" c #FF00DC",
". c #914500",
"+ c #B2A600",
"@ c #B9B400",

View file

@ -3,8 +3,8 @@ SO ressources/south.xpm
WE ressources/west.xpm
EA ressources/east.xpm
F 220,100,0
C 225,30,0
F 220,100,100
C 20,30,0
1111111111111111111111111
1000000000110000000000001

View file

@ -6,27 +6,31 @@
/* By: kcolin <kcolin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/07/17 14:54:36 by kcolin #+# #+# */
/* Updated: 2025/07/31 15:02:18 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 20
# 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

View file

@ -6,7 +6,7 @@
/* By: kcolin <kcolin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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

View file

@ -6,7 +6,7 @@
/* By: kcolin <kcolin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/07/17 14:20:00 by kcolin #+# #+# */
/* Updated: 2025/07/29 14:16:07 by tchampio ### ########.fr */
/* Updated: 2025/08/05 15:20:47 by kcolin ### ########.fr */
/* */
/* ************************************************************************** */
@ -14,6 +14,7 @@
#include "../player/player.h"
#include "drawutils.h"
#include "../consts.h"
#include "img_data.h"
void draw_2d_wall(unsigned int color, t_img_data *data,
int x, int y)
@ -34,6 +35,35 @@ void draw_2d_wall(unsigned int color, t_img_data *data,
}
}
void draw_player(unsigned int color, t_img_data *data,
int x, int y)
{
int i;
int j;
i = -(PLAYER_SIZE / 2);
while (i < (PLAYER_SIZE / 2))
{
j = -(PLAYER_SIZE / 2);
while (j < (PLAYER_SIZE / 2))
{
my_mlx_pixel_put(data, x + i, y + j, color);
j++;
}
i++;
}
}
void draw_heading(unsigned int color, t_img_data *data, t_player *player)
{
int x;
int y;
x = player->x * MAP_SIZE + player->dir_x * PLAYER_SIZE;
y = player->y * MAP_SIZE + player->dir_y * PLAYER_SIZE;
my_mlx_pixel_put(data, x, y, color);
}
void draw_map(t_mapdata *map, t_player *player, t_img_data *data)
{
int i;
@ -59,5 +89,6 @@ void draw_map(t_mapdata *map, t_player *player, t_img_data *data)
}
i++;
}
draw_2d_wall(0x00FF0000, data, MAP_SIZE * player->x, MAP_SIZE * player->y);
draw_player(0x00FF0000, data, MAP_SIZE * player->x, MAP_SIZE * player->y);
draw_heading(0x00FFFFFF, data, player);
}

View file

@ -6,16 +6,27 @@
/* By: kcolin <kcolin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/07/17 14:28:56 by kcolin #+# #+# */
/* Updated: 2025/07/17 15:48:56 by kcolin ### ########.fr */
/* Updated: 2025/08/06 14:02:08 by tchampio ### ########.fr */
/* */
/* ************************************************************************** */
#include "img_data.h"
#include "../consts.h"
int my_mlx_pixel_get(t_img_data *img, int x, int y)
{
char *dst;
dst = img->addr + (y * img->line_length + x * (img->bits_per_pixel / 8));
return (*(int *)dst);
}
void my_mlx_pixel_put(t_img_data *data, int x, int y, int color)
{
char *dst;
if (x < 0 || y < 0 || x >= HEIGHT || y >= WIDTH)
return ;
dst = data->addr + (y * data->line_length + x * (data->bits_per_pixel / 8));
*(unsigned int *)dst = color;
}

View file

@ -6,7 +6,7 @@
/* By: kcolin <kcolin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/07/17 14:30:04 by kcolin #+# #+# */
/* Updated: 2025/07/17 15:57:47 by kcolin ### ########.fr */
/* Updated: 2025/08/06 12:08:04 by tchampio ### ########.fr */
/* */
/* ************************************************************************** */
@ -16,5 +16,6 @@
# include "img_data.h"
void my_mlx_pixel_put(t_img_data *data, int x, int y, int color);
int my_mlx_pixel_get(t_img_data *img, int x, int y);
#endif // DRAWUTILS_H

View file

@ -6,7 +6,7 @@
/* By: kcolin <kcolin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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 <fcntl.h>
#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);

38
src/map/collision.c Normal file
View file

@ -0,0 +1,38 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* collision.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: kcolin <kcolin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/08/06 11:25:05 by kcolin #+# #+# */
/* Updated: 2025/08/06 11:49:00 by kcolin ### ########.fr */
/* */
/* ************************************************************************** */
#include "collision.h"
#include "../../libft/includes/libft.h"
static bool out_of_bounds(t_mapdata *data, int x, int y)
{
if (x < 0
|| y < 0
|| x >= data->mapheight
|| y > (int)ft_strlen(data->map[x]))
return (true);
return (false);
}
bool blocks_movement(t_mapdata *data, int x, int y)
{
if (out_of_bounds(data, x, y) || data->map[x][y] == '1')
return (true);
return (false);
}
bool blocks_view(t_mapdata *data, int x, int y)
{
if (out_of_bounds(data, x, y) || data->map[x][y] == '1')
return (true);
return (false);
}

21
src/map/collision.h Normal file
View file

@ -0,0 +1,21 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* collision.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: kcolin <kcolin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/08/06 11:24:10 by kcolin #+# #+# */
/* Updated: 2025/08/06 11:28:57 by kcolin ### ########.fr */
/* */
/* ************************************************************************** */
#ifndef COLLISION_H
# define COLLISION_H
# include "mapdata.h"
bool blocks_movement(t_mapdata *data, int x, int y);
bool blocks_view(t_mapdata *data, int x, int y);
#endif // COLLISION_H

View file

@ -6,79 +6,80 @@
/* By: kcolin <kcolin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/08/05 12:53:06 by kcolin #+# #+# */
/* Updated: 2025/08/05 12:53:06 by kcolin ### ########.fr */
/* Updated: 2025/08/06 11:46:04 by kcolin ### ########.fr */
/* */
/* ************************************************************************** */
#include "../cub3d_data.h"
#include "angle.h"
#include "../consts.h"
#include "../map/collision.h"
void move_player_forward(t_cub3d_data *data)
{
char **map;
t_mapdata *map;
double next_x;
double next_y;
float movspeed;
movspeed = MOVEMENT_SPEED * data->delta;
map = data->map->map;
map = data->map;
next_x = data->player.x + data->player.dir_x * movspeed;
next_y = data->player.y + data->player.dir_y * movspeed;
if (map[(int)data->player.y][(int)next_x] == '0')
if (!blocks_movement(map, (int)data->player.y, (int)next_x))
data->player.x += data->player.dir_x * movspeed;
if (map[(int)next_y][(int)data->player.x] == '0')
if (!blocks_movement(map, (int)next_y, (int)data->player.x))
data->player.y += data->player.dir_y * movspeed;
}
void move_player_backward(t_cub3d_data *data)
{
char **map;
t_mapdata *map;
double next_x;
double next_y;
float movspeed;
movspeed = MOVEMENT_SPEED * data->delta;
map = data->map->map;
map = data->map;
next_x = data->player.x - data->player.dir_x * movspeed;
next_y = data->player.y - data->player.dir_y * movspeed;
if (map[(int)data->player.y][(int)next_x] == '0')
if (!blocks_movement(map, (int)data->player.y, (int)next_x))
data->player.x -= data->player.dir_x * movspeed;
if (map[(int)next_y][(int)data->player.x] == '0')
if (!blocks_movement(map, (int)next_y, (int)data->player.x))
data->player.y -= data->player.dir_y * movspeed;
}
void move_player_strafe_left(t_cub3d_data *data)
{
char **map;
t_mapdata *map;
double next_x;
double next_y;
float movspeed;
movspeed = MOVEMENT_SPEED * data->delta;
map = data->map->map;
map = data->map;
next_x = data->player.x - data->player.plane_x * movspeed;
next_y = data->player.y - data->player.plane_y * movspeed;
if (map[(int)data->player.y][(int)next_x] == '0')
if (!blocks_movement(map, (int)data->player.y, (int)next_x))
data->player.x -= data->player.plane_x * movspeed;
if (map[(int)next_y][(int)data->player.x] == '0')
if (!blocks_movement(map, (int)next_y, (int)data->player.x))
data->player.y -= data->player.plane_y * movspeed;
}
void move_player_strafe_right(t_cub3d_data *data)
{
char **map;
t_mapdata *map;
double next_x;
double next_y;
float movspeed;
movspeed = MOVEMENT_SPEED * data->delta;
map = data->map->map;
map = data->map;
next_x = data->player.x + data->player.plane_x * movspeed;
next_y = data->player.y + data->player.plane_y * movspeed;
if (map[(int)data->player.y][(int)next_x] == '0')
if (!blocks_movement(map, (int)data->player.y, (int)next_x))
data->player.x += data->player.plane_x * movspeed;
if (map[(int)next_y][(int)data->player.x] == '0')
if (!blocks_movement(map, (int)next_y, (int)data->player.x))
data->player.y += data->player.plane_y * movspeed;
}

View file

@ -3,10 +3,10 @@
/* ::: :::::::: */
/* player.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: tchampio <tchampio@student.42lehavre. +#+ +:+ +#+ */
/* By: kcolin <kcolin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/07/29 11:42:44 by tchampio #+# #+# */
/* Updated: 2025/07/29 20:13:01 by tchampio ### ########.fr */
/* Created: 2025/08/06 11:29:14 by kcolin #+# #+# */
/* Updated: 2025/08/06 11:29:14 by kcolin ### ########.fr */
/* */
/* ************************************************************************** */
@ -59,7 +59,6 @@ void init_player(t_player *player, t_mapdata *map)
dir = map->map[map->starty][map->startx];
player->x = map->startx + 0.5;
player->y = map->starty + 0.5;
map->map[map->starty][map->startx] = '0';
player->health = 100;
player->points = 500;
if (dir == 'N' || dir == 'S')

View file

@ -6,7 +6,7 @@
/* By: kcolin <kcolin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/07/31 11:55:41 by kcolin #+# #+# */
/* Updated: 2025/07/31 11:58:02 by kcolin ### ########.fr */
/* Updated: 2025/08/06 14:02:40 by tchampio ### ########.fr */
/* */
/* ************************************************************************** */
@ -17,6 +17,7 @@
#include "../cub3d_data.h"
#include <float.h>
#include <math.h>
#include "../map/collision.h"
void init_ray(t_ray *ray, int pos_x, t_player *player)
{
@ -53,7 +54,7 @@ void ray_calculate_step(t_ray *ray, t_player *player)
}
}
void calculate_wall_dist(t_ray *ray, char **map)
void calculate_wall_dist(t_ray *ray, t_mapdata *map)
{
while (true)
{
@ -69,7 +70,7 @@ void calculate_wall_dist(t_ray *ray, char **map)
ray->map_y += ray->step_y;
ray->side = SOUTH;
}
if (map[ray->map_y][ray->map_x] != '0')
if (blocks_view(map, ray->map_y, ray->map_x))
break ;
}
if (ray->side == NORTH)
@ -105,9 +106,10 @@ void raycaster(t_cub3d_data *data, t_ray *ray)
{
init_ray(ray, x, &data->player);
ray_calculate_step(ray, &data->player);
calculate_wall_dist(ray, data->map->map);
calculate_wall_dist(ray, data->map);
calculate_wall_height(ray, &data->player);
render_walls(data, ray, x);
data->zbuffer[x] = ray->wall_dist;
x++;
}
}

View file

@ -6,7 +6,7 @@
/* By: kcolin <kcolin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/07/31 13:17:39 by kcolin #+# #+# */
/* Updated: 2025/08/05 13:25:01 by kcolin ### ########.fr */
/* Updated: 2025/08/06 12:08:33 by tchampio ### ########.fr */
/* */
/* ************************************************************************** */
@ -14,6 +14,7 @@
#include "../consts.h"
#include "ray.h"
#include "../renderer/render.h"
#include "../draw/drawutils.h"
t_cardinal_dir get_cardinal(t_ray *ray)
{
@ -33,13 +34,6 @@ t_cardinal_dir get_cardinal(t_ray *ray)
}
}
static int my_mlx_pixel_get(t_img_data *img, int x, int y)
{
char *dst;
dst = img->addr + (y * img->line_length + x * (img->bits_per_pixel / 8));
return (*(int *)dst);
}
static int get_color(t_cub3d_data *data, t_ray *ray, int tex_y)
{
@ -70,14 +64,26 @@ void render_walls(t_cub3d_data *data, t_ray *ray, int x)
unsigned int color;
double step;
double tex_y;
int y;
step = 1.0 * TEXTURE_SIZE / ray->wall_height;
tex_y = (ray->draw_start - HEIGHT / 2 + ray->wall_height / 2) * step;
while (ray->draw_start < ray->draw_end)
y = 0;
while (y < ray->draw_start)
{
matrix_set(data, x, y, data->map->c_color);
y++;
}
while (y < ray->draw_end - 1)
{
tex_y += step;
color = get_color(data, ray, (int)tex_y);
matrix_set(data, x, ray->draw_start, color);
ray->draw_start++;
matrix_set(data, x, y, color);
y++;
}
while (y < HEIGHT)
{
matrix_set(data, x, y, data->map->f_color);
y++;
}
}

View file

@ -6,20 +6,22 @@
/* By: tchampio <tchampio@student.42lehavre.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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

138
src/sprites/sprite_caster.c Normal file
View file

@ -0,0 +1,138 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* sprite_caster.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: tchampio <tchampio@student.42lehavre.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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 <math.h>
#include <stdio.h>
#include <stdlib.h>
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++;
}
}

View file

@ -0,0 +1,20 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* sprite_caster.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: tchampio <tchampio@student.42lehavre.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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

View file

@ -58,7 +58,7 @@ void free_map(t_mapdata *map)
free(map);
}
int destroy(t_cub3d_data *data)
int destroy(t_cub3d_data *data, int exit_code)
{
free_map(data->map);
if (data->mlx_win)
@ -82,7 +82,7 @@ int destroy(t_cub3d_data *data)
mlx_destroy_display(data->mlx);
free(data->mlx);
free(data->screen_matrix);
exit(0);
exit(exit_code);
return (0);
}

View file

@ -16,7 +16,7 @@
# include "../cub3d_data.h"
void gnl_exhaust(int fd);
int destroy(t_cub3d_data *data);
int destroy(t_cub3d_data *data, int exit_code);
void free_tab(char **tab);
void free_tab_length(char **tab, int length);
void free_map(t_mapdata *map);

View file

@ -22,7 +22,7 @@
int keypress_handler(int keycode, t_cub3d_data *data)
{
if (keycode == XK_Escape)
destroy(data);
destroy(data, 0);
if (keycode == XK_w)
data->keypresses.is_w_pressed = true;
if (keycode == XK_a)

View file

@ -6,7 +6,7 @@
/* By: kcolin <kcolin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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 */
/* */
/* ************************************************************************** */
@ -28,12 +28,12 @@ t_img_data *load_single_texture(t_cub3d_data *data, char *path)
if (img == NULL)
{
ft_printf("Error: failed to open image at %s\n", path);
destroy(data);
destroy(data, 1);
}
if (width != height || width != TEXTURE_SIZE)
{
ft_printf("Error: textures are not the right size\n");
destroy(data);
destroy(data, 1);
}
ft_printf("image: %p\n", img);
img_data = ft_calloc(sizeof(t_img_data), 1);
@ -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);
}

View file

@ -6,7 +6,7 @@
/* By: tchampio <tchampio@student.42lehavre. +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/07/31 13:28:47 by tchampio #+# #+# */
/* Updated: 2025/07/31 13:29:35 by tchampio ### ########.fr */
/* Updated: 2025/08/05 15:05:10 by tchampio ### ########.fr */
/* */
/* ************************************************************************** */
@ -16,5 +16,6 @@
# include "../cub3d_data.h"
void init_cub3d_data(t_cub3d_data *data, char **argv);
t_img_data *load_single_texture(t_cub3d_data *data, char *path);
#endif // INITS_H