Stip stippled transparency
This commit is contained in:
parent
cf9b5ae79d
commit
b6bdbcfc98
7 changed files with 23 additions and 228 deletions
|
|
@ -87,20 +87,6 @@ void DrawHalfTransparentBlendedRectTo(const Surface &out, unsigned sx, unsigned
|
|||
// Now everything is divisible by 4. Draw the aligned part.
|
||||
DrawHalfTransparentAligned32BlendedRectTo(out, sx, sy, width, height);
|
||||
}
|
||||
|
||||
void DrawHalfTransparentStippledRectTo(const Surface &out, int sx, int sy, int width, int height)
|
||||
{
|
||||
BYTE *pix = out.at(sx, sy);
|
||||
|
||||
for (int row = 0; row < height; row++) {
|
||||
for (int col = 0; col < width; col++) {
|
||||
if (((row & 1) != 0 && (col & 1) != 0) || ((row & 1) == 0 && (col & 1) == 0))
|
||||
*pix = 0;
|
||||
pix++;
|
||||
}
|
||||
pix += out.pitch() - width;
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
void DrawHorizontalLine(const Surface &out, Point from, int width, std::uint8_t colorIndex)
|
||||
|
|
@ -169,11 +155,7 @@ void DrawHalfTransparentRectTo(const Surface &out, int sx, int sy, int width, in
|
|||
height = out.h() - sy;
|
||||
}
|
||||
|
||||
if (*sgOptions.Graphics.blendedTransparancy) {
|
||||
DrawHalfTransparentBlendedRectTo(out, sx, sy, width, height);
|
||||
} else {
|
||||
DrawHalfTransparentStippledRectTo(out, sx, sy, width, height);
|
||||
}
|
||||
DrawHalfTransparentBlendedRectTo(out, sx, sy, width, height);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -537,32 +537,6 @@ void CelBlitSafeTo(const Surface &out, Point position, const byte *pRLEBytes, in
|
|||
RenderCel(out, position, pRLEBytes, nDataSize, nWidth, RenderLineMemcpy, NullLineEndFn);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Same as CelBlitLightSafeTo but with stippled transparency applied
|
||||
* @param out Target buffer
|
||||
* @param position Target buffer coordinate
|
||||
* @param pRLEBytes CEL pixel stream (run-length encoded)
|
||||
* @param nDataSize Size of CEL in bytes
|
||||
*/
|
||||
void CelBlitLightTransSafeTo(const Surface &out, Point position, const byte *pRLEBytes, int nDataSize, int nWidth)
|
||||
{
|
||||
assert(pRLEBytes != nullptr);
|
||||
const std::uint8_t *tbl = &LightTables[LightTableIndex * 256];
|
||||
bool shift = (reinterpret_cast<uintptr_t>(&out[position]) % 2 == 1);
|
||||
const bool pitchIsEven = (out.pitch() % 2 == 0);
|
||||
RenderCel(
|
||||
out, position, pRLEBytes, nDataSize, nWidth,
|
||||
[tbl, &shift](std::uint8_t *dst, const std::uint8_t *src, std::size_t width) {
|
||||
if (reinterpret_cast<uintptr_t>(dst) % 2 == (shift ? 1 : 0)) {
|
||||
++dst, ++src, --width;
|
||||
}
|
||||
for (const auto *dstEnd = dst + width; dst < dstEnd; dst += 2, src += 2) {
|
||||
*dst = tbl[*src];
|
||||
}
|
||||
},
|
||||
[pitchIsEven, &shift]() { if (pitchIsEven) shift = !shift; });
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Same as CelBlitLightSafe, with blended transparency applied
|
||||
* @param out The output buffer
|
||||
|
|
@ -665,10 +639,7 @@ void CelClippedBlitLightTransTo(const Surface &out, Point position, const CelSpr
|
|||
const byte *pRLEBytes = CelGetFrameClipped(cel.Data(), frame, &nDataSize);
|
||||
|
||||
if (cel_transparency_active) {
|
||||
if (*sgOptions.Graphics.blendedTransparancy)
|
||||
CelBlitLightBlendedSafeTo(out, position, pRLEBytes, nDataSize, cel.Width(frame), nullptr);
|
||||
else
|
||||
CelBlitLightTransSafeTo(out, position, pRLEBytes, nDataSize, cel.Width(frame));
|
||||
CelBlitLightBlendedSafeTo(out, position, pRLEBytes, nDataSize, cel.Width(frame), nullptr);
|
||||
} else if (LightTableIndex != 0)
|
||||
CelBlitLightSafeTo(out, position, pRLEBytes, nDataSize, cel.Width(frame), nullptr);
|
||||
else
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ void CelDrawLightTo(const Surface &out, Point position, const CelSprite &cel, in
|
|||
void CelClippedDrawLightTo(const Surface &out, Point position, const CelSprite &cel, int frame);
|
||||
|
||||
/**
|
||||
* @brief Same as CelBlitLightTransSafeTo
|
||||
* @brief Same as CelBlitLightSafeTo but with transparency applied
|
||||
* @param out Target buffer
|
||||
* @param position Target buffer coordinate
|
||||
* @param cel CEL sprite
|
||||
|
|
|
|||
|
|
@ -239,111 +239,6 @@ const std::uint32_t LeftMaskTransparent[TILE_HEIGHT] = {
|
|||
0xFFFFFFFF,
|
||||
0xFFFFFFFF
|
||||
};
|
||||
/** Specifies the draw masks used to render transparency of the right side of tiles. */
|
||||
const std::uint32_t RightMask[TILE_HEIGHT] = {
|
||||
0xEAAAAAAA,
|
||||
0xF5555555,
|
||||
0xFEAAAAAA,
|
||||
0xFF555555,
|
||||
0xFFEAAAAA,
|
||||
0xFFF55555,
|
||||
0xFFFEAAAA,
|
||||
0xFFFF5555,
|
||||
0xFFFFEAAA,
|
||||
0xFFFFF555,
|
||||
0xFFFFFEAA,
|
||||
0xFFFFFF55,
|
||||
0xFFFFFFEA,
|
||||
0xFFFFFFF5,
|
||||
0xFFFFFFFE,
|
||||
0xFFFFFFFF,
|
||||
0xFFFFFFFF,
|
||||
0xFFFFFFFF,
|
||||
0xFFFFFFFF,
|
||||
0xFFFFFFFF,
|
||||
0xFFFFFFFF,
|
||||
0xFFFFFFFF,
|
||||
0xFFFFFFFF,
|
||||
0xFFFFFFFF,
|
||||
0xFFFFFFFF,
|
||||
0xFFFFFFFF,
|
||||
0xFFFFFFFF,
|
||||
0xFFFFFFFF,
|
||||
0xFFFFFFFF,
|
||||
0xFFFFFFFF,
|
||||
0xFFFFFFFF,
|
||||
0xFFFFFFFF
|
||||
};
|
||||
/** Specifies the draw masks used to render transparency of the left side of tiles. */
|
||||
const std::uint32_t LeftMask[TILE_HEIGHT] = {
|
||||
0xAAAAAAAB,
|
||||
0x5555555F,
|
||||
0xAAAAAABF,
|
||||
0x555555FF,
|
||||
0xAAAAABFF,
|
||||
0x55555FFF,
|
||||
0xAAAABFFF,
|
||||
0x5555FFFF,
|
||||
0xAAABFFFF,
|
||||
0x555FFFFF,
|
||||
0xAABFFFFF,
|
||||
0x55FFFFFF,
|
||||
0xABFFFFFF,
|
||||
0x5FFFFFFF,
|
||||
0xBFFFFFFF,
|
||||
0xFFFFFFFF,
|
||||
0xFFFFFFFF,
|
||||
0xFFFFFFFF,
|
||||
0xFFFFFFFF,
|
||||
0xFFFFFFFF,
|
||||
0xFFFFFFFF,
|
||||
0xFFFFFFFF,
|
||||
0xFFFFFFFF,
|
||||
0xFFFFFFFF,
|
||||
0xFFFFFFFF,
|
||||
0xFFFFFFFF,
|
||||
0xFFFFFFFF,
|
||||
0xFFFFFFFF,
|
||||
0xFFFFFFFF,
|
||||
0xFFFFFFFF,
|
||||
0xFFFFFFFF,
|
||||
0xFFFFFFFF
|
||||
};
|
||||
/** Specifies the draw masks used to render transparency of wall tiles. */
|
||||
const std::uint32_t WallMask[TILE_HEIGHT] = {
|
||||
0xAAAAAAAA,
|
||||
0x55555555,
|
||||
0xAAAAAAAA,
|
||||
0x55555555,
|
||||
0xAAAAAAAA,
|
||||
0x55555555,
|
||||
0xAAAAAAAA,
|
||||
0x55555555,
|
||||
0xAAAAAAAA,
|
||||
0x55555555,
|
||||
0xAAAAAAAA,
|
||||
0x55555555,
|
||||
0xAAAAAAAA,
|
||||
0x55555555,
|
||||
0xAAAAAAAA,
|
||||
0x55555555,
|
||||
0xAAAAAAAA,
|
||||
0x55555555,
|
||||
0xAAAAAAAA,
|
||||
0x55555555,
|
||||
0xAAAAAAAA,
|
||||
0x55555555,
|
||||
0xAAAAAAAA,
|
||||
0x55555555,
|
||||
0xAAAAAAAA,
|
||||
0x55555555,
|
||||
0xAAAAAAAA,
|
||||
0x55555555,
|
||||
0xAAAAAAAA,
|
||||
0x55555555,
|
||||
0xAAAAAAAA,
|
||||
0x55555555
|
||||
};
|
||||
/** Fully opaque mask */
|
||||
const std::uint32_t SolidMask[TILE_HEIGHT] = {
|
||||
0xFFFFFFFF,
|
||||
|
|
@ -491,7 +386,6 @@ DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void ForEachSetBit(std::uint32_t mask, const
|
|||
enum class TransparencyType {
|
||||
Solid,
|
||||
Blended,
|
||||
Stippled,
|
||||
};
|
||||
|
||||
enum class LightType {
|
||||
|
|
@ -558,22 +452,6 @@ DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void RenderLineBlended(std::uint8_t *dst, co
|
|||
#endif
|
||||
}
|
||||
|
||||
template <LightType Light>
|
||||
DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void RenderLineStippled(std::uint8_t *dst, const std::uint8_t *src, const std::uint8_t *tbl, std::uint32_t mask)
|
||||
{
|
||||
if (Light == LightType::FullyDark) {
|
||||
ForEachSetBit(mask, [=](int i) { dst[i] = 0; });
|
||||
} else if (Light == LightType::FullyLit) {
|
||||
#ifndef DEBUG_RENDER_COLOR
|
||||
ForEachSetBit(mask, [=](int i) { dst[i] = src[i]; });
|
||||
#else
|
||||
ForEachSetBit(mask, [=](int i) { dst[i] = DBGCOLOR; });
|
||||
#endif
|
||||
} else { // Partially lit
|
||||
ForEachSetBit(mask, [=](int i) { dst[i] = tbl[src[i]]; });
|
||||
}
|
||||
}
|
||||
|
||||
template <TransparencyType Transparency, LightType Light>
|
||||
DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void RenderLine(std::uint8_t *dst, const std::uint8_t *src, std::uint_fast8_t n, const std::uint8_t *tbl, std::uint32_t mask)
|
||||
{
|
||||
|
|
@ -591,8 +469,6 @@ DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void RenderLine(std::uint8_t *dst, const std
|
|||
RenderLineOpaque<Light>(dst, src, n, tbl);
|
||||
} else if (Transparency == TransparencyType::Blended) {
|
||||
RenderLineBlended<Light>(dst, src, n, tbl, mask);
|
||||
} else {
|
||||
RenderLineStippled<Light>(dst, src, tbl, mask);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1252,24 +1128,18 @@ const std::uint32_t *GetMask(TileType tile)
|
|||
|
||||
if (cel_transparency_active) {
|
||||
if (arch_draw_type == 0) {
|
||||
if (*sgOptions.Graphics.blendedTransparancy) // Use a fully transparent mask
|
||||
return &WallMaskFullyTrasparent[TILE_HEIGHT - 1];
|
||||
return &WallMask[TILE_HEIGHT - 1];
|
||||
return &WallMaskFullyTrasparent[TILE_HEIGHT - 1];
|
||||
}
|
||||
if (arch_draw_type == 1 && tile != TileType::LeftTriangle) {
|
||||
const auto c = block_lvid[level_piece_id];
|
||||
if (c == 1 || c == 3) {
|
||||
if (*sgOptions.Graphics.blendedTransparancy) // Use a fully transparent mask
|
||||
return &LeftMaskTransparent[TILE_HEIGHT - 1];
|
||||
return &LeftMask[TILE_HEIGHT - 1];
|
||||
return &LeftMaskTransparent[TILE_HEIGHT - 1];
|
||||
}
|
||||
}
|
||||
if (arch_draw_type == 2 && tile != TileType::RightTriangle) {
|
||||
const auto c = block_lvid[level_piece_id];
|
||||
if (c == 2 || c == 3) {
|
||||
if (*sgOptions.Graphics.blendedTransparancy) // Use a fully transparent mask
|
||||
return &RightMaskTransparent[TILE_HEIGHT - 1];
|
||||
return &RightMask[TILE_HEIGHT - 1];
|
||||
return &RightMaskTransparent[TILE_HEIGHT - 1];
|
||||
}
|
||||
}
|
||||
} else if (arch_draw_type != 0 && cel_foliage_active) {
|
||||
|
|
@ -1412,22 +1282,12 @@ void RenderTile(const Surface &out, Point position)
|
|||
}
|
||||
} else {
|
||||
mask -= clip.bottom;
|
||||
if (*sgOptions.Graphics.blendedTransparancy) {
|
||||
if (LightTableIndex == LightsMax) {
|
||||
RenderTileType<TransparencyType::Blended, LightType::FullyDark>(tile, dst, dstPitch, src, mask, tbl, clip);
|
||||
} else if (LightTableIndex == 0) {
|
||||
RenderTileType<TransparencyType::Blended, LightType::FullyLit>(tile, dst, dstPitch, src, mask, tbl, clip);
|
||||
} else {
|
||||
RenderTileType<TransparencyType::Blended, LightType::PartiallyLit>(tile, dst, dstPitch, src, mask, tbl, clip);
|
||||
}
|
||||
if (LightTableIndex == LightsMax) {
|
||||
RenderTileType<TransparencyType::Blended, LightType::FullyDark>(tile, dst, dstPitch, src, mask, tbl, clip);
|
||||
} else if (LightTableIndex == 0) {
|
||||
RenderTileType<TransparencyType::Blended, LightType::FullyLit>(tile, dst, dstPitch, src, mask, tbl, clip);
|
||||
} else {
|
||||
if (LightTableIndex == LightsMax) {
|
||||
RenderTileType<TransparencyType::Stippled, LightType::FullyDark>(tile, dst, dstPitch, src, mask, tbl, clip);
|
||||
} else if (LightTableIndex == 0) {
|
||||
RenderTileType<TransparencyType::Stippled, LightType::FullyLit>(tile, dst, dstPitch, src, mask, tbl, clip);
|
||||
} else {
|
||||
RenderTileType<TransparencyType::Stippled, LightType::PartiallyLit>(tile, dst, dstPitch, src, mask, tbl, clip);
|
||||
}
|
||||
RenderTileType<TransparencyType::Blended, LightType::PartiallyLit>(tile, dst, dstPitch, src, mask, tbl, clip);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -179,12 +179,6 @@ void SetIniValue(const char *keyname, const char *valuename, int value)
|
|||
GetIni().SetLongValue(keyname, valuename, value, nullptr, false, true);
|
||||
}
|
||||
|
||||
void SetIniValue(const char *keyname, const char *valuename, std::uint8_t value)
|
||||
{
|
||||
IniChangedChecker changedChecker(keyname, valuename);
|
||||
GetIni().SetLongValue(keyname, valuename, value, nullptr, false, true);
|
||||
}
|
||||
|
||||
void SetIniValue(const char *keyname, const char *valuename, std::uint32_t value)
|
||||
{
|
||||
IniChangedChecker changedChecker(keyname, valuename);
|
||||
|
|
@ -780,7 +774,6 @@ GraphicsOptions::GraphicsOptions()
|
|||
, integerScaling("Integer Scaling", OptionEntryFlags::CantChangeInGame | OptionEntryFlags::RecreateUI, N_("Integer Scaling"), N_("Scales the image using whole number pixel ratio."), false)
|
||||
, vSync("Vertical Sync", OptionEntryFlags::RecreateUI, N_("Vertical Sync"), N_("Forces waiting for Vertical Sync. Prevents tearing effect when drawing a frame. Disabling it can help with mouse lag on some systems."), true)
|
||||
#endif
|
||||
, blendedTransparancy("Blended Transparency", OptionEntryFlags::CantChangeInGame, N_("Blended Transparency"), N_("Enables uniform transparency mode. This setting affects the transparency on walls, game text menus, and boxes. If disabled will default to old checkerboard transparency."), true)
|
||||
, colorCycling("Color Cycling", OptionEntryFlags::None, N_("Color Cycling"), N_("Color cycling effect used for water, lava, and acid animation."), true)
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
||||
, hardwareCursor("Hardware Cursor", OptionEntryFlags::CantChangeInGame | OptionEntryFlags::RecreateUI | (HardwareCursorSupported() ? OptionEntryFlags::None : OptionEntryFlags::Invisible), N_("Hardware Cursor"), N_("Use a hardware cursor"), HardwareCursorDefault())
|
||||
|
|
@ -820,7 +813,6 @@ std::vector<OptionEntryBase *> GraphicsOptions::GetEntries()
|
|||
&integerScaling,
|
||||
&vSync,
|
||||
#endif
|
||||
&blendedTransparancy,
|
||||
&colorCycling,
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
||||
&hardwareCursor,
|
||||
|
|
|
|||
|
|
@ -390,8 +390,6 @@ struct GraphicsOptions : OptionCategoryBase {
|
|||
/** @brief Enable vsync on the output. */
|
||||
OptionEntryBoolean vSync;
|
||||
#endif
|
||||
/** @brief Use blended transparency rather than stippled. */
|
||||
OptionEntryBoolean blendedTransparancy;
|
||||
/** @brief Gamma correction level. */
|
||||
int nGammaCorrection;
|
||||
/** @brief Enable color cycling animations. */
|
||||
|
|
|
|||
|
|
@ -118,9 +118,6 @@ void CycleColors(int from, int to)
|
|||
system_palette[to] = col;
|
||||
}
|
||||
|
||||
if (!*sgOptions.Graphics.blendedTransparancy)
|
||||
return;
|
||||
|
||||
for (auto &palette : paletteTransparencyLookup) {
|
||||
Uint8 col = palette[from];
|
||||
for (int j = from; j < to; j++) {
|
||||
|
|
@ -152,9 +149,6 @@ void CycleColorsReverse(int from, int to)
|
|||
system_palette[from] = col;
|
||||
}
|
||||
|
||||
if (!*sgOptions.Graphics.blendedTransparancy)
|
||||
return;
|
||||
|
||||
for (auto &palette : paletteTransparencyLookup) {
|
||||
Uint8 col = palette[to];
|
||||
for (int j = to; j > from; j--) {
|
||||
|
|
@ -224,7 +218,7 @@ void LoadPalette(const char *pszFileName, bool blend /*= true*/)
|
|||
#endif
|
||||
}
|
||||
|
||||
if (blend && *sgOptions.Graphics.blendedTransparancy) {
|
||||
if (blend) {
|
||||
if (leveltype == DTYPE_CAVES || leveltype == DTYPE_CRYPT) {
|
||||
GenerateBlendedLookupTable(orig_palette, 1, 31);
|
||||
} else if (leveltype == DTYPE_NEST) {
|
||||
|
|
@ -407,20 +401,18 @@ void palette_update_quest_palette(int n)
|
|||
logical_palette[i] = orig_palette[i];
|
||||
ApplyGamma(system_palette, logical_palette, 32);
|
||||
palette_update(0, 31);
|
||||
if (*sgOptions.Graphics.blendedTransparancy) {
|
||||
// Update blended transparency, but only for the color that was updated
|
||||
for (int j = 0; j < 256; j++) {
|
||||
if (i == j) { // No need to calculate transparency between 2 identical colors
|
||||
paletteTransparencyLookup[i][j] = j;
|
||||
continue;
|
||||
}
|
||||
SDL_Color blendedColor;
|
||||
blendedColor.r = ((int)logical_palette[i].r + (int)logical_palette[j].r) / 2;
|
||||
blendedColor.g = ((int)logical_palette[i].g + (int)logical_palette[j].g) / 2;
|
||||
blendedColor.b = ((int)logical_palette[i].b + (int)logical_palette[j].b) / 2;
|
||||
Uint8 best = FindBestMatchForColor(logical_palette, blendedColor, 1, 31);
|
||||
paletteTransparencyLookup[i][j] = paletteTransparencyLookup[j][i] = best;
|
||||
// Update blended transparency, but only for the color that was updated
|
||||
for (int j = 0; j < 256; j++) {
|
||||
if (i == j) { // No need to calculate transparency between 2 identical colors
|
||||
paletteTransparencyLookup[i][j] = j;
|
||||
continue;
|
||||
}
|
||||
SDL_Color blendedColor;
|
||||
blendedColor.r = ((int)logical_palette[i].r + (int)logical_palette[j].r) / 2;
|
||||
blendedColor.g = ((int)logical_palette[i].g + (int)logical_palette[j].g) / 2;
|
||||
blendedColor.b = ((int)logical_palette[i].b + (int)logical_palette[j].b) / 2;
|
||||
Uint8 best = FindBestMatchForColor(logical_palette, blendedColor, 1, 31);
|
||||
paletteTransparencyLookup[i][j] = paletteTransparencyLookup[j][i] = best;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue