diff --git a/source/code/global.hpp b/source/code/global.hpp index eb9c185..cfe4ede 100644 --- a/source/code/global.hpp +++ b/source/code/global.hpp @@ -26,6 +26,7 @@ http://www.blockattack.net #include #include "sago/SagoSpriteHolder.hpp" +#include "sago/SagoLogicalResize.hpp" #include "highscore.h" #include "sago/GameStateInterface.hpp" #include "TextManager.hpp" @@ -107,6 +108,7 @@ struct GlobalData { std::vector modList; ModInfo modinfo; Theme theme; + sago::SagoLogicalResize logicalResize; TextManager theTextManager; diff --git a/source/code/main.cpp b/source/code/main.cpp index 1ebb55d..710ea40 100644 --- a/source/code/main.cpp +++ b/source/code/main.cpp @@ -257,7 +257,8 @@ void ResetFullscreen() { if (globalData.xsize < FOUR_THREE_WIDTH) { globalData.xsize = FOUR_THREE_WIDTH; } - SDL_RenderSetLogicalSize(globalData.screen, globalData.xsize, globalData.ysize); + //SDL_RenderSetLogicalSize(globalData.screen, globalData.xsize, globalData.ysize); + globalData.logicalResize = sago::SagoLogicalResize(globalData.xsize, globalData.ysize); dataHolder.invalidateAll(globalData.screen); globalData.spriteHolder.reset(new sago::SagoSpriteHolder( dataHolder ) ); globalData.spriteHolder->ReadSprites(globalData.modinfo.getModSpriteFiles()); @@ -269,10 +270,12 @@ void ResetFullscreen() { SDL_ShowCursor(SDL_DISABLE); } -static bool logicalRenderer = false; - void DrawBackground(SDL_Renderer* target) { SDL_RenderClear(target); + int w=1; + int h=1; + SDL_GetRendererOutputSize(target, &w, &h); + globalData.logicalResize.SetPhysicalSize(w, h); sago::SagoSprite background = globalData.spriteHolder->GetSprite(globalData.theme.background.background_sprite); if ( (double)globalData.xsize/globalData.ysize > 1.5 && globalData.theme.background.background_sprite_16x9.length()) { background = globalData.spriteHolder->GetSprite(globalData.theme.background.background_sprite_16x9); @@ -296,7 +299,9 @@ void DrawBackground(SDL_Renderer* target) { } return; } - background.DrawScaled(target, ticks, 0, 0, globalData.xsize, globalData.ysize); + SDL_Rect r = {0,0,globalData.xsize,globalData.ysize}; + globalData.logicalResize.LogicalToPhysical(r); + background.DrawScaled(target, ticks, r.x, r.y, r.w, r.h); } /** @@ -1175,6 +1180,7 @@ int main(int argc, char* argv[]) { globalData.xsize = SIXTEEN_NINE_WIDTH; } globalData.ysize = SCREEN_HIGHT; + globalData.logicalResize = sago::SagoLogicalResize(globalData.xsize, globalData.ysize); sdlWindow = SDL_CreateWindow("Block Attack - Rise of the Blocks " VERSION_NUMBER, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, @@ -1187,10 +1193,9 @@ int main(int argc, char* argv[]) { } SDL_Renderer* renderer = SDL_CreateRenderer(sdlWindow, -1, rendererFlags); dieOnNullptr(renderer, "Unable to create render"); - if (config.autoScale) { + /*if (config.autoScale) { SDL_RenderSetLogicalSize(renderer, globalData.xsize, globalData.ysize); - logicalRenderer = true; - } + }*/ if (globalData.verboseLevel) { SDL_RendererInfo info; SDL_GetRendererInfo(renderer, &info); diff --git a/source/code/sago/SagoLogicalResize.hpp b/source/code/sago/SagoLogicalResize.hpp new file mode 100644 index 0000000..96698ed --- /dev/null +++ b/source/code/sago/SagoLogicalResize.hpp @@ -0,0 +1,80 @@ +#include +#include "SDL.h" + + +namespace sago { + +class SagoLogicalResize +{ +public: + SagoLogicalResize() : logical_width_(1), logical_height_(1), physical_width_(1), physical_height_(1) { SetScaleFactor(); } + SagoLogicalResize(int logical_width, int logical_height) + : logical_width_(std::max(1, logical_width)), logical_height_(std::max(1, logical_height)), physical_width_(1), physical_height_(1) { SetScaleFactor(); } + + void SetPhysicalSize(int physical_width, int physical_height) + { + physical_width_ = std::max(1, physical_width); + physical_height_ = std::max(1, physical_height); + SetScaleFactor(); + } + + void LogicalToPhysical(int logical_x, int logical_y, int &physical_x, int &physical_y) const + { + physical_x = logical_x; + physical_y = logical_y; + LogicalToPhysical(&physical_x, &physical_y); + } + + void LogicalToPhysical(int *x, int *y) const + { + if (x) { + *x = *x * scale_factor_ + left_margin_; + } + if (y) { + *y = *y * scale_factor_ + top_margin_; + } + } + + void LogicalToPhysical(SDL_Rect &inout) const + { + SDL_Rect input = inout; + LogicalToPhysical(&inout.x, &inout.y); + LogicalToPhysical(input.x + input.w + 1, input.y + input.h + 1, inout.w, inout.h); + inout.w -= inout.x - 1; + inout.h -= inout.y - 1; + } + + void PhysicalToLogical(int physical_x, int physical_y, int &logical_x, int &logical_y) const + { + logical_x = physical_x * logical_width_ / physical_width_ + left_margin_; + logical_y = physical_y * logical_height_ / physical_height_ + top_margin_; + } + + int GetTopMargin() const + { + return top_margin_; + } + + int GetLeftMargin() const + { + return left_margin_; + } + +private: + void SetScaleFactor() + { + scale_factor_ = std::min(physical_width_ / logical_width_, physical_height_ / logical_height_); + left_margin_ = (physical_width_ - logical_width_ * scale_factor_) / 2; + top_margin_ = (physical_height_ - logical_height_ * scale_factor_) / 2; + } + + double scale_factor_; + int top_margin_; + int left_margin_; + double logical_width_; + double logical_height_; + double physical_width_; + double physical_height_; +}; + +} // namespace sago \ No newline at end of file