How to detect DX > v9.0c?
BlitzMax Forums/BlitzMax Programming/How to detect DX > v9.0c?
| ||
Hi there, I have this old code and it only works up to DX 9.0c because that's the highest value stored in the registry key for DX. So how do you detect DX10/11? Any ideas? ThxSuperStrict ?win32 Const HKEY_LOCAL_MACHINE% = -2147483646 Extern "win32" Function RegOpenKey%(hKeyParent%,SubKey$z,phkResult:Byte Ptr)="RegOpenKeyA@12" Function RegCloseKey%(hKey%)="RegCloseKey@4" Function RegQueryValueEx%(hKey%,ValueName$z,Reserved%,nType:Byte Ptr,ValueBytes:Byte Ptr,ValueSize:Byte Ptr)="RegQueryValueExA@24" End Extern ? Print ccGetDirectXVersion() 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.0a" Case "4.04.00.0068" strVersion = "3.0" Case "4.04.00.0069" strVersion = "3.0" Case "4.04.00.0070" strVersion = "3.0a" Case "4.05.00.0155" strVersion = "5.0" Case "4.05.01.1600" strVersion = "5.0" Case "4.05.01.1998" strVersion = "5.2" Case "4.06.02.0436" strVersion = "6.1" Case "4.06.03.0518" strVersion = "6.1a" Case "4.07.00.0700" strVersion = "7.0" Case "4.07.00.0716" strVersion = "7.0a" Case "4.07.01.3000" strVersion = "7.1" Case "4.08.00.0400" strVersion = "8.0" Case "4.08.01.0810" strVersion = "8.1" Case "4.08.01.0881" strVersion = "8.1" Case "4.08.01.0901" strVersion = "8.1a" Case "4.08.02.0134" strVersion = "8.2" 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.0903" strVersion = "9.0c" Case "4.09.0000.0903" strVersion = "9.0c" Case "4.09.00.0904" strVersion = "9.0c" Case "4.09.0000.0904" strVersion = "9.0c" End Select ? Return strVersion End Function |
| ||
The only way you can properly do this as far as I am aware is to try and access features/interfaces unique to each version and test for their existence... a bit too low-level for me! (The above code will return 9.0c even if 10+ is installed because you can have 9.x and 10+ installed at the same time -- normal on Vista upwards I believe.) Simple hack way: You'd use your posted code for versions up to 9.0c, then this for further (integer) versions. I don't believe there's an official way, so if you want sub-versions you'll probably have to implement the interface-detection stuff. Can't imagine there's much practical need for it, though, for all the difference it'll make in terms of what you can do with that information. This technically just opens the DLLs if they're present, so in theory someone could have just copied them in without having DX installed, but I think it'd be pretty safe. |
| ||
Interesting results for 7 to 12 using the above, actually, and much as I'd expect:DirectX version 7 is NOT installed DirectX version 8 library exists but contains no D3D8CreateDevice function DirectX version 9 library exists but contains no D3D9CreateDevice function DirectX version 10 is installed DirectX version 11 is installed DirectX version 12 is NOT installed (Again, you'd use the Registry code for versions 8 and 9.) |
| ||
Wow nice one thanks James! That's a pretty good solution. Mind if I nab it for my public domain source file? |
| ||
No probs! You'll have to revisit if/when a new DX comes out, of course, to see if it still holds up. |
| ||
Thanks, appreciated. |
| ||
Hiya guys, DirectX version 8 library exists but contains no D3D8CreateDevice function DirectX version 9 library exists but contains no D3D9CreateDevice function The function names changed slightly on the newer versions. And Dx7 has a completely different approach to initializing. Direct3DCreate8 Direct3DCreate9 D3D10CreateDevice D3D11CreateDevice EDIT:- Forgot to update James method which is without a doubt the easiest way to detect the version. MS own functions are.. well.. could be better :-) Last edited 2012 |
| ||
What about using a c++ call to directxsetupgetversion? http://doc.51windows.net/Directx9_SDK/?url=/directx9_sdk/setup/reference/functions/directxsetupgetversion.htm |
| ||
@Dave Thanks for the clarification. @James should we close the kernel32 lib as well? e.g. If CloseLibrary then CloseLibrary lib I tried that and it didn't crash but I'm not sure I should be doing it... Last edited 2012 |
| ||
@therevills DirectXSetupGetVersion() only works up to version 9.c for some wacky reason hence "MS own functions are.. well.. could be better" @Jake The system maintains a reference count for all LoadLibrary and CloseLibrary calls, so it's OK to leave it in. It's even ok to leave it out as the system will clean up when the app exits. Last edited 2012 |
| ||
@Dave: Thanks for the reassurance, though I wonder if it's better to free up the memory when done. Done know how much kernel32 will consume. |
| ||
It doesn't consume much at all but I know what you mean. If you're really worried about it then technically speaking, the Kernel32 library is loaded with your app. This means you don't really need to load it in again. To use it in James example with the minimum of fuss - swap out the Local CloseLibrary:Int (library:Int) Local lib:Int = LoadLibraryA ("kernel32.dll") CloseLibrary = GetProcAddress (lib, "FreeLibrary") for Extern"Win32" Function CloseLibrary(hLib) = "FreeLibrary@4" EndExtern to use the existing instance already linked in to your exe. Last edited 2012 |
| ||
Nice one Dave, I'll give that a whirl. You are certainly a very useful Windows expert to have around! |
| ||
Also it made my debug mode access violation go away, weird but yay! http://www.blitzbasic.com/Community/posts.php?topic=98996 |
| ||
Yeah, I just put the library closure stuff in for completeness. It just frees the handle from LoadLibraryA so not too important since it'll close at the end anyway like Dave says. (Was just protecting against sticking this all in a function that might then in theory be called 100s of times, however unlikely!) Also, good point on FreeLibrary! |
| ||
I actually still use the registry stuff - just got the keys from a system with DX10 and DX11 ^_^ Anyway, I now default my games to dx9, and just test if it's win95/98/2000 or XP with less then 24bpp desktop, then I switch to dx7 or opengl. No need at all to poke at dlls =D |
| ||
To be honest I'm not using the detection to make any decisions, just to display some debug info. |