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
  • 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
117 results
Select Git revision
Show changes
Commits on Source (5)
...@@ -8,10 +8,11 @@ ...@@ -8,10 +8,11 @@
#include "utils/Log.h" #include "utils/Log.h"
rendermode_t rendermode = render_soft; rendermode_t rendermode = render_software;
rendermode_t chosenrendermode = render_none; rendermode_t chosenrendermode = render_none;
boolean highcolor = false; boolean highcolor = false;
boolean truecolor = false;
boolean allow_fullscreen = false; boolean allow_fullscreen = false;
...@@ -53,6 +54,16 @@ INT32 VID_SetMode(INT32 modenum) ...@@ -53,6 +54,16 @@ INT32 VID_SetMode(INT32 modenum)
return 0; return 0;
} }
boolean VID_IsASoftwareRenderer(rendermode_t mode)
{
return (mode == render_software);
}
boolean VID_InSoftwareRenderer(void)
{
return VID_IsASoftwareRenderer(rendermode);
}
boolean VID_CheckRenderer(void) boolean VID_CheckRenderer(void)
{ {
return false; return false;
......
...@@ -333,7 +333,7 @@ static void D_Display(void) ...@@ -333,7 +333,7 @@ static void D_Display(void)
SCR_Recalc(); // NOTE! setsizeneeded is set by SCR_Recalc() SCR_Recalc(); // NOTE! setsizeneeded is set by SCR_Recalc()
// View morph // View morph
if (rendermode == render_soft && !splitscreen) if (VID_InSoftwareRenderer() && !splitscreen)
R_CheckViewMorph(); R_CheckViewMorph();
// Change the view size if needed // Change the view size if needed
...@@ -475,20 +475,28 @@ static void D_Display(void) ...@@ -475,20 +475,28 @@ static void D_Display(void)
if (gamestate == GS_LEVEL || (gamestate == GS_TITLESCREEN && titlemapinaction && curbghide && (!hidetitlemap))) if (gamestate == GS_LEVEL || (gamestate == GS_TITLESCREEN && titlemapinaction && curbghide && (!hidetitlemap)))
{ {
// draw the view directly // draw the view directly
if (!automapactive && !dedicated && cv_renderview.value) if (!automapactive && !dedicated && cv_renderview.value)
{ {
SCR_SetSoftwareTranslucency(); // Set translucency method
if (!usetranstables)
R_InitAlphaLUT();
R_ApplyLevelInterpolators(R_UsingFrameInterpolation() ? rendertimefrac : FRACUNIT); R_ApplyLevelInterpolators(R_UsingFrameInterpolation() ? rendertimefrac : FRACUNIT);
PS_START_TIMING(ps_rendercalltime); PS_START_TIMING(ps_rendercalltime);
if (players[displayplayer].mo || players[displayplayer].playerstate == PST_DEAD) if (players[displayplayer].mo || players[displayplayer].playerstate == PST_DEAD)
{ {
topleft = screens[0] + viewwindowy*vid.width + viewwindowx; topleft = screens[0] + viewwindowy*vid.width + viewwindowx;
#ifdef TRUECOLOR
if (truecolor)
topleft_u32 = (UINT32 *)screens[0] + viewwindowy*vid.width + viewwindowx;
#endif
objectsdrawn = 0; objectsdrawn = 0;
#ifdef HWRENDER #ifdef HWRENDER
if (rendermode != render_soft) if (!VID_InSoftwareRenderer())
HWR_RenderPlayerView(0, &players[displayplayer]); HWR_RenderPlayerView(0, &players[displayplayer]);
else else
#endif #endif
if (rendermode != render_none) if (rendermode != render_none)
R_RenderPlayerView(&players[displayplayer]); R_RenderPlayerView(&players[displayplayer]);
} }
...@@ -496,17 +504,21 @@ static void D_Display(void) ...@@ -496,17 +504,21 @@ static void D_Display(void)
// render the second screen // render the second screen
if (splitscreen && players[secondarydisplayplayer].mo) if (splitscreen && players[secondarydisplayplayer].mo)
{ {
#ifdef HWRENDER #ifdef HWRENDER
if (rendermode != render_soft) if (!VID_InSoftwareRenderer())
HWR_RenderPlayerView(1, &players[secondarydisplayplayer]); HWR_RenderPlayerView(1, &players[secondarydisplayplayer]);
else else
#endif #endif
if (rendermode != render_none) if (rendermode != render_none)
{ {
viewwindowy = vid.height / 2; viewwindowy = vid.height / 2;
M_Memcpy(ylookup, ylookup2, viewheight*sizeof (ylookup[0])); M_Memcpy(ylookup, ylookup2, viewheight*sizeof (ylookup[0]));
topleft = screens[0] + viewwindowy*vid.width + viewwindowx; 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]); R_RenderPlayerView(&players[secondarydisplayplayer]);
...@@ -516,7 +528,7 @@ static void D_Display(void) ...@@ -516,7 +528,7 @@ static void D_Display(void)
} }
// Image postprocessing effect // Image postprocessing effect
if (rendermode == render_soft) if (VID_InSoftwareRenderer())
{ {
if (!splitscreen) if (!splitscreen)
R_ApplyViewMorph(); R_ApplyViewMorph();
...@@ -532,7 +544,7 @@ static void D_Display(void) ...@@ -532,7 +544,7 @@ static void D_Display(void)
if (lastdraw) 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); VID_BlitLinearScreen(screens[0], screens[1], vid.width*vid.bpp, vid.height, vid.width*vid.bpp, vid.rowbytes);
Y_ConsiderScreenBuffer(); Y_ConsiderScreenBuffer();
...@@ -688,6 +700,26 @@ static void D_Display(void) ...@@ -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 // D_SRB2Loop
// ========================================================================= // =========================================================================
......
...@@ -47,6 +47,12 @@ const char *D_Home(void); ...@@ -47,6 +47,12 @@ const char *D_Home(void);
boolean D_IsPathAllowed(const char *path); boolean D_IsPathAllowed(const char *path);
boolean D_CheckPathAllowed(const char *path, const char *why); boolean D_CheckPathAllowed(const char *path, const char *why);
//
// RENDERER STATE
//
void D_CheckRendererState(void);
void D_CheckColorDepth(INT32 newbitdepth, INT32 oldbitdepth);
// //
// BASE LEVEL // BASE LEVEL
// //
......
...@@ -2837,7 +2837,6 @@ void readsound(MYFILE *f, INT32 num) ...@@ -2837,7 +2837,6 @@ void readsound(MYFILE *f, INT32 num)
tmp = strchr(s, '\n'); tmp = strchr(s, '\n');
if (tmp) if (tmp)
*tmp = '\0'; *tmp = '\0';
tmp = strchr(s, '#'); tmp = strchr(s, '#');
if (tmp) if (tmp)
*tmp = '\0'; *tmp = '\0';
......
...@@ -659,6 +659,12 @@ extern const char *compdate, *comptime, *comprevision, *compbranch; ...@@ -659,6 +659,12 @@ extern const char *compdate, *comptime, *comprevision, *compbranch;
/// Render flats on walls /// Render flats on walls
#define WALLFLATS #define WALLFLATS
/// Software true color mode rendering
#ifndef NO_TRUECOLOR
#define TRUECOLOR
#endif
/// Maintain compatibility with older 2.2 demos /// Maintain compatibility with older 2.2 demos
#define OLD22DEMOCOMPAT #define OLD22DEMOCOMPAT
......
...@@ -6,6 +6,7 @@ rendermode_t rendermode = render_none; ...@@ -6,6 +6,7 @@ rendermode_t rendermode = render_none;
rendermode_t chosenrendermode = render_none; rendermode_t chosenrendermode = render_none;
boolean highcolor = false; boolean highcolor = false;
boolean truecolor = false;
boolean allow_fullscreen = false; boolean allow_fullscreen = false;
...@@ -41,6 +42,17 @@ INT32 VID_SetMode(INT32 modenum) ...@@ -41,6 +42,17 @@ INT32 VID_SetMode(INT32 modenum)
return 0; return 0;
} }
boolean VID_IsASoftwareRenderer(rendermode_t mode)
{
(void)mode;
return false;
}
boolean VID_InSoftwareRenderer(void)
{
return false;
}
boolean VID_CheckRenderer(void) boolean VID_CheckRenderer(void)
{ {
return false; return false;
......
...@@ -162,10 +162,17 @@ static fademask_t *F_GetFadeMask(UINT8 masknum, UINT8 scrnnum) { ...@@ -162,10 +162,17 @@ static fademask_t *F_GetFadeMask(UINT8 masknum, UINT8 scrnnum) {
{ {
// Determine pixel to use from fademask // Determine pixel to use from fademask
pcolor = &pMasterPalette[*lump++]; pcolor = &pMasterPalette[*lump++];
if (wipestyle == WIPESTYLE_COLORMAP) #ifdef TRUECOLOR
*mask++ = pcolor->s.red / FADECOLORMAPDIV; if (truecolor)
*mask++ = pcolor->s.red;
else 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); fm.xscale = FixedDiv(vid.width<<FRACBITS, fm.width<<FRACBITS);
...@@ -200,231 +207,583 @@ void F_WipeStageTitle(void) ...@@ -200,231 +207,583 @@ void F_WipeStageTitle(void)
} }
} }
/** Wipe ticker // Software mask wipe -- optimized; though it might not look like it!
* // Okay, to save you wondering *how* this is more optimized than the simpler
* \param fademask pixels to change // 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) static void F_DoWipe(fademask_t *fademask)
{ {
// Software mask wipe -- optimized; though it might not look like it! // wipe screen, start, end
// Okay, to save you wondering *how* this is more optimized than the simpler UINT8 *w = wipe_scr;
// version that came before it... 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 // Screw it, we do the fixed point math ourselves up front.
// screen, of which there are hundreds of thousands -- if not millions -- of. scrxpos[0] = 0;
// This worked fine for smaller screen sizes, but with excessively large for (relativepos = 0, maskx = 1; maskx < fademask->width; ++maskx)
// (1920x1200) screens that meant 4 million+ calls out to FixedMul, and that scrxpos[maskx] = (relativepos += fademask->xscale)>>FRACBITS;
// would take /just/ long enough that fades would start to noticably lag. 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 maskx = masky = 0;
// the next pixel in the fade mask. As a result, it's more complex (and might do
// 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.
{ {
// wipe screen, start, end draw_rowstart = scrxpos[maskx];
UINT8 *w = wipe_scr; draw_rowend = scrxpos[maskx + 1];
const UINT8 *s = wipe_scr_start; draw_linestart = scrypos[masky];
const UINT8 *e = wipe_scr_end; draw_lineend = scrypos[masky + 1];
// 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; relativepos = (draw_linestart * vid.width) + draw_rowstart;
draw_linestogo = draw_lineend - draw_linestart; 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 M_Memcpy(w_base+relativepos, s_base+relativepos, draw_rowend-draw_rowstart);
while (draw_linestogo--) 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 M_Memcpy(w_base+relativepos, e_base+relativepos, draw_rowend-draw_rowstart);
while (draw_linestogo--) relativepos += vid.width;
{
M_Memcpy(w_base+relativepos, e_base+relativepos, draw_rowend-draw_rowstart);
relativepos += vid.width;
}
} }
else }
{ else
// pointer to transtable that this mask would use {
transtbl = R_GetTranslucencyTable((9 - *mask) + 1); // pointer to transtable that this mask would use
transtbl = R_GetTranslucencyTable((9 - *mask) + 1);
// DRAWING LOOP // DRAWING LOOP
while (draw_linestogo--) while (draw_linestogo--)
{ {
w = w_base + relativepos; w = w_base + relativepos;
s = s_base + relativepos; s = s_base + relativepos;
e = e_base + relativepos; e = e_base + relativepos;
draw_rowstogo = draw_rowend - draw_rowstart; draw_rowstogo = draw_rowend - draw_rowstart;
while (draw_rowstogo--) while (draw_rowstogo--)
*w++ = transtbl[ ( *e++ << 8 ) + *s++ ]; *w++ = transtbl[ ( *e++ << 8 ) + *s++ ];
relativepos += vid.width; relativepos += vid.width;
}
// END DRAWING LOOP
} }
// END DRAWING LOOP
}
if (++maskx >= fademask->width) if (++maskx >= fademask->width)
++masky, maskx = 0; ++masky, maskx = 0;
} while (++mask < maskend); } while (++mask < maskend);
free(scrxpos); free(scrxpos);
free(scrypos); free(scrypos);
}
} }
// F_DoWipe for WIPESTYLE_COLORMAP
static void F_DoColormapWipe(fademask_t *fademask, UINT8 *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 draw_rowstart = scrxpos[maskx];
UINT8 *w = wipe_scr; draw_rowend = scrxpos[maskx + 1];
const UINT8 *s = wipe_scr_start; draw_linestart = scrypos[masky];
const UINT8 *e = wipe_scr_end; draw_lineend = scrypos[masky + 1];
// first pixel for each screen relativepos = (draw_linestart * vid.width) + draw_rowstart;
UINT8 *w_base = w; draw_linestogo = draw_lineend - draw_linestart;
const UINT8 *s_base = s;
const UINT8 *e_base = e; if (*mask == 0)
{
// mask data, end // shortcut - memcpy source to work
UINT8 *transtbl; while (draw_linestogo--)
const UINT8 *mask = fademask->mask; {
const UINT8 *maskend = mask + fademask->size; M_Memcpy(w_base+relativepos, s_base+relativepos, draw_rowend-draw_rowstart);
relativepos += vid.width;
// rectangle draw hints }
UINT32 draw_linestart, draw_rowstart; }
UINT32 draw_lineend, draw_rowend; else if (*mask >= FADECOLORMAPROWS)
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]; // shortcut - memcpy target to work
draw_rowend = scrxpos[maskx + 1]; while (draw_linestogo--)
draw_linestart = scrypos[masky]; {
draw_lineend = scrypos[masky + 1]; 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; transtbl = colormap + (nmask * 256);
draw_linestogo = draw_lineend - draw_linestart;
if (*mask == 0) // DRAWING LOOP
while (draw_linestogo--)
{ {
// shortcut - memcpy source to work w = w_base + relativepos;
while (draw_linestogo--) s = s_base + relativepos;
{ e = e_base + relativepos;
M_Memcpy(w_base+relativepos, s_base+relativepos, draw_rowend-draw_rowstart); draw_rowstogo = draw_rowend - draw_rowstart;
relativepos += vid.width;
} 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 w = w_base + relativepos;
while (draw_linestogo--) 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); *w = R_TranslucentMix(*s, *e, *mask);
relativepos += vid.width; 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; M_Memcpy(w_base+relativepos, s_base+relativepos, (draw_rowend-draw_rowstart) * vid.bpp);
if (wipestyleflags & WSF_FADEIN) relativepos += vid.width;
nmask = (FADECOLORMAPROWS-1) - nmask; }
}
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 // This is gonna be mad slow...
while (draw_linestogo--) while (draw_rowstogo--)
{ {
w = w_base + relativepos; // subtractive color blending
s = s_base + relativepos; pack.rgba = *sauce;
e = e_base + relativepos; r = pack.s.red - FADEREDFACTOR*alpha/10;
draw_rowstogo = draw_rowend - draw_rowstart; 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--) relativepos += vid.width;
*w++ = transtbl[*e++]; }
// 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) if (++maskx >= fademask->width)
++masky, maskx = 0; ++masky, maskx = 0;
} while (++mask < maskend); } while (++mask < maskend);
free(scrxpos); free(scrxpos);
free(scrypos); free(scrypos);
}
} }
#endif // TRUECOLOR
#endif #endif
/** Save the "before" screen of a wipe. /** Save the "before" screen of a wipe.
...@@ -433,7 +792,7 @@ void F_WipeStartScreen(void) ...@@ -433,7 +792,7 @@ void F_WipeStartScreen(void)
{ {
#ifndef NOWIPE #ifndef NOWIPE
#ifdef HWRENDER #ifdef HWRENDER
if(rendermode != render_soft) if(!VID_InSoftwareRenderer())
{ {
HWR_StartScreenWipe(); HWR_StartScreenWipe();
return; return;
...@@ -450,7 +809,7 @@ void F_WipeEndScreen(void) ...@@ -450,7 +809,7 @@ void F_WipeEndScreen(void)
{ {
#ifndef NOWIPE #ifndef NOWIPE
#ifdef HWRENDER #ifdef HWRENDER
if(rendermode != render_soft) if(!VID_InSoftwareRenderer())
{ {
HWR_EndScreenWipe(); HWR_EndScreenWipe();
return; return;
...@@ -513,6 +872,10 @@ boolean F_TryColormapFade(UINT8 wipecolor) ...@@ -513,6 +872,10 @@ boolean F_TryColormapFade(UINT8 wipecolor)
#ifdef HWRENDER #ifdef HWRENDER
if (rendermode == render_opengl) if (rendermode == render_opengl)
F_WipeColorFill(wipecolor); F_WipeColorFill(wipecolor);
#endif
#ifdef TRUECOLOR
if (VID_InSoftwareRenderer() && truecolor)
F_WipeColorFill(wipecolor);
#endif #endif
return true; return true;
} }
...@@ -574,10 +937,22 @@ void F_RunWipe(UINT8 wipetype, boolean drawMenu) ...@@ -574,10 +937,22 @@ void F_RunWipe(UINT8 wipetype, boolean drawMenu)
else else
#endif #endif
{ {
UINT8 *colormap = fadecolormap; #ifdef TRUECOLOR
if (wipestyleflags & WSF_TOWHITE) if (truecolor)
colormap += (FADECOLORMAPROWS * 256); {
F_DoColormapWipe(fmask, colormap); 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 // Draw the title card above the wipe
...@@ -593,7 +968,14 @@ void F_RunWipe(UINT8 wipetype, boolean drawMenu) ...@@ -593,7 +968,14 @@ void F_RunWipe(UINT8 wipetype, boolean drawMenu)
} }
else else
#endif #endif
F_DoWipe(fmask); {
#ifdef TRUECOLOR
if (truecolor)
F_DoWipe32(fmask);
else
#endif
F_DoWipe(fmask);
}
} }
I_OsPolling(); I_OsPolling();
......
...@@ -2501,7 +2501,7 @@ static inline void G_PlayerFinishLevel(INT32 player) ...@@ -2501,7 +2501,7 @@ static inline void G_PlayerFinishLevel(INT32 player)
p->starpostz = 0; p->starpostz = 0;
p->starpostnum = 0; p->starpostnum = 0;
if (rendermode == render_soft) if (VID_InSoftwareRenderer())
V_SetPaletteLump(GetPalette()); // Reset the palette V_SetPaletteLump(GetPalette()); // Reset the palette
} }
......
...@@ -42,6 +42,44 @@ static INT32 format2bpp(GLTextureFormat_t format) ...@@ -42,6 +42,44 @@ static INT32 format2bpp(GLTextureFormat_t format)
return 1; 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. // This code was originally placed directly in HWR_DrawPatchInCache.
// It is now split from it for my sanity! (and the sanity of others) // It is now split from it for my sanity! (and the sanity of others)
// -- Monster Iestyn (13/02/19) // -- Monster Iestyn (13/02/19)
...@@ -49,24 +87,34 @@ static void HWR_DrawColumnInCache(const column_t *patchcol, UINT8 *block, GLMipm ...@@ -49,24 +87,34 @@ static void HWR_DrawColumnInCache(const column_t *patchcol, UINT8 *block, GLMipm
INT32 pblockheight, INT32 blockmodulo, INT32 pblockheight, INT32 blockmodulo,
fixed_t yfracstep, fixed_t scale_y, fixed_t yfracstep, fixed_t scale_y,
texpatch_t *originPatch, INT32 patchheight, texpatch_t *originPatch, INT32 patchheight,
INT32 bpp) INT32 bpp, pictureformat_t format)
{ {
fixed_t yfrac, position, count; fixed_t yfrac, position, count;
UINT8 *dest; UINT8 *dest;
const UINT8 *source; const UINT8 *source = NULL;
const UINT16 *sourceu16 = NULL;
const UINT32 *sourceu32 = NULL;
INT32 topdelta, prevdelta = -1; INT32 topdelta, prevdelta = -1;
INT32 originy = 0; INT32 originy = 0;
// for writing a pixel to dest // for writing a pixel to dest
RGBA_t colortemp; RGBA_t colortemp;
UINT8 alpha; UINT8 alpha = 0;
UINT8 texel; UINT8 texel = 0;
UINT16 texelu16; 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 (void)patchheight; // This parameter is unused
if (originPatch) // originPatch can be NULL here, unlike in the software version if (originPatch) // originPatch can be NULL here, unlike in the software version
{
PixelBlendFunction = ASTBlendTexturePixel;
originy = originPatch->originy; originy = originPatch->originy;
}
memset(&texelu32, 0x00, sizeof(RGBA_t));
while (patchcol->topdelta != 0xff) while (patchcol->topdelta != 0xff)
{ {
...@@ -74,10 +122,15 @@ static void HWR_DrawColumnInCache(const column_t *patchcol, UINT8 *block, GLMipm ...@@ -74,10 +122,15 @@ static void HWR_DrawColumnInCache(const column_t *patchcol, UINT8 *block, GLMipm
if (topdelta <= prevdelta) if (topdelta <= prevdelta)
topdelta += prevdelta; topdelta += prevdelta;
prevdelta = topdelta; 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; 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; yfrac = 0;
//yfracstep = (patchcol->length << FRACBITS) / count; //yfracstep = (patchcol->length << FRACBITS) / count;
if (position < 0) if (position < 0)
...@@ -100,43 +153,84 @@ static void HWR_DrawColumnInCache(const column_t *patchcol, UINT8 *block, GLMipm ...@@ -100,43 +153,84 @@ static void HWR_DrawColumnInCache(const column_t *patchcol, UINT8 *block, GLMipm
{ {
count--; count--;
texel = source[yfrac>>FRACBITS]; // Read the texel
alpha = 0xFF; if (sourcebpp == PICDEPTH_32BPP)
// Make pixel transparent if chroma keyed {
if ((mipmap->flags & TF_CHROMAKEYED) && (texel == HWR_PATCHES_CHROMAKEY_COLORINDEX)) UINT32 s32 = sourceu32[yfrac>>FRACBITS];
alpha = 0x00; 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 //Hurdler: 25/04/2000: now support colormap in hardware mode
#ifdef COLORMAP_RGBA_PIXELS
if (mipmap->colormap) 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]; 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...) // 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 ?) // gcc do it ! but vcc not ! (why don't use cygwin gcc for win32 ?)
// Alam: SRB2 uses Mingw, HUGS // Alam: SRB2 uses Mingw, HUGS
switch (bpp) switch (bpp)
{ {
case 2 : // uhhhhhhhh.......... case 2 :
if ((originPatch != NULL) && (originPatch->style != AST_COPY)) if ((originPatch != NULL) && (originPatch->style != AST_COPY))
texel = ASTBlendPaletteIndexes(*(dest+1), texel, originPatch->style, originPatch->alpha); texel = ASTBlendPaletteIndexes(*(dest+1), texel, originPatch->style, originPatch->alpha);
texelu16 = (UINT16)((alpha<<8) | texel); texelu16 = (UINT16)((alpha<<8) | texel);
memcpy(dest, &texelu16, sizeof(UINT16)); memcpy(dest, &texelu16, sizeof(UINT16));
break; break;
case 3 : colortemp = V_GetColor(texel); case 3 : colortemp = texelu32;
if ((originPatch != NULL) && (originPatch->style != AST_COPY)) if ((originPatch != NULL) && (originPatch->style != AST_COPY))
{ {
RGBA_t rgbatexel; RGBA_t rgbatexel;
rgbatexel.rgba = *(UINT32 *)dest; 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)); memcpy(dest, &colortemp, sizeof(RGBA_t)-sizeof(UINT8));
break; break;
case 4 : colortemp = V_GetColor(texel); case 4 : colortemp = texelu32;
colortemp.s.alpha = alpha; colortemp.s.alpha = alpha;
if ((originPatch != NULL) && (originPatch->style != AST_COPY)) if ((originPatch != NULL) && (originPatch->style != AST_COPY))
{ {
RGBA_t rgbatexel; RGBA_t rgbatexel;
rgbatexel.rgba = *(UINT32 *)dest; 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)); memcpy(dest, &colortemp, sizeof(RGBA_t));
break; break;
...@@ -152,7 +246,13 @@ static void HWR_DrawColumnInCache(const column_t *patchcol, UINT8 *block, GLMipm ...@@ -152,7 +246,13 @@ static void HWR_DrawColumnInCache(const column_t *patchcol, UINT8 *block, GLMipm
dest += blockmodulo; dest += blockmodulo;
yfrac += yfracstep; 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, ...@@ -160,22 +260,33 @@ static void HWR_DrawFlippedColumnInCache(const column_t *patchcol, UINT8 *block,
INT32 pblockheight, INT32 blockmodulo, INT32 pblockheight, INT32 blockmodulo,
fixed_t yfracstep, fixed_t scale_y, fixed_t yfracstep, fixed_t scale_y,
texpatch_t *originPatch, INT32 patchheight, texpatch_t *originPatch, INT32 patchheight,
INT32 bpp) INT32 bpp, pictureformat_t format)
{ {
fixed_t yfrac, position, count; fixed_t yfrac, position, count;
UINT8 *dest; UINT8 *dest;
const UINT8 *source; const UINT8 *source = NULL;
const UINT16 *sourceu16 = NULL;
const UINT32 *sourceu32 = NULL;
INT32 topdelta, prevdelta = -1; INT32 topdelta, prevdelta = -1;
INT32 originy = 0; INT32 originy = 0;
// for writing a pixel to dest // for writing a pixel to dest
RGBA_t colortemp; RGBA_t colortemp;
UINT8 alpha; UINT8 alpha = 0;
UINT8 texel; UINT8 texel = 0;
UINT16 texelu16; 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 if (originPatch) // originPatch can be NULL here, unlike in the software version
{
PixelBlendFunction = ASTBlendTexturePixel;
originy = originPatch->originy; originy = originPatch->originy;
}
memset(&texelu32, 0x00, sizeof(RGBA_t));
while (patchcol->topdelta != 0xff) while (patchcol->topdelta != 0xff)
{ {
...@@ -184,10 +295,15 @@ static void HWR_DrawFlippedColumnInCache(const column_t *patchcol, UINT8 *block, ...@@ -184,10 +295,15 @@ static void HWR_DrawFlippedColumnInCache(const column_t *patchcol, UINT8 *block,
topdelta += prevdelta; topdelta += prevdelta;
prevdelta = topdelta; prevdelta = topdelta;
topdelta = patchheight-patchcol->length-topdelta; topdelta = patchheight-patchcol->length-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; 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; yfrac = (patchcol->length-1) << FRACBITS;
if (position < 0) if (position < 0)
...@@ -210,43 +326,84 @@ static void HWR_DrawFlippedColumnInCache(const column_t *patchcol, UINT8 *block, ...@@ -210,43 +326,84 @@ static void HWR_DrawFlippedColumnInCache(const column_t *patchcol, UINT8 *block,
{ {
count--; count--;
texel = source[yfrac>>FRACBITS]; // Read the texel
alpha = 0xFF; if (sourcebpp == PICDEPTH_32BPP)
// Make pixel transparent if chroma keyed {
if ((mipmap->flags & TF_CHROMAKEYED) && (texel == HWR_PATCHES_CHROMAKEY_COLORINDEX)) UINT32 s32 = sourceu32[yfrac>>FRACBITS];
alpha = 0x00; 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 //Hurdler: 25/04/2000: now support colormap in hardware mode
#ifdef COLORMAP_RGBA_PIXELS
if (mipmap->colormap) 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]; 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...) // 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 ?) // gcc do it ! but vcc not ! (why don't use cygwin gcc for win32 ?)
// Alam: SRB2 uses Mingw, HUGS // Alam: SRB2 uses Mingw, HUGS
switch (bpp) switch (bpp)
{ {
case 2 : // uhhhhhhhh.......... case 2 :
if ((originPatch != NULL) && (originPatch->style != AST_COPY)) if ((originPatch != NULL) && (originPatch->style != AST_COPY))
texel = ASTBlendPaletteIndexes(*(dest+1), texel, originPatch->style, originPatch->alpha); texel = ASTBlendPaletteIndexes(*(dest+1), texel, originPatch->style, originPatch->alpha);
texelu16 = (UINT16)((alpha<<8) | texel); texelu16 = (UINT16)((alpha<<8) | texel);
memcpy(dest, &texelu16, sizeof(UINT16)); memcpy(dest, &texelu16, sizeof(UINT16));
break; break;
case 3 : colortemp = V_GetColor(texel); case 3 : colortemp = texelu32;
if ((originPatch != NULL) && (originPatch->style != AST_COPY)) if ((originPatch != NULL) && (originPatch->style != AST_COPY))
{ {
RGBA_t rgbatexel; RGBA_t rgbatexel;
rgbatexel.rgba = *(UINT32 *)dest; 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)); memcpy(dest, &colortemp, sizeof(RGBA_t)-sizeof(UINT8));
break; break;
case 4 : colortemp = V_GetColor(texel); case 4 : colortemp = texelu32;
colortemp.s.alpha = alpha; colortemp.s.alpha = alpha;
if ((originPatch != NULL) && (originPatch->style != AST_COPY)) if ((originPatch != NULL) && (originPatch->style != AST_COPY))
{ {
RGBA_t rgbatexel; RGBA_t rgbatexel;
rgbatexel.rgba = *(UINT32 *)dest; 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)); memcpy(dest, &colortemp, sizeof(RGBA_t));
break; break;
...@@ -262,11 +419,16 @@ static void HWR_DrawFlippedColumnInCache(const column_t *patchcol, UINT8 *block, ...@@ -262,11 +419,16 @@ static void HWR_DrawFlippedColumnInCache(const column_t *patchcol, UINT8 *block,
dest += blockmodulo; dest += blockmodulo;
yfrac -= yfracstep; 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 // Simplified patch caching function
// for use by sprites and other patches that are not part of a wall texture // 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 // 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, ...@@ -275,7 +437,8 @@ static void HWR_DrawFlippedColumnInCache(const column_t *patchcol, UINT8 *block,
static void HWR_DrawPatchInCache(GLMipmap_t *mipmap, static void HWR_DrawPatchInCache(GLMipmap_t *mipmap,
INT32 pblockwidth, INT32 pblockheight, INT32 pblockwidth, INT32 pblockheight,
INT32 pwidth, INT32 pheight, INT32 pwidth, INT32 pheight,
const patch_t *realpatch) const patch_t *realpatch,
pictureformat_t format)
{ {
INT32 ncols; INT32 ncols;
fixed_t xfrac, xfracstep; fixed_t xfrac, xfracstep;
...@@ -301,6 +464,9 @@ static void HWR_DrawPatchInCache(GLMipmap_t *mipmap, ...@@ -301,6 +464,9 @@ static void HWR_DrawPatchInCache(GLMipmap_t *mipmap,
if (bpp < 1 || bpp > 4) if (bpp < 1 || bpp > 4)
I_Error("HWR_DrawPatchInCache: no drawer defined for this bpp (%d)\n",bpp); 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? // NOTE: should this actually be pblockwidth*bpp?
blockmodulo = pblockwidth*bpp; blockmodulo = pblockwidth*bpp;
...@@ -313,7 +479,7 @@ static void HWR_DrawPatchInCache(GLMipmap_t *mipmap, ...@@ -313,7 +479,7 @@ static void HWR_DrawPatchInCache(GLMipmap_t *mipmap,
pblockheight, blockmodulo, pblockheight, blockmodulo,
yfracstep, scale_y, yfracstep, scale_y,
NULL, pheight, // not that pheight is going to get used anyway... 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, ...@@ -321,7 +487,8 @@ static void HWR_DrawPatchInCache(GLMipmap_t *mipmap,
static void HWR_DrawTexturePatchInCache(GLMipmap_t *mipmap, static void HWR_DrawTexturePatchInCache(GLMipmap_t *mipmap,
INT32 pblockwidth, INT32 pblockheight, INT32 pblockwidth, INT32 pblockheight,
texture_t *texture, texpatch_t *patch, texture_t *texture, texpatch_t *patch,
const softwarepatch_t *realpatch) const softwarepatch_t *realpatch,
pictureformat_t format)
{ {
INT32 x, x1, x2; INT32 x, x1, x2;
INT32 col, ncols; INT32 col, ncols;
...@@ -337,7 +504,7 @@ static void HWR_DrawTexturePatchInCache(GLMipmap_t *mipmap, ...@@ -337,7 +504,7 @@ static void HWR_DrawTexturePatchInCache(GLMipmap_t *mipmap,
INT32 pblockheight, INT32 blockmodulo, INT32 pblockheight, INT32 blockmodulo,
fixed_t yfracstep, fixed_t scale_y, fixed_t yfracstep, fixed_t scale_y,
texpatch_t *originPatch, INT32 patchheight, texpatch_t *originPatch, INT32 patchheight,
INT32 bpp); INT32 bpp, pictureformat_t format);
if (texture->width <= 0 || texture->height <= 0) if (texture->width <= 0 || texture->height <= 0)
return; return;
...@@ -394,6 +561,9 @@ static void HWR_DrawTexturePatchInCache(GLMipmap_t *mipmap, ...@@ -394,6 +561,9 @@ static void HWR_DrawTexturePatchInCache(GLMipmap_t *mipmap,
if (bpp < 1 || bpp > 4) if (bpp < 1 || bpp > 4)
I_Error("HWR_DrawTexturePatchInCache: no drawer defined for this bpp (%d)\n",bpp); 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? // NOTE: should this actually be pblockwidth*bpp?
blockmodulo = pblockwidth*bpp; blockmodulo = pblockwidth*bpp;
...@@ -409,7 +579,7 @@ static void HWR_DrawTexturePatchInCache(GLMipmap_t *mipmap, ...@@ -409,7 +579,7 @@ static void HWR_DrawTexturePatchInCache(GLMipmap_t *mipmap,
pblockheight, blockmodulo, pblockheight, blockmodulo,
yfracstep, scale_y, yfracstep, scale_y,
patch, height, patch, height,
bpp); bpp, format);
} }
} }
...@@ -497,33 +667,37 @@ static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *grtex) ...@@ -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. // Composite the columns together.
for (i = 0, patch = texture->patches; i < texture->patchcount; i++, patch++) 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); size_t lumplength = W_LumpLengthPwad(patch->wad, patch->lump);
pdata = W_CacheLumpNumPwad(patch->wad, patch->lump, PU_CACHE); pdata = W_CacheLumpNumPwad(patch->wad, patch->lump, PU_CACHE);
realpatch = (softwarepatch_t *)pdata; realpatch = (softwarepatch_t *)pdata;
#ifndef NO_PNG_LUMPS #ifndef NO_PNG_LUMPS
if (Picture_IsLumpPNG((UINT8 *)realpatch, lumplength)) 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 else
#endif #endif
#ifdef WALLFLATS #ifdef WALLFLATS
if (texture->type == TEXTURETYPE_FLAT) 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 else
#endif #endif
{ {
(void)lumplength; (void)lumplength;
dealloc = false;
} }
HWR_DrawTexturePatchInCache(&grtex->mipmap, blockwidth, blockheight, texture, patch, realpatch); HWR_DrawTexturePatchInCache(&grtex->mipmap, blockwidth, blockheight, texture, patch, realpatch, format);
if (dealloc)
Z_Unlock(realpatch);
} }
//Hurdler: not efficient at all but I don't remember exactly how HWR_DrawPatchInCache works :( //Hurdler: not efficient at all but I don't remember exactly how HWR_DrawPatchInCache works :(
if (format2bpp(grtex->mipmap.format)==4) if (format2bpp(grtex->mipmap.format)==4)
...@@ -543,8 +717,9 @@ static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *grtex) ...@@ -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 // 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) if (grMipmap->width == 0)
{ {
grMipmap->width = grMipmap->height = 1; grMipmap->width = grMipmap->height = 1;
...@@ -566,12 +741,22 @@ void HWR_MakePatch (const patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipm ...@@ -566,12 +741,22 @@ void HWR_MakePatch (const patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipm
if (makebitmap) 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); MakeBlock(grMipmap);
HWR_DrawPatchInCache(grMipmap, HWR_DrawPatchInCache(grMipmap,
grMipmap->width, grMipmap->height, grMipmap->width, grMipmap->height,
patch->width, patch->height, source->width, source->height,
patch); source, grPatch->picfmt);
} }
} }
...@@ -821,21 +1006,47 @@ static void HWR_CacheFlat(GLMipmap_t *grMipmap, lumpnum_t flatlumpnum) ...@@ -821,21 +1006,47 @@ static void HWR_CacheFlat(GLMipmap_t *grMipmap, lumpnum_t flatlumpnum)
static void HWR_CacheTextureAsFlat(GLMipmap_t *grMipmap, INT32 texturenum) static void HWR_CacheTextureAsFlat(GLMipmap_t *grMipmap, INT32 texturenum)
{ {
UINT8 *flat; UINT8 *flat;
UINT8 *converted;
size_t size; 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 // setup the texture info
#ifdef PICTURES_ALLOWDEPTH
grMipmap->format = textureformat;
#else
grMipmap->format = GL_TEXFMT_P_8; 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; 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); flat = Z_Malloc(size, PU_HWRCACHE, &grMipmap->data);
converted = (UINT8 *)Picture_TextureToFlat(texturenum); converted = (UINT8 *)Picture_TextureToFlat(texturenum);
M_Memcpy(flat, converted, size); M_Memcpy(flat, converted, size);
Z_Free(converted); Z_Free(converted);
#endif
} }
// Download a Doom 'flat' to the hardware cache and make it ready for use // Download a Doom 'flat' to the hardware cache and make it ready for use
...@@ -908,12 +1119,14 @@ void HWR_GetLevelFlat(levelflat_t *levelflat) ...@@ -908,12 +1119,14 @@ void HWR_GetLevelFlat(levelflat_t *levelflat)
else if (levelflat->type == LEVELFLAT_PNG) else if (levelflat->type == LEVELFLAT_PNG)
{ {
GLMipmap_t *mipmap = levelflat->mipmap; GLMipmap_t *mipmap = levelflat->mipmap;
pictureformat_t format = PICFMT_FLAT32;
INT32 fmtbpp = Picture_FormatBPP(format);
// Cache the picture. // Cache the picture.
if (!levelflat->mippic) if (!levelflat->mippic)
{ {
INT32 pngwidth = 0, pngheight = 0; 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_ChangeTag(pic, PU_LEVEL);
Z_SetUser(pic, &levelflat->mippic); Z_SetUser(pic, &levelflat->mippic);
...@@ -926,7 +1139,7 @@ void HWR_GetLevelFlat(levelflat_t *levelflat) ...@@ -926,7 +1139,7 @@ void HWR_GetLevelFlat(levelflat_t *levelflat)
if (mipmap == NULL) if (mipmap == NULL)
{ {
mipmap = Z_Calloc(sizeof(GLMipmap_t), PU_STATIC, 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; mipmap->flags = TF_WRAPXY|TF_CHROMAKEYED;
levelflat->mipmap = mipmap; levelflat->mipmap = mipmap;
} }
...@@ -942,7 +1155,7 @@ void HWR_GetLevelFlat(levelflat_t *levelflat) ...@@ -942,7 +1155,7 @@ void HWR_GetLevelFlat(levelflat_t *levelflat)
mipmap->width = levelflat->width; mipmap->width = levelflat->width;
mipmap->height = levelflat->height; mipmap->height = levelflat->height;
size = (mipmap->width * mipmap->height); size = (mipmap->width * mipmap->height) * (fmtbpp / 8);
flat = Z_Malloc(size, PU_LEVEL, &mipmap->data); flat = Z_Malloc(size, PU_LEVEL, &mipmap->data);
M_Memcpy(flat, levelflat->mippic, size); M_Memcpy(flat, levelflat->mippic, size);
} }
......
...@@ -84,6 +84,7 @@ typedef struct GLMapTexture_s GLMapTexture_t; ...@@ -84,6 +84,7 @@ typedef struct GLMapTexture_s GLMapTexture_t;
struct GLPatch_s struct GLPatch_s
{ {
GLMipmap_t *mipmap; // Texture data. Allocated whenever the patch is. GLMipmap_t *mipmap; // Texture data. Allocated whenever the patch is.
int picfmt;
float max_s, max_t; float max_s, max_t;
}; };
typedef struct GLPatch_s GLPatch_t; typedef struct GLPatch_s GLPatch_t;
......
...@@ -82,7 +82,7 @@ typedef struct gl_vissprite_s ...@@ -82,7 +82,7 @@ typedef struct gl_vissprite_s
boolean flip, vflip; boolean flip, vflip;
boolean precip; // Tails 08-25-2002 boolean precip; // Tails 08-25-2002
boolean rotated; boolean rotated;
UINT8 translucency; //alpha level 0-255 boolean translucent;
angle_t angle; // for splats angle_t angle; // for splats
...@@ -92,6 +92,9 @@ typedef struct gl_vissprite_s ...@@ -92,6 +92,9 @@ typedef struct gl_vissprite_s
patch_t *gpatch; patch_t *gpatch;
mobj_t *mobj; // NOTE: This is a precipmobj_t if precip is true !!! Watch out. mobj_t *mobj; // NOTE: This is a precipmobj_t if precip is true !!! Watch out.
INT32 blendmode;
INT32 alpha;
} gl_vissprite_t; } gl_vissprite_t;
// -------- // --------
......
...@@ -704,36 +704,15 @@ FBITFIELD HWR_GetBlendModeFlag(INT32 style) ...@@ -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); if (style <= AST_COPY || style >= AST_OVERLAY)
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)
{ {
pSurf->PolyColor.s.alpha = 0xff; pSurf->PolyColor.s.alpha = 0xff;
return PF_Masked; return PF_Masked;
} }
pSurf->PolyColor.s.alpha = HWR_GetTranstableAlpha(transtablenum); pSurf->PolyColor.s.alpha = alpha;
return HWR_GetBlendModeFlag(style); return HWR_GetBlendModeFlag(style);
} }
...@@ -745,7 +724,7 @@ FBITFIELD HWR_TranstableToAlpha(INT32 transtablenum, FSurfaceInfo *pSurf) ...@@ -745,7 +724,7 @@ FBITFIELD HWR_TranstableToAlpha(INT32 transtablenum, FSurfaceInfo *pSurf)
return PF_Masked; return PF_Masked;
} }
pSurf->PolyColor.s.alpha = HWR_GetTranstableAlpha(transtablenum); pSurf->PolyColor.s.alpha = R_TransnumToAlpha(transtablenum);
return PF_Translucent; return PF_Translucent;
} }
...@@ -3760,8 +3739,8 @@ static void HWR_SplitSprite(gl_vissprite_t *spr) ...@@ -3760,8 +3739,8 @@ static void HWR_SplitSprite(gl_vissprite_t *spr)
FBITFIELD blend = 0; FBITFIELD blend = 0;
FBITFIELD occlusion; FBITFIELD occlusion;
INT32 shader = SHADER_DEFAULT; INT32 shader = SHADER_DEFAULT;
INT32 alpha;
boolean use_linkdraw_hack = false; boolean use_linkdraw_hack = false;
UINT8 alpha;
INT32 i; INT32 i;
float realtop, realbot, top, bot; float realtop, realbot, top, bot;
...@@ -3853,37 +3832,18 @@ static void HWR_SplitSprite(gl_vissprite_t *spr) ...@@ -3853,37 +3832,18 @@ static void HWR_SplitSprite(gl_vissprite_t *spr)
else else
occlusion = PF_Occlude; occlusion = PF_Occlude;
INT32 blendmode; alpha = spr->alpha;
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(spr->blendmode, alpha, &Surf);
blend = HWR_SurfaceBlend(blendmode, trans, &Surf);
} }
else 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; Surf.PolyColor.s.alpha = 0xFF;
blend = HWR_GetBlendModeFlag(blendmode)|occlusion; blend = HWR_GetBlendModeFlag(spr->blendmode) | occlusion;
if (!occlusion) use_linkdraw_hack = true; if (!occlusion)
use_linkdraw_hack = true;
} }
if (HWR_UseShader()) if (HWR_UseShader())
...@@ -3892,8 +3852,6 @@ static void HWR_SplitSprite(gl_vissprite_t *spr) ...@@ -3892,8 +3852,6 @@ static void HWR_SplitSprite(gl_vissprite_t *spr)
blend |= PF_ColorMapped; blend |= PF_ColorMapped;
} }
alpha = Surf.PolyColor.s.alpha;
// Start with the lightlevel and colormap from the top of the sprite // Start with the lightlevel and colormap from the top of the sprite
lightlevel = *list[sector->numlights - 1].lightlevel; lightlevel = *list[sector->numlights - 1].lightlevel;
if (!(spr->mobj->renderflags & RF_NOCOLORMAPS)) if (!(spr->mobj->renderflags & RF_NOCOLORMAPS))
...@@ -4297,49 +4255,16 @@ static void HWR_DrawSprite(gl_vissprite_t *spr) ...@@ -4297,49 +4255,16 @@ static void HWR_DrawSprite(gl_vissprite_t *spr)
else else
occlusion = PF_Occlude; occlusion = PF_Occlude;
INT32 blendmode; if (spr->translucent)
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
{ {
Surf.PolyColor.s.alpha = 0xFF; blend = HWR_SurfaceBlend(spr->blendmode, spr->alpha, &Surf);
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);
} }
else 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; Surf.PolyColor.s.alpha = 0xFF;
blend = HWR_GetBlendModeFlag(blendmode)|occlusion; blend = HWR_GetBlendModeFlag(spr->blendmode) | occlusion;
if (!occlusion) use_linkdraw_hack = true; 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;
} }
if (HWR_UseShader()) if (HWR_UseShader())
...@@ -4433,19 +4358,14 @@ static inline void HWR_DrawPrecipitationSprite(gl_vissprite_t *spr) ...@@ -4433,19 +4358,14 @@ static inline void HWR_DrawPrecipitationSprite(gl_vissprite_t *spr)
HWR_Lighting(&Surf, lightlevel, colormap); 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(spr->blendmode, spr->alpha, &Surf);
blend = HWR_SurfaceBlend(AST_TRANSLUCENT, trans, &Surf);
} }
else 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; Surf.PolyColor.s.alpha = 0xFF;
blend = HWR_GetBlendModeFlag(spr->mobj->blendmode)|PF_Occlude; blend = HWR_GetBlendModeFlag(spr->blendmode);
} }
if (HWR_UseShader()) if (HWR_UseShader())
...@@ -4999,6 +4919,9 @@ static void HWR_ProjectSprite(mobj_t *thing) ...@@ -4999,6 +4919,9 @@ static void HWR_ProjectSprite(mobj_t *thing)
boolean vflip = (!(thing->eflags & MFE_VERTICALFLIP) != !R_ThingVerticallyFlipped(thing)); boolean vflip = (!(thing->eflags & MFE_VERTICALFLIP) != !R_ThingVerticallyFlipped(thing));
boolean mirrored = thing->mirrored; boolean mirrored = thing->mirrored;
boolean hflip = (!R_ThingHorizontallyFlipped(thing) != !mirrored); boolean hflip = (!R_ThingHorizontallyFlipped(thing) != !mirrored);
INT32 blendmode, alpha = 255;
boolean translucent = false;
UINT32 trans;
INT32 dispoffset; INT32 dispoffset;
angle_t ang; angle_t ang;
...@@ -5020,22 +4943,32 @@ static void HWR_ProjectSprite(mobj_t *thing) ...@@ -5020,22 +4943,32 @@ static void HWR_ProjectSprite(mobj_t *thing)
if (!thing) if (!thing)
return; return;
INT32 blendmode; // Get the blend mode
if (thing->frame & FF_BLENDMASK) if (thing->frame & FF_BLENDMASK)
blendmode = ((thing->frame & FF_BLENDMASK) >> FF_BLENDSHIFT) + 1; blendmode = ((thing->frame & FF_BLENDMASK) >> FF_BLENDSHIFT) + 1;
else else
blendmode = thing->blendmode; blendmode = min(max(AST_COPY, thing->blendmode), AST_OVERLAY);
// Visibility check by the blend mode. // Determine the translucency value.
if (thing->frame & FF_TRANSMASK) 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; return;
translucent = true;
} }
dispoffset = thing->dispoffset; dispoffset = thing->dispoffset;
if (R_UsingFrameInterpolation() && !paused) if (R_UsingFrameInterpolation() && !paused)
{ {
R_InterpolateMobjState(thing, rendertimefrac, &interp); R_InterpolateMobjState(thing, rendertimefrac, &interp);
...@@ -5261,12 +5194,22 @@ static void HWR_ProjectSprite(mobj_t *thing) ...@@ -5261,12 +5194,22 @@ static void HWR_ProjectSprite(mobj_t *thing)
shadowheight = FIXED_TO_FLOAT(floordiff); shadowheight = FIXED_TO_FLOAT(floordiff);
shadowscale = FIXED_TO_FLOAT(FixedMul(FRACUNIT - floordiff/640, casterinterp.scale)); 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) if (splat)
spritexscale *= shadowscale; spritexscale *= shadowscale;
spriteyscale *= shadowscale; spriteyscale *= shadowscale;
} }
} }
translucent = !(blendmode == AST_TRANSLUCENT && alpha >= 255);
this_xscale = spritexscale * this_scale; this_xscale = spritexscale * this_scale;
this_yscale = spriteyscale * this_scale; this_yscale = spriteyscale * this_scale;
...@@ -5289,18 +5232,6 @@ static void HWR_ProjectSprite(mobj_t *thing) ...@@ -5289,18 +5232,6 @@ static void HWR_ProjectSprite(mobj_t *thing)
x2 = (FIXED_TO_FLOAT(spr_width - spr_offset) * this_xscale); 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; z1 = tr_y + x1 * rightsin;
z2 = tr_y - x2 * rightsin; z2 = tr_y - x2 * rightsin;
x1 = tr_x + x1 * rightcos; x1 = tr_x + x1 * rightcos;
...@@ -5473,6 +5404,9 @@ static void HWR_ProjectSprite(mobj_t *thing) ...@@ -5473,6 +5404,9 @@ static void HWR_ProjectSprite(mobj_t *thing)
vis->precip = false; vis->precip = false;
vis->translucent = translucent;
vis->blendmode = blendmode;
vis->alpha = alpha;
vis->angle = interp.angle; vis->angle = interp.angle;
} }
...@@ -5491,15 +5425,33 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing) ...@@ -5491,15 +5425,33 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing)
size_t lumpoff; size_t lumpoff;
unsigned rot = 0; unsigned rot = 0;
UINT8 flip; UINT8 flip;
INT32 blendmode, alpha = 255;
boolean translucent = false;
UINT32 trans;
if (!thing) if (!thing)
return; 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) 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; return;
translucent = !(blendmode == AST_TRANSLUCENT && alpha >= 255);
} }
// uncapped/interpolation // uncapped/interpolation
...@@ -5595,6 +5547,10 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing) ...@@ -5595,6 +5547,10 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing)
vis->precip = true; 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 // okay... this is a hack, but weather isn't networked, so it should be ok
if (!(thing->precipflags & PCF_THUNK)) if (!(thing->precipflags & PCF_THUNK))
{ {
......
...@@ -42,7 +42,7 @@ void HWR_SetViewSize(void); ...@@ -42,7 +42,7 @@ void HWR_SetViewSize(void);
void HWR_DrawPatch(patch_t *gpatch, INT32 x, INT32 y, INT32 option); 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_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_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_CreatePlanePolygons(INT32 bspnum);
void HWR_CreateStaticLightmaps(INT32 bspnum); void HWR_CreateStaticLightmaps(INT32 bspnum);
void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color); void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color);
...@@ -70,9 +70,8 @@ void HWR_DrawScreenFinalTexture(int width, int height); ...@@ -70,9 +70,8 @@ void HWR_DrawScreenFinalTexture(int width, int height);
void HWR_Lighting(FSurfaceInfo *Surface, INT32 light_level, extracolormap_t *colormap); 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_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_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); FBITFIELD HWR_TranstableToAlpha(INT32 transtablenum, FSurfaceInfo *pSurf);
boolean HWR_CompileShaders(void); boolean HWR_CompileShaders(void);
......
...@@ -415,7 +415,7 @@ static void md2_loadTexture(md2_t *model) ...@@ -415,7 +415,7 @@ static void md2_loadTexture(md2_t *model)
size = w*h; size = w*h;
while (size--) 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++; image++;
} }
} }
......
...@@ -2095,7 +2095,7 @@ void HU_Erase(void) ...@@ -2095,7 +2095,7 @@ void HU_Erase(void)
return; return;
// software mode copies view border pattern & beveled edges from the backbuffer // software mode copies view border pattern & beveled edges from the backbuffer
if (rendermode == render_soft) if (VID_InSoftwareRenderer())
{ {
topline = 0; topline = 0;
for (y = topline, yoffset = y*vid.width; y < bottomline; y++, yoffset += vid.width) for (y = topline, yoffset = y*vid.width; y < bottomline; y++, yoffset += vid.width)
......
...@@ -22,14 +22,15 @@ ...@@ -22,14 +22,15 @@
typedef enum typedef enum
{ {
/// Software // Software renderers
render_soft = 1, render_software = 1,
render_software_truecolor,
/// OpenGL // OpenGL
render_opengl = 2, render_opengl,
/// Dedicated // Dedicated mode
render_none = 3 // for dedicated server render_none,
} rendermode_t; } rendermode_t;
/** \brief current render mode /** \brief current render mode
...@@ -44,6 +45,10 @@ extern rendermode_t chosenrendermode; ...@@ -44,6 +45,10 @@ extern rendermode_t chosenrendermode;
*/ */
extern boolean highcolor; extern boolean highcolor;
/** \brief use truecolor modes if true
*/
extern boolean truecolor;
/** \brief setup video mode /** \brief setup video mode
*/ */
void I_StartupGraphics(void); void I_StartupGraphics(void);
...@@ -101,6 +106,15 @@ void VID_StartupOpenGL(void); ...@@ -101,6 +106,15 @@ void VID_StartupOpenGL(void);
*/ */
void VID_CheckGLLoaded(rendermode_t oldrender); 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 /** \brief The VID_GetModeName function
\param modenum video mode number \param modenum video mode number
......
...@@ -452,7 +452,7 @@ static int lib_pAproxDistance(lua_State *L) ...@@ -452,7 +452,7 @@ static int lib_pAproxDistance(lua_State *L)
fixed_t dx = luaL_checkfixed(L, 1); fixed_t dx = luaL_checkfixed(L, 1);
fixed_t dy = luaL_checkfixed(L, 2); fixed_t dy = luaL_checkfixed(L, 2);
//HUDSAFE //HUDSAFE
lua_pushfixed(L, P_AproxDistance(dx, dy)); lua_pushfixed(L, R_PointToDist2(0, 0, dx, dy));
return 1; return 1;
} }
......
...@@ -1226,11 +1226,24 @@ static int libd_dupy(lua_State *L) ...@@ -1226,11 +1226,24 @@ static int libd_dupy(lua_State *L)
static int libd_renderer(lua_State *L) static int libd_renderer(lua_State *L)
{ {
HUDONLY HUDONLY
switch (rendermode) {
case render_opengl: lua_pushliteral(L, "opengl"); break; // OpenGL renderer switch (rendermode)
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 // 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; return 1;
} }
......
...@@ -63,6 +63,7 @@ enum mobj_e { ...@@ -63,6 +63,7 @@ enum mobj_e {
mobj_renderflags, mobj_renderflags,
mobj_skin, mobj_skin,
mobj_color, mobj_color,
mobj_alpha,
mobj_blendmode, mobj_blendmode,
mobj_bnext, mobj_bnext,
mobj_bprev, mobj_bprev,
...@@ -140,6 +141,7 @@ static const char *const mobj_opt[] = { ...@@ -140,6 +141,7 @@ static const char *const mobj_opt[] = {
"renderflags", "renderflags",
"skin", "skin",
"color", "color",
"alpha",
"blendmode", "blendmode",
"bnext", "bnext",
"bprev", "bprev",
...@@ -320,6 +322,9 @@ static int mobj_get(lua_State *L) ...@@ -320,6 +322,9 @@ static int mobj_get(lua_State *L)
case mobj_color: case mobj_color:
lua_pushinteger(L, mo->color); lua_pushinteger(L, mo->color);
break; break;
case mobj_alpha:
lua_pushinteger(L, mo->alpha);
break;
case mobj_blendmode: case mobj_blendmode:
lua_pushinteger(L, mo->blendmode); lua_pushinteger(L, mo->blendmode);
break; break;
...@@ -661,6 +666,14 @@ static int mobj_set(lua_State *L) ...@@ -661,6 +666,14 @@ static int mobj_set(lua_State *L)
mo->color = newcolor; mo->color = newcolor;
break; 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: case mobj_blendmode:
{ {
INT32 blendmode = (INT32)luaL_checkinteger(L, 3); INT32 blendmode = (INT32)luaL_checkinteger(L, 3);
......
...@@ -508,11 +508,11 @@ static size_t gifframe_size = 8192; ...@@ -508,11 +508,11 @@ static size_t gifframe_size = 8192;
#ifdef HWRENDER #ifdef HWRENDER
static colorlookup_t gif_colorlookup; 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; UINT8 r, g, b;
size_t src = 0, dest = 0; 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); InitColorLUT(&gif_colorlookup, (gif_localcolortable) ? gif_framepalette : gif_headerpalette, true);
...@@ -522,11 +522,10 @@ static void GIF_rgbconvert(UINT8 *linear, UINT8 *scr) ...@@ -522,11 +522,10 @@ static void GIF_rgbconvert(UINT8 *linear, UINT8 *scr)
g = (UINT8)linear[src + 1]; g = (UINT8)linear[src + 1];
b = (UINT8)linear[src + 2]; b = (UINT8)linear[src + 2];
scr[dest] = GetColorLUTDirect(&gif_colorlookup, r, g, b); scr[dest] = GetColorLUTDirect(&gif_colorlookup, r, g, b);
src += (3 * scrbuf_downscaleamt); src += (bpp * scrbuf_downscaleamt);
dest += scrbuf_downscaleamt; dest += scrbuf_downscaleamt;
} }
} }
#endif
// //
// GIF_framewrite // GIF_framewrite
...@@ -561,17 +560,31 @@ static void GIF_framewrite(void) ...@@ -561,17 +560,31 @@ static void GIF_framewrite(void)
{ {
// before blit movie_screen points to last frame, cur_screen points to this frame // before blit movie_screen points to last frame, cur_screen points to this frame
UINT8 *cur_screen = screens[0]; 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); GIF_optimizeregion(cur_screen, movie_screen, &blitx, &blity, &blitw, &blith);
// blit to temp screen // blit to temp screen
if (rendermode == render_soft) if (VID_InSoftwareRenderer())
I_ReadScreen(movie_screen); {
#ifdef TRUECOLOR
if (truecolor)
GIF_rgbconvert(screens[0], movie_screen, 4);
else
#endif
I_ReadScreen(movie_screen);
}
#ifdef HWRENDER #ifdef HWRENDER
else if (rendermode == render_opengl) else if (rendermode == render_opengl)
{ {
UINT8 *linear = HWR_GetScreenshot(); UINT8 *sshot = HWR_GetScreenshot();
GIF_rgbconvert(linear, movie_screen); GIF_rgbconvert(sshot, movie_screen, 3);
free(linear); free(sshot);
} }
#endif #endif
} }
...@@ -581,22 +594,43 @@ static void GIF_framewrite(void) ...@@ -581,22 +594,43 @@ static void GIF_framewrite(void)
blitw = vid.width; blitw = vid.width;
blith = vid.height; blith = vid.height;
#ifdef HWRENDER if (gif_frames == 0)
// Copy the current OpenGL frame into the base screen
if (rendermode == render_opengl)
{ {
UINT8 *linear = HWR_GetScreenshot(); #ifdef HWRENDER
GIF_rgbconvert(linear, screens[0]); if (rendermode == render_opengl)
free(linear); {
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 #endif
// Copy the first frame into the movie screen // Copy the first frame into the movie screen
// OpenGL already does the same above. // OpenGL already does the same above.
if (gif_frames == 0 && rendermode == render_soft) if (gif_frames == 0 && VID_InSoftwareRenderer())
I_ReadScreen(movie_screen); I_ReadScreen(movie_screen);
movie_screen = screens[0]; 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 // screen regions are handled in GIF_lzw
......