mirror of https://github.com/inolen/redream.git
cleaned up some of the ta poly / vertex parameter parsing
This commit is contained in:
parent
f6dbdbcd02
commit
76bdc3fe5d
|
@ -110,39 +110,6 @@ static inline enum shade_mode translate_shade_mode(uint32_t shade_mode) {
|
|||
return shade_modes[shade_mode];
|
||||
}
|
||||
|
||||
static inline uint8_t ftou8(float x) {
|
||||
/* saturating floating point to uint8_t conversion */
|
||||
return MIN(MAX((int32_t)(x * 255.0f), 0), 255);
|
||||
}
|
||||
|
||||
static inline uint8_t fmulu8(uint8_t a, uint8_t b) {
|
||||
/* fixed point multiply, used for intensity scaling */
|
||||
return (uint8_t)((uint32_t)a * (uint32_t)b / 255);
|
||||
}
|
||||
|
||||
static inline void argb_to_rgba(uint32_t v, uint32_t *out) {
|
||||
((uint8_t *)out)[0] = (v & 0x00ff0000) >> 16;
|
||||
((uint8_t *)out)[1] = (v & 0x0000ff00) >> 8;
|
||||
((uint8_t *)out)[2] = (v & 0x000000ff);
|
||||
((uint8_t *)out)[3] = (v & 0xff000000) >> 24;
|
||||
}
|
||||
|
||||
static inline void byte_to_rgba(uint8_t r, uint8_t g, uint8_t b, uint8_t a,
|
||||
uint32_t *out) {
|
||||
((uint8_t *)out)[0] = r;
|
||||
((uint8_t *)out)[1] = g;
|
||||
((uint8_t *)out)[2] = b;
|
||||
((uint8_t *)out)[3] = a;
|
||||
}
|
||||
|
||||
static inline void float_to_rgba(float r, float g, float b, float a,
|
||||
uint32_t *out) {
|
||||
((uint8_t *)out)[0] = ftou8(r);
|
||||
((uint8_t *)out)[1] = ftou8(g);
|
||||
((uint8_t *)out)[2] = ftou8(b);
|
||||
((uint8_t *)out)[3] = ftou8(a);
|
||||
}
|
||||
|
||||
static texture_handle_t tr_convert_texture(struct tr *tr,
|
||||
const struct ta_context *ctx,
|
||||
union tsp tsp, union tcw tcw) {
|
||||
|
@ -311,40 +278,75 @@ static void tr_commit_surf(struct tr *tr, struct tr_context *rc) {
|
|||
/*
|
||||
* polygon parsing helpers
|
||||
*/
|
||||
#define PARSE_XYZ(x, y, z, xyz) \
|
||||
static inline uint8_t ftou8(float x) {
|
||||
/* saturating floating point to uint8_t conversion */
|
||||
return MIN(MAX((int32_t)(x * 255.0f), 0), 255);
|
||||
}
|
||||
|
||||
static inline uint8_t fmulu8(uint8_t a, uint8_t b) {
|
||||
/* fixed point multiply */
|
||||
return (uint8_t)((uint32_t)a * (uint32_t)b / 255);
|
||||
}
|
||||
|
||||
#define PARSE_XYZ(xyz, out) \
|
||||
{ \
|
||||
(out)[0] = (xyz)[0]; \
|
||||
(out)[1] = (xyz)[1]; \
|
||||
(out)[2] = (xyz)[2]; \
|
||||
}
|
||||
|
||||
#define PARSE_UV(uv, out) \
|
||||
{ \
|
||||
(out)[0] = (uv)[0]; \
|
||||
(out)[1] = (uv)[1]; \
|
||||
}
|
||||
|
||||
#define PARSE_UV16(vu, out) \
|
||||
{ \
|
||||
xyz[0] = (x); \
|
||||
xyz[1] = (y); \
|
||||
xyz[2] = (z); \
|
||||
uint32_t u = (vu)[1] << 16; \
|
||||
uint32_t v = (vu)[0] << 16; \
|
||||
(out)[0] = *(float *)&u; \
|
||||
(out)[1] = *(float *)&v; \
|
||||
}
|
||||
|
||||
#define PARSE_RGBA(base, out) \
|
||||
{ float_to_rgba(base##_r, base##_g, base##_b, base##_a, (uint32_t *)out); }
|
||||
|
||||
#define PARSE_PACKED(argb, out) \
|
||||
{ argb_to_rgba(argb, (uint32_t *)out); }
|
||||
|
||||
#define PARSE_BASE_INTENSITY(base_intensity, out) \
|
||||
{ \
|
||||
uint8_t i = ftou8(base_intensity); \
|
||||
byte_to_rgba(fmulu8(tr->face_color[0], i), fmulu8(tr->face_color[1], i), \
|
||||
fmulu8(tr->face_color[2], i), tr->face_color[3], out); \
|
||||
#define PARSE_FLOAT_COLOR(color, out) \
|
||||
{ \
|
||||
/* when converting from float point to a packed color, clamp each \
|
||||
component to 0-255 */ \
|
||||
((uint8_t *)out)[0] = ftou8(color##_r); \
|
||||
((uint8_t *)out)[1] = ftou8(color##_g); \
|
||||
((uint8_t *)out)[2] = ftou8(color##_b); \
|
||||
((uint8_t *)out)[3] = ftou8(color##_a); \
|
||||
}
|
||||
|
||||
#define PARSE_PACKED_COLOR(color, out) \
|
||||
{ \
|
||||
((uint8_t *)out)[0] = (color & 0x00ff0000) >> 16; \
|
||||
((uint8_t *)out)[1] = (color & 0x0000ff00) >> 8; \
|
||||
((uint8_t *)out)[2] = (color & 0x000000ff); \
|
||||
((uint8_t *)out)[3] = (color & 0xff000000) >> 24; \
|
||||
}
|
||||
|
||||
#define PARSE_INTENSITY(color, intensity, out) \
|
||||
{ \
|
||||
/* when converting from intensity to a packed color, each operand is \
|
||||
clamped to 0-255 before multiplication */ \
|
||||
uint8_t i = ftou8(intensity); \
|
||||
((uint8_t *)out)[0] = fmulu8(color[0], i); \
|
||||
((uint8_t *)out)[1] = fmulu8(color[1], i); \
|
||||
((uint8_t *)out)[2] = fmulu8(color[2], i); \
|
||||
((uint8_t *)out)[3] = color[3]; \
|
||||
}
|
||||
|
||||
#define PARSE_BASE_INTENSITY(base_intensity, out) \
|
||||
PARSE_INTENSITY(tr->face_color, base_intensity, out)
|
||||
|
||||
#define PARSE_OFFSET_INTENSITY(offset_intensity, out) \
|
||||
{ \
|
||||
uint8_t i = ftou8(offset_intensity); \
|
||||
byte_to_rgba(fmulu8(tr->face_offset_color[0], i), \
|
||||
fmulu8(tr->face_offset_color[1], i), \
|
||||
fmulu8(tr->face_offset_color[2], i), \
|
||||
tr->face_offset_color[3], out); \
|
||||
}
|
||||
PARSE_INTENSITY(tr->face_offset_color, offset_intensity, out)
|
||||
|
||||
static int tr_parse_bg_vert(const struct ta_context *ctx, struct tr_context *rc,
|
||||
int offset, struct ta_vertex *v) {
|
||||
PARSE_XYZ(*(float *)&ctx->bg_vertices[offset],
|
||||
*(float *)&ctx->bg_vertices[offset + 4],
|
||||
*(float *)&ctx->bg_vertices[offset + 8], v->xyz);
|
||||
PARSE_XYZ((float *)&ctx->bg_vertices[offset], v->xyz);
|
||||
offset += 12;
|
||||
|
||||
if (ctx->bg_isp.texture) {
|
||||
|
@ -355,7 +357,7 @@ static int tr_parse_bg_vert(const struct ta_context *ctx, struct tr_context *rc,
|
|||
}
|
||||
|
||||
uint32_t base_color = *(uint32_t *)&ctx->bg_vertices[offset];
|
||||
argb_to_rgba(base_color, &v->color);
|
||||
PARSE_PACKED_COLOR(base_color, &v->color);
|
||||
offset += 4;
|
||||
|
||||
if (ctx->bg_isp.offset) {
|
||||
|
@ -397,17 +399,26 @@ static void tr_parse_bg(struct tr *tr, const struct ta_context *ctx,
|
|||
|
||||
/* override xyz values supplied by ISP_BACKGND_T. while the hardware docs act
|
||||
like they should be correct, they're most definitely not in most cases */
|
||||
PARSE_XYZ(0.0f, (float)ctx->video_height, ctx->bg_depth, v0->xyz);
|
||||
PARSE_XYZ(0.0f, 0.0f, ctx->bg_depth, v1->xyz);
|
||||
PARSE_XYZ((float)ctx->video_width, (float)ctx->video_height, ctx->bg_depth,
|
||||
v2->xyz);
|
||||
v0->xyz[0] = 0.0f;
|
||||
v0->xyz[1] = (float)ctx->video_height;
|
||||
v0->xyz[2] = ctx->bg_depth;
|
||||
|
||||
v1->xyz[0] = 0.0f;
|
||||
v1->xyz[1] = 0.0f;
|
||||
v1->xyz[2] = ctx->bg_depth;
|
||||
|
||||
v2->xyz[0] = (float)ctx->video_width;
|
||||
v2->xyz[1] = (float)ctx->video_height;
|
||||
v2->xyz[2] = ctx->bg_depth;
|
||||
|
||||
/* 4th vertex isn't supplied, fill it out automatically */
|
||||
PARSE_XYZ(v2->xyz[0], v1->xyz[1], ctx->bg_depth, v3->xyz);
|
||||
v3->color = v0->color;
|
||||
v3->offset_color = v0->offset_color;
|
||||
v3->xyz[0] = v2->xyz[0];
|
||||
v3->xyz[1] = v1->xyz[1];
|
||||
v3->xyz[2] = ctx->bg_depth;
|
||||
v3->uv[0] = v2->uv[0];
|
||||
v3->uv[1] = v1->uv[1];
|
||||
v3->color = v0->color;
|
||||
v3->offset_color = v0->offset_color;
|
||||
|
||||
tr_commit_surf(tr, rc);
|
||||
|
||||
|
@ -439,17 +450,17 @@ static void tr_parse_poly_param(struct tr *tr, const struct ta_context *ctx,
|
|||
} break;
|
||||
|
||||
case 1: {
|
||||
PARSE_RGBA(param->type1.face_color, &tr->face_color);
|
||||
PARSE_FLOAT_COLOR(param->type1.face_color, &tr->face_color);
|
||||
} break;
|
||||
|
||||
case 2: {
|
||||
PARSE_RGBA(param->type2.face_color, &tr->face_color);
|
||||
PARSE_RGBA(param->type2.face_offset_color, &tr->face_offset_color);
|
||||
PARSE_FLOAT_COLOR(param->type2.face_color, &tr->face_color);
|
||||
PARSE_FLOAT_COLOR(param->type2.face_offset_color, &tr->face_offset_color);
|
||||
} break;
|
||||
|
||||
case 5: {
|
||||
PARSE_PACKED(param->sprite.base_color, &tr->sprite_color);
|
||||
PARSE_PACKED(param->sprite.offset_color, &tr->sprite_offset_color);
|
||||
PARSE_PACKED_COLOR(param->sprite.base_color, &tr->sprite_color);
|
||||
PARSE_PACKED_COLOR(param->sprite.offset_color, &tr->sprite_offset_color);
|
||||
} break;
|
||||
|
||||
default:
|
||||
|
@ -464,8 +475,7 @@ static void tr_parse_poly_param(struct tr *tr, const struct ta_context *ctx,
|
|||
and texture settings */
|
||||
struct ta_surface *surf = tr_reserve_surf(tr, rc, 0);
|
||||
surf->depth_write = !param->type0.isp.z_write_disable;
|
||||
surf->depth_func =
|
||||
translate_depth_func(param->type0.isp.depth_compare_mode);
|
||||
surf->depth_func = translate_depth_func(param->type0.isp.depth_compare_mode);
|
||||
surf->cull = translate_cull(param->type0.isp.culling_mode);
|
||||
surf->src_blend = translate_src_blend_func(param->type0.tsp.src_alpha_instr);
|
||||
surf->dst_blend = translate_dst_blend_func(param->type0.tsp.dst_alpha_instr);
|
||||
|
@ -517,100 +527,70 @@ static void tr_parse_vert_param(struct tr *tr, const struct ta_context *ctx,
|
|||
switch (tr->vert_type) {
|
||||
case 0: {
|
||||
struct ta_vertex *vert = tr_reserve_vert(tr, rc);
|
||||
PARSE_XYZ(param->type0.xyz[0], param->type0.xyz[1], param->type0.xyz[2],
|
||||
vert->xyz);
|
||||
PARSE_PACKED(param->type0.base_color, &vert->color);
|
||||
vert->offset_color = 0;
|
||||
vert->uv[0] = 0.0f;
|
||||
vert->uv[1] = 0.0f;
|
||||
PARSE_XYZ(param->type0.xyz, vert->xyz);
|
||||
PARSE_PACKED_COLOR(param->type0.base_color, &vert->color);
|
||||
} break;
|
||||
|
||||
case 1: {
|
||||
struct ta_vertex *vert = tr_reserve_vert(tr, rc);
|
||||
PARSE_XYZ(param->type1.xyz[0], param->type1.xyz[1], param->type1.xyz[2],
|
||||
vert->xyz);
|
||||
PARSE_RGBA(param->type1.base_color, &vert->color);
|
||||
vert->offset_color = 0;
|
||||
vert->uv[0] = 0.0f;
|
||||
vert->uv[1] = 0.0f;
|
||||
PARSE_XYZ(param->type1.xyz, vert->xyz);
|
||||
PARSE_FLOAT_COLOR(param->type1.base_color, &vert->color);
|
||||
} break;
|
||||
|
||||
case 2: {
|
||||
struct ta_vertex *vert = tr_reserve_vert(tr, rc);
|
||||
PARSE_XYZ(param->type2.xyz[0], param->type2.xyz[1], param->type2.xyz[2],
|
||||
vert->xyz);
|
||||
PARSE_XYZ(param->type2.xyz, vert->xyz);
|
||||
PARSE_BASE_INTENSITY(param->type2.base_intensity, &vert->color);
|
||||
vert->offset_color = 0;
|
||||
vert->uv[0] = 0.0f;
|
||||
vert->uv[1] = 0.0f;
|
||||
} break;
|
||||
|
||||
case 3: {
|
||||
struct ta_vertex *vert = tr_reserve_vert(tr, rc);
|
||||
PARSE_XYZ(param->type3.xyz[0], param->type3.xyz[1], param->type3.xyz[2],
|
||||
vert->xyz);
|
||||
PARSE_PACKED(param->type3.base_color, &vert->color);
|
||||
PARSE_PACKED(param->type3.offset_color, &vert->offset_color);
|
||||
vert->uv[0] = param->type3.uv[0];
|
||||
vert->uv[1] = param->type3.uv[1];
|
||||
PARSE_XYZ(param->type3.xyz, vert->xyz);
|
||||
PARSE_UV(param->type3.uv, vert->uv);
|
||||
PARSE_PACKED_COLOR(param->type3.base_color, &vert->color);
|
||||
PARSE_PACKED_COLOR(param->type3.offset_color, &vert->offset_color);
|
||||
} break;
|
||||
|
||||
case 4: {
|
||||
struct ta_vertex *vert = tr_reserve_vert(tr, rc);
|
||||
PARSE_XYZ(param->type4.xyz[0], param->type4.xyz[1], param->type4.xyz[2],
|
||||
vert->xyz);
|
||||
PARSE_PACKED(param->type4.base_color, &vert->color);
|
||||
PARSE_PACKED(param->type4.offset_color, &vert->offset_color);
|
||||
uint32_t u = param->type4.vu[1] << 16;
|
||||
uint32_t v = param->type4.vu[0] << 16;
|
||||
vert->uv[0] = *(float *)&u;
|
||||
vert->uv[1] = *(float *)&v;
|
||||
PARSE_XYZ(param->type4.xyz, vert->xyz);
|
||||
PARSE_UV16(param->type4.vu, vert->uv);
|
||||
PARSE_PACKED_COLOR(param->type4.base_color, &vert->color);
|
||||
PARSE_PACKED_COLOR(param->type4.offset_color, &vert->offset_color);
|
||||
} break;
|
||||
|
||||
case 5: {
|
||||
struct ta_vertex *vert = tr_reserve_vert(tr, rc);
|
||||
PARSE_XYZ(param->type5.xyz[0], param->type5.xyz[1], param->type5.xyz[2],
|
||||
vert->xyz);
|
||||
PARSE_RGBA(param->type5.base_color, &vert->color);
|
||||
PARSE_RGBA(param->type5.offset_color, &vert->offset_color);
|
||||
vert->uv[0] = param->type5.uv[0];
|
||||
vert->uv[1] = param->type5.uv[1];
|
||||
PARSE_XYZ(param->type5.xyz, vert->xyz);
|
||||
PARSE_UV(param->type5.uv, vert->uv);
|
||||
PARSE_FLOAT_COLOR(param->type5.base_color, &vert->color);
|
||||
PARSE_FLOAT_COLOR(param->type5.offset_color, &vert->offset_color);
|
||||
} break;
|
||||
|
||||
case 6: {
|
||||
struct ta_vertex *vert = tr_reserve_vert(tr, rc);
|
||||
PARSE_XYZ(param->type6.xyz[0], param->type6.xyz[1], param->type6.xyz[2],
|
||||
vert->xyz);
|
||||
PARSE_RGBA(param->type6.base_color, &vert->color);
|
||||
PARSE_RGBA(param->type6.offset_color, &vert->offset_color);
|
||||
uint32_t u = param->type6.vu[1] << 16;
|
||||
uint32_t v = param->type6.vu[0] << 16;
|
||||
vert->uv[0] = *(float *)&u;
|
||||
vert->uv[1] = *(float *)&v;
|
||||
PARSE_XYZ(param->type6.xyz, vert->xyz);
|
||||
PARSE_UV16(param->type6.vu, vert->uv);
|
||||
PARSE_FLOAT_COLOR(param->type6.base_color, &vert->color);
|
||||
PARSE_FLOAT_COLOR(param->type6.offset_color, &vert->offset_color);
|
||||
} break;
|
||||
|
||||
case 7: {
|
||||
struct ta_vertex *vert = tr_reserve_vert(tr, rc);
|
||||
PARSE_XYZ(param->type7.xyz[0], param->type7.xyz[1], param->type7.xyz[2],
|
||||
vert->xyz);
|
||||
PARSE_XYZ(param->type7.xyz, vert->xyz);
|
||||
PARSE_UV(param->type7.uv, vert->uv);
|
||||
PARSE_BASE_INTENSITY(param->type7.base_intensity, &vert->color);
|
||||
PARSE_OFFSET_INTENSITY(param->type7.offset_intensity,
|
||||
&vert->offset_color);
|
||||
vert->uv[0] = param->type7.uv[0];
|
||||
vert->uv[1] = param->type7.uv[1];
|
||||
} break;
|
||||
|
||||
case 8: {
|
||||
struct ta_vertex *vert = tr_reserve_vert(tr, rc);
|
||||
PARSE_XYZ(param->type8.xyz[0], param->type8.xyz[1], param->type8.xyz[2],
|
||||
vert->xyz);
|
||||
PARSE_XYZ(param->type8.xyz, vert->xyz);
|
||||
PARSE_UV16(param->type8.vu, vert->uv);
|
||||
PARSE_BASE_INTENSITY(param->type8.base_intensity, &vert->color);
|
||||
PARSE_OFFSET_INTENSITY(param->type8.offset_intensity,
|
||||
&vert->offset_color);
|
||||
uint32_t u = param->type8.vu[1] << 16;
|
||||
uint32_t v = param->type8.vu[0] << 16;
|
||||
vert->uv[0] = *(float *)&u;
|
||||
vert->uv[1] = *(float *)&v;
|
||||
} break;
|
||||
|
||||
case 15: {
|
||||
|
@ -623,11 +603,11 @@ static void tr_parse_vert_param(struct tr *tr, const struct ta_context *ctx,
|
|||
struct ta_vertex *vert = tr_reserve_vert(tr, rc);
|
||||
|
||||
/* FIXME this is assuming all sprites are billboards */
|
||||
PARSE_XYZ(param->sprite0.xyz[idx][0], param->sprite0.xyz[idx][1],
|
||||
param->sprite0.xyz[0][2], vert->xyz);
|
||||
memcpy(&vert->color, tr->sprite_color, sizeof(vert->color));
|
||||
memcpy(&vert->offset_color, tr->sprite_offset_color,
|
||||
sizeof(vert->offset_color));
|
||||
vert->xyz[0] = param->sprite0.xyz[idx][0];
|
||||
vert->xyz[1] = param->sprite0.xyz[idx][1];
|
||||
vert->xyz[2] = param->sprite0.xyz[0][2];
|
||||
vert->color = *(uint32_t *)&tr->sprite_color;
|
||||
vert->offset_color = *(uint32_t *)&tr->sprite_offset_color;
|
||||
}
|
||||
} break;
|
||||
|
||||
|
@ -641,11 +621,9 @@ static void tr_parse_vert_param(struct tr *tr, const struct ta_context *ctx,
|
|||
struct ta_vertex *vert = tr_reserve_vert(tr, rc);
|
||||
|
||||
/* FIXME this is assuming all sprites are billboards */
|
||||
PARSE_XYZ(param->sprite1.xyz[idx][0], param->sprite1.xyz[idx][1],
|
||||
param->sprite1.xyz[0][2], vert->xyz);
|
||||
memcpy(&vert->color, tr->sprite_color, sizeof(vert->color));
|
||||
memcpy(&vert->offset_color, tr->sprite_offset_color,
|
||||
sizeof(vert->offset_color));
|
||||
vert->xyz[0] = param->sprite1.xyz[idx][0];
|
||||
vert->xyz[1] = param->sprite1.xyz[idx][1];
|
||||
vert->xyz[2] = param->sprite1.xyz[0][2];
|
||||
uint32_t u, v;
|
||||
if (idx == 3) {
|
||||
u = (param->sprite1.uv[0] & 0xffff0000);
|
||||
|
@ -656,6 +634,8 @@ static void tr_parse_vert_param(struct tr *tr, const struct ta_context *ctx,
|
|||
}
|
||||
vert->uv[0] = *(float *)&u;
|
||||
vert->uv[1] = *(float *)&v;
|
||||
vert->color = *(uint32_t *)&tr->sprite_color;
|
||||
vert->offset_color = *(uint32_t *)&tr->sprite_offset_color;
|
||||
}
|
||||
} break;
|
||||
|
||||
|
|
Loading…
Reference in New Issue