summaryrefslogtreecommitdiff
path: root/src/tileset.c
blob: 7f5634dd934c0d47cc30ab5b61d528355c99b29e (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
#define MAX_TILE_ID 8192

static int tile_types[MAX_TILE_ID] = {0};
static const Tiled2cTile *tile_t2cs[MAX_TILE_ID] = {0};
static int tile_visuals[MAX_TILE_ID] = {0};
static int tile_numframes[MAX_TILE_ID] = {0};
static const Tiled2cFrame *tile_frames[MAX_TILE_ID] = {0};
static int tile_frame_id[MAX_TILE_ID] = {0};
static long tile_next_frame[MAX_TILE_ID] = {0};
static unsigned long last_tick = 0;

extern const Tiled2cSet tset_tsj;

__attribute__((constructor)) static void match_tile_types() {
	const auto tset = &tset_tsj;
	assert(MAX_TILE_ID > tset->tilecount);
	rfor (i, 0u, tset->numtiles) {
		const auto tile = &tset->tiles[i];
		tile_t2cs[tile->id] = tile;

		if (tile->numframes) {
			tile_numframes[tile->id] = tile->numframes;
			tile_frames[tile->id] = tile->frames;
		}
	}
	rfor (i, 0, MAX_TILE_ID) {
		tile_frame_id[i] = 0;
		if (tile_numframes[i]) {
			tile_visuals[i] = tile_frames[i][0].tileid;
			tile_next_frame[i] = tile_frames[i][0].duration *
			                     cfg.fps / 1000;
		} else
			tile_visuals[i] = i;
	}
}

void tileset_update() {
	const unsigned long tick = TZR_GetTick();
	const unsigned long elapsed = tick - last_tick;
	last_tick = tick;

	rfor (i, 0, MAX_TILE_ID) {
		if (!tile_numframes[i]) continue;
		tile_next_frame[i] -= elapsed;
		while (tile_next_frame[i] <= 0) {
			tile_frame_id[i] += 1;
			tile_frame_id[i] %= tile_numframes[i];
			const auto frame_id = tile_frame_id[i];
			tile_visuals[i] = tile_frames[i][frame_id].tileid;
			tile_next_frame[i] = tile_frames[i][frame_id]
			                     .duration * cfg.fps / 1000;
		}
	}
}

i32 tileset_width() {
	return tset_tsj.columns;
}

void tile_draw(u32 id, int x, int y) {
	const bool flip_x = (id & tiled_flip_x) != 0;
	const bool flip_y = (id & tiled_flip_y) != 0;
	const auto v = tile_visual(id);
	if (v < 0) return;
	const int ix = v % tset_tsj.columns * cfg.tile_width;
	const int iy = v / tset_tsj.columns * cfg.tile_height;
	TZR_DrawImage(TZR_RES(tset_tsj.path + 3),
	              x, y, ix, iy, cfg.tile_width, cfg.tile_height,
	              .flip_x=flip_x, .flip_y=flip_y);
}

u32 tile_type(u32 id) {
	assert((id & ~tiled_transforms) < MAX_TILE_ID);
	if (id <= 0)
		return TILE_NONE;
	return tile_types[(id & ~tiled_transforms) - 1];
}

const Tiled2cTile *tile_t2c(u32 id) {
	assert((id & ~tiled_transforms) < MAX_TILE_ID);
	if (id <= 0)
		return nullptr;
	return tile_t2cs[(id & ~tiled_transforms) - 1];
}

i32 tile_visual(u32 id) {
	assert((id & ~tiled_transforms) < MAX_TILE_ID);
	if (id <= 0)
		return -1;
	return tile_visuals[(id & ~tiled_transforms) - 1];
}