/*******************************************************************
  Initialize DirectX.
*******************************************************************/
bool CGraphics::InitializeDirectX(){
  m_d3d = Direct3DCreate9(D3D_SDK_VERSION); // create the Direct3D interface
  if(!m_d3d){
    ::MessageBox(m_hWnd, "DirectX failed!", "Fatal Error!", MB_OK | MB_ICONSTOP | MB_APPLMODAL);
    return false;
  }

  //D3DPRESENT_PARAMETERS d3dpp; // create a struct to hold various device information
  ZeroMemory(&m_d3dpp, sizeof(m_d3dpp));    // clear out the struct for use
	D3DDISPLAYMODE        CurrentMode;
  
  // Select back buffer format etc
	m_d3d->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &CurrentMode);

  //controlled by config.txt
  m_d3dpp.Windowed = !m_fullScreen;  //windowed
  m_d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;    // set the back buffer format to 32-bit
  m_d3dpp.BackBufferWidth = m_screenWidth;    // set the width of the buffer
  m_d3dpp.BackBufferHeight = m_screenHeight;    // set the height of the buffer
  m_d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;    // discard old frames
  m_d3dpp.hDeviceWindow = m_hWnd;    // set the window to be used by Direct3D
  m_d3dpp.PresentationInterval	= D3DPRESENT_INTERVAL_IMMEDIATE;
  m_d3dpp.FullScreen_RefreshRateInHz = m_fullScreen ? CurrentMode.RefreshRate : 0;
  m_d3dpp.EnableAutoDepthStencil = TRUE;
  m_d3dpp.AutoDepthStencilFormat		=  FindDepthStencilFormat( D3DADAPTER_DEFAULT, CurrentMode, D3DDEVTYPE_HAL );

  // create a device class using this information and the info from the d3dpp stuct
  m_d3d->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,m_hWnd,
                    D3DCREATE_SOFTWARE_VERTEXPROCESSING, &m_d3dpp, &m_d3ddev);
  /*
  if(FAILED( D3DXCreateSprite(m_d3ddev, &m_pSprite)) )
  {
    ::MessageBox(m_hWnd, "Failed to create a sprite!", "Fatal Error!", 0);//MB_OK | MB_ICONSTOP | MB_APPLMODAL);
    return false;
  }*/

  ReloadLost();

  return true;
}
Exemple #2
0
BOOL D3D_CDeviceInfo::Build(IDirect3D8& rkD3D, UINT iD3DAdapterInfo, UINT iDevType, D3D_CAdapterDisplayModeList& rkD3DADMList, BOOL (*pfnConfirmDevice)(D3DCAPS8& rkD3DCaps, UINT uBehavior, D3DFORMAT eD3DFmt))
{	
	assert(pfnConfirmDevice!=NULL && "D3D_CDeviceInfo::Build");

	const D3DDEVTYPE	c_eD3DDevType=msc_aeD3DDevType[iDevType];
	const TCHAR*		c_szD3DDevDesc=msc_aszD3DDevDesc[iDevType];

    m_eD3DDevType = c_eD3DDevType;
    rkD3D.GetDeviceCaps(iD3DAdapterInfo, c_eD3DDevType, &m_kD3DCaps);

    m_szDevDesc = c_szD3DDevDesc;
    m_uD3DModeInfoNum=0;
    m_canDoWindowed = FALSE;
    m_isWindowed = FALSE;
    m_eD3DMSTFullscreen = D3DMULTISAMPLE_NONE;
    m_eD3DMSTWindowed = D3DMULTISAMPLE_NONE;

	BOOL  aisFormatConfirmed[20];
	DWORD adwD3DBehavior[20];
	D3DFORMAT aeD3DFmtDepthStencil[20];
	
    BOOL isHALExists = FALSE;
    BOOL isHALWindowedCompatible = FALSE;
    BOOL isHALDesktopCompatible = FALSE;
    BOOL isHALSampleCompatible = FALSE;

	// GetFlagInfo
	{
		UINT uD3DFmtNum=rkD3DADMList.GetPixelFormatNum();

		for (DWORD iFmt=0; iFmt<uD3DFmtNum; ++iFmt)
		{
			D3DFORMAT eD3DFmtPixel=rkD3DADMList.GetPixelFormatr(iFmt);		
			DWORD dwD3DBehavior=0;
			BOOL isFormatConfirmed=FALSE;			

			aeD3DFmtDepthStencil[iFmt] = D3DFMT_UNKNOWN;

			// SkipNoRenderTargetFormat;
			if (FAILED(rkD3D.CheckDeviceType(iD3DAdapterInfo, m_eD3DDevType, eD3DFmtPixel, eD3DFmtPixel, FALSE)))
				continue;

			if (D3DDEVTYPE_HAL==m_eD3DDevType)
			{
				isHALExists=TRUE;
				
				if (m_kD3DCaps.Caps2 & D3DCAPS2_CANRENDERWINDOWED)
				{
					isHALWindowedCompatible=TRUE;

					if (iFmt==0)
						isHALDesktopCompatible=TRUE;
                
				}
			}

			// Confirm the device/format for HW vertex processing
			if (m_kD3DCaps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT)
			{
				if (m_kD3DCaps.DevCaps & D3DDEVCAPS_PUREDEVICE)
				{
					dwD3DBehavior=D3DCREATE_HARDWARE_VERTEXPROCESSING|D3DCREATE_PUREDEVICE;

					if (pfnConfirmDevice(m_kD3DCaps, dwD3DBehavior, eD3DFmtPixel))
						isFormatConfirmed = TRUE;
				}

				if (FALSE == isFormatConfirmed)
				{
					dwD3DBehavior = D3DCREATE_HARDWARE_VERTEXPROCESSING;

					if (pfnConfirmDevice(m_kD3DCaps, dwD3DBehavior, eD3DFmtPixel))
						isFormatConfirmed = TRUE;
				}

				if (FALSE == isFormatConfirmed)
				{
					dwD3DBehavior = D3DCREATE_MIXED_VERTEXPROCESSING;

					if (pfnConfirmDevice(m_kD3DCaps, dwD3DBehavior, eD3DFmtPixel))
						isFormatConfirmed = TRUE;
				}	
			}

			// Confirm the device/format for SW vertex processing        
			if (FALSE == isFormatConfirmed)
			{
				dwD3DBehavior = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
				
				if (pfnConfirmDevice(m_kD3DCaps, dwD3DBehavior, eD3DFmtPixel))
					isFormatConfirmed = TRUE;            
			}
			
			if (isFormatConfirmed)
			{
				if (!FindDepthStencilFormat(rkD3D, iD3DAdapterInfo, c_eD3DDevType, eD3DFmtPixel, &aeD3DFmtDepthStencil[iFmt]))
					isFormatConfirmed = TRUE;
            
			}
			
			adwD3DBehavior[iFmt]=dwD3DBehavior;
			aisFormatConfirmed[iFmt]=isFormatConfirmed;
		}
	}

	// BuildModeInfoList
	{
		UINT uD3DDMNum=rkD3DADMList.GetDisplayModeNum();
		UINT uD3DFmtNum=rkD3DADMList.GetPixelFormatNum();


		for (UINT iD3DDM=0; iD3DDM<uD3DDMNum; ++iD3DDM)
		{
			const D3DDISPLAYMODE& c_rkD3DDM=rkD3DADMList.GetDisplayModer(iD3DDM);
			for (DWORD iFmt=0; iFmt<uD3DFmtNum; ++iFmt)
			{			
				if (rkD3DADMList.GetPixelFormatr(iFmt)==c_rkD3DDM.Format)
				{
					if (aisFormatConfirmed[iFmt] == TRUE )
					{
						D3D_SModeInfo& rkModeInfo=m_akD3DModeInfo[m_uD3DModeInfoNum++];
						rkModeInfo.m_uScrWidth=c_rkD3DDM.Width;
						rkModeInfo.m_uScrHeight=c_rkD3DDM.Height;
						rkModeInfo.m_eD3DFmtPixel=c_rkD3DDM.Format;
						rkModeInfo.m_dwD3DBehavior=adwD3DBehavior[iFmt];
						rkModeInfo.m_eD3DFmtDepthStencil=aeD3DFmtDepthStencil[iFmt];
						
						if( m_eD3DDevType == D3DDEVTYPE_HAL )
							isHALSampleCompatible = TRUE;
					}
				}
			}
		}
	}

	// Check if the device is compatible with the desktop display mode
	// (which was added initially as formats[0])
	if (aisFormatConfirmed[0] && (m_kD3DCaps.Caps2 & D3DCAPS2_CANRENDERWINDOWED) )
	{
		m_canDoWindowed=TRUE;
		m_isWindowed=TRUE;
	}
	
	if (m_uD3DModeInfoNum>0)
		return TRUE;

	return FALSE;
}
Exemple #3
0
void BuildList(IDirect3D9* pD3D, GraphicsInfo* pGI)
{
	if(!pD3D)
	{
		return;
	}

	const DWORD dwNumDeviceTypes = 1;
	const char* szDeviceDescs[] = {"HAL"};
	const D3DDEVTYPE DeviceTypes[] = {D3DDEVTYPE_HAL};

	const int MAXNUMDISPLAYMODES = 100;
	const int MAXNUMFORMATS = 30;

	bool bHalExists = false;
	bool bHalIsSampleCompatible = false;

	int iNumAdapters = pD3D->GetAdapterCount();
	if(iNumAdapters <= 0)
	{
		return;
	}

	int iAdapter = 0;
	for(; iAdapter < iNumAdapters; ++iAdapter)
	{
		AdapterInfo ai;
		pD3D->GetAdapterIdentifier(iAdapter, 0, &ai.AdapterIdentifier);
		ai.dwCurrentDevice = 0;

		D3DDISPLAYMODE DisplayModes[MAXNUMDISPLAYMODES];  // of this adpater
		D3DFORMAT Formats[MAXNUMFORMATS];  // of this adpater
		DWORD dwNumDisplayModes = 0;  // of this adpater
		DWORD dwNumFormats = 0;  // of this adpater

		DWORD dwNumAdapterModes = pD3D->GetAdapterModeCount(iAdapter, 0);
		DWORD dwAdapterMode = 0;
		for(; dwAdapterMode < dwNumAdapterModes; ++dwAdapterMode)  // 填充显示模式和格式的数组
		{
			D3DDISPLAYMODE dm;
			pD3D->EnumAdapterModes(iAdapter, dwAdapterMode, &dm);

			// 只要分辨率大于等于640*480的16bits高彩(565)、24bits真彩、32bits真彩
			if(dm.Width < 640 || dm.Height < 480 || (dm.Format != D3DFMT_R5G6B5 && dm.Format != D3DFMT_R8G8B8 && dm.Format != D3DFMT_A8R8G8B8))  // && dm.Format != D3DFMT_X1R5G5B5 && dm.Format != FMT_A1R5G5B5 && dm.Format != D3DFMT_R8G8B8 && dm.Format != D3DFMT_A8R8G8B8D3D)
			{
				continue;
			}

			DWORD m = 0;
			for(; m < dwNumDisplayModes; ++m)
			{
				if(DisplayModes[m].Width == dm.Width && DisplayModes[m].Height == dm.Height && DisplayModes[m].Format == dm.Format)
				{
					if(DisplayModes[m].RefreshRate < dm.RefreshRate)
					{
						DisplayModes[m].RefreshRate = dm.RefreshRate;
					}

					break;
				}
			}

			// 找到了一个新的显示模式
			if(m == dwNumDisplayModes)
			{
				DisplayModes[m].Width = dm.Width;
				DisplayModes[m].Height = dm.Height;
				DisplayModes[m].Format = dm.Format;
				DisplayModes[m].RefreshRate = dm.RefreshRate;
				++dwNumDisplayModes;

				DWORD f = 0;
				for(; f < dwNumFormats; ++f)
				{
					if(Formats[f] == dm.Format)
					{
						break;
					}
				}

				// 找到了一个新的格式
				if(f == dwNumFormats)
				{
					Formats[dwNumFormats++] = dm.Format;
				}
			}
		}

		qsort(DisplayModes, dwNumDisplayModes, sizeof(D3DDISPLAYMODE), SortModesCallback);

		// We have already get all display formats wanted
		int iDevice = 0;
		for(; iDevice < dwNumDeviceTypes; ++iDevice)
		{
			DeviceInfo di;
			di.DeviceType = DeviceTypes[iDevice];
			pD3D->GetDeviceCaps(iAdapter, DeviceTypes[iDevice], &di.Caps);
			di.sDesc = string(szDeviceDescs[iDevice]);
			di.dwCurrentMode = 0;
			di.MultiSampleType = D3DMULTISAMPLE_NONE;  // Here is not correct!

			bool bFormatConfirmed[MAXNUMFORMATS];
			DWORD dwBehaviors[MAXNUMFORMATS];
			D3DFORMAT DepthStencilFormats[MAXNUMFORMATS];

			DWORD f = 0;
			for(; f < dwNumFormats; ++f)  // 检查格式是否合适并填充DepthStencilFormats数组
			{
				bFormatConfirmed[f] = false;
				DepthStencilFormats[f] = D3DFMT_UNKNOWN;

				if(FAILED(pD3D->CheckDeviceType(iAdapter, di.DeviceType, Formats[f], Formats[f], NULL)))
				{
					continue;
				}

				if(di.DeviceType == D3DDEVTYPE_HAL)
				{
					bHalExists = true;
				}

				if(di.Caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT)
				{
					if(di.Caps.DevCaps & D3DDEVCAPS_PUREDEVICE)
					{
						dwBehaviors[f] = D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE;

						if(SUCCEEDED(ConfirmDevice(&di.Caps, dwBehaviors[f], Formats[f])))
						{
							bFormatConfirmed[f] = true;
						}
					}

					if(!bFormatConfirmed[f])
					{
						dwBehaviors[f] = D3DCREATE_HARDWARE_VERTEXPROCESSING;

						if(SUCCEEDED(ConfirmDevice(&di.Caps, dwBehaviors[f], Formats[f])))
						{
							bFormatConfirmed[f] = true;
						}
					}

					if(!bFormatConfirmed[f])
					{
						dwBehaviors[f] = D3DCREATE_MIXED_VERTEXPROCESSING;

						if(SUCCEEDED(ConfirmDevice(&di.Caps, dwBehaviors[f], Formats[f])))
						{
							bFormatConfirmed[f] = true;
						}
					}
				}

				if(!bFormatConfirmed[f])
				{
					dwBehaviors[f] = D3DCREATE_SOFTWARE_VERTEXPROCESSING;

					if(SUCCEEDED(ConfirmDevice(&di.Caps, dwBehaviors[f], Formats[f])))
					{
						bFormatConfirmed[f] = true;
					}
				}

				if(bFormatConfirmed[f])
				{
					if(!FindDepthStencilFormat(pD3D, pGI->m_dwDepthBits, pGI->m_dwStencilBits, iAdapter, di.DeviceType, Formats[f], &DepthStencilFormats[f]))
					{
						bFormatConfirmed[f] = false;
					}
				}
			}

			// 检查是否找到了合适的格式
			for(f = 0; f < dwNumFormats; ++f)
			{
				if(bFormatConfirmed[f])
				{
					break;
				}
			}
			if(f == dwNumFormats)
			{
				throw GameError("[BuildList] No valid format detected!");
			}

			DWORD d = 0;
			for(; d < dwNumDisplayModes; ++d)
			{
				DWORD f = 0;
				for(; f < dwNumFormats; ++f)
				{
					if(DisplayModes[d].Format == Formats[f])
					{
						if(bFormatConfirmed[f])
						{
							ModeInfo mi;

							mi.Width = DisplayModes[d].Width;
							mi.Height = DisplayModes[d].Height;
							mi.Format = DisplayModes[d].Format;
							mi.RefreshRate = DisplayModes[d].RefreshRate;
							mi.dwBehavior = dwBehaviors[f];
							mi.DepthStencilFormat = DepthStencilFormats[f];

							di.vtModes.push_back(mi);

							if(di.DeviceType == D3DDEVTYPE_HAL)
							{
								bHalIsSampleCompatible = true;
							}
						}
					}
				}
			}

			bool bSizeValid = false;
			for(d = 0; d < di.vtModes.size(); ++d)
			{
				if(di.vtModes[d].Width >= pGI->m_dwWidth && di.vtModes[d].Height >= pGI->m_dwHeight)
				{
					di.dwCurrentMode = d;
					bSizeValid = true;

					if(di.vtModes[d].Format == D3DFMT_R5G6B5)
					{
						break;
					}
				}
			}

			if(!bSizeValid)
			{
				throw GameError("[BuildList] Default display mode for menu invalid!");
			}

			if(di.vtModes.size() > 0)
			{
				ai.vtDevices.push_back(di);
			}
		}

		if(ai.vtDevices.size() > 0)
		{
			pGI->m_vtAdapters.push_back(ai);
		}
	}

	if(pGI->m_vtAdapters.size() <= 0)
	{
		throw GameError("[BuildList] No compatible devices!");
	}
}
int EnumerateDriver(D3DDEVICEINFO **tabdev)
{
   typedef char devDesc[4];
   unsigned int i, j, k;
   const DWORD dwNumDeviceTypes = 1;
   devDesc strDeviceDescs[2] = { "HAL", "REF" };
   const D3DDEVTYPE DeviceTypes[] = { D3DDEVTYPE_HAL, D3DDEVTYPE_REF };
   BOOL bHALExists = FALSE;
   BOOL bHALIsWindowedCompatible = FALSE;
   BOOL bHALIsDesktopCompatible = FALSE;
   BOOL bHALIsSampleCompatible = FALSE;

   g_pD3D = Direct3DCreate9(D3D_SDK_VERSION);
   D3DDISPLAYMODE modes[100];
   D3DFORMAT      formats[20];
   DWORD dwNumFormats      = 0;
   DWORD dwNumModes        = 0;
   DWORD dwNumAdapterModes = g_pD3D->GetAdapterModeCount(0, D3DFMT_A8R8G8B8);
   DWORD dwNumDevices;

   for(i=0; i < dwNumAdapterModes; i++)
   {
      // Get the display mode attributes
      D3DDISPLAYMODE DisplayMode;
      g_pD3D->EnumAdapterModes(0, D3DFMT_A8R8G8B8, i, &DisplayMode);

      // Check if the mode already exists (to filter out refresh rates)
      for(j=0; j<dwNumModes; j++)
      {
         if(( modes[j].Width  == DisplayMode.Width  ) &&
            ( modes[j].Height == DisplayMode.Height ) &&
            ( modes[j].Format == DisplayMode.Format ))
                    break;
	  }
      // If we found a new mode, add it to the list of modes
      if (j == dwNumModes)
      {
         modes[dwNumModes].Width       = DisplayMode.Width;
         modes[dwNumModes].Height      = DisplayMode.Height;
         modes[dwNumModes].Format      = DisplayMode.Format;
         modes[dwNumModes].RefreshRate = 0;
         dwNumModes++;

         // Check if the mode's format already exists
         for(k=0; k<dwNumFormats; k++)
         {
            if (DisplayMode.Format == formats[k]) break;
		 }
         // If the format is new, add it to the list
         if(k==dwNumFormats) formats[dwNumFormats++] = DisplayMode.Format;
	  }
   }
   // Sort the list of display modes (by format, then width, then height)
   qsort(modes, dwNumModes, sizeof(D3DDISPLAYMODE), SortModesCallback);

   // Add devices to adapter
   dwNumDevices=0;
   for(i=0; i<dwNumDeviceTypes; i++)
   {
     // Fill in device info
     D3DDEVICEINFO *pDevice;
     pDevice  = &g_Devices[dwNumDevices];
	 pDevice->DeviceType = DeviceTypes[i];
	 // se non ci sono devices HAL o T&L ritorna errore
	 if (g_pD3D->GetDeviceCaps(0, D3DDEVTYPE_HAL, &pDevice->d3dCaps)!=D3D_OK)
	    return(-1);

     strcpy(pDevice->strDesc, strDeviceDescs[i]);
     pDevice->dwNumModes     = 0;
     pDevice->bCanDoWindowed = FALSE;
     pDevice->MultiSampleType = D3DMULTISAMPLE_NONE;

     // Examine each format supported by the adapter to see if it will
     // work with this device and meets the needs of the application.
     BOOL  bFormatConfirmed[20];
     DWORD dwBehavior[20];
     D3DFORMAT fmtDepthStencil[20];

     for(DWORD f=0; f<dwNumFormats; f++)
     {
        bFormatConfirmed[f] = FALSE;
        fmtDepthStencil[f] = D3DFMT_UNKNOWN;
        // Skip formats that cannot be used as render targets on this device
        if( FAILED(g_pD3D->CheckDeviceType(0, pDevice->DeviceType,
                                            formats[f], formats[f], FALSE )))
        continue;

        if(pDevice->DeviceType == D3DDEVTYPE_HAL )
        {
           // This system has a HAL device
           bHALExists = TRUE;
           if(pDevice->d3dCaps.Caps2)
           {
               // HAL can run in a window for some mode
               bHALIsWindowedCompatible = TRUE;
			   /*
               if(f == 0)
               {
                   // HAL can run in a window for the current desktop mode
                   bHALIsDesktopCompatible = TRUE;
               }
			   */
           }
		}

       // Confirm the device/format for HW vertex processing
       if (pDevice->d3dCaps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT)
       {
          if (pDevice->d3dCaps.DevCaps & D3DDEVCAPS_PUREDEVICE)
          {
              dwBehavior[f] = D3DCREATE_HARDWARE_VERTEXPROCESSING |
                              D3DCREATE_PUREDEVICE;
              bFormatConfirmed[f] = TRUE;
          }
          if (FALSE == bFormatConfirmed[f])
          {
             dwBehavior[f] = D3DCREATE_HARDWARE_VERTEXPROCESSING;
             bFormatConfirmed[f] = TRUE;
          }
          if (FALSE == bFormatConfirmed[f])
          {
             dwBehavior[f] = D3DCREATE_MIXED_VERTEXPROCESSING;
             bFormatConfirmed[f] = TRUE;
          }
	   }
       // Confirm the device/format for SW vertex processing
       if(bFormatConfirmed[f]==FALSE)
       {
         dwBehavior[f] = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
         bFormatConfirmed[f] = TRUE;
       }

       // Find a suitable depth/stencil buffer format for this device/format
       if(bFormatConfirmed[f])
       {
           if(!FindDepthStencilFormat(0, pDevice->DeviceType,
                         formats[f], &fmtDepthStencil[f]))
           {
              bFormatConfirmed[f] = FALSE;
		   }
       }
	 }

     // Add all enumerated display modes with confirmed formats to the
     // device's list of valid modes
     for(DWORD m=0L; m<dwNumModes; m++)
     {
         for( DWORD f=0; f<dwNumFormats; f++)
         {
             if (modes[m].Format == formats[f])
             {
                 if(bFormatConfirmed[f] == TRUE)
                 {
                   // Add this mode to the device's list of valid modes
                   pDevice->SupportedModes[pDevice->dwNumModes].Width      = modes[m].Width;
                   pDevice->SupportedModes[pDevice->dwNumModes].Height     = modes[m].Height;
                   pDevice->SupportedModes[pDevice->dwNumModes].Format     = modes[m].Format;
                   pDevice->SupportedModes[pDevice->dwNumModes].Bpp        = D3DFormat2Bpp(modes[m].Format);
                   pDevice->SupportedModes[pDevice->dwNumModes].dwBehavior = dwBehavior[f];
                   pDevice->SupportedModes[pDevice->dwNumModes].DepthStencilFormat = fmtDepthStencil[f];
                   pDevice->dwNumModes++;

                   if(pDevice->DeviceType == D3DDEVTYPE_HAL)
                                bHALIsSampleCompatible = TRUE;
                 }
              }
         }
	 }
     if (pDevice->d3dCaps.Caps2) pDevice->bCanDoWindowed = TRUE;
     if (pDevice->dwNumModes > 0) dwNumDevices++;
   }

   if(0 == dwNumDevices)
   {
	  *tabdev=NULL;
      return -1;
   }
   else
   {
	 *tabdev=g_Devices;
	 return(dwNumDevices);
   }
}
int32 CRenderLib::m_EnumerateScreenModes (void)
{
  uint32 i, j, k;
  DWORD NumAdapterModes;
  D3DDISPLAYMODE DisplayMode;
  D3DDISPLAYMODE Modes[100];
  DWORD NumModes;
  D3DFORMAT Formats[20];
  D3DFORMAT DepthStencilFormats[20];
  BOOL FormatConfirmed[20];
  DWORD NumFormats;
	 
  if (!p_IsDeviceCreated) return(0);

  NumAdapterModes=p_D3D->GetAdapterModeCount(D3DADAPTER_DEFAULT);
  NumModes=0;
  NumFormats=0;
  for(i=0; i<NumAdapterModes; i++)
  {
     p_D3D->EnumAdapterModes(D3DADAPTER_DEFAULT, i, &DisplayMode);
     for(j=0; j<NumModes; j++)
	 {
       if ((Modes[j].Width==DisplayMode.Width) &&
           (Modes[j].Height==DisplayMode.Height) &&
           (Modes[j].Format==DisplayMode.Format))
          break;
	 }
     if (j==NumModes)
     {
        Modes[NumModes].Width=DisplayMode.Width;
        Modes[NumModes].Height=DisplayMode.Height;
        Modes[NumModes].Format=DisplayMode.Format;
        Modes[NumModes].RefreshRate = 0;
        NumModes++;

        // Check if the mode's format already exists
        for(k=0; k<NumFormats; k++)
        {
           if (DisplayMode.Format==Formats[k]) break;
		}
        // If the format is new, add it to the list
        if(k==NumFormats)
		  Formats[NumFormats++]=DisplayMode.Format;
	 }
  }
  // Sort the list of display modes (by format, then width, then height)
  qsort(Modes, NumModes, sizeof(D3DDISPLAYMODE), SortModesCallback);

  // uso i soli formati che possono usati come target di un rendering
  for(i=0; i<NumFormats; i++)
  {
     FormatConfirmed[i]=FALSE;
     // Skip formats that cannot be used as render targets on this device
     if (FAILED(p_D3D->CheckDeviceType(D3DADAPTER_DEFAULT, p_DeviceType,
                                       Formats[i], Formats[i], FALSE)))
     continue;

     // Find a suitable depth/stencil buffer format for this device/format
     if (!FindDepthStencilFormat(D3DADAPTER_DEFAULT, p_DeviceType,
                                 Formats[i], &DepthStencilFormats[i]))
       FormatConfirmed[i] = FALSE;
	 else FormatConfirmed[i]=TRUE;
  }

  // espongo i modi video trovati, mettendo solo quelli con un format
  // video confermato dalla verifica appena compiuta
  p_DeviceInfo.NumSupportedModes=0;
  for(i=0; i<NumModes; i++)
    for(j=0; j<NumFormats; j++)
    {
      if ((Modes[i].Format==Formats[j]) && (FormatConfirmed[j]))
	  {
        // Add this mode to the device's list of valid modes
        p_DeviceInfo.SupportedModes[p_DeviceInfo.NumSupportedModes].Width=Modes[i].Width;
        p_DeviceInfo.SupportedModes[p_DeviceInfo.NumSupportedModes].Height=Modes[i].Height;
        p_DeviceInfo.SupportedModes[p_DeviceInfo.NumSupportedModes].Format=Modes[i].Format;
        p_DeviceInfo.SupportedModes[p_DeviceInfo.NumSupportedModes].Bpp=D3DFormat2Bpp(Modes[i].Format);
        p_DeviceInfo.SupportedModes[p_DeviceInfo.NumSupportedModes].Behavior=p_DeviceInfo.Behavior;
        p_DeviceInfo.SupportedModes[p_DeviceInfo.NumSupportedModes].DepthStencilFormat = DepthStencilFormats[j];
        p_DeviceInfo.NumSupportedModes++;
	  }
    }

  p_IsEnumerationDone=1;
  return(NumModes);
}