diff --git a/src/s_sound.c b/src/s_sound.c
index 181ca5a675f0d31552a5d205aa329adbefbca5cb..3993d7f981c30eff91343984a56f899e8c1d2ce8 100644
--- a/src/s_sound.c
+++ b/src/s_sound.c
@@ -531,6 +531,64 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
 			sep = (~sep) & 255;
 #endif
 
+		// Handle closed caption input.
+		if (cv_closedcaptioning.value && sfx->caption[0] != '/')
+		{
+			UINT8 i, set = NUMCAPTIONS-1, moveup = 255;
+			boolean same = false;
+			for (i = 0; i < set; i++)
+			{
+				same = ((sfx == closedcaptions[i].s) || (closedcaptions[i].s && fastcmp(sfx->caption, closedcaptions[i].s->caption)));
+				if (same)
+				{
+					set = i;
+					break;
+				}
+			}
+
+			if (!same)
+			{
+				for (i = 0; i < set; i++)
+				{
+					if (!(closedcaptions[i].c || closedcaptions[i].s) || (sfx->priority >= closedcaptions[i].s->priority))
+					{
+						set = i;
+						if (closedcaptions[i].s && (sfx->priority >= closedcaptions[i].s->priority))
+							moveup = i;
+						break;
+					}
+				}
+				for (i = NUMCAPTIONS-1; i > set; i--)
+				{
+					if (sfx == closedcaptions[i].s)
+					{
+						closedcaptions[i].c = NULL;
+						closedcaptions[i].s = NULL;
+						closedcaptions[i].t = 0;
+					}
+				}
+			}
+
+			if (moveup != 255)
+			{
+				for (i = moveup; i < NUMCAPTIONS-1; i++)
+				{
+					if (!(closedcaptions[i].c || closedcaptions[i].s))
+						break;
+				}
+				for (; i > set; i--)
+				{
+					closedcaptions[i].c = closedcaptions[i-1].c;
+					closedcaptions[i].s = closedcaptions[i-1].s;
+					closedcaptions[i].t = closedcaptions[i-1].t;
+				}
+			}
+
+			closedcaptions[set].c = &channels[cnum];
+			closedcaptions[set].s = sfx;
+			closedcaptions[set].t = TICRATE+2;
+		}
+
 		// Assigns the handle to one of the channels in the
 		// mix/output buffer.
 		channels[cnum].handle = I_StartSound(sfx_id, volume, sep, pitch, priority);
diff --git a/src/screen.c b/src/screen.c
index 12bb9c4bd5efb0316f62524be05e0a5edb1a148e..ca1e6b659424f725bcaecb0b4a699f656df0b971 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -478,11 +478,16 @@ void SCR_ClosedCaptions(void)
 				const mobj_t *o = (const mobj_t *)closedcaptions[i].c->origin;
 				if (o)
 				{
-					angle_t angle = R_PointToAngle(o->x, o->y) - localangle;
-					if (angle > ANGLE_45 && angle < ANGLE_135)
-						dir = '\x1C';
-					else if (angle > ANGLE_225 && angle < ANGLE_315)
-						dir = '\x1D';
+					if (!splitscreen)
+					{
+						angle_t angle = R_PointToAngle(o->x, o->y) - localangle;
+						if (angle > ANGLE_45 && angle < ANGLE_135)
+							dir = '\x1C';
+						else if (angle > ANGLE_225 && angle < ANGLE_315)
+							dir = '\x1D';
+						else
+							dir = '\x1E';
+					}
 					else
 						dir = '\x1E';
 				}