#############################################################################
# Configuration rules and options for Spore
# 
# Andrew Willmott
#
# This script both defines what the various game options
# do, and sets defaults for them based on the video
# card, sound card, CPU, and other factors.
#
# It also sets some properties determining what the
# hardware will support.
#
# the following are equivalent, the error code is used as the guid if no id is supplied
# alert "You are running with new preferences" 1010 -info
# alert "You are running with new preferences" 1010 -info -id 0x000003f2 
# alert "You are running with new preferences" 1010 -info -id AppConfig!0x000003f2 


#############################################################################
# Constants
# 

set Off 0
set On  1

set Low    1
set Medium 2
set High   3

# Shader paths -- must match with Material/config.mtl
seti shaderPath2_m 0
seti shaderPath2_0 1
seti shaderPath2_x 2
seti shaderPath3_0 3


#############################################################################
# Set up
#

setVariables

setb isVista false
if (match("${OSName}", "*vista*"))
    setb isVista true
endif

if ($isVista and $VistaKB940105Required)
   alert "The game may run out of address space with some configurations\nand video cards, resulting in stability problems.\n\nIt is recommended that you install the latest Windows Vista Service Pack\nand check for updated video drivers.\n\nFor details see the Microsoft Knowledge Base article\n\n    http://support.microsoft.com/default.aspx/kb/940105\n\n" 2003 -warning
endif
	
if ($cider)
   # Running under Mac wrapper. Set mac-specific options here
   boolProp AlwaysFullscreen true
   boolProp RenderTargetCorrection false
   boolProp MacSpecificText true
   boolProp Support51Audio false
endif

			
#############################################################################
# Initial defaults.
#
# These may be overridden below according to CPU or card.

setOption OptionShadows             $High
setOption OptionTextureDetail       $Medium 
setOption OptionEffects             $High
setOption OptionBakeQuality         $High
setOption OptionLighting            $High
setOption OptionPlanetQuality       $High
setOption OptionDOF                 $Low

setOption OptionPhotoRes            $Medium
setOption OptionVideoRes            $Medium
setOption OptionAudioPerformance    $Medium
setOption OptionGameQuality         $High

setOption OptionDiskCacheSize       4  # 1 GB
setOption OptionTutorialsEnabled    $On
setOption OptionShowHints           $On
setOption OptionEdgeScroll          $On
setOption OptionBuddiesOnly         $Off

setOption OptionExpireOld           $Off
setOption OptionArchiveExpired      $Off
setOption OptionExpireDays          30
setOption OptionDownloadSize         8

setOption OptionUpdateLimit         $Off
setOption OptionUpdateLimitDays      7

setOption OptionCaptureUI           $Off

setOption OptionCellControls        $Off
setOption OptionCreatureControls    $Off
setOption OptionTribeControls       $Off
setOption OptionCivControls         $Off
setOption OptionSpaceControls       $Off


#############################################################################
# Identify graphics adapter
#


# set some config variables based on a card table and vendor specific rules
# sets isCardFound, cardVendor, and cardName
include "VideoCards.txt"

# Fallback on the card name text supplied by the card itself.
# Assumes that at least the cardVendor has been matched, since
# vendor name is not contained in some vendor card names.
# Note that specific vendors are overridden to a default card.
#  For AMD    -> Radeon 9800 Pro
#  For NVIDIA -> NVIDIA GeForceFX 5200 SE

if (not $isCardFound)
   set cardName $graphicsCard
endif

#############################################################################
#
# Testing Code
#

# For testing
setb doTestCPU 0
setb doTestGPU 0

if ($doTestCPU)
    seti pentium4 0
    seti cpuCount 1
    
    seti cpuSpeed 2000
    set cpuBrand "AMD Athlon64"
endif

if ($doTestGPU)
    # test some 2.0/3.0 cards
    set cardVendor "AMD"
    set cardName "Radeon 9600"
    
    set cardVendor "Intel"
    set cardName "915"
    
    set cardVendor "NVIDIA"
    set cardName "GeForce 5900"
     
    # card strings confuse 6800 SE comparisons
    #set cardName "NVIDIA GeForce 6800 Series GPU"
         
    seti testShaderModel 2
    seti maxVertexProgramVersionHW ($testShaderModel*256)
    seti maxPixelProgramVersion    ($testShaderModel*256)
    
    # have to set this, since some overrides fallback on graphicsCard string
    set graphicsCard $cardName
endif

#############################################################################
#
# Option Levels
#

seti cpuLevelHigh          3
seti cpuLevelMedium        2
seti cpuLevelLow           1

seti gpuLevelHigh          3
seti gpuLevelMedium        2
seti gpuLevelLow           1

# Shader paths -- must match with Material/config.mtl
seti shaderPath2_m 0 #2 minimal
seti shaderPath2_0 1 
seti shaderPath2_x 2 
seti shaderPath3_0 3 

#############################################################################
#
# CPU Assessment
#

seti adjustedCPU $cpuSpeed

setb cpuAMD false
if (match("${cpuBrand}", "*AMD*"))
    setb cpuAMD true
endif

seti cpuCutoffLow 2000
seti cpuCutoffMed 2400

if ($pentium4 > 0)
    # intel p4 hyperthread or multiprocessor
    if ($hyperthreading > 0)
        # only count real cpus
        seti cpuCount (floor(${cpuCount} / 2))
    endif
    
    if ($cpuCount > 1)
        seti adjustedCPU (round($adjustedCPU * 1.3334))   
    endif

    seti cpuCutoffLow 2400
    seti cpuCutoffMed 2800

elseif ($cpuCount == 1)
    if ($cpuAMD) 
        # amd single core (xp, 64)
        seti cpuCutoffLow 1800
        seti cpuCutoffMed 2000
    else 
        # pentium m, celeron, etc 
        seti cpuCutoffLow 2000
        seti cpuCutoffMed 2200  
    endif
else    
    if ($cpuAMD) 
        # amd multicore (athlon 64x2)
        seti cpuCutoffLow 1600
        seti cpuCutoffMed 1900
    else 
        # intel multicore (core duo, core2 duo)
        seti cpuCutoffLow 1800
        seti cpuCutoffMed 2100
    endif
endif

# rate the cpu
if ($adjustedCPU < $cpuCutoffLow)
    seti cpuLevel $cpuLevelLow
elseif ($adjustedCPU < $cpuCutoffMed)
    seti cpuLevel $cpuLevelMedium
else
    seti cpuLevel $cpuLevelHigh
endif


#############################################################################
#
# GPU Assessment
#

# track specific vendors
setb isNvidia           false
#setb isNvidiaIntegrated false

setb isAMD				false
#setb isAMDIntegrated    false

setb isIntel			false
setb isIntelIntegrated  false

setb isS3			    false
setb isVendorUnknown	false

setb isLimitedVideoMemory false

# convert to major version
seti vsVersion (floor($maxVertexProgramVersionHW / 256))
seti psVersion (floor($maxPixelProgramVersion / 256))

# if not in database, assume any new card is "medium"
seti gpuLevel $gpuLevelMedium

if (match("${cardVendor}", "AMD") or match("${cardVendor}", "ATI"))
    setb isAMD true
elseif (match("${cardVendor}", "NVIDIA"))
    setb isNvidia true
elseif (match("${cardVendor}", "INTEL"))
    setb isIntel true
elseif (match("${cardVendor}", "S3"))
    setb isS3 true
else
    setb isVendorUnknown true
endif

# old driver build detection/warning
setb oldDriver false
seti oldDriverBuild 0

# force a driver build off mutigpu detection
#  or else multigpu must be disabled
setb isMultiGpu false
setb isOldDriverBuildExit false
setb sporeProfile false
if ($gpuCount > 1)
    setb isMultiGpu true
endif

if ((not $cider) and (not $doTestGPU))
    # test each vendor against specific known driver builds
    if ($isNvidia)
        
        # identify the build range that has a Spore profile
        if (($driverBuild >= 117600) and ($driverBuild <= 117699)) # notebook
            setb sporeProfile true
        elseif ($driverBuild >= 117741) # desktop
            setb sporeProfile true
        endif
           
        seti oldDriverBuild 116375  # 10/4/2007 
        if ($driverBuild < $oldDriverBuild)
            setb oldDriver true
        endif
        
        if ($isMultiGpu)
            #seti oldDriverBuild 117600
            setb isOldDriverBuildExit true
            
            # require a profile
            if (not $sporeProfile)
                setb oldDriver true
            endif
        endif
           
    elseif ($isIntel)
        seti oldDriverBuild 104906  # 12/19/2007
        #setb isOldDriverBuildExit true
        
        if ($driverBuild < $oldDriverBuild)
            setb oldDriver true
        endif
        
    elseif ($isAMD)
        if ($isVista)
            seti oldDriverBuild   100096  # 3/28/2008
            
            if ($isMultiGpu)
                seti oldDriverBuild 100119 # need correct num 6/5/2008
            endif
        else
            seti oldDriverBuild 106764  # 12/20/2007
            
            if ($isMultiGpu)
                seti oldDriverBuild 106806  # need correct num 6/5/2008
                setb isOldDriverBuildExit true
            endif
        endif
        
        if ($driverBuild < $oldDriverBuild)
            setb oldDriver true
        endif
    endif
      
    # this alert is only displayed the first time the game is launched, or when the preferences are deleted
    if ($oldDriver)
       if ($isOldDriverBuildExit)
           if ($isMultiGpu)
               alert "An older video driver is detected.\n\nTo ensure correct visuals and gameplay with multiple gpus,\ninstalling the latest video driver is required,\nor multiple gpu mode must be disabled.\nThe game will not run.\nPlease see the README for details.\n\n" 1012
           else
               alert "An older video driver is detected.\n\nTo ensure correct visuals and gameplay,\ninstalling the latest video driver is required.\nThe game will not run.  Please see the README for details.\n\n" 1011
           endif
       else
          alert "An older video driver is detected.\n\nTo ensure correct visuals and gameplay,\ninstalling the latest video driver is recommended.\n\n" 1010 -info
       endif
    endif
