diff --git a/src/options.cpp b/src/options.cpp index db136cf936262..58c5b65940592 100644 --- a/src/options.cpp +++ b/src/options.cpp @@ -1594,6 +1594,16 @@ void options_manager::add_options_graphics() { "linear", translate_marker( "Linear filtering" ) } }, "none", COPT_CURSES_HIDE ); + + add( "SCALING_FACTOR", "graphics", translate_marker( "Scaling factor" ), + translate_marker( "Factor by which to scale the display." ), { + { "1", translate_marker( "1x" ) }, + { "2", translate_marker( "2x" )}, + { "4", translate_marker( "4x" )}, + { "8", translate_marker( "8x" )} + }, + "1", COPT_CURSES_HIDE ); + } void options_manager::add_options_debug() diff --git a/src/sdltiles.cpp b/src/sdltiles.cpp index dbcfed027fcfc..6ea96f4379387 100644 --- a/src/sdltiles.cpp +++ b/src/sdltiles.cpp @@ -93,7 +93,7 @@ class Font { #ifdef __ANDROID__ opacity(1.0f), #endif - fontwidth(w), fontheight(h) { } + fontwidth( w ), fontheight( h ) { } virtual ~Font() = default; /** * Draw character t at (x,y) on the screen, @@ -198,6 +198,7 @@ int fontheight; //the height of the font, background is always this size static int TERMINAL_WIDTH; static int TERMINAL_HEIGHT; bool fullscreen; +int scaling_factor; static SDL_Joystick *joystick; // Only one joystick for now. @@ -311,7 +312,12 @@ void InitSDL() bool SetupRenderTarget() { SetRenderDrawBlendMode( renderer, SDL_BLENDMODE_NONE ); - display_buffer.reset( SDL_CreateTexture( renderer.get(), SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, WindowWidth, WindowHeight ) ); + if( scaling_factor > 0 ) { + SDL_RenderSetLogicalSize( renderer.get(), WindowWidth / scaling_factor, WindowHeight / scaling_factor ); + display_buffer.reset( SDL_CreateTexture( renderer.get(), SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, WindowWidth / scaling_factor, WindowHeight / scaling_factor ) ); + } else { + display_buffer.reset( SDL_CreateTexture( renderer.get(), SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, WindowWidth, WindowHeight ) ); + } if( printErrorIf( !display_buffer, "Failed to create window buffer" ) ) { return false; } @@ -330,8 +336,8 @@ void WinCreate() // Common flags used for fulscreen and for windowed int window_flags = 0; - WindowWidth = TERMINAL_WIDTH * fontwidth; - WindowHeight = TERMINAL_HEIGHT * fontheight; + WindowWidth = TERMINAL_WIDTH * fontwidth * scaling_factor; + WindowHeight = TERMINAL_HEIGHT * fontheight * scaling_factor; window_flags |= SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI; if( get_option( "SCALING_MODE" ) != "none" ) { @@ -448,7 +454,7 @@ void WinCreate() throwErrorIf( !SetupRenderTarget(), "Failed to initialize display buffer under software rendering, unable to continue." ); } - SDL_SetWindowMinimumSize( ::window.get(), fontwidth * 80, fontheight * 24 ); + SDL_SetWindowMinimumSize( ::window.get(), fontwidth * 80 * scaling_factor, fontheight * 24 * scaling_factor ); #ifdef __ANDROID__ // TODO: Not too sure why this works to make fullscreen on Android behave. :/ @@ -754,6 +760,9 @@ void refresh_display() // Select default target (the window), copy rendered buffer // there, present it, select the buffer as target again. SetRenderTarget( renderer, NULL ); + if( scaling_factor > 0 ) { + SDL_RenderSetLogicalSize( renderer.get(), WindowWidth / scaling_factor, WindowHeight / scaling_factor ); + } #ifdef __ANDROID__ SDL_Rect dstrect = get_android_render_rect( TERMINAL_WIDTH * fontwidth, TERMINAL_HEIGHT * fontheight ); SetRenderDrawColor( renderer, 0, 0, 0, 255 ); @@ -954,6 +963,9 @@ void clear_window_area( const catacurses::window &win_ ) void cata_cursesport::curses_drawwindow( const catacurses::window &w ) { + if( scaling_factor > 0 ) { + SDL_RenderSetLogicalSize( renderer.get(), WindowWidth / scaling_factor, WindowHeight / scaling_factor ); + } WINDOW *const win = w.get(); bool update = false; if (g && w == g->w_terrain && use_tiles) { @@ -1091,6 +1103,9 @@ bool Font::draw_window( const catacurses::window &w ) bool Font::draw_window( const catacurses::window &w, const int offsetx, const int offsety ) { + // SDL_RenderSetScale( renderer.get(), 1.2, 1.2); + SDL_RenderSetLogicalSize( renderer.get(), WindowWidth / scaling_factor, WindowHeight / scaling_factor ); + cata_cursesport::WINDOW *const win = w.get(); //Keeping track of the last drawn window const cata_cursesport::WINDOW *winBuffer = static_cast( ::winBuffer.lock().get() ); @@ -1432,8 +1447,8 @@ bool handle_resize(int w, int h) if( ( w != WindowWidth ) || ( h != WindowHeight ) ) { WindowWidth = w; WindowHeight = h; - TERMINAL_WIDTH = WindowWidth / fontwidth; - TERMINAL_HEIGHT = WindowHeight / fontheight; + TERMINAL_WIDTH = WindowWidth / fontwidth / scaling_factor; + TERMINAL_HEIGHT = WindowHeight / fontheight / scaling_factor; SetupRenderTarget(); game_ui::init_ui(); tilecontext->reinit_minimap(); @@ -2963,8 +2978,22 @@ void catacurses::init_interface() find_videodisplays(); - TERMINAL_WIDTH = get_option( "TERMINAL_X" ); - TERMINAL_HEIGHT = get_option( "TERMINAL_Y" ); + std::string scaling_factor_setting = get_option( "SCALING_FACTOR" ); + if( scaling_factor_setting == "1" ) { + scaling_factor = 1; + } else if( scaling_factor_setting == "2" ) { + scaling_factor = 2; + } else if( scaling_factor_setting == "4" ) { + scaling_factor = 4; + } else if( scaling_factor_setting == "8" ) { + scaling_factor = 8; + } else { + scaling_factor = 1; + } + std::cout << scaling_factor << std::endl; + + TERMINAL_WIDTH = get_option( "TERMINAL_X" ) / scaling_factor; + TERMINAL_HEIGHT = get_option( "TERMINAL_Y" ) / scaling_factor; WinCreate();