diff --git a/source/audiolib/src/driver_directsound.cpp b/source/audiolib/src/driver_directsound.cpp
index e01aa906b..c82891353 100644
--- a/source/audiolib/src/driver_directsound.cpp
+++ b/source/audiolib/src/driver_directsound.cpp
@@ -263,8 +263,6 @@ int DirectSoundDrv_PCM_Init(int *mixrate, int *numchannels, void * initdata)
     if (FAILED(err = IDirectSoundBuffer_Play(lpdsbprimary, 0, 0, DSBPLAY_LOOPING)))
         return DirectSound_Error(err, DSErr_Play);
 
-    mutex_init(&mutex);
-
     Initialised = 1;
 
     return DSErr_Ok;
diff --git a/source/blood/src/blood.cpp b/source/blood/src/blood.cpp
index 05945b2e8..4b2b445f2 100644
--- a/source/blood/src/blood.cpp
+++ b/source/blood/src/blood.cpp
@@ -1228,11 +1228,6 @@ int GameInterface::app_main()
     {
         I_Error("app_main: There was a problem initializing the Build engine: %s\n", engineerrstr);
     }
-
-    initprintf("Initializing OSD...\n");
-
-    OSD_SetVersion("Blood", 10, 0);
-    OSD_SetParameters(0, 0, 0, 12, 2, 12, OSD_ERROR, OSDTEXT_RED, 0);
     registerosdcommands();
 
 #if 0
diff --git a/source/build/include/mutex.h b/source/build/include/mutex.h
index 040279f8e..fba6f994c 100644
--- a/source/build/include/mutex.h
+++ b/source/build/include/mutex.h
@@ -1,34 +1,20 @@
 #ifndef mutex_h_
 #define mutex_h_
 
-/* Mutual exclusion mechanism wrappers for the different platforms */
+#include <mutex>
 
-#ifdef RENDERTYPEWIN
-# include "windows_inc.h"
-#else
-# define SDL_MAIN_HANDLED
-# include "sdl_inc.h"
-#endif
+typedef std::mutex mutex_t;
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifdef RENDERTYPEWIN
-typedef HANDLE mutex_t;
-#else
-/* PK: I don't like pointer typedefs, but SDL_CreateMutex() _returns_ one,
- *     so we're out of luck with our interface. */
-typedef SDL_SpinLock mutex_t;
-#endif
-
-extern int32_t mutex_init(mutex_t *mutex);
-extern void mutex_lock(mutex_t *mutex);
-extern void mutex_unlock(mutex_t *mutex);
-
-
-#ifdef __cplusplus
+inline void mutex_lock(mutex_t* mutex)
+{
+	mutex->lock();
 }
-#endif
+
+inline void mutex_unlock(mutex_t* mutex)
+{
+	mutex->unlock();
+}
+
+
 
 #endif
diff --git a/source/build/src/engine.cpp b/source/build/src/engine.cpp
index d17fee1e6..3842f2e2b 100644
--- a/source/build/src/engine.cpp
+++ b/source/build/src/engine.cpp
@@ -10365,8 +10365,6 @@ int32_t videoSetGameMode(char davidoption, int32_t daupscaledxdim, int32_t daups
     fydim = (float) ydim;
 #endif
 
-    OSD_ResizeDisplay(xdim, ydim);
-
     videoAllocateBuffers();
 
 #ifdef HIGH_PRECISION_SPRITE
@@ -12523,9 +12521,6 @@ void videoSet2dMode(int32_t daxdim, int32_t daydim)
 
         rendmode = REND_CLASSIC;
 #endif
-
-        OSD_ResizeDisplay(xdim, ydim);
-
         videoAllocateBuffers();
 
         ydim16 = ydim - STATUS2DSIZ2;
diff --git a/source/build/src/mutex.cpp b/source/build/src/mutex.cpp
index d66f0db49..e69de29bb 100644
--- a/source/build/src/mutex.cpp
+++ b/source/build/src/mutex.cpp
@@ -1,37 +0,0 @@
-#include "compat.h"
-
-#ifdef _WIN32
-# define NEED_PROCESS_H
-# include "windows_inc.h"
-#endif
-
-#include "mutex.h"
-
-int32_t mutex_init(mutex_t *mutex)
-{
-#ifdef RENDERTYPEWIN
-    *mutex = CreateMutex(0, FALSE, 0);
-    return (*mutex == 0);
-#else
-    *mutex = 0;
-    return 0;
-#endif
-}
-
-void mutex_lock(mutex_t *mutex)
-{
-#ifdef RENDERTYPEWIN
-    WaitForSingleObject(*mutex, INFINITE);
-#else
-    SDL_AtomicLock(mutex);
-#endif
-}
-
-void mutex_unlock(mutex_t *mutex)
-{
-#ifdef RENDERTYPEWIN
-    ReleaseMutex(*mutex);
-#else
-    SDL_AtomicUnlock(mutex);
-#endif
-}
diff --git a/source/build/src/osd.cpp b/source/build/src/osd.cpp
index 253cb3fff..a521247ee 100644
--- a/source/build/src/osd.cpp
+++ b/source/build/src/osd.cpp
@@ -235,9 +235,7 @@ void OSD_Init(void)
 {
     osd = (osdmain_t *)Xcalloc(1, sizeof(osdmain_t));
 
-    mutex_init(&osd->mutex);
-
-    if (!osd->keycode)
+	if (!osd->keycode)
         osd->keycode = sc_Tilde;
 
     osd->text.buf   = (char *)Xmalloc(OSDBUFFERSIZE);
diff --git a/source/build/src/sdlayer.cpp b/source/build/src/sdlayer.cpp
index d70d7c509..ee3d60f08 100644
--- a/source/build/src/sdlayer.cpp
+++ b/source/build/src/sdlayer.cpp
@@ -484,7 +484,7 @@ int32_t videoSetVsync(int32_t newSync)
             if (result == -1)
             {
                 newSync = 0;
-                OSD_Printf("Unable to enable VSync!\n");
+                Printf("Unable to enable VSync!\n");
             }
         }
 
@@ -678,11 +678,6 @@ static void LoadSDLControllerDB()
 
     int i = SDL_GameControllerAddMappingsFromRW(rwops, 1);
 
-    if (i == -1)
-        buildprintf("Failed loading game controller database: %s\n", SDL_GetError());
-    else
-        buildputs("Loaded game controller database\n");
-
     free(dbuf);
 }
 #endif
@@ -705,11 +700,11 @@ void joyScanDevices()
     int numjoysticks = SDL_NumJoysticks();
     if (numjoysticks < 1)
     {
-        buildputs("No game controllers found\n");
+        initprintf("No game controllers found\n");
     }
     else
     {
-        buildputs("Game controllers:\n");
+        initprintf("Game controllers:\n");
         for (int i = 0; i < numjoysticks; i++)
         {
             const char * name;
@@ -780,7 +775,7 @@ void joyScanDevices()
             }
         }
 
-        buildputs("No controllers are usable\n");
+        initprintf("No controllers are usable\n");
     }
 }
 
@@ -957,7 +952,8 @@ void mouseLockToWindow(char a)
         g_mouseLockedToWindow = g_mouseGrabbed;
     }
 
-    SDL_ShowCursor((osd && osd->flags & OSD_CAPTURE) ? SDL_ENABLE : SDL_DISABLE);
+	// Fixme
+    SDL_ShowCursor(GUICapture ? SDL_ENABLE : SDL_DISABLE);
 }
 
 void mouseMoveToCenter(void)
@@ -1789,8 +1785,7 @@ int scancodetoasciihack(SDL_Event &ev)
 			default: keyvalue = sc - SDL_SCANCODE_A + 1; break;  // Ctrl+A --> 1, etc.
 		}
 	}
