1 | //============================================================================ |
2 | // |
3 | // SSSS tt lll lll |
4 | // SS SS tt ll ll |
5 | // SS tttttt eeee ll ll aaaa |
6 | // SSSS tt ee ee ll ll aa |
7 | // SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" |
8 | // SS SS tt ee ll ll aa aa |
9 | // SSSS ttt eeeee llll llll aaaaa |
10 | // |
11 | // Copyright (c) 1995-2019 by Bradford W. Mott, Stephen Anthony |
12 | // and the Stella Team |
13 | // |
14 | // See the file "License.txt" for information on usage and redistribution of |
15 | // this file, and for a DISCLAIMER OF ALL WARRANTIES. |
16 | //============================================================================ |
17 | |
18 | #ifndef FBSURFACE_HXX |
19 | #define FBSURFACE_HXX |
20 | |
21 | class FrameBuffer; |
22 | class TIASurface; |
23 | |
24 | namespace GUI { |
25 | class Font; |
26 | } |
27 | namespace Common { |
28 | struct Rect; |
29 | } |
30 | |
31 | #include "FrameBufferConstants.hxx" |
32 | #include "bspf.hxx" |
33 | |
34 | /** |
35 | This class is basically a thin wrapper around the video toolkit 'surface' |
36 | structure. We do it this way so the actual video toolkit won't be dragged |
37 | into the depths of the codebase. All drawing is done into FBSurfaces, |
38 | which are then drawn into the FrameBuffer. Each FrameBuffer-derived class |
39 | is responsible for extending an FBSurface object suitable to the |
40 | FrameBuffer type. |
41 | |
42 | @author Stephen Anthony |
43 | */ |
44 | class FBSurface |
45 | { |
46 | public: |
47 | FBSurface(); |
48 | virtual ~FBSurface() = default; |
49 | |
50 | /** |
51 | This method returns the surface pixel pointer and pitch, which are |
52 | used when one wishes to modify the surface pixels directly. |
53 | */ |
54 | inline void basePtr(uInt32*& pixels, uInt32& pitch) const |
55 | { |
56 | pixels = myPixels; |
57 | pitch = myPitch; |
58 | } |
59 | |
60 | /** |
61 | This method is called to get a copy of the specified ARGB data from |
62 | the behind-the-scenes surface. |
63 | |
64 | @param buffer A copy of the pixel data in ARGB8888 format |
65 | @param pitch The pitch (in bytes) for the pixel data |
66 | @param rect The bounding rectangle for the buffer |
67 | */ |
68 | void readPixels(uInt8* buffer, uInt32 pitch, const Common::Rect& rect) const; |
69 | |
70 | ////////////////////////////////////////////////////////////////////////// |
71 | // Note: The drawing primitives below will work, but do not take |
72 | // advantage of any acceleration whatsoever. The methods are |
73 | // marked as 'virtual' so that child classes can choose to |
74 | // implement them more efficiently. |
75 | ////////////////////////////////////////////////////////////////////////// |
76 | |
77 | /** |
78 | This method should be called to draw a single pixel. |
79 | |
80 | @param x The x coordinate |
81 | @param y The y coordinate |
82 | @param color The color of the line |
83 | */ |
84 | virtual void pixel(uInt32 x, uInt32 y, ColorId color); |
85 | |
86 | /** |
87 | This method should be called to draw a line. |
88 | |
89 | @param x The first x coordinate |
90 | @param y The first y coordinate |
91 | @param x2 The second x coordinate |
92 | @param y2 The second y coordinate |
93 | @param color The color of the line |
94 | */ |
95 | virtual void line(uInt32 x, uInt32 y, uInt32 x2, uInt32 y2, ColorId color); |
96 | |
97 | /** |
98 | This method should be called to draw a horizontal line. |
99 | |
100 | @param x The first x coordinate |
101 | @param y The y coordinate |
102 | @param x2 The second x coordinate |
103 | @param color The color of the line |
104 | */ |
105 | virtual void hLine(uInt32 x, uInt32 y, uInt32 x2, ColorId color); |
106 | |
107 | /** |
108 | This method should be called to draw a vertical line. |
109 | |
110 | @param x The x coordinate |
111 | @param y The first y coordinate |
112 | @param y2 The second y coordinate |
113 | @param color The color of the line |
114 | */ |
115 | virtual void vLine(uInt32 x, uInt32 y, uInt32 y2, ColorId color); |
116 | |
117 | /** |
118 | This method should be called to draw a filled rectangle. |
119 | |
120 | @param x The x coordinate |
121 | @param y The y coordinate |
122 | @param w The width of the area |
123 | @param h The height of the area |
124 | @param color The fill color of the rectangle |
125 | */ |
126 | virtual void fillRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h, |
127 | ColorId color); |
128 | |
129 | /** |
130 | This method should be called to draw the specified character. |
131 | |
132 | @param font The font to use to draw the character |
133 | @param c The character to draw |
134 | @param x The x coordinate |
135 | @param y The y coordinate |
136 | @param color The color of the character |
137 | */ |
138 | virtual void drawChar(const GUI::Font& font, uInt8 c, uInt32 x, uInt32 y, |
139 | ColorId color, ColorId shadowColor = kNone); |
140 | |
141 | /** |
142 | This method should be called to draw the bitmap image. |
143 | |
144 | @param bitmap The data to draw |
145 | @param x The x coordinate |
146 | @param y The y coordinate |
147 | @param color The color of the bitmap |
148 | @param h The height of the data image |
149 | */ |
150 | virtual void drawBitmap(uInt32* bitmap, uInt32 x, uInt32 y, ColorId color, |
151 | uInt32 h = 8); |
152 | |
153 | /** |
154 | This method should be called to draw the bitmap image. |
155 | |
156 | @param bitmap The data to draw |
157 | @param x The x coordinate |
158 | @param y The y coordinate |
159 | @param color The color of the bitmap |
160 | @param w The width of the data image |
161 | @param h The height of the data image |
162 | */ |
163 | virtual void drawBitmap(uInt32* bitmap, uInt32 x, uInt32 y, ColorId color, |
164 | uInt32 w, uInt32 h); |
165 | |
166 | /** |
167 | This method should be called to convert and copy a given row of pixel |
168 | data into a FrameBuffer surface. The pixels must already be in the |
169 | format used by the surface. |
170 | |
171 | @param data The data in uInt8 R/G/B format |
172 | @param x The destination x-location to start drawing pixels |
173 | @param y The destination y-location to start drawing pixels |
174 | @param numpixels The number of pixels to draw |
175 | */ |
176 | virtual void drawPixels(uInt32* data, uInt32 x, uInt32 y, uInt32 numpixels); |
177 | |
178 | /** |
179 | This method should be called to draw a rectangular box with sides |
180 | at the specified coordinates. |
181 | |
182 | @param x The x coordinate |
183 | @param y The y coordinate |
184 | @param w The width of the box |
185 | @param h The height of the box |
186 | @param colorA Lighter color for outside line. |
187 | @param colorB Darker color for inside line. |
188 | */ |
189 | virtual void box(uInt32 x, uInt32 y, uInt32 w, uInt32 h, |
190 | ColorId colorA, ColorId colorB); |
191 | |
192 | /** |
193 | This method should be called to draw a framed rectangle with |
194 | several different possible styles. |
195 | |
196 | @param x The x coordinate |
197 | @param y The y coordinate |
198 | @param w The width of the area |
199 | @param h The height of the area |
200 | @param color The color of the surrounding frame |
201 | @param style The 'FrameStyle' to use for the surrounding frame |
202 | */ |
203 | virtual void frameRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h, |
204 | ColorId color, FrameStyle style = FrameStyle::Solid); |
205 | |
206 | /** |
207 | This method should be called to draw the specified string. |
208 | |
209 | @param font The font to draw the string with |
210 | @param s The string to draw |
211 | @param x The x coordinate |
212 | @param y The y coordinate |
213 | @param w The width of the string area |
214 | @param h The height of the string area (for multi line strings) |
215 | @param color The color of the text |
216 | @param align The alignment of the text in the string width area |
217 | @param deltax FIXME |
218 | @param useEllipsis Whether to use '...' when the string is too long |
219 | @return Number of lines drawn |
220 | */ |
221 | |
222 | virtual int drawString( |
223 | const GUI::Font& font, const string& s, int x, int y, int w, int h, |
224 | ColorId color, TextAlign align = TextAlign::Left, |
225 | int deltax = 0, bool useEllipsis = true, ColorId shadowColor = kNone); |
226 | |
227 | /** |
228 | This method should be called to draw the specified string. |
229 | |
230 | @param font The font to draw the string with |
231 | @param s The string to draw |
232 | @param x The x coordinate |
233 | @param y The y coordinate |
234 | @param w The width of the string area |
235 | @param color The color of the text |
236 | @param align The alignment of the text in the string width area |
237 | @param deltax FIXME |
238 | @param useEllipsis Whether to use '...' when the string is too long |
239 | */ |
240 | virtual void drawString( |
241 | const GUI::Font& font, const string& s, int x, int y, int w, |
242 | ColorId color, TextAlign align = TextAlign::Left, |
243 | int deltax = 0, bool useEllipsis = true, ColorId shadowColor = kNone); |
244 | |
245 | ////////////////////////////////////////////////////////////////////////// |
246 | // Note: The following methods are FBSurface-specific, and must be |
247 | // implemented in child classes. |
248 | // |
249 | // For the following, 'src' indicates the actual data buffer area |
250 | // (non-scaled) and 'dst' indicates the rendered area (possibly scaled). |
251 | ////////////////////////////////////////////////////////////////////////// |
252 | |
253 | /** |
254 | These methods answer the current *real* dimensions of the specified |
255 | surface. |
256 | */ |
257 | virtual uInt32 width() const = 0; |
258 | virtual uInt32 height() const = 0; |
259 | |
260 | /** |
261 | These methods answer the current *rendering* dimensions of the |
262 | specified surface. |
263 | */ |
264 | virtual const Common::Rect& srcRect() const = 0; |
265 | virtual const Common::Rect& dstRect() const = 0; |
266 | |
267 | /** |
268 | These methods set the origin point and width/height for the |
269 | specified service. They are defined as separate x/y and w/h |
270 | methods since these items are sometimes set separately. |
271 | */ |
272 | virtual void setSrcPos(uInt32 x, uInt32 y) = 0; |
273 | virtual void setSrcSize(uInt32 w, uInt32 h) = 0; |
274 | virtual void setDstPos(uInt32 x, uInt32 y) = 0; |
275 | virtual void setDstSize(uInt32 w, uInt32 h) = 0; |
276 | |
277 | /** |
278 | This method should be called to enable/disable showing the surface |
279 | (ie, if hidden it will not be drawn under any circumstances. |
280 | */ |
281 | virtual void setVisible(bool visible) = 0; |
282 | |
283 | /** |
284 | This method should be called to translate the given coordinates |
285 | to the (destination) surface coordinates. |
286 | |
287 | @param x X coordinate to translate |
288 | @param y Y coordinate to translate |
289 | */ |
290 | virtual void translateCoords(Int32& x, Int32& y) const = 0; |
291 | |
292 | /** |
293 | This method should be called to draw the surface to the screen. |
294 | It will return true if rendering actually occurred. |
295 | */ |
296 | virtual bool render() = 0; |
297 | |
298 | /** |
299 | This method should be called to reset the surface to empty |
300 | pixels / colour black. |
301 | */ |
302 | virtual void invalidate() = 0; |
303 | |
304 | /** |
305 | This method should be called to free any resources being used by |
306 | the surface. |
307 | */ |
308 | virtual void free() = 0; |
309 | |
310 | /** |
311 | This method should be called to reload the surface data/state. |
312 | It will normally be called after free(). |
313 | */ |
314 | virtual void reload() = 0; |
315 | |
316 | /** |
317 | This method should be called to resize the surface to the |
318 | given dimensions and reload data/state. The surface is not |
319 | modified if it is larger than the given dimensions. |
320 | */ |
321 | virtual void resize(uInt32 width, uInt32 height) = 0; |
322 | |
323 | /** |
324 | The rendering attributes that can be modified for this texture. |
325 | These probably can only be implemented in child FBSurfaces where |
326 | the specific functionality actually exists. |
327 | */ |
328 | struct Attributes { |
329 | bool smoothing; // Scaling is smoothed or blocky |
330 | bool blending; // Blending is enabled |
331 | uInt32 blendalpha; // Alpha to use in blending mode (0-100%) |
332 | }; |
333 | |
334 | /** |
335 | Get the currently applied attributes. |
336 | */ |
337 | Attributes& attributes() { return myAttributes; } |
338 | |
339 | /** |
340 | The child class chooses which (if any) of the actual attributes |
341 | can be applied. |
342 | |
343 | @param immediate Whether to re-initialize the surface immediately |
344 | with the new attributes, or wait until manually |
345 | reloaded |
346 | */ |
347 | virtual void applyAttributes(bool immediate = true) = 0; |
348 | |
349 | static void setPalette(const uInt32* palette) { myPalette = palette; } |
350 | |
351 | protected: |
352 | /** |
353 | This method must be called to indicate that the surface has been |
354 | modified, and should be redrawn at the next interval. |
355 | */ |
356 | virtual void setDirty() = 0; |
357 | |
358 | /** |
359 | This method should be called to check if the given coordinates |
360 | are in bounds of the surface. |
361 | |
362 | @param x The x coordinate to check |
363 | @param y The y coordinate to check |
364 | @return True if coordinates are in bounds |
365 | */ |
366 | bool checkBounds(const uInt32 x, const uInt32 y) const; |
367 | |
368 | void wrapString(const string& inStr, int pos, string& leftStr, string& rightStr) const; |
369 | |
370 | /** |
371 | Check if the given character is a whitespace. |
372 | @param s Character to check |
373 | @return True if whitespace character |
374 | */ |
375 | bool isWhiteSpace(const char s) const; |
376 | |
377 | protected: |
378 | static const uInt32* myPalette; |
379 | uInt32* myPixels; |
380 | uInt32 myPitch; |
381 | |
382 | Attributes myAttributes; |
383 | |
384 | private: |
385 | // Following constructors and assignment operators not supported |
386 | FBSurface(const FBSurface&) = delete; |
387 | FBSurface(FBSurface&&) = delete; |
388 | FBSurface& operator=(const FBSurface&) = delete; |
389 | FBSurface& operator=(FBSurface&&) = delete; |
390 | }; |
391 | |
392 | #endif |
393 | |