Detect DX version (and OpenGL version) installed?

BlitzMax Forums/BlitzMax Programming/Detect DX version (and OpenGL version) installed?

Grey Alien(Posted 2007) [#1]
Is there a way to detect the DX version installed? Currently if you play my game on a DX6 box, you don't get any error message just a load of crappy white boxes type thing. Probably because I'm using something like this:

If not D3D7Max2DDriver() Then
	'See if OpenGL is available and use that
EndIf

So basically OpenGL is probably being used instead of DX but at some crappy level where it can't render the game (I've seen the OpenGL drive "work" before on pleny of PCs but just display white stuff).

Any ideas how to detect DX version please?

OR maybe there's a way to detect the OpenGL version or something so that the game doesn't try to work in a version which is totally useless for BMax. That would work.

Thanks in advance for any help you may offer.


popcade(Posted 2007) [#2]
As to OpenGL version info, I can't find proper way to do it as GL_VERSION was only available after the context is created(ie. crashes before you can detect if invalid).

Anyone tried Indiepath's DirtyRect in BMax1.26?

As DX version that's easier, DX version info was stored in Registry.

http://msdn.microsoft.com/archive/default.asp?url=/archive/en-us/directx9_c_Dec_2004/directx/directxsdk/dxandxp.asp

The location is here
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\DirectX


Qube(Posted 2007) [#3]
This'll return the DX Version number.

Import "-ladvapi32"

Extern "win32"
   Function RegOpenKey:Int(hKeyParent:Int,SubKey$z,phkResult:Byte Ptr)="RegOpenKeyA@12"
   Function RegCloseKey:Int(hKey:Int)="RegCloseKey@4"
   Function RegQueryValueEx:Int(hKey:Int,ValueName$z,Reserved:Int,nType:Byte Ptr,ValueBytes:Byte Ptr,ValueSize:Byte Ptr)="RegQueryValueExA@24"
EndExtern

Const HKEY_LOCAL_MACHINE = -2147483646

hbank = CreateBank(4)
RegOpenKey(HKEY_LOCAL_MACHINE,"SOFTWARE\Microsoft\DirectX",BankBuf(hbank))
hKey = PeekInt(hbank,0)

value_bank = CreateBank(100)
value_bank_size = CreateBank(4)
type_bank = CreateBank(4)

PokeInt(type_bank,0,0)
PokeInt(value_bank_size,0,100)
   
RegQueryValueEx(hKey,"Version",0,BankBuf(type_bank),BankBuf(value_bank),BankBuf(value_bank_size))

dx_version:String = ""
For char=0 To PeekInt(value_bank_size,0)-1
	If PeekByte(value_bank,char)=0 Then Exit
	dx_version = dx_version + Chr(PeekByte(value_bank,char))
Next

RegCloseKey(hKey)

Print "DirectX Version : " + dx_version



xlsior(Posted 2007) [#4]
when I run it on my computer, it returns:

DirectX Version : 4.09.00.0904

If I check DXDiag, it says "DirectX 9.0c(4.09.00.0904)

Any idea how to find out the 'friendly' version number based on the long string returned by the code above?

(I mean, I wouldn't have interpreted 4.09.00.0904 as 9.0c myself... And Of course have no idea how 9.0b, 9.0a or 8.0 would be represented either)


Derron(Posted 2007) [#5]
All my PCs have already DX9 installed ... may be you have to change the PokeInt to get the value of
"InstalledVersion" instead of "Version".

"InstalledVersion" is a "REG_BINARY" (on my PC with the value : "00 00 00 09 00 00 00 00" - may be thats the base number.


-------

Or just use Qube's Code and evaluate the dx_version like:
local strVersion:string = ""
Select Case dx_version
    Case "4.02.0095"
        strVersion = "1.0"
    Case "4.03.00.1096"
        strVersion = "2.0"
    Case "4.04.0068"
        strVersion = "3.0"
    Case "4.04.0069"
        strVersion = "3.0"
    Case "4.05.00.0155"
        strVersion = "5.0"
    Case "4.05.01.1721"
        strVersion = "5.0"
    Case "4.05.01.1998"
        strVersion = "5.0"
    Case "4.06.02.0436"
        strVersion = "6.0"
    Case "4.07.00.0700"
        strVersion = "7.0"
    Case "4.07.00.0716"
        strVersion = "7.0a"
    Case "4.08.00.0400"
        strVersion = "8.0"
    Case "4.08.01.0881"
        strVersion = "8.1"
    Case "4.08.01.0810"
        strVersion = "8.1"
    Case "4.09.0000.0900"
        strVersion = "9.0"
    Case "4.09.00.0900"
        strVersion = "9.0"
    Case "4.09.0000.0901"
        strVersion = "9.0a"
    Case "4.09.00.0901"
        strVersion = "9.0a"
    Case "4.09.0000.0902"
        strVersion = "9.0b"
    Case "4.09.00.0902"
        strVersion = "9.0b"
    Case "4.09.00.0904"
        strVersion = "9.0c"
    Case "4.09.0000.0904"
        strVersion = "9.0c"
End Select


This was found using the 4.09.00.0904 as search param:
http://www.microsoft.com/technet/scriptcenter/resources/qanda/jan07/hey0108.mspx



bye
MB


xlsior(Posted 2007) [#6]
Minor typo in the 'select' statement.

Combined fixed code:



Thanks!


Grey Alien(Posted 2007) [#7]
Hey nice work guys, this is a very handy piece of code as we can now warn users with a text box if their DX is totally out of date! Thanks ALL!

Question: What about DX 10?

Still need to figure out how to check if OpenGL is man enough for the task of running BMax.


Derron(Posted 2007) [#8]
Just check your registry on vista (don't have it).

If its "4.10.XXXX" then you will know it ;D.

And to the minor typo: was poor copy/paste from the link with adding the dx_version and without using brain.


You may still cut the case-thing down when stripping out the rest of the points and numbers (as long as you don't need the information of 9.0c (just DX7, DX8, DX9...).


bye
MB


Grey Alien(Posted 2007) [#9]
Here's a STRICT version made into a function:

' -----------------------------------------------------------------------------
' ccGetDirectXVersion: Returns the DirectX version as a string
' By Qube and MichaelB 
' -----------------------------------------------------------------------------
Function ccGetDirectXVersion$()
	Local strVersion:String = ""

	?win32
	Local hbank:TBank = CreateBank(4)
	RegOpenKey(HKEY_LOCAL_MACHINE,"SOFTWARE\Microsoft\DirectX",BankBuf(hbank))
	Local hKey = PeekInt(hbank,0)
	
	Local value_bank:TBank = CreateBank(100)
	Local value_bank_size:TBank = CreateBank(4)
	Local type_bank:TBank = CreateBank(4)
	
	PokeInt(type_bank,0,0)
	PokeInt(value_bank_size,0,100)
	   
	RegQueryValueEx(hKey,"Version",0,BankBuf(type_bank),BankBuf(value_bank),BankBuf(value_bank_size))
	
	Local dx_version:String = ""
	For Local char=0 To PeekInt(value_bank_size,0)-1
		If PeekByte(value_bank,char)=0 Then Exit
		dx_version = dx_version + Chr(PeekByte(value_bank,char))
	Next
	
	RegCloseKey(hKey)
	
	Select dx_version
	    Case "4.02.0095"
	        strVersion = "1.0"
	    Case "4.03.00.1096"
	        strVersion = "2.0"
	    Case "4.04.0068"
	        strVersion = "3.0"
	    Case "4.04.0069"
	        strVersion = "3.0"
	    Case "4.05.00.0155"
	        strVersion = "5.0"
	    Case "4.05.01.1721"
	        strVersion = "5.0"
	    Case "4.05.01.1998"
	        strVersion = "5.0"
	    Case "4.06.02.0436"
	        strVersion = "6.0"
	    Case "4.07.00.0700"
	        strVersion = "7.0"
	    Case "4.07.00.0716"
	        strVersion = "7.0a"
	    Case "4.08.00.0400"
	        strVersion = "8.0"
	    Case "4.08.01.0881"
	        strVersion = "8.1"
	    Case "4.08.01.0810"
	        strVersion = "8.1"
	    Case "4.09.0000.0900"
	        strVersion = "9.0"
	    Case "4.09.00.0900"
	        strVersion = "9.0"
	    Case "4.09.0000.0901"
	        strVersion = "9.0a"
	    Case "4.09.00.0901"
	        strVersion = "9.0a"
	    Case "4.09.0000.0902"
	        strVersion = "9.0b"
	    Case "4.09.00.0902"
	        strVersion = "9.0b"
	    Case "4.09.00.0904"
	        strVersion = "9.0c"
	    Case "4.09.0000.0904"
	        strVersion = "9.0c"
	End Select
	?
	
	Return strVersion
End Function


And a handy checking function:

' -----------------------------------------------------------------------------
' ccDirectXVersionIsValid: Returns 1 if DirectX Version is >=7 (which is required for BlitzMax)
' -----------------------------------------------------------------------------
Function ccDirectXVersionIsValid%()
	Local v$ = ccGetDirectXVersion()
	Print v$
	Local valid=1
	'There is no 4.0!
	If v$ = "1.0" Or v$="2.0" Or v$="3.0" Or v$="5.0" Or v$="6.0" Then
		valid=0
	EndIf
	Return valid
End Function



xlsior(Posted 2007) [#10]
You missed a bit, grey: The code above still needs the following as well: