Merge branch 'master' of https://git.magicalgirl.moe/STJr/SRB2Internal.git into pretty_stuff

# Conflicts:
#	src/hardware/hw_draw.c
This commit is contained in:
toasterbabe 2018-04-06 19:38:19 +01:00
commit 4f3c9b5fad
12 changed files with 1085 additions and 618 deletions

View file

@ -242,11 +242,19 @@ static void F_SkyScroll(INT32 scrollspeed)
#ifdef HWRENDER #ifdef HWRENDER
else if (rendermode != render_none) else if (rendermode != render_none)
{ // if only software rendering could be this simple and retarded { // if only software rendering could be this simple and retarded
scrolled = animtimer; INT32 dupz = (vid.dupx < vid.dupy ? vid.dupx : vid.dupy);
if (scrolled > 0) INT32 y, pw = patwidth * dupz, ph = SHORT(pat->height) * dupz;
V_DrawScaledPatch(scrolled - patwidth, 0, 0, pat); scrolled = animtimer * dupz;
for (x = 0; x < fakedwidth; x += patwidth) for (x = 0; x < vid.width; x += pw)
V_DrawScaledPatch(x + scrolled, 0, 0, pat); {
for (y = 0; y < vid.height; y += ph)
{
if (scrolled > 0)
V_DrawScaledPatch(scrolled - pw, y, V_NOSCALESTART, pat);
V_DrawScaledPatch(x + scrolled, y, V_NOSCALESTART, pat);
}
}
} }
#endif #endif

View file

@ -20,8 +20,8 @@
#define _HWR_DEFS_ #define _HWR_DEFS_
#include "../doomtype.h" #include "../doomtype.h"
#define ZCLIP_PLANE 4.0f #define ZCLIP_PLANE 4.0f // Used for the actual game drawing
#define NZCLIP_PLANE 0.9f #define NZCLIP_PLANE 0.9f // Seems to be only used for the HUD and screen textures
// ========================================================================== // ==========================================================================
// SIMPLE TYPES // SIMPLE TYPES
@ -127,12 +127,13 @@ enum EPolyFlags
PF_Masked = 0x00000001, // Poly is alpha scaled and 0 alpha pels are discarded (holes in texture) PF_Masked = 0x00000001, // Poly is alpha scaled and 0 alpha pels are discarded (holes in texture)
PF_Translucent = 0x00000002, // Poly is transparent, alpha = level of transparency PF_Translucent = 0x00000002, // Poly is transparent, alpha = level of transparency
PF_Additive = 0x00000024, // Poly is added to the frame buffer PF_Additive = 0x00000004, // Poly is added to the frame buffer
PF_Environment = 0x00000008, // Poly should be drawn environment mapped. PF_Environment = 0x00000008, // Poly should be drawn environment mapped.
// Hurdler: used for text drawing // Hurdler: used for text drawing
PF_Substractive = 0x00000010, // for splat PF_Substractive = 0x00000010, // for splat
PF_NoAlphaTest = 0x00000020, // hiden param PF_NoAlphaTest = 0x00000020, // hiden param
PF_Blending = (PF_Environment|PF_Additive|PF_Translucent|PF_Masked|PF_Substractive)&~PF_NoAlphaTest, PF_Fog = 0x00000040, // Fog blocks
PF_Blending = (PF_Environment|PF_Additive|PF_Translucent|PF_Masked|PF_Substractive|PF_Fog)&~PF_NoAlphaTest,
// other flag bits // other flag bits

View file

@ -149,10 +149,9 @@ void HWR_DrawFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale,
// | /| // | /|
// |/ | // |/ |
// 0--1 // 0--1
float sdupx = FIXED_TO_FLOAT(vid.fdupx)*2.0f; float dupx, dupy, fscalew, fscaleh, fwidth, fheight;
float sdupy = FIXED_TO_FLOAT(vid.fdupy)*2.0f;
float pdupx = FIXED_TO_FLOAT(vid.fdupx)*2.0f*FIXED_TO_FLOAT(pscale); UINT8 perplayershuffle = 0;
float pdupy = FIXED_TO_FLOAT(vid.fdupy)*2.0f*FIXED_TO_FLOAT(pscale);
if (alphalevel >= 10 && alphalevel < 13) if (alphalevel >= 10 && alphalevel < 13)
return; return;
@ -163,67 +162,179 @@ void HWR_DrawFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale,
else else
HWR_GetMappedPatch(gpatch, colormap); HWR_GetMappedPatch(gpatch, colormap);
dupx = (float)vid.dupx;
dupy = (float)vid.dupy;
switch (option & V_SCALEPATCHMASK) switch (option & V_SCALEPATCHMASK)
{ {
case V_NOSCALEPATCH: case V_NOSCALEPATCH:
pdupx = pdupy = 2.0f; dupx = dupy = 1.0f;
break; break;
case V_SMALLSCALEPATCH: case V_SMALLSCALEPATCH:
pdupx = 2.0f * FIXED_TO_FLOAT(vid.fsmalldupx); dupx = (float)vid.smalldupx;
pdupy = 2.0f * FIXED_TO_FLOAT(vid.fsmalldupy); dupy = (float)vid.smalldupy;
break; break;
case V_MEDSCALEPATCH: case V_MEDSCALEPATCH:
pdupx = 2.0f * FIXED_TO_FLOAT(vid.fmeddupx); dupx = (float)vid.meddupx;
pdupy = 2.0f * FIXED_TO_FLOAT(vid.fmeddupy); dupy = (float)vid.meddupy;
break; break;
} }
if (option & V_NOSCALESTART) dupx = dupy = (dupx < dupy ? dupx : dupy);
sdupx = sdupy = 2.0f; fscalew = fscaleh = FIXED_TO_FLOAT(pscale);
if (option & V_OFFSET)
{
cx -= (float)gpatch->leftoffset * dupx * fscalew;
cy -= (float)gpatch->topoffset * dupy * fscaleh;
}
else
{
cy -= (float)gpatch->topoffset * fscaleh;
if (option & V_FLIP)
cx -= ((float)gpatch->width - (float)gpatch->leftoffset) * fscalew;
else
cx -= (float)gpatch->leftoffset * fscalew;
}
if (splitscreen && (option & V_PERPLAYER)) if (splitscreen && (option & V_PERPLAYER))
{ {
float adjusty = ((option & V_NOSCALESTART) ? vid.height : BASEVIDHEIGHT)/2.0f; float adjusty = ((option & V_NOSCALESTART) ? vid.height : BASEVIDHEIGHT)/2.0f;
pdupy /= 2; fscaleh /= 2;
cy /= 2; cy /= 2;
#ifdef QUADS #ifdef QUADS
if (splitscreen > 1) // 3 or 4 players if (splitscreen > 1) // 3 or 4 players
{ {
float adjustx = ((option & V_NOSCALESTART) ? vid.width : BASEVIDWIDTH)/2.0f; float adjustx = ((option & V_NOSCALESTART) ? vid.width : BASEVIDWIDTH)/2.0f;
pdupx /= 2; fscalew /= 2;
cx /= 2; cx /= 2;
if (stplyr == &players[secondarydisplayplayer]) if (stplyr == &players[displayplayer])
{
if (!(option & (V_SNAPTOTOP|V_SNAPTOBOTTOM)))
perplayershuffle |= 1;
if (!(option & (V_SNAPTOLEFT|V_SNAPTORIGHT)))
perplayershuffle |= 4;
option &= ~V_SNAPTOBOTTOM|V_SNAPTORIGHT;
}
else if (stplyr == &players[secondarydisplayplayer])
{
if (!(option & (V_SNAPTOTOP|V_SNAPTOBOTTOM)))
perplayershuffle |= 1;
if (!(option & (V_SNAPTOLEFT|V_SNAPTORIGHT)))
perplayershuffle |= 8;
cx += adjustx; cx += adjustx;
option &= ~V_SNAPTOBOTTOM|V_SNAPTOLEFT;
}
else if (stplyr == &players[thirddisplayplayer]) else if (stplyr == &players[thirddisplayplayer])
{
if (!(option & (V_SNAPTOTOP|V_SNAPTOBOTTOM)))
perplayershuffle |= 2;
if (!(option & (V_SNAPTOLEFT|V_SNAPTORIGHT)))
perplayershuffle |= 4;
cy += adjusty; cy += adjusty;
option &= ~V_SNAPTOTOP|V_SNAPTORIGHT;
}
else if (stplyr == &players[fourthdisplayplayer]) else if (stplyr == &players[fourthdisplayplayer])
{ {
if (!(option & (V_SNAPTOTOP|V_SNAPTOBOTTOM)))
perplayershuffle |= 2;
if (!(option & (V_SNAPTOLEFT|V_SNAPTORIGHT)))
perplayershuffle |= 8;
cx += adjustx; cx += adjustx;
cy += adjusty; cy += adjusty;
option &= ~V_SNAPTOTOP|V_SNAPTOLEFT;
} }
} }
else else
#endif #endif
// 2 players // 2 players
{ {
if (stplyr == &players[secondarydisplayplayer]) if (stplyr == &players[displayplayer])
{
if (!(option & (V_SNAPTOTOP|V_SNAPTOBOTTOM)))
perplayershuffle = 1;
option &= ~V_SNAPTOBOTTOM;
}
else //if (stplyr == &players[secondarydisplayplayer])
{
if (!(option & (V_SNAPTOTOP|V_SNAPTOBOTTOM)))
perplayershuffle = 2;
cy += adjusty; cy += adjusty;
option &= ~V_SNAPTOTOP;
}
} }
} }
if (option & V_FLIP) // Need to flip both this and sow if (!(option & V_NOSCALESTART))
{ {
v[0].x = v[3].x = (cx*sdupx-(gpatch->width-gpatch->leftoffset)*pdupx)/vid.width - 1; cx = cx * dupx;
v[2].x = v[1].x = (cx*sdupx+gpatch->leftoffset*pdupx)/vid.width - 1; cy = cy * dupy;
if (!(option & V_SCALEPATCHMASK))
{
// if it's meant to cover the whole screen, black out the rest
// cx and cy are possibly *slightly* off from float maths
// This is done before here compared to software because we directly alter cx and cy to centre
if (cx >= -0.1f && cx <= 0.1f && SHORT(gpatch->width) == BASEVIDWIDTH && cy >= -0.1f && cy <= 0.1f && SHORT(gpatch->height) == BASEVIDHEIGHT)
{
// Need to temporarily cache the real patch to get the colour of the top left pixel
patch_t *realpatch = W_CacheLumpNumPwad(gpatch->wadnum, gpatch->lumpnum, PU_STATIC);
const column_t *column = (const column_t *)((const UINT8 *)(realpatch) + LONG((realpatch)->columnofs[0]));
const UINT8 *source = (const UINT8 *)(column) + 3;
HWR_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, (column->topdelta == 0xff ? 31 : source[0]));
Z_Free(realpatch);
}
// centre screen
if (vid.width != BASEVIDWIDTH * vid.dupx)
{
if (option & V_SNAPTORIGHT)
cx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx));
else if (!(option & V_SNAPTOLEFT))
cx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx))/2;
if (perplayershuffle & 4)
cx -= ((float)vid.width - ((float)BASEVIDWIDTH * dupx))/4;
else if (perplayershuffle & 8)
cx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx))/4;
}
if (vid.height != BASEVIDHEIGHT * vid.dupy)
{
if (option & V_SNAPTOBOTTOM)
cy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy));
else if (!(option & V_SNAPTOTOP))
cy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy))/2;
if (perplayershuffle & 1)
cy -= ((float)vid.height - ((float)BASEVIDHEIGHT * dupy))/4;
else if (perplayershuffle & 2)
cy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy))/4;
}
}
}
if (pscale != FRACUNIT || (splitscreen && option & V_PERPLAYER))
{
fwidth = (float)gpatch->width * fscalew * dupx;
fheight = (float)gpatch->height * fscaleh * dupy;
} }
else else
{ {
v[0].x = v[3].x = (cx*sdupx-gpatch->leftoffset*pdupx)/vid.width - 1; fwidth = (float)gpatch->width * dupx;
v[2].x = v[1].x = (cx*sdupx+(gpatch->width-gpatch->leftoffset)*pdupx)/vid.width - 1; fheight = (float)gpatch->height * dupy;
} }
v[0].y = v[1].y = 1-(cy*sdupy-gpatch->topoffset*pdupy)/vid.height; // positions of the cx, cy, are between 0 and vid.width/vid.height now, we need them to be between -1 and 1
v[2].y = v[3].y = 1-(cy*sdupy+(gpatch->height-gpatch->topoffset)*pdupy)/vid.height; cx = -1 + (cx / (vid.width/2));
cy = 1 - (cy / (vid.height/2));
// fwidth and fheight are similar
fwidth /= vid.width / 2;
fheight /= vid.height / 2;
// set the polygon vertices to the right positions
v[0].x = v[3].x = cx;
v[2].x = v[1].x = cx + fwidth;
v[0].y = v[1].y = cy;
v[2].y = v[3].y = cy - fheight;
v[0].z = v[1].z = v[2].z = v[3].z = 1.0f; v[0].z = v[1].z = v[2].z = v[3].z = 1.0f;
@ -276,10 +387,7 @@ void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscal
// | /| // | /|
// |/ | // |/ |
// 0--1 // 0--1
float sdupx = FIXED_TO_FLOAT(vid.fdupx)*2.0f; float dupx, dupy, fscale, fwidth, fheight;
float sdupy = FIXED_TO_FLOAT(vid.fdupy)*2.0f;
float pdupx = FIXED_TO_FLOAT(vid.fdupx)*2.0f*FIXED_TO_FLOAT(pscale);
float pdupy = FIXED_TO_FLOAT(vid.fdupy)*2.0f*FIXED_TO_FLOAT(pscale);
if (alphalevel >= 10 && alphalevel < 13) if (alphalevel >= 10 && alphalevel < 13)
return; return;
@ -287,66 +395,117 @@ void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscal
// make patch ready in hardware cache // make patch ready in hardware cache
HWR_GetPatch(gpatch); HWR_GetPatch(gpatch);
dupx = (float)vid.dupx;
dupy = (float)vid.dupy;
switch (option & V_SCALEPATCHMASK) switch (option & V_SCALEPATCHMASK)
{ {
case V_NOSCALEPATCH: case V_NOSCALEPATCH:
pdupx = pdupy = 2.0f; dupx = dupy = 1.0f;
break; break;
case V_SMALLSCALEPATCH: case V_SMALLSCALEPATCH:
pdupx = 2.0f * FIXED_TO_FLOAT(vid.fsmalldupx); dupx = (float)vid.smalldupx;
pdupy = 2.0f * FIXED_TO_FLOAT(vid.fsmalldupy); dupy = (float)vid.smalldupy;
break; break;
case V_MEDSCALEPATCH: case V_MEDSCALEPATCH:
pdupx = 2.0f * FIXED_TO_FLOAT(vid.fmeddupx); dupx = (float)vid.meddupx;
pdupy = 2.0f * FIXED_TO_FLOAT(vid.fmeddupy); dupy = (float)vid.meddupy;
break; break;
} }
if (option & V_NOSCALESTART) dupx = dupy = (dupx < dupy ? dupx : dupy);
sdupx = sdupy = 2.0f; fscale = FIXED_TO_FLOAT(pscale);
if (splitscreen && (option & V_PERPLAYER)) // fuck it, no GL support for croppedpatch v_perplayer right now. it's not like it's accessible to Lua or anything, and we only use it for menus...
cy -= (float)gpatch->topoffset * fscale;
cx -= (float)gpatch->leftoffset * fscale;
if (!(option & V_NOSCALESTART))
{ {
float adjusty = ((option & V_NOSCALESTART) ? vid.height : BASEVIDHEIGHT)/2.0f; cx = cx * dupx;
pdupy /= 2; cy = cy * dupy;
cy /= 2;
// unlike software no need to adjust texture sourcing if (!(option & V_SCALEPATCHMASK))
#ifdef QUADS
if (splitscreen > 1) // 3 or 4 players
{ {
float adjustx = ((option & V_NOSCALESTART) ? vid.width : BASEVIDWIDTH)/2.0f; // if it's meant to cover the whole screen, black out the rest
pdupx /= 2; // cx and cy are possibly *slightly* off from float maths
cx /= 2; // This is done before here compared to software because we directly alter cx and cy to centre
if (stplyr == &players[secondarydisplayplayer]) if (cx >= -0.1f && cx <= 0.1f && SHORT(gpatch->width) == BASEVIDWIDTH && cy >= -0.1f && cy <= 0.1f && SHORT(gpatch->height) == BASEVIDHEIGHT)
cx += adjustx;
else if (stplyr == &players[thirddisplayplayer])
cy += adjusty;
if (stplyr == &players[fourthdisplayplayer])
{ {
cx += adjustx; // Need to temporarily cache the real patch to get the colour of the top left pixel
cy += adjusty; patch_t *realpatch = W_CacheLumpNumPwad(gpatch->wadnum, gpatch->lumpnum, PU_STATIC);
const column_t *column = (const column_t *)((const UINT8 *)(realpatch) + LONG((realpatch)->columnofs[0]));
const UINT8 *source = (const UINT8 *)(column) + 3;
HWR_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, (column->topdelta == 0xff ? 31 : source[0]));
Z_Free(realpatch);
}
// centre screen
if (vid.width != BASEVIDWIDTH * vid.dupx)
{
if (option & V_SNAPTORIGHT)
cx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx));
else if (!(option & V_SNAPTOLEFT))
cx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx))/2;
}
if (vid.height != BASEVIDHEIGHT * vid.dupy)
{
if (option & V_SNAPTOBOTTOM)
cy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy));
else if (!(option & V_SNAPTOTOP))
cy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy))/2;
} }
}
else
#endif
// 2 players
{
if (stplyr == &players[secondarydisplayplayer])
cy += adjusty;
} }
} }
v[0].x = v[3].x = (cx*sdupx - gpatch->leftoffset * pdupx) / vid.width - 1; fwidth = w;
v[2].x = v[1].x = (cx*sdupx + ((w) - gpatch->leftoffset) * pdupx) / vid.width - 1; fheight = h;
v[0].y = v[1].y = 1 - (cy*sdupy - gpatch->topoffset * pdupy) / vid.height;
v[2].y = v[3].y = 1 - (cy*sdupy + ((h) - gpatch->topoffset) * pdupy) / vid.height; if (fwidth > gpatch->width)
fwidth = gpatch->width;
if (fheight > gpatch->height)
fheight = gpatch->height;
if (pscale != FRACUNIT)
{
fwidth *= fscale * dupx;
fheight *= fscale * dupy;
}
else
{
fwidth *= dupx;
fheight *= dupy;
}
// positions of the cx, cy, are between 0 and vid.width/vid.height now, we need them to be between -1 and 1
cx = -1 + (cx / (vid.width/2));
cy = 1 - (cy / (vid.height/2));
// fwidth and fheight are similar
fwidth /= vid.width / 2;
fheight /= vid.height / 2;
// set the polygon vertices to the right positions
v[0].x = v[3].x = cx;
v[2].x = v[1].x = cx + fwidth;
v[0].y = v[1].y = cy;
v[2].y = v[3].y = cy - fheight;
v[0].z = v[1].z = v[2].z = v[3].z = 1.0f; v[0].z = v[1].z = v[2].z = v[3].z = 1.0f;
v[0].sow = v[3].sow = ((sx )/(float)gpatch->width )*gpatch->max_s; v[0].sow = v[3].sow = ((sx )/(float)gpatch->width )*gpatch->max_s;
v[2].sow = v[1].sow = ((sx+w)/(float)gpatch->width )*gpatch->max_s; if (sx + w > gpatch->width)
v[0].tow = v[1].tow = ((sy )/(float)gpatch->height)*gpatch->max_t; v[2].sow = v[1].sow = gpatch->max_s;
v[2].tow = v[3].tow = ((sy+h)/(float)gpatch->height)*gpatch->max_t; else
v[2].sow = v[1].sow = ((sx+w)/(float)gpatch->width )*gpatch->max_s;
v[0].tow = v[1].tow = ((sy )/(float)gpatch->height)*gpatch->max_t;
if (sy + h > gpatch->height)
v[2].tow = v[3].tow = gpatch->max_t;
else
v[2].tow = v[3].tow = ((sy+h)/(float)gpatch->height)*gpatch->max_t;
flags = BLENDMODE|PF_Clip|PF_NoZClip|PF_NoDepthTest; flags = BLENDMODE|PF_Clip|PF_NoZClip|PF_NoDepthTest;
@ -720,7 +879,9 @@ void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color)
{ {
FOutVector v[4]; FOutVector v[4];
FSurfaceInfo Surf; FSurfaceInfo Surf;
float sdupx, sdupy; float fx, fy, fw, fh;
UINT8 perplayershuffle = 0;
if (w < 0 || h < 0) if (w < 0 || h < 0)
return; // consistency w/ software return; // consistency w/ software
@ -729,46 +890,155 @@ void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color)
// | /| // | /|
// |/ | // |/ |
// 0--1 // 0--1
sdupx = FIXED_TO_FLOAT(vid.fdupx)*2.0f;
sdupy = FIXED_TO_FLOAT(vid.fdupy)*2.0f;
if (color & V_NOSCALESTART)
sdupx = sdupy = 2.0f;
if (splitscreen && (color & V_PERPLAYER)) if (splitscreen && (color & V_PERPLAYER))
{ {
float adjusty = ((color & V_NOSCALESTART) ? vid.height : BASEVIDHEIGHT)/2.0f; fixed_t adjusty = ((color & V_NOSCALESTART) ? vid.height : BASEVIDHEIGHT)/2.0f;
w >>= 1; h >>= 1;
y >>= 1; y >>= 1;
#ifdef QUADS #ifdef QUADS
if (splitscreen > 1) // 3 or 4 players if (splitscreen > 1) // 3 or 4 players
{ {
float adjustx = ((color & V_NOSCALESTART) ? vid.width : BASEVIDWIDTH)/2.0f; fixed_t adjustx = ((color & V_NOSCALESTART) ? vid.height : BASEVIDHEIGHT)/2.0f;
w >>= 1; w >>= 1;
x >>= 1; x >>= 1;
if (stplyr == &players[secondarydisplayplayer]) if (stplyr == &players[displayplayer])
x += adjustx;
else if (stplyr == &players[thirddisplayplayer])
y += adjusty;
else if (stplyr == &players[fourthdisplayplayer])
{ {
if (!(color & (V_SNAPTOTOP|V_SNAPTOBOTTOM)))
perplayershuffle |= 1;
if (!(color & (V_SNAPTOLEFT|V_SNAPTORIGHT)))
perplayershuffle |= 4;
color &= ~V_SNAPTOBOTTOM|V_SNAPTORIGHT;
}
else if (stplyr == &players[secondarydisplayplayer])
{
if (!(color & (V_SNAPTOTOP|V_SNAPTOBOTTOM)))
perplayershuffle |= 1;
if (!(color & (V_SNAPTOLEFT|V_SNAPTORIGHT)))
perplayershuffle |= 8;
x += adjustx;
color &= ~V_SNAPTOBOTTOM|V_SNAPTOLEFT;
}
else if (stplyr == &players[thirddisplayplayer])
{
if (!(color & (V_SNAPTOTOP|V_SNAPTOBOTTOM)))
perplayershuffle |= 2;
if (!(color & (V_SNAPTOLEFT|V_SNAPTORIGHT)))
perplayershuffle |= 4;
y += adjusty;
color &= ~V_SNAPTOTOP|V_SNAPTORIGHT;
}
else //if (stplyr == &players[fourthdisplayplayer])
{
if (!(color & (V_SNAPTOTOP|V_SNAPTOBOTTOM)))
perplayershuffle |= 2;
if (!(color & (V_SNAPTOLEFT|V_SNAPTORIGHT)))
perplayershuffle |= 8;
x += adjustx; x += adjustx;
y += adjusty; y += adjusty;
color &= ~V_SNAPTOTOP|V_SNAPTOLEFT;
} }
} }
else else
#endif #endif
// 2 players // 2 players
{ {
if (stplyr == &players[secondarydisplayplayer]) if (stplyr == &players[displayplayer])
{
if (!(color & (V_SNAPTOTOP|V_SNAPTOBOTTOM)))
perplayershuffle |= 1;
color &= ~V_SNAPTOBOTTOM;
}
else //if (stplyr == &players[secondarydisplayplayer])
{
if (!(color & (V_SNAPTOTOP|V_SNAPTOBOTTOM)))
perplayershuffle |= 2;
y += adjusty; y += adjusty;
color &= ~V_SNAPTOTOP;
}
} }
} }
v[0].x = v[3].x = (x*sdupx)/vid.width - 1; fx = (float)x;
v[2].x = v[1].x = (x*sdupx + w*sdupx)/vid.width - 1; fy = (float)y;
v[0].y = v[1].y = 1-(y*sdupy)/vid.height; fw = (float)w;
v[2].y = v[3].y = 1-(y*sdupy + h*sdupy)/vid.height; fh = (float)h;
if (!(color & V_NOSCALESTART))
{
float dupx = (float)vid.dupx, dupy = (float)vid.dupy;
if (x == 0 && y == 0 && w == BASEVIDWIDTH && h == BASEVIDHEIGHT)
{
RGBA_t rgbaColour = V_GetColor(color);
FRGBAFloat clearColour;
clearColour.red = (float)rgbaColour.s.red / 255;
clearColour.green = (float)rgbaColour.s.green / 255;
clearColour.blue = (float)rgbaColour.s.blue / 255;
clearColour.alpha = 1;
HWD.pfnClearBuffer(true, false, &clearColour);
return;
}
fx *= dupx;
fy *= dupy;
fw *= dupx;
fh *= dupy;
if (vid.width != BASEVIDWIDTH * vid.dupx)
{
if (color & V_SNAPTORIGHT)
fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx));
else if (!(color & V_SNAPTOLEFT))
fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx)) / 2;
if (perplayershuffle & 4)
fx -= ((float)vid.width - ((float)BASEVIDWIDTH * dupx)) / 4;
else if (perplayershuffle & 8)
fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx)) / 4;
}
if (vid.height != BASEVIDHEIGHT * dupy)
{
// same thing here
if (color & V_SNAPTOBOTTOM)
fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy));
else if (!(color & V_SNAPTOTOP))
fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy)) / 2;
if (perplayershuffle & 1)
fy -= ((float)vid.height - ((float)BASEVIDHEIGHT * dupy)) / 4;
else if (perplayershuffle & 2)
fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy)) / 4;
}
}
if (fx >= vid.width || fy >= vid.height)
return;
if (fx < 0)
{
fw += fx;
fx = 0;
}
if (fy < 0)
{
fh += fy;
fy = 0;
}
if (fw <= 0 || fh <= 0)
return;
if (fx + fw > vid.width)
fw = (float)vid.width - fx;
if (fy + fh > vid.height)
fh = (float)vid.height - fy;
fx = -1 + fx / (vid.width / 2);
fy = 1 - fy / (vid.height / 2);
fw = fw / (vid.width / 2);
fh = fh / (vid.height / 2);
v[0].x = v[3].x = fx;
v[2].x = v[1].x = fx + fw;
v[0].y = v[1].y = fy;
v[2].y = v[3].y = fy - fh;
//Hurdler: do we still use this argb color? if not, we should remove it //Hurdler: do we still use this argb color? if not, we should remove it
v[0].argb = v[1].argb = v[2].argb = v[3].argb = 0xff00ff00; //; v[0].argb = v[1].argb = v[2].argb = v[3].argb = 0xff00ff00; //;

View file

@ -79,6 +79,7 @@ EXPORT char *HWRAPI(GetRenderer) (void);
#define SCREENVERTS 10 #define SCREENVERTS 10
EXPORT void HWRAPI(PostImgRedraw) (float points[SCREENVERTS][SCREENVERTS][2]); EXPORT void HWRAPI(PostImgRedraw) (float points[SCREENVERTS][SCREENVERTS][2]);
#endif #endif
EXPORT void HWRAPI(FlushScreenTextures) (void);
EXPORT void HWRAPI(StartScreenWipe) (void); EXPORT void HWRAPI(StartScreenWipe) (void);
EXPORT void HWRAPI(EndScreenWipe) (void); EXPORT void HWRAPI(EndScreenWipe) (void);
EXPORT void HWRAPI(DoScreenWipe) (float alpha); EXPORT void HWRAPI(DoScreenWipe) (float alpha);
@ -124,6 +125,7 @@ struct hwdriver_s
#ifdef SHUFFLE #ifdef SHUFFLE
PostImgRedraw pfnPostImgRedraw; PostImgRedraw pfnPostImgRedraw;
#endif #endif
FlushScreenTextures pfnFlushScreenTextures;
StartScreenWipe pfnStartScreenWipe; StartScreenWipe pfnStartScreenWipe;
EndScreenWipe pfnEndScreenWipe; EndScreenWipe pfnEndScreenWipe;
DoScreenWipe pfnDoScreenWipe; DoScreenWipe pfnDoScreenWipe;