endif


if ($isNvidia)
    # gtx reverses standard naming convention
    if (match("${cardName}", "*GeForce GTX*"))
        # classify high
        seti gpuLevel $gpuLevelHigh
         
    # rules don't apply to Quadro numbering, if not renamed in db assume medium
    elseif (not match("${cardName}", "*Quadro*"))
        
        # classify low
        if (match("${cardName}", "*5??0*"))
            seti gpuLevel $gpuLevelLow
            
	    elseif (match("${cardName}", "*61?0*"))
	        seti gpuLevel $gpuLevelLow
	    elseif (match("${cardName}", "*62?0*"))
		    seti gpuLevel $gpuLevelLow
		elseif (match("${cardName}", "*65?0*"))
		    seti gpuLevel $gpuLevelLow
		    
	    elseif (match("${cardName}", "*72?0*"))
	        seti gpuLevel $gpuLevelLow
	    elseif (match("${cardName}", "*73?0*"))
	        seti gpuLevel $gpuLevelLow
	    elseif (match("${cardName}", "*74?0*"))
		    seti gpuLevel $gpuLevelLow
		elseif (match("${cardName}", "*75?0*"))
		    seti gpuLevel $gpuLevelLow
		    
		elseif (match("${cardName}", "*83?0*"))
		    seti gpuLevel $gpuLevelLow
		elseif (match("${cardName}", "*84?0*"))
		    seti gpuLevel $gpuLevelLow
		    
	    endif
   
        if ($gpuLevel == $gpuLevelLow)
            setb isLimitedVideoMemory true
        else
            # classify high
            if (match("${cardName}", "*98?0*"))
	            seti gpuLevel $gpuLevelHigh
	        elseif (match("${cardName}", "*96?0*"))
		        seti gpuLevel $gpuLevelHigh
		        
		    elseif (match("${cardName}", "*88?0*"))
		        seti gpuLevel $gpuLevelHigh
		    
		    elseif (match("${cardName}", "*79?0*"))
		        seti gpuLevel $gpuLevelHigh
		    elseif (match("${cardName}", "*78?0*"))
		        seti gpuLevel $gpuLevelHigh
		    endif
        endif
        	   
    endif
endif

if ($isAMD)
    # rules don't apply to FireGL/FireMV numbering, if not renamed in db assume medium
    if (not match("${cardName}", "*Fire*")) # FireGL/MV
    
        # classify low
        if (match("${cardName}", "*32?0*"))
		    seti gpuLevel $gpuLevelLow
		elseif (match("${cardName}", "*34?0*"))
		    seti gpuLevel $gpuLevelLow
		    
        elseif (match("${cardName}", "*23?0*"))
		    seti gpuLevel $gpuLevelLow
		elseif (match("${cardName}", "*24?0*"))
		    seti gpuLevel $gpuLevelLow
		    
        elseif (match("${cardName}", "*95?0*"))
            seti gpuLevel $gpuLevelLow
	    elseif (match("${cardName}", "*96?0*"))
	        seti gpuLevel $gpuLevelLow
	            
	    elseif (match("${cardName}", "*X12?0*"))
	        seti gpuLevel $gpuLevelLow
	    elseif (match("${cardName}", "*X13?0*"))
		    seti gpuLevel $gpuLevelLow
		elseif (match("${cardName}", "*X14?0*"))
		    seti gpuLevel $gpuLevelLow
		elseif (match("${cardName}", "*X15?0*"))
		    seti gpuLevel $gpuLevelLow
		        
	    elseif (match("${cardName}", "*X2?0*")) # X200/300/600, won't match HD 2400
		    seti gpuLevel $gpuLevelLow
		elseif (match("${cardName}", "*X3?0*"))
		    seti gpuLevel $gpuLevelLow
	    elseif (match("${cardName}", "*X6?0*"))
	        seti gpuLevel $gpuLevelLow
	  
	    endif
	    
	    if ($gpuLevel == $gpuLevelLow)
            setb isLimitedVideoMemory true
        else
            # classify high
            if (match("${cardName}", "*48?0*"))
                seti gpuLevel $gpuLevelHigh
            
            elseif (match("${cardName}", "*38?0*"))
                seti gpuLevel $gpuLevelHigh
            elseif (match("${cardName}", "*36?0*"))
                seti gpuLevel $gpuLevelHigh
	        elseif (match("${cardName}", "*29?0*"))
	            seti gpuLevel $gpuLevelHigh
	            
	        elseif (match("${cardName}", "*19?0*"))
	            seti gpuLevel $gpuLevelHigh
	        elseif (match("${cardName}", "*18?0*"))
	            seti gpuLevel $gpuLevelHigh
	        endif
	    endif
	endif	   
endif

if ($isIntel)
	if (match("${cardName}", "*915*") or match("${cardName}", "*945*"))
		seti gpuLevel $gpuLevelLow	
		setb isIntelIntegrated true	
	else
		seti gpuLevel $gpuLevelLow
	endif
    
    setb isLimitedVideoMemory true
endif

if ($isS3)
	seti gpuLevel $gpuLevelLow
	setb isLimitedVideoMemory true
endif

# unknown vendors dropped if below shader model
if ($isVendorUnknown)
	seti gpuLevel $gpuLevelLow
    setb isLimitedVideoMemory true
endif

# drop gpu level if less than 128MB of video memory, below minspec
if ($textureMemory < 125)
    seti gpuLevel $gpuLevelLow
endif


############################################################################
# Set base shader path
#

seti shaderPathToSet 0

if ($psVersion >= 3)
   seti shaderPathToSet $shaderPath3_0
   
   if ($isIntel)
	  seti shaderPathToSet $shaderPath2_m
   endif
elseif ($psVersion >= 2)
   # use temp register count to distinguish 2 from 2a/2b
   if ($cider)
        seti shaderPathToSet $shaderPath2_0
        if ($maxPSRegisters >= 26)
            seti shaderPathToSet $shaderPath2_x
        endif
        if ($isIntel)
            seti shaderPathToSet $shaderPath2_m
        endif
   else
        seti shaderPathToSet $shaderPath2_0
        if ($maxPSRegisters >= 32)
            seti shaderPathToSet $shaderPath2_x
        endif
        if ($isIntel)
            seti shaderPathToSet $shaderPath2_m
        endif
   endif
else
   # this message should be generated/localized code side
   alert "Sorry, your graphics card is below our min spec.\nThe game will not run.\nPlease see the README for details." 2001
endif

# NOTE: do not override this for special cases, unless the card will
# actually crash or has bugs. Instead setOption OptionLighting to
# reduce the path by default to what we recommend.
intProp shaderPath $shaderPathToSet

#############################################################################
# Instancing support

if ($cider)
    # no support for instancing
    setb instancing false
endif

if ($instancing)
    trace "=== Instancing can be enabled"
    boolProp effectsInstancing true

    # rendering artifacts using instancing on hw tnl based intel cards
    #  dropping to swvp does not help
    if ($isIntel)
	    # swvp cards benefit from instancing, check that drivers work correctly
	    if (match("${cardName}", "*915*") or match("${cardName}", "*945*") or match("${cardName}", "*Q35*"))
		    boolProp effectsInstancing true
	    else
		    boolProp effectsInstancing false	
	    endif
    endif
endif

# Report classification

trace "==="
trace "=== GPU level ${gpuLevel}"
trace "=== Card ${cardName}, Vendor ${cardVendor}, Driver ${driverBuild}, ${instancing}"
trace "==="
trace "=== CPU level ${cpuLevel}"
trace "=== CPU ${cpuCount}, Speed ${adjustedCPU}, HT ${hyperthreading}, P4 ${pentium4}" 


#############################################################################
# Set options based on cpu
#

