Use std::thread in place of the Windows API CreateThread.
Use std::thread in place of the Windows API CreateThread.

--- a/src/in_ncsf/XSFPlayer_NCSF.cpp
+++ b/src/in_ncsf/XSFPlayer_NCSF.cpp
@@ -9,10 +9,12 @@
  */
 
 #include <algorithm>
+#include <atomic>
 #include <bitset>
 #include <filesystem>
 #include <memory>
 #include <string>
+#include <thread>
 #include <vector>
 #include <cstddef>
 #include <cstdint>
@@ -102,13 +104,13 @@
 	this->xSF.reset(new XSFFile(path, 8, 12));
 }
 
-static HANDLE soundViewThreadHandle = INVALID_HANDLE_VALUE;
-static bool killSoundViewThread;
-
-static DWORD WINAPI soundViewThread(void *b)
+static std::unique_ptr<std::thread> soundViewThreadHandle;
+static std::atomic_bool killSoundViewThread;
+
+static void soundViewThread(XSFPlayer_NCSF *player)
 {
 	auto xSFConfig_NCSF = static_cast<XSFConfig_NCSF *>(xSFConfig.get());
-	xSFConfig_NCSF->CallSoundView(static_cast<XSFPlayer_NCSF *>(b), xSFConfig->GetHInstance(), nullptr);
+	xSFConfig_NCSF->CallSoundView(player, xSFConfig->GetHInstance(), nullptr);
 	MSG msg;
 	while (!killSoundViewThread)
 	{
@@ -120,7 +122,6 @@
 		}
 	}
 	xSFConfig_NCSF->CloseSoundView();
-	return 0;
 }
 
 XSFPlayer_NCSF::~XSFPlayer_NCSF()
@@ -136,7 +137,7 @@
 	if (this->useSoundViewDialog)
 	{
 		killSoundViewThread = false;
-		soundViewThreadHandle = CreateThread(nullptr, 0, soundViewThread, this, 0, nullptr);
+		soundViewThreadHandle.reset(new std::thread(soundViewThread, this));
 	}
 
 	PseudoFile file;
@@ -214,17 +215,9 @@
 {
 	this->player.Stop(true);
 
-	if (soundViewThreadHandle != INVALID_HANDLE_VALUE)
-	{
-		killSoundViewThread = true;
-		if (WaitForSingleObject(soundViewThreadHandle, 2000) == WAIT_TIMEOUT)
-		{
-			TerminateThread(soundViewThreadHandle, 0);
-			static_cast<XSFConfig_NCSF *>(xSFConfig.get())->CloseSoundView();
-		}
-		CloseHandle(soundViewThreadHandle);
-		soundViewThreadHandle = INVALID_HANDLE_VALUE;
-	}
+	killSoundViewThread = true;
+	soundViewThreadHandle->join();
+	soundViewThreadHandle.reset();
 }
 
 void XSFPlayer_NCSF::SetUseSoundViewDialog(bool newUseSoundViewDialog)

--- a/src/in_xsf_framework/in_xsf.cpp
+++ b/src/in_xsf_framework/in_xsf.cpp
@@ -6,9 +6,11 @@
  */
 
 #include <algorithm>
+#include <atomic>
 #include <memory>
 #include <stdexcept>
 #include <string>
+#include <thread>
 #include <utility>
 #include <vector>
 #include <cstddef>
@@ -28,18 +30,18 @@
 static std::unique_ptr<XSFPlayer> xSFPlayer;
 std::unique_ptr<XSFConfig> xSFConfig;
 static bool paused;
-static int seek_needed;
+static std::atomic_int seek_needed;
 static double decode_pos_ms;
-static HANDLE thread_handle = INVALID_HANDLE_VALUE;
-static bool killThread = false;
+static std::unique_ptr<std::thread> thread_handle;
+static std::atomic_bool killThread;
 
 static const unsigned NumChannels = 2;
 static const unsigned BitsPerSample = 16;
 
-DWORD WINAPI playThread(void *b)
+void playThread()
 {
 	bool done = false;
-	while (!*static_cast<bool *>(b))
+	while (!killThread)
 	{
 		if (seek_needed != -1)
 		{
@@ -55,7 +57,7 @@
 			if (!inMod.outMod->IsPlaying())
 			{
 				PostMessage(inMod.hMainWindow, WM_WA_MPEG_EOF, 0, 0);
-				return 0;
+				return;
 			}
 			Sleep(10);
 		}
@@ -77,7 +79,6 @@
 		else
 			Sleep(20);
 	}
-	return 0;
 }
 
 void config(HWND hwndParent)
@@ -198,7 +199,7 @@
 
 		xSFPlayer = std::move(tmpxSFPlayer);
 		killThread = false;
-		thread_handle = CreateThread(nullptr, 0, playThread, &killThread, 0, nullptr);
+		thread_handle.reset(new std::thread(playThread));
 		return 0;
 	}
 	catch (const std::exception &)
@@ -226,17 +227,9 @@
 
 void stop()
 {
-	if (thread_handle != INVALID_HANDLE_VALUE)
-	{
-		killThread = true;
-		if (WaitForSingleObject(thread_handle, 2000) == WAIT_TIMEOUT)
-		{
-			MessageBoxW(inMod.hMainWindow, L"error asking thread to die!", L"error killing decode thread", 0);
-			TerminateThread(thread_handle, 0);
-		}
-		CloseHandle(thread_handle);
-		thread_handle = INVALID_HANDLE_VALUE;
-	}
+	killThread = true;
+	thread_handle->join();
+	thread_handle.reset();
 	inMod.outMod->Close();
 	inMod.SAVSADeInit();
 	xSFPlayer.reset();