From dcb8b4624574f475ed2e3acca6dbbac811299dc8 Mon Sep 17 00:00:00 2001 From: Daanish Date: Mon, 1 Jun 2026 22:13:50 +0100 Subject: [PATCH] chore: split monolithic header to proper program files, add vec2 ruby class to proxy element position etc., other cleanup --- Makefile | 39 +- include/app/app.h | 2 +- include/binding/definitions.h | 1986 -------------------------- include/bindings/definitions.h | 63 + include/{binding => bindings}/ruby.h | 2 +- include/bindings/ruby_compiled.h | 1038 ++++++++++++++ libs/l_mgems/compile.sh | 4 +- samples/button.rb | 7 +- samples/stress.rb | 8 +- src/bindings/animation.cc | 187 +++ src/bindings/app.cc | 206 +++ src/bindings/element_image.cc | 326 +++++ src/bindings/element_rect.cc | 349 +++++ src/bindings/element_text.cc | 411 ++++++ src/bindings/font.cc | 72 + src/bindings/image.cc | 78 + src/bindings/params.cc | 68 + src/bindings/scene.cc | 199 +++ src/bindings/vec2.cc | 90 ++ src/main.cc | 2 +- writeup/analysis.md | 53 +- 21 files changed, 3153 insertions(+), 2037 deletions(-) delete mode 100644 include/binding/definitions.h create mode 100644 include/bindings/definitions.h rename include/{binding => bindings}/ruby.h (98%) create mode 100644 include/bindings/ruby_compiled.h create mode 100644 src/bindings/animation.cc create mode 100644 src/bindings/app.cc create mode 100644 src/bindings/element_image.cc create mode 100644 src/bindings/element_rect.cc create mode 100644 src/bindings/element_text.cc create mode 100644 src/bindings/font.cc create mode 100644 src/bindings/image.cc create mode 100644 src/bindings/params.cc create mode 100644 src/bindings/scene.cc create mode 100644 src/bindings/vec2.cc diff --git a/Makefile b/Makefile index 24ec806..460a3a9 100644 --- a/Makefile +++ b/Makefile @@ -69,42 +69,49 @@ release: mgems $(TARGET_RELEASE) setup: setup.rb @echo "Setting up clangd configuration..." - ruby setup.rb + @ruby setup.rb + @echo "Done." # ---------------- MRB_MGEMS ---------------- mgems: - $(MGEM_DIR)/compile.sh + @$(MGEM_DIR)/compile.sh # ---------------- PCH ---------------- $(PCH_DEBUG): $(INCLUDE_DIR)/pch.h - mkdir -p $(dir $@) - $(CXX) $(PCH_CFLAGS_DEBUG) -o $@ $< + @mkdir -p $(dir $@) + @$(CXX) $(PCH_CFLAGS_DEBUG) -o $@ $< + @echo "Precompiled header (debug) generated at $@" $(PCH_RELEASE): $(INCLUDE_DIR)/pch.h - mkdir -p $(dir $@) - $(CXX) $(PCH_CFLAGS_RELEASE) -o $@ $< + @mkdir -p $(dir $@) + @$(CXX) $(PCH_CFLAGS_RELEASE) -o $@ $< + @echo "Precompiled header (release) generated at $@" # ---------------- LINK ---------------- $(TARGET_DEBUG): $(PCH_DEBUG) $(OBJ_DEBUG) - mkdir -p $(BIN_DIR) - $(CXX) $(CFLAGS_DEBUG) -o $@ $(OBJ_DEBUG) $(SDL_LIBS_DEBUG) $(LIBS) + @mkdir -p $(BIN_DIR) + @$(CXX) $(CFLAGS_DEBUG) -o $@ $(OBJ_DEBUG) $(SDL_LIBS_DEBUG) $(LIBS) + @echo "Debug build complete: $@" $(TARGET_RELEASE): $(PCH_RELEASE) $(OBJ_RELEASE) - mkdir -p $(BIN_DIR) - $(CXX) $(CFLAGS_RELEASE) -o $@ $(OBJ_RELEASE) $(SDL_LIBS_RELEASE) $(LIBS) + @mkdir -p $(BIN_DIR) + @$(CXX) $(CFLAGS_RELEASE) -o $@ $(OBJ_RELEASE) $(SDL_LIBS_RELEASE) $(LIBS) + @echo "Release build complete: $@" # ---------------- COMPILE ---------------- $(OBJ_DIR)/debug/%.o: $(SRC_DIR)/%.cc $(PCH_DEBUG) - mkdir -p $(dir $@) - $(CXX) $(CFLAGS_DEBUG) -include $(INCLUDE_DIR)/pch.h -MMD -MP -c $< -o $@ + @mkdir -p $(dir $@) + @$(CXX) $(CFLAGS_DEBUG) -include $(INCLUDE_DIR)/pch.h -MMD -MP -c $< -o $@ + @echo "[CXX] Debug object file generated: $@ from $<" $(OBJ_DIR)/release/%.o: $(SRC_DIR)/%.cc $(PCH_RELEASE) - mkdir -p $(dir $@) - $(CXX) $(CFLAGS_RELEASE) -include $(INCLUDE_DIR)/pch.h -MMD -MP -c $< -o $@ + @mkdir -p $(dir $@) + @$(CXX) $(CFLAGS_RELEASE) -include $(INCLUDE_DIR)/pch.h -MMD -MP -c $< -o $@ + @echo "[CXX] Release object file generated: $@ from $<" # ---------------- DEP ---------------- @@ -114,4 +121,6 @@ $(OBJ_DIR)/release/%.o: $(SRC_DIR)/%.cc $(PCH_RELEASE) # ---------------- CLEAN ---------------- clean: - rm -rf $(OBJ_DIR) $(BIN_DIR) \ No newline at end of file + @rm -rf $(OBJ_DIR) $(BIN_DIR) + @$(MGEM_DIR)/compile.sh clean + @echo "Cleaned build artifacts." \ No newline at end of file diff --git a/include/app/app.h b/include/app/app.h index 30481de..3117956 100644 --- a/include/app/app.h +++ b/include/app/app.h @@ -1,7 +1,7 @@ #ifndef APP_H #define APP_H -#include "binding/ruby.h" +#include "bindings/ruby.h" #include "localization/localization.h" #include "utils.h" #include "window/window.h" diff --git a/include/binding/definitions.h b/include/binding/definitions.h deleted file mode 100644 index ae06344..0000000 --- a/include/binding/definitions.h +++ /dev/null @@ -1,1986 +0,0 @@ -#ifndef DEFINITIONS_H -#define DEFINITIONS_H - -#include "app/app.h" - -namespace definitions { -inline mrb_value wrap(mrb_state *mrb, RClass *cls, const mrb_data_type *type, uint64_t id) { - RBasic *obj_b = mrb_obj_alloc(mrb, MRB_TT_DATA, cls); - mrb_value obj = mrb_obj_value(obj_b); - - Wrapper *w = new Wrapper(); - w->id = id; - - mrb_data_init(obj, w, type); - - return obj; -} - -static void Params_free(mrb_state *mrb, void *ptr) { - UNUSED(mrb); - uint64_t id = ((Wrapper *)ptr)->id; - app::element_pool.release(id); - delete (Wrapper *)ptr; -} - -static const struct mrb_data_type Params_type = {"Params", Params_free}; - -static mrb_value Params_init(mrb_state *mrb, mrb_value self) { - Wrapper *old = (Wrapper *)DATA_PTR(self); - if (old) - mrb_free(mrb, old); - mrb_data_init(self, nullptr, &Params_type); - Wrapper *s = new Wrapper(); - - mrb_int id; - mrb_get_args(mrb, "z", &id); - - s->id = id; - - mrb_data_init(self, s, &Params_type); - return self; -} - -static mrb_value params_get(mrb_state *mrb, mrb_value self) { - mrb_sym key; - mrb_get_args(mrb, "n", &key); - - uint64_t id = ((Wrapper *)DATA_PTR(self))->id; - app::element_pool.use(id); - app::EText *element = (app::EText *)app::element_pool[id]; - - auto it = element->params.find(mrb_sym2name(mrb, key)); - if (it == element->params.end()) - return mrb_nil_value(); - return mrb_str_new_cstr(mrb, it->second.c_str()); -} - -static mrb_value params_set(mrb_state *mrb, mrb_value self) { - mrb_sym key; - mrb_value value; - mrb_get_args(mrb, "no", &key, &value); - - uint64_t id = ((Wrapper *)DATA_PTR(self))->id; - app::element_pool.use(id); - app::EText *element = (app::EText *)app::element_pool[id]; - - element->params[mrb_sym2name(mrb, key)] = mrb_str_to_cstr(mrb, mrb_obj_as_string(mrb, value)); - element->reload_text(); - - return mrb_nil_value(); -} - -static void Font_free(mrb_state *mrb, void *ptr) { - UNUSED(mrb); - uint64_t id = ((Wrapper *)ptr)->id; - font_pool.release(id); - delete (Wrapper *)ptr; -} - -static const struct mrb_data_type Font_type = {"Font", Font_free}; - -static mrb_value Font_init(mrb_state *mrb, mrb_value self) { - Wrapper *old = (Wrapper *)DATA_PTR(self); - if (old) - mrb_free(mrb, old); - mrb_data_init(self, nullptr, &Font_type); - Wrapper *s = new Wrapper(); - - char *path; - mrb_int size; - mrb_value kwargs; - mrb_get_args(mrb, "zi|H", &path, &size, &kwargs); - - bool pixel_art = false; - bool bold = false; - bool italic = false; - bool underline = false; - if (!mrb_nil_p(kwargs)) { - HASH_BOOL(kwargs, pixel_art, pixel_art); - HASH_BOOL(kwargs, bold, bold); - HASH_BOOL(kwargs, italic, italic); - HASH_BOOL(kwargs, underline, underline); - } - - s->id = window.load_font(path, size, bold, italic, underline, pixel_art); - - mrb_data_init(self, s, &Font_type); - return self; -} - -inline uint64_t get_id_Font(mrb_state *mrb, mrb_value self) { - Wrapper *wrapper; - Data_Get_Struct(mrb, self, &Font_type, wrapper); - return wrapper->id; -} - -static mrb_value font_equal(mrb_state *mrb, mrb_value self) { - mrb_value other; - mrb_get_args(mrb, "o", &other); - - if (!mrb_obj_is_kind_of(mrb, other, mrb_class_get(mrb, "Font"))) - return mrb_false_value(); - - uint64_t id_self = get_id_Font(mrb, self); - uint64_t id_other = get_id_Font(mrb, other); - - return mrb_bool_value(id_self == id_other); -} - -static mrb_value font_hash(mrb_state *mrb, mrb_value self) { - uint64_t id = get_id_Font(mrb, self); - return mrb_fixnum_value(id); -} - -static void Image_free(mrb_state *mrb, void *ptr) { - UNUSED(mrb); - uint64_t id = ((Wrapper *)ptr)->id; - image_pool.release(id); - delete (Wrapper *)ptr; -} - -static const struct mrb_data_type Image_type = {"Image", Image_free}; - -static mrb_value Image_init(mrb_state *mrb, mrb_value self) { - Wrapper *old = (Wrapper *)DATA_PTR(self); - if (old) - mrb_free(mrb, old); - mrb_data_init(self, nullptr, &Image_type); - Wrapper *s = new Wrapper(); - - char *path; - mrb_value kwargs; - mrb_get_args(mrb, "z|H", &path, &kwargs); - - bool pixel_art = false; - if (!mrb_nil_p(kwargs)) - HASH_BOOL(kwargs, pixel_art, pixel_art); - - s->id = window.load_image(path, pixel_art); - - mrb_data_init(self, s, &Image_type); - return self; -} - -inline uint64_t get_id_Image(mrb_state *mrb, mrb_value self) { - Wrapper *wrapper; - Data_Get_Struct(mrb, self, &Image_type, wrapper); - return wrapper->id; -} - -static mrb_value image_equal(mrb_state *mrb, mrb_value self) { - mrb_value other; - mrb_get_args(mrb, "o", &other); - - if (!mrb_obj_is_kind_of(mrb, other, mrb_class_get(mrb, "Image"))) - return mrb_false_value(); - - uint64_t id_self = get_id_Image(mrb, self); - uint64_t id_other = get_id_Image(mrb, other); - - return mrb_bool_value(id_self == id_other); -} - -static mrb_value image_hash(mrb_state *mrb, mrb_value self) { - uint64_t id = get_id_Image(mrb, self); - return mrb_fixnum_value(id); -} - -static mrb_value image_width(mrb_state *mrb, mrb_value self) { - uint64_t id = get_id_Image(mrb, self); - return mrb_float_value(mrb, window.get_image_size(id).x); -} - -static mrb_value image_height(mrb_state *mrb, mrb_value self) { - uint64_t id = get_id_Image(mrb, self); - return mrb_float_value(mrb, window.get_image_size(id).y); -} - -static void Animation_free(mrb_state *mrb, void *ptr) { - UNUSED(mrb); - uint64_t id = ((Wrapper *)ptr)->id; - animation_pool.release(id); - delete (Wrapper *)ptr; -} - -static const struct mrb_data_type Animation_type = { - "Animation", Animation_free -}; - -static mrb_value Animation_init(mrb_state *mrb, mrb_value self) { - Wrapper *old = (Wrapper *)DATA_PTR(self); - if (old) - mrb_free(mrb, old); - mrb_data_init(self, nullptr, &Animation_type); - Wrapper *s = new Wrapper(); - - const mrb_value *frames_val; - mrb_int frames_len; - mrb_value kwargs; - mrb_get_args(mrb, "a|H", &frames_val, &frames_len, &kwargs); - - float fps = 1.0f; - if (!mrb_nil_p(kwargs)) - HASH_FLOAT(kwargs, fps, fps); - - std::vector frame_ids; - for (mrb_int i = 0; i < frames_len; i++) { - mrb_value frame_val = frames_val[i]; - if (!mrb_obj_is_kind_of(mrb, frame_val, mrb_class_get(mrb, "Image"))) { - mrb_raise( - mrb, - mrb_class_get(mrb, "Exception"), - "Expected an array of Image objects" - ); - return mrb_nil_value(); - } - uint64_t frame_id = get_id_Image(mrb, frame_val); - image_pool.use(frame_id); - frame_ids.push_back(frame_id); - } - - Animation *animation = new Animation{frame_ids, fps}; - s->id = animation_pool.acquire(animation); - animation_pool.use(s->id); - - mrb_data_init(self, s, &Animation_type); - return self; -} - -inline uint64_t get_id_Animation(mrb_state *mrb, mrb_value self) { - Wrapper *wrapper; - Data_Get_Struct(mrb, self, &Animation_type, wrapper); - return wrapper->id; -} - -static mrb_value static_image_animation(mrb_state *mrb, mrb_value) { - mrb_value image_val; - mrb_get_args(mrb, "o", &image_val); - - if (!mrb_obj_is_kind_of(mrb, image_val, mrb_class_get(mrb, "Image"))) { - mrb_raise( - mrb, - mrb_class_get(mrb, "Exception"), - "Expected an Image object" - ); - return mrb_nil_value(); - } - - uint64_t frame_id = get_id_Image(mrb, image_val); - image_pool.use(frame_id); - - std::vector frames = {frame_id}; - Animation *animation = new Animation{frames, 1.0f}; - Wrapper *s = new Wrapper(); - s->id = animation_pool.acquire(animation); - animation_pool.use(s->id); - - return wrap(mrb, mrb_class_get(mrb, "Animation"), &Animation_type, s->id); -} - -static mrb_value animation_equal(mrb_state *mrb, mrb_value self) { - mrb_value other; - mrb_get_args(mrb, "o", &other); - - if (!mrb_obj_is_kind_of(mrb, other, mrb_class_get(mrb, "Animation"))) - return mrb_false_value(); - - uint64_t id_self = get_id_Animation(mrb, self); - uint64_t id_other = get_id_Animation(mrb, other); - - return mrb_bool_value(id_self == id_other); -} - -static mrb_value animation_hash(mrb_state *mrb, mrb_value self) { - uint64_t id = get_id_Animation(mrb, self); - return mrb_fixnum_value(id); -} - -static mrb_value animation_frames_set(mrb_state *mrb, mrb_value self) { - const mrb_value *frames_val; - mrb_int frames_len; - mrb_get_args(mrb, "a", &frames_val, &frames_len); - - uint64_t id = get_id_Animation(mrb, self); - Animation *animation = animation_pool[id]; - - std::vector new_frame_ids; - for (mrb_int i = 0; i < frames_len; i++) { - mrb_value frame_val = frames_val[i]; - if (!mrb_obj_is_kind_of(mrb, frame_val, mrb_class_get(mrb, "Image"))) { - mrb_raise( - mrb, - mrb_class_get(mrb, "Exception"), - "Expected an array of Image objects" - ); - return mrb_nil_value(); - } - uint64_t frame_id = get_id_Image(mrb, frame_val); - image_pool.use(frame_id); - new_frame_ids.push_back(frame_id); - } - - // Release old frames - for (uint64_t frame_id : animation->frames) - image_pool.release(frame_id); - - animation->frames = std::move(new_frame_ids); - - return mrb_nil_value(); -} - -static mrb_value animation_frames_get(mrb_state *mrb, mrb_value self) { - uint64_t id = get_id_Animation(mrb, self); - Animation *animation = animation_pool[id]; - - mrb_value frames_array = mrb_ary_new_capa(mrb, animation->frames.size()); - for (uint64_t frame_id : animation->frames) { - image_pool.use(frame_id); - mrb_value frame_obj = wrap(mrb, mrb_class_get(mrb, "Image"), &Image_type, frame_id); - mrb_ary_push(mrb, frames_array, frame_obj); - } - - return frames_array; -} - -static mrb_value animation_fps_set(mrb_state *mrb, mrb_value self) { - mrb_float fps; - mrb_get_args(mrb, "f", &fps); - - uint64_t id = get_id_Animation(mrb, self); - Animation *animation = animation_pool[id]; - animation->frame_rate = fps; - - return mrb_nil_value(); -} - -static mrb_value animation_fps_get(mrb_state *mrb, mrb_value self) { - uint64_t id = get_id_Animation(mrb, self); - Animation *animation = animation_pool[id]; - return mrb_float_value(mrb, animation->frame_rate); -} - -static void ElementText_free(mrb_state *mrb, void *ptr) { - UNUSED(mrb); - uint64_t id = ((Wrapper *)ptr)->id; - app::element_pool.release(id); - delete (Wrapper *)ptr; -} - -static const struct mrb_data_type ElementText_type = { - "ElementText", ElementText_free -}; - -static mrb_value ElementText_init(mrb_state *mrb, mrb_value self) { - Wrapper *old = (Wrapper *)DATA_PTR(self); - if (old) - mrb_free(mrb, old); - mrb_data_init(self, nullptr, &ElementText_type); - Wrapper *s = new Wrapper(); - - mrb_sym key; - mrb_value font_val; - mrb_int color_i = 0xFFFFFF; - mrb_value t_args; - mrb_value kwargs; - mrb_get_args(mrb, "noi|HH", &key, &font_val, &color_i, &t_args, &kwargs); - - auto key_id = Localization::key_from_sym(mrb, key); - - if (!mrb_obj_is_kind_of(mrb, font_val, mrb_class_get(mrb, "Font"))) { - mrb_raise(mrb, mrb_class_get(mrb, "Exception"), "Expected a Font object"); - return mrb_nil_value(); - } - - float x = 0, y = 0, z = 0, rotation = 0; - float scale_x = 1, scale_y = 1, alpha = 1; - float pivot_x = 0.5, pivot_y = 0.5; - mrb_sym click_mode_sym = sym_block; - if (!mrb_nil_p(kwargs)) { - mrb_value pos_hash = HASH_GET(kwargs, position); - if (!mrb_nil_p(pos_hash)) { - HASH_FLOAT(pos_hash, x, x); - HASH_FLOAT(pos_hash, y, y); - } - - mrb_value scale_hash = HASH_GET(kwargs, scale); - if (!mrb_nil_p(scale_hash)) { - HASH_FLOAT(scale_hash, x, scale_x); - HASH_FLOAT(scale_hash, y, scale_y); - } - - mrb_value pivot_hash = HASH_GET(kwargs, pivot); - if (!mrb_nil_p(pivot_hash)) { - HASH_FLOAT(pivot_hash, x, pivot_x); - HASH_FLOAT(pivot_hash, y, pivot_y); - } - - HASH_FLOAT(kwargs, z, z); - HASH_FLOAT(kwargs, rotation, rotation); - HASH_FLOAT(kwargs, alpha, alpha); - mrb_value v = HASH_GET(kwargs, click_mode); - if (!mrb_nil_p(v)) { - click_mode_sym = mrb_symbol(v); - } - } - - uint64_t id = get_id_Font(mrb, font_val); - font_pool.use(id); - - Color color = { - (uint8_t)((color_i >> 16) & 0xFF), - (uint8_t)((color_i >> 8) & 0xFF), - (uint8_t)((color_i) & 0xFF) - }; - - std::unordered_map params; - if (!mrb_nil_p(t_args)) { - mrb_value keys = mrb_hash_keys(mrb, t_args); - for (mrb_int i = 0; i < RARRAY_LEN(keys); i++) { - mrb_value key = RARRAY_PTR(keys)[i]; - mrb_value val = mrb_hash_get(mrb, t_args, key); - params[mrb_str_to_cstr(mrb, mrb_obj_as_string(mrb, key))] = - mrb_str_to_cstr(mrb, mrb_obj_as_string(mrb, val)); - } - } - - app::EText *element = new app::EText(key_id, id, color, params); - element->position = {x, y}; - element->scale = {scale_x, scale_y}; - element->rotation = rotation; - element->pivot = {pivot_x, pivot_y}; - element->alpha = alpha; - element->z = z; - - std::string click_mode = mrb_sym2name(mrb, click_mode_sym); - - if (click_mode == "pass") - element->click_mode = ClickMode::PASS; - else if (click_mode == "block") - element->click_mode = ClickMode::BLOCK; - else if (click_mode == "ignore") - element->click_mode = ClickMode::IGNORE; - - s->id = app::element_pool.acquire(element); - app::element_pool.use(s->id); - - mrb_data_init(self, s, &ElementText_type); - return self; -} - -inline uint64_t get_id_ElementText(mrb_state *mrb, mrb_value self) { - Wrapper *wrapper; - Data_Get_Struct(mrb, self, &ElementText_type, wrapper); - return wrapper->id; -} - -static mrb_value element_text_on_click(mrb_state *mrb, mrb_value self) { - mrb_value block; - mrb_get_args(mrb, "&", &block); - uint64_t id = get_id_ElementText(mrb, self); - app::Element *element = app::element_pool[id]; - element->on_click.set_proc(block); - return self; -} - -static mrb_value element_text_equal(mrb_state *mrb, mrb_value self) { - mrb_value other; - mrb_get_args(mrb, "o", &other); - - if (!mrb_obj_is_kind_of(mrb, other, mrb_class_get(mrb, "ElementText"))) - return mrb_false_value(); - - uint64_t id_self = get_id_ElementText(mrb, self); - uint64_t id_other = get_id_ElementText(mrb, other); - - return mrb_bool_value(id_self == id_other); -} - -static mrb_value element_text_inspect(mrb_state *mrb, mrb_value self) { - uint64_t id = get_id_ElementText(mrb, self); - app::EText *element = (app::EText *)app::element_pool[id]; - std::string str = "#key) - + " font_id=" + std::format("0x{:016x}", element->font_id) - + ">"; - return mrb_str_new_cstr(mrb, str.c_str()); -} - -static mrb_value element_text_to_s(mrb_state *mrb, mrb_value self) { - uint64_t id = get_id_ElementText(mrb, self); - app::EText *element = (app::EText *)app::element_pool[id]; - std::string localized_text = Localization::get(element->key, element->params); - return mrb_str_new_cstr(mrb, localized_text.c_str()); -} - -static mrb_value element_text_hash(mrb_state *mrb, mrb_value self) { - uint64_t id = get_id_ElementText(mrb, self); - return mrb_fixnum_value(id); -} - -static mrb_value element_text_key_get(mrb_state *mrb, mrb_value self) { - uint64_t id = get_id_ElementText(mrb, self); - app::EText *element = (app::EText *)app::element_pool[id]; - return mrb_symbol_value(Localization::lang_to_sym(mrb, element->key)); -} - -static mrb_value element_text_key_set(mrb_state *mrb, mrb_value self) { - mrb_sym key_sym; - mrb_get_args(mrb, "n", &key_sym); - - uint64_t id = get_id_ElementText(mrb, self); - app::EText *element = (app::EText *)app::element_pool[id]; - element->key = Localization::lang_from_sym(mrb, key_sym); - - return mrb_nil_value(); -} - -static mrb_value element_text_font_get(mrb_state *mrb, mrb_value self) { - uint64_t id = get_id_ElementText(mrb, self); - app::EText *element = (app::EText *)app::element_pool[id]; - if (element->font_id == UINT64_MAX) - return mrb_nil_value(); - font_pool.use(element->font_id); - return wrap(mrb, mrb_class_get(mrb, "Font"), &Font_type, element->font_id); -} - -static mrb_value element_text_params(mrb_state *mrb, mrb_value self) { - uint64_t id = get_id_ElementText(mrb, self); - app::element_pool.use(id); - return wrap(mrb, mrb_class_get(mrb, "Params"), &Params_type, id); -} - -static mrb_value element_text_font_set(mrb_state *mrb, mrb_value self) { - mrb_value font_val; - mrb_get_args(mrb, "o", &font_val); - - if (!mrb_obj_is_kind_of(mrb, font_val, mrb_class_get(mrb, "Font"))) { - mrb_raise(mrb, mrb_class_get(mrb, "Exception"), "Expected a Font object"); - return mrb_nil_value(); - } - - uint64_t font_id = get_id_Font(mrb, font_val); - - uint64_t id = get_id_ElementText(mrb, self); - app::EText *element = (app::EText *)app::element_pool[id]; - if (element->font_id != UINT64_MAX) - font_pool.release(element->font_id); - element->font_id = font_id; - font_pool.use(font_id); - - return mrb_nil_value(); -} - -static mrb_value element_text_color_get(mrb_state *mrb, mrb_value self) { - uint64_t id = get_id_ElementText(mrb, self); - app::EText *element = (app::EText *)app::element_pool[id]; - return mrb_fixnum_value( - (element->color.r << 16) | (element->color.g << 8) | (element->color.b) - ); -} - -static mrb_value element_text_color_set(mrb_state *mrb, mrb_value self) { - mrb_int color_val; - mrb_get_args(mrb, "i", &color_val); - uint64_t id = get_id_ElementText(mrb, self); - app::EText *element = (app::EText *)app::element_pool[id]; - element->color = { - (uint8_t)((color_val >> 16) & 0xFF), - (uint8_t)((color_val >> 8) & 0xFF), - (uint8_t)((color_val) & 0xFF) - }; - return mrb_nil_value(); -} - -static mrb_value element_text_position_get(mrb_state *mrb, mrb_value self) { - uint64_t id = get_id_ElementText(mrb, self); - app::EText *element = (app::EText *)app::element_pool[id]; - mrb_value pos_hash = mrb_hash_new(mrb); - HASH_SET(pos_hash, x, mrb_float_value(mrb, element->position.x)); - HASH_SET(pos_hash, y, mrb_float_value(mrb, element->position.y)); - return pos_hash; -} - -static mrb_value element_text_position_set(mrb_state *mrb, mrb_value self) { - mrb_value pos_hash; - mrb_get_args(mrb, "H", &pos_hash); - - uint64_t id = get_id_ElementText(mrb, self); - app::EText *element = (app::EText *)app::element_pool[id]; - - HASH_FLOAT(pos_hash, x, element->position.x); - HASH_FLOAT(pos_hash, y, element->position.y); - - return mrb_nil_value(); -} - -static mrb_value element_text_rotation_get(mrb_state *mrb, mrb_value self) { - uint64_t id = get_id_ElementText(mrb, self); - app::EText *element = (app::EText *)app::element_pool[id]; - return mrb_float_value(mrb, element->rotation); -} - -static mrb_value element_text_rotation_set(mrb_state *mrb, mrb_value self) { - mrb_float rotation; - mrb_get_args(mrb, "f", &rotation); - - uint64_t id = get_id_ElementText(mrb, self); - app::EText *element = (app::EText *)app::element_pool[id]; - element->rotation = rotation; - - return mrb_nil_value(); -} - -static mrb_value element_text_pivot_get(mrb_state *mrb, mrb_value self) { - uint64_t id = get_id_ElementText(mrb, self); - app::EText *element = (app::EText *)app::element_pool[id]; - mrb_value pivot_hash = mrb_hash_new(mrb); - HASH_SET(pivot_hash, x, mrb_float_value(mrb, element->pivot.x)); - HASH_SET(pivot_hash, y, mrb_float_value(mrb, element->pivot.y)); - return pivot_hash; -} - -static mrb_value element_text_pivot_set(mrb_state *mrb, mrb_value self) { - mrb_value pivot_hash; - mrb_get_args(mrb, "H", &pivot_hash); - - uint64_t id = get_id_ElementText(mrb, self); - app::EText *element = (app::EText *)app::element_pool[id]; - - HASH_FLOAT(pivot_hash, x, element->pivot.x); - HASH_FLOAT(pivot_hash, y, element->pivot.y); - - return mrb_nil_value(); -} - -static mrb_value element_text_scale_get(mrb_state *mrb, mrb_value self) { - uint64_t id = get_id_ElementText(mrb, self); - app::EText *element = (app::EText *)app::element_pool[id]; - mrb_value scale_hash = mrb_hash_new(mrb); - HASH_SET(scale_hash, x, mrb_float_value(mrb, element->scale.x)); - HASH_SET(scale_hash, y, mrb_float_value(mrb, element->scale.y)); - return scale_hash; -} - -static mrb_value element_text_scale_set(mrb_state *mrb, mrb_value self) { - mrb_value scale_hash; - mrb_get_args(mrb, "H", &scale_hash); - - uint64_t id = get_id_ElementText(mrb, self); - app::EText *element = (app::EText *)app::element_pool[id]; - - HASH_FLOAT(scale_hash, x, element->scale.x); - HASH_FLOAT(scale_hash, y, element->scale.y); - - return mrb_nil_value(); -} - -static mrb_value element_text_alpha_get(mrb_state *mrb, mrb_value self) { - uint64_t id = get_id_ElementText(mrb, self); - app::EText *element = (app::EText *)app::element_pool[id]; - return mrb_float_value(mrb, element->alpha); -} - -static mrb_value element_text_alpha_set(mrb_state *mrb, mrb_value self) { - mrb_float alpha; - mrb_get_args(mrb, "f", &alpha); - - uint64_t id = get_id_ElementText(mrb, self); - app::EText *element = (app::EText *)app::element_pool[id]; - element->alpha = alpha; - - return mrb_nil_value(); -} - -static mrb_value element_text_z_get(mrb_state *mrb, mrb_value self) { - uint64_t id = get_id_ElementText(mrb, self); - app::EText *element = (app::EText *)app::element_pool[id]; - return mrb_float_value(mrb, element->z); -} - -static mrb_value element_text_z_set(mrb_state *mrb, mrb_value self) { - mrb_float z; - mrb_get_args(mrb, "f", &z); - - uint64_t id = get_id_ElementText(mrb, self); - app::EText *element = (app::EText *)app::element_pool[id]; - element->z = z; - - return mrb_nil_value(); -} - -static mrb_value element_text_click_mode_get(mrb_state *mrb, mrb_value self) { - uint64_t id = get_id_ElementText(mrb, self); - app::EText *element = (app::EText *)app::element_pool[id]; - - std::string click_mode_str; - switch (element->click_mode) { - case ClickMode::PASS: - click_mode_str = "pass"; - break; - case ClickMode::BLOCK: - click_mode_str = "block"; - break; - case ClickMode::IGNORE: - click_mode_str = "ignore"; - break; - } - - return mrb_symbol_value(mrb_intern_cstr(mrb, click_mode_str.c_str())); -} - -static mrb_value element_text_click_mode_set(mrb_state *mrb, mrb_value self) { - mrb_sym click_mode_sym; - mrb_get_args(mrb, "n", &click_mode_sym); - - uint64_t id = get_id_ElementText(mrb, self); - app::EText *element = (app::EText *)app::element_pool[id]; - - std::string click_mode_str = mrb_sym2name(mrb, click_mode_sym); - - if (click_mode_str == "pass") - element->click_mode = ClickMode::PASS; - else if (click_mode_str == "block") - element->click_mode = ClickMode::BLOCK; - else if (click_mode_str == "ignore") - element->click_mode = ClickMode::IGNORE; - - return mrb_nil_value(); -} - -static mrb_value element_text_width(mrb_state *mrb, mrb_value self) { - uint64_t id = get_id_ElementText(mrb, self); - app::EText *element = (app::EText *)app::element_pool[id]; - return mrb_float_value(mrb, element->size().x); -} - -static mrb_value element_text_height(mrb_state *mrb, mrb_value self) { - uint64_t id = get_id_ElementText(mrb, self); - app::EText *element = (app::EText *)app::element_pool[id]; - return mrb_float_value(mrb, element->size().y); -} - -static void ElementRect_free(mrb_state *mrb, void *ptr) { - UNUSED(mrb); - uint64_t id = ((Wrapper *)ptr)->id; - app::element_pool.release(id); - delete (Wrapper *)ptr; -} - -static const struct mrb_data_type ElementRect_type = { - "ElementRect", - ElementRect_free -}; - -static mrb_value ElementRect_init(mrb_state *mrb, mrb_value self) { - Wrapper *old = (Wrapper *)DATA_PTR(self); - if (old) - mrb_free(mrb, old); - mrb_data_init(self, nullptr, &ElementRect_type); - Wrapper *s = new Wrapper(); - - mrb_float w, h; - mrb_int color_i = 0xFFFFFF; - mrb_value kwargs; - mrb_get_args(mrb, "ffi|H", &w, &h, &color_i, &kwargs); - - float x = 0, y = 0, z = 0, rotation = 0; - float scale_x = 1, scale_y = 1, alpha = 1, pivot_x = 0.5, pivot_y = 0.5; - mrb_sym click_mode_sym = sym_block; - if (!mrb_nil_p(kwargs)) { - mrb_value pos_hash = HASH_GET(kwargs, position); - if (!mrb_nil_p(pos_hash)) { - HASH_FLOAT(pos_hash, x, x); - HASH_FLOAT(pos_hash, y, y); - } - - mrb_value scale_hash = HASH_GET(kwargs, scale); - if (!mrb_nil_p(scale_hash)) { - HASH_FLOAT(scale_hash, x, scale_x); - HASH_FLOAT(scale_hash, y, scale_y); - } - - mrb_value pivot_hash = HASH_GET(kwargs, pivot); - if (!mrb_nil_p(pivot_hash)) { - HASH_FLOAT(pivot_hash, x, pivot_x); - HASH_FLOAT(pivot_hash, y, pivot_y); - } - - HASH_FLOAT(kwargs, z, z); - HASH_FLOAT(kwargs, rotation, rotation); - HASH_FLOAT(kwargs, alpha, alpha); - mrb_value v = HASH_GET(kwargs, click_mode); - if (!mrb_nil_p(v)) { - click_mode_sym = mrb_symbol(v); - } - } - - Vec2 shape = {(float)w, (float)h}; - - Color color = { - (uint8_t)((color_i >> 16) & 0xFF), - (uint8_t)((color_i >> 8) & 0xFF), - (uint8_t)((color_i) & 0xFF) - }; - - app::ERect *element = new app::ERect( - shape, - color - ); - element->position = {x, y}; - element->scale = {scale_x, scale_y}; - element->rotation = rotation; - element->pivot = {pivot_x, pivot_y}; - element->alpha = alpha; - element->z = z; - - std::string click_mode = mrb_sym2name(mrb, click_mode_sym); - - if (click_mode == "pass") - element->click_mode = ClickMode::PASS; - else if (click_mode == "block") - element->click_mode = ClickMode::BLOCK; - else if (click_mode == "ignore") - element->click_mode = ClickMode::IGNORE; - - s->id = app::element_pool.acquire(element); - app::element_pool.use(s->id); - - mrb_data_init(self, s, &ElementRect_type); - return self; -} - -inline uint64_t get_id_ElementRect(mrb_state *mrb, mrb_value self) { - Wrapper *wrapper; - Data_Get_Struct(mrb, self, &ElementRect_type, wrapper); - return wrapper->id; -} - -static mrb_value element_rect_on_click(mrb_state *mrb, mrb_value self) { - mrb_value block; - mrb_get_args(mrb, "&", &block); - uint64_t id = get_id_ElementRect(mrb, self); - app::Element *element = app::element_pool[id]; - element->on_click.set_proc(block); - return self; -} - -static mrb_value element_rect_width_set(mrb_state *mrb, mrb_value self) { - mrb_float width; - mrb_get_args(mrb, "f", &width); - - uint64_t id = get_id_ElementRect(mrb, self); - app::ERect *element = (app::ERect *)app::element_pool[id]; - element->shape.x = width; - - return mrb_nil_value(); -} - -static mrb_value element_rect_width_get(mrb_state *mrb, mrb_value self) { - uint64_t id = get_id_ElementRect(mrb, self); - app::ERect *element = (app::ERect *)app::element_pool[id]; - return mrb_float_value(mrb, element->shape.x); -} - -static mrb_value element_rect_height_set(mrb_state *mrb, mrb_value self) { - mrb_float height; - mrb_get_args(mrb, "f", &height); - - uint64_t id = get_id_ElementRect(mrb, self); - app::ERect *element = (app::ERect *)app::element_pool[id]; - element->shape.y = height; - - return mrb_nil_value(); -} - -static mrb_value element_rect_height_get(mrb_state *mrb, mrb_value self) { - uint64_t id = get_id_ElementRect(mrb, self); - app::ERect *element = (app::ERect *)app::element_pool[id]; - return mrb_float_value(mrb, element->shape.y); -} - -static mrb_value element_rect_color_set(mrb_state *mrb, mrb_value self) { - mrb_value color_val; - mrb_get_args(mrb, "o", &color_val); - uint64_t id = get_id_ElementRect(mrb, self); - app::ERect *element = (app::ERect *)app::element_pool[id]; - element->color = { - (uint8_t)((mrb_fixnum(color_val) >> 16) & 0xFF), - (uint8_t)((mrb_fixnum(color_val) >> 8) & 0xFF), - (uint8_t)((mrb_fixnum(color_val)) & 0xFF) - }; - return self; -} - -static mrb_value element_rect_color_get(mrb_state *mrb, mrb_value self) { - uint64_t id = get_id_ElementRect(mrb, self); - app::ERect *element = (app::ERect *)app::element_pool[id]; - uint32_t color = - ((uint32_t)element->color.r << 16) | ((uint32_t)element->color.g << 8) - | ((uint32_t)element->color.b); - return mrb_fixnum_value(color); -} - -static mrb_value element_rect_equal(mrb_state *mrb, mrb_value self) { - mrb_value other; - mrb_get_args(mrb, "o", &other); - - if (!mrb_obj_is_kind_of(mrb, other, mrb_class_get(mrb, "ElementRect"))) - return mrb_false_value(); - - uint64_t id_self = get_id_ElementRect(mrb, self); - uint64_t id_other = get_id_ElementRect(mrb, other); - - return mrb_bool_value(id_self == id_other); -} - -static mrb_value element_rect_inspect(mrb_state *mrb, mrb_value self) { - uint64_t id = get_id_ElementRect(mrb, self); - app::ERect *element = (app::ERect *)app::element_pool[id]; - std::string str = "#shape.x) - + " height=" + std::format("{}", element->shape.y) - + ">"; - return mrb_str_new_cstr(mrb, str.c_str()); -} - -static mrb_value element_rect_hash(mrb_state *mrb, mrb_value self) { - uint64_t id = get_id_ElementRect(mrb, self); - return mrb_fixnum_value(id); -} - -static mrb_value element_rect_position_get(mrb_state *mrb, mrb_value self) { - uint64_t id = get_id_ElementRect(mrb, self); - app::ERect *element = (app::ERect *)app::element_pool[id]; - mrb_value pos_hash = mrb_hash_new(mrb); - HASH_SET(pos_hash, x, mrb_float_value(mrb, element->position.x)); - HASH_SET(pos_hash, y, mrb_float_value(mrb, element->position.y)); - return pos_hash; -} - -static mrb_value element_rect_position_set(mrb_state *mrb, mrb_value self) { - mrb_value pos_hash; - mrb_get_args(mrb, "H", &pos_hash); - - uint64_t id = get_id_ElementRect(mrb, self); - app::ERect *element = (app::ERect *)app::element_pool[id]; - - HASH_FLOAT(pos_hash, x, element->position.x); - HASH_FLOAT(pos_hash, y, element->position.y); - - return mrb_nil_value(); -} - -static mrb_value element_rect_rotation_get(mrb_state *mrb, mrb_value self) { - uint64_t id = get_id_ElementRect(mrb, self); - app::ERect *element = (app::ERect *)app::element_pool[id]; - return mrb_float_value(mrb, element->rotation); -} - -static mrb_value element_rect_rotation_set(mrb_state *mrb, mrb_value self) { - mrb_float rotation; - mrb_get_args(mrb, "f", &rotation); - - uint64_t id = get_id_ElementRect(mrb, self); - app::ERect *element = (app::ERect *)app::element_pool[id]; - element->rotation = rotation; - - return mrb_nil_value(); -} - -static mrb_value element_rect_pivot_get(mrb_state *mrb, mrb_value self) { - uint64_t id = get_id_ElementRect(mrb, self); - app::ERect *element = (app::ERect *)app::element_pool[id]; - mrb_value pivot_hash = mrb_hash_new(mrb); - HASH_SET(pivot_hash, x, mrb_float_value(mrb, element->pivot.x)); - HASH_SET(pivot_hash, y, mrb_float_value(mrb, element->pivot.y)); - return pivot_hash; -} - -static mrb_value element_rect_pivot_set(mrb_state *mrb, mrb_value self) { - mrb_value pivot_hash; - mrb_get_args(mrb, "H", &pivot_hash); - - uint64_t id = get_id_ElementRect(mrb, self); - app::ERect *element = (app::ERect *)app::element_pool[id]; - - HASH_FLOAT(pivot_hash, x, element->pivot.x); - HASH_FLOAT(pivot_hash, y, element->pivot.y); - - return mrb_nil_value(); -} - -static mrb_value element_rect_scale_get(mrb_state *mrb, mrb_value self) { - uint64_t id = get_id_ElementRect(mrb, self); - app::ERect *element = (app::ERect *)app::element_pool[id]; - mrb_value scale_hash = mrb_hash_new(mrb); - HASH_SET(scale_hash, x, mrb_float_value(mrb, element->scale.x)); - HASH_SET(scale_hash, y, mrb_float_value(mrb, element->scale.y)); - return scale_hash; -} - -static mrb_value element_rect_scale_set(mrb_state *mrb, mrb_value self) { - mrb_value scale_hash; - mrb_get_args(mrb, "H", &scale_hash); - - uint64_t id = get_id_ElementRect(mrb, self); - app::ERect *element = (app::ERect *)app::element_pool[id]; - - HASH_FLOAT(scale_hash, x, element->scale.x); - HASH_FLOAT(scale_hash, y, element->scale.y); - - return mrb_nil_value(); -} - -static mrb_value element_rect_alpha_get(mrb_state *mrb, mrb_value self) { - uint64_t id = get_id_ElementRect(mrb, self); - app::ERect *element = (app::ERect *)app::element_pool[id]; - return mrb_float_value(mrb, element->alpha); -} - -static mrb_value element_rect_alpha_set(mrb_state *mrb, mrb_value self) { - mrb_float alpha; - mrb_get_args(mrb, "f", &alpha); - - uint64_t id = get_id_ElementRect(mrb, self); - app::ERect *element = (app::ERect *)app::element_pool[id]; - element->alpha = alpha; - - return mrb_nil_value(); -} - -static mrb_value element_rect_z_get(mrb_state *mrb, mrb_value self) { - uint64_t id = get_id_ElementRect(mrb, self); - app::ERect *element = (app::ERect *)app::element_pool[id]; - return mrb_float_value(mrb, element->z); -} - -static mrb_value element_rect_z_set(mrb_state *mrb, mrb_value self) { - mrb_float z; - mrb_get_args(mrb, "f", &z); - - uint64_t id = get_id_ElementRect(mrb, self); - app::ERect *element = (app::ERect *)app::element_pool[id]; - element->z = z; - - return mrb_nil_value(); -} - -static mrb_value element_rect_click_mode_get(mrb_state *mrb, mrb_value self) { - uint64_t id = get_id_ElementRect(mrb, self); - app::ERect *element = (app::ERect *)app::element_pool[id]; - - std::string click_mode_str; - switch (element->click_mode) { - case ClickMode::PASS: - click_mode_str = "pass"; - break; - case ClickMode::BLOCK: - click_mode_str = "block"; - break; - case ClickMode::IGNORE: - click_mode_str = "ignore"; - break; - } - - return mrb_symbol_value(mrb_intern_cstr(mrb, click_mode_str.c_str())); -} - -static mrb_value element_rect_click_mode_set(mrb_state *mrb, mrb_value self) { - mrb_sym click_mode_sym; - mrb_get_args(mrb, "n", &click_mode_sym); - - uint64_t id = get_id_ElementRect(mrb, self); - app::ERect *element = (app::ERect *)app::element_pool[id]; - - std::string click_mode = mrb_sym2name(mrb, click_mode_sym); - - if (click_mode == "pass") - element->click_mode = ClickMode::PASS; - else if (click_mode == "block") - element->click_mode = ClickMode::BLOCK; - else if (click_mode == "ignore") - element->click_mode = ClickMode::IGNORE; - - return mrb_nil_value(); -} - -static void ElementImage_free(mrb_state *mrb, void *ptr) { - UNUSED(mrb); - uint64_t id = ((Wrapper *)ptr)->id; - app::element_pool.release(id); - delete (Wrapper *)ptr; -} - -static const struct mrb_data_type ElementImage_type = { - "ElementImage", - ElementImage_free -}; - -static mrb_value ElementImage_init(mrb_state *mrb, mrb_value self) { - Wrapper *old = (Wrapper *)DATA_PTR(self); - if (old) - mrb_free(mrb, old); - mrb_data_init(self, nullptr, &ElementImage_type); - Wrapper *s = new Wrapper(); - - mrb_value animation_val; - mrb_value kwargs; - mrb_get_args(mrb, "o|H", &animation_val, &kwargs); - if (!mrb_obj_is_kind_of( - mrb, - animation_val, - mrb_class_get(mrb, "Animation") - )) { - mrb_raise( - mrb, - mrb_class_get(mrb, "Exception"), - "Expected an Animation object" - ); - return mrb_nil_value(); - } - - float x = 0, y = 0, z = 0, rotation = 0; - float scale_x = 1, scale_y = 1, alpha = 1, pivot_x = 0.5, pivot_y = 0.5; - mrb_sym click_mode_sym = sym_block; - if (!mrb_nil_p(kwargs)) { - mrb_value pos_hash = HASH_GET(kwargs, position); - if (!mrb_nil_p(pos_hash)) { - HASH_FLOAT(pos_hash, x, x); - HASH_FLOAT(pos_hash, y, y); - } - - mrb_value scale_hash = HASH_GET(kwargs, scale); - if (!mrb_nil_p(scale_hash)) { - HASH_FLOAT(scale_hash, x, scale_x); - HASH_FLOAT(scale_hash, y, scale_y); - } - - mrb_value pivot_hash = HASH_GET(kwargs, pivot); - if (!mrb_nil_p(pivot_hash)) { - HASH_FLOAT(pivot_hash, x, pivot_x); - HASH_FLOAT(pivot_hash, y, pivot_y); - } - - HASH_FLOAT(kwargs, z, z); - HASH_FLOAT(kwargs, rotation, rotation); - HASH_FLOAT(kwargs, alpha, alpha); - mrb_value v = HASH_GET(kwargs, click_mode); - if (!mrb_nil_p(v)) { - click_mode_sym = mrb_symbol(v); - } - } - - uint64_t id = get_id_Animation(mrb, animation_val); - animation_pool.use(id); - - app::EImage *element = new app::EImage(id); - element->position = {x, y}; - element->scale = {scale_x, scale_y}; - element->rotation = rotation; - element->pivot = {pivot_x, pivot_y}; - element->alpha = alpha; - element->z = z; - - std::string click_mode = mrb_sym2name(mrb, click_mode_sym); - - if (click_mode == "pass") - element->click_mode = ClickMode::PASS; - else if (click_mode == "block") - element->click_mode = ClickMode::BLOCK; - else if (click_mode == "ignore") - element->click_mode = ClickMode::IGNORE; - - s->id = app::element_pool.acquire(element); - app::element_pool.use(s->id); - - mrb_data_init(self, s, &ElementImage_type); - return self; -} - -inline uint64_t get_id_ElementImage(mrb_state *mrb, mrb_value self) { - Wrapper *wrapper; - Data_Get_Struct(mrb, self, &ElementImage_type, wrapper); - return wrapper->id; -} - -static mrb_value element_image_on_click(mrb_state *mrb, mrb_value self) { - mrb_value block; - mrb_get_args(mrb, "&", &block); - uint64_t id = get_id_ElementImage(mrb, self); - app::Element *element = app::element_pool[id]; - element->on_click.set_proc(block); - return self; -} - -static mrb_value element_image_equal(mrb_state *mrb, mrb_value self) { - mrb_value other; - mrb_get_args(mrb, "o", &other); - - if (!mrb_obj_is_kind_of(mrb, other, mrb_class_get(mrb, "ElementImage"))) - return mrb_false_value(); - - uint64_t id_self = get_id_ElementImage(mrb, self); - uint64_t id_other = get_id_ElementImage(mrb, other); - - return mrb_bool_value(id_self == id_other); -} - -static mrb_value element_image_inspect(mrb_state *mrb, mrb_value self) { - uint64_t id = get_id_ElementImage(mrb, self); - app::EImage *element = (app::EImage *)app::element_pool[id]; - std::string str = "#animation_id) - + ">"; - return mrb_str_new_cstr(mrb, str.c_str()); -} - -static mrb_value element_image_hash(mrb_state *mrb, mrb_value self) { - uint64_t id = get_id_ElementImage(mrb, self); - return mrb_fixnum_value(id); -} - -static mrb_value element_image_animation_set(mrb_state *mrb, mrb_value self) { - mrb_value animation; - mrb_get_args(mrb, "o", &animation); - - if (!mrb_obj_is_kind_of( - mrb, - animation, - mrb_class_get(mrb, "Animation") - )) { - mrb_raise( - mrb, - mrb_class_get(mrb, "Exception"), - "Expected an Animation object" - ); - return mrb_nil_value(); - } - - uint64_t animation_id = get_id_Animation(mrb, animation); - uint64_t id = get_id_ElementImage(mrb, self); - app::EImage *element = (app::EImage *)app::element_pool[id]; - - animation_pool.use(animation_id); - animation_pool.release(element->animation_id); - - element->animation_id = animation_id; - - return self; -} - -static mrb_value element_image_animation_get(mrb_state *mrb, mrb_value self) { - uint64_t id = get_id_ElementImage(mrb, self); - app::EImage *element = (app::EImage *)app::element_pool[id]; - uint64_t animation_id = element->animation_id; - if (animation_id == UINT64_MAX) - return mrb_nil_value(); - animation_pool.use(animation_id); - return wrap(mrb, mrb_class_get(mrb, "Animation"), &Animation_type, animation_id); -} - -static mrb_value element_image_position_get(mrb_state *mrb, mrb_value self) { - uint64_t id = get_id_ElementImage(mrb, self); - app::EImage *element = (app::EImage *)app::element_pool[id]; - mrb_value pos_hash = mrb_hash_new(mrb); - HASH_SET(pos_hash, x, mrb_float_value(mrb, element->position.x)); - HASH_SET(pos_hash, y, mrb_float_value(mrb, element->position.y)); - return pos_hash; -} - -static mrb_value element_image_position_set(mrb_state *mrb, mrb_value self) { - mrb_value pos_hash; - mrb_get_args(mrb, "H", &pos_hash); - - uint64_t id = get_id_ElementImage(mrb, self); - app::EImage *element = (app::EImage *)app::element_pool[id]; - - HASH_FLOAT(pos_hash, x, element->position.x); - HASH_FLOAT(pos_hash, y, element->position.y); - - return mrb_nil_value(); -} - -static mrb_value element_image_rotation_get(mrb_state *mrb, mrb_value self) { - uint64_t id = get_id_ElementImage(mrb, self); - app::EImage *element = (app::EImage *)app::element_pool[id]; - return mrb_float_value(mrb, element->rotation); -} - -static mrb_value element_image_rotation_set(mrb_state *mrb, mrb_value self) { - mrb_float rotation; - mrb_get_args(mrb, "f", &rotation); - - uint64_t id = get_id_ElementImage(mrb, self); - app::EImage *element = (app::EImage *)app::element_pool[id]; - element->rotation = rotation; - - return mrb_nil_value(); -} - -static mrb_value element_image_pivot_get(mrb_state *mrb, mrb_value self) { - uint64_t id = get_id_ElementImage(mrb, self); - app::EImage *element = (app::EImage *)app::element_pool[id]; - mrb_value pivot_hash = mrb_hash_new(mrb); - HASH_SET(pivot_hash, x, mrb_float_value(mrb, element->pivot.x)); - HASH_SET(pivot_hash, y, mrb_float_value(mrb, element->pivot.y)); - return pivot_hash; -} - -static mrb_value element_image_pivot_set(mrb_state *mrb, mrb_value self) { - mrb_value pivot_hash; - mrb_get_args(mrb, "H", &pivot_hash); - - uint64_t id = get_id_ElementImage(mrb, self); - app::EImage *element = (app::EImage *)app::element_pool[id]; - - HASH_FLOAT(pivot_hash, x, element->pivot.x); - HASH_FLOAT(pivot_hash, y, element->pivot.y); - - return mrb_nil_value(); -} - -static mrb_value element_image_scale_get(mrb_state *mrb, mrb_value self) { - uint64_t id = get_id_ElementImage(mrb, self); - app::EImage *element = (app::EImage *)app::element_pool[id]; - mrb_value scale_hash = mrb_hash_new(mrb); - HASH_SET(scale_hash, x, mrb_float_value(mrb, element->scale.x)); - HASH_SET(scale_hash, y, mrb_float_value(mrb, element->scale.y)); - return scale_hash; -} - -static mrb_value element_image_scale_set(mrb_state *mrb, mrb_value self) { - mrb_value scale_hash; - mrb_get_args(mrb, "H", &scale_hash); - - uint64_t id = get_id_ElementImage(mrb, self); - app::EImage *element = (app::EImage *)app::element_pool[id]; - - HASH_FLOAT(scale_hash, x, element->scale.x); - HASH_FLOAT(scale_hash, y, element->scale.y); - - return mrb_nil_value(); -} - -static mrb_value element_image_alpha_get(mrb_state *mrb, mrb_value self) { - uint64_t id = get_id_ElementImage(mrb, self); - app::EImage *element = (app::EImage *)app::element_pool[id]; - return mrb_float_value(mrb, element->alpha); -} - -static mrb_value element_image_alpha_set(mrb_state *mrb, mrb_value self) { - mrb_float alpha; - mrb_get_args(mrb, "f", &alpha); - - uint64_t id = get_id_ElementImage(mrb, self); - app::EImage *element = (app::EImage *)app::element_pool[id]; - element->alpha = alpha; - - return mrb_nil_value(); -} - -static mrb_value element_image_z_get(mrb_state *mrb, mrb_value self) { - uint64_t id = get_id_ElementImage(mrb, self); - app::EImage *element = (app::EImage *)app::element_pool[id]; - return mrb_float_value(mrb, element->z); -} - -static mrb_value element_image_z_set(mrb_state *mrb, mrb_value self) { - mrb_float z; - mrb_get_args(mrb, "f", &z); - - uint64_t id = get_id_ElementImage(mrb, self); - app::EImage *element = (app::EImage *)app::element_pool[id]; - element->z = z; - - return mrb_nil_value(); -} - -static mrb_value element_image_click_mode_get(mrb_state *mrb, mrb_value self) { - uint64_t id = get_id_ElementImage(mrb, self); - app::EImage *element = (app::EImage *)app::element_pool[id]; - - std::string click_mode_str; - switch (element->click_mode) { - case ClickMode::PASS: - click_mode_str = "pass"; - break; - case ClickMode::BLOCK: - click_mode_str = "block"; - break; - case ClickMode::IGNORE: - click_mode_str = "ignore"; - break; - } - - return mrb_symbol_value(mrb_intern_cstr(mrb, click_mode_str.c_str())); -} - -static mrb_value element_image_click_mode_set(mrb_state *mrb, mrb_value self) { - mrb_sym click_mode_sym; - mrb_get_args(mrb, "n", &click_mode_sym); - - uint64_t id = get_id_ElementImage(mrb, self); - app::EImage *element = (app::EImage *)app::element_pool[id]; - - std::string click_mode = mrb_sym2name(mrb, click_mode_sym); - - if (click_mode == "pass") - element->click_mode = ClickMode::PASS; - else if (click_mode == "block") - element->click_mode = ClickMode::BLOCK; - else if (click_mode == "ignore") - element->click_mode = ClickMode::IGNORE; - - return mrb_nil_value(); -} - -static void Scene_free(mrb_state *mrb, void *ptr) { - UNUSED(mrb); - uint64_t id = ((Wrapper *)ptr)->id; - app::scene_pool.release(id); - delete (Wrapper *)ptr; -} - -static const struct mrb_data_type Scene_type = {"Scene", Scene_free}; - -static mrb_value Scene_init(mrb_state *mrb, mrb_value self) { - Wrapper *old = (Wrapper *)DATA_PTR(self); - if (old) - mrb_free(mrb, old); - mrb_data_init(self, nullptr, &Scene_type); - Wrapper *s = new Wrapper(); - - app::Scene *loading_scene = new app::Scene{}; - s->id = app::scene_pool.acquire(loading_scene); - app::scene_pool.use(s->id); - - mrb_data_init(self, s, &Scene_type); - return self; -} - -inline uint64_t get_id_Scene(mrb_state *mrb, mrb_value self) { - Wrapper *wrapper; - Data_Get_Struct(mrb, self, &Scene_type, wrapper); - return wrapper->id; -} - -static mrb_value scene_add_element(mrb_state *mrb, mrb_value self) { - mrb_value element_val; - mrb_get_args(mrb, "o", &element_val); - - if ( - !mrb_obj_is_kind_of(mrb, element_val, mrb_class_get(mrb, "ElementText")) - && !mrb_obj_is_kind_of(mrb, element_val, mrb_class_get(mrb, "ElementRect")) - && !mrb_obj_is_kind_of(mrb, element_val, mrb_class_get(mrb, "ElementImage")) - ) { - mrb_raise( - mrb, - mrb_class_get(mrb, "Exception"), - "Expected an ElementText, ElementRect, or ElementImage object" - ); - return mrb_nil_value(); - } - - uint64_t id = get_id_Scene(mrb, self); - app::Scene *scene = app::scene_pool[id]; - - uint64_t element_id; - if (mrb_obj_is_kind_of(mrb, element_val, mrb_class_get(mrb, "ElementText"))) { - element_id = get_id_ElementText(mrb, element_val); - } else if ( - mrb_obj_is_kind_of(mrb, element_val, mrb_class_get(mrb, "ElementRect")) - ) { - element_id = get_id_ElementRect(mrb, element_val); - } else if ( - mrb_obj_is_kind_of(mrb, element_val, mrb_class_get(mrb, "ElementImage")) - ) { - element_id = get_id_ElementImage(mrb, element_val); - } else { - mrb_raise( - mrb, - mrb_class_get(mrb, "Exception"), - "Expected an ElementText, ElementRect, or ElementImage object" - ); - return mrb_nil_value(); - } - - scene->add_element(element_id); - - return self; -} - -static mrb_value scene_delete_element(mrb_state *mrb, mrb_value self) { - mrb_value element_val; - mrb_get_args(mrb, "o", &element_val); - - if ( - !mrb_obj_is_kind_of(mrb, element_val, mrb_class_get(mrb, "ElementText")) - && !mrb_obj_is_kind_of(mrb, element_val, mrb_class_get(mrb, "ElementRect")) - && !mrb_obj_is_kind_of(mrb, element_val, mrb_class_get(mrb, "ElementImage")) - ) { - mrb_raise( - mrb, - mrb_class_get(mrb, "Exception"), - "Expected an ElementText, ElementRect, or ElementImage object" - ); - return mrb_nil_value(); - } - - uint64_t id = get_id_Scene(mrb, self); - app::Scene *scene = app::scene_pool[id]; - - uint64_t element_id; - if (mrb_obj_is_kind_of(mrb, element_val, mrb_class_get(mrb, "ElementText"))) { - element_id = get_id_ElementText(mrb, element_val); - } else if ( - mrb_obj_is_kind_of(mrb, element_val, mrb_class_get(mrb, "ElementRect")) - ) { - element_id = get_id_ElementRect(mrb, element_val); - } else if ( - mrb_obj_is_kind_of(mrb, element_val, mrb_class_get(mrb, "ElementImage")) - ) { - element_id = get_id_ElementImage(mrb, element_val); - } else { - mrb_raise( - mrb, - mrb_class_get(mrb, "Exception"), - "Expected an ElementText, ElementRect, or ElementImage object" - ); - return mrb_nil_value(); - } - - scene->delete_element(element_id); - - return self; -} - -static mrb_value scene_on_update(mrb_state *mrb, mrb_value self) { - mrb_value block; - mrb_get_args(mrb, "&", &block); - - uint64_t id = get_id_Scene(mrb, self); - app::Scene *scene = app::scene_pool[id]; - scene->update.set_proc(block); - - return self; -} - -static mrb_value scene_elements_at(mrb_state *mrb, mrb_value self) { - mrb_value position_val; - mrb_get_args(mrb, "o", &position_val); - - float x = 0, y = 0; - HASH_FLOAT(position_val, x, x); - HASH_FLOAT(position_val, y, y); - Vec2 position = {x, y}; - - uint64_t id = get_id_Scene(mrb, self); - app::Scene *scene = app::scene_pool[id]; - - std::vector element_ids = scene->elements_at(position); - - mrb_value result = mrb_ary_new_capa(mrb, element_ids.size()); - for (uint64_t element_id : element_ids) { - app::Element *element = app::element_pool[element_id]; - app::element_pool.use(element_id); - if (element->type == Type::TEXT) { - RClass *ElementText_class = mrb_class_get(mrb, "ElementText"); - mrb_value obj = wrap(mrb, ElementText_class, &ElementText_type, element_id); - mrb_ary_push(mrb, result, obj); - } else if (element->type == Type::RECT) { - RClass *ElementRect_class = mrb_class_get(mrb, "ElementRect"); - mrb_value obj = wrap(mrb, ElementRect_class, &ElementRect_type, element_id); - mrb_ary_push(mrb, result, obj); - } else if (element->type == Type::IMAGE) { - RClass *ElementImage_class = mrb_class_get(mrb, "ElementImage"); - mrb_value obj = wrap(mrb, ElementImage_class, &ElementImage_type, element_id); - mrb_ary_push(mrb, result, obj); - } else { - continue; - } - } - - return result; -} - -static mrb_value scene_elements(mrb_state *mrb, mrb_value self) { - uint64_t id = get_id_Scene(mrb, self); - app::Scene *scene = app::scene_pool[id]; - - std::vector element_ids = scene->element_ids; - - mrb_value result = mrb_ary_new_capa(mrb, element_ids.size()); - for (uint64_t element_id : element_ids) { - app::Element *element = app::element_pool[element_id]; - app::element_pool.use(element_id); - if (element->type == Type::TEXT) { - RClass *ElementText_class = mrb_class_get(mrb, "ElementText"); - mrb_value obj = wrap(mrb, ElementText_class, &ElementText_type, element_id); - mrb_ary_push(mrb, result, obj); - } else if (element->type == Type::RECT) { - RClass *ElementRect_class = mrb_class_get(mrb, "ElementRect"); - mrb_value obj = wrap(mrb, ElementRect_class, &ElementRect_type, element_id); - mrb_ary_push(mrb, result, obj); - } else if (element->type == Type::IMAGE) { - RClass *ElementImage_class = mrb_class_get(mrb, "ElementImage"); - mrb_value obj = wrap(mrb, ElementImage_class, &ElementImage_type, element_id); - mrb_ary_push(mrb, result, obj); - } else { - continue; - } - } - - return result; -} - -static mrb_value scene_equal(mrb_state *mrb, mrb_value self) { - mrb_value other; - mrb_get_args(mrb, "o", &other); - - if (!mrb_obj_is_kind_of(mrb, other, mrb_class_get(mrb, "Scene"))) - return mrb_false_value(); - - uint64_t id_self = get_id_Scene(mrb, self); - uint64_t id_other = get_id_Scene(mrb, other); - - return mrb_bool_value(id_self == id_other); -} - -static mrb_value scene_inspect(mrb_state *mrb, mrb_value self) { - uint64_t id = get_id_Scene(mrb, self); - return mrb_str_new_cstr(mrb, ("#").c_str()); -} - -static mrb_value scene_hash(mrb_state *mrb, mrb_value self) { - uint64_t id = get_id_Scene(mrb, self); - return mrb_fixnum_value(id); -} - -static mrb_value app_run(mrb_state *mrb, mrb_value) { - mrb_int width, height; - mrb_value options_hash; - char *title = nullptr; - mrb_get_args(mrb, "iiz|H", &width, &height, &title, &options_hash); - - app_ = new app::App({(float)width, (float)height}, title); - - float fps = 60; - if (!mrb_nil_p(options_hash)) - HASH_FLOAT(options_hash, fps, fps); - - app_->set_fps(fps); - - return mrb_nil_value(); -} - -static mrb_value app_fps_get(mrb_state *mrb, mrb_value) { - return mrb_float_value(mrb, app_->get_fps()); -} - -static mrb_value app_fps_set(mrb_state *mrb, mrb_value) { - mrb_float fps; - mrb_get_args(mrb, "f", &fps); - app_->set_fps(fps); - return mrb_nil_value(); -} - -static mrb_value app_start(mrb_state *mrb, mrb_value) { - mrb_value scene_val; - mrb_get_args(mrb, "o", &scene_val); - - if (!mrb_obj_is_kind_of(mrb, scene_val, mrb_class_get(mrb, "Scene"))) { - mrb_raise(mrb, mrb_class_get(mrb, "Exception"), "Expected a Scene object"); - return mrb_nil_value(); - } - - uint64_t id = get_id_Scene(mrb, scene_val); - app_->switch_to_scene(id); - - app_->loop(); - - return mrb_nil_value(); -} - -static mrb_value app_current_scene(mrb_state *mrb, mrb_value) { - uint64_t id = app_->current_scene_id; - if (id == UINT64_MAX) - return mrb_nil_value(); - app::scene_pool.use(id); - return wrap(mrb, mrb_class_get(mrb, "Scene"), &Scene_type, id); -} - -static mrb_value app_on_update(mrb_state *mrb, mrb_value) { - mrb_value block; - mrb_get_args(mrb, "&", &block); - app_->update.set_proc(block); - return mrb_nil_value(); -} - -static mrb_value app_switch_to(mrb_state *mrb, mrb_value) { - mrb_value scene_val; - mrb_get_args(mrb, "o", &scene_val); - - if (!mrb_obj_is_kind_of(mrb, scene_val, mrb_class_get(mrb, "Scene"))) { - mrb_raise(mrb, mrb_class_get(mrb, "Exception"), "Expected a Scene object"); - return mrb_nil_value(); - } - - uint64_t id = get_id_Scene(mrb, scene_val); - app_->switch_to_scene(id); - - return mrb_nil_value(); -} - -static mrb_value app_localize(mrb_state *mrb, mrb_value) { - mrb_sym lang_sym, key_sym; - char *text; - - mrb_get_args(mrb, "nnz", &lang_sym, &key_sym, &text); - - auto lang = Localization::lang_from_sym(mrb, lang_sym); - - const char *key_name = mrb_sym2name(mrb, key_sym); - - auto it = Localization::localization_key_map.find(key_name); - Localization::Key key_id; - - if (it == Localization::localization_key_map.end()) { - key_id = (Localization::Key)Localization::localization_key_map.size(); - Localization::localization_key_map[key_name] = key_id; - } else { - key_id = it->second; - } - - Localization::set(lang, key_id, text); - - return mrb_nil_value(); -} - -static mrb_value app_language_set(mrb_state *mrb, mrb_value) { - mrb_sym lang_sym; - mrb_get_args(mrb, "n", &lang_sym); - Localization::current_language = Localization::lang_from_sym(mrb, lang_sym); - return mrb_nil_value(); -} - -static mrb_value app_language_get(mrb_state *mrb, mrb_value) { - return mrb_symbol_value(Localization::lang_to_sym(mrb, Localization::current_language)); -} - -static mrb_value app_mouse_position(mrb_state *mrb, mrb_value) { - Vec2 mouse_pos = app_->mouse_position; - mrb_value result = mrb_hash_new(mrb); - HASH_SET(result, x, mrb_float_value(mrb, mouse_pos.x)); - HASH_SET(result, y, mrb_float_value(mrb, mouse_pos.y)); - return result; -} - -static mrb_value app_is_down(mrb_state *mrb, mrb_value) { - mrb_sym key_sym; - mrb_get_args(mrb, "n", &key_sym); - std::string key_name = mrb_sym2name(mrb, key_sym); - Key key = get_key(key_name); - return mrb_bool_value(app_->down_keys[key]); -} - -static mrb_value app_is_pressed(mrb_state *mrb, mrb_value) { - mrb_sym key_sym; - mrb_get_args(mrb, "n", &key_sym); - std::string key_name = mrb_sym2name(mrb, key_sym); - Key key = get_key(key_name); - for (Key pressed_key : app_->pressed_keys) - if (pressed_key == key) - return mrb_bool_value(true); - return mrb_bool_value(false); -} - -static mrb_value app_is_released(mrb_state *mrb, mrb_value) { - mrb_sym key_sym; - mrb_get_args(mrb, "n", &key_sym); - std::string key_name = mrb_sym2name(mrb, key_sym); - Key key = get_key(key_name); - for (Key released_key : app_->released_keys) - if (released_key == key) - return mrb_bool_value(true); - return mrb_bool_value(false); -} - -static mrb_value app_map_key(mrb_state *mrb, mrb_value) { - mrb_sym key_sym; - mrb_sym action_sym; - mrb_get_args(mrb, "nn", &key_sym, &action_sym); - std::string key_name = mrb_sym2name(mrb, key_sym); - std::string action_name = mrb_sym2name(mrb, action_sym); - set_action_mapping(action_name, key_name); - return mrb_nil_value(); -} - -static mrb_value app_scroll(mrb_state *mrb, mrb_value) { - Vec2 scroll = app_->scroll; - mrb_value result = mrb_hash_new(mrb); - HASH_SET(result, x, mrb_float_value(mrb, scroll.x)); - HASH_SET(result, y, mrb_float_value(mrb, scroll.y)); - return result; -} - -static mrb_value app_text_input(mrb_state *mrb, mrb_value) { - return mrb_str_new_cstr(mrb, app_->text.c_str()); -} - -static mrb_value app_exit(mrb_state *, mrb_value) { - app_->exit(); - return mrb_nil_value(); -} - -inline void setup() { - DEF_CLASS(Params, MRB_ARGS_REQ(1)); - ADD_METHOD(Params, "[]", params_get, MRB_ARGS_REQ(1)); - ADD_METHOD(Params, "[]=", params_set, MRB_ARGS_REQ(2)); - - DEF_CLASS(Font, MRB_ARGS_REQ(2) | MRB_ARGS_OPT(1)); - ADD_METHOD(Font, "==", font_equal, MRB_ARGS_REQ(1)); - ADD_METHOD(Font, "eql?", font_equal, MRB_ARGS_REQ(1)); - ADD_METHOD(Font, "hash", font_hash, MRB_ARGS_NONE()); - - DEF_CLASS(Image, MRB_ARGS_REQ(1) | MRB_ARGS_OPT(1)); - ADD_METHOD(Image, "==", image_equal, MRB_ARGS_REQ(1)); - ADD_METHOD(Image, "eql?", image_equal, MRB_ARGS_REQ(1)); - ADD_METHOD(Image, "hash", image_hash, MRB_ARGS_NONE()); - ADD_METHOD(Image, "width", image_width, MRB_ARGS_NONE()); - ADD_METHOD(Image, "height", image_height, MRB_ARGS_NONE()); - - DEF_CLASS(Animation, MRB_ARGS_REQ(1) | MRB_ARGS_OPT(1)); - ADD_CLASS_METHOD(Animation, "from", static_image_animation, MRB_ARGS_REQ(1)); - ADD_METHOD(Animation, "==", animation_equal, MRB_ARGS_REQ(1)); - ADD_METHOD(Animation, "eql?", animation_equal, MRB_ARGS_REQ(1)); - ADD_METHOD(Animation, "hash", animation_hash, MRB_ARGS_NONE()); - ADD_METHOD(Animation, "fps=", animation_fps_set, MRB_ARGS_REQ(1)); - ADD_METHOD(Animation, "fps", animation_fps_get, MRB_ARGS_NONE()); - ADD_METHOD(Animation, "frames=", animation_frames_set, MRB_ARGS_REQ(1)); - ADD_METHOD(Animation, "frames", animation_frames_get, MRB_ARGS_NONE()); - - DEF_CLASS(ElementText, MRB_ARGS_REQ(3) | MRB_ARGS_OPT(2)); - ADD_METHOD(ElementText, "==", element_text_equal, MRB_ARGS_REQ(1)); - ADD_METHOD(ElementText, "eql?", element_text_equal, MRB_ARGS_REQ(1)); - ADD_METHOD(ElementText, "inspect", element_text_inspect, MRB_ARGS_NONE()); - ADD_METHOD(ElementText, "hash", element_text_hash, MRB_ARGS_NONE()); - ADD_METHOD(ElementText, "click", element_text_on_click, MRB_ARGS_BLOCK()); - ADD_METHOD(ElementText, "to_s", element_text_to_s, MRB_ARGS_NONE()); - ADD_METHOD(ElementText, "key=", element_text_key_set, MRB_ARGS_REQ(1)); - ADD_METHOD(ElementText, "key", element_text_key_get, MRB_ARGS_NONE()); - ADD_METHOD(ElementText, "color=", element_text_color_set, MRB_ARGS_REQ(1)); - ADD_METHOD(ElementText, "color", element_text_color_get, MRB_ARGS_NONE()); - ADD_METHOD(ElementText, "font=", element_text_font_set, MRB_ARGS_REQ(1)); - ADD_METHOD(ElementText, "font", element_text_font_get, MRB_ARGS_NONE()); - ADD_METHOD(ElementText, "params", element_text_params, MRB_ARGS_NONE()); -#warning "Make vector a proper class instead of using a hash for vectors" - ADD_METHOD(ElementText, "position=", element_text_position_set, MRB_ARGS_REQ(1)); - ADD_METHOD(ElementText, "position", element_text_position_get, MRB_ARGS_NONE()); - ADD_METHOD(ElementText, "scale=", element_text_scale_set, MRB_ARGS_REQ(1)); - ADD_METHOD(ElementText, "scale", element_text_scale_get, MRB_ARGS_NONE()); - ADD_METHOD(ElementText, "rotation=", element_text_rotation_set, MRB_ARGS_REQ(1)); - ADD_METHOD(ElementText, "rotation", element_text_rotation_get, MRB_ARGS_NONE()); - ADD_METHOD(ElementText, "pivot=", element_text_pivot_set, MRB_ARGS_REQ(1)); - ADD_METHOD(ElementText, "pivot", element_text_pivot_get, MRB_ARGS_NONE()); - ADD_METHOD(ElementText, "alpha=", element_text_alpha_set, MRB_ARGS_REQ(1)); - ADD_METHOD(ElementText, "alpha", element_text_alpha_get, MRB_ARGS_NONE()); - ADD_METHOD(ElementText, "z=", element_text_z_set, MRB_ARGS_REQ(1)); - ADD_METHOD(ElementText, "z", element_text_z_get, MRB_ARGS_NONE()); - ADD_METHOD(ElementText, "click_mode=", element_text_click_mode_set, MRB_ARGS_REQ(1)); - ADD_METHOD(ElementText, "click_mode", element_text_click_mode_get, MRB_ARGS_NONE()); - ADD_METHOD(ElementText, "width", element_text_width, MRB_ARGS_NONE()); - ADD_METHOD(ElementText, "height", element_text_height, MRB_ARGS_NONE()); - - DEF_CLASS(ElementRect, MRB_ARGS_REQ(3) | MRB_ARGS_OPT(1)); - ADD_METHOD(ElementRect, "==", element_rect_equal, MRB_ARGS_REQ(1)); - ADD_METHOD(ElementRect, "eql?", element_rect_equal, MRB_ARGS_REQ(1)); - ADD_METHOD(ElementRect, "inspect", element_rect_inspect, MRB_ARGS_NONE()); - ADD_METHOD(ElementRect, "to_s", element_rect_inspect, MRB_ARGS_NONE()); - ADD_METHOD(ElementRect, "hash", element_rect_hash, MRB_ARGS_NONE()); - ADD_METHOD(ElementRect, "click", element_rect_on_click, MRB_ARGS_BLOCK()); - ADD_METHOD(ElementRect, "width=", element_rect_width_set, MRB_ARGS_REQ(1)); - ADD_METHOD(ElementRect, "width", element_rect_width_get, MRB_ARGS_NONE()); - ADD_METHOD(ElementRect, "height=", element_rect_height_set, MRB_ARGS_REQ(1)); - ADD_METHOD(ElementRect, "height", element_rect_height_get, MRB_ARGS_NONE()); - ADD_METHOD(ElementRect, "color=", element_rect_color_set, MRB_ARGS_REQ(1)); - ADD_METHOD(ElementRect, "color", element_rect_color_get, MRB_ARGS_NONE()); - ADD_METHOD(ElementRect, "position=", element_rect_position_set, MRB_ARGS_REQ(1)); - ADD_METHOD(ElementRect, "position", element_rect_position_get, MRB_ARGS_NONE()); - ADD_METHOD(ElementRect, "scale=", element_rect_scale_set, MRB_ARGS_REQ(1)); - ADD_METHOD(ElementRect, "scale", element_rect_scale_get, MRB_ARGS_NONE()); - ADD_METHOD(ElementRect, "rotation=", element_rect_rotation_set, MRB_ARGS_REQ(1)); - ADD_METHOD(ElementRect, "rotation", element_rect_rotation_get, MRB_ARGS_NONE()); - ADD_METHOD(ElementRect, "pivot=", element_rect_pivot_set, MRB_ARGS_REQ(1)); - ADD_METHOD(ElementRect, "pivot", element_rect_pivot_get, MRB_ARGS_NONE()); - ADD_METHOD(ElementRect, "alpha=", element_rect_alpha_set, MRB_ARGS_REQ(1)); - ADD_METHOD(ElementRect, "alpha", element_rect_alpha_get, MRB_ARGS_NONE()); - ADD_METHOD(ElementRect, "z=", element_rect_z_set, MRB_ARGS_REQ(1)); - ADD_METHOD(ElementRect, "z", element_rect_z_get, MRB_ARGS_NONE()); - ADD_METHOD(ElementRect, "click_mode=", element_rect_click_mode_set, MRB_ARGS_REQ(1)); - ADD_METHOD(ElementRect, "click_mode", element_rect_click_mode_get, MRB_ARGS_NONE()); - - DEF_CLASS(ElementImage, MRB_ARGS_REQ(1) | MRB_ARGS_OPT(1)); - ADD_METHOD(ElementImage, "click", element_image_on_click, MRB_ARGS_BLOCK()); - ADD_METHOD(ElementImage, "==", element_image_equal, MRB_ARGS_REQ(1)); - ADD_METHOD(ElementImage, "eql?", element_image_equal, MRB_ARGS_REQ(1)); - ADD_METHOD(ElementImage, "inspect", element_image_inspect, MRB_ARGS_NONE()); - ADD_METHOD(ElementImage, "to_s", element_image_inspect, MRB_ARGS_NONE()); - ADD_METHOD(ElementImage, "hash", element_image_hash, MRB_ARGS_NONE()); - ADD_METHOD(ElementImage, "animation=", element_image_animation_set, MRB_ARGS_REQ(1)); - ADD_METHOD(ElementImage, "animation", element_image_animation_get, MRB_ARGS_NONE()); - ADD_METHOD(ElementImage, "position=", element_image_position_set, MRB_ARGS_REQ(1)); - ADD_METHOD(ElementImage, "position", element_image_position_get, MRB_ARGS_NONE()); - ADD_METHOD(ElementImage, "scale=", element_image_scale_set, MRB_ARGS_REQ(1)); - ADD_METHOD(ElementImage, "scale", element_image_scale_get, MRB_ARGS_NONE()); - ADD_METHOD(ElementImage, "rotation=", element_image_rotation_set, MRB_ARGS_REQ(1)); - ADD_METHOD(ElementImage, "rotation", element_image_rotation_get, MRB_ARGS_NONE()); - ADD_METHOD(ElementImage, "pivot=", element_image_pivot_set, MRB_ARGS_REQ(1)); - ADD_METHOD(ElementImage, "pivot", element_image_pivot_get, MRB_ARGS_NONE()); - ADD_METHOD(ElementImage, "alpha=", element_image_alpha_set, MRB_ARGS_REQ(1)); - ADD_METHOD(ElementImage, "alpha", element_image_alpha_get, MRB_ARGS_NONE()); - ADD_METHOD(ElementImage, "z=", element_image_z_set, MRB_ARGS_REQ(1)); - ADD_METHOD(ElementImage, "z", element_image_z_get, MRB_ARGS_NONE()); - ADD_METHOD(ElementImage, "click_mode=", element_image_click_mode_set, MRB_ARGS_REQ(1)); - ADD_METHOD(ElementImage, "click_mode", element_image_click_mode_get, MRB_ARGS_NONE()); - - DEF_CLASS(Scene, MRB_ARGS_NONE()); - ADD_METHOD(Scene, "==", scene_equal, MRB_ARGS_REQ(1)); - ADD_METHOD(Scene, "eql?", scene_equal, MRB_ARGS_REQ(1)); - ADD_METHOD(Scene, "inspect", scene_inspect, MRB_ARGS_NONE()); - ADD_METHOD(Scene, "to_s", scene_inspect, MRB_ARGS_NONE()); - ADD_METHOD(Scene, "hash", scene_hash, MRB_ARGS_NONE()); - ADD_METHOD(Scene, "<<", scene_add_element, MRB_ARGS_REQ(1)); - ADD_METHOD(Scene, "delete", scene_delete_element, MRB_ARGS_REQ(1)); - ADD_METHOD(Scene, "remove", scene_delete_element, MRB_ARGS_REQ(1)); - ADD_METHOD(Scene, "update", scene_on_update, MRB_ARGS_BLOCK()); - ADD_METHOD(Scene, "elements_at", scene_elements_at, MRB_ARGS_REQ(1)); - ADD_METHOD(Scene, "elements", scene_elements, MRB_ARGS_NONE()); - - DEF_MODULE(App); - ADD_MODULE_METHOD(App, "run", app_run, MRB_ARGS_REQ(3) | MRB_ARGS_OPT(1)); - ADD_MODULE_METHOD(App, "start", app_start, MRB_ARGS_REQ(1)); - ADD_MODULE_METHOD(App, "switch_to", app_switch_to, MRB_ARGS_REQ(1)); - ADD_MODULE_METHOD(App, "scene", app_current_scene, MRB_ARGS_NONE()); - ADD_MODULE_METHOD(App, "update", app_on_update, MRB_ARGS_BLOCK()); - ADD_MODULE_METHOD(App, "fps=", app_fps_set, MRB_ARGS_REQ(1)); - ADD_MODULE_METHOD(App, "fps", app_fps_get, MRB_ARGS_NONE()); - ADD_MODULE_METHOD(App, "localize", app_localize, MRB_ARGS_REQ(3)); - ADD_MODULE_METHOD(App, "language=", app_language_set, MRB_ARGS_REQ(1)); - ADD_MODULE_METHOD(App, "language", app_language_get, MRB_ARGS_NONE()); - ADD_MODULE_METHOD(App, "mouse_position", app_mouse_position, MRB_ARGS_NONE()); - ADD_MODULE_METHOD(App, "down?", app_is_down, MRB_ARGS_REQ(1)); - ADD_MODULE_METHOD(App, "pressed?", app_is_pressed, MRB_ARGS_REQ(1)); - ADD_MODULE_METHOD(App, "released?", app_is_released, MRB_ARGS_REQ(1)); - ADD_MODULE_METHOD(App, "map_key", app_map_key, MRB_ARGS_REQ(2)); - ADD_MODULE_METHOD(App, "scroll", app_scroll, MRB_ARGS_NONE()); - ADD_MODULE_METHOD(App, "text_input", app_text_input, MRB_ARGS_NONE()); - ADD_MODULE_METHOD(App, "exit!", app_exit, MRB_ARGS_NONE()); -} -} // namespace definitions - -#endif \ No newline at end of file diff --git a/include/bindings/definitions.h b/include/bindings/definitions.h new file mode 100644 index 0000000..27cac02 --- /dev/null +++ b/include/bindings/definitions.h @@ -0,0 +1,63 @@ +#ifndef DEFINITIONS_H +#define DEFINITIONS_H + +#include "bindings/ruby.h" + +namespace definitions { +struct Binding { + RClass *cls; + const mrb_data_type *type; +}; + +inline struct RubyBindings { + Binding Vec2; + Binding Params; + Binding Font; + Binding Image; + Binding Animation; + Binding ElementText; + Binding ElementRect; + Binding ElementImage; + Binding Scene; +} bindings; + +inline mrb_value wrap(Binding binding, uint64_t id) { + RBasic *obj_b = mrb_obj_alloc(Ruby::mrb, MRB_TT_DATA, binding.cls); + mrb_value obj = mrb_obj_value(obj_b); + + Wrapper *w = new Wrapper(); + w->id = id; + + mrb_data_init(obj, w, binding.type); + + return obj; +} + +mrb_value Vec2_wrap(uint64_t id, Vec2 *vec); + +void register_vec2(); +void register_params(); +void register_font(); +void register_image(); +void register_animation(); +void register_element_text(); +void register_element_rect(); +void register_element_image(); +void register_scene(); +void register_app(); + +inline void setup() { + register_vec2(); + register_params(); + register_font(); + register_image(); + register_animation(); + register_element_text(); + register_element_rect(); + register_element_image(); + register_scene(); + register_app(); +} +} // namespace definitions + +#endif \ No newline at end of file diff --git a/include/binding/ruby.h b/include/bindings/ruby.h similarity index 98% rename from include/binding/ruby.h rename to include/bindings/ruby.h index f12f94b..f933eaf 100644 --- a/include/binding/ruby.h +++ b/include/bindings/ruby.h @@ -4,7 +4,7 @@ #include "pch.h" #include "utils.h" -#include "binding/ruby_compiled.h" +#include "bindings/ruby_compiled.h" #define DEF_SYM(name) inline mrb_sym sym_##name = mrb_intern_cstr(Ruby::mrb, #name); #define SYM(name) mrb_symbol_value(sym_##name) diff --git a/include/bindings/ruby_compiled.h b/include/bindings/ruby_compiled.h new file mode 100644 index 0000000..c2121bc --- /dev/null +++ b/include/bindings/ruby_compiled.h @@ -0,0 +1,1038 @@ +#ifndef MGEMS_H +#define MGEMS_H +constexpr unsigned char mgems[] = { + 0x52, 0x49, 0x54, 0x45, 0x30, 0x34, 0x30, 0x30, 0x00, 0x00, 0x30, 0x5e, + 0x4d, 0x41, 0x54, 0x5a, 0x30, 0x30, 0x30, 0x30, 0x49, 0x52, 0x45, 0x50, + 0x00, 0x00, 0x2d, 0x39, 0x30, 0x34, 0x30, 0x30, 0x00, 0x00, 0x00, 0xe3, + 0x00, 0x01, 0x00, 0x03, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x67, + 0x11, 0x01, 0x11, 0x02, 0x67, 0x01, 0x00, 0x69, 0x01, 0x00, 0x11, 0x01, + 0x68, 0x01, 0x01, 0x69, 0x01, 0x01, 0x11, 0x01, 0x1d, 0x02, 0x00, 0x67, + 0x01, 0x02, 0x69, 0x01, 0x02, 0x11, 0x01, 0x11, 0x02, 0x67, 0x01, 0x03, + 0x69, 0x01, 0x03, 0x11, 0x01, 0x11, 0x02, 0x67, 0x01, 0x04, 0x69, 0x01, + 0x04, 0x11, 0x01, 0x11, 0x02, 0x67, 0x01, 0x05, 0x69, 0x01, 0x05, 0x11, + 0x01, 0x11, 0x02, 0x67, 0x01, 0x06, 0x69, 0x01, 0x06, 0x11, 0x01, 0x11, + 0x02, 0x67, 0x01, 0x07, 0x69, 0x01, 0x07, 0x11, 0x01, 0x11, 0x02, 0x67, + 0x01, 0x08, 0x69, 0x01, 0x08, 0x11, 0x01, 0x1d, 0x02, 0x09, 0x67, 0x01, + 0x0a, 0x69, 0x01, 0x09, 0x3d, 0x01, 0x76, 0x00, 0x00, 0x00, 0x0b, 0x00, + 0x0b, 0x50, 0x72, 0x65, 0x74, 0x74, 0x79, 0x50, 0x72, 0x69, 0x6e, 0x74, + 0x00, 0x00, 0x06, 0x4b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x00, 0x00, 0x02, + 0x50, 0x50, 0x00, 0x00, 0x06, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x00, + 0x00, 0x05, 0x41, 0x72, 0x72, 0x61, 0x79, 0x00, 0x00, 0x04, 0x48, 0x61, + 0x73, 0x68, 0x00, 0x00, 0x06, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x00, + 0x00, 0x05, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x00, 0x00, 0x09, 0x4d, 0x61, + 0x74, 0x63, 0x68, 0x44, 0x61, 0x74, 0x61, 0x00, 0x00, 0x0b, 0x42, 0x61, + 0x73, 0x69, 0x63, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x00, 0x00, 0x06, + 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x00, 0x00, 0x00, 0x01, 0xd1, 0x00, + 0x01, 0x00, 0x04, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x94, 0x1d, + 0x01, 0x01, 0x6c, 0x01, 0x00, 0x00, 0x1d, 0x01, 0x01, 0x6c, 0x01, 0x02, + 0x01, 0x6b, 0x01, 0x03, 0x02, 0x10, 0x02, 0x04, 0x2f, 0x01, 0x05, 0x01, + 0x10, 0x02, 0x06, 0x2f, 0x01, 0x05, 0x01, 0x10, 0x02, 0x07, 0x2f, 0x01, + 0x05, 0x01, 0x10, 0x02, 0x08, 0x2f, 0x01, 0x05, 0x01, 0x10, 0x02, 0x09, + 0x2f, 0x01, 0x05, 0x01, 0x10, 0x02, 0x0a, 0x2f, 0x01, 0x05, 0x01, 0x6b, + 0x01, 0x0b, 0x03, 0x6b, 0x01, 0x0c, 0x04, 0x6b, 0x01, 0x0d, 0x05, 0x6b, + 0x01, 0x0e, 0x06, 0x6b, 0x01, 0x0f, 0x07, 0x6b, 0x01, 0x10, 0x08, 0x6b, + 0x01, 0x11, 0x09, 0x6b, 0x01, 0x12, 0x0a, 0x6b, 0x01, 0x13, 0x0b, 0x11, + 0x01, 0x11, 0x02, 0x67, 0x01, 0x14, 0x69, 0x01, 0x0c, 0x11, 0x01, 0x11, + 0x02, 0x67, 0x01, 0x15, 0x69, 0x01, 0x0d, 0x11, 0x01, 0x11, 0x02, 0x67, + 0x01, 0x16, 0x69, 0x01, 0x0e, 0x11, 0x01, 0x11, 0x02, 0x67, 0x01, 0x17, + 0x69, 0x01, 0x0f, 0x11, 0x01, 0x11, 0x02, 0x67, 0x01, 0x18, 0x69, 0x01, + 0x10, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x06, 0x66, 0x6f, 0x72, + 0x6d, 0x61, 0x74, 0x00, 0x00, 0x0b, 0x50, 0x72, 0x65, 0x74, 0x74, 0x79, + 0x50, 0x72, 0x69, 0x6e, 0x74, 0x00, 0x00, 0x11, 0x73, 0x69, 0x6e, 0x67, + 0x6c, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x61, + 0x74, 0x00, 0x00, 0x0a, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, + 0x7a, 0x65, 0x00, 0x00, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x00, + 0x00, 0x0b, 0x61, 0x74, 0x74, 0x72, 0x5f, 0x72, 0x65, 0x61, 0x64, 0x65, + 0x72, 0x00, 0x00, 0x08, 0x6d, 0x61, 0x78, 0x77, 0x69, 0x64, 0x74, 0x68, + 0x00, 0x00, 0x07, 0x6e, 0x65, 0x77, 0x6c, 0x69, 0x6e, 0x65, 0x00, 0x00, + 0x08, 0x67, 0x65, 0x6e, 0x73, 0x70, 0x61, 0x63, 0x65, 0x00, 0x00, 0x06, + 0x69, 0x6e, 0x64, 0x65, 0x6e, 0x74, 0x00, 0x00, 0x0b, 0x67, 0x72, 0x6f, + 0x75, 0x70, 0x5f, 0x71, 0x75, 0x65, 0x75, 0x65, 0x00, 0x00, 0x0d, 0x63, + 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, + 0x00, 0x00, 0x14, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x5f, 0x6f, 0x75, 0x74, + 0x6d, 0x6f, 0x73, 0x74, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x00, + 0x00, 0x04, 0x74, 0x65, 0x78, 0x74, 0x00, 0x00, 0x0e, 0x66, 0x69, 0x6c, + 0x6c, 0x5f, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x61, 0x62, 0x6c, 0x65, 0x00, + 0x00, 0x09, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x61, 0x62, 0x6c, 0x65, 0x00, + 0x00, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x00, 0x00, 0x09, 0x67, 0x72, + 0x6f, 0x75, 0x70, 0x5f, 0x73, 0x75, 0x62, 0x00, 0x00, 0x04, 0x6e, 0x65, + 0x73, 0x74, 0x00, 0x00, 0x05, 0x66, 0x6c, 0x75, 0x73, 0x68, 0x00, 0x00, + 0x04, 0x54, 0x65, 0x78, 0x74, 0x00, 0x00, 0x09, 0x42, 0x72, 0x65, 0x61, + 0x6b, 0x61, 0x62, 0x6c, 0x65, 0x00, 0x00, 0x05, 0x47, 0x72, 0x6f, 0x75, + 0x70, 0x00, 0x00, 0x0a, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x51, 0x75, 0x65, + 0x75, 0x65, 0x00, 0x00, 0x0a, 0x53, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x4c, + 0x69, 0x6e, 0x65, 0x00, 0x00, 0x00, 0x00, 0x90, 0x00, 0x07, 0x00, 0x0c, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x39, 0x00, 0x80, 0x00, + 0x26, 0x00, 0x0c, 0x26, 0x00, 0x0c, 0x26, 0x00, 0x0c, 0x26, 0x00, 0x0c, + 0x26, 0x00, 0x13, 0x5c, 0x01, 0x00, 0x03, 0x02, 0x4f, 0x5c, 0x03, 0x01, + 0x62, 0x08, 0x00, 0x31, 0x07, 0x00, 0x00, 0x01, 0x04, 0x07, 0x1d, 0x07, + 0x01, 0x01, 0x08, 0x01, 0x01, 0x09, 0x02, 0x01, 0x0a, 0x03, 0x01, 0x0b, + 0x04, 0x34, 0x07, 0x02, 0x03, 0x01, 0x06, 0x07, 0x01, 0x08, 0x06, 0x44, + 0x07, 0x20, 0x00, 0x36, 0x07, 0x01, 0x01, 0x07, 0x06, 0x33, 0x07, 0x03, + 0x3d, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0a, + 0x00, 0x00, 0x04, 0x00, 0x06, 0x6c, 0x61, 0x6d, 0x62, 0x64, 0x61, 0x00, + 0x00, 0x0b, 0x50, 0x72, 0x65, 0x74, 0x74, 0x79, 0x50, 0x72, 0x69, 0x6e, + 0x74, 0x00, 0x00, 0x03, 0x6e, 0x65, 0x77, 0x00, 0x00, 0x05, 0x66, 0x6c, + 0x75, 0x73, 0x68, 0x00, 0x00, 0x00, 0x00, 0x27, 0x00, 0x03, 0x00, 0x06, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x39, 0x04, 0x00, 0x00, + 0x5c, 0x03, 0x00, 0x01, 0x04, 0x01, 0x4b, 0x03, 0x3d, 0x03, 0x00, 0x01, + 0x00, 0x00, 0x01, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, + 0x07, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x39, + 0x00, 0x80, 0x00, 0x26, 0x00, 0x0c, 0x26, 0x00, 0x0c, 0x26, 0x00, 0x0b, + 0x26, 0x00, 0x0a, 0x26, 0x00, 0x09, 0x5c, 0x01, 0x00, 0x11, 0x02, 0x11, + 0x03, 0x11, 0x04, 0x1d, 0x07, 0x00, 0x01, 0x08, 0x01, 0x32, 0x07, 0x01, + 0x01, 0x01, 0x06, 0x07, 0x01, 0x08, 0x06, 0x44, 0x07, 0x20, 0x00, 0x36, + 0x07, 0x01, 0x3d, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x0a, 0x53, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x4c, 0x69, 0x6e, 0x65, + 0x00, 0x00, 0x03, 0x6e, 0x65, 0x77, 0x00, 0x00, 0x00, 0x01, 0x2f, 0x00, + 0x07, 0x00, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6f, 0x39, + 0x00, 0x60, 0x01, 0x26, 0x00, 0x09, 0x26, 0x00, 0x09, 0x26, 0x00, 0x09, + 0x26, 0x00, 0x09, 0x5c, 0x01, 0x00, 0x03, 0x02, 0x4f, 0x5c, 0x03, 0x01, + 0x01, 0x05, 0x04, 0x1a, 0x01, 0x00, 0x1a, 0x02, 0x01, 0x1a, 0x03, 0x02, + 0x01, 0x07, 0x05, 0x27, 0x07, 0x00, 0x07, 0x62, 0x08, 0x00, 0x31, 0x07, + 0x03, 0x00, 0x1a, 0x07, 0x04, 0x06, 0x07, 0x1a, 0x07, 0x05, 0x06, 0x07, + 0x1a, 0x07, 0x06, 0x52, 0x07, 0x00, 0x1a, 0x07, 0x07, 0x1d, 0x07, 0x08, + 0x06, 0x08, 0x32, 0x07, 0x09, 0x01, 0x01, 0x06, 0x07, 0x01, 0x07, 0x06, + 0x52, 0x07, 0x01, 0x1a, 0x07, 0x0a, 0x1d, 0x07, 0x0b, 0x01, 0x08, 0x06, + 0x32, 0x07, 0x09, 0x01, 0x1a, 0x07, 0x0c, 0x06, 0x07, 0x1a, 0x07, 0x0d, + 0x3d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0a, + 0x00, 0x00, 0x0e, 0x00, 0x07, 0x40, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, + 0x00, 0x00, 0x09, 0x40, 0x6d, 0x61, 0x78, 0x77, 0x69, 0x64, 0x74, 0x68, + 0x00, 0x00, 0x08, 0x40, 0x6e, 0x65, 0x77, 0x6c, 0x69, 0x6e, 0x65, 0x00, + 0x00, 0x06, 0x6c, 0x61, 0x6d, 0x62, 0x64, 0x61, 0x00, 0x00, 0x09, 0x40, + 0x67, 0x65, 0x6e, 0x73, 0x70, 0x61, 0x63, 0x65, 0x00, 0x00, 0x0d, 0x40, + 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x77, 0x69, 0x64, 0x74, 0x68, + 0x00, 0x00, 0x0d, 0x40, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x5f, 0x77, + 0x69, 0x64, 0x74, 0x68, 0x00, 0x00, 0x07, 0x40, 0x62, 0x75, 0x66, 0x66, + 0x65, 0x72, 0x00, 0x00, 0x05, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x00, 0x00, + 0x03, 0x6e, 0x65, 0x77, 0x00, 0x00, 0x0c, 0x40, 0x67, 0x72, 0x6f, 0x75, + 0x70, 0x5f, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x00, 0x00, 0x0a, 0x47, 0x72, + 0x6f, 0x75, 0x70, 0x51, 0x75, 0x65, 0x75, 0x65, 0x00, 0x00, 0x0c, 0x40, + 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x71, 0x75, 0x65, 0x75, 0x65, 0x00, + 0x00, 0x07, 0x40, 0x69, 0x6e, 0x64, 0x65, 0x6e, 0x74, 0x00, 0x00, 0x00, + 0x00, 0x27, 0x00, 0x03, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0e, 0x39, 0x04, 0x00, 0x00, 0x5c, 0x03, 0x00, 0x01, 0x04, 0x01, + 0x4b, 0x03, 0x3d, 0x03, 0x00, 0x01, 0x00, 0x00, 0x01, 0x20, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0c, 0x39, 0x00, 0x00, 0x00, 0x19, 0x02, 0x00, + 0x33, 0x02, 0x01, 0x3d, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x0c, 0x40, + 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x00, + 0x00, 0x04, 0x6c, 0x61, 0x73, 0x74, 0x00, 0x00, 0x00, 0x01, 0x5d, 0x00, + 0x05, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xac, 0x39, + 0x00, 0x00, 0x00, 0x19, 0x05, 0x00, 0x19, 0x06, 0x01, 0x19, 0x07, 0x02, + 0x45, 0x06, 0x4e, 0x05, 0x28, 0x05, 0x00, 0x96, 0x00, 0x19, 0x05, 0x03, + 0x33, 0x05, 0x04, 0x01, 0x02, 0x05, 0x27, 0x05, 0x00, 0x04, 0x11, 0x05, + 0x3e, 0x05, 0x01, 0x05, 0x02, 0x33, 0x05, 0x05, 0x33, 0x05, 0x06, 0x27, + 0x05, 0x00, 0x2b, 0x00, 0x19, 0x05, 0x07, 0x33, 0x05, 0x08, 0x01, 0x03, + 0x05, 0x01, 0x05, 0x03, 0x19, 0x06, 0x09, 0x19, 0x07, 0x01, 0x32, 0x05, + 0x0a, 0x02, 0x1a, 0x05, 0x01, 0x19, 0x05, 0x02, 0x01, 0x06, 0x03, 0x33, + 0x06, 0x0b, 0x47, 0x05, 0x1a, 0x05, 0x02, 0x26, 0xff, 0xc8, 0x19, 0x05, + 0x07, 0x33, 0x05, 0x06, 0x33, 0x05, 0x0c, 0x28, 0x05, 0x00, 0x0d, 0x1d, + 0x05, 0x0d, 0x19, 0x06, 0x07, 0x33, 0x06, 0x0e, 0x32, 0x05, 0x0f, 0x01, + 0x28, 0x05, 0x00, 0x2b, 0x00, 0x19, 0x05, 0x07, 0x33, 0x05, 0x08, 0x01, + 0x04, 0x05, 0x01, 0x05, 0x04, 0x19, 0x06, 0x09, 0x19, 0x07, 0x01, 0x32, + 0x05, 0x0a, 0x02, 0x1a, 0x05, 0x01, 0x19, 0x05, 0x02, 0x01, 0x06, 0x04, + 0x33, 0x06, 0x0b, 0x47, 0x05, 0x1a, 0x05, 0x02, 0x26, 0xff, 0xb7, 0x26, + 0xff, 0x59, 0x40, 0x00, 0x00, 0x00, 0x10, 0x00, 0x09, 0x40, 0x6d, 0x61, + 0x78, 0x77, 0x69, 0x64, 0x74, 0x68, 0x00, 0x00, 0x0d, 0x40, 0x6f, 0x75, + 0x74, 0x70, 0x75, 0x74, 0x5f, 0x77, 0x69, 0x64, 0x74, 0x68, 0x00, 0x00, + 0x0d, 0x40, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x5f, 0x77, 0x69, 0x64, + 0x74, 0x68, 0x00, 0x00, 0x0c, 0x40, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, + 0x71, 0x75, 0x65, 0x75, 0x65, 0x00, 0x00, 0x03, 0x64, 0x65, 0x71, 0x00, + 0x00, 0x0a, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x61, 0x62, 0x6c, 0x65, 0x73, + 0x00, 0x00, 0x06, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x3f, 0x00, 0x00, 0x07, + 0x40, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x00, 0x00, 0x05, 0x73, 0x68, + 0x69, 0x66, 0x74, 0x00, 0x00, 0x07, 0x40, 0x6f, 0x75, 0x74, 0x70, 0x75, + 0x74, 0x00, 0x00, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x00, 0x00, + 0x05, 0x77, 0x69, 0x64, 0x74, 0x68, 0x00, 0x00, 0x01, 0x21, 0x00, 0x00, + 0x04, 0x54, 0x65, 0x78, 0x74, 0x00, 0x00, 0x05, 0x66, 0x69, 0x72, 0x73, + 0x74, 0x00, 0x00, 0x03, 0x3d, 0x3d, 0x3d, 0x00, 0x00, 0x00, 0x01, 0x12, + 0x00, 0x05, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, + 0x39, 0x04, 0x20, 0x00, 0x26, 0x00, 0x03, 0x26, 0x00, 0x09, 0x01, 0x05, + 0x01, 0x33, 0x05, 0x00, 0x01, 0x02, 0x05, 0x19, 0x05, 0x01, 0x33, 0x05, + 0x02, 0x28, 0x05, 0x00, 0x18, 0x19, 0x05, 0x03, 0x01, 0x06, 0x01, 0x32, + 0x05, 0x04, 0x01, 0x19, 0x05, 0x05, 0x01, 0x06, 0x02, 0x45, 0x05, 0x1a, + 0x05, 0x05, 0x26, 0x00, 0x45, 0x19, 0x05, 0x01, 0x33, 0x05, 0x06, 0x01, + 0x04, 0x05, 0x1d, 0x05, 0x07, 0x01, 0x06, 0x04, 0x32, 0x05, 0x08, 0x01, + 0x27, 0x05, 0x00, 0x13, 0x1d, 0x05, 0x07, 0x33, 0x05, 0x09, 0x01, 0x04, + 0x05, 0x19, 0x05, 0x01, 0x01, 0x06, 0x04, 0x32, 0x05, 0x04, 0x01, 0x01, + 0x05, 0x04, 0x01, 0x06, 0x01, 0x01, 0x07, 0x02, 0x32, 0x05, 0x0a, 0x02, + 0x19, 0x05, 0x0b, 0x01, 0x06, 0x02, 0x45, 0x05, 0x1a, 0x05, 0x0b, 0x30, + 0x05, 0x0c, 0x3d, 0x05, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x06, 0x6c, 0x65, + 0x6e, 0x67, 0x74, 0x68, 0x00, 0x00, 0x07, 0x40, 0x62, 0x75, 0x66, 0x66, + 0x65, 0x72, 0x00, 0x00, 0x06, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x3f, 0x00, + 0x00, 0x07, 0x40, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x00, 0x00, 0x02, + 0x3c, 0x3c, 0x00, 0x00, 0x0d, 0x40, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, + 0x5f, 0x77, 0x69, 0x64, 0x74, 0x68, 0x00, 0x00, 0x04, 0x6c, 0x61, 0x73, + 0x74, 0x00, 0x00, 0x04, 0x54, 0x65, 0x78, 0x74, 0x00, 0x00, 0x03, 0x3d, + 0x3d, 0x3d, 0x00, 0x00, 0x03, 0x6e, 0x65, 0x77, 0x00, 0x00, 0x03, 0x61, + 0x64, 0x64, 0x00, 0x00, 0x0d, 0x40, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, + 0x5f, 0x77, 0x69, 0x64, 0x74, 0x68, 0x00, 0x00, 0x14, 0x62, 0x72, 0x65, + 0x61, 0x6b, 0x5f, 0x6f, 0x75, 0x74, 0x6d, 0x6f, 0x73, 0x74, 0x5f, 0x67, + 0x72, 0x6f, 0x75, 0x70, 0x73, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x04, + 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x39, 0x00, + 0x40, 0x00, 0x26, 0x00, 0x06, 0x26, 0x00, 0x06, 0x26, 0x00, 0x0c, 0x5c, + 0x01, 0x00, 0x01, 0x04, 0x01, 0x33, 0x04, 0x00, 0x01, 0x02, 0x04, 0x62, + 0x05, 0x00, 0x31, 0x04, 0x01, 0x00, 0x3d, 0x04, 0x00, 0x01, 0x00, 0x00, + 0x01, 0x20, 0x00, 0x00, 0x02, 0x00, 0x06, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x00, 0x00, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x32, 0x00, 0x02, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x12, 0x39, 0x00, 0x00, 0x00, 0x21, 0x03, 0x01, 0x00, 0x21, 0x04, + 0x02, 0x00, 0x2f, 0x02, 0x00, 0x02, 0x3d, 0x02, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x09, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x61, 0x62, 0x6c, 0x65, 0x00, + 0x00, 0x00, 0x01, 0x51, 0x00, 0x05, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x7e, 0x39, 0x00, 0x40, 0x00, 0x26, 0x00, 0x06, 0x26, + 0x00, 0x06, 0x26, 0x00, 0x0c, 0x5c, 0x01, 0x00, 0x01, 0x05, 0x01, 0x33, + 0x05, 0x00, 0x01, 0x02, 0x05, 0x19, 0x05, 0x01, 0x33, 0x05, 0x02, 0x01, + 0x04, 0x05, 0x01, 0x05, 0x04, 0x33, 0x05, 0x03, 0x28, 0x05, 0x00, 0x2c, + 0x30, 0x05, 0x04, 0x19, 0x05, 0x05, 0x19, 0x06, 0x06, 0x32, 0x05, 0x07, + 0x01, 0x19, 0x05, 0x05, 0x19, 0x06, 0x08, 0x19, 0x07, 0x09, 0x32, 0x06, + 0x0a, 0x01, 0x32, 0x05, 0x07, 0x01, 0x19, 0x05, 0x09, 0x1a, 0x05, 0x0b, + 0x06, 0x05, 0x1a, 0x05, 0x0c, 0x26, 0x00, 0x24, 0x19, 0x05, 0x0d, 0x1d, + 0x06, 0x0e, 0x01, 0x07, 0x01, 0x01, 0x08, 0x02, 0x12, 0x09, 0x32, 0x06, + 0x0f, 0x03, 0x32, 0x05, 0x07, 0x01, 0x19, 0x05, 0x0c, 0x01, 0x06, 0x02, + 0x45, 0x05, 0x1a, 0x05, 0x0c, 0x30, 0x05, 0x10, 0x3d, 0x05, 0x00, 0x01, + 0x00, 0x00, 0x01, 0x20, 0x00, 0x00, 0x11, 0x00, 0x06, 0x6c, 0x65, 0x6e, + 0x67, 0x74, 0x68, 0x00, 0x00, 0x0c, 0x40, 0x67, 0x72, 0x6f, 0x75, 0x70, + 0x5f, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x00, 0x00, 0x04, 0x6c, 0x61, 0x73, + 0x74, 0x00, 0x00, 0x06, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x3f, 0x00, 0x00, + 0x05, 0x66, 0x6c, 0x75, 0x73, 0x68, 0x00, 0x00, 0x07, 0x40, 0x6f, 0x75, + 0x74, 0x70, 0x75, 0x74, 0x00, 0x00, 0x08, 0x40, 0x6e, 0x65, 0x77, 0x6c, + 0x69, 0x6e, 0x65, 0x00, 0x00, 0x02, 0x3c, 0x3c, 0x00, 0x00, 0x09, 0x40, + 0x67, 0x65, 0x6e, 0x73, 0x70, 0x61, 0x63, 0x65, 0x00, 0x00, 0x07, 0x40, + 0x69, 0x6e, 0x64, 0x65, 0x6e, 0x74, 0x00, 0x00, 0x04, 0x63, 0x61, 0x6c, + 0x6c, 0x00, 0x00, 0x0d, 0x40, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, + 0x77, 0x69, 0x64, 0x74, 0x68, 0x00, 0x00, 0x0d, 0x40, 0x62, 0x75, 0x66, + 0x66, 0x65, 0x72, 0x5f, 0x77, 0x69, 0x64, 0x74, 0x68, 0x00, 0x00, 0x07, + 0x40, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x00, 0x00, 0x09, 0x42, 0x72, + 0x65, 0x61, 0x6b, 0x61, 0x62, 0x6c, 0x65, 0x00, 0x00, 0x03, 0x6e, 0x65, + 0x77, 0x00, 0x00, 0x14, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x5f, 0x6f, 0x75, + 0x74, 0x6d, 0x6f, 0x73, 0x74, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, + 0x00, 0x00, 0x00, 0x00, 0x81, 0x00, 0x07, 0x00, 0x0b, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x4d, 0x39, 0x00, 0xa0, 0x00, 0x26, 0x00, 0x0f, + 0x26, 0x00, 0x0e, 0x26, 0x00, 0x0e, 0x26, 0x00, 0x0e, 0x26, 0x00, 0x14, + 0x26, 0x00, 0x1a, 0x06, 0x01, 0x5c, 0x02, 0x00, 0x5c, 0x03, 0x00, 0x01, + 0x07, 0x02, 0x33, 0x07, 0x00, 0x01, 0x04, 0x07, 0x01, 0x07, 0x03, 0x33, + 0x07, 0x00, 0x01, 0x05, 0x07, 0x01, 0x08, 0x02, 0x01, 0x09, 0x04, 0x2f, + 0x07, 0x01, 0x02, 0x62, 0x08, 0x00, 0x31, 0x07, 0x02, 0x00, 0x01, 0x08, + 0x03, 0x01, 0x09, 0x05, 0x2f, 0x07, 0x01, 0x02, 0x3d, 0x07, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x06, 0x6c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x00, 0x00, 0x04, 0x74, 0x65, 0x78, 0x74, 0x00, 0x00, 0x09, + 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x73, 0x75, 0x62, 0x00, 0x00, 0x00, + 0x00, 0x2c, 0x00, 0x02, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x11, 0x39, 0x00, 0x00, 0x00, 0x21, 0x03, 0x01, 0x00, 0x62, 0x04, + 0x00, 0x31, 0x02, 0x00, 0x01, 0x3d, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x04, 0x6e, 0x65, 0x73, 0x74, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x02, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x39, 0x00, + 0x00, 0x00, 0x44, 0x02, 0x28, 0x02, 0x36, 0x02, 0x00, 0x3d, 0x02, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0x00, 0x03, 0x00, 0x09, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x58, 0x39, 0x00, 0x00, 0x00, 0x1d, + 0x03, 0x00, 0x19, 0x04, 0x01, 0x33, 0x04, 0x02, 0x33, 0x04, 0x03, 0x46, + 0x04, 0x01, 0x32, 0x03, 0x04, 0x01, 0x01, 0x02, 0x03, 0x19, 0x03, 0x01, + 0x01, 0x04, 0x02, 0x32, 0x03, 0x05, 0x01, 0x19, 0x03, 0x06, 0x01, 0x04, + 0x02, 0x32, 0x03, 0x07, 0x01, 0x44, 0x03, 0x00, 0x00, 0x36, 0x03, 0x00, + 0x2b, 0x05, 0x19, 0x06, 0x01, 0x33, 0x06, 0x08, 0x01, 0x06, 0x02, 0x33, + 0x06, 0x09, 0x33, 0x06, 0x0a, 0x28, 0x06, 0x00, 0x0a, 0x19, 0x06, 0x06, + 0x01, 0x07, 0x02, 0x32, 0x06, 0x0b, 0x01, 0x2d, 0x05, 0x3d, 0x03, 0x01, + 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x35, + 0x00, 0x00, 0x00, 0x0c, 0x00, 0x05, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x00, + 0x00, 0x0c, 0x40, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x73, 0x74, 0x61, + 0x63, 0x6b, 0x00, 0x00, 0x04, 0x6c, 0x61, 0x73, 0x74, 0x00, 0x00, 0x05, + 0x64, 0x65, 0x70, 0x74, 0x68, 0x00, 0x00, 0x03, 0x6e, 0x65, 0x77, 0x00, + 0x00, 0x04, 0x70, 0x75, 0x73, 0x68, 0x00, 0x00, 0x0c, 0x40, 0x67, 0x72, + 0x6f, 0x75, 0x70, 0x5f, 0x71, 0x75, 0x65, 0x75, 0x65, 0x00, 0x00, 0x03, + 0x65, 0x6e, 0x71, 0x00, 0x00, 0x03, 0x70, 0x6f, 0x70, 0x00, 0x00, 0x0a, + 0x62, 0x72, 0x65, 0x61, 0x6b, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x00, 0x00, + 0x06, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x3f, 0x00, 0x00, 0x06, 0x64, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x00, 0x00, 0x00, 0x00, 0x52, 0x00, 0x03, 0x00, + 0x09, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x27, 0x39, 0x04, 0x00, + 0x00, 0x19, 0x03, 0x00, 0x01, 0x04, 0x01, 0x45, 0x03, 0x1a, 0x03, 0x00, + 0x44, 0x03, 0x08, 0x00, 0x36, 0x03, 0x00, 0x2b, 0x05, 0x19, 0x06, 0x00, + 0x01, 0x07, 0x01, 0x47, 0x06, 0x1a, 0x06, 0x00, 0x2d, 0x05, 0x3d, 0x03, + 0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, + 0x16, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x40, 0x69, 0x6e, 0x64, 0x65, + 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, 0x58, 0x00, 0x02, 0x00, 0x04, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x39, 0x00, 0x00, 0x00, 0x19, + 0x02, 0x00, 0x62, 0x03, 0x00, 0x34, 0x02, 0x01, 0x00, 0x19, 0x02, 0x00, + 0x33, 0x02, 0x02, 0x06, 0x02, 0x1a, 0x02, 0x03, 0x3d, 0x02, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x07, 0x40, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x00, + 0x00, 0x04, 0x65, 0x61, 0x63, 0x68, 0x00, 0x00, 0x05, 0x63, 0x6c, 0x65, + 0x61, 0x72, 0x00, 0x00, 0x0d, 0x40, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, + 0x5f, 0x77, 0x69, 0x64, 0x74, 0x68, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, + 0x03, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x39, + 0x04, 0x00, 0x00, 0x01, 0x03, 0x01, 0x19, 0x04, 0x00, 0x19, 0x05, 0x01, + 0x32, 0x03, 0x02, 0x02, 0x1a, 0x03, 0x01, 0x3d, 0x03, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x07, 0x40, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x00, 0x00, + 0x0d, 0x40, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x77, 0x69, 0x64, + 0x74, 0x68, 0x00, 0x00, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x00, + 0x00, 0x00, 0x00, 0x5b, 0x00, 0x01, 0x00, 0x04, 0x00, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x15, 0x6b, 0x01, 0x00, 0x00, 0x10, 0x02, 0x01, 0x2f, + 0x01, 0x02, 0x01, 0x6b, 0x01, 0x03, 0x01, 0x6b, 0x01, 0x04, 0x02, 0x3d, + 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x0a, 0x69, 0x6e, 0x69, 0x74, 0x69, + 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x00, 0x00, 0x05, 0x77, 0x69, 0x64, 0x74, + 0x68, 0x00, 0x00, 0x0b, 0x61, 0x74, 0x74, 0x72, 0x5f, 0x72, 0x65, 0x61, + 0x64, 0x65, 0x72, 0x00, 0x00, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, + 0x00, 0x00, 0x03, 0x61, 0x64, 0x64, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, + 0x02, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x39, + 0x00, 0x00, 0x00, 0x52, 0x02, 0x00, 0x1a, 0x02, 0x00, 0x06, 0x02, 0x1a, + 0x02, 0x01, 0x3d, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x05, 0x40, 0x6f, + 0x62, 0x6a, 0x73, 0x00, 0x00, 0x06, 0x40, 0x77, 0x69, 0x64, 0x74, 0x68, + 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x04, 0x00, 0x07, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x39, 0x08, 0x00, 0x00, 0x19, 0x04, 0x00, + 0x62, 0x05, 0x00, 0x34, 0x04, 0x01, 0x00, 0x01, 0x04, 0x02, 0x19, 0x05, + 0x02, 0x45, 0x04, 0x3d, 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x05, 0x40, + 0x6f, 0x62, 0x6a, 0x73, 0x00, 0x00, 0x04, 0x65, 0x61, 0x63, 0x68, 0x00, + 0x00, 0x06, 0x40, 0x77, 0x69, 0x64, 0x74, 0x68, 0x00, 0x00, 0x00, 0x00, + 0x2a, 0x00, 0x03, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x11, 0x39, 0x04, 0x00, 0x00, 0x21, 0x03, 0x01, 0x00, 0x01, 0x04, 0x01, + 0x32, 0x03, 0x00, 0x01, 0x3d, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, + 0x3c, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x45, 0x00, 0x04, 0x00, 0x07, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x39, 0x08, 0x00, 0x00, 0x19, + 0x04, 0x00, 0x01, 0x05, 0x01, 0x32, 0x04, 0x01, 0x01, 0x19, 0x04, 0x02, + 0x01, 0x05, 0x02, 0x45, 0x04, 0x1a, 0x04, 0x02, 0x3d, 0x04, 0x00, 0x00, + 0x00, 0x03, 0x00, 0x05, 0x40, 0x6f, 0x62, 0x6a, 0x73, 0x00, 0x00, 0x02, + 0x3c, 0x3c, 0x00, 0x00, 0x06, 0x40, 0x77, 0x69, 0x64, 0x74, 0x68, 0x00, + 0x00, 0x00, 0x00, 0x6e, 0x00, 0x01, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x1f, 0x6b, 0x01, 0x00, 0x00, 0x10, 0x02, 0x01, 0x2f, + 0x01, 0x02, 0x01, 0x10, 0x02, 0x03, 0x2f, 0x01, 0x02, 0x01, 0x10, 0x02, + 0x04, 0x2f, 0x01, 0x02, 0x01, 0x6b, 0x01, 0x05, 0x01, 0x3d, 0x00, 0x00, + 0x00, 0x00, 0x06, 0x00, 0x0a, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, + 0x69, 0x7a, 0x65, 0x00, 0x00, 0x03, 0x6f, 0x62, 0x6a, 0x00, 0x00, 0x0b, + 0x61, 0x74, 0x74, 0x72, 0x5f, 0x72, 0x65, 0x61, 0x64, 0x65, 0x72, 0x00, + 0x00, 0x05, 0x77, 0x69, 0x64, 0x74, 0x68, 0x00, 0x00, 0x06, 0x69, 0x6e, + 0x64, 0x65, 0x6e, 0x74, 0x00, 0x00, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, + 0x74, 0x00, 0x00, 0x00, 0x00, 0x97, 0x00, 0x05, 0x00, 0x08, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x39, 0x0c, 0x00, 0x00, 0x1a, 0x01, + 0x00, 0x1a, 0x02, 0x01, 0x1a, 0x03, 0x02, 0x01, 0x05, 0x03, 0x33, 0x05, + 0x03, 0x1a, 0x05, 0x04, 0x01, 0x05, 0x03, 0x33, 0x05, 0x05, 0x1a, 0x05, + 0x06, 0x19, 0x05, 0x06, 0x33, 0x05, 0x07, 0x12, 0x06, 0x32, 0x05, 0x08, + 0x01, 0x3d, 0x05, 0x00, 0x00, 0x00, 0x09, 0x00, 0x04, 0x40, 0x6f, 0x62, + 0x6a, 0x00, 0x00, 0x06, 0x40, 0x77, 0x69, 0x64, 0x74, 0x68, 0x00, 0x00, + 0x03, 0x40, 0x70, 0x70, 0x00, 0x00, 0x06, 0x69, 0x6e, 0x64, 0x65, 0x6e, + 0x74, 0x00, 0x00, 0x07, 0x40, 0x69, 0x6e, 0x64, 0x65, 0x6e, 0x74, 0x00, + 0x00, 0x0d, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x67, 0x72, + 0x6f, 0x75, 0x70, 0x00, 0x00, 0x06, 0x40, 0x67, 0x72, 0x6f, 0x75, 0x70, + 0x00, 0x00, 0x0a, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x61, 0x62, 0x6c, 0x65, + 0x73, 0x00, 0x00, 0x04, 0x70, 0x75, 0x73, 0x68, 0x00, 0x00, 0x00, 0x01, + 0x08, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x6c, 0x39, 0x08, 0x00, 0x00, 0x19, 0x04, 0x00, 0x33, 0x04, 0x01, 0x33, + 0x04, 0x02, 0x19, 0x04, 0x00, 0x33, 0x04, 0x03, 0x28, 0x04, 0x00, 0x27, + 0x01, 0x04, 0x01, 0x19, 0x05, 0x04, 0x33, 0x05, 0x05, 0x32, 0x04, 0x06, + 0x01, 0x01, 0x04, 0x01, 0x19, 0x05, 0x04, 0x33, 0x05, 0x07, 0x19, 0x06, + 0x08, 0x32, 0x05, 0x09, 0x01, 0x32, 0x04, 0x06, 0x01, 0x19, 0x04, 0x08, + 0x26, 0x00, 0x2c, 0x19, 0x04, 0x00, 0x33, 0x04, 0x01, 0x33, 0x04, 0x0a, + 0x28, 0x04, 0x00, 0x0d, 0x19, 0x04, 0x04, 0x33, 0x04, 0x0b, 0x19, 0x05, + 0x00, 0x32, 0x04, 0x0c, 0x01, 0x01, 0x04, 0x01, 0x19, 0x05, 0x0d, 0x32, + 0x04, 0x06, 0x01, 0x01, 0x04, 0x02, 0x19, 0x05, 0x0e, 0x45, 0x04, 0x3d, + 0x04, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x06, 0x40, 0x67, 0x72, 0x6f, 0x75, + 0x70, 0x00, 0x00, 0x0a, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x61, 0x62, 0x6c, + 0x65, 0x73, 0x00, 0x00, 0x05, 0x73, 0x68, 0x69, 0x66, 0x74, 0x00, 0x00, + 0x06, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x3f, 0x00, 0x00, 0x03, 0x40, 0x70, + 0x70, 0x00, 0x00, 0x07, 0x6e, 0x65, 0x77, 0x6c, 0x69, 0x6e, 0x65, 0x00, + 0x00, 0x02, 0x3c, 0x3c, 0x00, 0x00, 0x08, 0x67, 0x65, 0x6e, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x00, 0x00, 0x07, 0x40, 0x69, 0x6e, 0x64, 0x65, 0x6e, + 0x74, 0x00, 0x00, 0x04, 0x63, 0x61, 0x6c, 0x6c, 0x00, 0x00, 0x06, 0x65, + 0x6d, 0x70, 0x74, 0x79, 0x3f, 0x00, 0x00, 0x0b, 0x67, 0x72, 0x6f, 0x75, + 0x70, 0x5f, 0x71, 0x75, 0x65, 0x75, 0x65, 0x00, 0x00, 0x06, 0x64, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x00, 0x00, 0x04, 0x40, 0x6f, 0x62, 0x6a, 0x00, + 0x00, 0x06, 0x40, 0x77, 0x69, 0x64, 0x74, 0x68, 0x00, 0x00, 0x00, 0x00, + 0x7e, 0x00, 0x01, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x20, 0x6b, 0x01, 0x00, 0x00, 0x10, 0x02, 0x01, 0x2f, 0x01, 0x02, 0x01, + 0x10, 0x02, 0x03, 0x2f, 0x01, 0x02, 0x01, 0x6b, 0x01, 0x04, 0x01, 0x6b, + 0x01, 0x05, 0x02, 0x6b, 0x01, 0x06, 0x03, 0x3d, 0x00, 0x00, 0x00, 0x00, + 0x07, 0x00, 0x0a, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, + 0x65, 0x00, 0x00, 0x05, 0x64, 0x65, 0x70, 0x74, 0x68, 0x00, 0x00, 0x0b, + 0x61, 0x74, 0x74, 0x72, 0x5f, 0x72, 0x65, 0x61, 0x64, 0x65, 0x72, 0x00, + 0x00, 0x0a, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x61, 0x62, 0x6c, 0x65, 0x73, + 0x00, 0x00, 0x05, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x00, 0x00, 0x06, 0x62, + 0x72, 0x65, 0x61, 0x6b, 0x3f, 0x00, 0x00, 0x06, 0x66, 0x69, 0x72, 0x73, + 0x74, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x03, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x39, 0x04, 0x00, 0x00, 0x1a, + 0x01, 0x00, 0x52, 0x03, 0x00, 0x1a, 0x03, 0x01, 0x14, 0x03, 0x1a, 0x03, + 0x02, 0x3d, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x06, 0x40, 0x64, 0x65, + 0x70, 0x74, 0x68, 0x00, 0x00, 0x0b, 0x40, 0x62, 0x72, 0x65, 0x61, 0x6b, + 0x61, 0x62, 0x6c, 0x65, 0x73, 0x00, 0x00, 0x06, 0x40, 0x62, 0x72, 0x65, + 0x61, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x02, 0x00, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x39, 0x00, 0x00, 0x00, 0x13, + 0x02, 0x1a, 0x02, 0x00, 0x3d, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x06, + 0x40, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x26, 0x00, + 0x02, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x39, + 0x00, 0x00, 0x00, 0x19, 0x02, 0x00, 0x3d, 0x02, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x06, 0x40, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x00, 0x00, 0x00, 0x00, + 0x45, 0x00, 0x02, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1d, 0x39, 0x00, 0x00, 0x00, 0x19, 0x03, 0x00, 0x2f, 0x02, 0x01, 0x01, + 0x28, 0x02, 0x00, 0x05, 0x14, 0x02, 0x26, 0x00, 0x07, 0x14, 0x02, 0x1a, + 0x02, 0x00, 0x13, 0x02, 0x3d, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x06, + 0x40, 0x66, 0x69, 0x72, 0x73, 0x74, 0x00, 0x00, 0x08, 0x64, 0x65, 0x66, + 0x69, 0x6e, 0x65, 0x64, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x01, + 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x6b, 0x01, + 0x00, 0x00, 0x6b, 0x01, 0x01, 0x01, 0x6b, 0x01, 0x02, 0x02, 0x6b, 0x01, + 0x03, 0x03, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x0a, 0x69, 0x6e, + 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x00, 0x00, 0x03, 0x65, + 0x6e, 0x71, 0x00, 0x00, 0x03, 0x64, 0x65, 0x71, 0x00, 0x00, 0x06, 0x64, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x00, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x03, + 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x39, 0x00, + 0x10, 0x00, 0x52, 0x03, 0x00, 0x1a, 0x03, 0x00, 0x01, 0x03, 0x01, 0x62, + 0x04, 0x00, 0x34, 0x03, 0x01, 0x00, 0x3d, 0x03, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x06, 0x40, 0x71, 0x75, 0x65, 0x75, 0x65, 0x00, 0x00, 0x04, 0x65, + 0x61, 0x63, 0x68, 0x00, 0x00, 0x00, 0x00, 0x27, 0x00, 0x03, 0x00, 0x06, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x39, 0x04, 0x00, 0x00, + 0x01, 0x04, 0x01, 0x2f, 0x03, 0x00, 0x01, 0x3d, 0x03, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x03, 0x65, 0x6e, 0x71, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x00, + 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3b, 0x39, + 0x04, 0x00, 0x00, 0x01, 0x04, 0x01, 0x33, 0x04, 0x00, 0x01, 0x03, 0x04, + 0x01, 0x04, 0x03, 0x19, 0x05, 0x01, 0x33, 0x05, 0x02, 0x4e, 0x04, 0x27, + 0x04, 0x00, 0x0e, 0x00, 0x19, 0x04, 0x01, 0x52, 0x05, 0x00, 0x32, 0x04, + 0x03, 0x01, 0x26, 0xff, 0xe3, 0x19, 0x04, 0x01, 0x01, 0x05, 0x03, 0x23, + 0x04, 0x01, 0x05, 0x01, 0x32, 0x04, 0x03, 0x01, 0x3d, 0x04, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x05, 0x64, 0x65, 0x70, 0x74, 0x68, 0x00, 0x00, 0x06, + 0x40, 0x71, 0x75, 0x65, 0x75, 0x65, 0x00, 0x00, 0x06, 0x6c, 0x65, 0x6e, + 0x67, 0x74, 0x68, 0x00, 0x00, 0x02, 0x3c, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x00, 0x02, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0f, 0x39, 0x00, 0x00, 0x00, 0x19, 0x02, 0x00, 0x62, 0x03, 0x00, 0x34, + 0x02, 0x01, 0x00, 0x40, 0x00, 0x00, 0x00, 0x02, 0x00, 0x06, 0x40, 0x71, + 0x75, 0x65, 0x75, 0x65, 0x00, 0x00, 0x04, 0x65, 0x61, 0x63, 0x68, 0x00, + 0x00, 0x00, 0x00, 0x5d, 0x00, 0x03, 0x00, 0x06, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x28, 0x39, 0x04, 0x00, 0x00, 0x01, 0x03, 0x01, 0x33, + 0x03, 0x00, 0x48, 0x03, 0x01, 0x06, 0x04, 0x62, 0x05, 0x00, 0x34, 0x03, + 0x01, 0x01, 0x01, 0x03, 0x01, 0x62, 0x04, 0x01, 0x34, 0x03, 0x02, 0x00, + 0x01, 0x03, 0x01, 0x33, 0x03, 0x03, 0x3d, 0x03, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x06, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x00, 0x00, 0x06, 0x64, + 0x6f, 0x77, 0x6e, 0x74, 0x6f, 0x00, 0x00, 0x04, 0x65, 0x61, 0x63, 0x68, + 0x00, 0x00, 0x05, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x00, 0x00, 0x00, 0x00, + 0x7c, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3d, 0x39, 0x04, 0x00, 0x00, 0x21, 0x04, 0x01, 0x00, 0x01, 0x05, 0x01, + 0x23, 0x04, 0x33, 0x04, 0x00, 0x33, 0x04, 0x01, 0x28, 0x04, 0x00, 0x05, + 0x11, 0x04, 0x26, 0x00, 0x1f, 0x21, 0x04, 0x01, 0x00, 0x01, 0x05, 0x01, + 0x07, 0x06, 0x32, 0x04, 0x02, 0x02, 0x22, 0x04, 0x01, 0x00, 0x33, 0x04, + 0x03, 0x01, 0x03, 0x04, 0x01, 0x04, 0x03, 0x33, 0x04, 0x04, 0x3e, 0x03, + 0x3d, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x0a, 0x62, 0x72, 0x65, 0x61, + 0x6b, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x00, 0x00, 0x06, 0x65, 0x6d, 0x70, + 0x74, 0x79, 0x3f, 0x00, 0x00, 0x02, 0x5b, 0x5d, 0x00, 0x00, 0x05, 0x66, + 0x69, 0x72, 0x73, 0x74, 0x00, 0x00, 0x05, 0x62, 0x72, 0x65, 0x61, 0x6b, + 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x03, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0c, 0x39, 0x04, 0x00, 0x00, 0x01, 0x03, 0x01, + 0x33, 0x03, 0x00, 0x3d, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x05, 0x62, + 0x72, 0x65, 0x61, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x46, 0x00, 0x03, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x39, 0x04, 0x00, + 0x00, 0x19, 0x03, 0x00, 0x01, 0x04, 0x01, 0x33, 0x04, 0x01, 0x23, 0x03, + 0x01, 0x04, 0x01, 0x32, 0x03, 0x02, 0x01, 0x3d, 0x03, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x06, 0x40, 0x71, 0x75, 0x65, 0x75, 0x65, 0x00, 0x00, 0x05, + 0x64, 0x65, 0x70, 0x74, 0x68, 0x00, 0x00, 0x06, 0x64, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x00, 0x00, 0x00, 0x00, 0x72, 0x00, 0x01, 0x00, 0x01, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x6b, 0x01, 0x00, 0x00, 0x6b, + 0x01, 0x01, 0x01, 0x6b, 0x01, 0x02, 0x02, 0x6b, 0x01, 0x03, 0x03, 0x6b, + 0x01, 0x04, 0x04, 0x6b, 0x01, 0x05, 0x05, 0x6b, 0x01, 0x06, 0x06, 0x3d, + 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x0a, 0x69, 0x6e, 0x69, 0x74, 0x69, + 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x00, 0x00, 0x04, 0x74, 0x65, 0x78, 0x74, + 0x00, 0x00, 0x09, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x61, 0x62, 0x6c, 0x65, + 0x00, 0x00, 0x04, 0x6e, 0x65, 0x73, 0x74, 0x00, 0x00, 0x05, 0x67, 0x72, + 0x6f, 0x75, 0x70, 0x00, 0x00, 0x05, 0x66, 0x6c, 0x75, 0x73, 0x68, 0x00, + 0x00, 0x06, 0x66, 0x69, 0x72, 0x73, 0x74, 0x3f, 0x00, 0x00, 0x00, 0x00, + 0x45, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1e, 0x39, 0x04, 0x40, 0x00, 0x26, 0x00, 0x06, 0x26, 0x00, 0x05, 0x26, + 0x00, 0x04, 0x11, 0x02, 0x11, 0x03, 0x1a, 0x01, 0x00, 0x13, 0x05, 0x52, + 0x05, 0x01, 0x1a, 0x05, 0x01, 0x3d, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x07, 0x40, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x00, 0x00, 0x06, 0x40, + 0x66, 0x69, 0x72, 0x73, 0x74, 0x00, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, + 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x39, 0x04, + 0x20, 0x00, 0x26, 0x00, 0x03, 0x26, 0x00, 0x02, 0x11, 0x02, 0x19, 0x04, + 0x00, 0x01, 0x05, 0x01, 0x32, 0x04, 0x01, 0x01, 0x3d, 0x04, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x07, 0x40, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x00, + 0x00, 0x02, 0x3c, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x46, 0x00, 0x04, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x39, 0x00, 0x40, + 0x00, 0x26, 0x00, 0x06, 0x26, 0x00, 0x06, 0x26, 0x00, 0x05, 0x5c, 0x01, + 0x00, 0x11, 0x02, 0x19, 0x04, 0x00, 0x01, 0x05, 0x01, 0x32, 0x04, 0x01, + 0x01, 0x3d, 0x04, 0x00, 0x01, 0x00, 0x00, 0x01, 0x20, 0x00, 0x00, 0x02, + 0x00, 0x07, 0x40, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x00, 0x00, 0x02, + 0x3c, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x03, 0x00, 0x05, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x39, 0x04, 0x00, 0x00, 0x44, + 0x03, 0x08, 0x00, 0x36, 0x03, 0x00, 0x3d, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x8b, 0x00, 0x07, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x4e, 0x39, 0x00, 0xa0, 0x00, 0x26, 0x00, 0x0f, 0x26, + 0x00, 0x0e, 0x26, 0x00, 0x0e, 0x26, 0x00, 0x0e, 0x26, 0x00, 0x0d, 0x26, + 0x00, 0x0c, 0x11, 0x01, 0x5c, 0x02, 0x00, 0x5c, 0x03, 0x00, 0x11, 0x04, + 0x11, 0x05, 0x19, 0x07, 0x00, 0x13, 0x08, 0x32, 0x07, 0x01, 0x01, 0x19, + 0x07, 0x02, 0x01, 0x08, 0x02, 0x32, 0x07, 0x03, 0x01, 0x44, 0x07, 0x28, + 0x00, 0x36, 0x07, 0x00, 0x19, 0x07, 0x02, 0x01, 0x08, 0x03, 0x32, 0x07, + 0x03, 0x01, 0x19, 0x07, 0x00, 0x33, 0x07, 0x04, 0x3d, 0x07, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x06, 0x40, 0x66, 0x69, 0x72, + 0x73, 0x74, 0x00, 0x00, 0x04, 0x70, 0x75, 0x73, 0x68, 0x00, 0x00, 0x07, + 0x40, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x00, 0x00, 0x02, 0x3c, 0x3c, + 0x00, 0x00, 0x03, 0x70, 0x6f, 0x70, 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, + 0x02, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x39, + 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, + 0x00, 0x03, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, + 0x39, 0x00, 0x00, 0x00, 0x19, 0x03, 0x00, 0x05, 0x04, 0x23, 0x03, 0x01, + 0x02, 0x03, 0x19, 0x03, 0x00, 0x05, 0x04, 0x14, 0x05, 0x25, 0x03, 0x3d, + 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x06, 0x40, 0x66, 0x69, 0x72, 0x73, + 0x74, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x01, 0x00, 0x04, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x6b, 0x01, 0x00, 0x00, 0x30, 0x01, + 0x01, 0x6b, 0x01, 0x02, 0x01, 0x10, 0x02, 0x02, 0x2f, 0x01, 0x03, 0x01, + 0x3d, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x0e, 0x70, 0x72, 0x65, 0x74, + 0x74, 0x79, 0x5f, 0x69, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x00, 0x00, + 0x07, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x00, 0x00, 0x02, 0x70, + 0x70, 0x00, 0x00, 0x0f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x5f, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x34, + 0x00, 0x02, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, + 0x39, 0x00, 0x00, 0x00, 0x1d, 0x02, 0x00, 0x12, 0x03, 0x5c, 0x04, 0x00, + 0x32, 0x02, 0x01, 0x02, 0x3d, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x02, 0x50, 0x50, 0x00, 0x00, 0x02, 0x70, 0x70, 0x00, + 0x00, 0x00, 0x00, 0x54, 0x00, 0x03, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x2a, 0x39, 0x00, 0x10, 0x00, 0x01, 0x03, 0x01, 0x62, + 0x04, 0x00, 0x34, 0x03, 0x00, 0x00, 0x01, 0x03, 0x01, 0x33, 0x03, 0x01, + 0x07, 0x04, 0x4f, 0x03, 0x28, 0x03, 0x00, 0x09, 0x01, 0x03, 0x01, 0x33, + 0x03, 0x02, 0x26, 0x00, 0x03, 0x01, 0x03, 0x01, 0x3d, 0x03, 0x00, 0x00, + 0x00, 0x03, 0x00, 0x04, 0x65, 0x61, 0x63, 0x68, 0x00, 0x00, 0x04, 0x73, + 0x69, 0x7a, 0x65, 0x00, 0x00, 0x05, 0x66, 0x69, 0x72, 0x73, 0x74, 0x00, + 0x00, 0x00, 0x00, 0x2e, 0x00, 0x03, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x10, 0x39, 0x04, 0x00, 0x00, 0x1d, 0x03, 0x00, 0x01, + 0x04, 0x01, 0x32, 0x03, 0x01, 0x01, 0x3d, 0x03, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x02, 0x50, 0x50, 0x00, 0x00, 0x02, 0x70, 0x70, 0x00, 0x00, 0x00, + 0x00, 0xde, 0x00, 0x01, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x4b, 0x11, 0x01, 0x11, 0x02, 0x67, 0x01, 0x00, 0x69, 0x01, 0x00, + 0x1d, 0x01, 0x02, 0x6c, 0x01, 0x01, 0x01, 0x1d, 0x01, 0x02, 0x6c, 0x01, + 0x03, 0x02, 0x14, 0x01, 0x1a, 0x01, 0x04, 0x12, 0x01, 0x6f, 0x01, 0x69, + 0x01, 0x03, 0x11, 0x01, 0x68, 0x01, 0x05, 0x69, 0x01, 0x04, 0x1d, 0x02, + 0x05, 0x2f, 0x01, 0x06, 0x01, 0x11, 0x01, 0x1d, 0x02, 0x08, 0x1f, 0x02, + 0x07, 0x67, 0x01, 0x07, 0x69, 0x01, 0x05, 0x11, 0x01, 0x68, 0x01, 0x09, + 0x69, 0x01, 0x06, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x0e, 0x53, + 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x4f, 0x75, 0x74, 0x70, 0x75, + 0x74, 0x00, 0x00, 0x02, 0x70, 0x70, 0x00, 0x00, 0x02, 0x50, 0x50, 0x00, + 0x00, 0x0d, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x6c, 0x69, 0x6e, 0x65, + 0x5f, 0x70, 0x70, 0x00, 0x00, 0x12, 0x40, 0x73, 0x68, 0x61, 0x72, 0x69, + 0x6e, 0x67, 0x5f, 0x64, 0x65, 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x00, 0x00, 0x09, 0x50, 0x50, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, + 0x00, 0x00, 0x07, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x00, 0x00, + 0x0a, 0x53, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x4c, 0x69, 0x6e, 0x65, 0x00, + 0x00, 0x0b, 0x50, 0x72, 0x65, 0x74, 0x74, 0x79, 0x50, 0x72, 0x69, 0x6e, + 0x74, 0x00, 0x00, 0x0b, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x69, + 0x78, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x01, 0x00, 0x01, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x6b, 0x01, 0x00, 0x00, + 0x3d, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x3c, 0x3c, 0x00, 0x00, + 0x00, 0x00, 0x28, 0x00, 0x03, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0c, 0x39, 0x04, 0x00, 0x00, 0x01, 0x04, 0x01, 0x2f, 0x03, + 0x00, 0x01, 0x3f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x05, 0x70, 0x72, 0x69, + 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x06, 0x00, 0x0a, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x39, 0x04, 0x40, 0x00, 0x26, + 0x00, 0x06, 0x26, 0x00, 0x05, 0x26, 0x00, 0x05, 0x11, 0x02, 0x03, 0x03, + 0x4f, 0x01, 0x06, 0x02, 0x27, 0x06, 0x00, 0x09, 0x1d, 0x06, 0x00, 0x33, + 0x06, 0x01, 0x01, 0x02, 0x06, 0x1d, 0x06, 0x02, 0x01, 0x07, 0x02, 0x01, + 0x08, 0x03, 0x32, 0x06, 0x01, 0x02, 0x01, 0x05, 0x06, 0x01, 0x06, 0x05, + 0x62, 0x07, 0x00, 0x34, 0x06, 0x03, 0x00, 0x01, 0x06, 0x05, 0x33, 0x06, + 0x04, 0x01, 0x06, 0x02, 0x5c, 0x07, 0x00, 0x32, 0x06, 0x05, 0x01, 0x3d, + 0x06, 0x00, 0x01, 0x00, 0x00, 0x01, 0x0a, 0x00, 0x00, 0x06, 0x00, 0x0e, + 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x4f, 0x75, 0x74, 0x70, + 0x75, 0x74, 0x00, 0x00, 0x03, 0x6e, 0x65, 0x77, 0x00, 0x00, 0x02, 0x50, + 0x50, 0x00, 0x00, 0x11, 0x67, 0x75, 0x61, 0x72, 0x64, 0x5f, 0x69, 0x6e, + 0x73, 0x70, 0x65, 0x63, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x00, 0x00, 0x05, + 0x66, 0x6c, 0x75, 0x73, 0x68, 0x00, 0x00, 0x02, 0x3c, 0x3c, 0x00, 0x00, + 0x00, 0x00, 0x2b, 0x00, 0x02, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x12, 0x39, 0x00, 0x00, 0x00, 0x21, 0x02, 0x05, 0x00, 0x21, + 0x03, 0x01, 0x00, 0x32, 0x02, 0x00, 0x01, 0x3d, 0x02, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x02, 0x70, 0x70, 0x00, 0x00, 0x00, 0x00, 0x74, 0x00, 0x05, + 0x00, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x39, 0x04, + 0x20, 0x00, 0x26, 0x00, 0x03, 0x26, 0x00, 0x03, 0x15, 0x02, 0x00, 0x1d, + 0x05, 0x01, 0x01, 0x06, 0x02, 0x32, 0x05, 0x02, 0x01, 0x01, 0x04, 0x05, + 0x01, 0x05, 0x04, 0x62, 0x06, 0x00, 0x34, 0x05, 0x03, 0x00, 0x01, 0x05, + 0x04, 0x33, 0x05, 0x04, 0x3d, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x02, + 0x24, 0x3e, 0x00, 0x00, 0x0a, 0x53, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x4c, + 0x69, 0x6e, 0x65, 0x00, 0x00, 0x03, 0x6e, 0x65, 0x77, 0x00, 0x00, 0x11, + 0x67, 0x75, 0x61, 0x72, 0x64, 0x5f, 0x69, 0x6e, 0x73, 0x70, 0x65, 0x63, + 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x00, 0x00, 0x05, 0x66, 0x6c, 0x75, 0x73, + 0x68, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x02, 0x00, 0x05, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x39, 0x00, 0x00, 0x00, 0x21, 0x02, + 0x04, 0x00, 0x21, 0x03, 0x01, 0x00, 0x32, 0x02, 0x00, 0x01, 0x3d, 0x02, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x70, 0x70, 0x00, 0x00, 0x00, 0x00, + 0x41, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x09, 0x10, 0x02, 0x00, 0x2f, 0x01, 0x01, 0x01, 0x3d, 0x00, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x11, 0x73, 0x68, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x5f, + 0x64, 0x65, 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x0d, + 0x61, 0x74, 0x74, 0x72, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6f, + 0x72, 0x00, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x01, 0x00, 0x01, 0x00, 0x0c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x6b, 0x01, 0x00, 0x00, 0x6b, 0x01, + 0x01, 0x01, 0x6b, 0x01, 0x02, 0x02, 0x6b, 0x01, 0x03, 0x03, 0x6b, 0x01, + 0x04, 0x04, 0x6b, 0x01, 0x05, 0x05, 0x6b, 0x01, 0x06, 0x06, 0x6b, 0x01, + 0x07, 0x07, 0x6b, 0x01, 0x08, 0x08, 0x6b, 0x01, 0x09, 0x09, 0x6b, 0x01, + 0x0a, 0x0a, 0x6b, 0x01, 0x0b, 0x0b, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x0c, + 0x00, 0x0a, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, + 0x00, 0x00, 0x11, 0x67, 0x75, 0x61, 0x72, 0x64, 0x5f, 0x69, 0x6e, 0x73, + 0x70, 0x65, 0x63, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x00, 0x00, 0x11, 0x63, + 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x69, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, + 0x5f, 0x6b, 0x65, 0x79, 0x00, 0x00, 0x10, 0x70, 0x75, 0x73, 0x68, 0x5f, + 0x69, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x00, + 0x00, 0x0f, 0x70, 0x6f, 0x70, 0x5f, 0x69, 0x6e, 0x73, 0x70, 0x65, 0x63, + 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x00, 0x00, 0x02, 0x70, 0x70, 0x00, 0x00, + 0x0c, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x67, 0x72, 0x6f, 0x75, + 0x70, 0x00, 0x00, 0x14, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x61, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, + 0x00, 0x00, 0x0f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x5f, 0x62, 0x72, 0x65, + 0x61, 0x6b, 0x61, 0x62, 0x6c, 0x65, 0x00, 0x00, 0x07, 0x73, 0x65, 0x70, + 0x6c, 0x69, 0x73, 0x74, 0x00, 0x00, 0x09, 0x70, 0x70, 0x5f, 0x6f, 0x62, + 0x6a, 0x65, 0x63, 0x74, 0x00, 0x00, 0x07, 0x70, 0x70, 0x5f, 0x68, 0x61, + 0x73, 0x68, 0x00, 0x00, 0x00, 0x00, 0x35, 0x00, 0x03, 0x00, 0x07, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x39, 0x00, 0x10, 0x00, 0x38, + 0x04, 0x04, 0x00, 0x37, 0x03, 0x0f, 0x5e, 0x03, 0x00, 0x1a, 0x03, 0x00, + 0x3d, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0b, 0x40, 0x69, 0x6e, 0x73, + 0x70, 0x65, 0x63, 0x74, 0x69, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x00, 0x4c, + 0x00, 0x03, 0x00, 0x07, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1d, + 0x39, 0x00, 0x00, 0x00, 0x19, 0x02, 0x00, 0x5e, 0x03, 0x00, 0x1a, 0x03, + 0x00, 0x44, 0x03, 0x00, 0x00, 0x36, 0x03, 0x00, 0x2b, 0x05, 0x1a, 0x02, + 0x00, 0x2d, 0x05, 0x3d, 0x03, 0x01, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, + 0x00, 0x14, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0b, + 0x40, 0x69, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x69, 0x6e, 0x67, 0x00, + 0x00, 0x00, 0x00, 0x3d, 0x00, 0x03, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x10, 0x39, 0x04, 0x00, 0x00, 0x19, 0x03, 0x00, 0x01, + 0x04, 0x01, 0x32, 0x03, 0x01, 0x01, 0x3d, 0x03, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x0b, 0x40, 0x69, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x69, 0x6e, + 0x67, 0x00, 0x00, 0x08, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x3f, + 0x00, 0x00, 0x00, 0x00, 0x35, 0x00, 0x03, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x13, 0x39, 0x04, 0x00, 0x00, 0x19, 0x04, 0x00, + 0x01, 0x05, 0x01, 0x13, 0x06, 0x01, 0x03, 0x06, 0x25, 0x04, 0x3d, 0x03, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x0b, 0x40, 0x69, 0x6e, 0x73, 0x70, 0x65, + 0x63, 0x74, 0x69, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x03, + 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x39, 0x04, + 0x00, 0x00, 0x19, 0x03, 0x00, 0x01, 0x04, 0x01, 0x32, 0x03, 0x01, 0x01, + 0x3d, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x0b, 0x40, 0x69, 0x6e, 0x73, + 0x70, 0x65, 0x63, 0x74, 0x69, 0x6e, 0x67, 0x00, 0x00, 0x06, 0x64, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x00, 0x04, 0x00, + 0x0a, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x45, 0x39, 0x04, 0x00, + 0x00, 0x01, 0x04, 0x01, 0x33, 0x04, 0x00, 0x01, 0x03, 0x04, 0x01, 0x05, + 0x03, 0x2f, 0x04, 0x01, 0x01, 0x28, 0x04, 0x00, 0x08, 0x62, 0x05, 0x00, + 0x31, 0x04, 0x02, 0x00, 0x40, 0x01, 0x05, 0x03, 0x2f, 0x04, 0x03, 0x01, + 0x62, 0x05, 0x01, 0x31, 0x04, 0x02, 0x00, 0x2b, 0x06, 0x1d, 0x07, 0x04, + 0x33, 0x07, 0x05, 0x27, 0x07, 0x00, 0x07, 0x01, 0x08, 0x03, 0x2f, 0x07, + 0x06, 0x01, 0x2d, 0x06, 0x3d, 0x04, 0x01, 0x00, 0x00, 0x00, 0x20, 0x00, + 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x07, 0x00, + 0x09, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x00, 0x00, + 0x11, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x69, 0x6e, 0x73, 0x70, 0x65, + 0x63, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x00, 0x00, 0x05, 0x67, 0x72, 0x6f, + 0x75, 0x70, 0x00, 0x00, 0x10, 0x70, 0x75, 0x73, 0x68, 0x5f, 0x69, 0x6e, + 0x73, 0x70, 0x65, 0x63, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x00, 0x00, 0x02, + 0x50, 0x50, 0x00, 0x00, 0x11, 0x73, 0x68, 0x61, 0x72, 0x69, 0x6e, 0x67, + 0x5f, 0x64, 0x65, 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, + 0x0f, 0x70, 0x6f, 0x70, 0x5f, 0x69, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, + 0x5f, 0x6b, 0x65, 0x79, 0x00, 0x00, 0x00, 0x00, 0x39, 0x00, 0x02, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x39, 0x00, 0x00, + 0x00, 0x21, 0x02, 0x01, 0x00, 0x12, 0x03, 0x32, 0x02, 0x00, 0x01, 0x3d, + 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x12, 0x70, 0x72, 0x65, 0x74, 0x74, + 0x79, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x5f, 0x63, 0x79, 0x63, 0x6c, + 0x65, 0x00, 0x00, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00, 0x05, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x39, 0x00, 0x00, 0x00, 0x21, 0x02, + 0x01, 0x00, 0x12, 0x03, 0x32, 0x02, 0x00, 0x01, 0x3d, 0x02, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x0c, 0x70, 0x72, 0x65, 0x74, 0x74, 0x79, 0x5f, 0x70, + 0x72, 0x69, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, 0x59, 0x00, 0x04, 0x00, + 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x39, 0x04, 0x00, + 0x01, 0x01, 0x03, 0x02, 0x07, 0x05, 0x5c, 0x06, 0x00, 0x01, 0x07, 0x01, + 0x33, 0x07, 0x00, 0x33, 0x07, 0x01, 0x45, 0x06, 0x5c, 0x07, 0x01, 0x01, + 0x08, 0x03, 0x31, 0x04, 0x02, 0x03, 0x3d, 0x04, 0x00, 0x02, 0x00, 0x00, + 0x02, 0x23, 0x3c, 0x00, 0x00, 0x00, 0x01, 0x3e, 0x00, 0x00, 0x03, 0x00, + 0x05, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x00, 0x00, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x00, 0x00, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x5c, 0x00, 0x05, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x2b, 0x39, 0x04, 0x00, 0x01, 0x01, 0x03, 0x02, 0x01, 0x05, 0x01, + 0x33, 0x05, 0x00, 0x01, 0x04, 0x05, 0x01, 0x05, 0x04, 0x5c, 0x06, 0x00, + 0x32, 0x05, 0x01, 0x01, 0x07, 0x06, 0x01, 0x07, 0x04, 0x5c, 0x08, 0x00, + 0x01, 0x09, 0x03, 0x31, 0x05, 0x02, 0x03, 0x3d, 0x05, 0x00, 0x01, 0x00, + 0x00, 0x01, 0x3e, 0x00, 0x00, 0x03, 0x00, 0x04, 0x74, 0x6f, 0x5f, 0x73, + 0x00, 0x00, 0x06, 0x63, 0x68, 0x6f, 0x6d, 0x70, 0x21, 0x00, 0x00, 0x05, + 0x67, 0x72, 0x6f, 0x75, 0x70, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x02, + 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x39, 0x00, + 0x00, 0x00, 0x5c, 0x03, 0x00, 0x2f, 0x02, 0x00, 0x01, 0x30, 0x02, 0x01, + 0x3d, 0x02, 0x00, 0x01, 0x00, 0x00, 0x01, 0x2c, 0x00, 0x00, 0x02, 0x00, + 0x04, 0x74, 0x65, 0x78, 0x74, 0x00, 0x00, 0x09, 0x62, 0x72, 0x65, 0x61, + 0x6b, 0x61, 0x62, 0x6c, 0x65, 0x00, 0x00, 0x00, 0x00, 0x63, 0x00, 0x06, + 0x00, 0x09, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x39, 0x04, + 0x40, 0x00, 0x26, 0x00, 0x06, 0x26, 0x00, 0x05, 0x26, 0x00, 0x05, 0x11, + 0x02, 0x10, 0x03, 0x00, 0x01, 0x06, 0x02, 0x27, 0x06, 0x00, 0x0a, 0x62, + 0x07, 0x00, 0x31, 0x06, 0x01, 0x00, 0x01, 0x02, 0x06, 0x13, 0x05, 0x01, + 0x06, 0x01, 0x01, 0x07, 0x03, 0x62, 0x08, 0x01, 0x34, 0x06, 0x02, 0x01, + 0x3d, 0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x04, 0x65, 0x61, 0x63, 0x68, + 0x00, 0x00, 0x06, 0x6c, 0x61, 0x6d, 0x62, 0x64, 0x61, 0x00, 0x00, 0x08, + 0x5f, 0x5f, 0x73, 0x65, 0x6e, 0x64, 0x5f, 0x5f, 0x00, 0x00, 0x00, 0x00, + 0x2f, 0x00, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x09, 0x39, 0x00, 0x00, 0x00, 0x30, 0x02, 0x00, 0x3d, 0x02, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x0f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x5f, 0x62, 0x72, + 0x65, 0x61, 0x6b, 0x61, 0x62, 0x6c, 0x65, 0x00, 0x00, 0x00, 0x00, 0x48, + 0x00, 0x03, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, + 0x39, 0x00, 0x10, 0x00, 0x21, 0x03, 0x05, 0x00, 0x28, 0x03, 0x00, 0x09, + 0x14, 0x03, 0x22, 0x03, 0x05, 0x00, 0x26, 0x00, 0x07, 0x21, 0x03, 0x02, + 0x00, 0x33, 0x03, 0x00, 0x11, 0x04, 0x01, 0x05, 0x01, 0x54, 0x04, 0x44, + 0x03, 0x18, 0x01, 0x32, 0x03, 0x00, 0x0f, 0x3d, 0x03, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x04, 0x63, 0x61, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x3b, + 0x00, 0x03, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, + 0x39, 0x04, 0x00, 0x00, 0x01, 0x04, 0x01, 0x62, 0x05, 0x00, 0x31, 0x03, + 0x00, 0x01, 0x3d, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x14, 0x6f, 0x62, + 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, + 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x00, 0x00, 0x00, 0x00, 0x64, 0x00, + 0x02, 0x00, 0x06, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x39, + 0x00, 0x00, 0x00, 0x21, 0x03, 0x01, 0x00, 0x33, 0x03, 0x00, 0x62, 0x05, + 0x00, 0x31, 0x04, 0x01, 0x00, 0x62, 0x05, 0x01, 0x31, 0x02, 0x02, 0x02, + 0x3d, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x1f, 0x70, 0x72, 0x65, 0x74, + 0x74, 0x79, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x5f, 0x69, 0x6e, 0x73, + 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, + 0x6c, 0x65, 0x73, 0x00, 0x00, 0x06, 0x6c, 0x61, 0x6d, 0x62, 0x64, 0x61, + 0x00, 0x00, 0x07, 0x73, 0x65, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x00, 0x00, + 0x00, 0x00, 0x2d, 0x00, 0x02, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0d, 0x39, 0x00, 0x00, 0x00, 0x5c, 0x03, 0x00, 0x2f, 0x02, + 0x00, 0x01, 0x3d, 0x02, 0x00, 0x01, 0x00, 0x00, 0x01, 0x2c, 0x00, 0x00, + 0x01, 0x00, 0x04, 0x74, 0x65, 0x78, 0x74, 0x00, 0x00, 0x00, 0x00, 0x81, + 0x00, 0x03, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x37, + 0x39, 0x04, 0x00, 0x00, 0x30, 0x03, 0x00, 0x1d, 0x03, 0x01, 0x01, 0x04, + 0x01, 0x32, 0x03, 0x02, 0x01, 0x28, 0x03, 0x00, 0x09, 0x01, 0x03, 0x01, + 0x33, 0x03, 0x03, 0x01, 0x01, 0x03, 0x01, 0x04, 0x01, 0x2f, 0x03, 0x04, + 0x01, 0x5c, 0x04, 0x00, 0x2f, 0x03, 0x04, 0x01, 0x07, 0x04, 0x62, 0x05, + 0x00, 0x31, 0x03, 0x05, 0x01, 0x3d, 0x03, 0x00, 0x01, 0x00, 0x00, 0x01, + 0x3d, 0x00, 0x00, 0x06, 0x00, 0x09, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x61, + 0x62, 0x6c, 0x65, 0x00, 0x00, 0x06, 0x53, 0x79, 0x6d, 0x62, 0x6f, 0x6c, + 0x00, 0x00, 0x03, 0x3d, 0x3d, 0x3d, 0x00, 0x00, 0x04, 0x74, 0x6f, 0x5f, + 0x73, 0x00, 0x00, 0x04, 0x74, 0x65, 0x78, 0x74, 0x00, 0x00, 0x05, 0x67, + 0x72, 0x6f, 0x75, 0x70, 0x00, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x02, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x39, 0x00, 0x00, + 0x00, 0x5c, 0x03, 0x00, 0x2f, 0x02, 0x00, 0x01, 0x21, 0x03, 0x01, 0x02, + 0x21, 0x04, 0x01, 0x00, 0x32, 0x03, 0x01, 0x01, 0x2f, 0x02, 0x02, 0x01, + 0x3d, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x09, + 0x62, 0x72, 0x65, 0x61, 0x6b, 0x61, 0x62, 0x6c, 0x65, 0x00, 0x00, 0x15, + 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x76, 0x61, 0x72, + 0x69, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x67, 0x65, 0x74, 0x00, 0x00, 0x02, + 0x70, 0x70, 0x00, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x03, 0x00, 0x08, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x39, 0x04, 0x00, 0x00, 0x07, + 0x04, 0x5c, 0x05, 0x00, 0x5c, 0x06, 0x01, 0x62, 0x07, 0x00, 0x31, 0x03, + 0x00, 0x03, 0x3d, 0x03, 0x00, 0x02, 0x00, 0x00, 0x01, 0x7b, 0x00, 0x00, + 0x00, 0x01, 0x7d, 0x00, 0x00, 0x01, 0x00, 0x05, 0x67, 0x72, 0x6f, 0x75, + 0x70, 0x00, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x02, 0x00, 0x07, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x39, 0x00, 0x00, 0x00, 0x21, 0x03, + 0x01, 0x00, 0x11, 0x04, 0x10, 0x05, 0x00, 0x62, 0x06, 0x00, 0x31, 0x02, + 0x01, 0x03, 0x3d, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x04, 0x65, 0x61, + 0x63, 0x68, 0x00, 0x00, 0x07, 0x73, 0x65, 0x70, 0x6c, 0x69, 0x73, 0x74, + 0x00, 0x00, 0x00, 0x00, 0x29, 0x00, 0x04, 0x00, 0x06, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0d, 0x39, 0x08, 0x00, 0x00, 0x62, 0x05, 0x00, + 0x31, 0x04, 0x00, 0x00, 0x3d, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x05, + 0x67, 0x72, 0x6f, 0x75, 0x70, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x02, + 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x39, 0x00, + 0x00, 0x00, 0x21, 0x03, 0x01, 0x00, 0x2f, 0x02, 0x00, 0x01, 0x5c, 0x03, + 0x00, 0x2f, 0x02, 0x01, 0x01, 0x07, 0x03, 0x62, 0x04, 0x00, 0x31, 0x02, + 0x02, 0x01, 0x3d, 0x02, 0x00, 0x01, 0x00, 0x00, 0x02, 0x3d, 0x3e, 0x00, + 0x00, 0x03, 0x00, 0x02, 0x70, 0x70, 0x00, 0x00, 0x04, 0x74, 0x65, 0x78, + 0x74, 0x00, 0x00, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x3e, 0x00, 0x02, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x15, 0x39, 0x00, 0x00, 0x00, 0x5c, 0x03, 0x00, 0x2f, 0x02, 0x00, + 0x01, 0x21, 0x03, 0x02, 0x01, 0x2f, 0x02, 0x01, 0x01, 0x3d, 0x02, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x09, 0x62, 0x72, 0x65, + 0x61, 0x6b, 0x61, 0x62, 0x6c, 0x65, 0x00, 0x00, 0x02, 0x70, 0x70, 0x00, + 0x00, 0x00, 0x00, 0x33, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x09, 0x1d, 0x02, 0x00, 0x2f, 0x01, 0x01, 0x01, 0x3d, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x09, 0x50, 0x50, 0x4d, 0x65, 0x74, + 0x68, 0x6f, 0x64, 0x73, 0x00, 0x00, 0x07, 0x69, 0x6e, 0x63, 0x6c, 0x75, + 0x64, 0x65, 0x00, 0x00, 0x00, 0x00, 0x83, 0x00, 0x01, 0x00, 0x01, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x6b, 0x01, 0x00, 0x00, 0x6b, + 0x01, 0x01, 0x01, 0x6b, 0x01, 0x02, 0x02, 0x6b, 0x01, 0x03, 0x03, 0x3d, + 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x0c, 0x70, 0x72, 0x65, 0x74, 0x74, + 0x79, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x00, 0x00, 0x12, 0x70, 0x72, + 0x65, 0x74, 0x74, 0x79, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x5f, 0x63, + 0x79, 0x63, 0x6c, 0x65, 0x00, 0x00, 0x1f, 0x70, 0x72, 0x65, 0x74, 0x74, + 0x79, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x5f, 0x69, 0x6e, 0x73, 0x74, + 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, + 0x65, 0x73, 0x00, 0x00, 0x14, 0x70, 0x72, 0x65, 0x74, 0x74, 0x79, 0x5f, + 0x70, 0x72, 0x69, 0x6e, 0x74, 0x5f, 0x69, 0x6e, 0x73, 0x70, 0x65, 0x63, + 0x74, 0x00, 0x00, 0x00, 0x00, 0x73, 0x00, 0x03, 0x00, 0x06, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x39, 0x04, 0x00, 0x00, 0x14, 0x04, + 0x2f, 0x03, 0x00, 0x01, 0x10, 0x04, 0x01, 0x32, 0x03, 0x02, 0x01, 0x28, + 0x03, 0x00, 0x0d, 0x01, 0x03, 0x01, 0x30, 0x04, 0x01, 0x32, 0x03, 0x03, + 0x01, 0x26, 0x00, 0x09, 0x01, 0x03, 0x01, 0x12, 0x04, 0x32, 0x03, 0x04, + 0x01, 0x3d, 0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x07, 0x6d, 0x65, 0x74, + 0x68, 0x6f, 0x64, 0x73, 0x00, 0x00, 0x07, 0x69, 0x6e, 0x73, 0x70, 0x65, + 0x63, 0x74, 0x00, 0x00, 0x08, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, + 0x3f, 0x00, 0x00, 0x04, 0x74, 0x65, 0x78, 0x74, 0x00, 0x00, 0x09, 0x70, + 0x70, 0x5f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x00, 0x00, 0x00, 0x00, + 0x3d, 0x00, 0x03, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x12, 0x39, 0x04, 0x00, 0x00, 0x01, 0x03, 0x01, 0x12, 0x04, 0x62, 0x05, + 0x00, 0x34, 0x03, 0x00, 0x01, 0x3d, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x14, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x61, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x46, 0x00, 0x02, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x39, 0x00, 0x00, 0x00, 0x21, 0x02, 0x01, 0x00, 0x33, 0x02, + 0x00, 0x21, 0x02, 0x01, 0x00, 0x5c, 0x03, 0x00, 0x32, 0x02, 0x01, 0x01, + 0x3d, 0x02, 0x00, 0x01, 0x00, 0x00, 0x03, 0x2e, 0x2e, 0x2e, 0x00, 0x00, + 0x02, 0x00, 0x09, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x61, 0x62, 0x6c, 0x65, + 0x00, 0x00, 0x04, 0x74, 0x65, 0x78, 0x74, 0x00, 0x00, 0x00, 0x00, 0x3c, + 0x00, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, + 0x39, 0x00, 0x00, 0x00, 0x30, 0x02, 0x00, 0x33, 0x02, 0x01, 0x3d, 0x02, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x12, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, + 0x63, 0x65, 0x5f, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, + 0x00, 0x00, 0x04, 0x73, 0x6f, 0x72, 0x74, 0x00, 0x00, 0x00, 0x00, 0x3f, + 0x00, 0x02, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, + 0x39, 0x00, 0x00, 0x00, 0x1d, 0x02, 0x00, 0x12, 0x03, 0x5c, 0x04, 0x00, + 0x32, 0x02, 0x01, 0x02, 0x3d, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x02, 0x50, 0x50, 0x00, 0x00, 0x0d, 0x73, 0x69, 0x6e, + 0x67, 0x6c, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x5f, 0x70, 0x70, 0x00, 0x00, + 0x00, 0x00, 0x42, 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x6b, 0x01, 0x00, 0x00, 0x6b, 0x01, 0x01, 0x01, 0x3d, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x0c, 0x70, 0x72, 0x65, 0x74, 0x74, + 0x79, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x00, 0x00, 0x12, 0x70, 0x72, + 0x65, 0x74, 0x74, 0x79, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x5f, 0x63, + 0x79, 0x63, 0x6c, 0x65, 0x00, 0x00, 0x00, 0x00, 0x35, 0x00, 0x03, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x39, 0x04, 0x00, + 0x00, 0x01, 0x03, 0x01, 0x30, 0x04, 0x00, 0x32, 0x03, 0x01, 0x01, 0x3d, + 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x07, 0x69, 0x6e, 0x73, 0x70, 0x65, + 0x63, 0x74, 0x00, 0x00, 0x04, 0x74, 0x65, 0x78, 0x74, 0x00, 0x00, 0x00, + 0x00, 0x35, 0x00, 0x03, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x39, 0x04, 0x00, 0x00, 0x01, 0x03, 0x01, 0x30, 0x04, 0x00, + 0x32, 0x03, 0x01, 0x01, 0x3d, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x07, + 0x69, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x00, 0x00, 0x04, 0x74, 0x65, + 0x78, 0x74, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, 0x01, 0x00, 0x01, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x6b, 0x01, 0x00, 0x00, 0x6b, + 0x01, 0x01, 0x01, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x0c, 0x70, + 0x72, 0x65, 0x74, 0x74, 0x79, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x00, + 0x00, 0x12, 0x70, 0x72, 0x65, 0x74, 0x74, 0x79, 0x5f, 0x70, 0x72, 0x69, + 0x6e, 0x74, 0x5f, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x00, 0x00, 0x00, 0x00, + 0x3e, 0x00, 0x03, 0x00, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x39, 0x04, 0x00, 0x00, 0x01, 0x03, 0x01, 0x07, 0x04, 0x5c, 0x05, + 0x00, 0x5c, 0x06, 0x01, 0x62, 0x07, 0x00, 0x34, 0x03, 0x00, 0x03, 0x3d, + 0x03, 0x00, 0x02, 0x00, 0x00, 0x01, 0x5b, 0x00, 0x00, 0x00, 0x01, 0x5d, + 0x00, 0x00, 0x01, 0x00, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x00, 0x00, + 0x00, 0x00, 0x31, 0x00, 0x02, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x13, 0x39, 0x00, 0x00, 0x00, 0x21, 0x02, 0x01, 0x00, 0x12, + 0x03, 0x62, 0x04, 0x00, 0x34, 0x02, 0x00, 0x01, 0x3d, 0x02, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x07, 0x73, 0x65, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x00, + 0x00, 0x00, 0x00, 0x2a, 0x00, 0x03, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x11, 0x39, 0x04, 0x00, 0x00, 0x21, 0x03, 0x01, 0x01, + 0x01, 0x04, 0x01, 0x32, 0x03, 0x00, 0x01, 0x3d, 0x03, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x02, 0x70, 0x70, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x03, + 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x39, 0x04, + 0x00, 0x00, 0x01, 0x03, 0x01, 0x30, 0x04, 0x00, 0x28, 0x04, 0x00, 0x06, + 0x5c, 0x04, 0x00, 0x26, 0x00, 0x03, 0x5c, 0x04, 0x01, 0x32, 0x03, 0x01, + 0x01, 0x3d, 0x03, 0x00, 0x02, 0x00, 0x00, 0x02, 0x5b, 0x5d, 0x00, 0x00, + 0x00, 0x05, 0x5b, 0x2e, 0x2e, 0x2e, 0x5d, 0x00, 0x00, 0x02, 0x00, 0x06, + 0x65, 0x6d, 0x70, 0x74, 0x79, 0x3f, 0x00, 0x00, 0x04, 0x74, 0x65, 0x78, + 0x74, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x6b, 0x01, 0x00, 0x00, 0x6b, 0x01, + 0x01, 0x01, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x0c, 0x70, 0x72, + 0x65, 0x74, 0x74, 0x79, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x00, 0x00, + 0x12, 0x70, 0x72, 0x65, 0x74, 0x74, 0x79, 0x5f, 0x70, 0x72, 0x69, 0x6e, + 0x74, 0x5f, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x00, 0x00, 0x00, 0x00, 0x2d, + 0x00, 0x03, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, + 0x39, 0x04, 0x00, 0x00, 0x01, 0x03, 0x01, 0x12, 0x04, 0x32, 0x03, 0x00, + 0x01, 0x3d, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x70, 0x70, 0x5f, + 0x68, 0x61, 0x73, 0x68, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x03, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x39, 0x04, 0x00, + 0x00, 0x01, 0x03, 0x01, 0x30, 0x04, 0x00, 0x28, 0x04, 0x00, 0x06, 0x5c, + 0x04, 0x00, 0x26, 0x00, 0x03, 0x5c, 0x04, 0x01, 0x32, 0x03, 0x01, 0x01, + 0x3d, 0x03, 0x00, 0x02, 0x00, 0x00, 0x02, 0x7b, 0x7d, 0x00, 0x00, 0x00, + 0x05, 0x7b, 0x2e, 0x2e, 0x2e, 0x7d, 0x00, 0x00, 0x02, 0x00, 0x06, 0x65, + 0x6d, 0x70, 0x74, 0x79, 0x3f, 0x00, 0x00, 0x04, 0x74, 0x65, 0x78, 0x74, + 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0a, 0x6b, 0x01, 0x00, 0x00, 0x6b, 0x01, 0x01, + 0x01, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x0c, 0x70, 0x72, 0x65, + 0x74, 0x74, 0x79, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x00, 0x00, 0x12, + 0x70, 0x72, 0x65, 0x74, 0x74, 0x79, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, + 0x5f, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x00, 0x00, 0x00, 0x00, 0x61, 0x00, + 0x03, 0x00, 0x09, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x39, + 0x04, 0x00, 0x00, 0x01, 0x03, 0x01, 0x07, 0x04, 0x5c, 0x06, 0x00, 0x30, + 0x07, 0x00, 0x2f, 0x05, 0x01, 0x02, 0x5c, 0x06, 0x01, 0x62, 0x07, 0x00, + 0x34, 0x03, 0x02, 0x03, 0x3d, 0x03, 0x00, 0x02, 0x00, 0x00, 0x0b, 0x23, + 0x3c, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x25, 0x73, 0x00, 0x00, + 0x00, 0x01, 0x3e, 0x00, 0x00, 0x03, 0x00, 0x05, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x00, 0x00, 0x07, 0x73, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x66, 0x00, + 0x00, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x00, 0x00, 0x00, 0x00, 0x4c, + 0x00, 0x02, 0x00, 0x06, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, + 0x39, 0x00, 0x00, 0x00, 0x21, 0x02, 0x01, 0x00, 0x30, 0x03, 0x00, 0x62, + 0x05, 0x00, 0x31, 0x04, 0x01, 0x00, 0x62, 0x05, 0x01, 0x34, 0x02, 0x02, + 0x02, 0x3d, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x07, 0x6d, 0x65, 0x6d, + 0x62, 0x65, 0x72, 0x73, 0x00, 0x00, 0x06, 0x6c, 0x61, 0x6d, 0x62, 0x64, + 0x61, 0x00, 0x00, 0x07, 0x73, 0x65, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x00, + 0x00, 0x00, 0x00, 0x31, 0x00, 0x02, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x11, 0x39, 0x00, 0x00, 0x00, 0x21, 0x02, 0x01, 0x01, + 0x5c, 0x03, 0x00, 0x32, 0x02, 0x00, 0x01, 0x3d, 0x02, 0x00, 0x01, 0x00, + 0x00, 0x01, 0x2c, 0x00, 0x00, 0x01, 0x00, 0x04, 0x74, 0x65, 0x78, 0x74, + 0x00, 0x00, 0x00, 0x00, 0x6e, 0x00, 0x03, 0x00, 0x06, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x33, 0x39, 0x04, 0x00, 0x00, 0x21, 0x03, 0x01, + 0x01, 0x33, 0x03, 0x00, 0x21, 0x03, 0x01, 0x01, 0x01, 0x04, 0x01, 0x33, + 0x04, 0x01, 0x32, 0x03, 0x02, 0x01, 0x21, 0x03, 0x01, 0x01, 0x5c, 0x04, + 0x00, 0x32, 0x03, 0x02, 0x01, 0x21, 0x03, 0x01, 0x01, 0x07, 0x04, 0x62, + 0x05, 0x00, 0x34, 0x03, 0x03, 0x01, 0x3d, 0x03, 0x00, 0x01, 0x00, 0x00, + 0x01, 0x3d, 0x00, 0x00, 0x04, 0x00, 0x09, 0x62, 0x72, 0x65, 0x61, 0x6b, + 0x61, 0x62, 0x6c, 0x65, 0x00, 0x00, 0x04, 0x74, 0x6f, 0x5f, 0x73, 0x00, + 0x00, 0x04, 0x74, 0x65, 0x78, 0x74, 0x00, 0x00, 0x05, 0x67, 0x72, 0x6f, + 0x75, 0x70, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x02, 0x00, 0x06, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x39, 0x00, 0x00, 0x00, 0x21, + 0x02, 0x01, 0x02, 0x5c, 0x03, 0x00, 0x32, 0x02, 0x00, 0x01, 0x21, 0x02, + 0x01, 0x02, 0x12, 0x03, 0x21, 0x04, 0x01, 0x00, 0x23, 0x03, 0x32, 0x02, + 0x01, 0x01, 0x3d, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x09, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x61, 0x62, 0x6c, 0x65, 0x00, + 0x00, 0x02, 0x70, 0x70, 0x00, 0x00, 0x00, 0x00, 0x58, 0x00, 0x03, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x39, 0x04, 0x00, + 0x00, 0x01, 0x03, 0x01, 0x5c, 0x05, 0x00, 0x30, 0x06, 0x00, 0x2f, 0x04, + 0x01, 0x02, 0x32, 0x03, 0x02, 0x01, 0x3d, 0x03, 0x00, 0x01, 0x00, 0x00, + 0x10, 0x23, 0x3c, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x25, 0x73, + 0x3a, 0x2e, 0x2e, 0x2e, 0x3e, 0x00, 0x00, 0x03, 0x00, 0x05, 0x63, 0x6c, + 0x61, 0x73, 0x73, 0x00, 0x00, 0x07, 0x73, 0x70, 0x72, 0x69, 0x6e, 0x74, + 0x66, 0x00, 0x00, 0x04, 0x74, 0x65, 0x78, 0x74, 0x00, 0x00, 0x00, 0x00, + 0x29, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x06, 0x6b, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x0c, 0x70, 0x72, 0x65, 0x74, 0x74, 0x79, 0x5f, 0x70, 0x72, 0x69, 0x6e, + 0x74, 0x00, 0x00, 0x00, 0x00, 0x9f, 0x00, 0x03, 0x00, 0x06, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x39, 0x04, 0x00, 0x00, 0x01, 0x03, + 0x01, 0x30, 0x04, 0x00, 0x32, 0x03, 0x01, 0x01, 0x01, 0x03, 0x01, 0x5c, + 0x04, 0x00, 0x32, 0x03, 0x02, 0x01, 0x01, 0x03, 0x01, 0x30, 0x04, 0x03, + 0x28, 0x04, 0x00, 0x06, 0x5c, 0x04, 0x01, 0x26, 0x00, 0x03, 0x5c, 0x04, + 0x02, 0x32, 0x03, 0x04, 0x01, 0x01, 0x03, 0x01, 0x5c, 0x04, 0x00, 0x32, + 0x03, 0x02, 0x01, 0x01, 0x03, 0x01, 0x30, 0x04, 0x05, 0x32, 0x03, 0x01, + 0x01, 0x3d, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, + 0x2e, 0x2e, 0x2e, 0x00, 0x00, 0x00, 0x02, 0x2e, 0x2e, 0x00, 0x00, 0x06, + 0x00, 0x05, 0x62, 0x65, 0x67, 0x69, 0x6e, 0x00, 0x00, 0x02, 0x70, 0x70, + 0x00, 0x00, 0x09, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x61, 0x62, 0x6c, 0x65, + 0x00, 0x00, 0x0c, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x65, + 0x6e, 0x64, 0x3f, 0x00, 0x00, 0x04, 0x74, 0x65, 0x78, 0x74, 0x00, 0x00, + 0x03, 0x65, 0x6e, 0x64, 0x00, 0x00, 0x00, 0x00, 0x29, 0x00, 0x01, 0x00, + 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x6b, 0x01, 0x00, + 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0c, 0x70, 0x72, 0x65, + 0x74, 0x74, 0x79, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x00, 0x00, 0x00, + 0x00, 0x66, 0x00, 0x04, 0x00, 0x07, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x22, 0x39, 0x04, 0x00, 0x00, 0x52, 0x03, 0x00, 0x30, 0x04, 0x00, + 0x33, 0x04, 0x01, 0x62, 0x05, 0x00, 0x34, 0x04, 0x02, 0x00, 0x01, 0x04, + 0x01, 0x12, 0x05, 0x62, 0x06, 0x01, 0x34, 0x04, 0x03, 0x01, 0x3d, 0x04, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x06, 0x72, 0x65, 0x67, 0x65, 0x78, 0x70, + 0x00, 0x00, 0x0e, 0x6e, 0x61, 0x6d, 0x65, 0x64, 0x5f, 0x63, 0x61, 0x70, + 0x74, 0x75, 0x72, 0x65, 0x73, 0x00, 0x00, 0x04, 0x65, 0x61, 0x63, 0x68, + 0x00, 0x00, 0x0c, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x67, 0x72, + 0x6f, 0x75, 0x70, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x06, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x39, 0x08, 0x00, 0x00, + 0x01, 0x04, 0x02, 0x62, 0x05, 0x00, 0x34, 0x04, 0x00, 0x00, 0x3d, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x04, 0x65, 0x61, 0x63, 0x68, 0x00, 0x00, + 0x00, 0x00, 0x2a, 0x00, 0x03, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x16, 0x39, 0x04, 0x00, 0x00, 0x21, 0x04, 0x03, 0x01, 0x01, + 0x05, 0x01, 0x21, 0x06, 0x01, 0x00, 0x01, 0x03, 0x06, 0x25, 0x04, 0x3d, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x02, 0x00, + 0x06, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0x39, 0x00, 0x00, + 0x00, 0x21, 0x02, 0x01, 0x00, 0x33, 0x02, 0x00, 0x21, 0x02, 0x01, 0x00, + 0x06, 0x03, 0x30, 0x04, 0x01, 0x65, 0x03, 0x62, 0x05, 0x00, 0x31, 0x04, + 0x02, 0x00, 0x62, 0x05, 0x01, 0x34, 0x02, 0x03, 0x02, 0x3d, 0x02, 0x00, + 0x00, 0x00, 0x04, 0x00, 0x09, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x61, 0x62, + 0x6c, 0x65, 0x00, 0x00, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x00, 0x00, 0x06, + 0x6c, 0x61, 0x6d, 0x62, 0x64, 0x61, 0x00, 0x00, 0x07, 0x73, 0x65, 0x70, + 0x6c, 0x69, 0x73, 0x74, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x02, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x39, 0x00, 0x00, + 0x00, 0x21, 0x02, 0x01, 0x01, 0x33, 0x02, 0x00, 0x3d, 0x02, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x09, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x61, 0x62, 0x6c, + 0x65, 0x00, 0x00, 0x00, 0x00, 0x8e, 0x00, 0x03, 0x00, 0x07, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x69, 0x39, 0x04, 0x00, 0x00, 0x01, 0x03, + 0x01, 0x06, 0x04, 0x4d, 0x03, 0x28, 0x03, 0x00, 0x12, 0x21, 0x03, 0x01, + 0x01, 0x12, 0x04, 0x01, 0x05, 0x01, 0x23, 0x04, 0x32, 0x03, 0x00, 0x01, + 0x26, 0x00, 0x46, 0x21, 0x03, 0x03, 0x01, 0x01, 0x04, 0x01, 0x23, 0x03, + 0x28, 0x03, 0x00, 0x14, 0x21, 0x03, 0x01, 0x01, 0x21, 0x04, 0x03, 0x01, + 0x01, 0x05, 0x01, 0x23, 0x04, 0x32, 0x03, 0x01, 0x01, 0x26, 0x00, 0x0b, + 0x21, 0x03, 0x01, 0x01, 0x01, 0x04, 0x01, 0x32, 0x03, 0x00, 0x01, 0x21, + 0x03, 0x01, 0x01, 0x5c, 0x04, 0x00, 0x32, 0x03, 0x01, 0x01, 0x21, 0x03, + 0x01, 0x01, 0x12, 0x04, 0x01, 0x05, 0x01, 0x23, 0x04, 0x32, 0x03, 0x00, + 0x01, 0x3d, 0x03, 0x00, 0x01, 0x00, 0x00, 0x01, 0x3a, 0x00, 0x00, 0x02, + 0x00, 0x02, 0x70, 0x70, 0x00, 0x00, 0x04, 0x74, 0x65, 0x78, 0x74, 0x00, + 0x00, 0x00, 0x00, 0xb9, 0x00, 0x01, 0x00, 0x07, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x41, 0x1d, 0x02, 0x01, 0x1f, 0x02, 0x00, 0x2f, 0x01, + 0x02, 0x01, 0x1d, 0x01, 0x03, 0x1d, 0x02, 0x04, 0x1d, 0x03, 0x05, 0x1d, + 0x04, 0x06, 0x1d, 0x05, 0x07, 0x1d, 0x06, 0x08, 0x52, 0x01, 0x06, 0x62, + 0x02, 0x00, 0x34, 0x01, 0x09, 0x00, 0x1d, 0x01, 0x03, 0x1d, 0x02, 0x05, + 0x1d, 0x03, 0x06, 0x1d, 0x04, 0x07, 0x1d, 0x05, 0x08, 0x52, 0x01, 0x05, + 0x62, 0x02, 0x01, 0x34, 0x01, 0x09, 0x00, 0x3d, 0x01, 0x00, 0x00, 0x00, + 0x0a, 0x00, 0x0b, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x69, 0x78, + 0x69, 0x6e, 0x00, 0x00, 0x02, 0x50, 0x50, 0x00, 0x00, 0x07, 0x69, 0x6e, + 0x63, 0x6c, 0x75, 0x64, 0x65, 0x00, 0x00, 0x07, 0x4e, 0x75, 0x6d, 0x65, + 0x72, 0x69, 0x63, 0x00, 0x00, 0x06, 0x53, 0x79, 0x6d, 0x62, 0x6f, 0x6c, + 0x00, 0x00, 0x0a, 0x46, 0x61, 0x6c, 0x73, 0x65, 0x43, 0x6c, 0x61, 0x73, + 0x73, 0x00, 0x00, 0x09, 0x54, 0x72, 0x75, 0x65, 0x43, 0x6c, 0x61, 0x73, + 0x73, 0x00, 0x00, 0x08, 0x4e, 0x69, 0x6c, 0x43, 0x6c, 0x61, 0x73, 0x73, + 0x00, 0x00, 0x06, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x00, 0x00, 0x04, + 0x65, 0x61, 0x63, 0x68, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x03, 0x00, + 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x39, 0x04, 0x00, + 0x00, 0x01, 0x03, 0x01, 0x62, 0x04, 0x00, 0x34, 0x03, 0x00, 0x00, 0x3d, + 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0a, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x5f, 0x65, 0x76, 0x61, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x33, 0x00, 0x02, + 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x39, 0x00, + 0x00, 0x00, 0x6b, 0x02, 0x00, 0x00, 0x3d, 0x02, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x12, 0x70, 0x72, 0x65, 0x74, 0x74, 0x79, 0x5f, 0x70, 0x72, 0x69, + 0x6e, 0x74, 0x5f, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x00, 0x00, 0x00, 0x00, + 0x35, 0x00, 0x03, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x39, 0x04, 0x00, 0x00, 0x01, 0x03, 0x01, 0x30, 0x04, 0x00, 0x32, + 0x03, 0x01, 0x01, 0x3d, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x07, 0x69, + 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x00, 0x00, 0x04, 0x74, 0x65, 0x78, + 0x74, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x03, 0x00, 0x05, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x39, 0x04, 0x00, 0x00, 0x01, 0x03, + 0x01, 0x62, 0x04, 0x00, 0x34, 0x03, 0x00, 0x00, 0x3d, 0x03, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x0a, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x5f, 0x65, 0x76, + 0x61, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x02, 0x00, 0x03, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x39, 0x00, 0x00, 0x00, 0x6b, + 0x02, 0x00, 0x00, 0x3d, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0c, 0x70, + 0x72, 0x65, 0x74, 0x74, 0x79, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x00, + 0x00, 0x00, 0x00, 0x35, 0x00, 0x03, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x10, 0x39, 0x04, 0x00, 0x00, 0x01, 0x03, 0x01, 0x30, + 0x04, 0x00, 0x32, 0x03, 0x01, 0x01, 0x3d, 0x03, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x07, 0x69, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x00, 0x00, 0x04, + 0x74, 0x65, 0x78, 0x74, 0x00, 0x4c, 0x56, 0x41, 0x52, 0x00, 0x00, 0x03, + 0x09, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, + 0x74, 0x00, 0x08, 0x6d, 0x61, 0x78, 0x77, 0x69, 0x64, 0x74, 0x68, 0x00, + 0x07, 0x6e, 0x65, 0x77, 0x6c, 0x69, 0x6e, 0x65, 0x00, 0x08, 0x67, 0x65, + 0x6e, 0x73, 0x70, 0x61, 0x63, 0x65, 0x00, 0x01, 0x71, 0x00, 0x01, 0x6e, + 0x00, 0x0a, 0x72, 0x6f, 0x6f, 0x74, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, + 0x00, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x00, 0x04, 0x64, 0x61, 0x74, + 0x61, 0x00, 0x04, 0x74, 0x65, 0x78, 0x74, 0x00, 0x03, 0x6f, 0x62, 0x6a, + 0x00, 0x05, 0x77, 0x69, 0x64, 0x74, 0x68, 0x00, 0x03, 0x73, 0x65, 0x70, + 0x00, 0x06, 0x69, 0x6e, 0x64, 0x65, 0x6e, 0x74, 0x00, 0x08, 0x6f, 0x70, + 0x65, 0x6e, 0x5f, 0x6f, 0x62, 0x6a, 0x00, 0x09, 0x63, 0x6c, 0x6f, 0x73, + 0x65, 0x5f, 0x6f, 0x62, 0x6a, 0x00, 0x0a, 0x6f, 0x70, 0x65, 0x6e, 0x5f, + 0x77, 0x69, 0x64, 0x74, 0x68, 0x00, 0x0b, 0x63, 0x6c, 0x6f, 0x73, 0x65, + 0x5f, 0x77, 0x69, 0x64, 0x74, 0x68, 0x00, 0x03, 0x6f, 0x75, 0x74, 0x00, + 0x0c, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x77, 0x69, 0x64, 0x74, + 0x68, 0x00, 0x05, 0x64, 0x65, 0x70, 0x74, 0x68, 0x00, 0x06, 0x67, 0x72, + 0x6f, 0x75, 0x70, 0x73, 0x00, 0x01, 0x67, 0x00, 0x02, 0x67, 0x73, 0x00, + 0x01, 0x69, 0x00, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x00, 0x04, + 0x6f, 0x62, 0x6a, 0x73, 0x00, 0x06, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x00, 0x04, 0x61, 0x72, 0x67, 0x73, 0x00, 0x04, 0x73, 0x61, 0x76, 0x65, + 0x00, 0x02, 0x69, 0x64, 0x00, 0x05, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x00, + 0x03, 0x73, 0x74, 0x72, 0x00, 0x04, 0x6c, 0x69, 0x73, 0x74, 0x00, 0x0b, + 0x69, 0x74, 0x65, 0x72, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x00, + 0x05, 0x66, 0x69, 0x72, 0x73, 0x74, 0x00, 0x01, 0x76, 0x00, 0x01, 0x6b, + 0x00, 0x06, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x00, 0x02, 0x6e, 0x63, + 0x00, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x07, 0x69, 0x6e, 0x64, 0x65, + 0x78, 0x65, 0x73, 0x00, 0x01, 0x63, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, + 0x00, 0x03, 0xff, 0xff, 0x00, 0x04, 0x00, 0x05, 0xff, 0xff, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0xff, 0xff, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x02, 0xff, 0xff, 0x00, 0x03, 0x00, 0x06, 0x00, 0x05, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x07, 0x00, 0x08, 0x00, 0x09, + 0x00, 0x0a, 0x00, 0x0b, 0xff, 0xff, 0x00, 0x09, 0x00, 0x0c, 0x00, 0x0b, + 0xff, 0xff, 0xff, 0xff, 0x00, 0x0c, 0x00, 0x0b, 0xff, 0xff, 0x00, 0x07, + 0x00, 0x0d, 0x00, 0x0e, 0x00, 0x0f, 0x00, 0x10, 0x00, 0x11, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x07, 0x00, 0x0d, 0xff, 0xff, + 0xff, 0xff, 0x00, 0x08, 0xff, 0xff, 0xff, 0xff, 0x00, 0x12, 0x00, 0x13, + 0xff, 0xff, 0x00, 0x0a, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x0b, 0xff, 0xff, + 0x00, 0x0c, 0x00, 0x0b, 0x00, 0x04, 0xff, 0xff, 0x00, 0x12, 0x00, 0x13, + 0xff, 0xff, 0x00, 0x14, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x15, 0xff, 0xff, 0x00, 0x16, 0xff, 0xff, 0x00, 0x07, 0xff, 0xff, + 0x00, 0x14, 0xff, 0xff, 0x00, 0x17, 0xff, 0xff, 0x00, 0x18, 0xff, 0xff, + 0x00, 0x07, 0x00, 0x07, 0xff, 0xff, 0x00, 0x07, 0xff, 0xff, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x02, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x0b, 0xff, 0xff, + 0x00, 0x0c, 0x00, 0x0b, 0xff, 0xff, 0x00, 0x0d, 0xff, 0xff, 0x00, 0x0d, + 0x00, 0x0e, 0x00, 0x0f, 0x00, 0x10, 0x00, 0x11, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x00, 0x19, 0xff, 0xff, 0x00, 0x1a, 0xff, 0xff, 0x00, 0x0a, + 0xff, 0xff, 0x00, 0x1b, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x12, 0x00, 0x0b, + 0xff, 0xff, 0x00, 0x04, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x12, 0xff, 0xff, + 0x00, 0x04, 0xff, 0xff, 0x00, 0x1c, 0xff, 0xff, 0xff, 0xff, 0x00, 0x1d, + 0x00, 0x1e, 0xff, 0xff, 0x00, 0x1e, 0xff, 0xff, 0x00, 0x1e, 0xff, 0xff, + 0x00, 0x0a, 0xff, 0xff, 0x00, 0x1e, 0xff, 0xff, 0xff, 0xff, 0x00, 0x0a, + 0xff, 0xff, 0x00, 0x1f, 0x00, 0x0a, 0xff, 0xff, 0x00, 0x1f, 0x00, 0x20, + 0xff, 0xff, 0x00, 0x21, 0x00, 0x0c, 0x00, 0x22, 0xff, 0xff, 0x00, 0x23, + 0xff, 0xff, 0x00, 0x24, 0xff, 0xff, 0x00, 0x0a, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x00, 0x24, 0xff, 0xff, 0xff, 0xff, 0x00, 0x0a, 0xff, 0xff, + 0xff, 0xff, 0x00, 0x25, 0x00, 0x24, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x04, 0xff, 0xff, 0x00, 0x04, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x00, 0x04, 0xff, 0xff, 0x00, 0x04, 0xff, 0xff, 0x00, 0x04, + 0xff, 0xff, 0xff, 0xff, 0x00, 0x24, 0xff, 0xff, 0x00, 0x04, 0xff, 0xff, + 0x00, 0x04, 0xff, 0xff, 0x00, 0x04, 0xff, 0xff, 0x00, 0x04, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x00, 0x26, 0xff, 0xff, 0xff, 0xff, 0x00, 0x04, + 0xff, 0xff, 0x00, 0x04, 0xff, 0xff, 0x00, 0x04, 0xff, 0xff, 0x00, 0x27, + 0x00, 0x28, 0x00, 0x29, 0xff, 0xff, 0x00, 0x18, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x00, 0x18, 0xff, 0xff, 0x00, 0x2a, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x04, 0xff, 0xff, 0x00, 0x2a, 0xff, 0xff, 0xff, 0xff, 0x00, 0x04, + 0xff, 0xff, 0x45, 0x4e, 0x44, 0x00, 0x00, 0x00, 0x00, 0x08 +}; +constexpr unsigned int mgems_len = 12382; +#endif diff --git a/libs/l_mgems/compile.sh b/libs/l_mgems/compile.sh index 0d62ef4..34a9c3f 100755 --- a/libs/l_mgems/compile.sh +++ b/libs/l_mgems/compile.sh @@ -4,7 +4,7 @@ set -e SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)" OUTPUT_TMP=$(mktemp) -OUTPUT="$SCRIPT_DIR/../../include/binding/ruby_compiled.h" +OUTPUT="$SCRIPT_DIR/../../include/bindings/ruby_compiled.h" if test "$1" = "clean"; then rm -f "$OUTPUT" @@ -26,6 +26,8 @@ if test "$OUTPUT_TIME" -ge "$LATEST_FILE_TIME"; then exit 0 fi +echo "Compiling mgems..." + "$SCRIPT_DIR/../mruby/bin/mrbc" -o "$OUTPUT_TMP" "${FILES[@]}" { diff --git a/samples/button.rb b/samples/button.rb index 90c8020..8c0d6e6 100644 --- a/samples/button.rb +++ b/samples/button.rb @@ -1,4 +1,4 @@ -App.run 720, 480, "Button Test", fps: 240 +App.run 720, 480, "Button Test", fps: 60 main_scene = Scene.new @@ -18,7 +18,7 @@ text = ElementText.new :btn_text, default_font, 0xFFFF00, {name: "Me"}, position rect = ElementRect.new 100, 25, 0xFF0000, position: {x: 50, y: 50}, z: 0, rotation: 60, scale: { x: 1, y: 1 }, alpha: 0.8, click_mode: :block -image_element = ElementImage.new bg_animation, position: {x: 0, y: 0}, z: -1, click_mode: :ignore, alpha: 1 +image_element = ElementImage.new bg_animation, position: {x: 0, y: 0}, z: -1, click_mode: :block, alpha: 1 pp text, rect, image_element @@ -26,7 +26,7 @@ end_scene = Scene.new end_scene << rect text.click do - App.switch_to end_scene + #App.switch_to end_scene end image_element.click do @@ -75,6 +75,7 @@ App.update do |delta_time| elsif elem == text pp "Down over text element" end + elem.position.x += 10 end end diff --git a/samples/stress.rb b/samples/stress.rb index bd45693..d506eb8 100644 --- a/samples/stress.rb +++ b/samples/stress.rb @@ -1,4 +1,4 @@ -App.run 720, 480, "Stress Test", fps: 120 +App.run 720, 480, "Stress Test", fps: 60 scene = Scene.new @@ -30,7 +30,7 @@ App.localize(:en, :btn_text, "Stress Test %{count}") App.localize(:en, :text, "Random Text") -1.times do |i| +1000.times do |i| elements << ElementText.new( :text, font, @@ -43,7 +43,7 @@ App.localize(:en, :text, "Random Text") ) end -500.times do |i| +1000.times do |i| elements << ElementImage.new( animations.sample, position: { x: rand(0..700), y: rand(0..450) }, @@ -54,7 +54,7 @@ end ) end -500.times do |i| +1000.times do |i| elements << ElementRect.new( 20 + rand(100), 20 + rand(100), diff --git a/src/bindings/animation.cc b/src/bindings/animation.cc new file mode 100644 index 0000000..ef9ddfd --- /dev/null +++ b/src/bindings/animation.cc @@ -0,0 +1,187 @@ +#include "bindings/definitions.h" +#include "window/window.h" + +namespace { +void Animation_free(mrb_state *mrb, void *ptr) { + UNUSED(mrb); + uint64_t id = ((Wrapper *)ptr)->id; + animation_pool.release(id); + delete (Wrapper *)ptr; +} + +const struct mrb_data_type Animation_type = { + "Animation", Animation_free +}; + +mrb_value Animation_init(mrb_state *mrb, mrb_value self) { + Wrapper *old = (Wrapper *)DATA_PTR(self); + if (old) + mrb_free(mrb, old); + mrb_data_init(self, nullptr, &Animation_type); + Wrapper *s = new Wrapper(); + + const mrb_value *frames_val; + mrb_int frames_len; + mrb_value kwargs; + mrb_get_args(mrb, "a|H", &frames_val, &frames_len, &kwargs); + + float fps = 1.0f; + if (!mrb_nil_p(kwargs)) + HASH_FLOAT(kwargs, fps, fps); + + std::vector frame_ids; + for (mrb_int i = 0; i < frames_len; i++) { + mrb_value frame_val = frames_val[i]; + if (!mrb_obj_is_kind_of(mrb, frame_val, definitions::bindings.Image.cls)) { + mrb_raise( + mrb, + mrb_class_get(mrb, "Exception"), + "Expected an array of Image objects" + ); + return mrb_nil_value(); + } + + Wrapper *image_wrapper = (Wrapper *)DATA_PTR(frame_val); + uint64_t frame_id = image_wrapper->id; + image_pool.use(frame_id); + frame_ids.push_back(frame_id); + } + + Animation *animation = new Animation{frame_ids, fps}; + s->id = animation_pool.acquire(animation); + animation_pool.use(s->id); + + mrb_data_init(self, s, &Animation_type); + return self; +} + +mrb_value static_image_animation(mrb_state *mrb, mrb_value) { + mrb_value image_val; + mrb_get_args(mrb, "o", &image_val); + + if (!mrb_obj_is_kind_of(mrb, image_val, definitions::bindings.Image.cls)) { + mrb_raise( + mrb, + mrb_class_get(mrb, "Exception"), + "Expected an Image object" + ); + return mrb_nil_value(); + } + + Wrapper *image_wrapper = (Wrapper *)DATA_PTR(image_val); + uint64_t frame_id = image_wrapper->id; + image_pool.use(frame_id); + + std::vector frames = {frame_id}; + Animation *animation = new Animation{frames, 1.0f}; + Wrapper *s = new Wrapper(); + s->id = animation_pool.acquire(animation); + animation_pool.use(s->id); + + return definitions::wrap(definitions::bindings.Animation, s->id); +} + +mrb_value animation_equal(mrb_state *mrb, mrb_value self) { + mrb_value other; + mrb_get_args(mrb, "o", &other); + + if (!mrb_obj_is_kind_of(mrb, other, definitions::bindings.Animation.cls)) + return mrb_false_value(); + + Wrapper *self_wrapper = (Wrapper *)DATA_PTR(self); + uint64_t id_self = self_wrapper->id; + Wrapper *other_wrapper = (Wrapper *)DATA_PTR(other); + uint64_t id_other = other_wrapper->id; + + return mrb_bool_value(id_self == id_other); +} + +mrb_value animation_hash(mrb_state *, mrb_value self) { + Wrapper *wrapper = (Wrapper *)DATA_PTR(self); + return mrb_fixnum_value(wrapper->id); +} + +mrb_value animation_frames_set(mrb_state *mrb, mrb_value self) { + const mrb_value *frames_val; + mrb_int frames_len; + mrb_get_args(mrb, "a", &frames_val, &frames_len); + + Wrapper *self_wrapper = (Wrapper *)DATA_PTR(self); + uint64_t id = self_wrapper->id; + Animation *animation = animation_pool[id]; + + std::vector new_frame_ids; + for (mrb_int i = 0; i < frames_len; i++) { + mrb_value frame_val = frames_val[i]; + if (!mrb_obj_is_kind_of(mrb, frame_val, definitions::bindings.Image.cls)) { + mrb_raise( + mrb, + mrb_class_get(mrb, "Exception"), + "Expected an array of Image objects" + ); + return mrb_nil_value(); + } + Wrapper *image_wrapper = (Wrapper *)DATA_PTR(frame_val); + uint64_t frame_id = image_wrapper->id; + image_pool.use(frame_id); + new_frame_ids.push_back(frame_id); + } + + // Release old frames + for (uint64_t frame_id : animation->frames) + image_pool.release(frame_id); + + animation->frames = std::move(new_frame_ids); + + return mrb_nil_value(); +} + +mrb_value animation_frames_get(mrb_state *mrb, mrb_value self) { + Wrapper *self_wrapper = (Wrapper *)DATA_PTR(self); + uint64_t id = self_wrapper->id; + Animation *animation = animation_pool[id]; + + mrb_value frames_array = mrb_ary_new_capa(mrb, animation->frames.size()); + for (uint64_t frame_id : animation->frames) { + image_pool.use(frame_id); + mrb_value frame_obj = definitions::wrap(definitions::bindings.Image, frame_id); + mrb_ary_push(mrb, frames_array, frame_obj); + } + + return frames_array; +} + +mrb_value animation_fps_set(mrb_state *mrb, mrb_value self) { + mrb_float fps; + mrb_get_args(mrb, "f", &fps); + + Wrapper *self_wrapper = (Wrapper *)DATA_PTR(self); + uint64_t id = self_wrapper->id; + Animation *animation = animation_pool[id]; + animation->frame_rate = fps; + + return mrb_nil_value(); +} + +mrb_value animation_fps_get(mrb_state *mrb, mrb_value self) { + Wrapper *self_wrapper = (Wrapper *)DATA_PTR(self); + uint64_t id = self_wrapper->id; + Animation *animation = animation_pool[id]; + return mrb_float_value(mrb, animation->frame_rate); +} +} // namespace + +namespace definitions { +void register_animation() { + DEF_CLASS(Animation, MRB_ARGS_REQ(1) | MRB_ARGS_OPT(1)); + ADD_CLASS_METHOD(Animation, "from", static_image_animation, MRB_ARGS_REQ(1)); + ADD_METHOD(Animation, "==", animation_equal, MRB_ARGS_REQ(1)); + ADD_METHOD(Animation, "eql?", animation_equal, MRB_ARGS_REQ(1)); + ADD_METHOD(Animation, "hash", animation_hash, MRB_ARGS_NONE()); + ADD_METHOD(Animation, "fps=", animation_fps_set, MRB_ARGS_REQ(1)); + ADD_METHOD(Animation, "fps", animation_fps_get, MRB_ARGS_NONE()); + ADD_METHOD(Animation, "frames=", animation_frames_set, MRB_ARGS_REQ(1)); + ADD_METHOD(Animation, "frames", animation_frames_get, MRB_ARGS_NONE()); + bindings.Animation = {Animation_class, &Animation_type}; +} +} // namespace definitions diff --git a/src/bindings/app.cc b/src/bindings/app.cc new file mode 100644 index 0000000..35d7c9e --- /dev/null +++ b/src/bindings/app.cc @@ -0,0 +1,206 @@ +#include "app/app.h" +#include "bindings/definitions.h" + +namespace { +mrb_value app_run(mrb_state *mrb, mrb_value) { + mrb_int width, height; + mrb_value options_hash; + char *title = nullptr; + mrb_get_args(mrb, "iiz|H", &width, &height, &title, &options_hash); + + app_ = new app::App({(float)width, (float)height}, title); + + float fps = 60; + if (!mrb_nil_p(options_hash)) + HASH_FLOAT(options_hash, fps, fps); + + app_->set_fps(fps); + + return mrb_nil_value(); +} + +mrb_value app_fps_get(mrb_state *mrb, mrb_value) { + return mrb_float_value(mrb, app_->get_fps()); +} + +mrb_value app_fps_set(mrb_state *mrb, mrb_value) { + mrb_float fps; + mrb_get_args(mrb, "f", &fps); + app_->set_fps(fps); + return mrb_nil_value(); +} + +mrb_value app_start(mrb_state *mrb, mrb_value) { + mrb_value scene_val; + mrb_get_args(mrb, "o", &scene_val); + + if (!mrb_obj_is_kind_of(mrb, scene_val, mrb_class_get(mrb, "Scene"))) { + mrb_raise(mrb, mrb_class_get(mrb, "Exception"), "Expected a Scene object"); + return mrb_nil_value(); + } + + Wrapper *scene_wrapper = (Wrapper *)DATA_PTR(scene_val); + uint64_t id = scene_wrapper->id; + app_->switch_to_scene(id); + + app_->loop(); + + return mrb_nil_value(); +} + +mrb_value app_current_scene(mrb_state *, mrb_value) { + uint64_t id = app_->current_scene_id; + if (id == UINT64_MAX) + return mrb_nil_value(); + app::scene_pool.use(id); + return definitions::wrap(definitions::bindings.Scene, id); +} + +mrb_value app_on_update(mrb_state *mrb, mrb_value) { + mrb_value block; + mrb_get_args(mrb, "&", &block); + app_->update.set_proc(block); + return mrb_nil_value(); +} + +mrb_value app_switch_to(mrb_state *mrb, mrb_value) { + mrb_value scene_val; + mrb_get_args(mrb, "o", &scene_val); + + if (!mrb_obj_is_kind_of(mrb, scene_val, mrb_class_get(mrb, "Scene"))) { + mrb_raise(mrb, mrb_class_get(mrb, "Exception"), "Expected a Scene object"); + return mrb_nil_value(); + } + + Wrapper *scene_wrapper = (Wrapper *)DATA_PTR(scene_val); + uint64_t id = scene_wrapper->id; + app_->switch_to_scene(id); + + return mrb_nil_value(); +} + +mrb_value app_localize(mrb_state *mrb, mrb_value) { + mrb_sym lang_sym, key_sym; + char *text; + + mrb_get_args(mrb, "nnz", &lang_sym, &key_sym, &text); + + auto lang = Localization::lang_from_sym(mrb, lang_sym); + + const char *key_name = mrb_sym2name(mrb, key_sym); + + auto it = Localization::localization_key_map.find(key_name); + Localization::Key key_id; + + if (it == Localization::localization_key_map.end()) { + key_id = (Localization::Key)Localization::localization_key_map.size(); + Localization::localization_key_map[key_name] = key_id; + } else { + key_id = it->second; + } + + Localization::set(lang, key_id, text); + + return mrb_nil_value(); +} + +mrb_value app_language_set(mrb_state *mrb, mrb_value) { + mrb_sym lang_sym; + mrb_get_args(mrb, "n", &lang_sym); + Localization::current_language = Localization::lang_from_sym(mrb, lang_sym); + return mrb_nil_value(); +} + +mrb_value app_language_get(mrb_state *mrb, mrb_value) { + return mrb_symbol_value(Localization::lang_to_sym(mrb, Localization::current_language)); +} + +mrb_value app_mouse_position(mrb_state *mrb, mrb_value) { + Vec2 mouse_pos = app_->mouse_position; + mrb_value result = mrb_hash_new(mrb); + HASH_SET(result, x, mrb_float_value(mrb, mouse_pos.x)); + HASH_SET(result, y, mrb_float_value(mrb, mouse_pos.y)); + return result; +} + +mrb_value app_is_down(mrb_state *mrb, mrb_value) { + mrb_sym key_sym; + mrb_get_args(mrb, "n", &key_sym); + std::string key_name = mrb_sym2name(mrb, key_sym); + Key key = get_key(key_name); + return mrb_bool_value(app_->down_keys[key]); +} + +mrb_value app_is_pressed(mrb_state *mrb, mrb_value) { + mrb_sym key_sym; + mrb_get_args(mrb, "n", &key_sym); + std::string key_name = mrb_sym2name(mrb, key_sym); + Key key = get_key(key_name); + for (Key pressed_key : app_->pressed_keys) + if (pressed_key == key) + return mrb_bool_value(true); + return mrb_bool_value(false); +} + +mrb_value app_is_released(mrb_state *mrb, mrb_value) { + mrb_sym key_sym; + mrb_get_args(mrb, "n", &key_sym); + std::string key_name = mrb_sym2name(mrb, key_sym); + Key key = get_key(key_name); + for (Key released_key : app_->released_keys) + if (released_key == key) + return mrb_bool_value(true); + return mrb_bool_value(false); +} + +mrb_value app_map_key(mrb_state *mrb, mrb_value) { + mrb_sym key_sym; + mrb_sym action_sym; + mrb_get_args(mrb, "nn", &key_sym, &action_sym); + std::string key_name = mrb_sym2name(mrb, key_sym); + std::string action_name = mrb_sym2name(mrb, action_sym); + set_action_mapping(action_name, key_name); + return mrb_nil_value(); +} + +mrb_value app_scroll(mrb_state *mrb, mrb_value) { + Vec2 scroll = app_->scroll; + mrb_value result = mrb_hash_new(mrb); + HASH_SET(result, x, mrb_float_value(mrb, scroll.x)); + HASH_SET(result, y, mrb_float_value(mrb, scroll.y)); + return result; +} + +mrb_value app_text_input(mrb_state *mrb, mrb_value) { + return mrb_str_new_cstr(mrb, app_->text.c_str()); +} + +mrb_value app_exit(mrb_state *, mrb_value) { + app_->exit(); + return mrb_nil_value(); +} +} // namespace + +namespace definitions { +void register_app() { + DEF_MODULE(App); + ADD_MODULE_METHOD(App, "run", app_run, MRB_ARGS_REQ(3) | MRB_ARGS_OPT(1)); + ADD_MODULE_METHOD(App, "start", app_start, MRB_ARGS_REQ(1)); + ADD_MODULE_METHOD(App, "switch_to", app_switch_to, MRB_ARGS_REQ(1)); + ADD_MODULE_METHOD(App, "scene", app_current_scene, MRB_ARGS_NONE()); + ADD_MODULE_METHOD(App, "update", app_on_update, MRB_ARGS_BLOCK()); + ADD_MODULE_METHOD(App, "fps=", app_fps_set, MRB_ARGS_REQ(1)); + ADD_MODULE_METHOD(App, "fps", app_fps_get, MRB_ARGS_NONE()); + ADD_MODULE_METHOD(App, "localize", app_localize, MRB_ARGS_REQ(3)); + ADD_MODULE_METHOD(App, "language=", app_language_set, MRB_ARGS_REQ(1)); + ADD_MODULE_METHOD(App, "language", app_language_get, MRB_ARGS_NONE()); + ADD_MODULE_METHOD(App, "mouse_position", app_mouse_position, MRB_ARGS_NONE()); + ADD_MODULE_METHOD(App, "down?", app_is_down, MRB_ARGS_REQ(1)); + ADD_MODULE_METHOD(App, "pressed?", app_is_pressed, MRB_ARGS_REQ(1)); + ADD_MODULE_METHOD(App, "released?", app_is_released, MRB_ARGS_REQ(1)); + ADD_MODULE_METHOD(App, "map_key", app_map_key, MRB_ARGS_REQ(2)); + ADD_MODULE_METHOD(App, "scroll", app_scroll, MRB_ARGS_NONE()); + ADD_MODULE_METHOD(App, "text_input", app_text_input, MRB_ARGS_NONE()); + ADD_MODULE_METHOD(App, "exit!", app_exit, MRB_ARGS_NONE()); +} +} // namespace definitions diff --git a/src/bindings/element_image.cc b/src/bindings/element_image.cc new file mode 100644 index 0000000..f2fd742 --- /dev/null +++ b/src/bindings/element_image.cc @@ -0,0 +1,326 @@ +#include "app/app.h" +#include "bindings/definitions.h" + +namespace { +void ElementImage_free(mrb_state *mrb, void *ptr) { + UNUSED(mrb); + uint64_t id = ((Wrapper *)ptr)->id; + app::element_pool.release(id); + delete (Wrapper *)ptr; +} + +const struct mrb_data_type ElementImage_type = { + "ElementImage", + ElementImage_free +}; + +mrb_value ElementImage_init(mrb_state *mrb, mrb_value self) { + Wrapper *old = (Wrapper *)DATA_PTR(self); + if (old) + mrb_free(mrb, old); + mrb_data_init(self, nullptr, &ElementImage_type); + Wrapper *s = new Wrapper(); + + mrb_value animation_val; + mrb_value kwargs; + mrb_get_args(mrb, "o|H", &animation_val, &kwargs); + if (!mrb_obj_is_kind_of( + mrb, + animation_val, + definitions::bindings.Animation.cls + )) { + mrb_raise( + mrb, + mrb_class_get(mrb, "Exception"), + "Expected an Animation object" + ); + return mrb_nil_value(); + } + + float x = 0, y = 0, z = 0, rotation = 0; + float scale_x = 1, scale_y = 1, alpha = 1, pivot_x = 0.5, pivot_y = 0.5; + mrb_sym click_mode_sym = sym_block; + if (!mrb_nil_p(kwargs)) { + mrb_value pos_hash = HASH_GET(kwargs, position); + if (!mrb_nil_p(pos_hash)) { + HASH_FLOAT(pos_hash, x, x); + HASH_FLOAT(pos_hash, y, y); + } + + mrb_value scale_hash = HASH_GET(kwargs, scale); + if (!mrb_nil_p(scale_hash)) { + HASH_FLOAT(scale_hash, x, scale_x); + HASH_FLOAT(scale_hash, y, scale_y); + } + + mrb_value pivot_hash = HASH_GET(kwargs, pivot); + if (!mrb_nil_p(pivot_hash)) { + HASH_FLOAT(pivot_hash, x, pivot_x); + HASH_FLOAT(pivot_hash, y, pivot_y); + } + + HASH_FLOAT(kwargs, z, z); + HASH_FLOAT(kwargs, rotation, rotation); + HASH_FLOAT(kwargs, alpha, alpha); + mrb_value v = HASH_GET(kwargs, click_mode); + if (!mrb_nil_p(v)) { + click_mode_sym = mrb_symbol(v); + } + } + + Wrapper *animation_wrapper = (Wrapper *)DATA_PTR(animation_val); + uint64_t id = animation_wrapper->id; + animation_pool.use(id); + + app::EImage *element = new app::EImage(id); + element->position = {x, y}; + element->scale = {scale_x, scale_y}; + element->rotation = rotation; + element->pivot = {pivot_x, pivot_y}; + element->alpha = alpha; + element->z = z; + + std::string click_mode = mrb_sym2name(mrb, click_mode_sym); + + if (click_mode == "pass") + element->click_mode = ClickMode::PASS; + else if (click_mode == "block") + element->click_mode = ClickMode::BLOCK; + else if (click_mode == "ignore") + element->click_mode = ClickMode::IGNORE; + + s->id = app::element_pool.acquire(element); + app::element_pool.use(s->id); + + mrb_data_init(self, s, &ElementImage_type); + return self; +} + +mrb_value element_image_on_click(mrb_state *mrb, mrb_value self) { + mrb_value block; + mrb_get_args(mrb, "&", &block); + Wrapper *wrapper = (Wrapper *)DATA_PTR(self); + uint64_t id = wrapper->id; + app::Element *element = app::element_pool[id]; + element->on_click.set_proc(block); + return self; +} + +mrb_value element_image_equal(mrb_state *mrb, mrb_value self) { + mrb_value other; + mrb_get_args(mrb, "o", &other); + + if (!mrb_obj_is_kind_of(mrb, other, definitions::bindings.ElementImage.cls)) + return mrb_false_value(); + + Wrapper *wrapper_self = (Wrapper *)DATA_PTR(self); + Wrapper *wrapper_other = (Wrapper *)DATA_PTR(other); + return mrb_bool_value(wrapper_self->id == wrapper_other->id); +} + +mrb_value element_image_inspect(mrb_state *mrb, mrb_value self) { + Wrapper *wrapper = (Wrapper *)DATA_PTR(self); + uint64_t id = wrapper->id; + app::EImage *element = (app::EImage *)app::element_pool[id]; + std::string str = "#animation_id) + + ">"; + return mrb_str_new_cstr(mrb, str.c_str()); +} + +mrb_value element_image_hash(mrb_state *, mrb_value self) { + Wrapper *wrapper = (Wrapper *)DATA_PTR(self); + return mrb_fixnum_value(wrapper->id); +} + +mrb_value element_image_animation_set(mrb_state *mrb, mrb_value self) { + mrb_value animation; + mrb_get_args(mrb, "o", &animation); + + if (!mrb_obj_is_kind_of( + mrb, + animation, + definitions::bindings.Animation.cls + )) { + mrb_raise( + mrb, + mrb_class_get(mrb, "Exception"), + "Expected an Animation object" + ); + return mrb_nil_value(); + } + + Wrapper *animation_wrapper = (Wrapper *)DATA_PTR(animation); + uint64_t animation_id = animation_wrapper->id; + Wrapper *wrapper = (Wrapper *)DATA_PTR(self); + uint64_t id = wrapper->id; + app::EImage *element = (app::EImage *)app::element_pool[id]; + + animation_pool.use(animation_id); + animation_pool.release(element->animation_id); + + element->animation_id = animation_id; + + return self; +} + +mrb_value element_image_animation_get(mrb_state *, mrb_value self) { + Wrapper *wrapper = (Wrapper *)DATA_PTR(self); + uint64_t id = wrapper->id; + app::EImage *element = (app::EImage *)app::element_pool[id]; + uint64_t animation_id = element->animation_id; + if (animation_id == UINT64_MAX) + return mrb_nil_value(); + animation_pool.use(animation_id); + return definitions::wrap(definitions::bindings.Animation, animation_id); +} + +mrb_value element_image_position_get(mrb_state *, mrb_value self) { + Wrapper *wrapper = (Wrapper *)DATA_PTR(self); + uint64_t id = wrapper->id; + + app::EImage *element = (app::EImage *)app::element_pool[id]; + return definitions::Vec2_wrap(id, &element->position); +} + +mrb_value element_image_rotation_get(mrb_state *mrb, mrb_value self) { + Wrapper *wrapper = (Wrapper *)DATA_PTR(self); + uint64_t id = wrapper->id; + app::EImage *element = (app::EImage *)app::element_pool[id]; + return mrb_float_value(mrb, element->rotation); +} + +mrb_value element_image_rotation_set(mrb_state *mrb, mrb_value self) { + mrb_float rotation; + mrb_get_args(mrb, "f", &rotation); + + Wrapper *wrapper = (Wrapper *)DATA_PTR(self); + uint64_t id = wrapper->id; + app::EImage *element = (app::EImage *)app::element_pool[id]; + element->rotation = rotation; + + return mrb_nil_value(); +} + +mrb_value element_image_pivot_get(mrb_state *, mrb_value self) { + Wrapper *wrapper = (Wrapper *)DATA_PTR(self); + uint64_t id = wrapper->id; + app::EImage *element = (app::EImage *)app::element_pool[id]; + return definitions::Vec2_wrap(id, &element->pivot); +} + +mrb_value element_image_scale_get(mrb_state *, mrb_value self) { + Wrapper *wrapper = (Wrapper *)DATA_PTR(self); + uint64_t id = wrapper->id; + app::EImage *element = (app::EImage *)app::element_pool[id]; + return definitions::Vec2_wrap(id, &element->scale); +} + +mrb_value element_image_alpha_get(mrb_state *mrb, mrb_value self) { + Wrapper *wrapper = (Wrapper *)DATA_PTR(self); + uint64_t id = wrapper->id; + app::EImage *element = (app::EImage *)app::element_pool[id]; + return mrb_float_value(mrb, element->alpha); +} + +mrb_value element_image_alpha_set(mrb_state *mrb, mrb_value self) { + mrb_float alpha; + mrb_get_args(mrb, "f", &alpha); + + Wrapper *wrapper = (Wrapper *)DATA_PTR(self); + uint64_t id = wrapper->id; + app::EImage *element = (app::EImage *)app::element_pool[id]; + element->alpha = alpha; + + return mrb_nil_value(); +} + +mrb_value element_image_z_get(mrb_state *mrb, mrb_value self) { + Wrapper *wrapper = (Wrapper *)DATA_PTR(self); + uint64_t id = wrapper->id; + app::EImage *element = (app::EImage *)app::element_pool[id]; + return mrb_float_value(mrb, element->z); +} + +mrb_value element_image_z_set(mrb_state *mrb, mrb_value self) { + mrb_float z; + mrb_get_args(mrb, "f", &z); + + Wrapper *wrapper = (Wrapper *)DATA_PTR(self); + uint64_t id = wrapper->id; + app::EImage *element = (app::EImage *)app::element_pool[id]; + element->z = z; + + return mrb_nil_value(); +} + +mrb_value element_image_click_mode_get(mrb_state *mrb, mrb_value self) { + Wrapper *wrapper = (Wrapper *)DATA_PTR(self); + uint64_t id = wrapper->id; + app::EImage *element = (app::EImage *)app::element_pool[id]; + + std::string click_mode_str; + switch (element->click_mode) { + case ClickMode::PASS: + click_mode_str = "pass"; + break; + case ClickMode::BLOCK: + click_mode_str = "block"; + break; + case ClickMode::IGNORE: + click_mode_str = "ignore"; + break; + } + + return mrb_symbol_value(mrb_intern_cstr(mrb, click_mode_str.c_str())); +} + +mrb_value element_image_click_mode_set(mrb_state *mrb, mrb_value self) { + mrb_sym click_mode_sym; + mrb_get_args(mrb, "n", &click_mode_sym); + + Wrapper *wrapper = (Wrapper *)DATA_PTR(self); + uint64_t id = wrapper->id; + app::EImage *element = (app::EImage *)app::element_pool[id]; + + std::string click_mode = mrb_sym2name(mrb, click_mode_sym); + + if (click_mode == "pass") + element->click_mode = ClickMode::PASS; + else if (click_mode == "block") + element->click_mode = ClickMode::BLOCK; + else if (click_mode == "ignore") + element->click_mode = ClickMode::IGNORE; + + return mrb_nil_value(); +} +} // namespace + +namespace definitions { +void register_element_image() { + DEF_CLASS(ElementImage, MRB_ARGS_REQ(1) | MRB_ARGS_OPT(1)); + ADD_METHOD(ElementImage, "click", element_image_on_click, MRB_ARGS_BLOCK()); + ADD_METHOD(ElementImage, "==", element_image_equal, MRB_ARGS_REQ(1)); + ADD_METHOD(ElementImage, "eql?", element_image_equal, MRB_ARGS_REQ(1)); + ADD_METHOD(ElementImage, "inspect", element_image_inspect, MRB_ARGS_NONE()); + ADD_METHOD(ElementImage, "to_s", element_image_inspect, MRB_ARGS_NONE()); + ADD_METHOD(ElementImage, "hash", element_image_hash, MRB_ARGS_NONE()); + ADD_METHOD(ElementImage, "animation=", element_image_animation_set, MRB_ARGS_REQ(1)); + ADD_METHOD(ElementImage, "animation", element_image_animation_get, MRB_ARGS_NONE()); + ADD_METHOD(ElementImage, "position", element_image_position_get, MRB_ARGS_NONE()); + ADD_METHOD(ElementImage, "scale", element_image_scale_get, MRB_ARGS_NONE()); + ADD_METHOD(ElementImage, "rotation=", element_image_rotation_set, MRB_ARGS_REQ(1)); + ADD_METHOD(ElementImage, "rotation", element_image_rotation_get, MRB_ARGS_NONE()); + ADD_METHOD(ElementImage, "pivot", element_image_pivot_get, MRB_ARGS_NONE()); + ADD_METHOD(ElementImage, "alpha=", element_image_alpha_set, MRB_ARGS_REQ(1)); + ADD_METHOD(ElementImage, "alpha", element_image_alpha_get, MRB_ARGS_NONE()); + ADD_METHOD(ElementImage, "z=", element_image_z_set, MRB_ARGS_REQ(1)); + ADD_METHOD(ElementImage, "z", element_image_z_get, MRB_ARGS_NONE()); + ADD_METHOD(ElementImage, "click_mode=", element_image_click_mode_set, MRB_ARGS_REQ(1)); + ADD_METHOD(ElementImage, "click_mode", element_image_click_mode_get, MRB_ARGS_NONE()); + + bindings.ElementImage = {ElementImage_class, &ElementImage_type}; +} +} // namespace definitions \ No newline at end of file diff --git a/src/bindings/element_rect.cc b/src/bindings/element_rect.cc new file mode 100644 index 0000000..ace8c25 --- /dev/null +++ b/src/bindings/element_rect.cc @@ -0,0 +1,349 @@ +#include "app/app.h" +#include "bindings/definitions.h" + +namespace { +void ElementRect_free(mrb_state *mrb, void *ptr) { + UNUSED(mrb); + uint64_t id = ((Wrapper *)ptr)->id; + app::element_pool.release(id); + delete (Wrapper *)ptr; +} + +const struct mrb_data_type ElementRect_type = { + "ElementRect", + ElementRect_free +}; + +mrb_value ElementRect_init(mrb_state *mrb, mrb_value self) { + Wrapper *old = (Wrapper *)DATA_PTR(self); + if (old) + mrb_free(mrb, old); + mrb_data_init(self, nullptr, &ElementRect_type); + Wrapper *s = new Wrapper(); + + mrb_float w, h; + mrb_int color_i = 0xFFFFFF; + mrb_value kwargs; + mrb_get_args(mrb, "ffi|H", &w, &h, &color_i, &kwargs); + + float x = 0, y = 0, z = 0, rotation = 0; + float scale_x = 1, scale_y = 1, alpha = 1, pivot_x = 0.5, pivot_y = 0.5; + mrb_sym click_mode_sym = sym_block; + if (!mrb_nil_p(kwargs)) { + mrb_value pos_hash = HASH_GET(kwargs, position); + if (!mrb_nil_p(pos_hash)) { + HASH_FLOAT(pos_hash, x, x); + HASH_FLOAT(pos_hash, y, y); + } + + mrb_value scale_hash = HASH_GET(kwargs, scale); + if (!mrb_nil_p(scale_hash)) { + HASH_FLOAT(scale_hash, x, scale_x); + HASH_FLOAT(scale_hash, y, scale_y); + } + + mrb_value pivot_hash = HASH_GET(kwargs, pivot); + if (!mrb_nil_p(pivot_hash)) { + HASH_FLOAT(pivot_hash, x, pivot_x); + HASH_FLOAT(pivot_hash, y, pivot_y); + } + + HASH_FLOAT(kwargs, z, z); + HASH_FLOAT(kwargs, rotation, rotation); + HASH_FLOAT(kwargs, alpha, alpha); + mrb_value v = HASH_GET(kwargs, click_mode); + if (!mrb_nil_p(v)) { + click_mode_sym = mrb_symbol(v); + } + } + + Vec2 shape = {(float)w, (float)h}; + + Color color = { + (uint8_t)((color_i >> 16) & 0xFF), + (uint8_t)((color_i >> 8) & 0xFF), + (uint8_t)((color_i) & 0xFF) + }; + + app::ERect *element = new app::ERect( + shape, + color + ); + element->position = {x, y}; + element->scale = {scale_x, scale_y}; + element->rotation = rotation; + element->pivot = {pivot_x, pivot_y}; + element->alpha = alpha; + element->z = z; + + std::string click_mode = mrb_sym2name(mrb, click_mode_sym); + + if (click_mode == "pass") + element->click_mode = ClickMode::PASS; + else if (click_mode == "block") + element->click_mode = ClickMode::BLOCK; + else if (click_mode == "ignore") + element->click_mode = ClickMode::IGNORE; + + s->id = app::element_pool.acquire(element); + app::element_pool.use(s->id); + + mrb_data_init(self, s, &ElementRect_type); + return self; +} + +mrb_value element_rect_on_click(mrb_state *mrb, mrb_value self) { + mrb_value block; + mrb_get_args(mrb, "&", &block); + Wrapper *wrapper = (Wrapper *)DATA_PTR(self); + uint64_t id = wrapper->id; + app::Element *element = app::element_pool[id]; + element->on_click.set_proc(block); + return self; +} + +mrb_value element_rect_width_set(mrb_state *mrb, mrb_value self) { + mrb_float width; + mrb_get_args(mrb, "f", &width); + + Wrapper *wrapper = (Wrapper *)DATA_PTR(self); + uint64_t id = wrapper->id; + app::ERect *element = (app::ERect *)app::element_pool[id]; + element->shape.x = width; + + return mrb_nil_value(); +} + +mrb_value element_rect_width_get(mrb_state *mrb, mrb_value self) { + Wrapper *wrapper = (Wrapper *)DATA_PTR(self); + uint64_t id = wrapper->id; + app::ERect *element = (app::ERect *)app::element_pool[id]; + return mrb_float_value(mrb, element->shape.x); +} + +mrb_value element_rect_height_set(mrb_state *mrb, mrb_value self) { + mrb_float height; + mrb_get_args(mrb, "f", &height); + + Wrapper *wrapper = (Wrapper *)DATA_PTR(self); + uint64_t id = wrapper->id; + app::ERect *element = (app::ERect *)app::element_pool[id]; + element->shape.y = height; + + return mrb_nil_value(); +} + +mrb_value element_rect_height_get(mrb_state *mrb, mrb_value self) { + Wrapper *wrapper = (Wrapper *)DATA_PTR(self); + uint64_t id = wrapper->id; + app::ERect *element = (app::ERect *)app::element_pool[id]; + return mrb_float_value(mrb, element->shape.y); +} + +mrb_value element_rect_color_set(mrb_state *mrb, mrb_value self) { + mrb_value color_val; + mrb_get_args(mrb, "o", &color_val); + Wrapper *wrapper = (Wrapper *)DATA_PTR(self); + uint64_t id = wrapper->id; + app::ERect *element = (app::ERect *)app::element_pool[id]; + element->color = { + (uint8_t)((mrb_fixnum(color_val) >> 16) & 0xFF), + (uint8_t)((mrb_fixnum(color_val) >> 8) & 0xFF), + (uint8_t)((mrb_fixnum(color_val)) & 0xFF) + }; + return self; +} + +mrb_value element_rect_color_get(mrb_state *, mrb_value self) { + Wrapper *wrapper = (Wrapper *)DATA_PTR(self); + uint64_t id = wrapper->id; + app::ERect *element = (app::ERect *)app::element_pool[id]; + uint32_t color = + ((uint32_t)element->color.r << 16) | ((uint32_t)element->color.g << 8) + | ((uint32_t)element->color.b); + return mrb_fixnum_value(color); +} + +mrb_value element_rect_equal(mrb_state *mrb, mrb_value self) { + mrb_value other; + mrb_get_args(mrb, "o", &other); + + if (!mrb_obj_is_kind_of(mrb, other, definitions::bindings.ElementRect.cls)) + return mrb_false_value(); + + Wrapper *wrapper_self = (Wrapper *)DATA_PTR(self); + Wrapper *wrapper_other = (Wrapper *)DATA_PTR(other); + uint64_t id_self = wrapper_self->id; + uint64_t id_other = wrapper_other->id; + + return mrb_bool_value(id_self == id_other); +} + +mrb_value element_rect_inspect(mrb_state *mrb, mrb_value self) { + Wrapper *wrapper = (Wrapper *)DATA_PTR(self); + uint64_t id = wrapper->id; + app::ERect *element = (app::ERect *)app::element_pool[id]; + std::string str = "#shape.x) + + " height=" + std::format("{}", element->shape.y) + + ">"; + return mrb_str_new_cstr(mrb, str.c_str()); +} + +mrb_value element_rect_hash(mrb_state *, mrb_value self) { + Wrapper *wrapper = (Wrapper *)DATA_PTR(self); + uint64_t id = wrapper->id; + return mrb_fixnum_value(id); +} + +mrb_value element_rect_position_get(mrb_state *, mrb_value self) { + Wrapper *wrapper = (Wrapper *)DATA_PTR(self); + uint64_t id = wrapper->id; + app::ERect *element = (app::ERect *)app::element_pool[id]; + return definitions::Vec2_wrap(id, &element->position); +} + +mrb_value element_rect_rotation_get(mrb_state *mrb, mrb_value self) { + Wrapper *wrapper = (Wrapper *)DATA_PTR(self); + uint64_t id = wrapper->id; + app::ERect *element = (app::ERect *)app::element_pool[id]; + return mrb_float_value(mrb, element->rotation); +} + +mrb_value element_rect_rotation_set(mrb_state *mrb, mrb_value self) { + mrb_float rotation; + mrb_get_args(mrb, "f", &rotation); + + Wrapper *wrapper = (Wrapper *)DATA_PTR(self); + uint64_t id = wrapper->id; + app::ERect *element = (app::ERect *)app::element_pool[id]; + element->rotation = rotation; + + return mrb_nil_value(); +} + +mrb_value element_rect_pivot_get(mrb_state *, mrb_value self) { + Wrapper *wrapper = (Wrapper *)DATA_PTR(self); + uint64_t id = wrapper->id; + app::ERect *element = (app::ERect *)app::element_pool[id]; + return definitions::Vec2_wrap(id, &element->pivot); +} + +mrb_value element_rect_scale_get(mrb_state *, mrb_value self) { + Wrapper *wrapper = (Wrapper *)DATA_PTR(self); + uint64_t id = wrapper->id; + app::ERect *element = (app::ERect *)app::element_pool[id]; + return definitions::Vec2_wrap(id, &element->scale); +} + +mrb_value element_rect_alpha_get(mrb_state *mrb, mrb_value self) { + Wrapper *wrapper = (Wrapper *)DATA_PTR(self); + uint64_t id = wrapper->id; + app::ERect *element = (app::ERect *)app::element_pool[id]; + return mrb_float_value(mrb, element->alpha); +} + +mrb_value element_rect_alpha_set(mrb_state *mrb, mrb_value self) { + mrb_float alpha; + mrb_get_args(mrb, "f", &alpha); + + Wrapper *wrapper = (Wrapper *)DATA_PTR(self); + uint64_t id = wrapper->id; + app::ERect *element = (app::ERect *)app::element_pool[id]; + element->alpha = alpha; + + return mrb_nil_value(); +} + +mrb_value element_rect_z_get(mrb_state *mrb, mrb_value self) { + Wrapper *wrapper = (Wrapper *)DATA_PTR(self); + uint64_t id = wrapper->id; + app::ERect *element = (app::ERect *)app::element_pool[id]; + return mrb_float_value(mrb, element->z); +} + +mrb_value element_rect_z_set(mrb_state *mrb, mrb_value self) { + mrb_float z; + mrb_get_args(mrb, "f", &z); + + Wrapper *wrapper = (Wrapper *)DATA_PTR(self); + uint64_t id = wrapper->id; + app::ERect *element = (app::ERect *)app::element_pool[id]; + element->z = z; + + return mrb_nil_value(); +} + +mrb_value element_rect_click_mode_get(mrb_state *mrb, mrb_value self) { + Wrapper *wrapper = (Wrapper *)DATA_PTR(self); + uint64_t id = wrapper->id; + app::ERect *element = (app::ERect *)app::element_pool[id]; + + std::string click_mode_str; + switch (element->click_mode) { + case ClickMode::PASS: + click_mode_str = "pass"; + break; + case ClickMode::BLOCK: + click_mode_str = "block"; + break; + case ClickMode::IGNORE: + click_mode_str = "ignore"; + break; + } + + return mrb_symbol_value(mrb_intern_cstr(mrb, click_mode_str.c_str())); +} + +mrb_value element_rect_click_mode_set(mrb_state *mrb, mrb_value self) { + mrb_sym click_mode_sym; + mrb_get_args(mrb, "n", &click_mode_sym); + + Wrapper *wrapper = (Wrapper *)DATA_PTR(self); + uint64_t id = wrapper->id; + app::ERect *element = (app::ERect *)app::element_pool[id]; + + std::string click_mode = mrb_sym2name(mrb, click_mode_sym); + + if (click_mode == "pass") + element->click_mode = ClickMode::PASS; + else if (click_mode == "block") + element->click_mode = ClickMode::BLOCK; + else if (click_mode == "ignore") + element->click_mode = ClickMode::IGNORE; + + return mrb_nil_value(); +} +} // namespace + +namespace definitions { +void register_element_rect() { + DEF_CLASS(ElementRect, MRB_ARGS_REQ(3) | MRB_ARGS_OPT(1)); + ADD_METHOD(ElementRect, "==", element_rect_equal, MRB_ARGS_REQ(1)); + ADD_METHOD(ElementRect, "eql?", element_rect_equal, MRB_ARGS_REQ(1)); + ADD_METHOD(ElementRect, "inspect", element_rect_inspect, MRB_ARGS_NONE()); + ADD_METHOD(ElementRect, "to_s", element_rect_inspect, MRB_ARGS_NONE()); + ADD_METHOD(ElementRect, "hash", element_rect_hash, MRB_ARGS_NONE()); + ADD_METHOD(ElementRect, "click", element_rect_on_click, MRB_ARGS_BLOCK()); + ADD_METHOD(ElementRect, "width=", element_rect_width_set, MRB_ARGS_REQ(1)); + ADD_METHOD(ElementRect, "width", element_rect_width_get, MRB_ARGS_NONE()); + ADD_METHOD(ElementRect, "height=", element_rect_height_set, MRB_ARGS_REQ(1)); + ADD_METHOD(ElementRect, "height", element_rect_height_get, MRB_ARGS_NONE()); + ADD_METHOD(ElementRect, "color=", element_rect_color_set, MRB_ARGS_REQ(1)); + ADD_METHOD(ElementRect, "color", element_rect_color_get, MRB_ARGS_NONE()); + ADD_METHOD(ElementRect, "position", element_rect_position_get, MRB_ARGS_NONE()); + ADD_METHOD(ElementRect, "scale", element_rect_scale_get, MRB_ARGS_NONE()); + ADD_METHOD(ElementRect, "rotation=", element_rect_rotation_set, MRB_ARGS_REQ(1)); + ADD_METHOD(ElementRect, "rotation", element_rect_rotation_get, MRB_ARGS_NONE()); + ADD_METHOD(ElementRect, "pivot", element_rect_pivot_get, MRB_ARGS_NONE()); + ADD_METHOD(ElementRect, "alpha=", element_rect_alpha_set, MRB_ARGS_REQ(1)); + ADD_METHOD(ElementRect, "alpha", element_rect_alpha_get, MRB_ARGS_NONE()); + ADD_METHOD(ElementRect, "z=", element_rect_z_set, MRB_ARGS_REQ(1)); + ADD_METHOD(ElementRect, "z", element_rect_z_get, MRB_ARGS_NONE()); + ADD_METHOD(ElementRect, "click_mode=", element_rect_click_mode_set, MRB_ARGS_REQ(1)); + ADD_METHOD(ElementRect, "click_mode", element_rect_click_mode_get, MRB_ARGS_NONE()); + + bindings.ElementRect = {ElementRect_class, &ElementRect_type}; +} +} // namespace definitions \ No newline at end of file diff --git a/src/bindings/element_text.cc b/src/bindings/element_text.cc new file mode 100644 index 0000000..1e84dc2 --- /dev/null +++ b/src/bindings/element_text.cc @@ -0,0 +1,411 @@ +#include "app/app.h" +#include "bindings/definitions.h" + +namespace { +void ElementText_free(mrb_state *mrb, void *ptr) { + UNUSED(mrb); + uint64_t id = ((Wrapper *)ptr)->id; + app::element_pool.release(id); + delete (Wrapper *)ptr; +} + +const struct mrb_data_type ElementText_type = { + "ElementText", ElementText_free +}; + +mrb_value ElementText_init(mrb_state *mrb, mrb_value self) { + Wrapper *old = (Wrapper *)DATA_PTR(self); + if (old) + mrb_free(mrb, old); + mrb_data_init(self, nullptr, &ElementText_type); + Wrapper *s = new Wrapper(); + + mrb_sym key; + mrb_value font_val; + mrb_int color_i = 0xFFFFFF; + mrb_value t_args; + mrb_value kwargs; + mrb_get_args(mrb, "noi|HH", &key, &font_val, &color_i, &t_args, &kwargs); + + auto key_id = Localization::key_from_sym(mrb, key); + + if (!mrb_obj_is_kind_of(mrb, font_val, definitions::bindings.Font.cls)) { + mrb_raise(mrb, mrb_class_get(mrb, "Exception"), "Expected a Font object"); + return mrb_nil_value(); + } + + float x = 0, y = 0, z = 0, rotation = 0; + float scale_x = 1, scale_y = 1, alpha = 1; + float pivot_x = 0.5, pivot_y = 0.5; + mrb_sym click_mode_sym = sym_block; + if (!mrb_nil_p(kwargs)) { + mrb_value pos_hash = HASH_GET(kwargs, position); + if (!mrb_nil_p(pos_hash)) { + HASH_FLOAT(pos_hash, x, x); + HASH_FLOAT(pos_hash, y, y); + } + + mrb_value scale_hash = HASH_GET(kwargs, scale); + if (!mrb_nil_p(scale_hash)) { + HASH_FLOAT(scale_hash, x, scale_x); + HASH_FLOAT(scale_hash, y, scale_y); + } + + mrb_value pivot_hash = HASH_GET(kwargs, pivot); + if (!mrb_nil_p(pivot_hash)) { + HASH_FLOAT(pivot_hash, x, pivot_x); + HASH_FLOAT(pivot_hash, y, pivot_y); + } + + HASH_FLOAT(kwargs, z, z); + HASH_FLOAT(kwargs, rotation, rotation); + HASH_FLOAT(kwargs, alpha, alpha); + mrb_value v = HASH_GET(kwargs, click_mode); + if (!mrb_nil_p(v)) { + click_mode_sym = mrb_symbol(v); + } + } + + Wrapper *font_wrapper = (Wrapper *)DATA_PTR(font_val); + uint64_t id = font_wrapper->id; + font_pool.use(id); + + Color color = { + (uint8_t)((color_i >> 16) & 0xFF), + (uint8_t)((color_i >> 8) & 0xFF), + (uint8_t)((color_i) & 0xFF) + }; + + std::unordered_map params; + if (!mrb_nil_p(t_args)) { + mrb_value keys = mrb_hash_keys(mrb, t_args); + for (mrb_int i = 0; i < RARRAY_LEN(keys); i++) { + mrb_value key = RARRAY_PTR(keys)[i]; + mrb_value val = mrb_hash_get(mrb, t_args, key); + params[mrb_str_to_cstr(mrb, mrb_obj_as_string(mrb, key))] = + mrb_str_to_cstr(mrb, mrb_obj_as_string(mrb, val)); + } + } + + app::EText *element = new app::EText(key_id, id, color, params); + element->position = {x, y}; + element->scale = {scale_x, scale_y}; + element->rotation = rotation; + element->pivot = {pivot_x, pivot_y}; + element->alpha = alpha; + element->z = z; + + std::string click_mode = mrb_sym2name(mrb, click_mode_sym); + + if (click_mode == "pass") + element->click_mode = ClickMode::PASS; + else if (click_mode == "block") + element->click_mode = ClickMode::BLOCK; + else if (click_mode == "ignore") + element->click_mode = ClickMode::IGNORE; + + s->id = app::element_pool.acquire(element); + app::element_pool.use(s->id); + + mrb_data_init(self, s, &ElementText_type); + return self; +} + +mrb_value element_text_on_click(mrb_state *mrb, mrb_value self) { + mrb_value block; + mrb_get_args(mrb, "&", &block); + Wrapper *wrapper = (Wrapper *)DATA_PTR(self); + uint64_t id = wrapper->id; + app::Element *element = app::element_pool[id]; + element->on_click.set_proc(block); + return self; +} + +mrb_value element_text_equal(mrb_state *mrb, mrb_value self) { + mrb_value other; + mrb_get_args(mrb, "o", &other); + + if (!mrb_obj_is_kind_of(mrb, other, definitions::bindings.ElementText.cls)) + return mrb_false_value(); + + Wrapper *self_wrapper = (Wrapper *)DATA_PTR(self); + Wrapper *other_wrapper = (Wrapper *)DATA_PTR(other); + + return mrb_bool_value(self_wrapper->id == other_wrapper->id); +} + +mrb_value element_text_inspect(mrb_state *mrb, mrb_value self) { + Wrapper *wrapper = (Wrapper *)DATA_PTR(self); + uint64_t id = wrapper->id; + app::EText *element = (app::EText *)app::element_pool[id]; + std::string str = "#key) + + " font_id=" + std::format("0x{:016x}", element->font_id) + + ">"; + return mrb_str_new_cstr(mrb, str.c_str()); +} + +mrb_value element_text_to_s(mrb_state *mrb, mrb_value self) { + Wrapper *wrapper = (Wrapper *)DATA_PTR(self); + uint64_t id = wrapper->id; + app::EText *element = (app::EText *)app::element_pool[id]; + std::string localized_text = Localization::get(element->key, element->params); + return mrb_str_new_cstr(mrb, localized_text.c_str()); +} + +mrb_value element_text_hash(mrb_state *, mrb_value self) { + Wrapper *wrapper = (Wrapper *)DATA_PTR(self); + return mrb_fixnum_value(wrapper->id); +} + +mrb_value element_text_key_get(mrb_state *mrb, mrb_value self) { + Wrapper *wrapper = (Wrapper *)DATA_PTR(self); + uint64_t id = wrapper->id; + app::EText *element = (app::EText *)app::element_pool[id]; + return mrb_symbol_value(Localization::lang_to_sym(mrb, element->key)); +} + +mrb_value element_text_key_set(mrb_state *mrb, mrb_value self) { + mrb_sym key_sym; + mrb_get_args(mrb, "n", &key_sym); + + Wrapper *wrapper = (Wrapper *)DATA_PTR(self); + uint64_t id = wrapper->id; + app::EText *element = (app::EText *)app::element_pool[id]; + element->key = Localization::lang_from_sym(mrb, key_sym); + + return mrb_nil_value(); +} + +mrb_value element_text_font_get(mrb_state *, mrb_value self) { + Wrapper *wrapper = (Wrapper *)DATA_PTR(self); + uint64_t id = wrapper->id; + app::EText *element = (app::EText *)app::element_pool[id]; + if (element->font_id == UINT64_MAX) + return mrb_nil_value(); + font_pool.use(element->font_id); + return wrap(definitions::bindings.Font, element->font_id); +} + +mrb_value element_text_params(mrb_state *, mrb_value self) { + Wrapper *wrapper = (Wrapper *)DATA_PTR(self); + uint64_t id = wrapper->id; + app::element_pool.use(id); + return wrap(definitions::bindings.Params, id); +} + +mrb_value element_text_font_set(mrb_state *mrb, mrb_value self) { + mrb_value font_val; + mrb_get_args(mrb, "o", &font_val); + + if (!mrb_obj_is_kind_of(mrb, font_val, definitions::bindings.Font.cls)) { + mrb_raise(mrb, mrb_class_get(mrb, "Exception"), "Expected a Font object"); + return mrb_nil_value(); + } + + Wrapper *font_wrapper = (Wrapper *)DATA_PTR(font_val); + uint64_t font_id = font_wrapper->id; + + Wrapper *self_wrapper = (Wrapper *)DATA_PTR(self); + uint64_t id = self_wrapper->id; + + app::EText *element = (app::EText *)app::element_pool[id]; + if (element->font_id != UINT64_MAX) + font_pool.release(element->font_id); + element->font_id = font_id; + font_pool.use(font_id); + + return mrb_nil_value(); +} + +mrb_value element_text_color_get(mrb_state *, mrb_value self) { + Wrapper *wrapper = (Wrapper *)DATA_PTR(self); + uint64_t id = wrapper->id; + app::EText *element = (app::EText *)app::element_pool[id]; + return mrb_fixnum_value( + (element->color.r << 16) | (element->color.g << 8) | (element->color.b) + ); +} + +mrb_value element_text_color_set(mrb_state *mrb, mrb_value self) { + mrb_int color_val; + mrb_get_args(mrb, "i", &color_val); + Wrapper *wrapper = (Wrapper *)DATA_PTR(self); + uint64_t id = wrapper->id; + app::EText *element = (app::EText *)app::element_pool[id]; + element->color = { + (uint8_t)((color_val >> 16) & 0xFF), + (uint8_t)((color_val >> 8) & 0xFF), + (uint8_t)((color_val) & 0xFF) + }; + return mrb_nil_value(); +} + +mrb_value element_text_position_get(mrb_state *, mrb_value self) { + Wrapper *wrapper = (Wrapper *)DATA_PTR(self); + uint64_t id = wrapper->id; + app::EText *element = (app::EText *)app::element_pool[id]; + return definitions::Vec2_wrap(id, &element->position); +} + +mrb_value element_text_rotation_get(mrb_state *mrb, mrb_value self) { + Wrapper *wrapper = (Wrapper *)DATA_PTR(self); + uint64_t id = wrapper->id; + app::EText *element = (app::EText *)app::element_pool[id]; + return mrb_float_value(mrb, element->rotation); +} + +mrb_value element_text_rotation_set(mrb_state *mrb, mrb_value self) { + mrb_float rotation; + mrb_get_args(mrb, "f", &rotation); + + Wrapper *wrapper = (Wrapper *)DATA_PTR(self); + uint64_t id = wrapper->id; + app::EText *element = (app::EText *)app::element_pool[id]; + element->rotation = rotation; + + return mrb_nil_value(); +} + +mrb_value element_text_pivot_get(mrb_state *, mrb_value self) { + Wrapper *wrapper = (Wrapper *)DATA_PTR(self); + uint64_t id = wrapper->id; + app::EText *element = (app::EText *)app::element_pool[id]; + return definitions::Vec2_wrap(id, &element->pivot); +} + +mrb_value element_text_scale_get(mrb_state *, mrb_value self) { + Wrapper *wrapper = (Wrapper *)DATA_PTR(self); + uint64_t id = wrapper->id; + app::EText *element = (app::EText *)app::element_pool[id]; + return definitions::Vec2_wrap(id, &element->scale); +} + +mrb_value element_text_alpha_get(mrb_state *mrb, mrb_value self) { + Wrapper *wrapper = (Wrapper *)DATA_PTR(self); + uint64_t id = wrapper->id; + app::EText *element = (app::EText *)app::element_pool[id]; + return mrb_float_value(mrb, element->alpha); +} + +mrb_value element_text_alpha_set(mrb_state *mrb, mrb_value self) { + mrb_float alpha; + mrb_get_args(mrb, "f", &alpha); + + Wrapper *wrapper = (Wrapper *)DATA_PTR(self); + uint64_t id = wrapper->id; + app::EText *element = (app::EText *)app::element_pool[id]; + element->alpha = alpha; + + return mrb_nil_value(); +} + +mrb_value element_text_z_get(mrb_state *mrb, mrb_value self) { + Wrapper *wrapper = (Wrapper *)DATA_PTR(self); + uint64_t id = wrapper->id; + app::EText *element = (app::EText *)app::element_pool[id]; + return mrb_float_value(mrb, element->z); +} + +mrb_value element_text_z_set(mrb_state *mrb, mrb_value self) { + mrb_float z; + mrb_get_args(mrb, "f", &z); + + Wrapper *wrapper = (Wrapper *)DATA_PTR(self); + uint64_t id = wrapper->id; + app::EText *element = (app::EText *)app::element_pool[id]; + element->z = z; + + return mrb_nil_value(); +} + +mrb_value element_text_click_mode_get(mrb_state *mrb, mrb_value self) { + Wrapper *wrapper = (Wrapper *)DATA_PTR(self); + uint64_t id = wrapper->id; + app::EText *element = (app::EText *)app::element_pool[id]; + + std::string click_mode_str; + switch (element->click_mode) { + case ClickMode::PASS: + click_mode_str = "pass"; + break; + case ClickMode::BLOCK: + click_mode_str = "block"; + break; + case ClickMode::IGNORE: + click_mode_str = "ignore"; + break; + } + + return mrb_symbol_value(mrb_intern_cstr(mrb, click_mode_str.c_str())); +} + +mrb_value element_text_click_mode_set(mrb_state *mrb, mrb_value self) { + mrb_sym click_mode_sym; + mrb_get_args(mrb, "n", &click_mode_sym); + + Wrapper *wrapper = (Wrapper *)DATA_PTR(self); + uint64_t id = wrapper->id; + app::EText *element = (app::EText *)app::element_pool[id]; + + std::string click_mode_str = mrb_sym2name(mrb, click_mode_sym); + + if (click_mode_str == "pass") + element->click_mode = ClickMode::PASS; + else if (click_mode_str == "block") + element->click_mode = ClickMode::BLOCK; + else if (click_mode_str == "ignore") + element->click_mode = ClickMode::IGNORE; + + return mrb_nil_value(); +} + +mrb_value element_text_width(mrb_state *mrb, mrb_value self) { + Wrapper *wrapper = (Wrapper *)DATA_PTR(self); + uint64_t id = wrapper->id; + app::EText *element = (app::EText *)app::element_pool[id]; + return mrb_float_value(mrb, element->size().x); +} + +mrb_value element_text_height(mrb_state *mrb, mrb_value self) { + Wrapper *wrapper = (Wrapper *)DATA_PTR(self); + uint64_t id = wrapper->id; + app::EText *element = (app::EText *)app::element_pool[id]; + return mrb_float_value(mrb, element->size().y); +} +} // namespace + +namespace definitions { +void register_element_text() { + DEF_CLASS(ElementText, MRB_ARGS_REQ(3) | MRB_ARGS_OPT(2)); + ADD_METHOD(ElementText, "==", element_text_equal, MRB_ARGS_REQ(1)); + ADD_METHOD(ElementText, "eql?", element_text_equal, MRB_ARGS_REQ(1)); + ADD_METHOD(ElementText, "inspect", element_text_inspect, MRB_ARGS_NONE()); + ADD_METHOD(ElementText, "hash", element_text_hash, MRB_ARGS_NONE()); + ADD_METHOD(ElementText, "click", element_text_on_click, MRB_ARGS_BLOCK()); + ADD_METHOD(ElementText, "to_s", element_text_to_s, MRB_ARGS_NONE()); + ADD_METHOD(ElementText, "key=", element_text_key_set, MRB_ARGS_REQ(1)); + ADD_METHOD(ElementText, "key", element_text_key_get, MRB_ARGS_NONE()); + ADD_METHOD(ElementText, "color=", element_text_color_set, MRB_ARGS_REQ(1)); + ADD_METHOD(ElementText, "color", element_text_color_get, MRB_ARGS_NONE()); + ADD_METHOD(ElementText, "font=", element_text_font_set, MRB_ARGS_REQ(1)); + ADD_METHOD(ElementText, "font", element_text_font_get, MRB_ARGS_NONE()); + ADD_METHOD(ElementText, "params", element_text_params, MRB_ARGS_NONE()); + ADD_METHOD(ElementText, "position", element_text_position_get, MRB_ARGS_NONE()); + ADD_METHOD(ElementText, "scale", element_text_scale_get, MRB_ARGS_NONE()); + ADD_METHOD(ElementText, "rotation=", element_text_rotation_set, MRB_ARGS_REQ(1)); + ADD_METHOD(ElementText, "rotation", element_text_rotation_get, MRB_ARGS_NONE()); + ADD_METHOD(ElementText, "pivot", element_text_pivot_get, MRB_ARGS_NONE()); + ADD_METHOD(ElementText, "alpha=", element_text_alpha_set, MRB_ARGS_REQ(1)); + ADD_METHOD(ElementText, "alpha", element_text_alpha_get, MRB_ARGS_NONE()); + ADD_METHOD(ElementText, "z=", element_text_z_set, MRB_ARGS_REQ(1)); + ADD_METHOD(ElementText, "z", element_text_z_get, MRB_ARGS_NONE()); + ADD_METHOD(ElementText, "click_mode=", element_text_click_mode_set, MRB_ARGS_REQ(1)); + ADD_METHOD(ElementText, "click_mode", element_text_click_mode_get, MRB_ARGS_NONE()); + ADD_METHOD(ElementText, "width", element_text_width, MRB_ARGS_NONE()); + ADD_METHOD(ElementText, "height", element_text_height, MRB_ARGS_NONE()); + + bindings.ElementText = {ElementText_class, &ElementText_type}; +} +} // namespace definitions \ No newline at end of file diff --git a/src/bindings/font.cc b/src/bindings/font.cc new file mode 100644 index 0000000..d0c5c19 --- /dev/null +++ b/src/bindings/font.cc @@ -0,0 +1,72 @@ +#include "bindings/definitions.h" +#include "window/window.h" + +namespace { +void Font_free(mrb_state *mrb, void *ptr) { + UNUSED(mrb); + uint64_t id = ((Wrapper *)ptr)->id; + font_pool.release(id); + delete (Wrapper *)ptr; +} + +const struct mrb_data_type Font_type = {"Font", Font_free}; + +mrb_value Font_init(mrb_state *mrb, mrb_value self) { + Wrapper *old = (Wrapper *)DATA_PTR(self); + if (old) + mrb_free(mrb, old); + mrb_data_init(self, nullptr, &Font_type); + Wrapper *s = new Wrapper(); + + char *path; + mrb_int size; + mrb_value kwargs; + mrb_get_args(mrb, "zi|H", &path, &size, &kwargs); + + bool pixel_art = false; + bool bold = false; + bool italic = false; + bool underline = false; + if (!mrb_nil_p(kwargs)) { + HASH_BOOL(kwargs, pixel_art, pixel_art); + HASH_BOOL(kwargs, bold, bold); + HASH_BOOL(kwargs, italic, italic); + HASH_BOOL(kwargs, underline, underline); + } + + s->id = window.load_font(path, size, bold, italic, underline, pixel_art); + + mrb_data_init(self, s, &Font_type); + return self; +} + +mrb_value font_equal(mrb_state *mrb, mrb_value self) { + mrb_value other; + mrb_get_args(mrb, "o", &other); + + if (!mrb_obj_is_kind_of(mrb, other, definitions::bindings.Font.cls)) + return mrb_false_value(); + + Wrapper *wrapper = (Wrapper *)DATA_PTR(self); + uint64_t id_self = wrapper->id; + Wrapper *other_wrapper = (Wrapper *)DATA_PTR(other); + uint64_t id_other = other_wrapper->id; + + return mrb_bool_value(id_self == id_other); +} + +mrb_value font_hash(mrb_state *, mrb_value self) { + Wrapper *wrapper = (Wrapper *)DATA_PTR(self); + return mrb_fixnum_value(wrapper->id); +} +} // namespace + +namespace definitions { +void register_font() { + DEF_CLASS(Font, MRB_ARGS_REQ(2) | MRB_ARGS_OPT(1)); + ADD_METHOD(Font, "==", font_equal, MRB_ARGS_REQ(1)); + ADD_METHOD(Font, "eql?", font_equal, MRB_ARGS_REQ(1)); + ADD_METHOD(Font, "hash", font_hash, MRB_ARGS_NONE()); + bindings.Font = {Font_class, &Font_type}; +} +} // namespace definitions \ No newline at end of file diff --git a/src/bindings/image.cc b/src/bindings/image.cc new file mode 100644 index 0000000..581502b --- /dev/null +++ b/src/bindings/image.cc @@ -0,0 +1,78 @@ +#include "bindings/definitions.h" +#include "window/window.h" + +namespace { +void Image_free(mrb_state *mrb, void *ptr) { + UNUSED(mrb); + uint64_t id = ((Wrapper *)ptr)->id; + image_pool.release(id); + delete (Wrapper *)ptr; +} + +const struct mrb_data_type Image_type = {"Image", Image_free}; + +mrb_value Image_init(mrb_state *mrb, mrb_value self) { + Wrapper *old = (Wrapper *)DATA_PTR(self); + if (old) + mrb_free(mrb, old); + mrb_data_init(self, nullptr, &Image_type); + Wrapper *s = new Wrapper(); + + char *path; + mrb_value kwargs; + mrb_get_args(mrb, "z|H", &path, &kwargs); + + bool pixel_art = false; + if (!mrb_nil_p(kwargs)) + HASH_BOOL(kwargs, pixel_art, pixel_art); + + s->id = window.load_image(path, pixel_art); + + mrb_data_init(self, s, &Image_type); + return self; +} + +mrb_value image_equal(mrb_state *mrb, mrb_value self) { + mrb_value other; + mrb_get_args(mrb, "o", &other); + + if (!mrb_obj_is_kind_of(mrb, other, definitions::bindings.Image.cls)) + return mrb_false_value(); + + Wrapper *wrapper = (Wrapper *)DATA_PTR(self); + uint64_t id_self = wrapper->id; + Wrapper *other_wrapper = (Wrapper *)DATA_PTR(other); + uint64_t id_other = other_wrapper->id; + + return mrb_bool_value(id_self == id_other); +} + +mrb_value image_hash(mrb_state *, mrb_value self) { + Wrapper *wrapper = (Wrapper *)DATA_PTR(self); + return mrb_fixnum_value(wrapper->id); +} + +mrb_value image_width(mrb_state *mrb, mrb_value self) { + Wrapper *wrapper = (Wrapper *)DATA_PTR(self); + uint64_t id = wrapper->id; + return mrb_float_value(mrb, window.get_image_size(id).x); +} + +mrb_value image_height(mrb_state *mrb, mrb_value self) { + Wrapper *wrapper = (Wrapper *)DATA_PTR(self); + uint64_t id = wrapper->id; + return mrb_float_value(mrb, window.get_image_size(id).y); +} +} // namespace + +namespace definitions { +void register_image() { + DEF_CLASS(Image, MRB_ARGS_REQ(1) | MRB_ARGS_OPT(1)); + ADD_METHOD(Image, "==", image_equal, MRB_ARGS_REQ(1)); + ADD_METHOD(Image, "eql?", image_equal, MRB_ARGS_REQ(1)); + ADD_METHOD(Image, "hash", image_hash, MRB_ARGS_NONE()); + ADD_METHOD(Image, "width", image_width, MRB_ARGS_NONE()); + ADD_METHOD(Image, "height", image_height, MRB_ARGS_NONE()); + bindings.Image = {Image_class, &Image_type}; +} +} // namespace definitions \ No newline at end of file diff --git a/src/bindings/params.cc b/src/bindings/params.cc new file mode 100644 index 0000000..d04d6f0 --- /dev/null +++ b/src/bindings/params.cc @@ -0,0 +1,68 @@ +#include "app/app.h" +#include "bindings/definitions.h" + +namespace { +void Params_free(mrb_state *mrb, void *ptr) { + UNUSED(mrb); + uint64_t id = ((Wrapper *)ptr)->id; + app::element_pool.release(id); + delete (Wrapper *)ptr; +} + +const struct mrb_data_type Params_type = {"Params", Params_free}; + +mrb_value Params_init(mrb_state *mrb, mrb_value self) { + Wrapper *old = (Wrapper *)DATA_PTR(self); + if (old) + mrb_free(mrb, old); + mrb_data_init(self, nullptr, &Params_type); + Wrapper *s = new Wrapper(); + + mrb_int id; + mrb_get_args(mrb, "z", &id); + + app::element_pool.use(id); + s->id = id; + + mrb_data_init(self, s, &Params_type); + return self; +} + +mrb_value params_get(mrb_state *mrb, mrb_value self) { + mrb_sym key; + mrb_get_args(mrb, "n", &key); + + uint64_t id = ((Wrapper *)DATA_PTR(self))->id; + app::element_pool.use(id); + app::EText *element = (app::EText *)app::element_pool[id]; + + auto it = element->params.find(mrb_sym2name(mrb, key)); + if (it == element->params.end()) + return mrb_nil_value(); + return mrb_str_new_cstr(mrb, it->second.c_str()); +} + +mrb_value params_set(mrb_state *mrb, mrb_value self) { + mrb_sym key; + mrb_value value; + mrb_get_args(mrb, "no", &key, &value); + + uint64_t id = ((Wrapper *)DATA_PTR(self))->id; + app::element_pool.use(id); + app::EText *element = (app::EText *)app::element_pool[id]; + + element->params[mrb_sym2name(mrb, key)] = mrb_str_to_cstr(mrb, mrb_obj_as_string(mrb, value)); + element->reload_text(); + + return mrb_nil_value(); +} +} // namespace + +namespace definitions { +void register_params() { + DEF_CLASS(Params, MRB_ARGS_REQ(1)); + ADD_METHOD(Params, "[]", params_get, MRB_ARGS_REQ(1)); + ADD_METHOD(Params, "[]=", params_set, MRB_ARGS_REQ(2)); + bindings.Params = {Params_class, &Params_type}; +} +} // namespace definitions \ No newline at end of file diff --git a/src/bindings/scene.cc b/src/bindings/scene.cc new file mode 100644 index 0000000..f26be86 --- /dev/null +++ b/src/bindings/scene.cc @@ -0,0 +1,199 @@ +#include "app/app.h" +#include "bindings/definitions.h" + +namespace { +void Scene_free(mrb_state *mrb, void *ptr) { + UNUSED(mrb); + uint64_t id = ((Wrapper *)ptr)->id; + app::scene_pool.release(id); + delete (Wrapper *)ptr; +} + +const struct mrb_data_type Scene_type = {"Scene", Scene_free}; + +mrb_value Scene_init(mrb_state *mrb, mrb_value self) { + Wrapper *old = (Wrapper *)DATA_PTR(self); + if (old) + mrb_free(mrb, old); + mrb_data_init(self, nullptr, &Scene_type); + Wrapper *s = new Wrapper(); + + app::Scene *loading_scene = new app::Scene{}; + s->id = app::scene_pool.acquire(loading_scene); + app::scene_pool.use(s->id); + + mrb_data_init(self, s, &Scene_type); + return self; +} + +mrb_value scene_add_element(mrb_state *mrb, mrb_value self) { + mrb_value element_val; + mrb_get_args(mrb, "o", &element_val); + + if ( + !mrb_obj_is_kind_of(mrb, element_val, definitions::bindings.ElementText.cls) + && !mrb_obj_is_kind_of(mrb, element_val, definitions::bindings.ElementRect.cls) + && !mrb_obj_is_kind_of(mrb, element_val, definitions::bindings.ElementImage.cls) + ) { + mrb_raise( + mrb, + mrb_class_get(mrb, "Exception"), + "Expected an ElementText, ElementRect, or ElementImage object" + ); + return mrb_nil_value(); + } + + Wrapper *wrapper = (Wrapper *)DATA_PTR(self); + app::Scene *scene = app::scene_pool[wrapper->id]; + + Wrapper *element_wrapper = (Wrapper *)DATA_PTR(element_val); + scene->add_element(element_wrapper->id); + + return self; +} + +mrb_value scene_delete_element(mrb_state *mrb, mrb_value self) { + mrb_value element_val; + mrb_get_args(mrb, "o", &element_val); + + if ( + !mrb_obj_is_kind_of(mrb, element_val, definitions::bindings.ElementText.cls) + && !mrb_obj_is_kind_of(mrb, element_val, definitions::bindings.ElementRect.cls) + && !mrb_obj_is_kind_of(mrb, element_val, definitions::bindings.ElementImage.cls) + ) { + mrb_raise( + mrb, + mrb_class_get(mrb, "Exception"), + "Expected an ElementText, ElementRect, or ElementImage object" + ); + return mrb_nil_value(); + } + + Wrapper *wrapper = (Wrapper *)DATA_PTR(self); + app::Scene *scene = app::scene_pool[wrapper->id]; + + Wrapper *element_wrapper = (Wrapper *)DATA_PTR(element_val); + scene->delete_element(element_wrapper->id); + + return self; +} + +mrb_value scene_on_update(mrb_state *mrb, mrb_value self) { + mrb_value block; + mrb_get_args(mrb, "&", &block); + + Wrapper *wrapper = (Wrapper *)DATA_PTR(self); + app::Scene *scene = app::scene_pool[wrapper->id]; + scene->update.set_proc(block); + + return self; +} + +mrb_value scene_elements_at(mrb_state *mrb, mrb_value self) { + mrb_value position_val; + mrb_get_args(mrb, "o", &position_val); + + float x = 0, y = 0; + HASH_FLOAT(position_val, x, x); + HASH_FLOAT(position_val, y, y); + Vec2 position = {x, y}; + + Wrapper *wrapper = (Wrapper *)DATA_PTR(self); + app::Scene *scene = app::scene_pool[wrapper->id]; + + std::vector element_ids = scene->elements_at(position); + + mrb_value result = mrb_ary_new_capa(mrb, element_ids.size()); + for (uint64_t element_id : element_ids) { + app::Element *element = app::element_pool[element_id]; + app::element_pool.use(element_id); + if (element->type == Type::TEXT) { + mrb_value obj = definitions::wrap(definitions::bindings.ElementText, element_id); + mrb_ary_push(mrb, result, obj); + } else if (element->type == Type::RECT) { + mrb_value obj = definitions::wrap(definitions::bindings.ElementRect, element_id); + mrb_ary_push(mrb, result, obj); + } else if (element->type == Type::IMAGE) { + mrb_value obj = definitions::wrap(definitions::bindings.ElementImage, element_id); + mrb_ary_push(mrb, result, obj); + } else { + continue; + } + } + + return result; +} + +mrb_value scene_elements(mrb_state *mrb, mrb_value self) { + Wrapper *wrapper = (Wrapper *)DATA_PTR(self); + app::Scene *scene = app::scene_pool[wrapper->id]; + + std::vector element_ids = scene->element_ids; + + mrb_value result = mrb_ary_new_capa(mrb, element_ids.size()); + for (uint64_t element_id : element_ids) { + app::Element *element = app::element_pool[element_id]; + app::element_pool.use(element_id); + if (element->type == Type::TEXT) { + mrb_value obj = definitions::wrap(definitions::bindings.ElementText, element_id); + mrb_ary_push(mrb, result, obj); + } else if (element->type == Type::RECT) { + mrb_value obj = definitions::wrap(definitions::bindings.ElementRect, element_id); + mrb_ary_push(mrb, result, obj); + } else if (element->type == Type::IMAGE) { + mrb_value obj = definitions::wrap(definitions::bindings.ElementImage, element_id); + mrb_ary_push(mrb, result, obj); + } else { + continue; + } + } + + return result; +} + +mrb_value scene_equal(mrb_state *mrb, mrb_value self) { + mrb_value other; + mrb_get_args(mrb, "o", &other); + + if (!mrb_obj_is_kind_of(mrb, other, definitions::bindings.Scene.cls)) + return mrb_false_value(); + + Wrapper *self_wrapper = (Wrapper *)DATA_PTR(self); + uint64_t id_self = self_wrapper->id; + Wrapper *other_wrapper = (Wrapper *)DATA_PTR(other); + uint64_t id_other = other_wrapper->id; + + return mrb_bool_value(id_self == id_other); +} + +mrb_value scene_inspect(mrb_state *mrb, mrb_value self) { + Wrapper *wrapper = (Wrapper *)DATA_PTR(self); + uint64_t id = wrapper->id; + return mrb_str_new_cstr(mrb, ("#").c_str()); +} + +mrb_value scene_hash(mrb_state *, mrb_value self) { + Wrapper *wrapper = (Wrapper *)DATA_PTR(self); + uint64_t id = wrapper->id; + return mrb_fixnum_value(id); +} +} // namespace + +namespace definitions { +void register_scene() { + DEF_CLASS(Scene, MRB_ARGS_NONE()); + ADD_METHOD(Scene, "==", scene_equal, MRB_ARGS_REQ(1)); + ADD_METHOD(Scene, "eql?", scene_equal, MRB_ARGS_REQ(1)); + ADD_METHOD(Scene, "inspect", scene_inspect, MRB_ARGS_NONE()); + ADD_METHOD(Scene, "to_s", scene_inspect, MRB_ARGS_NONE()); + ADD_METHOD(Scene, "hash", scene_hash, MRB_ARGS_NONE()); + ADD_METHOD(Scene, "<<", scene_add_element, MRB_ARGS_REQ(1)); + ADD_METHOD(Scene, "delete", scene_delete_element, MRB_ARGS_REQ(1)); + ADD_METHOD(Scene, "remove", scene_delete_element, MRB_ARGS_REQ(1)); + ADD_METHOD(Scene, "update", scene_on_update, MRB_ARGS_BLOCK()); + ADD_METHOD(Scene, "elements_at", scene_elements_at, MRB_ARGS_REQ(1)); + ADD_METHOD(Scene, "elements", scene_elements, MRB_ARGS_NONE()); + + bindings.Scene = {Scene_class, &Scene_type}; +} +} // namespace definitions diff --git a/src/bindings/vec2.cc b/src/bindings/vec2.cc new file mode 100644 index 0000000..07fd948 --- /dev/null +++ b/src/bindings/vec2.cc @@ -0,0 +1,90 @@ +#include "app/app.h" +#include "bindings/definitions.h" + +namespace { +struct Vec2Wrapper : public Wrapper { + Vec2 *vec; +}; + +void Vec2_free(mrb_state *mrb, void *ptr) { + UNUSED(mrb); + uint64_t id = ((Wrapper *)ptr)->id; + app::element_pool.release(id); + delete (Wrapper *)ptr; +} + +const struct mrb_data_type Vec2_type = {"Vec2", Vec2_free}; + +mrb_value Vec2_init(mrb_state *mrb, mrb_value self) { + Wrapper *old = (Wrapper *)DATA_PTR(self); + if (old) + mrb_free(mrb, old); + mrb_data_init(self, nullptr, &Vec2_type); + Vec2Wrapper *s = new Vec2Wrapper(); + + mrb_int id; + mrb_get_args(mrb, "i", &id); + + app::element_pool.use(id); + s->id = id; + s->vec = &((app::EText *)app::element_pool[id])->position; + + mrb_data_init(self, s, &Vec2_type); + return self; +} + +mrb_value vec2_x(mrb_state *mrb, mrb_value self) { + Vec2Wrapper *s = (Vec2Wrapper *)DATA_PTR(self); + return mrb_float_value(mrb, s->vec->x); +} + +mrb_value vec2_y(mrb_state *mrb, mrb_value self) { + Vec2Wrapper *s = (Vec2Wrapper *)DATA_PTR(self); + return mrb_float_value(mrb, s->vec->y); +} + +mrb_value vec2_x_set(mrb_state *mrb, mrb_value self) { + mrb_float x; + mrb_get_args(mrb, "f", &x); + + Vec2Wrapper *s = (Vec2Wrapper *)DATA_PTR(self); + s->vec->x = (float)x; + + return mrb_nil_value(); +} + +mrb_value vec2_y_set(mrb_state *mrb, mrb_value self) { + mrb_float y; + mrb_get_args(mrb, "f", &y); + + Vec2Wrapper *s = (Vec2Wrapper *)DATA_PTR(self); + s->vec->y = (float)y; + + return mrb_nil_value(); +} +} // namespace + +namespace definitions { +void register_vec2() { + DEF_CLASS(Vec2, MRB_ARGS_REQ(2)); + ADD_METHOD(Vec2, "x", vec2_x, MRB_ARGS_NONE()); + ADD_METHOD(Vec2, "y", vec2_y, MRB_ARGS_NONE()); + ADD_METHOD(Vec2, "x=", vec2_x_set, MRB_ARGS_REQ(1)); + ADD_METHOD(Vec2, "y=", vec2_y_set, MRB_ARGS_REQ(1)); + bindings.Vec2 = {Vec2_class, &Vec2_type}; +} + +mrb_value Vec2_wrap(uint64_t id, Vec2 *vec) { + RBasic *obj_b = mrb_obj_alloc(Ruby::mrb, MRB_TT_DATA, bindings.Vec2.cls); + mrb_value obj = mrb_obj_value(obj_b); + + Vec2Wrapper *w = new Vec2Wrapper(); + app::element_pool.use(id); + w->id = id; + w->vec = vec; + + mrb_data_init(obj, w, &Vec2_type); + + return obj; +} +} // namespace definitions \ No newline at end of file diff --git a/src/main.cc b/src/main.cc index 9d50bb7..66d569e 100644 --- a/src/main.cc +++ b/src/main.cc @@ -1,4 +1,4 @@ -#include "binding/definitions.h" +#include "bindings/definitions.h" int main(int argc, char *argv[]) { Ruby::load_mgems(); diff --git a/writeup/analysis.md b/writeup/analysis.md index 3220faf..00247e7 100644 --- a/writeup/analysis.md +++ b/writeup/analysis.md @@ -6,15 +6,15 @@ The goal of this project is to build a high performance cross-desktop game engine for 2d games, -When a developer wishes to build a game they generally have 2 options, either they can code the entire game themselves by using a pure rendering library and handling all teh assets etc. themselves, this gives them a lot of control over how the game behaves and can usually also allow them to do a lot of optimizations specific to their idea, but it means they will have to make the coordinate systems and data store, asset management systems etc. all by themselves, on the other hand they could use a game engine. +When a developer wishes to build a game they generally have 2 options, either they can code the entire game themselves by using a pure rendering library and handling all the assets etc. themselves, this gives them a lot of control over how the game behaves and can usually also allow them to do a lot of optimizations specific to their idea, but it means they will have to make the coordinate systems and data store, asset management systems etc. all by themselves, on the other hand they could use a game engine. the most significant advantage of using game engines when building a game is simplifying development process. -They do this by allowing the developer to do a lot more out of teh box without having to reinvent the wheel themselves: +They do this by allowing the developer to do a lot more out of the box without having to reinvent the wheel themselves: -- They allow making teh game only once but having it work crossplatform on multiple different types of systems -- They allow asset management of game asstes like images, textures, audios etc. without teh need to ensure a uniform format and loading them or decoding them manually -- They also usually have built in physics engines for the coordinate system, which do not need to be reimplemented with al that math by teh developer, and these are done in optimized hot loops for greater performance. +- They allow making the game only once but having it work crossplatform on multiple different types of systems +- They allow asset management of game asstes like images, textures, audios etc. without the need to ensure a uniform format and loading them or decoding them manually +- They also usually have built in physics engines for the coordinate system, which do not need to be reimplemented with al that math by the developer, and these are done in optimized hot loops for greater performance. The engine is expected to be built in a low level context (for high performance), but allow using it from a high level simpler environment without losing any of the performance. It should also make the development process of a game easy with any common parts for games implemented and reusable. @@ -39,7 +39,7 @@ They extend a node's behaviour. So in godot you first define the blueprint, the structure of the game using the ui (or the markup files), and then attach scripts to the nodes to extend their behaviour and actually make them work, these scripts can intercommunicate using events. -Then the godot runtime extracts these scenes and builds teh node tree out of them and runs the scripts attached to the loaded nodes. +Then the godot runtime extracts these scenes and builds the node tree out of them and runs the scripts attached to the loaded nodes. these scripts are generally written in gdscript which is an interpreted language that is prcompiled to bytecode when the project is built and later on is executed by a runtime-VM. @@ -72,8 +72,8 @@ It is primaririly a ruby library for rendering and input capture. It is very good for fast prototyping as it has very simple methods and uses ruby which is very good for fast prototyping (see next sec). But it does not have a scene or nodes or object system of it's own, all such systems are to be implemented by the developer themselves, and while it provides methods for loading and using of assets they still need to be managed manually. This comes with the up that the developer can chose what kind of system they want to use. -It also requires teh ruby runtime and teh full source code when sharing making it less than ideal for any production games. -Also any kinds of GPU shading requires teh OpenGL libraries to be used directly and it provides no proper access to them. +It also requires the ruby runtime and the full source code when sharing making it less than ideal for any production games. +Also any kinds of GPU shading requires the OpenGL libraries to be used directly and it provides no proper access to them. As per their own homepage: Gosu is mainly used to teach or learn Ruby. Comparisions of architectures: @@ -81,16 +81,16 @@ Comparisions of architectures: - Data layout - In the node based system that godot uses each entity (node), stores all it's data in a single object - This means that when an object is to be worked on it can be used from a single place. It also closely follows a OOP like idea meaning it is simpler for developers more used to it. - - But it creates cache locality problems for example when teh physics system wants to move all elements forward, each object will have to be loaded and then updated and as objects do not have to be together in memory it causes a lot of access overhead. - - On the other hand ECS systems (like the one that can be used in unity), seperate pure data (compoenents) from teh entities. + - But it creates cache locality problems for example when the physics system wants to move all elements forward, each object will have to be loaded and then updated and as objects do not have to be together in memory it causes a lot of access overhead. + - On the other hand ECS systems (like the one that can be used in unity), seperate pure data (compoenents) from the entities. - This means that when a system wishes to work on a single kind of compoenent it can use tight loops to leverage performance gains from cpu cache locality. - It also scales very well for having way more entities as entities only use up space for the compoenents they require. - But it is also a much more complex mental model for the developer to work with. - Behaviour control - - In godot the bahaviour is very tightly attached to each node, and when executing teh game the behaviour of each node is run fully before going on to the next, this means that similar behaviour like physics is recalculated for each node seperately + - In godot the bahaviour is very tightly attached to each node, and when executing the game the behaviour of each node is run fully before going on to the next, this means that similar behaviour like physics is recalculated for each node seperately - While in unity most scripts are global systems, these systems can bulk operate on data making them better at potential multithreading or cpu optimizations. - but they require ore boilerplate code as logic has to be filtered down to apply to the correct nodes manually rather than by vrtue of existing on a node. -- While in a more simple framework like gosu these are all dependant on teh developers implementation. +- While in a more simple framework like gosu these are all dependant on the developers implementation. ^ Gosu. (n.d.). Gosu Homepage. [online] Available at: https://www.libgosu.org/ [Accessed 13 May 2026]. ^ Unity Docs. (n.d.). Unity Entity Component System concepts. [online] Available at: https://docs.unity3d.com/Packages/com.unity.entities@6.5/manual/concepts-intro.html [Accessed 13 May 2026]. See sub-links. @@ -100,11 +100,11 @@ Comparisions of architectures: ## Embedded scripting This engine does not use a UI builder. And so all gameplay logic, entity behaviour, definitions etc. must be implemented directly through code. -Because of this it is important to use a well established language in which teh developer can write their code. +Because of this it is important to use a well established language in which the developer can write their code. -Embedded scripting languages are programming lanaguges that are designed to be embedded in a host programming language. The embedded language is often an interpreted language which teh host is a compiled static typed language. They allow adding code to teh program that can be modified and interpreted at runtime. They are often used to extend on teh functionality of teh host language. And they also allow using functions defined in the host language which are usually much more performance optimized. +Embedded scripting languages are programming lanaguges that are designed to be embedded in a host programming language. The embedded language is often an interpreted language which the host is a compiled static typed language. They allow adding code to the program that can be modified and interpreted at runtime. They are often used to extend on the functionality of the host language. And they also allow using functions defined in the host language which are usually much more performance optimized. -They are usually very lightweight (so that teh final binary doesn't get bloated and runs fast enough). They are very useful for cuztom DSL/syntax. +They are usually very lightweight (so that the final binary doesn't get bloated and runs fast enough). They are very useful for cuztom DSL/syntax. And according to [this aticle](https://caiorss.github.io/C-Cpp-Notes/embedded_scripting_languages.html) they are particularly useful for game engines. @@ -125,12 +125,12 @@ The target users for this project could be one of 2 categories: - The engine can be used by game developers to create high performance games quickly. - The games are also built cross-platform meaning they can use the same project to export for different kinds of users. -- The standalone output of teh game engine means tehy wont have to worry about sharing multiple files and makes releases easier. +- The standalone output of the game engine means they wont have to worry about sharing multiple files and makes releases easier. - And for my own games it would help create a unique brand image for my games, it also helps out with any potential licensing issues with using external engines in my games. 2. Educators -- The game engine can be used by educators to teach programming / game development to students without making them build all teh systems from scratch. +- The game engine can be used by educators to teach programming / game development to students without making them build all the systems from scratch. - Using such an engine means that the students could be taught about paradigms like ecs and OOP in a simple environment. - They would also be learning ruby, which is an arguably very good for rapid prototyping due to its forgiving and highly readable syntax. @@ -246,7 +246,7 @@ core: - The world can render everything in view based on camera, and everything inside here is in world coordinates -- shaders, layers on top of teh world, (per world, not possible per entity) +- shaders, layers on top of the world, (per world, not possible per entity) extra: @@ -257,11 +257,14 @@ extra: - sprite system (tiled, animated, static etc.) - 9 segment ui system - audio playing -- network interface, with a lib to work with rack backends (and generic socket api) +- network interface, with a lib to stream data rom & a server instance also built into the packer binary (should allow ruby scripting the backend) - persistence store - rng helpers -- tweening system -- layout system +- tweening helpers +- layout system (with tree like grouping of elements that inherit transform of parent) +- video player (ffmpeg texture and audio streams) (requires ffmpeg at runtime) + +- super simple neural network system (with training and runtime phases) (if i have enough time) ## Embedded scripting language choice. @@ -269,7 +272,7 @@ Why ruby is great for development for the runtime of this engine: - Dynamic typing. it has almost no type declarations on variables, and duck typing means any object with particular behaviour can be treated the same. - Expressive syntax. ruby has one of the most expressive syntax that improves code readability by a lot, it allows operator overloading, very clean dsl structures, minimal puntuation neccessary, and a lot of syntactic shortcuts. -- Very rich standard library. teh ruby std lib has a lot of helpers for json, sockets, networking, file management, multithreading, regex etc. +- Very rich standard library. the ruby std lib has a lot of helpers for json, sockets, networking, file management, multithreading, regex etc. - It also has a lot of inbuilt datatypes with helper methods that allow doing a lot of stuff. it has integers with no hard maximum, floating point numbers, strings and arrays, but it also has symbols, hashmaps and regex etc. for much faster development. And as its official website itself states, ruby is easy to write, easy to read with natural syntax like spoken language. @@ -281,15 +284,15 @@ And as its official website itself states, ruby is easy to write, easy to read w For these reasons and my personal familiarity with the languge i've planned to use ruby as the languge in which the game engine is written code for. More specifically we will use the `mruby` version as it allows for embedding a lightweight ruby VM into our engine that can run the scripts without needing an external interpreter. -`Mruby` is a very lightwieght impleemntation of teh ruby runtime and also supports semi-compiled bytecodes. -The engine could compile the developers scripts into mruby bytecode when building the application and when it is to be used the teh mruby vm can run these bytecodes. +`Mruby` is a very lightwieght impleemntation of the ruby runtime and also supports semi-compiled bytecodes. +The engine could compile the developers scripts into mruby bytecode when building the application and when it is to be used the the mruby vm can run these bytecodes. ^ Mruby.org. (2026). mruby - Lightweight Ruby. [online] Available at: https://mruby.org/ [Accessed 13 May 2026]. ^ Ruby (2019). Ruby Programming Language. [online] Ruby-lang.org. Available at: https://www.ruby-lang.org/en/ [Accessed 13 May 2026]. ## -- then a draft one of teh requirements with justification of each based on the previous sections +- then a draft one of the requirements with justification of each based on the previous sections Requirements v1: