about summary refs log tree commit diff
path: root/src/engine
diff options
context:
space:
mode:
authorJakob Fries <jakob.fries@gmail.com>2007-12-25 03:25:13 +0000
committerJakob Fries <jakob.fries@gmail.com>2007-12-25 03:25:13 +0000
commitcd6d5e6237acf659d75fa64568506c152ce41ec9 (patch)
tree34f0a110da3796d10d272bd4742b000503103326 /src/engine
parent23d50255d2527c2aa1fa15964f0fd22d0ba95bc2 (diff)
downloadzcatch-cd6d5e6237acf659d75fa64568506c152ce41ec9.tar.gz
zcatch-cd6d5e6237acf659d75fa64568506c152ce41ec9.zip
new fonts added, lots more magic font code added, server bug fixed
Diffstat (limited to 'src/engine')
-rw-r--r--src/engine/client/ec_font.c27
-rw-r--r--src/engine/client/ec_font.h9
-rw-r--r--src/engine/client/ec_gfx.c122
-rw-r--r--src/engine/e_interface.h3
-rw-r--r--src/engine/e_snapshot.c4
5 files changed, 123 insertions, 42 deletions
diff --git a/src/engine/client/ec_font.c b/src/engine/client/ec_font.c
index 33a8deea..92ba3cb7 100644
--- a/src/engine/client/ec_font.c
+++ b/src/engine/client/ec_font.c
@@ -30,7 +30,6 @@ int font_load(FONT *font, const char *filename)
     FONT_DATA font_data;
 	IOHANDLE file;
 
-	dbg_msg("font/load", "loading %s", filename);
 	file = io_open(filename, IOFLAG_READ);
 	
 	if(file)
@@ -44,8 +43,6 @@ int font_load(FONT *font, const char *filename)
         swap_endian(&font_data, 2, sizeof(FONT_DATA)/2);
 #endif
 
-        dbg_msg("font/load", "width: %d, height: %d, sizeof(FONT_DATA): %d", font_data.width, font_data.height, sizeof(FONT_DATA));
-
         {
             float scale_factor_x = 1.0f/font_data.size;
             float scale_factor_y = 1.0f/font_data.size;
@@ -79,7 +76,7 @@ int font_load(FONT *font, const char *filename)
 
             for (i = 0; i < 256*256; i++)
             {
-                font->kerning[i] = font_data.kerning[i]*scale_factor_x;
+                font->kerning[i] = (char)font_data.kerning[i];
             }
         }
 
@@ -91,7 +88,7 @@ int font_load(FONT *font, const char *filename)
 
 int gfx_load_texture(const char *filename);
 
