# Conflicts:
#	src/r_draw.cpp
This commit is contained in:
Rachael Alexanderson 2016-12-04 09:33:06 -05:00
commit 7f86a5148c
5 changed files with 293 additions and 143 deletions

View file

@ -1144,7 +1144,7 @@ CCMD(currentpos)
} }
else else
{ {
Printf("You are not in game!"); Printf("You are not in game!\n");
} }
} }

View file

@ -2300,16 +2300,15 @@ void R_DrawSingleSkyCol1(uint32_t solid_top, uint32_t solid_bottom)
void R_DrawSingleSkyCol4(uint32_t solid_top, uint32_t solid_bottom) void R_DrawSingleSkyCol4(uint32_t solid_top, uint32_t solid_bottom)
{ {
for (int col = 0; col < 4; col++) uint8_t *dest = dc_dest;
{
uint8_t *dest = dc_dest + col;
int count = dc_count; int count = dc_count;
int pitch = dc_pitch; int pitch = dc_pitch;
const uint8_t *source0 = bufplce[col]; const uint8_t *source0[4] = { bufplce[0], bufplce[1], bufplce[2], bufplce[3] };
int textureheight0 = bufheight[0]; int textureheight0 = bufheight[0];
const uint32_t *palette = (const uint32_t *)GPalette.BaseColors;
int32_t frac = vplce[col]; int32_t frac[4] = { (int32_t)vplce[0], (int32_t)vplce[1], (int32_t)vplce[2], (int32_t)vplce[3] };
int32_t fracstep = vince[col]; int32_t fracstep[4] = { (int32_t)vince[0], (int32_t)vince[1], (int32_t)vince[2], (int32_t)vince[3] };
uint8_t output[4];
int start_fade = 2; // How fast it should fade out int start_fade = 2; // How fast it should fade out
@ -2319,40 +2318,108 @@ void R_DrawSingleSkyCol4(uint32_t solid_top, uint32_t solid_bottom)
int solid_bottom_r = RPART(solid_bottom); int solid_bottom_r = RPART(solid_bottom);
int solid_bottom_g = GPART(solid_bottom); int solid_bottom_g = GPART(solid_bottom);
int solid_bottom_b = BPART(solid_bottom); int solid_bottom_b = BPART(solid_bottom);
uint32_t solid_top_fill = RGB32k.RGB[(solid_top_r >> 3)][(solid_top_g >> 3)][(solid_top_b >> 3)];
uint32_t solid_bottom_fill = RGB32k.RGB[(solid_bottom_r >> 3)][(solid_bottom_g >> 3)][(solid_bottom_b >> 3)];
solid_top_fill = (solid_top_fill << 24) | (solid_top_fill << 16) | (solid_top_fill << 8) | solid_top_fill;
solid_bottom_fill = (solid_bottom_fill << 24) | (solid_bottom_fill << 16) | (solid_bottom_fill << 8) | solid_bottom_fill;
for (int index = 0; index < count; index++) // Find bands for top solid color, top fade, center textured, bottom fade, bottom solid color:
int fade_length = (1 << (24 - start_fade));
int start_fadetop_y = (-frac[0]) / fracstep[0];
int end_fadetop_y = (fade_length - frac[0]) / fracstep[0];
int start_fadebottom_y = ((2 << 24) - fade_length - frac[0]) / fracstep[0];
int end_fadebottom_y = ((2 << 24) - frac[0]) / fracstep[0];
for (int col = 1; col < 4; col++)
{ {
uint32_t sample_index = (((((uint32_t)frac) << 8) >> FRACBITS) * textureheight0) >> FRACBITS; start_fadetop_y = MIN(start_fadetop_y, (-frac[0]) / fracstep[0]);
uint8_t fg = source0[sample_index]; end_fadetop_y = MAX(end_fadetop_y, (fade_length - frac[0]) / fracstep[0]);
start_fadebottom_y = MIN(start_fadebottom_y, ((2 << 24) - fade_length - frac[0]) / fracstep[0]);
int alpha_top = MAX(MIN(frac >> (16 - start_fade), 256), 0); end_fadebottom_y = MAX(end_fadebottom_y, ((2 << 24) - frac[0]) / fracstep[0]);
int alpha_bottom = MAX(MIN(((2 << 24) - frac) >> (16 - start_fade), 256), 0);
if (alpha_top == 256 && alpha_bottom == 256)
{
*dest = fg;
} }
else start_fadetop_y = clamp(start_fadetop_y, 0, count);
{ end_fadetop_y = clamp(end_fadetop_y, 0, count);
int inv_alpha_top = 256 - alpha_top; start_fadebottom_y = clamp(start_fadebottom_y, 0, count);
int inv_alpha_bottom = 256 - alpha_bottom; end_fadebottom_y = clamp(end_fadebottom_y, 0, count);
const auto &c = GPalette.BaseColors[fg]; // Top solid color:
int c_red = c.r; for (int index = 0; index < start_fadetop_y; index++)
int c_green = c.g; {
int c_blue = c.b; *((uint32_t*)dest) = solid_top_fill;
dest += pitch;
for (int col = 0; col < 4; col++)
frac[col] += fracstep[col];
}
// Top fade:
for (int index = start_fadetop_y; index < end_fadetop_y; index++)
{
for (int col = 0; col < 4; col++)
{
uint32_t sample_index = (((((uint32_t)frac[col]) << 8) >> FRACBITS) * textureheight0) >> FRACBITS;
uint8_t fg = source0[col][sample_index];
uint32_t c = palette[fg];
int alpha_top = MAX(MIN(frac[col] >> (16 - start_fade), 256), 0);
int inv_alpha_top = 256 - alpha_top;
int c_red = RPART(c);
int c_green = GPART(c);
int c_blue = BPART(c);
c_red = (c_red * alpha_top + solid_top_r * inv_alpha_top) >> 8; c_red = (c_red * alpha_top + solid_top_r * inv_alpha_top) >> 8;
c_green = (c_green * alpha_top + solid_top_g * inv_alpha_top) >> 8; c_green = (c_green * alpha_top + solid_top_g * inv_alpha_top) >> 8;
c_blue = (c_blue * alpha_top + solid_top_b * inv_alpha_top) >> 8; c_blue = (c_blue * alpha_top + solid_top_b * inv_alpha_top) >> 8;
output[col] = RGB32k.RGB[(c_red >> 3)][(c_green >> 3)][(c_blue >> 3)];
frac[col] += fracstep[col];
}
*((uint32_t*)dest) = *((uint32_t*)output);
dest += pitch;
}
// Textured center:
for (int index = end_fadetop_y; index < start_fadebottom_y; index++)
{
for (int col = 0; col < 4; col++)
{
uint32_t sample_index = (((((uint32_t)frac[col]) << 8) >> FRACBITS) * textureheight0) >> FRACBITS;
output[col] = source0[col][sample_index];
frac[col] += fracstep[col];
}
*((uint32_t*)dest) = *((uint32_t*)output);
dest += pitch;
}
// Fade bottom:
for (int index = start_fadebottom_y; index < end_fadebottom_y; index++)
{
for (int col = 0; col < 4; col++)
{
uint32_t sample_index = (((((uint32_t)frac[col]) << 8) >> FRACBITS) * textureheight0) >> FRACBITS;
uint8_t fg = source0[col][sample_index];
uint32_t c = palette[fg];
int alpha_bottom = MAX(MIN(((2 << 24) - frac[col]) >> (16 - start_fade), 256), 0);
int inv_alpha_bottom = 256 - alpha_bottom;
int c_red = RPART(c);
int c_green = GPART(c);
int c_blue = BPART(c);
c_red = (c_red * alpha_bottom + solid_bottom_r * inv_alpha_bottom) >> 8; c_red = (c_red * alpha_bottom + solid_bottom_r * inv_alpha_bottom) >> 8;
c_green = (c_green * alpha_bottom + solid_bottom_g * inv_alpha_bottom) >> 8; c_green = (c_green * alpha_bottom + solid_bottom_g * inv_alpha_bottom) >> 8;
c_blue = (c_blue * alpha_bottom + solid_bottom_b * inv_alpha_bottom) >> 8; c_blue = (c_blue * alpha_bottom + solid_bottom_b * inv_alpha_bottom) >> 8;
*dest = RGB32k.RGB[(c_red >> 3)][(c_green >> 3)][(c_blue >> 3)]; output[col] = RGB32k.RGB[(c_red >> 3)][(c_green >> 3)][(c_blue >> 3)];
}
frac += fracstep; frac[col] += fracstep[col];
}
*((uint32_t*)dest) = *((uint32_t*)output);
dest += pitch; dest += pitch;
} }
// Bottom solid color:
for (int index = end_fadebottom_y; index < count; index++)
{
*((uint32_t*)dest) = solid_bottom_fill;
dest += pitch;
} }
} }
@ -2420,18 +2487,17 @@ void R_DrawDoubleSkyCol1(uint32_t solid_top, uint32_t solid_bottom)
void R_DrawDoubleSkyCol4(uint32_t solid_top, uint32_t solid_bottom) void R_DrawDoubleSkyCol4(uint32_t solid_top, uint32_t solid_bottom)
{ {
for (int col = 0; col < 4; col++) uint8_t *dest = dc_dest;
{
uint8_t *dest = dc_dest + col;
int count = dc_count; int count = dc_count;
int pitch = dc_pitch; int pitch = dc_pitch;
const uint8_t *source0 = bufplce[col]; const uint8_t *source0[4] = { bufplce[0], bufplce[1], bufplce[2], bufplce[3] };
const uint8_t *source1 = bufplce2[col]; const uint8_t *source1[4] = { bufplce2[0], bufplce2[1], bufplce2[2], bufplce2[3] };
int textureheight0 = bufheight[0]; int textureheight0 = bufheight[0];
uint32_t maxtextureheight1 = bufheight[1] - 1; uint32_t maxtextureheight1 = bufheight[1] - 1;
const uint32_t *palette = (const uint32_t *)GPalette.BaseColors;
int32_t frac = vplce[col]; int32_t frac[4] = { (int32_t)vplce[0], (int32_t)vplce[1], (int32_t)vplce[2], (int32_t)vplce[3] };
int32_t fracstep = vince[col]; int32_t fracstep[4] = { (int32_t)vince[0], (int32_t)vince[1], (int32_t)vince[2], (int32_t)vince[3] };
uint8_t output[4];
int start_fade = 2; // How fast it should fade out int start_fade = 2; // How fast it should fade out
@ -2441,45 +2507,126 @@ void R_DrawDoubleSkyCol4(uint32_t solid_top, uint32_t solid_bottom)
int solid_bottom_r = RPART(solid_bottom); int solid_bottom_r = RPART(solid_bottom);
int solid_bottom_g = GPART(solid_bottom); int solid_bottom_g = GPART(solid_bottom);
int solid_bottom_b = BPART(solid_bottom); int solid_bottom_b = BPART(solid_bottom);
uint32_t solid_top_fill = RGB32k.RGB[(solid_top_r >> 3)][(solid_top_g >> 3)][(solid_top_b >> 3)];
uint32_t solid_bottom_fill = RGB32k.RGB[(solid_bottom_r >> 3)][(solid_bottom_g >> 3)][(solid_bottom_b >> 3)];
solid_top_fill = (solid_top_fill << 24) | (solid_top_fill << 16) | (solid_top_fill << 8) | solid_top_fill;
solid_bottom_fill = (solid_bottom_fill << 24) | (solid_bottom_fill << 16) | (solid_bottom_fill << 8) | solid_bottom_fill;
for (int index = 0; index < count; index++) // Find bands for top solid color, top fade, center textured, bottom fade, bottom solid color:
int fade_length = (1 << (24 - start_fade));
int start_fadetop_y = (-frac[0]) / fracstep[0];
int end_fadetop_y = (fade_length - frac[0]) / fracstep[0];
int start_fadebottom_y = ((2 << 24) - fade_length - frac[0]) / fracstep[0];
int end_fadebottom_y = ((2 << 24) - frac[0]) / fracstep[0];
for (int col = 1; col < 4; col++)
{ {
uint32_t sample_index = (((((uint32_t)frac) << 8) >> FRACBITS) * textureheight0) >> FRACBITS; start_fadetop_y = MIN(start_fadetop_y, (-frac[0]) / fracstep[0]);
uint8_t fg = source0[sample_index]; end_fadetop_y = MAX(end_fadetop_y, (fade_length - frac[0]) / fracstep[0]);
start_fadebottom_y = MIN(start_fadebottom_y, ((2 << 24) - fade_length - frac[0]) / fracstep[0]);
end_fadebottom_y = MAX(end_fadebottom_y, ((2 << 24) - frac[0]) / fracstep[0]);
}
start_fadetop_y = clamp(start_fadetop_y, 0, count);
end_fadetop_y = clamp(end_fadetop_y, 0, count);
start_fadebottom_y = clamp(start_fadebottom_y, 0, count);
end_fadebottom_y = clamp(end_fadebottom_y, 0, count);
// Top solid color:
for (int index = 0; index < start_fadetop_y; index++)
{
*((uint32_t*)dest) = solid_top_fill;
dest += pitch;
for (int col = 0; col < 4; col++)
frac[col] += fracstep[col];
}
// Top fade:
for (int index = start_fadetop_y; index < end_fadetop_y; index++)
{
for (int col = 0; col < 4; col++)
{
uint32_t sample_index = (((((uint32_t)frac[col]) << 8) >> FRACBITS) * textureheight0) >> FRACBITS;
uint8_t fg = source0[col][sample_index];
if (fg == 0) if (fg == 0)
{ {
uint32_t sample_index2 = MIN(sample_index, maxtextureheight1); uint32_t sample_index2 = MIN(sample_index, maxtextureheight1);
fg = source1[sample_index2]; fg = source1[col][sample_index2];
} }
output[col] = fg;
int alpha_top = MAX(MIN(frac >> (16 - start_fade), 256), 0); uint32_t c = palette[fg];
int alpha_bottom = MAX(MIN(((2 << 24) - frac) >> (16 - start_fade), 256), 0); int alpha_top = MAX(MIN(frac[col] >> (16 - start_fade), 256), 0);
if (alpha_top == 256 && alpha_bottom == 256)
{
*dest = fg;
}
else
{
int inv_alpha_top = 256 - alpha_top; int inv_alpha_top = 256 - alpha_top;
int inv_alpha_bottom = 256 - alpha_bottom; int c_red = RPART(c);
int c_green = GPART(c);
const auto &c = GPalette.BaseColors[fg]; int c_blue = BPART(c);
int c_red = c.r;
int c_green = c.g;
int c_blue = c.b;
c_red = (c_red * alpha_top + solid_top_r * inv_alpha_top) >> 8; c_red = (c_red * alpha_top + solid_top_r * inv_alpha_top) >> 8;
c_green = (c_green * alpha_top + solid_top_g * inv_alpha_top) >> 8; c_green = (c_green * alpha_top + solid_top_g * inv_alpha_top) >> 8;
c_blue = (c_blue * alpha_top + solid_top_b * inv_alpha_top) >> 8; c_blue = (c_blue * alpha_top + solid_top_b * inv_alpha_top) >> 8;
output[col] = RGB32k.RGB[(c_red >> 3)][(c_green >> 3)][(c_blue >> 3)];
frac[col] += fracstep[col];
}
*((uint32_t*)dest) = *((uint32_t*)output);
dest += pitch;
}
// Textured center:
for (int index = end_fadetop_y; index < start_fadebottom_y; index++)
{
for (int col = 0; col < 4; col++)
{
uint32_t sample_index = (((((uint32_t)frac[col]) << 8) >> FRACBITS) * textureheight0) >> FRACBITS;
uint8_t fg = source0[col][sample_index];
if (fg == 0)
{
uint32_t sample_index2 = MIN(sample_index, maxtextureheight1);
fg = source1[col][sample_index2];
}
output[col] = fg;
frac[col] += fracstep[col];
}
*((uint32_t*)dest) = *((uint32_t*)output);
dest += pitch;
}
// Fade bottom:
for (int index = start_fadebottom_y; index < end_fadebottom_y; index++)
{
for (int col = 0; col < 4; col++)
{
uint32_t sample_index = (((((uint32_t)frac[col]) << 8) >> FRACBITS) * textureheight0) >> FRACBITS;
uint8_t fg = source0[col][sample_index];
if (fg == 0)
{
uint32_t sample_index2 = MIN(sample_index, maxtextureheight1);
fg = source1[col][sample_index2];
}
output[col] = fg;
uint32_t c = palette[fg];
int alpha_bottom = MAX(MIN(((2 << 24) - frac[col]) >> (16 - start_fade), 256), 0);
int inv_alpha_bottom = 256 - alpha_bottom;
int c_red = RPART(c);
int c_green = GPART(c);
int c_blue = BPART(c);
c_red = (c_red * alpha_bottom + solid_bottom_r * inv_alpha_bottom) >> 8; c_red = (c_red * alpha_bottom + solid_bottom_r * inv_alpha_bottom) >> 8;
c_green = (c_green * alpha_bottom + solid_bottom_g * inv_alpha_bottom) >> 8; c_green = (c_green * alpha_bottom + solid_bottom_g * inv_alpha_bottom) >> 8;
c_blue = (c_blue * alpha_bottom + solid_bottom_b * inv_alpha_bottom) >> 8; c_blue = (c_blue * alpha_bottom + solid_bottom_b * inv_alpha_bottom) >> 8;
*dest = RGB32k.RGB[(c_red >> 3)][(c_green >> 3)][(c_blue >> 3)]; output[col] = RGB32k.RGB[(c_red >> 3)][(c_green >> 3)][(c_blue >> 3)];
}
frac += fracstep; frac[col] += fracstep[col];
}
*((uint32_t*)dest) = *((uint32_t*)output);
dest += pitch; dest += pitch;
} }
// Bottom solid color:
for (int index = end_fadebottom_y; index < count; index++)
{
*((uint32_t*)dest) = solid_bottom_fill;
dest += pitch;
} }
} }

