Beispiel #1
0
//--------------------------------------------------------------------------
bool WindowsVideoDevice::_SetDisplayMode(VeVideoDisplay* pkDisplay,
	VeDisplayMode* pkMode) noexcept
{
	VeDisplayData* pkDisplayData = (VeDisplayData*)pkDisplay->m_spDriverData;
	VeDisplayModeData* pkData = (VeDisplayModeData*)pkMode->m_spDriverData;
	LONG status;

	status = ChangeDisplaySettingsExA(pkDisplayData->DeviceName,
		&pkData->DeviceMode, nullptr, CDS_FULLSCREEN, nullptr);
	if (status != DISP_CHANGE_SUCCESSFUL)
	{
		const VeChar8* pcReason = "Unknown reason";
		switch (status) {
		case DISP_CHANGE_BADFLAGS:
			pcReason = "DISP_CHANGE_BADFLAGS";
			break;
		case DISP_CHANGE_BADMODE:
			pcReason = "DISP_CHANGE_BADMODE";
			break;
		case DISP_CHANGE_BADPARAM:
			pcReason = "DISP_CHANGE_BADPARAM";
			break;
		case DISP_CHANGE_FAILED:
			pcReason = "DISP_CHANGE_FAILED";
			break;
		}
		VeDebugOutputCore("ChangeDisplaySettingsEx() failed: %s", pcReason);
		return false;
	}
	EnumDisplaySettingsA(pkDisplayData->DeviceName, ENUM_CURRENT_SETTINGS, &pkData->DeviceMode);
	return true;
}
Beispiel #2
0
int kinc_display_count_available_modes(int display_index) {
	DEVMODEA dev_mode = {0};
	dev_mode.dmSize = sizeof(DEVMODEA);
	int i = 0;
	for (; EnumDisplaySettingsA(displays[display_index].name, i, &dev_mode) != FALSE; ++i)
		;
	return i;
}
Beispiel #3
0
/***********************************************************************
 *		EnumDisplaySettingsExA (USER32.@)
 */
BOOL WINAPI EnumDisplaySettingsExA(LPCSTR lpszDeviceName, DWORD iModeNum,
				   LPDEVMODEA lpDevMode, DWORD dwFlags)
{
        FIXME_(system)("(%s,%lu,%p,%08lx): stub\n",
		       debugstr_a(lpszDeviceName), iModeNum, lpDevMode, dwFlags);

	return EnumDisplaySettingsA(lpszDeviceName, iModeNum, lpDevMode);
}
Beispiel #4
0
/***********************************************************************
 *		EnumDisplaySettings (USER.621)
 */
