Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision

Target

Select target project
  • STJr/SRB2
  • Sryder/SRB2
  • wolfy852/SRB2
  • Alpha2244/SRB2
  • Inuyasha/SRB2
  • yoshibot/SRB2
  • TehRealSalt/SRB2
  • PrisimaTF/SRB2
  • Hatninja/SRB2
  • SteelT/SRB2
  • james/SRB2
  • ShaderWraith/SRB2
  • SinnamonLat/SRB2
  • mazmazz_/SRB2
  • filpAM/SRB2
  • chaoloveicemdboy/SRB2
  • Whooa21/SRB2
  • Machturne/SRB2
  • Golden/SRB2
  • Tatsuru/SRB2
  • Snu/SRB2
  • Zwip-Zwap_Zapony/SRB2
  • fickleheart/SRB2
  • alphaRexJames/SRB2
  • JJK/SRB2
  • diskpoppy/SRB2
  • Hannu_Hanhi/SRB2
  • ZipperQR/SRB2
  • kays/SRB2
  • spherallic/SRB2
  • Zippy_Zolton/SRB2
  • namiishere/SRB2
  • Ors/SRB2
  • SMS_Alfredo/SRB2
  • sonic_edge/SRB2
  • lavla/SRB2
  • ashi/SRB2
  • X.organic/SRB2
  • Fafabis/SRB2
  • Meziu/SRB2
  • v-rob/SRB2
  • tertu/SRB2
  • bitten2up/SRB2
  • flarn2006/SRB2
  • Krabs/SRB2
  • clairebun/SRB2
  • Lactozilla/SRB2
  • thehackstack/SRB2
  • Spice/SRB2
  • win8linux/SRB2
  • JohnFrostFox/SRB2
  • talktoneon726/SRB2
  • Wane/SRB2
  • Lamibe/SRB2
  • spectrumuk2/srb-2
  • nerdyminer18/srb-2
  • 256nil/SRB2
  • ARJr/SRB2
  • Alam/SRB2
  • Zenya/srb-2-marathon-demos
  • Acelite/srb-2-archivedmodifications
  • MIDIMan/SRB2
  • Lach/SRB2
  • Frostiikin/bounce-tweaks
  • Hanicef/SRB2Classic
  • Jaden/SRB2
  • Tyron/SRB2
  • Astronight/SRB2
  • Mari0shi06/SRB2
  • aiire/SRB2
  • Galactice/SRB2
  • srb2-ports/srb2-dreamcast
  • sdasdas/SRB2
  • chreas/srb-2-vr
  • StarManiaKG/the-story-of-sinically-rocketing-and-botching-the-2nd
  • LoganAir/SRB2
  • NepDisk/srb-2
  • alufolie91/SRB2
  • Felicia.iso/SRB2
  • twi/SRB2
  • BarrelsOFun/SRB2
  • Speed2411/SRB2
  • Leather_Realms/SRB2
  • Ayemar/SRB2
  • Acelite/SRB2
  • VladDoc/SRB2
  • kaldrum/model-features
  • strawberryfox417/SRB2
  • Lugent/SRB2
  • Jisk/SRB2
  • Rem/SRB2
  • Refrag/SRB2
  • Henry_3230/srb-3230
  • TehPuertoRicanSpartan2/tprs-srb2
  • Leminn/srb-2-marathon-stuff
  • chromaticpipe2/SRB2
  • MiguelGustavo15/SRB2
  • Maru/srb-2-tests
  • SilicDev/SRB2
  • UnmatchedBracket/SRB2
  • HybridDog/SRB2
  • xordspar0/SRB2
  • jsjhbewfhh/SRB2
  • Fancy2209/SRB2
  • Lorsoen/SRB2
  • shindoukin/SRB2
  • GamerOfDays/SRB2
  • Craftyawesome/SRB2
  • tenshi-tensai-tennoji/SRB2
  • Scarfdudebalder/SRB2
  • luigi-budd/srb-2-fix-interplag-lockon
  • mskluesner/SRB2
  • johnpetersa19/SRB2
  • Pheazant/SRB2
  • chromaticpipe2/srb2classic
  • romoney5/SRB2
  • PAS/SRB2Classic
  • BlueStaggo/SRB2
