Implement taking smallmap screenshots.

This is largely based on this patch:
http://www.tt-forums.net/viewtopic.php?p=849533#p849533
with the following changes:
* this uses a button in the smallmap window instead of a console command
* screenshot now uses zoom level and mode of smallmap window
pull/3/head
Jonathan G Rennison 9 years ago
parent 163c30570b
commit 948b4e1d5e

@ -753,6 +753,7 @@ STR_SMALLMAP_INDUSTRY :{TINY_FONT}{STR
STR_SMALLMAP_LINKSTATS :{TINY_FONT}{STRING}
STR_SMALLMAP_COMPANY :{TINY_FONT}{COMPANY}
STR_SMALLMAP_TOWN :{TINY_FONT}{WHITE}{TOWN}
STR_SMALLMAP_SCREENSHOT :{BLACK}Screenshot
STR_SMALLMAP_DISABLE_ALL :{BLACK}Disable all
STR_SMALLMAP_ENABLE_ALL :{BLACK}Enable all
STR_SMALLMAP_SHOW_HEIGHT :{BLACK}Show height

@ -25,6 +25,7 @@
#include "window_func.h"
#include "tile_map.h"
#include "landscape.h"
#include "smallmap_gui.h"
#include "table/strings.h"
@ -810,6 +811,20 @@ bool MakeHeightmapScreenshot(const char *filename)
return sf->proc(filename, HeightmapCallback, NULL, MapSizeX(), MapSizeY(), 8, palette);
}
/**
* Show a a success or failure message indicating the result of a screenshot action
* @param ret whether the screenshot action was successful
*/
static void ShowScreenshotResultMessage(bool ret)
{
if (ret) {
SetDParamStr(0, _screenshot_name);
ShowErrorMessage(STR_MESSAGE_SCREENSHOT_SUCCESSFULLY, INVALID_STRING_ID, WL_WARNING);
} else {
ShowErrorMessage(STR_ERROR_SCREENSHOT_FAILED, INVALID_STRING_ID, WL_ERROR);
}
}
/**
* Make an actual screenshot.
* @param t the type of screenshot to make.
@ -856,12 +871,37 @@ bool MakeScreenshot(ScreenshotType t, const char *name)
NOT_REACHED();
}
if (ret) {
SetDParamStr(0, _screenshot_name);
ShowErrorMessage(STR_MESSAGE_SCREENSHOT_SUCCESSFULLY, INVALID_STRING_ID, WL_WARNING);
} else {
ShowErrorMessage(STR_ERROR_SCREENSHOT_FAILED, INVALID_STRING_ID, WL_ERROR);
}
ShowScreenshotResultMessage(ret);
return ret;
}
/**
* Callback for generating a smallmap screenshot.
* @param userdata SmallMapWindow window pointer
* @param buf Videobuffer with same bitdepth as current blitter
* @param y First line to render
* @param pitch Pitch of the videobuffer
* @param n Number of lines to render
*/
static void SmallMapCallback(void *userdata, void *buf, uint y, uint pitch, uint n)
{
SmallMapWindow *window = static_cast<SmallMapWindow *>(userdata);
window->ScreenshotCallbackHandler(buf, y, pitch, n);
}
/**
* Make a screenshot of the smallmap
* @param width the width of the screenshot
* @param height the height of the screenshot
* @param window a pointer to the smallmap window to use, the current mode and zoom status of the window is used for the screenshot
* @return true iff the screenshot was made successfully
*/
bool MakeSmallMapScreenshot(unsigned int width, unsigned int height, SmallMapWindow *window)
{
_screenshot_name[0] = '\0';
const ScreenshotFormat *sf = _screenshot_formats + _cur_screenshot_format;
bool ret = sf->proc(MakeScreenshotName(SCREENSHOT_NAME, sf->extension), SmallMapCallback, window, width, height, BlitterFactory::GetCurrentBlitter()->GetScreenDepth(), _cur_palette.palette);
ShowScreenshotResultMessage(ret);
return ret;
}

@ -26,8 +26,11 @@ enum ScreenshotType {
SC_HEIGHTMAP, ///< Heightmap of the world.
};
class SmallMapWindow;
void SetupScreenshotViewport(ScreenshotType t, struct ViewPort *vp);
bool MakeHeightmapScreenshot(const char *filename);
bool MakeSmallMapScreenshot(unsigned int width, unsigned int height, SmallMapWindow *window);
bool MakeScreenshot(ScreenshotType t, const char *name);
extern char _screenshot_format_name[8];

