OpenRCT2/src/openrct2/drawing/Drawing.h

638 lines
22 KiB
C
Raw Normal View History

/*****************************************************************************
* Copyright (c) 2014-2024 OpenRCT2 developers
*
* For a complete list of all authors, please refer to contributors.md
* Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2
*
* OpenRCT2 is licensed under the GNU General Public License version 3.
*****************************************************************************/
2021-08-21 12:55:28 +02:00
#pragma once
2014-10-06 18:36:58 +02:00
#include "../common.h"
#include "../core/String.hpp"
2018-01-06 00:08:58 +01:00
#include "../interface/Colour.h"
#include "../interface/ZoomLevel.h"
2020-08-26 01:59:11 +02:00
#include "../world/Location.hpp"
#include "Font.h"
#include "ImageId.hpp"
#include "Text.h"
2014-04-04 20:59:32 +02:00
#include <memory>
2020-05-27 21:12:01 +02:00
#include <optional>
#include <vector>
struct ScreenCoordsXY;
struct ScreenLine;
struct ScreenRect;
namespace OpenRCT2
{
struct IPlatformEnvironment;
struct IStream;
} // namespace OpenRCT2
namespace OpenRCT2::Drawing
{
struct IDrawingEngine;
}
2020-05-27 21:12:01 +02:00
struct PaletteBGRA
{
uint8_t Blue{};
uint8_t Green{};
uint8_t Red{};
uint8_t Alpha{};
};
constexpr auto PALETTE_SIZE = 256U;
2020-05-27 21:12:01 +02:00
struct GamePalette
{
PaletteBGRA Colour[PALETTE_SIZE]{};
PaletteBGRA& operator[](size_t idx)
2020-05-27 21:12:01 +02:00
{
assert(idx < PALETTE_SIZE);
if (idx >= PALETTE_SIZE)
{
static PaletteBGRA dummy;
return dummy;
}
return Colour[idx];
}
const PaletteBGRA operator[](size_t idx) const
2020-05-27 21:12:01 +02:00
{
assert(idx < PALETTE_SIZE);
if (idx >= PALETTE_SIZE)
return {};
return Colour[idx];
}
explicit operator uint8_t*()
{
return reinterpret_cast<uint8_t*>(Colour);
}
};
struct G1Element
2018-06-22 22:59:03 +02:00
{
uint8_t* offset = nullptr; // 0x00
int16_t width = 0; // 0x04
int16_t height = 0; // 0x06
int16_t x_offset = 0; // 0x08
int16_t y_offset = 0; // 0x0A
uint16_t flags = 0; // 0x0C
int32_t zoomed_offset = 0; // 0x0E
};
#pragma pack(push, 1)
struct RCTG1Header
{
uint32_t num_entries = 0;
uint32_t total_size = 0;
};
assert_struct_size(RCTG1Header, 8);
#pragma pack(pop)
struct Gx
{
RCTG1Header header;
std::vector<G1Element> elements;
std::unique_ptr<uint8_t[]> data;
};
struct DrawPixelInfo
2018-06-22 22:59:03 +02:00
{
uint8_t* bits{};
int32_t x{};
int32_t y{};
int32_t width{};
int32_t height{};
int32_t pitch{}; // note: this is actually (pitch - width)
ZoomLevel zoom_level{};
2020-08-26 19:56:58 +02:00
/**
* As x and y are based on 1:1 units, zooming in will cause a reduction in precision when mapping zoomed-in
* pixels to 1:1 pixels. When x, y are not a multiple of the zoom level, the remainder will be non-zero.
* The drawing of sprites will need to be offset by this amount.
*/
2020-08-22 14:01:11 +02:00
uint8_t remX{};
uint8_t remY{};
// Last position of drawn text.
ScreenCoordsXY lastStringPos{};
OpenRCT2::Drawing::IDrawingEngine* DrawingEngine{};
2020-08-22 14:00:15 +02:00
2020-08-26 01:59:11 +02:00
size_t GetBytesPerRow() const;
uint8_t* GetBitsOffset(const ScreenCoordsXY& pos) const;
DrawPixelInfo Crop(const ScreenCoordsXY& pos, const ScreenSize& size) const;
};
2014-04-04 20:59:32 +02:00
struct TextDrawInfo
{
int32_t startX;
int32_t startY;
int32_t x;
int32_t y;
int32_t maxX;
int32_t maxY;
int32_t flags;
uint8_t palette[8];
::FontStyle FontStyle;
const int8_t* y_offset;
};
enum : uint32_t
{
TEXT_DRAW_FLAG_INSET = 1 << 0,
TEXT_DRAW_FLAG_OUTLINE = 1 << 1,
TEXT_DRAW_FLAG_DARK = 1 << 2,
TEXT_DRAW_FLAG_EXTRA_DARK = 1 << 3,
TEXT_DRAW_FLAG_NO_FORMATTING = 1 << 28,
TEXT_DRAW_FLAG_Y_OFFSET_EFFECT = 1 << 29,
TEXT_DRAW_FLAG_TTF = 1 << 30,
TEXT_DRAW_FLAG_NO_DRAW = 1u << 31
};
struct RCTG1Element
2018-06-22 22:59:03 +02:00
{
uint32_t offset; // 0x00 note: uint32_t always!
int16_t width; // 0x04
int16_t height; // 0x06
int16_t x_offset; // 0x08
int16_t y_offset; // 0x0A
uint16_t flags; // 0x0C
uint16_t zoomed_offset; // 0x0E
};
assert_struct_size(RCTG1Element, 0x10);
2018-06-22 22:59:03 +02:00
enum
{
G1_FLAG_HAS_TRANSPARENCY = (1 << 0), // Image data contains transparent pixels (0XFF) which will not be rendered
2018-06-22 22:59:03 +02:00
G1_FLAG_1 = (1 << 1),
G1_FLAG_RLE_COMPRESSION = (1 << 2), // Image data is encoded using RCT2's form of run length encoding
2018-06-22 22:59:03 +02:00
G1_FLAG_PALETTE = (1 << 3), // Image data is a sequence of palette entries R8G8B8
G1_FLAG_HAS_ZOOM_SPRITE = (1 << 4), // Use a different sprite for higher zoom levels
2018-06-22 22:59:03 +02:00
G1_FLAG_NO_ZOOM_DRAW = (1 << 5), // Does not get drawn at higher zoom levels (only zoom 0)
};
using DrawBlendOp = uint8_t;
constexpr DrawBlendOp BLEND_NONE = 0;
/**
* Only supported by BITMAP. RLE images always encode transparency via the encoding.
* Pixel value of 0 represents transparent.
*/
constexpr DrawBlendOp BLEND_TRANSPARENT = 1 << 0;
/**
* Whether to use the pixel value from the source image.
* This is usually only unset for glass images where there the src is only a transparency mask.
*/
constexpr DrawBlendOp BLEND_SRC = 1 << 1;
/**
* Whether to use the pixel value of the destination image for blending.
* This is used for any image that filters the target image, e.g. glass or water.
*/
constexpr DrawBlendOp BLEND_DST = 2 << 2;
2018-06-22 22:59:03 +02:00
enum
{
INSET_RECT_FLAG_FILL_GREY = (1 << 2), // 0x04
INSET_RECT_FLAG_BORDER_NONE = (1 << 3), // 0x08
INSET_RECT_FLAG_FILL_NONE = (1 << 4), // 0x10
INSET_RECT_FLAG_BORDER_INSET = (1 << 5), // 0x20
INSET_RECT_FLAG_FILL_DONT_LIGHTEN = (1 << 6), // 0x40
2018-06-22 22:59:03 +02:00
INSET_RECT_FLAG_FILL_MID_LIGHT = (1 << 7), // 0x80
2016-11-10 18:54:33 +01:00
};
enum class FilterPaletteID : int32_t
2018-06-22 22:59:03 +02:00
{
PaletteNull = 0,
Extend color selection dropdown with more colors (#19446) * Setup for extended palette * Define order for color picker cells * Init G2 Palettes in ColoursInitMaps * Add Glass Palettes * Use special sprite for Invisible color * Set up new cheat for special colors * Add glass palettes to palette_to_g1_offset * Add entries for new colors in TranslucentWindowPalettes * Finish implementation of special colors cheat * Some cleanup * New colors almost work * Correct g2 palette loading indices * Invisible color sprite displays properly * Repaint works with large scenery and walls * Prevent random shop items from overflowing to junk palettes * More cleanup * Fix glass palettes * Add mapping of new colors to original colors for UI themes * Fix junk palettes for random shop items * Fix missing highlight color in software renderer * Convert small scenery support flag to allow use of new colors * Progress on displaying new colors in software renderer * Fix invisible color scheme sprite * Formatting cleanup * Resolve comparison of integer expressions of different signedness * Index g2 palette maps to fix visible chain lift * Progress on fixing new colors in software renderer * Fix station and support colors * Fix dropdown selected index * Get invisible color (mostly) working in software renderer * Use forceBmp for palette resources * Remove test function definition left in by mistake * Remove some obsolete range checks for original color values * Add changelog entry * Reorder color dropdown based on NE user feedback * Some cleanup * Further cleanup * Formatting * Add include for GetPaletteMapIndexForColour * Fix a couple things I broke * Fix function placement * Revert "Add include for GetPaletteMapIndexForColour" This reverts commit 0af9611e6656d792adb7a36efe7dbf3387a4a759. * Use color constants for color order list * Make remappable colors contiguous * turn off clang format for ordered color list * Appease clang * Use all colors for random shop item animation * Improvements to palette map resources * Fix chain lifts again + adjustments to a few colors * Update changelog and contributors.md * Revert changes to S4 and S6 importers which are no longer needed * Bump network, plugin, and minimum park versions * Revert "Progress on displaying new colors in software renderer" This reverts commit 337602e4a78a67f828d9c524138a1cb79b2c91dc. * Remove unnecessary comment --------- Co-authored-by: Trevor Finney <8711258+finneyt@users.noreply.github.com>
2023-04-06 09:36:07 +02:00
PaletteWater = COLOUR_COUNT,
2023-04-09 22:29:35 +02:00
PaletteLandMarker0, // North (corner/edge)
PaletteLandMarker1, // East (corner/edge)
PaletteLandMarker2, // South (corner/edge)
PaletteLandMarker3, // West (corner/edge)
PaletteSceneryGroundMarker,
PaletteWaterMarker,
2023-04-09 22:29:35 +02:00
PaletteQuarterMarker0, // North (not sure why it couldn't just use PaletteLandMarker0)
PaletteQuarterMarker1, // East
PaletteQuarterMarker2, // South
PaletteQuarterMarker3, // West
PaletteRideGroundMarker,
PaletteGhost, // Construction marker
Palette45, // Decolourise + lighten
Extend color selection dropdown with more colors (#19446) * Setup for extended palette * Define order for color picker cells * Init G2 Palettes in ColoursInitMaps * Add Glass Palettes * Use special sprite for Invisible color * Set up new cheat for special colors * Add glass palettes to palette_to_g1_offset * Add entries for new colors in TranslucentWindowPalettes * Finish implementation of special colors cheat * Some cleanup * New colors almost work * Correct g2 palette loading indices * Invisible color sprite displays properly * Repaint works with large scenery and walls * Prevent random shop items from overflowing to junk palettes * More cleanup * Fix glass palettes * Add mapping of new colors to original colors for UI themes * Fix junk palettes for random shop items * Fix missing highlight color in software renderer * Convert small scenery support flag to allow use of new colors * Progress on displaying new colors in software renderer * Fix invisible color scheme sprite * Formatting cleanup * Resolve comparison of integer expressions of different signedness * Index g2 palette maps to fix visible chain lift * Progress on fixing new colors in software renderer * Fix station and support colors * Fix dropdown selected index * Get invisible color (mostly) working in software renderer * Use forceBmp for palette resources * Remove test function definition left in by mistake * Remove some obsolete range checks for original color values * Add changelog entry * Reorder color dropdown based on NE user feedback * Some cleanup * Further cleanup * Formatting * Add include for GetPaletteMapIndexForColour * Fix a couple things I broke * Fix function placement * Revert "Add include for GetPaletteMapIndexForColour" This reverts commit 0af9611e6656d792adb7a36efe7dbf3387a4a759. * Use color constants for color order list * Make remappable colors contiguous * turn off clang format for ordered color list * Appease clang * Use all colors for random shop item animation * Improvements to palette map resources * Fix chain lifts again + adjustments to a few colors * Update changelog and contributors.md * Revert changes to S4 and S6 importers which are no longer needed * Bump network, plugin, and minimum park versions * Revert "Progress on displaying new colors in software renderer" This reverts commit 337602e4a78a67f828d9c524138a1cb79b2c91dc. * Remove unnecessary comment --------- Co-authored-by: Trevor Finney <8711258+finneyt@users.noreply.github.com>
2023-04-06 09:36:07 +02:00
Palette46,
PaletteDarken3,
PaletteDarken1 = PaletteDarken3 + 2,
PaletteDarken2,
Palette51, // Decolourise + darken
PaletteTranslucentGrey,
PaletteTranslucentGreyHighlight,
PaletteTranslucentGreyShadow,
PaletteTranslucentLightBlue,
PaletteTranslucentLightBlueHighlight,
PaletteTranslucentLightBlueShadow,
PaletteTranslucentBordeauxRed,
PaletteTranslucentBordeauxRedHighlight,
PaletteTranslucentBordeauxRedShadow,
PaletteTranslucentDarkGreen,
PaletteTranslucentDarkGreenHighlight,
PaletteTranslucentDarkGreenShadow,
PaletteTranslucentLightPurple,
PaletteTranslucentLightPurpleHighlight,
PaletteTranslucentLightPurpleShadow,
PaletteTranslucentDarkOliveGreen,
PaletteTranslucentDarkOliveGreenHighlight,
PaletteTranslucentDarkOliveGreenShadow,
PaletteTranslucentLightBrown,
PaletteTranslucentLightBrownHighlight,
PaletteTranslucentLightBrownShadow,
PaletteTranslucentYellow,
PaletteTranslucentYellowHighlight,
PaletteTranslucentYellowShadow,
PaletteTranslucentMossGreen,
PaletteTranslucentMossGreenHighlight,
PaletteTranslucentMossGreenShadow,
PaletteTranslucentOliveGreen,
PaletteTranslucentOliveGreenHighlight,
PaletteTranslucentOliveGreenShadow,
PaletteTranslucentBrightGreen,
PaletteTranslucentBrightGreenHighlight,
PaletteTranslucentBrightGreenShadow,
PaletteTranslucentSalmonPink,
PaletteTranslucentSalmonPinkHighlight,
PaletteTranslucentSalmonPinkShadow,
PaletteTranslucentBrightPurple,
PaletteTranslucentBrightPurpleHighlight,
PaletteTranslucentBrightPurpleShadow,
PaletteTranslucentBrightRed,
PaletteTranslucentBrightRedHighlight,
PaletteTranslucentBrightRedShadow,
PaletteTranslucentLightOrange,
PaletteTranslucentLightOrangeHighlight,
PaletteTranslucentLightOrangeShadow,
PaletteTranslucentTeal,
PaletteTranslucentTealHighlight,
PaletteTranslucentTealShadow,
PaletteTranslucentBrightPink,
PaletteTranslucentBrightPinkHighlight,
PaletteTranslucentBrightPinkShadow,
PaletteTranslucentDarkBrown,
PaletteTranslucentDarkBrownHighlight,
PaletteTranslucentDarkBrownShadow,
PaletteTranslucentLightPink,
PaletteTranslucentLightPinkHighlight,
PaletteTranslucentLightPinkShadow,
PaletteTranslucentWhite,
PaletteTranslucentWhiteHighlight,
PaletteTranslucentWhiteShadow,
PaletteGlass,
PaletteGlassBlack = PaletteGlass + COLOUR_BLACK,
PaletteGlassGrey = PaletteGlass + COLOUR_GREY,
PaletteGlassWhite = PaletteGlass + COLOUR_WHITE,
PaletteGlassDarkPurple = PaletteGlass + COLOUR_DARK_PURPLE,
PaletteGlassLightPurple = PaletteGlass + COLOUR_LIGHT_PURPLE,
PaletteGlassBrightPurple = PaletteGlass + COLOUR_BRIGHT_PURPLE,
PaletteGlassDarkBlue = PaletteGlass + COLOUR_DARK_BLUE,
PaletteGlassLightBlue = PaletteGlass + COLOUR_LIGHT_BLUE,
PaletteGlassIcyBlue = PaletteGlass + COLOUR_ICY_BLUE,
PaletteGlassTeal = PaletteGlass + COLOUR_TEAL,
PaletteGlassAquamarine = PaletteGlass + COLOUR_AQUAMARINE,
PaletteGlassSaturatedGreen = PaletteGlass + COLOUR_SATURATED_GREEN,
PaletteGlassDarkGreen = PaletteGlass + COLOUR_DARK_GREEN,
PaletteGlassMossGreen = PaletteGlass + COLOUR_MOSS_GREEN,
PaletteGlassBrightGreen = PaletteGlass + COLOUR_BRIGHT_GREEN,
PaletteGlassOliveGreen = PaletteGlass + COLOUR_OLIVE_GREEN,
PaletteGlassDarkOliveGreen = PaletteGlass + COLOUR_DARK_OLIVE_GREEN,
PaletteGlassBrightYellow = PaletteGlass + COLOUR_BRIGHT_YELLOW,
PaletteGlassYellow = PaletteGlass + COLOUR_YELLOW,
PaletteGlassDarkYellow = PaletteGlass + COLOUR_DARK_YELLOW,
PaletteGlassLightOrange = PaletteGlass + COLOUR_LIGHT_ORANGE,
PaletteGlassDarkOrange = PaletteGlass + COLOUR_DARK_ORANGE,
PaletteGlassLightBrown = PaletteGlass + COLOUR_LIGHT_BROWN,
PaletteGlassSaturatedBrown = PaletteGlass + COLOUR_SATURATED_BROWN,
PaletteGlassDarkBrown = PaletteGlass + COLOUR_DARK_BROWN,
PaletteGlassSalmonPink = PaletteGlass + COLOUR_SALMON_PINK,
PaletteGlassBordeauxRed = PaletteGlass + COLOUR_BORDEAUX_RED,
PaletteGlassSaturatedRed = PaletteGlass + COLOUR_SATURATED_RED,
PaletteGlassBrightRed = PaletteGlass + COLOUR_BRIGHT_RED,
PaletteGlassDarkPink = PaletteGlass + COLOUR_DARK_PINK,
PaletteGlassBrightPink = PaletteGlass + COLOUR_BRIGHT_PINK,
PaletteGlassLightPink = PaletteGlass + COLOUR_LIGHT_PINK,
Extend color selection dropdown with more colors (#19446) * Setup for extended palette * Define order for color picker cells * Init G2 Palettes in ColoursInitMaps * Add Glass Palettes * Use special sprite for Invisible color * Set up new cheat for special colors * Add glass palettes to palette_to_g1_offset * Add entries for new colors in TranslucentWindowPalettes * Finish implementation of special colors cheat * Some cleanup * New colors almost work * Correct g2 palette loading indices * Invisible color sprite displays properly * Repaint works with large scenery and walls * Prevent random shop items from overflowing to junk palettes * More cleanup * Fix glass palettes * Add mapping of new colors to original colors for UI themes * Fix junk palettes for random shop items * Fix missing highlight color in software renderer * Convert small scenery support flag to allow use of new colors * Progress on displaying new colors in software renderer * Fix invisible color scheme sprite * Formatting cleanup * Resolve comparison of integer expressions of different signedness * Index g2 palette maps to fix visible chain lift * Progress on fixing new colors in software renderer * Fix station and support colors * Fix dropdown selected index * Get invisible color (mostly) working in software renderer * Use forceBmp for palette resources * Remove test function definition left in by mistake * Remove some obsolete range checks for original color values * Add changelog entry * Reorder color dropdown based on NE user feedback * Some cleanup * Further cleanup * Formatting * Add include for GetPaletteMapIndexForColour * Fix a couple things I broke * Fix function placement * Revert "Add include for GetPaletteMapIndexForColour" This reverts commit 0af9611e6656d792adb7a36efe7dbf3387a4a759. * Use color constants for color order list * Make remappable colors contiguous * turn off clang format for ordered color list * Appease clang * Use all colors for random shop item animation * Improvements to palette map resources * Fix chain lifts again + adjustments to a few colors * Update changelog and contributors.md * Revert changes to S4 and S6 importers which are no longer needed * Bump network, plugin, and minimum park versions * Revert "Progress on displaying new colors in software renderer" This reverts commit 337602e4a78a67f828d9c524138a1cb79b2c91dc. * Remove unnecessary comment --------- Co-authored-by: Trevor Finney <8711258+finneyt@users.noreply.github.com>
2023-04-06 09:36:07 +02:00
PaletteGlassDarkOliveDark = PaletteGlass + COLOUR_DARK_OLIVE_DARK,
PaletteGlassDarkOliveLight = PaletteGlass + COLOUR_DARK_OLIVE_LIGHT,
PaletteGlassSaturatedBrownLight = PaletteGlass + COLOUR_SATURATED_BROWN_LIGHT,
PaletteGlassBordeauxRedDark = PaletteGlass + COLOUR_BORDEAUX_RED_DARK,
PaletteGlassBordeauxRedLight = PaletteGlass + COLOUR_BORDEAUX_RED_LIGHT,
PaletteGlassGrassGreenDark = PaletteGlass + COLOUR_GRASS_GREEN_DARK,
PaletteGlassGrassGreenLight = PaletteGlass + COLOUR_GRASS_GREEN_LIGHT,
PaletteGlassOliveDark = PaletteGlass + COLOUR_OLIVE_DARK,
PaletteGlassOliveLight = PaletteGlass + COLOUR_OLIVE_LIGHT,
PaletteGlassSaturatedGreenLight = PaletteGlass + COLOUR_SATURATED_GREEN_LIGHT,
PaletteGlassTanDark = PaletteGlass + COLOUR_TAN_DARK,
PaletteGlassTanLight = PaletteGlass + COLOUR_TAN_LIGHT,
PaletteGlassDullPurpleLight = PaletteGlass + COLOUR_DULL_PURPLE_LIGHT,
PaletteGlassDullGreenDark = PaletteGlass + COLOUR_DULL_GREEN_DARK,
PaletteGlassDullGreenLight = PaletteGlass + COLOUR_DULL_GREEN_LIGHT,
PaletteGlassSaturatedPurpleDark = PaletteGlass + COLOUR_SATURATED_PURPLE_DARK,
PaletteGlassSaturatedPurpleLight = PaletteGlass + COLOUR_SATURATED_PURPLE_LIGHT,
PaletteGlassOrangeLight = PaletteGlass + COLOUR_ORANGE_LIGHT,
PaletteGlassAquaDark = PaletteGlass + COLOUR_AQUA_DARK,
PaletteGlassMagentaLight = PaletteGlass + COLOUR_MAGENTA_LIGHT,
PaletteGlassDullBrownDark = PaletteGlass + COLOUR_DULL_BROWN_DARK,
PaletteGlassDullBrownLight = PaletteGlass + COLOUR_DULL_BROWN_LIGHT,
PaletteGlassInvisible = PaletteGlass + COLOUR_INVISIBLE,
PaletteGlassVoid = PaletteGlass + COLOUR_VOID,
};
2016-11-09 21:44:25 +01:00
struct TranslucentWindowPalette
2018-06-22 22:59:03 +02:00
{
FilterPaletteID base;
FilterPaletteID highlight;
FilterPaletteID shadow;
};
2016-11-10 13:20:47 +01:00
/**
* Represents an 8-bit indexed map that maps from one palette index to another.
*/
struct PaletteMap
{
private:
uint8_t* _data{};
uint32_t _dataLength{};
2020-05-30 15:23:48 +02:00
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-private-field"
uint16_t _numMaps;
2020-05-30 15:23:48 +02:00
#pragma clang diagnostic pop
uint16_t _mapLength;
public:
static const PaletteMap& GetDefault();
PaletteMap() = default;
PaletteMap(uint8_t* data, uint16_t numMaps, uint16_t mapLength)
: _data(data)
, _dataLength(numMaps * mapLength)
, _numMaps(numMaps)
, _mapLength(mapLength)
{
}
template<std::size_t TSize>
PaletteMap(uint8_t (&map)[TSize])
: _data(map)
, _dataLength(static_cast<uint32_t>(std::size(map)))
, _numMaps(1)
, _mapLength(static_cast<uint16_t>(std::size(map)))
{
}
uint8_t& operator[](size_t index);
uint8_t operator[](size_t index) const;
uint8_t Blend(uint8_t src, uint8_t dst) const;
void Copy(size_t dstIndex, const PaletteMap& src, size_t srcIndex, size_t length);
};
struct DrawSpriteArgs
{
ImageId Image;
const PaletteMap& PalMap;
const G1Element& SourceImage;
2020-05-31 15:46:23 +02:00
int32_t SrcX;
int32_t SrcY;
int32_t Width;
int32_t Height;
uint8_t* DestinationBits;
DrawSpriteArgs(
ImageId image, const PaletteMap& palMap, const G1Element& sourceImage, int32_t srcX, int32_t srcY, int32_t width,
int32_t height, uint8_t* destinationBits)
: Image(image)
, PalMap(palMap)
, SourceImage(sourceImage)
2020-05-31 15:46:23 +02:00
, SrcX(srcX)
, SrcY(srcY)
, Width(width)
, Height(height)
, DestinationBits(destinationBits)
{
}
};
2020-06-03 02:49:42 +02:00
template<DrawBlendOp TBlendOp> bool FASTCALL BlitPixel(const uint8_t* src, uint8_t* dst, const PaletteMap& paletteMap)
{
if constexpr (TBlendOp & BLEND_TRANSPARENT)
{
// Ignore transparent pixels
if (*src == 0)
{
return false;
}
}
if constexpr (((TBlendOp & BLEND_SRC) != 0) && ((TBlendOp & BLEND_DST) != 0))
{
auto pixel = paletteMap.Blend(*src, *dst);
if constexpr (TBlendOp & BLEND_TRANSPARENT)
{
if (pixel == 0)
{
return false;
}
}
*dst = pixel;
return true;
}
else if constexpr ((TBlendOp & BLEND_SRC) != 0)
{
auto pixel = paletteMap[*src];
if constexpr (TBlendOp & BLEND_TRANSPARENT)
{
if (pixel == 0)
{
return false;
}
}
*dst = pixel;
return true;
}
else if constexpr ((TBlendOp & BLEND_DST) != 0)
{
auto pixel = paletteMap[*dst];
if constexpr (TBlendOp & BLEND_TRANSPARENT)
{
if (pixel == 0)
{
return false;
}
}
*dst = pixel;
return true;
}
else
{
*dst = *src;
return true;
}
}
template<DrawBlendOp TBlendOp>
void FASTCALL BlitPixels(const uint8_t* src, uint8_t* dst, const PaletteMap& paletteMap, uint8_t zoom, size_t dstPitch)
{
auto yDstSkip = dstPitch - zoom;
for (uint8_t yy = 0; yy < zoom; yy++)
{
for (uint8_t xx = 0; xx < zoom; xx++)
{
BlitPixel<TBlendOp>(src, dst, paletteMap);
dst++;
}
dst += yDstSkip;
}
}
constexpr uint8_t kPaletteTotalOffsets = 192;
2016-11-10 18:54:33 +01:00
#define INSET_RECT_F_30 (INSET_RECT_FLAG_BORDER_INSET | INSET_RECT_FLAG_FILL_NONE)
#define INSET_RECT_F_60 (INSET_RECT_FLAG_BORDER_INSET | INSET_RECT_FLAG_FILL_DONT_LIGHTEN)
#define INSET_RECT_F_E0 (INSET_RECT_FLAG_BORDER_INSET | INSET_RECT_FLAG_FILL_DONT_LIGHTEN | INSET_RECT_FLAG_FILL_MID_LIGHT)
#define MAX_SCROLLING_TEXT_MODES 38
2020-05-27 21:12:01 +02:00
extern GamePalette gPalette;
extern uint8_t gGamePalette[256 * 4];
extern uint32_t gPaletteEffectFrame;
extern const FilterPaletteID GlassPaletteIds[COLOUR_COUNT];
extern thread_local uint8_t gPeepPalette[256];
extern thread_local uint8_t gOtherPalette[256];
extern uint8_t gTextPalette[];
extern const TranslucentWindowPalette TranslucentWindowPalettes[COLOUR_COUNT];
2014-10-06 18:36:58 +02:00
2021-11-30 01:13:45 +01:00
extern ImageId gPickupPeepImage;
extern int32_t gPickupPeepX;
extern int32_t gPickupPeepY;
2016-04-24 11:28:08 +02:00
2017-10-01 02:18:31 +02:00
extern bool gTinyFontAntiAliased;
2023-04-03 23:29:06 +02:00
bool ClipDrawPixelInfo(DrawPixelInfo& dst, DrawPixelInfo& src, const ScreenCoordsXY& coords, int32_t width, int32_t height);
void GfxSetDirtyBlocks(const ScreenRect& rect);
void GfxInvalidateScreen();
2014-04-04 20:59:32 +02:00
2014-10-06 18:36:58 +02:00
// palette
void GfxTransposePalette(int32_t pal, uint8_t product);
void LoadPalette();
2014-10-06 18:36:58 +02:00
// other
void GfxClear(DrawPixelInfo& dpi, uint8_t paletteIndex);
2023-04-03 23:29:06 +02:00
void GfxFilterPixel(DrawPixelInfo& dpi, const ScreenCoordsXY& coords, FilterPaletteID palette);
void GfxInvalidatePickedUpPeep();
2023-04-03 23:29:06 +02:00
void GfxDrawPickedUpPeep(DrawPixelInfo& dpi);
2014-10-06 18:36:58 +02:00
// line
void GfxDrawLine(DrawPixelInfo& dpi, const ScreenLine& line, int32_t colour);
void GfxDrawLineSoftware(DrawPixelInfo& dpi, const ScreenLine& line, int32_t colour);
void GfxDrawDashedLine(
DrawPixelInfo& dpi, const ScreenLine& screenLine, const int32_t dashedLineSegmentLength, const int32_t color);
2014-10-06 18:36:58 +02:00
// rect
void GfxFillRect(DrawPixelInfo& dpi, const ScreenRect& rect, int32_t colour);
void GfxFillRectInset(DrawPixelInfo& dpi, const ScreenRect& rect, int32_t colour, uint8_t flags);
void GfxFilterRect(DrawPixelInfo& dpi, const ScreenRect& rect, FilterPaletteID palette);
2014-10-06 18:36:58 +02:00
// sprite
bool GfxLoadG1(const OpenRCT2::IPlatformEnvironment& env);
bool GfxLoadG2();
bool GfxLoadCsg();
void GfxUnloadG1();
void GfxUnloadG2();
void GfxUnloadCsg();
const G1Element* GfxGetG1Element(const ImageId imageId);
const G1Element* GfxGetG1Element(ImageIndex image_id);
void GfxSetG1Element(ImageIndex imageId, const G1Element* g1);
std::optional<Gx> GfxLoadGx(const std::vector<uint8_t>& buffer);
bool IsCsgLoaded();
void FASTCALL GfxSpriteToBuffer(DrawPixelInfo& dpi, const DrawSpriteArgs& args);
void FASTCALL GfxBmpSpriteToBuffer(DrawPixelInfo& dpi, const DrawSpriteArgs& args);
void FASTCALL GfxRleSpriteToBuffer(DrawPixelInfo& dpi, const DrawSpriteArgs& args);
2023-04-03 20:38:28 +02:00
void FASTCALL GfxDrawSprite(DrawPixelInfo& dpi, const ImageId image_id, const ScreenCoordsXY& coords);
void FASTCALL GfxDrawGlyph(DrawPixelInfo& dpi, const ImageId image, const ScreenCoordsXY& coords, const PaletteMap& paletteMap);
void FASTCALL GfxDrawSpriteSolid(DrawPixelInfo& dpi, const ImageId image, const ScreenCoordsXY& coords, uint8_t colour);
void FASTCALL GfxDrawSpriteRawMasked(
DrawPixelInfo& dpi, const ScreenCoordsXY& coords, const ImageId maskImage, const ImageId colourImage);
void FASTCALL GfxDrawSpriteSoftware(DrawPixelInfo& dpi, const ImageId imageId, const ScreenCoordsXY& spriteCoords);
void FASTCALL GfxDrawSpritePaletteSetSoftware(
DrawPixelInfo& dpi, const ImageId imageId, const ScreenCoordsXY& coords, const PaletteMap& paletteMap);
void FASTCALL GfxDrawSpriteRawMaskedSoftware(
DrawPixelInfo& dpi, const ScreenCoordsXY& scrCoords, const ImageId maskImage, const ImageId colourImage);
2014-10-06 18:36:58 +02:00
// string
2023-02-24 22:05:07 +01:00
void GfxDrawString(DrawPixelInfo& dpi, const ScreenCoordsXY& coords, const_utf8string buffer, TextPaint textPaint = {});
2023-02-24 22:05:07 +01:00
void GfxDrawStringLeftCentred(DrawPixelInfo& dpi, StringId format, void* args, colour_t colour, const ScreenCoordsXY& coords);
void DrawStringCentredRaw(
2023-02-24 22:05:07 +01:00
DrawPixelInfo& dpi, const ScreenCoordsXY& coords, int32_t numLines, const utf8* text, FontStyle fontStyle);
void DrawNewsTicker(
2023-02-24 22:05:07 +01:00
DrawPixelInfo& dpi, const ScreenCoordsXY& coords, int32_t width, colour_t colour, StringId format, u8string_view args,
2018-06-22 22:59:03 +02:00
int32_t ticks);
void GfxDrawStringWithYOffsets(
2023-02-24 22:05:07 +01:00
DrawPixelInfo& dpi, const utf8* text, int32_t colour, const ScreenCoordsXY& coords, const int8_t* yOffsets,
bool forceSpriteFont, FontStyle fontStyle);
int32_t GfxWrapString(u8string_view text, int32_t width, FontStyle fontStyle, u8string* outWrappedText, int32_t* outNumLines);
int32_t GfxGetStringWidth(std::string_view text, FontStyle fontStyle);
int32_t GfxGetStringWidthNewLined(std::string_view text, FontStyle fontStyle);
int32_t GfxGetStringWidthNoFormatting(std::string_view text, FontStyle fontStyle);
int32_t StringGetHeightRaw(std::string_view text, FontStyle fontStyle);
int32_t GfxClipString(char* buffer, int32_t width, FontStyle fontStyle);
2023-08-10 13:39:38 +02:00
u8string ShortenPath(const u8string& path, int32_t availableWidth, FontStyle fontStyle);
void TTFDrawString(
2023-02-24 22:05:07 +01:00
DrawPixelInfo& dpi, const_utf8string text, int32_t colour, const ScreenCoordsXY& coords, bool noFormatting,
FontStyle fontStyle, TextDarkness darkness);
2015-07-26 01:55:17 +02:00
2015-07-29 03:03:34 +02:00
// scrolling text
void ScrollingTextInitialiseBitmaps();
void ScrollingTextInvalidate();
class Formatter;
ImageId ScrollingTextSetup(
struct PaintSession& session, StringId stringId, Formatter& ft, uint16_t scroll, uint16_t scrollingMode, colour_t colour);
2015-07-29 03:03:34 +02:00
size_t G1CalculateDataSize(const G1Element* g1);
2018-06-22 22:59:03 +02:00
void MaskScalar(
int32_t width, int32_t height, const uint8_t* RESTRICT maskSrc, const uint8_t* RESTRICT colourSrc, uint8_t* RESTRICT dst,
int32_t maskWrap, int32_t colourWrap, int32_t dstWrap);
void MaskSse4_1(
int32_t width, int32_t height, const uint8_t* RESTRICT maskSrc, const uint8_t* RESTRICT colourSrc, uint8_t* RESTRICT dst,
int32_t maskWrap, int32_t colourWrap, int32_t dstWrap);
void MaskAvx2(
int32_t width, int32_t height, const uint8_t* RESTRICT maskSrc, const uint8_t* RESTRICT colourSrc, uint8_t* RESTRICT dst,
int32_t maskWrap, int32_t colourWrap, int32_t dstWrap);
void MaskFn(
int32_t width, int32_t height, const uint8_t* RESTRICT maskSrc, const uint8_t* RESTRICT colourSrc, uint8_t* RESTRICT dst,
int32_t maskWrap, int32_t colourWrap, int32_t dstWrap);
std::optional<uint32_t> GetPaletteG1Index(colour_t paletteId);
std::optional<PaletteMap> GetPaletteMapForColour(colour_t paletteId);
void UpdatePalette(const uint8_t* colours, int32_t start_index, int32_t num_colours);
void RefreshVideo(bool recreateWindow);
void ToggleWindowedMode();
#include "NewDrawing.h"