|
OpenTTD Source
14.0-beta1
|
Go to the documentation of this file.
33 #include "table/strings.h"
76 #define MKCOLOUR(x) TO_LE32X(x)
83 PACK(
struct BitmapFileHeader {
89 static_assert(
sizeof(BitmapFileHeader) == 14);
94 int32_t width, height;
95 uint16_t planes, bitcount;
96 uint32_t compression, sizeimage, xpels, ypels, clrused, clrimp;
102 byte blue, green, red, reserved;
104 static_assert(
sizeof(
RgbQuad) == 4);
121 switch (pixelformat) {
122 case 8: bpp = 1;
break;
124 case 32: bpp = 3;
break;
126 default:
return false;
129 FILE *f = fopen(name,
"wb");
130 if (f ==
nullptr)
return false;
133 uint bytewidth =
Align(w * bpp, 4);
136 uint pal_size = pixelformat == 8 ?
sizeof(
RgbQuad) * 256 : 0;
139 BitmapFileHeader bfh;
140 bfh.type = TO_LE16(
'MB');
141 bfh.size = TO_LE32(
sizeof(BitmapFileHeader) +
sizeof(
BitmapInfoHeader) + pal_size +
static_cast<size_t>(bytewidth) * h);
143 bfh.off_bits = TO_LE32(
sizeof(BitmapFileHeader) +
sizeof(
BitmapInfoHeader) + pal_size);
148 bih.width = TO_LE32(w);
149 bih.height = TO_LE32(h);
150 bih.planes = TO_LE16(1);
151 bih.bitcount = TO_LE16(bpp * 8);
160 if (fwrite(&bfh,
sizeof(bfh), 1, f) != 1 || fwrite(&bih,
sizeof(bih), 1, f) != 1) {
165 if (pixelformat == 8) {
168 for (uint i = 0; i < 256; i++) {
169 rq[i].red = palette[i].r;
170 rq[i].green = palette[i].g;
171 rq[i].blue = palette[i].b;
175 if (fwrite(rq,
sizeof(rq), 1, f) != 1) {
182 uint maxlines =
Clamp(65536 / (w * pixelformat / 8), 16, 128);
184 uint8_t *buff = MallocT<uint8_t>(maxlines * w * pixelformat / 8);
185 uint8_t *line = CallocT<uint8_t>(bytewidth);
189 uint n = std::min(h, maxlines);
193 callb(userdata, buff, h, w, n);
197 if (pixelformat == 8) {
199 memcpy(line, buff + n * w, w);
205 for (uint i = 0; i < w; i++) {
206 dst[i * 3 ] = src[i].b;
207 dst[i * 3 + 1] = src[i].g;
208 dst[i * 3 + 2] = src[i].r;
212 if (fwrite(line, bytewidth, 1, f) != 1) {
231 #if defined(WITH_PNG)
234 #ifdef PNG_TEXT_SUPPORTED
242 static void PNGAPI png_my_error(png_structp png_ptr, png_const_charp message)
244 Debug(misc, 0,
"[libpng] error: {} - {}", message, (
const char *)png_get_error_ptr(png_ptr));
245 longjmp(png_jmpbuf(png_ptr), 1);
248 static void PNGAPI png_my_warning(png_structp png_ptr, png_const_charp message)
250 Debug(misc, 1,
"[libpng] warning: {} - {}", message, (
const char *)png_get_error_ptr(png_ptr));
271 uint bpp = pixelformat / 8;
276 if (pixelformat != 8 && pixelformat != 32)
return false;
278 f = fopen(name,
"wb");
279 if (f ==
nullptr)
return false;
281 png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
const_cast<char *
>(name), png_my_error, png_my_warning);
283 if (png_ptr ==
nullptr) {
288 info_ptr = png_create_info_struct(png_ptr);
289 if (info_ptr ==
nullptr) {
290 png_destroy_write_struct(&png_ptr, (png_infopp)
nullptr);
295 if (setjmp(png_jmpbuf(png_ptr))) {
296 png_destroy_write_struct(&png_ptr, &info_ptr);
301 png_init_io(png_ptr, f);
303 png_set_filter(png_ptr, 0, PNG_FILTER_NONE);
305 png_set_IHDR(png_ptr, info_ptr, w, h, 8, pixelformat == 8 ? PNG_COLOR_TYPE_PALETTE : PNG_COLOR_TYPE_RGB,
306 PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
308 #ifdef PNG_TEXT_SUPPORTED
311 png_text_struct text[2];
312 memset(text, 0,
sizeof(text));
313 text[0].key =
const_cast<char *
>(
"Software");
314 text[0].text =
const_cast<char *
>(_openttd_revision);
315 text[0].text_length = strlen(_openttd_revision);
316 text[0].compression = PNG_TEXT_COMPRESSION_NONE;
319 message.reserve(1024);
321 message +=
"NewGRFs:\n";
323 fmt::format_to(std::back_inserter(message),
"{:08X} {} {}\n",
BSWAP32(c->ident.grfid),
FormatArrayAsHex(c->ident.md5sum), c->filename);
325 message +=
"\nCompanies:\n";
327 if (c->ai_info ==
nullptr) {
328 fmt::format_to(std::back_inserter(message),
"{:2d}: Human\n", (
int)c->index);
330 fmt::format_to(std::back_inserter(message),
"{:2d}: {} (v{})\n", (
int)c->index, c->ai_info->GetName(), c->ai_info->GetVersion());
333 text[1].key =
const_cast<char *
>(
"Description");
334 text[1].text =
const_cast<char *
>(message.c_str());
335 text[1].text_length = message.size();
336 text[1].compression = PNG_TEXT_COMPRESSION_zTXt;
337 png_set_text(png_ptr, info_ptr, text, 2);
340 if (pixelformat == 8) {
342 for (i = 0; i != 256; i++) {
343 rq[i].red = palette[i].r;
344 rq[i].green = palette[i].g;
345 rq[i].blue = palette[i].b;
348 png_set_PLTE(png_ptr, info_ptr, rq, 256);
351 png_write_info(png_ptr, info_ptr);
352 png_set_flush(png_ptr, 512);
354 if (pixelformat == 32) {
363 png_set_sBIT(png_ptr, info_ptr, &sig_bit);
365 #if TTD_ENDIAN == TTD_LITTLE_ENDIAN
366 png_set_bgr(png_ptr);
367 png_set_filler(png_ptr, 0, PNG_FILLER_AFTER);
369 png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE);
374 maxlines =
Clamp(65536 / w, 16, 128);
377 void *buff = CallocT<uint8_t>(
static_cast<size_t>(w) * maxlines * bpp);
382 n = std::min(h - y, maxlines);
385 callb(userdata, buff, y, w, n);
389 for (i = 0; i != n; i++) {
390 png_write_row(png_ptr, (png_bytep)buff + i * w * bpp);
394 png_write_end(png_ptr, info_ptr);
395 png_destroy_write_struct(&png_ptr, &info_ptr);
417 byte pal_small[16 * 3];
448 if (pixelformat == 32) {
449 Debug(misc, 0,
"Can't convert a 32bpp screenshot to PCX format. Please pick another format.");
452 if (pixelformat != 8 || w == 0)
return false;
454 f = fopen(name,
"wb");
455 if (f ==
nullptr)
return false;
457 memset(&pcx, 0,
sizeof(pcx));
460 pcx.manufacturer = 10;
464 pcx.xmax = TO_LE16(w - 1);
465 pcx.ymax = TO_LE16(h - 1);
466 pcx.hdpi = TO_LE16(320);
467 pcx.vdpi = TO_LE16(320);
470 pcx.cpal = TO_LE16(1);
471 pcx.width = pcx.pitch = TO_LE16(w);
472 pcx.height = TO_LE16(h);
475 if (fwrite(&pcx,
sizeof(pcx), 1, f) != 1) {
481 maxlines =
Clamp(65536 / w, 16, 128);
484 uint8_t *buff = CallocT<uint8_t>(
static_cast<size_t>(w) * maxlines);
489 uint n = std::min(h - y, maxlines);
493 callb(userdata, buff, y, w, n);
497 for (i = 0; i != n; i++) {
498 const uint8_t *bufp = buff + i * w;
499 byte runchar = bufp[0];
504 for (j = 1; j < w; j++) {
505 uint8_t ch = bufp[j];
507 if (ch != runchar || runcount >= 0x3f) {
508 if (runcount > 1 || (runchar & 0xC0) == 0xC0) {
509 if (fputc(0xC0 | runcount, f) == EOF) {
515 if (fputc(runchar, f) == EOF) {
527 if (runcount > 1 || (runchar & 0xC0) == 0xC0) {
528 if (fputc(0xC0 | runcount, f) == EOF) {
534 if (fputc(runchar, f) == EOF) {
545 if (fputc(12, f) == EOF) {
553 for (uint i = 0; i < 256; i++) {
554 tmp[i * 3 + 0] = palette[i].r;
555 tmp[i * 3 + 1] = palette[i].g;
556 tmp[i * 3 + 2] = palette[i].b;
558 success = fwrite(tmp,
sizeof(tmp), 1, f) == 1;
571 #if defined(WITH_PNG)
605 void *src = blitter->
MoveTo(_screen.dst_ptr, 0, y);
627 _screen.dst_ptr = buf;
628 _screen.width = pitch;
630 _screen.pitch = pitch;
637 dpi.width = vp->
width;
645 while (vp->
width - left != 0) {
646 wx = std::min(vp->
width - left, 1600);
658 _screen = old_screen;
669 static const char *
MakeScreenshotName(
const char *default_fn,
const char *ext,
bool crashlog =
false)
693 for (uint serial = 1;; serial++) {
696 if (!generate)
break;
726 assert(width == 0 && height == 0);
737 vp->
width = _screen.width;
738 vp->
height = _screen.height;
743 assert(width == 0 && height == 0);
766 vp->overlay =
nullptr;
776 if (width == 0 || height == 0) {
789 vp->overlay =
nullptr;
821 byte *buf = (
byte *)buffer;
842 for (uint i = 0; i <
lengthof(palette); i++) {
885 if (width * height > 8192 * 8192) {
996 static void MinimapScreenCallback(
void *,
void *buf, uint y, uint pitch, uint n)
998 uint32_t *ubuf = (uint32_t *)buf;
999 uint num = (pitch * n);
1000 for (uint i = 0; i < num; i++) {
1001 uint row = y + (int)(i / pitch);
1007 uint32_t colour_buf = 0;
Palette _cur_palette
Current palette.
static debug_inline uint TileY(TileIndex tile)
Get the Y component of a tile.
Format of palette data in BMP header.
std::string FormatArrayAsHex(std::span< const byte > data)
Format a byte array into a continuous hex string.
void ShowQuery(StringID caption, StringID message, Window *parent, QueryCallbackProc *callback, bool focus)
Show a confirmation window with standard 'yes' and 'no' buttons The window is aligned to the centre o...
ScreenshotType
Type of requested screenshot.
std::string _personal_dir
custom directory for personal settings, saves, newgrf, etc.
void ShowErrorMessage(StringID summary_msg, int x, int y, CommandCost cc)
Display an error message in a window.
@ WL_WARNING
Other information.
static debug_inline uint MaxX()
Gets the maximum X coordinate within the map, including MP_VOID.
std::mutex lock
synchronization for playback status fields
How all blitters should look like.
int width
Screen width of the viewport.
@ SC_HEIGHTMAP
Heightmap of the world.
static void HeightmapCallback(void *, void *buffer, uint y, uint, uint n)
Callback for generating a heightmap.
ViewportData * viewport
Pointer to viewport data, if present.
int height
Screen height of the viewport.
virtual uint8_t GetScreenDepth()=0
Get the screen depth this blitter works for.
int top
Screen coordinate top edge of the viewport.
std::string _screenshot_format_name
Extension of the current screenshot format (corresponds with _cur_screenshot_format).
static const uint TILE_SIZE
Tile size in world coordinates.
ClientSettings _settings_client
The current settings for this game.
static void ScreenshotConfirmationCallback(Window *, bool confirmed)
Callback on the confirmation window for huge screenshots.
@ SC_ZOOMEDIN
Fully zoomed in screenshot of the visible area.
int virtual_top
Virtual top coordinate.
bool MakeHeightmapScreenshot(const char *filename)
Make a heightmap of the current map.
void InitializeScreenshotFormats()
Initialize screenshot format information on startup, with _screenshot_format_name filled from the loa...
#define Debug(category, level, format_string,...)
Ouptut a line of debugging information.
static debug_inline TileType GetTileType(Tile tile)
Get the tiletype of a given tile.
static ScreenshotType _confirmed_screenshot_type
Screenshot type the current query is about to confirm.
Data structure for viewport, display of a part of the world.
static uint32_t BSWAP32(uint32_t x)
Perform a 32 bits endianness bitswap on x.
Information about GRF, used in the game and (part of it) in savegames.
int virtual_left
Virtual left coordinate.
void free(const void *ptr)
Version of the standard free that accepts const pointers.
bool _screen_disable_anim
Disable palette animation (important for 32bpp-anim blitter during giant screenshot)
int left
Screen coordinate left edge of the viewport.
Colour palette[256]
Current palette. Entry 0 has to be always fully transparent!
bool FileExists(const std::string &filename)
Test whether the given filename exists.
GameSettings _settings_game
Game settings of a running game or the scenario editor.
static Blitter * GetCurrentBlitter()
Get the current active blitter (always set by calling SelectBlitter).
CompanyID _local_company
Company controlled by the human player at this client. Can also be COMPANY_SPECTATOR.
std::string GenerateDefaultSaveName()
Get the default name for a savegame or screenshot.
bool ScreenshotHandlerProc(const char *name, ScreenshotCallback *callb, void *userdata, uint w, uint h, int pixelformat, const Colour *palette)
Function signature for a screenshot generation routine for one of the available formats.
bool freeform_edges
allow terraforming the tiles at the map edges
PACK(struct BitmapFileHeader { uint16_t type;uint32_t size;uint32_t reserved;uint32_t off_bits;})
BMP File Header (stored in little endian)
void DrawDirtyBlocks()
Repaints the rectangle blocks which are marked as 'dirty'.
void ScreenshotCallback(void *userdata, void *buf, uint y, uint pitch, uint n)
Callback function signature for generating lines of pixel data to be written to the screenshot file.
uint _num_screenshot_formats
Number of available screenshot formats.
static const char * MakeScreenshotName(const char *default_fn, const char *ext, bool crashlog=false)
Construct a pathname for a screenshot file.
int virtual_width
width << zoom
@ ZOOM_LVL_WORLD_SCREENSHOT
Default zoom level for the world screen shot.
void QueueOnMainThread(std::function< void()> &&func)
Queue a function to be called on the main thread with game state lock held and video buffer locked.
@ ZOOM_LVL_VIEWPORT
Default zoom level for viewports.
static VideoDriver * GetInstance()
Get the currently active instance of the video driver.
virtual void CopyImageToBuffer(const void *video, void *dst, int width, int height, int dst_pitch)=0
Copy from the screen to a buffer in a palette format for 8bpp and RGBA format for 32bpp.
Structure to access the alpha, red, green, and blue channels from a 32 bit number.
ZoomLevel zoom_min
minimum zoom out level
static debug_inline uint SizeX()
Get the size of the map along the X.
static void LargeWorldCallback(void *userdata, void *buf, uint y, uint pitch, uint n)
generate a large piece of the world
static const ScreenshotFormat _screenshot_formats[]
Available screenshot formats.
uint TilePixelHeight(Tile tile)
Returns the height of a tile in pixels.
void SetScreenshotWindowVisibility(bool hide)
Set the visibility of the screenshot window when taking a screenshot.
static Pool::IterateWrapper< Titem > Iterate(size_t from=0)
Returns an iterable ensemble of all valid Titem.
static bool MakeBMPImage(const char *name, ScreenshotCallback *callb, void *userdata, uint w, uint h, int pixelformat, const Colour *palette)
Generic .BMP writer.
int UnScaleByZoom(int value, ZoomLevel zoom)
Scale by zoom level, usually shift right (when zoom > ZOOM_LVL_NORMAL) When shifting right,...
@ SC_WORLD
World screenshot.
static bool MakePCXImage(const char *name, ScreenshotCallback *callb, void *userdata, uint w, uint h, int pixelformat, const Colour *palette)
Generic .PCX file image writer.
static const char *const HEIGHTMAP_NAME
Default filename of a saved heightmap.
void SetupScreenshotViewport(ScreenshotType t, Viewport *vp, uint32_t width, uint32_t height)
Configure a Viewport for rendering (a part of) the map into a screenshot.
virtual void * MoveTo(void *video, int x, int y)=0
Move the destination pointer the requested amount x and y, keeping in mind any pitch and bpp of the r...
static debug_inline uint Size()
Get the size of the map.
void SetDParam(size_t n, uint64_t v)
Set a string parameter v at index n in the global string parameter array.
@ COMPANY_SPECTATOR
The client is spectating.
Window * GetMainWindow()
Get the main window, i.e.
struct GRFConfig * next
NOSAVE: Next item in the linked list.
Class to backup a specific variable and restore it upon destruction of this object to prevent stack v...
static bool RealMakeScreenshot(ScreenshotType t, std::string name, uint32_t width, uint32_t height)
Make a screenshot.
static bool MakePNGImage(const char *name, ScreenshotCallback *callb, void *userdata, uint w, uint h, int pixelformat, const Colour *palette)
Generic .PNG file image writer.
void SetDParamStr(size_t n, const char *str)
This function is used to "bind" a C string to a OpenTTD dparam slot.
@ SC_DEFAULTZOOM
Zoomed to default zoom level screenshot of the visible area.
static bool MakeSmallScreenshot(bool crashlog)
Make a screenshot of the current screen.
@ WL_ERROR
Errors (eg. saving/loading failed)
bool MakeMinimapWorldScreenshot()
Make a minimap screenshot.
#define TILE_ADDXY(tile, x, y)
Adds a given offset to a tile.
GRFConfig * _grfconfig
First item in list of current GRF set up.
uint _cur_screenshot_format
Index of the currently selected screenshot format in _screenshot_formats.
const char * GetCurrentScreenshotExtension()
Get filename extension of current screenshot file format.
#define lengthof(x)
Return the length of an fixed size array.
ZoomLevel zoom
The zoom level of the viewport.
static debug_inline TileIndex TileXY(uint x, uint y)
Returns the TileIndex of a coordinate.
static debug_inline uint TileHeight(Tile tile)
Returns the height of a tile.
@ SC_VIEWPORT
Screenshot of viewport.
void MakeScreenshotWithConfirm(ScreenshotType t)
Make a screenshot.
static std::string _screenshot_name
Filename of the screenshot file.
ConstructionSettings construction
construction of things in-game
Data structure for an opened window.
@ SC_CRASHLOG
Raw screenshot from blitter buffer.
constexpr T Clamp(const T a, const T min, const T max)
Clamp a value between an interval.
static debug_inline uint TileX(TileIndex tile)
Get the X component of a tile.
@ Never
Never include the heightmap.
int virtual_height
height << zoom
bool MakeScreenshot(ScreenshotType t, std::string name, uint32_t width, uint32_t height)
Schedule making a screenshot.
@ SC_MINIMAP
Minimap screenshot.
static const char *const SCREENSHOT_NAME
Default filename of a saved screenshot.
int ScaleByZoom(int value, ZoomLevel zoom)
Scale by zoom level, usually shift left (when zoom > ZOOM_LVL_NORMAL) When shifting right,...
static bool MakeLargeWorldScreenshot(ScreenshotType t, uint32_t width=0, uint32_t height=0)
Make a screenshot of the map.
uint _heightmap_highest_peak
When saving a heightmap, this contains the highest peak on the map.
Helper struct to ensure the video buffer is locked and ready for drawing.
uint32_t GetSmallMapOwnerPixels(TileIndex tile, TileType t, IncludeHeightmap include_heightmap)
Return the colour a tile would be displayed with in the small map in mode "Owner".
constexpr T Align(const T x, uint n)
Return the smallest multiple of n equal or greater than x.
uint8_t a
colour channels in LE order
static const StringID INVALID_STRING_ID
Constant representing an invalid string (16bit in case it is used in savegames)
static uint SizeY()
Get the size of the map along the Y.
GUISettings gui
settings related to the GUI
Point RemapCoords(int x, int y, int z)
Map 3D world or tile coordinate to equivalent 2D coordinate as used in the viewports and smallmap.
static void CurrentScreenCallback(void *, void *buf, uint y, uint pitch, uint n)
Callback of the screenshot generator that dumps the current video buffer.
std::string _full_screenshot_path
Pathname of the screenshot file.
Data about how and where to blit pixels.
const char * FiosGetScreenshotDir()
Get the directory for screenshots.