Changeset - r24995:a0ac81bc6d3b
[Not reviewed]
master
0 3 0
Patric Stout - 3 years ago 2021-01-22 15:16:33
truebrain@openttd.org
Feature: allow custom width/height of screenshot via console

Reworked how the screenshot command works while keeping it backwards
compatible. It can now more freely understand arguments, and has
the ability to make SC_DEFAULTZOOM screenshots.
3 files changed with 85 insertions and 36 deletions:
0 comments (0 inline, 0 general)
src/console_cmds.cpp
Show inline comments
 
@@ -1409,46 +1409,76 @@ 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("'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.");
 
		IConsoleHelp("Create a screenshot of the game. Usage: 'screenshot [viewport | normal | big | giant | minimap] [no_con] [size <width> <height>] [<filename>]'");
 
		IConsoleHelp("'viewport' (default) makes a screenshot of the current viewport (including menus, windows, ..), "
 
				"'normal' makes a screenshot of the visible area, "
 
				"'big' makes a zoomed-in screenshot of the visible area, "
 
				"'giant' makes a screenshot of the whole map, "
 
				"'minimap' makes a top-viewed minimap screenshot of the whole world which represents one tile by one pixel. "
 
				"'no_con' hides the console to create the screenshot (only useful in combination with 'viewport'). "
 
				"'size' sets the width and height of the viewport to make a screenshot of (only useful in combination with 'normal' or 'big').");
 
		return true;
 
	}
 

	
 
	if (argc > 3) return false;
 
	if (argc > 7) return false;
 

	
 
	ScreenshotType type = SC_VIEWPORT;
 
	uint32 width = 0;
 
	uint32 height = 0;
 
	const char *name = nullptr;
 
	uint32 arg_index = 1;
 

	
 
	if (argc > 1) {
 
		if (strcmp(argv[1], "big") == 0) {
 
			/* screenshot big [filename] */
 
	if (argc > arg_index) {
 
		if (strcmp(argv[arg_index], "viewport") == 0) {
 
			type = SC_VIEWPORT;
 
			arg_index += 1;
 
		} else if (strcmp(argv[arg_index], "normal") == 0) {
 
			type = SC_DEFAULTZOOM;
 
			arg_index += 1;
 
		} else if (strcmp(argv[arg_index], "big") == 0) {
 
			type = SC_ZOOMEDIN;
 
			if (argc > 2) name = argv[2];
 
		} else if (strcmp(argv[1], "giant") == 0) {
 
			/* screenshot giant [filename] */
 
			arg_index += 1;
 
		} else if (strcmp(argv[arg_index], "giant") == 0) {
 
			type = SC_WORLD;
 
			if (argc > 2) name = argv[2];
 
		} else if (strcmp(argv[1], "minimap") == 0) {
 
			/* screenshot minimap [filename] */
 
			arg_index += 1;
 
		} else if (strcmp(argv[arg_index], "minimap") == 0) {
 
			type = SC_MINIMAP;
 
			if (argc > 2) name = argv[2];
 
		} else if (strcmp(argv[1], "no_con") == 0) {
 
			/* screenshot no_con [filename] */
 
			IConsoleClose();
 
			if (argc > 2) name = argv[2];
 
		} else if (argc == 2) {
 
			/* screenshot filename */
 
			name = argv[1];
 
		} else {
 
			/* screenshot argv[1] argv[2] - invalid */
 
			return false;
 
			arg_index += 1;
 
		}
 
	}
 

	
 
	MakeScreenshot(type, name);
 
	if (argc > arg_index && strcmp(argv[arg_index], "no_con") == 0) {
 
		if (type != SC_VIEWPORT) {
 
			IConsoleError("'no_con' can only be used in combination with 'viewport'");
 
			return true;
 
		}
 
		IConsoleClose();
 
		arg_index += 1;
 
	}
 

	
 
	if (argc > arg_index + 2 && strcmp(argv[arg_index], "size") == 0) {
 
		/* size <width> <height> */
 
		if (type != SC_DEFAULTZOOM && type != SC_ZOOMEDIN) {
 
			IConsoleError("'size' can only be used in combination with 'normal' or 'big'");
 
			return true;
 
		}
 
		GetArgumentInteger(&width, argv[arg_index + 1]);
 
		GetArgumentInteger(&height, argv[arg_index + 2]);
 
		arg_index += 3;
 
	}
 

	
 
	if (argc > arg_index) {
 
		/* Last parameter that was not one of the keywords must be the filename. */
 
		name = argv[arg_index];
 
		arg_index += 1;
 
	}
 

	
 
	if (argc > arg_index) {
 
		/* We have parameters we did not process; means we misunderstood any of the above. */
 
		return false;
 
	}
 

	
 
	MakeScreenshot(type, name, width, height);
 
	return true;
 
}
 

	
src/screenshot.cpp
Show inline comments
 
@@ -710,13 +710,17 @@ static bool MakeSmallScreenshot(bool cra
 
/**
 
 * Configure a Viewport for rendering (a part of) the map into a screenshot.
 
 * @param t Screenshot type
 
 * @param width the width of the screenshot, or 0 for current viewport width (needs to be 0 with SC_VIEWPORT, SC_CRASHLOG, and SC_WORLD).
 
 * @param height the height of the screenshot, or 0 for current viewport height (needs to be 0 with SC_VIEWPORT, SC_CRASHLOG, and SC_WORLD).
 
 * @param[out] vp Result viewport
 
 */
 
void SetupScreenshotViewport(ScreenshotType t, Viewport *vp)
 
void SetupScreenshotViewport(ScreenshotType t, Viewport *vp, uint32 width, uint32 height)
 
{
 
	switch(t) {
 
		case SC_VIEWPORT:
 
		case SC_CRASHLOG: {
 
			assert(width == 0 && height == 0);
 

	
 
			Window *w = FindWindowById(WC_MAIN_WINDOW, 0);
 
			vp->virtual_left   = w->viewport->virtual_left;
 
			vp->virtual_top    = w->viewport->virtual_top;
 
@@ -726,12 +730,14 @@ void SetupScreenshotViewport(ScreenshotT
 
			/* Compute pixel coordinates */
 
			vp->left = 0;
 
			vp->top = 0;
 
			vp->width  = _screen.width;
 
			vp->width = _screen.width;
 
			vp->height = _screen.height;
 
			vp->overlay = w->viewport->overlay;
 
			break;
 
		}
 
		case SC_WORLD: {
 
			assert(width == 0 && height == 0);
 

	
 
			/* Determine world coordinates of screenshot */
 
			vp->zoom = ZOOM_LVL_WORLD_SCREENSHOT;
 

	
 
@@ -762,8 +768,14 @@ void SetupScreenshotViewport(ScreenshotT
 
			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;
 

	
 
			if (width == 0 || height == 0) {
 
				vp->virtual_width  = w->viewport->virtual_width;
 
				vp->virtual_height = w->viewport->virtual_height;
 
			} else {
 
				vp->virtual_width = width << vp->zoom;
 
				vp->virtual_height = height << vp->zoom;
 
			}
 

	
 
			/* Compute pixel coordinates */
 
			vp->left = 0;
 
@@ -779,12 +791,14 @@ void SetupScreenshotViewport(ScreenshotT
 
/**
 
 * Make a screenshot of the map.
 
 * @param t Screenshot type: World or viewport screenshot
 
 * @param width the width of the screenshot of, or 0 for current viewport width.
 
 * @param height the height of the screenshot of, or 0 for current viewport height.
 
 * @return true on success
 
 */
 
static bool MakeLargeWorldScreenshot(ScreenshotType t)
 
static bool MakeLargeWorldScreenshot(ScreenshotType t, uint32 width = 0, uint32 height = 0)
 
{
 
	Viewport vp;
 
	SetupScreenshotViewport(t, &vp);
 
	SetupScreenshotViewport(t, &vp, width, height);
 

	
 
	const ScreenshotFormat *sf = _screenshot_formats + _cur_screenshot_format;
 
	return sf->proc(MakeScreenshotName(SCREENSHOT_NAME, sf->extension), LargeWorldCallback, &vp, vp.width, vp.height,
 
@@ -877,10 +891,12 @@ void MakeScreenshotWithConfirm(Screensho
 
 * Unconditionally take a screenshot of the requested type.
 
 * @param t    the type of screenshot to make.
 
 * @param name the name to give to the screenshot.
 
 * @param width the width of the screenshot of, or 0 for current viewport width (only works for SC_ZOOMEDIN and SC_DEFAULTZOOM).
 
 * @param height the height of the screenshot of, or 0 for current viewport height (only works for SC_ZOOMEDIN and SC_DEFAULTZOOM).
 
 * @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 width, uint32 height)
 
{
 
	VideoDriver::VideoBufferLocker lock;
 

	
 
@@ -908,6 +924,9 @@ bool MakeScreenshot(ScreenshotType t, co
 

	
 
		case SC_ZOOMEDIN:
 
		case SC_DEFAULTZOOM:
 
			ret = MakeLargeWorldScreenshot(t, width, height);
 
			break;
 

	
 
		case SC_WORLD:
 
			ret = MakeLargeWorldScreenshot(t);
 
			break;
src/screenshot.h
Show inline comments
 
@@ -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 width = 0, uint32 height = 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 width = 0, uint32 height = 0);
 
bool MakeMinimapWorldScreenshot();
 

	
 
extern char _screenshot_format_name[8];
0 comments (0 inline, 0 general)