summaryrefslogtreecommitdiff
path: root/game.c
blob: 96864abb7a312d529dca33aa14d26e72a289105c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
/* ************************************************************************** */
/*                                                                            */
/*                                                        :::      ::::::::   */
/*   game.c                                             :+:      :+:    :+:   */
/*                                                    +:+ +:+         +:+     */
/*   By: kdx    <kdx   @student.42angouleme.fr      +#+  +:+       +#+        */
/*                                                +#+#+#+#+#+   +#+           */
/*   Created: 2022/10/09 07:30:46 by kdx               #+#    #+#             */
/*   Updated: 2022/10/16 01:47:03 by kdx              ###   ########.fr       */
/*                                                                            */
/* ************************************************************************** */

#include "libft/libft.h"
#include "game.h"
#include "sily.h"
#include "sprite.h"
#include "spritesheet.h"
#include <stdbool.h>

static t_err	load_sprite(t_game *game, t_sprite **dst, char *path, int size)
{
	*dst = sprite_load(game->sily, path, size & 255, size / 256);
	return (*dst == NULL);
}

static t_err	load_tileset(t_game *game, const char *pattern, int size,
	const char *tiles)
{
	int				i;
	char			*path;
	char			*path_x;
	unsigned char	tile;

	if (ft_strchr(pattern, 'X') == NULL)
		return (1);
	path = ft_strdup(pattern);
	if (path == NULL)
		return (1);
	path_x = ft_strchr(path, 'X');
	i = -1;
	while (tiles[++i] != '\0')
	{
		tile = tiles[i];
		*path_x = tile;
		if (load_sprite(game, &game->s_tiles[tile], path, size))
		{
			ft_free(path);
			return (1);
		}
	}
	ft_free(path);
	return (0);
}

static t_game	*load_sprites(t_game *game)
{
	if (load_tileset(game, "tiles/X.xpm", TSIZE + TSIZE * 256,
			"01ECabcdefghijklmnop"))
		return (game_destroy(game));
	if (load_sprite(game, &game->s_player, "player.xpm", TSIZE + TSIZE * 256))
		return (game_destroy(game));
	if (load_sprite(game, &game->s_badeline, "badeline.xpm",
			TSIZE + TSIZE * 256))
		return (game_destroy(game));
	game->ss_exit = spritesheet_load(game->sily, "exit/X.xpm", 3);
	if (game->ss_exit == NULL)
		return (game_destroy(game));
	return (game);
}

t_game	*game_new(const char *map_path)
{
	t_game	*game;
	t_err	err;

	if (ft_alloc(&game, sizeof(t_game)))
		return (NULL);
	err = map_load(&game->map, map_path);
	if (err)
		ft_printf("Error\n%s\n", map_load_error(err));
	if (err)
		return (game_destroy(game));
	game->collectibles = map_count(&game->map, TILE_COLLECTIBLE);
	game->sily = ft_calloc(1, sizeof(t_sily));
	if (game->sily == NULL)
		return (game_destroy(game));
	if (sily_init(game->sily, game->map.width * TSIZE, game->map.height * TSIZE,
			"SO LONG"))
		return (game_destroy(game));
	game->sily->game = game;
	ft_bzero(game->s_tiles, sizeof(game->s_tiles));
	if (load_sprites(game) == NULL)
		return (NULL);
	map_spawn(game, &game->map);
	game->badeline.follow = &game->player;
	game->badeline.active = false;
	return (game);
}

void	*game_destroy(t_game *game)
{
	int	i;

	if (game != NULL)
	{
		i = 0;
		spritesheet_destroy(game->sily, game->ss_exit);
		while (i < 256)
		{
			sprite_destroy(game->sily, game->s_tiles[i]);
			i++;
		}
		sprite_destroy(game->sily, game->s_badeline);
		sprite_destroy(game->sily, game->s_player);
		if (game->sily)
		{
			mlx_do_key_autorepeaton(game->sily->ctx);
			sily_deinit(game->sily);
		}
		ft_free(game->sily);
		map_destroy(&game->map);
		ft_free(game);
	}
	return (NULL);
}