diff options
author | Patric Stout <truebrain@openttd.org> | 2021-01-22 16:16:33 +0100 |
---|---|---|
committer | Patric Stout <github@truebrain.nl> | 2021-03-04 22:23:05 +0100 |
commit | ac5e77ea3b3e8e769d2198b0e8f4b6e56bb8fc91 (patch) | |
tree | e4fa407b4acdb700ddb380fd19ca9d6fd0d1e0f6 | |
parent | 879eb9c34803ac468afb582ffb348493f0a32e39 (diff) | |
download | openttd-ac5e77ea3b3e8e769d2198b0e8f4b6e56bb8fc91.tar.xz |
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.
-rw-r--r-- | src/console_cmds.cpp | 86 | ||||
-rw-r--r-- | src/screenshot.cpp | 33 | ||||
-rw-r--r-- | src/screenshot.h | 4 |
3 files changed, 86 insertions, 37 deletions
diff --git a/src/console_cmds.cpp b/src/console_cmds.cpp index 905a41c3e..3f454b1aa 100644 --- a/src/console_cmds.cpp +++ b/src/console_cmds.cpp @@ -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; - - if (argc > 1) { - if (strcmp(argv[1], "big") == 0) { - /* screenshot big [filename] */ + uint32 arg_index = 1; + + 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; + } + } + + 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); + MakeScreenshot(type, name, width, height); return true; } diff --git a/src/screenshot.cpp b/src/screenshot.cpp index 8c64115a4..a1ad6bfad 100644 --- a/src/screenshot.cpp +++ b/src/screenshot.cpp @@ -710,13 +710,17 @@ static bool MakeSmallScreenshot(bool crashlog) /** * 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(ScreenshotType t, Viewport *vp) /* 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(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; + + 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(ScreenshotType t, Viewport *vp) /** * 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(ScreenshotType t) * 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, const char *name) case SC_ZOOMEDIN: case SC_DEFAULTZOOM: + ret = MakeLargeWorldScreenshot(t, width, height); + break; + case SC_WORLD: ret = MakeLargeWorldScreenshot(t); break; diff --git a/src/screenshot.h b/src/screenshot.h index 400f8164e..148c018e1 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 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]; |