github to gitea
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* draw.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: jle-neze <[email protected]> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2025/09/12 18:18:26 by jle-neze #+# #+# */
|
||||
/* Updated: 2025/09/12 18:18:52 by jle-neze ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "cub.h"
|
||||
|
||||
void draw_background(t_game *g)
|
||||
{
|
||||
int x, y, half = g->gfx.h / 2;
|
||||
|
||||
for (y = 0; y < g->gfx.h; y++)
|
||||
{
|
||||
for (x = 0; x < g->gfx.w; x++)
|
||||
{
|
||||
if (y < half)
|
||||
img_put_pixel(&g->gfx.frame, x, y, g->colors.ceil);
|
||||
else
|
||||
img_put_pixel(&g->gfx.frame, x, y, g->colors.floor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* aussi exposée dans raycast.c, mais on garde la déclaration ici pour réutiliser ailleurs */
|
||||
void draw_vline(t_game *g, int x, int y0, int y1, int color)
|
||||
{
|
||||
if (y0 < 0) y0 = 0;
|
||||
if (y1 >= g->gfx.h) y1 = g->gfx.h - 1;
|
||||
for (int y = y0; y <= y1; y++)
|
||||
img_put_pixel(&g->gfx.frame, x, y, color);
|
||||
}
|
||||
|
||||
void draw_tex_vline(t_game *g, int x, int y0, int y1,
|
||||
t_tex *tex, int tex_x, double step, double tex_pos)
|
||||
{
|
||||
if (y0 < 0)
|
||||
{
|
||||
tex_pos += step * (-y0);
|
||||
y0 = 0;
|
||||
}
|
||||
if (y1 >= g->gfx.h)
|
||||
y1 = g->gfx.h - 1;
|
||||
for (int y = y0; y <= y1; y++)
|
||||
{
|
||||
int tex_y = (int)tex_pos;
|
||||
if (tex_y < 0) tex_y = 0;
|
||||
if (tex_y >= tex->h) tex_y = tex->h - 1;
|
||||
unsigned int color = tex_get_pixel(tex, tex_x, tex_y);
|
||||
img_put_pixel(&g->gfx.frame, x, y, (int)color);
|
||||
tex_pos += step;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* hooks.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: jle-neze <[email protected]> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2025/09/12 18:19:19 by jle-neze #+# #+# */
|
||||
/* Updated: 2025/09/12 18:19:22 by jle-neze ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "cub.h"
|
||||
#include "keys.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
int on_destroy(t_game *g)
|
||||
{
|
||||
textures_free(g);
|
||||
cleanup_window(g);
|
||||
world_free(&g->world);
|
||||
/* Libérer data si disponible */
|
||||
if (g->data)
|
||||
{
|
||||
free_textures(g->data->texture);
|
||||
free_data(g->data);
|
||||
}
|
||||
exit(0);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
static void set_key(int key, t_game *g, int press)
|
||||
{
|
||||
if (key == KEY_W) g->in.w = press;
|
||||
if (key == KEY_A) g->in.a = press;
|
||||
if (key == KEY_S) g->in.s = press;
|
||||
if (key == KEY_D) g->in.d = press;
|
||||
if (key == KEY_LEFT) g->in.left = press;
|
||||
if (key == KEY_RIGHT) g->in.right = press;
|
||||
}
|
||||
|
||||
int on_keydown(int key, t_game *g)
|
||||
{
|
||||
if (key == KEY_ESC)
|
||||
on_destroy(g);
|
||||
set_key(key, g, 1);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int on_keyup(int key, t_game *g)
|
||||
{
|
||||
set_key(key, g, 0);
|
||||
return (0);
|
||||
}
|
||||
|
||||
void setup_hooks(t_game *g)
|
||||
{
|
||||
/* croix de fermeture */
|
||||
mlx_hook(g->gfx.win, 17, 0, on_destroy, g);
|
||||
/* KeyPress / KeyRelease */
|
||||
mlx_hook(g->gfx.win, 2, 1L<<0, on_keydown, g);
|
||||
mlx_hook(g->gfx.win, 3, 1L<<1, on_keyup, g);
|
||||
/* boucle */
|
||||
mlx_loop_hook(g->gfx.mlx, game_loop, g);
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* image.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: jle-neze <[email protected]> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2025/09/12 18:19:47 by jle-neze #+# #+# */
|
||||
/* Updated: 2025/09/12 18:19:49 by jle-neze ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "cub.h"
|
||||
|
||||
void img_put_pixel(t_img *img, int x, int y, int color)
|
||||
{
|
||||
char *dst;
|
||||
|
||||
if (x < 0 || y < 0 || x >= img->w || y >= img->h)
|
||||
return ;
|
||||
dst = img->addr + (y * img->line_len + x * (img->bpp / 8));
|
||||
*(unsigned int *)dst = (unsigned int)color;
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* init.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: jle-neze <[email protected]> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2025/09/12 18:20:06 by jle-neze #+# #+# */
|
||||
/* Updated: 2025/09/12 18:20:08 by jle-neze ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "cub.h"
|
||||
|
||||
int init_window(t_game *g, int w, int h, char *title)
|
||||
{
|
||||
g->gfx.w = w;
|
||||
g->gfx.h = h;
|
||||
g->gfx.mlx = mlx_init();
|
||||
if (!g->gfx.mlx)
|
||||
return (1);
|
||||
g->gfx.win = mlx_new_window(g->gfx.mlx, w, h, title);
|
||||
if (!g->gfx.win)
|
||||
return (1);
|
||||
g->gfx.frame.ptr = mlx_new_image(g->gfx.mlx, w, h);
|
||||
if (!g->gfx.frame.ptr)
|
||||
return (1);
|
||||
g->gfx.frame.addr = mlx_get_data_addr(g->gfx.frame.ptr, &g->gfx.frame.bpp,
|
||||
&g->gfx.frame.line_len, &g->gfx.frame.endian);
|
||||
g->gfx.frame.w = w;
|
||||
g->gfx.frame.h = h;
|
||||
return (0);
|
||||
}
|
||||
|
||||
void cleanup_window(t_game *g)
|
||||
{
|
||||
if (!g)
|
||||
return ;
|
||||
if (g->gfx.frame.ptr)
|
||||
{
|
||||
mlx_destroy_image(g->gfx.mlx, g->gfx.frame.ptr);
|
||||
g->gfx.frame.ptr = NULL;
|
||||
}
|
||||
if (g->gfx.win)
|
||||
{
|
||||
mlx_destroy_window(g->gfx.mlx, g->gfx.win);
|
||||
g->gfx.win = NULL;
|
||||
}
|
||||
if (g->gfx.mlx)
|
||||
{
|
||||
mlx_destroy_display(g->gfx.mlx);
|
||||
free(g->gfx.mlx);
|
||||
g->gfx.mlx = NULL;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* loop.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: jle-neze <[email protected]> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2025/09/12 18:24:03 by jle-neze #+# #+# */
|
||||
/* Updated: 2025/09/12 18:24:05 by jle-neze ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "cub.h"
|
||||
|
||||
int game_loop(t_game *g)
|
||||
{
|
||||
/* 1) Update joueur selon input */
|
||||
player_update(g);
|
||||
/* 2) Dessin */
|
||||
draw_background(g);
|
||||
raycast_frame(g);
|
||||
mlx_put_image_to_window(g->gfx.mlx, g->gfx.win, g->gfx.frame.ptr, 0, 0);
|
||||
return (0);
|
||||
}
|
||||
/* Note: on pourrait optimiser en ne redessinant que ce qui change */
|
||||
@@ -0,0 +1,80 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* player.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: jle-neze <[email protected]> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2025/09/12 18:24:21 by jle-neze #+# #+# */
|
||||
/* Updated: 2025/09/12 18:24:22 by jle-neze ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "cub.h"
|
||||
|
||||
void player_init(t_game *g, double px, double py, double dx, double dy)
|
||||
{
|
||||
g->cam.pos_x = px;
|
||||
g->cam.pos_y = py;
|
||||
g->cam.dir_x = dx;
|
||||
g->cam.dir_y = dy;
|
||||
/* FOV ≈ 66° → plane perpendiculaire (0.66) */
|
||||
g->cam.plane_x = -dy * 0.66;
|
||||
g->cam.plane_y = dx * 0.66;
|
||||
g->move_speed = 0.07; /* ajuste si besoin */
|
||||
g->rot_speed = 0.05; /* rad/frame */
|
||||
}
|
||||
|
||||
/* petits helpers collision */
|
||||
static int is_wall(t_world *w, int mx, int my)
|
||||
{
|
||||
if (mx < 0 || my < 0 || mx >= w->w || my >= w->h) return (1);
|
||||
return (w->grid[my][mx] == '1');
|
||||
}
|
||||
|
||||
void player_update(t_game *g)
|
||||
{
|
||||
double nx, ny;
|
||||
|
||||
/* Avancer/retour W/S */
|
||||
if (g->in.w)
|
||||
{
|
||||
nx = g->cam.pos_x + g->cam.dir_x * g->move_speed;
|
||||
ny = g->cam.pos_y + g->cam.dir_y * g->move_speed;
|
||||
if (!is_wall(&g->world, (int)nx, (int)g->cam.pos_y)) g->cam.pos_x = nx;
|
||||
if (!is_wall(&g->world, (int)g->cam.pos_x, (int)ny)) g->cam.pos_y = ny;
|
||||
}
|
||||
if (g->in.s)
|
||||
{
|
||||
nx = g->cam.pos_x - g->cam.dir_x * g->move_speed;
|
||||
ny = g->cam.pos_y - g->cam.dir_y * g->move_speed;
|
||||
if (!is_wall(&g->world, (int)nx, (int)g->cam.pos_y)) g->cam.pos_x = nx;
|
||||
if (!is_wall(&g->world, (int)g->cam.pos_x, (int)ny)) g->cam.pos_y = ny;
|
||||
}
|
||||
/* Strafe A/D (gauche/droite) */
|
||||
if (g->in.a)
|
||||
{
|
||||
nx = g->cam.pos_x - g->cam.dir_y * g->move_speed;
|
||||
ny = g->cam.pos_y + g->cam.dir_x * g->move_speed;
|
||||
if (!is_wall(&g->world, (int)nx, (int)g->cam.pos_y)) g->cam.pos_x = nx;
|
||||
if (!is_wall(&g->world, (int)g->cam.pos_x, (int)ny)) g->cam.pos_y = ny;
|
||||
}
|
||||
if (g->in.d)
|
||||
{
|
||||
nx = g->cam.pos_x + g->cam.dir_y * g->move_speed;
|
||||
ny = g->cam.pos_y - g->cam.dir_x * g->move_speed;
|
||||
if (!is_wall(&g->world, (int)nx, (int)g->cam.pos_y)) g->cam.pos_x = nx;
|
||||
if (!is_wall(&g->world, (int)g->cam.pos_x, (int)ny)) g->cam.pos_y = ny;
|
||||
}
|
||||
/* Rotation gauche/droite */
|
||||
if (g->in.left || g->in.right)
|
||||
{
|
||||
double rs = g->rot_speed * (g->in.right ? 1.0 : -1.0);
|
||||
double old_dir_x = g->cam.dir_x;
|
||||
g->cam.dir_x = g->cam.dir_x * cos(rs) - g->cam.dir_y * sin(rs);
|
||||
g->cam.dir_y = old_dir_x * sin(rs) + g->cam.dir_y * cos(rs);
|
||||
double old_plane_x = g->cam.plane_x;
|
||||
g->cam.plane_x = g->cam.plane_x * cos(rs) - g->cam.plane_y * sin(rs);
|
||||
g->cam.plane_y = old_plane_x * sin(rs) + g->cam.plane_y * cos(rs);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,243 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* raycast.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: jle-neze <[email protected]> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2025/09/12 18:24:37 by jle-neze #+# #+# */
|
||||
/* Updated: 2025/10/26 02:20:06 by lfirmin ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "cub.h"
|
||||
|
||||
// /* petite fonction utilitaire: trace une ligne verticale remplie */
|
||||
// void draw_vline(t_game *g, int x, int y0, int y1, int color)
|
||||
// {
|
||||
// if (y0 < 0) y0 = 0;
|
||||
// if (y1 >= g->gfx.h) y1 = g->gfx.h - 1;
|
||||
// for (int y = y0; y <= y1; y++)
|
||||
// img_put_pixel(&g->gfx.frame, x, y, color);
|
||||
// }
|
||||
|
||||
/* Version 1: simple couleurs */
|
||||
// void raycast_frame(t_game *g)
|
||||
// {
|
||||
// for (int x = 0; x < g->gfx.w; x++)
|
||||
// {
|
||||
// double camera_x = 2.0 * x / (double)g->gfx.w - 1.0;
|
||||
// double ray_dir_x = g->cam.dir_x + g->cam.plane_x * camera_x;
|
||||
// double ray_dir_y = g->cam.dir_y + g->cam.plane_y * camera_x;
|
||||
|
||||
// int map_x = (int)g->cam.pos_x;
|
||||
// int map_y = (int)g->cam.pos_y;
|
||||
|
||||
// double delta_dist_x = (ray_dir_x == 0) ? 1e30 : fabs(1.0 / ray_dir_x);
|
||||
// double delta_dist_y = (ray_dir_y == 0) ? 1e30 : fabs(1.0 / ray_dir_y);
|
||||
|
||||
// int step_x, step_y;
|
||||
// double side_dist_x, side_dist_y;
|
||||
|
||||
// if (ray_dir_x < 0)
|
||||
// {
|
||||
// step_x = -1;
|
||||
// side_dist_x = (g->cam.pos_x - map_x) * delta_dist_x;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// step_x = 1;
|
||||
// side_dist_x = (map_x + 1.0 - g->cam.pos_x) * delta_dist_x;
|
||||
// }
|
||||
// if (ray_dir_y < 0)
|
||||
// {
|
||||
// step_y = -1;
|
||||
// side_dist_y = (g->cam.pos_y - map_y) * delta_dist_y;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// step_y = 1;
|
||||
// side_dist_y = (map_y + 1.0 - g->cam.pos_y) * delta_dist_y;
|
||||
// }
|
||||
|
||||
// int hit = 0;
|
||||
// int side = 0; /* 0:x, 1:y */
|
||||
|
||||
// while (!hit)
|
||||
// {
|
||||
// if (side_dist_x < side_dist_y)
|
||||
// {
|
||||
// side_dist_x += delta_dist_x;
|
||||
// map_x += step_x;
|
||||
// side = 0;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// side_dist_y += delta_dist_y;
|
||||
// map_y += step_y;
|
||||
// side = 1;
|
||||
// }
|
||||
// if (map_x < 0 || map_y < 0 || map_x >= g->world.w || map_y >= g->world.h
|
||||
// || g->world.grid[map_y][map_x] == '1')
|
||||
// hit = 1;
|
||||
// }
|
||||
// double perp_wall_dist;
|
||||
// if (side == 0)
|
||||
// perp_wall_dist = (side_dist_x - delta_dist_x);
|
||||
// else
|
||||
// perp_wall_dist = (side_dist_y - delta_dist_y);
|
||||
|
||||
// int line_h = (int)(g->gfx.h / (perp_wall_dist > 1e-6 ? perp_wall_dist : 1e-6));
|
||||
// int draw_start = -line_h / 2 + g->gfx.h / 2;
|
||||
// int draw_end = line_h / 2 + g->gfx.h / 2;
|
||||
|
||||
// /* Couleur: simple code NSEW selon step & side */
|
||||
// int color_idx;
|
||||
// if (side == 0)
|
||||
// color_idx = (step_x < 0) ? 2 /* E */ : 3 /* W */;
|
||||
// else
|
||||
// color_idx = (step_y < 0) ? 1 /* S */ : 0 /* N */;
|
||||
|
||||
// int color = g->colors.wall_nsew[color_idx];
|
||||
// if (side == 1) color = (color & 0xFEFEFE) >> 1; /* ombre simple */
|
||||
|
||||
// draw_vline(g, x, draw_start, draw_end, color);
|
||||
// }
|
||||
// }
|
||||
|
||||
/* 2eme test de la meme focntion (pas encore choisi laquelle)*/
|
||||
// void raycast_frame(t_game *g)
|
||||
// {
|
||||
// for (int x = 0; x < g->gfx.w; x++)
|
||||
// {
|
||||
// double camera_x = 2.0 * x / (double)g->gfx.w - 1.0;
|
||||
// double ray_dir_x = g->cam.dir_x + g->cam.plane_x * camera_x;
|
||||
// double ray_dir_y = g->cam.dir_y + g->cam.plane_y * camera_x;
|
||||
|
||||
// int map_x = (int)g->cam.pos_x;
|
||||
// int map_y = (int)g->cam.pos_y;
|
||||
|
||||
// double delta_dist_x = (ray_dir_x == 0) ? 1e30 : fabs(1.0 / ray_dir_x);
|
||||
// double delta_dist_y = (ray_dir_y == 0) ? 1e30 : fabs(1.0 / ray_dir_y);
|
||||
|
||||
// int step_x, step_y;
|
||||
// double side_dist_x, side_dist_y;
|
||||
|
||||
// if (ray_dir_x < 0) { step_x = -1; side_dist_x = (g->cam.pos_x - map_x) * delta_dist_x; }
|
||||
// else { step_x = 1; side_dist_x = (map_x + 1.0 - g->cam.pos_x) * delta_dist_x; }
|
||||
// if (ray_dir_y < 0) { step_y = -1; side_dist_y = (g->cam.pos_y - map_y) * delta_dist_y; }
|
||||
// else { step_y = 1; side_dist_y = (map_y + 1.0 - g->cam.pos_y) * delta_dist_y; }
|
||||
|
||||
// int hit = 0, side = 0;
|
||||
// while (!hit)
|
||||
// {
|
||||
// if (side_dist_x < side_dist_y) { side_dist_x += delta_dist_x; map_x += step_x; side = 0; }
|
||||
// else { side_dist_y += delta_dist_y; map_y += step_y; side = 1; }
|
||||
// if (map_x < 0 || map_y < 0 || map_x >= g->world.w || map_y >= g->world.h
|
||||
// || g->world.grid[map_y][map_x] == '1')
|
||||
// hit = 1;
|
||||
// }
|
||||
|
||||
// double perp_wall_dist = (side == 0) ? (side_dist_x - delta_dist_x) : (side_dist_y - delta_dist_y);
|
||||
// if (perp_wall_dist < 1e-6) perp_wall_dist = 1e-6;
|
||||
|
||||
// int line_h = (int)(g->gfx.h / perp_wall_dist);
|
||||
// int draw_start = -line_h / 2 + g->gfx.h / 2;
|
||||
// int draw_end = line_h / 2 + g->gfx.h / 2;
|
||||
|
||||
// int color_idx;
|
||||
// if (side == 0) color_idx = (step_x < 0) ? 2 /* E */ : 3 /* W */;
|
||||
// else color_idx = (step_y < 0) ? 1 /* S */ : 0 /* N */;
|
||||
|
||||
// int color = g->colors.wall_nsew[color_idx];
|
||||
// if (side == 1) color = (color & 0xFEFEFE) >> 1; /* ombre simple */
|
||||
|
||||
// draw_vline(g, x, draw_start, draw_end, color); /* impl. dans draw.c */
|
||||
// }
|
||||
// }
|
||||
|
||||
/* Version 3: textures */
|
||||
void raycast_frame(t_game *g)
|
||||
{
|
||||
const double EPS = 1e-6;
|
||||
|
||||
for (int x = 0; x < g->gfx.w; x++)
|
||||
{
|
||||
double camera_x = 2.0 * x / (double)g->gfx.w - 1.0;
|
||||
double ray_dir_x = g->cam.dir_x + g->cam.plane_x * camera_x;
|
||||
double ray_dir_y = g->cam.dir_y + g->cam.plane_y * camera_x;
|
||||
|
||||
int map_x = (int)g->cam.pos_x;
|
||||
int map_y = (int)g->cam.pos_y;
|
||||
|
||||
double delta_dist_x = (ray_dir_x == 0) ? 1e30 : fabs(1.0 / ray_dir_x);
|
||||
double delta_dist_y = (ray_dir_y == 0) ? 1e30 : fabs(1.0 / ray_dir_y);
|
||||
|
||||
int step_x, step_y;
|
||||
double side_dist_x, side_dist_y;
|
||||
|
||||
if (ray_dir_x < 0) { step_x = -1; side_dist_x = (g->cam.pos_x - map_x) * delta_dist_x; }
|
||||
else { step_x = 1; side_dist_x = (map_x + 1.0 - g->cam.pos_x) * delta_dist_x; }
|
||||
if (ray_dir_y < 0) { step_y = -1; side_dist_y = (g->cam.pos_y - map_y) * delta_dist_y; }
|
||||
else { step_y = 1; side_dist_y = (map_y + 1.0 - g->cam.pos_y) * delta_dist_y; }
|
||||
|
||||
int hit = 0, side = 0;
|
||||
while (!hit)
|
||||
{
|
||||
if (side_dist_x < side_dist_y) { side_dist_x += delta_dist_x; map_x += step_x; side = 0; }
|
||||
else { side_dist_y += delta_dist_y; map_y += step_y; side = 1; }
|
||||
if (map_x < 0 || map_y < 0 || map_x >= g->world.w || map_y >= g->world.h
|
||||
|| g->world.grid[map_y][map_x] == '1')
|
||||
hit = 1;
|
||||
}
|
||||
|
||||
double perp_wall_dist = (side == 0) ? (side_dist_x - delta_dist_x) : (side_dist_y - delta_dist_y);
|
||||
if (perp_wall_dist < EPS) perp_wall_dist = EPS;
|
||||
|
||||
int line_h = (int)(g->gfx.h / perp_wall_dist);
|
||||
int draw_start = -line_h / 2 + g->gfx.h / 2;
|
||||
int draw_end = line_h / 2 + g->gfx.h / 2;
|
||||
|
||||
/* Choix de texture 0:N 1:S 2:E 3:W (même logique que couleurs) */
|
||||
int tex_id;
|
||||
if (side == 0) tex_id = (step_x < 0) ? 2 /* E */ : 3 /* W */;
|
||||
else tex_id = (step_y < 0) ? 1 /* S */ : 0 /* N */;
|
||||
|
||||
if (!g->has_tex)
|
||||
{
|
||||
int color = g->colors.wall_nsew[tex_id];
|
||||
if (side == 1) color = (color & 0xFEFEFE) >> 1;
|
||||
draw_vline(g, x, draw_start, draw_end, color);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* --- TEXTURE MAPPING --- */
|
||||
t_tex *t = &g->tex[tex_id];
|
||||
|
||||
/* Position exacte du hit sur le mur (0..1) */
|
||||
double wall_x;
|
||||
if (side == 0)
|
||||
wall_x = g->cam.pos_y + perp_wall_dist * ray_dir_y;
|
||||
else
|
||||
wall_x = g->cam.pos_x + perp_wall_dist * ray_dir_x;
|
||||
wall_x -= floor(wall_x);
|
||||
|
||||
/* Coordonnée X dans la texture */
|
||||
int tex_x = (int)(wall_x * (double)t->w);
|
||||
if (side == 0 && ray_dir_x > 0) tex_x = t->w - tex_x - 1;
|
||||
if (side == 1 && ray_dir_y < 0) tex_x = t->w - tex_x - 1;
|
||||
|
||||
/* Échantillonnage vertical */
|
||||
double step = (double)t->h / (double)line_h;
|
||||
double tex_pos = (draw_start - g->gfx.h / 2 + line_h / 2) * step;
|
||||
|
||||
/* Ombre légère sur faces Y (optionnel) */
|
||||
draw_tex_vline(g, x, draw_start, draw_end, t, tex_x, step, tex_pos);
|
||||
if (side == 1) {
|
||||
/* sombrement simple: on pourrait parcourir y et foncer; plus simple: rien faire
|
||||
pour rester portable / endianness-safe. */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* textures.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: jle-neze <[email protected]> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2025/09/12 18:24:56 by jle-neze #+# #+# */
|
||||
/* Updated: 2025/09/12 18:24:58 by jle-neze ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "cub.h"
|
||||
|
||||
static int load_one(t_game *g, t_tex *t, const char *path)
|
||||
{
|
||||
t->ptr = mlx_xpm_file_to_image(g->gfx.mlx, (char *)path, &t->w, &t->h);
|
||||
if (!t->ptr)
|
||||
return (1);
|
||||
t->addr = mlx_get_data_addr(t->ptr, &t->bpp, &t->line_len, &t->endian);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int textures_load(t_game *g, const char *no, const char *so,
|
||||
const char *we, const char *ea)
|
||||
{
|
||||
if (load_one(g, &g->tex[0], no)
|
||||
|| load_one(g, &g->tex[1], so)
|
||||
|| load_one(g, &g->tex[2], we)
|
||||
|| load_one(g, &g->tex[3], ea))
|
||||
{
|
||||
textures_free(g);
|
||||
return (1);
|
||||
}
|
||||
g->has_tex = 1;
|
||||
return (0);
|
||||
}
|
||||
|
||||
void textures_free(t_game *g)
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
if (g->tex[i].ptr)
|
||||
mlx_destroy_image(g->gfx.mlx, g->tex[i].ptr);
|
||||
g->tex[i].ptr = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int tex_get_pixel(t_tex *t, int x, int y)
|
||||
{
|
||||
char *px = t->addr + (y * t->line_len + x * (t->bpp / 8));
|
||||
return (*(unsigned int *)px);
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* world.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: jle-neze <[email protected]> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2025/09/12 18:25:13 by jle-neze #+# #+# */
|
||||
/* Updated: 2025/09/12 18:25:17 by jle-neze ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "cub.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
// static const char *demo_map[] = {
|
||||
// "111111111111",
|
||||
// "100000000001",
|
||||
// "100011110001",
|
||||
// "100000010001",
|
||||
// "101111010001",
|
||||
// "100100010001",
|
||||
// "10010N010001", /* N = start dir nord, on l'ignore ici (juste info) */
|
||||
// "100000000001",
|
||||
// "111111111111",
|
||||
// NULL
|
||||
// };
|
||||
static const char *demo_map[] = {
|
||||
"111111111111",
|
||||
"100000000001",
|
||||
"100000000001",
|
||||
"100000000001",
|
||||
"100000001111",
|
||||
"100000000001",
|
||||
"100000000001", /* N = start dir nord, on l'ignore ici (juste info) */
|
||||
"100000000001",
|
||||
"111111111111",
|
||||
NULL
|
||||
};
|
||||
|
||||
int world_init_demo(t_world *w)
|
||||
{
|
||||
int h = 0;
|
||||
while (demo_map[h])
|
||||
h++;
|
||||
w->h = h;
|
||||
w->w = 0;
|
||||
for (int i = 0; i < h; i++)
|
||||
{
|
||||
int len = 0;
|
||||
while (demo_map[i][len]) len++;
|
||||
if (len > w->w) w->w = len;
|
||||
}
|
||||
w->grid = (char **)malloc(sizeof(char *) * (h + 1));
|
||||
if (!w->grid) return (1);
|
||||
for (int y = 0; y < h; y++)
|
||||
{
|
||||
w->grid[y] = (char *)malloc(w->w + 1);
|
||||
if (!w->grid[y]) return (1);
|
||||
for (int x = 0; x < w->w; x++)
|
||||
{
|
||||
char c = demo_map[y][x];
|
||||
if (c == 0) c = '1';
|
||||
if (c == 'N' || c == 'S' || c == 'E' || c == 'W')
|
||||
c = '0';
|
||||
w->grid[y][x] = c;
|
||||
}
|
||||
w->grid[y][w->w] = '\0';
|
||||
}
|
||||
w->grid[h] = NULL;
|
||||
return (0);
|
||||
}
|
||||
|
||||
void world_free(t_world *w)
|
||||
{
|
||||
if (!w->grid) return ;
|
||||
for (int y = 0; y < w->h; y++)
|
||||
free(w->grid[y]);
|
||||
free(w->grid);
|
||||
w->grid = NULL;
|
||||
}
|
||||
Reference in New Issue
Block a user