Fix the --screenshot commandline arg.

A new fake video mode video::fake::hide_window was added,
as screenshots need a rendering context and thus a window.
It draws everything as normal, just with the window hidden.

The other fake modes were also renamed to increase clarity a bit.
This commit is contained in:
Tommy 2023-10-31 14:25:11 +13:00
parent 50a21a2c6c
commit 3f95df8fdc
6 changed files with 39 additions and 14 deletions

View file

@ -790,7 +790,10 @@ surface display::screenshot(bool map_screenshot)
map_screenshot_ = true;
DBG_DP << "invalidating region for map screenshot";
invalidate_locations_in_rect(map_area());
DBG_DP << "drawing map screenshot";
draw();
map_screenshot_ = false;
@ -800,6 +803,7 @@ surface display::screenshot(bool map_screenshot)
ypos_ = old_ypos;
// Read rendered pixels back as an SDL surface.
LOG_DP << "reading pixels for map screenshot";
return video::read_pixels();
}
@ -1301,6 +1305,9 @@ void display::drawing_buffer_add(const drawing_layer layer, const map_location&
void display::drawing_buffer_commit()
{
DBG_DP << "committing drawing buffer"
<< " with " << drawing_buffer_.size() << " items";
// std::list::sort() is a stable sort
drawing_buffer_.sort();
@ -2394,7 +2401,7 @@ void display::draw()
set_scontext_unsynced leave_synced_context;
// This isn't the best, but also isn't important enough to do better.
if(redraw_background_) {
if(redraw_background_ && !map_screenshot_) {
DBG_DP << "display::draw redraw background";
render_map_outside_area();
draw_manager::invalidate_region(map_outside_area());
@ -3133,7 +3140,7 @@ void display::invalidate_all()
bool display::invalidate(const map_location& loc)
{
if(invalidateAll_)
if(invalidateAll_ && !map_screenshot_)
return false;
bool tmp;
@ -3143,7 +3150,7 @@ bool display::invalidate(const map_location& loc)
bool display::invalidate(const std::set<map_location>& locs)
{
if(invalidateAll_)
if(invalidateAll_ && !map_screenshot_)
return false;
bool ret = false;
for (const map_location& loc : locs) {
@ -3186,7 +3193,7 @@ bool display::invalidate_visible_locations_in_rect(const SDL_Rect& rect)
bool display::invalidate_locations_in_rect(const SDL_Rect& rect)
{
if(invalidateAll_)
if(invalidateAll_ && !map_screenshot_)
return false;
DBG_DP << "invalidating locations in " << rect;

View file

@ -313,6 +313,7 @@ bool game_launcher::init_video()
{
// Handle special commandline launch flags
if(cmdline_opts_.nogui
|| cmdline_opts_.screenshot
|| cmdline_opts_.headless_unit_test
|| cmdline_opts_.render_image)
{
@ -325,7 +326,14 @@ bool game_launcher::init_video()
PLAIN_LOG << "--nogui flag is only valid with --multiplayer or --screenshot or --plugin flags";
return false;
}
video::init(video::fake::window);
if(cmdline_opts_.screenshot) {
// Screenshots require a rendering context, and thus a window,
// so we create one but hidden.
video::init(video::fake::hide_window);
} else {
// Other functions don't require a window at all.
video::init(video::fake::no_window);
}
game_config::no_delay = true;
return true;
}

View file

@ -68,7 +68,7 @@ fake_display_manager::fake_display_manager()
, main_event_context_()
, disp_(dummy_board_, std::shared_ptr<wb::manager>(), dummy_reports, "", dummy_cfg_)
{
video::init(video::fake::draw);
video::init(video::fake::no_draw);
}
game_display& fake_display_manager::get_display()

View file

@ -74,7 +74,7 @@ namespace video
void render_screen(); // exposed and used only in draw_manager.cpp
// Internal functions
static void init_window();
static void init_window(bool hidden=false);
static void init_test_window();
static void init_fake();
static void init_test();
@ -98,12 +98,15 @@ void init(fake type)
case fake::none:
init_window();
break;
case fake::window:
case fake::no_window:
init_fake();
break;
case fake::draw:
case fake::no_draw:
init_test();
break;
case fake::hide_window:
init_window(true);
break;
default:
throw error("unrecognized fake type passed to video::init");
}
@ -151,6 +154,7 @@ bool testing()
void init_fake()
{
LOG_DP << "running headless";
headless_ = true;
refresh_rate_ = 1;
game_canvas_size_ = {800,600};
@ -351,7 +355,7 @@ void init_test_window()
update_test_framebuffer();
}
void init_window()
void init_window(bool hidden)
{
// Position
const int x = preferences::fullscreen() ? SDL_WINDOWPOS_UNDEFINED : SDL_WINDOWPOS_CENTERED;
@ -374,6 +378,11 @@ void init_window()
window_flags |= SDL_WINDOW_MAXIMIZED;
}
if(hidden) {
LOG_DP << "hiding main window";
window_flags |= SDL_WINDOW_HIDDEN;
}
uint32_t renderer_flags = SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE;
if(preferences::vsync()) {

View file

@ -38,10 +38,11 @@ namespace video
/**
* For describing the type of faked display, if any.
*
* fake::window never tries to create a window, or draw anything.
* fake::draw does create an offscreen window, but does not draw to it.
* fake::no_window never tries to create a window, or draw anything.
* fake::no_draw does create an offscreen window, but does not draw to it.
* fake::hide_window creates a window as normal, but does not display it.
*/
enum class fake { none, window, draw };
enum class fake { none, no_window, no_draw, hide_window };
/**
* Initialize the video subsystem.

View file

@ -503,7 +503,7 @@ static int process_command_args(const commandline_options& cmdline_opts)
srand(*cmdline_opts.rng_seed);
}
if(cmdline_opts.screenshot || cmdline_opts.render_image) {
if(cmdline_opts.render_image) {
SDL_setenv("SDL_VIDEODRIVER", "dummy", 1);
}