View file

@ -258,9 +258,10 @@ extern "C" void R_DrawFuzzColumnP_ASM (void);
extern "C" void R_DrawSpanP_ASM (void); extern "C" void R_DrawSpanP_ASM (void);
extern "C" void R_DrawSpanMaskedP_ASM (void); extern "C" void R_DrawSpanMaskedP_ASM (void);
void R_DrawColumnHorizP_C(void);
#else #else
void R_DrawColumnHorizP_C (void);
void R_DrawColumnP_C (void); void R_DrawColumnP_C (void);
void R_DrawFuzzColumnP_C (void); void R_DrawFuzzColumnP_C (void);
void R_DrawTranslatedColumnP_C (void); void R_DrawTranslatedColumnP_C (void);

View file

@ -863,66 +863,34 @@ void FString::Insert (size_t index, const char *instr, size_t instrlen)
void FString::ReplaceChars (char oldchar, char newchar) void FString::ReplaceChars (char oldchar, char newchar)
{ {
size_t i, j; if (oldchar == '\0')
return;
LockBuffer(); ReplaceChars([&oldchar](char c){ return c == oldchar; }, newchar);
for (i = 0, j = Len(); i < j; ++i)
{
if (Chars[i] == oldchar)
{
Chars[i] = newchar;
}
}
UnlockBuffer();
} }
void FString::ReplaceChars (const char *oldcharset, char newchar) void FString::ReplaceChars (const char *oldcharset, char newchar)
{ {
size_t i, j; if (oldcharset == NULL || oldcharset[0] == '\0')
return;
LockBuffer(); ReplaceChars([&oldcharset](char c){ return strchr(oldcharset, c) != NULL; }, newchar);
for (i = 0, j = Len(); i < j; ++i)
{
if (strchr (oldcharset, Chars[i]) != NULL)
{
Chars[i] = newchar;
}
}
UnlockBuffer();
} }
void FString::StripChars (char killchar) void FString::StripChars (char killchar)
{ {
size_t read, write, mylen; if (killchar == '\0')
return;
LockBuffer(); StripChars([&killchar](char c){ return c == killchar; });
for (read = write = 0, mylen = Len(); read < mylen; ++read)
{
if (Chars[read] != killchar)
{
Chars[write++] = Chars[read];
}
}
Chars[write] = '\0';
ReallocBuffer (write);
UnlockBuffer();
} }
void FString::StripChars (const char *killchars) void FString::StripChars (const char *killcharset)
{ {
size_t read, write, mylen; if (killcharset == NULL || killcharset[0] == '\0')
return;
LockBuffer(); StripChars([&killcharset](char c){ return strchr(killcharset, c) != NULL; });
for (read = write = 0, mylen = Len(); read < mylen; ++read)
{
if (strchr (killchars, Chars[read]) == NULL)
{
Chars[write++] = Chars[read];
}
}
Chars[write] = '\0';
ReallocBuffer (write);
UnlockBuffer();
} }
void FString::MergeChars (char merger) void FString::MergeChars (char merger)