BOOL16 WINAPI EnumDisplaySettings16(
	LPCSTR name,		/* [in] huh? */
	DWORD n,		/* [in] nth entry in display settings list*/
	LPDEVMODEA devmode	/* [out] devmode for that setting */
) {
	TRACE_(system)("(%s, %ld, %p)\n", name, n, devmode);
	return (BOOL16)EnumDisplaySettingsA(name, n, devmode);
}
Beispiel #5
0
static BOOL CALLBACK EnumerationCallback(HMONITOR monitor, HDC hdc_unused, LPRECT rect_unused, LPARAM lparam) {
	MONITORINFOEXA info;
	memset(&info, 0, sizeof(MONITORINFOEXA));
	info.cbSize = sizeof(MONITORINFOEXA);
	
	if (GetMonitorInfoA(monitor, (MONITORINFO*)&info) == FALSE) {
		return FALSE;
	}

	int free_slot = 0;
	for (; free_slot < MAXIMUM_DISPLAYS; ++free_slot) {
		if (displays[free_slot].monitor == monitor) {
			return FALSE;
		}

		if (displays[free_slot].monitor == NULL) {
			break;
		}
	}

	DisplayData *display = &displays[free_slot];
	strcpy_s(display->name, 32, info.szDevice);
	display->index = free_slot;
	display->monitor = monitor;
	display->primary = (info.dwFlags & MONITORINFOF_PRIMARY) != 0;
	display->available = true;
	display->x = info.rcMonitor.left;
	display->y = info.rcMonitor.top;
	display->width = info.rcMonitor.right - info.rcMonitor.left;
	display->height = info.rcMonitor.bottom - info.rcMonitor.top;
		
	HDC hdc = CreateDCA(NULL, display->name, NULL, NULL);
	display->ppi = GetDeviceCaps(hdc, LOGPIXELSX);
	int scale = GetDeviceCaps(hdc, SCALINGFACTORX);
	DeleteDC(hdc);

	if (MyGetDpiForMonitor != NULL) {
		unsigned dpiX, dpiY;
		MyGetDpiForMonitor(monitor, MDT_EFFECTIVE_DPI, &dpiX, &dpiY);
		display->ppi = (int)dpiX;
	}

	memset(&original_modes[free_slot], 0, sizeof(DEVMODEA));
	original_modes[free_slot].dmSize = sizeof(DEVMODEA);
	EnumDisplaySettingsA(display->name, ENUM_CURRENT_SETTINGS, &original_modes[free_slot]);
	display->frequency = original_modes[free_slot].dmDisplayFrequency;
	display->bpp = original_modes[free_slot].dmBitsPerPel;

	++screen_counter;
	return TRUE;
}
Beispiel #6
0
kinc_display_mode_t kinc_display_available_mode(int display_index, int mode_index) {
	DEVMODEA dev_mode = {0};
	dev_mode.dmSize = sizeof(DEVMODEA);
	EnumDisplaySettingsA(displays[display_index].name, mode_index, &dev_mode);
	kinc_display_mode_t mode;
	mode.x = displays[display_index].x;
	mode.y = displays[display_index].y;
	mode.width = dev_mode.dmPelsWidth;
	mode.height = dev_mode.dmPelsHeight;
	mode.frequency = dev_mode.dmDisplayFrequency;
	mode.bits_per_pixel = dev_mode.dmBitsPerPel;
	mode.pixels_per_inch = displays[display_index].ppi * mode.width / original_modes[display_index].dmPelsWidth;
	return mode;
}
//Imago - 7/28/09 this function will return the adapter's Windows desktop refresh rate setting
				// used to set the maximum refresh rate and avoid any PnP issues (thanks Sgt_Baker)
int GetMaxRate(int index = 0)
{
    DISPLAY_DEVICEA dd;
    dd.cb = sizeof(DISPLAY_DEVICEA);

	if (!EnumDisplayDevicesA(NULL, index, &dd, 0))
    {
		debugf("1: EnumDisplayDevices failed:%d\n", GetLastError());
        return 60;
    }
 
    DISPLAY_DEVICEA monitor;
    monitor.cb = sizeof(DISPLAY_DEVICEA);
    if (!EnumDisplayDevicesA(dd.DeviceName, 0, &monitor, 0))
    {
		debugf("2: EnumDisplayDevices failed:%d\n", GetLastError());
		if (!EnumDisplayDevicesA(NULL, 0, &monitor, 0))	{
			debugf("22: EnumDisplayDevices failed:%d\n", GetLastError());
			return 60;
		}
	}
 
    DEVMODEA dm;
    dm.dmSize = sizeof(DEVMODEA);
 
    if (!EnumDisplaySettingsA(dd.DeviceName, ENUM_CURRENT_SETTINGS, &dm))
    {
		debugf("3: EnumDisplaySettings failed:%d\n", GetLastError());
        return 60;
    }
 
	debugf("Device string: %s\n", dd.DeviceString);
    debugf("Monitor ID: %s\n", monitor.DeviceID);
	debugf("Monitor name: %s\n", monitor.DeviceName);
	debugf("Monitor string: %s\n", monitor.DeviceString);
    debugf("Refresh rate, in hertz: %d\n", dm.dmDisplayFrequency);
    debugf("Color depth: %d\n", dm.dmBitsPerPel);
    debugf("Screen resolution, in pixels: %d x %d\n", 
        dm.dmPelsWidth, dm.dmPelsHeight);

	return dm.dmDisplayFrequency;
}
Beispiel #8
0
void Nena::InteractiveTV::Web::View::Initialize(
	Nena::Application::Window *window, 
	Session *session
	)
{
	::BOOL status;
	::DEVMODEA screen;
	::Nena::Platform::ZeroValue(&screen);

	ZeroMemory(&screen, sizeof DEVMODEA);
	status = EnumDisplaySettingsA(nullptr, ENUM_CURRENT_SETTINGS, &screen);
	dims.u32[0] = (uint32) screen.dmPelsWidth;
	dims.u32[1] = (uint32) screen.dmPelsHeight;

	impl->Initialize(
		core->impl,		// web core
		dims.u32[0],	// screen width
		dims.u32[1],	// screen height
		session->impl	// session config
		);
}
Beispiel #9
0
/***********************************************************************
 *		EnumDisplaySettingsW (USER32.@)
 */
