+ }
+
+ loadingscreenstack = s->prev;
+ if(s->prev)
+ s->prev->relative_completion = (s->absolute_loading_amount_min + s->absolute_loading_amount_len - s->prev->absolute_loading_amount_min) / s->prev->absolute_loading_amount_len;
+ Z_Free(s);
+
+ if(redraw)
+ SCR_UpdateLoadingScreenIfShown();
+}
+
+void SCR_ClearLoadingScreen (qboolean redraw)
+{
+ while(loadingscreenstack)
+ SCR_PopLoadingScreen(redraw && !loadingscreenstack->prev);
+}
+
+static float SCR_DrawLoadingStack_r(loadingscreenstack_t *s, float y, float size)
+{
+ float x;
+ size_t len;
+ float total;
+
+ total = 0;
+#if 0
+ if(s)
+ {
+ total += SCR_DrawLoadingStack_r(s->prev, y, 8);
+ y -= total;
+ if(!s->prev || strcmp(s->msg, s->prev->msg))
+ {
+ len = strlen(s->msg);
+ x = (vid_conwidth.integer - DrawQ_TextWidth(s->msg, len, size, size, true, FONT_INFOBAR)) / 2;
+ y -= size;
+ DrawQ_Fill(0, y, vid_conwidth.integer, size, 0, 0, 0, 1, 0);
+ DrawQ_String(x, y, s->msg, len, size, size, 1, 1, 1, 1, 0, NULL, true, FONT_INFOBAR);
+ total += size;
+ }
+ }
+#else
+ if(s)
+ {
+ len = strlen(s->msg);
+ x = (vid_conwidth.integer - DrawQ_TextWidth(s->msg, len, size, size, true, FONT_INFOBAR)) / 2;
+ y -= size;
+ DrawQ_Fill(0, y, vid_conwidth.integer, size, 0, 0, 0, 1, 0);
+ DrawQ_String(x, y, s->msg, len, size, size, 1, 1, 1, 1, 0, NULL, true, FONT_INFOBAR);
+ total += size;
+ }
+#endif
+ return total;
+}
+
+static void SCR_DrawLoadingStack(void)
+{
+ float verts[12];
+ float colors[16];
+
+ loadingscreenheight = SCR_DrawLoadingStack_r(loadingscreenstack, vid_conheight.integer, scr_loadingscreen_barheight.value);
+ if(loadingscreenstack)
+ {
+ // height = 32; // sorry, using the actual one is ugly
+ GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
+ GL_DepthRange(0, 1);
+ GL_PolygonOffset(0, 0);
+ GL_DepthTest(false);
+// R_Mesh_ResetTextureState();
+ verts[2] = verts[5] = verts[8] = verts[11] = 0;
+ verts[0] = verts[9] = 0;
+ verts[1] = verts[4] = vid_conheight.integer - scr_loadingscreen_barheight.value;
+ verts[3] = verts[6] = vid_conwidth.integer * loadingscreenstack->absolute_loading_amount_min;
+ verts[7] = verts[10] = vid_conheight.integer;
+
+#if _MSC_VER >= 1400
+#define sscanf sscanf_s
+#endif
+ // ^^^^^^^^^^ blue component
+ // ^^^^^^ bottom row
+ // ^^^^^^^^^^^^ alpha is always on
+ colors[0] = 0; colors[1] = 0; colors[2] = 0; colors[3] = 1;
+ colors[4] = 0; colors[5] = 0; colors[6] = 0; colors[7] = 1;
+ sscanf(scr_loadingscreen_barcolor.string, "%f %f %f", &colors[8], &colors[9], &colors[10]); colors[11] = 1;
+ sscanf(scr_loadingscreen_barcolor.string, "%f %f %f", &colors[12], &colors[13], &colors[14]); colors[15] = 1;
+
+ R_Mesh_PrepareVertices_Generic_Arrays(4, verts, colors, NULL);
+ R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1, true);
+ R_Mesh_Draw(0, 4, 0, 2, polygonelement3i, NULL, 0, polygonelement3s, NULL, 0);
+
+ // make sure everything is cleared, including the progress indicator
+ if(loadingscreenheight < 8)
+ loadingscreenheight = 8;
+ }
+}
+
+static cachepic_t *loadingscreenpic;
+static float loadingscreenpic_vertex3f[12];
+static float loadingscreenpic_texcoord2f[8];
+
+static void SCR_DrawLoadingScreen_SharedSetup (qboolean clear)
+{
+ r_viewport_t viewport;
+ float x, y, w, h, sw, sh, f;