Detect DX version (and OpenGL version) installed?

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

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.

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

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


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)

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

Minor typo in the 'select' statement.

Combined fixed code:

'Name: Dave 
'Nick name: Qube 
'Email address: qube@... 
'Home page: <a href="http://www.syntaxbomb.com" target="_blank">http://www.syntaxbomb.com</a> 

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)

Local strVersion:String = ""

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

Print "DirectX Version : " + strversion+" ("+dx_version+")"



Thanks!

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.

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

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


You missed a bit, grey: The code above still needs the following as well:
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