483 lines
13 KiB
C++
483 lines
13 KiB
C++
#ifndef DEFINITIONS_H
|
|
#define DEFINITIONS_H
|
|
|
|
#include "app/app.h"
|
|
|
|
namespace definitions {
|
|
DEF_RB(
|
|
Font,
|
|
({ font_pool.release(id); }),
|
|
({
|
|
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);
|
|
})
|
|
)
|
|
|
|
DEF_RB(
|
|
Image,
|
|
({ image_pool.release(id); }),
|
|
({
|
|
char *path;
|
|
mrb_value kwargs;
|
|
mrb_get_args(mrb, "z|H", &path, &kwargs);
|
|
|
|
float alpha = 1.0f;
|
|
bool pixel_art = false;
|
|
if (!mrb_nil_p(kwargs)) {
|
|
HASH_FLOAT(kwargs, alpha, alpha);
|
|
HASH_BOOL(kwargs, pixel_art, pixel_art);
|
|
}
|
|
|
|
s->id = window.load_image(path, alpha, pixel_art);
|
|
})
|
|
)
|
|
|
|
DEF_RB(
|
|
Animation,
|
|
({
|
|
animation_pool.release(id);
|
|
}),
|
|
({
|
|
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<int> 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();
|
|
}
|
|
int 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, true};
|
|
s->id = animation_pool.acquire(animation);
|
|
animation_pool.use(s->id);
|
|
})
|
|
)
|
|
|
|
DEF_RB(
|
|
ElementText,
|
|
({
|
|
app::element_pool.release(id);
|
|
}),
|
|
({
|
|
mrb_value font_val;
|
|
mrb_sym key;
|
|
mrb_value kwargs;
|
|
mrb_get_args(mrb, "no|H", &key, &font_val, &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;
|
|
float y = 0;
|
|
float z = 0;
|
|
bool click_through = false;
|
|
if (!mrb_nil_p(kwargs)) {
|
|
mrb_value pos_hash = HASH_GET(kwargs, position);
|
|
HASH_FLOAT(pos_hash, x, x);
|
|
HASH_FLOAT(pos_hash, y, y);
|
|
|
|
HASH_FLOAT(kwargs, z, z);
|
|
HASH_BOOL(kwargs, click_through, click_through);
|
|
}
|
|
|
|
Vec2<float> position = {x, y};
|
|
|
|
int id = get_id_Font(mrb, font_val);
|
|
font_pool.use(id);
|
|
|
|
app::EText *element = new app::EText(key_id, id, {255, 255, 255, 255});
|
|
element->position = position;
|
|
element->z = z;
|
|
element->click_through = click_through;
|
|
|
|
s->id = app::element_pool.acquire(element);
|
|
app::element_pool.use(s->id);
|
|
})
|
|
)
|
|
|
|
static mrb_value element_text_on_click(mrb_state *mrb, mrb_value self) {
|
|
mrb_value block;
|
|
mrb_get_args(mrb, "&", &block);
|
|
int id = get_id_ElementText(mrb, self);
|
|
app::Element *element = app::element_pool[id];
|
|
element->on_click.set_proc(block);
|
|
return self;
|
|
}
|
|
|
|
DEF_RB(
|
|
ElementRect,
|
|
({
|
|
app::element_pool.release(id);
|
|
}),
|
|
({
|
|
mrb_value shape_val;
|
|
mrb_int color;
|
|
mrb_value kwargs;
|
|
mrb_get_args(mrb, "Hi|H", &shape_val, &color, &kwargs);
|
|
|
|
float x = 0, y = 0, w = 0, h = 0;
|
|
if (!mrb_nil_p(shape_val)) {
|
|
HASH_FLOAT(shape_val, x, x);
|
|
HASH_FLOAT(shape_val, y, y);
|
|
HASH_FLOAT(shape_val, w, w);
|
|
HASH_FLOAT(shape_val, h, h);
|
|
}
|
|
|
|
float z = 0;
|
|
if (!mrb_nil_p(kwargs))
|
|
HASH_FLOAT(kwargs, z, z);
|
|
|
|
Vec2<float> position = {x, y};
|
|
Vec2<float> shape = {w, h};
|
|
|
|
app::ERect *element = new app::ERect(
|
|
shape,
|
|
{(uint8_t)((color >> 24) & 0xFF),
|
|
(uint8_t)((color >> 16) & 0xFF),
|
|
(uint8_t)((color >> 8) & 0xFF),
|
|
(uint8_t)(color & 0xFF)}
|
|
);
|
|
element->position = position;
|
|
element->z = z;
|
|
|
|
s->id = app::element_pool.acquire(element);
|
|
app::element_pool.use(s->id);
|
|
})
|
|
)
|
|
|
|
static mrb_value element_rect_on_click(mrb_state *mrb, mrb_value self) {
|
|
mrb_value block;
|
|
mrb_get_args(mrb, "&", &block);
|
|
int 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_color_set(mrb_state *mrb, mrb_value self) {
|
|
mrb_value color_val;
|
|
mrb_get_args(mrb, "o", &color_val);
|
|
int id = get_id_ElementRect(mrb, self);
|
|
app::ERect *element = (app::ERect *)app::element_pool[id];
|
|
element->color = {
|
|
(uint8_t)((mrb_fixnum(color_val) >> 24) & 0xFF),
|
|
(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) {
|
|
int id = get_id_ElementRect(mrb, self);
|
|
app::ERect *element = (app::ERect *)app::element_pool[id];
|
|
uint32_t color = ((uint32_t)element->color.r << 24)
|
|
| ((uint32_t)element->color.g << 16)
|
|
| ((uint32_t)element->color.b << 8)
|
|
| (uint32_t)element->color.a;
|
|
return mrb_fixnum_value(color);
|
|
}
|
|
|
|
DEF_RB(
|
|
ElementImage,
|
|
({
|
|
app::element_pool.release(id);
|
|
}),
|
|
({
|
|
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;
|
|
float y = 0;
|
|
float z = 0;
|
|
bool click_through = false;
|
|
if (!mrb_nil_p(kwargs)) {
|
|
mrb_value pos_hash = HASH_GET(kwargs, position);
|
|
HASH_FLOAT(pos_hash, x, x);
|
|
HASH_FLOAT(pos_hash, y, y);
|
|
|
|
HASH_FLOAT(kwargs, z, z);
|
|
HASH_BOOL(kwargs, click_through, click_through);
|
|
}
|
|
|
|
int id = get_id_Animation(mrb, animation_val);
|
|
|
|
app::EImage *element = new app::EImage(id);
|
|
element->position = {x, y};
|
|
element->z = z;
|
|
element->click_through = click_through;
|
|
|
|
s->id = app::element_pool.acquire(element);
|
|
app::element_pool.use(s->id);
|
|
})
|
|
)
|
|
|
|
static mrb_value element_image_on_click(mrb_state *mrb, mrb_value self) {
|
|
mrb_value block;
|
|
mrb_get_args(mrb, "&", &block);
|
|
int id = get_id_ElementImage(mrb, self);
|
|
app::Element *element = app::element_pool[id];
|
|
element->on_click.set_proc(block);
|
|
return self;
|
|
}
|
|
|
|
DEF_RB(
|
|
Scene,
|
|
({
|
|
app::scene_pool.release(id);
|
|
}),
|
|
({
|
|
app::Scene *loading_scene = new app::Scene{};
|
|
s->id = app::scene_pool.acquire(loading_scene);
|
|
app::scene_pool.use(s->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();
|
|
}
|
|
|
|
int id = get_id_Scene(mrb, self);
|
|
app::Scene *scene = app::scene_pool[id];
|
|
|
|
// int element_id = get_id_Element(mrb, element_val);
|
|
|
|
int 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();
|
|
}
|
|
|
|
int id = get_id_Scene(mrb, self);
|
|
app::Scene *scene = app::scene_pool[id];
|
|
|
|
int 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);
|
|
|
|
int id = get_id_Scene(mrb, self);
|
|
app::Scene *scene = app::scene_pool[id];
|
|
scene->update.set_proc(block);
|
|
|
|
return self;
|
|
}
|
|
|
|
static mrb_value app_run(mrb_state *mrb, mrb_value) {
|
|
mrb_int width, height;
|
|
char *title = nullptr;
|
|
mrb_get_args(mrb, "iiz", &width, &height, &title);
|
|
|
|
app_ = new app::App({(float)width, (float)height}, title);
|
|
|
|
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();
|
|
}
|
|
|
|
int id = get_id_Scene(mrb, scene_val);
|
|
app_->switch_to_scene(id);
|
|
|
|
app_->loop();
|
|
|
|
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();
|
|
}
|
|
|
|
int 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::localized_strings[Localization::join_keys(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();
|
|
}
|
|
|
|
inline void setup() {
|
|
DEF_CLASS(Font, MRB_ARGS_REQ(2) | MRB_ARGS_OPT(1));
|
|
|
|
DEF_CLASS(Image, MRB_ARGS_REQ(1) | MRB_ARGS_OPT(1));
|
|
|
|
DEF_CLASS(Animation, MRB_ARGS_REQ(1) | MRB_ARGS_OPT(1));
|
|
|
|
DEF_CLASS(ElementText, MRB_ARGS_REQ(2) | MRB_ARGS_OPT(1));
|
|
ADD_METHOD(
|
|
ElementText,
|
|
"on_click",
|
|
element_text_on_click,
|
|
MRB_ARGS_BLOCK()
|
|
);
|
|
|
|
DEF_CLASS(ElementRect, MRB_ARGS_REQ(2) | MRB_ARGS_OPT(1));
|
|
ADD_METHOD(
|
|
ElementRect,
|
|
"on_click",
|
|
element_rect_on_click,
|
|
MRB_ARGS_BLOCK()
|
|
);
|
|
ADD_METHOD(
|
|
ElementRect,
|
|
"color=",
|
|
element_rect_color_set,
|
|
MRB_ARGS_REQ(1)
|
|
);
|
|
ADD_METHOD(
|
|
ElementRect,
|
|
"color",
|
|
element_rect_color_get,
|
|
MRB_ARGS_NONE()
|
|
);
|
|
|
|
DEF_CLASS(ElementImage, MRB_ARGS_REQ(1) | MRB_ARGS_OPT(1));
|
|
ADD_METHOD(
|
|
ElementImage,
|
|
"on_click",
|
|
element_image_on_click,
|
|
MRB_ARGS_BLOCK()
|
|
);
|
|
|
|
DEF_CLASS(Scene, 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, "on_update", scene_on_update, MRB_ARGS_BLOCK());
|
|
|
|
DEF_MODULE(App);
|
|
ADD_MODULE_METHOD(App, "run", app_run, MRB_ARGS_REQ(3));
|
|
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, "localize", app_localize, MRB_ARGS_REQ(3));
|
|
ADD_MODULE_METHOD(App, "language=", app_language_set, MRB_ARGS_REQ(1));
|
|
}
|
|
} // namespace definitions
|
|
|
|
#endif |