in doom_py/src/vizdoom/src/v_draw.cpp [330:741]
bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag, va_list tags, DrawParms *parms, bool hw) const
{
INTBOOL boolval;
int intval;
bool translationset = false;
bool virtBottom;
bool fillcolorset = false;
if (img == NULL || img->UseType == FTexture::TEX_Null)
{
va_end(tags);
return false;
}
// Do some sanity checks on the coordinates.
if (x < -16383 || x > 16383 || y < -16383 || y > 16383)
{
va_end(tags);
return false;
}
virtBottom = false;
parms->texwidth = img->GetScaledWidthDouble();
parms->texheight = img->GetScaledHeightDouble();
parms->windowleft = 0;
parms->windowright = parms->texwidth;
parms->dclip = this->GetHeight();
parms->uclip = 0;
parms->lclip = 0;
parms->rclip = this->GetWidth();
parms->destwidth = parms->windowright;
parms->destheight = parms->texheight;
parms->top = img->GetScaledTopOffset();
parms->left = img->GetScaledLeftOffset();
parms->alpha = FRACUNIT;
parms->fillcolor = -1;
parms->remap = NULL;
parms->translation = NULL;
parms->colorOverlay = 0;
parms->alphaChannel = false;
parms->flipX = false;
parms->shadowAlpha = 0;
parms->shadowColor = 0;
parms->virtWidth = this->GetWidth();
parms->virtHeight = this->GetHeight();
parms->keepratio = false;
parms->style.BlendOp = 255; // Dummy "not set" value
parms->masked = true;
parms->bilinear = false;
parms->specialcolormap = NULL;
parms->colormapstyle = NULL;
parms->x = x;
parms->y = y;
// Parse the tag list for attributes. (For floating point attributes,
// consider that the C ABI dictates that all floats be promoted to
// doubles when passed as function arguments.)
while (tag != TAG_DONE)
{
va_list *more_p;
DWORD data;
switch (tag)
{
case TAG_IGNORE:
default:
data = va_arg(tags, DWORD);
break;
case TAG_MORE:
more_p = va_arg(tags, va_list *);
va_end (tags);
#ifndef NO_VA_COPY
va_copy (tags, *more_p);
#else
tags = *more_p;
#endif
break;
case DTA_DestWidth:
parms->destwidth = va_arg(tags, int);
break;
case DTA_DestWidthF:
parms->destwidth = va_arg(tags, double);
break;
case DTA_DestHeight:
parms->destheight = va_arg(tags, int);
break;
case DTA_DestHeightF:
parms->destheight = va_arg(tags, double);
break;
case DTA_Clean:
boolval = va_arg(tags, INTBOOL);
if (boolval)
{
parms->x = (parms->x - 160.0) * CleanXfac + (Width * 0.5);
parms->y = (parms->y - 100.0) * CleanYfac + (Height * 0.5);
parms->destwidth = parms->texwidth * CleanXfac;
parms->destheight = parms->texheight * CleanYfac;
}
break;
case DTA_CleanNoMove:
boolval = va_arg(tags, INTBOOL);
if (boolval)
{
parms->destwidth = parms->texwidth * CleanXfac;
parms->destheight = parms->texheight * CleanYfac;
}
break;
case DTA_CleanNoMove_1:
boolval = va_arg(tags, INTBOOL);
if (boolval)
{
parms->destwidth = parms->texwidth * CleanXfac_1;
parms->destheight = parms->texheight * CleanYfac_1;
}
break;
case DTA_320x200:
boolval = va_arg(tags, INTBOOL);
if (boolval)
{
parms->virtWidth = 320;
parms->virtHeight = 200;
}
break;
case DTA_Bottom320x200:
boolval = va_arg(tags, INTBOOL);
if (boolval)
{
parms->virtWidth = 320;
parms->virtHeight = 200;
}
virtBottom = true;
break;
case DTA_HUDRules:
{
bool xright = parms->x < 0;
bool ybot = parms->y < 0;
intval = va_arg(tags, int);
if (hud_scale)
{
parms->x *= CleanXfac;
if (intval == HUD_HorizCenter)
parms->x += Width * 0.5;
else if (xright)
parms->x = Width + parms->x;
parms->y *= CleanYfac;
if (ybot)
parms->y = Height + parms->y;
parms->destwidth = parms->texwidth * CleanXfac;
parms->destheight = parms->texheight * CleanYfac;
}
else
{
if (intval == HUD_HorizCenter)
parms->x += Width * 0.5;
else if (xright)
parms->x = Width + parms->x;
if (ybot)
parms->y = Height + parms->y;
}
}
break;
case DTA_VirtualWidth:
parms->virtWidth = va_arg(tags, int);
break;
case DTA_VirtualWidthF:
parms->virtWidth = va_arg(tags, double);
break;
case DTA_VirtualHeight:
parms->virtHeight = va_arg(tags, int);
break;
case DTA_VirtualHeightF:
parms->virtHeight = va_arg(tags, double);
break;
case DTA_Fullscreen:
boolval = va_arg(tags, INTBOOL);
if (boolval)
{
parms->x = parms->y = 0;
parms->virtWidth = img->GetScaledWidthDouble();
parms->virtHeight = img->GetScaledHeightDouble();
}
break;
case DTA_Alpha:
parms->alpha = MIN<fixed_t>(FRACUNIT, va_arg (tags, fixed_t));
break;
case DTA_AlphaChannel:
parms->alphaChannel = va_arg(tags, INTBOOL);
break;
case DTA_FillColor:
parms->fillcolor = va_arg(tags, uint32);
fillcolorset = true;
break;
case DTA_Translation:
parms->remap = va_arg(tags, FRemapTable *);
if (parms->remap != NULL && parms->remap->Inactive)
{ // If it's inactive, pretend we were passed NULL instead.
parms->remap = NULL;
}
break;
case DTA_ColorOverlay:
parms->colorOverlay = va_arg(tags, DWORD);
break;
case DTA_FlipX:
parms->flipX = va_arg(tags, INTBOOL);
break;
case DTA_TopOffset:
parms->top = va_arg(tags, int);
break;
case DTA_TopOffsetF:
parms->top = va_arg(tags, double);
break;
case DTA_LeftOffset:
parms->left = va_arg(tags, int);
break;
case DTA_LeftOffsetF:
parms->left = va_arg(tags, double);
break;
case DTA_CenterOffset:
if (va_arg(tags, int))
{
parms->left = parms->texwidth * 0.5;
parms->top = parms->texheight * 0.5;
}
break;
case DTA_CenterBottomOffset:
if (va_arg(tags, int))
{
parms->left = parms->texwidth * 0.5;
parms->top = parms->texheight;
}
break;
case DTA_WindowLeft:
parms->windowleft = va_arg(tags, int);
break;
case DTA_WindowLeftF:
parms->windowleft = va_arg(tags, double);
break;
case DTA_WindowRight:
parms->windowright = va_arg(tags, int);
break;
case DTA_WindowRightF:
parms->windowright = va_arg(tags, double);
break;
case DTA_ClipTop:
parms->uclip = va_arg(tags, int);
if (parms->uclip < 0)
{
parms->uclip = 0;
}
break;
case DTA_ClipBottom:
parms->dclip = va_arg(tags, int);
if (parms->dclip > this->GetHeight())
{
parms->dclip = this->GetHeight();
}
break;
case DTA_ClipLeft:
parms->lclip = va_arg(tags, int);
if (parms->lclip < 0)
{
parms->lclip = 0;
}
break;
case DTA_ClipRight:
parms->rclip = va_arg(tags, int);
if (parms->rclip > this->GetWidth())
{
parms->rclip = this->GetWidth();
}
break;
case DTA_ShadowAlpha:
parms->shadowAlpha = MIN<fixed_t>(FRACUNIT, va_arg (tags, fixed_t));
break;
case DTA_ShadowColor:
parms->shadowColor = va_arg(tags, int);
break;
case DTA_Shadow:
boolval = va_arg(tags, INTBOOL);
if (boolval)
{
parms->shadowAlpha = FRACUNIT/2;
parms->shadowColor = 0;
}
else
{
parms->shadowAlpha = 0;
}
break;
case DTA_Masked:
parms->masked = va_arg(tags, INTBOOL);
break;
case DTA_BilinearFilter:
parms->bilinear = va_arg(tags, INTBOOL);
break;
case DTA_KeepRatio:
// I think this is a terribly misleading name, since it actually turns
// *off* aspect ratio correction.
parms->keepratio = va_arg(tags, INTBOOL);
break;
case DTA_RenderStyle:
parms->style.AsDWORD = va_arg(tags, DWORD);
break;
case DTA_SpecialColormap:
parms->specialcolormap = va_arg(tags, FSpecialColormap *);
break;
case DTA_ColormapStyle:
parms->colormapstyle = va_arg(tags, FColormapStyle *);
break;
}
tag = va_arg(tags, DWORD);
}
va_end (tags);
if (parms->uclip >= parms->dclip || parms->lclip >= parms->rclip)
{
return false;
}
if (parms->virtWidth != Width || parms->virtHeight != Height)
{
VirtualToRealCoords(parms->x, parms->y, parms->destwidth, parms->destheight,
parms->virtWidth, parms->virtHeight, virtBottom, !parms->keepratio);
}
if (parms->destwidth <= 0 || parms->destheight <= 0)
{
return false;
}
if (parms->remap != NULL)
{
parms->translation = parms->remap->Remap;
}
if (parms->style.BlendOp == 255)
{
if (fillcolorset)
{
if (parms->alphaChannel)
{
parms->style = STYLE_Shaded;
}
else if (parms->alpha < FRACUNIT)
{
parms->style = STYLE_TranslucentStencil;
}
else
{
parms->style = STYLE_Stencil;
}
}
else if (parms->alpha < FRACUNIT)
{
parms->style = STYLE_Translucent;
}
else
{
parms->style = STYLE_Normal;
}
}
return true;
}