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)
return I2(x, y);
return I2R(-1);
}
|