⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cursor.cpp

📁 Sm501 VGA芯片wince下驱动代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.
Copyright (c) 1995, 1996, 1997, 1998  Microsoft Corporation
Copyright (c) 1999-2000  Silicon Motion, Inc.

Module Name:	cursor.cpp

Abstract:		SMI hardware accelerated cursor

Functions:

Notes:

--*/

#include "precomp.h"


//convert to vgx cursor mask
unsigned char mask_table[]= 
{0, 128, 32, 160, 8, 136, 40, 168, 2, 130, 34, 162, 10, 138, 42, 170};
// 00 - 0x00                             08 - 0x02
// 01 - 0x80							 09 - 0x82
// 02 - 0x20							 0A - 0x22
// 03 -	0xA0 							 0B - 0xA2
// 04 - 0x08 							 0C - 0x0A
// 05 - 0x88 							 0D - 0x8A
// 06 - 0x28 							 0E - 0x2A
// 07 - 0xA8 							 0F - 0xAA

SCODE SMI::SetPointerShape(GPESurf *pMask, GPESurf *pColorSurf, int xHot, int yHot,
					 int cx, int cy)
{
	PUCHAR pByte;
	PUCHAR pBuf;
	int i, row, col_byte, stride;
	UCHAR and_mask, xor_mask;

	DEBUGMSG(GPE_ZONE_CURSOR, (TEXT("SMI::SetPointerShape()\r\n")));

	SetCursorColors(0x00ffffff, 0x00000000);	// Set colors to black & white

	pByte = m_pLAW + m_nCursorMemory;
	DEBUGMSG(GPE_ZONE_CURSOR, (TEXT("pByte = %08X, m_nCursorMemory = %08X\r\n"),
			pByte, m_nCursorMemory));

	// Not sure if this hide cursor is necessary, please verify
	DisableCursor();

	if (!pMask)
	{
		DEBUGMSG(GPE_ZONE_CURSOR, (TEXT("+Turning off cursor\r\n")));

		for (i = 0; i < 64*64/8*2; i++)	// Turn off cursor by setting mask to clear
			pByte[i] = 0;
	}
	else
	{
		// A cursor shape has been entered, draw it.
		DEBUGMSG(GPE_ZONE_CURSOR, (TEXT("+Setting pointer shape\r\n")));

		// Setup freq addressed information into local variables.
		stride = pMask->Stride();
		pBuf = (PUCHAR) pMask->Buffer();

		// initialize entire 32 x 32 shape to be ANDs=0xFF and XORs = 0x00
		// (i.e. transparent)
		m_nXHot = xHot;
		m_nYHot = yHot;	// we rely on MovePointer being called after this
		
		// Clear Cursor Mem to transparent.
		// 1/2/2003. Clear additional 1KB to 0 to patch Hw RevA cursor bottom garbage 
		// when cursor at bottom of screen.
		memset((PUCHAR) m_pLAW+m_nCursorMemory, 0, CURSUR_IMAGE_SIZE);

		for (row = 0, i=0; row < cy; row++)
		{
			i = row * 64/8 * 2;
			for (col_byte = 0; col_byte < cx/8; col_byte++)
			{
				and_mask = mask_table[(~pBuf[row * stride+col_byte ] & 0xF0)>>4];
				xor_mask = mask_table[(pBuf[(cy + row) * stride + col_byte] & 0xF0)>>4]/2;
				pByte[i++] = and_mask | xor_mask;

				and_mask = mask_table[(~pBuf[row * stride+col_byte] & 0x0F)];
				xor_mask = mask_table[(pBuf[(cy + row) * stride + col_byte] & 0x0F)]/2;
				pByte[i++] = and_mask | xor_mask;
			}
		}
	}

	RotateCursorShape(m_iRotate);

	AdjustCursorShape(); // For Zoom-In, Zoom-Out Feature

	SetCursorAddress(m_nCursorMemory);
	
	DEBUGMSG(GPE_ZONE_CURSOR, (TEXT("+Cursor shape set done\r\n")));

	return (S_OK);
}

