Quantcast
Channel: Intel Developer Zone Articles
Viewing all articles
Browse latest Browse all 3384

Code Samples for Detection of System GPU, Battery Mode, and Windows* 8 On-screen Keyboard in Unity*

$
0
0

Download PDF

Download the Intel® Toolkit from the Unity* Asset Store

This article provides a few tips we learned while working with game developers. The first tip is how to display Windows native mode touch and touch feedback visuals. The second is how to detect what kind of GPU is installed and what mode the user device’s battery is in, assuming the device has a battery. The last one is how to use the built-in on-screen keyboard in Windows* 8 with Unity* along with how to detect if the on-screen keyboard is visible. These topics address just a few of our external partners’ questions when they are trying to enable games for various platforms, so we figured it would be good to share them with others. The asset is available on the Unity Asset Store at http://u3d.as/content/intel/intel-toolkit.

A key contributor to this project was Steve Hughes’ article Adding Multi-Touch Support to Unity* Games on Microsoft Windows* 7 and Windows* 8 Desktop and code to add Windows 7/8 native touch to Unity.

Touch and Touch Feedback Visuals

Using Hughes’ code as a starting point, we added a visual element to it so users could visualize the data and see how to use it. Each finger on the screen has its own graphic indicating the touch point that was captured.

We also added some code that turned off the Windows default touch feedback visuals. For example, when you slide your finger across the screen on the Windows desktop, you’ll probably notice a little white trail indicating the path of your touch as it drags across the screen. These feedback visuals are nice, but in a game they may not be ideal. “So how do you turn those off programmatically,” one customer asked? Below is a snippet of the Windows API call that we found and used.

//in win8 sdk header
	typedef enum tagFEEDBACK_TYPE {
		FEEDBACK_TOUCH_CONTACTVISUALIZATION  = 1,
		FEEDBACK_PEN_BARRELVISUALIZATION     = 2,
		FEEDBACK_PEN_TAP                     = 3,
		FEEDBACK_PEN_DOUBLETAP               = 4,
		FEEDBACK_PEN_PRESSANDHOLD            = 5,
		FEEDBACK_PEN_RIGHTTAP                = 6,
		FEEDBACK_TOUCH_TAP                   = 7,
		FEEDBACK_TOUCH_DOUBLETAP             = 8,
		FEEDBACK_TOUCH_PRESSANDHOLD          = 9,
		FEEDBACK_TOUCH_RIGHTTAP              = 10,
		FEEDBACK_GESTURE_PRESSANDTAP         = 11,
		FEEDBACK_MAX                         = 0xFFFFFFFF
	} FEEDBACK_TYPE ;

	//check if win8 function exists
	//if so turn off the windows 8 touch feedback stuff
	typedef BOOL (*LPSETWINFEEDBACK)(HWND hwnd, FEEDBACK_TYPE feedback, DWORD dwFlags, UINT32 size, const VOID *configuration);
	HINSTANCE hDLL = NULL;
	LPSETWINFEEDBACK lpSetWinFeedBack;
	hDLL = LoadLibrary("User32.DLL");
	lpSetWinFeedBack = (LPSETWINFEEDBACK)GetProcAddress((HMODULE)hDLL, "SetWindowFeedbackSetting");

	if( lpSetWinFeedBack )
	{
		setval = FALSE;
		if(lpSetWinFeedBack( g_hRemoteWnd, FEEDBACK_TOUCH_CONTACTVISUALIZATION, 0, sizeof(BOOL), (void*)&setval) == false)
			return -7;
		setval = FALSE;
		if(lpSetWinFeedBack( g_hRemoteWnd, FEEDBACK_TOUCH_TAP, 0, sizeof(BOOL), (void*)&setval) == false)
			return -7;
		setval = FALSE;
		if(lpSetWinFeedBack( g_hRemoteWnd, FEEDBACK_TOUCH_PRESSANDHOLD, 0, sizeof(BOOL), (void*)&setval) == false)
			return -7;
		setval = FALSE;
		if(lpSetWinFeedBack( g_hRemoteWnd, FEEDBACK_TOUCH_DOUBLETAP, 0, sizeof(BOOL), (void*)&setval) == false)
			return -7;
		setval = FALSE;
		if(lpSetWinFeedBack( g_hRemoteWnd, FEEDBACK_TOUCH_RIGHTTAP, 0, sizeof(BOOL), (void*)&setval) == false)
			return -7;
		setval = FALSE;
		if(lpSetWinFeedBack( g_hRemoteWnd, FEEDBACK_GESTURE_PRESSANDTAP, 0, sizeof(BOOL), (void*)&setval) == false)
			return -7;
	}

