/* ** Command & Conquer Generals(tm) ** Copyright 2025 Electronic Arts Inc. ** ** This program is free software: you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation, either version 3 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program. If not, see . */ /***************************************************************************** ** ** ** Westwood Studios Pacific. ** ** ** ** Confidential Information ** ** Copyright (C) 2000 - All Rights Reserved ** ** ** ****************************************************************************** ** ** ** Project: Dune Emperor ** ** ** ** Module: (_) ** ** ** ** Version: $ID$ ** ** ** ** File name: audtimer.cpp ** ** ** ** Created by: 04/??/99 TR ** ** ** ** Description: ** ** ** *****************************************************************************/ /***************************************************************************** ** Includes ** *****************************************************************************/ #define WIN32_LEAN_AND_MEAN #include #include #include #include #include /***************************************************************************** ** Externals ** *****************************************************************************/ /***************************************************************************** ** Defines ** *****************************************************************************/ /***************************************************************************** ** Private Types ** *****************************************************************************/ /***************************************************************************** ** Private Data ** *****************************************************************************/ static TimeStamp lastTime = 0; static TimeStamp interval = 0; static TimeStamp timeOut = 0; static TimeStamp (*timerFunc)( void ) = NULL;// set to either highResGetTime or // failsafeGetTime at initialization static LONGLONG timerMilliSecScale; // res counter millisecond scaling factor /***************************************************************************** ** Public Data ** *****************************************************************************/ /***************************************************************************** ** Private Prototypes ** *****************************************************************************/ static TimeStamp failsafeGetTime( void ); static TimeStamp highResGetTime( void ); /***************************************************************************** ** Private Functions ** *****************************************************************************/ /******************************************************************/ /* */ /* */ /******************************************************************/ static TimeStamp highResGetTime( void ) { LARGE_INTEGER count; union { TimeStamp timeStamp; LARGE_INTEGER largeInt; } myTime; // read the high res counter QueryPerformanceCounter(&count); // convert high res ticks to number of milliseconds myTime.largeInt.QuadPart = count.QuadPart / timerMilliSecScale; return myTime.timeStamp; } /******************************************************************/ /* */ /* */ /******************************************************************/ static TimeStamp failsafeGetTime( void ) { static volatile TimeStamp time = (TimeStamp) 0x100000000; // last time value static unsigned int* const pl = (unsigned int* const) &time; // low word of time static unsigned int* const ph = (unsigned int* const) ((unsigned int)&time + 4); // high word of time unsigned int now, lw, hw, called; static volatile unsigned int calls = 0; calls++; retry: called = calls; hw = *ph; // read high word of time stamp lw = *pl; // read low word of time stamp if ( called != calls) { // AudioGetTime() has been re-entered. Cannot trust lw and lh values goto retry; } reread: now = timeGetTime (); if ( now < lw ) { // wrap round hw++; // increment high word by one } *ph = hw; *pl = now; if ( called != calls ) { // re-entered. cannot trust *ph and *pl to be correct called = calls; goto reread; } return time; } /***************************************************************************** ** Public Functions ** *****************************************************************************/ /******************************************************************/ /* */ /* */ /******************************************************************/ // // Initialize the high resolution timer by querying the system for it's // availability. If one does exist then we set the game timer function // to 'highResGetTime' otherwise we use the original code at 'failsafeGetTime'. // For the hi res counter we precalculate the millisecond scaling factor to // convert hi res ticks to millisecond usage. void InitAudioTimer( void ) { LARGE_INTEGER freq; // does hardware exist for high res counter? if (QueryPerformanceFrequency(&freq)) { // calculate timer ticks per second timerMilliSecScale = freq.QuadPart / (LONGLONG) SECONDS(1); timerFunc = highResGetTime; } else { // no high res timer, use old code instead timerFunc = failsafeGetTime; } } /******************************************************************/ /* */ /* */ /******************************************************************/ TimeStamp AudioGetTime( void ) { return timerFunc ? timerFunc() : 0 ; }