47 std::atomic<bool> _exit_game;
74 static const uint8_t *_colour_remap_ptr;
77 static const uint DIRTY_BLOCK_HEIGHT = 8;
78 static const uint DIRTY_BLOCK_WIDTH = 64;
80 static uint _dirty_bytes_per_line = 0;
81 static uint8_t *_dirty_blocks =
nullptr;
82 extern uint _dirty_block_colour;
84 void GfxScroll(
int left,
int top,
int width,
int height,
int xo,
int yo)
88 if (xo == 0 && yo == 0)
return;
90 if (_cursor.
visible) UndrawMouseCursor();
94 blitter->
ScrollBuffer(_screen.dst_ptr, left, top, width, height, xo, yo);
119 const int otop = top;
120 const int oleft = left;
123 if (left > right || top > bottom)
return;
124 if (right < dpi->left || left >= dpi->left + dpi->width)
return;
125 if (bottom < dpi->top || top >= dpi->top + dpi->height)
return;
127 if ( (left -= dpi->left) < 0) left = 0;
128 right = right - dpi->left + 1;
129 if (right > dpi->width) right = dpi->width;
133 if ( (top -= dpi->top) < 0) top = 0;
134 bottom = bottom - dpi->top + 1;
135 if (bottom > dpi->height) bottom = dpi->height;
139 dst = blitter->
MoveTo(dpi->dst_ptr, left, top);
143 blitter->
DrawRect(dst, right, bottom, (uint8_t)colour);
151 uint8_t bo = (oleft - left + dpi->left + otop - top + dpi->top) & 1;
153 for (
int i = (bo ^= 1); i < right; i += 2) blitter->
SetPixel(dst, i, 0, (uint8_t)colour);
154 dst = blitter->
MoveTo(dst, 0, 1);
155 }
while (--bottom > 0);
161 typedef std::pair<Point, Point> LineSegment;
173 std::vector<LineSegment> segments;
174 if (shape.size() < 3)
return segments;
175 segments.reserve(shape.size());
178 Point prev = shape.back();
181 for (
Point pt : shape) {
187 segments.emplace_back(pt, prev);
188 }
else if (prev.y < pt.y) {
189 segments.emplace_back(prev, pt);
219 segments.erase(std::remove_if(segments.begin(), segments.end(), [dpi](
const LineSegment &s) { return s.second.y <= 0 || s.first.y >= dpi->height; }), segments.end());
222 if (segments.empty())
return;
225 std::sort(segments.begin(), segments.end(), [](
const LineSegment &a,
const LineSegment &b) { return a.first.y < b.first.y; });
228 std::vector<LineSegment> active;
231 std::vector<int> intersections;
234 intersections.reserve(4);
237 int y = segments.front().first.y;
238 std::vector<LineSegment>::iterator nextseg = segments.begin();
239 while (!active.empty() || nextseg != segments.end()) {
241 active.erase(std::remove_if(active.begin(), active.end(), [y](
const LineSegment &s) { return s.second.y == y; }), active.end());
244 while (nextseg != segments.end() && nextseg->first.y == y) {
245 active.push_back(*nextseg);
254 if (y >= dpi->height)
return;
257 intersections.clear();
258 for (
const LineSegment &s : active) {
259 const int sdx = s.second.x - s.first.x;
260 const int sdy = s.second.y - s.first.y;
261 const int ldy = y - s.first.y;
262 const int x = s.first.x + sdx * ldy / sdy;
263 intersections.push_back(x);
267 std::sort(intersections.begin(), intersections.end());
268 for (
size_t i = 1; i < intersections.size(); i += 2) {
270 const int x1 = std::max(0, intersections[i - 1]);
271 const int x2 = std::min(intersections[i], dpi->width);
272 if (x2 < 0)
continue;
273 if (x1 >= dpi->width)
continue;
276 void *dst = blitter->
MoveTo(dpi->dst_ptr, x1, y);
279 blitter->
DrawRect(dst, x2 - x1, 1, (uint8_t)colour);
287 for (
int x = (x1 + y) & 1; x < x2 - x1; x += 2) {
288 blitter->
SetPixel(dst, x, 0, (uint8_t)colour);
313 static inline void GfxDoDrawLine(
void *video,
int x,
int y,
int x2,
int y2,
int screen_width,
int screen_height, uint8_t colour,
int width,
int dash = 0)
319 if (y2 == y || x2 == x) {
321 blitter->
DrawLine(video, x, y, x2, y2, screen_width, screen_height, colour, width, dash);
325 int grade_y = y2 - y;
326 int grade_x = x2 - x;
329 int extra = (int)
CeilDiv(3 * width, 4);
330 Rect clip = { -extra, -extra, screen_width - 1 + extra, screen_height - 1 + extra };
334 while (INT_MAX /
abs(grade_y) < std::max(
abs(clip.left - x),
abs(clip.right - x))) {
344 int left_isec_y = y + (clip.left - x) * grade_y / grade_x;
345 int right_isec_y = y + (clip.right - x) * grade_y / grade_x;
346 if ((left_isec_y > clip.bottom + margin && right_isec_y > clip.bottom + margin) ||
347 (left_isec_y < clip.top - margin && right_isec_y < clip.top - margin)) {
357 blitter->
DrawLine(video, x, y, x2, y2, screen_width, screen_height, colour, width, dash);
379 if (x + width / 2 < 0 && x2 + width / 2 < 0 )
return false;
380 if (y + width / 2 < 0 && y2 + width / 2 < 0 )
return false;
381 if (x - width / 2 > dpi->width && x2 - width / 2 > dpi->width )
return false;
382 if (y - width / 2 > dpi->height && y2 - width / 2 > dpi->height)
return false;
386 void GfxDrawLine(
int x,
int y,
int x2,
int y2,
int colour,
int width,
int dash)
390 GfxDoDrawLine(dpi->dst_ptr, x, y, x2, y2, dpi->width, dpi->height, colour, width, dash);
394 void GfxDrawLineUnscaled(
int x,
int y,
int x2,
int y2,
int colour)
418 void DrawBox(
int x,
int y,
int dx1,
int dy1,
int dx2,
int dy2,
int dx3,
int dy3)
435 static const uint8_t colour =
PC_WHITE;
437 GfxDrawLineUnscaled(x, y, x + dx1, y + dy1, colour);
438 GfxDrawLineUnscaled(x, y, x + dx2, y + dy2, colour);
439 GfxDrawLineUnscaled(x, y, x + dx3, y + dy3, colour);
441 GfxDrawLineUnscaled(x + dx1, y + dy1, x + dx1 + dx2, y + dy1 + dy2, colour);
442 GfxDrawLineUnscaled(x + dx1, y + dy1, x + dx1 + dx3, y + dy1 + dy3, colour);
443 GfxDrawLineUnscaled(x + dx2, y + dy2, x + dx2 + dx1, y + dy2 + dy1, colour);
444 GfxDrawLineUnscaled(x + dx2, y + dy2, x + dx2 + dx3, y + dy2 + dy3, colour);
445 GfxDrawLineUnscaled(x + dx3, y + dy3, x + dx3 + dx1, y + dy3 + dy1, colour);
446 GfxDrawLineUnscaled(x + dx3, y + dy3, x + dx3 + dx2, y + dy3 + dy2, colour);
458 GfxDrawLine(r.left, r.top, r.right, r.top, colour, width, dash);
459 GfxDrawLine(r.left, r.top, r.left, r.bottom, colour, width, dash);
460 GfxDrawLine(r.right, r.top, r.right, r.bottom, colour, width, dash);
461 GfxDrawLine(r.left, r.bottom, r.right, r.bottom, colour, width, dash);
470 if (colour == TC_INVALID)
return;
474 bool no_shade = (colour &
TC_NO_SHADE) != 0 || colour == TC_BLACK;
501 if (line.CountRuns() == 0)
return 0;
503 int w = line.GetWidth();
504 int h = line.GetLeading();
518 int max_w = right - left + 1;
524 truncation &= max_w < w;
526 const Sprite *dot_sprite =
nullptr;
527 bool dot_has_shadow =
false;
536 FontCache *fc = line.GetVisualRun(0).GetFont()->
fc;
540 dot_sprite = fc->
GetGlyph(dot_glyph);
543 min_x += 3 * dot_width;
544 offset_x = w - 3 * dot_width - max_w;
546 max_x -= 3 * dot_width;
563 right = left + w - 1;
569 right = left + w - 1;
573 left = right + 1 - w;
583 for (
bool do_shadow : {
true,
false }) {
584 bool colour_has_shadow =
false;
585 for (
int run_index = 0; run_index < line.CountRuns(); run_index++) {
587 const auto &glyphs = run.GetGlyphs();
588 const auto &positions = run.GetPositions();
589 const Font *f = run.GetFont();
593 if (colour == TC_INVALID ||
HasFlag(default_colour,
TC_FORCED)) colour = default_colour;
594 colour_has_shadow = (colour &
TC_NO_SHADE) == 0 && colour != TC_BLACK;
599 int dpi_left = dpi->left;
600 int dpi_right = dpi->left + dpi->width - 1;
602 for (
int i = 0; i < run.GetGlyphCount(); i++) {
606 if (glyph == 0xFFFF)
continue;
608 int begin_x = positions[i].left + left - offset_x;
609 int end_x = positions[i].right + left - offset_x;
610 int top = positions[i].top + y;
613 if (truncation && (begin_x < min_x || end_x > max_x))
continue;
617 if (begin_x + sprite->
x_offs > dpi_right || begin_x + sprite->
x_offs + sprite->
width < dpi_left)
continue;
619 if (do_shadow && (glyph & SPRITE_GLYPH) != 0)
continue;
621 GfxMainBlitter(sprite, begin_x + (do_shadow ? shadow_offset : 0), top + (do_shadow ? shadow_offset : 0),
BM_COLOUR_REMAP);
625 if (truncation && (!do_shadow || (dot_has_shadow && colour_has_shadow))) {
627 for (
int i = 0; i < 3; i++, x += dot_width) {
628 GfxMainBlitter(dot_sprite, x + (do_shadow ? shadow_offset : 0), y + (do_shadow ? shadow_offset : 0),
BM_COLOUR_REMAP);
663 int extra = max_height / 2;
665 if (_cur_dpi->top + _cur_dpi->height + extra < top || _cur_dpi->top > top + max_height + extra ||
666 _cur_dpi->left + _cur_dpi->width + extra < left || _cur_dpi->left > right + extra) {
670 Layouter layout(str, INT32_MAX, fontsize);
671 if (layout.empty())
return 0;
673 return DrawLayoutLine(*layout.front(), top, left, right, align, underline,
true, colour);
707 Layouter layout(str, maxw, fontsize);
731 return (uint)layout.size();
776 int maxw = right - left + 1;
777 int maxh = bottom - top + 1;
781 if (maxh <= 0)
return top;
783 Layouter layout(str, maxw, fontsize);
784 int total_height = layout.
GetBounds().height;
792 y =
RoundDivSU(bottom + top - total_height, 2);
796 y = bottom - total_height;
799 default: NOT_REACHED();
803 int first_line = bottom;
805 for (
const auto &line : layout) {
807 int line_height = line->GetLeading();
808 if (y >= top && y + line_height - 1 <= bottom) {
809 last_line = y + line_height;
810 if (first_line > y) first_line = y;
812 DrawLayoutLine(*line, y, left, right, align, underline,
false, colour);
853 Layouter layout(str, INT32_MAX, start_fontsize);
877 for (
auto str : list) {
892 for (
auto str : list) {
926 if (offset !=
nullptr) {
967 }
else if (pal != PAL_NONE) {
995 }
else if (pal != PAL_NONE) {
1019 template <
int ZOOM_BASE,
bool SCALED_XY>
1022 const DrawPixelInfo *dpi = (dst !=
nullptr) ? dst : _cur_dpi;
1035 if (sub ==
nullptr) {
1043 int clip_left = std::max(0, -sprite->
x_offs + sub->left * ZOOM_BASE );
1044 int clip_top = std::max(0, -sprite->
y_offs + sub->top * ZOOM_BASE );
1045 int clip_right = std::max(0, sprite->
width - (-sprite->
x_offs + (sub->right + 1) * ZOOM_BASE));
1046 int clip_bottom = std::max(0, sprite->
height - (-sprite->
y_offs + (sub->bottom + 1) * ZOOM_BASE));
1048 if (clip_left + clip_right >= sprite->
width)
return;
1049 if (clip_top + clip_bottom >= sprite->
height)
return;
1067 bp.
dst = dpi->dst_ptr;
1068 bp.
pitch = dpi->pitch;
1069 bp.
remap = _colour_remap_ptr;
1071 assert(sprite->
width > 0);
1072 assert(sprite->
height > 0);
1074 if (bp.
width <= 0)
return;
1075 if (bp.
height <= 0)
return;
1077 y -= SCALED_XY ?
ScaleByZoom(dpi->top, zoom) : dpi->top;
1081 bp.
height -= -y_unscaled;
1082 if (bp.
height <= 0)
return;
1086 bp.
top = y_unscaled;
1093 if (bp.
height <= 0)
return;
1096 x -= SCALED_XY ?
ScaleByZoom(dpi->left, zoom) : dpi->left;
1100 bp.
width -= -x_unscaled;
1101 if (bp.
width <= 0)
return;
1105 bp.
left = x_unscaled;
1112 if (bp.
width <= 0)
return;
1126 if (topleft <= clicked && clicked <= bottomright) {
1127 uint offset = (((size_t)clicked - (
size_t)topleft) / (blitter->
GetScreenDepth() / 8)) % bp.
pitch;
1128 if (offset < (uint)bp.
width) {
1156 size_t dim_size =
static_cast<size_t>(dim.width) * dim.height;
1157 std::unique_ptr<uint32_t[]> result = std::make_unique<uint32_t[]>(dim_size);
1162 dpi.dst_ptr = result.get();
1163 dpi.pitch = dim.width;
1166 dpi.width = dim.width;
1167 dpi.height = dim.height;
1170 dim_size =
static_cast<size_t>(dim.width) * dim.height;
1173 std::unique_ptr<uint8_t[]> pal_buffer{};
1174 if (blitter->GetScreenDepth() == 8) {
1175 pal_buffer = std::make_unique<uint8_t[]>(dim_size);
1176 dpi.dst_ptr = pal_buffer.get();
1181 GfxBlitter<1, true>(sprite, 0, 0,
BM_NORMAL,
nullptr, real_sprite, zoom, &dpi);
1182 disable_anim.Restore();
1184 if (blitter->GetScreenDepth() == 8) {
1186 uint32_t *dst = result.get();
1187 const uint8_t *src = pal_buffer.get();
1188 for (
size_t i = 0; i < dim_size; ++i) {
1198 GfxBlitter<ZOOM_BASE, false>(sprite, x, y, mode, sub, sprite_id, _cur_dpi->zoom);
1203 GfxBlitter<1, true>(sprite, x, y, mode, sub, sprite_id, zoom);
1215 for (uint i = 0; i != 224; i++) {
1243 for (
char c =
'0'; c <=
'9'; c++) {
1258 for (
char c =
'9'; c >=
'0'; c--) {
1263 if (c !=
'0') *front = c -
'0';
1268 void ScreenSizeChanged()
1270 _dirty_bytes_per_line =
CeilDiv(_screen.width, DIRTY_BLOCK_WIDTH);
1271 _dirty_blocks = ReallocT<uint8_t>(_dirty_blocks,
static_cast<size_t>(_dirty_bytes_per_line) *
CeilDiv(_screen.height, DIRTY_BLOCK_HEIGHT));
1281 void UndrawMouseCursor()
1287 if (_screen.dst_ptr ==
nullptr)
return;
1297 void DrawMouseCursor()
1303 if (_screen.dst_ptr ==
nullptr)
return;
1312 if (!_cursor.
dirty)
return;
1313 UndrawMouseCursor();
1317 int left = _cursor.
pos.x + _cursor.total_offs.x;
1323 if (left + width > _screen.width) {
1324 width = _screen.width - left;
1326 if (width <= 0)
return;
1328 int top = _cursor.
pos.y + _cursor.total_offs.y;
1334 if (top + height > _screen.height) {
1335 height = _screen.height - top;
1337 if (height <= 0)
return;
1339 _cursor.draw_pos.x = left;
1340 _cursor.draw_pos.y = top;
1350 _cur_dpi = &_screen;
1351 for (
const auto &cs : _cursor.
sprites) {
1352 DrawSprite(cs.image.sprite, cs.image.pal, _cursor.
pos.x + cs.pos.x, _cursor.
pos.y + cs.pos.y);
1358 _cursor.
dirty =
false;
1373 assert(right <= _screen.width && bottom <= _screen.height);
1375 if (right > _cursor.draw_pos.x &&
1376 left < _cursor.draw_pos.x + _cursor.
draw_size.x &&
1377 bottom > _cursor.draw_pos.y &&
1378 top < _cursor.draw_pos.y + _cursor.
draw_size.y) {
1379 UndrawMouseCursor();
1399 uint8_t *b = _dirty_blocks;
1400 const int w =
Align(_screen.width, DIRTY_BLOCK_WIDTH);
1401 const int h =
Align(_screen.height, DIRTY_BLOCK_HEIGHT);
1412 int right = x + DIRTY_BLOCK_WIDTH;
1420 p += _dirty_bytes_per_line;
1421 bottom += DIRTY_BLOCK_HEIGHT;
1422 }
while (bottom != h && *p != 0);
1425 h2 = (bottom - y) / DIRTY_BLOCK_HEIGHT;
1429 while (right != w) {
1434 if (!*p2)
goto no_more_coalesc;
1435 p2 += _dirty_bytes_per_line;
1440 right += DIRTY_BLOCK_WIDTH;
1446 p2 += _dirty_bytes_per_line;
1459 if (left < right && top < bottom) {
1464 }
while (b++, (x += DIRTY_BLOCK_WIDTH) != w);
1465 }
while (b += -(
int)(w / DIRTY_BLOCK_WIDTH) + _dirty_bytes_per_line, (y += DIRTY_BLOCK_HEIGHT) != h);
1467 ++_dirty_block_colour;
1492 if (left < 0) left = 0;
1493 if (top < 0) top = 0;
1494 if (right > _screen.width) right = _screen.width;
1495 if (bottom > _screen.height) bottom = _screen.height;
1497 if (left >= right || top >= bottom)
return;
1504 left /= DIRTY_BLOCK_WIDTH;
1505 top /= DIRTY_BLOCK_HEIGHT;
1507 b = _dirty_blocks + top * _dirty_bytes_per_line + left;
1509 width = ((right - 1) / DIRTY_BLOCK_WIDTH) - left + 1;
1510 height = ((bottom - 1) / DIRTY_BLOCK_HEIGHT) - top + 1;
1512 assert(width > 0 && height > 0);
1517 do b[--i] = 0xFF;
while (i != 0);
1519 b += _dirty_bytes_per_line;
1520 }
while (--height != 0);
1558 if ((left -= o->left) < 0) {
1560 if (width <= 0)
return false;
1567 if (width > o->width - left) {
1568 width = o->width - left;
1569 if (width <= 0)
return false;
1573 if ((top -= o->top) < 0) {
1575 if (height <= 0)
return false;
1582 n->dst_ptr = blitter->
MoveTo(o->dst_ptr, left, top);
1583 n->pitch = o->pitch;
1585 if (height > o->height - top) {
1586 height = o->height - top;
1587 if (height <= 0)
return false;
1604 for (
const auto &cs : _cursor.
sprites) {
1614 _cursor.total_offs = offs;
1619 int right = std::max(_cursor.total_offs.x + _cursor.
total_size.x, offs.x + size.x);
1620 int bottom = std::max(_cursor.total_offs.y + _cursor.
total_size.y, offs.y + size.y);
1621 if (offs.x < _cursor.total_offs.x) _cursor.total_offs.x = offs.x;
1622 if (offs.y < _cursor.total_offs.y) _cursor.total_offs.y = offs.y;
1623 _cursor.
total_size.x = right - _cursor.total_offs.x;
1624 _cursor.
total_size.y = bottom - _cursor.total_offs.y;
1628 _cursor.
dirty =
true;
1638 if (_cursor.
sprites.size() == 1 && _cursor.
sprites[0].image.sprite == cursor && _cursor.
sprites[0].image.pal == pal)
return;
1641 _cursor.
sprites.emplace_back(cursor, pal, 0, 0);
1646 static void SwitchAnimatedCursor()
1652 assert(!_cursor.
sprites.empty());
1662 SwitchAnimatedCursor();
1672 assert(!_cursor.
sprites.empty());
1701 assert(!_cursor.
sprites.empty());
1704 _cursor.
sprites[0].image.pal = PAL_NONE;
1705 SwitchAnimatedCursor();
1718 this->
delta.x = delta_x;
1719 this->
delta.y = delta_y;
1734 return this->
delta.x != 0 || this->
delta.y != 0;
1735 }
else if (this->
pos.x != x || this->pos.y != y) {
1744 bool ChangeResInGame(
int width,
int height)
1749 bool ToggleFullScreen(
bool fs)
1753 Debug(driver, 0,
"Could not find a suitable fullscreen resolution");
1758 void SortResolutions()
1817 auto zoom_shift = old_gui_zoom -
_gui_zoom;
1820 w->left = (w->left *
_gui_scale) / old_scale;
1823 if (w->viewport !=
nullptr) {
1831 void ChangeGameSpeed(
bool enable_fast_forward)
1833 if (enable_fast_forward) {
void UpdateAllVirtCoords()
Update the viewport coordinates of all signs.
Class for backupping variables and making sure they are restored later.
BlitterMode
The modes of blitting we can do.
@ BM_BLACK_REMAP
Perform remapping to a completely blackened sprite.
@ BM_COLOUR_REMAP
Perform a colour remapping.
@ BM_TRANSPARENT_REMAP
Perform transparency colour remapping.
@ BM_TRANSPARENT
Perform transparency darkening remapping.
@ BM_NORMAL
Perform the simple blitting.
@ BM_CRASH_REMAP
Perform a crash remapping.
constexpr debug_inline bool HasBit(const T x, const uint8_t y)
Checks if a bit in a value is set.
constexpr static debug_inline uint GB(const T x, const uint8_t s, const uint8_t n)
Fetch n bits from x, started at bit s.
static Blitter * GetCurrentBlitter()
Get the current active blitter (always set by calling SelectBlitter).
How all blitters should look like.
virtual uint8_t GetScreenDepth()=0
Get the screen depth this blitter works for.
virtual void SetPixel(void *video, int x, int y, uint8_t colour)=0
Draw a pixel with a given colour on the video-buffer.
virtual size_t BufferSize(uint width, uint height)=0
Calculate how much memory there is needed for an image of this size in the video-buffer.
virtual void DrawColourMappingRect(void *dst, int width, int height, PaletteID pal)=0
Draw a colourtable to the screen.
virtual void DrawRect(void *video, int width, int height, uint8_t colour)=0
Make a single horizontal line in a single colour on the video-buffer.
virtual void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom)=0
Draw an image to the screen, given an amount of params defined above.
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...
virtual void DrawLine(void *video, int x, int y, int x2, int y2, int screen_width, int screen_height, uint8_t colour, int width, int dash=0)=0
Draw a line with a given colour.
virtual void CopyToBuffer(const void *video, void *dst, int width, int height)=0
Copy from the screen to a buffer.
virtual void CopyFromBuffer(void *video, const void *src, int width, int height)=0
Copy from a buffer to the screen.
virtual void ScrollBuffer(void *video, int &left, int &top, int &width, int &height, int scroll_x, int scroll_y)=0
Scroll the videobuffer some 'x' and 'y' value.
Font cache for basic fonts.
virtual const Sprite * GetGlyph(GlyphID key)=0
Get the glyph (sprite) of the given key.
virtual GlyphID MapCharToGlyph(char32_t key, bool fallback=true)=0
Map a character into a glyph.
virtual uint GetGlyphWidth(GlyphID key)=0
Get the width of the glyph with the given key.
virtual bool GetDrawGlyphShadow()=0
Do we need to draw a glyph shadow?
Container with information about a font.
FontCache * fc
The font we are using.
TextColour colour
The colour this font has to be.
The layouter performs all the layout work.
Dimension GetBounds()
Get the boundaries of this paragraph.
A single line worth of VisualRuns.
Visual run contains data about the bit of text with the same font.
const T * GetBuffer() const
Get the currently allocated buffer.
T * Allocate(size_t count)
Get buffer of at least count times T.
virtual bool ToggleFullscreen(bool fullscreen)=0
Change the full screen setting.
virtual int GetSuggestedUIScale()
Get a suggested default GUI scale taking screen DPI into account.
virtual void ClearSystemSprites()
Clear all cached sprites.
virtual void MakeDirty(int left, int top, int width, int height)=0
Mark a particular area dirty.
virtual bool ChangeResolution(int w, int h)=0
Change the resolution of the window.
static VideoDriver * GetInstance()
Get the currently active instance of the video driver.
Some simple functions to help with accessing containers.
bool include(Container &container, typename Container::const_reference &item)
Helper function to append an item to a container if it is not already contained.
Control codes that are embedded in the translation strings.
#define Debug(category, level, format_string,...)
Ouptut a line of debugging information.
std::vector< Dimension > _resolutions
List of resolutions.
constexpr debug_inline bool HasFlag(const T x, const T y)
Checks if a value in a bitset enum is set.
Factory to 'query' all available blitters.
int GetCharacterHeight(FontSize size)
Get height of a character for a given font size.
const Sprite * GetGlyph(FontSize size, char32_t key)
Get the Sprite for a glyph.
uint GetGlyphWidth(FontSize size, char32_t key)
Get the width of a glyph.
uint32_t GlyphID
Glyphs are characters from a font.
Dimension maxdim(const Dimension &d1, const Dimension &d2)
Compute bounding box of both dimensions.
void GfxFillPolygon(const std::vector< Point > &shape, int colour, FillRectMode mode)
Fill a polygon with colour.
int GetStringHeight(std::string_view str, int maxw, FontSize fontsize)
Calculates height of string (in pixels).
void SetMouseCursor(CursorID sprite, PaletteID pal)
Assign a single non-animated sprite to the cursor.
void GetBroadestDigit(uint *front, uint *next, FontSize size)
Determine the broadest digits for guessing the maximum width of a n-digit number.
Dimension GetSpriteSize(SpriteID sprid, Point *offset, ZoomLevel zoom)
Get the size of a sprite.
void UpdateCursorSize()
Update cursor dimension.
static void SetCursorSprite(CursorID cursor, PaletteID pal)
Switch cursor to different sprite.
static int DrawLayoutLine(const ParagraphLayouter::Line &line, int y, int left, int right, StringAlignment align, bool underline, bool truncation, TextColour default_colour)
Drawing routine for drawing a laid out line of text.
bool _shift_pressed
Is Shift pressed?
static void GfxBlitter(const Sprite *const sprite, int x, int y, BlitterMode mode, const SubSprite *const sub, SpriteID sprite_id, ZoomLevel zoom, const DrawPixelInfo *dst=nullptr)
The code for setting up the blitter mode and sprite information before finally drawing the sprite.
PauseMode _pause_mode
The current pause mode.
bool _left_button_down
Is left mouse button pressed?
Dimension GetStringBoundingBox(std::string_view str, FontSize start_fontsize)
Return the string dimension in pixels.
static std::vector< LineSegment > MakePolygonSegments(const std::vector< Point > &shape, Point offset)
Make line segments from a polygon defined by points, translated by an offset.
void DrawRectOutline(const Rect &r, int colour, int width, int dash)
Draw the outline of a Rect.
Dimension GetStringListBoundingBox(std::span< const StringID > list, FontSize fontsize)
Get maximum dimension of a list of strings.
int GetStringLineCount(StringID str, int maxw)
Calculates number of lines of string.
int DrawString(int left, int right, int top, std::string_view str, TextColour colour, StringAlignment align, bool underline, FontSize fontsize)
Draw string, possibly truncated to make it fit in its allocated space.
bool _ctrl_pressed
Is Ctrl pressed?
static void SetColourRemap(TextColour colour)
Set the colour remap to be for the given colour.
static void GfxDoDrawLine(void *video, int x, int y, int x2, int y2, int screen_width, int screen_height, uint8_t colour, int width, int dash=0)
Check line clipping by using a linear equation and draw the visible part of the line given by x/y and...
uint8_t _dirkeys
1 = left, 2 = up, 4 = right, 8 = down
bool _screen_disable_anim
Disable palette animation (important for 32bpp-anim blitter during giant screenshot)
ZoomLevel _font_zoom
Sprite font Zoom level (not clamped)
bool _left_button_clicked
Is left mouse button clicked?
uint GetStringListWidth(std::span< const StringID > list, FontSize fontsize)
Get maximum width of a list of strings.
uint16_t _game_speed
Current game-speed; 100 is 1x, 0 is infinite.
static BlitterMode GetBlitterMode(PaletteID pal)
Helper function to get the blitter mode for different types of palettes.
void SetMouseCursorBusy(bool busy)
Set or unset the ZZZ cursor.
void LoadStringWidthTable(bool monospace)
Initialize _stringwidth_table cache.
std::unique_ptr< uint32_t[]> DrawSpriteToRgbaBuffer(SpriteID spriteId, ZoomLevel zoom)
Draws a sprite to a new RGBA buffer (see Colour union) instead of drawing to the screen.
GameSessionStats _game_session_stats
Statistics about the current session.
void GfxFillRect(int left, int top, int right, int bottom, int colour, FillRectMode mode)
Applies a certain FillRectMode-operation to a rectangle [left, right] x [top, bottom] on the screen.
void UpdateGUIZoom()
Resolve GUI zoom level, if auto-suggestion is requested.
void DrawSprite(SpriteID img, PaletteID pal, int x, int y, const SubSprite *sub, ZoomLevel zoom)
Draw a sprite, not in a viewport.
bool _right_button_clicked
Is right mouse button clicked?
uint8_t GetDigitWidth(FontSize size)
Return the maximum width of single digit.
int _gui_scale_cfg
GUI scale in config.
uint8_t GetCharacterWidth(FontSize size, char32_t key)
Return width of character glyph.
void DrawSpriteViewport(SpriteID img, PaletteID pal, int x, int y, const SubSprite *sub)
Draw a sprite in a viewport.
void SetAnimatedMouseCursor(const AnimCursor *table)
Assign an animation to the cursor.
static bool GfxPreprocessLine(DrawPixelInfo *dpi, int &x, int &y, int &x2, int &y2, int width)
Align parameters of a line to the given DPI and check simple clipping.
Dimension GetStringMultiLineBoundingBox(StringID str, const Dimension &suggestion)
Calculate string bounding box for multi-line strings.
int DrawStringMultiLine(int left, int right, int top, int bottom, std::string_view str, TextColour colour, StringAlignment align, bool underline, FontSize fontsize)
Draw string, possibly over multiple lines.
static uint8_t _stringwidth_table[FS_END][224]
Cache containing width of often used characters.
SwitchMode _switch_mode
The next mainloop command.
void DrawBox(int x, int y, int dx1, int dy1, int dx2, int dy2, int dx3, int dy3)
Draws the projection of a parallelepiped.
ZoomLevel _gui_zoom
GUI Zoom level.
bool FillDrawPixelInfo(DrawPixelInfo *n, int left, int top, int width, int height)
Set up a clipping area for only drawing into a certain area.
bool _right_button_down
Is right mouse button pressed?
static uint8_t _string_colourremap[3]
Recoloursprite for stringdrawing. The grf loader ensures that SpriteType::Font sprites only use colou...
bool AdjustGUIZoom(bool automatic)
Resolve GUI zoom level and adjust GUI to new zoom, if auto-suggestion is requested.
void DrawCharCentered(char32_t c, const Rect &r, TextColour colour)
Draw single character horizontally centered around (x,y)
int _gui_scale
GUI scale, 100 is 100%.
void DrawOverlappedWindowForAll(int left, int top, int right, int bottom)
From a rectangle that needs redrawing, find the windows that intersect with the rectangle.
Palette _cur_palette
Current palette.
int CenterBounds(int min, int max, int size)
Determine where to draw a centred object inside a widget.
Functions related to laying out the texts.
uint32_t SpriteID
The number of a sprite, without mapping bits and colourtables.
@ Recolour
Recolour sprite.
@ Normal
The most basic (normal) sprite.
StringAlignment
How to align the to-be drawn text.
@ SA_TOP
Top align the text.
@ SA_LEFT
Left align the text.
@ SA_HOR_MASK
Mask for horizontal alignment.
@ SA_RIGHT
Right align the text (must be a single bit).
@ SA_HOR_CENTER
Horizontally center the text.
@ SA_VERT_MASK
Mask for vertical alignment.
@ SA_FORCE
Force the alignment, i.e. don't swap for RTL languages.
@ SA_BOTTOM
Bottom align the text.
@ SA_VERT_CENTER
Vertically center the text.
uint32_t CursorID
The number of the cursor (sprite)
FontSize
Available font sizes.
@ FS_MONO
Index of the monospaced font in the font tables.
@ FS_SMALL
Index of the small font in the font tables.
@ FS_NORMAL
Index of the normal font in the font tables.
@ FS_LARGE
Index of the large font in the font tables.
uint32_t PaletteID
The number of the palette.
TextColour
Colour of the strings, see _string_colourmap in table/string_colours.h or docs/ottd-colourtext-palett...
@ TC_FORCED
Ignore colour changes from strings.
@ TC_NO_SHADE
Do not add shading to this text colour.
@ TC_IS_PALETTE_COLOUR
Colour value is already a real palette colour index, not an index of a StringColour.
FillRectMode
Define the operation GfxFillRect performs.
@ FILLRECT_CHECKER
Draw only every second pixel, used for greying-out.
@ FILLRECT_RECOLOUR
Apply a recolour sprite to the screen content.
static Rect _invalid_rect
The rect for repaint.
void AddDirtyBlock(int left, int top, int right, int bottom)
Extend the internal _invalid_rect rectangle to contain the rectangle defined by the given parameters.
void DrawDirtyBlocks()
Repaints the rectangle blocks which are marked as 'dirty'.
void MarkWholeScreenDirty()
This function mark the whole screen as dirty.
void RedrawScreenRect(int left, int top, int right, int bottom)
Repaints a specific rectangle of the screen.
constexpr T abs(const T a)
Returns the absolute value of (scalar) variable.
constexpr T Align(const T x, uint n)
Return the smallest multiple of n equal or greater than x.
constexpr int RoundDivSU(int a, uint b)
Computes round(a / b) for signed a and unsigned b.
constexpr uint CeilDiv(uint a, uint b)
Computes ceil(a / b) for non-negative a and b.
constexpr T Clamp(const T a, const T min, const T max)
Clamp a value between an interval.
bool _networking
are we in networking mode?
Basic functions/variables used all over the place.
void NetworkUndrawChatMessage()
Hide the chatbox.
Network functions used by other parts of OpenTTD.
Functions/types related to NewGRF debugging.
NewGrfDebugSpritePicker _newgrf_debug_sprite_picker
The sprite picker.
SwitchMode
Mode which defines what mode we're switching to.
PauseMode
Modes of pausing we've got.
GameMode
Mode which defines the state of the game.
static const uint8_t PC_WHITE
White palette colour.
Functions related to modal progress.
A number of safeguards to prevent using unsafe methods.
ClientSettings _settings_client
The current settings for this game.
Types related to global configuration settings.
void GfxClearFontSpriteCache()
Remove all encoded font sprites from the sprite cache without discarding sprite location information.
uint GetMaxSpriteID()
Get a reasonable (upper bound) estimate of the maximum SpriteID used in OpenTTD; there will be no spr...
This file contains all sprite-related enums and defines.
static const PaletteID PALETTE_ALL_BLACK
Exchange any color by black, needed for painting fictive tiles outside map.
static constexpr uint8_t PALETTE_WIDTH
number of bits of the sprite containing the recolour palette
static constexpr uint8_t PALETTE_MODIFIER_TRANSPARENT
when a sprite is to be displayed transparently, this bit needs to be set.
static const PaletteID PALETTE_CRASH
Recolour sprite greying of crashed vehicles.
static const CursorID SPR_CURSOR_MOUSE
Cursor sprite numbers.
static constexpr uint8_t PALETTE_TEXT_RECOLOUR
Set if palette is actually a magic text recolour.
static constexpr uint8_t SPRITE_WIDTH
number of bits for the sprite number
static const PaletteID PALETTE_TO_TRANSPARENT
This sets the sprite to transparent.
Definition of base types and functions in a cross-platform compatible way.
The colour translation of GRF's strings.
static const uint8_t _string_colourmap[17]
Colour mapping for TextColour.
std::string GetString(StringID string)
Resolve the given StringID into a std::string with all the associated DParam lookups and formatting.
TextDirection _current_text_dir
Text direction of the currently selected language.
Functions related to OTTD's strings.
@ TD_RTL
Text is written right-to-left by default.
uint32_t StringID
Numeric value that represents a string, independent of the selected language.
A single sprite of a list of animated cursors.
uint8_t display_time
Amount of ticks this sprite will be shown.
CursorID sprite
Must be set to LAST_ANIM when it is the last sprite of the loop.
Class to backup a specific variable and restore it later.
Parameters related to blitting.
int skip_top
How much pixels of the source to skip on the top (based on zoom of dst)
int sprite_height
Real height of the sprite.
void * dst
Destination buffer.
int left
The left offset in the 'dst' in pixels to start drawing.
int pitch
The pitch of the destination buffer.
int sprite_width
Real width of the sprite.
int skip_left
How much pixels of the source to skip on the left (based on zoom of dst)
int height
The height in pixels that needs to be drawn to dst.
const uint8_t * remap
XXX – Temporary storage for remap array.
int width
The width in pixels that needs to be drawn to dst.
const void * sprite
Pointer to the sprite how ever the encoder stored it.
int top
The top offset in the 'dst' in pixels to start drawing.
GUISettings gui
settings related to the GUI
Collection of variables for cursor-display and -animation.
bool visible
cursor is visible
bool UpdateCursorPosition(int x, int y)
Update cursor position on mouse movement.
uint animate_timeout
in case of animated cursor, number of ticks to show the current cursor
std::vector< CursorSprite > sprites
Sprites comprising cursor.
bool fix_at
mouse is moving, but cursor is not (used for scrolling)
const AnimCursor * animate_list
in case of animated cursor, list of frames
Point pos
logical mouse position
void UpdateCursorPositionRelative(int delta_x, int delta_y)
Update cursor position based on a relative change.
bool in_window
mouse inside this window, determines drawing logic
const AnimCursor * animate_cur
in case of animated cursor, current frame
Point total_size
union of sprite properties
bool dirty
the rect occupied by the mouse is dirty (redraw)
Point draw_size
position and size bounding-box for drawing
Point delta
relative mouse movement in this tick
Dimensions (a width and height) of a rectangle in 2D.
Data about how and where to blit pixels.
uint16_t fast_forward_speed_limit
Game speed to use when fast-forward is enabled.
ZoomLevel zoom_min
minimum zoom out level
ZoomLevel zoom_max
maximum zoom out level
NewGrfDebugSpritePickerMode mode
Current state.
void * clicked_pixel
Clicked pixel (pointer to blitter buffer)
std::vector< SpriteID > sprites
Sprites found.
Colour palette[256]
Current palette. Entry 0 has to be always fully transparent!
Coordinates of a point in 2D.
Specification of a rectangle with absolute coordinates of all edges.
Data structure describing a sprite.
uint16_t width
Width of the sprite.
uint16_t height
Height of the sprite.
int16_t y_offs
Number of pixels to shift the sprite downwards.
uint8_t data[]
Sprite data.
int16_t x_offs
Number of pixels to shift the sprite to the right.
Used to only draw a part of the sprite.
Iterable ensemble of all valid Windows.
Data structure for an opened window.
uint32_t data
Conversion of the channel information to a 32 bit number.
Base of all video drivers.
Functions related to (drawing on) viewports.
Window functions not directly related to making/drawing windows.
Functions, definitions and such used only by the GUI.
Functions related to zooming.
int ScaleByZoom(int value, ZoomLevel zoom)
Scale by zoom level, usually shift left (when zoom > ZOOM_LVL_MIN) When shifting right,...
int ScaleGUITrad(int value)
Scale traditional pixel dimensions to GUI zoom level.
int UnScaleByZoomLower(int value, ZoomLevel zoom)
Scale by zoom level, usually shift right (when zoom > ZOOM_LVL_MIN)
int UnScaleGUI(int value)
Short-hand to apply GUI zoom level.
int UnScaleByZoom(int value, ZoomLevel zoom)
Scale by zoom level, usually shift right (when zoom > ZOOM_LVL_MIN) When shifting right,...
ZoomLevel
All zoom levels we know.
@ ZOOM_LVL_NORMAL
The normal zoom level.
@ ZOOM_LVL_IN_2X
Zoomed 2 times in.
@ ZOOM_LVL_MIN
Minimum zoom level.
@ ZOOM_LVL_IN_4X
Zoomed 4 times in.