Index: trunk/src/winmm/dwaveout.cpp
===================================================================
--- trunk/src/winmm/dwaveout.cpp	(revision 5347)
+++ trunk/src/winmm/dwaveout.cpp	(revision 5348)
@@ -1,3 +1,3 @@
-/* $Id: dwaveout.cpp,v 1.32 2001-03-19 19:28:38 sandervl Exp $ */
+/* $Id: dwaveout.cpp,v 1.33 2001-03-21 12:33:22 sandervl Exp $ */
 
 /*
@@ -118,5 +118,5 @@
 
     curPlayBuf = curFillBuf = curFillPos = curPlayPos = 0;
-    readPos = writePos = 0;
+    bytesPlayed = bytesCopied = bytesReturned = 0;
 
     fMixerSetup   = FALSE;
@@ -130,4 +130,5 @@
     volume        = defvolume;
     State         = STATE_STOPPED;
+    queuedbuffers = 0;
 
     MixBuffer     = (MCI_MIX_BUFFER *)malloc(PREFILLBUF_DART*sizeof(MCI_MIX_BUFFER));
@@ -301,4 +302,5 @@
     int i, buflength;
 
+    queuedbuffers++;
     if(fMixerSetup == FALSE)
     {
@@ -383,5 +385,5 @@
 
         curPlayBuf = curFillBuf = curFillPos = curPlayPos = 0;
-        readPos = writePos = 0;
+        bytesPlayed = bytesCopied = bytesReturned = 0;
 
         for(i=0;i<PREFILLBUF_DART;i++) {
@@ -433,9 +435,28 @@
 
         writeBuffer();  //must be called before (re)starting playback
-
         wmutex->leave();
+
         if(State == STATE_STOPPED) {//continue playback
             restart();
         }
+        else
+        if(fUnderrun) {
+            dprintf(("Resume playback after underrun"));
+            fUnderrun = FALSE;
+            State = STATE_PLAYING;
+
+            memset(&GenericParms, 0, sizeof(GenericParms));
+
+            // Resume the playback.
+            mciSendCommand(DeviceId, MCI_RESUME, MCI_WAIT, (PVOID)&GenericParms, 0);
+
+            //write buffers to DART; starts playback
+            // MCI_MIXSETUP_PARMS->pMixWrite does alter FS: selector!
+            USHORT selTIB = GetFS(); // save current FS selector
+
+            MixSetupParms->pmixWrite(MixSetupParms->ulMixHandle, &MixBuffer[curPlayBuf], 1);
+
+            SetFS(selTIB);           // switch back to the saved FS selector
+        }
     }
     return(MMSYSERR_NOERROR);
@@ -446,4 +467,6 @@
 {
  MCI_GENERIC_PARMS Params;
+
+    dprintf(("WINMM: DartWaveOut::pause"));
 
     wmutex->enter(VMUTEX_WAIT_FOREVER);
@@ -459,5 +482,5 @@
     memset(&Params, 0, sizeof(Params));
 
-    // Stop the playback.
+    // Pause the playback.
     mciSendCommand(DeviceId, MCI_PAUSE, MCI_WAIT, (PVOID)&Params, 0);
 
@@ -483,5 +506,5 @@
 
     curPlayBuf = curFillBuf = curFillPos = curPlayPos = 0;
-    readPos = writePos = 0;
+    bytesPlayed = bytesCopied = bytesReturned = 0;
 
     return(MMSYSERR_NOERROR);
@@ -510,4 +533,5 @@
         wavehdr->dwFlags  |= WHDR_DONE;
         wavehdr->dwFlags  &= ~WHDR_INQUEUE;
+        wavehdr->reserved  = 0;
         tmpwavehdr         = wavehdr;
         wavehdr            = wavehdr->lpNext;
@@ -530,5 +554,6 @@
 
     curPlayBuf = curFillBuf = curFillPos = curPlayPos = 0;
-    readPos = writePos = 0;
+    bytesPlayed = bytesCopied = bytesReturned = 0;
+    queuedbuffers = 0;
 
     wmutex->leave();
@@ -567,4 +592,5 @@
         SetFS(selTIB);           // switch back to the saved FS selector
     }
+
     return(MMSYSERR_NOERROR);
 }
@@ -674,5 +700,5 @@
  WAVEHDR *whdr, *prevhdr = NULL;
 
-    dprintf2(("WINMM: handler %d\n", curPlayBuf));
+    dprintf2(("WINMM: handler %d; buffers left %d", curPlayBuf, queuedbuffers));
     if(ulFlags == MIX_STREAM_ERROR) {
         if(ulStatus == ERROR_DEVICE_UNDERRUN) {
@@ -693,5 +719,5 @@
     wmutex->enter(VMUTEX_WAIT_FOREVER);
 
-    readPos += MixBuffer[curPlayBuf].ulBufferLength;
+    bytesPlayed += MixBuffer[curPlayBuf].ulBufferLength;
 
     if(curPlayBuf == PREFILLBUF_DART-1)
@@ -699,28 +725,21 @@
     else curPlayBuf++;
 
+    fUnderrun = FALSE;
+
     whdr = wavehdr;
-    if(whdr == NULL) {
-        //last buffer played -> no new ones -> silence buffer & continue
-        dprintf(("WINMM: WaveOut handler LAST BUFFER PLAYED! state %s", (State == STATE_PLAYING) ? "playing" : "stopped"));
-        if(State == STATE_PLAYING) {
-            fUnderrun = TRUE;
-////            memset(MixBuffer[curPlayBuf].pBuffer, 0, MixBuffer[curPlayBuf].ulBufferLength);
-            goto sendbuffer;
-        }
-        wmutex->leave();
-        return;
-    }
-    fUnderrun = FALSE;
     while(whdr) {
         if(whdr->reserved == WHDR_DONE)
         {
-            if(readPos < writePos + whdr->dwBufferLength) {
-                dprintf2(("Buffer marked done, but not yet played completely (%d,%d)", readPos, writePos));
+            if(bytesPlayed < bytesReturned + whdr->dwBufferLength) {
+                dprintf2(("Buffer marked done, but not yet played completely (play %d/%d, cop %d, ret %d)", bytesPlayed, getPosition(), bytesCopied, bytesReturned));
                 break;  //not yet done
             }
 
-            dprintf2(("WINMM: handler buf %X done (read %d, write %d)", whdr, readPos, writePos));
-            whdr->dwFlags &= ~WHDR_INQUEUE;
-            whdr->dwFlags |= WHDR_DONE;
+            dprintf2(("WINMM: handler buf %X done (play %d/%d, cop %d, ret %d)", whdr, bytesPlayed, getPosition(), bytesCopied, bytesReturned));
+            queuedbuffers--;
+
+            whdr->dwFlags  &= ~WHDR_INQUEUE;
+            whdr->dwFlags  |= WHDR_DONE;
+            whdr->reserved  = 0;
 
             if(prevhdr == NULL)
@@ -730,5 +749,5 @@
             whdr->lpNext = NULL;
 
-            writePos += whdr->dwBufferLength;
+            bytesReturned += whdr->dwBufferLength;
             wmutex->leave();
 
@@ -750,4 +769,17 @@
     }
 
+    if(wavehdr == NULL) {
+        //last buffer played -> no new ones -> silence buffer & continue
+        dprintf(("WINMM: WaveOut handler LAST BUFFER PLAYED! state %s (play %d (%d), cop %d, ret %d)", (State == STATE_PLAYING) ? "playing" : "stopped", bytesPlayed, getPosition(), bytesCopied, bytesReturned));
+        if(State == STATE_PLAYING) {
+            fUnderrun = TRUE;
+            pause();
+////            memset(MixBuffer[curPlayBuf].pBuffer, 0, MixBuffer[curPlayBuf].ulBufferLength);
+////            goto sendbuffer;
+        }
+        wmutex->leave();
+        return;
+    }
+
     writeBuffer();
 
@@ -760,4 +792,6 @@
     MixSetupParms->pmixWrite(MixSetupParms->ulMixHandle, &MixBuffer[curPlayBuf], 1);
     SetFS(selTIB);           // switch back to the saved FS selector
+
+    dprintf2(("WINMM: handler DONE"));
 }
 /******************************************************************************/
