Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

DarkBASIC Professional Discussion / Games not Running Correctly on Windows 8.1

Author
Message
zoltar
14
Years of Service
User Offline
Joined: 2nd Mar 2011
Location:
Posted: 9th Oct 2015 20:15 Edited at: 9th Oct 2015 20:18
Good day everybody. Yesterday I discovered that my games no longer run correctly on Windows 8.1 Single Language. I haven't discarded the possibility of being a combination with or specific to a hardware.

The symptoms are varied, from not making a transition between levels, to not changing the angle of a sprite. However, there are no crashes.

I will try to isolate the commands that are not longer working properly. Meanwhile, I thought it'd be a good idea to ask if anyone experienced the same problem and already figured out a solution or anyone has any idea on what could be going on. I would really appreciate any input on this subject.

The games were tested on the following Windos 8.1 configurations:

Alienware 17 R2
Windows 8.1 Single Language
Intel i7
Nvidia GTX 980M

Microsoft Surface
Windows 8.1 Pro
Intel i5
Intel Embedded Graphics

A comparison of the Windows Update log didn't throw any significant differences between both computers. The games still work fine on Windows XP, Windows Vista and Windows 8.1 Pro but not on Windows 8.1 Single Language. I haven't tested them yet on Windows 7 or 10.

Edit: the application type of the executable files is media without compression or encryption.
Cescano
10
Years of Service
User Offline
Joined: 4th Sep 2014
Location: Italy
Posted: 9th Oct 2015 21:38
Hi, I have developed a 73k lines game under Windows 8.1 and I didn't had any problem of compatibility (except opening the latest editor updated 2010).

Can you explain better what happens exactly when you make a transition from a level to the next one?
Do you have updated DBpro to the latest 7.7 version?
zoltar
14
Years of Service
User Offline
Joined: 2nd Mar 2011
Location:
Posted: 9th Oct 2015 22:17
Hi, Cescano. The games were compiled using DBPro compiler 1.077 with DBPro Editor (Powered by Synergy) Build Jun 23 2010 on a Windows XP machine. The games were running fine across all Windows versions until yesterday when they stopped running correctly on Windows 8.1 SL. I know is impossible to help without some code so I'm trying to isolate the problem in one of the games so we can focus the efforts on the culprit. So far the problem is not the rotate sprite command, which works fine on its own, but it seems a function never gets called when the game runs on Windows 8.1 SL. Probably the interpreter.
zoltar
14
Years of Service
User Offline
Joined: 2nd Mar 2011
Location:
Posted: 10th Oct 2015 00:53
Really odds things going on. Like different behaviors depending on the depth of nested functions or unexpected elapsed time of 60 seconds instead of 1000 milliseconds. My best guess so far is how the timer() command behaves on different Windows versions or how the interpreter initializes the variables on different Windows versions or so it seems. I found a negligible logical error while passing a time stamp where I was initializing a declared local variable but passing an undeclared and uninitialized variable instead. Once I fixed that the game started to behave as expected once again. The odd thing is that the games just recently started to produce this unexpected behavior on Windows 8.1 SL.

The explanation of what I call a negligible logical error is as follows. I trigger timed events by comparing a time stamp that is propagated through out the game against a time stamp and a latency associated to an object. If the result of the propagated time stamp minus the object's time stamp is greater than the object's latency then a timed event is triggered for that object. As far as I know the timer() command will always return a value greater than zero and an undeclared variable will always be initialized to zero so the first test will always be true for the average latency that is under 1000 to 10000 milliseconds when a time stamp of zero is passed along.

Any thoughts, ideas or comments on this issue are welcome.
Cescano
10
Years of Service
User Offline
Joined: 4th Sep 2014
Location: Italy
Posted: 10th Oct 2015 03:57
So far the only thing I have in mind could be you are using a variable not set to global.
I use to set as global most of the variables I use, it's not Worth trying to save a few KB of memory while instead you could create bugs here and there.

