summaryrefslogtreecommitdiff
path: root/src/cell.c
blob: 543cea13a29e243dd7af749e74e9e2fd66f048ad (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
float g_shake = 0.0f;

#define expect(X) if (!(X)) { \
	perr("expect failed: "STR(X)); \
	fclose(fp); \
	cell_destroy(this, false); \
	return NULL; \
}

Cell *
cell_load(const char *pattern, int id, int x, int y)
{
	assert(pattern != NULL);
	assert(id >= 0);

	char buf[64] = {0};
	snprintf(buf, sizeof(buf) - 1, pattern, id);

	FILE *fp = fopen(buf, "rb");
	if (fp == NULL) {
		perr("failed to open '%s': %s", buf, strerror(errno));
		return NULL;
	}

	Cell *this = NULL;
	int width = 0, height = 0;
	fscanf(fp, "%d[^,\n]", &width);
	fscanf(fp, "%*c");
	fscanf(fp, "%d[^,\n]", &height);
	fscanf(fp, "%*c");

	expect(width > 0);
	expect(height > 0);

	this = alloc(sizeof(Cell));
	expect(this != NULL);

	this->id = id;
	this->x = x;
	this->y = y;
	this->width = width;
	this->height = height;
	this->data = alloc(sizeof(this->data[0]) * this->width * this->height);
	expect(this->data != NULL);

	rfor (i, 0, this->width * this->height) {
		fscanf(fp, "%d[^,\n]", &this->data[i]);
		fscanf(fp, "%*c");
	}

	fclose(fp);
	return this;
}

void
cell_destroy(Cell *this, bool recurse)
{
	if (this == NULL)
		return;
	if (recurse)
		cell_destroy(this->next, true);
	if (this->data != NULL)
		free(this->data);
	free(this);
}

void
cell_draw(Cell *this, int x, int y)
{
	const TZR_Uint tset = TZR_RES("res/tset.bmp");
	if (tset == 0)
		return;

	const int tset_width = TZR_GetImageWidth(tset) / cfg.tile_width;
	rfor (ty, 0, this->height) {
		rfor (tx, 0, this->width) {
			const int tile = this->data[tx + ty * this->width];
			if (tile == 0)
				continue;
			int dy = y + ty * cfg.tile_height;
			int dx = x + tx * cfg.tile_width;
			const int ix = (tile-1) % tset_width * cfg.tile_width;
			int iy = (tile-1) / tset_width * cfg.tile_height;
			const int r = rand();
			TZR_DrawImage(tset,
			              dx, dy,
			              ix, iy,
			              cfg.tile_width, cfg.tile_height,
			              .flip_x=r&1, .flip_y=(r&2)!=0);
		}
	}
}

int2
cell_find(Cell *this, int tile)
{
	rfor (y, 0, this->height)
		rfor (x, 0, this->width)
			if (this->data[x + y * this->width] == tile + 1)
				return I2(x, y);
	return I2R(-1);
}