@ -23,6 +23,7 @@
#include "sound_func.h"
#include "window_func.h"
#include "company_base.h"
#include "screenshot.h"
#include "smallmap_gui.h"
@ -936,7 +937,7 @@ void SmallMapWindow::DrawMapIndicators() const
*
* @param dpi pointer to pixel to write onto
*/
void SmallMapWindow::DrawSmallMap(DrawPixelInfo *dpi) const
void SmallMapWindow::DrawSmallMap(DrawPixelInfo *dpi, bool draw_indicators) const
{
Blitter *blitter = BlitterFactory::GetCurrentBlitter();
DrawPixelInfo *old_dpi;
@ -992,7 +993,7 @@ void SmallMapWindow::DrawSmallMap(DrawPixelInfo *dpi) const
if (this->show_towns) this->DrawTowns(dpi);
/* Draw map indicators */
this->DrawMapIndicators();
if (draw_indicators) this->DrawMapIndicators();
_cur_dpi = old_dpi;
}
@ -1487,6 +1488,10 @@ int SmallMapWindow::GetPositionOnLegend(Point pt)
this->SetWidgetLoweredState(WID_SM_SHOW_HEIGHT, _smallmap_show_heightmap);
this->SetDirty();
break;
case WID_SM_SCREENSHOT:
TakeScreenshot();
break;
}
}
@ -1650,6 +1655,71 @@ Point SmallMapWindow::GetStationMiddle(const Station *st) const
return ret;
}
/**
* Take a screenshot of the contents of the smallmap window, at the current zoom level and mode
* This calls MakeSmallMapScreenshot which uses ScreenshotCallbackHandler as the screenshot callback
*/
void SmallMapWindow::TakeScreenshot()
{
int32 width = ((MapMaxX() + MapMaxY()) * 2) / this->zoom;
int32 height = (MapMaxX() + MapMaxY() + 1) / this->zoom;
int32 saved_scroll_x = this->scroll_x;
int32 saved_scroll_y = this->scroll_y;
int32 saved_subscroll = this->subscroll;
this->subscroll = 0;
MakeSmallMapScreenshot(width, height, this);
this->scroll_x = saved_scroll_x;
this->scroll_y = saved_scroll_y;
this->subscroll = saved_subscroll;
}
/**
* Callback called by the screenshot code to draw a section of the smallmap to the output buffer
* @param buf Videobuffer with same bitdepth as current blitter
* @param y First line to render
* @param pitch Pitch of the videobuffer
* @param n Number of lines to render
*/
void SmallMapWindow::ScreenshotCallbackHandler(void *buf, uint y, uint pitch, uint n)
{
DrawPixelInfo dpi, *old_dpi;
/* We are no longer rendering to the screen */
DrawPixelInfo old_screen = _screen;
bool old_disable_anim = _screen_disable_anim;
_screen.dst_ptr = buf;
_screen.width = pitch;
_screen.height = n;
_screen.pitch = pitch;
_screen_disable_anim = true;
old_dpi = _cur_dpi;
_cur_dpi = &dpi;
dpi.dst_ptr = buf;
dpi.height = n;
dpi.width = ((MapMaxX() + MapMaxY()) * 2) / this->zoom;
dpi.pitch = pitch;
dpi.zoom = ZOOM_LVL_NORMAL;
dpi.left = 0;
dpi.top = y;
int32 pos = (((int32)MapMaxX() + 1) * TILE_PIXELS) / 4;
this->scroll_x = pos;
this->scroll_y = -pos;
/* make the screenshot */
this->DrawSmallMap(&dpi, false);
_cur_dpi = old_dpi;
/* Switch back to rendering to the screen */
_screen = old_screen;
_screen_disable_anim = old_disable_anim;
}
SmallMapWindow::SmallMapType SmallMapWindow::map_type = SMT_CONTOUR;
bool SmallMapWindow::show_towns = true;
int SmallMapWindow::max_heightlevel = -1;
@ -1798,6 +1868,7 @@ static const NWidgetPart _nested_smallmap_widgets[] = {
NWidgetFunction(SmallMapDisplay), // Smallmap display and legend bar + image buttons.
/* Bottom button row and resize box. */
NWidget(NWID_HORIZONTAL),
NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_SM_SCREENSHOT), SetDataTip(STR_SMALLMAP_SCREENSHOT, STR_NULL),
NWidget(NWID_SELECTION, INVALID_COLOUR, WID_SM_SELECT_BUTTONS),
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_SM_ENABLE_ALL), SetDataTip(STR_SMALLMAP_ENABLE_ALL, STR_NULL),

@ -157,7 +157,7 @@ protected:
void DrawSmallMapColumn(void *dst, uint xc, uint yc, int pitch, int reps, int start_pos, int end_pos, Blitter *blitter) const;
void DrawVehicles(const DrawPixelInfo *dpi, Blitter *blitter) const;
void DrawTowns(const DrawPixelInfo *dpi) const;
void DrawSmallMap(DrawPixelInfo *dpi) const;
void DrawSmallMap(DrawPixelInfo *dpi, bool draw_indicators = true) const;
Point RemapTile(int tile_x, int tile_y) const;
Point PixelToTile(int px, int py, int *sub, bool add_sub = true) const;
@ -189,6 +189,9 @@ public:
virtual void OnTick();
virtual void OnScroll(Point delta);
virtual void OnMouseOver(Point pt, int widget);
void TakeScreenshot();
void ScreenshotCallbackHandler(void *buf, uint y, uint pitch, uint n);
};
#endif /* SMALLMAP_GUI_H */

@ -34,6 +34,7 @@ enum SmallMapWidgets {
WID_SM_ENABLE_ALL, ///< Button to enable display of all legend entries.
WID_SM_DISABLE_ALL, ///< Button to disable display of all legend entries.
WID_SM_SHOW_HEIGHT, ///< Show heightmap toggle button.
WID_SM_SCREENSHOT, ///< Button to take smallmap screenshots
};
#endif /* WIDGETS_SMALLMAP_WIDGET_H */

Loading…
Cancel
Save