Changeset - r26711:a4f8e9c41dea
[Not reviewed]
master
0 26 0
Patric Stout - 18 months ago 2023-01-02 20:30:02
truebrain@openttd.org
Codechange: address CodeQL issue "Multiplication result converted to larger type" (#10306)

Most are very unlikely to ever be triggered in our codebase; two
stand out: linkgraph and money cheat. Those, potentially, could
wrap earlier than expected.
26 files changed with 74 insertions and 66 deletions:
0 comments (0 inline, 0 general)
src/blitter/32bpp_anim.cpp
Show inline comments
 
@@ -469,27 +469,27 @@ void Blitter_32bppAnim::ScrollBuffer(voi
 
		uint tw = width + (scroll_x >= 0 ? -scroll_x : scroll_x);
 
		uint th = height + scroll_y;
 
		for (; th > 0; th--) {
 
			memmove(dst, src, tw * sizeof(uint16));
 
			src += this->anim_buf_pitch;
 
			dst += this->anim_buf_pitch;
 
		}
 
	}
 

	
 
	Blitter_32bppBase::ScrollBuffer(video, left, top, width, height, scroll_x, scroll_y);
 
}
 

	
 
int Blitter_32bppAnim::BufferSize(int width, int height)
 
size_t Blitter_32bppAnim::BufferSize(uint width, uint height)
 
{
 
	return width * height * (sizeof(uint32) + sizeof(uint16));
 
	return (sizeof(uint32) + sizeof(uint16)) * width * height;
 
}
 

	
 
void Blitter_32bppAnim::PaletteAnimate(const Palette &palette)
 
{
 
	assert(!_screen_disable_anim);
 

	
 
	this->palette = palette;
 
	/* If first_dirty is 0, it is for 8bpp indication to send the new
 
	 *  palette. However, only the animation colours might possibly change.
 
	 *  Especially when going between toyland and non-toyland. */
 
	assert(this->palette.first_dirty == PALETTE_ANIM_START || this->palette.first_dirty == 0);
 

	
src/blitter/32bpp_anim.hpp
Show inline comments
 
@@ -34,25 +34,25 @@ public:
 
	}
 

	
 
	~Blitter_32bppAnim();
 

	
 
	void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom) override;
 
	void DrawColourMappingRect(void *dst, int width, int height, PaletteID pal) override;
 
	void SetPixel(void *video, int x, int y, uint8 colour) override;
 
	void DrawLine(void *video, int x, int y, int x2, int y2, int screen_width, int screen_height, uint8 colour, int width, int dash) override;
 
	void DrawRect(void *video, int width, int height, uint8 colour) override;
 
	void CopyFromBuffer(void *video, const void *src, int width, int height) override;
 
	void CopyToBuffer(const void *video, void *dst, int width, int height) override;
 
	void ScrollBuffer(void *video, int &left, int &top, int &width, int &height, int scroll_x, int scroll_y) override;
 
	int BufferSize(int width, int height) override;
 
	size_t BufferSize(uint width, uint height) override;
 
	void PaletteAnimate(const Palette &palette) override;
 
	Blitter::PaletteAnimation UsePaletteAnimation() override;
 

	
 
	const char *GetName() override { return "32bpp-anim"; }
 
	int GetBytesPerPixel() override { return 6; }
 
	void PostResize() override;
 

	
 
	/**
 
	 * Look up the colour in the current palette.
 
	 */
 
	inline Colour LookupColourInPalette(uint index)
 
	{
src/blitter/32bpp_base.cpp
Show inline comments
 
@@ -131,27 +131,27 @@ void Blitter_32bppBase::ScrollBuffer(voi
 
		}
 

	
 
		/* the y-displacement may be 0 therefore we have to use memmove,
 
		 * because source and destination may overlap */
 
		for (int h = height; h > 0; h--) {
 
			memmove(dst, src, width * sizeof(uint32));
 
			src += _screen.pitch;
 
			dst += _screen.pitch;
 
		}
 
	}
 
}
 

	
 
int Blitter_32bppBase::BufferSize(int width, int height)
 
size_t Blitter_32bppBase::BufferSize(uint width, uint height)
 
{
 
	return width * height * sizeof(uint32);
 
	return sizeof(uint32) * width * height;
 
}
 

	
 
void Blitter_32bppBase::PaletteAnimate(const Palette &palette)
 
{
 
	/* By default, 32bpp doesn't have palette animation */
 
}
 

	
 
Colour Blitter_32bppBase::ReallyAdjustBrightness(Colour colour, uint8 brightness)
 
{
 
	assert(DEFAULT_BRIGHTNESS == 1 << 7);
 

	
 
	uint64 combined = (((uint64) colour.r) << 32) | (((uint64) colour.g) << 16) | ((uint64) colour.b);
src/blitter/32bpp_base.hpp
Show inline comments
 
@@ -18,25 +18,25 @@
 
/** Base for all 32bpp blitters. */
 
class Blitter_32bppBase : public Blitter {
 
public:
 
	uint8 GetScreenDepth() override { return 32; }
 
	void *MoveTo(void *video, int x, int y) override;
 
	void SetPixel(void *video, int x, int y, uint8 colour) override;
 
	void DrawLine(void *video, int x, int y, int x2, int y2, int screen_width, int screen_height, uint8 colour, int width, int dash) override;
 
	void DrawRect(void *video, int width, int height, uint8 colour) override;
 
	void CopyFromBuffer(void *video, const void *src, int width, int height) override;
 
	void CopyToBuffer(const void *video, void *dst, int width, int height) override;
 
	void CopyImageToBuffer(const void *video, void *dst, int width, int height, int dst_pitch) override;
 
	void ScrollBuffer(void *video, int &left, int &top, int &width, int &height, int scroll_x, int scroll_y) override;
 
	int BufferSize(int width, int height) override;
 
	size_t BufferSize(uint width, uint height) override;
 
	void PaletteAnimate(const Palette &palette) override;
 
	Blitter::PaletteAnimation UsePaletteAnimation() override;
 
	int GetBytesPerPixel() override { return 4; }
 

	
 
	/**
 
	 * Look up the colour in the current palette.
 
	 */
 
	static inline Colour LookupColourInPalette(uint index)
 
	{
 
		return _cur_palette.palette[index];
 
	}
 

	
src/blitter/40bpp_anim.cpp
Show inline comments
 
@@ -22,27 +22,28 @@
 
/** Instantiation of the 40bpp with animation blitter factory. */
 
static FBlitter_40bppAnim iFBlitter_40bppAnim;
 

	
 
/** Cached black value. */
 
static const Colour _black_colour(0, 0, 0);
 

	
 

	
 
void Blitter_40bppAnim::SetPixel(void *video, int x, int y, uint8 colour)
 
{
 
	if (_screen_disable_anim) {
 
		Blitter_32bppOptimized::SetPixel(video, x, y, colour);
 
	} else {
 
		*((Colour *)video + x + y * _screen.pitch) = _black_colour;
 
		size_t y_offset = static_cast<size_t>(y) * _screen.pitch;
 
		*((Colour *)video + x + y_offset) = _black_colour;
 

	
 
		VideoDriver::GetInstance()->GetAnimBuffer()[((uint32 *)video - (uint32 *)_screen.dst_ptr) + x + y * _screen.pitch] = colour;
 
		VideoDriver::GetInstance()->GetAnimBuffer()[((uint32 *)video - (uint32 *)_screen.dst_ptr) + x + y_offset] = colour;
 
	}
 
}
 

	
 
void Blitter_40bppAnim::DrawRect(void *video, int width, int height, uint8 colour)
 
{
 
	if (_screen_disable_anim) {
 
		/* This means our output is not to the screen, so we can't be doing any animation stuff, so use our parent DrawRect() */
 
		Blitter_32bppOptimized::DrawRect(video, width, height, colour);
 
		return;
 
	}
 

	
 
	assert(VideoDriver::GetInstance()->GetAnimBuffer() != nullptr);
 
@@ -491,26 +492,26 @@ void Blitter_40bppAnim::ScrollBuffer(voi
 
		uint tw = width + (scroll_x >= 0 ? -scroll_x : scroll_x);
 
		uint th = height + scroll_y;
 
		for (; th > 0; th--) {
 
			memmove(dst, src, tw * sizeof(uint8));
 
			src += _screen.pitch;
 
			dst += _screen.pitch;
 
		}
 
	}
 

	
 
	Blitter_32bppBase::ScrollBuffer(video, left, top, width, height, scroll_x, scroll_y);
 
}
 

	
 
int Blitter_40bppAnim::BufferSize(int width, int height)
 
size_t Blitter_40bppAnim::BufferSize(uint width, uint height)
 
{
 
	return width * height * (sizeof(uint32) + sizeof(uint8));
 
	return (sizeof(uint32) + sizeof(uint8)) * width * height;
 
}
 

	
 
Blitter::PaletteAnimation Blitter_40bppAnim::UsePaletteAnimation()
 
{
 
	return Blitter::PALETTE_ANIMATION_VIDEO_BACKEND;
 
}
 

	
 
bool Blitter_40bppAnim::NeedsAnimationBuffer()
 
{
 
	return true;
 
}
src/blitter/40bpp_anim.hpp
Show inline comments
 
@@ -20,25 +20,25 @@ public:
 

	
 
	// void *MoveTo(void *video, int x, int y) override;
 
	void SetPixel(void *video, int x, int y, uint8 colour) override;
 
	void DrawRect(void *video, int width, int height, uint8 colour) override;
 
	void DrawLine(void *video, int x, int y, int x2, int y2, int screen_width, int screen_height, uint8 colour, int width, int dash) override;
 
	void CopyFromBuffer(void *video, const void *src, int width, int height) override;
 
	void CopyToBuffer(const void *video, void *dst, int width, int height) override;
 
	void CopyImageToBuffer(const void *video, void *dst, int width, int height, int dst_pitch) override;
 
	void ScrollBuffer(void *video, int &left, int &top, int &width, int &height, int scroll_x, int scroll_y) override;
 
	void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom) override;
 
	void DrawColourMappingRect(void *dst, int width, int height, PaletteID pal) override;
 
	Sprite *Encode(const SpriteLoader::Sprite *sprite, AllocatorProc *allocator) override;
 
	int BufferSize(int width, int height) override;
 
	size_t BufferSize(uint width, uint height) override;
 
	Blitter::PaletteAnimation UsePaletteAnimation() override;
 
	bool NeedsAnimationBuffer() override;
 

	
 
	const char *GetName()  override { return "40bpp-anim"; }
 
	int GetBytesPerPixel()  override { return 5; }
 

	
 
	template <BlitterMode mode> void Draw(const Blitter::BlitterParams *bp, ZoomLevel zoom);
 

	
 
protected:
 
	static inline Colour RealizeBlendedColour(uint8 anim, Colour c)
 
	{
 
		return anim != 0 ? AdjustBrightness(LookupColourInPalette(anim), GetColourBrightness(c)) : c;
src/blitter/8bpp_base.cpp
Show inline comments
 
@@ -135,26 +135,26 @@ void Blitter_8bppBase::ScrollBuffer(void
 
		}
 

	
 
		/* the y-displacement may be 0 therefore we have to use memmove,
 
		 * because source and destination may overlap */
 
		for (int h = height; h > 0; h--) {
 
			memmove(dst, src, width * sizeof(uint8));
 
			src += _screen.pitch;
 
			dst += _screen.pitch;
 
		}
 
	}
 
}
 

	
 
