diff --git a/src/conio/SDL_win32_main.c b/src/conio/SDL_win32_main.c
index d261bd0f4feb6bf4a30293f2151feed403424c3d..fdbc7c498567757aad60986ecfa9ca547ce522a5 100644
--- a/src/conio/SDL_win32_main.c
+++ b/src/conio/SDL_win32_main.c
@@ -241,13 +241,13 @@ int console_main(int argc, char *argv[], char **env)
 	}
 
 	/* Run the application main() code */
-	SDL_main_env(argc, argv, env);
+	n=SDL_main_env(argc, argv, env);
 
 	/* Exit cleanly, calling atexit() functions */
-	exit(0);
+	exit(n);
 
 	/* Hush little compiler, don't you cry... */
-	return(0);
+	return(n);
 }
 
 /* This is where execution begins [windowed apps] */
diff --git a/src/conio/ciolib.c b/src/conio/ciolib.c
index 9b68a8987ddb874feec177c94ab9daf73994517f..1ee07ef4c4d8305fa05be40721e57608d2386c70 100644
--- a/src/conio/ciolib.c
+++ b/src/conio/ciolib.c
@@ -114,7 +114,7 @@ CIOLIBEXPORT char * CIOLIBCALL ciolib_getcliptext(void);
 #ifdef WITH_SDL
 int try_sdl_init(int mode)
 {
-	if(!sdl_init(mode)) {
+	if(!sdl_initciolib(mode)) {
 		cio_api.mouse=1;
 		cio_api.puttext=sdl_puttext;
 		cio_api.gettext=sdl_gettext;
diff --git a/src/conio/sdl_con.c b/src/conio/sdl_con.c
index 868ac1d8cae5ac6b6a38949d65ee1b2101f08e00..2a60439764170bd048ed58136168f2434d4974c4 100644
--- a/src/conio/sdl_con.c
+++ b/src/conio/sdl_con.c
@@ -35,10 +35,6 @@
 
 #include "sdlfuncs.h"
 
-#ifndef _WIN32
-struct sdlfuncs sdl;
-#endif
-
 extern int	CIOLIB_main(int argc, char **argv, char **enviro);
 
 /********************************************************/
@@ -495,12 +491,6 @@ int sdl_draw_char(unsigned short vch, int xpos, int ypos, int update)
 	return(0);
 }
 
-/* atexit() function */
-void sdl_exit(void)
-{
-	sdl.Quit();
-}
-
 /* Called from main thread only (Passes Event) */
 int sdl_init(int mode)
 {
@@ -1342,18 +1332,6 @@ struct mainparams {
 	char	**env;
 };
 
-/* Called from events thread only */
-int sdl_runmain(void *data)
-{
-	struct mainparams *mp=data;
-	SDL_Event	ev;
-
-	sdl_exitcode=CIOLIB_main(mp->argc, mp->argv, mp->env);
-	ev.type=SDL_QUIT;
-	while(sdl.PeepEvents(&ev, 1, SDL_ADDEVENT, 0xffffffff)!=1);
-	return(0);
-}
-
 /* Mouse event/keyboard thread */
 int sdl_mouse_thread(void *data)
 {
@@ -1364,77 +1342,11 @@ int sdl_mouse_thread(void *data)
 }
 
 /* Event Thread */
-#ifndef main
-int main(int argc, char **argv, char **env)
-#else
-int SDL_main_env(int argc, char **argv, char **env)
-#endif
+int sdl_video_event_thread(void *data)
 {
-	unsigned int i;
 	SDL_Event	ev;
-	struct mainparams mp;
-	char	drivername[64];
-
-#ifndef _WIN32
-	load_sdl_funcs(&sdl);
-#endif
-
-	if(sdl.gotfuncs) {
-#ifdef _WIN32
-		/* Fail to windib (ie: No mouse attached) */
-		if(sdl.Init(SDL_INIT_VIDEO)) {
-			if(getenv("SDL_VIDEODRIVER")==NULL) {
-				putenv("SDL_VIDEODRIVER=windib");
-				WinExec(GetCommandLine(), SW_SHOWDEFAULT);
-				exit(0);
-			}
-			sdl.gotfuncs=FALSE;
-		}
-#else
-
-		/*
-		 * On Linux, SDL doesn't properly detect availability of the
-		 * framebuffer apparently.  This results in remote connections
-		 * displaying on the local framebuffer... a definate no-no.
-		 * This ugly hack attempts to prevent this... of course, remote X11
-		 * connections must still be allowed.
-		 */
-		if(getenv("REMOTEHOST")!=NULL && getenv("DISPLAY")==NULL)
-			sdl.gotfuncs=FALSE;
-		else {
-			if(sdl.Init(SDL_INIT_VIDEO))
-				sdl.gotfuncs=FALSE;
-		}
-#endif
-		if(sdl.VideoDriverName(drivername, sizeof(drivername))!=NULL) {
-			/* Unacceptable drivers */
-			if((!strcmp(drivername, "caca")) || (!strcmp(drivername,"aalib")) || (!strcmp(drivername,"dummy"))) {
-				sdl.gotfuncs=FALSE;
-				sdl.Quit();
-			}
-		}
-	}
 
 	if(sdl.gotfuncs) {
-		atexit(sdl_exit);
-		mp.argc=argc;
-		mp.argv=argv;
-		mp.env=env;
-
-		sdl_key_pending=sdl.SDL_CreateSemaphore(0);
-		sdl_init_complete=sdl.SDL_CreateSemaphore(0);
-		sdl_ufunc_ret=sdl.SDL_CreateSemaphore(0);
-		sdl_updlock=sdl.SDL_CreateMutex();
-		sdl_keylock=sdl.SDL_CreateMutex();
-		sdl_vstatlock=sdl.SDL_CreateMutex();
-		sdl_ufunc_lock=sdl.SDL_CreateMutex();
-#if !defined(NO_X) && defined(__unix__)
-		sdl_pastebuf_set=sdl.SDL_CreateSemaphore(0);
-		sdl_pastebuf_copied=sdl.SDL_CreateSemaphore(0);
-		sdl_copybuf_mutex=sdl.SDL_CreateMutex();
-#endif
-		sdl.CreateThread(sdl_runmain, &mp);
-
 		while(1) {
 			if(sdl.WaitEvent(&ev)==1) {
 				switch (ev.type) {
@@ -1849,7 +1761,27 @@ int SDL_main_env(int argc, char **argv, char **env)
 			}
 		}
 	}
-	else {
-		return(CIOLIB_main(argc, argv, env));
-	}
 }
+
+int sdl_initciolib(int mode)
+{
+	if(!sdl.gotfuncs)
+		return(-1);
+	if(init_sdl_video()==-1)
+		return(-1);
+	sdl_key_pending=sdl.SDL_CreateSemaphore(0);
+	sdl_init_complete=sdl.SDL_CreateSemaphore(0);
+	sdl_ufunc_ret=sdl.SDL_CreateSemaphore(0);
+	sdl_updlock=sdl.SDL_CreateMutex();
+	sdl_keylock=sdl.SDL_CreateMutex();
+	sdl_vstatlock=sdl.SDL_CreateMutex();
+	sdl_ufunc_lock=sdl.SDL_CreateMutex();
+#if !defined(NO_X) && defined(__unix__)
+	sdl_pastebuf_set=sdl.SDL_CreateSemaphore(0);
+	sdl_pastebuf_copied=sdl.SDL_CreateSemaphore(0);
+	sdl_copybuf_mutex=sdl.SDL_CreateMutex();
+#endif
+	sdl.CreateThread(sdl_video_event_thread, NULL);
+	return(sdl_init(mode));
+}
+
diff --git a/src/conio/sdl_con.h b/src/conio/sdl_con.h
index 6ed46311e01a1c92e43dc44f9e5b872f16b0f841..8ff08c548f528cd5c60a74c91799d02cf11d0c8e 100644
--- a/src/conio/sdl_con.h
+++ b/src/conio/sdl_con.h
@@ -22,7 +22,7 @@ int sdl_wherey(void);
 int sdl_wherex(void);
 int sdl_putch(int ch);
 void sdl_gotoxy(int x, int y);
-void sdl_initciolib(long inmode);
+int sdl_initciolib(long inmode);
 void sdl_gettextinfo(struct text_info *info);
 void sdl_setcursortype(int type);
 int sdl_getch(void);
@@ -38,6 +38,7 @@ char *sdl_getcliptext(void);
 int sdl_setfont(int font, int force);
 int sdl_getfont(void);
 int sdl_loadfont(char *filename);
+int sdl_video_event_thread(void *data);
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/conio/sdlfuncs.c b/src/conio/sdlfuncs.c
index 8044bf5b3cfff0672a4cc9c91cb2990b7f4da570..2e1fdb8352b0a76ca656b4623314c668709394a3 100644
--- a/src/conio/sdlfuncs.c
+++ b/src/conio/sdlfuncs.c
@@ -1,7 +1,17 @@
 #include <stdio.h>	/* NULL */
 
+#include "gen_defs.h"
 #include "sdlfuncs.h"
 
+#ifndef _WIN32
+struct sdlfuncs sdl;
+#endif
+
+static int sdl_funcs_loaded=0;
+static int sdl_initialized=0;
+static int sdl_audio_initialized=0;
+static int sdl_video_initialized=0;
+
 #ifdef STATIC_SDL
 int load_sdl_funcs(struct sdlfuncs *sdlf)
 {
@@ -36,7 +46,10 @@ int load_sdl_funcs(struct sdlfuncs *sdlf)
 	sdlf->EnableKeyRepeat=SDL_EnableKeyRepeat;
 	sdlf->GetWMInfo=SDL_GetWMInfo;
 	sdlf->GetError=SDL_GetError;
+	sdlf->InitSubSystem=SDL_InitSubSystem;
+	sdlf->QuitSubSystem=SDL_QuitSubSystem;
 	sdlf->gotfuncs=1;
+	sdl_funcs_loaded=1;
 	return(0);
 }
 #else
@@ -166,7 +179,16 @@ int load_sdl_funcs(struct sdlfuncs *sdlf)
 		FreeLibrary(sdl_dll);
 		return(-1);
 	}
+	if((sdlf->InitSubSystem=GetProcAddress(sdl_dll, "SDL_InitSubSystem"))==NULL) {
+		FreeLibrary(sdl_dll);
+		return(-1);
+	}
+	if((sdlf->QuitSubSystem=GetProcAddress(sdl_dll, "SDL_QuitSubSystem"))==NULL) {
+		FreeLibrary(sdl_dll);
+		return(-1);
+	}
 	sdlf->gotfuncs=1;
+	sdl_funcs_loaded=1;
 	return(0);
 }
 #elif defined(__unix__)
@@ -291,8 +313,106 @@ int load_sdl_funcs(struct sdlfuncs *sdlf)
 		return(-1);
 	}
 	sdlf->gotfuncs=1;
+	sdl_funcs_loaded=1;
 	return(0);
 }
 #endif
 
 #endif
