1 /*
2  * This file is part of OpenTTD.
3  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
6  */
7 
8 /** @file gfx_func.h Functions related to the gfx engine. */
9 
10 /**
11  * @defgroup dirty Dirty
12  *
13  * Handles the repaint of some part of the screen.
14  *
15  * Some places in the code are called functions which makes something "dirty".
16  * This has nothing to do with making a Tile or Window darker or less visible.
17  * This term comes from memory caching and is used to define an object must
18  * be repaint. If some data of an object (like a Tile, Window, Vehicle, whatever)
19  * are changed which are so extensive the object must be repaint its marked
20  * as "dirty". The video driver repaint this object instead of the whole screen
21  * (this is btw. also possible if needed). This is used to avoid a
22  * flickering of the screen by the video driver constantly repainting it.
23  *
24  * This whole mechanism is controlled by an rectangle defined in #_invalid_rect. This
25  * rectangle defines the area on the screen which must be repaint. If a new object
26  * needs to be repainted this rectangle is extended to 'catch' the object on the
27  * screen. At some point (which is normally uninteresting for patch writers) this
28  * rectangle is send to the video drivers method
29  * VideoDriver::MakeDirty and it is truncated back to an empty rectangle. At some
30  * later point (which is uninteresting, too) the video driver
31  * repaints all these saved rectangle instead of the whole screen and drop the
32  * rectangle information. Then a new round begins by marking objects "dirty".
33  *
34  * @see VideoDriver::MakeDirty
35  * @see _invalid_rect
36  * @see _screen
37  */
38 
39 
40 #ifndef GFX_FUNC_H
41 #define GFX_FUNC_H
42 
43 #include "gfx_type.h"
44 #include "strings_type.h"
45 #include "string_type.h"
46 
47 void GameLoop();
48 
49 void CreateConsole();
50 
51 extern byte _dirkeys;        ///< 1 = left, 2 = up, 4 = right, 8 = down
52 extern bool _fullscreen;
53 extern byte _support8bpp;
54 extern CursorVars _cursor;
55 extern bool _ctrl_pressed;   ///< Is Ctrl pressed?
56 extern bool _shift_pressed;  ///< Is Shift pressed?
57 extern uint16 _game_speed;
58 
59 extern bool _left_button_down;
60 extern bool _left_button_clicked;
61 extern bool _right_button_down;
62 extern bool _right_button_clicked;
63 
64 extern DrawPixelInfo _screen;
65 extern bool _screen_disable_anim;   ///< Disable palette animation (important for 32bpp-anim blitter during giant screenshot)
66 
67 extern std::vector<Dimension> _resolutions;
68 extern Dimension _cur_resolution;
69 extern Palette _cur_palette; ///< Current palette
70 
71 void HandleToolbarHotkey(int hotkey);
72 void HandleKeypress(uint keycode, WChar key);
73 void HandleTextInput(const char *str, bool marked = false, const char *caret = nullptr, const char *insert_location = nullptr, const char *replacement_end = nullptr);
74 void HandleCtrlChanged();
75 void HandleMouseEvents();
76 void UpdateWindows();
77 void ChangeGameSpeed(bool enable_fast_forward);
78 
79 void DrawMouseCursor();
80 void ScreenSizeChanged();
81 void GameSizeChanged();
82 void UpdateGUIZoom();
83 void UndrawMouseCursor();
84 
85 /** Size of the buffer used for drawing strings. */
86 static const int DRAW_STRING_BUFFER = 2048;
87 
88 void RedrawScreenRect(int left, int top, int right, int bottom);
89 void GfxScroll(int left, int top, int width, int height, int xo, int yo);
90 
91 Dimension GetSpriteSize(SpriteID sprid, Point *offset = nullptr, ZoomLevel zoom = ZOOM_LVL_GUI);
92 void DrawSpriteViewport(SpriteID img, PaletteID pal, int x, int y, const SubSprite *sub = nullptr);
93 void DrawSprite(SpriteID img, PaletteID pal, int x, int y, const SubSprite *sub = nullptr, ZoomLevel zoom = ZOOM_LVL_GUI);
94 std::unique_ptr<uint32[]> DrawSpriteToRgbaBuffer(SpriteID spriteId);
95 
96 int DrawString(int left, int right, int top, const char *str, TextColour colour = TC_FROMSTRING, StringAlignment align = SA_LEFT, bool underline = false, FontSize fontsize = FS_NORMAL);
97 int DrawString(int left, int right, int top, const std::string &str, TextColour colour = TC_FROMSTRING, StringAlignment align = SA_LEFT, bool underline = false, FontSize fontsize = FS_NORMAL);
98 int DrawString(int left, int right, int top, StringID str, TextColour colour = TC_FROMSTRING, StringAlignment align = SA_LEFT, bool underline = false, FontSize fontsize = FS_NORMAL);
99 int DrawStringMultiLine(int left, int right, int top, int bottom, const char *str, TextColour colour = TC_FROMSTRING, StringAlignment align = (SA_TOP | SA_LEFT), bool underline = false, FontSize fontsize = FS_NORMAL);
100 int DrawStringMultiLine(int left, int right, int top, int bottom, const std::string &str, TextColour colour = TC_FROMSTRING, StringAlignment align = (SA_TOP | SA_LEFT), bool underline = false, FontSize fontsize = FS_NORMAL);
101 int DrawStringMultiLine(int left, int right, int top, int bottom, StringID str, TextColour colour = TC_FROMSTRING, StringAlignment align = (SA_TOP | SA_LEFT), bool underline = false, FontSize fontsize = FS_NORMAL);
102 
103 void DrawCharCentered(WChar c, const Rect &r, TextColour colour);
104 
105 void GfxFillRect(int left, int top, int right, int bottom, int colour, FillRectMode mode = FILLRECT_OPAQUE);
106 void GfxFillPolygon(const std::vector<Point> &shape, int colour, FillRectMode mode = FILLRECT_OPAQUE);
107 void GfxDrawLine(int left, int top, int right, int bottom, int colour, int width = 1, int dash = 0);
108 void DrawBox(int x, int y, int dx1, int dy1, int dx2, int dy2, int dx3, int dy3);
109 
110 Dimension GetStringBoundingBox(const char *str, FontSize start_fontsize = FS_NORMAL);
111 Dimension GetStringBoundingBox(const std::string &str, FontSize start_fontsize = FS_NORMAL);
112 Dimension GetStringBoundingBox(StringID strid);
113 int GetStringHeight(const char *str, int maxw, FontSize fontsize = FS_NORMAL);
114 int GetStringHeight(StringID str, int maxw);
115 int GetStringLineCount(StringID str, int maxw);
116 Dimension GetStringMultiLineBoundingBox(StringID str, const Dimension &suggestion);
117 Dimension GetStringMultiLineBoundingBox(const char *str, const Dimension &suggestion);
118 void LoadStringWidthTable(bool monospace = false);
119 Point GetCharPosInString(const char *str, const char *ch, FontSize start_fontsize = FS_NORMAL);
120 const char *GetCharAtPosition(const char *str, int x, FontSize start_fontsize = FS_NORMAL);
121 
122 void DrawDirtyBlocks();
123 void AddDirtyBlock(int left, int top, int right, int bottom);
124 void MarkWholeScreenDirty();
125 
126 bool CopyPalette(Palette &local_palette, bool force_copy = false);
127 void GfxInitPalettes();
128 void CheckBlitter();
129 
130 bool FillDrawPixelInfo(DrawPixelInfo *n, int left, int top, int width, int height);
131 
132 /**
133  * Determine where to draw a centred object inside a widget.
134  * @param min The top or left coordinate.
135  * @param max The bottom or right coordinate.
136  * @param size The height or width of the object to draw.
137  * @return Offset of where to start drawing the object.
138  */
CenterBounds(int min,int max,int size)139 static inline int CenterBounds(int min, int max, int size)
140 {
141 	return min + (max - min - size + 1) / 2;
142 }
143 
144 /* window.cpp */
145 void DrawOverlappedWindowForAll(int left, int top, int right, int bottom);
146 
147 void SetMouseCursorBusy(bool busy);
148 void SetMouseCursor(CursorID cursor, PaletteID pal);
149 void SetAnimatedMouseCursor(const AnimCursor *table);
150 void CursorTick();
151 void UpdateCursorSize();
152 bool ChangeResInGame(int w, int h);
153 void SortResolutions();
154 bool ToggleFullScreen(bool fs);
155 
156 /* gfx.cpp */
157 byte GetCharacterWidth(FontSize size, WChar key);
158 byte GetDigitWidth(FontSize size = FS_NORMAL);
159 void GetBroadestDigit(uint *front, uint *next, FontSize size = FS_NORMAL);
160 
161 int GetCharacterHeight(FontSize size);
162 
163 /** Height of characters in the small (#FS_SMALL) font. @note Some characters may be oversized. */
164 #define FONT_HEIGHT_SMALL  (GetCharacterHeight(FS_SMALL))
165 
166 /** Height of characters in the normal (#FS_NORMAL) font. @note Some characters may be oversized. */
167 #define FONT_HEIGHT_NORMAL (GetCharacterHeight(FS_NORMAL))
168 
169 /** Height of characters in the large (#FS_LARGE) font. @note Some characters may be oversized. */
170 #define FONT_HEIGHT_LARGE  (GetCharacterHeight(FS_LARGE))
171 
172 /** Height of characters in the large (#FS_MONO) font. @note Some characters may be oversized. */
173 #define FONT_HEIGHT_MONO  (GetCharacterHeight(FS_MONO))
174 
175 extern DrawPixelInfo *_cur_dpi;
176 
177 TextColour GetContrastColour(uint8 background, uint8 threshold = 128);
178 
179 /**
180  * All 16 colour gradients
181  * 8 colours per gradient from darkest (0) to lightest (7)
182  */
183 extern byte _colour_gradient[COLOUR_END][8];
184 
185 /**
186  * Return the colour for a particular greyscale level.
187  * @param level Intensity, 0 = black, 15 = white
188  * @return colour
189  */
190 #define GREY_SCALE(level) (level)
191 
192 static const uint8 PC_BLACK              = GREY_SCALE(1);  ///< Black palette colour.
193 static const uint8 PC_DARK_GREY          = GREY_SCALE(6);  ///< Dark grey palette colour.
194 static const uint8 PC_GREY               = GREY_SCALE(10); ///< Grey palette colour.
195 static const uint8 PC_WHITE              = GREY_SCALE(15); ///< White palette colour.
196 
197 static const uint8 PC_VERY_DARK_RED      = 0xB2;           ///< Almost-black red palette colour.
198 static const uint8 PC_DARK_RED           = 0xB4;           ///< Dark red palette colour.
199 static const uint8 PC_RED                = 0xB8;           ///< Red palette colour.
200 
201 static const uint8 PC_VERY_DARK_BROWN    = 0x56;           ///< Almost-black brown palette colour.
202 
203 static const uint8 PC_ORANGE             = 0xC2;           ///< Orange palette colour.
204 
205 static const uint8 PC_YELLOW             = 0xBF;           ///< Yellow palette colour.
206 static const uint8 PC_LIGHT_YELLOW       = 0x44;           ///< Light yellow palette colour.
207 static const uint8 PC_VERY_LIGHT_YELLOW  = 0x45;           ///< Almost-white yellow palette colour.
208 
209 static const uint8 PC_GREEN              = 0xD0;           ///< Green palette colour.
210 
211 static const uint8 PC_VERY_DARK_BLUE     = 0x9A;           ///< Almost-black blue palette colour.
212 static const uint8 PC_DARK_BLUE          = 0x9D;           ///< Dark blue palette colour.
213 static const uint8 PC_LIGHT_BLUE         = 0x98;           ///< Light blue palette colour.
214 
215 static const uint8 PC_ROUGH_LAND         = 0x52;           ///< Dark green palette colour for rough land.
216 static const uint8 PC_GRASS_LAND         = 0x54;           ///< Dark green palette colour for grass land.
217 static const uint8 PC_BARE_LAND          = 0x37;           ///< Brown palette colour for bare land.
218 static const uint8 PC_RAINFOREST         = 0x5C;           ///< Pale green palette colour for rainforest.
219 static const uint8 PC_FIELDS             = 0x25;           ///< Light brown palette colour for fields.
220 static const uint8 PC_TREES              = 0x57;           ///< Green palette colour for trees.
221 static const uint8 PC_WATER              = 0xC9;           ///< Dark blue palette colour for water.
222 #endif /* GFX_FUNC_H */
223