SDL: directsound: Cleaned up WaitDevice.

From a0820ed8332d3f049674217a6e0bb508fc863b54 Mon Sep 17 00:00:00 2001
From: "Ryan C. Gordon" <[EMAIL REDACTED]>
Date: Tue, 3 Oct 2023 09:54:30 -0400
Subject: [PATCH] directsound: Cleaned up WaitDevice.

This should retry until GetCurrentPosition succeeds. Otherwise, we would be
going on to the next iteration too soon.

Also generally streamlined the code while I was in here.
---
 src/audio/directsound/SDL_directsound.c | 58 +++++++------------------
 1 file changed, 16 insertions(+), 42 deletions(-)

diff --git a/src/audio/directsound/SDL_directsound.c b/src/audio/directsound/SDL_directsound.c
index ab12c8cd9a33..bf812b50b4f7 100644
--- a/src/audio/directsound/SDL_directsound.c
+++ b/src/audio/directsound/SDL_directsound.c
@@ -227,61 +227,35 @@ static void DSOUND_DetectDevices(SDL_AudioDevice **default_output, SDL_AudioDevi
 
 static void DSOUND_WaitDevice(SDL_AudioDevice *device)
 {
-    DWORD status = 0;
-    DWORD cursor = 0;
-    DWORD junk = 0;
-    HRESULT result = DS_OK;
-
     /* Semi-busy wait, since we have no way of getting play notification
        on a primary mixing buffer located in hardware (DirectX 5.0)
      */
-    result = IDirectSoundBuffer_GetCurrentPosition(device->hidden->mixbuf,
-                                                   &junk, &cursor);
-    if (result != DS_OK) {
-        if (result == DSERR_BUFFERLOST) {
-            IDirectSoundBuffer_Restore(device->hidden->mixbuf);
-        }
-#ifdef DEBUG_SOUND
-        SetDSerror("DirectSound GetCurrentPosition", result);
-#endif
-        return;
-    }
-
-    while ((cursor / device->buffer_size) == device->hidden->lastchunk) {
-        if (SDL_AtomicGet(&device->shutdown)) {
-            return;
-        }
-
-        SDL_Delay(1);
+    while (!SDL_AtomicGet(&device->shutdown)) {
+        DWORD status = 0;
+        DWORD cursor = 0;
+        DWORD junk = 0;
+        HRESULT result = DS_OK;
 
         // Try to restore a lost sound buffer
         IDirectSoundBuffer_GetStatus(device->hidden->mixbuf, &status);
         if (status & DSBSTATUS_BUFFERLOST) {
             IDirectSoundBuffer_Restore(device->hidden->mixbuf);
-            IDirectSoundBuffer_GetStatus(device->hidden->mixbuf, &status);
-            if (status & DSBSTATUS_BUFFERLOST) {
-                break;
+        } else if (!(status & DSBSTATUS_PLAYING)) {
+            result = IDirectSoundBuffer_Play(device->hidden->mixbuf, 0, 0, DSBPLAY_LOOPING);
+        } else {
+            // Find out where we are playing
+            result = IDirectSoundBuffer_GetCurrentPosition(device->hidden->mixbuf, &junk, &cursor);
+            if ((result == DS_OK) && ((cursor / device->buffer_size) != device->hidden->lastchunk)) {
+                break;  // ready for next chunk!
             }
         }
-        if (!(status & DSBSTATUS_PLAYING)) {
-            result = IDirectSoundBuffer_Play(device->hidden->mixbuf, 0, 0,
-                                             DSBPLAY_LOOPING);
-            if (result == DS_OK) {
-                continue;
-            }
-#ifdef DEBUG_SOUND
-            SetDSerror("DirectSound Play", result);
-#endif
-            return;
-        }
 
-        // Find out where we are playing
-        result = IDirectSoundBuffer_GetCurrentPosition(device->hidden->mixbuf,
-                                                       &junk, &cursor);
-        if (result != DS_OK) {
-            SetDSerror("DirectSound GetCurrentPosition", result);
+        if ((result != DS_OK) && (result != DSERR_BUFFERLOST)) {
+            SDL_AudioDeviceDisconnected(device);
             return;
         }
+
+        SDL_Delay(1);  // not ready yet; sleep a bit.
     }
 }