Esempio n. 1
0
//--------------------------------------------------------------
// write device modes
void mgWriteDeviceModes(
  FILE* output,
  LPDIRECT3D9 d3d)
{
  int count = d3d->GetAdapterModeCount(D3DADAPTER_DEFAULT, D3DFMT_X8R8G8B8);
  fprintf(output, "\n");
  fprintf(output, "------------------ device modes -----------------\n");
  fprintf(output, "%d X8R8G8B8 modes.\n", count);
  D3DDISPLAYMODE mode;
  for (int i = 0; i < count; i++)
  {
    d3d->EnumAdapterModes(D3DADAPTER_DEFAULT, D3DFMT_X8R8G8B8, i, &mode);
    const char* format = "";
    switch (mode.Format)
    {
      case D3DFMT_R8G8B8: format="R8G8B8"; break;
      case D3DFMT_A8R8G8B8: format="A8R8G8B8"; break;
      case D3DFMT_X8R8G8B8: format="X8R8G8B8"; break;
      case D3DFMT_R5G6B5: format="R5G6B5"; break;
      case D3DFMT_X1R5G5B5: format="X1R5G5B5"; break;
      case D3DFMT_A1R5G5B5: format="A1R5G5B5"; break;
      case D3DFMT_A4R4G4B4: format="A4R4G4B4"; break;
      case D3DFMT_R3G3B2: format="R3G3B2"; break;
      case D3DFMT_A8R3G3B2: format="A8R3G3B2"; break;
      case D3DFMT_X4R4G4B4: format="X4R4G4B4"; break;
      case D3DFMT_A2B10G10R10: format="A2B10G10R10"; break;
      case D3DFMT_A2R10G10B10: format="A2R10G10B10"; break;
      default: format="??"; break;
    }
    fprintf(output, "%d by %d (%.2f), refresh=%d, format=%s\n", mode.Width, mode.Height, 
      (double) mode.Width / mode.Height, mode.RefreshRate, (const char*) format);
  }
}
Esempio n. 2
0
RString RageDisplay_D3D::Init( const VideoModeParams &p, bool /* bAllowUnacceleratedRenderer */ )
{
	GraphicsWindow::Initialize( true );

	LOG->Trace( "RageDisplay_D3D::RageDisplay_D3D()" );
	LOG->MapLog("renderer", "Current renderer: Direct3D");

	g_pd3d = Direct3DCreate9(D3D_SDK_VERSION);
	if(!g_pd3d)
	{
		LOG->Trace( "Direct3DCreate9 failed" );
		return D3D_NOT_INSTALLED.GetValue();
	}

	if( FAILED( g_pd3d->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &g_DeviceCaps) ) )
		return HARDWARE_ACCELERATION_NOT_AVAILABLE.GetValue();
			

	D3DADAPTER_IDENTIFIER9	identifier;
	g_pd3d->GetAdapterIdentifier( D3DADAPTER_DEFAULT, 0, &identifier );

	LOG->Trace( 
		"Driver: %s\n"
		"Description: %s\n"
		"Max texture size: %d\n"
		"Alpha in palette: %s\n",
		identifier.Driver, 
		identifier.Description,
		g_DeviceCaps.MaxTextureWidth,
		(g_DeviceCaps.TextureCaps & D3DPTEXTURECAPS_ALPHAPALETTE) ? "yes" : "no" );

	LOG->Trace( "This display adaptor supports the following modes:" );
	D3DDISPLAYMODE mode;

	UINT modeCount = g_pd3d->GetAdapterModeCount(D3DADAPTER_DEFAULT, g_DefaultAdapterFormat);

	for( UINT u=0; u < modeCount; u++ )
		if( SUCCEEDED( g_pd3d->EnumAdapterModes( D3DADAPTER_DEFAULT, g_DefaultAdapterFormat, u, &mode ) ) )
			LOG->Trace( "  %ux%u %uHz, format %d", mode.Width, mode.Height, mode.RefreshRate, mode.Format );

	g_PaletteIndex.clear();
	for( int i = 0; i < 256; ++i )
		g_PaletteIndex.push_back(i);

	// Save the original desktop format.
	g_pd3d->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &g_DesktopMode );

	/* Up until now, all we've done is set up g_pd3d and do some queries. Now,
	 * actually initialize the window. Do this after as many error conditions as
	 * possible, because if we have to shut it down again we'll flash a window briefly. */
	bool bIgnore = false;
	return SetVideoMode( p, bIgnore );
}
Esempio n. 3
0
void RageDisplay_D3D::GetDisplayResolutions( DisplayResolutions &out ) const
{
	out.clear();
	int iCnt = g_pd3d->GetAdapterModeCount( D3DADAPTER_DEFAULT, g_DefaultAdapterFormat );

	for( int i = 0; i < iCnt; ++i )
	{
		D3DDISPLAYMODE mode;
		g_pd3d->EnumAdapterModes( D3DADAPTER_DEFAULT, g_DefaultAdapterFormat, i, &mode );

		DisplayResolution res = { mode.Width, mode.Height };
		out.insert( res );
	}
}
Esempio n. 4
0
/*********************************************************************
* initDirect3D
* initializes direct3D
*********************************************************************/
bool initDirect3D()
{
	pD3D = NULL;

	// create the directX object
	if( NULL == ( pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )
	{
		return false;
	}

	// this section gets the adapter details
	D3DADAPTER_IDENTIFIER9 ident;
	pD3D->GetAdapterIdentifier(D3DADAPTER_DEFAULT, 0, &ident);	
	addItemToList("Adapter Details");
	addItemToList(ident.Description);
	addItemToList(ident.DeviceName);
	addItemToList(ident.Driver);
	
	// collects how many modes this adapter has
	UINT numModes = pD3D->GetAdapterModeCount(D3DADAPTER_DEFAULT, D3DFMT_X8R8G8B8);
	for (UINT i=0; i<numModes-1; i++)
	{
		D3DDISPLAYMODE mode;
		char modeString[255];
		// get the displaymode structure for this adapter mode
		pD3D->EnumAdapterModes(D3DADAPTER_DEFAULT, D3DFMT_X8R8G8B8, i, &mode);

		// draw a blank line in the listbox
		addItemToList("");
		// output the width
		sprintf(modeString, "Width=%d",mode.Width);
		addItemToList(modeString);
		// output the height
		sprintf(modeString, "Height=%d",mode.Height);		
		addItemToList(modeString);
		// output the refreshrate
		sprintf(modeString, "RefreshRate=%d",mode.RefreshRate);		
		addItemToList(modeString);		
	}	
	
	return true;
}
Esempio n. 5
0
HRESULT HookIDirect3D9::EnumAdapterModes(LPVOID _this, UINT Adapter,D3DFORMAT Format,UINT Mode,D3DDISPLAYMODE* pMode)
{
	LOG_API();
	return pD3D->EnumAdapterModes(Adapter, Format, Mode, pMode);
}
Esempio n. 6
0
/* If the given parameters have failed, try to lower them. */
bool D3DReduceParams( D3DPRESENT_PARAMETERS	*pp )
{
	D3DDISPLAYMODE current;
	current.Format = pp->BackBufferFormat;
	current.Height = pp->BackBufferHeight;
	current.Width = pp->BackBufferWidth;
	current.RefreshRate = pp->FullScreen_RefreshRateInHz;

	const int iCnt = g_pd3d->GetAdapterModeCount( D3DADAPTER_DEFAULT, g_DefaultAdapterFormat );
	int iBest = -1;
	int iBestScore = 0;
	LOG->Trace( "cur: %ux%u %uHz, format %i", current.Width, current.Height, current.RefreshRate, current.Format );
	for( int i = 0; i < iCnt; ++i )
	{
		D3DDISPLAYMODE mode;
		g_pd3d->EnumAdapterModes( D3DADAPTER_DEFAULT, g_DefaultAdapterFormat, i, &mode );

		/* Never change the format. */
		if( mode.Format != current.Format )
			continue;
		/* Never increase the parameters. */
		if( mode.Height > current.Height || mode.Width > current.Width || mode.RefreshRate > current.RefreshRate )
			continue;

		/* Never go below 640x480 unless we already are. */
		if( (current.Width >= 640 && current.Height >= 480) && (mode.Width < 640 || mode.Height < 480) )
			continue;

		/* Never go below 60Hz. */
		if( mode.RefreshRate && mode.RefreshRate < 60 )
			continue;

		/* If mode.RefreshRate is 0, it means "default".  We don't know what that means;
		 * assume it's 60Hz. */

		/* Higher scores are better. */
		int iScore = 0;
		if( current.RefreshRate >= 70 && mode.RefreshRate < 70 )
		{
			/* Top priority: we really want to avoid dropping to a refresh rate that's
			 * below 70Hz. */
			iScore -= 100000;
		}
		else if( mode.RefreshRate < current.RefreshRate )
		{
			/* Low priority: We're lowering the refresh rate, but not too far.  current.RefreshRate
			 * might be 0, in which case this simply gives points for higher refresh
			 * rates. */
			iScore += (mode.RefreshRate - current.RefreshRate);
		}

		/* Medium priority: */
		int iResolutionDiff = (current.Height - mode.Height) + (current.Width - mode.Width);
		iScore -= iResolutionDiff * 100;

		if( iBest == -1 || iScore > iBestScore )
		{
			iBest = i;
			iBestScore = iScore;
		}

		LOG->Trace( "try: %ux%u %uHz, format %i: score %i", mode.Width, mode.Height, mode.RefreshRate, mode.Format, iScore );
	}

	if( iBest == -1 )
		return false;

	D3DDISPLAYMODE BestMode;
	g_pd3d->EnumAdapterModes( D3DADAPTER_DEFAULT, g_DefaultAdapterFormat, iBest, &BestMode );
	pp->BackBufferHeight = BestMode.Height;
	pp->BackBufferWidth = BestMode.Width;
	pp->FullScreen_RefreshRateInHz = BestMode.RefreshRate;

	return true;
}
Esempio n. 7
0
CString RageDisplay_D3D::Init( VideoModeParams p )
{
	GraphicsWindow::Initialize();

	LOG->Trace( "RageDisplay_D3D::RageDisplay_D3D()" );
	LOG->MapLog("renderer", "Current renderer: Direct3D");

	typedef IDirect3D9 * (WINAPI * Direct3DCreate9_t) (UINT SDKVersion);
	Direct3DCreate9_t pDirect3DCreate9;
#if defined(XBOX)
	pDirect3DCreate8 = Direct3DCreate8;
#else
	g_D3D9_Module = LoadLibrary("D3D9.dll");
	if(!g_D3D9_Module)
		return D3D_NOT_INSTALLED;

	pDirect3DCreate9 = (Direct3DCreate9_t) GetProcAddress(g_D3D9_Module, "Direct3DCreate9");
	if(!pDirect3DCreate9)
	{
		LOG->Trace( "Direct3DCreate9 not found" );
		return D3D_NOT_INSTALLED;
	}
#endif

	g_pd3d = pDirect3DCreate9( D3D_SDK_VERSION );
	if(!g_pd3d)
	{
		LOG->Trace( "Direct3DCreate9 failed" );
		return D3D_NOT_INSTALLED;
	}

	if( FAILED( g_pd3d->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &g_DeviceCaps) ) )
		return
			"Your system is reporting that Direct3D hardware acceleration is not available.  "
			"Please obtain an updated driver from your video card manufacturer.\n\n";

	D3DADAPTER_IDENTIFIER9	identifier;
	g_pd3d->GetAdapterIdentifier( D3DADAPTER_DEFAULT, 0, &identifier );

	LOG->Trace( 
		"Driver: %s\n"
		"Description: %s\n"
		"Max texture size: %d\n"
		"Alpha in palette: %s\n",
		identifier.Driver, 
		identifier.Description,
		g_DeviceCaps.MaxTextureWidth,
		(g_DeviceCaps.TextureCaps & D3DPTEXTURECAPS_ALPHAPALETTE) ? "yes" : "no" );

	LOG->Trace( "This display adaptor supports the following modes:" );
	D3DDISPLAYMODE mode;
	UINT modeCount = g_pd3d->GetAdapterModeCount(D3DADAPTER_DEFAULT, g_DefaultAdapterFormat);
	
	for( UINT u=0; u<modeCount; u++ )
		if( SUCCEEDED( g_pd3d->EnumAdapterModes( D3DADAPTER_DEFAULT, g_DefaultAdapterFormat, u, &mode ) ) )
			LOG->Trace( "  %ux%u %uHz, format %d", mode.Width, mode.Height, mode.RefreshRate, mode.Format );

	g_PaletteIndex.clear();
	for( int i = 0; i < 256; ++i )
		g_PaletteIndex.push_back(i);

	// Save the original desktop format.
	g_pd3d->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &g_DesktopMode );

	/* Up until now, all we've done is set up g_pd3d and do some queries.  Now,
	 * actually initialize the window.  Do this after as many error conditions
	 * as possible, because if we have to shut it down again we'll flash a window
	 * briefly. */
	bool bIgnore = false;
	return SetVideoMode( p, bIgnore );
}
Esempio n. 8
0
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);
   }
}
Esempio n. 9
0
BOOL render_init( render_info_t * info )
{
	HRESULT LastError;
	render_viewport_t viewport;

	// should get this from d3d caps
	bSquareOnly = FALSE;

	// default gamma table
	build_gamma_table(1.0);

	// Set up Direct3D interface object
	lpD3D = Direct3DCreate9(D3D_SDK_VERSION);
	if (!lpD3D)
	{
		DebugPrintf("couldnt create d3d9\n");
		return FALSE;
	}

	// create d3d device
	D3DPRESENT_PARAMETERS d3dpp;
	ZeroMemory (&d3dpp, sizeof(d3dpp));

	//
	d3dpp.Windowed = !info->fullscreen;

	//
	// presentation settings
	//

	d3dpp.hDeviceWindow					= GetActiveWindow();			// the window handle
	d3dpp.BackBufferCount				= 1;							// we only have one swap chain
    d3dpp.SwapEffect					= D3DSWAPEFFECT_DISCARD;		// does not protect the contents of the backbuffer after flipping (faster)
																		// shouldn't we specify D3DSWAPEFFECT_FLIP ?
																		// wouldn't D3DSWAPEFFECT_OVERLAY be fastest ?
	d3dpp.FullScreen_RefreshRateInHz	= D3DPRESENT_RATE_DEFAULT;		// display refresh
	d3dpp.EnableAutoDepthStencil		= TRUE;							// let d3d manage the z-buffer

	if(info->vsync)	
		d3dpp.PresentationInterval		= D3DPRESENT_INTERVAL_ONE;			// enable vsync
	else
		d3dpp.PresentationInterval		= D3DPRESENT_INTERVAL_IMMEDIATE;	// disable vsync

	// 16 bit zbuffer
	//d3dpp.AutoDepthStencilFormat	= D3DFMT_D15S1; // 16 bit depth buffer with 1 bit stencil
	d3dpp.AutoDepthStencilFormat	= D3DFMT_D16;	// 16 bit depth buffer

	// 32 bit back buffer
	// Also supports 32 bit zbuffer
	if( SUCCEEDED(lpD3D->CheckDeviceType(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DFMT_X8R8G8B8, d3dpp.Windowed)))
	{
		bpp = 32;
		d3dpp.BackBufferFormat			= D3DFMT_X8R8G8B8;
		//d3dpp.AutoDepthStencilFormat	= D3DFMT_D32;	// 32 bit depth buffer
		d3dpp.AutoDepthStencilFormat	= D3DFMT_D24S8;	// 24 bit depth buffer with 8 bit stencil buffer
		DebugPrintf("picked 24 bit D3DFMT_X8R8G8B8 back buffer\n");
	}
	// 16 bit
	else if(SUCCEEDED(lpD3D->CheckDeviceType(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X1R5G5B5, D3DFMT_X1R5G5B5, d3dpp.Windowed)))
	{
		d3dpp.BackBufferFormat	= D3DFMT_X1R5G5B5;
		DebugPrintf("picked 16 bit D3DFMT_X1R5G5B5 back buffer\n");
	}
	// 16 bit 
	else if(SUCCEEDED(lpD3D->CheckDeviceType(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_R5G6B5, D3DFMT_R5G6B5, d3dpp.Windowed)))
	{
		d3dpp.BackBufferFormat	= D3DFMT_R5G6B5;
		DebugPrintf("picked 16 bit D3DFMT_R5G6B5 back buffer\n");
	}
	// failed
	else
	{
		CloseWindow(d3dpp.hDeviceWindow);
		Msg("Failed to find a suitable back buffer format");
		exit(1);
	}

	//
	// Enumerates display modes 
	// picking info->default_mode if it exists
	// or picking the biggest mode possible :]
	//

#if 0 // done by sdl now
	{
		int mode = 0;
		int desired_mode = -1;
		int best_mode = 0; // default to the first mode
		int i;
		int x = 0;
		int count				=  (int) lpD3D->GetAdapterModeCount( D3DADAPTER_DEFAULT, d3dpp.BackBufferFormat );
		info->Mode			= (render_display_mode_t *) malloc( count * sizeof(render_display_mode_t) );
		D3DDISPLAYMODE * modes	= (D3DDISPLAYMODE *) malloc( count * sizeof(D3DDISPLAYMODE) );
		for ( i = 0; i < count; i++ )
		{
			// get the mode description
			lpD3D->EnumAdapterModes( D3DADAPTER_DEFAULT, d3dpp.BackBufferFormat, i, &modes[i] );
			DebugPrintf("Enumerated mode: %dx%d @ %dhz , format=%d\n",
				modes[i].Width,modes[i].Height,modes[i].RefreshRate,modes[i].Format);

			// ignore modes under 640x480
			if(modes[i].Width < 640 || modes[i].Height < 480)
			{
				DebugPrintf("Skipping mode because it's to small for anyone to want...\n");
				continue;
			}

			// save the mode
			info->Mode[x].h    = modes[i].Height;
			info->Mode[x].w    = modes[i].Width;
			info->Mode[x].bpp  = bpp;

			// if this is the mode the user wanted pick it
			if(	info->Mode[x].w == info->default_mode.w &&
				info->Mode[x].h == info->default_mode.h )
			{
				desired_mode = x;
			}
			
			// smallest mode as default
			if( info->Mode[x].w < info->Mode[best_mode].w && 
				info->Mode[x].h < info->Mode[best_mode].h )
			{
				best_mode = x;
			}

			// biggest mode by width as default
			//if(info->Mode[x].w > info->Mode[best_mode].w )
			//	best_mode = x;

			// 800x600 @ 60 as default
			//if(	info->Mode[x].w == 800 && info->Mode[x].h == 600 )
			//	desired_mode = x;

			// go to next storage location
			x++;
		
		}
		info->NumModes = x;
		if( desired_mode >= 0 )
		{
			mode = desired_mode;
		}
		else
		{
			mode = best_mode;
		}
		info->CurrMode = mode;
		info->ThisMode = info->Mode[ info->CurrMode ];
		info->WindowsDisplay = info->Mode[ info->CurrMode ];
		info->window_size.cx		= info->ThisMode.w;
		info->window_size.cy		= info->ThisMode.h;
		info->WindowsDisplay.w  = info->ThisMode.w;
		info->WindowsDisplay.h  = info->ThisMode.h;
		free(modes);
	}
#endif // done by sdl now

	d3dpp.BackBufferWidth   = info->ThisMode.w;
	d3dpp.BackBufferHeight  = info->ThisMode.h;
		
	info->aspect_ratio		= (float) info->ThisMode.w / (float) info->ThisMode.h;

	DebugPrintf("Using display mode: %dx%d\n",
		info->ThisMode.w,info->ThisMode.h);

	// try to create a device falling back to less capable versions

	//
	// TODO
	// the docs say that pure devices don't support Get* calls
	// which explains why people are crashing on FSGet* functions for no reason
	// to support pure device we'd have to track our own states
	//

	/*
	LastError = lpD3D->CreateDevice(
		D3DADAPTER_DEFAULT,							// the default video card 
		D3DDEVTYPE_HAL,								// device type - hal = Hardware rasterization
		d3dpp.hDeviceWindow,							// the window handle

		// these define how the device is created

		D3DCREATE_HARDWARE_VERTEXPROCESSING |		// do vertex processing in hardware
		D3DCREATE_PUREDEVICE, 						// D3D will not support Get* calls for anything that can be stored in state blocks.
													// and not to provide any emulation services for vertex processing.
													// Thus if the device does not support vertex processing,
													// then the application can use only post-transformed vertices.

		&d3dpp,										// presentation parameters defined above
		&lpD3DDevice						// pointer that will contain the returned device
	);

	if (SUCCEEDED(LastError))
	{
		Msg("pure");
	}

	if (FAILED(LastError)) 
	*/
	{
		LastError = lpD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, d3dpp.hDeviceWindow,
			D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp, &lpD3DDevice);
		if (SUCCEEDED(LastError))
		{
			DebugPrintf("d3d device created: hardware\n");
		}
		else
		{
			const char * error = render_error_description(LastError);
			DebugPrintf("d3d device create failed with hardware: %s\n",error);
		}
	}

	if (FAILED(LastError)) 
	{
		LastError = lpD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, d3dpp.hDeviceWindow,
			D3DCREATE_MIXED_VERTEXPROCESSING,		// do vertex processing in both hardware and software
			&d3dpp, &lpD3DDevice);
		if (SUCCEEDED(LastError))
		{
			DebugPrintf("d3d device created: mixed\n");
		}
		else
		{
			const char * error = render_error_description(LastError);
			DebugPrintf("d3d device create failed with mixed: %s\n",error);
		}
	}

	if (FAILED(LastError)) 
	{
		LastError = lpD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, d3dpp.hDeviceWindow,
			D3DCREATE_SOFTWARE_VERTEXPROCESSING,	// do vertex processing in software only
			&d3dpp, &lpD3DDevice);
		if (SUCCEEDED(LastError))
		{
			DebugPrintf("d3d device created: software\n");
		}
		else
		{
			const char * error = render_error_description(LastError);
			DebugPrintf("d3d device create failed with software: %s\n",error);
		}
	}

	if (FAILED(LastError))
	{
		CloseWindow(d3dpp.hDeviceWindow);
		Msg("Failed to create a suitable d3d device:\n%s",
			render_error_description(LastError));
		exit(1);
	}

	info->ok_to_render = TRUE;

	viewport.X = 0;
	viewport.Y = 0;
	/* do "after device created" stuff */
	ZeroMemory( &viewport, sizeof(viewport) );
	{
		WINDOWPLACEMENT placement;
		placement.length = sizeof(WINDOWPLACEMENT);
		if(GetWindowPlacement( d3dpp.hDeviceWindow, &placement ))
		{
			viewport.X = placement.rcNormalPosition.left;
			viewport.Y = placement.rcNormalPosition.top;
		}
	}
	viewport.Width = d3dpp.BackBufferWidth;
	viewport.Height = d3dpp.BackBufferHeight;
	viewport.MinZ = 0.0f;
	viewport.MaxZ = 1.0f;

	LastError = FSSetViewPort(&viewport);
	if (!LastError)
	{
		DebugPrintf("couldn't set viewport\n");
	}

    if(!init_render_states( info ))
		return FALSE;

	return TRUE;
}