/*
	COMPAT.CFG

	This file is used by the game to determine certain settings related
	to graphics compatibility which may need to be changed after the game
	has been released (either by the users themselves or with the help
	of tech support).  For example, after the game has been out for some
	time, there may be a new graphics chipset on the market which causes
	unforeseen graphical glitches within the game.  The settings in this
	file can allow the game to be more easily tuned to specific hardware,
	to help handle some of these kinds of situations.
*/

/*
-----------------------------------------------------------------------------
	CONSTANTS
-----------------------------------------------------------------------------
*/
/*
	Vendor constants - these are PCI vendor IDs for makers of various
	graphics chipsets.  Feel free to add to this at will.
*/
var int VENDOR_NVIDIA	= 0x10DE;
var int VENDOR_ATI		= 0x1002;
var int VENDOR_INTEL	= 0x8086;
var int VENDOR_SIS		= 0x1039;
var int VENDOR_MATROX	= 0x102B;

/*
-----------------------------------------------------------------------------
	APP INITIALIZATION
-----------------------------------------------------------------------------
*/
// the following properties are available during app initialization
property int compat_AppVidMemory;
property int compat_AppSysMemFreeMB;
property int compat_AppSysMemTotalMB;
property int compat_AppOrigScreenWidth;
property int compat_AppOrigScreenHeight;

/*
	GetAppDefaultArtRes - returns the default art resolution to use
*/
function(int) GetAppDefaultArtRes
{
	/* CDH commented out: not going to use Ultra as a default, for perf reasons; users can still change to Ultra of course
	if ((compat_AppSysMemTotalMB >= 768) && (compat_AppOrigScreenHeight >= 1200) && (compat_AppVidMemory >= 92))
	{		
		return 1200;
	}
	else
	*/
	if ((compat_AppSysMemTotalMB >= 256) && (compat_AppOrigScreenHeight >= 600) && (compat_AppVidMemory >= 60))
	{
		return 768;
	}
	else
	{
		return 600;
	}
}

/*
-----------------------------------------------------------------------------
	DD & D3D INITIALIZATION
-----------------------------------------------------------------------------
*/
// the following properties are available after D3D initialization
property int compat_D3DInterface;
property int compat_D3DVendorID;
property int compat_D3DDeviceID;
property string compat_D3DDeviceDescription;
property int compat_D3DDriverVersionA;
property int compat_D3DDriverVersionB;
property int compat_D3DDriverVersionC;
property int compat_D3DDriverVersionD;
property string compat_D3DDriverVersion; // "A.B.C.D"
property string compat_D3DDriverName; // usually the name of the driver dll
property float compat_D3DVSVersion;
property float compat_D3DPSVersion;
property bool compat_IsVista;

// these properties are fallbacks for specific in-game shaders; 0 is the default
// The properties are named (shadername)_fallback or (shadername)_fallback_forced,
// although the forced form should be used sparingly as it bypasses validation.
property int shader_whiteout_fallback = 0;
property int shader_sidebar_p_fallback = 0;
property int shader_sidebar_tube_p_fallback = 0;
property int shader_sidebar_engine_p_fallback = 0;
property int shader_cube_p_fallback = 0;
property int shader_rainbow_cube_p_fallback = 0;

// internal function to initialize shader fallbacks
function InitShaders
{
	var int vendor = compat_D3DVendorID;
	var int device = compat_D3DDeviceID;

	var int maxstages = 4;

	if (vendor == VENDOR_NVIDIA)
	{
		if (device < 0x0200) // NV20, aka GeForce3
			maxstages = 2; // geforce 2 (NV11-16) and geforce 4 mx (NV17-18) era cards
		else if (compat_D3DPSVersion < 1.0)
			maxstages = 2;
	}
	else if (vendor == VENDOR_INTEL)
	{
		if (compat_D3DPSVersion < 1.0)
			maxstages = 1;
	}
	else
	{
		if (compat_D3DPSVersion < 1.0)
			maxstages = 2;
	}

	if (maxstages == 2)
	{
		shader_whiteout_fallback = 2;
		shader_sidebar_p_fallback = 2;
		shader_rainbow_cube_p_fallback = 2;
	}
	else if (maxstages == 1)
	{
		shader_whiteout_fallback = 3;
		shader_sidebar_p_fallback = 3;
		shader_sidebar_tube_p_fallback = 2;
		shader_rainbow_cube_p_fallback = 3;
	}

	log("maxstages = " + maxstages);
	log("shader_whiteout = " + shader_whiteout_fallback);
	log("shader_sidebar_p = " + shader_sidebar_p_fallback);
	log("shader_sidebar_tube_p = " + shader_sidebar_tube_p_fallback);
	log("shader_sidebar_engine_p = " + shader_sidebar_engine_p_fallback);
	log("shader_cube_p = " + shader_cube_p_fallback);
	log("shader_rainbow_cube_p = " + shader_rainbow_cube_p_fallback);
}