Basically, you want to call in to SetWindowFeedbackSetting, but you have to be careful because we found that if you don’t set the events in the correct order, you might get some unexpected crashes. Our example shows the order that we used to shut off all of the visual feedback correctly without causing issues in our application.

GPU Detect

We took one of our previously published samples, GPU Detect, that shows developers how to identify Intel® graphics hardware and obtain relevant information for their games. Typically this information is used to help create default performance settings for different SKUs of hardware. Sometimes the SKU is not enough information to determine the correct performance level for a part. For example, if you have two systems with the same SKU but different thermal design power (TDP) limits, performance can be different between the two. In our GPU detection sample we provide a mechanism that shows how to get information like TDP so you can fine-tune your settings for different platforms. Here is the latest version of the GPU Detect sample.

In this asset we pull data from that sample and display it in UI elements in Unity.

Battery and frame rate clamping

While we’re identifying useful information, we also pull some mobility metrics and display them in Unity via user interface (UI) elements. The mobility metrics provide info on battery life and modes. You can use this information to clamp the frame rate down to something like 30 if the user has unplugged the system. Clamping the frame rate, assuming the frame rate is higher at the time, can help extend battery life. You can put the following lines of code in your Unity script to clamp the frame rate to 30.

Application.targetFramerate = 30;
QualitySettings.vSyncCount = 2;

Using Windows On-screen Keyboard with Unity

Writing your own on-screen keyboard can be a real pain especially if you require it to be localized, and  Microsoft has already built one so we just needed to figure out how to get it to play nicely with the Unity engine. To use it in Unity you have to force your Unity window to come up in borderless windowed mode. It will not work in fullscreen mode. You can launch or present the different keyboards with a simple function call provided in the sample (.dll portion). You also need a way to detect the status of the on-screen keyboard (is it currently displayed on the screen or hidden?). We have a call in the sample that shows you how to do that, but it is commented out (see below).

__declspec(dllexport) BOOL __cdecl IsVirtualKeyboardVisible()
{
	BOOL	bRet = FALSE;
	RECT	InputPaneScreenLocation = { 0, 0, 0, 0 };
	/*
	__try
	{
		HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);

		IFrameworkInputPane *IinputPane = NULL;

		if (SUCCEEDED(hr))
		{
			//
			// http://msdn.microsoft.com/en-us/library/windows/desktop/hh706967(v=vs.85).aspx
			//
			hr = CoCreateInstance(__uuidof(FrameworkInputPane), 0, CLSCTX_ALL, __uuidof(IFrameworkInputPane), (LPVOID*)&IinputPane);
			IinputPane->Location(&InputPaneScreenLocation);

			if (InputPaneScreenLocation.bottom == 0 && InputPaneScreenLocation.left == 0 &&
				InputPaneScreenLocation.right == 0 && InputPaneScreenLocation.top == 0)
			{
				// VKB is not visible
				bRet = FALSE;
			}
			else
			{
				// VKB is visible
				bRet = TRUE;
			}
		}

	}	// try
	__finally
	{
		CoUninitialize();
	}
	*/
	return bRet;
}

We hope you find these code samples useful. Pick and choose what works for your project.

About the Author

Jeff LaFlam has been working on optimizing video games for Intel® hardware for the past 8 years. He has worked with several game developers throughout the U.S. He also enjoys designing, creating, and playing games in his spare time.

 

This sample source code is released under the Intel Sample Source Code License Agreement.


Viewing all articles
Browse latest Browse all 3384

Trending Articles