Maybe you could post the exact code you are using to do the math. I have had problems with the timer() in the past as well. Loading a saved game for example was doing the same problem you are having because it was comparing the old timer saved with the current time on the machine (that was the first time I have made a save system so I have dropped in the file any variable).
Never save a timer variable on a saved game.

Also I am not sure 100% but I recall that the timer() works also with negative numbers, I don't remember if in Dbpro or while programming in second life with the LSL.
Chris Tate
DBPro Master
16
Years of Service
User Offline
Joined: 29th Aug 2008
Location: London, England
Posted: 10th Oct 2015 10:58
I have seen that the Timer() function returns the the system time since the system started; so after a number of days being left on it the signed integer may roll back. I haven't used the function for years.

You should use the Matrix1 HiTimer() function instead, which commences from when your application starts and has an overload for return different frequencies of time; it is the best timer function I have seen available. There is also Lee's PerfTimer() command which provides high frequency timing.
zoltar
14
Years of Service
User Offline
Joined: 2nd Mar 2011
Location:
Posted: 10th Oct 2015 21:16 Edited at: 10th Oct 2015 21:25
It turns out my guess was correct. The Timer() command behavior is different on different Windows versions, but it shouldn't, so I can only conclude that the Kernel32 library comes with a bug, at least, on Windows 8.1 Pro and Single Language.

If I remember correctly the Timer() command simply calls the GetTickCount() function located in the Kernel32 library. Someone who is more familiar with the actual code might want to correct me if I'm wrong. However, I "verified" this by calling Timer() and GetTickCount() side by side and also "confirmed" that the variables are initialized to zero by DBPro.

On Windows XP and Vista, Timer() returns a positive number equivalent to the elapsed time since the computer was turned on and the function call starting from zero. This matches the documented behavior of the function on MSDN.

On Windows 8.1 Single Language, Timer() returns a number equivalent to the elapsed time since the computer was turned on and the function call but starting from the most negative value of a 32-bit signed variable. This differs from the documented behavior.

On Windows 8.1 Pro, Timer() returns a very high positive value, outside the range of a 32-bit unsigned variable, that cannot possibly be equivalent to the elapsed time since the computer was turned on and the function call. This also differs from the documented behavior.

Here's the code I used



Both Windows 8.1 behaviors are unexpected but things only get wacky when the Timer() command returns a negative number and you are, intentionally or not, relying on the default initialization of variables.

Windows API Kernel32 Library GetTickCount() function MSDN Documentation
https://msdn.microsoft.com/en-us/library/windows/desktop/ms724408%28v=vs.85%29.aspx

Most likely the odd behavior on my other games relates to this problem but in case it's something else I'll post an update about it.

@Cescano

The language favors, actually enforces, the use of global variables, as you cannot pass them to functions by reference or have functions to return structured types. Anyway, somehow the propagation of the timestamp as a parameter makes more sense to me in this case. It was the ability to (unintentionally) use an undeclared variable on the fly that made me trip on this.

The math is very simple

