DXERROR err=SURFACELOST
BlitzMax Forums/BlitzMax Programming/DXERROR err=SURFACELOST
| ||
Firstly, sorry I if missed something in the past year or so about this issue, but I tried searching and couldn't find anything conclusive. Basically, when I first made my framework I was sure that I made it so that full-screen games could alt+tab and withstand control+alt+del without crashing or coming back to a blank screen. But now my games crash when I restore them after minimizing them. Specifically they crash with DXERROR err=SURFACELOST in the BlitzMax console. Note that my games use DX7 and the crash can be duplicated by running the following code and alt+tabbing out/in. If you comment out the line that sets the driver, it works fine! SetGraphicsDriver D3D7Max2DDriver() Graphics 800,600,32 Local counter:Int=0 While Not KeyHit(key_escape) Cls DrawText counter,0,0 counter:+1 Flip 1 Wend The plot thickens, because I went back and tested some of my old compiles from around the time I was sure I had this working, and they don't crash when you restore them BUT I do see a black screen. They haven't frozen because I can hear mouse over sounds and keys work. Since I wrote those old builds I have changed my video card so I don't know if that is having an effect for some reason. I could swear this stuff used to work fine. Am I going mad? Portals won't accept a game that fails alt+tab, so it may be I have to convert over to DX9, but what happened to DX7? (or perhaps it's my video card which is an NVidia Geforce GTX 275) If you can test the code above and tell me if it works/crashes on your machine that would be great thanks! Does anyone have any further information about this? Many thanks in advance! [edit]I'm running BMax 1.41 on DX 9.0c on XP SP3. Last edited 2011 |
| ||
Works fine here, without any crash. GF 9700GTM, BMax 1.37 (oops, I should run a update.) |
| ||
Interesting. Well if it still works after the update then it's my video card. Perhaps it's just not built for DX7 support. I wonder how many other cards have the issue and if we should be looking to support them with a tweak to the BMax DX7 code? Last edited 2011 |
| ||
Works fine on my machine (specs in my sig)... Also Pirate Solitaire uses GAF v1.11 (which uses DX7 driver) and BlitzMax v1.41 - and Im sure BFG would have picked up something in their testing... Last edited 2011 |
| ||
Thanks. It must be my video card then. So I guess the question is, what % of modern cards does it crash on? Can anyone else test? |
| ||
Jake, Works fine on both my laptop and desktop - see sigs for info. Oh - latest version of BlitzMax. Last edited 2011 |
| ||
Works fine on my laptop - Intel GMA965, 2GB RAM, Windows 7, DX11. BTW: I have an 8500GT I can test on but I'm going out for a while now - will give it a go when I get back. Last edited 2011 |
| ||
Unless you have a big limitation, offer users a choice of driver and in your readme/troubleshoot explain it is a fix. |
| ||
offer users a choice of driver and in your readme/troubleshoot explain it is a fix. In casual games, advanced options like that are a big no-no.just checked on my 8500GT (Windows 7, DX11, 2GB RAM) - works fine. [edit] Oh yeah - I'm using Blitzmax 1.41. Last edited 2011 |
| ||
Reloading the graphics from file or pixmaps should refresh the device textures, not sure how to reload the built-in image font. Alternatively, calling Graphics() and recreating the window should force an internal texture refresh. As far as I know, bmax keeps parallel pixmaps to all the TImage data. I haven't personally tried this, just speculating. |
| ||
No error here either on ATI X1300. But I didn't update blitzmax in ages :P~ |
| ||
In casual games, advanced options like that are a big no-no. That's why you hide it, or dress it up as some kind of "safe mode" option or something. You don't need to include a book on it! |
| ||
Thanks for testing everyone. Hmm, well at least it's rare (only my PC), that's reassuring. Not sure how easy a fix is to be honest. May try recreating graphics. |
| ||
So I finally fixed this by testing if the driver is DX7 and the game is fullscreen and it is being returned to from an alt+tab (I'm testing for the game being unsuspended). All I do is call Graphics() again as per HrdNutz's suggestion and it works fine! Probably wasn't worth adding this fix as most people will be using the DX9 driver (which is fine) but my framework falls back to DX7 if DX9 is not available and I didn't want it to crash on some graphics cards. It's possible some casual players may have similar setups as some of my games have over 1 Million demo downloads. |
| ||
Tbh being in the casual game market means you have to support every conceivable version of dx from 7 and up. This being the case maybe posting the fix somewhere so others dont fall into the trap might help other blitzers. Its a very good point tho and one that we will have to keep a very close eye on as to when driver manufacturers stop supporting legacy direct x versions seeing as its four revisions over 7 now? |
| ||
The fix is entwined quite deeply into my framework so isn't easy to extract and post. But basically you check for EVENT_APPRESUME and then you call Graphics again instead of doing nothing. You only do this when the BMax DX7 Driver is being used and the game is full-screen. |
| ||
(with some help) I came up with this a couple of years ago... http://www.blitzbasic.com/Community/posts.php?topic=88279#1002201 and added it to my framework as a separate module because of its depedency on MaxGUI (which at the time wasn't free). As you'll see, it is calling endgraphics() graphics() when the user moves away from full screen. I can't recall if I got it to handle Alt+tabbing in and out in the same way tho. |
| ||
Hey Jake, mind if you share your GAF change? I guess its in Commontypes: Method DoPeekEvent() While PeekEvent() ... Case EVENT_APPRESUME SuspendedEvent = 0 End Select Wend So what do we do in EVENT_APPRESUME? |
| ||
Sure thing. It's in CheckWindow() after then main else:If Suspended = True 'To avoid a hang on some graphics cards with DX7, we should recreate the graphics. If DriverDX7 And FullScreen Then GraphicsCreate() EndIf |
| ||
btw I also updated SetDXDriver to avoid it using DX9 before testing for it. You may not be using a ForceDX7 flag. I only really added that for testing and perhaps to set on older games if I don't want to update them to DX9 and add in custom cursor toggle etc.Method SetDXDriver(ForceDX7:Int) ?Win32 If ForceDX7 Then DriverDX7 = 1 DriverDX9 = 0 SetGraphicsDriver D3D7Max2DDriver() Else 'Double check DX9 is available. If D3D9Max2DDriver() DriverDX7 = 0 DriverDX9 = 1 SetGraphicsDriver D3D9Max2DDriver() Else DriverDX7 = 1 DriverDX9 = 0 SetGraphicsDriver(D3D7Max2DDriver()) 'This may mean that DoSetVirtualResolution() fails due to DX7, but the small netbooks it is required on are all DX9 anyway. EndIf EndIf ? End Method Last edited 2012 |
| ||
I also added in more direct versions based on a wikipedia article to ccGetDirectXVersion in PublicDomain.bmx. I basically realised there were some versions missing from the list and was worried it could mean the game would choose the wrong driver or something.Function ccCheckDirectXVersionUpTo9$() 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 I also updated ccDirectXVersionIsValid() in CommonCode to take into account the updated GetDirectXVersion as follows (it only checks first digit now): ' ----------------------------------------------------------------------------- ' ccDirectXVersionIsValid: Returns 1 if DirectX Version is >=7 (which is required for BlitzMax) ' ----------------------------------------------------------------------------- Function ccDirectXVersionIsValid%() Local v$ = ccGetDirectXVersion() v$ = ccFirstStringToSub(v$,".") Local valid%=1 'There is no 4.0! If v$ = "1" Or v$="2" Or v$="3" Or v$="5" Or v$="6" Then 'There was no version 4. valid=0 EndIf Return valid End Function Last edited 2012 |
| ||
Plus I updated ccGetVersionString in publicdomain.bmx to take windows 8 into account (untested)Function ccGetVersionString:String() Const VER_PLATFORM_WIN32s% = 0 Const VER_PLATFORM_WIN32_WINDOWS% = 1 Const VER_PLATFORM_WIN32_NT% = 2 Local versionName:String ?win32 Local VersionInfo:TOSVersionInfoEx=New TOSVersionInfoEx VersionInfo.dwOSVersionInfoSize=SizeOf(VersionInfo) GetVersionExA(VersionInfo) Select versionInfo.dwPlatformID Case VER_PLATFORM_WIN32s; VersionName = "Win32s" Case VER_PLATFORM_WIN32_NT; VersionName = "Windows NT" Select versionInfo.dwVerMajor Case 4; VersionName = "Windows NT" Case 5; Select versionInfo.dwVerMinor Case 0; VersionName = "Windows 2000" Case 1; VersionName = "Windows XP" Case 2; VersionName = "Windows XP" '64-bit, but returns just "Windows XP" to be compatible with TGame.Init() End Select Case 6; Select versionInfo.dwVerMinor Case 0; VersionName = "Windows Vista" Case 1; VersionName = "Windows 7" Case 2; VersionName = "Windows 8" End Select End Select Case VER_PLATFORM_WIN32_WINDOWS Select versionInfo.dwVerMinor Case 0; VersionName = "Windows 95" Case 90; VersionName = "Windows ME" Case 10; VersionName = "Windows 98" End Select End Select ? Return VersionName End Function |
| ||
Thanks a lot Jake :) I'll be adding that lot to my version for sure! |
| ||
@therevills: just realised that ccDirectXVersionIsValid has a bug, change the v$ = mid(V$,1,1) to v$ = ccFirstStringToSub(v$,".") So that it works for DX10+ Edited above post with fix. |