Fixed a problem with timer values that are smaller than the minimum time that can be assigned to the SetTimer() win32 call (approx 50ms). The patch splits up the timer into several interrupts if too long time has passed. This fixes good old OutRun, which uses timers of approx 10ms. As a bonus, this aalso fixes situations where we have fallen behind for other reasons.

Peter Dons Tychsen donpedro at tdcadsl.dk
Wed Nov 26 15:22:41 CST 2008


---
 dlls/winedos/timer.c |   24 ++++++++++++++++++++----
 1 files changed, 20 insertions(+), 4 deletions(-)

diff --git a/dlls/winedos/timer.c b/dlls/winedos/timer.c
index f023b85..fe3cf5a 100644
--- a/dlls/winedos/timer.c
+++ b/dlls/winedos/timer.c
@@ -58,6 +58,8 @@ static UINT TIMER_ticks = 0;
 /* Number of pending timer IRQs. */
 static LONG TIMER_pending = 0;
 
+/* Number of milliseconds between IRQs. */
+static DWORD TIMER_millis = 0;
 
 /*********************************************************************** 
  *              TIMER_Relay
@@ -81,11 +83,11 @@ static void CALLBACK TIMER_TimerProc( HWND     hwnd,
                                       DWORD    dwTime )
 {
     LONG pending = InterlockedIncrement( &TIMER_pending );
+    DWORD delta = (dwTime >= TIMER_stamp) ? 
+        (dwTime - TIMER_stamp) : (0xffffffff - (TIMER_stamp - dwTime));
 
     if (pending >= TIMER_MAX_PENDING)
     {
-        DWORD delta = (dwTime >= TIMER_stamp) ? 
-            (dwTime - TIMER_stamp) : (0xffffffff - (TIMER_stamp - dwTime));
 
         if (delta >= 60000)
         {
@@ -97,8 +99,19 @@ static void CALLBACK TIMER_TimerProc( HWND     hwnd,
     }
     else
     {
-        TIMER_stamp = dwTime;
-        DOSVM_QueueEvent( 0, DOS_PRIORITY_REALTIME, TIMER_Relay, NULL );
+        int i;
+        
+        /* Calculate the number of valid timer interrupts we can generate */
+        DWORD count = delta / TIMER_millis;
+        
+        /* Forward the timestamp with the time used */
+        TIMER_stamp += (count * TIMER_millis);
+        
+        /* Generate interrupts */
+        for(i=0;i<count;i++)
+        { 
+          DOSVM_QueueEvent( 0, DOS_PRIORITY_REALTIME, TIMER_Relay, NULL );
+        }
     }
 }
 
@@ -122,6 +135,9 @@ static void WINAPI TIMER_DoSetTimer( ULONG_PTR arg )
     TIMER_id = SetTimer( NULL, 0, millis, TIMER_TimerProc );
     TIMER_stamp = GetTickCount();
     TIMER_ticks = arg;
+    
+    /* Remember number of milliseconds to wait */
+    TIMER_millis = millis;
 }
 
 
-- 
1.5.4.3


--=-jHjl7yp3RBchEH/a0DzU--




More information about the wine-patches mailing list