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
21class FrameBuffer;
22class TIASurface;
23
24namespace GUI {
25 class Font;
26}
27namespace 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*/
44class 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