setOption OptionEffects             $cpuLevel
setOption OptionBakeQuality         $cpuLevel
setOption OptionPlanetQuality       $cpuLevel
setOption OptionAudioPerformance    $cpuLevel
setOption OptionGameQuality         $cpuLevel


#############################################################################
# MRT
#

boolProp MRT 0
if ( $numSimultaneousRTs > 1 )
	boolProp MRT 1
endif

############################################################################
# Resolution
#
if (($gpuLevel >= $gpuLevelMedium) and (not $isLimitedVideoMemory))
    seti resolutionTarget (1024 * 768)
else
    seti resolutionTarget (800 * 600)
endif

setResolution $resolutionTarget

############################################################################
# Texture Detail
#

if (($gpuLevel == $gpuLevelLow) or ($isLimitedVideoMemory))
    setOption OptionTextureDetail $Low
endif

############################################################################
# DOF
#

if (($gpuLevel >= $gpuLevelHigh) and ($cpuLevel >= $cpuLevelHigh))
    setOption OptionDOF $High
endif

############################################################################
# Shadow settings
#

seti shadowOption $cpuLevel
if ($gpuLevel < $cpuLevel)
	seti shadowOption $gpuLevel  
endif

trace "=== Shadow setting ${shadowOption}"
setOption OptionShadows $shadowOption


############################################################################
# Event Query
#

# Vista exhibits hangs when using D3DQUERYTYPE_EVENT.  

#trace "OS = ${OSName}"
if ($isVista or $cider)
    trace "=== Vista/Mac: avoiding GPU flush"
    intProp NumFramesToBuffer 3    # avoid GPU lock to reduce buffering -- leave it to the driver
endif

############################################################################
# Lighting level controls shaders that run.  Can be set higher.

setOption OptionLighting $gpuLevel

if ($cpuLevel == $cpuLevelLow)
    # this sets the 2_m shader path
	setOption OptionLighting $Low
endif

############################################################################
# UI Drop shadows

if (($gpuLevel == $gpuLevelLow) or $isLimitedVideoMemory)
	intProp dropShadowQualityImage 1
	intProp dropShadowQualityText  1
endif


############################################################################
# Drop CPU Settings By GPU
#

if ($gpuLevel == $gpuLevelMedium)
    # prevent high cpu level from pushing too many batches to medium gpu
    #  this helps medium gpu classification apply to more cards
    if ($cpuLevel == $cpuLevelHigh)
        setOption OptionPlanetQuality $Medium
        setOption OptionEffects       $Medium
    endif
    
    if ($cpuLevel == $cpuLevelHigh)
        setOption OptionGameQuality $Medium
    endif
    
elseif ($gpuLevel == $gpuLevelLow)
    setOption OptionEffects       $Low
    setOption OptionBakeQuality   $Low
    setOption OptionPlanetQuality $Low
    setOption OptionGameQuality   $Low
      
    # swvp needs more cpu processing
    if ($isIntelIntegrated)
       setOption OptionAudioPerformance $Low
    endif
endif

#######################################
# Safe mode
# 

# Set options to safe values. In safe mode, all options will
# be reset to their defaults, but the prefs won't be saved.

# Basically setting anything that might trigger bad hardware behaviour to low.
if ($safeMode)
    trace "=== SAFE MODE"
    
    alert "Running in safe mode" 8888 -info
    
    setOption OptionLighting      $Low
    setOption OptionShadows       $Low
    setOption OptionEffects       $Low       
    setOption OptionTextureDetail $Medium
    setOption OptionPlanetQuality       $Low
    setOption OptionAudioPerformance    $Low
    setOption OptionPhotoRes            $Low
    setOption OptionVideoRes            $Low
endif

# These are all of the alert dialogs localized if text is present (from AppConfig.txt)
if (varExists(showConfigAlerts) and ($showConfigAlerts))
    trace "=== Test Alerts"
    
    alert "not localized" 1000 -info -always # 3e8
    alert "not localized" 1001 -info -always # 3e9
    alert "not localized" 1002 -info -always # 3ea
    alert "not localized" 1004 -info -always # 3ec
    alert "not localized" 1005 -info -always # 3ed
    
    alert "not localized" 1010 -info -always # 3f2
    alert "not localized" 1011 -info -always # 3f3
    alert "not localized" 1012 -info -always # 3f4
    
    alert "not localized" 2000 -info -always # 7d0
    alert "not localized" 2001 -info -always # 7d1
    alert "not localized" 2002 -info -always # 7d2
    alert "not localized" 2003 -info -always # 7d3
endif
