about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJakob Fries <jakob.fries@gmail.com>2007-12-22 02:55:19 +0000
committerJakob Fries <jakob.fries@gmail.com>2007-12-22 02:55:19 +0000
commit1ddfbba3666a835b59fc79b59aaae367ee93a6ea (patch)
treee5304209e6a0ab62c083aee01bc46d68333cd2cd
parent87b89138f42bbc1a276c4e92429ce651500e871c (diff)
downloadzcatch-1ddfbba3666a835b59fc79b59aaae367ee93a6ea.tar.gz
zcatch-1ddfbba3666a835b59fc79b59aaae367ee93a6ea.zip
add new font stuff
-rw-r--r--scripts/font_converter.py121
-rw-r--r--src/engine/client/ec_gfx.c1
-rw-r--r--src/engine/client/ec_ui.c158
-rw-r--r--src/engine/client/ec_ui.h27
-rw-r--r--src/game/client/gc_menu.cpp2
5 files changed, 309 insertions, 0 deletions
diff --git a/scripts/font_converter.py b/scripts/font_converter.py
new file mode 100644
index 00000000..f2ba0e49
--- /dev/null
+++ b/scripts/font_converter.py
@@ -0,0 +1,121 @@
+from __future__ import with_statement
+import struct
+import sys
+
+def convert(input, output):
+    with open(input, "r") as in_file:
+        with open(output, "w") as out_file:
+            def build_dic(parts):
+                dic = {}
+
+                for part in parts:
+                    key, value = part.split('=')
+
+                    try:
+                        dic[key] = int(value)
+                    except:
+                        dic[key] = value
+
+                return dic
+
+            def get_entry(line):
+
+                parts = line.split()
+                type = parts[0]
+
+                dic = build_dic(parts[1:])
+
+                return type, dic
+
+            def write_int16(val):
+                out_file.write(struct.pack('<h', val))
+
+            def write_info(dic):
+                write_int16(dic["size"])
+
+            def write_common(dic):
+                write_int16(dic["scaleW"])
+                write_int16(dic["scaleH"])
+                write_int16(dic["lineHeight"])
+                write_int16(dic["base"])
+
+            def write_page(dic):
+                pass
+
+            def write_chars(dic):
+                pass
+
+            def write_char(dic):
+                write_int16(dic["x"])
+                write_int16(dic["y"])
+                write_int16(dic["width"])
+                write_int16(dic["height"])
+                write_int16(dic["xoffset"])
+                write_int16(dic["yoffset"])
+                write_int16(dic["xadvance"])
+
+            def write_default_char():
+                write_int16(0)
+                write_int16(0)
+                write_int16(0)
+                write_int16(0)
+                write_int16(0)
+                write_int16(0)
+                write_int16(0)
+
+            def write_kernings(dic):
+                pass
+
+            def write_kerning(dic):
+                write_int16(dic["amount"])
+
+            def write_default_kerning():
+                write_int16(0)
+
+            chars = []
+            kernings = []
+            for i in range(256):
+                chars.append(None)
+            for i in range(256*256):
+                kernings.append(None)
+
+            def save_char(dic):
+                chars[dic["id"]] = dic
+
+            def save_kerning(dic):
+                kernings[dic["first"] + dic["second"]*256] = dic
+
+            write_table = {
+                "info": write_info,
+                "common": write_common,
+                "page": write_page,
+                "chars": write_chars,
+                "char": save_char,
+                "kernings": write_kernings,
+                "kerning": save_kerning
+            }
+
+            for line in in_file:
+                type, dic = get_entry(line)
+                
+                write_table[type](dic)
+
+            for i in range(256):
+                if chars[i]:
+                    write_char(chars[i])
+                else:
+                    write_default_char()
+
+            for i in range(256*256):
+                if kernings[i]:
+                    write_kerning(kernings[i])
+                else:
+                    write_default_kerning()
+
+if len(sys.argv) != 3:
+    print "font converter! converts .fnt files to teewars .tfnt"
+    print "usage: font_converter <input> <output>"
+else:
+    print "converting..."
+    convert(sys.argv[1], sys.argv[2])
+    print "done!"
diff --git a/src/engine/client/ec_gfx.c b/src/engine/client/ec_gfx.c
index 431350f2..d93d07df 100644
--- a/src/engine/client/ec_gfx.c
+++ b/src/engine/client/ec_gfx.c
@@ -554,6 +554,7 @@ int gfx_load_png(IMAGE_INFO *img, const char *filename)
 	{
 		dbg_msg("game/png", "invalid format. filename='%s'", filename);
 		png_close_file(&png);
+        return 0;
 	}
 		
 	buffer = (unsigned char *)mem_alloc(png.width * png.height * png.bpp, 1);
diff --git a/src/engine/client/ec_ui.c b/src/engine/client/ec_ui.c
index 5ba9c0d9..b0e088a0 100644
--- a/src/engine/client/ec_ui.c
+++ b/src/engine/client/ec_ui.c
@@ -275,3 +275,161 @@ void ui_margin(const struct rect *original, int pixels, struct rect *other_rect)
     other_rect->w = r.w - 2*pixels;
     other_rect->h = r.h - 2*pixels;
 }
