/* * 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 #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)); }