// // Created by m on 12/3/21. // #include #include #include "sdlrenderer.hpp" void SdlRenderer::flush() { SDL_RenderPresent(this->renderer.get()); SDL_SetRenderDrawColor(this->renderer.get(), COLOR_BLACK.r, COLOR_BLACK.g, COLOR_BLACK.b, COLOR_BLACK.a); SDL_RenderClear(this->renderer.get()); } void SdlRenderer::draw_point(int x, int y, Color color) { SDL_SetRenderDrawColor(this->renderer.get(), color.r, color.g, color.b, color.a); SDL_RenderDrawPoint(this->renderer.get(), x, y); } void SdlRenderer::draw_text(std::optional details, std::string text, int x, int y) { TextRenderDetails unpacked_details = details.value_or(this->renderer_params.default_font); std::shared_ptr font = this->font_manager->fetch_resource(SdlFontArgs(unpacked_details.size, unpacked_details.font_path)); std::shared_ptr texture = this->texture_manager->load_text_as_texture(text, font, unpacked_details.color); render_texture(x, y, texture, nullptr); } SdlRenderer::~SdlRenderer() { // clear resource managers pointing to shared pointers // This avoids an invalid read, since otherwise TTF_Quit will cleanup fonts and then clearing the shared pointers will try it again font_manager->clear_all_resources(); texture_manager->clear_all_resources(); // exit subsystems IMG_Quit(); TTF_Quit(); SDL_Quit(); } void SdlRenderer::render_texture(int x, int y, const std::shared_ptr& texture, SDL_Rect *src) { int w, h; if(src == nullptr) { SDL_QueryTexture(texture.get(), nullptr, nullptr, &w, &h); } else { w = src->w; h = src->h; } SDL_Rect rect = {x,y,w,h}; SDL_RenderCopy(this->renderer.get(), texture.get(), src, &rect); } void SdlRenderer::draw_sprite(Sprite sprite, int x, int y) { SpriteSheet *sprite_sheet = sprite.sprite_sheet; TextureManagerFetchArgs args = TextureManagerFetchArgs {sprite_sheet->path, sprite_sheet->color_key}; std::shared_ptr texture = this->texture_manager->fetch_resource(args); int w, h; SDL_QueryTexture(texture.get(), nullptr, nullptr, &w, &h); int l = (sprite_sheet->sprite_width * sprite.index) / w; int src_y = l*sprite_sheet->sprite_height; int src_x = (sprite_sheet->sprite_width * sprite.index) % w; auto source = SDL_Rect{src_x, src_y, sprite_sheet->sprite_width, sprite_sheet->sprite_height}; render_texture(x, y, texture, &source); } SdlRenderer::SdlRenderer(RendererParams renderer_params) : renderer_params(std::move(renderer_params)) { if(SDL_Init(SDL_INIT_VIDEO) < 0) { printf("SDL vide oinit failed: %s\n", SDL_GetError()); exit(EXIT_FAILURE); } auto img_flags = IMG_INIT_PNG; if(!(IMG_Init(img_flags) & img_flags)) { printf("Failed to init image loading: %s\n", IMG_GetError()); exit(EXIT_FAILURE); } if(TTF_Init() < 0) { printf("Failed to initialize font loading: %s\n", TTF_GetError()); exit(EXIT_FAILURE); } SDL_Window* sdl_window = SDL_CreateWindow(this->renderer_params.title.c_str(), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, this->renderer_params.width, this->renderer_params.height, SDL_WINDOW_SHOWN); if(sdl_window == nullptr) { printf("error making window: %s\n", SDL_GetError()); exit(EXIT_FAILURE); } else { this->window = std::unique_ptr(sdl_window); SDL_Renderer* sdl_renderer = SDL_CreateRenderer(this->window.get(), -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC); this->renderer = std::shared_ptr(sdl_renderer, SDL_DestroyRenderer); this->texture_manager = std::make_unique(this->renderer); this->font_manager = std::make_unique(); SDL_RenderClear(this->renderer.get()); } }