Ejemplo n.º 1
0
float Rect::DisCenterRect(Rect r1, Rect r2) {
	Point p1, p2;
	float result;
	p1 = CenterRect(r1);
	p2 = CenterRect(r2);
	result = p1.DisPoints(p1, p2);
	return result;
}
Ejemplo n.º 2
0
void TopWindow::Open(HWND hwnd)
{
	GuiLock __;
	if(dokeys && (!GUI_AKD_Conservative() || GetAccessKeysDeep() <= 1))
		DistributeAccessKeys();
	UsrLogT(3, "OPEN " + Desc(this));
	LLOG("TopWindow::Open, owner HWND = " << FormatIntHex((int)hwnd, 8) << ", Active = " << FormatIntHex((int)::GetActiveWindow(), 8));
	IgnoreMouseUp();
	SyncCaption();
#ifdef PLATFORM_WINCE
	if(!GetRect().IsEmpty())
#endif
	if(fullscreen) {
		SetRect(GetScreenSize());
		Create(hwnd, WS_POPUP, 0, false, SW_SHOWMAXIMIZED, false);
	}
	else {
		CenterRect(hwnd, hwnd && hwnd == GetTrayHWND__() ? center ? 2 : 0 : center);
		Create(hwnd, style, exstyle, false, state == OVERLAPPED ? SW_SHOWNORMAL :
		                                    state == MINIMIZED  ? SW_MINIMIZE :
		                                                          SW_MAXIMIZE, false);
	}
	PlaceFocus();
	SyncCaption();
	FixIcons();
}
Ejemplo n.º 3
0
void Model::UpdateView(void)
{
    //Define the central Rect (non scrolling area)
    sf::FloatRect CenterRect(CurrentView.Rect.Left + SCROLL_W ,CurrentView.Rect.Top + SCROLL_H ,CurrentView.Rect.Right - SCROLL_W ,CurrentView.Rect.Bottom  - SCROLL_H );
    //Change View if needed & Update Cursor position
    if(player->GetTop() < CenterRect.Top && player->GetTop() > SCROLL_H )
    {
        float Offset = player->GetTop() - CenterRect.Top;
        CurrentView.Rect.Offset(0,Offset);
        cursor->Move(0,Offset);
    }
    else if((player->GetTop() + player->GetHeight() > CenterRect.Bottom) && (player->GetTop() + player->GetHeight() < MAP_HEIGHT * 32 - SCROLL_H) )
    {
        float Offset = player->GetTop() + player->GetHeight() - CenterRect.Bottom;
        CurrentView.Rect.Offset(0,Offset);
        cursor->Move(0,Offset);
    }
    if(player->GetLeft() < CenterRect.Left && player->GetLeft() > SCROLL_W)
    {
        float Offset = player->GetLeft() - CenterRect.Left;
        CurrentView.Rect.Offset(Offset,0);
        cursor->Move(Offset,0);
    }
    else if((player->GetLeft() + player->GetWidth()> CenterRect.Right) && (player->GetLeft() + player->GetWidth()< MAP_WIDTH * 32 - SCROLL_W))
    {
        float Offset = player->GetLeft() + player->GetWidth() - CenterRect.Right;
        CurrentView.Rect.Offset(Offset,0);
        cursor->Move(Offset,0);
    }
}
Ejemplo n.º 4
0
void CSearchBarCtrl::OnPaint()
{
	CPaintDC dc(this);

	CRect rtTriangle;
	CRect rtBack;
	

	CClientRect	rtClient(this);
	CBufferDC	bufDC(dc.GetSafeHdc(), rtClient);
	rtTriangle.CopyRect(rtClient);

	SendMessage(WM_ERASEBKGND, (WPARAM) bufDC.GetSafeHdc(), 1);

	CSize	sizeIcon;
	CRect	rtIcon;
	CFaceManager::GetInstance()->GetImageSize(m_nCurrentIcon, sizeIcon);
	CenterRect(&rtIcon, rtClient, sizeIcon);

	rtIcon.left = rtClient.left + MARGIN_WIDTH;
	rtIcon.top = rtClient.top + MARGIN_WIDTH;
	rtIcon.right = rtIcon.left + sizeIcon.cx;

	rtBack.left = rtClient.left + 2;
	rtBack.top = rtClient.top + 2;
	rtBack.bottom = rtClient.bottom;
	rtBack.right = sizeIcon.cx - 8;


	if (m_bHover)
	{
		bufDC.FillSolidRect(rtBack, RGB(226,226,226));//RGB(238,236,221)
	}
	else
	{
		bufDC.FillSolidRect(rtBack, RGB(240,240,240));//RGB(238,236,221)
	}

	{
		CPenDC pen(bufDC.GetSafeHdc(), RGB(200,200,200));


		bufDC.MoveTo(rtBack.bottom + 6, rtBack.top - 1);
		bufDC.LineTo(rtBack.bottom + 6, rtBack.right - 5);

	}

	m_ImageList.Draw(&bufDC, m_nCurrentIcon, CPoint(rtIcon.left, rtIcon.top), ILD_NORMAL);

	rtTriangle.left = rtClient.left + MARGIN_WIDTH + 1;
	rtTriangle.bottom = rtClient.bottom - rtClient.Height()/2 + MARGIN_WIDTH;
	rtTriangle.right = rtTriangle.left + sizeIcon.cx;


	DrawTriangle(&bufDC, rtTriangle);

}
Ejemplo n.º 5
0
BOOL COFSNcDlg2::LoadWindow(IXMLDOMNode *pXmlRoot, CRect &r, CRect &rMin, CRect &rMax)
{
	ASSERT(pXmlRoot != NULL);
	
	CComPtr<IXMLDOMNode> pWindow = NULL;
	CComBSTR bs, bsBgPath;
	LoadSkins skin;
	long nErrorCode = 0;
	IStreamPtr pStream = NULL;
	CPaintDC dc(this);
	WCHAR *szNULL = L"\0x00";
	
	pXmlRoot->selectSingleNode(CComBSTR(L"Window"), &pWindow);
	if(pWindow)
	{
		// Load window size
		bs.Empty();
		SelectChildNode(pWindow, CComBSTR(L"XLen"), NULL, &bs);
		if(bs.m_str != NULL)
			r.right = r.left + wcstol(bs.m_str, &szNULL, 10);
		bs.Empty();
		SelectChildNode(pWindow, CComBSTR(L"YLen"), NULL, &bs);
		if(bs.m_str != NULL)
			r.bottom = r.top + wcstol(bs.m_str, &szNULL, 10);

		// Load min size
		LoadRect(pWindow, _T("MinSize"), rMin);
		// Load max size
		LoadRect(pWindow, _T("MaxSize"), rMax);
		
		// Load regions for corners
		DeleteObject(m_rgnTL);
		DeleteObject(m_rgnTR);
		DeleteObject(m_rgnBL);
		DeleteObject(m_rgnBR);
		m_rgnTL = m_rgnTR = m_rgnBL = m_rgnBR = NULL;
		LoadRegion(pWindow, _T("TL"), &m_rgnTL);
		LoadRegion(pWindow, _T("TR"), &m_rgnTR);
		LoadRegion(pWindow, _T("BL"), &m_rgnBL);
		LoadRegion(pWindow, _T("BR"), &m_rgnBR);
		
		CenterRect(r);
		AdjustRect(r);
		// Try Fix Focus behavior [7/23/2002]
		SetWindowPos(NULL, r.left, r.top, r.Width(), r.Height(), SWP_NOZORDER|SWP_NOACTIVATE);

		// Load background image
		m_bBackgroundPicture = (LoadPictures(pWindow) > 0);

		//pWindow->Release();
	}
	
	return TRUE;
}
Ejemplo n.º 6
0
void CWebWindow::OnCmdDoAction(LPCTSTR ActionName, LPCTSTR Params, BSTR* Result)
{
	if(ActionName == NULL)
		return;
	if(0 == _tcsicmp(ActionName, _T("Window.Close")))
	{	
		if(m_nIEVersion >= 550)	// This function is only for compatibility with IE 5.0
			return;

		PostMessage(WM_CLOSE);
		return;
	}
	if(0 == _tcsicmp(ActionName, _T("Window.SetSize")))
	{
		// Params = string: Width,Height,IsResizable

		//if(m_nIEVersion >= 550)	// This function is only for compatibility with IE 5.0
		//	return;

		CRect r;
		long cx=-1, cy=-1, resizable=-1;
		_stscanf(Params, _T("%d,%d,%d"), &cx, &cy, &resizable);
		if(cx < 0 || cy < 0 || resizable < 0)
			return;
		m_bResizable = resizable != 0;
		m_browser.GetWindowRect(&r);
		r.right = r.left + cx;
		r.bottom = r.top + cy;
		CenterRect(r);
		SetBrowserRect(r);
		return;
	}
	if(0 == _tcsicmp(ActionName, _T("FileUpload")))
	{
		// Params = XML with upload parameters
		CWnd* pWnd = GetMessageParent();
		if(pWnd)
			pWnd->SendMessage(WM_UPLOAD_APP_FILE, reinterpret_cast<WPARAM>(Params));
	}
}
Ejemplo n.º 7
0
// Copies RGBA8 data from RAM to the currently bound render target.
void SoftGPU::CopyToCurrentFboFromDisplayRam(int srcwidth, int srcheight)
{
	float dstwidth = (float)PSP_CoreParameter().pixelWidth;
	float dstheight = (float)PSP_CoreParameter().pixelHeight;

	glstate.blend.disable();
	glstate.viewport.set(0, 0, dstwidth, dstheight);
	glstate.scissorTest.disable();

	glBindTexture(GL_TEXTURE_2D, temp_texture);

	GLfloat texvert_u;
	if (displayFramebuf_ == 0) {
		u32 data[] = {0};
		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
		texvert_u = 1.0f;
	} else if (displayFormat_ == GE_FORMAT_8888) {
		u8 *data = Memory::GetPointer(displayFramebuf_);
		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)displayStride_, (GLsizei)srcheight, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
		texvert_u = (float)srcwidth / displayStride_;
	} else {
		// TODO: This should probably be converted in a shader instead..
		// TODO: Do something less brain damaged to manage this buffer...
		u32 *buf = new u32[srcwidth * srcheight];
		FormatBuffer displayBuffer;
		displayBuffer.data = Memory::GetPointer(displayFramebuf_);
		for (int y = 0; y < srcheight; ++y) {
			u32 *buf_line = &buf[y * srcwidth];
			const u16 *fb_line = &displayBuffer.as16[y * displayStride_];

			switch (displayFormat_) {
			case GE_FORMAT_565:
				for (int x = 0; x < srcwidth; ++x) {
					buf_line[x] = RGB565ToRGBA8888(fb_line[x]);
				}
				break;

			case GE_FORMAT_5551:
				for (int x = 0; x < srcwidth; ++x) {
					buf_line[x] = RGBA5551ToRGBA8888(fb_line[x]);
				}
				break;

			case GE_FORMAT_4444:
				for (int x = 0; x < srcwidth; ++x) {
					buf_line[x] = RGBA4444ToRGBA8888(fb_line[x]);
				}
				break;

			default:
				ERROR_LOG_REPORT(G3D, "Software: Unexpected framebuffer format: %d", displayFormat_);
			}
		}

		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)srcwidth, (GLsizei)srcheight, 0, GL_RGBA, GL_UNSIGNED_BYTE, buf);
		texvert_u = 1.0f;

		delete[] buf;
	}

	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

	glUseProgram(program);

	float x, y, w, h;
	CenterRect(&x, &y, &w, &h, 480.0f, 272.0f, dstwidth, dstheight, ROTATION_LOCKED_HORIZONTAL);

	x /= 0.5f * dstwidth;
	y /= 0.5f * dstheight;
	w /= 0.5f * dstwidth;
	h /= 0.5f * dstheight;
	float x2 = x + w;
	float y2 = y + h;
	x -= 1.0f;
	y -= 1.0f;
	x2 -= 1.0f;
	y2 -= 1.0f;

	const GLfloat verts[4][2] = {
		{ x, y }, // Left top
		{ x, y2}, // left bottom
		{ x2, y2}, // right bottom
		{ x2, y}  // right top
	};

	const GLfloat texverts[4][2] = {
		{0, 1},
		{0, 0},
		{texvert_u, 0},
		{texvert_u, 1}
	};

	glstate.arrayBuffer.unbind();
	glstate.elementArrayBuffer.unbind();
	glVertexAttribPointer(attr_pos, 2, GL_FLOAT, GL_FALSE, 0, verts);
	glVertexAttribPointer(attr_tex, 2, GL_FLOAT, GL_FALSE, 0, texverts);
	glEnableVertexAttribArray(attr_pos);
	glEnableVertexAttribArray(attr_tex);
	glUniform1i(uni_tex, 0);
	glActiveTexture(GL_TEXTURE0);
	glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
	glDisableVertexAttribArray(attr_pos);
	glDisableVertexAttribArray(attr_tex);

	glBindTexture(GL_TEXTURE_2D, 0);
}
Ejemplo n.º 8
0
void TransformDrawEngine::ApplyDrawState(int prim) {
	// TODO: All this setup is soon so expensive that we'll need dirty flags, or simply do it in the command writes where we detect dirty by xoring. Silly to do all this work on every drawcall.

	if (gstate_c.textureChanged != TEXCHANGE_UNCHANGED && !gstate.isModeClear() && gstate.isTextureMapEnabled()) {
		textureCache_->SetTexture();
		gstate_c.textureChanged = TEXCHANGE_UNCHANGED;
	}

	// TODO: The top bit of the alpha channel should be written to the stencil bit somehow. This appears to require very expensive multipass rendering :( Alternatively, one could do a
	// single fullscreen pass that converts alpha to stencil (or 2 passes, to set both the 0 and 1 values) very easily.

	// Set blend
	bool wantBlend = !gstate.isModeClear() && gstate.isAlphaBlendEnabled();
	glstate.blend.set(wantBlend);
	if (wantBlend) {
		// This can't be done exactly as there are several PSP blend modes that are impossible to do on OpenGL ES 2.0, and some even on regular OpenGL for desktop.
		// HOWEVER - we should be able to approximate the 2x modes in the shader, although they will clip wrongly.

		// Examples of seen unimplementable blend states:
		// Mortal Kombat Unchained: FixA=0000ff FixB=000080 FuncA=10 FuncB=10

		int blendFuncA  = gstate.getBlendFuncA();
		int blendFuncB  = gstate.getBlendFuncB();
		GEBlendMode blendFuncEq = gstate.getBlendEq();
		if (blendFuncA > GE_SRCBLEND_FIXA) blendFuncA = GE_SRCBLEND_FIXA;
		if (blendFuncB > GE_DSTBLEND_FIXB) blendFuncB = GE_DSTBLEND_FIXB;

		float constantAlpha = 1.0f;
		ReplaceAlphaType replaceAlphaWithStencil = ReplaceAlphaWithStencil();
		if (gstate.isStencilTestEnabled() && replaceAlphaWithStencil == REPLACE_ALPHA_NO) {
			if (ReplaceAlphaWithStencilType() == STENCIL_VALUE_UNIFORM) {
				constantAlpha = (float) gstate.getStencilTestRef() * (1.0f / 255.0f);
			}
		}

		// Shortcut by using GL_ONE where possible, no need to set blendcolor
		GLuint glBlendFuncA = blendFuncA == GE_SRCBLEND_FIXA ? blendColor2Func(gstate.getFixA()) : aLookup[blendFuncA];
		GLuint glBlendFuncB = blendFuncB == GE_DSTBLEND_FIXB ? blendColor2Func(gstate.getFixB()) : bLookup[blendFuncB];

		if (replaceAlphaWithStencil == REPLACE_ALPHA_DUALSOURCE) {
			glBlendFuncA = toDualSource(glBlendFuncA);
			glBlendFuncB = toDualSource(glBlendFuncB);
		}

		if (blendFuncA == GE_SRCBLEND_FIXA || blendFuncB == GE_DSTBLEND_FIXB) {
			Vec3f fixA = Vec3f::FromRGB(gstate.getFixA());
			Vec3f fixB = Vec3f::FromRGB(gstate.getFixB());
			if (glBlendFuncA == GL_INVALID_ENUM && glBlendFuncB != GL_INVALID_ENUM) {
				// Can use blendcolor trivially.
				const float blendColor[4] = {fixA.x, fixA.y, fixA.z, constantAlpha};
				glstate.blendColor.set(blendColor);
				glBlendFuncA = GL_CONSTANT_COLOR;
			} else if (glBlendFuncA != GL_INVALID_ENUM && glBlendFuncB == GL_INVALID_ENUM) {
				// Can use blendcolor trivially.
				const float blendColor[4] = {fixB.x, fixB.y, fixB.z, constantAlpha};
				glstate.blendColor.set(blendColor);
				glBlendFuncB = GL_CONSTANT_COLOR;
			} else if (glBlendFuncA == GL_INVALID_ENUM && glBlendFuncB == GL_INVALID_ENUM) {
				if (blendColorSimilar(fixA, Vec3f::AssignToAll(constantAlpha) - fixB)) {
					glBlendFuncA = GL_CONSTANT_COLOR;
					glBlendFuncB = GL_ONE_MINUS_CONSTANT_COLOR;
					const float blendColor[4] = {fixA.x, fixA.y, fixA.z, constantAlpha};
					glstate.blendColor.set(blendColor);
				} else if (blendColorSimilar(fixA, fixB)) {
					glBlendFuncA = GL_CONSTANT_COLOR;
					glBlendFuncB = GL_CONSTANT_COLOR;
					const float blendColor[4] = {fixA.x, fixA.y, fixA.z, constantAlpha};
					glstate.blendColor.set(blendColor);
				} else {
					static bool didReportBlend = false;
					if (!didReportBlend)
						Reporting::ReportMessage("ERROR INVALID blendcolorstate: FixA=%06x FixB=%06x FuncA=%i FuncB=%i", gstate.getFixA(), gstate.getFixB(), gstate.getBlendFuncA(), gstate.getBlendFuncB());
					didReportBlend = true;

					DEBUG_LOG(G3D, "ERROR INVALID blendcolorstate: FixA=%06x FixB=%06x FuncA=%i FuncB=%i", gstate.getFixA(), gstate.getFixB(), gstate.getBlendFuncA(), gstate.getBlendFuncB());
					// Let's approximate, at least.  Close is better than totally off.
					const bool nearZeroA = blendColorSimilar(fixA, Vec3f::AssignToAll(0.0f), 0.25f);
					const bool nearZeroB = blendColorSimilar(fixB, Vec3f::AssignToAll(0.0f), 0.25f);
					if (nearZeroA || blendColorSimilar(fixA, Vec3f::AssignToAll(1.0f), 0.25f)) {
						glBlendFuncA = nearZeroA ? GL_ZERO : GL_ONE;
						glBlendFuncB = GL_CONSTANT_COLOR;
						const float blendColor[4] = {fixB.x, fixB.y, fixB.z, constantAlpha};
						glstate.blendColor.set(blendColor);
					// We need to pick something.  Let's go with A as the fixed color.
					} else {
						glBlendFuncA = GL_CONSTANT_COLOR;
						glBlendFuncB = nearZeroB ? GL_ZERO : GL_ONE;
						const float blendColor[4] = {fixA.x, fixA.y, fixA.z, constantAlpha};
						glstate.blendColor.set(blendColor);
					}
				}
			} else {
				// We optimized both, but that's probably not necessary, so let's pick one to be constant.
				// For now let's just pick whichever was fixed instead of checking error.
				if (blendFuncA == GE_SRCBLEND_FIXA) {
					glBlendFuncA = GL_CONSTANT_COLOR;
					const float blendColor[4] = {fixA.x, fixA.y, fixA.z, constantAlpha};
					glstate.blendColor.set(blendColor);
				} else {
					glBlendFuncB = GL_CONSTANT_COLOR;
					const float blendColor[4] = {fixB.x, fixB.y, fixB.z, constantAlpha};
					glstate.blendColor.set(blendColor);
				}
			}
		} else if (constantAlpha < 1.0f) {
			const float blendColor[4] = {1.0f, 1.0f, 1.0f, constantAlpha};
			glstate.blendColor.set(blendColor);
		}

		// Some Android devices (especially Mali, it seems) composite badly if there's alpha in the backbuffer.
		// So in non-buffered rendering, we will simply consider the dest alpha to be zero in blending equations.
#ifdef ANDROID
		if (g_Config.iRenderingMode == FB_NON_BUFFERED_MODE) {
			if (glBlendFuncA == GL_DST_ALPHA) glBlendFuncA = GL_ZERO;
			if (glBlendFuncB == GL_DST_ALPHA) glBlendFuncB = GL_ZERO;
			if (glBlendFuncA == GL_ONE_MINUS_DST_ALPHA) glBlendFuncA = GL_ONE;
			if (glBlendFuncB == GL_ONE_MINUS_DST_ALPHA) glBlendFuncB = GL_ONE;
		}
#endif

		// At this point, through all paths above, glBlendFuncA and glBlendFuncB will be set right somehow.

		// The stencil-to-alpha in fragment shader doesn't apply here (blending is enabled), and we shouldn't
		// do any blending in the alpha channel as that doesn't seem to happen on PSP. So lacking a better option,
		// the only value we can set alpha to here without multipass and dual source alpha is zero (by setting
		// the factors to zero). So let's do that.
		if (replaceAlphaWithStencil != REPLACE_ALPHA_NO) {
			// Let the fragment shader take care of it.
			glstate.blendFuncSeparate.set(glBlendFuncA, glBlendFuncB, GL_ONE, GL_ZERO);
		} else if (gstate.isStencilTestEnabled()) {
			switch (ReplaceAlphaWithStencilType()) {
			case STENCIL_VALUE_KEEP:
				glstate.blendFuncSeparate.set(glBlendFuncA, glBlendFuncB, GL_ZERO, GL_ONE);
				break;
			case STENCIL_VALUE_ONE:
				// This won't give one but it's our best shot...
				glstate.blendFuncSeparate.set(glBlendFuncA, glBlendFuncB, GL_ONE, GL_ONE);
				break;
			case STENCIL_VALUE_ZERO:
				glstate.blendFuncSeparate.set(glBlendFuncA, glBlendFuncB, GL_ZERO, GL_ZERO);
				break;
			case STENCIL_VALUE_UNIFORM:
				// This won't give a correct value (it multiplies) but it may be better than random values.
				glstate.blendFuncSeparate.set(glBlendFuncA, glBlendFuncB, GL_CONSTANT_ALPHA, GL_ZERO);
				break;
			case STENCIL_VALUE_UNKNOWN:
				// For now, let's err at zero.  This is INVERT or INCR/DECR.
				glstate.blendFuncSeparate.set(glBlendFuncA, glBlendFuncB, GL_ZERO, GL_ZERO);
				break;
			}
		} else {
			// Retain the existing value when stencil testing is off.
			glstate.blendFuncSeparate.set(glBlendFuncA, glBlendFuncB, GL_ZERO, GL_ONE);
		}

		if (blendFuncEq == GE_BLENDMODE_ABSDIFF) {
			WARN_LOG_REPORT_ONCE(blendAbsdiff, G3D, "Unsupported absdiff blend mode");
		}

		if (((blendFuncEq >= GE_BLENDMODE_MIN) && gl_extensions.EXT_blend_minmax) || gl_extensions.GLES3) {
			if (blendFuncEq == GE_BLENDMODE_ABSDIFF && gl_extensions.EXT_shader_framebuffer_fetch) {
				// Handle GE_BLENDMODE_ABSDIFF in fragment shader and turn off regular alpha blending here.
				glstate.blend.set(false);
			} else {
				glstate.blendEquation.set(eqLookup[blendFuncEq]);
			}
		} else {
			glstate.blendEquation.set(eqLookupNoMinMax[blendFuncEq]);
		}
	}

	bool alwaysDepthWrite = g_Config.bAlwaysDepthWrite;
	bool enableStencilTest = !g_Config.bDisableStencilTest;

	// Dither
	if (gstate.isDitherEnabled()) {
		glstate.dither.enable();
		glstate.dither.set(GL_TRUE);
	} else
		glstate.dither.disable();

	if (gstate.isModeClear()) {
#if !defined(USING_GLES2)
		// Logic Ops
		glstate.colorLogicOp.disable();
#endif
		// Culling
		glstate.cullFace.disable();

		// Depth Test
		glstate.depthTest.enable();
		glstate.depthFunc.set(GL_ALWAYS);
		glstate.depthWrite.set(gstate.isClearModeDepthMask() || alwaysDepthWrite ? GL_TRUE : GL_FALSE);
		if (gstate.isClearModeDepthMask() || alwaysDepthWrite) {
			framebufferManager_->SetDepthUpdated();
		}

		// Color Test
		bool colorMask = gstate.isClearModeColorMask();
		bool alphaMask = gstate.isClearModeAlphaMask();
		glstate.colorMask.set(colorMask, colorMask, colorMask, alphaMask);

		// Stencil Test
		if (alphaMask && enableStencilTest) {
			glstate.stencilTest.enable();
			glstate.stencilOp.set(GL_REPLACE, GL_REPLACE, GL_REPLACE);
			// TODO: In clear mode, the stencil value is set to the alpha value of the vertex.
			// A normal clear will be 2 points, the second point has the color.
			// We should set "ref" to that value instead of 0.
			// In case of clear rectangles, we set it again once we know what the color is.
			glstate.stencilFunc.set(GL_ALWAYS, 255, 0xFF);
		} else {
			glstate.stencilTest.disable();
		}
	} else {
#if !defined(USING_GLES2)
		// Logic Ops
		if (gstate.isLogicOpEnabled() && gstate.getLogicOp() != GE_LOGIC_COPY) {
			glstate.colorLogicOp.enable();
			glstate.logicOp.set(logicOps[gstate.getLogicOp()]);
		} else {
			glstate.colorLogicOp.disable();
		}
#endif
		// Set cull
		bool cullEnabled = !gstate.isModeThrough() && prim != GE_PRIM_RECTANGLES && gstate.isCullEnabled();
		if (cullEnabled) {
			glstate.cullFace.enable();
			glstate.cullFaceMode.set(cullingMode[gstate.getCullMode()]);
		} else {
			glstate.cullFace.disable();
		}

		// Depth Test
		if (gstate.isDepthTestEnabled()) {
			glstate.depthTest.enable();
			glstate.depthFunc.set(ztests[gstate.getDepthTestFunction()]);
			glstate.depthWrite.set(gstate.isDepthWriteEnabled() || alwaysDepthWrite ? GL_TRUE : GL_FALSE);
			framebufferManager_->SetDepthUpdated();
		} else {
			glstate.depthTest.disable();
		}

		// PSP color/alpha mask is per bit but we can only support per byte.
		// But let's do that, at least. And let's try a threshold.
		bool rmask = (gstate.pmskc & 0xFF) < 128;
		bool gmask = ((gstate.pmskc >> 8) & 0xFF) < 128;
		bool bmask = ((gstate.pmskc >> 16) & 0xFF) < 128;
		bool amask = (gstate.pmska & 0xFF) < 128;

		// Let's not write to alpha if stencil isn't enabled.
		if (!gstate.isStencilTestEnabled()) {
			amask = false;
		} else {
			// If the stencil type is set to KEEP, we shouldn't write to the stencil/alpha channel.
			if (ReplaceAlphaWithStencilType() == STENCIL_VALUE_KEEP) {
				amask = false;
			}
		}
		if (g_Config.bAlphaMaskHack) {
			amask = true;  // Yes, this makes no sense, but it "fixes" the 3rd Birthday by popular demand.
		}

		glstate.colorMask.set(rmask, gmask, bmask, amask);

		// Stencil Test
		if (gstate.isStencilTestEnabled() && enableStencilTest) {
			glstate.stencilTest.enable();
			glstate.stencilFunc.set(ztests[gstate.getStencilTestFunction()],
				gstate.getStencilTestRef(),
				gstate.getStencilTestMask());
			glstate.stencilOp.set(stencilOps[gstate.getStencilOpSFail()],  // stencil fail
				stencilOps[gstate.getStencilOpZFail()],  // depth fail
				stencilOps[gstate.getStencilOpZPass()]); // depth pass
		} else {
			glstate.stencilTest.disable();
		}
	}

	float renderWidthFactor, renderHeightFactor;
	float renderWidth, renderHeight;
	float renderX, renderY;
	bool useBufferedRendering = g_Config.iRenderingMode != FB_NON_BUFFERED_MODE;
	if (useBufferedRendering) {
		renderX = 0.0f;
		renderY = 0.0f;
		renderWidth = framebufferManager_->GetRenderWidth();
		renderHeight = framebufferManager_->GetRenderHeight();
	} else {
		// TODO: Aspect-ratio aware and centered
		float pixelW = PSP_CoreParameter().pixelWidth;
		float pixelH = PSP_CoreParameter().pixelHeight;
		CenterRect(&renderX, &renderY, &renderWidth, &renderHeight, 480, 272, pixelW, pixelH);
	}

	renderWidthFactor = (float)renderWidth / framebufferManager_->GetTargetWidth();
	renderHeightFactor = (float)renderHeight / framebufferManager_->GetTargetHeight();

	bool throughmode = gstate.isModeThrough();

	// Scissor
	int scissorX1 = gstate.getScissorX1();
	int scissorY1 = gstate.getScissorY1();
	int scissorX2 = gstate.getScissorX2() + 1;
	int scissorY2 = gstate.getScissorY2() + 1;

	// This is a bit of a hack as the render buffer isn't always that size
	if (scissorX1 == 0 && scissorY1 == 0 
		&& scissorX2 >= (int) gstate_c.curRTWidth
		&& scissorY2 >= (int) gstate_c.curRTHeight) {
		glstate.scissorTest.disable();
	} else {
		glstate.scissorTest.enable();
		glstate.scissorRect.set(
			renderX + scissorX1 * renderWidthFactor,
			renderY + renderHeight - (scissorY2 * renderHeightFactor),
			(scissorX2 - scissorX1) * renderWidthFactor,
			(scissorY2 - scissorY1) * renderHeightFactor);
	}

	/*
	int regionX1 = gstate.region1 & 0x3FF;
	int regionY1 = (gstate.region1 >> 10) & 0x3FF;
	int regionX2 = (gstate.region2 & 0x3FF) + 1;
	int regionY2 = ((gstate.region2 >> 10) & 0x3FF) + 1;
	*/
	int regionX1 = 0;
	int regionY1 = 0;
	int regionX2 = gstate_c.curRTWidth;
	int regionY2 = gstate_c.curRTHeight;

	float offsetX = gstate.getOffsetX();
	float offsetY = gstate.getOffsetY();

	if (throughmode) {
		// No viewport transform here. Let's experiment with using region.
		glstate.viewport.set(
			renderX + (0 + regionX1) * renderWidthFactor, 
			renderY + (0 - regionY1) * renderHeightFactor,
			(regionX2 - regionX1) * renderWidthFactor,
			(regionY2 - regionY1) * renderHeightFactor);
		glstate.depthRange.set(0.0f, 1.0f);
	} else {
		// These we can turn into a glViewport call, offset by offsetX and offsetY. Math after.
		float vpXa = getFloat24(gstate.viewportx1);
		float vpXb = getFloat24(gstate.viewportx2);
		float vpYa = getFloat24(gstate.viewporty1);
		float vpYb = getFloat24(gstate.viewporty2);

		// The viewport transform appears to go like this: 
		// Xscreen = -offsetX + vpXb + vpXa * Xview
		// Yscreen = -offsetY + vpYb + vpYa * Yview
		// Zscreen = vpZb + vpZa * Zview

		// This means that to get the analogue glViewport we must:
		float vpX0 = vpXb - offsetX - vpXa;
		float vpY0 = vpYb - offsetY + vpYa;   // Need to account for sign of Y
		gstate_c.vpWidth = vpXa * 2.0f;
		gstate_c.vpHeight = -vpYa * 2.0f;

		float vpWidth = fabsf(gstate_c.vpWidth);
		float vpHeight = fabsf(gstate_c.vpHeight);

		vpX0 *= renderWidthFactor;
		vpY0 *= renderHeightFactor;
		vpWidth *= renderWidthFactor;
		vpHeight *= renderHeightFactor;

		vpX0 = (vpXb - offsetX - fabsf(vpXa)) * renderWidthFactor;
		// Flip vpY0 to match the OpenGL coordinate system.
		vpY0 = renderHeight - (vpYb - offsetY + fabsf(vpYa)) * renderHeightFactor;		
		
		glstate.viewport.set(vpX0 + renderX, vpY0 + renderY, vpWidth, vpHeight);
		// Sadly, as glViewport takes integers, we will not be able to support sub pixel offsets this way. But meh.
		// shaderManager_->DirtyUniform(DIRTY_PROJMATRIX);

		float zScale = getFloat24(gstate.viewportz1) / 65535.0f;
		float zOff = getFloat24(gstate.viewportz2) / 65535.0f;
		float depthRangeMin = zOff - zScale;
		float depthRangeMax = zOff + zScale;
		glstate.depthRange.set(depthRangeMin, depthRangeMax);
	}
}
Ejemplo n.º 9
0
void CTabItem_MainTabBn::Paint(CDC* pDC)
{
	//CRect		rtDraw(GetRectInbar());
	//CBufferDC	bufDC(pDC->GetSafeHdc(), rtDraw);

	//CBrush brush(RGB(200, 200, 200));
	//bufDC.FillRect(&rtDraw, &brush);

	//int iOldMode = pDC->GetBkMode();
	//bufDC.SetBkMode(TRANSPARENT);
	//bufDC.DrawText(m_strCaption, rtDraw, DT_VCENTER | DT_SINGLELINE | DT_CENTER);
	//bufDC.SetBkMode(iOldMode);
	//DrawRound(pDC->GetSafeHdc(), rtDraw, 3);

	/*CFontDC font(pDC->GetSafeHdc(), _T("Wingdings 3"));
	font = 12;*/

	CRect	rect;

	rect = GetRect();
	rect.right -= m_iItemGap;

	//if (m_bActive)
	//{
	//	DrawActiveBk(pDC, rect);
	//}
	//else
	//{   
	//	if(IsHover())
	//	{
	//		DrawHover(pDC, rect);
	//	}
	//	else
	//	{
	//		DrawInactiveBk(pDC, rect);
	//	}
	//}

	CSize	sizeIcon;
	CRect	rtIcon;
	CFaceManager::GetInstance()->GetImageSize(II_MAINTABMORE_N, sizeIcon);
	CenterRect(&rtIcon, rect, sizeIcon);
	rtIcon.OffsetRect(0, 3);

	if (IsHover())
	{
		CFaceManager::GetInstance()->DrawImageBar(IBI_MAINBTN_H, pDC->m_hDC, rect);
		CFaceManager::GetInstance()->DrawImage(II_MAINTABMORE_H, pDC->m_hDC, rtIcon);
	}
	else
	{
		CFaceManager::GetInstance()->DrawImageBar(IBI_MAINBTN_N, pDC->m_hDC, rect);
		CFaceManager::GetInstance()->DrawImage(II_MAINTABMORE_N, pDC->m_hDC, rtIcon);
	}

	
	//{
	//	CPenDC	penDC(pDC->GetSafeHdc(), RGB(255, 255, 255));
	//	DrawTriangle(pDC, rect);
	//}
}
Ejemplo n.º 10
0
void TopWindow::Open(Ctrl *owner)
{
	LLOG("TopWindow::Open");
	GuiLock __; 
	if(dokeys && (!GUI_AKD_Conservative() || GetAccessKeysDeep() <= 1))
		DistributeAccessKeys();
	USRLOG("   OPEN " + Desc(this));
	LLOG("OPEN " << Name() << " owner: " << UPP::Name(owner));
	IgnoreMouseUp();
	bool weplace = owner && center == 1 || center == 2 || !GetRect().IsEmpty();
	if(fullscreen)
		SetRect(0, 0, Xwidth, Xheight);
	else
		CenterRect(owner);
	LLOG("Open NextRequest " << NextRequest(Xdisplay));
	Create(owner, false, false);
	XSetWMProperties (Xdisplay, GetWindow(), NULL, NULL, NULL, 0, NULL, NULL, NULL);
	xminsize.cx = xmaxsize.cx = Null;
	title2.Clear();
	if(!weplace) {
		LLOG("SyncCaption");
		SyncCaption();
	}
	LLOG("SyncSizeHints");
	size_hints->flags = 0;
	SyncSizeHints();
	Rect r = GetRect();
	size_hints->x = r.left;
	size_hints->y = r.top;
	size_hints->width = r.Width();
	size_hints->height = r.Height();
	size_hints->win_gravity = StaticGravity;
	size_hints->flags |= PPosition|PSize|PWinGravity;
	if(owner) {
		ASSERT(owner->IsOpen());
		LLOG("XSetTransientForHint");
		XSetTransientForHint(Xdisplay, GetWindow(), owner->GetWindow());
	}
	LLOG("XSetWMNormalHints");
	XSetWMNormalHints(Xdisplay, GetWindow(), size_hints);
	Atom protocols[3];
	protocols[0] = XAtom("WM_DELETE_WINDOW");
	protocols[1] = XAtom("WM_TAKE_FOCUS");
	protocols[2] = XAtom("_NET_WM_PING");
	LLOG("XSetWMProtocols");
	XSetWMProtocols(Xdisplay, GetWindow(), protocols, 3);
	String x = GetExeTitle().ToString();
	const char *progname = ~x;
	class_hint->res_name = (char *)progname;
	class_hint->res_class = (char *)progname;
	XSetClassHint(Xdisplay, GetWindow(), class_hint);
	LLOG("WndShow(" << visible << ")");
	WndShow(visible);
	if(visible) {
		XEvent e;
		LLOG("XWindowEvent");
		XWindowEvent(Xdisplay, top->window, VisibilityChangeMask, &e);
		ignoretakefocus = true;
		SetTimeCallback(500, THISBACK(EndIgnoreTakeFocus));
		LLOG("SetWndFocus");
		SetWndFocus();
		for(int i = 0; i < 50; i++) {
			// X11 tries to move our window, so ignore the first set of ConfigureNotify
			// and move the window into position after FocusIn - but not if we want WM to
			// place the window
			if(weplace)
				while(XCheckTypedWindowEvent(Xdisplay, top->window, ConfigureNotify, &e)) {
					if(e.xconfigure.window != top->window)
						ProcessEvent(&e);
				}	
			if(XCheckTypedWindowEvent(Xdisplay, top->window, FocusIn, &e)) {
				ProcessEvent(&e);
				if(e.xfocus.window == top->window)
					break;
			}
			Sleep(10);
		}
	}
	if(weplace) {
		WndSetPos(GetRect());
		LLOG("SyncCaption");
		SyncCaption();
	}
	LLOG(">Open NextRequest " << NextRequest(Xdisplay));
	LLOG(">OPENED " << Name());
	PlaceFocus();
	StateH(OPEN);
	Vector<int> fe = GetPropertyInts(top->window, XAtom("_NET_FRAME_EXTENTS"));
	if(fe.GetCount() >= 4 &&
	   fe[0] >= 0 && fe[0] <= 16 && fe[1] >= 0 && fe[1] <= 16 && //fluxbox returns wrong numbers - quick&dirty workaround
	   fe[2] >= 0 && fe[2] <= 64 && fe[3] >= 0 && fe[3] <= 48)
	{
		GuiLock __;
		windowFrameMargin.left = max(windowFrameMargin.left, fe[0]);
		windowFrameMargin.right = max(windowFrameMargin.right, fe[1]);
		windowFrameMargin.top = max(windowFrameMargin.top, fe[2]);
		windowFrameMargin.bottom = max(windowFrameMargin.bottom, fe[3]);
	}
	if(IsOpen() && top)
		top->owner = owner;

	long curr_pid = getpid();

	static Window wm_client_leader;
	ONCELOCK {
		wm_client_leader = XCreateSimpleWindow(Xdisplay, Xroot, 0, 0, 1, 1, 0, 0, 0);
		XChangeProperty(Xdisplay, wm_client_leader, XAtom("WM_CLIENT_LEADER"),
		                XA_WINDOW, 32, PropModeReplace, (byte *)&wm_client_leader, 1);
		XChangeProperty(Xdisplay, wm_client_leader, XAtom("_NET_WM_PID"), XA_CARDINAL, 32,
		                PropModeReplace, (byte *) &curr_pid, 1);
	}

	Window win = GetWindow();
	XChangeProperty(Xdisplay, win, XAtom("_NET_WM_PID"), XA_CARDINAL, 32,
	                PropModeReplace, (byte *) &curr_pid, 1);
	XChangeProperty(Xdisplay, win, XAtom("WM_CLIENT_LEADER"),
	                XA_WINDOW, 32, PropModeReplace, (byte *)&wm_client_leader, 1);

	int version = 5;
	XChangeProperty(Xdisplay, win, XAtom("XdndAware"), XA_ATOM, 32,
					0, (byte *)&version, 1);

	SyncState();
	FixIcons();
}
Ejemplo n.º 11
0
void TransformDrawEngine::ApplyDrawState(int prim) {
	// TODO: All this setup is soon so expensive that we'll need dirty flags, or simply do it in the command writes where we detect dirty by xoring. Silly to do all this work on every drawcall.

	if (gstate_c.textureChanged) {
		if (gstate.isTextureMapEnabled()) {
			textureCache_->SetTexture();
		}
		gstate_c.textureChanged = false;
	}

	// TODO: The top bit of the alpha channel should be written to the stencil bit somehow. This appears to require very expensive multipass rendering :( Alternatively, one could do a
	// single fullscreen pass that converts alpha to stencil (or 2 passes, to set both the 0 and 1 values) very easily.

	// Set blend
	bool wantBlend = !gstate.isModeClear() && gstate.isAlphaBlendEnabled();
	glstate.blend.set(wantBlend);
	if (wantBlend) {
		// This can't be done exactly as there are several PSP blend modes that are impossible to do on OpenGL ES 2.0, and some even on regular OpenGL for desktop.
		// HOWEVER - we should be able to approximate the 2x modes in the shader, although they will clip wrongly.

		// Examples of seen unimplementable blend states:
		// Mortal Kombat Unchained: FixA=0000ff FixB=000080 FuncA=10 FuncB=10

		int blendFuncA  = gstate.getBlendFuncA();
		int blendFuncB  = gstate.getBlendFuncB();
		int blendFuncEq = gstate.getBlendEq();
		if (blendFuncA > GE_SRCBLEND_FIXA) blendFuncA = GE_SRCBLEND_FIXA;
		if (blendFuncB > GE_DSTBLEND_FIXB) blendFuncB = GE_DSTBLEND_FIXB;

		// Shortcut by using GL_ONE where possible, no need to set blendcolor
		GLuint glBlendFuncA = blendFuncA == GE_SRCBLEND_FIXA ? blendColor2Func(gstate.getFixA()) : aLookup[blendFuncA];
		GLuint glBlendFuncB = blendFuncB == GE_DSTBLEND_FIXB ? blendColor2Func(gstate.getFixB()) : bLookup[blendFuncB];
		if (blendFuncA == GE_SRCBLEND_FIXA || blendFuncB == GE_DSTBLEND_FIXB) {
			Vec3f fixA = Vec3f::FromRGB(gstate.getFixA());
			Vec3f fixB = Vec3f::FromRGB(gstate.getFixB());
			if (glBlendFuncA == GL_INVALID_ENUM && glBlendFuncB != GL_INVALID_ENUM) {
				// Can use blendcolor trivially.
				const float blendColor[4] = {fixA.x, fixA.y, fixA.z, 1.0f};
				glstate.blendColor.set(blendColor);
				glBlendFuncA = GL_CONSTANT_COLOR;
			} else if (glBlendFuncA != GL_INVALID_ENUM && glBlendFuncB == GL_INVALID_ENUM) {
				// Can use blendcolor trivially.
				const float blendColor[4] = {fixB.x, fixB.y, fixB.z, 1.0f};
				glstate.blendColor.set(blendColor);
				glBlendFuncB = GL_CONSTANT_COLOR;
			} else if (glBlendFuncA == GL_INVALID_ENUM && glBlendFuncB == GL_INVALID_ENUM) {
				if (blendColorSimilar(fixA, Vec3f::AssignToAll(1.0f) - fixB)) {
					glBlendFuncA = GL_CONSTANT_COLOR;
					glBlendFuncB = GL_ONE_MINUS_CONSTANT_COLOR;
					const float blendColor[4] = {fixA.x, fixA.y, fixA.z, 1.0f};
					glstate.blendColor.set(blendColor);
				} else if (blendColorSimilar(fixA, fixB)) {
					glBlendFuncA = GL_CONSTANT_COLOR;
					glBlendFuncB = GL_CONSTANT_COLOR;
					const float blendColor[4] = {fixA.x, fixA.y, fixA.z, 1.0f};
					glstate.blendColor.set(blendColor);
				} else {
					static bool didReportBlend = false;
					if (!didReportBlend)
						Reporting::ReportMessage("ERROR INVALID blendcolorstate: FixA=%06x FixB=%06x FuncA=%i FuncB=%i", gstate.getFixA(), gstate.getFixB(), gstate.getBlendFuncA(), gstate.getBlendFuncB());
					didReportBlend = true;

					DEBUG_LOG(HLE, "ERROR INVALID blendcolorstate: FixA=%06x FixB=%06x FuncA=%i FuncB=%i", gstate.getFixA(), gstate.getFixB(), gstate.getBlendFuncA(), gstate.getBlendFuncB());
					// Let's approximate, at least.  Close is better than totally off.
					const bool nearZeroA = blendColorSimilar(fixA, Vec3f::AssignToAll(0.0f), 0.25f);
					const bool nearZeroB = blendColorSimilar(fixB, Vec3f::AssignToAll(0.0f), 0.25f);
					if (nearZeroA || blendColorSimilar(fixA, Vec3f::AssignToAll(1.0f), 0.25f)) {
						glBlendFuncA = nearZeroA ? GL_ZERO : GL_ONE;
						glBlendFuncB = GL_CONSTANT_COLOR;
						const float blendColor[4] = {fixB.x, fixB.y, fixB.z, 1.0f};
						glstate.blendColor.set(blendColor);
					// We need to pick something.  Let's go with A as the fixed color.
					} else {
						glBlendFuncA = GL_CONSTANT_COLOR;
						glBlendFuncB = nearZeroB ? GL_ZERO : GL_ONE;
						const float blendColor[4] = {fixA.x, fixA.y, fixA.z, 1.0f};
						glstate.blendColor.set(blendColor);
					}
				}
			}
		}

		// At this point, through all paths above, glBlendFuncA and glBlendFuncB will be set right somehow.
		if (!gstate.isStencilTestEnabled()) {
			// Fixes some Persona 2 issues, may be correct? (that is, don't change dest alpha at all if blending)
			// If this doesn't break anything else, it's likely to be right.
			// I guess an alternative solution would be to simply disable alpha writes if alpha blending is enabled.
			glstate.blendFuncSeparate.set(glBlendFuncA, glBlendFuncB, GL_ZERO, glBlendFuncB);
		} else {
			glstate.blendFuncSeparate.set(glBlendFuncA, glBlendFuncB, glBlendFuncA, glBlendFuncB);
		}
		glstate.blendEquation.set(eqLookup[blendFuncEq]);
	}

	// Dither
	if (gstate.isDitherEnabled()) {
		glstate.dither.enable();
		glstate.dither.set(GL_TRUE);
	} else
		glstate.dither.disable();

	if (gstate.isModeClear()) {

#if !defined(USING_GLES2)
		// Logic Ops
		glstate.colorLogicOp.disable();
#endif
		// Culling 
		glstate.cullFace.disable();
		
		// Depth Test
		glstate.depthTest.enable();
		glstate.depthFunc.set(GL_ALWAYS);
		glstate.depthWrite.set(gstate.isClearModeDepthWriteEnabled() ? GL_TRUE : GL_FALSE);

		// Color Test
		bool colorMask = gstate.isClearModeColorMask();
		bool alphaMask = gstate.isClearModeAlphaMask();
		glstate.colorMask.set(colorMask, colorMask, colorMask, alphaMask);

		// Stencil Test
		if (alphaMask) {
			glstate.stencilTest.enable();
			glstate.stencilOp.set(GL_REPLACE, GL_REPLACE, GL_REPLACE);
			glstate.stencilFunc.set(GL_ALWAYS, 0, 0xFF);
		} else 
			glstate.stencilTest.disable();
		
	} else {

#if !defined(USING_GLES2)
		// Logic Ops
		if (gstate.isLogicOpEnabled() && gstate.getLogicOp() != GE_LOGIC_COPY) {
			glstate.colorLogicOp.enable();
			glstate.logicOp.set(logicOps[gstate.getLogicOp()]);
		} else
			glstate.colorLogicOp.disable();
#endif		
		// Set cull
		bool cullEnabled = !gstate.isModeThrough() && prim != GE_PRIM_RECTANGLES && gstate.isCullEnabled();
		if (cullEnabled) {
			glstate.cullFace.enable();
			glstate.cullFaceMode.set(cullingMode[gstate.getCullMode()]);
		} else
			glstate.cullFace.disable();
	
		// Depth Test
		if (gstate.isDepthTestEnabled()) {
			glstate.depthTest.enable();
			glstate.depthFunc.set(ztests[gstate.getDepthTestFunction()]);
			glstate.depthWrite.set(gstate.isDepthWriteEnabled() ? GL_TRUE : GL_FALSE);
		} else 
			glstate.depthTest.disable();
		
		// PSP color/alpha mask is per bit but we can only support per byte.
		// But let's do that, at least. And let's try a threshold.
		bool rmask = (gstate.pmskc & 0xFF) < 128;
		bool gmask = ((gstate.pmskc >> 8) & 0xFF) < 128;
		bool bmask = ((gstate.pmskc >> 16) & 0xFF) < 128;
		bool amask = (gstate.pmska & 0xFF) < 128;
		glstate.colorMask.set(rmask, gmask, bmask, amask);
		
		// Stencil Test
		if (gstate.isStencilTestEnabled()) {
			glstate.stencilTest.enable();
			glstate.stencilFunc.set(ztests[gstate.getStencilTestFunction()],
				gstate.getStencilTestRef(),
				gstate.getStencilTestMask());
			glstate.stencilOp.set(stencilOps[gstate.getStencilOpSFail()],  // stencil fail
				stencilOps[gstate.getStencilOpZFail()],  // depth fail
				stencilOps[gstate.getStencilOpZPass()]); // depth pass
		} else 
			glstate.stencilTest.disable();
		
	}

	float renderWidthFactor, renderHeightFactor;
	float renderWidth, renderHeight;
	float renderX, renderY;
	bool useBufferedRendering = g_Config.iRenderingMode != FB_NON_BUFFERED_MODE;
	if (useBufferedRendering) {
		renderX = 0.0f;
		renderY = 0.0f;
		renderWidth = framebufferManager_->GetRenderWidth();
		renderHeight = framebufferManager_->GetRenderHeight();
		renderWidthFactor = (float)renderWidth / framebufferManager_->GetTargetWidth();
		renderHeightFactor = (float)renderHeight / framebufferManager_->GetTargetHeight();
	} else {
		// TODO: Aspect-ratio aware and centered
		float pixelW = PSP_CoreParameter().pixelWidth;
		float pixelH = PSP_CoreParameter().pixelHeight;
		CenterRect(&renderX, &renderY, &renderWidth, &renderHeight, 480, 272, pixelW, pixelH);
		renderWidthFactor = renderWidth / 480.0f;
		renderHeightFactor = renderHeight / 272.0f;
	}

	bool throughmode = gstate.isModeThrough();

	// Scissor
	int scissorX1 = gstate.getScissorX1();
	int scissorY1 = gstate.getScissorY1();
	int scissorX2 = gstate.getScissorX2() + 1;
	int scissorY2 = gstate.getScissorY2() + 1;

	// This is a bit of a hack as the render buffer isn't always that size
	if (scissorX1 == 0 && scissorY1 == 0 
		&& scissorX2 >= (int) gstate_c.curRTWidth
		&& scissorY2 >= (int) gstate_c.curRTHeight) {
		glstate.scissorTest.disable();
	} else {
		glstate.scissorTest.enable();
		glstate.scissorRect.set(
			renderX + scissorX1 * renderWidthFactor,
			renderY + renderHeight - (scissorY2 * renderHeightFactor),
			(scissorX2 - scissorX1) * renderWidthFactor,
			(scissorY2 - scissorY1) * renderHeightFactor);
	}

	/*
	int regionX1 = gstate.region1 & 0x3FF;
	int regionY1 = (gstate.region1 >> 10) & 0x3FF;
	int regionX2 = (gstate.region2 & 0x3FF) + 1;
	int regionY2 = ((gstate.region2 >> 10) & 0x3FF) + 1;
	*/
	int regionX1 = 0;
	int regionY1 = 0;
	int regionX2 = gstate_c.curRTWidth;
	int regionY2 = gstate_c.curRTHeight;

	float offsetX = (float)(gstate.offsetx & 0xFFFF) / 16.0f;
	float offsetY = (float)(gstate.offsety & 0xFFFF) / 16.0f;

	if (throughmode) {
		// No viewport transform here. Let's experiment with using region.
		glstate.viewport.set(
			renderX + (0 + regionX1) * renderWidthFactor, 
			renderY + (0 - regionY1) * renderHeightFactor,
			(regionX2 - regionX1) * renderWidthFactor,
			(regionY2 - regionY1) * renderHeightFactor);
		glstate.depthRange.set(0.0f, 1.0f);
	} else {
		// These we can turn into a glViewport call, offset by offsetX and offsetY. Math after.
		float vpXa = getFloat24(gstate.viewportx1);
		float vpXb = getFloat24(gstate.viewportx2);
		float vpYa = getFloat24(gstate.viewporty1);
		float vpYb = getFloat24(gstate.viewporty2);

		// The viewport transform appears to go like this: 
		// Xscreen = -offsetX + vpXb + vpXa * Xview
		// Yscreen = -offsetY + vpYb + vpYa * Yview
		// Zscreen = vpZb + vpZa * Zview

		// This means that to get the analogue glViewport we must:
		float vpX0 = vpXb - offsetX - vpXa;
		float vpY0 = vpYb - offsetY + vpYa;   // Need to account for sign of Y
		gstate_c.vpWidth = vpXa * 2.0f;
		gstate_c.vpHeight = -vpYa * 2.0f;

		float vpWidth = fabsf(gstate_c.vpWidth);
		float vpHeight = fabsf(gstate_c.vpHeight);

		vpX0 *= renderWidthFactor;
		vpY0 *= renderHeightFactor;
		vpWidth *= renderWidthFactor;
		vpHeight *= renderHeightFactor;

		vpX0 = (vpXb - offsetX - fabsf(vpXa)) * renderWidthFactor;
		// Flip vpY0 to match the OpenGL coordinate system.
		vpY0 = renderHeight - (vpYb - offsetY + fabsf(vpYa)) * renderHeightFactor;		
		
		glstate.viewport.set(vpX0 + renderX, vpY0 + renderY, vpWidth, vpHeight);
		// Sadly, as glViewport takes integers, we will not be able to support sub pixel offsets this way. But meh.
		// shaderManager_->DirtyUniform(DIRTY_PROJMATRIX);

		float zScale = getFloat24(gstate.viewportz1) / 65535.0f;
		float zOff = getFloat24(gstate.viewportz2) / 65535.0f;
		float depthRangeMin = zOff - zScale;
		float depthRangeMax = zOff + zScale;
		glstate.depthRange.set(depthRangeMin, depthRangeMax);
	}
}
Ejemplo n.º 12
0
void CWebWindow::OnWebBeforeNavigate2(LPDISPATCH pDisp, VARIANT FAR* URL, VARIANT FAR* Flags, VARIANT FAR* TargetFrameName, VARIANT FAR* PostData, VARIANT FAR* Headers, BOOL FAR* Cancel)
{
	m_bNavigateStarted = TRUE;
	if(!m_bChild && m_bFileDownload)
	{
		PostMessage(WM_CLOSE);
		return;
	}
	if(!m_bCatchNavigate)
	{
		m_bCatchNavigate = TRUE;
		return;
	}
	
	long cx = 0, cy = 0, tearoff = -1, fullscreen = 0;
	GetTargetRect(pDisp, cx, cy, tearoff, fullscreen);
	
	/*if(IsTVFileType(URL->bstrVal))
	{
		CDlgTV *pDlg = new CDlgTV;
		if(pDlg)
		{
			pDlg->CreateAutoKiller(URL->bstrVal, GetDesktopWindow(), cx, cy);
			*Cancel = VARIANT_TRUE;
		}

	}
	else*/ if(tearoff == 0)
	{
		m_bCatchWindowOpen = FALSE;
		*Cancel = TRUE;
		CString str(URL->bstrVal);
		if(S_OK != ::NavigateNewWindow(pDisp, str))
			ShellExecute(::GetDesktopWindow(), _T("open"), str, NULL, NULL, SW_SHOWDEFAULT);
	}
	else if(tearoff == 1)
	{
		CWebWindow *pWnd = new CWebWindow;

		CRect winRect;
		GetWindowRect(&winRect);
			
		pWnd->CreateAutoKiller(_T("/Browser/Common/skin.xml"), GetMessageParent(), GetDesktopWindow(), winRect.left-100, winRect.top+20, cx, cy, NULL, CString(URL->bstrVal), FALSE, FALSE, TRUE, 0, FALSE, TRUE, fullscreen!=0);
		*Cancel = VARIANT_TRUE;
	}
	else if(!m_bChild && m_strURL.IsEmpty()) // if called window.open()
	{
		CRect r = m_rTarget;
		if(!m_bSizeSet)
		{
			r.right = m_rBrowser.Width();
			r.bottom = m_rBrowser.Height();
		}
		if(!m_bPositionSet)
			CenterRect(r);
		SetBrowserRect(r);
		ShowWindow(SW_SHOW);
		SetForegroundWindow();
		SetActiveWindow();
		m_strURL = CString(URL->bstrVal);
	}
}