raze/source/common/2d/v_draw.h
Simon dff31bcad2 Additional 2D drawer for fullscreen palette blend (for damage/pickups)
and also for drawing the crosshair and fps counter.
Required for RazeXR since the standard HUD 2D drawer is now scalable.
2023-01-16 20:14:08 +00:00

339 lines
12 KiB
C++

#pragma once
#include "v_2ddrawer.h"
#include "c_cvars.h"
#include "intrect.h"
// TagItem definitions for DrawTexture. As far as I know, tag lists
// originated on the Amiga.
//
// Think of TagItems as an array of the following structure:
//
// struct TagItem {
// uint32_t ti_Tag;
// uint32_t ti_Data;
// };
enum tags : uint32_t
{
TAG_DONE = (0), /* Used to indicate the end of the Tag list */
TAG_END = (0), /* Ditto */
/* list pointed to in ti_Data */
TAG_USER = ((uint32_t)(1u << 30))
};
enum
{
FSMode_None = 0,
FSMode_ScaleToFit = 1,
FSMode_ScaleToFill = 2,
FSMode_ScaleToFit43 = 3,
FSMode_ScaleToScreen = 4,
FSMode_ScaleToFit43Top = 5,
FSMode_ScaleToFit43Bottom = 6,
FSMode_ScaleToHeight = 7,
FSMode_Max,
// These all use ScaleToFit43, their purpose is to cut down on verbosity because they imply the virtual screen size.
FSMode_Predefined = 1000,
FSMode_Fit320x200 = 1000,
FSMode_Fit320x240,
FSMode_Fit640x400,
FSMode_Fit640x480,
FSMode_Fit320x200Top,
FSMode_Predefined_Max,
};
enum
{
DTA_Base = TAG_USER + 5000,
DTA_DestWidth, // width of area to draw to
DTA_DestHeight, // height of area to draw to
DTA_Alpha, // alpha value for translucency
DTA_FillColor, // color to stencil onto the destination
DTA_TranslationIndex, // translation table to recolor the source
DTA_AlphaChannel, // bool: the source is an alpha channel; used with DTA_FillColor
DTA_Clean, // bool: scale texture size and position by CleanXfac and CleanYfac
DTA_320x200, // bool: scale texture size and position to fit on a virtual 320x200 screen
DTA_Bottom320x200, // bool: same as DTA_320x200 but centers virtual screen on bottom for 1280x1024 targets
DTA_CleanNoMove, // bool: like DTA_Clean but does not reposition output position
DTA_CleanNoMove_1, // bool: like DTA_CleanNoMove, but uses Clean[XY]fac_1 instead
DTA_FlipX, // bool: flip image horizontally //FIXME: Does not work with DTA_Window(Left|Right)
DTA_ShadowColor, // color of shadow
DTA_ShadowAlpha, // alpha of shadow
DTA_Shadow, // set shadow color and alphas to defaults
DTA_VirtualWidth, // pretend the canvas is this wide
DTA_VirtualHeight, // pretend the canvas is this tall
DTA_TopOffset, // override texture's top offset
DTA_LeftOffset, // override texture's left offset
DTA_CenterOffset, // bool: override texture's left and top offsets and set them for the texture's middle
DTA_CenterBottomOffset,// bool: override texture's left and top offsets and set them for the texture's bottom middle
DTA_WindowLeft, // don't draw anything left of this column (on source, not dest)
DTA_WindowRight, // don't draw anything at or to the right of this column (on source, not dest)
DTA_ClipTop, // don't draw anything above this row (on dest, not source)
DTA_ClipBottom, // don't draw anything at or below this row (on dest, not source)
DTA_ClipLeft, // don't draw anything to the left of this column (on dest, not source)
DTA_ClipRight, // don't draw anything at or to the right of this column (on dest, not source)
DTA_Masked, // true(default)=use masks from texture, false=ignore masks
DTA_HUDRules, // use fullscreen HUD rules to position and size textures
DTA_HUDRulesC, // only used internally for marking HUD_HorizCenter
DTA_KeepRatio, // doesn't adjust screen size for DTA_Virtual* if the aspect ratio is not 4:3
DTA_RenderStyle, // same as render style for actors
DTA_ColorOverlay, // uint32_t: ARGB to overlay on top of image; limited to black for software
DTA_BilinearFilter, // bool: apply bilinear filtering to the image
DTA_SpecialColormap,// pointer to FSpecialColormapParameters
DTA_Desaturate, // explicit desaturation factor (does not do anything in Legacy OpenGL)
DTA_Fullscreen, // Draw image fullscreen (same as DTA_VirtualWidth/Height with graphics size.)
// floating point duplicates of some of the above:
DTA_DestWidthF,
DTA_DestHeightF,
DTA_TopOffsetF,
DTA_LeftOffsetF,
DTA_VirtualWidthF,
DTA_VirtualHeightF,
DTA_WindowLeftF,
DTA_WindowRightF,
// For DrawText calls:
DTA_TextLen, // stop after this many characters, even if \0 not hit
DTA_CellX, // horizontal size of character cell
DTA_CellY, // vertical size of character cell
// New additions.
DTA_Color,
DTA_FlipY, // bool: flip image vertically
DTA_SrcX, // specify a source rectangle (this supersedes the poorly implemented DTA_WindowLeft/Right
DTA_SrcY,
DTA_SrcWidth,
DTA_SrcHeight,
DTA_LegacyRenderStyle, // takes an old-style STYLE_* constant instead of an FRenderStyle
DTA_Burn, // activates the burn shader for this element
DTA_Spacing, // Strings only: Additional spacing between characters
DTA_Monospace, // Fonts only: Use a fixed distance between characters.
DTA_FullscreenEx,
DTA_FullscreenScale,
DTA_ScaleX,
DTA_ScaleY,
DTA_ViewportX, // Defines the viewport on the screen that should be rendered to.
DTA_ViewportY,
DTA_ViewportWidth,
DTA_ViewportHeight,
DTA_CenterOffsetRel, // Apply texture offsets relative to center, instead of top left. This is standard alignment for Build's 2D content.
DTA_TopLeft, // always align to top left. Added to have a boolean condition for this alignment.
DTA_Pin, // Pin a non-widescreen image to the left/right edge of the screen.
DTA_Rotate,
DTA_FlipOffsets, // Flips offsets when using DTA_FlipX and DTA_FlipY, this cannot be automatic due to unexpected behavior with unoffsetted graphics.
DTA_Indexed, // Use an indexed texture combined with the given translation.
DTA_CleanTop, // Like DTA_Clean but aligns to the top of the screen instead of the center.
DTA_NoOffset, // Ignore 2D drawer's offset.
};
enum EMonospacing : int
{
Off = 0,
CellLeft = 1,
CellCenter = 2,
CellRight = 3
};
enum
{
HUD_Normal,
HUD_HorizCenter
};
class FFont;
struct FRemapTable;
class player_t;
typedef uint32_t angle_t;
struct DrawParms
{
double x, y;
double texwidth;
double texheight;
double destwidth;
double destheight;
double virtWidth;
double virtHeight;
double windowleft;
double windowright;
int cleanmode;
int dclip;
int uclip;
int lclip;
int rclip;
double top;
double left;
float Alpha;
PalEntry fillcolor;
int TranslationId;
PalEntry colorOverlay;
PalEntry color;
int alphaChannel;
int flipX;
int flipY;
//float shadowAlpha;
int shadowColor;
int keepratio;
int masked;
int bilinear;
FRenderStyle style;
struct FSpecialColormap *specialcolormap;
int desaturate;
int scalex, scaley;
int cellx, celly;
int monospace;
int spacing;
int maxstrlen;
bool fortext;
bool virtBottom;
bool burn;
bool flipoffsets;
bool indexed;
bool nooffset;
int8_t fsscalemode;
double srcx, srcy;
double srcwidth, srcheight;
double patchscalex, patchscaley;
double rotateangle;
IntRect viewport;
bool vertexColorChange(const DrawParms& other) {
return
this->Alpha != other.Alpha ||
this->fillcolor != other.fillcolor ||
this->colorOverlay != other.colorOverlay ||
this->color != other.color ||
this->style.Flags != other.style.Flags ||
this->style.BlendOp != other.style.BlendOp ||
this->desaturate != other.desaturate;
}
};
struct Va_List
{
va_list list;
};
struct VMVa_List
{
VMValue *args;
int curindex;
int numargs;
const uint8_t *reginfo;
};
float ActiveRatio (int width, int height, float *trueratio = NULL);
inline double ActiveRatio (double width, double height) { return ActiveRatio(int(width), int(height)); }
int AspectBaseWidth(float aspect);
int AspectBaseHeight(float aspect);
double AspectPspriteOffset(float aspect);
int AspectMultiplier(float aspect);
bool AspectTallerThanWide(float aspect);
extern F2DDrawer* twod_blend;
extern F2DDrawer* twod;
int GetUIScale(F2DDrawer* drawer, int altval);
int GetConScale(F2DDrawer* drawer, int altval);
EXTERN_CVAR(Int, uiscale);
EXTERN_CVAR(Int, con_scale);
inline int active_con_scale(F2DDrawer *drawer)
{
return GetConScale(drawer, con_scale);
}
#ifdef DrawText
#undef DrawText // See WinUser.h for the definition of DrawText as a macro
#endif
enum
{
DrawTexture_Normal,
DrawTexture_Text,
DrawTexture_Fill,
};
template<class T>
bool ParseDrawTextureTags(F2DDrawer *drawer, FGameTexture* img, double x, double y, uint32_t tag, T& tags, DrawParms* parms, int type, PalEntry fill = ~0u, double fillalpha = 0.0);
template<class T>
void DrawTextCommon(F2DDrawer *drawer, FFont* font, int normalcolor, double x, double y, const T* string, DrawParms& parms);
bool SetTextureParms(F2DDrawer *drawer, DrawParms* parms, FGameTexture* img, double x, double y);
void GetFullscreenRect(double width, double height, int fsmode, DoubleRect* rect);
void DrawText(F2DDrawer* drawer, FFont* font, int normalcolor, double x, double y, const char* string, int tag_first, ...);
void DrawText(F2DDrawer* drawer, FFont* font, int normalcolor, double x, double y, const char32_t* string, int tag_first, ...);
void DrawChar(F2DDrawer* drawer, FFont* font, int normalcolor, double x, double y, int character, int tag_first, ...);
void DrawTexture(F2DDrawer* drawer, FGameTexture* img, double x, double y, int tags_first, ...);
void DrawTexture(F2DDrawer *drawer, FTextureID texid, bool animate, double x, double y, int tags_first, ...);
void DoDim(F2DDrawer* drawer, PalEntry color, float amount, int x1, int y1, int w, int h, FRenderStyle* style = nullptr);
void Dim(F2DDrawer* drawer, PalEntry color, float damount, int x1, int y1, int w, int h, FRenderStyle* style = nullptr);
void DrawBorder(F2DDrawer* drawer, FTextureID, int x1, int y1, int x2, int y2);
void DrawFrame(F2DDrawer* twod, PalEntry color, int left, int top, int width, int height, int thickness);
// Set an area to a specified color
void ClearRect(F2DDrawer* drawer, int left, int top, int right, int bottom, int palcolor, uint32_t color);
void VirtualToRealCoords(F2DDrawer* drawer, double& x, double& y, double& w, double& h, double vwidth, double vheight, bool vbottom = false, bool handleaspect = true);
// Code that uses these (i.e. SBARINFO) should probably be evaluated for using doubles all around instead.
void VirtualToRealCoordsInt(F2DDrawer* drawer, int& x, int& y, int& w, int& h, int vwidth, int vheight, bool vbottom = false, bool handleaspect = true);
extern int CleanWidth, CleanHeight, CleanXfac, CleanYfac;
extern int CleanWidth_1, CleanHeight_1, CleanXfac_1, CleanYfac_1;
void V_CalcCleanFacs(int designwidth, int designheight, int realwidth, int realheight, int* cleanx, int* cleany, int* cx1 = NULL, int* cx2 = NULL);
class ScaleOverrider
{
int savedxfac, savedyfac, savedwidth, savedheight;
public:
// This is to allow certain elements to use an optimal fullscreen scale which for the menu would be too large.
// The old code contained far too much mess to compensate for the menus which negatively affected everything else.
// However, for compatibility reasons the currently used variables cannot be changed so they have to be overridden temporarily.
// This class provides a safe interface for this because it ensures that the values get restored afterward.
// Currently, the intermission and the level summary screen use this.
ScaleOverrider(F2DDrawer *drawer)
{
savedxfac = CleanXfac;
savedyfac = CleanYfac;
savedwidth = CleanWidth;
savedheight = CleanHeight;
if (drawer)
{
V_CalcCleanFacs(320, 200, drawer->GetWidth(), drawer->GetHeight(), &CleanXfac, &CleanYfac);
CleanWidth = drawer->GetWidth() / CleanXfac;
CleanHeight = drawer->GetHeight() / CleanYfac;
}
}
~ScaleOverrider()
{
CleanXfac = savedxfac;
CleanYfac = savedyfac;
CleanWidth = savedwidth;
CleanHeight = savedheight;
}
};
void Draw2D(F2DDrawer* drawer, FRenderState& state);
void Draw2D(F2DDrawer* drawer, FRenderState& state, int x, int y, int width, int height);