#include #include #ifdef FONTS_FIX #ifdef _MSC_VER #include #else //!_MSC_VER #include #include #endif //_MSC_VER #endif //FONTS_FIX #ifdef MAP_EDITOR2 #include "../map_editor2/global.h" #else #include "global.h" #endif /* NOTE: This file contains implementations of the following, currently unused, and commented functions: * Look at the end of the file. * * void remove_font(int); */ #define FONT_START_CHAR 32 #define FONT_CHARS_PER_LINE 14 #define FONT_X_SPACING 18 #define FONT_Y_SPACING 21 #define FONTS_ARRAY_SIZE 10 typedef struct { int spacing; int texture_id; int widths[10*FONT_CHARS_PER_LINE]; char name[32]; } font_info; int cur_font_num=0; int max_fonts=0; font_info *fonts[FONTS_ARRAY_SIZE]; #ifdef FONTS_FIX char font_names[FONTS_ARRAY_SIZE][30]; #endif //FONTS_FIX int chat_font=0; int name_font=0; int book_font=0; int get_font_width(int cur_char); int get_nstring_width(const unsigned char *str, int len); int set_font_parameters (int num); int get_font_char(unsigned char cur_char) { if(cur_char=127) { if(cur_char<=127+c_ubound) { //color, won't show return -1; } else if(cur_char>127+c_ubound) { switch(cur_char) { case 193: cur_char=AACCENT;break; case 196: cur_char=AUMLAUT;break; case 197: cur_char=ARING;break; case 198: cur_char=AELIG;break; case 201: cur_char=EACCENT;break; case 205: cur_char=IACCENT;break; case 209: cur_char=ENYE;break; case 211: cur_char=OACCENT;break; case 214: cur_char=OUMLAUT;break; case 216: cur_char=OSLASH;break; case 218: cur_char=UACCENT;break; case 220: cur_char=UUMLAUT;break; case 223: cur_char=DOUBLES;break; case 224: cur_char=AGRAVE;break; case 225: cur_char=aACCENT;break; case 226: cur_char=ACIRC;break; case 228: cur_char=aUMLAUT;break; case 229: cur_char=aRING;break; case 230: cur_char=aELIG;break; case 231: cur_char=CCEDIL;break; case 232: cur_char=EGRAVE;break; case 233: cur_char=EACUTE;break; case 234: cur_char=ECIRC;break; case 235: cur_char=EUML;break; case 237: cur_char=iACCENT;break; case 239: cur_char=IUML;break; case 241: cur_char=EnyE;break; case 243: cur_char=oACCENT;break; case 244: cur_char=OCIRC;break; case 246: cur_char=oUMLAUT;break; case 248: cur_char=oSLASH;break; case 249: cur_char=uGRAVE;break; case 250: cur_char=uACCENT;break; case 252: cur_char=uUMLAUT;break; default: return -1; //ignore it } if(cur_char>=SPECIALCHAR_LBOUND && cur_char<=SPECIALCHAR_UBOUND) { cur_char-=(SPECIALCHAR_LBOUND-127); } } } // finally, adjust for the missing lead characters cur_char-=FONT_START_CHAR; return((int)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(cur_char >= 127+c_lbound && cur_char<=127+c_ubound) { float r,g,b; //must be a color cur_char -= 127+c_lbound; 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; //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)); } // returns how far to move for the next char, or negative on error int draw_char_scaled(unsigned char cur_char, int cur_x, int cur_y, float displayed_font_x_size, float displayed_font_y_size) { float u_start,u_end,v_start,v_end; int chr,col,row; int displayed_font_x_width; int font_bit_width, ignored_bits; chr= find_font_char(cur_char); if(chr < 0) // watch for illegal/non-display characters { return 0; } // first, see where that char is, in the font.bmp col= chr/FONT_CHARS_PER_LINE; row= chr%FONT_CHARS_PER_LINE; //displayed_font_x_width=(int)displayed_font_x_size; font_bit_width= get_font_width(chr); displayed_font_x_width= (int)(0.5f+((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? //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; 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; // and place the text from the graphics on the map glTexCoord2f(u_start,v_start); glVertex3i(cur_x,cur_y,0); glTexCoord2f(u_start,v_end); glVertex3i(cur_x,cur_y+(displayed_font_y_size+1),0); glTexCoord2f(u_end,v_end); glVertex3i(cur_x+displayed_font_x_width,cur_y+(displayed_font_y_size+1),0); glTexCoord2f(u_end,v_start); glVertex3i(cur_x+displayed_font_x_width,cur_y,0); return(displayed_font_x_width); // return how far to move for the next character } #ifndef MAP_EDITOR2 void recolour_message(text_message *msg){ if (msg->chan_idx >= CHAT_CHANNEL1 && msg->chan_idx <= CHAT_CHANNEL3 && msg->len > 0 && msg->data[0] && !msg->deleted){ if (active_channels[current_channel] != msg->channel){ msg->data[0] = (Uint8)(127+c_grey2); } else { msg->data[0] = (Uint8)(127+c_grey1); } } } #endif void recolour_messages(text_message *msgs){ int i; for(i=0;i= msgs_size) imsg = 0; if (msgs[imsg].data == NULL || imsg == msg_start || msgs[imsg].deleted) // nothing to draw return; } else { break; } } if (msgs[imsg].data == NULL || msgs[imsg].deleted) return; } #endif //! MAP_EDITOR2 if (ichar > 0) { ch = msgs[imsg].data[ichar]; if (!IS_COLOR (ch)) { // search backwards for the last color for (i = ichar-1; i >= 0; i--) { ch = msgs[imsg].data[i]; if (IS_COLOR (ch)) { float r, g, b; ch -= 127+c_lbound; r = colors_list[ch].r1 / 255.0f; g = colors_list[ch].g1 / 255.0f; b = colors_list[ch].b1 / 255.0f; glColor3f (r, g, b); break; } } } } glEnable (GL_ALPHA_TEST); // enable alpha filtering, so we have some alpha key glAlphaFunc (GL_GREATER, 0.1f); get_and_set_texture_id (font_text); i = 0; cur_x = x; cur_y = y; glBegin (GL_QUADS); while (1) { if (i == cursor) { cursor_x = cur_x; cursor_y = cur_y; if (cursor_x - x > width - displayed_font_x_size) { cursor_x = x; cursor_y = cur_y + displayed_font_y_size; } } cur_char = msgs[imsg].data[ichar]; // watch for special characters if (cur_char == '\0') { // end of message if (++imsg >= msgs_size) { imsg = 0; } #ifndef MAP_EDITOR2 if (filter != FILTER_ALL) { // skip all messages of the wrong channel while (1) { char skip = 0; int channel = msgs[imsg].chan_idx; if (channel != filter) { switch (channel) { case CHAT_LOCAL: skip = local_chat_separate; break; case CHAT_PERSONAL: skip = personal_chat_separate; break; case CHAT_GM: skip = guild_chat_separate; break; case CHAT_SERVER: skip = server_chat_separate; break; case CHAT_MOD: skip = mod_chat_separate; break; case CHAT_MODPM: skip = 0; break; default: skip = 1; } } switch (channel) { case CHAT_CHANNEL1: case CHAT_CHANNEL2: case CHAT_CHANNEL3: skip = (msgs[imsg].channel != active_channels[filter - CHAT_CHANNEL1]); } if (skip) { if (++imsg >= msgs_size) imsg = 0; if (msgs[imsg].data == NULL || imsg == msg_start) break; } else { break; } } } #endif if (msgs[imsg].data == NULL || imsg == msg_start || msgs[imsg].deleted) break; rewrap_message(&msgs[imsg], text_zoom, width, NULL); ichar = 0; } if (cur_char == '\n' || cur_char == '\r' || cur_char == '\0') { // newline cur_y += displayed_font_y_size; if (cur_y - y > height - displayed_font_y_size) break; cur_x = x; if (cur_char != '\0') ichar++; i++; continue; } cur_x += draw_char_scaled (cur_char, cur_x, cur_y, displayed_font_x_size, displayed_font_y_size); ichar++; i++; if (cur_x - x > width - displayed_font_x_size) { // ignore rest of this line while (msgs[imsg].data[ichar] != '\0' && msgs[imsg].data[ichar] != '\n' && msgs[imsg].data[ichar] != '\r') { ichar++; i++; } } } if (cursor_x >= x && cursor_y >= y && cursor_y - y <= height - displayed_font_y_size) { draw_char_scaled ('_', cursor_x, cursor_y, displayed_font_x_size, displayed_font_y_size); } glEnd(); glDisable(GL_ALPHA_TEST); #ifdef OPENGL_TRACE CHECK_GL_ERRORS(); #endif //OPENGL_TRACE } int draw_string (int x, int y, const unsigned char * our_string, int max_lines) { return draw_string_zoomed_width (x, y, our_string, window_width, max_lines, 1.0f); } int draw_string_width(int x, int y, const unsigned char * our_string, int max_width, int max_lines) { return draw_string_zoomed_width (x, y, our_string, max_width, max_lines, 1.0f); } int draw_string_zoomed (int x, int y, const unsigned char * our_string, int max_lines, float text_zoom) { return draw_string_zoomed_width (x, y, our_string, window_width, max_lines, text_zoom); } int draw_string_zoomed_width (int x, int y, const unsigned char * our_string, int max_width, int max_lines, float text_zoom) { float displayed_font_x_size= 11.0*text_zoom; float displayed_font_y_size= 18.0*text_zoom; unsigned char cur_char; int i; int cur_x,cur_y; int current_lines= 1; #ifdef OPENGL_TRACE CHECK_GL_ERRORS(); #endif //OPENGL_TRACE glEnable(GL_ALPHA_TEST);//enable alpha filtering, so we have some alpha key glAlphaFunc(GL_GREATER,0.1f); get_and_set_texture_id(font_text); i=0; cur_x=x; cur_y=y; glBegin(GL_QUADS); while(1) { cur_char=our_string[i]; // watch for special characters if(!cur_char) // end of line { break; } else if (cur_char == '\n' || cur_char == '\r') // newline { cur_y+=displayed_font_y_size; cur_x=x; i++; current_lines++; if(current_lines>max_lines)break; continue; } else if (cur_x+displayed_font_x_size-x>=max_width){ cur_y+=displayed_font_y_size; cur_x=x; current_lines++; if(current_lines>max_lines)break; } cur_x+=draw_char_scaled(cur_char, cur_x, cur_y, displayed_font_x_size, displayed_font_y_size); i++; } glEnd(); glDisable(GL_ALPHA_TEST); #ifdef OPENGL_TRACE CHECK_GL_ERRORS(); #endif //OPENGL_TRACE return current_lines; } void draw_string_clipped(int x, int y, const unsigned char * our_string, int width, int height) { draw_string_zoomed_clipped (x, y, our_string, -1, width, height, 1.0f); } void draw_string_zoomed_clipped (int x, int y, const unsigned char* our_string, int cursor_pos, int width, int height, float text_zoom) { float displayed_font_x_size = DEFAULT_FONT_X_LEN * text_zoom; float displayed_font_y_size = DEFAULT_FONT_Y_LEN * text_zoom; unsigned char cur_char; int i; int cur_x, cur_y; int cursor_x = x-1, cursor_y = y-1; if (width < displayed_font_x_size || height < displayed_font_y_size) // no point in trying return; glEnable (GL_ALPHA_TEST); // enable alpha filtering, so we have some alpha key glAlphaFunc (GL_GREATER, 0.1f); get_and_set_texture_id (font_text); i = 0; cur_x = x; cur_y = y; glBegin (GL_QUADS); while (1) { if (i == cursor_pos) { cursor_x = cur_x; cursor_y = cur_y; if (cursor_x - x > width - displayed_font_x_size) { cursor_x = x; cursor_y = cur_y + displayed_font_y_size; } } cur_char = our_string[i]; // watch for special characters if (!cur_char) { // end of string break; } else if (cur_char == '\n' || cur_char == '\r') { // newline cur_y += displayed_font_y_size; if (cur_y - y > height - displayed_font_y_size) break; cur_x = x; i++; continue; } // cur_x += draw_font_char_scaled (0, cur_char, cur_x, cur_y, text_zoom); cur_x += draw_char_scaled (cur_char, cur_x, cur_y, displayed_font_x_size, displayed_font_y_size); i++; if (cur_x - x > width - displayed_font_x_size) { // ignore rest of this line while (our_string[i] != '\0' && our_string[i] != '\n' && our_string[i] != '\r') i++; } } if (cursor_x >= x && cursor_y >= y && cursor_y - y <= height - displayed_font_y_size) { draw_char_scaled ('_', cursor_x, cursor_y, displayed_font_x_size, displayed_font_y_size); } glEnd(); glDisable(GL_ALPHA_TEST); #ifdef OPENGL_TRACE CHECK_GL_ERRORS(); #endif //OPENGL_TRACE } #ifdef DEBUG void print_string_escaped (const char *str) { int i; for (i=0; str[i]; i++) if (str[i]=='\r') printf ("\\r"); else if (str[i] == '\n') printf ("\\n\n"); else if ((unsigned char)str[i] < 127+c_red1 || (unsigned char)str[i] > 127+c_ubound) printf ("%c", str[i]); printf ("\nlen = %d\n", i); } #endif int reset_soft_breaks (char *str, int len, int size, float zoom, int width, int *cursor, float *max_line_width) { char *buf; unsigned int ibuf; unsigned int nchar; int font_bit_width; int nlines; float line_width; int isrc, idst; int lastline; int dcursor = 0; /* the generic special text window code needs to know the maximum line length in pixels. This information is used but was previously throw away in this function. Others may fine it useful for setting the winow size, so pass back to the caller if they provide somewhere to store it. */ float local_max_line_width = 0; if (str == NULL) { return 0; } /* allocate the working buffer so it can hold the maximum the source string can take. Previously, the fixed length buffer was sometimes not big enough. The code looked to attempt to cope but was floored. When ever the wrap caused more characters to be in the output, some of the source would be lost. This is still possable if the source size cannot take the extra characters. For example, try #glinfo and watch as the end characters are lost. At least characters are no longer lost wrap process. If you make size large enough for no character will be lost. Twice the actual string length is probably enough */ buf = (char *)calloc(size, sizeof(char)); nlines = 1; isrc = ibuf = idst = 0; line_width = 0; lastline = 0; // fill the buffer while (isrc < len && str[isrc] != '\0') { // skip old line breaks if (str[isrc] == '\r') { if (cursor && isrc < *cursor) { dcursor--; } isrc++; continue; } // see if it's an explicit line break if (str[isrc] == '\n') { nlines++; if (line_width > local_max_line_width) local_max_line_width = line_width; line_width = 0; } else { font_bit_width = (int) (0.5f + get_char_width (str[isrc]) * 11.0f * zoom / 12.0f); if (line_width + font_bit_width > width) { // search back for a space for (nchar = 0; ibuf-nchar-1 > lastline; nchar++) { if (buf[ibuf-nchar-1] == ' ') { break; } } if (ibuf-nchar-1 <= lastline) // no space found, introduce a break in // the middle of the word nchar = 0; // introduce the break, and reset the counters ibuf -= nchar; /* previously, we just stepped back by nchar. however, if this text contained an \r we would not move back far enough and so loose characters. any \r in the src will be stepped over at the top of the loop */ while (nchar > 0) { isrc--; if (str[isrc] != '\r') nchar--; } buf[ibuf] = '\r'; nlines++; ibuf++; if (cursor && isrc < *cursor) { dcursor++; } if (ibuf >= size - 1) { break; } if (line_width > local_max_line_width) local_max_line_width = line_width; lastline = ibuf; line_width = font_bit_width; } else { line_width += font_bit_width; } } // copy the character into the buffer buf[ibuf] = str[isrc]; isrc++; ibuf++; if (ibuf >= size - 1) { break; } } safe_strncpy(str, buf, size * sizeof(char)); str[size-1] = '\0'; if (cursor) { *cursor += dcursor; if(*cursor > size-1) { /* If there's a better way to detect this, please do */ *cursor = size-1; } } free(buf); if (line_width > local_max_line_width) local_max_line_width = line_width; if (max_line_width!=NULL) *max_line_width = local_max_line_width; return nlines; } void draw_string_small(int x, int y,const unsigned char * our_string,int max_lines) { //int displayed_font_x_size=SMALL_FONT_X_LEN; //int displayed_font_y_size=SMALL_FONT_Y_LEN; unsigned char cur_char; int i; int cur_x,cur_y; int current_lines=0; #ifdef OPENGL_TRACE CHECK_GL_ERRORS(); #endif //OPENGL_TRACE glEnable(GL_ALPHA_TEST);//enable alpha filtering, so we have some alpha key glAlphaFunc(GL_GREATER,0.1f); get_and_set_texture_id(font_text); i=0; cur_x=x; cur_y=y; glBegin(GL_QUADS); while(1) { cur_char=our_string[i]; if(!cur_char) { break; } else if(cur_char=='\n') { cur_y+=SMALL_FONT_Y_LEN; cur_x=x; i++; current_lines++; if(current_lines>=max_lines)break; continue; } cur_x+=draw_char_scaled(cur_char, cur_x, cur_y, SMALL_FONT_X_LEN, SMALL_FONT_Y_LEN); i++; } glEnd(); glDisable(GL_ALPHA_TEST); #ifdef OPENGL_TRACE CHECK_GL_ERRORS(); #endif //OPENGL_TRACE } #ifdef ELC #ifndef MAP_EDITOR2 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; //int font_x_size=FONT_X_SPACING; //int font_y_size=FONT_Y_SPACING; int font_bit_width, ignored_bits; unsigned char cur_char; int chr; int i; float cur_x,cur_y; int current_lines=0; 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; glEnable(GL_ALPHA_TEST);//enable alpha filtering, so we have some alpha key glAlphaFunc(GL_GREATER,0.1f); get_and_set_texture_id(font_text); i=0; cur_x=x; cur_y=y; glBegin(GL_QUADS); 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(cur_char >127 && cur_char<=127+c_ubound) //Can IS_COLOR() be used here? { 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; 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; 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(cur_char >127 && cur_char<=127+c_ubound) //Can IS_COLOR() be used here? { glBegin(GL_QUADS); //Ooops - NV bug fix!! } i++; } glEnd(); glDisable(GL_ALPHA_TEST); #ifdef OPENGL_TRACE CHECK_GL_ERRORS(); #endif //OPENGL_TRACE } #endif #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; ispacing; return wdt; } int init_fonts () { int i; max_fonts = 0; for(i = 0; i < FONTS_ARRAY_SIZE; i++) { fonts[i] = NULL; #ifndef FONTS_FIX } if (set_font_parameters (0) < 0) return 0; if (set_font_parameters (1) < 0) return 0; if (set_font_parameters (2) < 0) return 0; if (set_font_parameters (3) < 0) return 0; #else if (set_font_parameters (i) < 0) return 0; } #endif //FONTS_FIX cur_font_num = 0; return 1; } void cleanup_fonts(void) { int i; for(i = 0; i < FONTS_ARRAY_SIZE; i++) { if(fonts[i] != NULL) { free(fonts[i]); } } } void reload_fonts() { int i; int poor_man_save=poor_man; int use_mipmaps_save=use_mipmaps; poor_man=0; use_mipmaps=0; for(i=0;i < FONTS_ARRAY_SIZE; i++){ if(fonts[i] != NULL){ if(fonts[i]->texture_id>=0){ glDeleteTextures(1, (GLuint*)&texture_cache[fonts[i]->texture_id].texture_id); texture_cache[fonts[i]->texture_id].texture_id=0; get_texture_id(fonts[i]->texture_id); } } } poor_man=poor_man_save; use_mipmaps=use_mipmaps_save; #ifdef OPENGL_TRACE CHECK_GL_ERRORS(); #endif //OPENGL_TRACE } int load_font_textures () { int poor_man_save=poor_man; int use_mipmaps_save=use_mipmaps; int i = 0; #ifdef FONTS_FIX #ifdef _MSC_VER struct _finddata_t c_file; long hFile; #else //!_MSC_VER DIR *dp; struct dirent *ep; #endif //_MSC_VER char file[60] = ""; char str[60] = ""; #endif //FONTS_FIX if (fonts[0] == NULL || fonts[1] == NULL || fonts[2] == NULL || fonts[3]==NULL ) { for (i = 0; i < FONTS_ARRAY_SIZE; i++) { if (fonts[i] != NULL) free (fonts[i]); fonts[i] = NULL; } if ( !init_fonts () ) return 0; } poor_man=0; use_mipmaps=0; fonts[0]->texture_id = load_texture_cache("./textures/font.bmp", 0); #ifndef FONTS_FIX fonts[1]->texture_id = load_texture_cache_deferred("./textures/fontv.bmp", 0); fonts[2]->texture_id = load_texture_cache_deferred("./textures/font2.bmp", 0); fonts[3]->texture_id = load_texture_cache_deferred("./textures/font3.bmp", 0); #else //FONTS_FIX i = 1; // Force the selection of the base font. add_multi_option("chat_font", "Type 1"); add_multi_option("name_font", "Type 1"); // Find what font's exist and load them #ifdef _MSC_VER chdir("./textures/"); if( (hFile = _findfirst( "font*.bmp", &c_file )) == -1L ){ chdir(".."); return 0; } do { int len; safe_strncpy(file, c_file.name, sizeof(file)); #else //!_MSC_VER dp = opendir ("./textures/"); if (dp == NULL) { return 0; } while ((ep = readdir (dp)) && i < FONTS_ARRAY_SIZE) { int len; safe_strncpy(file, ep->d_name, sizeof(file)); #endif //_MSC_VER len= strlen(file); if (len + strlen("./textures/") <= sizeof(str) && !strncasecmp(file, "font", 4) && (has_suffix(file, len, ".bmp", 4) || has_suffix(file, len, ".bmp.gz", 7)) && (!has_suffix(file, len, "_alpha.bmp", 10)) && (!has_suffix(file, len, "_alpha.bmp.gz", 13))) { // Get the filename, remove the .bmp and add _alpha.bmp to a copy, then replace the .bmp #ifdef _MSC_VER safe_strncpy(str, file, sizeof(str)); #else //!_MSC_VER safe_snprintf(str, sizeof(str), "./textures/%s", file); #endif //!_MSC_VER if(has_suffix(file, len, ".bmp.gz", 7)){ file[len - 7]= 0; } else { file[len - 4]= 0; } fonts[i]->texture_id = load_texture_cache_deferred(str, 0); safe_snprintf(font_names[i], sizeof(font_names[i]), "Type %i - %s", i + 1, file); add_multi_option("chat_font", font_names[i]); add_multi_option("name_font", font_names[i]); i++; } } #ifdef _MSC_VER while ( _findnext( hFile, &c_file ) == 0 ); _findclose( hFile ); chdir(".."); #else //!_MSC_VER (void) closedir (dp); #endif //_MSC_VER #endif //FONTS_FIX poor_man=poor_man_save; use_mipmaps=use_mipmaps_save; //set the default font cur_font_num = 0; font_text = fonts[0]->texture_id; return 1; } int set_font_parameters (int num) { int i; // error checking if(num < 0 || num >= FONTS_ARRAY_SIZE) { return -1; } // allocate space if needed if(fonts[num] == NULL) { fonts[num]=(font_info *)calloc(1, sizeof(font_info)); if(fonts[num] == NULL) { log_error(cant_load_font); return -1; } } //watch the highest font if(num >= max_fonts) { max_fonts=num+1; } // set default font info my_strcp (fonts[num]->name, "default"); fonts[num]->spacing=0; // load font information // TODO: write this and remove the hack! if(num!=1||num!=2)for(i=0; iwidths[i]=12; if(num==1){ static int widths[]={ 4,2,7,11,8,12,12,2,7,7,9,10,3,8, 2,10,10,10,8,8,10,7,9,9,9,9,3,3, 10,10,10,9,12,12,9,10,10,9,9,10,9,8, 7,11,8,11,10,11,9,11,11,9,10,9,12,12, 12,12,10,6,10,6,10,12,3,11,9,9,9,9, 8,9,9,4,6,10,4,11,9,10,9,9,8,8, 8,9,10,12,10,10,9,8,2,8,10,8,12,12, 12,12,12,12,12,12,12,12,12,12,12,12,12,12, 12,12,12,12,12,12,12,12,12,12,12,12,12,12, 12,12,12,12,12,12,12,12,12,12,12,12,12,12, }; memcpy(fonts[num]->widths, widths, sizeof(widths)); fonts[num]->spacing=4; } if(num==2){ static int widths[]={ 8, 8, 8, 10, 8, 10, 10, 8, 8, 8, 8, 10, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 10, 10, 10, 8, 12, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 8, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 8, 8, 8, 8, 8, 8, 8, 10, 8, 8, 8, 8, 8, 8, 10, 8, 8, 8, 8, 8, 8, 8, 8, 8, 10, 8, 8, 8, 10, 8, 10, 10, 8, 10, 8, 8, 8, 10, 10, 10, 8, 10, 10, 8, 8, 8, 12, 12, 12, 10, 10, 12, 10, 12, 12, 12, }; memcpy(fonts[num]->widths, widths, sizeof(widths)); fonts[num]->spacing=2; } //and return return num; } int set_font(int num) { if(num >= 0 && num < max_fonts && fonts[num] && fonts[num]->texture_id >= 0) { cur_font_num=num; font_text=fonts[cur_font_num]->texture_id; } return cur_font_num; } /* currently UNUSED void remove_font(int num) { if(num < max_fonts && fonts[num]) { free(fonts[num]); fonts[num]=NULL; if (num == max_fonts-1) { max_fonts--; } } } */