+
+int init_sdl_video(void)
+{
+	/* This is all handled in SDL_main_env() */
+	if(sdl_video_initialized)
+		return(0);
+	else
+		return(-1);
+}
+
+int init_sdl_audio(void)
+{
+	if(!sdl_initialized)
+		return(-1);
+	if(sdl_audio_initialized)
+		return(0);
+	if(sdl.InitSubSystem(SDL_INIT_AUDIO)==0) {
+		sdl_audio_initialized=TRUE;
+		return(0);
+	}
+	return(-1);
+}
+
+/* atexit() function */
+static void sdl_exit(void)
+{
+	sdl.Quit();
+}
+
+#ifndef main
+int main(int argc, char **argv, char **env)
+#else
+int SDL_main_env(int argc, char **argv, char **env)
+#endif
+{
+	unsigned int i;
+	SDL_Event	ev;
+	char	drivername[64];
+
+#ifndef _WIN32
+	load_sdl_funcs(&sdl);
+#endif
+
+	if(sdl.gotfuncs) {
+#ifdef _WIN32
+		/* Fail to windib (ie: No mouse attached) */
+		if(sdl.Init(SDL_INIT_VIDEO)) {
+			if(getenv("SDL_VIDEODRIVER")==NULL) {
+				putenv("SDL_VIDEODRIVER=windib");
+				WinExec(GetCommandLine(), SW_SHOWDEFAULT);
+				exit(0);
+			}
+			sdl.gotfuncs=FALSE;
+		}
+		else {
+			sdl_video_initialized=TRUE;
+		}
+#else
+
+		/*
+		 * On Linux, SDL doesn't properly detect availability of the
+		 * framebuffer apparently.  This results in remote connections
+		 * displaying on the local framebuffer... a definate no-no.
+		 * This ugly hack attempts to prevent this... of course, remote X11
+		 * connections must still be allowed.
+		 */
+		if(getenv("REMOTEHOST")!=NULL && getenv("DISPLAY")==NULL) {
+			/* Sure ,we can't use video, but audio is still valid! */
+			if(sdl.Init(0)==0)
+				sdl_initialized=TRUE;
+			sdl.gotfuncs=FALSE;
+		}
+		else {
+			if(sdl.Init(SDL_INIT_VIDEO))
+				sdl.gotfuncs=FALSE;
+			else {
+				sdl_initialized=TRUE;
+				sdl_video_initialized=TRUE;
+			}
+		}
+#endif
+		if(sdl_video_initialized && sdl.VideoDriverName(drivername, sizeof(drivername))!=NULL) {
+			/* Unacceptable drivers */
+			if((!strcmp(drivername, "caca")) || (!strcmp(drivername,"aalib")) || (!strcmp(drivername,"dummy"))) {
+				sdl.gotfuncs=FALSE;
+				sdl.QuitSubSystem(SDL_INIT_VIDEO);
+				sdl_video_initialized=FALSE;
+			}
+			else {
+				sdl_video_initialized=TRUE;
+			}
+		}
+	}
+	if(sdl_initialized)
+		atexit(sdl_exit);
+	return(CIOLIB_main(argc, argv, env));
+}
diff --git a/src/conio/sdlfuncs.h b/src/conio/sdlfuncs.h
index 0232e6a39459e4b891b071aa1386e4a08f27221c..fb1a6a3b23552d4f4120e8757b992f5c97cf007a 100644
--- a/src/conio/sdlfuncs.h
+++ b/src/conio/sdlfuncs.h
@@ -37,18 +37,20 @@ struct sdlfuncs {
 	int	(*EnableKeyRepeat)	(int delay, int interval);
 	int	(*GetWMInfo)	(struct SDL_SysWMinfo *info);
 	char	*(*GetError)	(void);
+	int (*InitSubSystem)(Uint32 flags);
+	void (*QuitSubSystem)(Uint32 flags);
 	int	gotfuncs;
 };
 
-#ifdef _WIN32
-/* Defined in SDL_win32_main.c */
+/* Defined in SDL_win32_main.c for Win32 */
 extern struct sdlfuncs	sdl;
-#endif
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 int load_sdl_funcs(struct sdlfuncs *sdlf);
+int init_sdl_audio(void);
+int init_sdl_video(void);
 #ifdef __cplusplus
 }
 #endif