BOOL WINAPI EnumDisplaySettingsW(LPCWSTR name,DWORD n,LPDEVMODEW devmode)
{
    DEVMODEA devmodeA;
    BOOL ret;
    LPSTR nameA = NULL;

    if (name){
        DWORD len = WideCharToMultiByte( CP_ACP, 0, name, -1, NULL, 0, NULL, NULL );
        
        
        nameA = HeapAlloc( GetProcessHeap(), 0, len );

        if (nameA == NULL){
            ERR_(system)("not enough memory to allocate a string conversion buffer for '%s'\n", debugstr_w(name));

            return FALSE;
        }
        
        WideCharToMultiByte( CP_ACP, 0, name, -1, nameA, len, NULL, NULL );
    }


    ret = EnumDisplaySettingsA(nameA,n,&devmodeA);
    if (ret)
    {
        devmode->dmBitsPerPel       = devmodeA.dmBitsPerPel;
        devmode->dmPelsHeight       = devmodeA.dmPelsHeight;
        devmode->dmPelsWidth        = devmodeA.dmPelsWidth;
        devmode->dmDisplayFlags     = devmodeA.dmDisplayFlags;
        devmode->dmDisplayFrequency = devmodeA.dmDisplayFrequency;
        devmode->dmFields           = devmodeA.dmFields;
        /* FIXME: convert rest too, if they are ever returned */
    }


    if (nameA)
        HeapFree(GetProcessHeap(),0,nameA);

    return ret;
}
Beispiel #10
0
static int Win32_GetVideoModeOnScreen(SST_DisplayTarget target, size_t screenIndex, SST_VideoMode* vmodeReturn)
{
	SST_DisplayTarget_Win32* displayTarget = (SST_DisplayTarget_Win32*)target;
	const DISPLAY_DEVICEA* dev = &displayTarget->devs[screenIndex];
	DEVMODEA devMode;
	int ok = 0;

	devMode.dmSize = sizeof(devMode);

	if(EnumDisplaySettingsA(dev->DeviceName, ENUM_CURRENT_SETTINGS, &devMode))
	{
		vmodeReturn->bpp = devMode.dmBitsPerPel;
		vmodeReturn->width = devMode.dmPelsWidth;
		vmodeReturn->height = devMode.dmPelsHeight;
		vmodeReturn->refreshRate = devMode.dmDisplayFrequency;

		if(vmodeReturn->refreshRate == 1)
			vmodeReturn->refreshRate = SST_DEFAULT_REFRESHRATE;

		ok = 1;
	}

	return ok;
}
Beispiel #11
0
bool NativeApp::PreInit() {
	
	COut(C_Info) << "Detecting video system..." << std::endl;

//#define HACK_DISABLE_GL
#if defined(RAD_OPT_GL) && !defined(HACK_DISABLE_GL)

	{
		WNDCLASSEXA clex;
		memset(&clex, 0, sizeof(WNDCLASSEXA));

		clex.cbSize = sizeof(WNDCLASSEXA);
		clex.style = CS_OWNDC;
		clex.lpfnWndProc = DefWindowProc;
		clex.hInstance = s_hInstance;
		clex.lpszClassName = "rad_openGL_ini";

		RegisterClassExA(&clex);
	}

	HWND wglWnd = CreateWindowA(
		"rad_openGL_ini", 
		"", 
		WS_CLIPCHILDREN|WS_CLIPSIBLINGS,
		0,
		0,
		100,
		100,
		0,
		0,
		s_hInstance,
		0
	);

	if (!wglWnd) {
		COut(C_Error) << "ERROR: Unable to create device window!" << std::endl;
		return false;
	}

	HDC wglDC = GetDC(wglWnd);

	{
		PIXELFORMATDESCRIPTOR pfd;
		memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
		pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
		pfd.nVersion = 1;
		pfd.dwFlags = PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|PFD_DOUBLEBUFFER;
		pfd.iPixelType = PFD_TYPE_RGBA;
		pfd.cColorBits = 24;
		pfd.cAlphaBits = 8;
		pfd.cDepthBits = 24;
		pfd.cStencilBits = 8;
		pfd.iLayerType = PFD_MAIN_PLANE;

		int pf = ChoosePixelFormat(wglDC, &pfd);
		if (pf < 1) {
			ReleaseDC(wglWnd, wglDC);
			DestroyWindow(wglWnd);
			COut(C_Error) << "ERROR: Unable to bind device window pixel format!" << std::endl;
			return false;
		}

		DescribePixelFormat(wglDC, pf, sizeof(PIXELFORMATDESCRIPTOR), &pfd);

		if (!SetPixelFormat(wglDC, pf, &pfd)) {
			COut(C_Error) << "ERROR: Unable to bind device window pixel format!" << std::endl;
			return false;
		}
	}

	HGLRC wglRC = myWglCreateContex(wglDC);
	
	if (!wglRC) {
		COut(C_Error) << "ERROR: Unable to create device window context!" << std::endl;
		return false;
	}

	wglMakeCurrent(wglDC, wglRC);
	
	PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)wglGetProcAddress("wglGetExtensionsStringARB");
	if (!wglGetExtensionsStringARB) {
		wglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)wglGetProcAddress("wglGetExtensionsStringEXT");
		if (!wglGetExtensionsStringARB) {
			wglMakeCurrent(0, 0);
			wglDeleteContext(wglRC);
			ReleaseDC(wglWnd, wglDC);
			DestroyWindow(wglWnd);
			COut(C_Error) << "Unable to find wglGetExtensionsStringARB" << std::endl;
			return false;
		}
	}

	const char *wglStrings = wglGetExtensionsStringARB(wglDC);

	if (wglStrings)
		COut(C_Info) << "wglGetExtensionsStringARB: " << wglStrings << std::endl;

	if (!wglStrings || !string::strstr(wglStrings, "WGL_ARB_pixel_format")) {
		wglMakeCurrent(0, 0);
		wglDeleteContext(wglRC);
		ReleaseDC(wglWnd, wglDC);
		DestroyWindow(wglWnd);
		COut(C_Error) << "WGL_ARB_pixel_format is required but not found." << std::endl;
		return false;
	}

	bool multiSample = false;
	if (string::strstr(wglStrings, "WGL_ARB_multisample"))
		multiSample = true;

	PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB");
	PFNWGLGETPIXELFORMATATTRIBIVARBPROC wglGetPixelFormatAttribivARB = (PFNWGLGETPIXELFORMATATTRIBIVARBPROC)wglGetProcAddress("wglGetPixelFormatAttribivARB");

