This project is licensed under the MIT License. See the LICENSE file for details.
This project is a Cub3D-style 3D raycasting engine (with bonus features like textures/sky, a minimap, and an animated weapon). It renders a pseudo-3D scene from a grid-based .cub map using a DDA (Digital Differential Analyzer) raycasting loop.
The src/main.c entrypoint launches the Cub3D game (main_cube3d).
Prerequisites (based on the current Makefile link line):
cclibft/(built via theMakefile)- MinilibX for Linux in
mlx_linux/ - SDL2 + SDL2_mixer development libs
- X11 (for MinilibX)
Build everything:
makeYou will get the executable:
./Gnawa3D
Run the default bonus map:
make runRun any map you want (must be a readable .cub file):
./Gnawa3D maps/map_bonus.cubThese are the controls printed by the Makefile:
W/S: move forward / move backwardA/D: strafe left / strafe rightLeft Arrow/Right Arrow: rotate left / rotate rightESC: exit
Additional in-code behavior:
SPACEis used during the intro sequence (advances intro mode).- Mouse movement updates the view angle (relative mouse X delta).
The program expects the map file path as the only argument.
- Path must end with
.cub - Path must not contain spaces
- File must be readable
The map file contains lines like:
NO <path_to_xpm>: north textureSO <path_to_xpm>: south textureWE <path_to_xpm>: west textureEA <path_to_xpm>: east textureF r,g,b: floor color (0-255 per channel)C r,g,b: ceiling color (0-255 per channel)
Example (from maps/map_bonus.cub):
NO ./textures/Untitled.xpm
SO ./textures/Untitled.xpm
WE ./textures/Untitled.xpm
EA ./textures/Untitled.xpm
F 0,0,0
C 255,255,255After the header, the map is made of lines made only of:
1: wall (rays stop when they hit1)0: empty spaceN,S,E,W: player start position and facing direction- spaces/tabs : allowed padding inside map lines
Example:
1111111111111111111111111111111111111
1S00000000001000000000000000000000001
...For each frame, the engine casts one ray per screen column and draws vertical slices.
-
Ray setup
WIDTHrays are computed across the field of view (FOV).- For a ray index
i, the ray angle is:start_angle + i * angle_step
- The ray direction is derived from
cos(angle)/sin(angle).
-
DDA grid traversal
- The ray starts in the player’s current map cell (
mapx,mapy). deltaDistX/Yrepresent the distance the ray needs to travel to cross the next grid line on each axis.stepX/stepYindicate whether the ray moves forward or backward along each axis.- While the ray has not hit a wall:
- advance to the next grid boundary (update
mapx/mapy) - stop when
map[mapy][mapx] == '1'
- advance to the next grid boundary (update
- The ray starts in the player’s current map cell (
-
Wall distance + perspective correction
- Perpendicular wall distance is computed using
sidedist - deltadist. - A fish-eye correction is applied based on the angle difference between the ray and the player view direction.
- Wall height is then computed from the distance.
- Perpendicular wall distance is computed using
-
Texture selection and coordinates
- The hit “side” (x-side vs y-side) and the ray direction decide which of the 4 textures to use.
wall_x(fractional hit position) is converted intotex_xto sample the correct texture column.
-
Drawing
- Sky is drawn for pixels above the wall (textured sky mapping by column/ray angle).
- Wall slice is drawn as a vertical textured segment using a
tex_stepaccumulator. - Floor is filled below using the floor color (
F r,g,b).
-
Minimap
- A circular minimap is drawn around the player.
- It maps nearby world cells onto minimap pixels and also draws the player direction line.