118 results
Select Git revision
Show changes
Commits on Source (5)
......@@ -8,10 +8,11 @@
#include "utils/Log.h"
rendermode_t rendermode = render_soft;
rendermode_t rendermode = render_software;
rendermode_t chosenrendermode = render_none;
boolean highcolor = false;
boolean truecolor = false;
boolean allow_fullscreen = false;
......@@ -53,6 +54,16 @@ INT32 VID_SetMode(INT32 modenum)
return 0;
}
boolean VID_IsASoftwareRenderer(rendermode_t mode)
{
return (mode == render_software);
}
boolean VID_InSoftwareRenderer(void)
{
return VID_IsASoftwareRenderer(rendermode);
}
boolean VID_CheckRenderer(void)
{
return false;
......
......@@ -333,7 +333,7 @@ static void D_Display(void)
SCR_Recalc(); // NOTE! setsizeneeded is set by SCR_Recalc()
// View morph
if (rendermode == render_soft && !splitscreen)
if (VID_InSoftwareRenderer() && !splitscreen)
R_CheckViewMorph();
// Change the view size if needed
......@@ -475,20 +475,28 @@ static void D_Display(void)
if (gamestate == GS_LEVEL || (gamestate == GS_TITLESCREEN && titlemapinaction && curbghide && (!hidetitlemap)))
{
// draw the view directly
if (!automapactive && !dedicated && cv_renderview.value)
{
SCR_SetSoftwareTranslucency(); // Set translucency method
if (!usetranstables)
R_InitAlphaLUT();
R_ApplyLevelInterpolators(R_UsingFrameInterpolation() ? rendertimefrac : FRACUNIT);
PS_START_TIMING(ps_rendercalltime);
if (players[displayplayer].mo || players[displayplayer].playerstate == PST_DEAD)
{
topleft = screens[0] + viewwindowy*vid.width + viewwindowx;
#ifdef TRUECOLOR
if (truecolor)
topleft_u32 = (UINT32 *)screens[0] + viewwindowy*vid.width + viewwindowx;
#endif
objectsdrawn = 0;
#ifdef HWRENDER
if (rendermode != render_soft)
#ifdef HWRENDER
if (!VID_InSoftwareRenderer())
HWR_RenderPlayerView(0, &players[displayplayer]);
else
#endif
#endif
if (rendermode != render_none)
R_RenderPlayerView(&players[displayplayer]);
}
......@@ -496,17 +504,21 @@ static void D_Display(void)
// render the second screen
if (splitscreen && players[secondarydisplayplayer].mo)
{
#ifdef HWRENDER
if (rendermode != render_soft)
#ifdef HWRENDER
if (!VID_InSoftwareRenderer())
HWR_RenderPlayerView(1, &players[secondarydisplayplayer]);
else
#endif
#endif
if (rendermode != render_none)
{
viewwindowy = vid.height / 2;
M_Memcpy(ylookup, ylookup2, viewheight*sizeof (ylookup[0]));
topleft = screens[0] + viewwindowy*vid.width + viewwindowx;
#ifdef TRUECOLOR
if (truecolor)
topleft_u32 = (UINT32 *)screens[0] + viewwindowy*vid.width + viewwindowx;
#endif
R_RenderPlayerView(&players[secondarydisplayplayer]);
......@@ -516,7 +528,7 @@ static void D_Display(void)
}
// Image postprocessing effect
if (rendermode == render_soft)
if (VID_InSoftwareRenderer())
{
if (!splitscreen)
R_ApplyViewMorph();
......@@ -532,7 +544,7 @@ static void D_Display(void)
if (lastdraw)
{
if (rendermode == render_soft)
if (VID_InSoftwareRenderer())
{
VID_BlitLinearScreen(screens[0], screens[1], vid.width*vid.bpp, vid.height, vid.width*vid.bpp, vid.rowbytes);
Y_ConsiderScreenBuffer();
......@@ -688,6 +700,26 @@ static void D_Display(void)
}
}
void D_CheckColorDepth(INT32 newbitdepth, INT32 oldbitdepth)
{
#ifdef TRUECOLOR
if (oldbitdepth == 0) // Video init
return;
if (newbitdepth != oldbitdepth)
{
// Reload every texture.
R_FlushTextureCache();
// Also free levelflat pictures.
R_ClearLevelFlats();
}
#else
(void)newbitdepth;
(void)oldbitdepth;
#endif
}
// =========================================================================
// D_SRB2Loop
// =========================================================================
......
......@@ -47,6 +47,12 @@ const char *D_Home(void);
boolean D_IsPathAllowed(const char *path);
boolean D_CheckPathAllowed(const char *path, const char *why);
//
// RENDERER STATE
//
void D_CheckRendererState(void);
void D_CheckColorDepth(INT32 newbitdepth, INT32 oldbitdepth);
//
// BASE LEVEL
//
......
......@@ -2837,7 +2837,6 @@ void readsound(MYFILE *f, INT32 num)
tmp = strchr(s, '\n');
if (tmp)
*tmp = '\0';
tmp = strchr(s, '#');
if (tmp)
*tmp = '\0';
......
......@@ -659,6 +659,12 @@ extern const char *compdate, *comptime, *comprevision, *compbranch;
/// Render flats on walls
#define WALLFLATS
/// Software true color mode rendering
#ifndef NO_TRUECOLOR
#define TRUECOLOR
#endif
/// Maintain compatibility with older 2.2 demos
#define OLD22DEMOCOMPAT
......
......@@ -6,6 +6,7 @@ rendermode_t rendermode = render_none;
rendermode_t chosenrendermode = render_none;
boolean highcolor = false;
boolean truecolor = false;
boolean allow_fullscreen = false;
......@@ -41,6 +42,17 @@ INT32 VID_SetMode(INT32 modenum)
return 0;
}
boolean VID_IsASoftwareRenderer(rendermode_t mode)
{
(void)mode;
return false;
}
boolean VID_InSoftwareRenderer(void)
{
return false;
}
boolean VID_CheckRenderer(void)
{
return false;
......
......@@ -162,10 +162,17 @@ static fademask_t *F_GetFadeMask(UINT8 masknum, UINT8 scrnnum) {
{
// Determine pixel to use from fademask
pcolor = &pMasterPalette[*lump++];
if (wipestyle == WIPESTYLE_COLORMAP)
*mask++ = pcolor->s.red / FADECOLORMAPDIV;
#ifdef TRUECOLOR
if (truecolor)
*mask++ = pcolor->s.red;
else
*mask++ = FixedDiv((pcolor->s.red+1)<<FRACBITS, paldiv)>>FRACBITS;
#endif
{
if (wipestyle == WIPESTYLE_COLORMAP)
*mask++ = pcolor->s.red / FADECOLORMAPDIV;
else
*mask++ = FixedDiv((pcolor->s.red+1)<<FRACBITS, paldiv)>>FRACBITS;
}
}
fm.xscale = FixedDiv(vid.width<<FRACBITS, fm.width<<FRACBITS);
......@@ -200,231 +207,583 @@ void F_WipeStageTitle(void)
}
}
/** Wipe ticker
*
* \param fademask pixels to change
*/
// Software mask wipe -- optimized; though it might not look like it!
// Okay, to save you wondering *how* this is more optimized than the simpler
// version that came before it...
// ---
// The previous code did two FixedMul calls for every single pixel on the
// screen, of which there are hundreds of thousands -- if not millions -- of.
// This worked fine for smaller screen sizes, but with excessively large
// (1920x1200) screens that meant 4 million+ calls out to FixedMul, and that
// would take /just/ long enough that fades would start to noticably lag.
// ---
// This code iterates over the fade mask's pixels instead of the screen's,
// and deals with drawing over each rectangular area before it moves on to
// the next pixel in the fade mask. As a result, it's more complex (and might
// look a little messy; sorry!) but it simultaneously runs at twice the speed.
// In addition, we precalculate all the X and Y positions that we need to draw
// from and to, so it uses a little extra memory, but again, helps it run faster.
static void F_DoWipe(fademask_t *fademask)
{
// Software mask wipe -- optimized; though it might not look like it!
// Okay, to save you wondering *how* this is more optimized than the simpler
// version that came before it...
// wipe screen, start, end
UINT8 *w = wipe_scr;
const UINT8 *s = wipe_scr_start;
const UINT8 *e = wipe_scr_end;
// first pixel for each screen
UINT8 *w_base = w;
const UINT8 *s_base = s;
const UINT8 *e_base = e;
// mask data, end
UINT8 *transtbl;
const UINT8 *mask = fademask->mask;
const UINT8 *maskend = mask + fademask->size;
// rectangle draw hints
UINT32 draw_linestart, draw_rowstart;
UINT32 draw_lineend, draw_rowend;
UINT32 draw_linestogo, draw_rowstogo;
// rectangle coordinates, etc.
UINT16* scrxpos = (UINT16*)malloc((fademask->width + 1) * sizeof(UINT16));
UINT16* scrypos = (UINT16*)malloc((fademask->height + 1) * sizeof(UINT16));
UINT16 maskx, masky;
UINT32 relativepos;
// ---
// The previous code did two FixedMul calls for every single pixel on the
// screen, of which there are hundreds of thousands -- if not millions -- of.
// This worked fine for smaller screen sizes, but with excessively large
// (1920x1200) screens that meant 4 million+ calls out to FixedMul, and that
// would take /just/ long enough that fades would start to noticably lag.
// Screw it, we do the fixed point math ourselves up front.
scrxpos[0] = 0;
for (relativepos = 0, maskx = 1; maskx < fademask->width; ++maskx)
scrxpos[maskx] = (relativepos += fademask->xscale)>>FRACBITS;
scrxpos[fademask->width] = vid.width;
scrypos[0] = 0;
for (relativepos = 0, masky = 1; masky < fademask->height; ++masky)
scrypos[masky] = (relativepos += fademask->yscale)>>FRACBITS;
scrypos[fademask->height] = vid.height;
// ---
// This code iterates over the fade mask's pixels instead of the screen's,
// and deals with drawing over each rectangular area before it moves on to
// the next pixel in the fade mask. As a result, it's more complex (and might
// look a little messy; sorry!) but it simultaneously runs at twice the speed.
// In addition, we precalculate all the X and Y positions that we need to draw
// from and to, so it uses a little extra memory, but again, helps it run faster.
maskx = masky = 0;
do
{
// wipe screen, start, end
UINT8 *w = wipe_scr;
const UINT8 *s = wipe_scr_start;
const UINT8 *e = wipe_scr_end;
// first pixel for each screen
UINT8 *w_base = w;
const UINT8 *s_base = s;
const UINT8 *e_base = e;
// mask data, end
UINT8 *transtbl;
const UINT8 *mask = fademask->mask;
const UINT8 *maskend = mask + fademask->size;
// rectangle draw hints
UINT32 draw_linestart, draw_rowstart;
UINT32 draw_lineend, draw_rowend;
UINT32 draw_linestogo, draw_rowstogo;
// rectangle coordinates, etc.
UINT16* scrxpos = (UINT16*)malloc((fademask->width + 1) * sizeof(UINT16));
UINT16* scrypos = (UINT16*)malloc((fademask->height + 1) * sizeof(UINT16));
UINT16 maskx, masky;
UINT32 relativepos;
// ---
// Screw it, we do the fixed point math ourselves up front.
scrxpos[0] = 0;
for (relativepos = 0, maskx = 1; maskx < fademask->width; ++maskx)
scrxpos[maskx] = (relativepos += fademask->xscale)>>FRACBITS;
scrxpos[fademask->width] = vid.width;
scrypos[0] = 0;
for (relativepos = 0, masky = 1; masky < fademask->height; ++masky)
scrypos[masky] = (relativepos += fademask->yscale)>>FRACBITS;
scrypos[fademask->height] = vid.height;
// ---
maskx = masky = 0;
do
{
draw_rowstart = scrxpos[maskx];
draw_rowend = scrxpos[maskx + 1];
draw_linestart = scrypos[masky];
draw_lineend = scrypos[masky + 1];
draw_rowstart = scrxpos[maskx];
draw_rowend = scrxpos[maskx + 1];
draw_linestart = scrypos[masky];
draw_lineend = scrypos[masky + 1];
relativepos = (draw_linestart * vid.width) + draw_rowstart;
draw_linestogo = draw_lineend - draw_linestart;
relativepos = (draw_linestart * vid.width) + draw_rowstart;
draw_linestogo = draw_lineend - draw_linestart;
if (*mask == 0)
if (*mask == 0)
{
// shortcut - memcpy source to work
while (draw_linestogo--)
{
// shortcut - memcpy source to work
while (draw_linestogo--)
{
M_Memcpy(w_base+relativepos, s_base+relativepos, draw_rowend-draw_rowstart);
relativepos += vid.width;
}
M_Memcpy(w_base+relativepos, s_base+relativepos, draw_rowend-draw_rowstart);
relativepos += vid.width;
}
else if (*mask >= 10)
}
else if (*mask >= 10)
{
// shortcut - memcpy target to work
while (draw_linestogo--)
{
// shortcut - memcpy target to work
while (draw_linestogo--)
{
M_Memcpy(w_base+relativepos, e_base+relativepos, draw_rowend-draw_rowstart);
relativepos += vid.width;
}
M_Memcpy(w_base+relativepos, e_base+relativepos, draw_rowend-draw_rowstart);
relativepos += vid.width;
}
else
{
// pointer to transtable that this mask would use
transtbl = R_GetTranslucencyTable((9 - *mask) + 1);
}
else
{
// pointer to transtable that this mask would use
transtbl = R_GetTranslucencyTable((9 - *mask) + 1);
// DRAWING LOOP
while (draw_linestogo--)
{
w = w_base + relativepos;
s = s_base + relativepos;
e = e_base + relativepos;
draw_rowstogo = draw_rowend - draw_rowstart;
// DRAWING LOOP
while (draw_linestogo--)
{
w = w_base + relativepos;
s = s_base + relativepos;
e = e_base + relativepos;
draw_rowstogo = draw_rowend - draw_rowstart;
while (draw_rowstogo--)
*w++ = transtbl[ ( *e++ << 8 ) + *s++ ];
while (draw_rowstogo--)
*w++ = transtbl[ ( *e++ << 8 ) + *s++ ];
relativepos += vid.width;
}
// END DRAWING LOOP
relativepos += vid.width;
}
// END DRAWING LOOP
}
if (++maskx >= fademask->width)
++masky, maskx = 0;
} while (++mask < maskend);
if (++maskx >= fademask->width)
++masky, maskx = 0;
} while (++mask < maskend);
free(scrxpos);
free(scrypos);
}
free(scrxpos);
free(scrypos);
}
// F_DoWipe for WIPESTYLE_COLORMAP
static void F_DoColormapWipe(fademask_t *fademask, UINT8 *colormap)
{
// Lactozilla: F_DoWipe for WIPESTYLE_COLORMAP
// wipe screen, start, end
UINT8 *w = wipe_scr;
const UINT8 *s = wipe_scr_start;
const UINT8 *e = wipe_scr_end;
// first pixel for each screen
UINT8 *w_base = w;
const UINT8 *s_base = s;
const UINT8 *e_base = e;
// mask data, end
UINT8 *transtbl;
const UINT8 *mask = fademask->mask;
const UINT8 *maskend = mask + fademask->size;
// rectangle draw hints
UINT32 draw_linestart, draw_rowstart;
UINT32 draw_lineend, draw_rowend;
UINT32 draw_linestogo, draw_rowstogo;
// rectangle coordinates, etc.
UINT16* scrxpos = (UINT16*)malloc((fademask->width + 1) * sizeof(UINT16));
UINT16* scrypos = (UINT16*)malloc((fademask->height + 1) * sizeof(UINT16));
UINT16 maskx, masky;
UINT32 relativepos;
// ---
// Screw it, we do the fixed point math ourselves up front.
scrxpos[0] = 0;
for (relativepos = 0, maskx = 1; maskx < fademask->width; ++maskx)
scrxpos[maskx] = (relativepos += fademask->xscale)>>FRACBITS;
scrxpos[fademask->width] = vid.width;
scrypos[0] = 0;
for (relativepos = 0, masky = 1; masky < fademask->height; ++masky)
scrypos[masky] = (relativepos += fademask->yscale)>>FRACBITS;
scrypos[fademask->height] = vid.height;
// ---
maskx = masky = 0;
do
{
// wipe screen, start, end
UINT8 *w = wipe_scr;
const UINT8 *s = wipe_scr_start;
const UINT8 *e = wipe_scr_end;
// first pixel for each screen
UINT8 *w_base = w;
const UINT8 *s_base = s;
const UINT8 *e_base = e;
// mask data, end
UINT8 *transtbl;
const UINT8 *mask = fademask->mask;
const UINT8 *maskend = mask + fademask->size;
// rectangle draw hints
UINT32 draw_linestart, draw_rowstart;
UINT32 draw_lineend, draw_rowend;
UINT32 draw_linestogo, draw_rowstogo;
// rectangle coordinates, etc.
UINT16* scrxpos = (UINT16*)malloc((fademask->width + 1) * sizeof(UINT16));
UINT16* scrypos = (UINT16*)malloc((fademask->height + 1) * sizeof(UINT16));
UINT16 maskx, masky;
UINT32 relativepos;
// ---
// Screw it, we do the fixed point math ourselves up front.
scrxpos[0] = 0;
for (relativepos = 0, maskx = 1; maskx < fademask->width; ++maskx)
scrxpos[maskx] = (relativepos += fademask->xscale)>>FRACBITS;
scrxpos[fademask->width] = vid.width;
scrypos[0] = 0;
for (relativepos = 0, masky = 1; masky < fademask->height; ++masky)
scrypos[masky] = (relativepos += fademask->yscale)>>FRACBITS;
scrypos[fademask->height] = vid.height;
// ---
maskx = masky = 0;
do
draw_rowstart = scrxpos[maskx];
draw_rowend = scrxpos[maskx + 1];
draw_linestart = scrypos[masky];
draw_lineend = scrypos[masky + 1];
relativepos = (draw_linestart * vid.width) + draw_rowstart;
draw_linestogo = draw_lineend - draw_linestart;
if (*mask == 0)
{
// shortcut - memcpy source to work
while (draw_linestogo--)
{
M_Memcpy(w_base+relativepos, s_base+relativepos, draw_rowend-draw_rowstart);
relativepos += vid.width;
}
}
else if (*mask >= FADECOLORMAPROWS)
{
draw_rowstart = scrxpos[maskx];
draw_rowend = scrxpos[maskx + 1];
draw_linestart = scrypos[masky];
draw_lineend = scrypos[masky + 1];
// shortcut - memcpy target to work
while (draw_linestogo--)
{
M_Memcpy(w_base+relativepos, e_base+relativepos, draw_rowend-draw_rowstart);
relativepos += vid.width;
}
}
else
{
int nmask = *mask;
if (wipestyleflags & WSF_FADEIN)
nmask = (FADECOLORMAPROWS-1) - nmask;
relativepos = (draw_linestart * vid.width) + draw_rowstart;
draw_linestogo = draw_lineend - draw_linestart;
transtbl = colormap + (nmask * 256);
if (*mask == 0)
// DRAWING LOOP
while (draw_linestogo--)
{
// shortcut - memcpy source to work
while (draw_linestogo--)
{
M_Memcpy(w_base+relativepos, s_base+relativepos, draw_rowend-draw_rowstart);
relativepos += vid.width;
}
w = w_base + relativepos;
s = s_base + relativepos;
e = e_base + relativepos;
draw_rowstogo = draw_rowend - draw_rowstart;
while (draw_rowstogo--)
*w++ = transtbl[*e++];
relativepos += vid.width;
}
// END DRAWING LOOP
}
if (++maskx >= fademask->width)
++masky, maskx = 0;
} while (++mask < maskend);
free(scrxpos);
free(scrypos);
}
#ifdef TRUECOLOR
static void F_DoWipe32(fademask_t *fademask)
{
// wipe screen, start, end
UINT32 *w = (UINT32 *)wipe_scr;
const UINT32 *s = (UINT32 *)wipe_scr_start;
const UINT32 *e = (UINT32 *)wipe_scr_end;
// first pixel for each screen
UINT32 *w_base = w;
const UINT32 *s_base = s;
const UINT32 *e_base = e;
// mask data, end
const UINT8 *mask = fademask->mask;
const UINT8 *maskend = mask + fademask->size;
// rectangle draw hints
UINT32 draw_linestart, draw_rowstart;
UINT32 draw_lineend, draw_rowend;
UINT32 draw_linestogo, draw_rowstogo;
// rectangle coordinates, etc.
UINT16* scrxpos = (UINT16*)malloc((fademask->width + 1) * sizeof(UINT16));
UINT16* scrypos = (UINT16*)malloc((fademask->height + 1) * sizeof(UINT16));
UINT16 maskx, masky;
UINT32 relativepos;
// ---
// Screw it, we do the fixed point math ourselves up front.
scrxpos[0] = 0;
for (relativepos = 0, maskx = 1; maskx < fademask->width; ++maskx)
scrxpos[maskx] = (relativepos += fademask->xscale)>>FRACBITS;
scrxpos[fademask->width] = vid.width;
scrypos[0] = 0;
for (relativepos = 0, masky = 1; masky < fademask->height; ++masky)
scrypos[masky] = (relativepos += fademask->yscale)>>FRACBITS;
scrypos[fademask->height] = vid.height;
// ---
maskx = masky = 0;
do
{
draw_rowstart = scrxpos[maskx];
draw_rowend = scrxpos[maskx + 1];
draw_linestart = scrypos[masky];
draw_lineend = scrypos[masky + 1];
relativepos = (draw_linestart * vid.width) + draw_rowstart;
draw_linestogo = draw_lineend - draw_linestart;
if (*mask == 0)
{
// shortcut - memcpy source to work
while (draw_linestogo--)
{
M_Memcpy(w_base+relativepos, s_base+relativepos, (draw_rowend-draw_rowstart) * vid.bpp);
relativepos += vid.width;
}
}
else if (*mask >= 255)
{
// shortcut - memcpy target to work
while (draw_linestogo--)
{
M_Memcpy(w_base+relativepos, e_base+relativepos, (draw_rowend-draw_rowstart) * vid.bpp);
relativepos += vid.width;
}
else if (*mask >= FADECOLORMAPROWS)
}
else
{
// DRAWING LOOP
while (draw_linestogo--)
{
// shortcut - memcpy target to work
while (draw_linestogo--)
w = w_base + relativepos;
s = s_base + relativepos;
e = e_base + relativepos;
draw_rowstogo = draw_rowend - draw_rowstart;
while (draw_rowstogo--)
{
M_Memcpy(w_base+relativepos, e_base+relativepos, draw_rowend-draw_rowstart);
relativepos += vid.width;
*w = R_TranslucentMix(*s, *e, *mask);
w++;
e++;
s++;
}
relativepos += vid.width;
}
else
// END DRAWING LOOP
}
if (++maskx >= fademask->width)
++masky, maskx = 0;
} while (++mask < maskend);
free(scrxpos);
free(scrypos);
}
// F_DoWipe32 for WIPESTYLE_COLORMAP
static void F_DoColormapWipe32(fademask_t *fademask)
{
RGBA_t pack;
INT16 r, g, b;
// wipe screen, start, end
UINT32 *w = (UINT32 *)wipe_scr;
const UINT32 *s = (UINT32 *)wipe_scr_start;
const UINT32 *e = (UINT32 *)wipe_scr_end;
// first pixel for each screen
UINT32 *w_base = w;
const UINT32 *s_base = s;
const UINT32 *e_base = e;
// mask data, end
const UINT8 *mask = fademask->mask;
const UINT8 *maskend = mask + fademask->size;
// rectangle draw hints
UINT32 draw_linestart, draw_rowstart;
UINT32 draw_lineend, draw_rowend;
UINT32 draw_linestogo, draw_rowstogo;
// rectangle coordinates, etc.
UINT16* scrxpos = (UINT16*)malloc((fademask->width + 1) * sizeof(UINT16));
UINT16* scrypos = (UINT16*)malloc((fademask->height + 1) * sizeof(UINT16));
UINT16 maskx, masky;
UINT32 relativepos;
// ---
// Screw it, we do the fixed point math ourselves up front.
scrxpos[0] = 0;
for (relativepos = 0, maskx = 1; maskx < fademask->width; ++maskx)
scrxpos[maskx] = (relativepos += fademask->xscale)>>FRACBITS;
scrxpos[fademask->width] = vid.width;
scrypos[0] = 0;
for (relativepos = 0, masky = 1; masky < fademask->height; ++masky)
scrypos[masky] = (relativepos += fademask->yscale)>>FRACBITS;
scrypos[fademask->height] = vid.height;
// ---
maskx = masky = 0;
do
{
draw_rowstart = scrxpos[maskx];
draw_rowend = scrxpos[maskx + 1];
draw_linestart = scrypos[masky];
draw_lineend = scrypos[masky + 1];
relativepos = (draw_linestart * vid.width) + draw_rowstart;
draw_linestogo = draw_lineend - draw_linestart;
if (*mask == 0)
{
// shortcut - memcpy source to work
while (draw_linestogo--)
{
int nmask = *mask;
if (wipestyleflags & WSF_FADEIN)
nmask = (FADECOLORMAPROWS-1) - nmask;
M_Memcpy(w_base+relativepos, s_base+relativepos, (draw_rowend-draw_rowstart) * vid.bpp);
relativepos += vid.width;
}
}
else if (*mask >= 255)
{
// shortcut - memcpy target to work
while (draw_linestogo--)
{
M_Memcpy(w_base+relativepos, e_base+relativepos, (draw_rowend-draw_rowstart) * vid.bpp);
relativepos += vid.width;
}
}
else
{
// DRAWING LOOP
while (draw_linestogo--)
{
UINT8 alpha = *mask;
const UINT32 *sauce = NULL;
w = w_base + relativepos;
s = s_base + relativepos;
e = e_base + relativepos;
draw_rowstogo = draw_rowend - draw_rowstart;
transtbl = colormap + (nmask * 256);
if (wipestyleflags & WSF_FADEIN)
{
alpha = 0xFF - alpha;
sauce = e;
}
else
sauce = s;
// DRAWING LOOP
while (draw_linestogo--)
// This is gonna be mad slow...
while (draw_rowstogo--)
{
w = w_base + relativepos;
s = s_base + relativepos;
e = e_base + relativepos;
draw_rowstogo = draw_rowend - draw_rowstart;
// subtractive color blending
pack.rgba = *sauce;
r = pack.s.red - FADEREDFACTOR*alpha/10;
g = pack.s.green - FADEGREENFACTOR*alpha/10;
b = pack.s.blue - FADEBLUEFACTOR*alpha/10;
// clamp values
if (r < 0) r = 0;
if (g < 0) g = 0;
if (b < 0) b = 0;
// pack into rgba
pack.s.red = r;
pack.s.green = g;
pack.s.blue = b;
*w = pack.rgba;
w++;
sauce++;
}
while (draw_rowstogo--)
*w++ = transtbl[*e++];
relativepos += vid.width;
}
// END DRAWING LOOP
}
relativepos += vid.width;
if (++maskx >= fademask->width)
++masky, maskx = 0;
} while (++mask < maskend);
free(scrxpos);
free(scrypos);
}
// F_DoWipe32 for WIPESTYLE_COLORMAP and WSF_TOWHITE
static void F_DoWhiteColormapWipe32(fademask_t *fademask)
{
RGBA_t pack;
INT16 r, g, b;
// wipe screen, start, end
UINT32 *w = (UINT32 *)wipe_scr;
const UINT32 *s = (UINT32 *)wipe_scr_start;
const UINT32 *e = (UINT32 *)wipe_scr_end;
// first pixel for each screen
UINT32 *w_base = w;
const UINT32 *s_base = s;
const UINT32 *e_base = e;
// mask data, end
const UINT8 *mask = fademask->mask;
const UINT8 *maskend = mask + fademask->size;
// rectangle draw hints
UINT32 draw_linestart, draw_rowstart;
UINT32 draw_lineend, draw_rowend;
UINT32 draw_linestogo, draw_rowstogo;
// rectangle coordinates, etc.
UINT16* scrxpos = (UINT16*)malloc((fademask->width + 1) * sizeof(UINT16));
UINT16* scrypos = (UINT16*)malloc((fademask->height + 1) * sizeof(UINT16));
UINT16 maskx, masky;
UINT32 relativepos;
// ---
// Screw it, we do the fixed point math ourselves up front.
scrxpos[0] = 0;
for (relativepos = 0, maskx = 1; maskx < fademask->width; ++maskx)
scrxpos[maskx] = (relativepos += fademask->xscale)>>FRACBITS;
scrxpos[fademask->width] = vid.width;
scrypos[0] = 0;
for (relativepos = 0, masky = 1; masky < fademask->height; ++masky)
scrypos[masky] = (relativepos += fademask->yscale)>>FRACBITS;
scrypos[fademask->height] = vid.height;
// ---
maskx = masky = 0;
do
{
draw_rowstart = scrxpos[maskx];
draw_rowend = scrxpos[maskx + 1];
draw_linestart = scrypos[masky];
draw_lineend = scrypos[masky + 1];
relativepos = (draw_linestart * vid.width) + draw_rowstart;
draw_linestogo = draw_lineend - draw_linestart;
if (*mask == 0)
{
// shortcut - memcpy source to work
while (draw_linestogo--)
{
M_Memcpy(w_base+relativepos, s_base+relativepos, (draw_rowend-draw_rowstart) * vid.bpp);
relativepos += vid.width;
}
}
else if (*mask >= 255)
{
// shortcut - memcpy target to work
while (draw_linestogo--)
{
M_Memcpy(w_base+relativepos, e_base+relativepos, (draw_rowend-draw_rowstart) * vid.bpp);
relativepos += vid.width;
}
}
else
{
// DRAWING LOOP
while (draw_linestogo--)
{
UINT8 alpha = *mask;
const UINT32 *sauce = NULL;
w = w_base + relativepos;
s = s_base + relativepos;
e = e_base + relativepos;
draw_rowstogo = draw_rowend - draw_rowstart;
if (wipestyleflags & WSF_FADEIN)
{
alpha = 0xFF - alpha;
sauce = e;
}
// END DRAWING LOOP
else
sauce = s;
// This is gonna be mad slow...
while (draw_rowstogo--)
{
// additive color blending
pack.rgba = *sauce;
r = pack.s.red + FADEREDFACTOR*alpha/10;
g = pack.s.green + FADEGREENFACTOR*alpha/10;
b = pack.s.blue + FADEBLUEFACTOR*alpha/10;
// clamp values
if (r > 255) r = 255;
if (g > 255) g = 255;
if (b > 255) b = 255;
// pack into rgba
pack.s.red = r;
pack.s.green = g;
pack.s.blue = b;
*w = pack.rgba;
w++;
sauce++;
}
relativepos += vid.width;
}
// END DRAWING LOOP
}
if (++maskx >= fademask->width)
++masky, maskx = 0;
} while (++mask < maskend);
if (++maskx >= fademask->width)
++masky, maskx = 0;
} while (++mask < maskend);
free(scrxpos);
free(scrypos);
}
free(scrxpos);
free(scrypos);
}
#endif // TRUECOLOR
#endif
/** Save the "before" screen of a wipe.
......@@ -433,7 +792,7 @@ void F_WipeStartScreen(void)
{
#ifndef NOWIPE
#ifdef HWRENDER
if(rendermode != render_soft)
if(!VID_InSoftwareRenderer())
{
HWR_StartScreenWipe();
return;
......@@ -450,7 +809,7 @@ void F_WipeEndScreen(void)
{
#ifndef NOWIPE
#ifdef HWRENDER
if(rendermode != render_soft)
if(!VID_InSoftwareRenderer())
{
HWR_EndScreenWipe();
return;
......@@ -513,6 +872,10 @@ boolean F_TryColormapFade(UINT8 wipecolor)
#ifdef HWRENDER
if (rendermode == render_opengl)
F_WipeColorFill(wipecolor);
#endif
#ifdef TRUECOLOR
if (VID_InSoftwareRenderer() && truecolor)
F_WipeColorFill(wipecolor);
#endif
return true;
}
......@@ -574,10 +937,22 @@ void F_RunWipe(UINT8 wipetype, boolean drawMenu)
else
#endif
{
UINT8 *colormap = fadecolormap;
if (wipestyleflags & WSF_TOWHITE)
colormap += (FADECOLORMAPROWS * 256);
F_DoColormapWipe(fmask, colormap);
#ifdef TRUECOLOR
if (truecolor)
{
if (wipestyleflags & WSF_TOWHITE)
F_DoWhiteColormapWipe32(fmask);
else
F_DoColormapWipe32(fmask);
}
else
#endif
{
UINT8 *colormap = fadecolormap;
if (wipestyleflags & WSF_TOWHITE)
colormap += (FADECOLORMAPROWS * 256);
F_DoColormapWipe(fmask, colormap);
}
}
// Draw the title card above the wipe
......@@ -593,7 +968,14 @@ void F_RunWipe(UINT8 wipetype, boolean drawMenu)
}
else
#endif
F_DoWipe(fmask);
{
#ifdef TRUECOLOR
if (truecolor)
F_DoWipe32(fmask);
else
#endif
F_DoWipe(fmask);
}
}
I_OsPolling();
......
......@@ -2501,7 +2501,7 @@ static inline void G_PlayerFinishLevel(INT32 player)
p->starpostz = 0;
p->starpostnum = 0;
if (rendermode == render_soft)
if (VID_InSoftwareRenderer())
V_SetPaletteLump(GetPalette()); // Reset the palette
}
......
......@@ -42,6 +42,44 @@ static INT32 format2bpp(GLTextureFormat_t format)
return 1;
}
static colorlookup_t texel_colorlookup;
#ifdef COLORMAP_RGBA_PIXELS
// Lactozilla: Compare the pixel's RGB color with the palette's.
// If they match, remap it.
static void ColormapRGBAPixel(RGBA_t *texelu32, UINT8 *texel, const UINT8 *colormap)
{
UINT8 *basepal = V_CacheBasePalette();
INT32 i = 0;
for (; i < 256; i++)
{
UINT8 r = *(basepal), g = *(basepal + 1), b = *(basepal + 2);
UINT32 rgb = R_PutRgbaRGB(r, g, b);
if (rgb == R_GetRgbaRGB(texelu32->rgba))
{
// Find the RGBA color of the mapped palette index
RGBA_t mapped = V_GetColor(colormap[i]);
// Convert to the target bit depth
if (texel)
{
*texel = GetColorLUT(&texel_colorlookup, mapped.s.red, mapped.s.green, mapped.s.blue);
texelu32->rgba = mapped.rgba;
}
else // This preserves the source pixel's translucency.
texelu32->rgba = R_GetRgbaRGB(mapped.rgba) + R_PutRgbaA(R_GetRgbaA(texelu32->rgba));
// Stop looking for a matching color
break;
}
basepal += 3;
}
}
#endif
// This code was originally placed directly in HWR_DrawPatchInCache.
// It is now split from it for my sanity! (and the sanity of others)
// -- Monster Iestyn (13/02/19)
......@@ -49,24 +87,34 @@ static void HWR_DrawColumnInCache(const column_t *patchcol, UINT8 *block, GLMipm
INT32 pblockheight, INT32 blockmodulo,
fixed_t yfracstep, fixed_t scale_y,
texpatch_t *originPatch, INT32 patchheight,
INT32 bpp)
INT32 bpp, pictureformat_t format)
{
fixed_t yfrac, position, count;
UINT8 *dest;
const UINT8 *source;
const UINT8 *source = NULL;
const UINT16 *sourceu16 = NULL;
const UINT32 *sourceu32 = NULL;
INT32 topdelta, prevdelta = -1;
INT32 originy = 0;
// for writing a pixel to dest
RGBA_t colortemp;
UINT8 alpha;
UINT8 texel;
UINT8 alpha = 0;
UINT8 texel = 0;
UINT16 texelu16;
RGBA_t texelu32;
INT32 sourcebpp = Picture_FormatBPP(format);
static UINT32 (*PixelBlendFunction)(RGBA_t background, RGBA_t foreground, int style, UINT8 alpha) = ASTBlendPixel;
(void)patchheight; // This parameter is unused
if (originPatch) // originPatch can be NULL here, unlike in the software version
{
PixelBlendFunction = ASTBlendTexturePixel;
originy = originPatch->originy;
}
memset(&texelu32, 0x00, sizeof(RGBA_t));
while (patchcol->topdelta != 0xff)
{
......@@ -74,10 +122,15 @@ static void HWR_DrawColumnInCache(const column_t *patchcol, UINT8 *block, GLMipm
if (topdelta <= prevdelta)
topdelta += prevdelta;
prevdelta = topdelta;
source = (const UINT8 *)patchcol + 3;
count = ((patchcol->length * scale_y) + (FRACUNIT/2)) >> FRACBITS;
count = ((patchcol->length * scale_y) + (FRACUNIT/2)) >> FRACBITS;
position = originy + topdelta;
source = (const UINT8 *)patchcol + 3;
if (sourcebpp == PICDEPTH_32BPP)
sourceu32 = (const UINT32 *)source;
else if (sourcebpp == PICDEPTH_16BPP)
sourceu16 = (const UINT16 *)source;
yfrac = 0;
//yfracstep = (patchcol->length << FRACBITS) / count;
if (position < 0)
......@@ -100,43 +153,84 @@ static void HWR_DrawColumnInCache(const column_t *patchcol, UINT8 *block, GLMipm
{
count--;
texel = source[yfrac>>FRACBITS];
alpha = 0xFF;
// Make pixel transparent if chroma keyed
if ((mipmap->flags & TF_CHROMAKEYED) && (texel == HWR_PATCHES_CHROMAKEY_COLORINDEX))
alpha = 0x00;
// Read the texel
if (sourcebpp == PICDEPTH_32BPP)
{
UINT32 s32 = sourceu32[yfrac>>FRACBITS];
texelu32.rgba = s32;
alpha = texelu32.s.alpha;
// Convert to the target bit depth
if (bpp < 3)
texel = GetColorLUT(&texel_colorlookup, texelu32.s.red, texelu32.s.green, texelu32.s.blue);
}
else
{
if (sourcebpp == PICDEPTH_16BPP)
{
UINT16 px = sourceu16[yfrac>>FRACBITS];
texel = (px & 0xFF);
alpha = ((sourceu16[yfrac>>FRACBITS] & 0xFF00) >> 8);
}
else
texel = source[yfrac>>FRACBITS];
// Set translucency for 8bpp source pictures
if (sourcebpp == 8)
{
alpha = 0xFF;
// If the mipmap is chromakeyed, check if the texel's color
// is equivalent to the chroma key's color index.
if ((mipmap->flags & TF_CHROMAKEYED) && (texel == HWR_PATCHES_CHROMAKEY_COLORINDEX))
alpha = 0x00;
}
}
//Hurdler: 25/04/2000: now support colormap in hardware mode
#ifdef COLORMAP_RGBA_PIXELS
if (mipmap->colormap)
{
if (sourcebpp == PICDEPTH_32BPP)
ColormapRGBAPixel(&texelu32, (bpp < 3) ? (&texel) : NULL, mipmap->colormap->data);
else
texel = mipmap->colormap->data[texel];
}
#else
if (mipmap->colormap && sourcebpp == PICDEPTH_8BPP)
texel = mipmap->colormap->data[texel];
#endif
// Convert to the target bit depth
if ((sourcebpp <= 16) && (bpp >= 3))
texelu32 = V_GetColor(texel);
// hope compiler will get this switch out of the loops (dreams...)
// gcc do it ! but vcc not ! (why don't use cygwin gcc for win32 ?)
// Alam: SRB2 uses Mingw, HUGS
switch (bpp)
{
case 2 : // uhhhhhhhh..........
case 2 :
if ((originPatch != NULL) && (originPatch->style != AST_COPY))
texel = ASTBlendPaletteIndexes(*(dest+1), texel, originPatch->style, originPatch->alpha);
texelu16 = (UINT16)((alpha<<8) | texel);
memcpy(dest, &texelu16, sizeof(UINT16));
break;
case 3 : colortemp = V_GetColor(texel);
case 3 : colortemp = texelu32;
if ((originPatch != NULL) && (originPatch->style != AST_COPY))
{
RGBA_t rgbatexel;
rgbatexel.rgba = *(UINT32 *)dest;
colortemp.rgba = ASTBlendTexturePixel(rgbatexel, colortemp, originPatch->style, originPatch->alpha);
colortemp.rgba = PixelBlendFunction(rgbatexel, colortemp, originPatch->style, originPatch->alpha);
}
memcpy(dest, &colortemp, sizeof(RGBA_t)-sizeof(UINT8));
break;
case 4 : colortemp = V_GetColor(texel);
case 4 : colortemp = texelu32;
colortemp.s.alpha = alpha;
if ((originPatch != NULL) && (originPatch->style != AST_COPY))
{
RGBA_t rgbatexel;
rgbatexel.rgba = *(UINT32 *)dest;
colortemp.rgba = ASTBlendTexturePixel(rgbatexel, colortemp, originPatch->style, originPatch->alpha);
colortemp.rgba = PixelBlendFunction(rgbatexel, colortemp, originPatch->style, originPatch->alpha);
}
memcpy(dest, &colortemp, sizeof(RGBA_t));
break;
......@@ -152,7 +246,13 @@ static void HWR_DrawColumnInCache(const column_t *patchcol, UINT8 *block, GLMipm
dest += blockmodulo;
yfrac += yfracstep;
}
patchcol = (const column_t *)((const UINT8 *)patchcol + patchcol->length + 4);
if (sourcebpp == PICDEPTH_32BPP)
patchcol = (const column_t *)((const UINT32 *)patchcol + patchcol->length);
else if (sourcebpp == PICDEPTH_16BPP)
patchcol = (const column_t *)((const UINT16 *)patchcol + patchcol->length);
else
patchcol = (const column_t *)((const UINT8 *)patchcol + patchcol->length);
patchcol = (const column_t *)((const UINT8 *)patchcol + 4);
}
}
......@@ -160,22 +260,33 @@ static void HWR_DrawFlippedColumnInCache(const column_t *patchcol, UINT8 *block,
INT32 pblockheight, INT32 blockmodulo,
fixed_t yfracstep, fixed_t scale_y,
texpatch_t *originPatch, INT32 patchheight,
INT32 bpp)
INT32 bpp, pictureformat_t format)
{
fixed_t yfrac, position, count;
UINT8 *dest;
const UINT8 *source;
const UINT8 *source = NULL;
const UINT16 *sourceu16 = NULL;
const UINT32 *sourceu32 = NULL;
INT32 topdelta, prevdelta = -1;
INT32 originy = 0;
// for writing a pixel to dest
RGBA_t colortemp;
UINT8 alpha;
UINT8 texel;
UINT8 alpha = 0;
UINT8 texel = 0;
UINT16 texelu16;
RGBA_t texelu32;
INT32 sourcebpp = Picture_FormatBPP(format);
static UINT32 (*PixelBlendFunction)(RGBA_t background, RGBA_t foreground, int style, UINT8 alpha) = ASTBlendPixel;
if (originPatch) // originPatch can be NULL here, unlike in the software version
{
PixelBlendFunction = ASTBlendTexturePixel;
originy = originPatch->originy;
}
memset(&texelu32, 0x00, sizeof(RGBA_t));
while (patchcol->topdelta != 0xff)
{
......@@ -184,10 +295,15 @@ static void HWR_DrawFlippedColumnInCache(const column_t *patchcol, UINT8 *block,
topdelta += prevdelta;
prevdelta = topdelta;
topdelta = patchheight-patchcol->length-topdelta;
source = (const UINT8 *)patchcol + 3;
count = ((patchcol->length * scale_y) + (FRACUNIT/2)) >> FRACBITS;
position = originy + topdelta;
source = (const UINT8 *)patchcol + 3;
if (sourcebpp == PICDEPTH_32BPP)
sourceu32 = (const UINT32 *)source;
else if (sourcebpp == PICDEPTH_16BPP)
sourceu16 = (const UINT16 *)source;
yfrac = (patchcol->length-1) << FRACBITS;
if (position < 0)
......@@ -210,43 +326,84 @@ static void HWR_DrawFlippedColumnInCache(const column_t *patchcol, UINT8 *block,
{
count--;
texel = source[yfrac>>FRACBITS];
alpha = 0xFF;
// Make pixel transparent if chroma keyed
if ((mipmap->flags & TF_CHROMAKEYED) && (texel == HWR_PATCHES_CHROMAKEY_COLORINDEX))
alpha = 0x00;
// Read the texel
if (sourcebpp == PICDEPTH_32BPP)
{
UINT32 s32 = sourceu32[yfrac>>FRACBITS];
texelu32.rgba = s32;
alpha = texelu32.s.alpha;
// Convert to the target bit depth
if (bpp < 3)
texel = GetColorLUT(&texel_colorlookup, texelu32.s.red, texelu32.s.green, texelu32.s.blue);
}
else
{
if (sourcebpp == PICDEPTH_16BPP)
{
UINT16 px = sourceu16[yfrac>>FRACBITS];
texel = (px & 0xFF);
alpha = ((sourceu16[yfrac>>FRACBITS] & 0xFF00) >> 8);
}
else
texel = source[yfrac>>FRACBITS];
// Set translucency for 8bpp source pictures
if (sourcebpp == 8)
{
alpha = 0xFF;
// If the mipmap is chromakeyed, check if the texel's color
// is equivalent to the chroma key's color index.
if ((mipmap->flags & TF_CHROMAKEYED) && (texel == HWR_PATCHES_CHROMAKEY_COLORINDEX))
alpha = 0x00;
}
}
//Hurdler: 25/04/2000: now support colormap in hardware mode
#ifdef COLORMAP_RGBA_PIXELS
if (mipmap->colormap)
{
if (sourcebpp == PICDEPTH_32BPP)
ColormapRGBAPixel(&texelu32, (bpp < 3) ? (&texel) : NULL, mipmap->colormap->data);
else
texel = mipmap->colormap->data[texel];
}
#else
if (mipmap->colormap && sourcebpp == PICDEPTH_8BPP)
texel = mipmap->colormap->data[texel];
#endif
// Convert to the target bit depth
if ((sourcebpp <= 16) && (bpp >= 3))
texelu32 = V_GetColor(texel);
// hope compiler will get this switch out of the loops (dreams...)
// gcc do it ! but vcc not ! (why don't use cygwin gcc for win32 ?)
// Alam: SRB2 uses Mingw, HUGS
switch (bpp)
{
case 2 : // uhhhhhhhh..........
case 2 :
if ((originPatch != NULL) && (originPatch->style != AST_COPY))
texel = ASTBlendPaletteIndexes(*(dest+1), texel, originPatch->style, originPatch->alpha);
texelu16 = (UINT16)((alpha<<8) | texel);
memcpy(dest, &texelu16, sizeof(UINT16));
break;
case 3 : colortemp = V_GetColor(texel);
case 3 : colortemp = texelu32;
if ((originPatch != NULL) && (originPatch->style != AST_COPY))
{
RGBA_t rgbatexel;
rgbatexel.rgba = *(UINT32 *)dest;
colortemp.rgba = ASTBlendTexturePixel(rgbatexel, colortemp, originPatch->style, originPatch->alpha);
colortemp.rgba = PixelBlendFunction(rgbatexel, colortemp, originPatch->style, originPatch->alpha);
}
memcpy(dest, &colortemp, sizeof(RGBA_t)-sizeof(UINT8));
break;
case 4 : colortemp = V_GetColor(texel);
case 4 : colortemp = texelu32;
colortemp.s.alpha = alpha;
if ((originPatch != NULL) && (originPatch->style != AST_COPY))
{
RGBA_t rgbatexel;
rgbatexel.rgba = *(UINT32 *)dest;
colortemp.rgba = ASTBlendTexturePixel(rgbatexel, colortemp, originPatch->style, originPatch->alpha);
colortemp.rgba = PixelBlendFunction(rgbatexel, colortemp, originPatch->style, originPatch->alpha);
}
memcpy(dest, &colortemp, sizeof(RGBA_t));
break;
......@@ -262,11 +419,16 @@ static void HWR_DrawFlippedColumnInCache(const column_t *patchcol, UINT8 *block,
dest += blockmodulo;
yfrac -= yfracstep;
}
patchcol = (const column_t *)((const UINT8 *)patchcol + patchcol->length + 4);
if (sourcebpp == PICDEPTH_32BPP)
patchcol = (const column_t *)((const UINT32 *)patchcol + patchcol->length);
else if (sourcebpp == PICDEPTH_16BPP)
patchcol = (const column_t *)((const UINT16 *)patchcol + patchcol->length);
else
patchcol = (const column_t *)((const UINT8 *)patchcol + patchcol->length);
patchcol = (const column_t *)((const UINT8 *)patchcol + 4);
}
}
// Simplified patch caching function
// for use by sprites and other patches that are not part of a wall texture
// no alpha or flipping should be present since we do not want non-texture graphics to have them
......@@ -275,7 +437,8 @@ static void HWR_DrawFlippedColumnInCache(const column_t *patchcol, UINT8 *block,
static void HWR_DrawPatchInCache(GLMipmap_t *mipmap,
INT32 pblockwidth, INT32 pblockheight,
INT32 pwidth, INT32 pheight,
const patch_t *realpatch)
const patch_t *realpatch,
pictureformat_t format)
{
INT32 ncols;
fixed_t xfrac, xfracstep;
......@@ -301,6 +464,9 @@ static void HWR_DrawPatchInCache(GLMipmap_t *mipmap,
if (bpp < 1 || bpp > 4)
I_Error("HWR_DrawPatchInCache: no drawer defined for this bpp (%d)\n",bpp);
// Initialize the texel color lookup table
InitColorLUT(&texel_colorlookup, pLocalPalette, false);
// NOTE: should this actually be pblockwidth*bpp?
blockmodulo = pblockwidth*bpp;
......@@ -313,7 +479,7 @@ static void HWR_DrawPatchInCache(GLMipmap_t *mipmap,
pblockheight, blockmodulo,
yfracstep, scale_y,
NULL, pheight, // not that pheight is going to get used anyway...
bpp);
bpp, format);
}
}
......@@ -321,7 +487,8 @@ static void HWR_DrawPatchInCache(GLMipmap_t *mipmap,
static void HWR_DrawTexturePatchInCache(GLMipmap_t *mipmap,
INT32 pblockwidth, INT32 pblockheight,
texture_t *texture, texpatch_t *patch,
const softwarepatch_t *realpatch)
const softwarepatch_t *realpatch,
pictureformat_t format)
{
INT32 x, x1, x2;
INT32 col, ncols;
......@@ -337,7 +504,7 @@ static void HWR_DrawTexturePatchInCache(GLMipmap_t *mipmap,
INT32 pblockheight, INT32 blockmodulo,
fixed_t yfracstep, fixed_t scale_y,
texpatch_t *originPatch, INT32 patchheight,
INT32 bpp);
INT32 bpp, pictureformat_t format);
if (texture->width <= 0 || texture->height <= 0)
return;
......@@ -394,6 +561,9 @@ static void HWR_DrawTexturePatchInCache(GLMipmap_t *mipmap,
if (bpp < 1 || bpp > 4)
I_Error("HWR_DrawTexturePatchInCache: no drawer defined for this bpp (%d)\n",bpp);
// Initialize the texel color lookup table
InitColorLUT(&texel_colorlookup, pLocalPalette, false);
// NOTE: should this actually be pblockwidth*bpp?
blockmodulo = pblockwidth*bpp;
......@@ -409,7 +579,7 @@ static void HWR_DrawTexturePatchInCache(GLMipmap_t *mipmap,
pblockheight, blockmodulo,
yfracstep, scale_y,
patch, height,
bpp);
bpp, format);
}
}
......@@ -497,33 +667,37 @@ static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *grtex)
}
}
if (texture->format == PICFMT_NONE)
texture->format = PICFMT_PATCH;
// Composite the columns together.
for (i = 0, patch = texture->patches; i < texture->patchcount; i++, patch++)
{
boolean dealloc = true;
pictureformat_t format = PICFMT_PATCH;
size_t lumplength = W_LumpLengthPwad(patch->wad, patch->lump);
pdata = W_CacheLumpNumPwad(patch->wad, patch->lump, PU_CACHE);
realpatch = (softwarepatch_t *)pdata;
#ifndef NO_PNG_LUMPS
if (Picture_IsLumpPNG((UINT8 *)realpatch, lumplength))
realpatch = (softwarepatch_t *)Picture_PNGConvert(pdata, PICFMT_DOOMPATCH, NULL, NULL, NULL, NULL, lumplength, NULL, 0);
{
#ifdef PICTURES_ALLOWDEPTH
format = PICFMT_PATCH32;
#endif
realpatch = (softwarepatch_t *)Picture_PNGConvert(pdata, Picture_PatchFormatTranslation(format), NULL, NULL, NULL, NULL, lumplength, NULL, 0);
}
else
#endif
#ifdef WALLFLATS
if (texture->type == TEXTURETYPE_FLAT)
realpatch = (softwarepatch_t *)Picture_Convert(PICFMT_FLAT, pdata, PICFMT_DOOMPATCH, 0, NULL, texture->width, texture->height, 0, 0, 0);
realpatch = (softwarepatch_t *)Picture_Convert(PICFMT_FLAT, pdata, Picture_PatchFormatTranslation(format), 0, NULL, texture->width, texture->height, 0, 0, 0);
else
#endif
{
(void)lumplength;
dealloc = false;
}
HWR_DrawTexturePatchInCache(&grtex->mipmap, blockwidth, blockheight, texture, patch, realpatch);
if (dealloc)
Z_Unlock(realpatch);
HWR_DrawTexturePatchInCache(&grtex->mipmap, blockwidth, blockheight, texture, patch, realpatch, format);
}
//Hurdler: not efficient at all but I don't remember exactly how HWR_DrawPatchInCache works :(
if (format2bpp(grtex->mipmap.format)==4)
......@@ -543,8 +717,9 @@ static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *grtex)
}
// patch may be NULL if grMipmap has been initialised already and makebitmap is false
void HWR_MakePatch (const patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipmap, boolean makebitmap)
void HWR_MakePatch (patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipmap, boolean makebitmap)
{
// don't do it twice (like a cache)
if (grMipmap->width == 0)
{
grMipmap->width = grMipmap->height = 1;
......@@ -566,12 +741,22 @@ void HWR_MakePatch (const patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipm
if (makebitmap)
{
patch_t *source = patch;
#ifdef PICTURES_ALLOWDEPTH
patch_t *tc = Patch_GetTruecolor(source);
if (tc)
source = tc;
#endif
grPatch->picfmt = source->format;
MakeBlock(grMipmap);
HWR_DrawPatchInCache(grMipmap,
grMipmap->width, grMipmap->height,
patch->width, patch->height,
patch);
source->width, source->height,
source, grPatch->picfmt);
}
}
......@@ -821,21 +1006,47 @@ static void HWR_CacheFlat(GLMipmap_t *grMipmap, lumpnum_t flatlumpnum)
static void HWR_CacheTextureAsFlat(GLMipmap_t *grMipmap, INT32 texturenum)
{
UINT8 *flat;
UINT8 *converted;
size_t size;
#ifdef PICTURES_ALLOWDEPTH
GLMapTexture_t *grtex;
#else
UINT8 *converted;
#endif
#ifdef PICTURES_ALLOWDEPTH
// Texture in hardware cache
grtex = &gl_textures[texturenum];
// Generate texture if missing from the cache
// The texture CAN be downloaded but have no data,
// which is perfectly fine when the GPU has it,
// but not for this kind of conversion.
if (!grtex->mipmap.data)
HWR_GenerateTexture(texturenum, grtex);
#endif
// setup the texture info
#ifdef PICTURES_ALLOWDEPTH
grMipmap->format = textureformat;
#else
grMipmap->format = GL_TEXFMT_P_8;
grMipmap->flags = TF_WRAPXY|TF_CHROMAKEYED;
#endif
grMipmap->width = (UINT16)textures[texturenum]->width;
grMipmap->flags = TF_WRAPXY|TF_CHROMAKEYED;
grMipmap->width = (UINT16)textures[texturenum]->width;
grMipmap->height = (UINT16)textures[texturenum]->height;
size = (grMipmap->width * grMipmap->height);
#ifdef PICTURES_ALLOWDEPTH
size = (grMipmap->width * grMipmap->height) * format2bpp(textureformat);
flat = Z_Malloc(size, PU_HWRCACHE, &grMipmap->data);
M_Memcpy(flat, grtex->mipmap.data, size);
#else
size = (grMipmap->width * grMipmap->height);
flat = Z_Malloc(size, PU_HWRCACHE, &grMipmap->data);
converted = (UINT8 *)Picture_TextureToFlat(texturenum);
M_Memcpy(flat, converted, size);
Z_Free(converted);
#endif
}
// Download a Doom 'flat' to the hardware cache and make it ready for use
......@@ -908,12 +1119,14 @@ void HWR_GetLevelFlat(levelflat_t *levelflat)
else if (levelflat->type == LEVELFLAT_PNG)
{
GLMipmap_t *mipmap = levelflat->mipmap;
pictureformat_t format = PICFMT_FLAT32;
INT32 fmtbpp = Picture_FormatBPP(format);
// Cache the picture.
if (!levelflat->mippic)
{
INT32 pngwidth = 0, pngheight = 0;
void *pic = Picture_PNGConvert(W_CacheLumpNum(levelflat->u.flat.lumpnum, PU_CACHE), PICFMT_FLAT, &pngwidth, &pngheight, NULL, NULL, W_LumpLength(levelflat->u.flat.lumpnum), NULL, 0);
void *pic = Picture_PNGConvert(W_CacheLumpNum(levelflat->u.flat.lumpnum, PU_CACHE), format, &pngwidth, &pngheight, NULL, NULL, W_LumpLength(levelflat->u.flat.lumpnum), NULL, 0);
Z_ChangeTag(pic, PU_LEVEL);
Z_SetUser(pic, &levelflat->mippic);
......@@ -926,7 +1139,7 @@ void HWR_GetLevelFlat(levelflat_t *levelflat)
if (mipmap == NULL)
{
mipmap = Z_Calloc(sizeof(GLMipmap_t), PU_STATIC, NULL);
mipmap->format = GL_TEXFMT_P_8;
mipmap->format = (fmtbpp == PICDEPTH_32BPP ? GL_TEXFMT_RGBA : GL_TEXFMT_P_8);
mipmap->flags = TF_WRAPXY|TF_CHROMAKEYED;
levelflat->mipmap = mipmap;
}
......@@ -942,7 +1155,7 @@ void HWR_GetLevelFlat(levelflat_t *levelflat)
mipmap->width = levelflat->width;
mipmap->height = levelflat->height;
size = (mipmap->width * mipmap->height);
size = (mipmap->width * mipmap->height) * (fmtbpp / 8);
flat = Z_Malloc(size, PU_LEVEL, &mipmap->data);
M_Memcpy(flat, levelflat->mippic, size);
}
......
......@@ -84,6 +84,7 @@ typedef struct GLMapTexture_s GLMapTexture_t;
struct GLPatch_s
{
GLMipmap_t *mipmap; // Texture data. Allocated whenever the patch is.
int picfmt;
float max_s, max_t;
};
typedef struct GLPatch_s GLPatch_t;
......
......@@ -82,7 +82,7 @@ typedef struct gl_vissprite_s
boolean flip, vflip;
boolean precip; // Tails 08-25-2002
boolean rotated;
UINT8 translucency; //alpha level 0-255
boolean translucent;
angle_t angle; // for splats
......@@ -92,6 +92,9 @@ typedef struct gl_vissprite_s
patch_t *gpatch;
mobj_t *mobj; // NOTE: This is a precipmobj_t if precip is true !!! Watch out.
INT32 blendmode;
INT32 alpha;
} gl_vissprite_t;
// --------
......
......@@ -704,36 +704,15 @@ FBITFIELD HWR_GetBlendModeFlag(INT32 style)
}
}
UINT8 HWR_GetTranstableAlpha(INT32 transtablenum)
FBITFIELD HWR_SurfaceBlend(INT32 style, INT32 alpha, FSurfaceInfo *pSurf)
{
transtablenum = max(min(transtablenum, tr_trans90), 0);
switch (transtablenum)
{
case 0 : return 0xff;
case tr_trans10 : return 0xe6;
case tr_trans20 : return 0xcc;
case tr_trans30 : return 0xb3;
case tr_trans40 : return 0x99;
case tr_trans50 : return 0x80;
case tr_trans60 : return 0x66;
case tr_trans70 : return 0x4c;
case tr_trans80 : return 0x33;
case tr_trans90 : return 0x19;
}
return 0xff;
}
FBITFIELD HWR_SurfaceBlend(INT32 style, INT32 transtablenum, FSurfaceInfo *pSurf)
{
if (!transtablenum || style <= AST_COPY || style >= AST_OVERLAY)
if (style <= AST_COPY || style >= AST_OVERLAY)
{
pSurf->PolyColor.s.alpha = 0xff;
return PF_Masked;
}
pSurf->PolyColor.s.alpha = HWR_GetTranstableAlpha(transtablenum);
pSurf->PolyColor.s.alpha = alpha;
return HWR_GetBlendModeFlag(style);
}
......@@ -745,7 +724,7 @@ FBITFIELD HWR_TranstableToAlpha(INT32 transtablenum, FSurfaceInfo *pSurf)
return PF_Masked;
}
pSurf->PolyColor.s.alpha = HWR_GetTranstableAlpha(transtablenum);
pSurf->PolyColor.s.alpha = R_TransnumToAlpha(transtablenum);
return PF_Translucent;
}
......@@ -3760,8 +3739,8 @@ static void HWR_SplitSprite(gl_vissprite_t *spr)
FBITFIELD blend = 0;
FBITFIELD occlusion;
INT32 shader = SHADER_DEFAULT;
INT32 alpha;
boolean use_linkdraw_hack = false;
UINT8 alpha;
INT32 i;
float realtop, realbot, top, bot;
......@@ -3853,37 +3832,18 @@ static void HWR_SplitSprite(gl_vissprite_t *spr)
else
occlusion = PF_Occlude;
INT32 blendmode;
if (spr->mobj->frame & FF_BLENDMASK)
blendmode = ((spr->mobj->frame & FF_BLENDMASK) >> FF_BLENDSHIFT) + 1;
else
blendmode = spr->mobj->blendmode;
alpha = spr->alpha;
if (!cv_translucency.value) // translucency disabled
{
Surf.PolyColor.s.alpha = 0xFF;
blend = PF_Translucent|occlusion;
if (!occlusion) use_linkdraw_hack = true;
}
else if (spr->mobj->flags2 & MF2_SHADOW)
{
Surf.PolyColor.s.alpha = 0x40;
blend = HWR_GetBlendModeFlag(blendmode);
}
else if (spr->mobj->frame & FF_TRANSMASK)
if (spr->translucent)
{
INT32 trans = (spr->mobj->frame & FF_TRANSMASK)>>FF_TRANSSHIFT;
blend = HWR_SurfaceBlend(blendmode, trans, &Surf);
blend = HWR_SurfaceBlend(spr->blendmode, alpha, &Surf);
}
else
{
// BP: i agree that is little better in environement but it don't
// work properly under glide nor with fogcolor to ffffff :(
// Hurdler: PF_Environement would be cool, but we need to fix
// the issue with the fog before
Surf.PolyColor.s.alpha = 0xFF;
blend = HWR_GetBlendModeFlag(blendmode)|occlusion;
if (!occlusion) use_linkdraw_hack = true;
blend = HWR_GetBlendModeFlag(spr->blendmode) | occlusion;
if (!occlusion)
use_linkdraw_hack = true;
}
if (HWR_UseShader())
......@@ -3892,8 +3852,6 @@ static void HWR_SplitSprite(gl_vissprite_t *spr)
blend |= PF_ColorMapped;
}
alpha = Surf.PolyColor.s.alpha;
// Start with the lightlevel and colormap from the top of the sprite
lightlevel = *list[sector->numlights - 1].lightlevel;
if (!(spr->mobj->renderflags & RF_NOCOLORMAPS))
......@@ -4297,49 +4255,16 @@ static void HWR_DrawSprite(gl_vissprite_t *spr)
else
occlusion = PF_Occlude;
INT32 blendmode;
if (spr->mobj->frame & FF_BLENDMASK)
blendmode = ((spr->mobj->frame & FF_BLENDMASK) >> FF_BLENDSHIFT) + 1;
else
blendmode = spr->mobj->blendmode;
if (!cv_translucency.value) // translucency disabled
if (spr->translucent)
{
Surf.PolyColor.s.alpha = 0xFF;
blend = PF_Translucent|occlusion;
if (!occlusion) use_linkdraw_hack = true;
}
else if (spr->mobj->flags2 & MF2_SHADOW)
{
Surf.PolyColor.s.alpha = 0x40;
blend = HWR_GetBlendModeFlag(blendmode);
}
else if (spr->mobj->frame & FF_TRANSMASK)
{
INT32 trans = (spr->mobj->frame & FF_TRANSMASK)>>FF_TRANSSHIFT;
blend = HWR_SurfaceBlend(blendmode, trans, &Surf);
blend = HWR_SurfaceBlend(spr->blendmode, spr->alpha, &Surf);
}
else
{
// BP: i agree that is little better in environement but it don't
// work properly under glide nor with fogcolor to ffffff :(
// Hurdler: PF_Environement would be cool, but we need to fix
// the issue with the fog before
Surf.PolyColor.s.alpha = 0xFF;
blend = HWR_GetBlendModeFlag(blendmode)|occlusion;
if (!occlusion) use_linkdraw_hack = true;
}
if (spr->renderflags & RF_SHADOWEFFECTS)
{
INT32 alpha = Surf.PolyColor.s.alpha;
alpha -= ((INT32)(spr->shadowheight / 4.0f)) + 75;
if (alpha < 1)
return;
Surf.PolyColor.s.alpha = (UINT8)(alpha);
blend = PF_Translucent|occlusion;
if (!occlusion) use_linkdraw_hack = true;
blend = HWR_GetBlendModeFlag(spr->blendmode) | occlusion;
if (!occlusion)
use_linkdraw_hack = true;
}
if (HWR_UseShader())
......@@ -4433,19 +4358,14 @@ static inline void HWR_DrawPrecipitationSprite(gl_vissprite_t *spr)
HWR_Lighting(&Surf, lightlevel, colormap);
}
if (spr->mobj->frame & FF_TRANSMASK)
if (spr->translucent)
{
INT32 trans = (spr->mobj->frame & FF_TRANSMASK)>>FF_TRANSSHIFT;
blend = HWR_SurfaceBlend(AST_TRANSLUCENT, trans, &Surf);
blend = HWR_SurfaceBlend(spr->blendmode, spr->alpha, &Surf);
}
else
{
// BP: i agree that is little better in environement but it don't
// work properly under glide nor with fogcolor to ffffff :(
// Hurdler: PF_Environement would be cool, but we need to fix
// the issue with the fog before
Surf.PolyColor.s.alpha = 0xFF;
blend = HWR_GetBlendModeFlag(spr->mobj->blendmode)|PF_Occlude;
blend = HWR_GetBlendModeFlag(spr->blendmode);
}
if (HWR_UseShader())
......@@ -4999,6 +4919,9 @@ static void HWR_ProjectSprite(mobj_t *thing)
boolean vflip = (!(thing->eflags & MFE_VERTICALFLIP) != !R_ThingVerticallyFlipped(thing));
boolean mirrored = thing->mirrored;
boolean hflip = (!R_ThingHorizontallyFlipped(thing) != !mirrored);
INT32 blendmode, alpha = 255;
boolean translucent = false;
UINT32 trans;
INT32 dispoffset;
angle_t ang;
......@@ -5020,22 +4943,32 @@ static void HWR_ProjectSprite(mobj_t *thing)
if (!thing)
return;
INT32 blendmode;
// Get the blend mode
if (thing->frame & FF_BLENDMASK)
blendmode = ((thing->frame & FF_BLENDMASK) >> FF_BLENDSHIFT) + 1;
else
blendmode = thing->blendmode;
blendmode = min(max(AST_COPY, thing->blendmode), AST_OVERLAY);
// Visibility check by the blend mode.
if (thing->frame & FF_TRANSMASK)
// Determine the translucency value.
if (thing->flags2 & MF2_SHADOW) // actually only the player should use this (temporary invisibility)
trans = tr_trans80; // because now the translucency is set through FF_TRANSMASK
else if (thing->frame & FF_TRANSMASK)
trans = (thing->frame & FF_TRANSMASK) >> FF_TRANSSHIFT;
else
trans = 0;
if (cv_translucency.value && blendmode != AST_COPY && blendmode != AST_OVERLAY)
{
if (!R_BlendLevelVisible(blendmode, (thing->frame & FF_TRANSMASK)>>FF_TRANSSHIFT))
alpha = thing->alpha - (0xFF - R_BlendModeTransnumToAlpha(blendmode, trans));
if (!R_BlendLevelVisible(blendmode, alpha))
return;
translucent = true;
}
dispoffset = thing->dispoffset;
if (R_UsingFrameInterpolation() && !paused)
{
R_InterpolateMobjState(thing, rendertimefrac, &interp);
......@@ -5261,12 +5194,22 @@ static void HWR_ProjectSprite(mobj_t *thing)
shadowheight = FIXED_TO_FLOAT(floordiff);
shadowscale = FIXED_TO_FLOAT(FixedMul(FRACUNIT - floordiff/640, casterinterp.scale));
if (translucent)
{
alpha -= ((INT32)(shadowheight / 4.0f)) + 75;
if (!R_BlendLevelVisible(blendmode, alpha))
return;
}
if (splat)
spritexscale *= shadowscale;
spriteyscale *= shadowscale;
}
}
translucent = !(blendmode == AST_TRANSLUCENT && alpha >= 255);
this_xscale = spritexscale * this_scale;
this_yscale = spriteyscale * this_scale;
......@@ -5289,18 +5232,6 @@ static void HWR_ProjectSprite(mobj_t *thing)
x2 = (FIXED_TO_FLOAT(spr_width - spr_offset) * this_xscale);
}
// test if too close
/*
if (papersprite)
{
z1 = tz - x1 * angle_scalez;
z2 = tz + x2 * angle_scalez;
if (max(z1, z2) < ZCLIP_PLANE)
return;
}
*/
z1 = tr_y + x1 * rightsin;
z2 = tr_y - x2 * rightsin;
x1 = tr_x + x1 * rightcos;
......@@ -5473,6 +5404,9 @@ static void HWR_ProjectSprite(mobj_t *thing)
vis->precip = false;
vis->translucent = translucent;
vis->blendmode = blendmode;
vis->alpha = alpha;
vis->angle = interp.angle;
}
......@@ -5491,15 +5425,33 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing)
size_t lumpoff;
unsigned rot = 0;
UINT8 flip;
INT32 blendmode, alpha = 255;
boolean translucent = false;
UINT32 trans;
if (!thing)
return;
// Visibility check by the blend mode.
// Get the blend mode
if (thing->frame & FF_BLENDMASK)
blendmode = ((thing->frame & FF_BLENDMASK) >> FF_BLENDSHIFT) + 1;
else
blendmode = min(max(AST_COPY, thing->blendmode), AST_OVERLAY);
// Determine the translucency value.
if (thing->frame & FF_TRANSMASK)
trans = (thing->frame & FF_TRANSMASK) >> FF_TRANSSHIFT;
else
trans = 0;
if (cv_translucency.value && blendmode != AST_COPY && blendmode != AST_OVERLAY)
{
if (!R_BlendLevelVisible(thing->blendmode, (thing->frame & FF_TRANSMASK)>>FF_TRANSSHIFT))
alpha = thing->alpha - (0xFF - R_BlendModeTransnumToAlpha(blendmode, trans));
if (!R_BlendLevelVisible(blendmode, alpha))
return;
translucent = !(blendmode == AST_TRANSLUCENT && alpha >= 255);
}
// uncapped/interpolation
......@@ -5595,6 +5547,10 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing)
vis->precip = true;
vis->translucent = translucent;
vis->blendmode = blendmode;
vis->alpha = alpha;
// okay... this is a hack, but weather isn't networked, so it should be ok
if (!(thing->precipflags & PCF_THUNK))
{
......
......@@ -42,7 +42,7 @@ void HWR_SetViewSize(void);
void HWR_DrawPatch(patch_t *gpatch, INT32 x, INT32 y, INT32 option);
void HWR_DrawStretchyFixedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, fixed_t vscale, INT32 option, const UINT8 *colormap);
void HWR_DrawCroppedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, fixed_t vscale, INT32 option, const UINT8 *colormap, fixed_t sx, fixed_t sy, fixed_t w, fixed_t h);
void HWR_MakePatch(const patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipmap, boolean makebitmap);
void HWR_MakePatch(patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipmap, boolean makebitmap);
void HWR_CreatePlanePolygons(INT32 bspnum);
void HWR_CreateStaticLightmaps(INT32 bspnum);
void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color);
......@@ -70,9 +70,8 @@ void HWR_DrawScreenFinalTexture(int width, int height);
void HWR_Lighting(FSurfaceInfo *Surface, INT32 light_level, extracolormap_t *colormap);
UINT8 HWR_FogBlockAlpha(INT32 light, extracolormap_t *colormap); // Let's see if this can work
UINT8 HWR_GetTranstableAlpha(INT32 transtablenum);
FBITFIELD HWR_GetBlendModeFlag(INT32 style);
FBITFIELD HWR_SurfaceBlend(INT32 style, INT32 transtablenum, FSurfaceInfo *pSurf);
FBITFIELD HWR_SurfaceBlend(INT32 style, INT32 alpha, FSurfaceInfo *pSurf);
FBITFIELD HWR_TranstableToAlpha(INT32 transtablenum, FSurfaceInfo *pSurf);
boolean HWR_CompileShaders(void);
......
......@@ -415,7 +415,7 @@ static void md2_loadTexture(md2_t *model)
size = w*h;
while (size--)
{
V_CubeApply(&image->s.red, &image->s.green, &image->s.blue);
ColorCube_Apply(&image->s.red, &image->s.green, &image->s.blue);
image++;
}
}
......
......@@ -2095,7 +2095,7 @@ void HU_Erase(void)
return;
// software mode copies view border pattern & beveled edges from the backbuffer
if (rendermode == render_soft)
if (VID_InSoftwareRenderer())
{
topline = 0;
for (y = topline, yoffset = y*vid.width; y < bottomline; y++, yoffset += vid.width)
......
......@@ -22,14 +22,15 @@
typedef enum
{
/// Software
render_soft = 1,
// Software renderers
render_software = 1,
render_software_truecolor,
/// OpenGL
render_opengl = 2,
// OpenGL
render_opengl,
/// Dedicated
render_none = 3 // for dedicated server
// Dedicated mode
render_none,
} rendermode_t;
/** \brief current render mode
......@@ -44,6 +45,10 @@ extern rendermode_t chosenrendermode;
*/
extern boolean highcolor;
/** \brief use truecolor modes if true
*/
extern boolean truecolor;
/** \brief setup video mode
*/
void I_StartupGraphics(void);
......@@ -101,6 +106,15 @@ void VID_StartupOpenGL(void);
*/
void VID_CheckGLLoaded(rendermode_t oldrender);
/** \brief Returns true if mode is a Software renderer.
\param mode A render mode.
*/
boolean VID_IsASoftwareRenderer(rendermode_t mode);
/** \brief Returns true if the current rendermode.
*/
boolean VID_InSoftwareRenderer(void);
/** \brief The VID_GetModeName function
\param modenum video mode number
......
......@@ -452,7 +452,7 @@ static int lib_pAproxDistance(lua_State *L)
fixed_t dx = luaL_checkfixed(L, 1);
fixed_t dy = luaL_checkfixed(L, 2);
//HUDSAFE
lua_pushfixed(L, P_AproxDistance(dx, dy));
lua_pushfixed(L, R_PointToDist2(0, 0, dx, dy));
return 1;
}
......
......@@ -1226,11 +1226,24 @@ static int libd_dupy(lua_State *L)
static int libd_renderer(lua_State *L)
{
HUDONLY
switch (rendermode) {
case render_opengl: lua_pushliteral(L, "opengl"); break; // OpenGL renderer
case render_soft: lua_pushliteral(L, "software"); break; // Software renderer
default: lua_pushliteral(L, "none"); break; // render_none (for dedicated), in case there's any reason this should be run
switch (rendermode)
{
// Software renderers
case render_software:
case render_software_truecolor:
lua_pushliteral(L, "software");
break;
// OpenGL renderer
case render_opengl:
lua_pushliteral(L, "opengl");
break;
// render_none (for dedicated), in case there's any reason this should be run
default:
lua_pushliteral(L, "none");
break;
}
return 1;
}
......
......@@ -63,6 +63,7 @@ enum mobj_e {
mobj_renderflags,
mobj_skin,
mobj_color,
mobj_alpha,
mobj_blendmode,
mobj_bnext,
mobj_bprev,
......@@ -140,6 +141,7 @@ static const char *const mobj_opt[] = {
"renderflags",
"skin",
"color",
"alpha",
"blendmode",
"bnext",
"bprev",
......@@ -320,6 +322,9 @@ static int mobj_get(lua_State *L)
case mobj_color:
lua_pushinteger(L, mo->color);
break;
case mobj_alpha:
lua_pushinteger(L, mo->alpha);
break;
case mobj_blendmode:
lua_pushinteger(L, mo->blendmode);
break;
......@@ -661,6 +666,14 @@ static int mobj_set(lua_State *L)
mo->color = newcolor;
break;
}
case mobj_alpha:
{
INT32 newalpha = (INT32)luaL_checkinteger(L,3);
if (newalpha < 0 || newalpha > 255)
return luaL_error(L, "mobj.alpha %d out of range (0 - 255).", newalpha);
mo->alpha = newalpha;
break;
}
case mobj_blendmode:
{
INT32 blendmode = (INT32)luaL_checkinteger(L, 3);
......
......@@ -508,11 +508,11 @@ static size_t gifframe_size = 8192;
#ifdef HWRENDER
static colorlookup_t gif_colorlookup;
static void GIF_rgbconvert(UINT8 *linear, UINT8 *scr)
static void GIF_rgbconvert(UINT8 *linear, UINT8 *scr, size_t bpp)
{
UINT8 r, g, b;
size_t src = 0, dest = 0;
size_t size = (vid.width * vid.height * 3);
size_t size = (vid.width * vid.height * bpp);
InitColorLUT(&gif_colorlookup, (gif_localcolortable) ? gif_framepalette : gif_headerpalette, true);
......@@ -522,11 +522,10 @@ static void GIF_rgbconvert(UINT8 *linear, UINT8 *scr)
g = (UINT8)linear[src + 1];
b = (UINT8)linear[src + 2];
scr[dest] = GetColorLUTDirect(&gif_colorlookup, r, g, b);
src += (3 * scrbuf_downscaleamt);
src += (bpp * scrbuf_downscaleamt);
dest += scrbuf_downscaleamt;
}
}
#endif
//
// GIF_framewrite
......@@ -561,17 +560,31 @@ static void GIF_framewrite(void)
{
// before blit movie_screen points to last frame, cur_screen points to this frame
UINT8 *cur_screen = screens[0];
#ifdef TRUECOLOR
if (VID_InSoftwareRenderer() && truecolor)
{
cur_screen = screens[2] + (vid.width * vid.height);
GIF_rgbconvert(screens[0], cur_screen, 4);
}
#endif
GIF_optimizeregion(cur_screen, movie_screen, &blitx, &blity, &blitw, &blith);
// blit to temp screen
if (rendermode == render_soft)
I_ReadScreen(movie_screen);
if (VID_InSoftwareRenderer())
{
#ifdef TRUECOLOR
if (truecolor)
GIF_rgbconvert(screens[0], movie_screen, 4);
else
#endif
I_ReadScreen(movie_screen);
}
#ifdef HWRENDER
else if (rendermode == render_opengl)
{
UINT8 *linear = HWR_GetScreenshot();
GIF_rgbconvert(linear, movie_screen);
free(linear);
UINT8 *sshot = HWR_GetScreenshot();
GIF_rgbconvert(sshot, movie_screen, 3);
free(sshot);
}
#endif
}
......@@ -581,22 +594,43 @@ static void GIF_framewrite(void)
blitw = vid.width;
blith = vid.height;
#ifdef HWRENDER
// Copy the current OpenGL frame into the base screen
if (rendermode == render_opengl)
if (gif_frames == 0)
{
UINT8 *linear = HWR_GetScreenshot();
GIF_rgbconvert(linear, screens[0]);
free(linear);
#ifdef HWRENDER
if (rendermode == render_opengl)
{
UINT8 *sshot = HWR_GetScreenshot();
GIF_rgbconvert(sshot, screens[0], 3);
free(sshot);
}
else
#endif
if (VID_InSoftwareRenderer())
{
#ifdef TRUECOLOR
if (truecolor)
GIF_rgbconvert(screens[0], movie_screen, 4);
else
#endif
I_ReadScreen(movie_screen);
}
}
#endif
// Copy the first frame into the movie screen
// OpenGL already does the same above.
if (gif_frames == 0 && rendermode == render_soft)
if (gif_frames == 0 && VID_InSoftwareRenderer())
I_ReadScreen(movie_screen);
movie_screen = screens[0];
#ifdef TRUECOLOR
if (VID_InSoftwareRenderer() && truecolor)
{
UINT8 *blit = screens[2] + (vid.width * vid.height);
GIF_rgbconvert(screens[0], blit, 4);
movie_screen = blit;
}
#endif
}
// screen regions are handled in GIF_lzw
......