View file

@ -236,11 +236,45 @@ public:
void Insert (size_t index, const char *instr); void Insert (size_t index, const char *instr);
void Insert (size_t index, const char *instr, size_t instrlen); void Insert (size_t index, const char *instr, size_t instrlen);
template<typename Func>
void ReplaceChars (Func IsOldChar, char newchar)
{
size_t i, j;
LockBuffer();
for (i = 0, j = Len(); i < j; ++i)
{
if (IsOldChar(Chars[i]))
{
Chars[i] = newchar;
}
}
UnlockBuffer();
}
void ReplaceChars (char oldchar, char newchar); void ReplaceChars (char oldchar, char newchar);
void ReplaceChars (const char *oldcharset, char newchar); void ReplaceChars (const char *oldcharset, char newchar);
template<typename Func>
void StripChars (Func IsKillChar)
{
size_t read, write, mylen;
LockBuffer();
for (read = write = 0, mylen = Len(); read < mylen; ++read)
{
if (!IsKillChar(Chars[read]))
{
Chars[write++] = Chars[read];
}
}
Chars[write] = '\0';
ReallocBuffer (write);
UnlockBuffer();
}
void StripChars (char killchar); void StripChars (char killchar);
void StripChars (const char *killchars); void StripChars (const char *killcharset);
void MergeChars (char merger); void MergeChars (char merger);
void MergeChars (char merger, char newchar); void MergeChars (char merger, char newchar);