// converts a character into which entry in font.bmp to use, negative on error or no output int find_font_char(unsigned char cur_char) { if(cur_char >= 127 && cur_char<=127+c_grey4) { float r,g,b; //must be a color cur_char-=127; r=(float)colors_list[cur_char].r1/255.0f; g=(float)colors_list[cur_char].g1/255.0f; b=(float)colors_list[cur_char].b1/255.0f; glColor3f(r,g,b); return(-1); // nothing to do } return(get_font_char(cur_char)); }
// converts a character into which entry in font.bmp to use, negative on error or no output int find_font_char (unsigned char cur_char) { if (is_color (cur_char)) { float r,g,b; //must be a color int color = from_color_char (cur_char); r = (float) colors_list[color].r1 / 255.0f; g = (float) colors_list[color].g1 / 255.0f; b = (float) colors_list[color].b1 / 255.0f; //This fixes missing letters in the font on some clients //No idea why going from 3f to 4f helps, but it does glColor4f(r,g,b,1.0); return(-1); // nothing to do } return(get_font_char(cur_char)); }
int get_char_width(unsigned char cur_char) { return get_font_width(get_font_char(cur_char)); }
void draw_ortho_ingame_string(float x, float y,float z, const unsigned char * our_string, int max_lines, float font_x_scale, float font_y_scale) { float u_start,u_end,v_start,v_end; int col,row; float displayed_font_x_size; float displayed_font_y_size; float displayed_font_x_width; #ifndef SKY_FPV_OPTIONAL int font_x_size=FONT_X_SPACING; int font_y_size=FONT_Y_SPACING; #endif // not SKY_FPV_OPTIONAL int font_bit_width, ignored_bits; unsigned char cur_char; int chr; int i; float cur_x,cur_y; int current_lines=0; #ifndef SKY_FPV_OPTIONAL /* if(big) { displayed_font_x_size=0.17*zoom_level*name_zoom/3.0; displayed_font_y_size=0.25*zoom_level*name_zoom/3.0; } else { displayed_font_x_size=SMALL_INGAME_FONT_X_LEN*zoom_level*name_zoom/3.0; displayed_font_y_size=SMALL_INGAME_FONT_Y_LEN*zoom_level*name_zoom/3.0; } */ #endif // not SKY_FPV_OPTIONAL displayed_font_x_size=font_x_scale*name_zoom*12.0; displayed_font_y_size=font_y_scale*name_zoom*12.0; glEnable(GL_ALPHA_TEST);//enable alpha filtering, so we have some alpha key glAlphaFunc(GL_GREATER,0.1f); #ifdef NEW_TEXTURES bind_texture(font_text); #else /* NEW_TEXTURES */ get_and_set_texture_id(font_text); #endif /* NEW_TEXTURES */ i=0; cur_x=x; cur_y=y; glBegin(GL_QUADS); #ifndef SKY_FPV_OPTIONAL while(1) { cur_char=our_string[i]; if(!cur_char) { break; } else if(cur_char=='\n') { cur_y+=displayed_font_y_size; cur_x=x; i++; current_lines++; if(current_lines>=max_lines)break; continue; } else if (is_color (cur_char)) { glEnd(); //Ooops - NV bug fix!! } chr=find_font_char(cur_char); if(chr >= 0) { col=chr/FONT_CHARS_PER_LINE; row=chr%FONT_CHARS_PER_LINE; font_bit_width=get_font_width(chr); displayed_font_x_width=((float)font_bit_width)*displayed_font_x_size/12.0; ignored_bits=(12-font_bit_width)/2; // how many bits on each side of the char are ignored? if(ignored_bits < 0)ignored_bits=0; //now get the texture coordinates u_start=(float)(row*font_x_size+ignored_bits)/256.0f; u_end=(float)(row*font_x_size+font_x_size-7-ignored_bits)/256.0f; #ifdef NEW_TEXTURES v_start=(float)(1+col*font_y_size)/256.0f; v_end=(float)(col*font_y_size+font_y_size-1)/256.0f; #else v_start=(float)1.0f-(1+col*font_y_size)/256.0f; v_end=(float)1.0f-(col*font_y_size+font_y_size-1)/256.0f; #endif //NEW_TEXTURES //v_end=(float)1.0f-(col*font_y_size+font_y_size-2)/256.0f; glTexCoord2f(u_start,v_start); glVertex3f(cur_x,cur_y+displayed_font_y_size,z); glTexCoord2f(u_start,v_end); glVertex3f(cur_x,cur_y,z); glTexCoord2f(u_end,v_end); glVertex3f(cur_x+displayed_font_x_width,cur_y,z); glTexCoord2f(u_end,v_start); glVertex3f(cur_x+displayed_font_x_width,cur_y+displayed_font_y_size,z); //cur_x+=displayed_font_x_size; cur_x+=displayed_font_x_width; } else if (is_color (cur_char)) { glBegin(GL_QUADS); //Ooops - NV bug fix!! } #else // SKY_FPV_OPTIONAL while(1){ cur_char=our_string[i]; if(!cur_char){ break; } else if(cur_char=='\n'){ cur_y+=displayed_font_y_size; cur_x=x; #endif // SKY_FPV_OPTIONAL i++; #ifdef SKY_FPV_OPTIONAL current_lines++; if(current_lines>=max_lines)break; continue; } else if (is_color (cur_char)){ glEnd(); //Ooops - NV bug fix!! glBegin(GL_QUADS); } chr=find_font_char(cur_char); if(chr >= 0){ col=chr/FONT_CHARS_PER_LINE; row=chr%FONT_CHARS_PER_LINE; font_bit_width=get_font_width(chr); displayed_font_x_width=((float)font_bit_width)*displayed_font_x_size/12.0; ignored_bits=(12-font_bit_width)/2; // how many bits on each side of the char are ignored? if(ignored_bits < 0)ignored_bits=0; //now get the texture coordinates u_start=(float)(row*FONT_X_SPACING+ignored_bits)/256.0f; u_end=(float)(row*FONT_X_SPACING+FONT_X_SPACING-7-ignored_bits)/256.0f; #ifdef NEW_TEXTURES v_start=(float)(1+col*FONT_Y_SPACING)/256.0f; v_end=(float)(col*FONT_Y_SPACING+FONT_Y_SPACING-1)/256.0f; #else v_start=(float)1.0f-(1+col*FONT_Y_SPACING)/256.0f; v_end=(float)1.0f-(col*FONT_Y_SPACING+FONT_Y_SPACING-1)/256.0f; #endif //NEW_TEXTURES glTexCoord2f(u_start,v_start); glVertex3f(cur_x,cur_y+displayed_font_y_size,z); glTexCoord2f(u_start,v_end); glVertex3f(cur_x,cur_y,z); glTexCoord2f(u_end,v_end); glVertex3f(cur_x+displayed_font_x_width,cur_y,z); glTexCoord2f(u_end,v_start); glVertex3f(cur_x+displayed_font_x_width,cur_y+displayed_font_y_size,z); cur_x+=displayed_font_x_width; } else if(is_color (cur_char)){ glEnd(); //Ooops - NV bug fix!! glBegin(GL_QUADS); #endif // SKY_FPV_OPTIONAL } #ifdef SKY_FPV_OPTIONAL i++; } #endif // SKY_FPV_OPTIONAL glEnd(); glDisable(GL_ALPHA_TEST); } void draw_ingame_string(float x, float y,const unsigned char * our_string, int max_lines, float font_x_scale, float font_y_scale) { float u_start,u_end,v_start,v_end; int col,row; float displayed_font_x_size; float displayed_font_y_size; float displayed_font_x_width; #ifndef SKY_FPV_OPTIONAL //int font_x_size=FONT_X_SPACING; //int font_y_size=FONT_Y_SPACING; #endif // not SKY_FPV_OPTIONAL int font_bit_width, ignored_bits; unsigned char cur_char; int chr; int i; float cur_x,cur_y; int current_lines=0; #ifdef SKY_FPV_OPTIONAL double model[16], proj[16],hx,hy,hz; int view[4]; displayed_font_x_size=font_x_scale*name_zoom*12.0*font_scale; displayed_font_y_size=font_y_scale*name_zoom*12.0*font_scale; glGetDoublev(GL_MODELVIEW_MATRIX, model); glGetDoublev(GL_PROJECTION_MATRIX, proj); glGetIntegerv(GL_VIEWPORT, view); gluProject((double)x,0.0f,(double)y,model, proj, view, &hx,&hy,&hz); glPushMatrix(); glLoadIdentity(); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); glOrtho(view[0],view[2]+view[0],view[1],view[3]+view[1],0.0f,-1.0f); #endif // SKY_FPV_OPTIONAL #ifndef SKY_FPV_OPTIONAL displayed_font_x_size=font_x_scale*zoom_level*name_zoom/3.0; displayed_font_y_size=font_y_scale*zoom_level*name_zoom/3.0; #endif // not SKY_FPV_OPTIONAL glEnable(GL_ALPHA_TEST);//enable alpha filtering, so we have some alpha key glAlphaFunc(GL_GREATER,0.1f); #ifdef NEW_TEXTURES bind_texture(font_text); #else /* NEW_TEXTURES */ get_and_set_texture_id(font_text); #endif /* NEW_TEXTURES */ i=0; #ifndef SKY_FPV_OPTIONAL cur_x=x; cur_y=y; #else // SKY_FPV_OPTIONAL cur_x=hx; cur_y=hy; #endif // SKY_FPV_OPTIONAL glBegin(GL_QUADS); #ifndef SKY_FPV_OPTIONAL while(1) { cur_char=our_string[i]; if(!cur_char) { break; } else if(cur_char=='\n') { cur_y+=displayed_font_y_size; cur_x=x; i++; current_lines++; if(current_lines>=max_lines)break; continue; } else if(is_color (cur_char)) { glEnd(); //Ooops - NV bug fix!! } chr=find_font_char(cur_char); if(chr >= 0) { col=chr/FONT_CHARS_PER_LINE; row=chr%FONT_CHARS_PER_LINE; font_bit_width=get_font_width(chr); displayed_font_x_width=((float)font_bit_width)*displayed_font_x_size/12.0; ignored_bits=(12-font_bit_width)/2; // how many bits on each side of the char are ignored? if(ignored_bits < 0)ignored_bits=0; //now get the texture coordinates u_start=(float)(row*FONT_X_SPACING+ignored_bits)/256.0f; u_end=(float)(row*FONT_X_SPACING+FONT_X_SPACING-7-ignored_bits)/256.0f; #ifdef NEW_TEXTURES v_start=(float)(1+col*FONT_Y_SPACING)/256.0f; v_end=(float)(col*FONT_Y_SPACING+FONT_Y_SPACING-1)/256.0f; #else v_start=(float)1.0f-(1+col*FONT_Y_SPACING)/256.0f; v_end=(float)1.0f-(col*FONT_Y_SPACING+FONT_Y_SPACING-1)/256.0f; #endif //NEW_TEXTURES glTexCoord2f(u_start,v_start); glVertex3f(cur_x,0,cur_y+displayed_font_y_size); glTexCoord2f(u_start,v_end); glVertex3f(cur_x,0,cur_y); glTexCoord2f(u_end,v_end); glVertex3f(cur_x+displayed_font_x_width,0,cur_y); glTexCoord2f(u_end,v_start); glVertex3f(cur_x+displayed_font_x_width,0,cur_y+displayed_font_y_size); cur_x+=displayed_font_x_width; } else if (is_color (cur_char)) { glBegin(GL_QUADS); //Ooops - NV bug fix!! } #else // SKY_FPV_OPTIONAL while(1){ cur_char=our_string[i]; if(!cur_char){ break; }else if(cur_char=='\n'){ cur_y+=displayed_font_y_size; cur_x=hx; #endif // SKY_FPV_OPTIONAL i++; #ifdef SKY_FPV_OPTIONAL current_lines++; if(current_lines>=max_lines)break; continue; } else if (is_color (cur_char)) { glEnd(); //Ooops - NV bug fix!! glBegin(GL_QUADS); } chr=find_font_char(cur_char); if(chr >= 0){ col=chr/FONT_CHARS_PER_LINE; row=chr%FONT_CHARS_PER_LINE; font_bit_width=get_font_width(chr); displayed_font_x_width=((float)font_bit_width)*displayed_font_x_size/12.0; ignored_bits=(12-font_bit_width)/2; // how many bits on each side of the char are ignored? if(ignored_bits < 0)ignored_bits=0; //now get the texture coordinates u_start=(float)(row*FONT_X_SPACING+ignored_bits)/256.0f; u_end=(float)(row*FONT_X_SPACING+FONT_X_SPACING-7-ignored_bits)/256.0f; #ifdef NEW_TEXTURES v_start=(float)(1+col*FONT_Y_SPACING)/256.0f; v_end=(float)(col*FONT_Y_SPACING+FONT_Y_SPACING-1)/256.0f; #else v_start=(float)1.0f-(1+col*FONT_Y_SPACING)/256.0f; v_end=(float)1.0f-(col*FONT_Y_SPACING+FONT_Y_SPACING-1)/256.0f; #endif // NEW_TEXTURES glTexCoord2f(u_start,v_start); glVertex3f(cur_x,cur_y+displayed_font_y_size,0); glTexCoord2f(u_start,v_end); glVertex3f(cur_x,cur_y,0); glTexCoord2f(u_end,v_end); glVertex3f(cur_x+displayed_font_x_width,cur_y,0); glTexCoord2f(u_end,v_start); glVertex3f(cur_x+displayed_font_x_width,cur_y+displayed_font_y_size,0); cur_x+=displayed_font_x_width; } else if (is_color (cur_char)) { glEnd(); //Ooops - NV bug fix!! glBegin(GL_QUADS); #endif // SKY_FPV_OPTIONAL } #ifdef SKY_FPV_OPTIONAL i++; } #endif // SKY_FPV_OPTIONAL glEnd(); glDisable(GL_ALPHA_TEST); #ifdef SKY_FPV_OPTIONAL glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); #endif // SKY_FPV_OPTIONAL } #endif //!MAP_EDITOR_2 #endif //ELC // font handling int get_font_width(int cur_char) { // ignore unknown characters if (cur_char < 0) { return 0; } // return width of character + spacing between chars (supports variable width fonts) return (fonts[cur_font_num]->widths[cur_char] + fonts[cur_font_num]->spacing); } int get_char_width(unsigned char cur_char) { return get_font_width(get_font_char(cur_char)); } int get_string_width(const unsigned char *str) { return get_nstring_width(str, strlen((char*)str)); } int get_nstring_width(const unsigned char *str, int len) { int i, wdt=0; for(i=0; i<len; i++) { wdt+= get_char_width(str[i]); } // adjust to ignore the final spacing wdt-= fonts[cur_font_num]->spacing; return wdt; }