From 81823e862eee203699fbd5c84f4a975aa3923ebd Mon Sep 17 00:00:00 2001 From: zelaven Date: Sun, 29 Sep 2024 16:53:34 +0200 Subject: [PATCH] Initial commit --- microui/microui.c | 1208 +++++++++++++++++++++++++++++++++++++++++++++ microui/microui.h | 296 +++++++++++ src/a.out | Bin 0 -> 147176 bytes src/atlas.inl | 995 +++++++++++++++++++++++++++++++++++++ src/build.sh | 16 + src/cpu.c | 161 ++++++ src/main.c | 449 +++++++++++++++++ src/program1.txt | 2 + src/program2.txt | 2 + src/renderer.c | 188 +++++++ src/renderer.h | 17 + src/test.txt | 64 +++ 12 files changed, 3398 insertions(+) create mode 100644 microui/microui.c create mode 100644 microui/microui.h create mode 100755 src/a.out create mode 100644 src/atlas.inl create mode 100755 src/build.sh create mode 100644 src/cpu.c create mode 100644 src/main.c create mode 100644 src/program1.txt create mode 100644 src/program2.txt create mode 100644 src/renderer.c create mode 100644 src/renderer.h create mode 100644 src/test.txt diff --git a/microui/microui.c b/microui/microui.c new file mode 100644 index 0000000..0415e45 --- /dev/null +++ b/microui/microui.c @@ -0,0 +1,1208 @@ +/* +** Copyright (c) 2024 rxi +** +** Permission is hereby granted, free of charge, to any person obtaining a copy +** of this software and associated documentation files (the "Software"), to +** deal in the Software without restriction, including without limitation the +** rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +** sell copies of the Software, and to permit persons to whom the Software is +** furnished to do so, subject to the following conditions: +** +** The above copyright notice and this permission notice shall be included in +** all copies or substantial portions of the Software. +** +** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +** FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +** IN THE SOFTWARE. +*/ + +#include +#include +#include +#include "microui.h" + +#define unused(x) ((void) (x)) + +#define expect(x) do { \ + if (!(x)) { \ + fprintf(stderr, "Fatal error: %s:%d: assertion '%s' failed\n", \ + __FILE__, __LINE__, #x); \ + abort(); \ + } \ + } while (0) + +#define push(stk, val) do { \ + expect((stk).idx < (int) (sizeof((stk).items) / sizeof(*(stk).items))); \ + (stk).items[(stk).idx] = (val); \ + (stk).idx++; /* incremented after incase `val` uses this value */ \ + } while (0) + +#define pop(stk) do { \ + expect((stk).idx > 0); \ + (stk).idx--; \ + } while (0) + + +static mu_Rect unclipped_rect = { 0, 0, 0x1000000, 0x1000000 }; + +static mu_Style default_style = { + /* font | size | padding | spacing | indent */ + NULL, { 68, 10 }, 5, 4, 24, + /* title_height | scrollbar_size | thumb_size */ + 24, 12, 8, + { + { 230, 230, 230, 255 }, /* MU_COLOR_TEXT */ + { 25, 25, 25, 255 }, /* MU_COLOR_BORDER */ + { 50, 50, 50, 255 }, /* MU_COLOR_WINDOWBG */ + { 25, 25, 25, 255 }, /* MU_COLOR_TITLEBG */ + { 240, 240, 240, 255 }, /* MU_COLOR_TITLETEXT */ + { 0, 0, 0, 0 }, /* MU_COLOR_PANELBG */ + { 75, 75, 75, 255 }, /* MU_COLOR_BUTTON */ + { 95, 95, 95, 255 }, /* MU_COLOR_BUTTONHOVER */ + { 115, 115, 115, 255 }, /* MU_COLOR_BUTTONFOCUS */ + { 30, 30, 30, 255 }, /* MU_COLOR_BASE */ + { 35, 35, 35, 255 }, /* MU_COLOR_BASEHOVER */ + { 40, 40, 40, 255 }, /* MU_COLOR_BASEFOCUS */ + { 43, 43, 43, 255 }, /* MU_COLOR_SCROLLBASE */ + { 30, 30, 30, 255 } /* MU_COLOR_SCROLLTHUMB */ + } +}; + + +mu_Vec2 mu_vec2(int x, int y) { + mu_Vec2 res; + res.x = x; res.y = y; + return res; +} + + +mu_Rect mu_rect(int x, int y, int w, int h) { + mu_Rect res; + res.x = x; res.y = y; res.w = w; res.h = h; + return res; +} + + +mu_Color mu_color(int r, int g, int b, int a) { + mu_Color res; + res.r = r; res.g = g; res.b = b; res.a = a; + return res; +} + + +static mu_Rect expand_rect(mu_Rect rect, int n) { + return mu_rect(rect.x - n, rect.y - n, rect.w + n * 2, rect.h + n * 2); +} + + +static mu_Rect intersect_rects(mu_Rect r1, mu_Rect r2) { + int x1 = mu_max(r1.x, r2.x); + int y1 = mu_max(r1.y, r2.y); + int x2 = mu_min(r1.x + r1.w, r2.x + r2.w); + int y2 = mu_min(r1.y + r1.h, r2.y + r2.h); + if (x2 < x1) { x2 = x1; } + if (y2 < y1) { y2 = y1; } + return mu_rect(x1, y1, x2 - x1, y2 - y1); +} + + +static int rect_overlaps_vec2(mu_Rect r, mu_Vec2 p) { + return p.x >= r.x && p.x < r.x + r.w && p.y >= r.y && p.y < r.y + r.h; +} + + +static void draw_frame(mu_Context *ctx, mu_Rect rect, int colorid) { + mu_draw_rect(ctx, rect, ctx->style->colors[colorid]); + if (colorid == MU_COLOR_SCROLLBASE || + colorid == MU_COLOR_SCROLLTHUMB || + colorid == MU_COLOR_TITLEBG) { return; } + /* draw border */ + if (ctx->style->colors[MU_COLOR_BORDER].a) { + mu_draw_box(ctx, expand_rect(rect, 1), ctx->style->colors[MU_COLOR_BORDER]); + } +} + + +void mu_init(mu_Context *ctx) { + memset(ctx, 0, sizeof(*ctx)); + ctx->draw_frame = draw_frame; + ctx->_style = default_style; + ctx->style = &ctx->_style; +} + + +void mu_begin(mu_Context *ctx) { + expect(ctx->text_width && ctx->text_height); + ctx->command_list.idx = 0; + ctx->root_list.idx = 0; + ctx->scroll_target = NULL; + ctx->hover_root = ctx->next_hover_root; + ctx->next_hover_root = NULL; + ctx->mouse_delta.x = ctx->mouse_pos.x - ctx->last_mouse_pos.x; + ctx->mouse_delta.y = ctx->mouse_pos.y - ctx->last_mouse_pos.y; + ctx->frame++; +} + + +static int compare_zindex(const void *a, const void *b) { + return (*(mu_Container**) a)->zindex - (*(mu_Container**) b)->zindex; +} + + +void mu_end(mu_Context *ctx) { + int i, n; + /* check stacks */ + expect(ctx->container_stack.idx == 0); + expect(ctx->clip_stack.idx == 0); + expect(ctx->id_stack.idx == 0); + expect(ctx->layout_stack.idx == 0); + + /* handle scroll input */ + if (ctx->scroll_target) { + ctx->scroll_target->scroll.x += ctx->scroll_delta.x; + ctx->scroll_target->scroll.y += ctx->scroll_delta.y; + } + + /* unset focus if focus id was not touched this frame */ + if (!ctx->updated_focus) { ctx->focus = 0; } + ctx->updated_focus = 0; + + /* bring hover root to front if mouse was pressed */ + if (ctx->mouse_pressed && ctx->next_hover_root && + ctx->next_hover_root->zindex < ctx->last_zindex && + ctx->next_hover_root->zindex >= 0 + ) { + mu_bring_to_front(ctx, ctx->next_hover_root); + } + + /* reset input state */ + ctx->key_pressed = 0; + ctx->input_text[0] = '\0'; + ctx->mouse_pressed = 0; + ctx->scroll_delta = mu_vec2(0, 0); + ctx->last_mouse_pos = ctx->mouse_pos; + + /* sort root containers by zindex */ + n = ctx->root_list.idx; + qsort(ctx->root_list.items, n, sizeof(mu_Container*), compare_zindex); + + /* set root container jump commands */ + for (i = 0; i < n; i++) { + mu_Container *cnt = ctx->root_list.items[i]; + /* if this is the first container then make the first command jump to it. + ** otherwise set the previous container's tail to jump to this one */ + if (i == 0) { + mu_Command *cmd = (mu_Command*) ctx->command_list.items; + cmd->jump.dst = (char*) cnt->head + sizeof(mu_JumpCommand); + } else { + mu_Container *prev = ctx->root_list.items[i - 1]; + prev->tail->jump.dst = (char*) cnt->head + sizeof(mu_JumpCommand); + } + /* make the last container's tail jump to the end of command list */ + if (i == n - 1) { + cnt->tail->jump.dst = ctx->command_list.items + ctx->command_list.idx; + } + } +} + + +void mu_set_focus(mu_Context *ctx, mu_Id id) { + ctx->focus = id; + ctx->updated_focus = 1; +} + + +/* 32bit fnv-1a hash */ +#define HASH_INITIAL 2166136261 + +static void hash(mu_Id *hash, const void *data, int size) { + const unsigned char *p = data; + while (size--) { + *hash = (*hash ^ *p++) * 16777619; + } +} + + +mu_Id mu_get_id(mu_Context *ctx, const void *data, int size) { + int idx = ctx->id_stack.idx; + mu_Id res = (idx > 0) ? ctx->id_stack.items[idx - 1] : HASH_INITIAL; + hash(&res, data, size); + ctx->last_id = res; + return res; +} + + +void mu_push_id(mu_Context *ctx, const void *data, int size) { + push(ctx->id_stack, mu_get_id(ctx, data, size)); +} + + +void mu_pop_id(mu_Context *ctx) { + pop(ctx->id_stack); +} + + +void mu_push_clip_rect(mu_Context *ctx, mu_Rect rect) { + mu_Rect last = mu_get_clip_rect(ctx); + push(ctx->clip_stack, intersect_rects(rect, last)); +} + + +void mu_pop_clip_rect(mu_Context *ctx) { + pop(ctx->clip_stack); +} + + +mu_Rect mu_get_clip_rect(mu_Context *ctx) { + expect(ctx->clip_stack.idx > 0); + return ctx->clip_stack.items[ctx->clip_stack.idx - 1]; +} + + +int mu_check_clip(mu_Context *ctx, mu_Rect r) { + mu_Rect cr = mu_get_clip_rect(ctx); + if (r.x > cr.x + cr.w || r.x + r.w < cr.x || + r.y > cr.y + cr.h || r.y + r.h < cr.y ) { return MU_CLIP_ALL; } + if (r.x >= cr.x && r.x + r.w <= cr.x + cr.w && + r.y >= cr.y && r.y + r.h <= cr.y + cr.h ) { return 0; } + return MU_CLIP_PART; +} + + +static void push_layout(mu_Context *ctx, mu_Rect body, mu_Vec2 scroll) { + mu_Layout layout; + int width = 0; + memset(&layout, 0, sizeof(layout)); + layout.body = mu_rect(body.x - scroll.x, body.y - scroll.y, body.w, body.h); + layout.max = mu_vec2(-0x1000000, -0x1000000); + push(ctx->layout_stack, layout); + mu_layout_row(ctx, 1, &width, 0); +} + + +static mu_Layout* get_layout(mu_Context *ctx) { + return &ctx->layout_stack.items[ctx->layout_stack.idx - 1]; +} + + +static void pop_container(mu_Context *ctx) { + mu_Container *cnt = mu_get_current_container(ctx); + mu_Layout *layout = get_layout(ctx); + cnt->content_size.x = layout->max.x - layout->body.x; + cnt->content_size.y = layout->max.y - layout->body.y; + /* pop container, layout and id */ + pop(ctx->container_stack); + pop(ctx->layout_stack); + mu_pop_id(ctx); +} + + +mu_Container* mu_get_current_container(mu_Context *ctx) { + expect(ctx->container_stack.idx > 0); + return ctx->container_stack.items[ ctx->container_stack.idx - 1 ]; +} + + +static mu_Container* get_container(mu_Context *ctx, mu_Id id, int opt) { + mu_Container *cnt; + /* try to get existing container from pool */ + int idx = mu_pool_get(ctx, ctx->container_pool, MU_CONTAINERPOOL_SIZE, id); + if (idx >= 0) { + if (ctx->containers[idx].open || ~opt & MU_OPT_CLOSED) { + mu_pool_update(ctx, ctx->container_pool, idx); + } + return &ctx->containers[idx]; + } + if (opt & MU_OPT_CLOSED) { return NULL; } + /* container not found in pool: init new container */ + idx = mu_pool_init(ctx, ctx->container_pool, MU_CONTAINERPOOL_SIZE, id); + cnt = &ctx->containers[idx]; + memset(cnt, 0, sizeof(*cnt)); + cnt->open = 1; + mu_bring_to_front(ctx, cnt); + return cnt; +} + + +mu_Container* mu_get_container(mu_Context *ctx, const char *name) { + mu_Id id = mu_get_id(ctx, name, strlen(name)); + return get_container(ctx, id, 0); +} + + +void mu_bring_to_front(mu_Context *ctx, mu_Container *cnt) { + cnt->zindex = ++ctx->last_zindex; +} + + +/*============================================================================ +** pool +**============================================================================*/ + +int mu_pool_init(mu_Context *ctx, mu_PoolItem *items, int len, mu_Id id) { + int i, n = -1, f = ctx->frame; + for (i = 0; i < len; i++) { + if (items[i].last_update < f) { + f = items[i].last_update; + n = i; + } + } + expect(n > -1); + items[n].id = id; + mu_pool_update(ctx, items, n); + return n; +} + + +int mu_pool_get(mu_Context *ctx, mu_PoolItem *items, int len, mu_Id id) { + int i; + unused(ctx); + for (i = 0; i < len; i++) { + if (items[i].id == id) { return i; } + } + return -1; +} + + +void mu_pool_update(mu_Context *ctx, mu_PoolItem *items, int idx) { + items[idx].last_update = ctx->frame; +} + + +/*============================================================================ +** input handlers +**============================================================================*/ + +void mu_input_mousemove(mu_Context *ctx, int x, int y) { + ctx->mouse_pos = mu_vec2(x, y); +} + + +void mu_input_mousedown(mu_Context *ctx, int x, int y, int btn) { + mu_input_mousemove(ctx, x, y); + ctx->mouse_down |= btn; + ctx->mouse_pressed |= btn; +} + + +void mu_input_mouseup(mu_Context *ctx, int x, int y, int btn) { + mu_input_mousemove(ctx, x, y); + ctx->mouse_down &= ~btn; +} + + +void mu_input_scroll(mu_Context *ctx, int x, int y) { + ctx->scroll_delta.x += x; + ctx->scroll_delta.y += y; +} + + +void mu_input_keydown(mu_Context *ctx, int key) { + ctx->key_pressed |= key; + ctx->key_down |= key; +} + + +void mu_input_keyup(mu_Context *ctx, int key) { + ctx->key_down &= ~key; +} + + +void mu_input_text(mu_Context *ctx, const char *text) { + int len = strlen(ctx->input_text); + int size = strlen(text) + 1; + expect(len + size <= (int) sizeof(ctx->input_text)); + memcpy(ctx->input_text + len, text, size); +} + + +/*============================================================================ +** commandlist +**============================================================================*/ + +mu_Command* mu_push_command(mu_Context *ctx, int type, int size) { + mu_Command *cmd = (mu_Command*) (ctx->command_list.items + ctx->command_list.idx); + expect(ctx->command_list.idx + size < MU_COMMANDLIST_SIZE); + cmd->base.type = type; + cmd->base.size = size; + ctx->command_list.idx += size; + return cmd; +} + + +int mu_next_command(mu_Context *ctx, mu_Command **cmd) { + if (*cmd) { + *cmd = (mu_Command*) (((char*) *cmd) + (*cmd)->base.size); + } else { + *cmd = (mu_Command*) ctx->command_list.items; + } + while ((char*) *cmd != ctx->command_list.items + ctx->command_list.idx) { + if ((*cmd)->type != MU_COMMAND_JUMP) { return 1; } + *cmd = (*cmd)->jump.dst; + } + return 0; +} + + +static mu_Command* push_jump(mu_Context *ctx, mu_Command *dst) { + mu_Command *cmd; + cmd = mu_push_command(ctx, MU_COMMAND_JUMP, sizeof(mu_JumpCommand)); + cmd->jump.dst = dst; + return cmd; +} + + +void mu_set_clip(mu_Context *ctx, mu_Rect rect) { + mu_Command *cmd; + cmd = mu_push_command(ctx, MU_COMMAND_CLIP, sizeof(mu_ClipCommand)); + cmd->clip.rect = rect; +} + + +void mu_draw_rect(mu_Context *ctx, mu_Rect rect, mu_Color color) { + mu_Command *cmd; + rect = intersect_rects(rect, mu_get_clip_rect(ctx)); + if (rect.w > 0 && rect.h > 0) { + cmd = mu_push_command(ctx, MU_COMMAND_RECT, sizeof(mu_RectCommand)); + cmd->rect.rect = rect; + cmd->rect.color = color; + } +} + + +void mu_draw_box(mu_Context *ctx, mu_Rect rect, mu_Color color) { + mu_draw_rect(ctx, mu_rect(rect.x + 1, rect.y, rect.w - 2, 1), color); + mu_draw_rect(ctx, mu_rect(rect.x + 1, rect.y + rect.h - 1, rect.w - 2, 1), color); + mu_draw_rect(ctx, mu_rect(rect.x, rect.y, 1, rect.h), color); + mu_draw_rect(ctx, mu_rect(rect.x + rect.w - 1, rect.y, 1, rect.h), color); +} + + +void mu_draw_text(mu_Context *ctx, mu_Font font, const char *str, int len, + mu_Vec2 pos, mu_Color color) +{ + mu_Command *cmd; + mu_Rect rect = mu_rect( + pos.x, pos.y, ctx->text_width(font, str, len), ctx->text_height(font)); + int clipped = mu_check_clip(ctx, rect); + if (clipped == MU_CLIP_ALL ) { return; } + if (clipped == MU_CLIP_PART) { mu_set_clip(ctx, mu_get_clip_rect(ctx)); } + /* add command */ + if (len < 0) { len = strlen(str); } + cmd = mu_push_command(ctx, MU_COMMAND_TEXT, sizeof(mu_TextCommand) + len); + memcpy(cmd->text.str, str, len); + cmd->text.str[len] = '\0'; + cmd->text.pos = pos; + cmd->text.color = color; + cmd->text.font = font; + /* reset clipping if it was set */ + if (clipped) { mu_set_clip(ctx, unclipped_rect); } +} + + +void mu_draw_icon(mu_Context *ctx, int id, mu_Rect rect, mu_Color color) { + mu_Command *cmd; + /* do clip command if the rect isn't fully contained within the cliprect */ + int clipped = mu_check_clip(ctx, rect); + if (clipped == MU_CLIP_ALL ) { return; } + if (clipped == MU_CLIP_PART) { mu_set_clip(ctx, mu_get_clip_rect(ctx)); } + /* do icon command */ + cmd = mu_push_command(ctx, MU_COMMAND_ICON, sizeof(mu_IconCommand)); + cmd->icon.id = id; + cmd->icon.rect = rect; + cmd->icon.color = color; + /* reset clipping if it was set */ + if (clipped) { mu_set_clip(ctx, unclipped_rect); } +} + + +/*============================================================================ +** layout +**============================================================================*/ + +enum { RELATIVE = 1, ABSOLUTE = 2 }; + + +void mu_layout_begin_column(mu_Context *ctx) { + push_layout(ctx, mu_layout_next(ctx), mu_vec2(0, 0)); +} + + +void mu_layout_end_column(mu_Context *ctx) { + mu_Layout *a, *b; + b = get_layout(ctx); + pop(ctx->layout_stack); + /* inherit position/next_row/max from child layout if they are greater */ + a = get_layout(ctx); + a->position.x = mu_max(a->position.x, b->position.x + b->body.x - a->body.x); + a->next_row = mu_max(a->next_row, b->next_row + b->body.y - a->body.y); + a->max.x = mu_max(a->max.x, b->max.x); + a->max.y = mu_max(a->max.y, b->max.y); +} + + +void mu_layout_row(mu_Context *ctx, int items, const int *widths, int height) { + mu_Layout *layout = get_layout(ctx); + if (widths) { + expect(items <= MU_MAX_WIDTHS); + memcpy(layout->widths, widths, items * sizeof(widths[0])); + } + layout->items = items; + layout->position = mu_vec2(layout->indent, layout->next_row); + layout->size.y = height; + layout->item_index = 0; +} + + +void mu_layout_width(mu_Context *ctx, int width) { + get_layout(ctx)->size.x = width; +} + + +void mu_layout_height(mu_Context *ctx, int height) { + get_layout(ctx)->size.y = height; +} + + +void mu_layout_set_next(mu_Context *ctx, mu_Rect r, int relative) { + mu_Layout *layout = get_layout(ctx); + layout->next = r; + layout->next_type = relative ? RELATIVE : ABSOLUTE; +} + + +mu_Rect mu_layout_next(mu_Context *ctx) { + mu_Layout *layout = get_layout(ctx); + mu_Style *style = ctx->style; + mu_Rect res; + + if (layout->next_type) { + /* handle rect set by `mu_layout_set_next` */ + int type = layout->next_type; + layout->next_type = 0; + res = layout->next; + if (type == ABSOLUTE) { return (ctx->last_rect = res); } + + } else { + /* handle next row */ + if (layout->item_index == layout->items) { + mu_layout_row(ctx, layout->items, NULL, layout->size.y); + } + + /* position */ + res.x = layout->position.x; + res.y = layout->position.y; + + /* size */ + res.w = layout->items > 0 ? layout->widths[layout->item_index] : layout->size.x; + res.h = layout->size.y; + if (res.w == 0) { res.w = style->size.x + style->padding * 2; } + if (res.h == 0) { res.h = style->size.y + style->padding * 2; } + if (res.w < 0) { res.w += layout->body.w - res.x + 1; } + if (res.h < 0) { res.h += layout->body.h - res.y + 1; } + + layout->item_index++; + } + + /* update position */ + layout->position.x += res.w + style->spacing; + layout->next_row = mu_max(layout->next_row, res.y + res.h + style->spacing); + + /* apply body offset */ + res.x += layout->body.x; + res.y += layout->body.y; + + /* update max position */ + layout->max.x = mu_max(layout->max.x, res.x + res.w); + layout->max.y = mu_max(layout->max.y, res.y + res.h); + + return (ctx->last_rect = res); +} + + +/*============================================================================ +** controls +**============================================================================*/ + +static int in_hover_root(mu_Context *ctx) { + int i = ctx->container_stack.idx; + while (i--) { + if (ctx->container_stack.items[i] == ctx->hover_root) { return 1; } + /* only root containers have their `head` field set; stop searching if we've + ** reached the current root container */ + if (ctx->container_stack.items[i]->head) { break; } + } + return 0; +} + + +void mu_draw_control_frame(mu_Context *ctx, mu_Id id, mu_Rect rect, + int colorid, int opt) +{ + if (opt & MU_OPT_NOFRAME) { return; } + colorid += (ctx->focus == id) ? 2 : (ctx->hover == id) ? 1 : 0; + ctx->draw_frame(ctx, rect, colorid); +} + + +void mu_draw_control_text(mu_Context *ctx, const char *str, mu_Rect rect, + int colorid, int opt) +{ + mu_Vec2 pos; + mu_Font font = ctx->style->font; + int tw = ctx->text_width(font, str, -1); + mu_push_clip_rect(ctx, rect); + pos.y = rect.y + (rect.h - ctx->text_height(font)) / 2; + if (opt & MU_OPT_ALIGNCENTER) { + pos.x = rect.x + (rect.w - tw) / 2; + } else if (opt & MU_OPT_ALIGNRIGHT) { + pos.x = rect.x + rect.w - tw - ctx->style->padding; + } else { + pos.x = rect.x + ctx->style->padding; + } + mu_draw_text(ctx, font, str, -1, pos, ctx->style->colors[colorid]); + mu_pop_clip_rect(ctx); +} + + +int mu_mouse_over(mu_Context *ctx, mu_Rect rect) { + return rect_overlaps_vec2(rect, ctx->mouse_pos) && + rect_overlaps_vec2(mu_get_clip_rect(ctx), ctx->mouse_pos) && + in_hover_root(ctx); +} + + +void mu_update_control(mu_Context *ctx, mu_Id id, mu_Rect rect, int opt) { + int mouseover = mu_mouse_over(ctx, rect); + + if (ctx->focus == id) { ctx->updated_focus = 1; } + if (opt & MU_OPT_NOINTERACT) { return; } + if (mouseover && !ctx->mouse_down) { ctx->hover = id; } + + if (ctx->focus == id) { + if (ctx->mouse_pressed && !mouseover) { mu_set_focus(ctx, 0); } + if (!ctx->mouse_down && ~opt & MU_OPT_HOLDFOCUS) { mu_set_focus(ctx, 0); } + } + + if (ctx->hover == id) { + if (ctx->mouse_pressed) { + mu_set_focus(ctx, id); + } else if (!mouseover) { + ctx->hover = 0; + } + } +} + + +void mu_text(mu_Context *ctx, const char *text) { + const char *start, *end, *p = text; + int width = -1; + mu_Font font = ctx->style->font; + mu_Color color = ctx->style->colors[MU_COLOR_TEXT]; + mu_layout_begin_column(ctx); + mu_layout_row(ctx, 1, &width, ctx->text_height(font)); + do { + mu_Rect r = mu_layout_next(ctx); + int w = 0; + start = end = p; + do { + const char* word = p; + while (*p && *p != ' ' && *p != '\n') { p++; } + w += ctx->text_width(font, word, p - word); + if (w > r.w && end != start) { break; } + w += ctx->text_width(font, p, 1); + end = p++; + } while (*end && *end != '\n'); + mu_draw_text(ctx, font, start, end - start, mu_vec2(r.x, r.y), color); + p = end + 1; + } while (*end); + mu_layout_end_column(ctx); +} + + +void mu_label(mu_Context *ctx, const char *text) { + mu_draw_control_text(ctx, text, mu_layout_next(ctx), MU_COLOR_TEXT, 0); +} + + +int mu_button_ex(mu_Context *ctx, const char *label, int icon, int opt) { + int res = 0; + mu_Id id = label ? mu_get_id(ctx, label, strlen(label)) + : mu_get_id(ctx, &icon, sizeof(icon)); + mu_Rect r = mu_layout_next(ctx); + mu_update_control(ctx, id, r, opt); + /* handle click */ + if (ctx->mouse_pressed == MU_MOUSE_LEFT && ctx->focus == id) { + res |= MU_RES_SUBMIT; + } + /* draw */ + mu_draw_control_frame(ctx, id, r, MU_COLOR_BUTTON, opt); + if (label) { mu_draw_control_text(ctx, label, r, MU_COLOR_TEXT, opt); } + if (icon) { mu_draw_icon(ctx, icon, r, ctx->style->colors[MU_COLOR_TEXT]); } + return res; +} + + +int mu_checkbox(mu_Context *ctx, const char *label, int *state) { + int res = 0; + mu_Id id = mu_get_id(ctx, &state, sizeof(state)); + mu_Rect r = mu_layout_next(ctx); + mu_Rect box = mu_rect(r.x, r.y, r.h, r.h); + mu_update_control(ctx, id, r, 0); + /* handle click */ + if (ctx->mouse_pressed == MU_MOUSE_LEFT && ctx->focus == id) { + res |= MU_RES_CHANGE; + *state = !*state; + } + /* draw */ + mu_draw_control_frame(ctx, id, box, MU_COLOR_BASE, 0); + if (*state) { + mu_draw_icon(ctx, MU_ICON_CHECK, box, ctx->style->colors[MU_COLOR_TEXT]); + } + r = mu_rect(r.x + box.w, r.y, r.w - box.w, r.h); + mu_draw_control_text(ctx, label, r, MU_COLOR_TEXT, 0); + return res; +} + + +int mu_textbox_raw(mu_Context *ctx, char *buf, int bufsz, mu_Id id, mu_Rect r, + int opt) +{ + int res = 0; + mu_update_control(ctx, id, r, opt | MU_OPT_HOLDFOCUS); + + if (ctx->focus == id) { + /* handle text input */ + int len = strlen(buf); + int n = mu_min(bufsz - len - 1, (int) strlen(ctx->input_text)); + if (n > 0) { + memcpy(buf + len, ctx->input_text, n); + len += n; + buf[len] = '\0'; + res |= MU_RES_CHANGE; + } + /* handle backspace */ + if (ctx->key_pressed & MU_KEY_BACKSPACE && len > 0) { + /* skip utf-8 continuation bytes */ + while ((buf[--len] & 0xc0) == 0x80 && len > 0); + buf[len] = '\0'; + res |= MU_RES_CHANGE; + } + /* handle return */ + if (ctx->key_pressed & MU_KEY_RETURN) { + mu_set_focus(ctx, 0); + res |= MU_RES_SUBMIT; + } + } + + /* draw */ + mu_draw_control_frame(ctx, id, r, MU_COLOR_BASE, opt); + if (ctx->focus == id) { + mu_Color color = ctx->style->colors[MU_COLOR_TEXT]; + mu_Font font = ctx->style->font; + int textw = ctx->text_width(font, buf, -1); + int texth = ctx->text_height(font); + int ofx = r.w - ctx->style->padding - textw - 1; + int textx = r.x + mu_min(ofx, ctx->style->padding); + int texty = r.y + (r.h - texth) / 2; + mu_push_clip_rect(ctx, r); + mu_draw_text(ctx, font, buf, -1, mu_vec2(textx, texty), color); + mu_draw_rect(ctx, mu_rect(textx + textw, texty, 1, texth), color); + mu_pop_clip_rect(ctx); + } else { + mu_draw_control_text(ctx, buf, r, MU_COLOR_TEXT, opt); + } + + return res; +} + + +static int number_textbox(mu_Context *ctx, mu_Real *value, mu_Rect r, mu_Id id) { + if (ctx->mouse_pressed == MU_MOUSE_LEFT && ctx->key_down & MU_KEY_SHIFT && + ctx->hover == id + ) { + ctx->number_edit = id; + sprintf(ctx->number_edit_buf, MU_REAL_FMT, *value); + } + if (ctx->number_edit == id) { + int res = mu_textbox_raw( + ctx, ctx->number_edit_buf, sizeof(ctx->number_edit_buf), id, r, 0); + if (res & MU_RES_SUBMIT || ctx->focus != id) { + *value = strtod(ctx->number_edit_buf, NULL); + ctx->number_edit = 0; + } else { + return 1; + } + } + return 0; +} + + +int mu_textbox_ex(mu_Context *ctx, char *buf, int bufsz, int opt) { + mu_Id id = mu_get_id(ctx, &buf, sizeof(buf)); + mu_Rect r = mu_layout_next(ctx); + return mu_textbox_raw(ctx, buf, bufsz, id, r, opt); +} + + +int mu_slider_ex(mu_Context *ctx, mu_Real *value, mu_Real low, mu_Real high, + mu_Real step, const char *fmt, int opt) +{ + char buf[MU_MAX_FMT + 1]; + mu_Rect thumb; + int x, w, res = 0; + mu_Real last = *value, v = last; + mu_Id id = mu_get_id(ctx, &value, sizeof(value)); + mu_Rect base = mu_layout_next(ctx); + + /* handle text input mode */ + if (number_textbox(ctx, &v, base, id)) { return res; } + + /* handle normal mode */ + mu_update_control(ctx, id, base, opt); + + /* handle input */ + if (ctx->focus == id && + (ctx->mouse_down | ctx->mouse_pressed) == MU_MOUSE_LEFT) + { + v = low + (ctx->mouse_pos.x - base.x) * (high - low) / base.w; + if (step) { v = ((long long)((v + step / 2) / step)) * step; } + } + /* clamp and store value, update res */ + *value = v = mu_clamp(v, low, high); + if (last != v) { res |= MU_RES_CHANGE; } + + /* draw base */ + mu_draw_control_frame(ctx, id, base, MU_COLOR_BASE, opt); + /* draw thumb */ + w = ctx->style->thumb_size; + x = (v - low) * (base.w - w) / (high - low); + thumb = mu_rect(base.x + x, base.y, w, base.h); + mu_draw_control_frame(ctx, id, thumb, MU_COLOR_BUTTON, opt); + /* draw text */ + sprintf(buf, fmt, v); + mu_draw_control_text(ctx, buf, base, MU_COLOR_TEXT, opt); + + return res; +} + + +int mu_number_ex(mu_Context *ctx, mu_Real *value, mu_Real step, + const char *fmt, int opt) +{ + char buf[MU_MAX_FMT + 1]; + int res = 0; + mu_Id id = mu_get_id(ctx, &value, sizeof(value)); + mu_Rect base = mu_layout_next(ctx); + mu_Real last = *value; + + /* handle text input mode */ + if (number_textbox(ctx, value, base, id)) { return res; } + + /* handle normal mode */ + mu_update_control(ctx, id, base, opt); + + /* handle input */ + if (ctx->focus == id && ctx->mouse_down == MU_MOUSE_LEFT) { + *value += ctx->mouse_delta.x * step; + } + /* set flag if value changed */ + if (*value != last) { res |= MU_RES_CHANGE; } + + /* draw base */ + mu_draw_control_frame(ctx, id, base, MU_COLOR_BASE, opt); + /* draw text */ + sprintf(buf, fmt, *value); + mu_draw_control_text(ctx, buf, base, MU_COLOR_TEXT, opt); + + return res; +} + + +static int header(mu_Context *ctx, const char *label, int istreenode, int opt) { + mu_Rect r; + int active, expanded; + mu_Id id = mu_get_id(ctx, label, strlen(label)); + int idx = mu_pool_get(ctx, ctx->treenode_pool, MU_TREENODEPOOL_SIZE, id); + int width = -1; + mu_layout_row(ctx, 1, &width, 0); + + active = (idx >= 0); + expanded = (opt & MU_OPT_EXPANDED) ? !active : active; + r = mu_layout_next(ctx); + mu_update_control(ctx, id, r, 0); + + /* handle click */ + active ^= (ctx->mouse_pressed == MU_MOUSE_LEFT && ctx->focus == id); + + /* update pool ref */ + if (idx >= 0) { + if (active) { mu_pool_update(ctx, ctx->treenode_pool, idx); } + else { memset(&ctx->treenode_pool[idx], 0, sizeof(mu_PoolItem)); } + } else if (active) { + mu_pool_init(ctx, ctx->treenode_pool, MU_TREENODEPOOL_SIZE, id); + } + + /* draw */ + if (istreenode) { + if (ctx->hover == id) { ctx->draw_frame(ctx, r, MU_COLOR_BUTTONHOVER); } + } else { + mu_draw_control_frame(ctx, id, r, MU_COLOR_BUTTON, 0); + } + mu_draw_icon( + ctx, expanded ? MU_ICON_EXPANDED : MU_ICON_COLLAPSED, + mu_rect(r.x, r.y, r.h, r.h), ctx->style->colors[MU_COLOR_TEXT]); + r.x += r.h - ctx->style->padding; + r.w -= r.h - ctx->style->padding; + mu_draw_control_text(ctx, label, r, MU_COLOR_TEXT, 0); + + return expanded ? MU_RES_ACTIVE : 0; +} + + +int mu_header_ex(mu_Context *ctx, const char *label, int opt) { + return header(ctx, label, 0, opt); +} + + +int mu_begin_treenode_ex(mu_Context *ctx, const char *label, int opt) { + int res = header(ctx, label, 1, opt); + if (res & MU_RES_ACTIVE) { + get_layout(ctx)->indent += ctx->style->indent; + push(ctx->id_stack, ctx->last_id); + } + return res; +} + + +void mu_end_treenode(mu_Context *ctx) { + get_layout(ctx)->indent -= ctx->style->indent; + mu_pop_id(ctx); +} + + +#define scrollbar(ctx, cnt, b, cs, x, y, w, h) \ + do { \ + /* only add scrollbar if content size is larger than body */ \ + int maxscroll = cs.y - b->h; \ + \ + if (maxscroll > 0 && b->h > 0) { \ + mu_Rect base, thumb; \ + mu_Id id = mu_get_id(ctx, "!scrollbar" #y, 11); \ + \ + /* get sizing / positioning */ \ + base = *b; \ + base.x = b->x + b->w; \ + base.w = ctx->style->scrollbar_size; \ + \ + /* handle input */ \ + mu_update_control(ctx, id, base, 0); \ + if (ctx->focus == id && ctx->mouse_down == MU_MOUSE_LEFT) { \ + cnt->scroll.y += ctx->mouse_delta.y * cs.y / base.h; \ + } \ + /* clamp scroll to limits */ \ + cnt->scroll.y = mu_clamp(cnt->scroll.y, 0, maxscroll); \ + \ + /* draw base and thumb */ \ + ctx->draw_frame(ctx, base, MU_COLOR_SCROLLBASE); \ + thumb = base; \ + thumb.h = mu_max(ctx->style->thumb_size, base.h * b->h / cs.y); \ + thumb.y += cnt->scroll.y * (base.h - thumb.h) / maxscroll; \ + ctx->draw_frame(ctx, thumb, MU_COLOR_SCROLLTHUMB); \ + \ + /* set this as the scroll_target (will get scrolled on mousewheel) */ \ + /* if the mouse is over it */ \ + if (mu_mouse_over(ctx, *b)) { ctx->scroll_target = cnt; } \ + } else { \ + cnt->scroll.y = 0; \ + } \ + } while (0) + + +static void scrollbars(mu_Context *ctx, mu_Container *cnt, mu_Rect *body) { + int sz = ctx->style->scrollbar_size; + mu_Vec2 cs = cnt->content_size; + cs.x += ctx->style->padding * 2; + cs.y += ctx->style->padding * 2; + mu_push_clip_rect(ctx, *body); + /* resize body to make room for scrollbars */ + if (cs.y > cnt->body.h) { body->w -= sz; } + if (cs.x > cnt->body.w) { body->h -= sz; } + /* to create a horizontal or vertical scrollbar almost-identical code is + ** used; only the references to `x|y` `w|h` need to be switched */ + scrollbar(ctx, cnt, body, cs, x, y, w, h); + scrollbar(ctx, cnt, body, cs, y, x, h, w); + mu_pop_clip_rect(ctx); +} + + +static void push_container_body( + mu_Context *ctx, mu_Container *cnt, mu_Rect body, int opt +) { + if (~opt & MU_OPT_NOSCROLL) { scrollbars(ctx, cnt, &body); } + push_layout(ctx, expand_rect(body, -ctx->style->padding), cnt->scroll); + cnt->body = body; +} + + +static void begin_root_container(mu_Context *ctx, mu_Container *cnt) { + push(ctx->container_stack, cnt); + /* push container to roots list and push head command */ + push(ctx->root_list, cnt); + cnt->head = push_jump(ctx, NULL); + /* set as hover root if the mouse is overlapping this container and it has a + ** higher zindex than the current hover root */ + if (rect_overlaps_vec2(cnt->rect, ctx->mouse_pos) && + (!ctx->next_hover_root || cnt->zindex > ctx->next_hover_root->zindex) + ) { + ctx->next_hover_root = cnt; + } + /* clipping is reset here in case a root-container is made within + ** another root-containers's begin/end block; this prevents the inner + ** root-container being clipped to the outer */ + push(ctx->clip_stack, unclipped_rect); +} + + +static void end_root_container(mu_Context *ctx) { + /* push tail 'goto' jump command and set head 'skip' command. the final steps + ** on initing these are done in mu_end() */ + mu_Container *cnt = mu_get_current_container(ctx); + cnt->tail = push_jump(ctx, NULL); + cnt->head->jump.dst = ctx->command_list.items + ctx->command_list.idx; + /* pop base clip rect and container */ + mu_pop_clip_rect(ctx); + pop_container(ctx); +} + + +int mu_begin_window_ex(mu_Context *ctx, const char *title, mu_Rect rect, int opt) { + mu_Rect body; + mu_Id id = mu_get_id(ctx, title, strlen(title)); + mu_Container *cnt = get_container(ctx, id, opt); + if (!cnt || !cnt->open) { return 0; } + push(ctx->id_stack, id); + + if (cnt->rect.w == 0) { cnt->rect = rect; } + begin_root_container(ctx, cnt); + rect = body = cnt->rect; + + /* draw frame */ + if (~opt & MU_OPT_NOFRAME) { + ctx->draw_frame(ctx, rect, MU_COLOR_WINDOWBG); + } + + /* do title bar */ + if (~opt & MU_OPT_NOTITLE) { + mu_Rect tr = rect; + tr.h = ctx->style->title_height; + ctx->draw_frame(ctx, tr, MU_COLOR_TITLEBG); + + /* do title text */ + if (~opt & MU_OPT_NOTITLE) { + mu_Id id = mu_get_id(ctx, "!title", 6); + mu_update_control(ctx, id, tr, opt); + mu_draw_control_text(ctx, title, tr, MU_COLOR_TITLETEXT, opt); + if (id == ctx->focus && ctx->mouse_down == MU_MOUSE_LEFT) { + cnt->rect.x += ctx->mouse_delta.x; + cnt->rect.y += ctx->mouse_delta.y; + } + body.y += tr.h; + body.h -= tr.h; + } + + /* do `close` button */ + if (~opt & MU_OPT_NOCLOSE) { + mu_Id id = mu_get_id(ctx, "!close", 6); + mu_Rect r = mu_rect(tr.x + tr.w - tr.h, tr.y, tr.h, tr.h); + tr.w -= r.w; + mu_draw_icon(ctx, MU_ICON_CLOSE, r, ctx->style->colors[MU_COLOR_TITLETEXT]); + mu_update_control(ctx, id, r, opt); + if (ctx->mouse_pressed == MU_MOUSE_LEFT && id == ctx->focus) { + cnt->open = 0; + } + } + } + + push_container_body(ctx, cnt, body, opt); + + /* do `resize` handle */ + if (~opt & MU_OPT_NORESIZE) { + int sz = ctx->style->title_height; + mu_Id id = mu_get_id(ctx, "!resize", 7); + mu_Rect r = mu_rect(rect.x + rect.w - sz, rect.y + rect.h - sz, sz, sz); + mu_update_control(ctx, id, r, opt); + if (id == ctx->focus && ctx->mouse_down == MU_MOUSE_LEFT) { + cnt->rect.w = mu_max(96, cnt->rect.w + ctx->mouse_delta.x); + cnt->rect.h = mu_max(64, cnt->rect.h + ctx->mouse_delta.y); + } + } + + /* resize to content size */ + if (opt & MU_OPT_AUTOSIZE) { + mu_Rect r = get_layout(ctx)->body; + cnt->rect.w = cnt->content_size.x + (cnt->rect.w - r.w); + cnt->rect.h = cnt->content_size.y + (cnt->rect.h - r.h); + } + + /* close if this is a popup window and elsewhere was clicked */ + if (opt & MU_OPT_POPUP && ctx->mouse_pressed && ctx->hover_root != cnt) { + cnt->open = 0; + } + + mu_push_clip_rect(ctx, cnt->body); + return MU_RES_ACTIVE; +} + + +void mu_end_window(mu_Context *ctx) { + mu_pop_clip_rect(ctx); + end_root_container(ctx); +} + + +void mu_open_popup(mu_Context *ctx, const char *name) { + mu_Container *cnt = mu_get_container(ctx, name); + /* set as hover root so popup isn't closed in begin_window_ex() */ + ctx->hover_root = ctx->next_hover_root = cnt; + /* position at mouse cursor, open and bring-to-front */ + cnt->rect = mu_rect(ctx->mouse_pos.x, ctx->mouse_pos.y, 1, 1); + cnt->open = 1; + mu_bring_to_front(ctx, cnt); +} + + +int mu_begin_popup(mu_Context *ctx, const char *name) { + int opt = MU_OPT_POPUP | MU_OPT_AUTOSIZE | MU_OPT_NORESIZE | + MU_OPT_NOSCROLL | MU_OPT_NOTITLE | MU_OPT_CLOSED; + return mu_begin_window_ex(ctx, name, mu_rect(0, 0, 0, 0), opt); +} + + +void mu_end_popup(mu_Context *ctx) { + mu_end_window(ctx); +} + + +void mu_begin_panel_ex(mu_Context *ctx, const char *name, int opt) { + mu_Container *cnt; + mu_push_id(ctx, name, strlen(name)); + cnt = get_container(ctx, ctx->last_id, opt); + cnt->rect = mu_layout_next(ctx); + if (~opt & MU_OPT_NOFRAME) { + ctx->draw_frame(ctx, cnt->rect, MU_COLOR_PANELBG); + } + push(ctx->container_stack, cnt); + push_container_body(ctx, cnt, cnt->rect, opt); + mu_push_clip_rect(ctx, cnt->body); +} + + +void mu_end_panel(mu_Context *ctx) { + mu_pop_clip_rect(ctx); + pop_container(ctx); +} diff --git a/microui/microui.h b/microui/microui.h new file mode 100644 index 0000000..6e18639 --- /dev/null +++ b/microui/microui.h @@ -0,0 +1,296 @@ +/* +** Copyright (c) 2024 rxi +** +** This library is free software; you can redistribute it and/or modify it +** under the terms of the MIT license. See `microui.c` for details. +*/ + +#ifndef MICROUI_H +#define MICROUI_H + +#define MU_VERSION "2.02" + +#define MU_COMMANDLIST_SIZE (256 * 1024) +#define MU_ROOTLIST_SIZE 32 +#define MU_CONTAINERSTACK_SIZE 32 +#define MU_CLIPSTACK_SIZE 32 +#define MU_IDSTACK_SIZE 32 +#define MU_LAYOUTSTACK_SIZE 16 +#define MU_CONTAINERPOOL_SIZE 48 +#define MU_TREENODEPOOL_SIZE 48 +#define MU_MAX_WIDTHS 16 +#define MU_REAL float +#define MU_REAL_FMT "%.3g" +#define MU_SLIDER_FMT "%.2f" +#define MU_MAX_FMT 127 + +#define mu_stack(T, n) struct { int idx; T items[n]; } +#define mu_min(a, b) ((a) < (b) ? (a) : (b)) +#define mu_max(a, b) ((a) > (b) ? (a) : (b)) +#define mu_clamp(x, a, b) mu_min(b, mu_max(a, x)) + +enum { + MU_CLIP_PART = 1, + MU_CLIP_ALL +}; + +enum { + MU_COMMAND_JUMP = 1, + MU_COMMAND_CLIP, + MU_COMMAND_RECT, + MU_COMMAND_TEXT, + MU_COMMAND_ICON, + MU_COMMAND_MAX +}; + +enum { + MU_COLOR_TEXT, + MU_COLOR_BORDER, + MU_COLOR_WINDOWBG, + MU_COLOR_TITLEBG, + MU_COLOR_TITLETEXT, + MU_COLOR_PANELBG, + MU_COLOR_BUTTON, + MU_COLOR_BUTTONHOVER, + MU_COLOR_BUTTONFOCUS, + MU_COLOR_BASE, + MU_COLOR_BASEHOVER, + MU_COLOR_BASEFOCUS, + MU_COLOR_SCROLLBASE, + MU_COLOR_SCROLLTHUMB, + MU_COLOR_MAX +}; + +enum { + MU_ICON_CLOSE = 1, + MU_ICON_CHECK, + MU_ICON_COLLAPSED, + MU_ICON_EXPANDED, + MU_ICON_MAX +}; + +enum { + MU_RES_ACTIVE = (1 << 0), + MU_RES_SUBMIT = (1 << 1), + MU_RES_CHANGE = (1 << 2) +}; + +enum { + MU_OPT_ALIGNCENTER = (1 << 0), + MU_OPT_ALIGNRIGHT = (1 << 1), + MU_OPT_NOINTERACT = (1 << 2), + MU_OPT_NOFRAME = (1 << 3), + MU_OPT_NORESIZE = (1 << 4), + MU_OPT_NOSCROLL = (1 << 5), + MU_OPT_NOCLOSE = (1 << 6), + MU_OPT_NOTITLE = (1 << 7), + MU_OPT_HOLDFOCUS = (1 << 8), + MU_OPT_AUTOSIZE = (1 << 9), + MU_OPT_POPUP = (1 << 10), + MU_OPT_CLOSED = (1 << 11), + MU_OPT_EXPANDED = (1 << 12) +}; + +enum { + MU_MOUSE_LEFT = (1 << 0), + MU_MOUSE_RIGHT = (1 << 1), + MU_MOUSE_MIDDLE = (1 << 2) +}; + +enum { + MU_KEY_SHIFT = (1 << 0), + MU_KEY_CTRL = (1 << 1), + MU_KEY_ALT = (1 << 2), + MU_KEY_BACKSPACE = (1 << 3), + MU_KEY_RETURN = (1 << 4) +}; + + +typedef struct mu_Context mu_Context; +typedef unsigned mu_Id; +typedef MU_REAL mu_Real; +typedef void* mu_Font; + +typedef struct { int x, y; } mu_Vec2; +typedef struct { int x, y, w, h; } mu_Rect; +typedef struct { unsigned char r, g, b, a; } mu_Color; +typedef struct { mu_Id id; int last_update; } mu_PoolItem; + +typedef struct { int type, size; } mu_BaseCommand; +typedef struct { mu_BaseCommand base; void *dst; } mu_JumpCommand; +typedef struct { mu_BaseCommand base; mu_Rect rect; } mu_ClipCommand; +typedef struct { mu_BaseCommand base; mu_Rect rect; mu_Color color; } mu_RectCommand; +typedef struct { mu_BaseCommand base; mu_Font font; mu_Vec2 pos; mu_Color color; char str[1]; } mu_TextCommand; +typedef struct { mu_BaseCommand base; mu_Rect rect; int id; mu_Color color; } mu_IconCommand; + +typedef union { + int type; + mu_BaseCommand base; + mu_JumpCommand jump; + mu_ClipCommand clip; + mu_RectCommand rect; + mu_TextCommand text; + mu_IconCommand icon; +} mu_Command; + +typedef struct { + mu_Rect body; + mu_Rect next; + mu_Vec2 position; + mu_Vec2 size; + mu_Vec2 max; + int widths[MU_MAX_WIDTHS]; + int items; + int item_index; + int next_row; + int next_type; + int indent; +} mu_Layout; + +typedef struct { + mu_Command *head, *tail; + mu_Rect rect; + mu_Rect body; + mu_Vec2 content_size; + mu_Vec2 scroll; + int zindex; + int open; +} mu_Container; + +typedef struct { + mu_Font font; + mu_Vec2 size; + int padding; + int spacing; + int indent; + int title_height; + int scrollbar_size; + int thumb_size; + mu_Color colors[MU_COLOR_MAX]; +} mu_Style; + +struct mu_Context { + /* callbacks */ + int (*text_width)(mu_Font font, const char *str, int len); + int (*text_height)(mu_Font font); + void (*draw_frame)(mu_Context *ctx, mu_Rect rect, int colorid); + /* core state */ + mu_Style _style; + mu_Style *style; + mu_Id hover; + mu_Id focus; + mu_Id last_id; + mu_Rect last_rect; + int last_zindex; + int updated_focus; + int frame; + mu_Container *hover_root; + mu_Container *next_hover_root; + mu_Container *scroll_target; + char number_edit_buf[MU_MAX_FMT]; + mu_Id number_edit; + /* stacks */ + mu_stack(char, MU_COMMANDLIST_SIZE) command_list; + mu_stack(mu_Container*, MU_ROOTLIST_SIZE) root_list; + mu_stack(mu_Container*, MU_CONTAINERSTACK_SIZE) container_stack; + mu_stack(mu_Rect, MU_CLIPSTACK_SIZE) clip_stack; + mu_stack(mu_Id, MU_IDSTACK_SIZE) id_stack; + mu_stack(mu_Layout, MU_LAYOUTSTACK_SIZE) layout_stack; + /* retained state pools */ + mu_PoolItem container_pool[MU_CONTAINERPOOL_SIZE]; + mu_Container containers[MU_CONTAINERPOOL_SIZE]; + mu_PoolItem treenode_pool[MU_TREENODEPOOL_SIZE]; + /* input state */ + mu_Vec2 mouse_pos; + mu_Vec2 last_mouse_pos; + mu_Vec2 mouse_delta; + mu_Vec2 scroll_delta; + int mouse_down; + int mouse_pressed; + int key_down; + int key_pressed; + char input_text[32]; +}; + + +mu_Vec2 mu_vec2(int x, int y); +mu_Rect mu_rect(int x, int y, int w, int h); +mu_Color mu_color(int r, int g, int b, int a); + +void mu_init(mu_Context *ctx); +void mu_begin(mu_Context *ctx); +void mu_end(mu_Context *ctx); +void mu_set_focus(mu_Context *ctx, mu_Id id); +mu_Id mu_get_id(mu_Context *ctx, const void *data, int size); +void mu_push_id(mu_Context *ctx, const void *data, int size); +void mu_pop_id(mu_Context *ctx); +void mu_push_clip_rect(mu_Context *ctx, mu_Rect rect); +void mu_pop_clip_rect(mu_Context *ctx); +mu_Rect mu_get_clip_rect(mu_Context *ctx); +int mu_check_clip(mu_Context *ctx, mu_Rect r); +mu_Container* mu_get_current_container(mu_Context *ctx); +mu_Container* mu_get_container(mu_Context *ctx, const char *name); +void mu_bring_to_front(mu_Context *ctx, mu_Container *cnt); + +int mu_pool_init(mu_Context *ctx, mu_PoolItem *items, int len, mu_Id id); +int mu_pool_get(mu_Context *ctx, mu_PoolItem *items, int len, mu_Id id); +void mu_pool_update(mu_Context *ctx, mu_PoolItem *items, int idx); + +void mu_input_mousemove(mu_Context *ctx, int x, int y); +void mu_input_mousedown(mu_Context *ctx, int x, int y, int btn); +void mu_input_mouseup(mu_Context *ctx, int x, int y, int btn); +void mu_input_scroll(mu_Context *ctx, int x, int y); +void mu_input_keydown(mu_Context *ctx, int key); +void mu_input_keyup(mu_Context *ctx, int key); +void mu_input_text(mu_Context *ctx, const char *text); + +mu_Command* mu_push_command(mu_Context *ctx, int type, int size); +int mu_next_command(mu_Context *ctx, mu_Command **cmd); +void mu_set_clip(mu_Context *ctx, mu_Rect rect); +void mu_draw_rect(mu_Context *ctx, mu_Rect rect, mu_Color color); +void mu_draw_box(mu_Context *ctx, mu_Rect rect, mu_Color color); +void mu_draw_text(mu_Context *ctx, mu_Font font, const char *str, int len, mu_Vec2 pos, mu_Color color); +void mu_draw_icon(mu_Context *ctx, int id, mu_Rect rect, mu_Color color); + +void mu_layout_row(mu_Context *ctx, int items, const int *widths, int height); +void mu_layout_width(mu_Context *ctx, int width); +void mu_layout_height(mu_Context *ctx, int height); +void mu_layout_begin_column(mu_Context *ctx); +void mu_layout_end_column(mu_Context *ctx); +void mu_layout_set_next(mu_Context *ctx, mu_Rect r, int relative); +mu_Rect mu_layout_next(mu_Context *ctx); + +void mu_draw_control_frame(mu_Context *ctx, mu_Id id, mu_Rect rect, int colorid, int opt); +void mu_draw_control_text(mu_Context *ctx, const char *str, mu_Rect rect, int colorid, int opt); +int mu_mouse_over(mu_Context *ctx, mu_Rect rect); +void mu_update_control(mu_Context *ctx, mu_Id id, mu_Rect rect, int opt); + +#define mu_button(ctx, label) mu_button_ex(ctx, label, 0, MU_OPT_ALIGNCENTER) +#define mu_textbox(ctx, buf, bufsz) mu_textbox_ex(ctx, buf, bufsz, 0) +#define mu_slider(ctx, value, lo, hi) mu_slider_ex(ctx, value, lo, hi, 0, MU_SLIDER_FMT, MU_OPT_ALIGNCENTER) +#define mu_number(ctx, value, step) mu_number_ex(ctx, value, step, MU_SLIDER_FMT, MU_OPT_ALIGNCENTER) +#define mu_header(ctx, label) mu_header_ex(ctx, label, 0) +#define mu_begin_treenode(ctx, label) mu_begin_treenode_ex(ctx, label, 0) +#define mu_begin_window(ctx, title, rect) mu_begin_window_ex(ctx, title, rect, 0) +#define mu_begin_panel(ctx, name) mu_begin_panel_ex(ctx, name, 0) + +void mu_text(mu_Context *ctx, const char *text); +void mu_label(mu_Context *ctx, const char *text); +int mu_button_ex(mu_Context *ctx, const char *label, int icon, int opt); +int mu_checkbox(mu_Context *ctx, const char *label, int *state); +int mu_textbox_raw(mu_Context *ctx, char *buf, int bufsz, mu_Id id, mu_Rect r, int opt); +int mu_textbox_ex(mu_Context *ctx, char *buf, int bufsz, int opt); +int mu_slider_ex(mu_Context *ctx, mu_Real *value, mu_Real low, mu_Real high, mu_Real step, const char *fmt, int opt); +int mu_number_ex(mu_Context *ctx, mu_Real *value, mu_Real step, const char *fmt, int opt); +int mu_header_ex(mu_Context *ctx, const char *label, int opt); +int mu_begin_treenode_ex(mu_Context *ctx, const char *label, int opt); +void mu_end_treenode(mu_Context *ctx); +int mu_begin_window_ex(mu_Context *ctx, const char *title, mu_Rect rect, int opt); +void mu_end_window(mu_Context *ctx); +void mu_open_popup(mu_Context *ctx, const char *name); +int mu_begin_popup(mu_Context *ctx, const char *name); +void mu_end_popup(mu_Context *ctx); +void mu_begin_panel_ex(mu_Context *ctx, const char *name, int opt); +void mu_end_panel(mu_Context *ctx); + +#endif diff --git a/src/a.out b/src/a.out new file mode 100755 index 0000000000000000000000000000000000000000..badfdd467970999d55fe185913e165be018d99ac GIT binary patch literal 147176 zcmeEv3tUvy_WvFpii!@VCi%#*e5NTrFrS6W=vY#eQdXKGpi&5298yaZLyGA*MGuR* zJ?w2=E9?Lv+4CK*|?R4^6;s5-kj9Xh@LqHTNm)ASnhEVKPnmg6YvlU-;Pg+Y85K$g}~? z`MA8bI)4Kg(N*FNXwFBrS-V}**M8~`vtwksc1{=hpzBHIqI?_ld>iz91`N~fX+XoC zq$B-})a}_2MuA43DE=0rVZJ4LzJ@Sb=QkjgL7!KOpykhdzX(KjTB{kH#PIuzh3!Tr0wl`b{y05K@gl>w&tYFT7R?Kc|^;A8dyIbTjxr zn!(@S48B`4nV;wawtyG=smlnR2%^Q|{Pi`1?1*e`PcLmo>wm)(n4fGx~=#!%yK- zdvTetbwxq=81t=|J$wGbwA9&)obegX*|Wv$Dbr(SCnjYi%}-wBOv;!ZGchGCHEDYM z+>|6qYmzc8dg|VW7RRTX=u=XYy(F1= zVp^&*X^B(JPq{TYX>od520g~6rN_iOGm@9!*`CUZ%ukt`7N0mJ5weq=OM#!9lsX+5 zGc%GFQRbu!h>1;0hO`W%CqO5ijMPmT&IM_JQr5(jWJsCjgzCUeOi7B*n3$H5M%j=h zHa;VMVG^Vy6Or&fsZyz!v_#4noxDibEH-n|09H#ygYKQbqh+ zBBE&YrJ+|39TY*qP6Qz)Po>8p^th0oM$l7&e40FU%7lrthYlJtTo{kTe2>1TA=h~6 zLkC6Dh_Fyhgg^R^U?9HfKLaai5-0JJ;^UIM249e#o45>qdJe{43;aX~L@}{1qmAtqFgn314Tz>n=u8 zbw5CTt+$Ck#Dwo-!iSmgeNFgq6TY7bZ!_WhoACWi_^V9#2orvQ2|v<=r?rCdi8A4@ zHjsc06Mm2hA8W!7HsNQO@DV2b920(s3BSOEA8Nv9eaw@mT8K9Lpa*9Lta8@nyW1zL(`|)k<5rrp8FCdzyLc^!`Zc5XZil>az zTPaOjDV`!uzfWn}Lh)?i^jnmstrO2$PQOfP+A{IvbNX3I(^iQmo70a|nwG7ebWT4^ zY1$g`%;EF{l%_2aPb{bJqcm-Wc%nF+L2258@Pw6sFkES$jad?V2J(SY4wc**o>8mJBTN<9V zoW6q6w3Xq>=X4iJ(-wv&o70z2nzk-H>6~s&Y1%sT%;9tZrD+Sp6U*s8-a(qSE<913 z{*BVKrRIs?bQPs(E6ro$^pBLLEe%f?r@y8&ZDn`_rw>w^wlF-k=c)c5Q`$!93Qq5) zG;LXU$~e81(zI3KDdP0|l%_2T&jwDvMQPfa@T}$Z%ao=q2~R$!pQSWyMR>9~{Wzs* z3&NAm>4zyzTMwQ&oPL1PwB_K5<@9}&rmY4~6sI#NO3x(zK=E z3FGt~lpaKB!RcElJ($w9_1ylHrmX`{1*a!adI+V|a2<8FbtvQReVbHV3zV7wTkH+4JcI4j zS$ll??wRL%CVxTlJoCXD2N@-HI^Gx6BNcm{BcaUUDsxzh9G2av-9`x78x#=HnDTd> zl4Gy4tjwy@AYl2<5_`QNslI`v`+hehHKfGrlpK4#B`2%Cn;f zQp;v#U*4?j;3i~$kJ>`^VF`W*u;@j&>hkP0*3I^sJiC^ir9~}ojf9q?wnSP!MbOg@ zyCzkFhYokRvQ*Gi>y9Ek4&cbw70IcIux<|app)g)T2>WV zb1N_(0P`*|*3F&Xq@KI$#}G%W-9SFasfsX1D|DC=^*Ef8%YJBO)}iwdyF7Gn@LDhk z&kGQt*bg=646{y=#LxiiW@muKvFm5ZJYn4&9T4EyMG{L%;@??fIWp%ISsLW;{ulD! z$@!0P{(uJgzdiZy%kRqhD>#2(gZ$6`h5X;ZO}XrqN=&5^2PsFmVYV$X+5WaVO=Iyv zE_+!{R(Xi^p-E^Q#a`}kcg&^cK~uhi97<4tqX5nKGUc|EX%%~eCt&!IVUg3*o-(nO&_{rzuL`{A(uGP3?LSpR~_`nA-DT%W14Q31~;gbe-?NcQuP zAZ43NCD~7${!6k0N%rk5`;a?5P_dikPzg6c4wc|Y_|oi;di^!kUxiEe(A}QKf`3ET zY1%C1+^PPpSsWz$1(w~=uuuJkZdrVex<#3XZjShCN9LRU7bHBu5>ENI3T5v67c$#9 zGdTpf1&eeLZ2uX0H{3rw6m^8J)ccUfgQ=|veP8_x1K}WCjLWVz)_4A2$h?L# z*C=*%fW5|Luf;%Wplwe>+ghpZe&ndO+M!ld*lf;G9E|vurCx;5+cg8k{*rmMP82Diu!3*H+JW;f&0O zlFNyg^G~4sR9-A{p}caIM`W+O*IC~FoUHv)-gc)f=N+HC3d+Fpx*~r$$t#lbDxiOb z$PDr-Jl&zhp^%s|Fjnk9cV(S3WNlT>J<6^+uSVRm@E0QP+Dh@PxlIwE4P{jAt)-(e}S7ZcJ0KY)H$OpQ*%#ZqS7 zEb{C-v$J*%UVaI_M=fuG?u&qiBGUR_uz}R&X;h7B@5u-2%B&)uXZwTy5#mSnC|otFx0^GUs1x)|)puoQ?GVnk znEH3-*-xVi2&iP@4An=m7nwRP4c8fvYW*PQ^gI_$gfVCHrUnG$*o!RaygBw_WGIHy zA7wAMK3b2d2%>iIwCwB)jp}QpMikH+8qLu)+JN??YH)vahQe&zZKhB&Qxh|)f?B@M zNtU}Ea;=+-(A;&2jsYFH`#XbG6;yq2tgMN}9OH0pFNE`JI7D*y0EtnOTM7t$MD}*V z2xpW-$)yY!F2^z`I}exm->CaCvm<9a=gGVj=Gez9C8~wgXPJf|>#7L!my+CKUB0IT zg(zz%=_<1nS>UtQ&>{fl!m}&4oSqd4D0Xn=(vkoe1`?wJqp-vVt+KnCCa{hHx`4c} zCb^#Xagk7P>FVsN>#<9{+_F38$H4x(U1d3SftfA0(z3TYc&iNnVyWo7upBPjvT{3B zgUn`qq(2@U${I3>!=1}Davj)8LuUtFNTwD$B#lQ)8W@j&VB`JcZ<1aNx^6tfxK1m| zWSPhx4Z3wRTes;(KY7Av^l1n>7r-SJA~@aPid*lBSvS>X&!6gwDbUBJVh_vSZ*lEH z56egADNr)kIh3rz@h-$~2OO^5>UU$Q!uCQXdlf1%%D&E;YejW{+CY{0pqAaAVqZVN zUh3LIoQ~ibJ%YHV&w@B=&x$sZnxk5(FY#ws%DLIuEuT*$>*j3AoM+#YowaAq@-TeQ zTR{>0o*dOCv4hD?>>0H@6yH(Hhv0kCiUEqfl==WEWkFuILznGEOdL}j zM8zoC(@{!JMF_?QiCl&j10}zYu z+U4nCDLue(MFmRcI&n5GSWW7QaVvx2FVX&YcBUHcQnH|X9JI`2rN_H|pW-UrBK0j% z@4%W~i9;A)<{lfM#2vyUpbrYyUNsUD5MWclO3Fdz`a#lE^!z!BtL|$uFN#1h)I(uk znAfoHT_Yg|?pB#q=ZyxU(DgArW|q0)_Pb(A9d4cn%eT@Nm$ajL=5iri_8Jt;^XQJ@ zM6uU8Tyb?MsSNm9@~KKpO|%lX9|f1wmR>YE*7(>dt|IIjW$Stz2O2bAWX7N(wf^U$ZRD%87 zknXr5yZs}~cappfOIYkiT@YH3`L_`N4vMFU zwGdl9Sd|X+2(bzqFwk*3|Gz(&wlgo=aruoaJL=Ax_^;3kBVGkWB2k7_Gys zFM>74o{eph?3T-4^3qDwpI{k1Y1r+Tdw`O5yXOusm27kLN}|};8u=07GcOnM5HC|# z`)D8dX!kHJAH8j@5*u!?phvUzJH+<q~hNJru+mk?%`qP`fbIuPqNkdSc2ss6Ecpm7cAQbb6D)FR%We| zkwXZLcB4dW``k{|U+LUf6Jn?9-v&Bc00)m-+b(%zVGgf1;| zBTFk$$Dv-B*ILWE-&*6FaCEMNB{L zErQH)WQI4hQPHb>6-~U2YPepn;d-MK6sX6{kdS?~R{}eft#k$1;f_342>|-oYkhRH zdY>p5Wmp{c;NeHryRS5q@g4$~~wN7l$%&?Mx@DMF~hCN27zip(pq zuO?e_k6xYC4^Duiuv|ZG+RRL+fdN$uplWqb;wzA|&|+?CVu{gNGQk4F_=zY{yVYtM zdTB?w3f+P+C2cJ{nznNYb_3KHsHAin^Aywx9)fQdg(t6rapw}mdg=>DsjBw1Fwt7l zWN3S`Kc3y4XqVFA!l30;DW_sXJTIfKV8u5sFbJM#l^b@Dj}N&(7#Bd;hnCZ$g&uR( z6NA8`b1DPtL$pF37YGfUiy2rSqF02*(Isi;pTS{dZjS*#BYM#{4fg5>1A zwGvf|L)>+m9)>^hxDqI6Ig?RVP?a>vBDRKC-qgS!+Be7R<(i#@L z{Rx31nt^5X{I-0qrRV46bI}%Z`zUpOD1&R;Kq3Mq(%Z8UUnE{Zw+MFLjW6q?Yk|wD z3v!0z%lhc!oCZaU+={^c$pLc?1g}`F7WsnZRL~~#? z6a6y^1CPT<)z=wxlA$aOSFZ0S*B8Ww+U-`)kr?EqVrbz(gs&)nWNUI@ZdSoC#rtR_ zYLg*w9_pp2pyv$=lpE|(M5AH6uFB@hs&Qqi4dPt|`-Z^-zoGG{x`O-CL#Lkf9o!k; zB*Umr#I+n2|YbePxsQ(6L><`J4Ia& z{Y0n}P(#Ij3Q5lWIV9350$s1}F(G0XSm68@w786F0(LRJ5K_bz`r1lZ8P0Ro5UNj3 zv2Cm9Lla;>D9-pI;3ZCYaqEFopN1~*n{?8&G7+5$CPI{rkr5onN%Fk6@)M>c@aCgw z{pO(8p{#5jCHSr5U3jTLZ}cji)*hw?cnaSQ)*L^P#Vnms@h#s&g;hwZH$gV`7{NTx z`s=>mtXGvP!FS435mNXI>t3B81YjqE^Q`@<@%JORzX3dezf!bdIguRJ)FSl-2;3>C zkm*!N4=SVzPpD7eaamE+Q|xE~+wP?Pp>F$*sYh!<*bEJ*?H~YoOKQS=RBD%<@NPnl z1y$+vR!tWncdOuX$#T!sbY$*eFJoV?TH8^aT1rVa#XFSTf@DeXY>1%`yqEV3GS=a$ zo8me_U4}?gX;5PM$?I3FyRdqVcG*hWw~oxrnKaYPEi6+mDU%@zC=9^hkP=Ax5m1~{m;%jS~fx@*@-YkS(O zFE-QWm}oeCC^gffO|&}2zTZsiXQI{99xyGja;c`U;*x3!lSTWJ*6{H|g&lPcR> z=vR!34MLCmp$R;><9$uwLxF$K53f?Bop2B*kQ5xF2X}f*?I>J9?J+yKW3j%gp`mra zuVK=NBNR%21K;2XXuuKEh$FB8#{d%tj$0ukr~yYS6Nl6zxBI zTKJHw;yMXeQ{iyUQeD`ui#Y<9``Ra{qSEPg23Zxf#pl}{z7}g*Oc|y>Xzo zx#F@{2v?aX46z*B$}rkrw|2qF0FU4-PgYju`za<2MYiR=yGZ}e59D%~+#cYGXT8cfe ziPxYOOK^(FdzvbprdCi?nS;TjYe2UsZbt-@Z!#Jxxu358P*7APm#wbfQ0@klTL@iH=@s?n>8SyNwCaQl}zlblp~P& zohIT;OpItVWtNKA1_$lqNw1F`uEP|TJ^#CZ17Tazm5Iivg-yxu$YZaoo`$EoMon;y zj&0Ngrx46EXo737YQYr;i@jD_ua2xoBC(U#7DLY+tGVJTbBi+9pcUk-S9l3j@J@hX z+zl}S8sjXP8JlXx779DOUvC7wZmc5(HlXAxw7ijsmOu_ z4*qy*(<6+wZ{A4}#$CJMJ-+$PdIx%)9k(X@SRVAT90UuNNcQs$SQ30Jm0+m=OML^D zC?Cslu&DE_%T;SXOo@nGrhi3|OBAAtkH7RPu0D%pgF^|vsZxfh*MZ5n(Zmrkg}}H3 zWLI(Th)gRDC!=Lp7NeFqYMBG}sbua7$<6(~$sBofi%HG1pGS^7`vo|7+>U~ECG)@W z547iS#Bz`?sK6=Wk$i3C0J4-vtk4*IAO>Y&qNqntO)u{G$5DOciX zrorh%%xJQaYD;wgL#c^sFP*mqYfy% z3~N@5SVNzzmb`YX4(6Q;pGkBh(|G}m(!im>9&zO^9FL%~bdI3J;lj#6N6zjLWokaw zUvxx4C;WT>q-J!Yg?VMDGZx=%o!8?#&>3yywQi0YjNuq5(=(R9Z6LS3oR25hnefLvxH{I#C zwj3@8vd^$Nl(uh5>{}As57-D`Uy;~XC3YmRQNTVgu`fuh1K3z#pO)AHiJbxL9AF=l z*vBPy0kG*(E!qJmQ^hXH_f-h>2}6A_F(8=4{ub6txRFWEQ6WfV4x@1iQB$#xg-yII z3b{^qr##xwb4NZ;z}Pwt{{m6|D+k#MbtT!+wEQD(NGr*9&~}QRa+G9qH!zY)KCS$@ zR9F5w0_XG5#lHU);CLSd_0#E&E*Qd^vKhnVF4>X>#hnwhQz1UYF2@#6SMhU}h z>h~A9d_^d+QFy9_EtIGzIzse$1GEOFcg)^Ob}Tl2U@EfCko|0(?YF`@FOs(IPIu!O z)>%Qou+AUo9%}9Zwhjc$z|NX3pcc^u%=;_}SStnemjbRe3)n&eqP+rU273j(D+Oeb zfS05IHI6knPr%S%2?+@F3aIc2NRRFgxzsu!$8zpdl%o^~CD|h$HCPZ`@Mzg(~Z*pD96$*A>90I2zRZb(^t@|Zc zY)JKRI+l(lw}ra`4W(4b9AN->ggeOD4dJmN6oaakQTDP-+~h$>)38BoW7jDYLaU{37Xh>;t*%SD=7NWbtFgbDzb_Ct&(|ki7t_#bFH?smV z8|=EV;A|RXm@9L#PKo7RFk?zvsnS-{@%xrabbc5nwU3_fwvy*zsD^OVO~D(VRZT=~ z6}}g(y7Kc-8FnrH_mrYO^G&$CB$21*vYx8KO61h_SWeESxI{XeTQE{7j72Xwe=~u| zOMvnYbvHz+;h*wIRh0s&2Bu>fD$^9ex}C*zhYp9@eBxNSi)!PFewbQYFH<^8=uO%4 zO)X}cGNg97MJq_TzEZg?Qtq@=ZjMwglYrreYX1f0?#H=0HJcP5?Fx6!MH$gYP7Qh7 zat;k}aBmKdi_p{8n~O(c8FQq^=Mo58mTR8NCLbzq=YfI`8AcPm}Rn< zyQ!F9SL*Z=E}IFr{gI^oKia_Tg$?IT%JRL4I` z&9yOpO+N+vZ)t+yNBbu z|G$*&Bwt~<{Xe74W>uV|p2m_Kt~E12CRtck;Y%&y3wF4jq2!XnN;XaNIdxX{9uMx} z&h;pocuN=A>N{h&)ejLcTKy*UEA{JAYITzk+$&%c6gZNLr~-6XF_@$~6m&geex7te zgo~Yt88~)x&ym;#65A2jZosBX>=KFX1uW*`7$`g|4|#_pJr-#iD+NeLBRv)AwMef+ zdOFfGk=}rGA<~IRryyN~G=`$XiS#n0_alAC;mXSRzgmAwZw%T=^tTqGiO$a>q)!)NQs5ka9Dn+=tC_gGp|_ zS1t+g%9UM5dV$wyr^f3!!eAF!Z*x`l6>(LvsK_C*$N*VnXLFH{qu;9CWs&fVq`mGL zrOUcLn|eZYS%|kdZU$@&x#B9Qo(}hhSKHBi$?HypUlHgFVb_g7Z2|gU|utde= zN*WlW!RXua5?}>!Jp2)kps{G9-8#y~A&3)`CcR4*Q%^|VOO%9o?F1~=`wnk zb1H%bG6tiKCk%n8rlUJ-tl%v{3@N>b)A|nu<4P1BM0FHdhK^D&EwaoCG^Y|3G|FDT z+|~?@^v1cSy)MUo3ehe0R*ozy%*m<~ODPuW3d3PhS93jj>s;Aer^B8Yc*z8efmaEu zsA+rPsA2O43Sc{_99#EfXFsD&gNi;=`=Vm5V?9-%x)-L&hT_T;++Z%x34v5q5gM?yuFM*azh+@ON~Qfcx`Q&Z z1{Qba(4r^bQW9eQ36yLqKjE=L^66@3^dE4l?;3iC-88~zsPZTbLXr+>(0A#Kpx%NT z{x*&c?*5QF>_qg=Ep+<_f#)lB?y!Xfj1D^teO292L>-pjgJrLiNB7oc54P-*Me)6h z5nwi~scUHVv-$eE5mOeg8|CW{tgH&NLJ4SXDI2G0fr5413lD)o_1R?T__owhi)I}= znss~>l~lVxN478ahr{GUg$oB@P}nD%+5!t4F5Nt&>aZ(I9tVHCCDubelN>_9Ghl3R zgCiacs~!V97NACb7)NVk=B3+BPJR1xoQ_1W9Kw&R8rVoOBp54cbbP}irH)a%Gylnv zX@kH)zhS*K3?p8?LxTaAPm4O;fx}0m(YYj_V~)Vkfcu4x&4uM#!$}~;)8x0W^9qci zUQ`C5EsdB!WrDgsV@8aXuR

EP=4N3-$r*@O*C>Uj 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 Le>PGfa_RhEvK{sF literal 0 HcmV?d00001 diff --git a/src/atlas.inl b/src/atlas.inl new file mode 100644 index 0000000..8e9e5d3 --- /dev/null +++ b/src/atlas.inl @@ -0,0 +1,995 @@ + +enum { ATLAS_WHITE = MU_ICON_MAX, ATLAS_FONT }; +enum { ATLAS_WIDTH = 128, ATLAS_HEIGHT = 128 }; + + +static unsigned char atlas_texture[ATLAS_WIDTH * ATLAS_HEIGHT] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xc0, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x32, 0x0b, 0x00, 0x00, 0x00, + 0x00, 0x31, 0x35, 0x01, 0x00, 0x00, 0x00, 0x15, 0x35, 0x1d, 0x30, 0x19, + 0x00, 0x00, 0x0f, 0x35, 0x06, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x2d, 0x00, 0x00, 0x00, + 0x14, 0x26, 0x00, 0x00, 0x31, 0x2a, 0x00, 0x00, 0x00, 0x10, 0x31, 0x00, + 0x00, 0x00, 0x00, 0x06, 0x3e, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x06, 0x3e, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x40, 0x0d, 0x00, 0x00, 0x00, 0x00, + 0x31, 0x35, 0x2f, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x41, + 0x37, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x21, 0xe0, 0xea, 0x2c, 0x00, 0x00, 0x00, 0x00, + 0x36, 0xc4, 0xdb, 0xb2, 0xd9, 0xc1, 0x1a, 0x00, 0x00, 0xea, 0xff, 0x39, + 0x00, 0x00, 0x00, 0x9e, 0xff, 0x88, 0xbe, 0x9c, 0x00, 0x00, 0x72, 0xff, + 0x48, 0x00, 0x00, 0xbb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1c, 0xe4, 0xce, 0x8d, 0x00, 0x00, 0xb5, 0x60, 0x00, 0x00, + 0xea, 0xfa, 0x2c, 0x00, 0x00, 0x4e, 0xeb, 0x00, 0x00, 0x1c, 0x8f, 0xea, + 0xea, 0xee, 0x92, 0x1f, 0x00, 0x00, 0x1c, 0x8f, 0xea, 0xea, 0xee, 0x92, + 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x42, 0xf3, 0xcd, 0xf5, 0x3a, 0x00, 0x00, 0x00, 0xea, 0xf2, 0xef, 0xe5, + 0x8f, 0x2f, 0x00, 0x00, 0x0f, 0xa0, 0xfe, 0xf2, 0xf1, 0xfa, 0x33, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, + 0xe0, 0xea, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x35, 0xdc, 0x33, 0x00, 0x06, + 0x00, 0x5a, 0xd7, 0x13, 0x00, 0xea, 0xd8, 0x92, 0x00, 0x00, 0x09, 0xf0, + 0xd9, 0x88, 0x7b, 0xda, 0x00, 0x00, 0xb9, 0xe9, 0x91, 0x00, 0x05, 0xf4, + 0x03, 0x35, 0x02, 0x32, 0x1f, 0x00, 0x04, 0x37, 0x24, 0x00, 0x5b, 0xa9, + 0x1b, 0xe7, 0x01, 0x44, 0xd0, 0x02, 0x00, 0x00, 0xea, 0xe4, 0xc3, 0x01, + 0x00, 0x4e, 0xeb, 0x00, 0x00, 0x8f, 0xd8, 0x42, 0x01, 0x3a, 0xd0, 0x9b, + 0x00, 0x00, 0x8f, 0xd8, 0x42, 0x01, 0x3a, 0xd0, 0x9b, 0x00, 0x2e, 0x1a, + 0x00, 0x03, 0x36, 0x19, 0x00, 0x04, 0x36, 0x00, 0xa3, 0xa0, 0x00, 0xb5, + 0x8d, 0x00, 0x00, 0x00, 0xea, 0x6d, 0x01, 0x3d, 0xac, 0xe5, 0x03, 0x00, + 0xa1, 0xeb, 0x63, 0x0c, 0x03, 0x2e, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0xe1, 0xeb, 0x2d, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xd6, 0x38, 0x37, 0xb4, 0xd6, 0xe9, 0x35, 0x9e, 0x5c, + 0x00, 0xea, 0x87, 0xe8, 0x03, 0x00, 0x56, 0xcc, 0xba, 0x88, 0x38, 0xff, + 0x1a, 0x09, 0xf7, 0x84, 0xd9, 0x00, 0x39, 0xfe, 0x0e, 0xff, 0xb7, 0xe1, + 0xf3, 0x94, 0xbc, 0xde, 0xfb, 0x97, 0x73, 0x9b, 0x0b, 0xfb, 0x0b, 0xcf, + 0x44, 0x01, 0x00, 0x00, 0xea, 0x65, 0xf7, 0x63, 0x00, 0x4e, 0xeb, 0x00, + 0x01, 0xe0, 0x79, 0x00, 0x00, 0x00, 0x6b, 0xea, 0x03, 0x01, 0xe0, 0x79, + 0x00, 0x00, 0x00, 0x6b, 0xea, 0x03, 0xb0, 0xa4, 0x00, 0x39, 0xfe, 0xa0, + 0x00, 0x3d, 0xfd, 0x00, 0x6e, 0xe0, 0x5b, 0xef, 0x41, 0x00, 0x00, 0x00, + 0xea, 0x6d, 0x00, 0x00, 0x17, 0xfd, 0x47, 0x18, 0xff, 0x8f, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x21, 0xe1, 0xeb, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0xe3, + 0x00, 0xc5, 0x51, 0x00, 0xd4, 0x37, 0x61, 0x99, 0x00, 0xea, 0x4d, 0xe9, + 0x45, 0x00, 0xb2, 0x70, 0xbf, 0x88, 0x04, 0xf0, 0x59, 0x48, 0xe9, 0x18, + 0xfd, 0x23, 0x77, 0xd4, 0x0e, 0xff, 0x9f, 0x02, 0x54, 0xff, 0x86, 0x00, + 0x69, 0xf0, 0x39, 0xd1, 0x61, 0xca, 0x60, 0xb6, 0x6f, 0xe3, 0x98, 0x00, + 0xea, 0x4a, 0x7f, 0xec, 0x15, 0x4e, 0xeb, 0x00, 0x32, 0xff, 0x36, 0x00, + 0x00, 0x00, 0x29, 0xff, 0x3e, 0x32, 0xff, 0x36, 0x00, 0x00, 0x00, 0x29, + 0xff, 0x3f, 0x68, 0xe6, 0x00, 0x83, 0xaf, 0xe7, 0x01, 0x80, 0xc9, 0x00, + 0x18, 0xf4, 0xff, 0x53, 0x00, 0x15, 0x3b, 0x00, 0xea, 0x6d, 0x00, 0x00, + 0x00, 0xc5, 0xa2, 0x41, 0xff, 0x39, 0x00, 0x40, 0x73, 0x73, 0x35, 0x00, + 0x00, 0x00, 0x3d, 0xed, 0x45, 0x00, 0x00, 0x00, 0x22, 0xe1, 0xeb, 0x2d, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f, 0xb3, 0x12, 0xf9, 0x04, 0x03, + 0xef, 0x2c, 0x6a, 0x94, 0x00, 0xea, 0x4d, 0x95, 0x9e, 0x14, 0xf6, 0x18, + 0xc1, 0x88, 0x00, 0xb2, 0x96, 0x8e, 0xa4, 0x00, 0xcb, 0x6a, 0xb5, 0x92, + 0x0e, 0xff, 0x59, 0x00, 0x27, 0xff, 0x3d, 0x00, 0x3a, 0xff, 0x04, 0x71, + 0xae, 0x40, 0xe0, 0x2e, 0xee, 0x1e, 0xd5, 0x00, 0xea, 0x4d, 0x08, 0xd9, + 0xa0, 0x4b, 0xeb, 0x00, 0x20, 0xfe, 0x45, 0x00, 0x00, 0x00, 0x37, 0xff, + 0x2c, 0x20, 0xfe, 0x45, 0x00, 0x00, 0x00, 0x37, 0xff, 0x3b, 0x21, 0xff, + 0x29, 0xcc, 0x4a, 0xe9, 0x30, 0xc3, 0x81, 0x14, 0xdf, 0xab, 0xbd, 0xcd, + 0x14, 0x9c, 0xb5, 0x00, 0xea, 0x6d, 0x00, 0x00, 0x00, 0xdc, 0xa6, 0x20, + 0xfe, 0x42, 0x00, 0x63, 0xb2, 0xf4, 0x76, 0x00, 0x00, 0x00, 0x13, 0xd0, + 0xf6, 0x45, 0x00, 0x22, 0xe1, 0xeb, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3f, 0xe7, 0x03, 0xd7, 0x5e, 0x75, 0xf7, 0x8d, 0xc7, 0x4a, + 0x00, 0xea, 0x4d, 0x3c, 0xf0, 0x71, 0xb7, 0x00, 0xc1, 0x88, 0x00, 0x70, + 0xc9, 0xcb, 0x5d, 0x00, 0x83, 0xa2, 0xe9, 0x4f, 0x0e, 0xff, 0x43, 0x00, + 0x26, 0xff, 0x2d, 0x00, 0x39, 0xff, 0x00, 0x00, 0x00, 0x7c, 0x9a, 0x1f, + 0xf1, 0x00, 0xaf, 0x00, 0xea, 0x4d, 0x00, 0x44, 0xfe, 0x83, 0xeb, 0x00, + 0x00, 0xcd, 0x89, 0x00, 0x00, 0x00, 0x7b, 0xd9, 0x00, 0x00, 0xcd, 0x89, + 0x00, 0x00, 0x00, 0x7b, 0xf8, 0x08, 0x00, 0xd8, 0x75, 0xf8, 0x0d, 0xa7, + 0x79, 0xf7, 0x39, 0x5b, 0xfc, 0x0a, 0x09, 0xba, 0xd4, 0xf6, 0x39, 0x00, + 0xea, 0x6d, 0x00, 0x00, 0x31, 0xff, 0x75, 0x00, 0xcc, 0x8f, 0x00, 0x00, + 0x00, 0xdb, 0x76, 0x00, 0x00, 0x00, 0x00, 0x13, 0xd0, 0xf6, 0x63, 0xe1, + 0xeb, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xf3, + 0x44, 0x2c, 0x96, 0x87, 0x29, 0xa3, 0x64, 0x00, 0x00, 0xea, 0x4d, 0x01, + 0xe1, 0xf3, 0x5b, 0x00, 0xc1, 0x88, 0x00, 0x2e, 0xf7, 0xf5, 0x17, 0x00, + 0x3a, 0xec, 0xfc, 0x10, 0x0e, 0xff, 0x43, 0x00, 0x26, 0xff, 0x2d, 0x00, + 0x39, 0xff, 0x00, 0x00, 0x17, 0xe6, 0x19, 0x02, 0xee, 0x13, 0xd0, 0x00, + 0xea, 0x4d, 0x00, 0x00, 0xa5, 0xf6, 0xeb, 0x00, 0x00, 0x7d, 0xec, 0x7a, + 0x24, 0x73, 0xe7, 0x87, 0x00, 0x00, 0x7d, 0xec, 0x7a, 0x24, 0x73, 0xe7, + 0x9c, 0x00, 0x00, 0x91, 0xda, 0xbd, 0x00, 0x61, 0xd9, 0xed, 0x03, 0x2b, + 0xfe, 0x67, 0x1d, 0x70, 0xfc, 0xf0, 0x1a, 0x00, 0xea, 0x7f, 0x31, 0x81, + 0xdc, 0xdc, 0x0a, 0x00, 0x79, 0xef, 0x83, 0x23, 0x1c, 0xe1, 0x76, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x13, 0xd0, 0xff, 0xec, 0x2e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6b, 0xdc, 0x78, 0x20, 0x0d, + 0x3c, 0x3b, 0x00, 0x00, 0x00, 0xea, 0x4d, 0x00, 0x8a, 0xf3, 0x0b, 0x00, + 0xc1, 0x88, 0x00, 0x01, 0xea, 0xce, 0x00, 0x00, 0x03, 0xed, 0xc9, 0x00, + 0x0e, 0xff, 0x43, 0x00, 0x26, 0xff, 0x2d, 0x00, 0x39, 0xff, 0x00, 0x00, + 0x98, 0x7e, 0x00, 0x00, 0x78, 0xe7, 0xb0, 0x00, 0xea, 0x4d, 0x00, 0x00, + 0x18, 0xef, 0xeb, 0x00, 0x00, 0x06, 0x54, 0xb6, 0xfb, 0xbb, 0x57, 0x07, + 0x00, 0x00, 0x06, 0x54, 0xb6, 0xfc, 0xff, 0x8d, 0x01, 0x00, 0x00, 0x49, + 0xff, 0x74, 0x00, 0x1b, 0xfe, 0xa8, 0x00, 0x00, 0x7f, 0xde, 0xff, 0xe7, + 0x72, 0xb1, 0xdb, 0x00, 0xea, 0xff, 0xf8, 0xd6, 0x92, 0x13, 0x00, 0x00, + 0x06, 0x52, 0xb4, 0xfb, 0xff, 0xe5, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x13, 0xbc, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x44, 0xb7, 0xde, 0xdb, 0xad, 0x50, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x1b, 0xda, 0xbb, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, + 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0xe6, + 0xa0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x17, 0x00, 0x00, 0x00, + 0x2a, 0x1e, 0x00, 0x35, 0x13, 0x00, 0x00, 0x00, 0x2c, 0x1c, 0x00, 0x00, + 0x0c, 0x27, 0x00, 0x29, 0x09, 0x00, 0x00, 0x00, 0x3c, 0x24, 0x00, 0x00, + 0x00, 0x31, 0x35, 0x30, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x44, + 0x1f, 0x00, 0x00, 0x31, 0x17, 0x00, 0x00, 0x13, 0x35, 0x00, 0x31, 0x35, + 0x2b, 0x02, 0x00, 0x00, 0x00, 0x31, 0x35, 0x2a, 0x02, 0x00, 0x00, 0x33, + 0x16, 0x00, 0x00, 0x00, 0x0f, 0x35, 0x27, 0x28, 0x00, 0x00, 0x00, 0x1f, + 0x2e, 0x0b, 0xbc, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x13, 0xbc, 0x2a, 0x0b, 0xbc, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xea, 0x6d, 0x00, 0x00, 0x00, 0xc9, 0x8e, 0x00, 0xfc, + 0x5b, 0x00, 0x00, 0x00, 0xd2, 0x84, 0x00, 0x00, 0x59, 0xa9, 0x00, 0xea, + 0x0f, 0x00, 0x00, 0x34, 0xfe, 0xce, 0x00, 0x00, 0x00, 0xea, 0xf2, 0xed, + 0xfa, 0xce, 0x1a, 0x00, 0x09, 0xb5, 0xfd, 0xe7, 0xf5, 0xaf, 0x00, 0xea, + 0x6d, 0x00, 0x0c, 0xcf, 0xa7, 0x00, 0xea, 0xf2, 0xf3, 0xea, 0x94, 0x00, + 0x00, 0xea, 0xf4, 0xf6, 0xec, 0x9d, 0x00, 0xc0, 0x9e, 0x00, 0x00, 0x00, + 0x7a, 0xe5, 0x58, 0xf8, 0x26, 0x00, 0x0d, 0xe4, 0x7a, 0x0e, 0xff, 0x43, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0xff, 0x39, 0x0e, + 0xff, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xea, + 0x6d, 0x00, 0x00, 0x00, 0xc9, 0x8e, 0x00, 0xfc, 0x5b, 0x00, 0x00, 0x00, + 0xd2, 0x84, 0x00, 0x00, 0x89, 0x79, 0x1c, 0xdd, 0x00, 0x00, 0x00, 0x93, + 0xad, 0xf9, 0x2e, 0x00, 0x00, 0xea, 0x6d, 0x00, 0x19, 0xe3, 0x8c, 0x00, + 0xab, 0xe1, 0x4f, 0x02, 0x07, 0x1f, 0x00, 0xea, 0x6d, 0x03, 0xb2, 0xc6, + 0x08, 0x00, 0xea, 0x6d, 0x03, 0x4d, 0xff, 0x33, 0x00, 0xea, 0x6d, 0x03, + 0x49, 0xff, 0x3a, 0x67, 0xee, 0x06, 0x00, 0x00, 0xd0, 0x8e, 0x00, 0xb3, + 0xbb, 0x00, 0x8e, 0xcf, 0x05, 0x0e, 0xff, 0x41, 0x12, 0x25, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x20, 0x18, 0xff, 0x39, 0x0e, 0xff, 0x41, 0x2e, 0x33, + 0x01, 0x00, 0x03, 0x35, 0x01, 0x2e, 0x34, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0x39, 0x05, 0x00, 0x00, 0x03, 0x36, 0x02, 0x11, 0x25, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xea, 0x6d, 0x00, 0x00, 0x00, + 0xc9, 0x8e, 0x00, 0xfc, 0x5b, 0x00, 0x00, 0x00, 0xd2, 0x84, 0x41, 0xd3, + 0xf0, 0xe3, 0xdd, 0xf4, 0xd3, 0x00, 0x06, 0xec, 0x52, 0xb4, 0x8d, 0x00, + 0x00, 0xea, 0x6d, 0x00, 0x06, 0xdd, 0x86, 0x0b, 0xfc, 0x81, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xea, 0x6d, 0x8d, 0xdd, 0x15, 0x00, 0x00, 0xea, 0x6d, + 0x00, 0x07, 0xf3, 0x64, 0x00, 0xea, 0x6d, 0x00, 0x0a, 0xf4, 0x69, 0x13, + 0xfa, 0x4a, 0x00, 0x27, 0xff, 0x34, 0x00, 0x1c, 0xf1, 0x86, 0xf7, 0x33, + 0x00, 0x0e, 0xff, 0xaa, 0xd3, 0xf8, 0xab, 0x01, 0x00, 0x87, 0xf6, 0xda, + 0xa5, 0xff, 0x39, 0x0e, 0xff, 0xc0, 0xe5, 0xf2, 0xd5, 0x03, 0x0e, 0xff, + 0xb4, 0xe5, 0xf2, 0xd6, 0x04, 0x00, 0x00, 0x00, 0x00, 0x6d, 0xe7, 0xdd, + 0xe7, 0x6d, 0x00, 0x0e, 0xff, 0x98, 0xd2, 0xf8, 0xab, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xea, 0xe9, 0xd9, 0xd9, 0xd9, 0xf7, 0x8e, 0x00, 0xfc, + 0x5b, 0x00, 0x00, 0x00, 0xd2, 0x84, 0x09, 0x1d, 0xec, 0x2e, 0x93, 0x87, + 0x1d, 0x00, 0x52, 0xf1, 0x09, 0x5d, 0xe8, 0x04, 0x00, 0xea, 0xe4, 0xd3, + 0xf6, 0xb1, 0x0d, 0x3c, 0xff, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0xea, + 0xc9, 0xff, 0x60, 0x00, 0x00, 0x00, 0xea, 0x8a, 0x49, 0x9e, 0xf1, 0x0d, + 0x00, 0xea, 0xa6, 0x71, 0xbb, 0xe1, 0x1a, 0x00, 0xb4, 0xa0, 0x00, 0x7d, + 0xda, 0x00, 0x00, 0x00, 0x74, 0xff, 0x93, 0x00, 0x00, 0x0e, 0xff, 0x9c, + 0x02, 0x2a, 0xff, 0x32, 0x0e, 0xfa, 0x5a, 0x00, 0x6f, 0xff, 0x39, 0x0e, + 0xff, 0xa6, 0x04, 0x1e, 0xff, 0x42, 0x0e, 0xff, 0xa5, 0x04, 0x1e, 0xff, + 0x42, 0x00, 0x00, 0x00, 0x07, 0xf1, 0x59, 0x00, 0x55, 0xf2, 0x09, 0x0e, + 0xff, 0x99, 0x01, 0x2d, 0xff, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0xea, + 0x98, 0x4c, 0x4c, 0x4c, 0xd9, 0x8e, 0x00, 0xfc, 0x5b, 0x00, 0x00, 0x00, + 0xd2, 0x84, 0x37, 0x58, 0xef, 0x4a, 0xc6, 0x83, 0x38, 0x00, 0xb1, 0xd5, + 0x6f, 0x7d, 0xff, 0x4c, 0x00, 0xea, 0x94, 0x47, 0x70, 0xe7, 0x83, 0x22, + 0xff, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0xea, 0xd2, 0xaf, 0xe2, 0x10, + 0x00, 0x00, 0xea, 0xf5, 0xda, 0x94, 0x3e, 0x00, 0x00, 0xea, 0xd6, 0xc4, + 0xfd, 0x27, 0x00, 0x00, 0x5b, 0xef, 0x06, 0xd3, 0x81, 0x00, 0x00, 0x01, + 0xbc, 0xeb, 0xd2, 0x06, 0x00, 0x0e, 0xff, 0x56, 0x00, 0x00, 0xdd, 0x77, + 0x50, 0xfb, 0x0c, 0x00, 0x23, 0xff, 0x39, 0x0e, 0xff, 0x5c, 0x00, 0x00, + 0xeb, 0x68, 0x0e, 0xff, 0x5c, 0x00, 0x00, 0xeb, 0x68, 0x00, 0x00, 0x00, + 0x4c, 0xfb, 0x0b, 0x00, 0x08, 0xf8, 0x51, 0x0e, 0xff, 0x52, 0x00, 0x00, + 0xde, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0xea, 0x6d, 0x00, 0x00, 0x00, + 0xc9, 0x8e, 0x00, 0xd3, 0x85, 0x00, 0x00, 0x09, 0xf4, 0x6b, 0x7b, 0xc7, + 0xdf, 0xa7, 0xfd, 0xa9, 0x7f, 0x16, 0xfa, 0xc4, 0xb8, 0xb8, 0xe2, 0xab, + 0x00, 0xea, 0x6d, 0x00, 0x00, 0x8e, 0xdf, 0x00, 0xd2, 0x89, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xea, 0x6d, 0x0f, 0xe0, 0xa1, 0x00, 0x00, 0xea, 0x6d, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xea, 0x6d, 0x01, 0xc6, 0xa5, 0x00, 0x00, + 0x0c, 0xf5, 0x69, 0xff, 0x28, 0x00, 0x00, 0x60, 0xec, 0x21, 0xe4, 0x80, + 0x00, 0x0e, 0xff, 0x65, 0x00, 0x01, 0xea, 0x67, 0x43, 0xfe, 0x12, 0x00, + 0x25, 0xff, 0x39, 0x0e, 0xff, 0x43, 0x00, 0x00, 0xea, 0x68, 0x0e, 0xff, + 0x43, 0x00, 0x00, 0xea, 0x68, 0x00, 0x00, 0x00, 0x4c, 0xfe, 0x16, 0x00, + 0x11, 0xfd, 0x40, 0x0e, 0xff, 0x65, 0x00, 0x01, 0xeb, 0x67, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xea, 0x6d, 0x00, 0x00, 0x00, 0xc9, 0x8e, 0x00, 0x72, + 0xdf, 0x4b, 0x23, 0x8c, 0xfa, 0x28, 0x00, 0x7c, 0x81, 0x1a, 0xe5, 0x00, + 0x00, 0x70, 0xeb, 0x05, 0x00, 0x00, 0x5c, 0xf8, 0x00, 0xea, 0x7f, 0x22, + 0x4a, 0xdd, 0x95, 0x00, 0x84, 0xed, 0x7c, 0x1d, 0x24, 0x32, 0x00, 0xea, + 0x6d, 0x00, 0x40, 0xfd, 0x52, 0x00, 0xea, 0x6d, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xea, 0x6d, 0x00, 0x31, 0xfc, 0x49, 0x00, 0x00, 0xa8, 0xe3, 0xcd, + 0x00, 0x00, 0x17, 0xed, 0x62, 0x00, 0x54, 0xf9, 0x2d, 0x0e, 0xff, 0xbc, + 0x1d, 0x5f, 0xff, 0x21, 0x07, 0xf5, 0x7e, 0x11, 0x8d, 0xff, 0x39, 0x0e, + 0xff, 0x43, 0x00, 0x00, 0xea, 0x68, 0x0e, 0xff, 0x43, 0x00, 0x00, 0xea, + 0x68, 0x00, 0x00, 0x00, 0x14, 0xf2, 0x88, 0x15, 0x82, 0xe8, 0x03, 0x0e, + 0xff, 0xbc, 0x1e, 0x61, 0xff, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xea, + 0x6d, 0x00, 0x00, 0x00, 0xc9, 0x8e, 0x00, 0x10, 0x85, 0xdc, 0xfe, 0xd9, + 0x4c, 0x00, 0x00, 0xaa, 0x50, 0x4b, 0xb4, 0x00, 0x00, 0xcf, 0x97, 0x00, + 0x00, 0x00, 0x0c, 0xf4, 0x00, 0xea, 0xff, 0xff, 0xdd, 0x93, 0x1c, 0x00, + 0x08, 0x5c, 0xc0, 0xfe, 0xed, 0x7b, 0x00, 0xea, 0x6d, 0x00, 0x00, 0x8d, + 0xea, 0x00, 0xea, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0xea, 0x6d, 0x00, + 0x00, 0x95, 0xe0, 0x00, 0x00, 0x4f, 0xff, 0x74, 0x00, 0x00, 0xa8, 0xc3, + 0x01, 0x00, 0x00, 0xb7, 0xca, 0x0e, 0xfd, 0x6f, 0xd4, 0xe5, 0x72, 0x00, + 0x00, 0x5c, 0xd9, 0xdb, 0x63, 0xef, 0x39, 0x0e, 0xff, 0x43, 0x00, 0x00, + 0xea, 0x68, 0x0e, 0xff, 0x43, 0x00, 0x00, 0xea, 0x68, 0x00, 0x00, 0x00, + 0x00, 0x43, 0xdb, 0xfc, 0xb7, 0x46, 0x00, 0x0e, 0xff, 0x8c, 0xd4, 0xe4, + 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x02, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, + 0x00, 0x00, 0x00, 0x0e, 0xff, 0x43, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, + 0xff, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0xc2, 0x33, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x79, + 0x00, 0x00, 0x00, 0x00, 0x58, 0x8a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0a, 0x2f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2e, + 0x14, 0x00, 0x00, 0x04, 0x32, 0x3b, 0x03, 0x00, 0x00, 0x00, 0x21, 0x38, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x07, 0x3b, 0x0f, 0x00, 0x2e, 0x35, 0x35, + 0x35, 0x16, 0x00, 0x00, 0x03, 0x26, 0x49, 0x1f, 0x1e, 0x33, 0x33, 0x33, + 0x33, 0x33, 0x00, 0x00, 0x18, 0x3a, 0x05, 0x00, 0x00, 0x00, 0x14, 0x37, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2f, + 0x00, 0x31, 0x35, 0x35, 0x35, 0x27, 0x00, 0x31, 0x35, 0x35, 0x35, 0x26, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0xa6, 0xea, 0x9e, 0x53, 0x0f, 0x03, + 0x5f, 0xa3, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6d, + 0xe9, 0xea, 0xb4, 0x23, 0x00, 0x07, 0x98, 0xff, 0x61, 0x00, 0x27, 0xd4, + 0xee, 0xe8, 0xe8, 0x2f, 0x32, 0xcf, 0xdd, 0xe5, 0xef, 0x33, 0x00, 0x00, + 0x00, 0x89, 0xff, 0x41, 0x00, 0xea, 0xf9, 0xf6, 0xf6, 0x64, 0x00, 0x25, + 0xcf, 0xfe, 0xd1, 0x6c, 0x90, 0xf6, 0xf6, 0xf6, 0xf9, 0xff, 0x00, 0xa0, + 0xea, 0xca, 0xee, 0x3e, 0x00, 0x9e, 0xf3, 0xe2, 0xe3, 0x1c, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xfc, 0x00, 0xea, 0xf4, 0xec, + 0xec, 0xac, 0x00, 0xea, 0xf4, 0xec, 0xec, 0xa9, 0x00, 0x00, 0x00, 0x00, + 0x17, 0x3a, 0x05, 0x30, 0x0c, 0x06, 0x36, 0x0c, 0x00, 0x00, 0x34, 0x13, + 0x16, 0xf6, 0x91, 0xc3, 0x79, 0x5b, 0x80, 0xed, 0xc9, 0xd9, 0xdb, 0xcb, + 0x00, 0x00, 0x31, 0xa9, 0x00, 0x00, 0x06, 0xf7, 0x57, 0x0c, 0xbd, 0x88, + 0x05, 0xc6, 0xb6, 0xed, 0x61, 0x00, 0x08, 0x64, 0x05, 0x02, 0xbf, 0x9d, + 0x04, 0x3a, 0x00, 0x01, 0xbe, 0xa2, 0x00, 0x00, 0x3d, 0xd1, 0xfc, 0x41, + 0x02, 0xfc, 0x41, 0x00, 0x00, 0x00, 0x00, 0xc9, 0xa9, 0x1f, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x90, 0xbf, 0x23, 0xfe, 0x27, 0x00, 0x9b, 0xaf, + 0x2b, 0xfc, 0x21, 0x00, 0xa9, 0xb1, 0x00, 0x00, 0x00, 0x01, 0x50, 0xce, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6f, 0x98, 0x1e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc1, 0x00, 0xea, 0x6d, 0x00, 0x00, 0x00, 0x00, 0xea, + 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0xf6, 0xdf, 0xbf, 0xf9, + 0x39, 0x1d, 0xff, 0x38, 0x00, 0x00, 0xf6, 0x5c, 0x30, 0xff, 0x55, 0xa7, + 0x00, 0x00, 0x06, 0x21, 0xdd, 0xeb, 0x45, 0x0c, 0x00, 0x00, 0x3a, 0xc8, + 0x00, 0x00, 0x35, 0xfd, 0x09, 0x00, 0x77, 0xc1, 0x00, 0x44, 0x03, 0xee, + 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa6, 0xa9, 0x00, 0x00, 0x00, 0x09, + 0xdb, 0x79, 0x00, 0x0d, 0xdc, 0x43, 0xff, 0x41, 0x13, 0xff, 0x38, 0x0f, + 0x00, 0x00, 0x36, 0xff, 0x34, 0x26, 0x05, 0x00, 0x00, 0x00, 0x00, 0x12, + 0xf3, 0x4e, 0x0a, 0xf1, 0x6b, 0x16, 0xce, 0x80, 0x6e, 0xda, 0x00, 0x00, + 0x58, 0xe9, 0x00, 0x01, 0x50, 0xce, 0xbc, 0x44, 0x49, 0xab, 0xab, 0xab, + 0xab, 0xa8, 0x0f, 0x78, 0xe1, 0x98, 0x1f, 0x00, 0x00, 0x01, 0xdb, 0x62, + 0x00, 0xea, 0x6d, 0x00, 0x00, 0x00, 0x00, 0xea, 0x6a, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xfa, 0x58, 0x00, 0x6f, 0xff, 0x39, 0x1d, 0xff, 0x38, + 0x00, 0x00, 0xf6, 0x5c, 0x00, 0x90, 0xfc, 0xdd, 0x46, 0x00, 0x00, 0x8b, + 0xbb, 0x75, 0xce, 0x06, 0x41, 0x8d, 0xa7, 0xe7, 0x8d, 0x8d, 0x6b, 0xe3, + 0x00, 0x00, 0x52, 0xf5, 0x00, 0x00, 0x00, 0xf0, 0x61, 0x00, 0x00, 0x00, + 0x00, 0x31, 0xf8, 0x3f, 0x00, 0x33, 0xcb, 0xf8, 0x85, 0x05, 0x00, 0x9c, + 0x8e, 0x08, 0xff, 0x41, 0x1f, 0xfd, 0xfe, 0xfa, 0xb8, 0x2d, 0x5b, 0xf2, + 0xc9, 0xe6, 0xe7, 0x5a, 0x00, 0x00, 0x00, 0x7c, 0xd9, 0x02, 0x00, 0x37, + 0xfb, 0xf8, 0xa4, 0x02, 0x2e, 0xfd, 0x49, 0x26, 0xbd, 0xfe, 0x35, 0xce, + 0xac, 0x34, 0x00, 0x00, 0x24, 0x55, 0x55, 0x55, 0x55, 0x53, 0x00, 0x00, + 0x08, 0x68, 0xd8, 0x98, 0x00, 0x3b, 0xf4, 0x0d, 0x00, 0xea, 0xe8, 0xd6, + 0xd6, 0x6f, 0x00, 0xea, 0xb6, 0x82, 0x82, 0x42, 0x00, 0x00, 0x4f, 0xfb, + 0x0c, 0x00, 0x23, 0xff, 0x39, 0x1d, 0xff, 0x38, 0x00, 0x00, 0xf6, 0x5c, + 0x00, 0x00, 0x3a, 0xe4, 0xf4, 0x89, 0x00, 0x24, 0x30, 0x0c, 0x48, 0x00, + 0x34, 0x72, 0x92, 0xe1, 0x72, 0x72, 0x5e, 0xea, 0x00, 0x00, 0x59, 0xee, + 0x00, 0x00, 0x00, 0xf0, 0x61, 0x00, 0x00, 0x00, 0x22, 0xe6, 0x76, 0x00, + 0x00, 0x15, 0x57, 0x82, 0xe7, 0x79, 0x4d, 0xd5, 0x09, 0x08, 0xff, 0x41, + 0x00, 0x13, 0x03, 0x2c, 0xcd, 0xa5, 0x6f, 0xfc, 0x30, 0x01, 0x81, 0xd3, + 0x00, 0x00, 0x09, 0xe9, 0x6a, 0x00, 0x0f, 0xc5, 0xb2, 0x78, 0xed, 0x63, + 0x00, 0x7f, 0xe4, 0xe4, 0xa5, 0xeb, 0x34, 0xc4, 0xcd, 0x64, 0x0a, 0x00, + 0x2e, 0x6c, 0x6c, 0x6c, 0x6c, 0x6a, 0x00, 0x00, 0x29, 0x92, 0xe4, 0x93, + 0x00, 0x9a, 0xa3, 0x00, 0x00, 0xea, 0x96, 0x48, 0x48, 0x25, 0x00, 0xea, + 0xc8, 0xa1, 0xa1, 0x52, 0x00, 0x00, 0x43, 0xfe, 0x12, 0x00, 0x23, 0xff, + 0x39, 0x1c, 0xff, 0x3d, 0x00, 0x1c, 0xff, 0x5c, 0x06, 0x00, 0x17, 0xa7, + 0x8a, 0xdd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3a, 0xc8, + 0x00, 0x00, 0x25, 0xff, 0x0f, 0x00, 0x7f, 0xb8, 0x00, 0x00, 0x00, 0xf0, + 0x61, 0x00, 0x00, 0x20, 0xe0, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x84, 0xe4, 0xc4, 0xf0, 0xe2, 0xe3, 0xff, 0xe9, 0x00, 0x00, 0x00, 0x00, + 0x7b, 0xdd, 0x4b, 0xf3, 0x07, 0x00, 0x47, 0xf8, 0x00, 0x00, 0x68, 0xed, + 0x0b, 0x00, 0x5f, 0xe3, 0x02, 0x00, 0x5d, 0xeb, 0x00, 0x00, 0x01, 0x00, + 0xaa, 0xbd, 0x00, 0x00, 0x35, 0xa5, 0xea, 0x90, 0x3f, 0x92, 0x92, 0x92, + 0x92, 0x90, 0x34, 0xbe, 0xe0, 0x74, 0x10, 0x00, 0x09, 0xf0, 0x44, 0x00, + 0x00, 0xea, 0x6d, 0x00, 0x00, 0x00, 0x00, 0xea, 0x6a, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x07, 0xf5, 0x7b, 0x10, 0x8b, 0xff, 0x39, 0x02, 0xe4, 0x8c, + 0x10, 0x86, 0xff, 0x5c, 0x60, 0xd2, 0xa9, 0xea, 0xfd, 0x77, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x91, 0x00, 0x00, 0x01, 0xea, + 0x87, 0x2f, 0xd5, 0x81, 0x00, 0x00, 0x00, 0xf0, 0x61, 0x00, 0x1f, 0xdf, + 0x9f, 0x29, 0x29, 0x29, 0x36, 0x28, 0x04, 0x29, 0xcd, 0x9c, 0x2a, 0x35, + 0x35, 0x3b, 0xff, 0x69, 0x28, 0x37, 0x09, 0x32, 0xd3, 0x81, 0x16, 0xef, + 0x7f, 0x18, 0xa7, 0xaf, 0x00, 0x03, 0xdb, 0x87, 0x00, 0x00, 0x3e, 0xf5, + 0x26, 0x05, 0x88, 0xc7, 0x00, 0x06, 0x1b, 0x75, 0xf4, 0x48, 0x00, 0x00, + 0x00, 0x00, 0x1b, 0x87, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x56, + 0x04, 0x00, 0x00, 0x00, 0x5a, 0xe2, 0x02, 0x00, 0x00, 0xea, 0x81, 0x24, + 0x24, 0x1a, 0x00, 0xea, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, + 0xda, 0xda, 0x71, 0xff, 0x39, 0x00, 0x68, 0xe4, 0xfa, 0xa6, 0xd0, 0x5c, + 0x09, 0x38, 0x74, 0xc9, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0xb5, 0xef, 0x82, 0x10, + 0x00, 0x00, 0x00, 0xf0, 0x61, 0x00, 0x7e, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x5f, 0xdc, 0xfc, 0xe9, 0xa6, 0x22, 0x00, 0x00, 0x00, 0x08, 0xff, 0x41, + 0x3e, 0xd7, 0xfd, 0xe4, 0x95, 0x17, 0x00, 0x47, 0xdc, 0xfb, 0xb2, 0x30, + 0x00, 0x55, 0xfa, 0x1b, 0x00, 0x00, 0x00, 0x90, 0xe3, 0xf2, 0xbf, 0x3c, + 0x00, 0xec, 0xfc, 0xde, 0x57, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xb9, 0x85, 0x00, 0x00, 0x00, 0xea, 0xff, 0xff, 0xff, 0xba, 0x00, 0xea, + 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x04, 0x1a, 0xff, + 0x39, 0x00, 0x00, 0x02, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x70, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0f, 0x0d, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0xff, 0x39, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x14, 0xc2, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x17, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x15, 0x43, 0x14, 0x00, 0x2d, 0x35, 0x35, 0x35, + 0x35, 0x35, 0x32, 0x1b, 0x00, 0x00, 0x00, 0x26, 0x1c, 0x35, 0x35, 0x35, + 0x35, 0x35, 0x00, 0x00, 0x1d, 0x17, 0x00, 0x00, 0x00, 0x00, 0x8c, 0xa9, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0xbc, 0x2f, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x7a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x35, 0x35, + 0x35, 0x2b, 0x0d, 0x35, 0x04, 0x35, 0x0e, 0x00, 0x12, 0x41, 0x0e, 0x00, + 0x2f, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xea, 0x6d, 0x00, 0x00, 0x00, 0x00, 0xa1, + 0xf9, 0xe4, 0xfe, 0x7c, 0xc9, 0xf0, 0xf6, 0xfe, 0xf0, 0xf0, 0x9e, 0xd1, + 0x02, 0x00, 0x14, 0xf1, 0x7c, 0xf0, 0xf0, 0xf0, 0xf8, 0xff, 0x00, 0x00, + 0xbd, 0xae, 0x00, 0x00, 0x00, 0x00, 0x0b, 0xb2, 0x74, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0e, 0xff, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0xaa, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xb5, 0x60, 0x60, 0x60, 0xaa, 0x33, 0xfc, + 0x02, 0xf9, 0x36, 0x9f, 0xeb, 0xd6, 0xf7, 0x5d, 0xa5, 0x99, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xea, 0x6d, 0x00, 0x00, 0x00, 0x2b, 0xfe, 0x2d, 0x00, 0x1a, 0x15, + 0x00, 0x00, 0x6c, 0xea, 0x00, 0x00, 0x1d, 0xf7, 0x58, 0x00, 0x8a, 0xda, + 0x00, 0x00, 0x00, 0x08, 0xd5, 0x9c, 0x00, 0x35, 0xc9, 0xd2, 0x34, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x03, 0x35, 0x42, 0x09, 0x00, + 0x00, 0x00, 0x07, 0x38, 0x03, 0x00, 0x00, 0x00, 0x28, 0x48, 0x36, 0x36, + 0x0e, 0xff, 0x40, 0x00, 0x0e, 0x36, 0x34, 0x17, 0x00, 0x00, 0x0f, 0x36, + 0x25, 0x2c, 0x00, 0x00, 0x1a, 0x35, 0x33, 0x1a, 0x00, 0x00, 0x10, 0x36, + 0x00, 0x00, 0x58, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x95, 0x00, 0x00, 0x00, 0x95, 0x1f, 0xea, 0x00, 0xe6, 0x22, 0x1c, + 0x04, 0x00, 0x7a, 0xcf, 0x46, 0xef, 0x09, 0x00, 0x00, 0x00, 0x04, 0x3e, + 0x21, 0x00, 0x04, 0x36, 0x34, 0x06, 0x00, 0x00, 0x00, 0xea, 0x6d, 0x00, + 0x00, 0x00, 0x24, 0xff, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0xea, + 0x00, 0x00, 0x00, 0x8b, 0xd9, 0x1d, 0xf5, 0x54, 0x00, 0x00, 0x00, 0x8b, + 0xe0, 0x0e, 0x00, 0xac, 0x58, 0x54, 0xb7, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xa7, 0xd5, 0xc6, 0xf3, 0x42, 0x00, 0x6d, 0xe1, 0xc7, + 0xe1, 0x49, 0x02, 0xca, 0xbd, 0xb6, 0xff, 0xb2, 0x0e, 0xff, 0x40, 0x0c, + 0xc7, 0xae, 0xba, 0xa4, 0x00, 0x00, 0x7f, 0xdf, 0x46, 0xfb, 0x38, 0x08, + 0xd8, 0x97, 0xb6, 0xb1, 0x00, 0x00, 0x81, 0xe2, 0x00, 0x00, 0x58, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x95, 0x00, 0x00, + 0x00, 0x95, 0x0a, 0xa3, 0x00, 0xa1, 0x0d, 0x00, 0x00, 0x02, 0xa9, 0xb9, + 0x03, 0xe3, 0x58, 0x00, 0x00, 0x70, 0xe7, 0xdd, 0xf7, 0x11, 0xe9, 0xe3, + 0xd8, 0xcf, 0x00, 0x00, 0x00, 0xea, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x84, + 0xfb, 0xb6, 0x33, 0x00, 0x00, 0x00, 0x6c, 0xea, 0x00, 0x00, 0x00, 0x12, + 0xef, 0xd9, 0xc8, 0x01, 0x00, 0x00, 0x3b, 0xfb, 0x42, 0x00, 0x26, 0xdf, + 0x04, 0x02, 0xd1, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, + 0x00, 0x00, 0xa7, 0xa5, 0x07, 0xf1, 0x3f, 0x00, 0x77, 0xba, 0x45, 0xf4, + 0x06, 0x01, 0xe9, 0x66, 0x0e, 0xff, 0x45, 0xbc, 0xbb, 0x07, 0x59, 0xf3, + 0x0a, 0x00, 0xd8, 0x80, 0x00, 0x95, 0xd5, 0x8f, 0xdb, 0x0b, 0x50, 0xf9, + 0x13, 0x00, 0xd8, 0x85, 0x00, 0x00, 0x58, 0xaa, 0x00, 0x00, 0x2c, 0xb1, + 0xcf, 0x88, 0x4c, 0x89, 0x00, 0x95, 0x00, 0x00, 0x00, 0x95, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x9a, 0xd6, 0x1d, 0x00, 0x86, 0xb7, 0x00, + 0x07, 0xf1, 0x62, 0x00, 0x06, 0x58, 0xf8, 0x20, 0x00, 0x08, 0x00, 0x00, + 0x00, 0xea, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0xbe, 0xfe, 0x5a, + 0x00, 0x00, 0x6c, 0xea, 0x00, 0x00, 0x00, 0x00, 0x79, 0xff, 0x40, 0x00, + 0x00, 0x0a, 0xda, 0x92, 0x00, 0x00, 0x9a, 0x75, 0x00, 0x00, 0x53, 0xc0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x8b, 0xbf, 0xe6, 0xc5, + 0x49, 0xfe, 0xc3, 0xc2, 0xd2, 0xfc, 0x36, 0xfe, 0x39, 0x2b, 0xf8, 0x29, + 0x0e, 0xff, 0xc7, 0xf9, 0x18, 0x00, 0x09, 0xef, 0x57, 0x32, 0xfd, 0x20, + 0x00, 0x0b, 0xe0, 0xff, 0x3d, 0x00, 0x04, 0xe5, 0x69, 0x31, 0xfe, 0x25, + 0x00, 0x00, 0x58, 0xaa, 0x00, 0x00, 0x49, 0x3a, 0x47, 0x91, 0xbd, 0x67, + 0x00, 0x95, 0x00, 0x00, 0x00, 0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x43, 0xe6, 0x15, 0x00, 0x00, 0x28, 0xfb, 0x1a, 0x4a, 0xfb, 0x0d, 0x00, + 0x00, 0x11, 0xc2, 0xf4, 0x90, 0x19, 0x00, 0x00, 0x00, 0xea, 0x6d, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaf, 0xbe, 0x00, 0x00, 0x6c, 0xea, + 0x00, 0x00, 0x00, 0x00, 0x47, 0xff, 0x12, 0x00, 0x00, 0x91, 0xda, 0x0a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x27, 0xfc, 0x6a, 0x1e, 0x9a, 0xc5, 0x3b, 0xfd, 0x42, 0x31, + 0x31, 0x31, 0x00, 0x9f, 0xe5, 0xb3, 0x5d, 0x00, 0x0e, 0xff, 0xac, 0xd2, + 0xa4, 0x00, 0x00, 0x97, 0xac, 0x88, 0xbc, 0x00, 0x00, 0x2b, 0xf7, 0xee, + 0x75, 0x00, 0x00, 0x82, 0xbf, 0x86, 0xc3, 0x00, 0x00, 0x00, 0x58, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x95, 0x00, 0x00, + 0x00, 0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x5b, 0x00, 0x00, + 0x00, 0x00, 0xc7, 0x76, 0x40, 0xfe, 0x15, 0x00, 0x00, 0x00, 0x01, 0x4f, + 0xd1, 0xdf, 0x00, 0x00, 0x00, 0xea, 0x83, 0x27, 0x27, 0x23, 0x39, 0x44, + 0x14, 0x2b, 0xd1, 0x7b, 0x00, 0x00, 0x6c, 0xea, 0x00, 0x00, 0x00, 0x00, + 0x47, 0xff, 0x12, 0x00, 0x40, 0xfd, 0x60, 0x27, 0x27, 0x27, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f, 0xf6, + 0x0f, 0x1f, 0xe4, 0xc5, 0x01, 0xe0, 0x89, 0x0e, 0x07, 0x31, 0x08, 0xfa, + 0x4e, 0x24, 0x0a, 0x00, 0x0e, 0xff, 0x40, 0x2b, 0xf5, 0x65, 0x00, 0x36, + 0xef, 0xd1, 0x5b, 0x00, 0x05, 0xcd, 0x9e, 0x4b, 0xf8, 0x2d, 0x00, 0x1e, + 0xf6, 0xda, 0x63, 0x00, 0x00, 0x00, 0x58, 0xaa, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x95, 0x00, 0x00, 0x00, 0x95, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x68, 0xd4, + 0x04, 0xec, 0x8a, 0x14, 0x3f, 0x27, 0x2c, 0x01, 0x54, 0xee, 0x00, 0x00, + 0x00, 0xea, 0xff, 0xff, 0xff, 0xe6, 0x51, 0xdb, 0xfd, 0xea, 0xa3, 0x11, + 0x00, 0x00, 0x6c, 0xea, 0x00, 0x00, 0x00, 0x00, 0x47, 0xff, 0x12, 0x00, + 0xa0, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xc8, 0xf7, 0xdf, 0x83, 0xc5, + 0x00, 0x3f, 0xae, 0xf4, 0xfc, 0x9f, 0x0a, 0xd2, 0xfc, 0xfb, 0xf7, 0x90, + 0x0e, 0xff, 0x40, 0x00, 0x65, 0xf6, 0x00, 0x00, 0xd4, 0xf0, 0x09, 0x00, + 0x83, 0xe5, 0x10, 0x00, 0xa2, 0xd0, 0x00, 0x00, 0xb4, 0xf4, 0x0d, 0x00, + 0x00, 0x00, 0x58, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xc6, 0x95, 0x95, 0x95, 0xb6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x82, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x11, 0xf7, 0x00, 0x4f, 0xbf, 0xfe, + 0xf1, 0x57, 0xe9, 0xf3, 0xde, 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0c, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, + 0x0a, 0x00, 0xaa, 0x94, 0x08, 0x02, 0x4e, 0xf8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x06, 0xbf, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x58, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x0f, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x05, 0x00, 0x00, 0x0f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0xae, + 0x37, 0x49, 0xae, 0x9e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0xc3, + 0xf1, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x58, 0xaa, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x79, 0xb0, 0x96, 0x5c, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0x9f, 0x3a, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3d, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a, 0xff, 0x5a, 0xff, 0x8f, 0x00, + 0x00, 0x00, 0xff, 0x8f, 0x00, 0x00, 0x00, 0x8f, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0xaa, 0x3c, 0x8f, 0xff, 0x8f, 0x00, 0x00, 0x8f, 0xff, + 0x8f, 0x00, 0x8f, 0xff, 0x8f, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x8f, 0xff, 0x8f, 0x00, 0x00, 0x8f, 0xff, 0x8f, 0xff, 0x8f, + 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, + 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x14, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x6e, 0xaa, 0x00, 0x3c, 0xaa, 0x3c, 0x00, 0x00, 0x8f, + 0xff, 0x8f, 0x00, 0x00, 0x8f, 0xff, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x86, 0xbd, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x17, + 0x00, 0x00, 0x00, 0x0a, 0x35, 0x13, 0x00, 0x00, 0x30, 0x20, 0x1d, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x31, 0x17, 0x00, 0x33, 0x15, 0x07, 0x35, 0x35, + 0x26, 0x35, 0x31, 0x03, 0x7f, 0x18, 0x03, 0x7f, 0x18, 0x0b, 0xbc, 0x31, + 0x00, 0x00, 0x0d, 0x35, 0x00, 0x00, 0x00, 0x5e, 0xff, 0x70, 0x00, 0x00, + 0x00, 0x00, 0x70, 0xff, 0x5e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa5, + 0xff, 0x00, 0x5a, 0xff, 0x5a, 0x00, 0x8f, 0xff, 0x8f, 0x00, 0x00, 0x00, + 0x00, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x81, 0xd8, 0x56, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x4f, 0x3b, 0x00, 0x00, 0x00, 0xb5, 0xf5, 0xb0, 0xe7, 0x28, 0x00, 0x26, + 0xff, 0x55, 0x00, 0x3e, 0xe7, 0x4c, 0xdc, 0x06, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xea, 0x6d, 0x00, 0xf4, 0x64, 0x22, 0xff, 0xcb, 0x8e, 0xd6, 0xeb, 0x0b, + 0xc5, 0x2f, 0x0b, 0xc5, 0x2f, 0x0e, 0xff, 0x43, 0x00, 0x00, 0x33, 0xfc, + 0x00, 0x00, 0x00, 0x00, 0x70, 0xff, 0x70, 0x00, 0x00, 0x70, 0xff, 0x70, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x8f, 0xff, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x17, 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x07, + 0xcd, 0xa8, 0x36, 0x03, 0x35, 0x00, 0x24, 0x0b, 0xcf, 0x85, 0x36, 0x00, + 0x32, 0xfd, 0x1b, 0x01, 0xbb, 0x85, 0x00, 0x19, 0xff, 0x48, 0x01, 0xca, + 0x70, 0x01, 0xca, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x2c, 0x09, 0x00, 0x2c, 0x08, 0x00, 0xea, 0x6d, 0x00, 0xf4, + 0x64, 0x22, 0xff, 0x12, 0x00, 0x46, 0xeb, 0x03, 0x36, 0x0e, 0x03, 0x36, + 0x0e, 0x0e, 0xff, 0x43, 0x00, 0x00, 0x1f, 0xea, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x70, 0xff, 0x70, 0x70, 0xff, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x55, 0x37, 0x00, 0x37, 0x55, 0x00, 0x1e, 0x55, 0x1e, 0xff, 0x8f, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x57, 0xcc, + 0xcc, 0xe8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x98, 0xf3, 0xe6, 0xc9, 0x0e, + 0xff, 0x85, 0xfc, 0x93, 0xfb, 0xde, 0xc9, 0x00, 0x41, 0xf6, 0x00, 0x00, + 0x9e, 0x99, 0x00, 0x0c, 0xff, 0x3c, 0x2c, 0xff, 0x0f, 0x00, 0x69, 0xd0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0xf8, 0x54, + 0x20, 0xf8, 0x51, 0x00, 0xea, 0x6d, 0x00, 0xf4, 0x64, 0x22, 0xff, 0x12, + 0x00, 0x46, 0xeb, 0x0e, 0xff, 0x43, 0x0e, 0xff, 0x43, 0x0e, 0xff, 0x43, + 0x00, 0x00, 0x0a, 0xa3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xff, + 0xff, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xa5, 0x00, 0xa5, + 0xff, 0x00, 0x5a, 0xff, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xe6, 0x6f, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xc7, 0x8b, 0x00, 0x0e, 0xff, 0xc7, 0x1f, 0x00, + 0xee, 0x64, 0x00, 0x00, 0x64, 0xe7, 0x00, 0x00, 0x8f, 0xba, 0x00, 0x01, + 0xfd, 0x2f, 0x54, 0xe5, 0x00, 0x00, 0x41, 0xf6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x45, 0x09, 0x03, 0x46, 0x09, 0x00, + 0xea, 0x6d, 0x00, 0xf4, 0x64, 0x22, 0xff, 0x12, 0x00, 0x46, 0xeb, 0x0e, + 0xff, 0x43, 0x0e, 0xff, 0x43, 0x0e, 0xff, 0x43, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xff, 0xff, 0x70, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x55, 0x37, 0x00, 0x37, 0x55, 0x00, 0x1e, 0x55, + 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0xb1, 0xb6, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xc7, 0x8b, 0x00, 0x0e, 0xff, 0x5d, 0x00, 0x00, 0xee, 0x64, 0x00, 0x9b, + 0xe8, 0x53, 0x00, 0x00, 0x23, 0xc4, 0xd7, 0x00, 0xf1, 0x22, 0x7b, 0xbe, + 0x00, 0x00, 0x1a, 0xff, 0x00, 0x00, 0x00, 0x62, 0xa4, 0xa4, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xea, 0x6d, 0x00, 0xf4, + 0x64, 0x22, 0xff, 0x12, 0x00, 0x46, 0xeb, 0x0e, 0xff, 0x43, 0x0e, 0xff, + 0x43, 0x0e, 0xff, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x70, 0xff, 0x70, 0x70, 0xff, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x69, + 0xe8, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc7, 0x8b, 0x00, 0x0e, + 0xff, 0x43, 0x00, 0x00, 0xee, 0x64, 0x00, 0x52, 0xcc, 0xa7, 0x00, 0x00, + 0x4e, 0xea, 0x76, 0x00, 0x75, 0x0c, 0x6f, 0xca, 0x00, 0x00, 0x26, 0xff, + 0x00, 0x00, 0x00, 0x49, 0x7a, 0x7a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xea, 0x6d, 0x00, 0xf4, 0x64, 0x22, 0xff, 0x12, + 0x00, 0x46, 0xeb, 0x0e, 0xff, 0x43, 0x0e, 0xff, 0x43, 0x0e, 0xff, 0x43, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xff, 0x70, 0x00, + 0x00, 0x70, 0xff, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0xf5, 0x4c, 0x03, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xc7, 0x8b, 0x00, 0x0e, 0xff, 0x43, 0x00, 0x00, + 0xd0, 0x8f, 0x05, 0x00, 0x4a, 0xf5, 0x00, 0x00, 0x99, 0xa2, 0x00, 0x08, + 0x75, 0x17, 0x47, 0xf2, 0x01, 0x00, 0x4e, 0xeb, 0x09, 0x56, 0x17, 0x00, + 0x00, 0x00, 0x08, 0x75, 0x17, 0x08, 0x75, 0x17, 0x09, 0x56, 0x17, 0x00, + 0xea, 0x6d, 0x00, 0xf4, 0x64, 0x22, 0xff, 0x12, 0x00, 0x46, 0xeb, 0x0e, + 0xff, 0x43, 0x0e, 0xff, 0x43, 0x0e, 0xff, 0x43, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x5e, 0xff, 0x70, 0x00, 0x00, 0x00, 0x00, 0x70, 0xff, + 0x5e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x9a, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xc7, 0x8b, 0x00, 0x0e, 0xff, 0x43, 0x00, 0x00, 0x62, 0xee, 0xfc, 0x00, + 0x41, 0xf7, 0x00, 0x00, 0x9f, 0x99, 0x00, 0x27, 0xfe, 0x4f, 0x1a, 0xfc, + 0x27, 0x00, 0x82, 0xba, 0x3d, 0xf9, 0x14, 0x00, 0x00, 0x00, 0x27, 0xfe, + 0x4f, 0x27, 0xfe, 0x4f, 0x3d, 0xf9, 0x14, 0x00, 0xea, 0x6d, 0x00, 0xf6, + 0x60, 0x22, 0xff, 0x12, 0x00, 0x46, 0xeb, 0x0e, 0xff, 0x43, 0x0e, 0xff, + 0x43, 0x0e, 0xff, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, + 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x14, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x0e, 0x00, 0x13, 0xf7, 0x74, 0x3a, + 0xe1, 0x6d, 0x00, 0x00, 0x12, 0x00, 0x00, 0x97, 0x9e, 0x0d, 0xeb, 0x3d, + 0x71, 0xaf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x12, 0x00, + 0x71, 0xaf, 0x00, 0x00, 0x00, 0x00, 0x33, 0xff, 0x25, 0x22, 0xff, 0x3c, + 0x20, 0x67, 0xeb, 0x00, 0x00, 0x00, 0x17, 0xff, 0x42, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, + 0xc1, 0xc1, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0xa8, 0x8b, 0x86, 0x0d, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x16, 0xc8, 0x5c, 0x97, 0x00, 0x49, 0x33, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x33, 0x00, 0x00, + 0x00, 0x00, 0xf9, 0xad, 0x00, 0x1c, 0xd1, 0xd1, 0x95, 0xd1, 0xc0, 0x00, + 0x00, 0x00, 0xba, 0xf7, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + + +static mu_Rect atlas[] = { + [ MU_ICON_CLOSE ] = { 88, 68, 16, 16 }, + [ MU_ICON_CHECK ] = { 0, 0, 18, 18 }, + [ MU_ICON_EXPANDED ] = { 118, 68, 7, 5 }, + [ MU_ICON_COLLAPSED ] = { 113, 68, 5, 7 }, + [ ATLAS_WHITE ] = { 125, 68, 3, 3 }, + [ ATLAS_FONT+32 ] = { 84, 68, 2, 17 }, + [ ATLAS_FONT+33 ] = { 39, 68, 3, 17 }, + [ ATLAS_FONT+34 ] = { 114, 51, 5, 17 }, + [ ATLAS_FONT+35 ] = { 34, 17, 7, 17 }, + [ ATLAS_FONT+36 ] = { 28, 34, 6, 17 }, + [ ATLAS_FONT+37 ] = { 58, 0, 9, 17 }, + [ ATLAS_FONT+38 ] = { 103, 0, 8, 17 }, + [ ATLAS_FONT+39 ] = { 86, 68, 2, 17 }, + [ ATLAS_FONT+40 ] = { 42, 68, 3, 17 }, + [ ATLAS_FONT+41 ] = { 45, 68, 3, 17 }, + [ ATLAS_FONT+42 ] = { 34, 34, 6, 17 }, + [ ATLAS_FONT+43 ] = { 40, 34, 6, 17 }, + [ ATLAS_FONT+44 ] = { 48, 68, 3, 17 }, + [ ATLAS_FONT+45 ] = { 51, 68, 3, 17 }, + [ ATLAS_FONT+46 ] = { 54, 68, 3, 17 }, + [ ATLAS_FONT+47 ] = { 124, 34, 4, 17 }, + [ ATLAS_FONT+48 ] = { 46, 34, 6, 17 }, + [ ATLAS_FONT+49 ] = { 52, 34, 6, 17 }, + [ ATLAS_FONT+50 ] = { 58, 34, 6, 17 }, + [ ATLAS_FONT+51 ] = { 64, 34, 6, 17 }, + [ ATLAS_FONT+52 ] = { 70, 34, 6, 17 }, + [ ATLAS_FONT+53 ] = { 76, 34, 6, 17 }, + [ ATLAS_FONT+54 ] = { 82, 34, 6, 17 }, + [ ATLAS_FONT+55 ] = { 88, 34, 6, 17 }, + [ ATLAS_FONT+56 ] = { 94, 34, 6, 17 }, + [ ATLAS_FONT+57 ] = { 100, 34, 6, 17 }, + [ ATLAS_FONT+58 ] = { 57, 68, 3, 17 }, + [ ATLAS_FONT+59 ] = { 60, 68, 3, 17 }, + [ ATLAS_FONT+60 ] = { 106, 34, 6, 17 }, + [ ATLAS_FONT+61 ] = { 112, 34, 6, 17 }, + [ ATLAS_FONT+62 ] = { 118, 34, 6, 17 }, + [ ATLAS_FONT+63 ] = { 119, 51, 5, 17 }, + [ ATLAS_FONT+64 ] = { 18, 0, 10, 17 }, + [ ATLAS_FONT+65 ] = { 41, 17, 7, 17 }, + [ ATLAS_FONT+66 ] = { 48, 17, 7, 17 }, + [ ATLAS_FONT+67 ] = { 55, 17, 7, 17 }, + [ ATLAS_FONT+68 ] = { 111, 0, 8, 17 }, + [ ATLAS_FONT+69 ] = { 0, 35, 6, 17 }, + [ ATLAS_FONT+70 ] = { 6, 35, 6, 17 }, + [ ATLAS_FONT+71 ] = { 119, 0, 8, 17 }, + [ ATLAS_FONT+72 ] = { 18, 17, 8, 17 }, + [ ATLAS_FONT+73 ] = { 63, 68, 3, 17 }, + [ ATLAS_FONT+74 ] = { 66, 68, 3, 17 }, + [ ATLAS_FONT+75 ] = { 62, 17, 7, 17 }, + [ ATLAS_FONT+76 ] = { 12, 51, 6, 17 }, + [ ATLAS_FONT+77 ] = { 28, 0, 10, 17 }, + [ ATLAS_FONT+78 ] = { 67, 0, 9, 17 }, + [ ATLAS_FONT+79 ] = { 76, 0, 9, 17 }, + [ ATLAS_FONT+80 ] = { 69, 17, 7, 17 }, + [ ATLAS_FONT+81 ] = { 85, 0, 9, 17 }, + [ ATLAS_FONT+82 ] = { 76, 17, 7, 17 }, + [ ATLAS_FONT+83 ] = { 18, 51, 6, 17 }, + [ ATLAS_FONT+84 ] = { 24, 51, 6, 17 }, + [ ATLAS_FONT+85 ] = { 26, 17, 8, 17 }, + [ ATLAS_FONT+86 ] = { 83, 17, 7, 17 }, + [ ATLAS_FONT+87 ] = { 38, 0, 10, 17 }, + [ ATLAS_FONT+88 ] = { 90, 17, 7, 17 }, + [ ATLAS_FONT+89 ] = { 30, 51, 6, 17 }, + [ ATLAS_FONT+90 ] = { 36, 51, 6, 17 }, + [ ATLAS_FONT+91 ] = { 69, 68, 3, 17 }, + [ ATLAS_FONT+92 ] = { 124, 51, 4, 17 }, + [ ATLAS_FONT+93 ] = { 72, 68, 3, 17 }, + [ ATLAS_FONT+94 ] = { 42, 51, 6, 17 }, + [ ATLAS_FONT+95 ] = { 15, 68, 4, 17 }, + [ ATLAS_FONT+96 ] = { 48, 51, 6, 17 }, + [ ATLAS_FONT+97 ] = { 54, 51, 6, 17 }, + [ ATLAS_FONT+98 ] = { 97, 17, 7, 17 }, + [ ATLAS_FONT+99 ] = { 0, 52, 5, 17 }, + [ ATLAS_FONT+100 ] = { 104, 17, 7, 17 }, + [ ATLAS_FONT+101 ] = { 60, 51, 6, 17 }, + [ ATLAS_FONT+102 ] = { 19, 68, 4, 17 }, + [ ATLAS_FONT+103 ] = { 66, 51, 6, 17 }, + [ ATLAS_FONT+104 ] = { 111, 17, 7, 17 }, + [ ATLAS_FONT+105 ] = { 75, 68, 3, 17 }, + [ ATLAS_FONT+106 ] = { 78, 68, 3, 17 }, + [ ATLAS_FONT+107 ] = { 72, 51, 6, 17 }, + [ ATLAS_FONT+108 ] = { 81, 68, 3, 17 }, + [ ATLAS_FONT+109 ] = { 48, 0, 10, 17 }, + [ ATLAS_FONT+110 ] = { 118, 17, 7, 17 }, + [ ATLAS_FONT+111 ] = { 0, 18, 7, 17 }, + [ ATLAS_FONT+112 ] = { 7, 18, 7, 17 }, + [ ATLAS_FONT+113 ] = { 14, 34, 7, 17 }, + [ ATLAS_FONT+114 ] = { 23, 68, 4, 17 }, + [ ATLAS_FONT+115 ] = { 5, 52, 5, 17 }, + [ ATLAS_FONT+116 ] = { 27, 68, 4, 17 }, + [ ATLAS_FONT+117 ] = { 21, 34, 7, 17 }, + [ ATLAS_FONT+118 ] = { 78, 51, 6, 17 }, + [ ATLAS_FONT+119 ] = { 94, 0, 9, 17 }, + [ ATLAS_FONT+120 ] = { 84, 51, 6, 17 }, + [ ATLAS_FONT+121 ] = { 90, 51, 6, 17 }, + [ ATLAS_FONT+122 ] = { 10, 68, 5, 17 }, + [ ATLAS_FONT+123 ] = { 31, 68, 4, 17 }, + [ ATLAS_FONT+124 ] = { 96, 51, 6, 17 }, + [ ATLAS_FONT+125 ] = { 35, 68, 4, 17 }, + [ ATLAS_FONT+126 ] = { 102, 51, 6, 17 }, + [ ATLAS_FONT+127 ] = { 108, 51, 6, 17 }, +}; + diff --git a/src/build.sh b/src/build.sh new file mode 100755 index 0000000..9fc183c --- /dev/null +++ b/src/build.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +OS_NAME=`uname -o 2>/dev/null || uname -s` + +if [ $OS_NAME == "Msys" ]; then + GLFLAG="-lopengl32" +elif [ $OS_NAME == "Darwin" ]; then + GLFLAG="-framework OpenGL" +else + GLFLAG="-lGL" +fi + +CFLAGS="-I../microui -Wall -std=gnu11 -pedantic `sdl2-config --libs` $GLFLAG -lm -O0 -g" + +gcc main.c renderer.c ../microui/microui.c $CFLAGS + diff --git a/src/cpu.c b/src/cpu.c new file mode 100644 index 0000000..80acaea --- /dev/null +++ b/src/cpu.c @@ -0,0 +1,161 @@ + + + + + +typedef struct { + char text[3]; +} Cpu_Memory_Cell; + +#define NUM_MEMORY_CELLS 256 +Cpu_Memory_Cell memory[NUM_MEMORY_CELLS]; +_Static_assert(NUM_MEMORY_CELLS % 4 == 0, "NUM_MEMORY_CELLS must be a multiple of 4."); + + + +#if 0 +typedef struct { + char text[3]; +} Cpu_Register; +#endif + +typedef Cpu_Memory_Cell Cpu_Register; + +#define NUM_REGISTERS 8 +Cpu_Register program_counter;// = {"00"}; +char *register_names[NUM_REGISTERS] = { + "Register 0", "Register 1", "Register 2", "Register 3", + "Register 4", "Register 5", "Register 6", "Register 7", +}; +Cpu_Register registers[NUM_REGISTERS]; + +bool cpu_running = false; + +void cpu_memory_clear() { + for(int i = 0; i < NUM_MEMORY_CELLS; i++) + { + memory[i].text[0] = '0'; + memory[i].text[1] = '0'; + } + for(int i = 0; i < NUM_REGISTERS; i++) { + registers[i].text[0] = '0'; + registers[i].text[1] = '0'; + } + program_counter.text[0] = '0'; + program_counter.text[1] = '0'; +} + + +void cpu_reset() { + for(int i = 0; i < NUM_REGISTERS; i++) { + registers[i].text[0] = '0'; + registers[i].text[1] = '0'; + } + program_counter.text[0] = '0'; + program_counter.text[1] = '0'; + cpu_running = true; +} + +int char_to_nibble(char c) { + char nibble = c; + if(nibble >= 'A') { + nibble -= 7; + } + nibble -= '0'; + return nibble; +} + +int cell_to_value(Cpu_Memory_Cell cell) { + char ms_nibble = char_to_nibble(cell.text[0]); + char ls_nibble = char_to_nibble(cell.text[1]); + int value = ms_nibble << 4 | ls_nibble; + return value; +} + +void cell_copy(Cpu_Memory_Cell *dst, Cpu_Memory_Cell src) { + dst->text[0] = src.text[0]; + dst->text[1] = src.text[1]; +} + +void cell_assign_value(Cpu_Memory_Cell *dst, int value) { + assert(value <= 255); + snprintf(dst->text, sizeof(dst->text), "%2.2X", value); +} + +typedef enum { + CPU_OPCODE_NONE = 0x00, // X X X + CPU_OPCODE_HALT = 0x01, // X X X + CPU_OPCODE_LOAD = 0x02, // X R R + CPU_OPCODE_STORE = 0x03, // X R R + CPU_OPCODE_SET = 0x04, // X R I + CPU_OPCODE_MOV = 0x05, // X R R + CPU_OPCODE_JUMP = 0x06, // X X R + CPU_OPCODE_ADD = 0x07, // R R R + CPU_OPCODE_SUB = 0x08, // R R R +} Cpu_Opcode; +void cpu_step() { + if(!cpu_running) { + return; + } + + int pc = cell_to_value(program_counter); + if(pc > NUM_MEMORY_CELLS - 3) { + cpu_running = false; + return; + } + int opcode = cell_to_value(memory[pc]); + int param1 = cell_to_value(memory[pc+1]); + int param2 = cell_to_value(memory[pc+2]); + int param3 = cell_to_value(memory[pc+3]); + printf("Step params: %2.2X %2.2X %2.2X\n", param1, param2, param3); + int new_pc = pc + 4; + switch(opcode) { + case CPU_OPCODE_NONE: break; + case CPU_OPCODE_HALT: { + cpu_running = 0; + new_pc = pc; + } break; + case CPU_OPCODE_LOAD: { + cell_copy(®isters[param2], memory[param3]); + } break; + case CPU_OPCODE_STORE: { + cell_copy(&memory[param3], registers[param2]); + } break; + case CPU_OPCODE_SET: { + cell_copy(®isters[param2], memory[pc+3]); + } break; + case CPU_OPCODE_MOV: { + cell_copy(®isters[param2], registers[param3]); + } break; + case CPU_OPCODE_JUMP: { + new_pc = cell_to_value(registers[param3]); + } break; + case CPU_OPCODE_ADD: { + int left_operand = cell_to_value(registers[param2]); + int right_operand = cell_to_value(registers[param3]); + int result = left_operand + right_operand; + cell_assign_value(®isters[param1], result); + } break; + case CPU_OPCODE_SUB: { + int left_operand = cell_to_value(registers[param2]); + int right_operand = cell_to_value(registers[param3]); + int result = left_operand - right_operand; + cell_assign_value(®isters[param1], result); + } break; + } + + if(new_pc > NUM_MEMORY_CELLS - 3) { + cpu_running = false; + return; + } else { + cell_assign_value(&program_counter, new_pc); + } +} + + + + + + + + diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..f1e0c47 --- /dev/null +++ b/src/main.c @@ -0,0 +1,449 @@ +#include +#include +#include "renderer.h" +#include "../microui/microui.h" +#include +#include +#include + +// I had to change -std to gnu11 instead of c11 for this one. +// Defining the posix version macro didn't do anything at all. +#include +#include + +#include "cpu.c" + +int load_program(char *filepath) { + bool success = true; + FILE *file = NULL; + if(success) { + file = fopen(filepath, "r"); + if(file == NULL) { + perror("Error opening file for reading"); + success = false; + }} + + if(success) { + int seek_status = fseek(file, 0, SEEK_END); + if(seek_status != 0) { + perror("Error seeking in file"); + success = false; + } + } + + long file_size = 0; + if(success) { + file_size = ftell(file); + int seek_status = fseek(file, 0, SEEK_SET); + if(seek_status != 0) { + perror("Error seeking in file"); + success = false; + } + } + + char *data = NULL; + if(success) { + data = malloc(file_size); + if(data == NULL) { + success = false; + } + } + + if(success) { + size_t read_count = fread(data, 1, file_size, file); + if(read_count != file_size) { + fprintf(stderr, "Incomplete read, aborting.\n"); + return 1; + } + } + + if(success) { + cpu_memory_clear(); + int memory_cursor = 0; + Cpu_Memory_Cell cell = {"00"}; + bool first_nibble = true; + for(int i = 0; i < file_size; i++) { + char c = data[i]; + if((c < '0') || (c > '9' && c < 'A') || (c > 'F')) { + if(c != ' ' && c != '\n' && c != '\t') { + fprintf(stderr, "Strange character in memory file: %c\n", c); + success = false; + break; + } + } else { + if(memory_cursor >= NUM_MEMORY_CELLS) { + fprintf(stderr, "Memory in file too big for machine memory.\n"); + success = false; + break; + } + if(first_nibble) { + cell.text[0] = c; + first_nibble = false; + } else { + cell.text[1] = c; + first_nibble = true; + memory[memory_cursor] = cell; + memory_cursor += 1; + } + } + } + if(!first_nibble) { + fprintf(stderr, "Number of nibbles in file is odd!\n"); + success = false; + } + } + + if(file != NULL) { + fclose(file); + } + if(data != NULL) { + free(data); + } + return success ? 0 : 1; +} + +int save_program(char *filepath) { + bool success = true; + FILE *file = NULL; + if(success) { + file = fopen(filepath, "w"); + if(file == NULL) { + perror("Error opening file for writing"); + success = false; + }} + + if(success) { + char text[NUM_MEMORY_CELLS * 3]; + for(int i = 0; i < NUM_MEMORY_CELLS; i++) { + char *c1 = &text[i*3]; + char *c2 = c1+1; + char *whitespace = c2+1; + *c1 = memory[i].text[0]; + *c2 = memory[i].text[1]; + *whitespace = (i%4==3) ? '\n' : ' '; + } + + size_t written = fwrite(text, sizeof(text), 1, file); + if(written == 0) { + perror("Write error"); + success = false; + } + } + + if(file != NULL) { + fclose(file); + } + return success ? 0 : 1; +} + +int width = 800; +int height = 600; + +typedef int64_t i64; + + + +int mu_textbox_raw2(mu_Context *ctx, char *buf, int bufsz, mu_Id id, mu_Rect r, + int opt) +{ + int res = 0; + mu_update_control(ctx, id, r, opt | MU_OPT_HOLDFOCUS); + + if (ctx->focus == id) { + /* handle text input */ + int len = strlen(buf); + int n = mu_min(bufsz - len - 1, (int) strlen(ctx->input_text)); + if (n > 0) { + char input_char = ctx->input_text[0]; + if(input_char >= 'a' && input_char <= 'f') { + input_char -= 0x20; // Convert to upper case. + } + if((input_char >= '0' && input_char <= '9') || (input_char >= 'A' && input_char <= 'F')) + { + buf[len] = input_char; + len++; + buf[len] = '\0'; + res |= MU_RES_CHANGE; + } + } + /* handle backspace */ + if (ctx->key_pressed & MU_KEY_BACKSPACE && len > 0) { + --len; + buf[len] = '\0'; + res |= MU_RES_CHANGE; + } + /* handle return */ + if (ctx->key_pressed & MU_KEY_RETURN) { + mu_set_focus(ctx, 0); + res |= MU_RES_SUBMIT; + } + } + + /* draw */ + mu_draw_control_frame(ctx, id, r, MU_COLOR_BASE, opt); + if (ctx->focus == id) { + mu_Color color = ctx->style->colors[MU_COLOR_TEXT]; + mu_Font font = ctx->style->font; + int textw = ctx->text_width(font, buf, -1); + int texth = ctx->text_height(font); + int ofx = r.w - ctx->style->padding - textw - 1; + int textx = r.x + mu_min(ofx, ctx->style->padding); + int texty = r.y + (r.h - texth) / 2; + mu_push_clip_rect(ctx, r); + mu_draw_text(ctx, font, buf, -1, mu_vec2(textx, texty), color); + mu_draw_rect(ctx, mu_rect(textx + textw, texty, 1, texth), color); + mu_pop_clip_rect(ctx); + } else { + mu_draw_control_text(ctx, buf, r, MU_COLOR_TEXT, opt); + } + + return res; +} + +int mu_textbox_ex2(mu_Context *ctx, char *buf, int bufsz, int opt) { + mu_Id id = mu_get_id(ctx, &buf, sizeof(buf)); + mu_Rect r = mu_layout_next(ctx); + return mu_textbox_raw2(ctx, buf, bufsz, id, r, opt); +} +#define mu_textbox2(ctx, buf, bufsz) mu_textbox_ex2(ctx, buf, bufsz, 0) + +int measure_text(mu_Context *ctx, char *text) +{ + mu_Font font = ctx->style->font; + return ctx->text_width(font, text, -1); +} + + +//static float bg[3] = { 90, 95, 100 }; +static float bg[3] = { 255, 230, 230 }; + +char filepath_buffer[1024*4] = {0}; + +static void process_frame( + mu_Context *ctx, + i64 current_seconds_timestamp +) { + mu_begin(ctx); + if ( + //mu_begin_window(ctx, "My Window", mu_rect(10, 10, 300, 400)) + mu_begin_window_ex(ctx, "My Window", mu_rect(0, 0, width, height), + MU_OPT_NOTITLE|MU_OPT_NORESIZE) + ) { + + mu_layout_row(ctx, 4, (int[]) { 200, 200, 200, -1 }, -1); + mu_begin_panel(ctx, "register panel"); + mu_layout_row(ctx, 2, (int[]) { 120, -1 }, 0); + mu_label(ctx, cpu_running ? "Running" : "Halted"); mu_label(ctx, ""); + mu_label(ctx, "Program counter:"); + mu_label(ctx, program_counter.text); + //mu_label(ctx, "Register 0:"); + //mu_label(ctx, "0x00"); + //mu_label(ctx, "Register 1:"); + //mu_label(ctx, "0x00"); + for(int i = 0; i < NUM_REGISTERS; i++) { + mu_label(ctx, register_names[i]); + mu_label(ctx, registers[i].text); + } + mu_end_panel(ctx); + + mu_begin_panel(ctx, "memory panel"); + mu_Container *panel = mu_get_current_container(ctx); + // NOTE(Zelaven): Garbage formula that kinda works. +#if 0 + int width = (panel->rect.w-ctx->style->padding*2-ctx->style->spacing*4)/4; + printf("%d = %d / 4\n", width, panel->rect.w-ctx->style->padding*2-ctx->style->spacing*3); + printf("%f = %f / 4.0\n", + ((float)panel->rect.w-(float)ctx->style->padding*2.0f-(float)ctx->style->spacing*3.0f)/4.0f, + (float)panel->rect.w-(float)ctx->style->spacing*2.0f-(float)ctx->style->spacing*3.0f); + mu_layout_row(ctx, 4, (int[]) { width, width, width, width }, 0); + static char mem1[3] = {0}; + mu_textbox(ctx, mem1, sizeof(mem1)); + static char mem2[3] = {0}; + mu_textbox2(ctx, mem2, sizeof(mem2)); + static char mem3[3] = {0}; + mu_textbox2(ctx, mem3, sizeof(mem3)); + static char mem4[3] = {0}; + mu_textbox2(ctx, mem4, sizeof(mem4)); +#endif +#if 0 + int marker_width = measure_text(ctx, ">__"); + int label_width = measure_text(ctx, "0x0000__"); + int cell_real_estate = (panel->rect.w-ctx->style->padding*2-ctx->style->spacing*5) - marker_width - label_width; + int cell_width = cell_real_estate / 4; + mu_layout_row(ctx, 6, (int[]) { marker_width, label_width, cell_width, cell_width, cell_width, cell_width }, 0); + mu_label(ctx, ">"); + mu_label(ctx, "0x0000"); + static char mem1[3] = {0}; + mu_textbox(ctx, mem1, sizeof(mem1)); + static char mem2[3] = {0}; + mu_textbox2(ctx, mem2, sizeof(mem2)); + static char mem3[3] = {0}; + mu_textbox2(ctx, mem3, sizeof(mem3)); + static char mem4[3] = {0}; + mu_textbox2(ctx, mem4, sizeof(mem4)); + mu_end_panel(ctx); +#endif + int marker_width = measure_text(ctx, ">__"); + int label_width = measure_text(ctx, "0x0000__"); + int cell_real_estate = (panel->rect.w-ctx->style->padding*2-ctx->style->spacing*5) - marker_width - label_width - ctx->style->scrollbar_size; + int cells_per_row = 4; + int cell_width = cell_real_estate / cells_per_row; + mu_layout_row(ctx, 2+cells_per_row, (int[]) { marker_width, label_width, cell_width, cell_width, cell_width, cell_width }, 0); + for(int i = 0; i < NUM_MEMORY_CELLS; i += cells_per_row) + { + mu_label(ctx, (cell_to_value(program_counter) == i) ? ">" : ""); + char buf[7] = "0x0000"; + snprintf(buf, sizeof(buf), "0x%4.4X", i); + mu_label(ctx, buf); + for(int j = 0; j < cells_per_row; j++) { + mu_textbox2(ctx, memory[i+j].text, 3); + } + } + mu_end_panel(ctx); + + mu_begin_panel(ctx, "buttons panel"); + mu_layout_row(ctx, 2, (int[]) { 100, -1 }, 0); + if(mu_button(ctx, "Reset")) { + cpu_reset(); + } + if(mu_button(ctx, "Clear")) { + cpu_memory_clear(); + cpu_running = false; + } + if(mu_button(ctx, "Step")) { + cpu_step(); + } + mu_end_panel(ctx); + + mu_begin_panel(ctx, "save/load panel"); + mu_layout_row(ctx, 1, (int[]) { -1 }, 0); + mu_textbox(ctx, filepath_buffer, sizeof(filepath_buffer)); + if(mu_button(ctx, "Save")) { + save_program(filepath_buffer); + } + if(mu_button(ctx, "Load")) { + load_program(filepath_buffer); + cpu_reset(); + cpu_running = false; + } + mu_end_panel(ctx); + + mu_end_window(ctx); + } + mu_end(ctx); +} + +static const char button_map[256] = { + [ SDL_BUTTON_LEFT & 0xff ] = MU_MOUSE_LEFT, + [ SDL_BUTTON_RIGHT & 0xff ] = MU_MOUSE_RIGHT, + [ SDL_BUTTON_MIDDLE & 0xff ] = MU_MOUSE_MIDDLE, +}; + +static const char key_map[256] = { + [ SDLK_LSHIFT & 0xff ] = MU_KEY_SHIFT, + [ SDLK_RSHIFT & 0xff ] = MU_KEY_SHIFT, + [ SDLK_LCTRL & 0xff ] = MU_KEY_CTRL, + [ SDLK_RCTRL & 0xff ] = MU_KEY_CTRL, + [ SDLK_LALT & 0xff ] = MU_KEY_ALT, + [ SDLK_RALT & 0xff ] = MU_KEY_ALT, + [ SDLK_RETURN & 0xff ] = MU_KEY_RETURN, + [ SDLK_BACKSPACE & 0xff ] = MU_KEY_BACKSPACE, +}; + +static int text_width(mu_Font font, const char *text, int len) { + if (len == -1) { len = strlen(text); } + return r_get_text_width(text, len); +} + +static int text_height(mu_Font font) { + return r_get_text_height(); +} + +int main(int argc, char **argv) { + if(argc > 1) { + int filepath_length = strlen(argv[1]); + int buffer_length = sizeof(filepath_buffer); + if(filepath_length < buffer_length) { + strncpy(filepath_buffer, argv[1], buffer_length); + } else { + strncpy(filepath_buffer, "Filepath is too long.", buffer_length); + } + if(load_program(argv[1]) != 0) { + return 1; + } + } else { + cpu_memory_clear(); + } + + /* init SDL and renderer */ + SDL_Init(SDL_INIT_EVERYTHING); + r_init(width, height); + + /* init microui */ + mu_Context *ctx = malloc(sizeof(mu_Context)); + mu_init(ctx); + ctx->text_width = text_width; + ctx->text_height = text_height; + + /* main loop */ + for (;;) { + /* handle SDL events */ + SDL_Event e; + while (SDL_PollEvent(&e)) { + switch (e.type) { + case SDL_QUIT: exit(EXIT_SUCCESS); break; + case SDL_MOUSEMOTION: mu_input_mousemove(ctx, e.motion.x, e.motion.y); break; + case SDL_MOUSEWHEEL: mu_input_scroll(ctx, 0, e.wheel.y * -30); break; + case SDL_TEXTINPUT: mu_input_text(ctx, e.text.text); break; + + case SDL_MOUSEBUTTONDOWN: + case SDL_MOUSEBUTTONUP: { + int b = button_map[e.button.button & 0xff]; + if (b && e.type == SDL_MOUSEBUTTONDOWN) { mu_input_mousedown(ctx, e.button.x, e.button.y, b); } + if (b && e.type == SDL_MOUSEBUTTONUP) { mu_input_mouseup(ctx, e.button.x, e.button.y, b); } + break; + } + + case SDL_KEYDOWN: + case SDL_KEYUP: { + int c = key_map[e.key.keysym.sym & 0xff]; + if (c && e.type == SDL_KEYDOWN) { mu_input_keydown(ctx, c); } + if (c && e.type == SDL_KEYUP) { mu_input_keyup(ctx, c); } + break; + } + } + } + + i64 current_seconds_timestamp = 0; + { + struct timespec clock_timestamp; + int clock_retval = clock_gettime(CLOCK_BOOTTIME, &clock_timestamp); + if(clock_retval != 0) { + int error = errno; + perror("clock_gettime failed: "); + fprintf(stderr, "Errno number: %d\n", error); + return 1; + } + current_seconds_timestamp = clock_timestamp.tv_sec; + } + + /* process frame */ + process_frame(ctx, current_seconds_timestamp); + + /* render */ + r_clear(mu_color(bg[0], bg[1], bg[2], 255)); + mu_Command *cmd = NULL; + while (mu_next_command(ctx, &cmd)) { + switch (cmd->type) { + case MU_COMMAND_TEXT: r_draw_text(cmd->text.str, cmd->text.pos, cmd->text.color); break; + case MU_COMMAND_RECT: r_draw_rect(cmd->rect.rect, cmd->rect.color); break; + case MU_COMMAND_ICON: r_draw_icon(cmd->icon.id, cmd->icon.rect, cmd->icon.color); break; + case MU_COMMAND_CLIP: r_set_clip_rect(cmd->clip.rect); break; + } + } + r_present(); + } + + return 0; +} + diff --git a/src/program1.txt b/src/program1.txt new file mode 100644 index 0000000..923cdde --- /dev/null +++ b/src/program1.txt @@ -0,0 +1,2 @@ +04 00 02 42 +01 diff --git a/src/program2.txt b/src/program2.txt new file mode 100644 index 0000000..ff14c59 --- /dev/null +++ b/src/program2.txt @@ -0,0 +1,2 @@ +04 00 01 F8 +06 00 00 01 diff --git a/src/renderer.c b/src/renderer.c new file mode 100644 index 0000000..f72478d --- /dev/null +++ b/src/renderer.c @@ -0,0 +1,188 @@ +#include +#include +#include +#include "renderer.h" +#include "atlas.inl" + +#define BUFFER_SIZE 16384 + +static GLfloat tex_buf[BUFFER_SIZE * 8]; +static GLfloat vert_buf[BUFFER_SIZE * 8]; +static GLubyte color_buf[BUFFER_SIZE * 16]; +static GLuint index_buf[BUFFER_SIZE * 6]; + +static int width = 800; +static int height = 600; +static int buf_idx; + +static SDL_Window *window; + + +void r_init(int _width, int _height) { + width = _width; height = _height; + + /* init SDL window */ + window = SDL_CreateWindow( + "Brookshearish Machine (uses microui and sample renderer by rxi)", + SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, + width, height, SDL_WINDOW_OPENGL); + SDL_GL_CreateContext(window); + + /* init gl */ + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glEnable(GL_SCISSOR_TEST); + glEnable(GL_TEXTURE_2D); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + + /* init texture */ + GLuint id; + glGenTextures(1, &id); + glBindTexture(GL_TEXTURE_2D, id); + glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, ATLAS_WIDTH, ATLAS_HEIGHT, 0, + GL_ALPHA, GL_UNSIGNED_BYTE, atlas_texture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + assert(glGetError() == 0); +} + + +static void flush(void) { + if (buf_idx == 0) { return; } + + glViewport(0, 0, width, height); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho(0.0f, width, height, 0.0f, -1.0f, +1.0f); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + + glTexCoordPointer(2, GL_FLOAT, 0, tex_buf); + glVertexPointer(2, GL_FLOAT, 0, vert_buf); + glColorPointer(4, GL_UNSIGNED_BYTE, 0, color_buf); + glDrawElements(GL_TRIANGLES, buf_idx * 6, GL_UNSIGNED_INT, index_buf); + + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + + buf_idx = 0; +} + + +static void push_quad(mu_Rect dst, mu_Rect src, mu_Color color) { + if (buf_idx == BUFFER_SIZE) { flush(); } + + int texvert_idx = buf_idx * 8; + int color_idx = buf_idx * 16; + int element_idx = buf_idx * 4; + int index_idx = buf_idx * 6; + buf_idx++; + + /* update texture buffer */ + float x = src.x / (float) ATLAS_WIDTH; + float y = src.y / (float) ATLAS_HEIGHT; + float w = src.w / (float) ATLAS_WIDTH; + float h = src.h / (float) ATLAS_HEIGHT; + tex_buf[texvert_idx + 0] = x; + tex_buf[texvert_idx + 1] = y; + tex_buf[texvert_idx + 2] = x + w; + tex_buf[texvert_idx + 3] = y; + tex_buf[texvert_idx + 4] = x; + tex_buf[texvert_idx + 5] = y + h; + tex_buf[texvert_idx + 6] = x + w; + tex_buf[texvert_idx + 7] = y + h; + + /* update vertex buffer */ + vert_buf[texvert_idx + 0] = dst.x; + vert_buf[texvert_idx + 1] = dst.y; + vert_buf[texvert_idx + 2] = dst.x + dst.w; + vert_buf[texvert_idx + 3] = dst.y; + vert_buf[texvert_idx + 4] = dst.x; + vert_buf[texvert_idx + 5] = dst.y + dst.h; + vert_buf[texvert_idx + 6] = dst.x + dst.w; + vert_buf[texvert_idx + 7] = dst.y + dst.h; + + /* update color buffer */ + memcpy(color_buf + color_idx + 0, &color, 4); + memcpy(color_buf + color_idx + 4, &color, 4); + memcpy(color_buf + color_idx + 8, &color, 4); + memcpy(color_buf + color_idx + 12, &color, 4); + + /* update index buffer */ + index_buf[index_idx + 0] = element_idx + 0; + index_buf[index_idx + 1] = element_idx + 1; + index_buf[index_idx + 2] = element_idx + 2; + index_buf[index_idx + 3] = element_idx + 2; + index_buf[index_idx + 4] = element_idx + 3; + index_buf[index_idx + 5] = element_idx + 1; +} + + +void r_draw_rect(mu_Rect rect, mu_Color color) { + push_quad(rect, atlas[ATLAS_WHITE], color); +} + + +void r_draw_text(const char *text, mu_Vec2 pos, mu_Color color) { + mu_Rect dst = { pos.x, pos.y, 0, 0 }; + for (const char *p = text; *p; p++) { + if ((*p & 0xc0) == 0x80) { continue; } + int chr = mu_min((unsigned char) *p, 127); + mu_Rect src = atlas[ATLAS_FONT + chr]; + dst.w = src.w; + dst.h = src.h; + push_quad(dst, src, color); + dst.x += dst.w; + } +} + + +void r_draw_icon(int id, mu_Rect rect, mu_Color color) { + mu_Rect src = atlas[id]; + int x = rect.x + (rect.w - src.w) / 2; + int y = rect.y + (rect.h - src.h) / 2; + push_quad(mu_rect(x, y, src.w, src.h), src, color); +} + + +int r_get_text_width(const char *text, int len) { + int res = 0; + for (const char *p = text; *p && len--; p++) { + if ((*p & 0xc0) == 0x80) { continue; } + int chr = mu_min((unsigned char) *p, 127); + res += atlas[ATLAS_FONT + chr].w; + } + return res; +} + + +int r_get_text_height(void) { + return 18; +} + + +void r_set_clip_rect(mu_Rect rect) { + flush(); + glScissor(rect.x, height - (rect.y + rect.h), rect.w, rect.h); +} + + +void r_clear(mu_Color clr) { + flush(); + glClearColor(clr.r / 255., clr.g / 255., clr.b / 255., clr.a / 255.); + glClear(GL_COLOR_BUFFER_BIT); +} + + +void r_present(void) { + flush(); + SDL_GL_SwapWindow(window); +} diff --git a/src/renderer.h b/src/renderer.h new file mode 100644 index 0000000..78d58f4 --- /dev/null +++ b/src/renderer.h @@ -0,0 +1,17 @@ +#ifndef RENDERER_H +#define RENDERER_H + +#include "microui.h" + +void r_init(int _width, int _height); +void r_draw_rect(mu_Rect rect, mu_Color color); +void r_draw_text(const char *text, mu_Vec2 pos, mu_Color color); +void r_draw_icon(int id, mu_Rect rect, mu_Color color); + int r_get_text_width(const char *text, int len); + int r_get_text_height(void); +void r_set_clip_rect(mu_Rect rect); +void r_clear(mu_Color color); +void r_present(void); + +#endif + diff --git a/src/test.txt b/src/test.txt new file mode 100644 index 0000000..70964a8 --- /dev/null +++ b/src/test.txt @@ -0,0 +1,64 @@ +04 00 01 F8 +06 00 00 01 +00 00 00 00 +00 00 00 00 +00 00 00 00 +00 00 00 00 +00 00 00 00 +00 00 00 00 +00 00 00 00 +00 00 00 00 +00 00 00 00 +00 00 00 00 +00 00 00 00 +00 00 00 00 +00 00 00 00 +00 00 00 00 +00 00 00 00 +00 00 00 00 +00 00 00 00 +00 00 00 00 +00 00 00 00 +00 00 00 00 +00 00 00 00 +00 00 00 00 +00 00 00 00 +00 00 00 00 +00 00 00 00 +00 00 00 00 +00 00 00 00 +00 00 00 00 +00 00 00 00 +00 00 00 00 +00 00 00 00 +00 00 00 00 +00 00 00 00 +00 00 00 00 +00 00 00 00 +00 00 00 00 +00 00 00 00 +00 00 00 00 +00 00 00 00 +00 00 00 00 +00 00 00 00 +00 00 00 00 +00 00 00 00 +00 00 00 00 +00 00 00 00 +00 00 00 00 +00 00 00 00 +00 00 00 00 +00 00 00 00 +00 00 00 00 +00 00 00 00 +00 00 00 00 +00 00 00 00 +00 00 00 00 +00 00 00 00 +00 00 00 00 +00 00 00 00 +00 00 00 00 +00 00 00 00 +00 00 00 00 +00 00 00 00 +00 00 00 00