static void poly_aabb(int n, const int32_t * point, struct srt *srt, struct matrix *ts, int aabb[4]) { struct matrix mat; if (ts == NULL) { matrix_identity(&mat); } else { mat = *ts; } matrix_srt(&mat, srt); int *m = mat.m; int i; for (i=0;i<n;i++) { int x = point[i*2]; int y = point[i*2+1]; int xx = (x * m[0] + y * m[2]) / 1024 + m[4]; int yy = (x * m[1] + y * m[3]) / 1024 + m[5]; if (xx < aabb[0]) aabb[0] = xx; if (xx > aabb[2]) aabb[2] = xx; if (yy < aabb[1]) aabb[1] = yy; if (yy > aabb[3]) aabb[3] = yy; } }
void sprite_drawquad(struct pack_picture *picture, const struct srt *srt, const struct sprite_trans *arg) { struct matrix tmp; struct vertex_pack vb[4]; int i,j; if (arg->mat == NULL) { matrix_identity(&tmp); } else { tmp = *arg->mat; } matrix_srt(&tmp, srt); int *m = tmp.m; for (i=0;i<picture->n;i++) { struct pack_quad *q = &picture->rect[i]; int glid = texture_glid(q->texid); if (glid == 0) continue; shader_texture(glid, 0); for (j=0;j<4;j++) { int xx = q->screen_coord[j*2+0]; int yy = q->screen_coord[j*2+1]; float vx = (xx * m[0] + yy * m[2]) / 1024 + m[4]; float vy = (xx * m[1] + yy * m[3]) / 1024 + m[5]; float tx = q->texture_coord[j*2+0]; float ty = q->texture_coord[j*2+1]; screen_trans(&vx,&vy); vb[j].vx = vx; vb[j].vy = vy; vb[j].tx = tx; vb[j].ty = ty; } shader_draw(vb, arg->color, arg->additive); } }
static void anchor_update(struct sprite *s, struct srt *srt, struct sprite_trans *arg) { struct matrix *r = s->s.mat; if (arg->mat == NULL) { matrix_identity(r); } else { *r = *arg->mat; } matrix_srt(r, srt); }
static int child_pos(struct sprite *s, struct srt *srt, struct sprite_trans *ts, struct sprite *t, int pos[2]) { struct sprite_trans temp; struct matrix temp_matrix; struct sprite_trans *st = trans_mul(&s->t, ts, &temp, &temp_matrix); if (s == t) { struct matrix tmp; if (st->mat == NULL) { matrix_identity(&tmp); } else { tmp = *st->mat; } matrix_srt(&tmp, srt); switch (s->type) { case TYPE_PICTURE: picture_pos(tmp.m, s->s.pic, srt, st, pos); return 0; case TYPE_LABEL: label_pos(tmp.m, s->s.label, srt, st, pos); return 0; case TYPE_ANIMATION: case TYPE_PANNEL: pos[0] = tmp.m[4] / SCREEN_SCALE; pos[1] = tmp.m[5] / SCREEN_SCALE; return 0; default: return 1; } } if (s->type != TYPE_ANIMATION){ return 1; } struct pack_animation *ani = s->s.ani; int frame = real_frame(s) + s->start_frame; struct pack_frame * pf = &ani->frame[frame]; int i; for (i=0;i<pf->n;i++) { struct pack_part *pp = &pf->part[i]; int index = pp->component_id; struct sprite * child = s->data.children[index]; if (child == NULL) { continue; } struct sprite_trans temp2; struct matrix temp_matrix2; struct sprite_trans *ct = trans_mul(&pp->t, st, &temp2, &temp_matrix2); if (child_pos(child, srt, ct, t, pos) == 0) { return 0; } } return 1; }
void calc_particle_system_mat(struct particle * p, struct matrix *m, int edge) { matrix_identity(m); struct srt srt; srt.rot = p->rotation * 1024 / 360; srt.scalex = p->size * 1024 / edge; srt.scaley = srt.scalex; srt.offx = (p->pos.x + p->startPos.x) * SCREEN_SCALE; srt.offy = (p->pos.y + p->startPos.y) * SCREEN_SCALE; matrix_srt(m, &srt); matrix_mul(m, m, &p->emitMatrix); }
void calc_particle_system_mat(struct particle * p, struct matrix *m, int edge) { struct srt srt; struct matrix tmp; matrix_identity(m); srt.rot = (int)(p->rotation * 1024 / 360); srt.scalex = (int)(p->size * 1024 / edge); srt.scaley = srt.scalex; srt.offx = (int)((p->pos.x + p->startPos.x) * SCREEN_SCALE); srt.offy = (int)((p->pos.y + p->startPos.y) * SCREEN_SCALE); matrix_srt(m, &srt); memcpy(tmp.m, m, sizeof(int) * 6); matrix_mul(m, &tmp, &p->emitMatrix); }
void sprite_drawquad(struct pack_picture *picture, struct pack_picture *mask, const struct srt *srt, const struct sprite_trans *arg) { struct matrix tmp; float vb[16]; int i,j; if (arg->mat == NULL) { matrix_identity(&tmp); } else { tmp = *arg->mat; } matrix_srt(&tmp, srt); int *m = tmp.m; for (i=0;i<picture->n;i++) { struct pack_quad *q = &picture->rect[i]; int glid = texture_glid(q->texid); if (glid == 0) continue; shader_texture(glid); for (j=0;j<4;j++) { int xx = q->screen_coord[j*2+0]; int yy = q->screen_coord[j*2+1]; float vx = (xx * m[0] + yy * m[2]) / 1024 + m[4]; float vy = (xx * m[1] + yy * m[3]) / 1024 + m[5]; float tx = q->texture_coord[j*2+0]; float ty = q->texture_coord[j*2+1]; screen_trans(&vx,&vy); texture_coord(q->texid, &tx, &ty); vb[j*4+0] = vx; vb[j*4+1] = vy; vb[j*4+2] = tx; vb[j*4+3] = ty; } if(!enable_visible_test || !screen_is_poly_invisible(vb,4,4)) { if (mask != NULL) { float tx = mask->rect[0].texture_coord[0]; float ty = mask->rect[0].texture_coord[1]; texture_coord(mask->rect[0].texid, &tx, &ty); float delta_tx = tx - vb[2]; float delta_ty = ty - vb[3]; shader_mask(delta_tx, delta_ty); } shader_draw(vb, arg->color); } } }
void sprite_drawpolygon(struct pack_polygon *poly, const struct srt *srt, const struct sprite_trans *arg) { struct matrix tmp; int i,j; if (arg->mat == NULL) { matrix_identity(&tmp); } else { tmp = *arg->mat; } matrix_srt(&tmp, srt); int *m = tmp.m; for (i=0;i<poly->n;i++) { struct pack_poly *p = &poly->poly[i]; int glid = texture_glid(p->texid); if (glid == 0) continue; shader_texture(glid); int pn = p->n; ARRAY(float, vb, 4 * pn); for (j=0;j<pn;j++) { int xx = p->screen_coord[j*2+0]; int yy = p->screen_coord[j*2+1]; float vx = (xx * m[0] + yy * m[2]) / 1024 + m[4]; float vy = (xx * m[1] + yy * m[3]) / 1024 + m[5]; float tx = p->texture_coord[j*2+0]; float ty = p->texture_coord[j*2+1]; screen_trans(&vx,&vy); texture_coord(p->texid, &tx, &ty); vb[j*4+0] = vx; vb[j*4+1] = vy; vb[j*4+2] = tx; vb[j*4+3] = ty; } shader_drawpolygon(pn, vb, arg->color); } }
static int draw_utf8(int unicode, int cx, int cy, int size, const struct srt *srt, uint32_t color, const struct sprite_trans *arg) { const struct dfont_rect * rect = dfont_lookup(Dfont, unicode, FONT_SIZE); if (rect == NULL) { return 0; } struct matrix tmp; struct matrix mat1 = {{ 1024,0,0,1024, cx* SCREEN_SCALE, cy*SCREEN_SCALE }}; struct matrix *m; if (arg->mat) { m=&tmp; matrix_mul(m, &mat1, arg->mat); } else { m=&mat1; } matrix_srt(m, srt); draw_rect(rect,size,m,color); return (rect->w-1) * size / FONT_SIZE ; }
int sprite_pos(struct sprite *s, struct srt *srt, struct matrix *m, int pos[2]) { struct matrix temp; struct matrix *t = mat_mul(s->t.mat, m, &temp); matrix_srt(t, srt); switch (s->type) { case TYPE_PICTURE: picture_pos(t->m, s->s.pic, pos); return 0; case TYPE_LABEL: label_pos(t->m, s->s.label, pos); return 0; case TYPE_ANIMATION: case TYPE_PANNEL: pos[0] = t->m[4] / SCREEN_SCALE; pos[1] = t->m[5] / SCREEN_SCALE; return 0; default: return 1; } }
static void set_scissor(const struct pack_pannel *p, const struct srt *srt, const struct sprite_trans *arg) { struct matrix tmp; if (arg->mat == NULL) { matrix_identity(&tmp); } else { tmp = *arg->mat; } matrix_srt(&tmp, srt); int *m = tmp.m; int x[4] = { 0, p->width * SCREEN_SCALE, p->width * SCREEN_SCALE, 0 }; int y[4] = { 0, 0, p->height * SCREEN_SCALE, p->height * SCREEN_SCALE }; int minx = (x[0] * m[0] + y[0] * m[2]) / 1024 + m[4]; int miny = (x[0] * m[1] + y[0] * m[3]) / 1024 + m[5]; int maxx = minx; int maxy = miny; int i; for (i=1;i<4;i++) { int vx = (x[i] * m[0] + y[i] * m[2]) / 1024 + m[4]; int vy = (x[i] * m[1] + y[i] * m[3]) / 1024 + m[5]; if (vx<minx) { minx = vx; } else if (vx > maxx) { maxx = vx; } if (vy<miny) { miny = vy; } else if (vy > maxy) { maxy = vy; } } minx /= SCREEN_SCALE; miny /= SCREEN_SCALE; maxx /= SCREEN_SCALE; maxy /= SCREEN_SCALE; scissor_push(minx,miny,maxx-minx,maxy-miny); }
static int test_child(struct sprite *s, struct srt *srt, struct matrix * ts, int x, int y, struct sprite ** touch) { struct matrix temp; struct matrix *t = mat_mul(s->t.mat, ts, &temp); if (s->type == TYPE_ANIMATION) { struct sprite *tmp = NULL; int testin = test_animation(s , srt, t, x,y, &tmp); if (testin) { *touch = tmp; return 1; } else if (tmp) { if (s->message) { *touch = s; return 1; } else { *touch = tmp; return 0; } } } struct matrix mat; if (t == NULL) { matrix_identity(&mat); } else { mat = *t; } matrix_srt(&mat, srt); struct matrix imat; if (matrix_inverse(&mat, &imat)) { // invalid matrix *touch = NULL; return 0; } int *m = imat.m; int xx = (x * m[0] + y * m[2]) / 1024 + m[4]; int yy = (x * m[1] + y * m[3]) / 1024 + m[5]; int testin; struct sprite * tmp = s; switch (s->type) { case TYPE_PICTURE: testin = test_quad(s->s.pic, xx, yy); break; case TYPE_POLYGON: testin = test_polygon(s->s.poly, xx, yy); break; case TYPE_LABEL: testin = test_label(s->s.label, xx, yy); break; case TYPE_PANNEL: testin = test_pannel(s->s.pannel, xx, yy); break; case TYPE_ANCHOR: *touch = NULL; return 0; default: // todo : invalid type *touch = NULL; return 0; } if (testin) { *touch = tmp; return s->message; } else { *touch = NULL; return 0; } }