-	else if (
-			 ev.key.keysym.sym != g_keyAsciiTable[OSD_OSDKey()] && !SDL_IsTextInputActive()) // What is this? Preventing key repeat or what? :?
+	else
 	{
 		/*
 		Necessary for Duke 3D's method of entering cheats to work without showing IMEs.
@@ -1855,12 +1850,11 @@ int32_t handleevents_pollsdl(void)
                 do
                 {
                     code = ev.text.text[j];
-
-                    if (code != g_keyAsciiTable[OSD_OSDKey()] && !inputState.keyBufferFull())
-                    {
-                        if (OSD_HandleChar(code))
-                            inputState.keyBufferInsert(code);
-                    }
+					// Fixme: Send an EV_GUI_Event instead and properly deal with Unicode.
+#if 0
+					if (OSD_HandleChar(code))
+						inputState.keyBufferInsert(code);
+#endif
                 } while (j < SDL_TEXTINPUTEVENT_TEXT_SIZE-1 && ev.text.text[++j]);
                 break;
 
@@ -1879,6 +1873,7 @@ int32_t handleevents_pollsdl(void)
 				
 
 				int keyvalue = ev.type == SDL_KEYDOWN? scancodetoasciihack(ev) : 0;
+#if 0
 				if (keyvalue > 0)
 				{
 					keyvalue = OSD_HandleChar(keyvalue); // returns the char if it doesn't process it.
@@ -1889,9 +1884,10 @@ int32_t handleevents_pollsdl(void)
 				// j == -1: Console was opened
 				// j == 0: Console is active and used the key
 				// j == 2: Console is inactive and did not use the key
-				
 				if (j == -1) inputState.ClearKeysDown(); // Flush the entire keyboard state for the game when the console opens.
 				if (j <= 0) break;	// Do not pass on to the game
+#endif
+				
 
 				event_t evt = { (uint8_t)(ev.type == SDL_KEYUP? EV_KeyUp : EV_KeyDown), 0, (int16_t)code, (int16_t)keyvalue };
 				D_PostEvent(&evt);
diff --git a/source/common/gameconfigfile.cpp b/source/common/gameconfigfile.cpp
index 303a48bbc..5aad19550 100644
--- a/source/common/gameconfigfile.cpp
+++ b/source/common/gameconfigfile.cpp
@@ -48,14 +48,10 @@
 //#include "d_main.h"
 #include "keyboard.h"
 #include "control.h"
-#include "osd.h"
+#include "printf.h"
 #include "gamecontrol.h"
 #include "version.h"
 
-#ifdef Printf
-#undef Printf
-#endif
-
 #define LASTRUNVERSION "1"
 
 #if !defined _MSC_VER && !defined __APPLE__
@@ -529,7 +525,7 @@ void FGameConfigFile::AddAutoexec (FArgs *list, const char *game)
 CCMD (whereisini)
 {
 	FString path = M_GetConfigPath(false);
-	OSD_Printf ("%s\n", path.GetChars());
+	Printf ("%s\n", path.GetChars());
 }
 
 FGameConfigFile* GameConfig;
diff --git a/source/common/gamecvars.cpp b/source/common/gamecvars.cpp
index b46a3ad60..af3c2b474 100644
--- a/source/common/gamecvars.cpp
+++ b/source/common/gamecvars.cpp
@@ -346,7 +346,7 @@ CUSTOM_CVARD(Float, r_ambientlight, 1.0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG, "sets t
 	else r_ambientlightrecip = 1.f / self;
 }
 
-CVARD(Bool, r_shadows, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG, "enable/disable sprite and model shadows")//, (void *)&ud.shadows, CVAR_BOOL, 0, 1 },
+CVARD(Bool, r_shadows, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG, "enable/disable sprite and model shadows")
 
 // Gross hack stuff. Only settable from the command line
 CVARD(Bool, r_rotatespritenowidescreen, false, CVAR_NOSET, "pass bit 1024 to all CON rotatesprite calls")
diff --git a/source/common/inputstate.h b/source/common/inputstate.h
index 99ae440a1..683f4bc8c 100644
--- a/source/common/inputstate.h
+++ b/source/common/inputstate.h
@@ -11,16 +11,7 @@
 extern char appactive;
 
 typedef uint8_t kb_scancode;
-
-
-typedef struct
-{
-	const char* key;
-	char* cmdstr;
-	char repeat;
-	char laststate;
-}
-consolekeybind_t;
+extern bool GUICapture;
 
 // This encapsulates the entire game-readable input state which previously was spread out across several files.
 
@@ -272,7 +263,7 @@ public:
 
 	int32_t mouseReadButtons(void)
 	{
-		return (!g_mouseEnabled || !appactive || !g_mouseInsideWindow || (osd && osd->flags & OSD_CAPTURE)) ? 0 : g_mouseBits;
+		return (!g_mouseEnabled || !appactive || !g_mouseInsideWindow || GUICapture) ? 0 : g_mouseBits;
 	}
 	
 	int mouseClickState()
diff --git a/source/duke3d/src/cmdline.cpp b/source/duke3d/src/cmdline.cpp
index 0c3cbcc54..693af0657 100644
--- a/source/duke3d/src/cmdline.cpp
+++ b/source/duke3d/src/cmdline.cpp
@@ -28,6 +28,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 #include "renderlayer.h"
 #include "cmdline.h"
 #include "m_argv.h"
+#include "printf.h"
 
 BEGIN_DUKE_NS
 
@@ -71,7 +72,7 @@ void G_CheckCommandLine()
 	if (Args->CheckParm("-altai"))
 	{
 		ud.playerai = 1;
-		OSD_Printf("Other player AI.\n");
+		Printf("Other player AI.\n");
 	}
 	auto val = Args->CheckValue("-skill");
 	if (val)
@@ -91,7 +92,7 @@ void G_CheckCommandLine()
 			ud.m_respawn_items = 1;
 			ud.m_respawn_inventory = 1;
 		}
-		OSD_Printf("Respawn on.\n");
+		Printf("Respawn on.\n");
 	}
 	if (Args->CheckParm("-showcoords") || Args->CheckParm("-w"))
 	{
diff --git a/source/duke3d/src/game.cpp b/source/duke3d/src/game.cpp
index fcd954a02..52c8bc335 100644
--- a/source/duke3d/src/game.cpp
+++ b/source/duke3d/src/game.cpp
@@ -104,8 +104,6 @@ int32_t g_levelTextTime = 0;
 extern char forcegl;
 #endif
 
-void M32RunScript(const char *s) { UNREFERENCED_PARAMETER(s); };  // needed for linking since it's referenced from build/src/osd.c
-
 const char *G_DefaultRtsFile(void)
 {
 #ifndef EDUKE32_STANDALONE
@@ -6262,10 +6260,6 @@ int GameInterface::app_main()
 
 	VM_OnEvent(EVENT_SETDEFAULTS, g_player[myconnectindex].ps->i, myconnectindex);
 
-    initprintf("Initializing OSD...\n");
-
-    OSD_SetVersion(tempbuf, 10,0);
-    OSD_SetParameters(0, 0, 0, 12, 2, 12, OSD_ERROR, OSDTEXT_RED, 0);
     registerosdcommands();
 
 #ifdef HAVE_CLIPSHAPE_FEATURE
diff --git a/source/duke3d/src/game.h b/source/duke3d/src/game.h
index 90cea299e..771f9e09a 100644
--- a/source/duke3d/src/game.h
+++ b/source/duke3d/src/game.h
@@ -317,7 +317,6 @@ void G_PrintGameQuotes(int32_t snum);
 void G_SetCrosshairColor(int32_t r,int32_t g,int32_t b);
 void G_Shutdown(void);
 void G_UpdatePlayerFromMenu(void);
-void M32RunScript(const char *s);
 void P_DoQuote(int32_t q,DukePlayer_t *p);
 void P_SetGamePalette(DukePlayer_t *player, uint32_t palid, int32_t set);
 
diff --git a/source/duke3d/src/sounds.cpp b/source/duke3d/src/sounds.cpp
index 0f72cfc3f..c69034008 100644
--- a/source/duke3d/src/sounds.cpp
+++ b/source/duke3d/src/sounds.cpp
@@ -98,7 +98,6 @@ void S_SoundStartup(void)
 	snd_reversestereo.Callback();
     FX_SetCallBack(S_Callback);
     FX_SetPrintf(OSD_Printf);
-    mutex_init(&m_callback);
 }
 
 void S_SoundShutdown(void)
diff --git a/source/rr/src/game.cpp b/source/rr/src/game.cpp
index 36a8a1e31..6d3ae8de7 100644
--- a/source/rr/src/game.cpp
+++ b/source/rr/src/game.cpp
@@ -101,8 +101,6 @@ int32_t g_levelTextTime = 0;
 extern char forcegl;
 #endif
 
-void M32RunScript(const char *s) { UNREFERENCED_PARAMETER(s); };  // needed for linking since it's referenced from build/src/osd.c
-
 const char *G_DefaultRtsFile(void)
 {
     if (DUKE)
@@ -7677,11 +7675,6 @@ int GameInterface::app_main()
     g_mostConcurrentPlayers = ud.multimode;  // XXX: redundant?
 
     ud.last_level = -1;
-
-    initprintf("Initializing OSD...\n");
-
-    OSD_SetVersion(tempbuf, 10,0);
-    OSD_SetParameters(0, 0, 0, 12, 2, 12, OSD_ERROR, OSDTEXT_RED, 0);
     registerosdcommands();
 
 #ifdef HAVE_CLIPSHAPE_FEATURE