+
+typedef struct
+{
+    short x, y;
+    short width, height;
+    short x_offset, y_offset;
+    short x_advance;
+} FONT_CHARACTER;
+
+typedef struct
+{
+    short size;
+    short width, height;
+
+    short line_height;
+    short base;
+
+    FONT_CHARACTER characters[256];
+
+    short kerning[256*256];
+} FONT_DATA;
+
+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)
+	{
+        int i;
+
+        io_read(file, &font_data, sizeof(FONT_DATA));
+        io_close(file);
+
+#if defined(CONF_ARCH_ENDIAN_BIG)
+        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 = ((float)font_data.size)/font_data.width;
+            float scale_factor_y = ((float)font_data.size)/font_data.height;
+            float scale_factor_tex_x = 1.0f/font_data.width;
+            float scale_factor_tex_y = 1.0f/font_data.height;
+
+            for (i = 0; i < 256; i++)
+            {
+                float tex_x0 = font_data.characters[i].x*scale_factor_tex_x;
+                float tex_y0 = font_data.characters[i].y*scale_factor_tex_y;
+                float tex_x1 = (font_data.characters[i].x+font_data.characters[i].width)*scale_factor_tex_x;
+                float tex_y1 = (font_data.characters[i].y+font_data.characters[i].height)*scale_factor_tex_y;
+
+                float width = font_data.characters[i].width*scale_factor_x;
+                float height = font_data.characters[i].height*scale_factor_y;
+                float x_offset = font_data.characters[i].x_offset*scale_factor_x;
+                float y_offset = font_data.characters[i].y_offset*scale_factor_y;
+                float x_advance = font_data.characters[i].x_advance*scale_factor_x;
+
+                font->characters[i].tex_x0 = tex_x0;
+                font->characters[i].tex_y0 = tex_y0;
+                font->characters[i].tex_x1 = tex_x1;
+                font->characters[i].tex_y1 = tex_y1;
+                font->characters[i].width = width;
+                font->characters[i].height = height;
+                font->characters[i].x_offset = x_offset;
+                font->characters[i].y_offset = y_offset;
+                font->characters[i].x_advance = x_advance;
+
+            }
+
+            for (i = 0; i < 256*256; i++)
+            {
+                font->kerning[i] = font_data.kerning[i]*scale_factor_x;
+            }
+        }
+
+        return 0;
+    }
+    else
+        return -1;
+}
+
+int font_save(FONT *font, const char *filename)
+{
+    return 0;
+}
+
+float font_string_width(FONT *font, const char *string, float size)
+{
+    float width = 0.0f;
+
+    const unsigned char *c = (unsigned char *)string;
+
+    while (*c)
+    {
+        float tex_x0, tex_y0, tex_x1, tex_y1;
+        float char_width, char_height;
+        float x_offset, y_offset, x_advance;
+
+        font_character_info(font, *c, &tex_x0, &tex_y0, &tex_x1, &tex_y1, &char_width, &char_height, &x_offset, &y_offset, &x_advance);
+
+
+        width += x_advance;
+
+        c++;
+    }
+
+
+    return width*size;
+}
+
+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)
+{
+    CHARACTER *character = &font->characters[c];
+
+    *tex_x0 = character->tex_x0;
+    *tex_y0 = character->tex_y0;
+    *tex_x1 = character->tex_x1;
+    *tex_y1 = character->tex_y1;
+    *width = character->width;
+    *height = character->height;
+    *x_offset = character->x_offset;
+    *y_offset = character->y_offset;
+    *x_advance = character->x_advance;
+}
+
+void font_render(FONT *font, const char *string, float x, float y, float size)
+{
+    const unsigned char *c = (unsigned char *)string;
+
+    gfx_texture_set(font->texture);
+
+	gfx_quads_begin();
+	gfx_setcolor(1.0f, 1.0f, 1.0f, 1.0f);
+    
+    while (*c)
+    {
+        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);
+
+		gfx_quads_setsubset(tex_x0, tex_y0, tex_x1, tex_y1);
+
+		gfx_quads_drawTL(x+x_offset*size, y+y_offset*size, width*size, height*size);
+
+        x += x_advance*size;
+
+        c++;
+    }
+
+	gfx_quads_end();
+}
diff --git a/src/engine/client/ec_ui.h b/src/engine/client/ec_ui.h
index 15c63b90..3464a2e6 100644
--- a/src/engine/client/ec_ui.h
+++ b/src/engine/client/ec_ui.h
@@ -29,6 +29,33 @@ void ui_do_image(int texture, float x, float y, float w, float h);
 void ui_do_label(float x, float y, const char *text, float size);
 int ui_do_button(const void *id, const char *text, int checked, float x, float y, float w, float h, draw_button_callback draw_func, void *extra);
 
+typedef struct
+{
+    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;
+}
+CHARACTER;
+
+typedef struct
+{
+    int texture;
+    CHARACTER characters[256];
+    float kerning[256*256];
+} FONT;
+
+int font_load(FONT *font, const char *filename);
+int font_save(FONT *font, const char *filename);
+float font_string_width(FONT *font, const char *string, float size);
+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);
+void font_render(FONT *font, const char *string, float x, float y, float size);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/game/client/gc_menu.cpp b/src/game/client/gc_menu.cpp
index fdb3f755..449004d9 100644
--- a/src/game/client/gc_menu.cpp
+++ b/src/game/client/gc_menu.cpp
@@ -1831,6 +1831,8 @@ void menu_do_connected()
 
 void menu_init()
 {
+    int i;
+
 	if(config.cl_show_welcome)
 		popup = POPUP_FIRST_LAUNCH;
 	config.cl_show_welcome = 0;