diff --git a/.gitignore b/.gitignore index f20dc81..c36bda2 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,5 @@ *.d *.a cub3D +build/ +.cache/ diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..245caf4 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,26 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Debug Run Debug", + "type": "cppdbg", + "request": "launch", + "program": "${workspaceFolder}/build/debug/cub3D", // Replace with your executable path + "args": [], + "stopAtEntry": false, + "cwd": "${workspaceFolder}", + "environment": [], + "externalConsole": false, + "MIMode": "gdb", + "miDebuggerPath": "/usr/bin/gdb", // Adjust if gdb is in a different location + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + } + ], + "preLaunchTask": "Debug" + }, + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..7f7aa60 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,8 @@ +{ + "files.associations": { + "game.h": "c", + "cub3d.h": "c", + "screen.h": "c", + "mlx42.h": "c" + } +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..a7f1a0b --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,41 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "Debug", + "type": "shell", + "command": "make", + "args": ["debug"], + "group": { + "kind": "build", + "isDefault": true + }, + "problemMatcher": [], + "detail": "Runs the make target for run_debug" + }, + { + "label": "Run ASAN", + "type": "shell", + "command": "make", + "args": ["run_asan"], + "group": { + "kind": "build", + "isDefault": false + }, + "problemMatcher": [], + "detail": "Runs the make target for run_asan" + }, + { + "label": "Make Run", + "type": "shell", + "command": "make", + "args": ["run"], + "group": { + "kind": "build", + "isDefault": false + }, + "problemMatcher": [], + "detail": "Runs the make run command" + } + ] +} \ No newline at end of file diff --git a/compile_commands.json b/compile_commands.json deleted file mode 100644 index 6d1b83f..0000000 --- a/compile_commands.json +++ /dev/null @@ -1,7 +0,0 @@ -[ - { - "command": "cc -c -Wall -Werror -Werror -O2 -I./inc -I./lib/libft/inc -I./lib/MLX42/include/MLX42 -o build/release/obj/main.o src/main.c", - "directory": "/home/whaffman/Projects/cub3d", - "file": "/home/whaffman/Projects/cub3d/src/main.c" - } -] \ No newline at end of file diff --git a/compile_flags.txt b/compile_flags.txt new file mode 100644 index 0000000..1e38c10 --- /dev/null +++ b/compile_flags.txt @@ -0,0 +1,6 @@ +-I +./inc +-I +./lib/libft/inc +-I +./lib/MLX42/include/MLX42 \ No newline at end of file diff --git a/inc/allowed.h b/inc/allowed.h new file mode 100644 index 0000000..f665beb --- /dev/null +++ b/inc/allowed.h @@ -0,0 +1,24 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* allowed.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: qmennen +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/04/15 15:31:54 by qmennen #+# #+# */ +/* Updated: 2025/04/15 15:57:15 by qmennen ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef ALLOWED_H +# define ALLOWED_H + +# include +# include +# include +# include +# include +# include +#include +# include // TODO: Check if this is allowed? +#endif diff --git a/inc/cub3d.h b/inc/cub3d.h index ed23b4c..d2bda32 100644 --- a/inc/cub3d.h +++ b/inc/cub3d.h @@ -1,63 +1,49 @@ /* ************************************************************************** */ /* */ -/* :::::::: */ -/* cub3d.h :+: :+: */ -/* +:+ */ -/* By: qmennen +#+ */ -/* +#+ */ -/* Created: 2025/04/15 12:22:29 by qmennen #+# #+# */ -/* Updated: 2025/04/15 18:07:02 by whaffman ######## odam.nl */ +/* ::: :::::::: */ +/* cub3d.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: qmennen +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/04/15 12:22:29 by qmennen #+# #+# */ +/* Updated: 2025/04/17 20:13:46 by qmennen ### ########.fr */ /* */ /* ************************************************************************** */ #ifndef CUB3D_H # define CUB3D_H +# define FAILURE 0 +# define SUCCESS 1 + +# define WIDTH 1280 +# define HEIGHT 720 +# define TITLE "Cub3D" + +# define RESET "\033[0m" +# define BLACK "\033[0;30m" +# define RED "\033[0;31m" +# define GREEN "\033[0;32m" +# define YELLOW "\033[0;33m" +# define BLUE "\033[0;34m" +# define MAGENTA "\033[0;35m" +# define CYAN "\033[0;36m" +# define WHITE "\033[0;37m" + +# define NUM_KEYS 256 +# define TILE_SIZE 16 + # include # include +# include +# include "types.h" +# include "errors.h" +# include "map.h" +# include "game.h" +# include "screen.h" +# include "keyboard.h" +# include "hooks.h" +# include "render.h" +# include "player.h" -typedef enum TILE -{ - TILE_VISITED = -2, - TILE_VOID = -1, - TILE_EMPTY = 0, - TILE_WALL = 1, - TILE_PLAYER = 2, -} t_tile; - -typedef struct s_vec2 -{ - float x; - float y; -} t_vec2; - -typedef struct s_player -{ - t_vec2 pos; - float speed; - float angle; - float fov; -} t_player; - -typedef struct s_map -{ - unsigned int width; - unsigned int height; - t_tile **grid; -} t_map; - -typedef struct s_screen -{ - mlx_t *mlx; - mlx_image_t *img; - unsigned int width; - unsigned int height; -} t_screen; - -typedef struct s_game -{ - t_map *map; - t_player *player; -} t_game; - -#endif \ No newline at end of file +#endif diff --git a/inc/errors.h b/inc/errors.h new file mode 100644 index 0000000..c93c4ec --- /dev/null +++ b/inc/errors.h @@ -0,0 +1,22 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* errors.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: qmennen +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/04/15 15:42:55 by qmennen #+# #+# */ +/* Updated: 2025/04/15 15:59:42 by qmennen ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef ERRORS_H +# define ERRORS_H + +# include "cub3d.h" + + +const char *last_error(); +void game_error(t_game *game, const char *msg); + +#endif diff --git a/inc/game.h b/inc/game.h new file mode 100644 index 0000000..dc5aa90 --- /dev/null +++ b/inc/game.h @@ -0,0 +1,22 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* game.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: qmennen +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/04/15 15:46:16 by qmennen #+# #+# */ +/* Updated: 2025/04/15 17:58:22 by qmennen ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef GAME_H +# define GAME_H + +# include "cub3d.h" + +int game_create(t_game **game); +void game_loop(void *param); +void game_terminate(t_game *game); + +#endif diff --git a/inc/hooks.h b/inc/hooks.h new file mode 100644 index 0000000..41e493a --- /dev/null +++ b/inc/hooks.h @@ -0,0 +1,20 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* hooks.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: qmennen +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/04/15 17:51:44 by qmennen #+# #+# */ +/* Updated: 2025/04/17 19:51:48 by qmennen ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef HOOKS_H +# define HOOKS_H + +# include "cub3d.h" + +void keyhandle(mlx_key_data_t keydata, void *param); + +#endif diff --git a/inc/keyboard.h b/inc/keyboard.h new file mode 100644 index 0000000..fca3bdf --- /dev/null +++ b/inc/keyboard.h @@ -0,0 +1,24 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* keyboard.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: qmennen +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/04/17 19:29:36 by qmennen #+# #+# */ +/* Updated: 2025/04/17 20:00:21 by qmennen ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef KEYBOARD_H +# define KEYBOARD_H + +# include "cub3d.h" + +int keyboard_create(t_game **game); +void keyboard_update(t_game *game); +int get_key(t_game *game, int k); +int get_key_down(t_game *game, int k); +int get_key_up(t_game *game, int k); + +#endif diff --git a/inc/map.h b/inc/map.h new file mode 100644 index 0000000..c6f8c0f --- /dev/null +++ b/inc/map.h @@ -0,0 +1,21 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* map.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: qmennen +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/04/17 19:19:19 by qmennen #+# #+# */ +/* Updated: 2025/04/17 19:23:59 by qmennen ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef MAP_H +# define MAP_H + +# include "cub3d.h" + +int map_create(t_game **game); +void map_free(t_map *map); + +#endif diff --git a/inc/player.h b/inc/player.h new file mode 100644 index 0000000..880235a --- /dev/null +++ b/inc/player.h @@ -0,0 +1,22 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* player.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: qmennen +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/04/15 18:53:27 by qmennen #+# #+# */ +/* Updated: 2025/04/17 19:49:36 by qmennen ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef PLAYER_H +# define PLAYER_H + +# include "cub3d.h" + +int player_create(t_game **game); +void player_render(t_screen *screen, t_player *player); +void player_update(t_game *game); + +#endif diff --git a/inc/render.h b/inc/render.h new file mode 100644 index 0000000..97b320d --- /dev/null +++ b/inc/render.h @@ -0,0 +1,25 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* render.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: qmennen +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/04/15 16:28:16 by qmennen #+# #+# */ +/* Updated: 2025/04/17 20:08:08 by qmennen ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef RENDER_H +# define RENDER_H + +# include "cub3d.h" + +int render_check_bounds(t_screen *screen, t_vec2 *point); +void render_line(t_screen *screen, t_vec2 start, t_vec2 end, unsigned int color); +void render_circle(t_screen *screen, t_vec2 point, int radius, unsigned int color); +void render_clear(t_screen *screen); +void render_entities(t_game *game); +void render_map(t_screen *screen, t_map *map); + +#endif diff --git a/inc/screen.h b/inc/screen.h new file mode 100644 index 0000000..960982e --- /dev/null +++ b/inc/screen.h @@ -0,0 +1,21 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* screen.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: qmennen +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/04/15 15:30:34 by qmennen #+# #+# */ +/* Updated: 2025/04/15 16:48:24 by qmennen ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef SCREEN_H +# define SCREEN_H + +#include "cub3d.h" + +t_screen *screen_create(); +void screen_center(t_screen *screen); + +#endif diff --git a/inc/types.h b/inc/types.h new file mode 100644 index 0000000..b15e898 --- /dev/null +++ b/inc/types.h @@ -0,0 +1,69 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* types.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: qmennen +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/04/15 15:52:44 by qmennen #+# #+# */ +/* Updated: 2025/04/17 19:38:44 by qmennen ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef TYPES_H +# define TYPES_H + +# include "cub3d.h" + +typedef enum TILE +{ + TILE_VOID = -1, + TILE_EMPTY = 0, + TILE_WALL = 1, + TILE_PLAYER = 2, +} t_tile; + +typedef struct s_vec2 +{ + float x; + float y; +} t_vec2; + +typedef struct s_player +{ + t_vec2 pos; + float speed; + float angle; + float fov; +} t_player; + +typedef struct s_map +{ + unsigned int width; + unsigned int height; + t_tile **grid; +} t_map; + +typedef struct s_keyboard +{ + int keys[NUM_KEYS]; + int last_keys[NUM_KEYS]; +} t_keyboard; + +typedef struct s_screen +{ + mlx_t *mlx; + mlx_image_t *img; + unsigned int width; + unsigned int height; +} t_screen; + +typedef struct s_game +{ + t_map *map; + t_player *player; + t_screen *screen; + t_keyboard *keyboard; +} t_game; + +#endif diff --git a/src/game.c b/src/game.c new file mode 100644 index 0000000..d74a9ea --- /dev/null +++ b/src/game.c @@ -0,0 +1,60 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* game.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: qmennen +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/04/15 15:46:08 by qmennen #+# #+# */ +/* Updated: 2025/04/17 20:01:19 by qmennen ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "cub3d.h" + +int game_create(t_game **game) +{ + *game = malloc(sizeof(t_game)); + if (!game) + return (FAILURE); + (*game)->player = NULL; + (*game)->map = NULL; + (*game)->screen = screen_create(); + if ((*game)->screen == NULL) + return (FAILURE); + if (((*game)->screen->mlx == NULL) || ((*game)->screen->img == NULL)) + return (FAILURE); + mlx_image_to_window((*game)->screen->mlx, (*game)->screen->img, 0, 0); + return (SUCCESS); +} + +void game_loop(void *param) +{ + t_game *game; + + game = (t_game *)param; + render_clear(game->screen); + player_update(game); + render_entities(game); + render_map(game->screen, game->map); + keyboard_update(game); // Goes last +} + +void game_terminate(t_game *game) +{ + if (game->screen) + { + mlx_delete_image(game->screen->mlx, game->screen->img); + mlx_close_window(game->screen->mlx); + mlx_terminate(game->screen->mlx); + free(game->screen); + } + if (game->player) + free(game->player); + if (game->map) + map_free(game->map); + if (game->keyboard) + free(game->keyboard); + free(game); + exit(EXIT_SUCCESS); +} diff --git a/src/main.c b/src/main.c index 14fd905..32f9c5b 100644 --- a/src/main.c +++ b/src/main.c @@ -1,108 +1,42 @@ -#include -#include -#include -#include +/* ************************************************************************** */ +/* */ +/* :::::::: */ +/* main.c :+: :+: */ +/* +:+ */ +/* By: qmennen +#+ */ +/* +#+ */ +/* Created: 2025/04/15 16:01:29 by qmennen #+# #+# */ +/* Updated: 2025/04/18 10:56:08 by whaffman ######## odam.nl */ +/* */ +/* ************************************************************************** */ -#include "MLX42.h" +# include "cub3d.h" -#define WIDTH 1024 -#define HEIGHT 1024 - -typedef struct s_things t_things; -typedef struct s_things +static int init_game(t_game **game) { - mlx_t* mlx; - mlx_image_t* img; -} t_things; + if (! game_create(game)) + return (FAILURE); + if (!player_create(game)) + return (FAILURE); + if (!map_create(game)) + return (FAILURE); + if (!keyboard_create(game)) + return (FAILURE); + screen_center((*game)->screen); + mlx_key_hook((*game)->screen->mlx, keyhandle, *game); + mlx_loop_hook((*game)->screen->mlx, game_loop, *game); + return (SUCCESS); +} -// // Exit the program as failure. -// static void ft_error(void) -// { -// fprintf(stderr, "%s", mlx_strerror(mlx_errno)); -// exit(EXIT_FAILURE); -// } +int main(void) +{ + t_game *game; -// static int check_bounds(int x, int y, int width, int height) -// { -// if (x < 0 || x >= width || y < 0 || y >= height) -// return (1); -// return (0); -// } - -// static void draw_circle(mlx_image_t* img, int x, int y, int radius, uint32_t color) -// { -// for (int i = -radius; i <= radius; i++) -// { -// for (int j = -radius; j <= radius; j++) -// { -// if (i * i + j * j <= radius * radius) -// { -// if (check_bounds(x + i, y + j, img->width, img->height)) -// continue; -// mlx_put_pixel(img, x + i, y + j, color << 8 |(int)(((float)radius * radius - i * i - j*j ) / (float)(radius * radius) * 255)); -// } -// } -// } -// } - -// static void draw_random_circle(mlx_image_t* img) -// { -// int x = rand() % img->width; -// int y = rand() % img->height; -// int radius = rand() % 50 + 10; // Random radius between 10 and 60 -// uint32_t color = (rand() % 256 << 16) | (rand() % 256 << 8) | (rand() % 256); -// draw_circle(img, x, y, radius, color); -// } - - -// // Print the window width and height. -// static void ft_hook(void* param) -// { -// t_things *arg = param; -// const mlx_t* mlx = arg->mlx; -// mlx_image_t* img = arg->img; -// static float last_time; - -// last_time += mlx->delta_time; -// // printf("delta_time: %f last_time: %f\n", mlx->delta_time, last_time); -// if (last_time > 0.05) -// { - -// draw_random_circle(img); -// printf("FPS: %d\n", (int)(1.0 / last_time)); -// last_time = 0; -// } -// } - -// int32_t main(void) -// { -// t_things *things; -// // MLX allows you to define its core behaviour before startup. - -// things = malloc(sizeof(t_things)); -// if (!things) -// ft_error(); - -// mlx_t* mlx = mlx_init(WIDTH, HEIGHT, "42Balls", true); -// if (!mlx) -// ft_error(); - -// things->mlx = mlx; -// /* Do stuff */ - -// // Create and display the image. -// mlx_image_t* img = mlx_new_image(mlx, WIDTH, HEIGHT); -// if (!img || (mlx_image_to_window(mlx, img, 0, 0) < 0)) -// ft_error(); -// things->img = img; - -// // Register a hook and pass mlx as an optional param. -// // NOTE: Do this before calling mlx_loop! -// mlx_loop_hook(mlx, ft_hook, things); -// mlx_loop(mlx); -// mlx_delete_image(mlx, img); -// mlx_terminate(mlx); -// free(things); - -// return (EXIT_SUCCESS); -// } \ No newline at end of file + errno = 0; + game = NULL; + init_game(&game); + perror("after init"); + mlx_loop(game->screen->mlx); + game_terminate(game); + return (EXIT_SUCCESS); +} diff --git a/src/map.c b/src/map.c index add1492..ba5446c 100644 --- a/src/map.c +++ b/src/map.c @@ -7,7 +7,6 @@ #define FAILURE 0 #define SUCCESS 1 -t_map *get_temp_map() { const t_tile const_map[10][10] = { @@ -164,4 +163,40 @@ int main(void) fprintf(stderr, "YES, GOOD MAP FRIEND\n"); free_map(&map); return 0; -} \ No newline at end of file +} + + +int map_create(t_game **game) +{ + t_map *map; + + map = malloc(sizeof(t_map)); + if (!map) + return (FAILURE); + /** + * + * TEMP MAP + * + */ + map->width = 10; + map->height = 10; + map->grid = get_temp_map(); + (*game)->map = map; + return (SUCCESS); +} + +void map_free(t_map *map) +{ + int i; + int j; + + i = 0; + while (i < map->height) + { + j = 0; + free(map->grid[i]); + i++; + } + free(map->grid); + free(map); +} diff --git a/src/player.c b/src/player.c new file mode 100644 index 0000000..2e8c682 --- /dev/null +++ b/src/player.c @@ -0,0 +1,66 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* player.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: qmennen +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/04/15 18:53:19 by qmennen #+# #+# */ +/* Updated: 2025/04/17 20:04:25 by qmennen ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "player.h" +#include "render.h" +#include "types.h" + +int player_create(t_game **game) +{ + t_player *player; + + player = malloc(sizeof(t_player)); + if (!player) + return (FAILURE); + player->pos.x = 20.f; + player->pos.y = 20.f; + player->angle = 0.f; + player->speed = 80.f; + player->fov = 90.f; + (*game)->player = player; + return (SUCCESS); +} + +static void move(t_player *player, int dir, float delta) +{ + player->pos.x += dir * (cos(player->angle) * player->speed * delta); + player->pos.y += dir * (sin(player->angle) * player->speed * delta); +} + +static void rotate(t_player *player, int dir) +{ + player->angle += dir * .1f; +} + +void player_update(t_game *game) +{ + if (get_key(game, MLX_KEY_W)) + move(game->player, 1, game->screen->mlx->delta_time); + else if (get_key(game, MLX_KEY_S)) + move(game->player, -1, game->screen->mlx->delta_time); + if (get_key(game, MLX_KEY_LEFT)) + rotate(game->player, -1); + else if (get_key(game, MLX_KEY_RIGHT)) + rotate(game->player, 1); +} + +void player_render(t_screen *screen, t_player *player) +{ + t_vec2 direction; + + if (player->pos.x < 0 || player->pos.x >= screen->width || player->pos.y < 0 || player->pos.y >= screen->height) + return ; + render_circle(screen, player->pos, 4, 0x3294a8ff); + direction.x = player->pos.x + cos(player->angle) * 30; + direction.y = player->pos.y + sin(player->angle) * 30; + render_line(screen, player->pos, direction, 0xa83232ff); +} diff --git a/src/render/render.c b/src/render/render.c new file mode 100644 index 0000000..0f20a4f --- /dev/null +++ b/src/render/render.c @@ -0,0 +1,62 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* render.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: qmennen +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/04/15 16:28:10 by qmennen #+# #+# */ +/* Updated: 2025/04/17 20:14:43 by qmennen ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "render.h" +#include "MLX42.h" + +int render_check_bounds(t_screen *screen, t_vec2 *point) +{ + return (point->x >= 0 && point->x < screen->width && point->y > 0 && point->y < screen->height); +} + +void render_tile(t_screen *screen, int x, int y, t_tile tile) +{ + int i; + int xp; + int yp; + + i = 0; + if (tile == 0) + return ; + while ((i++) < TILE_SIZE * TILE_SIZE) + { + xp = x + (i % TILE_SIZE); + yp = y + (i / TILE_SIZE); + if (xp < 0 || xp >= screen->width || yp < 0 || yp >= screen->height) + continue; + if (tile == TILE_WALL) + mlx_put_pixel(screen->img, xp, yp, 0xA88132ff); + } +} + +void render_map(t_screen *screen, t_map *map) +{ + int i; + int x; + int y; + + i = 0; + while (i < map->width * map->height) + { + x = i % map->width; + y = i / map->height; + if (x < 0 || x >= map->width || y < 0 || y >= map->height) + continue; + render_tile(screen, x * TILE_SIZE, y * TILE_SIZE, map->grid[x][y]); + i++; + } +} + +void render_entities(t_game *game) +{ + player_render(game->screen, game->player); +} diff --git a/src/render/render_circle.c b/src/render/render_circle.c new file mode 100644 index 0000000..0df9ba2 --- /dev/null +++ b/src/render/render_circle.c @@ -0,0 +1,32 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* render_circle.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: qmennen +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/04/17 20:06:19 by qmennen #+# #+# */ +/* Updated: 2025/04/17 20:06:32 by qmennen ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "render.h" + +void render_circle(t_screen *screen, t_vec2 point, int radius, unsigned int color) +{ + int i; + int size; + int x; + int y; + + i = 0; + size = 2 * radius + 1; + while (i <= size * size) + { + x = i % size - radius; + y = i / size - radius; + if (x * x + y * y <= radius * radius) + mlx_put_pixel(screen->img, (int) point.x + x, (int) point.y + y, color); + i++; + } +} diff --git a/src/render/render_clear.c b/src/render/render_clear.c new file mode 100644 index 0000000..d6c7474 --- /dev/null +++ b/src/render/render_clear.c @@ -0,0 +1,23 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* clear_screen.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: qmennen +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/04/17 20:05:51 by qmennen #+# #+# */ +/* Updated: 2025/04/17 20:06:00 by qmennen ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "render.h" + +void render_clear(t_screen *screen) +{ + int i; + + i = 0; + while (i++ < screen->width * screen->height) + mlx_put_pixel(screen->img, i % screen->width, i / screen->width, 0x212121FF); +} + diff --git a/src/render/render_line.c b/src/render/render_line.c new file mode 100644 index 0000000..2ea8009 --- /dev/null +++ b/src/render/render_line.c @@ -0,0 +1,92 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* render_line.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: qmennen +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/04/17 20:06:40 by qmennen #+# #+# */ +/* Updated: 2025/04/17 20:08:17 by qmennen ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "render.h" + +static void line_low(t_screen *screen, t_vec2 start, t_vec2 end, unsigned int color) +{ + int delta; + int yi; + t_vec2 current; + t_vec2 delta_point; + + delta_point.x = end.x - start.x; + delta_point.y = abs((int) end.y - (int) start.y); + yi = 1; + if (end.y - start.y < 0) + yi = -1; + delta = 2 * delta_point.y - delta_point.x; + current = start; + while (current.x <= end.x) + { + if (render_check_bounds(screen, ¤t)) + mlx_put_pixel(screen->img, (int)current.x, (int)current.y, color); + if (delta > 0) + { + current.y += yi; + delta -= 2 * delta_point.x; + } + delta += 2 * delta_point.y; + current.x++; + } +} + +static void line_high(t_screen *screen, t_vec2 start, t_vec2 end, unsigned int color) +{ + int delta; + int xi; + t_vec2 current; + t_vec2 delta_point; + + delta_point.x = abs((int) end.x - (int) start.x); + delta_point.y = end.y - start.y; + xi = 1; + if (end.x - start.x < 0) + xi = -1; + delta = 2 * delta_point.x - delta_point.y; + current = start; + while (current.y <= end.y) + { + if (render_check_bounds(screen, ¤t)) + mlx_put_pixel(screen->img, (int)current.x, (int)current.y, color); + if (delta > 0) + { + current.x += xi; + delta -= 2 * delta_point.y; + } + delta += 2 * delta_point.x; + current.y++; + } +} + +void render_line(t_screen *screen, t_vec2 start, t_vec2 end, unsigned int color) +{ + if ((start.x < 0 || start.x >= (int) screen->img->width + || start.y < 0 || start.y >= (int) screen->img->height) + && (end.x < 0 || end.x >= (int) screen->img->width + || end.y < 0 || end.y >= (int) screen->img->height)) + return ; + if (abs((int) end.y - (int) start.y) < abs((int) end.x - (int) start.x)) + { + if (start.x > end.x) + line_low(screen, end, start, color); + else + line_low(screen, start, end, color); + } + else + { + if (start.y > end.y) + line_high(screen, end, start, color); + else + line_high(screen, start, end, color); + } +} diff --git a/src/screen.c b/src/screen.c new file mode 100644 index 0000000..9acd38c --- /dev/null +++ b/src/screen.c @@ -0,0 +1,50 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* screen.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: qmennen +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/04/15 15:30:27 by qmennen #+# #+# */ +/* Updated: 2025/04/15 19:21:23 by qmennen ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "screen.h" +#include "MLX42.h" +#include + +t_screen *screen_create() +{ + t_screen *screen; + mlx_image_t *img; + mlx_t *mlx; + + screen = malloc(sizeof(t_screen)); + if (!screen) + return (NULL); + screen->width = WIDTH; + screen->height = HEIGHT; + mlx = mlx_init(WIDTH, HEIGHT, TITLE, false); + //TODO: figure out why errno = 11 after this call + screen->mlx = mlx; + img = mlx_new_image(screen->mlx, WIDTH, HEIGHT); + screen->img = img; + return (screen); +} + +void screen_center(t_screen *screen) +{ + int m_width; + int m_height; + + m_width = 0; + m_height = 0; + mlx_get_monitor_size(0, &m_width, &m_height); + if (m_width == 0 || m_height == 0) + { + printf(RED"Failed to retrieve monitor size to center window\n"RESET); + return ; + } + mlx_set_window_pos(screen->mlx, (m_width - screen->width) / 2, (m_height - screen->height) / 2); +} diff --git a/src/util/errors.c b/src/util/errors.c new file mode 100644 index 0000000..3b69f8d --- /dev/null +++ b/src/util/errors.c @@ -0,0 +1,34 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* errors.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: qmennen +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/04/15 15:40:14 by qmennen #+# #+# */ +/* Updated: 2025/04/15 16:10:57 by qmennen ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "MLX42.h" +#include "cub3d.h" + +const char *last_error() +{ + if (mlx_errno > 0) + return (mlx_strerror(mlx_errno)); + else if (errno > 0) + return (strerror(errno)); + else + return (NULL); +} + +void game_error(t_game *game, const char *msg) +{ + const char *last_err = last_error(); + if (msg == NULL && last_err) + printf(RED"%s\n"RESET, last_err); + else + printf(RED"%s\n"RESET, msg); + game_terminate(game); +} diff --git a/src/util/hooks.c b/src/util/hooks.c new file mode 100644 index 0000000..92869a6 --- /dev/null +++ b/src/util/hooks.c @@ -0,0 +1,22 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* hooks.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: qmennen +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/04/15 17:51:26 by qmennen #+# #+# */ +/* Updated: 2025/04/17 19:57:35 by qmennen ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "hooks.h" + +void keyhandle(mlx_key_data_t keydata, void *param) +{ + t_game *game; + + game = (t_game *)param; + if (keydata.key == MLX_KEY_ESCAPE) + game_terminate(game); +} diff --git a/src/util/keyboard.c b/src/util/keyboard.c new file mode 100644 index 0000000..9abdf1a --- /dev/null +++ b/src/util/keyboard.c @@ -0,0 +1,58 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* keyboard.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: qmennen +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/04/17 19:29:29 by qmennen #+# #+# */ +/* Updated: 2025/04/17 19:59:53 by qmennen ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "keyboard.h" + +int keyboard_create(t_game **game) +{ + t_keyboard *keyboard; + int i; + + keyboard = malloc(sizeof(t_keyboard)); + if (!keyboard) + return (FAILURE); + (*game)->keyboard = keyboard; + i = 0; + while (i < NUM_KEYS) + { + (*game)->keyboard->keys[i] = 0; + i++; + } + return (SUCCESS); +} + +void keyboard_update(t_game *game) +{ + int i; + + i = 0; + while (i < NUM_KEYS) + { + game->keyboard->last_keys[i] = get_key(game, i); + i++; + } +} + +int get_key(t_game *game, int k) +{ + return mlx_is_key_down(game->screen->mlx, k); +} + +int get_key_down(t_game *game, int k) +{ + return (get_key(game, k) && !game->keyboard->last_keys[k]); +} + +int get_key_up(t_game *game, int k) +{ + return (!get_key(game, k) && game->keyboard->last_keys[k]); +}