about summary refs log tree commit diff
path: root/src/engine/client/gfx.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/engine/client/gfx.c')
-rw-r--r--src/engine/client/gfx.c194
1 files changed, 194 insertions, 0 deletions
diff --git a/src/engine/client/gfx.c b/src/engine/client/gfx.c
index c0c0d12a..13c35a39 100644
--- a/src/engine/client/gfx.c
+++ b/src/engine/client/gfx.c
@@ -68,6 +68,7 @@ enum
 static TEXTURE textures[MAX_TEXTURES];
 static int first_free_texture;
 static int memory_usage = 0;
+static float scale = 1.0f;
 
 static const unsigned char null_texture_data[] = {
 	0xff,0x00,0x00,0xff, 0xff,0x00,0x00,0xff, 0x00,0xff,0x00,0xff, 0x00,0xff,0x00,0xff, 
@@ -120,6 +121,199 @@ static void draw_quad()
 		flush();
 }
 
+struct node
+{
+    struct node *left_child, *right_child;
+    struct rect *rect;
+};
+
+#define TREE_SIZE 128
+static struct node memory[TREE_SIZE];
+static int memory_used;
+static struct rect screen = { 0.0f, 0.0f, 800.0f, 600.0f };
+static struct node root;
+
+static struct node *allocate_node()
+{
+    if (memory_used >= TREE_SIZE)
+    {
+        dbg_msg("GUI tree error",  "all tree nodes are taken. =(");
+        return 0x0;
+    }
+    else
+        return &memory[memory_used++];
+}
+
+static void clear_node(struct node *n)
+{
+    n->left_child = 0x0;
+    n->right_child = 0x0;
+    n->rect = 0x0;
+}
+
+static struct node *find(struct node *n, struct rect *r)
+{
+    if (!n)
+        return 0x0;
+    else if (n->rect == r)
+        return n;
+    else
+    {
+        struct node *result = find(n->left_child, r);
+
+        if (result)
+            return result;
+        else
+            return find(n->right_child, r);
+    }
+}
+
+static struct node *find_node(struct rect *rect)
+{
+    return find(&root, rect);
+}
+
+static void set_children(struct rect *parent, struct rect *child1, struct rect *child2)
+{
+    struct node *n = find_node(parent);
+    struct node *c1 = allocate_node();
+    struct node *c2 = allocate_node();
+
+    if (!n)
+        dbg_msg("GUI tree error", "could not find parent in tree.");
+
+    if (n->left_child || n->right_child)
+        dbg_msg("GUI tree error", "node already has children.");
+
+    clear_node(c1);
+    clear_node(c2);
+
+    c1->rect = child1;
+    c2->rect = child2;
+
+    n->left_child = c1;
+    n->right_child = c2;
+}
+
+static void foreach_leaf(struct node *n, rect_fun fun)
+{
+    if (n->left_child && n->right_child)
+    {
+        foreach_leaf(n->left_child, fun);
+        foreach_leaf(n->right_child, fun);
+    }
+    else
+        fun(n->rect);
+}
+
+void ui_foreach_rect(rect_fun fun)
+{
+    foreach_leaf(&root, fun);
+}
+
+struct rect *ui_screen()
+{
+    if (config.debug)
+    {
+        memory_used = 0;
+        clear_node(&root);
+        root.rect = &screen;
+    }
+
+    return &screen;
+}
+
+void ui_scale(float s)
+{
+    scale = s;
+}
+
+void ui_hsplit_t(struct rect *original, int pixels, struct rect *top, struct rect *bottom)
+{
+    struct rect r = *original;
+    pixels *= scale;
+
+    top->x = r.x;
+    top->y = r.y;
+    top->w = r.w;
+    top->h = pixels;
+
+    bottom->x = r.x;
+    bottom->y = r.y + pixels;
+    bottom->w = r.w;
+    bottom->h = r.h - pixels;
+
+    set_children(original, top, bottom);
+}
+
+void ui_hsplit_b(struct rect *original, int pixels, struct rect *top, struct rect *bottom)
+{
+    struct rect r = *original;
+    pixels *= scale;
+
+    top->x = r.x;
+    top->y = r.y;
+    top->w = r.w;
+    top->h = r.h - pixels;
+
+    bottom->x = r.x;
+    bottom->y = r.y + r.h - pixels;
+    bottom->w = r.w;
+    bottom->h = pixels;
+
+    if (config.debug)
+        set_children(original, top, bottom);
+}
+
+void ui_vsplit_l(struct rect *original, int pixels, struct rect *left, struct rect *right)
+{
+    struct rect r = *original;
+    pixels *= scale;
+
+    left->x = r.x;
+    left->y = r.y;
+    left->w = pixels;
+    left->h = r.h;
+
+    right->x = r.x + pixels;
+    right->y = r.y;
+    right->w = r.w - pixels;
+    right->h = r.h;
+
+    if (config.debug)
+        set_children(original, left, right);
+}
+
+void ui_vsplit_r(struct rect *original, int pixels, struct rect *left, struct rect *right)
+{
+    struct rect r = *original;
+    pixels *= scale;
+
+    left->x = r.x;
+    left->y = r.y;
+    left->w = r.w - pixels;
+    left->h = r.h;
+
+    right->x = r.x + r.w - pixels;
+    right->y = r.y;
+    right->w = pixels;
+    right->h = r.h;
+
+    if (config.debug)
+        set_children(original, left, right);
+}
+
+void ui_margin(struct rect *original, int pixels, struct rect *other_rect)
+{
+    struct rect r = *original;
+    pixels *= scale;
+
+    other_rect->x = r.x + pixels;
+    other_rect->y = r.y + pixels;
+    other_rect->w = r.w - 2*pixels;
+    other_rect->h = r.h - 2*pixels;
+}
+
 int gfx_init()
 {
 	int i;