diff --git a/src/sdl/i_input.cpp b/src/sdl/i_input.cpp
index 60467366e2..4f933826ef 100644
--- a/src/sdl/i_input.cpp
+++ b/src/sdl/i_input.cpp
@@ -21,7 +21,7 @@
 static void I_CheckGUICapture ();
 static void I_CheckNativeMouse ();
 
-static bool GUICapture;
+bool GUICapture;
 static bool NativeMouse = true;
 
 extern int paused;
@@ -36,6 +36,9 @@ EXTERN_CVAR (Bool, fullscreen)
 extern int WaitingForKey, chatmodeon;
 extern constate_e ConsoleState;
 
+extern SDL_Surface *cursorSurface;
+extern SDL_Rect cursorBlit;
+
 static BYTE KeySymToDIK[SDLK_LAST], DownState[SDLK_LAST];
 
 static WORD DIKToKeySym[256] =
@@ -114,6 +117,11 @@ static void I_CheckGUICapture ()
 		GUICapture = wantCapt;
 		if (wantCapt)
 		{
+			int x, y;
+			SDL_GetMouseState (&x, &y);
+			cursorBlit.x = x;
+			cursorBlit.y = y;
+
 			FlushDIKState ();
 			memset (DownState, 0, sizeof(DownState));
 			repeat = !sdl_nokeyrepeat;
@@ -260,15 +268,14 @@ static void I_CheckNativeMouse ()
 	if (wantNative != NativeMouse)
 	{
 		NativeMouse = wantNative;
+		SDL_ShowCursor (wantNative ? cursorSurface == NULL : 0);
 		if (wantNative)
 		{
-			SDL_ShowCursor (1);
 			SDL_WM_GrabInput (SDL_GRAB_OFF);
 			FlushDIKState (KEY_MOUSE1, KEY_MOUSE8);
 		}
 		else
 		{
-			SDL_ShowCursor (0);
 			SDL_WM_GrabInput (SDL_GRAB_ON);
 			CenterMouse ();
 		}
@@ -347,8 +354,8 @@ void MessagePump (const SDL_Event &sev)
 			int x, y;
 			SDL_GetMouseState (&x, &y);
 
-			event.data1 = x;
-			event.data2 = y;
+			cursorBlit.x = event.data1 = x;
+			cursorBlit.y = event.data2 = y;
 			event.type = EV_GUI_Event;
 			if(sev.type == SDL_MOUSEMOTION)
 				event.subtype = EV_GUI_MouseMove;
diff --git a/src/sdl/i_system.cpp b/src/sdl/i_system.cpp
index af717324e1..49628eef47 100644
--- a/src/sdl/i_system.cpp
+++ b/src/sdl/i_system.cpp
@@ -60,6 +60,9 @@
 #include "i_system.h"
 #include "c_dispatch.h"
 #include "templates.h"
+#include "v_palette.h"
+#include "textures.h"
+#include "bitmap.h"
 
 #include "stats.h"
 #include "hardware.h"
@@ -830,7 +833,39 @@ unsigned int I_MakeRNGSeed()
 	return seed;
 }
 
+SDL_Surface *cursorSurface = NULL;
+SDL_Rect cursorBlit = {0, 0, 32, 32};
 bool I_SetCursor(FTexture *cursorpic)
 {
-	return false;
+	if (cursorpic != NULL && cursorpic->UseType != FTexture::TEX_Null)
+	{
+		// Must be no larger than 32x32.
+		if (cursorpic->GetWidth() > 32 || cursorpic->GetHeight() > 32)
+		{
+			return false;
+		}
+
+		if (cursorSurface == NULL)
+			cursorSurface = SDL_CreateRGBSurface (0, 32, 32, 32, MAKEARGB(0,255,0,0), MAKEARGB(0,0,255,0), MAKEARGB(0,0,0,255), MAKEARGB(255,0,0,0));
+
+		SDL_ShowCursor(0);
+		SDL_LockSurface(cursorSurface);
+		BYTE buffer[32*32*4];
+		memset(buffer, 0, 32*32*4);
+		FBitmap bmp(buffer, 32*4, 32, 32);
+		cursorpic->CopyTrueColorPixels(&bmp, 0, 0);
+		memcpy(cursorSurface->pixels, bmp.GetPixels(), 32*32*4);
+		SDL_UnlockSurface(cursorSurface);
+	}
+	else
+	{
+		SDL_ShowCursor(1);
+
+		if (cursorSurface != NULL)
+		{
+			SDL_FreeSurface(cursorSurface);
+			cursorSurface = NULL;
+		}
+	}
+	return true;
 }
diff --git a/src/sdl/sdlvideo.cpp b/src/sdl/sdlvideo.cpp
index b028aafad7..efff947057 100644
--- a/src/sdl/sdlvideo.cpp
+++ b/src/sdl/sdlvideo.cpp
@@ -76,6 +76,9 @@ void DoBlending (const PalEntry *from, PalEntry *to, int count, int r, int g, in
 // EXTERNAL DATA DECLARATIONS ----------------------------------------------
 
 extern IVideo *Video;
+extern SDL_Surface *cursorSurface;
+extern SDL_Rect cursorBlit;
+extern bool GUICapture;
 
 EXTERN_CVAR (Float, Gamma)
 
@@ -404,7 +407,13 @@ void SDLFB::Update ()
 	}
 	
 	SDL_UnlockSurface (Screen);
-	
+
+	if (cursorSurface != NULL && GUICapture)
+	{
+		// SDL requires us to draw a surface to get true color cursors.
+		SDL_BlitSurface(cursorSurface, NULL, Screen, &cursorBlit);
+	}
+
 	SDLFlipCycles.Clock();
 	SDL_Flip (Screen);
 	SDLFlipCycles.Unclock();
diff --git a/wadsrc/static/menudef.txt b/wadsrc/static/menudef.txt
index cb6844d932..825ae51a84 100644
--- a/wadsrc/static/menudef.txt
+++ b/wadsrc/static/menudef.txt
@@ -528,10 +528,7 @@ OptionMenu "MouseOptions"
 	Option "Enable mouse",				"use_mouse", "YesNo"
 	Option "Enable mouse in menus",	"m_use_mouse", "MenuMouse", "use_mouse"
 	Option "Show back button",		"m_show_backbutton", "Corners", "use_mouse"
-	IfOption(Windows)	// No cursors on SDL right now.
-	{
-		Option "Cursor",				"vid_cursor", "Cursors"
-	}
+	Option "Cursor",				"vid_cursor", "Cursors"
 	StaticText 	""
 	Slider "Overall sensitivity",		"mouse_sensitivity", 0.5, 2.5, 0.1
 	Option "Prescale mouse movement",	"m_noprescale", "NoYes"