View file

@ -68,6 +68,7 @@ typedef struct gr_vissprite_s
struct gr_vissprite_s *prev; struct gr_vissprite_s *prev;
struct gr_vissprite_s *next; struct gr_vissprite_s *next;
float x1, x2; float x1, x2;
float z1, z2;
float tz, ty; float tz, ty;
lumpnum_t patchlumpnum; lumpnum_t patchlumpnum;
boolean flip; boolean flip;
@ -78,7 +79,6 @@ typedef struct gr_vissprite_s
//Hurdler: 25/04/2000: now support colormap in hardware mode //Hurdler: 25/04/2000: now support colormap in hardware mode
UINT8 *colormap; UINT8 *colormap;
INT32 dispoffset; // copy of info->dispoffset, affects ordering but not drawing INT32 dispoffset; // copy of info->dispoffset, affects ordering but not drawing
float z1, z2;
} gr_vissprite_t; } gr_vissprite_t;
// -------- // --------

File diff suppressed because it is too large Load diff

View file

@ -57,7 +57,7 @@ typedef struct GLRGBAFloat GLRGBAFloat;
#define N_PI_DEMI (M_PIl/2.0f) //(1.5707963268f) #define N_PI_DEMI (M_PIl/2.0f) //(1.5707963268f)
#define ASPECT_RATIO (1.0f) //(320.0f/200.0f) #define ASPECT_RATIO (1.0f) //(320.0f/200.0f)
#define FAR_CLIPPING_PLANE 150000.0f // Draw further! Tails 01-21-2001 #define FAR_CLIPPING_PLANE 32768.0f // Draw further! Tails 01-21-2001
static float NEAR_CLIPPING_PLANE = NZCLIP_PLANE; static float NEAR_CLIPPING_PLANE = NZCLIP_PLANE;
// ************************************************************************** // **************************************************************************
@ -101,10 +101,19 @@ static GLint viewport[4];
#endif #endif
// Yay for arbitrary numbers! NextTexAvail is buggy for some reason. // Yay for arbitrary numbers! NextTexAvail is buggy for some reason.
static GLuint screentexture = 60000; // Sryder: NextTexAvail is broken for these because palette changes or changes to the texture filter or antialiasing
static GLuint startScreenWipe = 60001; // flush all of the stored textures, leaving them unavailable at times such as between levels
static GLuint endScreenWipe = 60002; // These need to start at 0 and be set to their number, and be reset to 0 when deleted so that intel GPUs
static GLuint finalScreenTexture = 60003; // can know when the textures aren't there, as textures are always considered resident in their virtual memory
// TODO: Store them in a more normal way
#define SCRTEX_SCREENTEXTURE 65535
#define SCRTEX_STARTSCREENWIPE 65534
#define SCRTEX_ENDSCREENWIPE 65533
#define SCRTEX_FINALSCREENTEXTURE 65532
static GLuint screentexture = 0;
static GLuint startScreenWipe = 0;
static GLuint endScreenWipe = 0;
static GLuint finalScreenTexture = 0;
#if 0 #if 0
GLuint screentexture = FIRST_TEX_AVAIL; GLuint screentexture = FIRST_TEX_AVAIL;
#endif #endif
@ -245,6 +254,7 @@ FUNCPRINTF void DBG_Printf(const char *lpFmt, ...)
#define pglBindTexture glBindTexture #define pglBindTexture glBindTexture
/* texture mapping */ //GL_EXT_copy_texture /* texture mapping */ //GL_EXT_copy_texture
#define pglCopyTexImage2D glCopyTexImage2D #define pglCopyTexImage2D glCopyTexImage2D
#define pglCopyTexSubImage2D glCopyTexSubImage2D
#else //!STATIC_OPENGL #else //!STATIC_OPENGL
@ -361,6 +371,8 @@ static PFNglBindTexture pglBindTexture;
/* texture mapping */ //GL_EXT_copy_texture /* texture mapping */ //GL_EXT_copy_texture
typedef void (APIENTRY * PFNglCopyTexImage2D) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); typedef void (APIENTRY * PFNglCopyTexImage2D) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
static PFNglCopyTexImage2D pglCopyTexImage2D; static PFNglCopyTexImage2D pglCopyTexImage2D;
typedef void (APIENTRY * PFNglCopyTexSubImage2D) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
static PFNglCopyTexSubImage2D pglCopyTexSubImage2D;
#endif #endif
/* GLU functions */ /* GLU functions */
typedef GLint (APIENTRY * PFNgluBuild2DMipmaps) (GLenum target, GLint internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *data); typedef GLint (APIENTRY * PFNgluBuild2DMipmaps) (GLenum target, GLint internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *data);
@ -460,6 +472,7 @@ boolean SetupGLfunc(void)
GETOPENGLFUNC(pglBindTexture , glBindTexture) GETOPENGLFUNC(pglBindTexture , glBindTexture)
GETOPENGLFUNC(pglCopyTexImage2D , glCopyTexImage2D) GETOPENGLFUNC(pglCopyTexImage2D , glCopyTexImage2D)
GETOPENGLFUNC(pglCopyTexSubImage2D , glCopyTexSubImage2D)
#undef GETOPENGLFUNC #undef GETOPENGLFUNC
@ -597,6 +610,10 @@ void SetModelView(GLint w, GLint h)
{ {
// DBG_Printf("SetModelView(): %dx%d\n", (int)w, (int)h); // DBG_Printf("SetModelView(): %dx%d\n", (int)w, (int)h);
// The screen textures need to be flushed if the width or height change so that they be remade for the correct size
if (screen_width != w || screen_height != h)
FlushScreenTextures();
screen_width = w; screen_width = w;
screen_height = h; screen_height = h;
@ -734,6 +751,7 @@ void Flush(void)
screentexture = FIRST_TEX_AVAIL; screentexture = FIRST_TEX_AVAIL;
} }
#endif #endif
tex_downloaded = 0; tex_downloaded = 0;
} }
@ -948,26 +966,38 @@ EXPORT void HWRAPI(SetBlend) (FBITFIELD PolyFlags)
switch (PolyFlags & PF_Blending) { switch (PolyFlags & PF_Blending) {
case PF_Translucent & PF_Blending: case PF_Translucent & PF_Blending:
pglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // alpha = level of transparency pglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // alpha = level of transparency
pglAlphaFunc(GL_NOTEQUAL, 0.0f);
break; break;
case PF_Masked & PF_Blending: case PF_Masked & PF_Blending:
// Hurdler: does that mean lighting is only made by alpha src? // Hurdler: does that mean lighting is only made by alpha src?
// it sounds ok, but not for polygonsmooth // it sounds ok, but not for polygonsmooth
pglBlendFunc(GL_SRC_ALPHA, GL_ZERO); // 0 alpha = holes in texture pglBlendFunc(GL_SRC_ALPHA, GL_ZERO); // 0 alpha = holes in texture
pglAlphaFunc(GL_GREATER, 0.5f);
break; break;
case PF_Additive & PF_Blending: case PF_Additive & PF_Blending:
pglBlendFunc(GL_SRC_ALPHA, GL_ONE); // src * alpha + dest pglBlendFunc(GL_SRC_ALPHA, GL_ONE); // src * alpha + dest
pglAlphaFunc(GL_NOTEQUAL, 0.0f);
break; break;
case PF_Environment & PF_Blending: case PF_Environment & PF_Blending:
pglBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); pglBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
pglAlphaFunc(GL_NOTEQUAL, 0.0f);
break; break;
case PF_Substractive & PF_Blending: case PF_Substractive & PF_Blending:
// good for shadow // good for shadow
// not realy but what else ? // not realy but what else ?
pglBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_COLOR); pglBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_COLOR);
pglAlphaFunc(GL_NOTEQUAL, 0.0f);
break;
case PF_Fog & PF_Fog:
// Sryder: Fog
// multiplies input colour by input alpha, and destination colour by input colour, then adds them
pglBlendFunc(GL_SRC_ALPHA, GL_SRC_COLOR);
pglAlphaFunc(GL_NOTEQUAL, 0.0f);
break; break;
default : // must be 0, otherwise it's an error default : // must be 0, otherwise it's an error
// No blending // No blending
pglBlendFunc(GL_ONE, GL_ZERO); // the same as no blending pglBlendFunc(GL_ONE, GL_ZERO); // the same as no blending
pglAlphaFunc(GL_GREATER, 0.5f);
break; break;
} }
} }
@ -1120,6 +1150,7 @@ EXPORT void HWRAPI(SetTexture) (FTextureInfo *pTexInfo)
tex[w*j+i].s.green = 0; tex[w*j+i].s.green = 0;
tex[w*j+i].s.blue = 0; tex[w*j+i].s.blue = 0;
tex[w*j+i].s.alpha = 0; tex[w*j+i].s.alpha = 0;
pTexInfo->flags |= TF_TRANSPARENT; // there is a hole in it
} }
else else
{ {
@ -1189,8 +1220,17 @@ EXPORT void HWRAPI(SetTexture) (FTextureInfo *pTexInfo)
tex_downloaded = pTexInfo->downloaded; tex_downloaded = pTexInfo->downloaded;
pglBindTexture(GL_TEXTURE_2D, pTexInfo->downloaded); pglBindTexture(GL_TEXTURE_2D, pTexInfo->downloaded);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter); // disable texture filtering on any texture that has holes so there's no dumb borders or blending issues
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter); if (pTexInfo->flags & TF_TRANSPARENT)
{
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
}
else
{
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter);
}
#ifdef USE_PALETTED_TEXTURE #ifdef USE_PALETTED_TEXTURE
//Hurdler: not really supported and not tested recently //Hurdler: not really supported and not tested recently
@ -1559,12 +1599,6 @@ static void DrawMD2Ex(INT32 *gl_cmd_buffer, md2_frame_t *frame, INT32 duration,
ambient[1] = 0.75f; ambient[1] = 0.75f;
if (ambient[2] > 0.75f) if (ambient[2] > 0.75f)
ambient[2] = 0.75f; ambient[2] = 0.75f;
if (color[3] < 255)
{
pglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
pglDepthMask(GL_FALSE);
}
} }
pglEnable(GL_CULL_FACE); pglEnable(GL_CULL_FACE);
@ -1589,10 +1623,12 @@ static void DrawMD2Ex(INT32 *gl_cmd_buffer, md2_frame_t *frame, INT32 duration,
pglMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambient); pglMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambient);
pglMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse); pglMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse);
#endif #endif
if (color[3] < 255)
SetBlend(PF_Translucent|PF_Modulated|PF_Clip);
else
SetBlend(PF_Masked|PF_Modulated|PF_Occlude|PF_Clip);
} }
DrawPolygon(NULL, NULL, 0, PF_Masked|PF_Modulated|PF_Occlude|PF_Clip);
pglPushMatrix(); // should be the same as glLoadIdentity pglPushMatrix(); // should be the same as glLoadIdentity
//Hurdler: now it seems to work //Hurdler: now it seems to work
pglTranslatef(pos->x, pos->z, pos->y); pglTranslatef(pos->x, pos->z, pos->y);
@ -1600,14 +1636,6 @@ static void DrawMD2Ex(INT32 *gl_cmd_buffer, md2_frame_t *frame, INT32 duration,
scaley = -scaley; scaley = -scaley;
pglRotatef(pos->angley, 0.0f, -1.0f, 0.0f); pglRotatef(pos->angley, 0.0f, -1.0f, 0.0f);
pglRotatef(pos->anglex, -1.0f, 0.0f, 0.0f); pglRotatef(pos->anglex, -1.0f, 0.0f, 0.0f);
//pglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // alpha = level of transparency
// Remove depth mask when the model is transparent so it doesn't cut thorugh sprites // SRB2CBTODO: For all stuff too?!
if (color && color[3] < 255)
{
pglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // alpha = level of transparency
pglDepthMask(GL_FALSE);
}
val = *gl_cmd_buffer++; val = *gl_cmd_buffer++;
@ -1675,7 +1703,6 @@ static void DrawMD2Ex(INT32 *gl_cmd_buffer, md2_frame_t *frame, INT32 duration,
if (color) if (color)
pglDisable(GL_LIGHTING); pglDisable(GL_LIGHTING);
pglShadeModel(GL_FLAT); pglShadeModel(GL_FLAT);
pglDepthMask(GL_TRUE);
pglDisable(GL_CULL_FACE); pglDisable(GL_CULL_FACE);
} }
@ -1822,10 +1849,25 @@ EXPORT void HWRAPI(PostImgRedraw) (float points[SCREENVERTS][SCREENVERTS][2])
} }
#endif //SHUFFLE #endif //SHUFFLE
// Sryder: This needs to be called whenever the screen changes resolution in order to reset the screen textures to use
// a new size
EXPORT void HWRAPI(FlushScreenTextures) (void)
{
pglDeleteTextures(1, &screentexture);
pglDeleteTextures(1, &startScreenWipe);
pglDeleteTextures(1, &endScreenWipe);
pglDeleteTextures(1, &finalScreenTexture);
screentexture = 0;
startScreenWipe = 0;
endScreenWipe = 0;
finalScreenTexture = 0;
}
// Create Screen to fade from // Create Screen to fade from
EXPORT void HWRAPI(StartScreenWipe) (void) EXPORT void HWRAPI(StartScreenWipe) (void)
{ {
INT32 texsize = 2048; INT32 texsize = 2048;
boolean firstTime = (startScreenWipe == 0);
// Use a power of two texture, dammit // Use a power of two texture, dammit
if(screen_width <= 512) if(screen_width <= 512)
@ -1834,20 +1876,29 @@ EXPORT void HWRAPI(StartScreenWipe) (void)
texsize = 1024; texsize = 1024;
// Create screen texture // Create screen texture
if (firstTime)
startScreenWipe = SCRTEX_STARTSCREENWIPE;
pglBindTexture(GL_TEXTURE_2D, startScreenWipe); pglBindTexture(GL_TEXTURE_2D, startScreenWipe);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
Clamp2D(GL_TEXTURE_WRAP_S);
Clamp2D(GL_TEXTURE_WRAP_T);
pglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, texsize, texsize, 0);
tex_downloaded = 0; // 0 so it knows it doesn't have any of the cached patches downloaded right now if (firstTime)
{
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
Clamp2D(GL_TEXTURE_WRAP_S);
Clamp2D(GL_TEXTURE_WRAP_T);
pglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, texsize, texsize, 0);
}
else
pglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, texsize, texsize);
tex_downloaded = startScreenWipe;
} }
// Create Screen to fade to // Create Screen to fade to
EXPORT void HWRAPI(EndScreenWipe)(void) EXPORT void HWRAPI(EndScreenWipe)(void)
{ {
INT32 texsize = 2048; INT32 texsize = 2048;
boolean firstTime = (endScreenWipe == 0);
// Use a power of two texture, dammit // Use a power of two texture, dammit
if(screen_width <= 512) if(screen_width <= 512)
@ -1856,14 +1907,22 @@ EXPORT void HWRAPI(EndScreenWipe)(void)
texsize = 1024; texsize = 1024;
// Create screen texture // Create screen texture
if (firstTime)
endScreenWipe = SCRTEX_ENDSCREENWIPE;
pglBindTexture(GL_TEXTURE_2D, endScreenWipe); pglBindTexture(GL_TEXTURE_2D, endScreenWipe);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
Clamp2D(GL_TEXTURE_WRAP_S);
Clamp2D(GL_TEXTURE_WRAP_T);
pglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, texsize, texsize, 0);
tex_downloaded = 0; // 0 so it knows it doesn't have any of the cached patches downloaded right now if (firstTime)
{
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
Clamp2D(GL_TEXTURE_WRAP_S);
Clamp2D(GL_TEXTURE_WRAP_T);
pglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, texsize, texsize, 0);
}
else
pglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, texsize, texsize);
tex_downloaded = endScreenWipe;
} }
@ -1905,7 +1964,7 @@ EXPORT void HWRAPI(DrawIntermissionBG)(void)
pglEnd(); pglEnd();
tex_downloaded = 0; // 0 so it knows it doesn't have any of the cached patches downloaded right now tex_downloaded = screentexture;
} }
// Do screen fades! // Do screen fades!
@ -1993,6 +2052,7 @@ EXPORT void HWRAPI(DoScreenWipe)(float alpha)
pglDisable(GL_TEXTURE_2D); // disable the texture in the 2nd texture unit pglDisable(GL_TEXTURE_2D); // disable the texture in the 2nd texture unit
pglActiveTexture(GL_TEXTURE0); pglActiveTexture(GL_TEXTURE0);
tex_downloaded = endScreenWipe;
} }
else else
{ {
@ -2017,9 +2077,8 @@ EXPORT void HWRAPI(DoScreenWipe)(float alpha)
pglTexCoord2f(xfix, 0.0f); pglTexCoord2f(xfix, 0.0f);
pglVertex3f(1.0f, -1.0f, 1.0f); pglVertex3f(1.0f, -1.0f, 1.0f);
pglEnd(); pglEnd();
tex_downloaded = endScreenWipe;
} }
tex_downloaded = 0; // 0 so it knows it doesn't have any of the cached patches downloaded right now
} }
@ -2027,6 +2086,7 @@ EXPORT void HWRAPI(DoScreenWipe)(float alpha)
EXPORT void HWRAPI(MakeScreenTexture) (void) EXPORT void HWRAPI(MakeScreenTexture) (void)
{ {
INT32 texsize = 2048; INT32 texsize = 2048;
boolean firstTime = (screentexture == 0);
// Use a power of two texture, dammit // Use a power of two texture, dammit
if(screen_width <= 512) if(screen_width <= 512)
@ -2035,19 +2095,28 @@ EXPORT void HWRAPI(MakeScreenTexture) (void)
texsize = 1024; texsize = 1024;
// Create screen texture // Create screen texture
if (firstTime)
screentexture = SCRTEX_SCREENTEXTURE;
pglBindTexture(GL_TEXTURE_2D, screentexture); pglBindTexture(GL_TEXTURE_2D, screentexture);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
Clamp2D(GL_TEXTURE_WRAP_S);
Clamp2D(GL_TEXTURE_WRAP_T);
pglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, texsize, texsize, 0);
tex_downloaded = 0; // 0 so it knows it doesn't have any of the cached patches downloaded right now if (firstTime)
{
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
Clamp2D(GL_TEXTURE_WRAP_S);
Clamp2D(GL_TEXTURE_WRAP_T);
pglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, texsize, texsize, 0);
}
else
pglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, texsize, texsize);
tex_downloaded = screentexture;
} }
EXPORT void HWRAPI(MakeScreenFinalTexture) (void) EXPORT void HWRAPI(MakeScreenFinalTexture) (void)
{ {
INT32 texsize = 2048; INT32 texsize = 2048;
boolean firstTime = (finalScreenTexture == 0);
// Use a power of two texture, dammit // Use a power of two texture, dammit
if(screen_width <= 512) if(screen_width <= 512)
@ -2056,20 +2125,31 @@ EXPORT void HWRAPI(MakeScreenFinalTexture) (void)
texsize = 1024; texsize = 1024;
// Create screen texture // Create screen texture
if (firstTime)
finalScreenTexture = SCRTEX_FINALSCREENTEXTURE;
pglBindTexture(GL_TEXTURE_2D, finalScreenTexture); pglBindTexture(GL_TEXTURE_2D, finalScreenTexture);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
Clamp2D(GL_TEXTURE_WRAP_S);
Clamp2D(GL_TEXTURE_WRAP_T);
pglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, texsize, texsize, 0);
tex_downloaded = 0; // 0 so it knows it doesn't have any of the cached patches downloaded right now if (firstTime)
{
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
Clamp2D(GL_TEXTURE_WRAP_S);
Clamp2D(GL_TEXTURE_WRAP_T);
pglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, texsize, texsize, 0);
}
else
pglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, texsize, texsize);
tex_downloaded = finalScreenTexture;
} }
EXPORT void HWRAPI(DrawScreenFinalTexture)(int width, int height) EXPORT void HWRAPI(DrawScreenFinalTexture)(int width, int height)
{ {
float xfix, yfix; float xfix, yfix;
float origaspect, newaspect;
float xoff = 1, yoff = 1; // xoffset and yoffset for the polygon to have black bars around the screen
FRGBAFloat clearColour;
INT32 texsize = 2048; INT32 texsize = 2048;
if(screen_width <= 1024) if(screen_width <= 1024)
@ -2080,35 +2160,47 @@ EXPORT void HWRAPI(DrawScreenFinalTexture)(int width, int height)
xfix = 1/((float)(texsize)/((float)((screen_width)))); xfix = 1/((float)(texsize)/((float)((screen_width))));
yfix = 1/((float)(texsize)/((float)((screen_height)))); yfix = 1/((float)(texsize)/((float)((screen_height))));
//pglClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); origaspect = (float)screen_width / screen_height;
newaspect = (float)width / height;
if (origaspect < newaspect)
{
xoff = origaspect / newaspect;
yoff = 1;
}
else if (origaspect > newaspect)
{
xoff = 1;
yoff = newaspect / origaspect;
}
pglViewport(0, 0, width, height); pglViewport(0, 0, width, height);
clearColour.red = clearColour.green = clearColour.blue = 0;
clearColour.alpha = 1;
ClearBuffer(true, false, &clearColour);
pglBindTexture(GL_TEXTURE_2D, finalScreenTexture); pglBindTexture(GL_TEXTURE_2D, finalScreenTexture);
pglBegin(GL_QUADS); pglBegin(GL_QUADS);
pglColor4f(1.0f, 1.0f, 1.0f, 1.0f); pglColor4f(1.0f, 1.0f, 1.0f, 1.0f);
// Bottom left // Bottom left
pglTexCoord2f(0.0f, 0.0f); pglTexCoord2f(0.0f, 0.0f);
pglVertex3f(-1, -1, 1.0f); pglVertex3f(-xoff, -yoff, 1.0f);
// Top left // Top left
pglTexCoord2f(0.0f, yfix); pglTexCoord2f(0.0f, yfix);
pglVertex3f(-1, 1, 1.0f); pglVertex3f(-xoff, yoff, 1.0f);
// Top right // Top right
pglTexCoord2f(xfix, yfix); pglTexCoord2f(xfix, yfix);
pglVertex3f(1, 1, 1.0f); pglVertex3f(xoff, yoff, 1.0f);
// Bottom right // Bottom right
pglTexCoord2f(xfix, 0.0f); pglTexCoord2f(xfix, 0.0f);
pglVertex3f(1, -1, 1.0f); pglVertex3f(xoff, -yoff, 1.0f);
pglEnd(); pglEnd();
SetModelView(screen_width, screen_height); tex_downloaded = finalScreenTexture;
SetStates();
tex_downloaded = 0; // 0 so it knows it doesn't have any of the cached patches downloaded right now
} }
#endif //HWRENDER #endif //HWRENDER

