diff --git a/configure.ac b/configure.ac
index 7b3e1c3..f4fd582 100644
--- a/configure.ac
+++ b/configure.ac
@@ -410,6 +410,21 @@ AC_CHECK_LIB(GLU, main,
 		[${OPENGL_LIBS} -lm]), [${OPENGL_LIBS} -lm])
 AC_SUBST([OPENGL_LIBS], [${OPENGL_LIBS}])
 
+# Look for OpenGLC
+AC_CHECK_HEADER(GL/glc.h, ,
+	AC_MSG_ERROR([OpenGLC header not found. Please install QuesoGLC: http://quesoglc.sourceforge.net/]))
+AC_CHECK_LIB(GLC, main,
+	OPENGLC_LIBS="-lGLC",
+	AC_CHECK_LIB(glc32, main,
+		OPENGLC_LIBS="-lglc32",
+		AC_MSG_ERROR([OpenGLC library not found. Please install QuesoGLC: http://quesoglc.sourceforge.net/])))
+if test "x$enable_static" = "xyes" ; then
+	# If linking statically, make sure to link against the direct dependencies, too.
+	# FIXME Remove this whenever QuesoGLC has a pkg-config file
+	OPENGLC_LIBS="${OPENGLC_LIBS} ${FONTCONFIG_LIBS} ${FREETYPE_LIBS}"
+fi
+AC_SUBST([OPENGLC_LIBS], [${OPENGLC_LIBS}])
+
 # When (cross-)compiling for Windows (MinGW) we need to link in BFD for the Dr.
 # MinGW derived exception handler.
 if test "x$host_os_mingw32" = "xyes" ; then
diff --git a/lib/framework/framework.vcxproj b/lib/framework/framework.vcxproj
index 99b98c4..8cd1162 100644
--- a/lib/framework/framework.vcxproj
+++ b/lib/framework/framework.vcxproj
@@ -169,11 +169,7 @@
     </PreBuildEvent>
   </ItemDefinitionGroup>
   <ItemGroup>
-    <ClCompile Include="configfile.cpp" />
     <ClCompile Include="crc.cpp" />
-    <ClCompile Include="cursors.cpp" />
-    <ClCompile Include="cursors16.cpp" />
-    <ClCompile Include="cursors32.cpp" />
     <ClCompile Include="debug.cpp" />
     <ClCompile Include="frame.cpp" />
     <ClCompile Include="frameresource.cpp" />
@@ -215,9 +211,7 @@
     </ProjectReference>
   </ItemGroup>
   <ItemGroup>
-    <ClInclude Include="configfile.h" />
     <ClInclude Include="crc.h" />
-    <ClInclude Include="cursors.h" />
     <ClInclude Include="debug.h" />
     <ClInclude Include="endian_hack.h" />
     <ClInclude Include="file.h" />
diff --git a/lib/framework/framework.vcxproj.filters b/lib/framework/framework.vcxproj.filters
index 9ebe729..c5a132b 100644
--- a/lib/framework/framework.vcxproj.filters
+++ b/lib/framework/framework.vcxproj.filters
@@ -14,21 +14,9 @@
     </Filter>
   </ItemGroup>
   <ItemGroup>
-    <ClCompile Include="configfile.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
     <ClCompile Include="crc.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
-    <ClCompile Include="cursors.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="cursors16.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="cursors32.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
     <ClCompile Include="debug.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
@@ -95,15 +83,9 @@
     </BisonParser>
   </ItemGroup>
   <ItemGroup>
-    <ClInclude Include="configfile.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
     <ClInclude Include="crc.h">
       <Filter>Header Files</Filter>
     </ClInclude>
-    <ClInclude Include="cursors.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
     <ClInclude Include="debug.h">
       <Filter>Header Files</Filter>
     </ClInclude>
@@ -188,9 +170,6 @@
     <ClInclude Include="vector.h">
       <Filter>Header Files</Filter>
     </ClInclude>
-    <ClInclude Include="wz2100icon.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
     <ClInclude Include="wzapp.h">
       <Filter>Header Files</Filter>
     </ClInclude>
diff --git a/lib/framework/wzapp.cpp b/lib/framework/wzapp.cpp
index d06a060..98910f4 100644
--- a/lib/framework/wzapp.cpp
+++ b/lib/framework/wzapp.cpp
@@ -1079,6 +1079,9 @@ int wzSemaphoreAvailable(WZ_SEMAPHORE *semaphore)
 /***     Font support   ***/
 /**************************/
 
+// Font and text drawing support based on Qt postponed until we can get it working properly on
+// all platforms, and with decent speed, and without clobbering existing OpenGL states.
+#if 0
 void iV_SetFont(enum iV_fonts FontID)
 {
 	WzMainWindow::instance()->setFontType(FontID);
@@ -1159,6 +1162,13 @@ void iV_DrawTextRotated(const char* string, float XPos, float YPos, float rotati
 	pie_SetRendMode(REND_OPAQUE);		// beat state machinery into submission
 }
 
+
+void iV_SetTextSize(float size)
+{
+	WzMainWindow::instance()->setFontSize(size);
+}
+#endif
+
 void wzFatalDialog(const char *text)
 {
 	crashing = true;
diff --git a/lib/ivis_opengl/Makefile.am b/lib/ivis_opengl/Makefile.am
index 78fa528..7857d4b 100644
--- a/lib/ivis_opengl/Makefile.am
+++ b/lib/ivis_opengl/Makefile.am
@@ -1,4 +1,4 @@
-AM_CPPFLAGS = $(PNG_CFLAGS) $(OPENGL_CFLAGS) $(WZ_CPPFLAGS) $(GLEW_CFLAGS) $(QT4_CFLAGS)
+AM_CPPFLAGS = $(PNG_CFLAGS) $(OPENGL_CFLAGS) $(OPENGLC_CFLAGS) $(WZ_CPPFLAGS) $(GLEW_CFLAGS) $(QT4_CFLAGS)
 AM_CFLAGS = $(WZ_CFLAGS) -Wno-missing-declarations
 AM_CXXFLAGS = $(WZ_CXXFLAGS) $(QT4_CFLAGS)
 
diff --git a/lib/ivis_opengl/textdraw.cpp b/lib/ivis_opengl/textdraw.cpp
index 8f7c921..e4bf384 100644
--- a/lib/ivis_opengl/textdraw.cpp
+++ b/lib/ivis_opengl/textdraw.cpp
@@ -36,6 +36,413 @@
 #define ASCII_NEWLINE			('@')
 #define ASCII_COLOURMODE		('#')
 
+#ifdef WZ_OS_MAC
+# include <QuesoGLC/glc.h>
+#else
+# include <GL/glc.h>
+#endif
+
+static char font_family[128];
+static char font_face_regular[128];
+static char font_face_bold[128];
+
+static float font_size = 12.f;
+// Contains the font color in the following order: red, green, blue, alpha
+static float font_colour[4] = {1.f, 1.f, 1.f, 1.f};
+
+static GLint _glcContext = 0;
+static GLint _glcFont_Regular = 0;
+static GLint _glcFont_Bold = 0;
+
+/***************************************************************************/
+/*
+ *	Source
+ */
+/***************************************************************************/
+
+void iV_font(const char *fontName, const char *fontFace, const char *fontFaceBold)
+{
+	if (_glcContext)
+	{
+		debug(LOG_ERROR, "Cannot change font in running game, yet.");
+		return;
+	}
+	if (fontName)
+	{
+		sstrcpy(font_family, fontName);
+	}
+	if (fontFace)
+	{
+		sstrcpy(font_face_regular, fontFace);
+	}
+	if (fontFaceBold)
+	{
+		sstrcpy(font_face_bold, fontFaceBold);
+	}
+}
+
+static inline void iV_printFontList(void)
+{
+	unsigned int i;
+	unsigned int font_count = glcGeti(GLC_CURRENT_FONT_COUNT);
+	debug(LOG_NEVER, "GLC_CURRENT_FONT_COUNT = %d", font_count);
+
+	if (font_count == 0)
+	{
+		debug(LOG_ERROR, "The required font (%s) isn't loaded", font_family);
+
+		// Fall back to unselected fonts since the requested font apparently
+		// isn't available.
+		glcEnable(GLC_AUTO_FONT);
+	}
+
+	for (i = 0; i < font_count; ++i)
+	{
+		GLint font = glcGetListi(GLC_CURRENT_FONT_LIST, i);
+		/* The output of the family name and the face is printed using 2 steps
+		 * because glcGetFontc and glcGetFontFace return their result in the
+		 * same buffer (according to GLC specs).
+		 */
+		char prBuffer[1024];
+		snprintf(prBuffer, sizeof(prBuffer), "Font #%d : %s ", (int)font, (const char*)glcGetFontc(font, GLC_FAMILY));
+		prBuffer[sizeof(prBuffer) - 1] = 0;
+		sstrcat(prBuffer, (char const *)glcGetFontFace(font));
+		debug(LOG_NEVER, "%s", prBuffer);
+	}
+}
+
+static void iV_initializeGLC(void)
+{
+	if (_glcContext)
+	{
+		return;
+	}
+
+	_glcContext = glcGenContext();
+	if (!_glcContext)
+	{
+		debug(LOG_ERROR, "Failed to initialize");
+	}
+	else
+	{
+		debug(LOG_NEVER, "Successfully initialized. _glcContext = %d", (int)_glcContext);
+	}
+
+	glcContext(_glcContext);
+
+	glcEnable(GLC_AUTO_FONT);		// We *do* want font fall-backs
+	glcRenderStyle(GLC_TEXTURE);
+	glcStringType(GLC_UTF8_QSO); // Set GLC's string type to UTF-8 FIXME should be UCS4 to avoid conversions
+
+	#ifdef WZ_OS_MAC
+	{
+		char resourcePath[PATH_MAX];
+		CFURLRef resourceURL = CFBundleCopyResourcesDirectoryURL(CFBundleGetMainBundle());
+		if (CFURLGetFileSystemRepresentation(resourceURL, true, (UInt8 *) resourcePath, PATH_MAX))
+		{
+			sstrcat(resourcePath, "/Fonts");
+			glcAppendCatalog(resourcePath);
+		}
+		else
+		{
+			debug(LOG_ERROR, "Could not change to resources directory.");
+		}
+
+		if (resourceURL != NULL)
+		{
+			CFRelease(resourceURL);
+		}
+	}
+	#endif
+
+	_glcFont_Regular = glcGenFontID();
+	_glcFont_Bold = glcGenFontID();
+
+	if (!glcNewFontFromFamily(_glcFont_Regular, font_family))
+	{
+		debug(LOG_ERROR, "Failed to select font family %s as regular font", font_family);
+	}
+	else
+	{
+		debug(LOG_NEVER, "Successfully selected font family %s as regular font", font_family);
+	}
+
+	if (!glcFontFace(_glcFont_Regular, font_face_regular))
+	{
+		debug(LOG_WARNING, "Failed to select the \"%s\" font face of font family %s", font_face_regular, font_family);
+	}
+	else
+	{
+		debug(LOG_NEVER, "Successfully selected the \"%s\" font face of font family %s", font_face_regular, font_family);
+	}
+
+	if (!glcNewFontFromFamily(_glcFont_Bold, font_family))
+	{
+		debug(LOG_ERROR, "iV_initializeGLC: Failed to select font family %s for the bold font", font_family);
+	}
+	else
+	{
+		debug(LOG_NEVER, "Successfully selected font family %s for the bold font", font_family);
+	}
+
+	if (!glcFontFace(_glcFont_Bold, font_face_bold))
+	{
+		debug(LOG_WARNING, "Failed to select the \"%s\" font face of font family %s", font_face_bold, font_family);
+	}
+	else
+	{
+		debug(LOG_NEVER, "Successfully selected the \"%s\" font face of font family %s", font_face_bold, font_family);
+	}
+
+	debug(LOG_NEVER, "Finished initializing GLC");
+}
+
+void iV_TextInit()
+{
+	iV_initializeGLC();
+	iV_SetFont(font_regular);
+
+#ifdef DEBUG
+	iV_printFontList();
+#endif
+}
+
+void iV_TextShutdown()
+{
+	if (_glcFont_Regular)
+	{
+		glcDeleteFont(_glcFont_Regular);
+	}
+
+	if (_glcFont_Bold)
+	{
+		glcDeleteFont(_glcFont_Bold);
+	}
+
+	glcContext(0);
+
+	if (_glcContext)
+	{
+		glcDeleteContext(_glcContext);
+	}
+}
+
+void iV_SetFont(enum iV_fonts FontID)
+{
+	switch (FontID)
+	{
+		default:
+		case font_scaled:
+		case font_regular:
+			iV_SetTextSize(12.f);
+			glcFont(_glcFont_Regular);
+			break;
+
+		case font_large:
+			iV_SetTextSize(21.f);
+			glcFont(_glcFont_Bold);
+			break;
+
+		case font_small:
+			iV_SetTextSize(9.f);
+			glcFont(_glcFont_Regular);
+			break;
+	}
+}
+
+static inline float getGLCResolution(void)
+{
+	float resolution = glcGetf(GLC_RESOLUTION);
+
+	// The default resolution as used by OpenGLC is 72 dpi
+	if (resolution == 0.f)
+	{
+		return 72.f;
+	}
+
+	return resolution;
+}
+
+static inline float getGLCPixelSize(void)
+{
+	float pixel_size = font_size * getGLCResolution() / 72.f;
+	return pixel_size;
+}
+
+static inline float getGLCPointWidth(const float* boundingbox)
+{
+	// boundingbox contains: [ xlb ylb xrb yrb xrt yrt xlt ylt ]
+	// l = left; r = right; b = bottom; t = top;
+	float rightTopX = boundingbox[4];
+	float leftTopX = boundingbox[6];
+
+	float point_width = rightTopX - leftTopX;
+
+	return point_width;
+}
+
+static inline float getGLCPointHeight(const float* boundingbox)
+{
+	// boundingbox contains: [ xlb ylb xrb yrb xrt yrt xlt ylt ]
+	// l = left; r = right; b = bottom; t = top;
+	float leftBottomY = boundingbox[1];
+	float leftTopY = boundingbox[7];
+
+	float point_height = fabsf(leftTopY - leftBottomY);
+
+	return point_height;
+}
+
+static inline float getGLCPointToPixel(float point_width)
+{
+	float pixel_width = point_width * getGLCPixelSize();
+
+	return pixel_width;
+}
+
+unsigned int iV_GetTextWidth(const char* string)
+{
+	float boundingbox[8];
+	float pixel_width, point_width;
+
+	glcMeasureString(GL_FALSE, string);
+	if (!glcGetStringMetric(GLC_BOUNDS, boundingbox))
+	{
+		debug(LOG_ERROR, "Couldn't retrieve a bounding box for the string \"%s\"", string);
+		return 0;
+	}
+
+	point_width = getGLCPointWidth(boundingbox);
+	pixel_width = getGLCPointToPixel(point_width);
+	return (unsigned int)pixel_width;
+}
+
+unsigned int iV_GetCountedTextWidth(const char* string, size_t string_length)
+{
+	float boundingbox[8];
+	float pixel_width, point_width;
+
+	glcMeasureCountedString(GL_FALSE, string_length, string);
+	if (!glcGetStringMetric(GLC_BOUNDS, boundingbox))
+	{
+		debug(LOG_ERROR, "Couldn't retrieve a bounding box for the string \"%s\" of length %u", 
+		      string, (unsigned int)string_length);
+		return 0;
+	}
+
+	point_width = getGLCPointWidth(boundingbox);
+	pixel_width = getGLCPointToPixel(point_width);
+	return (unsigned int)pixel_width;
+}
+
+unsigned int iV_GetTextHeight(const char* string)
+{
+	float boundingbox[8];
+	float pixel_height, point_height;
+
+	glcMeasureString(GL_FALSE, string);
+	if (!glcGetStringMetric(GLC_BOUNDS, boundingbox))
+	{
+		debug(LOG_ERROR, "Couldn't retrieve a bounding box for the string \"%s\"", string);
+		return 0;
+	}
+
+	point_height = getGLCPointHeight(boundingbox);
+	pixel_height = getGLCPointToPixel(point_height);
+	return (unsigned int)pixel_height;
+}
+
+unsigned int iV_GetCharWidth(uint32_t charCode)
+{
+	float boundingbox[8];
+	float pixel_width, point_width;
+
+	if (!glcGetCharMetric(charCode, GLC_BOUNDS, boundingbox))
+	{
+		debug(LOG_ERROR, "Couldn't retrieve a bounding box for the character code %u", charCode);
+		return 0;
+	}
+
+	point_width = getGLCPointWidth(boundingbox);
+	pixel_width = getGLCPointToPixel(point_width);
+	return (unsigned int)pixel_width;
+}
+
+int iV_GetTextLineSize()
+{
+	float boundingbox[8];
+	float pixel_height, point_height;
+
+	if (!glcGetMaxCharMetric(GLC_BOUNDS, boundingbox))
+	{
+		debug(LOG_ERROR, "Couldn't retrieve a bounding box for the character");
+		return 0;
+	}
+
+	point_height = getGLCPointHeight(boundingbox);
+	pixel_height = getGLCPointToPixel(point_height);
+	return (unsigned int)pixel_height;
+}
+
+static float iV_GetMaxCharBaseY(void)
+{
+	float base_line[4]; // [ xl yl xr yr ]
+
+	if (!glcGetMaxCharMetric(GLC_BASELINE, base_line))
+	{
+		debug(LOG_ERROR, "Couldn't retrieve the baseline for the character");
+		return 0;
+	}
+
+	return base_line[1];
+}
+
+int iV_GetTextAboveBase(void)
+{
+	float point_base_y = iV_GetMaxCharBaseY();
+	float point_top_y;
+	float boundingbox[8];
+	float pixel_height, point_height;
+
+	if (!glcGetMaxCharMetric(GLC_BOUNDS, boundingbox))
+	{
+		debug(LOG_ERROR, "Couldn't retrieve a bounding box for the character");
+		return 0;
+	}
+
+	point_top_y = boundingbox[7];
+	point_height = point_base_y - point_top_y;
+	pixel_height = getGLCPointToPixel(point_height);
+	return (int)pixel_height;
+}
+
+int iV_GetTextBelowBase(void)
+{
+	float point_base_y = iV_GetMaxCharBaseY();
+	float point_bottom_y;
+	float boundingbox[8];
+	float pixel_height, point_height;
+
+	if (!glcGetMaxCharMetric(GLC_BOUNDS, boundingbox))
+	{
+		debug(LOG_ERROR, "Couldn't retrieve a bounding box for the character");
+		return 0;
+	}
+
+	point_bottom_y = boundingbox[1];
+	point_height = point_bottom_y - point_base_y;
+	pixel_height = getGLCPointToPixel(point_height);
+	return (int)pixel_height;
+}
+
+void iV_SetTextColour(PIELIGHT colour)
+{
+	font_colour[0] = colour.byte.r / 255.0f;
+	font_colour[1] = colour.byte.g / 255.0f;
+	font_colour[2] = colour.byte.b / 255.0f;
+	font_colour[3] = colour.byte.a / 255.0f;
+}
+
 /** Draws formatted text with word wrap, long word splitting, embedded newlines
  *  (uses '@' rather than '\n') and colour toggle mode ('#') which enables or
  *  disables font colouring.
@@ -195,3 +602,79 @@ int iV_DrawFormattedText(const char* String, UDWORD x, UDWORD y, UDWORD Width, U
 
 	return jy;
 }
+
+void iV_DrawTextRotated(const char* string, float XPos, float YPos, float rotation)
+{
+	GLint matrix_mode = 0;
+	ASSERT_OR_RETURN( , string, "Couldn't render string!");
+	pie_SetTexturePage(TEXPAGE_EXTERN);
+
+	glGetIntegerv(GL_MATRIX_MODE, &matrix_mode);
+	glMatrixMode(GL_TEXTURE);
+	glPushMatrix();
+	glLoadIdentity();
+	glMatrixMode(GL_MODELVIEW);
+	glPushMatrix();
+
+	if (rotation != 0.f)
+	{
+		rotation = 360.f - rotation;
+	}
+
+	glTranslatef(XPos, YPos, 0.f);
+	glRotatef(180.f, 1.f, 0.f, 0.f);
+	glRotatef(rotation, 0.f, 0.f, 1.f);
+	glScalef(font_size, font_size, 0.f);
+
+	glColor4fv(font_colour);
+
+	glFrontFace(GL_CW);
+	glcRenderString(string);
+	glFrontFace(GL_CCW);
+
+	glPopMatrix();
+	glMatrixMode(GL_TEXTURE);
+	glPopMatrix();
+	glMatrixMode(matrix_mode);
+
+	// Reset the current model view matrix
+	glLoadIdentity();
+}
+
+static void iV_DrawTextRotatedFv(float x, float y, float rotation, const char* format, va_list ap)
+{
+	va_list aq;
+	size_t size;
+	char* str;
+
+	/* Required because we're using the va_list ap twice otherwise, which
+	 * results in undefined behaviour. See stdarg(3) for details.
+	 */
+	va_copy(aq, ap);
+
+	// Allocate a buffer large enough to hold our string on the stack
+	size = vsnprintf(NULL, 0, format, ap);
+	str = (char *)alloca(size + 1);
+
+	// Print into our newly created string buffer
+	vsprintf(str, format, aq);
+
+	va_end(aq);
+
+	// Draw the produced string to the screen at the given position and rotation
+	iV_DrawTextRotated(str, x, y, rotation);
+}
+
+void iV_DrawTextF(float x, float y, const char* format, ...)
+{
+	va_list ap;
+
+	va_start(ap, format);
+		iV_DrawTextRotatedFv(x, y, 0.f, format, ap);
+	va_end(ap);
+}
+
+void iV_SetTextSize(float size)
+{
+	font_size = size;
+}
\ No newline at end of file
diff --git a/lib/ivis_opengl/textdraw.h b/lib/ivis_opengl/textdraw.h
index ee0aee4..b9bf740 100644
--- a/lib/ivis_opengl/textdraw.h
+++ b/lib/ivis_opengl/textdraw.h
@@ -55,6 +55,9 @@ enum {
 };
 
 extern int iV_DrawFormattedText(const char* String, UDWORD x, UDWORD y, UDWORD Width, UDWORD Justify);
+
+extern void iV_SetTextSize(float size);
+
 extern void iV_DrawTextRotated(const char* string, float x, float y, float rotation);
 
 /** Draws text with a printf syntax to the screen.
@@ -64,4 +67,6 @@ static inline void iV_DrawText(const char* string, float x, float y)
 	iV_DrawTextRotated(string, x, y, 0.f);
 }
 
+extern void iV_DrawTextF(float x, float y, const char* format, ...) WZ_DECL_FORMAT(printf, 3, 4);
+
 #endif // _INCLUDED_TEXTDRAW_