/*
	Is3DSupported - returns whether the current D3D interface settings are
	acceptable (if this function is called, all other aspects of D3D
	initialization have passed for that particular compat_D3DInterface,
	so this function gets a final yea/nay on it).  The default should be true.
*/
function(bool) Is3DSupported
{
	if (compat_D3DVendorID == VENDOR_SIS)
	{
		log("Returning Is3DSupported false due to SIS");
		return false;
	}
	else if (compat_D3DVendorID == VENDOR_NVIDIA)
	{
		if ((compat_D3DDeviceID >= 0x100) && (compat_D3DDeviceID < 0x110)) // GeForce1 (aka GeForce 256) range
		{
			log("Returning Is3DSupported false due to old nVidia GeForce 1 card");
			return false;
		}
		else
		{
			return true;
		}
	}
	else if (compat_D3DVendorID == VENDOR_ATI)
	{
		if (compat_D3DDeviceID == 0x5159) // Radeon 7000
		{
			log("Returning Is3DSupported false due to old Radeon 7000 card");
			return false;
		}
		else if ((compat_D3DInterface == 9) && (compat_D3DDriverVersion == "6.14.10.6599"))
		{
			log("Returning Is3DSupported false due to bad ATI D3D9 driver");
			return false;
		}
		else
		{
			return true;
		}
	}
	else if (compat_D3DVendorID == VENDOR_MATROX)
	{
		log("Returning Is3DSupported false due to Matrox");
		return false;
	}

	return true;
}

/*
	Is3DRecommended - returns whether the current D3D interface settings
	indicate that 3D support is recommended, not just technically possible.
	This is primarily used to indicate buggy/flaky drivers, where we don't want
	to strictly disable 3D (and make the user think their hardware is inferior),
	but need to give some indication to them that a driver update would be a
	very good idea.
*/
function(bool) Is3DRecommended
{
	if (compat_D3DVendorID == VENDOR_NVIDIA)
	{
		if (compat_IsVista && (compat_D3DDriverVersion == "7.15.10.9686"))
		{
			log("Returning Is3DRecommended false due to bad default Vista driver for nVidia cards");
			return false;
		}
		else if (compat_D3DDeviceID < 0x0200) // NV20, aka GeForce3
		{
			// need at least 6.14.10.9371
			var bool isGoodDriver = true;

			if (compat_D3DDriverVersionA < 6)
			{
				isGoodDriver = false;
			}
			else if (compat_D3DDriverVersionA == 6)
			{
				if (compat_D3DDriverVersionB < 14)
				{
					isGoodDriver = false;
				}
				else if (compat_D3DDriverVersionB == 14)
				{
					if (compat_D3DDriverVersionC < 10)
					{
						isGoodDriver = false;
					}
					else if (compat_D3DDriverVersionC == 10)
					{
						if (compat_D3DDriverVersionD < 9371)
						{
							isGoodDriver = false;
						}
					}
				}
			}

			if (!isGoodDriver)
			{
				log("Returning Is3DRecommended false due to outdated legacy GeForce2/4MX driver");
				return false;
			}
		}
	}
	else if (compat_D3DVendorID == VENDOR_ATI)
	{
		if ((compat_D3DDeviceID == 0x5960) || (compat_D3DDeviceID == 0x5961)) // Radeon 9200/9250
		{
			log("Returning Is3DRecommended false due to Radeon 9200/9250 card");
			return false;
		}
	}

	return true;
}

/*
	NeedMatchDepthBufferBits - returns whether the card needs its depth buffer
	bit depth to match the color buffer bit depth; used primarily with older hardware.
*/
function(bool) NeedMatchDepthBufferBits
{
	if (compat_D3DVendorID == VENDOR_NVIDIA)
	{
		if (compat_D3DDeviceID < 0x0200) // NV20, aka GeForce3
		{
			return true; // geforce 2 (NV11-16) and geforce 4 mx (NV17-18) era cards
		}
	}

	return false;
}

/*
	IsHighResSupported & IsUltraResSupported - returns whether 768p or 1200p
	resolution (respectively) is supported.  The same D3D initialization
	settings from Is3DSupported should be available.  Default should be true.
*/
function(bool) IsHighResSupported
{
	if (compat_AppVidMemory < 60)
		return false;

	return true;
}

function(bool) IsUltraResSupported
{
	if (compat_AppVidMemory < 92)
		return false;

	return true;
}

/*
	DDInterfaceReady - called after the DDInterface has been initialized,
	including any D3DInterface that may be within it
*/
function DDInterfaceReady
{
	if (compat_D3DInterface > 0)
	{
		call InitShaders();
	}
}
