aboutsummaryrefslogtreecommitdiff
path: root/src/instance
diff options
context:
space:
mode:
authorXavier Del Campo Romero <xavi.dcr@tutanota.com>2021-07-03 00:49:03 +0200
committerXavier Del Campo Romero <xavi.dcr@tutanota.com>2022-03-30 08:20:20 +0200
commit8c10334252821b6310cf744218f7ad8bed7917f2 (patch)
treef6f11d71eac56fa834783ef54a977b80f2e5efc2 /src/instance
parentfc9beffe0103a80bf883f85b7ae09dc42b7af50e (diff)
Add project source code
Diffstat (limited to 'src/instance')
-rw-r--r--src/instance/CMakeLists.txt3
-rw-r--r--src/instance/inc/instance.h68
-rw-r--r--src/instance/src/instance.c150
3 files changed, 221 insertions, 0 deletions
diff --git a/src/instance/CMakeLists.txt b/src/instance/CMakeLists.txt
new file mode 100644
index 0000000..2e777a9
--- /dev/null
+++ b/src/instance/CMakeLists.txt
@@ -0,0 +1,3 @@
+add_library(instance "src/instance.c")
+target_include_directories(instance PUBLIC "inc")
+target_link_libraries(instance PUBLIC camera gfx util)
diff --git a/src/instance/inc/instance.h b/src/instance/inc/instance.h
new file mode 100644
index 0000000..ca8a606
--- /dev/null
+++ b/src/instance/inc/instance.h
@@ -0,0 +1,68 @@
+#ifndef INSTANCE_H
+#define INSTANCE_H
+
+#include <camera.h>
+#include <gfx.h>
+#include <util.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+typedef unsigned int instance_hp;
+
+struct instance
+{
+ bool alive, dying;
+ unsigned int hp;
+ struct util_rect r;
+};
+
+typedef bool (*instance_attacked_cb)(struct instance *i, unsigned int ap);
+typedef bool (*instance_sheltered_cb)(struct instance *self, struct instance *other);
+typedef void (*instance_done_cb)(struct instance *i, void *op);
+
+struct instance_render_cfg
+{
+ const struct instance *i;
+ const struct camera *cam;
+ enum
+ {
+ INSTANCE_RENDER_CFG_SPRITE,
+ INSTANCE_RENDER_CFG_QUAD
+ } prim_type;
+
+ union
+ {
+ struct sprite *s;
+ const struct instance_render_quad
+ {
+ struct quad *q;
+ short w, h;
+ uint8_t u;
+ bool xflip;
+ } *quad;
+ } prim;
+
+ bool sel;
+ instance_hp max_hp;
+ const struct instance_render_off
+ {
+ short x, y;
+ } *off;
+};
+
+bool instance_attacked(struct instance *self, unsigned int ap);
+void instance_clear_pools(void);
+int instance_render(const struct instance_render_cfg *cfg);
+int instance_render_target(const struct instance *const i, const struct camera *cam);
+void instance_cyclic(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* INSTANCE_H */
diff --git a/src/instance/src/instance.c b/src/instance/src/instance.c
new file mode 100644
index 0000000..03f4872
--- /dev/null
+++ b/src/instance/src/instance.c
@@ -0,0 +1,150 @@
+#include <instance.h>
+#include <gfx.h>
+#include <limits.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <string.h>
+
+static unsigned char line_g;
+static bool line_g_flip;
+
+bool instance_attacked(struct instance *const self, const instance_hp ap)
+{
+ if (self->hp > ap)
+ self->hp -= ap;
+ else
+ {
+ self->hp = 0;
+ self->alive = false;
+ }
+
+ return !self->alive;
+}
+
+void instance_cyclic(void)
+{
+ if (!line_g_flip)
+ {
+ if ((line_g += 5) >= UCHAR_MAX)
+ line_g_flip ^= true;
+ }
+ else if (!(line_g -= 5))
+ line_g_flip ^= true;
+}
+
+static int draw_sel(const struct instance *const i, const short x, const short y)
+{
+ struct stp_4line *const l = stp_4line_get();
+
+ if (!l)
+ return -1;
+
+ enum {R = 0, G = 255, B = 0};
+
+ l->x = l->vertices[2].x = l->vertices[3].x = x;
+ l->y = l->vertices[0].y = l->vertices[3].y = y;
+ l->vertices[0].x = l->vertices[1].x = x + i->r.w;
+ l->vertices[1].y = l->vertices[2].y = y + i->r.h;
+ l->r = R;
+ l->g = line_g;
+ l->b = B >> 2;
+
+ for (size_t i = 0; i < sizeof l->vertices / sizeof *l->vertices; i++)
+ {
+ struct stp_4line_vtx *const v = &l->vertices[i];
+
+ v->r = R;
+ v->b = B;
+ }
+
+ l->vertices[0].g = l->vertices[2].g = UCHAR_MAX - line_g;
+ l->vertices[1].g = l->vertices[3].g = line_g;
+ stp_4line_sort(l);
+
+ struct stp_4line *const ll = stp_4line_get();
+
+ if (!ll)
+ return -1;
+
+ *ll = *l;
+ ll->x = ll->vertices[2].x = ll->vertices[3].x = l->x ? l->x - 1 : 0;
+ ll->y = ll->vertices[0].y = ll->vertices[3].y = l->y ? l->y - 1 : 0;
+ ll->vertices[0].x = ll->vertices[1].x = l->vertices[0].x + 1;
+ ll->vertices[1].y = ll->vertices[2].y = l->vertices[1].y + 1;
+ stp_4line_sort(ll);
+ return 0;
+}
+
+static void render_sprite(struct sprite *const s,
+ const struct instance_render_off *const off, const short x, const short y)
+{
+ s->x = off ? x + off->x : x;
+ s->y = off ? y + off->y : y;
+ sprite_sort(s);
+}
+
+static void render_quad(const struct instance_render_quad *const rq,
+ const struct instance_render_off *const off, const short x, const short y)
+{
+ struct quad *const q = rq->q;
+ const short x0 = x + off->x, x1 = x0 + rq->w - 1;
+
+ if (rq->xflip)
+ {
+ q->x0 = q->x2 = x1;
+ q->x1 = q->x3 = x0;
+ q->u0 = q->u2 = rq->u;
+ q->u1 = q->u3 = rq->u + rq->w - 1;
+ }
+ else
+ {
+ q->x0 = q->x2 = x0;
+ q->x1 = q->x3 = x1;
+ q->u0 = q->u2 = rq->u;
+ q->u1 = q->u3 = rq->u + rq->w - 1;
+ }
+
+ const short y0 = y + off->y, y1 = y0 + rq->h - 1;
+
+ q->y0 = q->y1 = y0;
+ q->y2 = q->y3 = y1;
+ quad_sort(q);
+}
+
+int instance_render(const struct instance_render_cfg *const cfg)
+{
+ const struct instance *const i = cfg->i;
+ short x, y;
+
+ if (camera_translate(cfg->cam, &i->r, &x, &y))
+ {
+ const struct instance_render_off *const off = cfg->off;
+
+ if (cfg->sel && draw_sel(i, x, y))
+ return -1;
+
+ switch (cfg->prim_type)
+ {
+ case INSTANCE_RENDER_CFG_SPRITE:
+ render_sprite(cfg->prim.s, off, x, y);
+ break;
+
+ case INSTANCE_RENDER_CFG_QUAD:
+ render_quad(cfg->prim.quad, off, x, y);
+ break;
+ }
+ }
+
+ return 0;
+}
+
+int instance_render_target(const struct instance *const i,
+ const struct camera *const cam)
+{
+ short x, y;
+
+ if (camera_translate(cam, &i->r, &x, &y))
+ return draw_sel(i, x, y);
+
+ return -1;
+}