diff --git a/src/m_misc.c b/src/m_misc.c
index 701fba2db0ce1668ba30dae18a9ed96aeeb325fd..f7d5cf9613b17ff00e5390f4a50710193470707f 100644
--- a/src/m_misc.c
+++ b/src/m_misc.c
@@ -1672,73 +1672,6 @@ void strcatbf(char *s1, const char *s2, const char *s3)
 	strcat(s1, tmp);
 }
 
-/** Locate a substring, case-insensitively.
-  * Know that I hate this style. -James
-  *
-  * \param s The string to search within.
-  * \param q The substring to find.
-  * \return a pointer to the located substring, or NULL if it could be found.
-*/
-char *strcasestr(const char *s, const char *q)
-{
-	void **vpp;/* a hack! */
-
-	size_t qz;
-
-	const char *up;
-	const char *lp;
-
-	int uc;
-	int lc;
-
-	qz = strlen(q);
-
-	uc = toupper(*q);
-	lc = tolower(*q);
-
-	up = s;
-	lp = s;
-
-	do
-	{
-		if (uc > 0)
-		{
-			up = strchr(up, uc);
-			if (!up || ( lc == 0 && lp < up ))
-				uc = -1;
-			else
-			if (strnicmp(q, up, qz) == 0)
-				uc = 0;
-			else
-				up++;
-		}
-		if (lc > 0)
-		{
-			lp = strchr(lp, lc);
-			if (!lp || ( uc == 0 && up < lp ))
-				lc = -1;
-			else
-			if (strnicmp(q, lp, qz) == 0)
-				lc = 0;
-			else
-				lp++;
-		}
-	}
-	while (( uc > 0 ) || ( lc > 0 )) ;
-
-	if (uc == 0)
-		vpp = (void **)&up;
-	else
-		vpp = (void **)&lp;
-
-	/*
-	We can dereference a double void pointer and cast it to remove const.
-	This works because the original variable (the pointer) is writeable,
-	but its value is not.
-	*/
-	return (char *)*vpp;
-}
-
 /** Converts an ASCII Hex string into an integer. Thanks, Borland!
   * <Inuyasha> I don't know if this belongs here specifically, but it sure
   *            doesn't belong in p_spec.c, that's for sure
diff --git a/src/strcasestr.c b/src/strcasestr.c
new file mode 100644
index 0000000000000000000000000000000000000000..2077dc3ffa322e96c38c66536199cafebd8c0447
--- /dev/null
+++ b/src/strcasestr.c
@@ -0,0 +1,110 @@
+/*
+strcasestr -- case insensitive substring searching function.
+*/
+/*
+Copyright 2019 James R.
+All rights reserved.
+
+Redistribution and use in source forms, with or without modification, is
+permitted provided that the following condition is met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+   condition and the following disclaimer.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#define SWAP( a, b ) \
+(\
+		(a) ^= (b),\
+		(b) ^= (a),\
+		(a) ^= (b)\
+)
+
+static inline int
+trycmp (char **pp, char *cp,
+		const char *q, size_t qn)
+{
+	char *p;
+	p = (*pp);
+	if (strncasecmp(p, q, qn) == 0)
+		return 0;
+	(*pp) = strchr(&p[1], (*cp));
+	return 1;
+}
+
+static inline void
+swapp (char ***ppap, char ***ppbp, char **cpap, char **cpbp)
+{
+	SWAP(*(intptr_t *)ppap, *(intptr_t *)ppbp);
+	SWAP(*(intptr_t *)cpap, *(intptr_t *)cpbp);
+}
+
+char *
+strcasestr (const char *s, const char *q)
+{
+	size_t  qn;
+
+	char    uc;
+	char    lc;
+
+	char   *up;
+	char   *lp;
+
+	char **ppa;
+	char **ppb;
+
+	char  *cpa;
+	char  *cpb;
+
+	uc = toupper(*q);
+	lc = tolower(*q);
+
+	up = strchr(s, uc);
+	lp = strchr(s, lc);
+
+	if (!( (intptr_t)up|(intptr_t)lp ))
+		return 0;
+
+	if (!lp || up < lp)
+	{
+		ppa = &up;
+		ppb = &lp;
+
+		cpa = &uc;
+		cpb = &lc;
+	}
+	else
+	{
+		ppa = &lp;
+		ppb = &up;
+
+		cpa = &lc;
+		cpb = &uc;
+	}
+
+	qn = strlen(q);
+
+	for (;;)
+	{
+		if (trycmp(ppa, cpa, q, qn) == 0)
+			return (*ppa);
+
+		if (!( (intptr_t)up|(intptr_t)lp ))
+			break;
+
+		if (!(*ppa) || ( (*ppb) && (*ppb) < (*ppa) ))
+			swapp(&ppa, &ppb, &cpa, &cpb);
+	}
+
+	return 0;
+}
diff --git a/src/string.c b/src/string.c
index 2a03e87296711f437b9bf4e61a0217b3e37bcf81..c415e5245a85acf2d57940bc53f7ed4891d46671 100644
--- a/src/string.c
+++ b/src/string.c
@@ -2,6 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 2006      by Graue.
 // Copyright (C) 2006-2018 by Sonic Team Junior.
+// Copyright (C) 2019      by James R.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
@@ -50,3 +51,5 @@ size_t strlcpy(char *dst, const char *src, size_t siz)
 }
 
 #endif
+
+#include "strcasestr.c"