View file

@ -94,6 +94,7 @@ void *hwSym(const char *funcName,void *handle)
#ifdef SHUFFLE #ifdef SHUFFLE
GETFUNC(PostImgRedraw); GETFUNC(PostImgRedraw);
#endif //SHUFFLE #endif //SHUFFLE
GETFUNC(FlushScreenTextures);
GETFUNC(StartScreenWipe); GETFUNC(StartScreenWipe);
GETFUNC(EndScreenWipe); GETFUNC(EndScreenWipe);
GETFUNC(DoScreenWipe); GETFUNC(DoScreenWipe);

View file

@ -1446,6 +1446,7 @@ void I_StartupGraphics(void)
#ifdef SHUFFLE #ifdef SHUFFLE
HWD.pfnPostImgRedraw = hwSym("PostImgRedraw",NULL); HWD.pfnPostImgRedraw = hwSym("PostImgRedraw",NULL);
#endif #endif
HWD.pfnFlushScreenTextures=hwSym("FlushScreenTextures",NULL);
HWD.pfnStartScreenWipe = hwSym("StartScreenWipe",NULL); HWD.pfnStartScreenWipe = hwSym("StartScreenWipe",NULL);
HWD.pfnEndScreenWipe = hwSym("EndScreenWipe",NULL); HWD.pfnEndScreenWipe = hwSym("EndScreenWipe",NULL);
HWD.pfnDoScreenWipe = hwSym("DoScreenWipe",NULL); HWD.pfnDoScreenWipe = hwSym("DoScreenWipe",NULL);

