diff options
Diffstat (limited to 'src/engine/client')
| -rw-r--r-- | src/engine/client/gfx.c | 194 |
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; |