/** * Compute a RGB value with a specific format * \param r, g, b RGB values [0-255]. * \param def_ordinal RGB format definition. * \return RGB nibble as ordinal value. */ adv_pixel pixel_make_from_def(unsigned r, unsigned g, unsigned b, adv_color_def def_ordinal) { union adv_color_def_union def; def.ordinal = def_ordinal; switch (def.nibble.type) { case adv_color_type_rgb : return rgb_nibble_insert(r, rgb_shift_make_from_def(def.nibble.red_len, def.nibble.red_pos), rgb_mask_make_from_def(def.nibble.red_len, def.nibble.red_pos)) | rgb_nibble_insert(g, rgb_shift_make_from_def(def.nibble.green_len, def.nibble.green_pos), rgb_mask_make_from_def(def.nibble.green_len, def.nibble.green_pos)) | rgb_nibble_insert(b, rgb_shift_make_from_def(def.nibble.blue_len, def.nibble.blue_pos), rgb_mask_make_from_def(def.nibble.blue_len, def.nibble.blue_pos)); case adv_color_type_yuy2 : { /* Y = 0.299 R + 0.587 G + 0.114 B U = -0.1687 R - 0.3313 G + 0.5 B + 128 V = 0.5 R - 0.4187 G - 0.0813 B + 128 */ unsigned y = ((19595*r + 38469*g + 7471*b) >> 16) & 0xFF; unsigned u = ((-11055*r - 21712*g + 32768*b + 8388608) >> 16) & 0xFF; unsigned v = ((32768*r - 27439*g - 5328*b + 8388608) >> 16) & 0xFF; return cpu_uint32_make_uint8(y, u, y, v); } default : /* return always 0 if the pixel is not computable, */ /* for example in palettized modes */ return 0; } }
/** * Compute a RGBA value with a specific format * \param r, g, b, a RGBA values [0-255]. * \param def_ordinal RGBA format definition. * \return RGBA nibble as ordinal value. */ adv_pixel alpha_make_from_def(unsigned r, unsigned g, unsigned b, unsigned a, adv_color_def def_ordinal) { int alpha_shift; adv_pixel alpha_mask; adv_pixel p; alpha_shiftmask_get(&alpha_shift, &alpha_mask, def_ordinal); return pixel_make_from_def(r, g, b, def_ordinal) | rgb_nibble_insert(a, alpha_shift, alpha_mask); }
static void ui_color_alpha_set(adv_pixel* map, const adv_color_rgb* fore, const adv_color_rgb* back, adv_color_def buffer_def, unsigned translucency) { unsigned i; int t; int red_shift, green_shift, blue_shift, alpha_shift; adv_pixel red_mask, green_mask, blue_mask, alpha_mask; union adv_color_def_union udef; udef.ordinal = buffer_def; rgb_shiftmask_get(&red_shift, &red_mask, udef.nibble.red_len, udef.nibble.red_pos); rgb_shiftmask_get(&green_shift, &green_mask, udef.nibble.green_len, udef.nibble.green_pos); rgb_shiftmask_get(&blue_shift, &blue_mask, udef.nibble.blue_len, udef.nibble.blue_pos); alpha_shiftmask_get(&alpha_shift, &alpha_mask, buffer_def); t = translucency; for (i = 0; i < 256; ++i) { int cr, cg, cb, ca; double F, B, A; double I, T; double a, b, c; /* I = ui foreground/background alpha channel T = ui/game alpha channel a = ui foreground component b = ui background component c = game component the color is computed with a * UI_FOREGROUND + b * UI_BACKGROUND + c * GAME with the corner conditions : T=1 -> a=I,b=1-I,c=0 T=0 -> a=I,b=0,c=1-I I=0 -> a=0,b=T,c=1-T I=1 -> a=1,b=0,c=0 where always a+b+c = 1 the following relations are arbitrarily chosen : a = I b = T * (1-I) c = (1-T) * (1-I) */ I = i / 255.0; T = t / 255.0; a = I; b = T * (1 - I); c = (1 - T) * (1 - I); A = 1 - c; /* alpha channel */ if (A == 0) { F = 0; B = 0; } else { /* the alpha component is implicitely applied */ F = a / A; B = b / A; } cr = fore->red * F + back->red * B; cg = fore->green * F + back->green * B; cb = fore->blue * F + back->blue * B; ca = 255 * A; if (cr > 255) cr = 255; if (cg > 255) cg = 255; if (cb > 255) cb = 255; if (ca > 255) ca = 255; map[i] = rgb_nibble_insert(cr, red_shift, red_mask) | rgb_nibble_insert(cg, green_shift, green_mask) | rgb_nibble_insert(cb, blue_shift, blue_mask) | rgb_nibble_insert(ca, alpha_shift, alpha_mask); } }