View file

@ -214,8 +214,11 @@ void OglSdlFinishUpdate(boolean waitvbl)
HWR_DrawScreenFinalTexture(sdlw, sdlh); HWR_DrawScreenFinalTexture(sdlw, sdlh);
SDL_GL_SwapWindow(window); SDL_GL_SwapWindow(window);
SetModelView(realwidth, realheight); GClipRect(0, 0, realwidth, realheight, NZCLIP_PLANE);
SetStates();
// Sryder: We need to draw the final screen texture again into the other buffer in the original position so that
// effects that want to take the old screen can do so after this
HWR_DrawScreenFinalTexture(realwidth, realheight);
} }
EXPORT void HWRAPI( OglSdlSetPalette) (RGBA_t *palette, RGBA_t *pgamma) EXPORT void HWRAPI( OglSdlSetPalette) (RGBA_t *palette, RGBA_t *pgamma)

View file

@ -1405,14 +1405,6 @@ void V_DrawPatchFill(patch_t *pat)
INT32 dupz = (vid.dupx < vid.dupy ? vid.dupx : vid.dupy); INT32 dupz = (vid.dupx < vid.dupy ? vid.dupx : vid.dupy);
INT32 x, y, pw = SHORT(pat->width) * dupz, ph = SHORT(pat->height) * dupz; INT32 x, y, pw = SHORT(pat->width) * dupz, ph = SHORT(pat->height) * dupz;
#ifdef HWRENDER
if (rendermode == render_opengl)
{
pw = FixedMul(SHORT(pat->width)*FRACUNIT, vid.fdupx)>>FRACBITS;
ph = FixedMul(SHORT(pat->height)*FRACUNIT, vid.fdupy)>>FRACBITS;
}
#endif
for (x = 0; x < vid.width; x += pw) for (x = 0; x < vid.width; x += pw)
{ {
for (y = 0; y < vid.height; y += ph) for (y = 0; y < vid.height; y += ph)

View file

@ -117,6 +117,7 @@ static loadfunc_t hwdFuncTable[] = {
#ifdef SHUFFLE #ifdef SHUFFLE
{"PostImgRedraw@4", &hwdriver.pfnPostImgRedraw}, {"PostImgRedraw@4", &hwdriver.pfnPostImgRedraw},
#endif #endif
{"FlushScreenTextures@0",&hwdriver.pfnFlushScreenTextures},
{"StartScreenWipe@0", &hwdriver.pfnStartScreenWipe}, {"StartScreenWipe@0", &hwdriver.pfnStartScreenWipe},
{"EndScreenWipe@0", &hwdriver.pfnEndScreenWipe}, {"EndScreenWipe@0", &hwdriver.pfnEndScreenWipe},
{"DoScreenWipe@4", &hwdriver.pfnDoScreenWipe}, {"DoScreenWipe@4", &hwdriver.pfnDoScreenWipe},
@ -147,6 +148,7 @@ static loadfunc_t hwdFuncTable[] = {
#ifdef SHUFFLE #ifdef SHUFFLE
{"PostImgRedraw", &hwdriver.pfnPostImgRedraw}, {"PostImgRedraw", &hwdriver.pfnPostImgRedraw},
#endif #endif
{"FlushScreenTextures"},&hwdriver.pfnFlushScreenTextures},
{"StartScreenWipe", &hwdriver.pfnStartScreenWipe}, {"StartScreenWipe", &hwdriver.pfnStartScreenWipe},
{"EndScreenWipe", &hwdriver.pfnEndScreenWipe}, {"EndScreenWipe", &hwdriver.pfnEndScreenWipe},
{"DoScreenWipe", &hwdriver.pfnDoScreenWipe}, {"DoScreenWipe", &hwdriver.pfnDoScreenWipe},