+ text++;
+ }
+ i--;
+ }
+ // get the backup
+ ch = nextch;
+ // using a value of -1 for the oldstyle map because NULL means uninitialized...
+ // this way we don't need to rebind fnt->tex for every old-style character
+ // E000..E0FF: emulate old-font characters (to still have smileys and such available)
+ if (shadow)
+ {
+ x += 1.0/pix_x * r_textshadow.value;
+ y += 1.0/pix_y * r_textshadow.value;
+ }
+ if (!fontmap || (ch <= 0xFF && fontmap->glyphs[ch].image) || (ch >= 0xE000 && ch <= 0xE0FF))
+ {
+ if (ch >= 0xE000)
+ ch -= 0xE000;
+ if (ch > 0xFF)
+ goto out;
+ if (fontmap)
+ {
+ if (map != ft2_oldstyle_map)
+ {
+ if (batchcount)
+ {
+ // switching from freetype to non-freetype rendering
+ R_Mesh_PrepareVertices_Generic_Arrays(batchcount * 4, vertex3f, color4f, texcoord2f);
+ R_Mesh_Draw(0, batchcount * 4, 0, batchcount * 2, quadelement3i, NULL, 0, quadelement3s, NULL, 0);
+ batchcount = 0;
+ ac = color4f;
+ at = texcoord2f;
+ av = vertex3f;
+ }
+ R_SetupShader_Generic(fnt->tex, NULL, GL_MODULATE, 1, (flags & DRAWFLAGS_BLEND) ? false : true, true, false);
+ map = ft2_oldstyle_map;
+ }
+ }
+ prevch = 0;
+ //num = (unsigned char) text[i];
+ //thisw = fnt->width_of[num];
+ thisw = fnt->width_of[ch];
+ // FIXME make these smaller to just include the occupied part of the character for slightly faster rendering
+ if (r_nearest_conchars.integer)
+ {
+ s = (ch & 15)*0.0625f;
+ t = (ch >> 4)*0.0625f;
+ u = 0.0625f * thisw;
+ v = 0.0625f;
+ }
+ else
+ {
+ s = (ch & 15)*0.0625f + (0.5f / tw);
+ t = (ch >> 4)*0.0625f + (0.5f / th);
+ u = 0.0625f * thisw - (1.0f / tw);
+ v = 0.0625f - (1.0f / th);
+ }
+ ac[ 0] = DrawQ_Color[0];ac[ 1] = DrawQ_Color[1];ac[ 2] = DrawQ_Color[2];ac[ 3] = DrawQ_Color[3];
+ ac[ 4] = DrawQ_Color[0];ac[ 5] = DrawQ_Color[1];ac[ 6] = DrawQ_Color[2];ac[ 7] = DrawQ_Color[3];
+ ac[ 8] = DrawQ_Color[0];ac[ 9] = DrawQ_Color[1];ac[10] = DrawQ_Color[2];ac[11] = DrawQ_Color[3];
+ ac[12] = DrawQ_Color[0];ac[13] = DrawQ_Color[1];ac[14] = DrawQ_Color[2];ac[15] = DrawQ_Color[3];
+ at[ 0] = s ; at[ 1] = t ;
+ at[ 2] = s+u ; at[ 3] = t ;
+ at[ 4] = s+u ; at[ 5] = t+v ;
+ at[ 6] = s ; at[ 7] = t+v ;
+ av[ 0] = x ; av[ 1] = y ; av[ 2] = 10;
+ av[ 3] = x+dw*thisw ; av[ 4] = y ; av[ 5] = 10;
+ av[ 6] = x+dw*thisw ; av[ 7] = y+dh ; av[ 8] = 10;
+ av[ 9] = x ; av[10] = y+dh ; av[11] = 10;
+ ac += 16;
+ at += 8;
+ av += 12;
+ batchcount++;
+ if (batchcount >= QUADELEMENTS_MAXQUADS)
+ {
+ R_Mesh_PrepareVertices_Generic_Arrays(batchcount * 4, vertex3f, color4f, texcoord2f);
+ R_Mesh_Draw(0, batchcount * 4, 0, batchcount * 2, quadelement3i, NULL, 0, quadelement3s, NULL, 0);
+ batchcount = 0;
+ ac = color4f;
+ at = texcoord2f;
+ av = vertex3f;
+ }
+ x += width_of[ch] * dw;
+ } else {
+ if (!map || map == ft2_oldstyle_map || ch < map->start || ch >= map->start + FONT_CHARS_PER_MAP)
+ {
+ // new charmap - need to render
+ if (batchcount)
+ {
+ // we need a different character map, render what we currently have:
+ R_Mesh_PrepareVertices_Generic_Arrays(batchcount * 4, vertex3f, color4f, texcoord2f);
+ R_Mesh_Draw(0, batchcount * 4, 0, batchcount * 2, quadelement3i, NULL, 0, quadelement3s, NULL, 0);
+ batchcount = 0;
+ ac = color4f;
+ at = texcoord2f;
+ av = vertex3f;
+ }
+ // find the new map
+ map = FontMap_FindForChar(fontmap, ch);
+ if (!map)
+ {
+ if (!Font_LoadMapForIndex(ft2, map_index, ch, &map))
+ {
+ shadow = -1;
+ break;
+ }
+ if (!map)
+ {
+ // this shouldn't happen
+ shadow = -1;
+ break;
+ }
+ }
+ R_SetupShader_Generic(map->pic->tex, NULL, GL_MODULATE, 1, (flags & DRAWFLAGS_BLEND) ? false : true, true, false);
+ }
+
+ mapch = ch - map->start;
+ thisw = map->glyphs[mapch].advance_x;
+
+ //x += ftbase_x;
+ y += ftbase_y;
+ if (prevch && Font_GetKerningForMap(ft2, map_index, w, h, prevch, ch, &kx, &ky))
+ {
+ x += kx * dw;
+ y += ky * dh;
+ }
+ else
+ kx = ky = 0;
+ ac[ 0] = DrawQ_Color[0]; ac[ 1] = DrawQ_Color[1]; ac[ 2] = DrawQ_Color[2]; ac[ 3] = DrawQ_Color[3];
+ ac[ 4] = DrawQ_Color[0]; ac[ 5] = DrawQ_Color[1]; ac[ 6] = DrawQ_Color[2]; ac[ 7] = DrawQ_Color[3];
+ ac[ 8] = DrawQ_Color[0]; ac[ 9] = DrawQ_Color[1]; ac[10] = DrawQ_Color[2]; ac[11] = DrawQ_Color[3];
+ ac[12] = DrawQ_Color[0]; ac[13] = DrawQ_Color[1]; ac[14] = DrawQ_Color[2]; ac[15] = DrawQ_Color[3];
+ at[0] = map->glyphs[mapch].txmin; at[1] = map->glyphs[mapch].tymin;
+ at[2] = map->glyphs[mapch].txmax; at[3] = map->glyphs[mapch].tymin;
+ at[4] = map->glyphs[mapch].txmax; at[5] = map->glyphs[mapch].tymax;
+ at[6] = map->glyphs[mapch].txmin; at[7] = map->glyphs[mapch].tymax;
+ av[ 0] = x + dw * map->glyphs[mapch].vxmin; av[ 1] = y + dh * map->glyphs[mapch].vymin; av[ 2] = 10;
+ av[ 3] = x + dw * map->glyphs[mapch].vxmax; av[ 4] = y + dh * map->glyphs[mapch].vymin; av[ 5] = 10;
+ av[ 6] = x + dw * map->glyphs[mapch].vxmax; av[ 7] = y + dh * map->glyphs[mapch].vymax; av[ 8] = 10;
+ av[ 9] = x + dw * map->glyphs[mapch].vxmin; av[10] = y + dh * map->glyphs[mapch].vymax; av[11] = 10;
+ //x -= ftbase_x;
+ y -= ftbase_y;
+
+ x += thisw * dw;
+ ac += 16;
+ at += 8;
+ av += 12;
+ batchcount++;
+ if (batchcount >= QUADELEMENTS_MAXQUADS)
+ {
+ R_Mesh_PrepareVertices_Generic_Arrays(batchcount * 4, vertex3f, color4f, texcoord2f);
+ R_Mesh_Draw(0, batchcount * 4, 0, batchcount * 2, quadelement3i, NULL, 0, quadelement3s, NULL, 0);
+ batchcount = 0;
+ ac = color4f;
+ at = texcoord2f;
+ av = vertex3f;