summaryrefslogtreecommitdiff
path: root/src/sprite.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/sprite.c')
-rw-r--r--src/sprite.c198
1 files changed, 198 insertions, 0 deletions
diff --git a/src/sprite.c b/src/sprite.c
new file mode 100644
index 0000000..b8495d4
--- /dev/null
+++ b/src/sprite.c
@@ -0,0 +1,198 @@
+/*
+ * Copyright 2022 Frederico de Oliveira Linhares
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "sprite.h"
+#include "sprite_implementation.h"
+
+#include <mruby/hash.h>
+
+#include "point.h"
+#include "texture.h"
+
+// This variable works as a constant
+static mrb_sym id_at_texture;
+
+void
+cg_free_sprite(mrb_state *mrb, void* obj)
+{
+ struct cg_sprite *ptr = obj;
+
+ mrb_free(mrb, ptr);
+}
+
+const struct mrb_data_type cg_sprite_type = {
+ "CG_Sprite", cg_free_sprite };
+
+static mrb_value
+cg_cSrpite_load_yaml(mrb_state *mrb, mrb_value klass)
+{
+ const char *file_path;
+ struct cg_SpriteArray_s sprite_ary;
+ mrb_value hash, texture;
+
+ mrb_get_args(mrb, "zo", &file_path, &texture);
+
+ if(!cg_SpriteArray_constructor(&sprite_ary, file_path))
+ mrb_raise(mrb, E_RUNTIME_ERROR, "failed to open sprites");
+
+ hash = mrb_hash_new_capa(mrb, sprite_ary.len);
+
+ for(int i = 0; i < sprite_ary.len; i++)
+ {
+ mrb_hash_set(
+ mrb, hash,
+ mrb_symbol_value(mrb_intern_cstr(mrb, sprite_ary.sprites[i].name)),
+ mrb_funcall(
+ mrb, klass, "new", 5,
+ texture,
+ mrb_int_value(mrb, sprite_ary.sprites[i].x),
+ mrb_int_value(mrb, sprite_ary.sprites[i].y),
+ mrb_int_value(mrb, sprite_ary.sprites[i].width),
+ mrb_int_value(mrb, sprite_ary.sprites[i].height)));
+ }
+
+ cg_SpriteArray_destructor(&sprite_ary);
+
+ return hash;
+}
+
+static mrb_value
+cg_cSprite_initialize(mrb_state *mrb, mrb_value self)
+{
+ mrb_value texture_v;
+ mrb_int x, y, width, height;
+ struct cg_sprite *ptr;
+
+ mrb_get_args(mrb, "oiiii", &texture_v, &x, &y, &width, &height);
+ ptr = (struct cg_sprite *)DATA_PTR(self);
+ if(ptr) mrb_free(mrb, ptr);
+ ptr = (struct cg_sprite *)mrb_malloc(mrb, sizeof(struct cg_sprite));
+
+ mrb_iv_set(mrb, self, id_at_texture, texture_v);
+ ptr->rect.x = x;
+ ptr->rect.y = y;
+ ptr->rect.w = width;
+ ptr->rect.h = height;
+
+ mrb_data_init(self, ptr, &cg_sprite_type);
+ return self;
+}
+
+static mrb_value
+cg_cSprite_texture(mrb_state *mrb, mrb_value self)
+{
+ return mrb_iv_get(mrb, self, id_at_texture);
+}
+
+static mrb_value
+cg_cSprite_width(mrb_state *mrb, mrb_value self)
+{
+ struct cg_sprite *ptr;
+
+ ptr = (struct cg_sprite *)DATA_PTR(self);
+
+ return mrb_int_value(mrb, ptr->rect.w);
+}
+
+static mrb_value
+cg_cSprite_height(mrb_state *mrb, mrb_value self)
+{
+ struct cg_sprite *ptr;
+
+ ptr = (struct cg_sprite *)DATA_PTR(self);
+
+ return mrb_int_value(mrb, ptr->rect.h);
+}
+
+static mrb_value
+cg_cSprite_draw(mrb_state *mrb, mrb_value self)
+{
+ SDL_Rect dst_rect;
+
+ mrb_value texture_v;
+
+ struct cg_sprite *ptr;
+ struct cg_texture *texture_ptr;
+ struct cg_point *point;
+
+ mrb_get_args(mrb, "d", &point, &cg_point_type);
+
+ ptr = (struct cg_sprite *)DATA_PTR(self);
+ texture_v = mrb_iv_get(mrb, self, id_at_texture);
+ texture_ptr = (struct cg_texture *)DATA_PTR(texture_v);
+
+ dst_rect.x = point->data.x;
+ dst_rect.y = point->data.y;
+ dst_rect.w = ptr->rect.w;
+ dst_rect.h = ptr->rect.h;
+
+ SDL_RenderCopy(cg_core.renderer, texture_ptr->data, &ptr->rect, &dst_rect);
+
+ return self;
+}
+
+static mrb_value
+cg_cSprite_draw_xy(mrb_state *mrb, mrb_value self)
+{
+ SDL_Rect dst_rect;
+
+ mrb_value texture_v;
+
+ mrb_int x, y;
+ struct cg_sprite *ptr;
+ struct cg_texture *texture_ptr;
+
+ mrb_get_args(mrb, "ii", &x, &y);
+
+ ptr = (struct cg_sprite *)DATA_PTR(self);
+ texture_v = mrb_iv_get(mrb, self, id_at_texture);
+ texture_ptr = (struct cg_texture *)DATA_PTR(texture_v);
+
+ dst_rect.x = x;
+ dst_rect.y = y;
+ dst_rect.w = ptr->rect.w;
+ dst_rect.h = ptr->rect.h;
+
+ SDL_RenderCopy(cg_core.renderer, texture_ptr->data, &ptr->rect, &dst_rect);
+
+ return self;
+}
+
+void
+cg_sprite_init(mrb_state *mrb)
+{
+ struct RClass *cg_m, *cg_cSprite;
+
+ id_at_texture = mrb_intern_lit(mrb, "@texture");
+
+ cg_m = mrb_module_get(mrb, "CandyGear");
+ cg_cSprite = mrb_define_class_under(mrb, cg_m, "Sprite", mrb->object_class);
+ MRB_SET_INSTANCE_TT(cg_cSprite, MRB_TT_DATA);
+ mrb_define_class_method(
+ mrb, cg_cSprite, "load_yaml", cg_cSrpite_load_yaml, MRB_ARGS_REQ(2));
+ mrb_define_method(
+ mrb, cg_cSprite, "initialize", cg_cSprite_initialize, MRB_ARGS_REQ(5));
+ mrb_define_method(
+ mrb, cg_cSprite, "texture", cg_cSprite_texture, MRB_ARGS_NONE());
+ mrb_define_method(
+ mrb, cg_cSprite, "width", cg_cSprite_width, MRB_ARGS_NONE());
+ mrb_define_method(
+ mrb, cg_cSprite, "height", cg_cSprite_height, MRB_ARGS_NONE());
+ mrb_define_method(
+ mrb, cg_cSprite, "draw", cg_cSprite_draw, MRB_ARGS_REQ(1));
+ mrb_define_method(
+ mrb, cg_cSprite, "draw_xy", cg_cSprite_draw_xy, MRB_ARGS_REQ(2));
+}