-int font_set_load(FONT_SET *font_set, const char *font_filename, const char *texture_filename, int fonts, ...)
+int font_set_load(FONT_SET *font_set, const char *font_filename, const char *text_texture_filename, const char *outline_texture_filename, int fonts, ...)
 {
     int i;
     va_list va; 
@@ -103,36 +100,36 @@ int font_set_load(FONT_SET *font_set, const char *font_filename, const char *tex
     {
         int size;
         char composed_font_filename[256];
-        char composed_texture_filename[256];
+        char composed_text_texture_filename[256];
+        char composed_outline_texture_filename[256];
         FONT *font = &font_set->fonts[i];
 
         size = va_arg(va, int);
         sprintf(composed_font_filename, font_filename, size);
-        sprintf(composed_texture_filename, texture_filename, size);
+        sprintf(composed_text_texture_filename, text_texture_filename, size);
+        sprintf(composed_outline_texture_filename, outline_texture_filename, size);
 
         if (font_load(font, composed_font_filename))
         {
+            dbg_msg("font/loading", "failed loading font %s.", composed_font_filename);
             va_end(va);
             return -1;
         }
 
         font->size = size;
-        font->texture = gfx_load_texture(composed_texture_filename);
-
-        dbg_msg("font_set/loading", "filename: %s", composed_font_filename);
+        font->text_texture = gfx_load_texture(composed_text_texture_filename);
+        font->outline_texture = gfx_load_texture(composed_outline_texture_filename);
     }
 
     va_end(va);
     return 0;
 }
 
-float font_set_string_width(FONT_SET *font_set, const char *string, float size)
+float font_text_width(FONT *font, const char *text, float size, int length)
 {
     float width = 0.0f;
 
-    const unsigned char *c = (unsigned char *)string;
-
-    FONT *font = &font_set->fonts[0];
+    const unsigned char *c = (unsigned char *)text;
 
     while (*c)
     {
@@ -167,7 +164,7 @@ void font_character_info(FONT *font, unsigned char c, float *tex_x0, float *tex_
 
 float font_kerning(FONT *font, unsigned char c1, unsigned char c2)
 {
-    return font->kerning[c1 + c2*256];
+    return font->kerning[c1 + c2*256] / (float)font->size;
 }
 
 FONT *font_set_pick(FONT_SET *font_set, float size)
diff --git a/src/engine/client/ec_font.h b/src/engine/client/ec_font.h
index 6b4d5910..a68a8452 100644
--- a/src/engine/client/ec_font.h
+++ b/src/engine/client/ec_font.h
@@ -18,10 +18,11 @@ CHARACTER;
 
 typedef struct
 {
-    int texture;
+    int text_texture;
+    int outline_texture;
     int size;
     CHARACTER characters[256];
-    float kerning[256*256];
+    char kerning[256*256];
 } FONT;
 
 typedef struct
@@ -31,8 +32,8 @@ typedef struct
 } FONT_SET;
 
 int font_load(FONT *font, const char *filename);
-int font_set_load(FONT_SET *font_set, const char *font_filename, const char *texture_filename, int fonts, ...);
-float font_string_width(FONT_SET *font_set, const char *string, float size);
+int font_set_load(FONT_SET *font_set, const char *font_filename, const char *text_texture_filename, const char *outline_texture_filename, int fonts, ...);
+float font_text_width(FONT *font, const char *text, float size, int width);
 void font_character_info(FONT *font, unsigned char c, float *tex_x0, float *tex_y0, float *tex_x1, float *tex_y1, float *width, float *height, float *x_offset, float *y_offset, float *x_advance);
 float font_kerning(FONT *font, unsigned char c1, unsigned char c2);
 FONT *font_set_pick(FONT_SET *font_set, float size);
diff --git a/src/engine/client/ec_gfx.c b/src/engine/client/ec_gfx.c
index 106226a4..83bfff17 100644
--- a/src/engine/client/ec_gfx.c
+++ b/src/engine/client/ec_gfx.c
@@ -229,6 +229,7 @@ int gfx_init()
 			return 0;
 		}
 	}
+
 	
 	glfwSetWindowSizeCallback(screen_resize);
 	
@@ -889,40 +890,115 @@ static float pretty_g=1;
 static float pretty_b=1;
 static float pretty_a=1;
 
-void gfx_text(void *font_set_v, float x, float y, const char *text, float size)
-{
-    const unsigned char *c = (unsigned char *)text;
+FONT *gfx_font_set;
 
+float gfx_text_raw(void *font_set_v, float x, float y, float size, const char *text, int length)
+{
     FONT_SET *font_set = font_set_v;
-    FONT *font = font_set_pick(font_set, size);
+    float fake_to_screen_x = (screen_width/(screen_x1-screen_x0));
+    float fake_to_screen_y = (screen_height/(screen_y1-screen_y0));
 
-    gfx_texture_set(font->texture);
+    FONT *font;
 
-	gfx_quads_begin();
-	gfx_setcolor(pretty_r, pretty_g, pretty_b, pretty_a);
-    
-    while (*c)
+    // to correct coords, convert to screen coords, round, and convert back
+    int actual_x = x * fake_to_screen_x;
+    int actual_y = y * fake_to_screen_y;
+    x = actual_x / fake_to_screen_x;
+    y = actual_y / fake_to_screen_y;
+
+    // same with size
+    int actual_size = size * fake_to_screen_y;
+    size = actual_size / fake_to_screen_y;
+
+    font = font_set_pick(font_set, actual_size);
+
+    int i;
+    float draw_x;
+
+    if (length < 0)
+        length = strlen(text);
+
+    for (i = 0; i < 2; i++)
     {
-        float tex_x0, tex_y0, tex_x1, tex_y1;
-        float width, height;
-        float x_offset, y_offset, x_advance;
+        const unsigned char *c = (unsigned char *)text;
+        int to_render = length;
+        draw_x = x;
+
+        if (i == 0)
+            gfx_texture_set(font->outline_texture);
+        else
+            gfx_texture_set(font->text_texture);
 
-        float advance;
+        gfx_quads_begin();
+        if (i == 0)
+            gfx_setcolor(0.0f, 0.0f, 0.0f, 0.3f);
+        else
+            gfx_setcolor(pretty_r, pretty_g, pretty_b, pretty_a);
+        
+        while (to_render--)
+        {
+            float tex_x0, tex_y0, tex_x1, tex_y1;
+            float width, height;
+            float x_offset, y_offset, x_advance;
 
-        font_character_info(font, *c, &tex_x0, &tex_y0, &tex_x1, &tex_y1, &width, &height, &x_offset, &y_offset, &x_advance);
+            float advance;
 
-		gfx_quads_setsubset(tex_x0, tex_y0, tex_x1, tex_y1);
+            font_character_info(font, *c, &tex_x0, &tex_y0, &tex_x1, &tex_y1, &width, &height, &x_offset, &y_offset, &x_advance);
 
-		gfx_quads_drawTL(x+x_offset*size, y+y_offset*size, width*size, height*size);
+            gfx_quads_setsubset(tex_x0, tex_y0, tex_x1, tex_y1);
 
-        advance = x_advance + font_kerning(font, *c, *(c+1));
+            gfx_quads_drawTL(draw_x+x_offset*size, y+y_offset*size, width*size, height*size);
 
-        x += advance*size;
+            advance = x_advance + font_kerning(font, *c, *(c+1));
 
-        c++;
+            draw_x += advance*size;
+
+            c++;
+        }
+
+        gfx_quads_end();
     }
 
-	gfx_quads_end();
+    return draw_x;
+}
+
+void gfx_text(void *font_set_v, float x, float y, float size, const char *text, int max_width)
+{
+	if(max_width == -1)
+		gfx_text_raw(font_set_v, x, y, size, text, -1);
+	else
+	{
+		float startx = x;
+		while(*text)
+		{
+			int wlen = word_length(text);
+			float w = gfx_text_width(font_set_v, size, text, wlen);
+			if(x+w-startx > max_width)
+			{
+				y += size;
+				x = startx;
+			}
+			
+			x = gfx_text_raw(font_set_v, x, y, size, text, wlen);
+			
+			text += wlen;
+		}
+	}
+    gfx_text_raw(font_set_v, x, y, size, text, -1);
+}
+
+float gfx_text_width(void *font_set_v, float size, const char *text, int length)
+{
+    FONT_SET *font_set = font_set_v;
+    FONT *font;
+    float fake_to_screen_y = (screen_height/(screen_y1-screen_y0));
+
+    int actual_size = size * fake_to_screen_y;
+    size = actual_size / fake_to_screen_y;
+
+    font = font_set_pick(font_set, actual_size);
+
+    return font_text_width(font, text, size, length);
 }
 
 void gfx_pretty_text_color(float r, float g, float b, float a)
@@ -974,10 +1050,10 @@ float gfx_pretty_text_raw(float x, float y, float size, const char *text_, int l
 	return x;
 }
 
-
-
 void gfx_pretty_text(float x, float y, float size, const char *text, int max_width)
 {
+    //gfx_text(gfx_font_set, x, y, 0.8*size, text, max_width);
+    //return;
 	if(max_width == -1)
 		gfx_pretty_text_raw(x, y, size, text, -1);
 	else
@@ -1002,6 +1078,8 @@ void gfx_pretty_text(float x, float y, float size, const char *text, int max_wid
 
 float gfx_pretty_text_width(float size, const char *text_, int length)
 {
+    //return gfx_text_width(gfx_font_set, 0.8*size, text_, length);
+
 	const float spacing = 0.05f;
 	float w = 0.0f;
 	const unsigned char *text = (unsigned char *)text_;
diff --git a/src/engine/e_interface.h b/src/engine/e_interface.h
index 9f86d4c8..a4f3baa9 100644
--- a/src/engine/e_interface.h
+++ b/src/engine/e_interface.h
@@ -856,7 +856,8 @@ void client_serverbrowse_update();
 
 /* undocumented graphics stuff */
 
-void gfx_text(void *font, float x, float y, const char *text, float size);
+void gfx_text(void *font, float x, float y, float size, const char *text, int max_width);
+float gfx_text_width(void *font, float size, const char *text, int length);
 void gfx_pretty_text_color(float r, float g, float b, float a);
 void gfx_pretty_text(float x, float y, float size, const char *text, int max_width);
 float gfx_pretty_text_width(float size, const char *text, int length);
diff --git a/src/engine/e_snapshot.c b/src/engine/e_snapshot.c
index d2379217..66b9a295 100644
--- a/src/engine/e_snapshot.c
+++ b/src/engine/e_snapshot.c
@@ -427,6 +427,10 @@ void snapstorage_purge_until(SNAPSTORAGE *ss, int tick)
 			return; /* no more to remove */
 		mem_free(h);
 		
+        // did we come to the end of the list?
+        if (!next)
+            break;
+
 		ss->first = next;
 		next->prev = 0x0;