#endif

	DISPLAY_DEVICEA wdd;
	for (int i = 0; ; ++i) {
		wdd.cb = sizeof(DISPLAY_DEVICEA);
		if (!EnumDisplayDevicesA(0, (DWORD)i, &wdd, 0))
			break;
		if (!(wdd.StateFlags&DISPLAY_DEVICE_ACTIVE))
			continue;
		
		::DisplayDevice::Ref _dd(new (ZEngine) ::DisplayDevice());
		DisplayDevice *dd = &_dd->m_imp;

		dd->m_vars.reset(new (ZEngine) DDVars());
		DDVars *ddv = DDVars::Get(dd->m_vars);

		memcpy(&ddv->dd, &wdd, sizeof(DISPLAY_DEVICEA));

		if (wdd.StateFlags&DISPLAY_DEVICE_PRIMARY_DEVICE) {
			dd->m_primary = true;
		} else {
			dd->m_primary = false;
		}

		DEVMODEA dm;
		dm.dmSize = sizeof(DEVMODEA);

		BOOL r = EnumDisplaySettingsA(ddv->dd.DeviceName, ENUM_CURRENT_SETTINGS, &dm);

		if (!r || ((dm.dmFields&kRequiredDMFields) != kRequiredDMFields)) {
			if (dd->m_primary) {
				// this is kinda bad
				COut(C_Error) << "ERROR: failed to enumerate primary display, initialization failed." << std::endl;
				return false;
			}

			continue;
		}

		if (!(dm.dmFields & DM_POSITION)) {
			// dmPosition is not valid, meaning we cannot identify this as secondary monitor...
			if (dd->m_primary) {
				dm.dmPosition.x = 0;
				dm.dmPosition.y = 0;
				dm.dmFields |= DM_POSITION;
			} else {
				continue; // this monitor cannot be identified.
			}
		}

		string::ncpy((char*)dm.dmDeviceName, wdd.DeviceName, 32);
		memcpy(&ddv->dm, &dm, sizeof(DEVMODEA));
		dd->m_defMode = VidModeFromDevMode(dm);
		dd->m_curMode = dd->m_defMode;
		dd->m_maxMSAA = 0;
		dd->m_maxAnisotropy = 0;

		// enumerate valid display modes.
		COut(C_Info) << "Display " << i << ": '" << ddv->dd.DeviceName << " - " << ddv->dd.DeviceString << "':" << std::endl;

		for (int k = 0; ; ++k) {
			dm.dmSize = sizeof(DEVMODEA);
			if (!EnumDisplaySettingsA(ddv->dd.DeviceName, k, &dm))
				break;
			if ((dm.dmFields&kRequiredDMFields) != kRequiredDMFields)
				continue;
			if (dm.dmBitsPerPel < 32)
				continue;
			r::VidMode m = VidModeFromDevMode(dm);

			r::VidModeVec::iterator it;
			for (it = dd->m_vidModes.begin(); it != dd->m_vidModes.end(); ++it) {
				r::VidMode &x = *it;

				if (x.w == m.w &&
					x.h == m.h) {
					// matches.
					// prefer we use the same hz as our desktop...
					if (m.hz == dd->m_defMode.hz)
						x.hz = m.hz;
					break;
				}
			}

			if (it == dd->m_vidModes.end())
				dd->m_vidModes.push_back(m);
		}

		for (r::VidModeVec::const_iterator it = dd->m_vidModes.begin(); it != dd->m_vidModes.end(); ++it) {
			const r::VidMode &m = *it;
			COut(C_Info) << "\t" << (it-dd->m_vidModes.begin()) << ": " << m.w << "x" << m.h << "x" << m.bpp << " @ " << m.hz << "hz" << std::endl;
		}

		if (dd->m_vidModes.empty()) {
			if (dd->m_primary) {
				COut(C_Error) << "ERROR: primary display '" << ddv->dd.DeviceName << "' is invalid, initialization failed." << std::endl;
				return false;
			}
			continue;
		}

#if defined(RAD_OPT_GL) && !defined(HACK_DISABLE_GL)
		if (multiSample) {

			int maxSamples = 0;

			int reqAttribs[9] = {
				WGL_SUPPORT_OPENGL_ARB,
				WGL_DRAW_TO_WINDOW_ARB,
				WGL_ACCELERATION_ARB,
				WGL_PIXEL_TYPE_ARB,
				WGL_COLOR_BITS_ARB,
				WGL_ALPHA_BITS_ARB,
				WGL_DEPTH_BITS_ARB,
				WGL_STENCIL_BITS_ARB,
				WGL_SAMPLES_ARB
			};

			int attribs[9];

			// Enumerate all pixel formats, find highest multi-sample count
			for (int k = 1; ; ++k) { // PF's are 1 based
				if (!wglGetPixelFormatAttribivARB(wglDC, k, PFD_MAIN_PLANE, 9, reqAttribs, attribs))
					break;
				if (attribs[0] != TRUE)
					continue;
				if (attribs[1] != TRUE)
					continue;
				if (attribs[2] != WGL_FULL_ACCELERATION_ARB)
					continue;
				if (attribs[3] != WGL_TYPE_RGBA_ARB)
					continue;
				if (attribs[4] < 24)
					continue;
				if (attribs[5] < 8)
					continue;
				if (attribs[6] < 24)
					continue;
				if (attribs[7] < 8)
					continue;

				if (maxSamples < attribs[8])
					maxSamples = attribs[8];

				if (maxSamples >= kMaxMultiSample)
					break;
			}

			dd->m_maxMSAA = maxSamples;
		}

		const char *glExt = (const char *)glGetString(GL_EXTENSIONS);
		if (glExt && string::strstr(glExt, "GL_EXT_texture_filter_anisotropic")) {
			GLint maxAnisotropy;
			glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxAnisotropy);
			dd->m_maxAnisotropy = maxAnisotropy;
		}
		