@@ -792,10 +826,11 @@
         memcpy((char *)MixBuffer[curFillBuf].pBuffer + curPlayPos,
                curhdr->lpData + curFillPos,  buflength);
-        curPlayPos += buflength;
-        curFillPos += buflength;
-
+        curPlayPos  += buflength;
+        curFillPos  += buflength;
+        bytesCopied += buflength;
 
         if(curFillPos == curhdr->dwBufferLength) {
-            dprintf2(("Buffer %d done (%x)", curFillBuf, curhdr));
+            dprintf2(("Buffer %d done ptr %x size %d %x %x %x %x %x %x", curFillBuf, curhdr->lpData, curhdr->dwBufferLength, curhdr->dwBytesRecorded, curhdr->dwUser, curhdr->dwFlags, curhdr->dwLoops, curhdr->lpNext, curhdr->reserved));
+
             curFillPos = 0;
             curhdr->reserved = WHDR_DONE;
Index: trunk/src/winmm/dwaveout.h
===================================================================
--- trunk/src/winmm/dwaveout.h	(revision 5347)
+++ trunk/src/winmm/dwaveout.h	(revision 5348)
@@ -1,3 +1,3 @@
-/* $Id: dwaveout.h,v 1.11 2001-03-19 19:28:38 sandervl Exp $ */
+/* $Id: dwaveout.h,v 1.12 2001-03-21 12:33:22 sandervl Exp $ */
 
 /*
@@ -85,5 +85,6 @@
     int   curPlayBuf, curFillBuf;
     ULONG curFillPos, curPlayPos; //fillpos == pos in os2 mix buffer, bufpos == pos in win buffer
-    ULONG readPos, writePos;
+    ULONG bytesPlayed, bytesCopied, bytesReturned;
+    int   queuedbuffers;
 
     // callback interface
Index: trunk/src/winmm/time.cpp
===================================================================
--- trunk/src/winmm/time.cpp	(revision 5347)
+++ trunk/src/winmm/time.cpp	(revision 5348)
@@ -1,3 +1,3 @@
-/* $Id: time.cpp,v 1.9 2000-02-17 14:09:32 sandervl Exp $ */
+/* $Id: time.cpp,v 1.10 2001-03-21 12:33:22 sandervl Exp $ */
 
 /*
@@ -223,4 +223,5 @@
               UINT,     arg2)
 {
+  dprintf2(("timeGetSystemTime %x %d", arg1, arg2));
   return O32_timeGetSystemTime(arg1, arg2);
 }
@@ -241,5 +242,24 @@
 DWORD WIN32API timeGetTime()
 {
-  return O32_timeGetTime();
-}
-
+ DWORD time;
+#if 0
+ LARGE_INTEGER lint;
+ static LARGE_INTEGER freq;
+ static BOOL fInit = FALSE;
+
+  if(fInit == FALSE) {
+     QueryPerformanceFrequency(&freq);
+     freq.LowPart /= 1000;
+     fInit = TRUE;
+  }
+  QueryPerformanceCounter(&lint);
+  time = lint.LowPart/freq.LowPart;
+  dprintf2(("timeGetTime %x (%x:%x)", time, lint.LowPart, lint.HighPart));
+#else
+  //SvL: TODO: Inaccurate
+  time = O32_timeGetTime();
+  dprintf2(("timeGetTime %x", time));
+#endif
+  return time;
+}
+
Index: trunk/src/winmm/waveout.cpp
===================================================================
--- trunk/src/winmm/waveout.cpp	(revision 5347)
+++ trunk/src/winmm/waveout.cpp	(revision 5348)
@@ -1,3 +1,3 @@
-/* $Id: waveout.cpp,v 1.18 2001-03-19 19:28:39 sandervl Exp $ */
+/* $Id: waveout.cpp,v 1.19 2001-03-21 12:33:22 sandervl Exp $ */
 //#undef DEBUG
 /*
@@ -108,5 +108,5 @@
         pwh->dwFlags &= ~WHDR_DONE;
 
-        dprintf(("waveOutWrite %x %d %x", pwh->lpData, pwh->dwBufferLength, pwh->dwFlags));
+        dprintf(("waveOutWrite ptr %x size %d %x %x %x %x %x %x", pwh->lpData, pwh->dwBufferLength, pwh->dwBytesRecorded, pwh->dwUser, pwh->dwFlags, pwh->dwLoops, pwh->lpNext, pwh->reserved));
         return(dwave->write(pwh, cbwh));
   }
