inline void Material::ApplyChannelControl(u8 render_alpha, bool &modulate_colors) const
{
	if(flags->channel_control)
	{
		GX_SetChanCtrl(0, 0, 0, chan_control->color_matsrc, 0, 0, 2 );
		GX_SetChanCtrl(2, 0, 0, chan_control->alpha_matsrc, 0, 0, 2 );

		if(chan_control->alpha_matsrc != 1 && chan_control->color_matsrc != 1)
			modulate_colors = false;

		if(!chan_control->alpha_matsrc || !chan_control->color_matsrc)
		{
			GXColor matColor = (GXColor){0xff, 0xff, 0xff, MultiplyAlpha(0xff, render_alpha) };

			if(flags->material_color)
				matColor = (GXColor){ mat_color->r, mat_color->g, mat_color->b,
									  MultiplyAlpha(mat_color->a, render_alpha) };

			GX_SetChanMatColor(4, matColor);

			if((*(u32 *)&matColor) == 0xFFFFFFFF)
				modulate_colors = true;
		}
	}
	else
	{
		GX_SetChanCtrl(4, 0, 0, 1, 0, 0, 2);
	}

	GX_SetNumChans(1);
}
inline void QuadPane::SetVertex(int ind, float x, float y, u8 render_alpha) const
{
	// position
	GX_Position3f32(x, y, 0.f);

	const GXColor &vertex_color = header->vertex_colors[ind];
	// color
	GX_Color4u8(vertex_color.r, vertex_color.g, vertex_color.b,
				MultiplyAlpha(vertex_color.a, render_alpha));

	// texture coord
	for(u32 i = 0; i < header->tex_coord_count; i++)
		GX_TexCoord2f32(tex_coords[i].coords[ind].s, tex_coords[i].coords[ind].t);
}
Example #3
0
void PixmanBitmap::ConvertImage(int& width, int& height, void*& pixels, bool transparent) {
	const DynamicFormat& img_format = transparent ? image_format : opaque_image_format;

	// premultiply alpha
	for (int y = 0; y < height; y++) {
		uint8* dst = (uint8*) pixels + y * width * 4;
		for (int x = 0; x < width; x++) {
			uint8 &r = *dst++;
			uint8 &g = *dst++;
			uint8 &b = *dst++;
			uint8 &a = *dst++;
			MultiplyAlpha(r, g, b, a);
		}
	}

	PixmanBitmap src(pixels, width, height, 0, img_format);
	Clear();
	Blit(0, 0, &src, src.GetRect(), 255);
	free(pixels);
}
void Textbox::Draw(const BannerResources& resources, u8 parent_alpha, const float ws_scale, Mtx &modelview) const
{
	if(!text)
		return;

	if(header->font_index >= resources.fonts.size())
		return;

	WiiFont *font = resources.fonts[header->font_index];
	if(!font->IsLoaded())
		return;

	// Ugly...but doing it by going through all panes is more ugly
	// TODO: move it to somewhere else
	if(lineWidths.empty())
		((Textbox *) this)->SetTextWidth(font);

	if(lineWidths.empty())
		return;

	SetupGX(resources);

	GX_LoadPosMtxImm(modelview, GX_PNMTX0);

	// Setup text color
	GXColor color0 = { header->color[0].r,
					   header->color[0].g,
					   header->color[0].b,
					   MultiplyAlpha(header->color[0].a, parent_alpha) };

	GXColor color1 = { header->color[1].r,
					   header->color[1].g,
					   header->color[1].b,
					   MultiplyAlpha(header->color[1].a, parent_alpha) };

	u32 lastSheetIdx = 0xffff;
	float scale = header->font_size /(float)font->CharacterHeight();

	// use complete text width if not aligned to middle
	float textWidth = (GetAlignHor() == 1) ? lineWidths[0] : frameWidth;

	// position offset calculation for first line...why the hell is it that complex?
	float xPos = -0.5f * ( GetOriginX() * GetWidth() * ws_scale +
							GetAlignHor() * (-GetWidth()  * ws_scale + textWidth) );
	float yPos = -0.5f * ( GetAlignVer() * -frameHeight +
							GetHeight() * (GetAlignVer() - (2 - GetOriginY())) )
						 - header->font_size;

	// store the character width here for later use, it's constant over the text
	float charWidth = scale * (float)font->CharacterWidth();
	int lineNumber = 0;

	for(const u16 *txtString = text; *txtString != 0; txtString++)
	{
		if(*txtString == '\n')
		{
			lineNumber++;
			// use complete text width if not aligned to middle
			textWidth = (GetAlignHor() == 1) ? lineWidths[lineNumber] : frameWidth;
			// calculate text position depending on line width
			xPos = -0.5f * (GetOriginX() * GetWidth() * ws_scale +
							GetAlignHor() * (-GetWidth() * ws_scale + textWidth));
			// go one line down
			yPos -= (header->font_size + header->space_line);
			continue;
		}

		const WiiFont::CharInfo *charInfo = font->GetCharInfo(*txtString);
		if(!charInfo)
			continue;

		if(charInfo->sheetIdx != lastSheetIdx)
		{
			lastSheetIdx = charInfo->sheetIdx;

			if(!font->Apply(charInfo->sheetIdx))
				continue;
		}

		if(charInfo->unk)
			xPos += scale * (float)charInfo->advanceKerning;

		GX_Begin(GX_QUADS, GX_VTXFMT0, 4);

		GX_Position3f32(xPos, yPos, 0.f);
		GX_Color4u8(color1.r, color1.g, color1.b, color1.a);
		GX_TexCoord2f32(charInfo->s1, charInfo->t2);

		GX_Position3f32(xPos + charWidth, yPos, 0.f);
		GX_Color4u8(color1.r, color1.g, color1.b, color1.a);
		GX_TexCoord2f32(charInfo->s2, charInfo->t2);

		GX_Position3f32(xPos + charWidth, yPos + header->font_size, 0.f);
		GX_Color4u8(color0.r, color0.g, color0.b, color0.a);
		GX_TexCoord2f32(charInfo->s2, charInfo->t1);

		GX_Position3f32(xPos, yPos + header->font_size, 0.f);
		GX_Color4u8(color0.r, color0.g, color0.b, color0.a);
		GX_TexCoord2f32(charInfo->s1, charInfo->t1);

		GX_End();

		xPos += scale * (float)charInfo->advanceGlyphX;
	}
}
void Pane::Render(const Resources& resources, u8 parent_alpha, Mtx &modelview,
				  bool widescreen, bool modify_alpha) const
{
	if (!GetVisible() || GetHide())
		return;

	u8 render_alpha = header->alpha;

    if(RootPane && parent_alpha != 0xFF)
    {
        render_alpha = MultiplyAlpha(header->alpha, parent_alpha);
        modify_alpha = true;
    }
	else if(!RootPane && modify_alpha)
	{
		render_alpha = MultiplyAlpha(header->alpha, parent_alpha);
	}
	else if(GetInfluencedAlpha() && header->alpha != 0xff)
	{
		modify_alpha = true;
		parent_alpha = MultiplyAlpha(header->alpha, parent_alpha);
	}

	float ws_scale = 1.0f;

	if( widescreen && GetWidescren() )
	{
		ws_scale *= 0.82f; // should actually be 0.75?
		widescreen = false;
	}

	Mtx m1,m2,m3,m4;
	guMtxIdentity (m1);

	// Scale
	guMtxScaleApply(m1,m1, header->scale.x * ws_scale, header->scale.y, 1.f);

	// Rotate
	guMtxRotDeg ( m2, 'x', header->rotate.x );
	guMtxRotDeg ( m3, 'y', header->rotate.y );
	guMtxRotDeg ( m4, 'z', header->rotate.z );
	guMtxConcat(m2, m3, m2);
	guMtxConcat(m2, m4, m2);
	guMtxConcat(m1, m2, m1);

	// Translate
	guMtxTransApply(m1,m1, header->translate.x, header->translate.y, header->translate.z);

	guMtxConcat (modelview, m1, pane_view);

	bool scissor = gxScissorForBindedLayouts;
	u32 scissorX = 0;
	u32 scissorY = 0;
	u32 scissorW = 0;
	u32 scissorH = 0;

	// calculate scissors if they will be used
	if( scissor )
	{
		Mtx mv2, mv3;
		guMtxIdentity (mv2);
		guMtxIdentity (mv3);
		guMtxTransApply(mv2,mv2, -0.5f * GetOriginX() * GetWidth(), -0.5f * GetOriginY() * GetHeight(), 0.f);
		guMtxTransApply(mv3,mv3, 0.5f * GetOriginX() * GetWidth(), 0.5f * GetOriginY() * GetHeight(), 0.f);
		guMtxScaleApply(mv2, mv2, 1.0f, -1.0f, 1.0f);
		guMtxScaleApply(mv3, mv3, 1.0f, -1.0f, 1.0f);
		guMtxConcat (pane_view, mv2, mv2);
		guMtxConcat (pane_view, mv3, mv3);

		f32 viewport[6];
		f32 projection[7];

		GX_GetViewportv(viewport);
        GX_GetProjectionv(MainProjection, projection, GX_ORTHOGRAPHIC);

		guVector vecTL;
		guVector vecBR;
		GX_Project(0.0f, 0.0f, 0.0f, mv2, projection, viewport, &vecTL.x, &vecTL.y, &vecTL.z);
		GX_Project(0.0f, 0.0f, 0.0f, mv3, projection, viewport, &vecBR.x, &vecBR.y, &vecBR.z);

        // round up scissor box offset and round down the size
        scissorX = (u32)(0.5f + std::max(vecTL.x, 0.0f));
        scissorY = (u32)(0.5f + std::max(vecTL.y, 0.0f));
        scissorW = (u32)std::max(vecBR.x - vecTL.x, 0.0f);
        scissorH = (u32)std::max(vecBR.y - vecTL.y, 0.0f);

		GX_SetScissor( scissorX, scissorY, scissorW, scissorH );
	}

	// binded layouts dont inheiret the modified widescreen setting
	bool realWS = ( _CONF_GetAspectRatio() == CONF_ASPECT_16_9 );

	// draw binded layouts that appear under this one
	foreach( Layout *l, bindedLayoutsUnder )
	{
		l->RenderWithCurrentMtx( pane_view, realWS );
	}
Example #6
0
uint32 PixmanBitmap::GetUint32Color(uint8 r, uint8 g, uint8 b, uint8 a) const {
	MultiplyAlpha(r, g, b, a);
	return pixel_format.rgba_to_uint32(r, g, b, a);
}