diff options
Diffstat (limited to 'src/cell.c')
-rw-r--r-- | src/cell.c | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/src/cell.c b/src/cell.c new file mode 100644 index 0000000..b90d1ee --- /dev/null +++ b/src/cell.c @@ -0,0 +1,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); +} |