SCODE SMI::MovePointer(int x, int y)
{
	DEBUGMSG(GPE_ZONE_CURSOR, (TEXT("SMI::MovePointer(%d, %d)\r\n"), x, y));

	int newX,newY;

#ifdef ROTATION_ENABLE
	int nHideCursor = -33;
#else // ! ROTATION_ENABLE
	int nHideCursor = -1;
#endif // ROTATION_ENABLE

	switch (m_iRotate)
	{
#ifdef ROTATION_ENABLE
		case DMDO_270:
			newX = m_nScreenHeight - y - m_nXHot - 1;	// Hot spot is currently 32,32
			newY = x - m_nYHot;
			break;
		case DMDO_180:
			newX = m_nScreenWidth - x - m_nXHot - 1;
			newY = m_nScreenHeight - y - m_nYHot - 1;
			break;
		case DMDO_90:
			newX = y - m_nXHot;
			newY = m_nScreenWidth - x - m_nYHot - 1;
			break;
#endif 
		case 0:
		default:
			newX = x - m_nXHot;
			newY = y - m_nYHot;
			break;
	}

	//Fix hw cursor X,Y out of screen range. 11/01/02
	if (newX >= m_nScreenWidthSave)
		newX = m_nScreenWidthSave-1;

	if (newY >= m_nScreenHeightSave)
		newY = m_nScreenHeightSave-1;

	if (x == nHideCursor)
		DisableCursor();

	// Check for Virtual Panning
	if ( ((DWORD)m_SMISettings.m_dwCxPanel != m_dwCxZoom) ||
		 ((DWORD)m_SMISettings.m_dwCyPanel != m_dwCyZoom) )
	{
//		if (newX >= 0)
		{
			if ((newX+m_nXHot) < m_nPanningX)
			{
				// Pan left.
				m_nPanningX = newX + m_nXHot;
				if (m_nPanningX < 0) m_nPanningX = 0;
			}
			else if ((newX+m_nXHot) >= (m_nPanningX + (int)m_dwCxZoom))
			{
				// Pan right.
				m_nPanningX = (newX + m_nXHot + 1 - (int)m_dwCxZoom);
				if (m_nPanningX > m_nScreenWidthSave - (int)m_dwCxZoom)
					m_nPanningX = m_nScreenWidthSave - (int)m_dwCxZoom;
			}
		}
//		if (newY >= 0)
		{
			if ((newY+m_nYHot) < m_nPanningY)
			{
				// Pan up.
				m_nPanningY = newY + m_nYHot;
				if (m_nPanningY < 0) m_nPanningY = 0;
			}
			else if ((newY+m_nYHot) >= (m_nPanningY + (int)m_dwCyZoom))
			{
				// Pan down.
				m_nPanningY = (newY + m_nYHot + 1 - (int)m_dwCyZoom);
				if (m_nPanningY > m_nScreenHeightSave - (int)m_dwCyZoom)
					m_nPanningY = m_nScreenHeightSave - (int)m_dwCyZoom;
			}
		}

		newX -= m_nPanningX;
		newY -= m_nPanningY;

		// Adjust newX/newY ratio
		newX = (newX * m_SMISettings.m_dwCxPanel)/m_dwCxZoom;
		newY = (newY * m_SMISettings.m_dwCyPanel)/m_dwCyZoom;

		POKE_32(VIDEO_DISPLAY_CTRL, 
			FIELD_VALUE(PEEK_32(VIDEO_DISPLAY_CTRL), VIDEO_DISPLAY_CTRL, PIXEL, 
				((m_nPanningX * (m_nScreenBpp/8)) % 16)/(m_nScreenBpp/8))
			);

		POKE_32(VIDEO_FB_0_ADDRESS, 
			FIELD_SET(0, VIDEO_FB_0_ADDRESS, STATUS, PENDING) |
			FIELD_VALUE(0, VIDEO_FB_0_ADDRESS, EXT, m_SMISettings.m_bUMA) |
			FIELD_VALUE(0, VIDEO_FB_0_ADDRESS, ADDRESS, 
				VgxSurfAddr(m_pPrimarySurface->OffsetInVideoMemory())
				+m_nPanningY*m_nScreenStride+m_nPanningX*m_nScreenBpp/8) | 
			0);

	}
	// Check for Virtual Panning
	else if ( ((DWORD)m_nScreenWidthSave > m_SMISettings.m_dwCxPanel) ||
		 ((DWORD)m_nScreenHeightSave > m_SMISettings.m_dwCyPanel) )
	{
//		if (newX >= 0)
		{
			if ((newX+m_nXHot) < m_nPanningX)
			{
				// Pan left.
				m_nPanningX = newX + m_nXHot;
				if (m_nPanningX < 0) m_nPanningX = 0;
			}
			else if ((newX+m_nXHot) >= (m_nPanningX + (int)m_SMISettings.m_dwCxPanel))
			{
				// Pan right.
				m_nPanningX = (newX + m_nXHot + 1 - (int)m_SMISettings.m_dwCxPanel);
				if (m_nPanningX > m_nScreenWidthSave - (int)m_SMISettings.m_dwCxPanel)
					m_nPanningX = m_nScreenWidthSave - (int)m_SMISettings.m_dwCxPanel;
			}
		}
//		if (newY >= 0)
		{
			if ((newY+m_nYHot) < m_nPanningY)
			{
				// Pan up.
				m_nPanningY = newY + m_nYHot;
				if (m_nPanningY < 0) m_nPanningY = 0;
			}
			else if ((newY+m_nYHot) >= (m_nPanningY + (int)m_SMISettings.m_dwCyPanel))
			{
				// Pan down.
				m_nPanningY = (newY + m_nYHot + 1 - (int)m_SMISettings.m_dwCyPanel);
				if (m_nPanningY > m_nScreenHeightSave - (int)m_SMISettings.m_dwCyPanel)
					m_nPanningY = m_nScreenHeightSave - (int)m_SMISettings.m_dwCyPanel;
			}
		}

		newX -= m_nPanningX;
		newY -= m_nPanningY;

		POKE_32(PANEL_WINDOW_WIDTH,
	  	  	FIELD_VALUE(0, PANEL_WINDOW_WIDTH, WIDTH, m_nScreenWidthSave-1) |
			FIELD_VALUE(0, PANEL_WINDOW_WIDTH, X, m_nPanningX) );

		POKE_32(PANEL_WINDOW_HEIGHT,
		  	FIELD_VALUE(0, PANEL_WINDOW_HEIGHT, HEIGHT, m_nScreenHeightSave-1) |
		  	FIELD_VALUE(0, PANEL_WINDOW_HEIGHT, Y, m_nPanningY) );
	
	}

    ULONG dwVal = PEEK_32(PANEL_HWC_LOCATION);

    if (newX >= 0)
    {
        dwVal = FIELD_VALUE(dwVal, PANEL_HWC_LOCATION, X, newX); 
        dwVal = FIELD_SET(dwVal, PANEL_HWC_LOCATION, LEFT, INSIDE);
    }
    else
    {
        dwVal = FIELD_VALUE(dwVal, PANEL_HWC_LOCATION, X, -newX); 
        dwVal = FIELD_SET(dwVal, PANEL_HWC_LOCATION, LEFT, OUTSIDE); 
    }

    if (newY >= 0)
    {
        dwVal = FIELD_VALUE(dwVal, PANEL_HWC_LOCATION, Y, newY); 
        dwVal = FIELD_SET(dwVal, PANEL_HWC_LOCATION, TOP, INSIDE); 
    }
    else
    {
        dwVal = FIELD_VALUE(dwVal, PANEL_HWC_LOCATION, Y, -newY); 
        dwVal = FIELD_SET(dwVal, PANEL_HWC_LOCATION, TOP, OUTSIDE); 
    }

    // 1/2/2003. Clear additional 1KB to 0 to patch hw cursor bottom garbage. do not need to WaitForVBlank() now.
    // Hardware bugs - Had to wait for VBlank before change position
    // WaitForVBlank();
    POKE_32(PANEL_HWC_LOCATION, dwVal);

	if (x != nHideCursor)
		EnableCursor();

 	return (S_OK);
}

void SMI::SetCursorColors(ULONG foreground, ULONG background)
{
	ULONG color3=0x0000; //for invert color, assume it is Black at this time.

	DEBUGMSG(GPE_ZONE_CURSOR, (TEXT("SMI::SetCursorColors(0x%x, 0x%x)\r\n"),
		foreground, background));

    POKE_32(PANEL_HWC_COLOR_01, background<<16 | color3);
    POKE_32(PANEL_HWC_COLOR_2, foreground);
}

void SMI::SetCursorAddress(ULONG dwAddress)
{
        ULONG dwAdd = PEEK_32(PANEL_HWC_ADDRESS);
        dwAdd = FIELD_VALUE(dwAdd, PANEL_HWC_ADDRESS, EXT, m_SMISettings.m_bUMA);
        dwAdd = FIELD_VALUE(dwAdd, PANEL_HWC_ADDRESS, ADDRESS, VgxSurfAddr(dwAddress));
        dwAdd = FIELD_VALUE(dwAdd, PANEL_HWC_ADDRESS, ENABLE, m_nPanelHwcOnOff);
        POKE_32(PANEL_HWC_ADDRESS, dwAdd);
}

void SMI::DisableCursor(void)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -