diff options
Diffstat (limited to 'src/sprite.c')
-rw-r--r-- | src/sprite.c | 198 |
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)); +} |