130 lines
3.2 KiB
C
130 lines
3.2 KiB
C
#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;
|
|
|
|
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)
|
|
{
|
|
enum {R = 0, G = 255, B = 0};
|
|
|
|
stp_4line_get_or_ret(l, -1);
|
|
stp_4line_init(l);
|
|
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);
|
|
stp_4line_get_or_ret(ll, -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;
|
|
}
|