int Blitter_8bppBase::BufferSize(int width, int height)
 
size_t Blitter_8bppBase::BufferSize(uint width, uint height)
 
{
 
	return width * height;
 
	return static_cast<size_t>(width) * height;
 
}
 

	
 
void Blitter_8bppBase::PaletteAnimate(const Palette &palette)
 
{
 
	/* Video backend takes care of the palette animation */
 
}
 

	
 
Blitter::PaletteAnimation Blitter_8bppBase::UsePaletteAnimation()
 
{
 
	return Blitter::PALETTE_ANIMATION_VIDEO_BACKEND;
 
}
src/blitter/8bpp_base.hpp
Show inline comments
 
@@ -16,19 +16,19 @@
 
class Blitter_8bppBase : public Blitter {
 
public:
 
	uint8 GetScreenDepth() override { return 8; }
 
	void DrawColourMappingRect(void *dst, int width, int height, PaletteID pal) override;
 
	void *MoveTo(void *video, int x, int y) override;
 
	void SetPixel(void *video, int x, int y, uint8 colour) override;
 
	void DrawLine(void *video, int x, int y, int x2, int y2, int screen_width, int screen_height, uint8 colour, int width, int dash) override;
 
	void DrawRect(void *video, int width, int height, uint8 colour) override;
 
	void CopyFromBuffer(void *video, const void *src, int width, int height) override;
 
	void CopyToBuffer(const void *video, void *dst, int width, int height) override;
 
	void CopyImageToBuffer(const void *video, void *dst, int width, int height, int dst_pitch) override;
 
	void ScrollBuffer(void *video, int &left, int &top, int &width, int &height, int scroll_x, int scroll_y) override;
 
	int BufferSize(int width, int height) override;
 
	size_t BufferSize(uint width, uint height) override;
 
	void PaletteAnimate(const Palette &palette) override;
 
	Blitter::PaletteAnimation UsePaletteAnimation() override;
 
	int GetBytesPerPixel() override { return 1; }
 
};
 

	
 
#endif /* BLITTER_8BPP_BASE_HPP */
src/blitter/base.hpp
Show inline comments
 
@@ -161,25 +161,25 @@ public:
 
	 * @param height The height of the screen to scroll.
 
	 * @param scroll_x How much to scroll in X.
 
	 * @param scroll_y How much to scroll in Y.
 
	 */
 
	virtual void ScrollBuffer(void *video, int &left, int &top, int &width, int &height, int scroll_x, int scroll_y) = 0;
 

	
 
	/**
 
	 * Calculate how much memory there is needed for an image of this size in the video-buffer.
 
	 * @param width The width of the buffer-to-be.
 
	 * @param height The height of the buffer-to-be.
 
	 * @return The size needed for the buffer.
 
	 */
 
	virtual int BufferSize(int width, int height) = 0;
 
	virtual size_t BufferSize(uint width, uint height) = 0;
 

	
 
	/**
 
	 * Called when the 8bpp palette is changed; you should redraw all pixels on the screen that
 
	 *  are equal to the 8bpp palette indexes 'first_dirty' to 'first_dirty + count_dirty'.
 
	 * @param palette The new palette.
 
	 */
 
	virtual void PaletteAnimate(const Palette &palette) = 0;
 

	
 
	/**
 
	 * Check if the blitter uses palette animation at all.
 
	 * @return True if it uses palette animation.
 
	 */
src/blitter/null.hpp
Show inline comments
 
@@ -18,25 +18,25 @@ public:
 
	uint8 GetScreenDepth() override { return 0; }
 
	void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom) override {};
 
	void DrawColourMappingRect(void *dst, int width, int height, PaletteID pal) override {};
 
	Sprite *Encode(const SpriteLoader::Sprite *sprite, AllocatorProc *allocator) override;
 
	void *MoveTo(void *video, int x, int y) override { return nullptr; };
 
	void SetPixel(void *video, int x, int y, uint8 colour) override {};
 
	void DrawRect(void *video, int width, int height, uint8 colour) override {};
 
	void DrawLine(void *video, int x, int y, int x2, int y2, int screen_width, int screen_height, uint8 colour, int width, int dash) override {};
 
	void CopyFromBuffer(void *video, const void *src, int width, int height) override {};
 
	void CopyToBuffer(const void *video, void *dst, int width, int height) override {};
 
	void CopyImageToBuffer(const void *video, void *dst, int width, int height, int dst_pitch) override {};
 
	void ScrollBuffer(void *video, int &left, int &top, int &width, int &height, int scroll_x, int scroll_y) override {};
 
	int BufferSize(int width, int height) override { return 0; };
 
	size_t BufferSize(uint width, uint height) override { return 0; };
 
	void PaletteAnimate(const Palette &palette) override { };
 
	Blitter::PaletteAnimation UsePaletteAnimation() override { return Blitter::PALETTE_ANIMATION_NONE; };
 

	
 
	const char *GetName() override { return "null"; }
 
	int GetBytesPerPixel() override { return 0; }
 
};
 

	
 
/** Factory for the blitter that does nothing. */
 
class FBlitter_Null : public BlitterFactory {
 
public:
 
	FBlitter_Null() : BlitterFactory("null", "Null Blitter (does nothing)") {}
 
