CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 11 of 11
  1. #1
    Join Date
    Aug 2020
    Posts
    3

    Time calculation in the main game loop.

    There is the code in the Quake 2 main game loop implementation:

    Code:
        if (!initialized)
        {	// let base retain 16 bits of effectively random data
        	base = timeGetTime() & 0xffff0000;
        	initialized = true;
        }
        curtime = timeGetTime() - base;
    I'm wondering about the line:
    base = timeGetTime() & 0xffff0000
    Why are they applying the
    0xffff0000
    mask on the retrieved time?
    Why not to use just:

    Code:
     if (!initialized)
        {	// let base retain 16 bits of effectively random data
        	initialTime = timeGetTime();
        	initialized = true;
        }
        curtime = timeGetTime() - initialTime;
    ???
    What is the role of that mask?

  2. #2
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: Time calculation in the main game loop.

    What is base used for elsewhere? The comment refers to it being used for 16-bit random data??
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  3. #3
    Join Date
    Feb 2017
    Posts
    677

    Re: Time calculation in the main game loop.

    Quote Originally Posted by 2kaud View Post
    What is base used for elsewhere? The comment refers to it being used for 16-bit random data??
    I wondered that too and found the file where the OP code is from. It's halfway down here,

    https://unix.superglobalmegacorp.com...q_shwin.c.html

    The base variable is static and local to the function.

  4. #4
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: Time calculation in the main game loop.

    On Windows, timeGetTime() returns the elapsed time since the system was started in milliseconds as an unsigned 32 bit value. base will be up to approx 65 seconds less than the actual time since Windows was started as the lower 16 bits are zeroed. It is being assigned to an int which is signed. For the subtraction, base will be promoted to unsigned, subtracted from the unsigned result from timeGetTime() to produce an unsigned number and is then cast to a signed int!

    In this context, I don't get the comment re 16 bits of random data. The top 16 bits of base will effectively be 16 bits of random data, but this doesn't seem to be used elsewhere??

    As curtime is based upon base, it can be overstated by up to 65 seconds. What is curtime/Sys_Milliseconds() used for elsewhere?

    Why not just as per OP post #1 (not tried):

    Code:
    unsigned int curtime;
    
    unsigned int Sys_Milliseconds (void)
    {
    	static unsigned int base = timeGetTime();
    
    	return curtime = timeGetTime() - base;
    }
    It depends, I guess, as to how curtime/Sys_Milliseconds() is used.

    PS Is this code for Windows or Linux - see post #5
    Last edited by 2kaud; August 26th, 2020 at 06:08 AM.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  5. #5
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: Time calculation in the main game loop.

    Quote Originally Posted by wolle View Post
    I wondered that too and found the file where the OP code is from. It's halfway down here,

    https://unix.superglobalmegacorp.com...q_shwin.c.html

    The base variable is static and local to the function.
    If this is the source code referred, then timeGetTime() is implemented somewhere as timeGetTime() is a Windows API, not a Linux/Unix one and that reference is for Unix/Linux. Unix/Linux doesn't have timeGetTime() API as standard. The implemented version may be different from the Windows version.
    Last edited by 2kaud; August 26th, 2020 at 06:10 AM.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  6. #6
    Join Date
    Aug 2020
    Posts
    3

    Re: Time calculation in the main game loop.

    Quote Originally Posted by 2kaud View Post
    If this is the source code referred, then timeGetTime() is implemented somewhere as timeGetTime() is a Windows API, not a Linux/Unix one and that reference is for Unix/Linux. Unix/Linux doesn't have timeGetTime() API as standard. The implemented version may be different from the Windows version.
    The code is indeed from original Quake2 game source code for Windows. I'm supporting the code once again, but this time with context, where the
    Sys_Milliseconds
    function is actually called.


    Sys_Milliseconds function implementation (q_shwin.c):

    Code:
    /*
    ================
    Sys_Milliseconds
    ================
    */
    int	curtime;
    int Sys_Milliseconds (void)
    {
    	static int		base;
    	static qboolean	initialized = false;
    
    	if (!initialized)
    	{	// let base retain 16 bits of effectively random data
    		base = timeGetTime() & 0xffff0000;
    		initialized = true;
    	}
    	curtime = timeGetTime() - base;
    
    	return curtime;
    }
    So I You are so nice and try to comment it...

    Sys_Milliseconds function usage (sys_win.c) - the main game loop:

    Code:
    ...
    	oldtime = Sys_Milliseconds ();
    
            /* main window message loop */
    	while (1)
    	{
    		// if at a full screen console, don't update unless needed
    		if (Minimized || (dedicated && dedicated->value) )
    		{
    			Sleep (1);
    		}
    
    		while (PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE))
    		{
    			if (!GetMessage (&msg, NULL, 0, 0))
    				Com_Quit ();
    			sys_msg_time = msg.time;
    			TranslateMessage (&msg);
       			DispatchMessage (&msg);
    		}
    
    		do
    		{
    			newtime = Sys_Milliseconds ();
    			time = newtime - oldtime;
    		} while (time < 1);
    //			Con_Printf ("time:%5.2f - %5.2f = %5.2f\n", newtime, oldtime, time);
    
    		//	_controlfp( ~( _EM_ZERODIVIDE /*| _EM_INVALID*/ ), _MCW_EM );
    		_controlfp( _PC_24, _MCW_PC );
    		Qcommon_Frame (time);
    
    		oldtime = newtime;
    	}
    ...
    Now I'm wondering is it at all possible for the
    time
    variable to be < 1? since the
    oldtime
    will ALWAYS be > then
    newtime
    just because we take the
    newtime
    AFTER the
    oldtime
    !?

    Can You be so nice and try to explain it to Me.
    Thx.

  7. #7
    Join Date
    Feb 2017
    Posts
    677

    Re: Time calculation in the main game loop.

    Quote Originally Posted by 2kaud View Post
    In this context, I don't get the comment re 16 bits of random data. The top 16 bits of base will effectively be 16 bits of random data, but this doesn't seem to be used elsewhere??
    I interpret this comment,

    // let base retain 16 bits of effectively random data

    to mean that it's not the randomness of base that is retained, it's the randomness of Sys_Milliseconds that base helps retain.

    If base was done like this,

    base = timeGetTime()

    then Sys_Milliseconds would always start from 0 (or close to). But if it's done like this,

    base = timeGetTime() & 0xffff0000;

    then Sys_Milliseconds will start with a number consisting of 16 random bits.

    This can be important because people often call the system timer to get a "real" random value when an application starts and this "trick" with base makes sure Sys_Milliseconds delivers that.
    Last edited by wolle; August 26th, 2020 at 01:34 PM.

  8. #8
    Join Date
    Feb 2017
    Posts
    677

    Re: Time calculation in the main game loop.

    Quote Originally Posted by Derek911 View Post
    Now I'm wondering is it at all possible for the time variable to be < 1? since the oldtime
    will ALWAYS be > then newtime just because we take the newtime AFTER the oldtime !?
    Are you sure? I'd say it's the other way around because almost always the arrow of time is represented by increasing clocks. It means newtime will always be equal to or larger than oldtime.

    What I understand, the time-delay do-loop in the code you showed ensures that the PeekMessage while-loop is entered once per millisecond at the most.
    Last edited by wolle; August 27th, 2020 at 01:40 AM.

  9. #9
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: Time calculation in the main game loop.

    Quote Originally Posted by wolle View Post
    I interpret this comment,

    // let base retain 16 bits of effectively random data

    to mean that it's not the randomness of base that is retained, it's the randomness of Sys_Milliseconds that base helps retain.

    If base was done like this,

    base = timeGetTime()

    then Sys_Milliseconds would always start from 0 (or close to). But if it's done like this,

    base = timeGetTime() & 0xffff0000;

    then Sys_Milliseconds will start with a number consisting of 16 random bits.

    This can be important because people often call the system timer to get a "real" random value when an application starts and this "trick" with base makes sure Sys_Milliseconds delivers that.
    Yes, but it doesn't seem to be used this way - as per comment in post #8
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  10. #10
    Join Date
    Feb 2017
    Posts
    677

    Re: Time calculation in the main game loop.

    Quote Originally Posted by 2kaud View Post
    Yes, but it doesn't seem to be used this way - as per comment in post #8
    Well, not in this particular OP case but I suppose Sys_Milliseconds is originally designed for general use to behave as expected of a system timer (as I describe in #7). Anyway, that's the only reason I can think of that motivates,

    base = timeGetTime() & 0xffff0000;
    Last edited by wolle; August 27th, 2020 at 03:24 AM.

  11. #11
    Join Date
    Sep 2020
    Posts
    3

    Re: Time calculation in the main game loop.

    Thanks for this!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured