mirror of
https://github.com/CorsixTH/CorsixTH.git
synced 2025-07-23 04:13:01 +02:00
Use version 20 which is the current latest. Fix bug clang-tidy found if reading the save file fails. Format code per clang-format-20 I surpressed all new warnings in clang-tidy but we will probably want to enable and fix some of them. run-clang-tidy is used instead of calling clang-tidy directly in order to automatically pull all source files.
738 lines
22 KiB
C++
738 lines
22 KiB
C++
/*
|
|
Copyright (c) 2009-2013 Peter "Corsix" Cawley and Edvin "Lego3" Linge
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
this software and associated documentation files (the "Software"), to deal in
|
|
the Software without restriction, including without limitation the rights to
|
|
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
of the Software, and to permit persons to whom the Software is furnished to do
|
|
so, subject to the following conditions:
|
|
|
|
The above copyright notice and this permission notice shall be included in all
|
|
copies or substantial portions of the Software.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
SOFTWARE.
|
|
*/
|
|
|
|
#ifndef CORSIX_TH_TH_GFX_SDL_H_
|
|
#define CORSIX_TH_TH_GFX_SDL_H_
|
|
|
|
#include "config.h"
|
|
|
|
#include <SDL.h>
|
|
|
|
#include <memory>
|
|
#include <stack>
|
|
#include <stdexcept>
|
|
#include <vector>
|
|
|
|
#include "th_gfx_common.h"
|
|
|
|
class cursor;
|
|
class line_sequence;
|
|
class lua_persist_reader;
|
|
class lua_persist_writer;
|
|
|
|
struct clip_rect : public SDL_Rect {
|
|
typedef Sint16 x_y_type;
|
|
typedef Uint16 w_h_type;
|
|
};
|
|
|
|
struct render_target_creation_params;
|
|
|
|
enum class scaled_items;
|
|
|
|
//! 32bpp ARGB colour. See #palette::pack_argb
|
|
typedef uint32_t argb_colour;
|
|
|
|
//! 8bpp palette class.
|
|
class palette {
|
|
public: // External API
|
|
palette();
|
|
|
|
//! Load palette from the supplied data.
|
|
/*!
|
|
Note that the data uses palette entries of 6 bit colours.
|
|
@param pData Data loaded from the file.
|
|
@param iDataLength Size of the data.
|
|
@return Whether loading of the palette succeeded.
|
|
*/
|
|
bool load_from_th_file(const uint8_t* pData, size_t iDataLength);
|
|
|
|
//! Set an entry of the palette.
|
|
/*!
|
|
The RGB colour (255, 0, 255) is used as the transparent colour.
|
|
@param iEntry Entry number to change.
|
|
@param iR Amount of red in the new entry.
|
|
@param iG Amount of green in the new entry.
|
|
@param iB Amount of blue in the new entry.
|
|
@return Setting the entry succeeded.
|
|
*/
|
|
bool set_entry(int iEntry, uint8_t iR, uint8_t iG, uint8_t iB);
|
|
|
|
public: // Internal (this rendering engine only) API
|
|
//! Convert A, R, G, B values to a 32bpp colour.
|
|
/*!
|
|
@param iA Amount of opacity (0-255).
|
|
@param iR Amount of red (0-255).
|
|
@param iG Amount of green (0-255).
|
|
@param iB Amount of blue (0-255).
|
|
@return 32bpp value representing the provided colour values.
|
|
*/
|
|
static constexpr argb_colour pack_argb(uint8_t iA, uint8_t iR, uint8_t iG,
|
|
uint8_t iB) {
|
|
return (static_cast<argb_colour>(iR) << 0) |
|
|
(static_cast<argb_colour>(iG) << 8) |
|
|
(static_cast<argb_colour>(iB) << 16) |
|
|
(static_cast<argb_colour>(iA) << 24);
|
|
}
|
|
|
|
//! Get the red component of a colour.
|
|
/*!
|
|
@param iColour Colour to examine.
|
|
@return The red component intensity of the colour.
|
|
*/
|
|
static constexpr uint8_t get_red(argb_colour iColour) {
|
|
return static_cast<uint8_t>((iColour >> 0) & 0xFF);
|
|
}
|
|
|
|
//! Get the green component of a colour.
|
|
/*!
|
|
@param iColour Colour to examine.
|
|
@return The green component intensity of the colour.
|
|
*/
|
|
static constexpr uint8_t get_green(argb_colour iColour) {
|
|
return static_cast<uint8_t>((iColour >> 8) & 0xFF);
|
|
}
|
|
|
|
//! Get the blue component of a colour.
|
|
/*!
|
|
@param iColour Colour to examine.
|
|
@return The blue component intensity of the colour.
|
|
*/
|
|
static constexpr uint8_t get_blue(argb_colour iColour) {
|
|
return static_cast<uint8_t>((iColour >> 16) & 0xFF);
|
|
}
|
|
|
|
//! Get the opacity component of a colour.
|
|
/*!
|
|
@param iColour Colour to examine.
|
|
@return The opacity of the colour.
|
|
*/
|
|
static constexpr uint8_t get_alpha(argb_colour iColour) {
|
|
return static_cast<uint8_t>((iColour >> 24) & 0xFF);
|
|
}
|
|
|
|
//! Get the number of colours in the palette.
|
|
/*!
|
|
@return The number of colours in the palette.
|
|
*/
|
|
int get_colour_count() const;
|
|
|
|
//! Get the internal palette data for fast (read-only) access.
|
|
/*!
|
|
@return Table with all 256 colours of the palette.
|
|
*/
|
|
const argb_colour* get_argb_data() const;
|
|
|
|
//! Set an entry of the palette.
|
|
/*!
|
|
@param iEntry Entry to modify.
|
|
@param iVal Palette value to set.
|
|
*/
|
|
inline void set_argb(int iEntry, uint32_t iVal) {
|
|
colour_index_to_argb_map[iEntry] = iVal;
|
|
}
|
|
|
|
private:
|
|
//! 32bpp palette colours associated with the 8bpp colour index.
|
|
uint32_t colour_index_to_argb_map[256];
|
|
|
|
//! Number of colours in the palette.
|
|
int colour_count;
|
|
};
|
|
|
|
/*!
|
|
Utility class for decoding 32bpp images.
|
|
*/
|
|
class full_colour_renderer {
|
|
public:
|
|
//! Initialize the renderer for a specific render.
|
|
/*!
|
|
@param iWidth Pixel width of the resulting image
|
|
@param iHeight Pixel height of the resulting image
|
|
*/
|
|
full_colour_renderer(int iWidth, int iHeight);
|
|
virtual ~full_colour_renderer() = default;
|
|
|
|
//! Decode a 32bpp image, and push it to the storage backend.
|
|
/*!
|
|
@param pImg Encoded 32bpp image.
|
|
@param pPalette Palette of a legacy sprite.
|
|
@param iSpriteFlags Flags how to render the sprite.
|
|
@return Decoding was successful.
|
|
*/
|
|
void decode_image(const uint8_t* pImg, const ::palette* pPalette,
|
|
uint32_t iSpriteFlags);
|
|
|
|
private:
|
|
//! Store a decoded pixel. Use x and y if necessary.
|
|
/*!
|
|
@param pixel Pixel to store.
|
|
*/
|
|
virtual void store_argb(uint32_t pixel) = 0;
|
|
|
|
const int width;
|
|
const int height;
|
|
int x;
|
|
int y;
|
|
|
|
//! Push a pixel to the storage.
|
|
/*!
|
|
@param iValue Pixel value to store.
|
|
*/
|
|
inline void push_pixel(uint32_t iValue) {
|
|
if (y < height) {
|
|
store_argb(iValue);
|
|
x++;
|
|
if (x >= width) {
|
|
x = 0;
|
|
y++;
|
|
}
|
|
} else {
|
|
throw std::logic_error("Attempt to push_pixel past the end of the image");
|
|
}
|
|
}
|
|
};
|
|
|
|
class full_colour_storing : public full_colour_renderer {
|
|
public:
|
|
full_colour_storing(uint32_t* pDest, int iWidth, int iHeight);
|
|
|
|
private:
|
|
void store_argb(uint32_t pixel) override;
|
|
|
|
//! Pointer to the storage (not owned by this class).
|
|
uint32_t* destination;
|
|
};
|
|
|
|
class wx_storing : public full_colour_renderer {
|
|
public:
|
|
wx_storing(uint8_t* pRGBData, uint8_t* pAData, int iWidth, int iHeight);
|
|
|
|
private:
|
|
void store_argb(uint32_t pixel) override;
|
|
|
|
//! Pointer to the RGB storage (not owned by this class).
|
|
uint8_t* rgb_data;
|
|
|
|
//! Pointer to the Alpha channel storage (not owned by this class).
|
|
uint8_t* alpha_data;
|
|
};
|
|
|
|
class render_target {
|
|
public: // External API
|
|
render_target();
|
|
~render_target();
|
|
|
|
//! Encode an RGB triplet for fillRect()
|
|
static constexpr uint32_t map_colour(uint8_t iR, uint8_t iG, uint8_t iB) {
|
|
return palette::pack_argb(0xFF, iR, iG, iB);
|
|
}
|
|
|
|
//! Initialise the render target
|
|
bool create(const render_target_creation_params* pParams);
|
|
|
|
//! Update the parameters for the render target
|
|
bool update(const render_target_creation_params* pParams);
|
|
|
|
//! Shut down the render target
|
|
void destroy();
|
|
|
|
//! Get the reason for the last operation failing
|
|
const char* get_last_error();
|
|
|
|
//! Begin rendering a new frame
|
|
bool start_frame();
|
|
|
|
//! Finish rendering the current frame and present it
|
|
bool end_frame();
|
|
|
|
//! Paint the entire render target black
|
|
bool fill_black();
|
|
|
|
//! Sets a blue filter on the current surface.
|
|
// Used to add the blue effect when the game is paused.
|
|
void set_blue_filter_active(bool bActivate);
|
|
|
|
//! Fill a rectangle of the render target with a solid colour
|
|
bool fill_rect(uint32_t iColour, int iX, int iY, int iW, int iH);
|
|
|
|
class scoped_clip {
|
|
public:
|
|
scoped_clip(render_target*, const clip_rect* pRect);
|
|
~scoped_clip();
|
|
|
|
private:
|
|
render_target* target = nullptr;
|
|
};
|
|
|
|
//! Push a new clip rectangle.
|
|
void push_clip_rect(const clip_rect* pRect);
|
|
|
|
//! Restore the previous clip rectangle.
|
|
void pop_clip_rect();
|
|
|
|
//! Get the width of the render target (in pixels)
|
|
int get_width() const;
|
|
|
|
//! Get the height of the render target (in pixels)
|
|
int get_height() const;
|
|
|
|
//! Enable optimisations for non-overlapping draws
|
|
void start_nonoverlapping_draws();
|
|
|
|
//! Disable optimisations for non-overlapping draws
|
|
void finish_nonoverlapping_draws();
|
|
|
|
//! Set the cursor to be used
|
|
void set_cursor(cursor* pCursor);
|
|
|
|
//! Update the cursor position (if the cursor is being simulated)
|
|
void set_cursor_position(int iX, int iY);
|
|
|
|
//! Take a screenshot and save it as a bitmap
|
|
bool take_screenshot(const char* sFile);
|
|
|
|
//! Set the amount by which future draw operations are scaled.
|
|
/*!
|
|
@param fScale New scale to use.
|
|
@param eWhatToScale Th kind of items to scale.
|
|
@return Whether the scale could be set.
|
|
*/
|
|
bool set_scale_factor(double fScale, scaled_items eWhatToScale);
|
|
|
|
//! Set the window caption
|
|
void set_caption(const char* sCaption);
|
|
|
|
//! Toggle mouse capture on the window.
|
|
void set_window_grab(bool bActivate);
|
|
|
|
//! Get any user-displayable information to describe the renderer path used
|
|
const char* get_renderer_details() const;
|
|
|
|
// If you add any extra methods here which are called from outside the
|
|
// rendering engine, then be sure to at least add dummy implementations
|
|
// to the other rendering engines.
|
|
|
|
public: // Internal (this rendering engine only) API
|
|
class scoped_buffer {
|
|
public:
|
|
virtual ~scoped_buffer() = default;
|
|
};
|
|
|
|
SDL_Renderer* get_renderer() const { return renderer; }
|
|
|
|
//! Should bitmaps be scaled?
|
|
/*!
|
|
@param [out] pFactor If the function returns \c true, the factor to use
|
|
for scaling (can be \c nullptr if not interested in the value).
|
|
@return Whether bitmaps should be scaled.
|
|
*/
|
|
bool should_scale_bitmaps(double* pFactor);
|
|
|
|
SDL_Texture* create_palettized_texture(int iWidth, int iHeight,
|
|
const uint8_t* pPixels,
|
|
const ::palette* pPalette,
|
|
uint32_t iSpriteFlags) const;
|
|
SDL_Texture* create_texture(int iWidth, int iHeight,
|
|
const uint32_t* pPixels) const;
|
|
void draw(SDL_Texture* pTexture, const SDL_Rect* prcSrcRect,
|
|
const SDL_Rect* prcDstRect, int iFlags);
|
|
void draw_line(line_sequence* pLine, int iX, int iY);
|
|
|
|
//! Begin drawing to an intermediate unscaled texture targeting the given
|
|
//! location and size. The intermediate drawing will be committed once
|
|
//! the returned scoped_buffer is destroyed.
|
|
/*!
|
|
@param iX X-coordinate of left side of drawing rectangle.
|
|
@param iY Y-coordinate of top side of drawing rectangle.
|
|
@param iWidth Width of drawing rectangle.
|
|
@param iHeight Height of drawing rectangle.
|
|
*/
|
|
std::unique_ptr<scoped_buffer> begin_intermediate_drawing(int iX, int iY,
|
|
int iWidth,
|
|
int iHeight);
|
|
|
|
private:
|
|
class scoped_target_texture;
|
|
friend class scoped_target_texture;
|
|
|
|
double draw_scale() const;
|
|
|
|
void destroy_intermediate_textures();
|
|
|
|
SDL_Window* window;
|
|
SDL_Renderer* renderer;
|
|
scoped_target_texture* current_target = nullptr;
|
|
std::unique_ptr<scoped_target_texture> zoom_buffer;
|
|
SDL_PixelFormat* pixel_format;
|
|
bool blue_filter_active;
|
|
cursor* game_cursor;
|
|
double bitmap_scale_factor; ///< Bitmap scale factor.
|
|
double global_scale_factor; ///< Global scale factor.
|
|
int width;
|
|
int height;
|
|
int cursor_x;
|
|
int cursor_y;
|
|
|
|
std::stack<SDL_Rect> clip_rects; ///< Stack of requested clip rects.
|
|
|
|
// Intermediate textures used in the production of the current frame.
|
|
// These are destroyed after the frame is presented.
|
|
std::vector<SDL_Texture*> intermediate_textures;
|
|
|
|
bool scale_bitmaps; ///< Whether bitmaps should be scaled.
|
|
bool supports_target_textures;
|
|
|
|
// In SDL2 < 2.0.4 there is an issue with the y coordinates used for
|
|
// ClipRects in opengl and opengles.
|
|
// see: https://bugzilla.libsdl.org/show_bug.cgi?id=2700
|
|
bool apply_opengl_clip_fix;
|
|
bool direct_zoom;
|
|
};
|
|
|
|
//! Stored image.
|
|
class raw_bitmap {
|
|
public:
|
|
raw_bitmap();
|
|
~raw_bitmap();
|
|
|
|
//! Set the palette of the image.
|
|
/*!
|
|
@param pPalette Palette to set for this image.
|
|
*/
|
|
void set_palette(const ::palette* pPalette);
|
|
|
|
//! Load the image from the supplied pixel data.
|
|
/*!
|
|
Loader uses the palette supplied before.
|
|
@param pPixelData Image data loaded from a TH file.
|
|
@param iPixelDataLength Size of the loaded image data.
|
|
@param iWidth Width of the image.
|
|
@param pEventualCanvas Canvas to render the image to (eventually).
|
|
@return Loading was a success.
|
|
*/
|
|
void load_from_th_file(const uint8_t* pPixelData, size_t iPixelDataLength,
|
|
int iWidth, render_target* pEventualCanvas);
|
|
|
|
//! Draw the image at a given position at the given canvas.
|
|
/*!
|
|
@param pCanvas Canvas to draw at.
|
|
@param iX Destination x position.
|
|
@param iY Destination y position.
|
|
*/
|
|
void draw(render_target* pCanvas, int iX, int iY);
|
|
|
|
//! Draw part of the image at a given position at the given canvas.
|
|
/*!
|
|
@param pCanvas Canvas to draw at.
|
|
@param iX Destination x position.
|
|
@param iY Destination y position.
|
|
@param iSrcX X position of the part to display.
|
|
@param iSrcY Y position of the part to display.
|
|
@param iWidth Width of the part to display.
|
|
@param iHeight Height of the part to display.
|
|
*/
|
|
void draw(render_target* pCanvas, int iX, int iY, int iSrcX, int iSrcY,
|
|
int iWidth, int iHeight);
|
|
|
|
private:
|
|
//! Image stored in SDL format for quick rendering.
|
|
SDL_Texture* texture;
|
|
|
|
//! Palette of the image.
|
|
const ::palette* bitmap_palette;
|
|
|
|
//! Target canvas.
|
|
render_target* target;
|
|
|
|
//! Width of the stored image.
|
|
int width;
|
|
|
|
//! Height of the stored image.
|
|
int height;
|
|
};
|
|
|
|
//! Sheet of sprites.
|
|
class sprite_sheet {
|
|
public: // External API
|
|
sprite_sheet();
|
|
~sprite_sheet();
|
|
|
|
//! Set the palette to use for the sprites in the sheet.
|
|
/*!
|
|
@param pPalette Palette to use for the sprites at the sheet.
|
|
*/
|
|
void set_palette(const ::palette* pPalette);
|
|
|
|
//! Load the sprites from the supplied data (using the palette supplied
|
|
//! earlier).
|
|
/*!
|
|
@param pTableData Start of table data with TH sprite information (see
|
|
th_sprite_properties).
|
|
@param iTableDataLength Length of the table data.
|
|
@param pChunkData Start of image data (chunks).
|
|
@param iChunkDataLength Length of the chunk data.
|
|
@param bComplexChunks Whether the supplied chunks are 'complex'.
|
|
@param pEventualCanvas Canvas to draw at.
|
|
@return Loading succeeded.
|
|
*/
|
|
bool load_from_th_file(const uint8_t* pTableData, size_t iTableDataLength,
|
|
const uint8_t* pChunkData, size_t iChunkDataLength,
|
|
bool bComplexChunks, render_target* pEventualCanvas);
|
|
|
|
//! Set the data of a sprite.
|
|
/*!
|
|
@param iSprite Number of the sprite to set.
|
|
@param pData Data of the sprite.
|
|
@param bTakeData Whether the data block may be taken (must be new[]
|
|
then).
|
|
@param iDataLength Length of the data.
|
|
@param iWidth Width of the sprite.
|
|
@param iHeight Height of the sprite.
|
|
@return Setting the sprite succeeded.
|
|
*/
|
|
bool set_sprite_data(size_t iSprite, const uint8_t* pData, bool bTakeData,
|
|
size_t iDataLength, int iWidth, int iHeight);
|
|
|
|
//! Supply a new mapped palette to a sprite.
|
|
/*!
|
|
@param iSprite Sprite getting the mapped palette.
|
|
@param pMap The palette map to apply.
|
|
@param iAlt32 What to do for a 32bpp sprite (#thdf_alt32_mask bits).
|
|
*/
|
|
void set_sprite_alt_palette_map(size_t iSprite, const uint8_t* pMap,
|
|
uint32_t iAlt32);
|
|
|
|
//! Get the number of sprites at the sheet.
|
|
/*!
|
|
@return The number of sprites available at the sheet.
|
|
*/
|
|
size_t get_sprite_count() const;
|
|
|
|
//! Set the number of sprites in the sheet.
|
|
/*!
|
|
@param iCount The desired number of sprites.
|
|
@param pCanvas Canvas to draw at.
|
|
@return Whether the number of sprites could be allocated.
|
|
*/
|
|
bool set_sprite_count(size_t iCount, render_target* pCanvas);
|
|
|
|
//! Get size of a sprite.
|
|
/*!
|
|
@param iSprite Sprite to get info from.
|
|
@param pWidth [out] If not nullptr, the sprite width is stored in the
|
|
destination.
|
|
@param pHeight [out] If not nullptr, the sprite height is stored in the
|
|
destination.
|
|
@return Size could be provided for the sprite.
|
|
*/
|
|
bool get_sprite_size(size_t iSprite, int* pWidth, int* pHeight) const;
|
|
|
|
//! Get size of a sprite, assuming all input is correctly supplied.
|
|
/*!
|
|
@param iSprite Sprite to get info from.
|
|
@param pWidth [out] The sprite width is stored in the destination.
|
|
@param pHeight [out] The sprite height is stored in the destination.
|
|
*/
|
|
void get_sprite_size_unchecked(size_t iSprite, int* pWidth,
|
|
int* pHeight) const;
|
|
|
|
//! Get the best colour to represent the sprite.
|
|
/*!
|
|
@param iSprite Sprite number to analyze.
|
|
@param pColour [out] Resulting colour.
|
|
@return Best colour could be established.
|
|
*/
|
|
bool get_sprite_average_colour(size_t iSprite, argb_colour* pColour) const;
|
|
|
|
//! Return whether the given sprite show any pixel when displayed.
|
|
/*!
|
|
@param iSprite Sprite number to analyze.
|
|
@return Whether any pixel of the sprite is visible.
|
|
*/
|
|
bool is_sprite_visible(size_t iSprite) const;
|
|
|
|
//! Draw a sprite onto the canvas.
|
|
/*!
|
|
@param pCanvas Canvas to draw on.
|
|
@param iSprite Sprite to draw.
|
|
@param iX X position to draw the sprite.
|
|
@param iY Y position to draw the sprite.
|
|
@param iFlags Flags to apply for drawing.
|
|
@param effect_ticks The number of ticks into the effect animation.
|
|
@param effect The animation effect to apply to the sprite.
|
|
*/
|
|
void draw_sprite(render_target* pCanvas, size_t iSprite, int iX, int iY,
|
|
uint32_t iFlags, size_t effect_ticks = 0u,
|
|
animation_effect effect = animation_effect::none);
|
|
|
|
//! Test whether a sprite was hit.
|
|
/*!
|
|
@param iSprite Sprite being tested.
|
|
@param iX X position of the point to test relative to the origin of the
|
|
sprite.
|
|
@param iY Y position of the point to test relative to the origin of the
|
|
sprite.
|
|
@param iFlags Draw flags to apply to the sprite before testing.
|
|
@return Whether the sprite covers the give point.
|
|
*/
|
|
bool hit_test_sprite(size_t iSprite, int iX, int iY, uint32_t iFlags) const;
|
|
|
|
public: // Internal (this rendering engine only) API
|
|
//! Draw a sprite into wxImage data arrays (for the Map Editor)
|
|
/*!
|
|
@param iSprite Sprite number to draw.
|
|
@param pRGBData Output RGB data array.
|
|
@param pAData Output Alpha channel array.
|
|
*/
|
|
void wx_draw_sprite(size_t iSprite, uint8_t* pRGBData, uint8_t* pAData);
|
|
|
|
private:
|
|
friend class cursor;
|
|
#if CORSIX_TH_USE_PACK_PRAGMAS
|
|
#pragma pack(push)
|
|
#pragma pack(1)
|
|
#endif
|
|
//! Sprite structure in the table file.
|
|
struct th_sprite_properties {
|
|
//! Position of the sprite in the chunk data file.
|
|
uint32_t position;
|
|
|
|
//! Width of the sprite.
|
|
uint8_t width;
|
|
|
|
//! Height of the sprite.
|
|
uint8_t height;
|
|
} CORSIX_TH_PACKED_FLAGS;
|
|
#if CORSIX_TH_USE_PACK_PRAGMAS
|
|
#pragma pack(pop)
|
|
#endif
|
|
|
|
//! Sprites of the sheet.
|
|
struct sprite {
|
|
//! SDL structure containing the sprite with original palette.
|
|
SDL_Texture* texture;
|
|
|
|
//! SDL structure containing the sprite with alternative palette.
|
|
SDL_Texture* alt_texture;
|
|
|
|
//! Data of the sprite.
|
|
const uint8_t* data;
|
|
|
|
//! Alternative palette (if available).
|
|
const uint8_t* alt_palette_map;
|
|
|
|
//! Flags how to render the sprite, contains #THDF_Alt32_Mask bits.
|
|
uint32_t sprite_flags;
|
|
|
|
//! Width of the sprite.
|
|
int width;
|
|
|
|
//! Height of the sprite.
|
|
int height;
|
|
}* sprites;
|
|
|
|
//! Original palette.
|
|
const ::palette* palette;
|
|
|
|
//! Target to render to.
|
|
render_target* target;
|
|
|
|
//! Number of sprites in the sprite sheet.
|
|
size_t sprite_count;
|
|
|
|
//! Free memory of a single sprite.
|
|
/*!
|
|
@param iNumber Number of the sprite to clear.
|
|
*/
|
|
void _freeSingleSprite(size_t iNumber);
|
|
|
|
//! Free the memory used by the sprites. Also releases the SDL bitmaps.
|
|
void _freeSprites();
|
|
|
|
//! Construct an alternative version (with its alternative palette map) of
|
|
//! the sprite.
|
|
/*!
|
|
@param pSprite Sprite to change.
|
|
@return SDL texture containing the sprite.
|
|
*/
|
|
SDL_Texture* _makeAltBitmap(sprite* pSprite);
|
|
};
|
|
|
|
class cursor {
|
|
public:
|
|
cursor();
|
|
~cursor();
|
|
|
|
bool create_from_sprite(sprite_sheet* pSheet, size_t iSprite,
|
|
int iHotspotX = 0, int iHotspotY = 0);
|
|
|
|
void use(render_target* pTarget);
|
|
|
|
static bool set_position(render_target* pTarget, int iX, int iY);
|
|
|
|
void draw(render_target* pCanvas, int iX, int iY);
|
|
|
|
private:
|
|
SDL_Surface* bitmap;
|
|
SDL_Cursor* hidden_cursor;
|
|
int hotspot_x;
|
|
int hotspot_y;
|
|
};
|
|
|
|
class line_sequence {
|
|
public:
|
|
line_sequence();
|
|
|
|
void move_to(double fX, double fY);
|
|
|
|
void line_to(double fX, double fY);
|
|
|
|
void set_width(double lineWidth);
|
|
|
|
void draw(render_target* pCanvas, int iX, int iY);
|
|
|
|
void set_colour(uint8_t iR, uint8_t iG, uint8_t iB, uint8_t iA = 255);
|
|
|
|
void persist(lua_persist_writer* pWriter) const;
|
|
void depersist(lua_persist_reader* pReader);
|
|
|
|
private:
|
|
friend class render_target;
|
|
void initialize();
|
|
|
|
enum class line_command : uint32_t { move = 0, line = 1 };
|
|
|
|
class line_element {
|
|
public:
|
|
line_command type;
|
|
double x, y;
|
|
line_element(line_command type, double x, double y)
|
|
: type(type), x(x), y(y) {}
|
|
};
|
|
|
|
std::vector<line_element> line_elements;
|
|
double width;
|
|
uint8_t red, green, blue, alpha;
|
|
};
|
|
|
|
#endif // CORSIX_TH_TH_GFX_SDL_H_
|