	Blitter *CreateInstance() override { return new Blitter_Null(); }
src/bmp.cpp
Show inline comments
 
@@ -381,25 +381,25 @@ bool BmpReadHeader(BmpBuffer *buffer, Bm
 

	
 
	return buffer->real_pos <= info->offset;
 
}
 

	
 
/*
 
 * Reads the bitmap
 
 * 1 bpp and 4 bpp bitmaps are converted to 8 bpp bitmaps
 
 */
 
bool BmpReadBitmap(BmpBuffer *buffer, BmpInfo *info, BmpData *data)
 
{
 
	assert(info != nullptr && data != nullptr);
 

	
 
	data->bitmap = CallocT<byte>(info->width * info->height * ((info->bpp == 24) ? 3 : 1));
 
	data->bitmap = CallocT<byte>(static_cast<size_t>(info->width) * info->height * ((info->bpp == 24) ? 3 : 1));
 

	
 
	/* Load image */
 
	SetStreamOffset(buffer, info->offset);
 
	switch (info->compression) {
 
	case 0: // no compression
 
		switch (info->bpp) {
 
		case 1:  return BmpRead1(buffer, info, data);
 
		case 4:  return BmpRead4(buffer, info, data);
 
		case 8:  return BmpRead8(buffer, info, data);
 
		case 24: return BmpRead24(buffer, info, data);
 
		default: NOT_REACHED();
 
		}
src/cheat_gui.cpp
Show inline comments
 
@@ -47,25 +47,25 @@ static int32 _money_cheat_amount = 10000
 

	
 
/**
 
 * Handle cheating of money.
 
 * Note that the amount of money of a company must be changed through a command
 
 * rather than by setting a variable. Since the cheat data structure expects a
 
 * variable, the amount of given/taken money is used for this purpose.
 
 * @param p1 not used.
 
 * @param p2 is -1 or +1 (down/up)
 
 * @return Amount of money cheat.
 
 */
 
static int32 ClickMoneyCheat(int32 p1, int32 p2)
 
{
 
	Command<CMD_MONEY_CHEAT>::Post(p2 * _money_cheat_amount);
 
	Command<CMD_MONEY_CHEAT>::Post(Money(_money_cheat_amount) * p2);
 
	return _money_cheat_amount;
 
}
 

	
 
/**
 
 * Handle changing of company.
 
 * @param p1 company to set to
 
 * @param p2 is -1 or +1 (down/up)
 
 * @return The new company.
 
 */
 
static int32 ClickChangeCompanyCheat(int32 p1, int32 p2)
 
{
 
	while ((uint)p1 < Company::GetPoolSize()) {
src/fontcache/freetypefontcache.cpp
Show inline comments
 
@@ -231,25 +231,25 @@ const Sprite *FreeTypeFontCache::Interna
 
	aa = (slot->bitmap.pixel_mode == FT_PIXEL_MODE_GRAY);
 

	
 
	/* Add 1 scaled pixel for the shadow on the medium font. Our sprite must be at least 1x1 pixel */
 
	uint shadow = (this->fs == FS_NORMAL) ? ScaleGUITrad(1) : 0;
 
	uint width  = std::max(1U, (uint)slot->bitmap.width + shadow);
 
	uint height = std::max(1U, (uint)slot->bitmap.rows  + shadow);
 

	
 
	/* Limit glyph size to prevent overflows later on. */
 
	if (width > MAX_GLYPH_DIM || height > MAX_GLYPH_DIM) usererror("Font glyph is too large");
 

	
 
	/* FreeType has rendered the glyph, now we allocate a sprite and copy the image into it */
 
	SpriteLoader::Sprite sprite;
 
	sprite.AllocateData(ZOOM_LVL_NORMAL, width * height);
 
	sprite.AllocateData(ZOOM_LVL_NORMAL, static_cast<size_t>(width) * height);
 
	sprite.type = ST_FONT;
 
	sprite.colours = (aa ? SCC_PAL | SCC_ALPHA : SCC_PAL);
 
	sprite.width = width;
 
	sprite.height = height;
 
	sprite.x_offs = slot->bitmap_left;
 
	sprite.y_offs = this->ascender - slot->bitmap_top;
 

	
 
	/* Draw shadow for medium size */
 
	if (this->fs == FS_NORMAL && !aa) {
 
		for (uint y = 0; y < (uint)slot->bitmap.rows; y++) {
 
			for (uint x = 0; x < (uint)slot->bitmap.width; x++) {
 
				if (HasBit(slot->bitmap.buffer[(x / 8) + y * slot->bitmap.pitch], 7 - (x % 8))) {
src/gfx.cpp
Show inline comments
 
@@ -1213,58 +1213,61 @@ static void GfxBlitter(const Sprite * co
 
std::unique_ptr<uint32[]> DrawSpriteToRgbaBuffer(SpriteID spriteId, ZoomLevel zoom)
 
{
 
	/* Invalid zoom level requested? */
 
	if (zoom < _settings_client.gui.zoom_min || zoom > _settings_client.gui.zoom_max) return nullptr;
 

	
 
	Blitter *blitter = BlitterFactory::GetCurrentBlitter();
 
	if (blitter->GetScreenDepth() != 8 && blitter->GetScreenDepth() != 32) return nullptr;
 

	
 
	/* Gather information about the sprite to write, reserve memory */
 
	const SpriteID real_sprite = GB(spriteId, 0, SPRITE_WIDTH);
 
	const Sprite *sprite = GetSprite(real_sprite, ST_NORMAL);
 
	Dimension dim = GetSpriteSize(real_sprite, nullptr, zoom);
 
	std::unique_ptr<uint32[]> result(new uint32[dim.width * dim.height]);
 
	size_t dim_size = static_cast<size_t>(dim.width) * dim.height;
 
	std::unique_ptr<uint32[]> result(new uint32[dim_size]);
 
	/* Set buffer to fully transparent. */
 
	MemSetT(result.get(), 0, dim.width * dim.height);
 
	MemSetT(result.get(), 0, dim_size);
 

	
 
	/* Prepare new DrawPixelInfo - Normally this would be the screen but we want to draw to another buffer here.
 
	 * Normally, pitch would be scaled screen width, but in our case our "screen" is only the sprite width wide. */
 
	DrawPixelInfo dpi;
 
	dpi.dst_ptr = result.get();
 
	dpi.pitch = dim.width;
 
	dpi.left = 0;
 
	dpi.top = 0;
 
	dpi.width = dim.width;
 
	dpi.height = dim.height;
 
	dpi.zoom = zoom;
 

	
 
	dim_size = static_cast<size_t>(dim.width) * dim.height;
 

	
 
	/* If the current blitter is a paletted blitter, we have to render to an extra buffer and resolve the palette later. */
 
	std::unique_ptr<byte[]> pal_buffer{};
 
	if (blitter->GetScreenDepth() == 8) {
 
		pal_buffer.reset(new byte[dim.width * dim.height]);
 
		MemSetT(pal_buffer.get(), 0, dim.width * dim.height);
 
		pal_buffer.reset(new byte[dim_size]);
 
		MemSetT(pal_buffer.get(), 0, dim_size);
 

	
 
		dpi.dst_ptr = pal_buffer.get();
 
	}
 

	
 
	/* Temporarily disable screen animations while blitting - This prevents 40bpp_anim from writing to the animation buffer. */
 
	Backup<bool> disable_anim(_screen_disable_anim, true, FILE_LINE);
 
	GfxBlitter<1, true>(sprite, 0, 0, BM_NORMAL, nullptr, real_sprite, zoom, &dpi);
 
	disable_anim.Restore();
 

	
 
	if (blitter->GetScreenDepth() == 8) {
 
		/* Resolve palette. */
 
		uint32 *dst = result.get();
 
		const byte *src = pal_buffer.get();
 
		for (size_t i = 0; i < dim.height * dim.width; ++i) {
 
		for (size_t i = 0; i < dim_size; ++i) {
 
			*dst++ = _cur_palette.palette[*src++].data;
 
		}
 
	}
 

	
 
	return result;
 
}
 

	
 
static void GfxMainBlitterViewport(const Sprite *sprite, int x, int y, BlitterMode mode, const SubSprite *sub, SpriteID sprite_id)
 
{
 
	GfxBlitter<ZOOM_LVL_BASE, false>(sprite, x, y, mode, sub, sprite_id, _cur_dpi->zoom);
 
}
 

	
 
@@ -1497,25 +1500,25 @@ void GetBroadestDigit(uint *front, uint 
 
		int w = GetCharacterWidth(size, c);
 
		if (w > width) {
 
			width = w;
 
			*next = c - '0';
 
			if (c != '0') *front = c - '0';
 
		}
 
	}
 
}
 

	
 
void ScreenSizeChanged()
 
{
 
	_dirty_bytes_per_line = CeilDiv(_screen.width, DIRTY_BLOCK_WIDTH);
 
	_dirty_blocks = ReallocT<byte>(_dirty_blocks, _dirty_bytes_per_line * CeilDiv(_screen.height, DIRTY_BLOCK_HEIGHT));
 
	_dirty_blocks = ReallocT<byte>(_dirty_blocks, static_cast<size_t>(_dirty_bytes_per_line) * CeilDiv(_screen.height, DIRTY_BLOCK_HEIGHT));
 

	
 
	/* check the dirty rect */
 
	if (_invalid_rect.right >= _screen.width) _invalid_rect.right = _screen.width;
 
	if (_invalid_rect.bottom >= _screen.height) _invalid_rect.bottom = _screen.height;
 

	
 
	/* screen size changed and the old bitmap is invalid now, so we don't want to undraw it */
 
	_cursor.visible = false;
 
}
 

	
 
void UndrawMouseCursor()
 
{
 
	/* Don't undraw mouse cursor if it is handled by the video driver. */
src/ground_vehicle.cpp
Show inline comments
 
@@ -132,25 +132,25 @@ int GroundVehicle<T, Type>::GetAccelerat
 
	int64 resistance = 0;
 

	
 
	bool maglev = v->GetAccelerationType() == 2;
 

	
 
	const int area = v->GetAirDragArea();
 
	if (!maglev) {
 
		/* Static resistance plus rolling friction. */
 
		resistance = this->gcache.cached_axle_resistance;
 
		resistance += mass * v->GetRollingFriction();
 
	}
 
	/* Air drag; the air drag coefficient is in an arbitrary NewGRF-unit,
 
	 * so we need some magic conversion factor. */
 
	resistance += (area * this->gcache.cached_air_drag * speed * speed) / 1000;
 
	resistance += static_cast<int64>(area) * this->gcache.cached_air_drag * speed * speed / 1000;
 

	
 
	resistance += this->GetSlopeResistance();
 

	
 
	/* This value allows to know if the vehicle is accelerating or braking. */
 
	AccelStatus mode = v->GetAccelerationStatus();
 

	
 
	const int max_te = this->gcache.cached_max_te; // [N]
 
	/* Constructued from power, with need to multiply by 18 and assuming
 
	 * low speed, it needs to be a 64 bit integer too. */
 
	int64 force;
 
	if (speed > 0) {
 
		if (!maglev) {
src/heightmap.cpp
Show inline comments
 
@@ -179,25 +179,25 @@ static bool ReadHeightmapPNG(const char 
 

	
 
	uint width = png_get_image_width(png_ptr, info_ptr);
 
	uint height = png_get_image_height(png_ptr, info_ptr);
 

	
 
	if (!IsValidHeightmapDimension(width, height)) {
 
		ShowErrorMessage(STR_ERROR_PNGMAP, STR_ERROR_HEIGHTMAP_TOO_LARGE, WL_ERROR);
 
		fclose(fp);
 
		png_destroy_read_struct(&png_ptr, &info_ptr, nullptr);
 
		return false;
 
	}
 

	
 
	if (map != nullptr) {
 
		*map = MallocT<byte>(width * height);
 
		*map = MallocT<byte>(static_cast<size_t>(width) * height);
 
		ReadHeightmapPNGImageData(*map, png_ptr, info_ptr);
 
	}
 

	
 
	*x = width;
 
	*y = height;
 

	
 
	fclose(fp);
 
	png_destroy_read_struct(&png_ptr, &info_ptr, nullptr);
 
	return true;
 
}
 

	
 
#endif /* WITH_PNG */
 
@@ -294,25 +294,25 @@ static bool ReadHeightmapBMP(const char 
 
		BmpDestroyData(&data);
 
		return false;
 
	}
 

	
 
	if (map != nullptr) {
 
		if (!BmpReadBitmap(&buffer, &info, &data)) {
 
			ShowErrorMessage(STR_ERROR_BMPMAP, STR_ERROR_BMPMAP_IMAGE_TYPE, WL_ERROR);
 
			fclose(f);
 
			BmpDestroyData(&data);
 
			return false;
 
		}
 

	
 
		*map = MallocT<byte>(info.width * info.height);
 
		*map = MallocT<byte>(static_cast<size_t>(info.width) * info.height);
 
		ReadHeightmapBMPImageData(*map, &info, &data);
 
	}
 

	
 
	BmpDestroyData(&data);
 

	
 
	*x = info.width;
 
	*y = info.height;
 

	
 
	fclose(f);
 
	return true;
 
}
 

	
src/linkgraph/linkgraph.cpp
Show inline comments
 
@@ -195,25 +195,25 @@ NodeID LinkGraph::AddNode(const Station 
 
 * @param to Destination node of the link.
 
 * @param capacity Capacity of the link.
 
 * @param usage Usage to be added.
 
 * @param mode Update mode to be used.
 
 */
 
void LinkGraph::Node::AddEdge(NodeID to, uint capacity, uint usage, uint32 travel_time, EdgeUpdateMode mode)
 
{
 
	assert(this->index != to);
 
	BaseEdge &edge = this->edges[to];
 
	BaseEdge &first = this->edges[this->index];
 
	edge.capacity = capacity;
 
	edge.usage = usage;
 
	edge.travel_time_sum = travel_time * capacity;
 
	edge.travel_time_sum = static_cast<uint64>(travel_time) * capacity;
 
	edge.next_edge = first.next_edge;
 
	first.next_edge = to;
 
	if (mode & EUM_UNRESTRICTED)  edge.last_unrestricted_update = _date;
 
	if (mode & EUM_RESTRICTED) edge.last_restricted_update = _date;
 
}
 

	
 
/**
 
 * Creates an edge if none exists yet or updates an existing edge.
 
 * @param to Target node.
 
 * @param capacity Capacity of the link.
 
 * @param usage Usage to be added.
 
 * @param mode Update mode to be used.
 
@@ -266,36 +266,36 @@ void LinkGraph::Node::RemoveEdge(NodeID 
 
 * @param capacity Capacity to be added/updated.
 
 * @param usage Usage to be added.
 
 * @param travel_time Travel time to be added, in ticks.
 
 * @param mode Update mode to be applied.
 
 */
 
void LinkGraph::Edge::Update(uint capacity, uint usage, uint32 travel_time, EdgeUpdateMode mode)
 
{
 
	assert(this->edge.capacity > 0);
 
	assert(capacity >= usage);
 

	
 
	if (mode & EUM_INCREASE) {
 
		if (this->edge.travel_time_sum == 0) {
 
			this->edge.travel_time_sum = (this->edge.capacity + capacity) * travel_time;
 
			this->edge.travel_time_sum = static_cast<uint64>(this->edge.capacity + capacity) * travel_time;
 
		} else if (travel_time == 0) {
 
			this->edge.travel_time_sum += this->edge.travel_time_sum / this->edge.capacity * capacity;
 
		} else {
 
			this->edge.travel_time_sum += travel_time * capacity;
 
			this->edge.travel_time_sum += static_cast<uint64>(travel_time) * capacity;
 
		}
 
		this->edge.capacity += capacity;
 
		this->edge.usage += usage;
 
	} else if (mode & EUM_REFRESH) {
 
		if (this->edge.travel_time_sum == 0) {
 
			this->edge.capacity = std::max(this->edge.capacity, capacity);
 
			this->edge.travel_time_sum = travel_time * this->edge.capacity;
 
			this->edge.travel_time_sum = static_cast<uint64>(travel_time) * this->edge.capacity;
 
		} else if (capacity > this->edge.capacity) {
 
			this->edge.travel_time_sum = this->edge.travel_time_sum / this->edge.capacity * capacity;
 
			this->edge.capacity = capacity;
 
		}
 
		this->edge.usage = std::max(this->edge.usage, usage);
 
	}
 
	if (mode & EUM_UNRESTRICTED) this->edge.last_unrestricted_update = _date;
 
	if (mode & EUM_RESTRICTED) this->edge.last_restricted_update = _date;
 
}
 

	
 
/**
 
 * Resize the component and fill it with empty nodes and edges. Used when
src/network/network_chat_gui.cpp
Show inline comments
 
@@ -99,25 +99,25 @@ void CDECL NetworkAddChatMessage(TextCol
 
	cmsg->colour = colour;
 
	cmsg->remove_time = std::chrono::steady_clock::now() + std::chrono::seconds(duration);
 

	
 
	_chatmessage_dirty_time = std::chrono::steady_clock::now();
 
	_chatmessage_dirty = true;
 
}
 

	
 
/** Initialize all font-dependent chat box sizes. */
 
void NetworkReInitChatBoxSize()
 
{
 
	_chatmsg_box.y       = 3 * FONT_HEIGHT_NORMAL;
 
	_chatmsg_box.height  = MAX_CHAT_MESSAGES * (FONT_HEIGHT_NORMAL + ScaleGUITrad(NETWORK_CHAT_LINE_SPACING)) + ScaleGUITrad(4);
 
	_chatmessage_backup  = ReallocT(_chatmessage_backup, _chatmsg_box.width * _chatmsg_box.height * BlitterFactory::GetCurrentBlitter()->GetBytesPerPixel());
 
	_chatmessage_backup  = ReallocT(_chatmessage_backup, static_cast<size_t>(_chatmsg_box.width) * _chatmsg_box.height * BlitterFactory::GetCurrentBlitter()->GetBytesPerPixel());
 
}
 

	
 
/** Initialize all buffers of the chat visualisation. */
 
void NetworkInitChatMessage()
 
{
 
	MAX_CHAT_MESSAGES    = _settings_client.gui.network_chat_box_height;
 

	
 
	_chatmsg_list.clear();
 
	_chatmsg_box.x       = ScaleGUITrad(10);
 
	_chatmsg_box.width   = _settings_client.gui.network_chat_box_width_pct * _screen.width / 100;
 
	NetworkReInitChatBoxSize();
 
	_chatmessage_visible = false;
 
@@ -205,25 +205,25 @@ void NetworkDrawChatMessage()
 
	int y      = _screen.height - _chatmsg_box.y - _chatmsg_box.height;
 
	int width  = _chatmsg_box.width;
 
	int height = _chatmsg_box.height;
 
	if (y < 0) {
 
		height = std::max(height + y, std::min(_chatmsg_box.height, _screen.height));
 
		y = 0;
 
	}
 
	if (x + width >= _screen.width) {
 
		width = _screen.width - x;
 
	}
 
	if (width <= 0 || height <= 0) return;
 

	
 
	assert(blitter->BufferSize(width, height) <= (int)(_chatmsg_box.width * _chatmsg_box.height * blitter->GetBytesPerPixel()));
 
	assert(blitter->BufferSize(width, height) <= static_cast<size_t>(_chatmsg_box.width) * _chatmsg_box.height * blitter->GetBytesPerPixel());
 

	
 
	/* Make a copy of the screen as it is before painting (for undraw) */
 
	blitter->CopyToBuffer(blitter->MoveTo(_screen.dst_ptr, x, y), _chatmessage_backup, width, height);
 

	
 
	_cur_dpi = &_screen; // switch to _screen painting
 

	
 
	auto now = std::chrono::steady_clock::now();
 
	int string_height = 0;
 
	for (auto &cmsg : _chatmsg_list) {
 
		if (!show_all && cmsg.remove_time < now) continue;
 
		SetDParamStr(0, cmsg.message);
 
		string_height += GetStringLineCount(STR_JUST_RAW_STRING, width - 1) * FONT_HEIGHT_NORMAL + NETWORK_CHAT_LINE_SPACING;
src/screenshot.cpp
Show inline comments
 
@@ -128,25 +128,25 @@ static bool MakeBMPImage(const char *nam
 
	FILE *f = fopen(name, "wb");
 
	if (f == nullptr) return false;
 

	
 
	/* Each scanline must be aligned on a 32bit boundary */
 
	uint bytewidth = Align(w * bpp, 4); // bytes per line in file
 

	
 
	/* Size of palette. Only present for 8bpp mode */
 
	uint pal_size = pixelformat == 8 ? sizeof(RgbQuad) * 256 : 0;
 

	
 
	/* Setup the file header */
 
	BitmapFileHeader bfh;
 
	bfh.type = TO_LE16('MB');
 
	bfh.size = TO_LE32(sizeof(BitmapFileHeader) + sizeof(BitmapInfoHeader) + pal_size + bytewidth * h);
 
	bfh.size = TO_LE32(sizeof(BitmapFileHeader) + sizeof(BitmapInfoHeader) + pal_size + static_cast<size_t>(bytewidth) * h);
 
	bfh.reserved = 0;
 
	bfh.off_bits = TO_LE32(sizeof(BitmapFileHeader) + sizeof(BitmapInfoHeader) + pal_size);
 

	
 
	/* Setup the info header */
 
	BitmapInfoHeader bih;
 
	bih.size = TO_LE32(sizeof(BitmapInfoHeader));
 
	bih.width = TO_LE32(w);
 
	bih.height = TO_LE32(h);
 
	bih.planes = TO_LE16(1);
 
	bih.bitcount = TO_LE16(bpp * 8);
 
	bih.compression = 0;
 
	bih.sizeimage = 0;
 
@@ -365,25 +365,25 @@ static bool MakePNGImage(const char *nam
 
#if TTD_ENDIAN == TTD_LITTLE_ENDIAN
 
		png_set_bgr(png_ptr);
 
		png_set_filler(png_ptr, 0, PNG_FILLER_AFTER);
 
#else
 
		png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE);
 
#endif /* TTD_ENDIAN == TTD_LITTLE_ENDIAN */
 
	}
 

	
 
	/* use by default 64k temp memory */
 
	maxlines = Clamp(65536 / w, 16, 128);
 

	
 
	/* now generate the bitmap bits */
 
	void *buff = CallocT<uint8>(w * maxlines * bpp); // by default generate 128 lines at a time.
 
	void *buff = CallocT<uint8>(static_cast<size_t>(w) * maxlines * bpp); // by default generate 128 lines at a time.
 

	
 
	y = 0;
 
	do {
 
		/* determine # lines to write */
 
		n = std::min(h - y, maxlines);
 

	
 
		/* render the pixels into the buffer */
 
		callb(userdata, buff, y, w, n);
 
		y += n;
 

	
 
		/* write them to png */
 
		for (i = 0; i != n; i++) {
 
@@ -472,25 +472,25 @@ static bool MakePCXImage(const char *nam
 
	pcx.height = TO_LE16(h);
 

	
 
	/* write pcx header */
 
	if (fwrite(&pcx, sizeof(pcx), 1, f) != 1) {
 
		fclose(f);
 
		return false;
 
	}
 

	
 
	/* use by default 64k temp memory */
 
	maxlines = Clamp(65536 / w, 16, 128);
 

	
 
	/* now generate the bitmap bits */
 
	uint8 *buff = CallocT<uint8>(w * maxlines); // by default generate 128 lines at a time.
 
	uint8 *buff = CallocT<uint8>(static_cast<size_t>(w) * maxlines); // by default generate 128 lines at a time.
 

	
 
	y = 0;
 
	do {
 
		/* determine # lines to write */
 
		uint n = std::min(h - y, maxlines);
 
		uint i;
 

	
 
		/* render the pixels into the buffer */
 
		callb(userdata, buff, y, w, n);
 
		y += n;
 

	
 
		/* write them to pcx */
src/spritecache.cpp
Show inline comments
 
@@ -227,48 +227,48 @@ static bool ResizeSpriteIn(SpriteLoader:
 
{
 
	uint8 scaled_1 = ScaleByZoom(1, (ZoomLevel)(src - tgt));
 

	
 
	/* Check for possible memory overflow. */
 
	if (sprite[src].width * scaled_1 > UINT16_MAX || sprite[src].height * scaled_1 > UINT16_MAX) return false;
 

	
 
	sprite[tgt].width  = sprite[src].width  * scaled_1;
 
	sprite[tgt].height = sprite[src].height * scaled_1;
 
	sprite[tgt].x_offs = sprite[src].x_offs * scaled_1;
 
	sprite[tgt].y_offs = sprite[src].y_offs * scaled_1;
 
	sprite[tgt].colours = sprite[src].colours;
 

	
 
	sprite[tgt].AllocateData(tgt, sprite[tgt].width * sprite[tgt].height);
 
	sprite[tgt].AllocateData(tgt, static_cast<size_t>(sprite[tgt].width) * sprite[tgt].height);
 

	
 
	SpriteLoader::CommonPixel *dst = sprite[tgt].data;
 
	for (int y = 0; y < sprite[tgt].height; y++) {
 
		const SpriteLoader::CommonPixel *src_ln = &sprite[src].data[y / scaled_1 * sprite[src].width];
 
		for (int x = 0; x < sprite[tgt].width; x++) {
 
			*dst = src_ln[x / scaled_1];
 
			dst++;
 
		}
 
	}
 

	
 
	return true;
 
}
 

	
 
static void ResizeSpriteOut(SpriteLoader::Sprite *sprite, ZoomLevel zoom)
 
{
 
	/* Algorithm based on 32bpp_Optimized::ResizeSprite() */
 
	sprite[zoom].width  = UnScaleByZoom(sprite[ZOOM_LVL_NORMAL].width,  zoom);
 
	sprite[zoom].height = UnScaleByZoom(sprite[ZOOM_LVL_NORMAL].height, zoom);
 
	sprite[zoom].x_offs = UnScaleByZoom(sprite[ZOOM_LVL_NORMAL].x_offs, zoom);
 
	sprite[zoom].y_offs = UnScaleByZoom(sprite[ZOOM_LVL_NORMAL].y_offs, zoom);
 
	sprite[zoom].colours = sprite[ZOOM_LVL_NORMAL].colours;
 

	
 
	sprite[zoom].AllocateData(zoom, sprite[zoom].height * sprite[zoom].width);
 
	sprite[zoom].AllocateData(zoom, static_cast<size_t>(sprite[zoom].height) * sprite[zoom].width);
 

	
 
	SpriteLoader::CommonPixel *dst = sprite[zoom].data;
 
	const SpriteLoader::CommonPixel *src = sprite[zoom - 1].data;
 
	[[maybe_unused]] const SpriteLoader::CommonPixel *src_end = src + sprite[zoom - 1].height * sprite[zoom - 1].width;
 

	
 
	for (uint y = 0; y < sprite[zoom].height; y++) {
 
		const SpriteLoader::CommonPixel *src_ln = src + sprite[zoom - 1].width;
 
		assert(src_ln <= src_end);
 
		for (uint x = 0; x < sprite[zoom].width; x++) {
 
			assert(src < src_ln);
 
			if (src + 1 != src_ln && (src + 1)->a != 0) {
 
				*dst = *(src + 1);
 
@@ -281,27 +281,28 @@ static void ResizeSpriteOut(SpriteLoader
 
		src = src_ln + sprite[zoom - 1].width;
 
	}
 
}
 

	
 
static bool PadSingleSprite(SpriteLoader::Sprite *sprite, ZoomLevel zoom, uint pad_left, uint pad_top, uint pad_right, uint pad_bottom)
 
{
 
	uint width  = sprite->width + pad_left + pad_right;
 
	uint height = sprite->height + pad_top + pad_bottom;
 

	
 
	if (width > UINT16_MAX || height > UINT16_MAX) return false;
 

	
 
	/* Copy source data and reallocate sprite memory. */
 
	SpriteLoader::CommonPixel *src_data = MallocT<SpriteLoader::CommonPixel>(sprite->width * sprite->height);
 
	MemCpyT(src_data, sprite->data, sprite->width * sprite->height);
 
	sprite->AllocateData(zoom, width * height);
 
	size_t sprite_size = static_cast<size_t>(sprite->width) * sprite->height;
 
	SpriteLoader::CommonPixel *src_data = MallocT<SpriteLoader::CommonPixel>(sprite_size);
 
	MemCpyT(src_data, sprite->data, sprite_size);
 
	sprite->AllocateData(zoom, static_cast<size_t>(width) * height);
 

	
 
	/* Copy with padding to destination. */
 
	SpriteLoader::CommonPixel *src = src_data;
 
	SpriteLoader::CommonPixel *data = sprite->data;
 
	for (uint y = 0; y < height; y++) {
 
		if (y < pad_top || pad_bottom + y >= height) {
 
			/* Top/bottom padding. */
 
			MemSetT(data, 0, width);
 
			data += width;
 
		} else {
 
			if (pad_left > 0) {
 
				/* Pad left. */
src/spriteloader/grf.cpp
Show inline comments
 
@@ -83,25 +83,25 @@ bool DecodeSingleSprite(SpriteLoader::Sp
 
			int size = -(code >> 3);
 
			num -= size;
 
			if (num < 0) return WarnCorruptSprite(file, file_pos, __LINE__);
 
			for (; size > 0; size--) {
 
				*dest = *(dest - data_offset);
 
				dest++;
 
			}
 
		}
 
	}
 

	
 
	if (num != 0) return WarnCorruptSprite(file, file_pos, __LINE__);
 

	
 
	sprite->AllocateData(zoom_lvl, sprite->width * sprite->height);
 
	sprite->AllocateData(zoom_lvl, static_cast<size_t>(sprite->width) * sprite->height);
 

	
 
	/* Convert colour depth to pixel size. */
 
	int bpp = 0;
 
	if (colour_fmt & SCC_RGB)   bpp += 3; // Has RGB data.
 
	if (colour_fmt & SCC_ALPHA) bpp++;    // Has alpha data.
 
	if (colour_fmt & SCC_PAL)   bpp++;    // Has palette data.
 

	
 
	/* When there are transparency pixels, this format has another trick.. decode it */
 
	if (type & 0x08) {
 
		for (int y = 0; y < sprite->height; y++) {
 
			bool last_item = false;
 
			/* Look up in the header-table where the real data is stored for this row */
 
@@ -159,31 +159,32 @@ bool DecodeSingleSprite(SpriteLoader::Sp
 
							case ST_FONT:   data->m = std::min<uint>(*dest, 2u); break;
 
							default:        data->m = *dest; break;
 
						}
 
						/* Magic blue. */
 
						if (colour_fmt == SCC_PAL && *dest == 0) data->a = 0x00;
 
						dest++;
 
					}
 
					data++;
 
				}
 
			} while (!last_item);
 
		}
 
	} else {
 
		if (dest_size < sprite->width * sprite->height * bpp) {
 
		int64 sprite_size = static_cast<int64>(sprite->width) * sprite->height * bpp;
 
		if (dest_size < sprite_size) {
 
			return WarnCorruptSprite(file, file_pos, __LINE__);
 
		}
 

	
 
		if (dest_size > sprite->width * sprite->height * bpp) {
 
		if (dest_size > sprite_size) {
 
			static byte warning_level = 0;
 
			Debug(sprite, warning_level, "Ignoring {} unused extra bytes from the sprite from {} at position {}", dest_size - sprite->width * sprite->height * bpp, file.GetSimplifiedFilename(), file_pos);
 
			Debug(sprite, warning_level, "Ignoring {} unused extra bytes from the sprite from {} at position {}", dest_size - sprite_size, file.GetSimplifiedFilename(), file_pos);
 
			warning_level = 6;
 
		}
 

	
 
		dest = dest_orig.get();
 

	
 
		for (int i = 0; i < sprite->width * sprite->height; i++) {
 
			byte *pixel = &dest[i * bpp];
 

	
 
			if (colour_fmt & SCC_RGB) {
 
				sprite->data[i].r = *pixel++;
 
				sprite->data[i].g = *pixel++;
 
				sprite->data[i].b = *pixel++;
src/station_cmd.cpp
Show inline comments
 
@@ -1117,25 +1117,25 @@ static inline byte *CreateMulti(byte *la
 
 * @param layout    The layout to write to.
 
 * @param numtracks The number of tracks to write.
 
 * @param plat_len  The length of the platforms.
 
 * @param statspec  The specification of the station to (possibly) get the layout from.
 
 */
 
void GetStationLayout(byte *layout, uint numtracks, uint plat_len, const StationSpec *statspec)
 
{
 
	if (statspec != nullptr && statspec->layouts.size() >= plat_len &&
 
			statspec->layouts[plat_len - 1].size() >= numtracks &&
 
			!statspec->layouts[plat_len - 1][numtracks - 1].empty()) {
 
		/* Custom layout defined, follow it. */
 
		memcpy(layout, statspec->layouts[plat_len - 1][numtracks - 1].data(),
 
			plat_len * numtracks);
 
			static_cast<size_t>(plat_len) * numtracks);
 
		return;
 
	}
 

	
 
	if (plat_len == 1) {
 
		CreateSingle(layout, numtracks);
 
	} else {
 
		if (numtracks & 1) layout = CreateSingle(layout, plat_len);
 
		int n = numtracks >> 1;
 

	
 
		while (--n >= 0) {
 
			layout = CreateMulti(layout, plat_len, 4);
 
			layout = CreateMulti(layout, plat_len, 6);
 
@@ -1855,25 +1855,25 @@ CommandCost CmdBuildRoadStop(DoCommandFl
 
	/* Total road stop cost. */
 
	CommandCost cost(EXPENSES_CONSTRUCTION, roadstop_area.w * roadstop_area.h * _price[is_truck_stop ? PR_BUILD_STATION_TRUCK : PR_BUILD_STATION_BUS]);
 
	StationID est = INVALID_STATION;
 
	ret = CheckFlatLandRoadStop(roadstop_area, flags, is_drive_through ? 5 << axis : 1 << ddir, is_drive_through, is_truck_stop, axis, &est, rt);
 
	if (ret.Failed()) return ret;
 
	cost.AddCost(ret);
 

	
 
	Station *st = nullptr;
 
	ret = FindJoiningRoadStop(est, station_to_join, adjacent, roadstop_area, &st);
 
	if (ret.Failed()) return ret;
 

	
 
	/* Check if this number of road stops can be allocated. */
 
	if (!RoadStop::CanAllocateItem(roadstop_area.w * roadstop_area.h)) return_cmd_error(is_truck_stop ? STR_ERROR_TOO_MANY_TRUCK_STOPS : STR_ERROR_TOO_MANY_BUS_STOPS);
 
	if (!RoadStop::CanAllocateItem(static_cast<size_t>(roadstop_area.w) * roadstop_area.h)) return_cmd_error(is_truck_stop ? STR_ERROR_TOO_MANY_TRUCK_STOPS : STR_ERROR_TOO_MANY_BUS_STOPS);
 

	
 
	ret = BuildStationPart(&st, flags, reuse, roadstop_area, STATIONNAMING_ROAD);
 
	if (ret.Failed()) return ret;
 

	
 
	if (flags & DC_EXEC) {
 
		/* Check every tile in the area. */
 
		for (TileIndex cur_tile : roadstop_area) {
 
			/* Get existing road types and owners before any tile clearing */
 
			RoadType road_rt = MayHaveRoad(cur_tile) ? GetRoadType(cur_tile, RTT_ROAD) : INVALID_ROADTYPE;
 
			RoadType tram_rt = MayHaveRoad(cur_tile) ? GetRoadType(cur_tile, RTT_TRAM) : INVALID_ROADTYPE;
 
			Owner road_owner = road_rt != INVALID_ROADTYPE ? GetRoadOwner(cur_tile, RTT_ROAD) : _current_company;
 
			Owner tram_owner = tram_rt != INVALID_ROADTYPE ? GetRoadOwner(cur_tile, RTT_TRAM) : _current_company;
src/tgp.cpp
Show inline comments
 
@@ -317,25 +317,25 @@ static inline bool IsValidXY(int x, int 
 
/**
 
 * Allocate array of (MapSizeX()+1)*(MapSizeY()+1) heights and init the _height_map structure members
 
 * @return true on success
 
 */
 
static inline bool AllocHeightMap()
 
{
 
	assert(_height_map.h.empty());
 

	
 
	_height_map.size_x = MapSizeX();
 
	_height_map.size_y = MapSizeY();
 

	
 
	/* Allocate memory block for height map row pointers */
 
	size_t total_size = (_height_map.size_x + 1) * (_height_map.size_y + 1);
 
	size_t total_size = static_cast<size_t>(_height_map.size_x + 1) * (_height_map.size_y + 1);
 
	_height_map.dim_x = _height_map.size_x + 1;
 
	_height_map.h.resize(total_size);
 

	
 
	return true;
 
}
 

	
 
/** Free height map */
 
static inline void FreeHeightMap()
 
{
 
	_height_map.h.clear();
 
}
 

	
 
@@ -571,25 +571,25 @@ static void HeightMapCurves(uint level)
 
		{ lengthof(curve_map_2), curve_map_2 },
 
		{ lengthof(curve_map_3), curve_map_3 },
 
		{ lengthof(curve_map_4), curve_map_4 },
 
	};
 

	
 
	height_t ht[lengthof(curve_maps)];
 
	MemSetT(ht, 0, lengthof(ht));
 

	
 
	/* Set up a grid to choose curve maps based on location; attempt to get a somewhat square grid */
 
	float factor = sqrt((float)_height_map.size_x / (float)_height_map.size_y);
 
	uint sx = Clamp((int)(((1 << level) * factor) + 0.5), 1, 128);
 
	uint sy = Clamp((int)(((1 << level) / factor) + 0.5), 1, 128);
 
	byte *c = AllocaM(byte, sx * sy);
 
	byte *c = AllocaM(byte, static_cast<size_t>(sx) * sy);
 

	
 
	for (uint i = 0; i < sx * sy; i++) {
 
		c[i] = Random() % lengthof(curve_maps);
 
	}
 

	
 
	/* Apply curves */
 
	for (int x = 0; x < _height_map.size_x; x++) {
 

	
 
		/* Get our X grid positions and bi-linear ratio */
 
		float fx = (float)(sx * x) / _height_map.size_x + 1.0f;
 
		uint x1 = (uint)fx;
 
		uint x2 = x1;
src/video/allegro_v.cpp
Show inline comments
 
@@ -195,25 +195,25 @@ static bool CreateMainSurface(uint w, ui
 
		return false;
 
	}
 

	
 
	/* The size of the screen might be bigger than the part we can actually draw on!
 
	 * So calculate the size based on the top, bottom, left and right */
 
	_allegro_screen = create_bitmap_ex(bpp, screen->cr - screen->cl, screen->cb - screen->ct);
 
	_screen.width = _allegro_screen->w;
 
	_screen.height = _allegro_screen->h;
 
	_screen.pitch = ((byte*)screen->line[1] - (byte*)screen->line[0]) / (bpp / 8);
 
	_screen.dst_ptr = _allegro_screen->line[0];
 

	
 
	/* Initialise the screen so we don't blit garbage to the screen */
 
	memset(_screen.dst_ptr, 0, _screen.height * _screen.pitch);
 
	memset(_screen.dst_ptr, 0, static_cast<size_t>(_screen.height) * _screen.pitch);
 

	
 
	/* Set the mouse at the place where we expect it */
 
	poll_mouse();
 
	_cursor.pos.x = mouse_x;
 
	_cursor.pos.y = mouse_y;
 

	
 
	BlitterFactory::GetCurrentBlitter()->PostResize();
 

	
 
	InitPalette();
 

	
 
	char caption[32];
 
	seprintf(caption, lastof(caption), "OpenTTD %s", _openttd_revision);
src/video/dedicated_v.cpp
Show inline comments
 
@@ -130,25 +130,25 @@ static void *_dedicated_video_mem;
 
bool _dedicated_forks;
 

	
 
extern bool SafeLoad(const std::string &filename, SaveLoadOperation fop, DetailedFileType dft, GameMode newgm, Subdirectory subdir, struct LoadFilter *lf = nullptr);
 

	
 
static FVideoDriver_Dedicated iFVideoDriver_Dedicated;
 

	
 

	
 
const char *VideoDriver_Dedicated::Start(const StringList &parm)
 
{
 
	this->UpdateAutoResolution();
 

	
 
	int bpp = BlitterFactory::GetCurrentBlitter()->GetScreenDepth();
 
	_dedicated_video_mem = (bpp == 0) ? nullptr : MallocT<byte>(_cur_resolution.width * _cur_resolution.height * (bpp / 8));
 
	_dedicated_video_mem = (bpp == 0) ? nullptr : MallocT<byte>(static_cast<size_t>(_cur_resolution.width) * _cur_resolution.height * (bpp / 8));
 

	
 
	_screen.width  = _screen.pitch = _cur_resolution.width;
 
	_screen.height = _cur_resolution.height;
 
	_screen.dst_ptr = _dedicated_video_mem;
 
	ScreenSizeChanged();
 
	BlitterFactory::GetCurrentBlitter()->PostResize();
 

	
 
#if defined(_WIN32)
 
	/* For win32 we need to allocate a console (debug mode does the same) */
 
	CreateConsole();
 
	CreateWindowsConsoleThread();
 
	SetConsoleTitle(L"OpenTTD Dedicated Server");
src/video/opengl.cpp
Show inline comments
 
@@ -909,90 +909,91 @@ static void ClearPixelBuffer(size_t len,
 
 * Change the size of the drawing window and allocate matching resources.
 
 * @param w New width of the window.
 
 * @param h New height of the window.
 
 * @param force Recreate resources even if size didn't change.
 
 * @param False if nothing had to be done, true otherwise.
 
 */
 
bool OpenGLBackend::Resize(int w, int h, bool force)
 
{
 
	if (!force && _screen.width == w && _screen.height == h) return false;
 

	
 
	int bpp = BlitterFactory::GetCurrentBlitter()->GetScreenDepth();
 
	int pitch = Align(w, 4);
 
	size_t line_pixel_count = static_cast<size_t>(pitch) * h;
 

	
 
	_glViewport(0, 0, w, h);
 

	
 
	_glPixelStorei(GL_UNPACK_ROW_LENGTH, pitch);
 

	
 
	this->vid_buffer = nullptr;
 
	if (this->persistent_mapping_supported) {
 
		_glDeleteBuffers(1, &this->vid_pbo);
 
		_glGenBuffers(1, &this->vid_pbo);
 
		_glBindBuffer(GL_PIXEL_UNPACK_BUFFER, this->vid_pbo);
 
		_glBufferStorage(GL_PIXEL_UNPACK_BUFFER, pitch * h * bpp / 8, nullptr, GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT | GL_CLIENT_STORAGE_BIT);
 
		_glBufferStorage(GL_PIXEL_UNPACK_BUFFER, line_pixel_count * bpp / 8, nullptr, GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT | GL_CLIENT_STORAGE_BIT);
 
	} else {
 
		/* Re-allocate video buffer texture and backing store. */
 
		_glBindBuffer(GL_PIXEL_UNPACK_BUFFER, this->vid_pbo);
 
		_glBufferData(GL_PIXEL_UNPACK_BUFFER, pitch * h * bpp / 8, nullptr, GL_DYNAMIC_DRAW);
 
		_glBufferData(GL_PIXEL_UNPACK_BUFFER, line_pixel_count * bpp / 8, nullptr, GL_DYNAMIC_DRAW);
 
	}
 

	
 
	if (bpp == 32) {
 
		/* Initialize backing store alpha to opaque for 32bpp modes. */
 
		Colour black(0, 0, 0);
 
		if (_glClearBufferSubData != nullptr) {
 
			_glClearBufferSubData(GL_PIXEL_UNPACK_BUFFER, GL_RGBA8, 0, pitch * h * bpp / 8, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, &black.data);
 
			_glClearBufferSubData(GL_PIXEL_UNPACK_BUFFER, GL_RGBA8, 0, line_pixel_count * bpp / 8, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, &black.data);
 
		} else {
 
			ClearPixelBuffer<uint32>(pitch * h, black.data);
 
			ClearPixelBuffer<uint32>(line_pixel_count, black.data);
 
		}
 
	} else if (bpp == 8) {
 
		if (_glClearBufferSubData != nullptr) {
 
			byte b = 0;
 
			_glClearBufferSubData(GL_PIXEL_UNPACK_BUFFER, GL_R8, 0, pitch * h, GL_RED, GL_UNSIGNED_BYTE, &b);
 
			_glClearBufferSubData(GL_PIXEL_UNPACK_BUFFER, GL_R8, 0, line_pixel_count, GL_RED, GL_UNSIGNED_BYTE, &b);
 
		} else {
 
			ClearPixelBuffer<byte>(pitch * h, 0);
 
			ClearPixelBuffer<byte>(line_pixel_count, 0);
 
		}
 
	}
 

	
 
	_glActiveTexture(GL_TEXTURE0);
 
	_glBindTexture(GL_TEXTURE_2D, this->vid_texture);
 
	switch (bpp) {
 
		case 8:
 
			_glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, w, h, 0, GL_RED, GL_UNSIGNED_BYTE, nullptr);
 
			break;
 

	
 
		default:
 
			_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, nullptr);
 
			break;
 
	}
 
	_glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
 

	
 
	/* Does this blitter need a separate animation buffer? */
 
	if (BlitterFactory::GetCurrentBlitter()->NeedsAnimationBuffer()) {
 
		this->anim_buffer = nullptr;
 
		if (this->persistent_mapping_supported) {
 
			_glDeleteBuffers(1, &this->anim_pbo);
 
			_glGenBuffers(1, &this->anim_pbo);
 
			_glBindBuffer(GL_PIXEL_UNPACK_BUFFER, this->anim_pbo);
 
			_glBufferStorage(GL_PIXEL_UNPACK_BUFFER, pitch * h, nullptr, GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT | GL_CLIENT_STORAGE_BIT);
 
			_glBufferStorage(GL_PIXEL_UNPACK_BUFFER, line_pixel_count, nullptr, GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT | GL_CLIENT_STORAGE_BIT);
 
		} else {
 
			_glBindBuffer(GL_PIXEL_UNPACK_BUFFER, this->anim_pbo);
 
			_glBufferData(GL_PIXEL_UNPACK_BUFFER, pitch * h, nullptr, GL_DYNAMIC_DRAW);
 
			_glBufferData(GL_PIXEL_UNPACK_BUFFER, line_pixel_count, nullptr, GL_DYNAMIC_DRAW);
 
		}
 

	
 
		/* Initialize buffer as 0 == no remap. */
 
		if (_glClearBufferSubData != nullptr) {
 
			byte b = 0;
 
			_glClearBufferSubData(GL_PIXEL_UNPACK_BUFFER, GL_R8, 0, pitch * h, GL_RED, GL_UNSIGNED_BYTE, &b);
 
			_glClearBufferSubData(GL_PIXEL_UNPACK_BUFFER, GL_R8, 0, line_pixel_count, GL_RED, GL_UNSIGNED_BYTE, &b);
 
		} else {
 
			ClearPixelBuffer<byte>(pitch * h, 0);
 
			ClearPixelBuffer<byte>(line_pixel_count, 0);
 
		}
 

	
 
		_glBindTexture(GL_TEXTURE_2D, this->anim_texture);
 
		_glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, w, h, 0, GL_RED, GL_UNSIGNED_BYTE, nullptr);
 
		_glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
 
	} else {
 
		if (this->anim_buffer != nullptr) {
 
			_glBindBuffer(GL_PIXEL_UNPACK_BUFFER, this->anim_pbo);
 
			_glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
 
			_glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
 
			this->anim_buffer = nullptr;
 
		}
 
@@ -1182,25 +1183,25 @@ uint8 *OpenGLBackend::GetAnimBuffer()
 
{
 
	if (this->anim_pbo == 0) return nullptr;
 

	
 
#ifndef NO_GL_BUFFER_SYNC
 
	if (this->sync_anim_mapping != nullptr) _glClientWaitSync(this->sync_anim_mapping, GL_SYNC_FLUSH_COMMANDS_BIT, 100000000); // 100ms timeout.
 
#endif
 

	
 
	if (!this->persistent_mapping_supported) {
 
		_glBindBuffer(GL_PIXEL_UNPACK_BUFFER, this->anim_pbo);
 
		this->anim_buffer = _glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_READ_WRITE);
 
	} else if (this->anim_buffer == nullptr) {
 
		_glBindBuffer(GL_PIXEL_UNPACK_BUFFER, this->anim_pbo);
 
		this->anim_buffer = _glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, 0, _screen.pitch * _screen.height, GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
 
		this->anim_buffer = _glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, 0, static_cast<GLsizeiptr>(_screen.pitch) * _screen.height, GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
 
	}
 

	
 
	return (uint8 *)this->anim_buffer;
 
}
 

	
 
/**
 
 * Update video buffer texture after the video buffer was filled.
 
 * @param update_rect Rectangle encompassing the dirty region of the video buffer.
 
 */
 
void OpenGLBackend::ReleaseVideoBuffer(const Rect &update_rect)
 
{
 
	assert(this->vid_pbo != 0);
 
@@ -1482,39 +1483,40 @@ OpenGLSprite::~OpenGLSprite()
 
 */
 
void OpenGLSprite::Update(uint width, uint height, uint level, const SpriteLoader::CommonPixel * data)
 
{
 
	static ReusableBuffer<Colour> buf_rgba;
 
	static ReusableBuffer<uint8> buf_pal;
 

	
 
	_glActiveTexture(GL_TEXTURE0);
 
	_glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
 
	_glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
 

	
 
	if (this->tex[TEX_RGBA] != 0) {
 
		/* Unpack pixel data */
 
		Colour *rgba = buf_rgba.Allocate(width * height);
 
		for (size_t i = 0; i < width * height; i++) {
 
		size_t size = static_cast<size_t>(width) * height;
 
		Colour *rgba = buf_rgba.Allocate(size);
 
		for (size_t i = 0; i < size; i++) {
 
			rgba[i].r = data[i].r;
 
			rgba[i].g = data[i].g;
 
			rgba[i].b = data[i].b;
 
			rgba[i].a = data[i].a;
 
		}
 

	
 
		_glBindTexture(GL_TEXTURE_2D, this->tex[TEX_RGBA]);
 
		_glTexSubImage2D(GL_TEXTURE_2D, level, 0, 0, width, height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, rgba);
 
	}
 

	
 
	if (this->tex[TEX_REMAP] != 0) {
 
		/* Unpack and align pixel data. */
 
		int pitch = Align(width, 4);
 
		size_t pitch = Align(width, 4);
 

	
 
		uint8 *pal = buf_pal.Allocate(pitch * height);
 
		const SpriteLoader::CommonPixel *row = data;
 
		for (uint y = 0; y < height; y++, pal += pitch, row += width) {
 
			for (uint x = 0; x < width; x++) {
 
				pal[x] = row[x].m;
 
			}
 
		}
 

	
 
		_glBindTexture(GL_TEXTURE_2D, this->tex[TEX_REMAP]);
 
		_glTexSubImage2D(GL_TEXTURE_2D, level, 0, 0, width, height, GL_RED, GL_UNSIGNED_BYTE, buf_pal.GetBuffer());
 
	}
0 comments (0 inline, 0 general)