diff --git a/src/endgame/island.cpp b/src/endgame/island.cpp index 12a45db3..7eb59346 100644 --- a/src/endgame/island.cpp +++ b/src/endgame/island.cpp @@ -80,7 +80,7 @@ void island_draw() { // draw the scene - Renderer::getInstance()->fillScreen(BLACK); + Renderer::getInstance()->clearScreen(BLACK); Renderer::getInstance()->setClip(island.scene_x, island.scene_y, Renderer::getInstance()->sprites.sprites[SPR_ISLAND_SCENE].w, Renderer::getInstance()->sprites.sprites[SPR_ISLAND_SCENE].h); diff --git a/src/game.cpp b/src/game.cpp index 52d8f37b..8c85c63d 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -220,7 +220,7 @@ bool Game::pause(int pausemode, int param) void Game::tick(void) { - Renderer::getInstance()->clearScreen(); + Renderer::getInstance()->clearScreen(BLACK); debug_clear(); if (game.paused) @@ -353,7 +353,7 @@ void DrawScene(void) { int scr_x, scr_y; extern int flipacceltime; - Renderer::getInstance()->fillScreen(BLACK); + Renderer::getInstance()->clearScreen(BLACK); // draw background map tiles if (!flipacceltime) diff --git a/src/graphics/Renderer.cpp b/src/graphics/Renderer.cpp index 701299f8..292a9034 100644 --- a/src/graphics/Renderer.cpp +++ b/src/graphics/Renderer.cpp @@ -69,6 +69,7 @@ bool Renderer::initVideo(int scale) { uint32_t window_flags = SDL_WINDOW_SHOWN | SDL_WINDOW_ALLOW_HIGHDPI; + //TODO: sync this with setResolution if (widescreen) { screenWidth = 432; screenHeight = 243; @@ -138,6 +139,9 @@ bool Renderer::initVideo(int scale) return false; } + if (!createRenderTarget(screenWidth, screenHeight)) + return false; + std::string spotpath = ResourceManager::getInstance()->getPath("spot.png"); SDL_Surface *image; @@ -148,6 +152,24 @@ bool Renderer::initVideo(int scale) return true; } +bool Renderer::createRenderTarget(int width, int height) +{ + SDL_RendererInfo info; + SDL_GetRendererInfo(_renderer, &info); + + _texture = SDL_CreateTexture(_renderer, + info.texture_formats[0], + SDL_TEXTUREACCESS_TARGET, + width, height); + if (SDL_SetRenderTarget(_renderer, _texture)) { + LOG_ERROR("Renderer::createRenderTarget: SDL_SetRenderTarget failed: {}", SDL_GetError()); + return false; + } + SDL_RenderClear(_renderer); + + return true; +} + bool Renderer::flushAll() { LOG_DEBUG("Renderer::flushAll()"); @@ -200,18 +222,24 @@ bool Renderer::setResolution(int scale, bool newWidescreen) LOG_INFO("Renderer logical resolution: {}x{}", newWidth, newHeight); SDL_SetWindowSize(_window, newWidth * scale, newHeight * scale); + + SDL_SetRenderTarget(_renderer, NULL); + SDL_DestroyTexture(_texture); if (SDL_RenderSetLogicalSize(_renderer, newWidth, newHeight)) { LOG_ERROR("Renderer::setResolution: SDL_RenderSetLogicalSize failed: {}", SDL_GetError()); return false; } + if (!flushAll()) + return false; + + if (!createRenderTarget(newWidth, newHeight)) + return false; + screenWidth = newWidth; screenHeight = newHeight; widescreen = newWidescreen; - if (!flushAll()) - return false; - recalc_map_offsets(); textbox.RecalculateOffsets(); @@ -237,7 +265,7 @@ void Renderer::showLoadingScreen() int x = (screenWidth / 2) - (loading.width() / 2); int y = (screenHeight / 2) - loading.height(); - fillScreen(BLACK); + clearScreen(BLACK); drawSurface(&loading, x, y); flip(); } @@ -252,16 +280,15 @@ SDL_Window* Renderer::window() return _window; } -void Renderer::clearScreen() -{ - SDL_SetRenderDrawColor(_renderer, 0, 0, 0, SDL_ALPHA_OPAQUE); - SDL_RenderClear(_renderer); -} - void Renderer::flip() { // LOG_INFO("===FLIPPING===\n"); + SDL_SetRenderTarget(_renderer, NULL); + SDL_SetRenderDrawColor(_renderer, 0, 0, 0, SDL_ALPHA_OPAQUE); + SDL_RenderClear(_renderer); + SDL_RenderCopy(_renderer, _texture, NULL, NULL); SDL_RenderPresent(_renderer); + SDL_SetRenderTarget(_renderer, _texture); // LOG_INFO("===FLIPPED===\n"); } @@ -390,7 +417,7 @@ void Renderer::drawPixel(int x, int y, uint8_t r, uint8_t g, uint8_t b) fillRect(x, y, x, y, r, g, b); } -void Renderer::fillScreen(uint8_t r, uint8_t g, uint8_t b) +void Renderer::clearScreen(uint8_t r, uint8_t g, uint8_t b) { SDL_SetRenderDrawColor(_renderer, r, g, b, SDL_ALPHA_OPAQUE); SDL_RenderFillRect(_renderer, NULL); diff --git a/src/graphics/Renderer.h b/src/graphics/Renderer.h index 59939012..088d254b 100644 --- a/src/graphics/Renderer.h +++ b/src/graphics/Renderer.h @@ -48,16 +48,14 @@ class Renderer void showLoadingScreen(); - void clearScreen(); - void drawSurface(Surface *src, int x, int y); void drawSurface(Surface *src, int dstx, int dsty, int srcx, int srcy, int wd, int ht); void drawSurfaceMirrored(Surface *src, int dstx, int dsty, int srcx, int srcy, int wd, int ht); void blitPatternAcross(Surface *sfc, int x_dst, int y_dst, int y_src, int height); - void fillScreen(NXColor color); - void fillScreen(uint8_t r, uint8_t g, uint8_t b); + void clearScreen(NXColor color); + void clearScreen(uint8_t r, uint8_t g, uint8_t b); void drawLine(int x1, int y1, int x2, int y2, NXColor color); @@ -96,12 +94,15 @@ class Renderer private: SDL_Window *_window = nullptr; SDL_Renderer *_renderer = nullptr; + SDL_Texture *_texture = nullptr; int _current_res = -1; bool _need_clip = false; SDL_Rect _clip_rect; SDL_Texture* _spot_light; bool _fullscreen = false; + bool createRenderTarget(int width, int height); + protected: friend class Singleton; @@ -151,9 +152,9 @@ void inline Renderer::drawPixel(int x, int y, NXColor color) drawPixel(x, y, color.r, color.g, color.b); } -void inline Renderer::fillScreen(NXColor color) +void inline Renderer::clearScreen(NXColor color) { - fillScreen(color.r, color.g, color.b); + clearScreen(color.r, color.g, color.b); } void inline Renderer::setClip(NXRect *rect) diff --git a/src/intro/intro.cpp b/src/intro/intro.cpp index 85b8d907..f591d860 100644 --- a/src/intro/intro.cpp +++ b/src/intro/intro.cpp @@ -43,7 +43,7 @@ void intro_tick() } if (blanktimer > 0) { - Renderer::getInstance()->fillScreen(BLACK); + Renderer::getInstance()->clearScreen(BLACK); if (--blanktimer == 0) game.setmode(GM_TITLE); diff --git a/src/intro/title.cpp b/src/intro/title.cpp index 6229aa3c..6cea97cf 100644 --- a/src/intro/title.cpp +++ b/src/intro/title.cpp @@ -62,7 +62,7 @@ std::vector _menuitems; static void draw_title() { // background is dk grey, not pure black - Renderer::getInstance()->fillScreen(0x20, 0x20, 0x20); + Renderer::getInstance()->clearScreen(0x20, 0x20, 0x20); map_draw_backdrop(); // DrawFastLeftLayered(); @@ -343,7 +343,7 @@ void title_tick() { if (title.seldelay > 0) { - Renderer::getInstance()->fillScreen(BLACK); + Renderer::getInstance()->clearScreen(BLACK); title.seldelay--; if (!title.seldelay) @@ -357,7 +357,7 @@ void title_tick() } else { - Renderer::getInstance()->fillScreen(BLACK); + Renderer::getInstance()->clearScreen(BLACK); if (!textbox.SaveSelect.IsVisible()) { // selection was made, and settings.last_save_slot is now set appropriately diff --git a/src/map.cpp b/src/map.cpp index dfe4dd72..94ec6376 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -588,9 +588,9 @@ void map_draw_backdrop(void) case BK_HIDE3: { if (game.curmap == STAGE_KINGS) // intro cutscene - Renderer::getInstance()->fillScreen(BLACK); + Renderer::getInstance()->clearScreen(BLACK); else - Renderer::getInstance()->fillScreen(DK_BLUE); + Renderer::getInstance()->clearScreen(DK_BLUE); } return; @@ -644,15 +644,15 @@ void DrawFastLeftLayered(void) y1 = x = 0; // fix for extra height if (map.backdrop == 9) - Renderer::getInstance()->fillScreen(111, 156, 214); + Renderer::getInstance()->clearScreen(111, 156, 214); else if (map.backdrop == 10 && game.curmap != 64) - Renderer::getInstance()->fillScreen(107, 105, 82); + Renderer::getInstance()->clearScreen(107, 105, 82); else if (map.backdrop == 12) - Renderer::getInstance()->fillScreen(179, 190, 210); + Renderer::getInstance()->clearScreen(179, 190, 210); else if (map.backdrop == 13) - Renderer::getInstance()->fillScreen(170, 101, 0); + Renderer::getInstance()->clearScreen(170, 101, 0); else if (map.backdrop == 14) - Renderer::getInstance()->fillScreen(202, 97, 97); + Renderer::getInstance()->clearScreen(202, 97, 97); for (i = 0; i < nlayers; i++) { diff --git a/src/pause/mods.cpp b/src/pause/mods.cpp index 9c3f83c5..4e3ac62b 100644 --- a/src/pause/mods.cpp +++ b/src/pause/mods.cpp @@ -72,7 +72,7 @@ bool mods_init(int param) void mods_tick() { if (moddlg != NULL) { - Renderer::getInstance()->fillScreen(BLACK); + Renderer::getInstance()->clearScreen(BLACK); moddlg->Draw(); moddlg->RunInput(); } diff --git a/src/pause/options.cpp b/src/pause/options.cpp index 0aa50887..e1507fcf 100644 --- a/src/pause/options.cpp +++ b/src/pause/options.cpp @@ -113,7 +113,7 @@ void options_tick() unsigned int i; FocusHolder *fh; - Renderer::getInstance()->fillScreen(BLACK); + Renderer::getInstance()->clearScreen(BLACK); Options::run_and_draw_objects(); fh = (FocusHolder *)optionstack.at(optionstack.size() - 1); diff --git a/src/screeneffect.cpp b/src/screeneffect.cpp index a091ccad..b73a69a8 100644 --- a/src/screeneffect.cpp +++ b/src/screeneffect.cpp @@ -41,7 +41,7 @@ void SE_FlashScreen::Draw(void) } if (flashstate) - Renderer::getInstance()->fillScreen(0xff, 0xff, 0xff); + Renderer::getInstance()->clearScreen(0xff, 0xff, 0xff); } /* @@ -170,7 +170,7 @@ void SE_Fade::Draw(void) } else if (state == FS_FADED_OUT) { - Renderer::getInstance()->fillScreen(DK_BLUE); + Renderer::getInstance()->clearScreen(DK_BLUE); return; }