diff options
| author | Xavier Del Campo Romero <xavi.dcr@tutanota.com> | 2021-07-03 00:49:03 +0200 |
|---|---|---|
| committer | Xavier Del Campo Romero <xavi.dcr@tutanota.com> | 2022-03-30 08:20:20 +0200 |
| commit | 8c10334252821b6310cf744218f7ad8bed7917f2 (patch) | |
| tree | f6f11d71eac56fa834783ef54a977b80f2e5efc2 /src/instance | |
| parent | fc9beffe0103a80bf883f85b7ae09dc42b7af50e (diff) | |
Add project source code
Diffstat (limited to 'src/instance')
| -rw-r--r-- | src/instance/CMakeLists.txt | 3 | ||||
| -rw-r--r-- | src/instance/inc/instance.h | 68 | ||||
| -rw-r--r-- | src/instance/src/instance.c | 150 |
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; +} |
