From 76dc64d3a57846acb82862d8788b90535b30e238 Mon Sep 17 00:00:00 2001
From: Tim Felgentreff <timfelgentreff@gmail.com>
Date: Sun, 29 May 2022 18:52:14 +0100
Subject: [PATCH] fixup failing music callback - don't let music play failure
 spam the event queue

---
 src/sound/music.cpp        | 9 ++++++++-
 src/sound/sound_server.cpp | 9 ++++++++-
 2 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/src/sound/music.cpp b/src/sound/music.cpp
index b2b3d93bc..735af36d4 100644
--- a/src/sound/music.cpp
+++ b/src/sound/music.cpp
@@ -63,11 +63,18 @@ bool CallbackMusic;                       /// flag true callback ccl if stops
 */
 static void MusicFinishedCallback()
 {
+	static long MusicCallbackDebounce = 0;
+	long ticks = SDL_GetTicks();
+	if (MusicCallbackDebounce + 1000 < ticks) {
+		// only accept music finished callbacks for music playing longer than 1s
+		return;
+	}
+	MusicCallbackDebounce = ticks;
 	SDL_Event event;
 	SDL_zero(event);
 	event.type = SDL_SOUND_FINISHED;
 	event.user.code = 1;
-	event.user.data1 = CheckMusicFinished;
+	event.user.data1 = (void*) CheckMusicFinished;
 	SDL_PeepEvents(&event, 1, SDL_ADDEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT);
 }
 
diff --git a/src/sound/sound_server.cpp b/src/sound/sound_server.cpp
index 31290bd7d..1fe221cf0 100644
--- a/src/sound/sound_server.cpp
+++ b/src/sound/sound_server.cpp
@@ -269,16 +269,23 @@ bool UnitSoundIsPlaying(Origin *origin)
 */
 static void ChannelFinished(int channel)
 {
+	static long ChannelCallbackDebounce[MaxChannels] = {0};
 	if (channel < 0 || channel >= MaxChannels) {
 		fprintf(stderr, "ERROR: Out of bounds channel (how?)\n");
 		return;
 	}
+	long ticks = SDL_GetTicks();
+	if (ChannelCallbackDebounce[channel] + 200 < ticks) {
+		// only accept sound finished callbacks for sounds playing longer than 0.2s
+		return;
+	}
+	ChannelCallbackDebounce[channel] = ticks;
 	if (Channels[channel].FinishedCallback != NULL) {
 		SDL_Event event;
 		SDL_zero(event);
 		event.type = SDL_SOUND_FINISHED;
 		event.user.code = channel;
-		event.user.data1 = Channels[channel].FinishedCallback;
+		event.user.data1 = (void*) Channels[channel].FinishedCallback;
 		SDL_PeepEvents(&event, 1, SDL_ADDEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT);
 	}
 	delete Channels[channel].Unit;