mirror of https://github.com/stella-emu/stella.git
396 lines
13 KiB
C++
396 lines
13 KiB
C++
//============================================================================
|
|
//
|
|
// SSSS tt lll lll
|
|
// SS SS tt ll ll
|
|
// SS tttttt eeee ll ll aaaa
|
|
// SSSS tt ee ee ll ll aa
|
|
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
|
// SS SS tt ee ll ll aa aa
|
|
// SSSS ttt eeeee llll llll aaaaa
|
|
//
|
|
// Copyright (c) 1995-2019 by Bradford W. Mott, Stephen Anthony
|
|
// and the Stella Team
|
|
//
|
|
// See the file "License.txt" for information on usage and redistribution of
|
|
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
|
//============================================================================
|
|
|
|
#ifndef FBSURFACE_HXX
|
|
#define FBSURFACE_HXX
|
|
|
|
class FrameBuffer;
|
|
class TIASurface;
|
|
|
|
namespace GUI {
|
|
class Font;
|
|
}
|
|
namespace Common {
|
|
struct Rect;
|
|
}
|
|
|
|
#include "FrameBufferConstants.hxx"
|
|
#include "FrameBuffer.hxx"
|
|
#include "bspf.hxx"
|
|
|
|
/**
|
|
This class is basically a thin wrapper around the video toolkit 'surface'
|
|
structure. We do it this way so the actual video toolkit won't be dragged
|
|
into the depths of the codebase. All drawing is done into FBSurfaces,
|
|
which are then drawn into the FrameBuffer. Each FrameBuffer-derived class
|
|
is responsible for extending an FBSurface object suitable to the
|
|
FrameBuffer type.
|
|
|
|
NOTE: myPixels and myPitch MUST be set in child classes that inherit
|
|
from this class
|
|
|
|
@author Stephen Anthony
|
|
*/
|
|
class FBSurface
|
|
{
|
|
public:
|
|
FBSurface() = default;
|
|
virtual ~FBSurface() = default;
|
|
|
|
/**
|
|
This method returns the surface pixel pointer and pitch, which are
|
|
used when one wishes to modify the surface pixels directly.
|
|
*/
|
|
inline void basePtr(uInt32*& pixels, uInt32& pitch) const
|
|
{
|
|
pixels = myPixels;
|
|
pitch = myPitch;
|
|
}
|
|
|
|
/**
|
|
This method is called to get a copy of the specified ARGB data from
|
|
the behind-the-scenes surface.
|
|
|
|
@param buffer A copy of the pixel data in ARGB8888 format
|
|
@param pitch The pitch (in bytes) for the pixel data
|
|
@param rect The bounding rectangle for the buffer
|
|
*/
|
|
void readPixels(uInt8* buffer, uInt32 pitch, const Common::Rect& rect) const;
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// Note: The drawing primitives below will work, but do not take
|
|
// advantage of any acceleration whatsoever. The methods are
|
|
// marked as 'virtual' so that child classes can choose to
|
|
// implement them more efficiently.
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
/**
|
|
This method should be called to draw a single pixel.
|
|
|
|
@param x The x coordinate
|
|
@param y The y coordinate
|
|
@param color The color of the line
|
|
*/
|
|
virtual void pixel(uInt32 x, uInt32 y, ColorId color);
|
|
|
|
/**
|
|
This method should be called to draw a line.
|
|
|
|
@param x The first x coordinate
|
|
@param y The first y coordinate
|
|
@param x2 The second x coordinate
|
|
@param y2 The second y coordinate
|
|
@param color The color of the line
|
|
*/
|
|
virtual void line(uInt32 x, uInt32 y, uInt32 x2, uInt32 y2, ColorId color);
|
|
|
|
/**
|
|
This method should be called to draw a horizontal line.
|
|
|
|
@param x The first x coordinate
|
|
@param y The y coordinate
|
|
@param x2 The second x coordinate
|
|
@param color The color of the line
|
|
*/
|
|
virtual void hLine(uInt32 x, uInt32 y, uInt32 x2, ColorId color);
|
|
|
|
/**
|
|
This method should be called to draw a vertical line.
|
|
|
|
@param x The x coordinate
|
|
@param y The first y coordinate
|
|
@param y2 The second y coordinate
|
|
@param color The color of the line
|
|
*/
|
|
virtual void vLine(uInt32 x, uInt32 y, uInt32 y2, ColorId color);
|
|
|
|
/**
|
|
This method should be called to draw a filled rectangle.
|
|
|
|
@param x The x coordinate
|
|
@param y The y coordinate
|
|
@param w The width of the area
|
|
@param h The height of the area
|
|
@param color The fill color of the rectangle
|
|
*/
|
|
virtual void fillRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h,
|
|
ColorId color);
|
|
|
|
/**
|
|
This method should be called to draw the specified character.
|
|
|
|
@param font The font to use to draw the character
|
|
@param c The character to draw
|
|
@param x The x coordinate
|
|
@param y The y coordinate
|
|
@param color The color of the character
|
|
*/
|
|
virtual void drawChar(const GUI::Font& font, uInt8 c, uInt32 x, uInt32 y,
|
|
ColorId color, ColorId shadowColor = kNone);
|
|
|
|
/**
|
|
This method should be called to draw the bitmap image.
|
|
|
|
@param bitmap The data to draw
|
|
@param x The x coordinate
|
|
@param y The y coordinate
|
|
@param color The color of the bitmap
|
|
@param h The height of the data image
|
|
*/
|
|
virtual void drawBitmap(const uInt32* bitmap, uInt32 x, uInt32 y, ColorId color,
|
|
uInt32 h = 8);
|
|
|
|
/**
|
|
This method should be called to draw the bitmap image.
|
|
|
|
@param bitmap The data to draw
|
|
@param x The x coordinate
|
|
@param y The y coordinate
|
|
@param color The color of the bitmap
|
|
@param w The width of the data image
|
|
@param h The height of the data image
|
|
*/
|
|
virtual void drawBitmap(const uInt32* bitmap, uInt32 x, uInt32 y, ColorId color,
|
|
uInt32 w, uInt32 h);
|
|
|
|
/**
|
|
This method should be called to convert and copy a given row of pixel
|
|
data into a FrameBuffer surface. The pixels must already be in the
|
|
format used by the surface.
|
|
|
|
@param data The data in uInt8 R/G/B format
|
|
@param x The destination x-location to start drawing pixels
|
|
@param y The destination y-location to start drawing pixels
|
|
@param numpixels The number of pixels to draw
|
|
*/
|
|
virtual void drawPixels(const uInt32* data, uInt32 x, uInt32 y, uInt32 numpixels);
|
|
|
|
/**
|
|
This method should be called to draw a rectangular box with sides
|
|
at the specified coordinates.
|
|
|
|
@param x The x coordinate
|
|
@param y The y coordinate
|
|
@param w The width of the box
|
|
@param h The height of the box
|
|
@param colorA Lighter color for outside line.
|
|
@param colorB Darker color for inside line.
|
|
*/
|
|
virtual void box(uInt32 x, uInt32 y, uInt32 w, uInt32 h,
|
|
ColorId colorA, ColorId colorB);
|
|
|
|
/**
|
|
This method should be called to draw a framed rectangle with
|
|
several different possible styles.
|
|
|
|
@param x The x coordinate
|
|
@param y The y coordinate
|
|
@param w The width of the area
|
|
@param h The height of the area
|
|
@param color The color of the surrounding frame
|
|
@param style The 'FrameStyle' to use for the surrounding frame
|
|
*/
|
|
virtual void frameRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h,
|
|
ColorId color, FrameStyle style = FrameStyle::Solid);
|
|
|
|
/**
|
|
This method should be called to draw the specified string.
|
|
|
|
@param font The font to draw the string with
|
|
@param s The string to draw
|
|
@param x The x coordinate
|
|
@param y The y coordinate
|
|
@param w The width of the string area
|
|
@param h The height of the string area (for multi line strings)
|
|
@param color The color of the text
|
|
@param align The alignment of the text in the string width area
|
|
@param deltax FIXME
|
|
@param useEllipsis Whether to use '...' when the string is too long
|
|
@return Number of lines drawn
|
|
*/
|
|
|
|
virtual int drawString(
|
|
const GUI::Font& font, const string& s, int x, int y, int w, int h,
|
|
ColorId color, TextAlign align = TextAlign::Left,
|
|
int deltax = 0, bool useEllipsis = true, ColorId shadowColor = kNone);
|
|
|
|
/**
|
|
This method should be called to draw the specified string.
|
|
|
|
@param font The font to draw the string with
|
|
@param s The string to draw
|
|
@param x The x coordinate
|
|
@param y The y coordinate
|
|
@param w The width of the string area
|
|
@param color The color of the text
|
|
@param align The alignment of the text in the string width area
|
|
@param deltax FIXME
|
|
@param useEllipsis Whether to use '...' when the string is too long
|
|
*/
|
|
virtual void drawString(
|
|
const GUI::Font& font, const string& s, int x, int y, int w,
|
|
ColorId color, TextAlign align = TextAlign::Left,
|
|
int deltax = 0, bool useEllipsis = true, ColorId shadowColor = kNone);
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// Note: The following methods are FBSurface-specific, and must be
|
|
// implemented in child classes.
|
|
//
|
|
// For the following, 'src' indicates the actual data buffer area
|
|
// (non-scaled) and 'dst' indicates the rendered area (possibly scaled).
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
/**
|
|
These methods answer the current *real* dimensions of the specified
|
|
surface.
|
|
*/
|
|
virtual uInt32 width() const = 0;
|
|
virtual uInt32 height() const = 0;
|
|
|
|
/**
|
|
These methods answer the current *rendering* dimensions of the
|
|
specified surface.
|
|
*/
|
|
virtual const Common::Rect& srcRect() const = 0;
|
|
virtual const Common::Rect& dstRect() const = 0;
|
|
|
|
/**
|
|
These methods set the origin point and width/height for the
|
|
specified service. They are defined as separate x/y and w/h
|
|
methods since these items are sometimes set separately.
|
|
*/
|
|
virtual void setSrcPos(uInt32 x, uInt32 y) = 0;
|
|
virtual void setSrcSize(uInt32 w, uInt32 h) = 0;
|
|
virtual void setDstPos(uInt32 x, uInt32 y) = 0;
|
|
virtual void setDstSize(uInt32 w, uInt32 h) = 0;
|
|
|
|
/**
|
|
This method should be called to enable/disable showing the surface
|
|
(ie, if hidden it will not be drawn under any circumstances.
|
|
*/
|
|
virtual void setVisible(bool visible) = 0;
|
|
|
|
/**
|
|
This method should be called to translate the given coordinates
|
|
to the (destination) surface coordinates.
|
|
|
|
@param x X coordinate to translate
|
|
@param y Y coordinate to translate
|
|
*/
|
|
virtual void translateCoords(Int32& x, Int32& y) const = 0;
|
|
|
|
/**
|
|
This method should be called to draw the surface to the screen.
|
|
It will return true if rendering actually occurred.
|
|
*/
|
|
virtual bool render() = 0;
|
|
|
|
/**
|
|
This method should be called to reset the surface to empty
|
|
pixels / colour black.
|
|
*/
|
|
virtual void invalidate() = 0;
|
|
|
|
/**
|
|
This method should be called to free any resources being used by
|
|
the surface.
|
|
*/
|
|
virtual void free() = 0;
|
|
|
|
/**
|
|
This method should be called to reload the surface data/state.
|
|
It will normally be called after free().
|
|
*/
|
|
virtual void reload() = 0;
|
|
|
|
/**
|
|
This method should be called to resize the surface to the
|
|
given dimensions and reload data/state. The surface is not
|
|
modified if it is larger than the given dimensions.
|
|
*/
|
|
virtual void resize(uInt32 width, uInt32 height) = 0;
|
|
|
|
/**
|
|
The rendering attributes that can be modified for this texture.
|
|
These probably can only be implemented in child FBSurfaces where
|
|
the specific functionality actually exists.
|
|
*/
|
|
struct Attributes {
|
|
bool blending{false}; // Blending is enabled
|
|
uInt32 blendalpha{100}; // Alpha to use in blending mode (0-100%)
|
|
|
|
bool operator==(const Attributes& other) const {
|
|
return blendalpha == other.blendalpha && blending == other.blending;
|
|
}
|
|
};
|
|
|
|
/**
|
|
Get the currently applied attributes.
|
|
*/
|
|
Attributes& attributes() { return myAttributes; }
|
|
|
|
/**
|
|
Configure scaling interpolation.
|
|
*/
|
|
virtual void setScalingInterpolation(FrameBuffer::ScalingInterpolation) = 0;
|
|
|
|
/**
|
|
The child class chooses which (if any) of the actual attributes
|
|
can be applied.
|
|
*/
|
|
virtual void applyAttributes() = 0;
|
|
|
|
static void setPalette(const FullPaletteArray& palette) { myPalette = palette; }
|
|
|
|
protected:
|
|
/**
|
|
This method should be called to check if the given coordinates
|
|
are in bounds of the surface.
|
|
|
|
@param x The x coordinate to check
|
|
@param y The y coordinate to check
|
|
@return True if coordinates are in bounds
|
|
*/
|
|
bool checkBounds(const uInt32 x, const uInt32 y) const;
|
|
|
|
void wrapString(const string& inStr, int pos, string& leftStr, string& rightStr) const;
|
|
|
|
/**
|
|
Check if the given character is a whitespace.
|
|
@param s Character to check
|
|
@return True if whitespace character
|
|
*/
|
|
bool isWhiteSpace(const char s) const;
|
|
|
|
protected:
|
|
uInt32* myPixels{nullptr}; // NOTE: MUST be set in child classes
|
|
uInt32 myPitch{0}; // NOTE: MUST be set in child classes
|
|
|
|
Attributes myAttributes;
|
|
|
|
static FullPaletteArray myPalette;
|
|
|
|
private:
|
|
// Following constructors and assignment operators not supported
|
|
FBSurface(const FBSurface&) = delete;
|
|
FBSurface(FBSurface&&) = delete;
|
|
FBSurface& operator=(const FBSurface&) = delete;
|
|
FBSurface& operator=(FBSurface&&) = delete;
|
|
};
|
|
|
|
#endif
|