summaryrefslogtreecommitdiff
path: root/src/cell.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cell.c')
-rw-r--r--src/cell.c102
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);
+}