diff --git a/src/console_cmds.cpp b/src/console_cmds.cpp index 140d91e70f5f0..c2f62ff7125f8 100644 --- a/src/console_cmds.cpp +++ b/src/console_cmds.cpp @@ -1407,17 +1407,21 @@ DEF_CONSOLE_CMD(ConAlias) DEF_CONSOLE_CMD(ConScreenShot) { if (argc == 0) { - IConsoleHelp("Create a screenshot of the game. Usage: 'screenshot [big | giant | no_con | minimap] [file name]'"); + IConsoleHelp("Create a screenshot of the game. Usage: 'screenshot [big | giant | no_con | minimap | res ] []'"); IConsoleHelp("'big' makes a zoomed-in screenshot of the visible area, 'giant' makes a screenshot of the " "whole map, 'no_con' hides the console to create the screenshot. 'big' or 'giant' " "screenshots are always drawn without console. " - "'minimap' makes a top-viewed minimap screenshot of whole world which represents one tile by one pixel."); + "'minimap' makes a top-viewed minimap screenshot of whole world which represents one tile by one pixel. " + "'res' makes a screenshot at the default zoom level, but with a custom screen resolution. " + "if either or is 0, a default zoom screenshot of the visible area is made instead."); return true; } - if (argc > 3) return false; + if ((argc > 3 && strcmp(argv[1], "res") != 0) || argc > 5) return false; ScreenshotType type = SC_VIEWPORT; + uint32 res_x = 0; + uint32 res_y = 0; const char *name = nullptr; if (argc > 1) { @@ -1437,6 +1441,13 @@ DEF_CONSOLE_CMD(ConScreenShot) /* screenshot no_con [filename] */ IConsoleClose(); if (argc > 2) name = argv[2]; + } else if (strcmp(argv[1], "res") == 0) { + /* screenshot res [filename] */ + if (argc < 4) return false; + type = SC_DEFAULTZOOM; + GetArgumentInteger(&res_x, argv[2]); + GetArgumentInteger(&res_y, argv[3]); + if (argc > 4) name = argv[4]; } else if (argc == 2) { /* screenshot filename */ name = argv[1]; @@ -1446,7 +1457,7 @@ DEF_CONSOLE_CMD(ConScreenShot) } } - MakeScreenshot(type, name); + MakeScreenshot(type, name, res_x, res_y); return true; } diff --git a/src/screenshot.cpp b/src/screenshot.cpp index ef76b9f0e7eb2..8f418dcc6284f 100644 --- a/src/screenshot.cpp +++ b/src/screenshot.cpp @@ -711,7 +711,7 @@ static bool MakeSmallScreenshot(bool crashlog) * @param t Screenshot type * @param[out] vp Result viewport */ -void SetupScreenshotViewport(ScreenshotType t, Viewport *vp) +void SetupScreenshotViewport(ScreenshotType t, Viewport *vp, uint32 res_x, uint32 res_y) { switch(t) { case SC_VIEWPORT: @@ -761,14 +761,23 @@ void SetupScreenshotViewport(ScreenshotType t, Viewport *vp) Window *w = FindWindowById(WC_MAIN_WINDOW, 0); vp->virtual_left = w->viewport->virtual_left; vp->virtual_top = w->viewport->virtual_top; - vp->virtual_width = w->viewport->virtual_width; - vp->virtual_height = w->viewport->virtual_height; - - /* Compute pixel coordinates */ vp->left = 0; vp->top = 0; - vp->width = UnScaleByZoom(vp->virtual_width, vp->zoom); - vp->height = UnScaleByZoom(vp->virtual_height, vp->zoom); + + if (res_x != 0 && res_y != 0) { + vp->width = res_x; + vp->height = res_y; + + vp->virtual_width = res_x << vp->zoom; + vp->virtual_height = res_y << vp->zoom; + } else { + vp->virtual_width = w->viewport->virtual_width; + vp->virtual_height = w->viewport->virtual_height; + + /* Compute pixel coordinates */ + vp->width = UnScaleByZoom(vp->virtual_width, vp->zoom); + vp->height = UnScaleByZoom(vp->virtual_height, vp->zoom); + } vp->overlay = nullptr; break; } @@ -780,10 +789,10 @@ void SetupScreenshotViewport(ScreenshotType t, Viewport *vp) * @param t Screenshot type: World or viewport screenshot * @return true on success */ -static bool MakeLargeWorldScreenshot(ScreenshotType t) +static bool MakeLargeWorldScreenshot(ScreenshotType t, uint32 res_x = 0, uint32 res_y = 0) { Viewport vp; - SetupScreenshotViewport(t, &vp); + SetupScreenshotViewport(t, &vp, res_x, res_y); const ScreenshotFormat *sf = _screenshot_formats + _cur_screenshot_format; return sf->proc(MakeScreenshotName(SCREENSHOT_NAME, sf->extension), LargeWorldCallback, &vp, vp.width, vp.height, @@ -879,7 +888,7 @@ void MakeScreenshotWithConfirm(ScreenshotType t) * @return true iff the screenshot was made successfully * @see MakeScreenshotWithConfirm */ -bool MakeScreenshot(ScreenshotType t, const char *name) +bool MakeScreenshot(ScreenshotType t, const char *name, uint32 res_x, uint32 res_y) { if (t == SC_VIEWPORT) { /* First draw the dirty parts of the screen and only then change the name @@ -906,7 +915,7 @@ bool MakeScreenshot(ScreenshotType t, const char *name) case SC_ZOOMEDIN: case SC_DEFAULTZOOM: case SC_WORLD: - ret = MakeLargeWorldScreenshot(t); + ret = MakeLargeWorldScreenshot(t, res_x, res_y); break; case SC_HEIGHTMAP: { diff --git a/src/screenshot.h b/src/screenshot.h index 400f8164e5acb..e829d1d8ea47c 100644 --- a/src/screenshot.h +++ b/src/screenshot.h @@ -25,10 +25,10 @@ enum ScreenshotType { SC_MINIMAP, ///< Minimap screenshot. }; -void SetupScreenshotViewport(ScreenshotType t, struct Viewport *vp); +void SetupScreenshotViewport(ScreenshotType t, struct Viewport *vp, uint32 res_x = 0, uint32 res_y = 0); bool MakeHeightmapScreenshot(const char *filename); void MakeScreenshotWithConfirm(ScreenshotType t); -bool MakeScreenshot(ScreenshotType t, const char *name); +bool MakeScreenshot(ScreenshotType t, const char *name, uint32 res_x = 0, uint32 res_y = 0); bool MakeMinimapWorldScreenshot(); extern char _screenshot_format_name[8];