B3DSDK with sources

Archives Forums/Blitz3D SDK Programming/B3DSDK with sources

@rtur(Posted 2007) [#1]
Will be source version of SDK?
I need to fix few bugs with Blitz3D(crashes after device lost- locking computer and logon, logon after screensaver, changing desktop resolution while game is running etc) but it is impossible to 100% fix this bugs without sources.

Currently I've completed casual game. I've worked on it during 14 months. And publisher does not releases it only because this bugs(requirements to quality of casual games has been increased after Vista release).
I'm ready to pay $500-$1000 to have sources of B3D, so I can fix this and other future bugs by myself. I need it only for my projects, not for creating any ñompetitive engine.


_33(Posted 2007) [#2]
Are those reported in the bug report for Blitz3D?


popcade(Posted 2007) [#3]
You can get Torque source for around $150, consider Blitz3D has age,$500 is too tacky for just "fixing a few bugs"...


@rtur(Posted 2007) [#4]
>Are those reported in the bug report for Blitz3D?
I've reported few months ago in bug reports forum and write email to Mark. But still no reply/bugfix :(

David Guy had made Dll to catch logoff etc but it does not solve problem at 100%. Games still crashes.

And the reason why I don't go to another framework(like Torque,Playground,PopCap,HGE etc) that I've got already completed game and I need to release it right now. And I've build good framework(~1Mb of blitz code), content pipeline etc.


_33(Posted 2007) [#5]
@rtur, I suggest you send an update to blitz support regarding your issues. I think blitz3d is due for an update :P


DGuy(Posted 2007) [#6]
>David Guy had made Dll to catch logoff etc but it does not solve problem at 100%. Games still crashes.

@rtur, if you can tell me under what conditions B3D is causing a MAV after a focus loss, I'll update the DLL I wrote to handle them:

* after device lost-locking computer
* logon
* logon after screensaver
* changing desktop resolution while game is running
* any others ?

While most/all of the conditions above should be handled, (I'm pretty sure I tested them all) I'll re-check to make sure. :)

David


Pinete(Posted 2007) [#7]
I'm working too in a casual game.
Could you please tell a little more about this kind of problems?
What kind of issue are you refering to when talking about logon or logon after screensaver???

Thanks in advance!


DGuy(Posted 2007) [#8]
Well, after re-testing my DLL I realized I was handling Ctrl+Alt+Del but NOT handling Alt+Ctrl+Del. Both have the same results but generate a different sequence of windows messages.

@Pinete
View these threads for some background:
http://www.blitzbasic.com/Community/posts.php?topic=67837
http://www.blitzbasic.com/Community/posts.php?topic=67841

Using my DLL, under both WinXP and Vista, I am unable to find any combination of Logout/login/user-switch/screensaver, etc. or focus loss event that causes a MAV.

BUT, as stated in the above threads there is a rare occurrence that will definitely cause a MAV: A focus loss event, while RenderWorld is executing, that results in loss of DirectDraw surfaces.

This can not be handled externally, even by detecting the focus lose while RenderWorld is executing, and attempting a RestoreAllSurfaces call. The only way to remedy this 100%, it seems, would be to re-write RenderWorld so it checks for/handles surface-loss.

So, to this ends, I would have to second @rtur request to either fix this rare but reproducible bug or for some sort of source-code license so users can fix it.


Pinete(Posted 2007) [#9]
Thanks a lot DGuy!
Could you please explain me a little more how to use this in my Blitz program?

Thanks in advance!

All the best.


@rtur(Posted 2007) [#10]
On small test example MAV occurs very rarely. But on big project I have MAV during about 20%-30% of logoffs on WinXP.


marksibly(Posted 2007) [#11]
Hi,

I'll be looking into this very soon. I've contacted DGuy and hopefully he'll be able to help too.

I've been reluctant to pursue a 'reload all the graphics' solution, as it's a really icky thing to lump on the programmer, esp. in a supposedly user-friendly language like Blitz.

But realistically, I don't think there's much alternative any more.

Pooh!


Pinete(Posted 2007) [#12]
Hi!

so, what's your recomendation, Mark? to use DGuy dll?

Could be hope a Blitz3D native future solution regarding the problems with windowed/full screen/'reload all graphics solution'/logout-login....??

Really that's a very important stuff because if you want to be published is possible publishers ask you for avoid that kind of problems...

Regards,

All the best.


marksibly(Posted 2007) [#13]

so, what's your recomendation, Mark? to use DGuy dll?


Yes, and I'll work on building this stuff into b3d and b3dsdk.


DStastny(Posted 2007) [#14]
Mark if you see this..

IDirectDraw7::TestCooperativeLevel should handle the issues of detecting the lost of the primary surface without checking windows messages for keystroks or testing for surface lost on primary. If you can raise this back to API then we can respond by reloading graphics and such.

Doug


@rtur(Posted 2007) [#15]
Hi Mark,
I've created surface restoration hack, that restores textures after logout without reloading graphics manualy.
But it need to be implemented into Blitz3D because there is still some textures that are not restored(that loaded into video memory with 256 flag).

Problem of blitz programs - that they stops execution of code if window lost focus. Game need set internal timers to pause, set all sounds to silent and so on...
So, I suggest to make few functions that will be called by blitz:
PauseGame() - will be called when window loses focus
ResumeGame() - will be called when window recieves focus
EndGame() - will be called when window closes, so user can unload all his stuff. And of course user can call this functions by himself if needed.

In my DLL that we have made with Platon this functions are finded in memory by DLL function and that called from DLL( written in PureBasic) when window lost/recieve focus and closes.
It works fine for handling usual focus lost, like Alt+Tab, Ctrl+Shift+Esc etc. But when user LogOut and than LogingIn ResumeGame function calls during RenderWorld command execution. And something crashes in it.
On small example it crashes VERY rarely. You can logout/login hundred times before it will crash. But on huge game it crases very often. It can crash at first time, or second. Sometimes from 5-th. I don't know why. Maybe in my game RenderWold rendering very big amounts of different textures complex meshes etc while in example there is only few cubes with texture...

Here is dlls and test code: http://www.arthurostapenko.com/other/blitzbugfixes/BSys2.rar
2 All Please test this on you games.
I've commented code, so I think it will be easy to integrate into any game.

Test for Win+L, Ctrl+Alt+Del, Ctrl+Alt+Esc, Alt+Tab. Launch game and change desktop resolution(there is still manual restoration here:( ), Launch programm and wait for screensaver(usual blitz game crashes after launching directX screensaver)- screensaver must not be launched while game window is active, but it launches if game is minimized :(

There is also small bug in blitz games- When game starts in fullscreen and than changed to windowed HWND_TOPMOST(I think) flag not cleared, so game in windowed mode is alway on top of other applications.
(When game launched in window mode than it is not "always on top".)

Also all other casual frameworks has fast fullscreen<->windowed mode change, without reloading all graphics.
It need to be integrated into Blitz3D also.


Pinete(Posted 2007) [#16]
Hi @rtur!,

thanks for the DLL.

I've been testing the test.bb and if I set full screen and press alt+tab, when return to the app this is freeze. If I continue pressing alt+tab app doesn't respond anymore...

How can be done alt+tab when app is Full screen to have not problems?


Thanks in advance!


@rtur(Posted 2007) [#17]
2 Pinete
Strange problem. On my system it works fine with both fullscreen and windowed mode.

What is your system(OS, hardware, DX version, video drivers version)?
Do you have any other programms runing?


@rtur(Posted 2007) [#18]
Or maybe you are running this sample form IDE.
Do not do this. Compile to EXE and then run test.exe file.


Pinete(Posted 2007) [#19]
ok, I will try again at home.. I guess I was running from IDE...
My system is WinXP SP2, Directx9.0c, 6600GT and don't know video drivers version, so I will tell you in my nest post in one hour or so..

Thank you very much @rtur


@rtur(Posted 2007) [#20]
Try with disabled debugger, it must work.


Pinete(Posted 2007) [#21]
Yes, it works :) you're right...
But I've some questions...
After examining the test.bb a little more I've take into account that really it is based on the idea of unload/reload all the graphics... isn't it?

So what should be the way to avoid load and unload graphics?

From Blitzmax you can press alt+tab or ctrl+alt+del without problems, or at least, I've not have problems at all...

Summarizing, the question is: How to avoid to unload / reload all the graphics??

Thanks in advance @rtur!!!


All the best!


@rtur(Posted 2007) [#22]
Unload/reload all the graphics needed only if device lost. It happens when you change desktop resolution while game is running.
When you press alt+tab or ctrl+alt+del or Win+L - there is no device lost happens. Only surface deleted from videomemory(when Win+L pressed).
This function restore surface(if it is not vidmem texture):

Function RestoreSurfaces(Entity)

For i=1 To CountSurfaces(Entity)
Surface=GetSurface(Entity,i)
vdPokeInt(Surface+64,0) ;; Set 64 offset of surface to zero, forwarding surface restoration
Next

End Function

Look at ResumeGame() function, there are all entities restores it's surfaces automaticaly.

>From Blitzmax you can press alt+tab or ctrl+alt+del without problems, or at least, I've not have problems at all...
Yes BlitzMax handles Win+L and others events well, I hope Mark or Skidracer will fix this bugs in Blitz3D too.
Because I'm still having crash at RenderWorld in my game, when press Win+L.
(test sample does not crash, I don't know why..maybe because I have a lot of textures and other stuff to render)


@rtur(Posted 2007) [#23]
>Summarizing, the question is: How to avoid to unload / reload all the graphics??

It is impossible to make 100% working protection from device/surface and other losts without Blitz3D sources. So I can't fix it completely. That's why I've suggested to make source code license for Blitz3D. For $500 price, for example.
So it is does not needed for usual hobby Blitz3D programmer(who will not pay such money), but needed for serious casual/shareware games developers(who can pay such price and fix all future bugs by ourselves).


Pinete(Posted 2007) [#24]
understand..
yes, absolutely agree with you...
Right now Blitz3D has some specific lacks that make it unusable to make things like you say, i.e. professional casual games development...
if you could find a solution for this I'll pay the $500 of the license and other $500 for the solution...

best regards!


@rtur(Posted 2007) [#25]
Mark already has two customers for source license of B3D/SDK ;)


DStastny(Posted 2007) [#26]
I wrote a DLL function that handles the detection of the lost device. Guaranteed works in all cases.

As for automatically reloading the surfaces as you found out you cant restore surfaces if they are in vid memory. You also cant restore surfaces if you need to recreate the worth the problem. Its not that hard to structure code to device. Situations such as change resolution or another application going fullscreen.

BMAX works because all graphics a buffered, and the textures are recreated if the device needs to be recreated. I suspect Mark doesnt want to do that due to major underlying changes. I dont want him pausing my application logic due to drawing being suspended.

I am just waiting on SystemProperty to be exposed in SDK and Ill be fine.

Its really simple solution, no hooking messages or testing surfaces.

Read my above post and the documentation for the method. Implement DLL to call that function and process the return.

Doug


DGuy(Posted 2007) [#27]
Thanks to Budman suggestion about 'TestCooperativeLevel()' I was able to simplfy the logic used to detect/handle loss of surfaces. The new logic basically looks like this:

case WM_ACTIVATEAPP:
  {
  _has_focus = (wParam == UINT(TRUE)); 

  if( _has_focus )
    {
    if( _b3d_pddsPrim->IsLost() == DDERR_SURFACELOST )
      {
      while( _b3d_pdd->TestCooperativeLevelsimplify() != DD_OK ) Sleep( 100 );
      _b3d_pdd->RestoreAllSurfaces();
      }
    }
  }
  break;
This restores all surfaces (albeit, without their pre-lost contents), and allows b3D to keep running without MAV. I was able to remove the explicit calls in BB code to check for surface-lost or possible-log outs and was able to discard all the key-press-checks. The only thing I would add is a flag that the user can check to see if they need to reload their graphics.

Now, while the above solution works in all cases my more complex solution did, it also, unfortunetly, fails in the same situation: A loss of focus, while RenderWorld is executing, that results in surface loss.

This leads me to believe that RenderWorld is locking/getting pointers to surfaces and attempting to use those same pointer after surface loss/restore.

Even though a dump of surface info before and after the call to RestoreAllSurfaces show all surfaces as lost, then all surfaces as restored, if this all occurs while RenderWorld is executing, a MAV will result 100% of the time.

@Budman
If you could post the relevent parts of your solution, that would be appreciated. I am very convinced, though, that an external solution is not possible (please, prove me wrong ;) )

David


DGuy(Posted 2007) [#28]
@@rthr:
There is also small bug in blitz games- When game starts in fullscreen and than changed to windowed HWND_TOPMOST(I think) flag not cleared, so game in windowed mode is alway on top of other applications.
(When game launched in window mode than it is not "always on top".)

I ran into that issue also. The way I got around it was after I set windowed mode I call this:
win32_SetWindowPos(SystemProperty("AppHWND"), (-2),0,0,0,0,$03) ;removes ALWAYS-TOP-MOST property when comming from fullscreen mode
decls:
.lib "User32.dll"
win32_SetWindowPos%(hwnd%,hwndInsertAfter%,x%,y%,cx%,cy%,uflags%):"SetWindowPos"
David


DStastny(Posted 2007) [#29]
@DGuy

Here is the code for DLL, I used Delphi since well its quick easy DLL and I had it handy since I am using Delphi with the SDK.

Easy port to C++ though. Note I translated the complex HRESULTS to simple constants to pass back to Blitz.



Now here is sample in Blitz3d since I am waiting for SystemProperty added to SDK.



You'll notice I am not messing with Restoring Surfaces as you pointed out there is not much you can do to guarantee you get it all setback up correctly.

You'll also note I don't lock the main loop. You still want to be able to get application to process a slight delay to yield CPU is all you need. You need to do this if you have network game running and don't want to starve the network code while Testcooperative Level is failing.

This is pretty basic code, come straight from the SDK and I have used it since Dx7 was published with no problems. For some reason BRL never codes this correctly. Took forever to get the driver correct in BMAX.

This should work correctly for all cases Full Screen focus lost, window blitz app losing focus to other full screen dx application, etc. The SDK is real clear this function is the key to making DX7 work friendly with the OS and other applications. Blitz Handles surface lost internally although I doubt textures loaded into video memory are correctly restored. No solution to that other than no real reason to choose that option. Modern Video Cards have more than enough texture memory for us to worry about loading unloading textures.

You want to call this before your check for surface lost. As failure of this function means pretty much your screwed and need to rebuild the display device and reload everything its just needs to be called correctly until it gives you an OK.

Nice catch on the TopMost flag never noticed that.

Doug


Pinete(Posted 2007) [#30]
I guess we should put this in code archives or the Blitz3D other forum too.
This way this important piece of codes will be accesible by more people..
:)

All the best!


@rtur(Posted 2007) [#31]
Thanks DGuy, SetWindowPos works fine.


DGuy(Posted 2007) [#32]
@Budman

I appreciate you taking the time to post the code sample, and again, your mention of TestCooperativeLevel() allowed me to simplify my surface lose logic, Thanks. :)

Unfortunately, even using your logic and after an hour+ more of debugging, using slight logic tweaks and command orderings, I am still able to get RenderWorld to MAV.

The issue is this: Even though a check is being performed JUST before RenderWorld is called, it is still possible from the time the check ends, until the time that RenderWorld completes, for B3D to lose focus, and during focus loss, lose surface memory, and thus cause RenderWorld to go boom.

I've tested this not only with my in-progress app, which consists of a few thousand lines of code, but also with sample apps that come with B3D. As @rthr mentioned, with smaller apps the MAV does not happen as often (probably because B3D is spending less time inside RenderWorld), but it still occurs.

RenderWorld has to be made sensitive to the fact that it can lose the Texture/Surface memory it is working with and respond accordingly. The only way to do that is to have internal access to RenderWorld. Thankfully, Mark seems keen to get this issue solved ...

David


DStastny(Posted 2007) [#33]
@DGUY

I cant imagine what RenderWorld is doing to lose the surface. The way directX works is by with OS to actually yield the surfaces it happens durning processing of the message loop. Basically any time PeekMessage is called the surface is lost. I suspect RenderWorld is calling Peekmessage in which case it would explain the random timing issue as after testing cooperative level you need to do drawing and check returns. If surface lost comes back stop drawing. Dx7 driver implementations are notoriously bad at cheating and not safely dealing with failing gracefully with surface lost conditions. Are you using Video Textures, flag 256 or ImageBuffers? mixing 2d and 3d drawing?

Doug


DStastny(Posted 2007) [#34]
@DGUY

With my test code before RenderWorld are you attempting to restore the surfaces if TestCoop fails? If so the cause of your MAVs might be something else, like you say without the source cant tell. But if the Rendering in Renderworld uses Vertex and Index Buffers they need to be handled as well if the TestCoopertive Fails, RestoreAllSurfaces does not fix them. They need to be destroyed and recreated. Maybe the cause of your problem is tied to the failure to ensure they are in valid state.

In which case if test fails endgraphics reload might fix.


Have you tried minimal case app like my demo which destroys and recreates display and still cause it to crash?

I think your probably right we are going to be stuck until Renderworld is crash safe and possible returns a result as to what we need to do. ie RenderWorld returns false we know we need to recreate our resources.

Reason I am even looking at Dx7 for myself is I need minimal 3d support and to support lower end hardware. Which has me back at Dx7. Blitz3d nice as it is is not powerful enough for what I need in a language, an BMax doesn't support threads so the SDK seems like a happy medium. I would really hate to have to write my own Dx7 engine from scratch as this is part time fun. I already have a full time job.

I didnt have half the trouble writing the Max2d Dx9 driver as I have dealing with Dx7 clunkiness and bad drivers.

I couldnt get my test app to crash under XP but I will move it to my old Win2k laptop with a really crappy video card and try it there.

Doug


@rtur(Posted 2007) [#35]
Mark, any news with Win+L fix?

Can you answer to my emails, please.