void DU_DrawString(int x, int y, const unsigned char *string, int charHeight, int iconHeight, int maxRows, int maxWidth, residx_t fontshader, bool docolors) { wchar_t ws[1024]; wchar_t *s; int xx; int i, which = -1; int cnt; //int len; int s_len; int rows = 0; int realFontShader; wchar_t icon_wstring[10]; wchar_t clan_wstring[10]; fontData_t *fontData; fontGlyphData_t **chars; bitmap_t *bmp; mbstowcs(icon_wstring, "^icon ", 10); icon_wstring[9] = 0; mbstowcs(clan_wstring, "^clan ", 10); clan_wstring[9] = 0; if (string[0] == 0) return; //string = _(string); fontData = Res_GetFont(fontshader); if (!fontData) return; for (i = 0; i < MAX_FONT_SIZES + 1; i++) { if (i == MAX_FONT_SIZES || charHeight <= fontData->fontSizes[i]) { which = MAX(0,MIN(MAX_FONT_SIZES-1, i)); break; } } if(which == -1) // UTTAR return; realFontShader = fontData->fontShaders[which]; bmp = fontData->bmps[which]; chars = fontData->chars[which]; //Console_DPrintf("c: %i, slot %i\n", c, fontData->charMap[c]); //len = strlen((char*)string); ws[1023] = 0; s_len = mbstowcs(ws, (char*)string, 1023); if (s_len == -1) { Console_DPrintf("Invalid multibyte string %s\n", string); return; } ws[s_len] = 0; s = ws; xx = x; cnt = 0; Vid_UseShader(realFontShader); while ( *s && rows < maxRows) { switch (*s) { case '\n': rows++; xx = x; //NOTE: we might want to change this +1 to a param y += charHeight + 1; cnt = 0; break; case '^': //we could be drawing an icon if (wmemcmp(s, icon_wstring, 6)==0 && wcslen(s) > 7 && wcschr(&s[7], '^')) { char icon[1024]; int i=0; const wchar_t *start = s; s+=6; while (*s != 0 && *s != '\n' && *s != ' ' && *s != '^' && i < 1023) { icon[i] = *s; s++; i++; } //try to show this if (i > 0 && *s == '^') { icon[i] = 0; Vid_UnuseShader(); Draw_Quad2d(xx, y, iconHeight, iconHeight, 0, 0, 1, 1, Res_LoadShaderEx(fmt("/textures/econs/%s.s2g", icon), SHD_NO_SHADER)); Vid_UseShader(realFontShader); xx += iconHeight; s++; continue; } else { s = (wchar_t *)start; } } //we could be drawing a clan icon else if (wmemcmp(s, clan_wstring, 6)==0 && wcslen(s) > 7 && wcschr(&s[7], '^')) { char icon[1024]; int i=0; const wchar_t *start = s; s+=6; while (*s != 0 && *s != '\n' && *s != ' ' && *s != '^' && i < 1023) { icon[i] = *s; s++; i++; } //try to show this if (i > 0 && *s == '^') { icon[i] = 0; Vid_UnuseShader(); Draw_Quad2d(xx, y, iconHeight, iconHeight, 0, 0, 1, 1, File_GetClanIcon(atoi(icon))); Vid_UseShader(realFontShader); xx += iconHeight + SPACE_AFTER_ICON; s++; continue; } else { s = (wchar_t *)start; } } //check for a color change else { bool valid = true; int colorCodeLen = 1; vec4_t tmpcolor = {1.0, 1.0, 1.0, 1.0}; tmpcolor[3] = Draw_GetCurrentAlpha(); s += 1; switch (*s) { case 'r': //let's use a brighter red to be more easily readable tmpcolor[1] = 0.3; tmpcolor[2] = 0.3; break; case 'g': tmpcolor[0] = 0.0; tmpcolor[2] = 0.0; break; case 'b': //let's use a brighter blue to be more easily readable tmpcolor[0] = 0.3; tmpcolor[1] = 0.3; break; case 'w': break; case 'k': tmpcolor[0] = 0.0; tmpcolor[1] = 0.0; tmpcolor[2] = 0.0; break; case 'y': tmpcolor[2] = 0.1; break; case 'c': tmpcolor[0] = 0.0; break; case 'm': tmpcolor[1] = 0.0; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (wcslen(s) < 3) { s -= 1; valid = false; break; } if (s[1] >= '0' && s[1] <= '9' && s[2] >= '0' && s[2] <= '9') { tmpcolor[0] = ((s[0] - '0') / 9.0); tmpcolor[1] = ((s[1] - '0') / 9.0); tmpcolor[2] = ((s[2] - '0') / 9.0); colorCodeLen = 3; } else { s -= 1; valid = false; break; } break; default: s -= 1; valid = false; break; } if (valid) { s += colorCodeLen; if (docolors) Draw_SetColor(tmpcolor); continue; } } //*** intentional fall through *** default: if (xx - x < maxWidth) xx += DU_DrawChar(xx, y, charHeight, *s, fontshader, fontData, chars, bmp, -2); cnt++; } s++; } Vid_UnuseShader(); }
void DU_DrawStringMonospaced(int x, int y, const unsigned char *string, int charWidth, int charHeight, int maxRows, int maxChars, residx_t fontshader) { const char *s; int xx; int cnt; int rows = 0; s = (const char*)string; xx = x; cnt = 0; Vid_UseShader(fontshader); while ( *s && cnt < maxChars && rows < maxRows) { switch (*s) { case '\n': rows++; xx = x; //NOTE: we might want to change this +1 to a param y += charHeight + 1; cnt = 0; break; case '^': //we could be drawing an icon if (memcmp(s, "^icon ", 6)==0 && strlen(s) > 7 && strchr(&s[7], '^')) { char icon[1024]; int i=0; const char *start = s; s+=6; while (*s != 0 && *s != '\n' && *s != ' ' && *s != '^' && i < 1023) { icon[i] = *s; s++; i++; } //try to show this if (i > 0 && *s == '^') { icon[i] = 0; Vid_UnuseShader(); Draw_Quad2d(xx, y, charWidth, charHeight, 0, 0, 1, 1, Res_LoadShaderEx(fmt("/textures/econs/%s.s2g", icon), SHD_NO_SHADER)); Vid_UseShader(fontshader); xx += charWidth; s++; continue; } else { s = (char *)start; } } //we could be drawing an icon else if (memcmp(s, "^clan ", 6)==0 && strlen(s) > 7 && strchr(&s[7], '^')) { char icon[1024]; int i=0; const char *start = s; s+=6; while (*s != 0 && *s != '\n' && *s != ' ' && *s != '^' && i < 1023) { icon[i] = *s; s++; i++; } //try to show this if (i > 0 && *s == '^') { icon[i] = 0; Vid_UnuseShader(); Draw_Quad2d(xx, y, MIN(charWidth, charHeight), MIN(charWidth, charHeight), 0, 0, 1, 1, File_GetClanIcon(atoi(icon))); Vid_UseShader(fontshader); xx += charWidth; //+ SPACE_AFTER_ICON; // UTTAR: Would screw the width calculations here s++; continue; } else { s = (char *)start; } } //check for a color change else { bool valid = true; int colorCodeLen = 1; vec4_t tmpcolor = {1.0, 1.0, 1.0, 1.0}; tmpcolor[3] = Draw_GetCurrentAlpha(); s += 1; switch (*s) { case 'r': //let's use a brighter red to be more easily readable tmpcolor[1] = 0.3; tmpcolor[2] = 0.3; break; case 'g': tmpcolor[0] = 0.0; tmpcolor[2] = 0.0; break; case 'b': //let's use a brighter blue to be more easily readable tmpcolor[0] = 0.3; tmpcolor[1] = 0.3; break; case 'w': break; case 'k': tmpcolor[0] = 0.0; tmpcolor[1] = 0.0; tmpcolor[2] = 0.0; break; case 'y': tmpcolor[2] = 0.1; break; case 'c': tmpcolor[0] = 0.0; break; case 'm': tmpcolor[1] = 0.0; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (strlen(s) < 3) { s -= 1; valid = false; break; } if (s[1] >= '0' && s[1] <= '9' && s[2] >= '0' && s[2] <= '9') { tmpcolor[0] = ((s[0] - '0') / 9.0); tmpcolor[1] = ((s[1] - '0') / 9.0); tmpcolor[2] = ((s[2] - '0') / 9.0); colorCodeLen = 3; } else { s -= 1; valid = false; break; } break; default: s -= 1; valid = false; break; } if (valid) { s += colorCodeLen; Draw_SetColor(tmpcolor); continue; } } /* intentional fall-through */ default: DU_DrawCharMonospaced(xx, y, charWidth, charHeight, *s, (residx_t)-2/*fontshader*/); xx += charWidth; cnt++; } s++; } Vid_UnuseShader(); }
///////////////////////////// // Draw_Init // // Initializes the game window. int Draw_Init(int width, int height, char *title, int pfps, int fps) { // Set globals proc_t_frame = 1000000 / pfps; draw_t_frame = 1000000 / fps; _fps = fps; _width = width; _height = height; // Initialize SDL if (SDL_Init(SDL_INIT_VIDEO) < 0) { Print("Draw_Init: Failure initializing SDL.\n"); Print("\tSDL Error: %s\n", SDL_GetError()); return (0); } // Initialize video mode _screen = SDL_SetVideoMode(width, height, 32, SDL_HWSURFACE | SDL_OPENGL); if (_screen == NULL) { Print("Draw_Init: Failure initializing video mode.\n"); Print("\tSDL Error: %s\n", SDL_GetError()); return (0); } SDL_WM_SetCaption(title, NULL); Draw_ShowInfo(); #if USE_OpenGL // Set the desired state glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); glDisable(GL_CULL_FACE); glEnable(GL_TEXTURE_2D); glDisable(GL_LIGHTING); glDisable(GL_DEPTH_TEST); glDepthMask(GL_FALSE); // Triplebuffer swap glClear(GL_COLOR_BUFFER_BIT); SDL_GL_SwapBuffers(); glClear(GL_COLOR_BUFFER_BIT); SDL_GL_SwapBuffers(); glClear(GL_COLOR_BUFFER_BIT); SDL_GL_SwapBuffers(); glClear(GL_COLOR_BUFFER_BIT); glEnableClientState(GL_COLOR_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glEnableClientState(GL_VERTEX_ARRAY); #endif #if USE_OpenGLES const char vertexShaderSource[] = "attribute vec4 aPosition; \n" "attribute vec2 aTexCoord; \n" "attribute vec4 aColor; \n" "varying vec2 vTexCoord; \n" "varying vec4 vColor; \n" "uniform mat4 sProjectionMatrix; \n" "void main() { \n" " gl_Position = aPosition * \n" " sProjectionMatrix; \n" " vTexCoord = aTexCoord; \n" " vColor = aColor; \n" "} \n"; const char fragmentShaderSource[] = "precision mediump float; \n" "varying vec2 vTexCoord; \n" "varying vec4 vColor; \n" "uniform sampler2D sTexture; \n" "void main() { \n" " gl_FragColor = texture2D(sTexture, vTexCoord)*vColor; \n" "} \n"; programObject = Draw_BuildProgram(vertexShaderSource, fragmentShaderSource); glUseProgram(programObject); vertPosLoc = glGetAttribLocation(programObject, "aPosition"); vertTexLoc = glGetAttribLocation(programObject, "aTexCoord"); vertColorLoc = glGetAttribLocation(programObject, "aColor"); textureLoc = glGetUniformLocation(programObject, "sTexture"); projectionMatrixLoc = glGetUniformLocation(programObject, "sProjectionMatrix"); glUniform1i(textureLoc, 0); glGenBuffers(1, &vertexObject); glBindBuffer(GL_ARRAY_BUFFER, vertexObject); glBufferData(GL_ARRAY_BUFFER, Vertex2D_Length * sizeof(float) * Max_Vertices, NULL, GL_DYNAMIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, vertexObject); glVertexAttribPointer(vertPosLoc, 2, GL_FLOAT, GL_FALSE, Vertex2D_Length * sizeof(float), (void *)(0 * sizeof(float))); glVertexAttribPointer(vertTexLoc, 2, GL_FLOAT, GL_FALSE, Vertex2D_Length * sizeof(float), (void *)(2 * sizeof(float))); glVertexAttribPointer(vertColorLoc, 4, GL_FLOAT, GL_FALSE, Vertex2D_Length * sizeof(float), (void *)(4 * sizeof(float))); glEnableVertexAttribArray(vertPosLoc); glEnableVertexAttribArray(vertTexLoc); glEnableVertexAttribArray(vertColorLoc); unsigned char whiteTexData[4] = {255, 255, 255, 255}; _whiteTex = Draw_UploadGLTexture(1, 1, whiteTexData); #endif // Set the proyection (2D) glViewport(0, 0, _width, _height); float projectionMatrix[16] = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}; projectionMatrix[0] = (2.0f / _width); projectionMatrix[5] = -(2.0f / _height); projectionMatrix[10] = -0.001f; projectionMatrix[3] = -1.0f; projectionMatrix[7] = 1.0f; Draw_SetMatrix(projectionMatrix); // Enable Alpha blending glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // Initialize the triangle array _quadArray = QuadArray2D_Create(400); Draw_SetColor(1.0f, 1.0f, 1.0f, 1.0f); return (1); }