#endif

		m_displayDevices.push_back(_dd);

		if (dd->m_primary)
			m_primaryDisplay = _dd;
	}

	if (!m_primaryDisplay) {
		COut(C_Error) << "ERROR: no primary display detected, initialization failed!" << std::endl;
		return false;
	}

	return true;
}
Beispiel #12
0
//--------------------------------------------------------------------------
static bool GetDisplayMode(LPCSTR deviceName, DWORD index,
	VeDisplayMode* mode) noexcept
{
	VeDisplayModeData* data;
	DEVMODEA devmode;
	HDC hdc;

	devmode.dmSize = sizeof(devmode);
	devmode.dmDriverExtra = 0;
	if (!EnumDisplaySettingsA(deviceName, index, &devmode))
	{
		return false;
	}

	data = VE_NEW VeDisplayModeData;
	VE_ASSERT(data);
	data->DeviceMode = devmode;
	data->DeviceMode.dmFields =
		(DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY |
			DM_DISPLAYFLAGS);
	data->ScaleX = 1.0f;
	data->ScaleY = 1.0f;

	mode->m_u32Format = VE_PIXELFORMAT_UNKNOWN;
	mode->m_i32Width = devmode.dmPelsWidth;
	mode->m_i32Height = devmode.dmPelsHeight;
	mode->m_i32RefreshRate = devmode.dmDisplayFrequency;
	mode->m_spDriverData = data;

	if (index == ENUM_CURRENT_SETTINGS
		&& (hdc = CreateDCA(deviceName, nullptr, nullptr, nullptr)) != nullptr)
	{
		char bmi_data[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)];
		LPBITMAPINFO bmi;
		HBITMAP hbm;
		int logical_width = GetDeviceCaps(hdc, HORZRES);
		int logical_height = GetDeviceCaps(hdc, VERTRES);

		data->ScaleX = (float)logical_width / devmode.dmPelsWidth;
		data->ScaleY = (float)logical_height / devmode.dmPelsHeight;
		mode->m_i32Width = logical_width;
		mode->m_i32Height = logical_height;

		VeZeroMemory(bmi_data, sizeof(bmi_data));
		bmi = (LPBITMAPINFO)bmi_data;
		bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);

		hbm = CreateCompatibleBitmap(hdc, 1, 1);
		GetDIBits(hdc, hbm, 0, 1, nullptr, bmi, DIB_RGB_COLORS);
		GetDIBits(hdc, hbm, 0, 1, nullptr, bmi, DIB_RGB_COLORS);
		DeleteObject(hbm);
		DeleteDC(hdc);
		if (bmi->bmiHeader.biCompression == BI_BITFIELDS)
		{
			switch (*(VeUInt32 *)bmi->bmiColors)
			{
			case 0x00FF0000:
				mode->m_u32Format = VE_PIXELFORMAT_RGB888;
				break;
			case 0x000000FF:
				mode->m_u32Format = VE_PIXELFORMAT_BGR888;
				break;
			case 0xF800:
				mode->m_u32Format = VE_PIXELFORMAT_RGB565;
				break;
			case 0x7C00:
				mode->m_u32Format = VE_PIXELFORMAT_RGB555;
				break;
			}
		}
		else if (bmi->bmiHeader.biBitCount == 8)
		{
			mode->m_u32Format = VE_PIXELFORMAT_INDEX8;
		}
		else if (bmi->bmiHeader.biBitCount == 4)
		{
			mode->m_u32Format = VE_PIXELFORMAT_INDEX4LSB;
		}
	}
	else
	{
		if ((devmode.dmFields & DM_BITSPERPEL) == DM_BITSPERPEL)
		{
			switch (devmode.dmBitsPerPel)
			{
			case 32:
				mode->m_u32Format = VE_PIXELFORMAT_RGB888;
				break;
			case 24:
				mode->m_u32Format = VE_PIXELFORMAT_RGB24;
				break;
			case 16:
				mode->m_u32Format = VE_PIXELFORMAT_RGB565;
				break;
			case 15:
				mode->m_u32Format = VE_PIXELFORMAT_RGB555;
				break;
			case 8:
				mode->m_u32Format = VE_PIXELFORMAT_INDEX8;
				break;
			case 4:
				mode->m_u32Format = VE_PIXELFORMAT_INDEX4LSB;
				break;
			}
		}
	}
	return true;
}
Beispiel #13
0
int DxVsyncSource::vsyncThread(void* context)
{
    DxVsyncSource* me = reinterpret_cast<DxVsyncSource*>(context);

    SDL_SetThreadPriority(SDL_THREAD_PRIORITY_HIGH);

    D3DKMT_OPENADAPTERFROMHDC openAdapterParams = {};
    HMONITOR lastMonitor = nullptr;
    DEVMODEA monitorMode;
    monitorMode.dmSize = sizeof(monitorMode);

    while (SDL_AtomicGet(&me->m_Stopping) == 0) {
        D3DKMT_WAITFORVERTICALBLANKEVENT waitForVblankEventParams;
        NTSTATUS status;

        // If the monitor has changed from last time, open the new adapter
        HMONITOR currentMonitor = MonitorFromWindow(me->m_Window, MONITOR_DEFAULTTONEAREST);
        if (currentMonitor != lastMonitor) {
            MONITORINFOEXA monitorInfo = {};
            monitorInfo.cbSize = sizeof(monitorInfo);
            if (!GetMonitorInfoA(currentMonitor, &monitorInfo)) {
                SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
                             "GetMonitorInfo() failed: %d",
                             GetLastError());
                SDL_Delay(10);
                continue;
            }

            if (!EnumDisplaySettingsA(monitorInfo.szDevice, ENUM_CURRENT_SETTINGS, &monitorMode)) {
                SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
                             "EnumDisplaySettings() failed: %d",
                             GetLastError());
                SDL_Delay(10);
                continue;
            }

            SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
                        "Monitor changed: %s %d Hz",
                        monitorInfo.szDevice,
                        monitorMode.dmDisplayFrequency);

            if (openAdapterParams.hAdapter != 0) {
                D3DKMT_CLOSEADAPTER closeAdapterParams = {};
                closeAdapterParams.hAdapter = openAdapterParams.hAdapter;
                me->m_D3DKMTCloseAdapter(&closeAdapterParams);
            }

            openAdapterParams.hDc = CreateDCA(nullptr, monitorInfo.szDevice, nullptr, nullptr);
            if (!openAdapterParams.hDc) {
                SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
                             "CreateDC() failed: %d",
                             GetLastError());
                SDL_Delay(10);
                continue;
            }

            status = me->m_D3DKMTOpenAdapterFromHdc(&openAdapterParams);
            DeleteDC(openAdapterParams.hDc);

            if (status != STATUS_SUCCESS) {
                SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
                             "D3DKMTOpenAdapterFromHdc() failed: %x",
                             status);
                SDL_Delay(10);
                continue;
            }

            lastMonitor = currentMonitor;
        }

        waitForVblankEventParams.hAdapter = openAdapterParams.hAdapter;
        waitForVblankEventParams.hDevice = 0;
        waitForVblankEventParams.VidPnSourceId = openAdapterParams.VidPnSourceId;

        status = me->m_D3DKMTWaitForVerticalBlankEvent(&waitForVblankEventParams);
        if (status != STATUS_SUCCESS) {
            SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
                         "D3DKMTWaitForVerticalBlankEvent() failed: %x",
                         status);
            SDL_Delay(10);
            continue;
        }

        me->m_Pacer->vsyncCallback(1000 / me->m_DisplayFps);
    }

    if (openAdapterParams.hAdapter != 0) {
        D3DKMT_CLOSEADAPTER closeAdapterParams = {};
        closeAdapterParams.hAdapter = openAdapterParams.hAdapter;
        me->m_D3DKMTCloseAdapter(&closeAdapterParams);
    }

    return 0;
}