PDA

View Full Version : Serious Bug - Date handling with unDelphiX in hardware mode



AthenaOfDelphi
20-02-2007, 01:48 PM
Please see this thread (http://www.pascalgamedevelopment.com/viewtopic.php?t=4190) for details.

Whilst the title suggests this is a date related issue, I have a feeling based on my tests that the problem is much wider ranging (affecting float to string conversions also).

AthenaOfDelphi
20-02-2007, 04:05 PM
The problem appears to be related to the use of floating point instructions (FMUL for example) after DirectX has been initialized using say TDXDraw.initialize.

seiferalmasy
20-02-2007, 04:17 PM
Translated for seifer: Athena is on top of this situation :P

czar
20-02-2007, 05:12 PM
Starting with WIndows XP if you have Do3D set in delphiX you will find you get errors with floats. Set maths precision to double and the porblem is solved.

It took me ages to work this out. We started getting this problem with our maths software quite a few years ago.

Put math into your uses section and set precions to double (can't remember exact code)

AthenaOfDelphi
20-02-2007, 06:22 PM
I'd say starting with Windows 2000 because the problem is affecting my machine.

However, many thanks for that czar,


Set8087CW((Default8087CW and $FCFF) or $0200);


That seems to fix the problem. I banged it into my test bed after the initialization/finalization of TDXDraw and it appears to work :-)

seiferalmasy
20-02-2007, 06:33 PM
Indeed it does. You guys are amazing with that kinda problem solving:) Weldone;)

I take it delphix could be fixed quite easily to sort this problem without the need for that code?

Thanks:)

czar
20-02-2007, 06:39 PM
Yes it probably is win2k also - just none of our users had Windows 2000. So we only noticed it when they start migrating from Windows 98 to XP.

I use this

SetPrecisionMode(pmDouble);

AthenaOfDelphi
20-02-2007, 07:03 PM
Thanks czar,

SetPrecisionMode was introduced with Delphi 6, so seiferalmasy if you are using Delphi 6 or later, then use SetPrecisionMode as opposed to the code I posted.

seiferalmasy
20-02-2007, 07:22 PM
looks like i am snookered for now with easier code, am using D5;)

Sly
20-02-2007, 09:51 PM
Because it uses a floating point number to represent the date and time, as time advances you start to get more floating point inaccuracies. Enabling do3D will be switching the FPU to single-precision mode, this introducing inaccuracies into the floating point calculations required to calculate the date. Switching it back to double-precision mode will increase the floating point accuracy once again, until such a time many years from now where even double-precision is no longer accurate enough.

We had this in our console games as well. With the game running for several days non-stop, several things would just stop working. The main bug was that the player character's run animation would no longer animate, therefore he would be stuck on a single frame of the run animation from that point on but still be moving around the world.

Why was this happening? We have a game timer which gets updated every frame. It is simply a floating point value that gets the frame time added to it. In a 30fps game, it adds 0.0333 to the game time every frame. Floating point numbers are much more accurate at lower values than at higher values. After running non-stop for several days, 0.0333 became less than the floating point accuracy at the current game time, thus adding 0.0333 had no effect on the game time. Animations would stop, game events would stop, but things not relying on the game time would still be behaving as normal.

Clootie
20-02-2007, 11:47 PM
Issue you are seeing is not Windows related, but Direct3D one. Actually it's not an issue, but a "feature". By default after calling Direct3D.CreateDevice() FPU is switched to single precision. One could avoid this by adding D3DCREATE_FPU_PRESERVE flag while calling CreateDevice (MSDN link (http://msdn.microsoft.com/archive/default.asp?url=/archive/en-us/directx9_c/directx/graphics/reference/d3d/constants/d3dcreate.asp)). A lot of additional information can be found just by searching for D3DCREATE_FPU_PRESERVE on Google.