if current_time - recorded_time > latency
`time to do something here
endif

Thanks for the tips and help.

@Chris Tate

Yes, that's a documented behavior for GetTickCount(), after aproximmately 49.7 the variable overflows and rolls back to zero. But as long as it is an unsigned variable (DWORD) you can safely compute the absolute difference between two values directly with at most an error of one unit which is negligible for a value that has a resolution of 10 to 16 units.

I have that library sitting around somewhere. The author is IanM if I remember correctly. I haven't used it because my games are too simple for a high resolution timer. Same goes for Lee's PerfTimer() command.

Thanks for the tips and help.
Chris Tate
DBPro Master
16
Years of Service
User Offline
Joined: 29th Aug 2008
Location: London, England
Posted: 10th Oct 2015 22:40 Edited at: 10th Oct 2015 22:43
Cool, just to clarify a bit better; HiTimer() uses a high resolution only when you tell it to via the frequency parameter; otherwise it uses milliseconds just like Timer()/GetTickCount() (and if desired, seconds, minutes or any-given frequency of time).

Thanks for the useful information
WickedX
16
Years of Service
User Offline
Joined: 8th Feb 2009
Location: A Mile High
Posted: 11th Oct 2015 07:11
DarkBasic Professional timer function calls the window multimedia API function timeGetTime. The timeGetTime function is more accurate. GetTickCount is incremented by the clock tick frequency on every clock tick and as such the delta values waver around the actual time but timeGetTime’s delta is highly predictable.

zoltar
14
Years of Service
User Offline
Joined: 2nd Mar 2011
Location:
Posted: 11th Oct 2015 19:20
@Chris Tate

Thanks for the clarification. Do you know what Windows API function is called by HiTimer()?

@WickedX

Thanks for the insight. Do you know what resolution is used?

@All

Things are getting weirder to the point of feeling like I'm telling a tale about Sasquatch while holding a dark grainy picture taken with a potato.

Out of curiosity I tested the behavior of timeGetTime() side by side with Timer() and GetTickCount(). To my surprise all three functions were returning a small positive value within the range of an unsigned 32-bit variable on Windows 8.1 Single Language. So I tested the behavior of the games and all were running smoothly again as if nothing had ever happened. I checked the Windows Update log looking for a fresh update but nothing was installed in the last week. I have no idea what's going on.

I also noticed that the value on Windows 8.1 SL was above 4,800,000 but the computer was turned on for only a couple of minutes. At least yesterday the value was more accurate in terms of what should be returned by the function, regardless of it being negative.

Taking aside a better resolution and its consistency, the value returned by timeGetTime() should behave exactly as the one returned by GetTickCount(). That is, a DWORD value equivalent to the elapsed time since the computer was started and when the function was called. So again, there's no chance for it to be bigger than 2^32 or negative, as it was happening yesterday on Windows 8.1 Pro and Single Language, respectively.

For those who want to run their own tests here's the code. I haven't done any tests on Windows 7 so results on it are welcome.



Windows API WinMM Library timeGetTime() function MSDN Documentation
https://msdn.microsoft.com/en-us/library/windows/desktop/dd757629(v=vs.85).aspx
WickedX
16
Years of Service
User Offline
Joined: 8th Feb 2009
Location: A Mile High
Posted: 11th Oct 2015 21:21
This is from the msdn links you provided.

GetTickCount:
Quote: "The resolution of the GetTickCount function is limited to the resolution of the system timer, which is typically in the range of 10 milliseconds to 16 milliseconds."


timeGetTime:
Quote: "The default precision of the timeGetTime function can be five milliseconds or more, depending on the machine. You can use the timeBeginPeriod and timeEndPeriod functions to increase the precision of timeGetTime."


This is the internal code for DBPro’s timer function.


HiTimer calls the kernel32 function QueryPerformanceCounter.
zoltar
14
Years of Service
User Offline
Joined: 2nd Mar 2011
Location:
Posted: 12th Oct 2015 19:00 Edited at: 12th Oct 2015 19:01
@WickedX

Thank you, very insightful. Yes, the value passed by DBPro to the time*Period() functions was what I was asking about. I wonder why they (Lee?) decided to typecast the dword into an integer, that's odd. Anyway, cheers!
samimnoorzaitgc
User Banned
Posted: 7th Dec 2015 18:58
Anyway, seems like you got your answer @zoltar.
Grow your Audience with our Reliable, Global and Real Traffic. Trusted Traffic Store provides cheap instant website traffic:
www.trustedtrafficstore.co As cheap as $12.99 for ten thousand global website traffic. Give your website a boost of traffic now!

Login to post a reply

Server time is: 2025-08-08 17:19:09
Your offset time is: 2025-08-08 17:19:09