Merge remote-tracking branch 'upstream/master' into md2-smoother-interpolation

This commit is contained in:
Steel Titanium 2018-07-05 01:23:56 -04:00
commit c8d0eb04f4
28 changed files with 1142 additions and 662 deletions

View file

@ -842,8 +842,9 @@ boolean CON_Responder(event_t *ev)
return true;
}
// don't eat the key
return false;
// ...why shouldn't it eat the key? if it doesn't, it just means you
// can control Sonic from the console, which is silly
return true; //return false;
}
// command completion forward (tab) and backward (shift-tab)
@ -1042,7 +1043,7 @@ boolean CON_Responder(event_t *ev)
// enter a char into the command prompt
if (key < 32 || key > 127)
return false;
return true; // even if key can't be printed, eat it anyway
// add key to cmd line here
if (key >= 'A' && key <= 'Z' && !shiftdown) //this is only really necessary for dedicated servers

View file

@ -1157,22 +1157,37 @@ static inline void CL_DrawConnectionStatus(void)
if (lastfilenum != -1)
{
INT32 dldlength;
static char tempname[32];
static char tempname[28];
fileneeded_t *file = &fileneeded[lastfilenum];
char *filename = file->filename;
Net_GetNetStat();
dldlength = (INT32)((fileneeded[lastfilenum].currentsize/(double)fileneeded[lastfilenum].totalsize) * 256);
dldlength = (INT32)((file->currentsize/(double)file->totalsize) * 256);
if (dldlength > 256)
dldlength = 256;
V_DrawFill(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-24, 256, 8, 175);
V_DrawFill(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-24, dldlength, 8, 160);
memset(tempname, 0, sizeof(tempname));
nameonly(strncpy(tempname, fileneeded[lastfilenum].filename, 31));
// offset filename to just the name only part
filename += strlen(filename) - nameonlylength(filename);
if (strlen(filename) > sizeof(tempname)-1) // too long to display fully
{
size_t endhalfpos = strlen(filename)-10;
// display as first 14 chars + ... + last 10 chars
// which should add up to 27 if our math(s) is correct
snprintf(tempname, sizeof(tempname), "%.14s...%.10s", filename, filename+endhalfpos);
}
else // we can copy the whole thing in safely
{
strncpy(tempname, filename, sizeof(tempname)-1);
}
V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-24-32, V_YELLOWMAP,
va(M_GetText("Downloading \"%s\""), tempname));
V_DrawString(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-24, V_20TRANS|V_MONOSPACE,
va(" %4uK/%4uK",fileneeded[lastfilenum].currentsize>>10,fileneeded[lastfilenum].totalsize>>10));
va(" %4uK/%4uK",fileneeded[lastfilenum].currentsize>>10,file->totalsize>>10));
V_DrawRightAlignedString(BASEVIDWIDTH/2+128, BASEVIDHEIGHT-24, V_20TRANS|V_MONOSPACE,
va("%3.1fK/s ", ((double)getbps)/1024));
}
@ -2229,7 +2244,7 @@ static void Command_connect(void)
// Assume we connect directly.
boolean viams = false;
if (COM_Argc() < 2)
if (COM_Argc() < 2 || *COM_Argv(1) == 0)
{
CONS_Printf(M_GetText(
"Connect <serveraddress> (port): connect to a server\n"
@ -3984,7 +3999,8 @@ FILESTAMP
INT32 k = *txtpak++; // playernum
const size_t txtsize = txtpak[0]+1;
M_Memcpy(D_GetTextcmd(i, k), txtpak, txtsize);
if (i >= gametic) // Don't copy old net commands
M_Memcpy(D_GetTextcmd(i, k), txtpak, txtsize);
txtpak += txtsize;
}
}

View file

@ -730,11 +730,6 @@ void D_StartTitle(void)
CON_ToggleOff();
// Reset the palette
#ifdef HWRENDER
if (rendermode == render_opengl)
HWR_SetPaletteColor(0);
else
#endif
if (rendermode != render_none)
V_SetPaletteLump("PLAYPAL");
}
@ -1068,7 +1063,7 @@ void D_SRB2Main(void)
// add any files specified on the command line with -file wadfile
// to the wad list
if (!(M_CheckParm("-connect")))
if (!(M_CheckParm("-connect") && !M_CheckParm("-server")))
{
if (M_CheckParm("-file"))
{
@ -1224,7 +1219,15 @@ void D_SRB2Main(void)
R_Init();
// setting up sound
CONS_Printf("S_Init(): Setting up sound.\n");
if (dedicated)
{
nosound = true;
nomidimusic = nodigimusic = true;
}
else
{
CONS_Printf("S_Init(): Setting up sound.\n");
}
if (M_CheckParm("-nosound"))
nosound = true;
if (M_CheckParm("-nomusic")) // combines -nomidimusic and -nodigmusic
@ -1323,7 +1326,7 @@ void D_SRB2Main(void)
ultimatemode = true;
}
if (autostart || netgame || M_CheckParm("+connect") || M_CheckParm("-connect"))
if (autostart || netgame)
{
gameaction = ga_nothing;
@ -1361,8 +1364,7 @@ void D_SRB2Main(void)
}
}
if (server && !M_CheckParm("+map") && !M_CheckParm("+connect")
&& !M_CheckParm("-connect"))
if (server && !M_CheckParm("+map"))
{
// Prevent warping to nonexistent levels
if (W_CheckNumForName(G_BuildMapName(pstartmap)) == LUMPERROR)

View file

@ -582,7 +582,6 @@ void D_RegisterServerCommands(void)
*/
void D_RegisterClientCommands(void)
{
const char *username;
INT32 i;
for (i = 0; i < MAXSKINCOLORS; i++)
@ -639,8 +638,6 @@ void D_RegisterClientCommands(void)
#endif
// register these so it is saved to config
if ((username = I_GetUserName()))
cv_playername.defaultvalue = username;
CV_RegisterVar(&cv_playername);
CV_RegisterVar(&cv_playercolor);
CV_RegisterVar(&cv_skin); // r_things.c (skin NAME)

View file

@ -990,19 +990,41 @@ filestatus_t checkfilemd5(char *filename, const UINT8 *wantedmd5sum)
return FS_FOUND; // will never happen, but makes the compiler shut up
}
// Rewritten by Monster Iestyn to be less stupid
// Note: if completepath is true, "filename" is modified, but only if FS_FOUND is going to be returned
// (Don't worry about WinCE's version of filesearch, nobody cares about that OS anymore)
filestatus_t findfile(char *filename, const UINT8 *wantedmd5sum, boolean completepath)
{
filestatus_t homecheck = filesearch(filename, srb2home, wantedmd5sum, false, 10);
if (homecheck == FS_FOUND)
return filesearch(filename, srb2home, wantedmd5sum, completepath, 10);
filestatus_t homecheck; // store result of last file search
boolean badmd5 = false; // store whether md5 was bad from either of the first two searches (if nothing was found in the third)
homecheck = filesearch(filename, srb2path, wantedmd5sum, false, 10);
if (homecheck == FS_FOUND)
return filesearch(filename, srb2path, wantedmd5sum, completepath, 10);
// first, check SRB2's "home" directory
homecheck = filesearch(filename, srb2home, wantedmd5sum, completepath, 10);
if (homecheck == FS_FOUND) // we found the file, so return that we have :)
return FS_FOUND;
else if (homecheck == FS_MD5SUMBAD) // file has a bad md5; move on and look for a file with the right md5
badmd5 = true;
// if not found at all, just move on without doing anything
// next, check SRB2's "path" directory
homecheck = filesearch(filename, srb2path, wantedmd5sum, completepath, 10);
if (homecheck == FS_FOUND) // we found the file, so return that we have :)
return FS_FOUND;
else if (homecheck == FS_MD5SUMBAD) // file has a bad md5; move on and look for a file with the right md5
badmd5 = true;
// if not found at all, just move on without doing anything
// finally check "." directory
#ifdef _arch_dreamcast
return filesearch(filename, "/cd", wantedmd5sum, completepath, 10);
homecheck = filesearch(filename, "/cd", wantedmd5sum, completepath, 10);
#else
return filesearch(filename, ".", wantedmd5sum, completepath, 10);
homecheck = filesearch(filename, ".", wantedmd5sum, completepath, 10);
#endif
if (homecheck != FS_NOTFOUND) // if not found this time, fall back on the below return statement
return homecheck; // otherwise return the result we got
return (badmd5 ? FS_MD5SUMBAD : FS_NOTFOUND); // md5 sum bad or file not found
}

View file

@ -233,11 +233,19 @@ static void F_SkyScroll(INT32 scrollspeed)
#ifdef HWRENDER
else if (rendermode != render_none)
{ // if only software rendering could be this simple and retarded
scrolled = animtimer;
if (scrolled > 0)
V_DrawScaledPatch(scrolled - SHORT(pat->width), 0, 0, pat);
for (x = 0; x < fakedwidth; x += SHORT(pat->width))
V_DrawScaledPatch(x + scrolled, 0, 0, pat);
INT32 dupz = (vid.dupx < vid.dupy ? vid.dupx : vid.dupy);
INT32 y, pw = SHORT(pat->width) * dupz, ph = SHORT(pat->height) * dupz;
scrolled = animtimer * dupz;
for (x = 0; x < vid.width; x += pw)
{
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
@ -969,7 +977,7 @@ static const char *credits[] = {
"\1Programming",
"Alam \"GBC\" Arias",
"Logan \"GBA\" Arias",
"Tim \"RedEnchilada\" Bordelon",
"Colette \"fickle\" Bordelon",
"Callum Dickinson",
"Scott \"Graue\" Feeney",
"Nathan \"Jazz\" Giroux",
@ -978,12 +986,12 @@ static const char *credits[] = {
"Ronald \"Furyhunter\" Kinard", // The SDL2 port
"John \"JTE\" Muniz",
"Ehab \"Wolfy\" Saeed",
"\"Kaito Sinclaire\"",
"\"SSNTails\"",
"Matthew \"Inuyasha\" Walsh",
"",
"\1Programming",
"\1Assistance",
"\"chi.miru\"", // Red's secret weapon, the REAL reason slopes exist (also helped port drawing code from ZDoom)
"\"chi.miru\"", // helped port slope drawing code from ZDoom
"Andrew \"orospakr\" Clunis",
"Gregor \"Oogaland\" Dick",
"Louis-Antoine \"LJSonic\" de Moulins", // for fixing 2.1's netcode (de Rochefort doesn't quite fit on the screen sorry lol)
@ -999,7 +1007,7 @@ static const char *credits[] = {
"",
"\1Sprite Artists",
"Odi \"Iceman404\" Atunzu",
"Victor \"VAdaPEGA\" Ara\x1Fjo", // Araújo -- sorry for our limited font! D:
"Victor \"VAdaPEGA\" Ara\x1Fjo", // Araújo -- sorry for our limited font! D:
"Jim \"MotorRoach\" DeMello",
"Desmond \"Blade\" DesJardins",
"Sherman \"CoatRack\" DesJardins",
@ -1017,7 +1025,7 @@ static const char *credits[] = {
"\1Music and Sound",
"\1Production",
"Malcolm \"RedXVI\" Brown",
"David \"Bulmybag\" Bulmer",
"Dave \"DemonTomatoDave\" Bulmer",
"Paul \"Boinciel\" Clempson",
"Cyan Helkaraxe",
"Kepa \"Nev3r\" Iceta",
@ -1041,13 +1049,13 @@ static const char *credits[] = {
"Kepa \"Nev3r\" Iceta",
"Thomas \"Shadow Hog\" Igoe",
"Erik \"Torgo\" Nielsen",
"\"Kaito Sinclaire\"",
"Wessel \"Spherallic\" Smit",
"\"Spazzo\"",
"\"SSNTails\"",
"Rob Tisdell",
"Jarrett \"JEV3\" Voight",
"Johnny \"Sonikku\" Wallbank",
"Matthew \"Inuyasha\" Walsh",
"Marco \"Digiku\" Zafra",
"",
"\1Boss Design",

View file

@ -3588,7 +3588,8 @@ void G_InitNew(UINT8 pultmode, const char *mapname, boolean resetplayer, boolean
unlocktriggers = 0;
// clear itemfinder, just in case
CV_StealthSetValue(&cv_itemfinder, 0);
if (!dedicated) // except in dedicated servers, where it is not registered and can actually I_Error debug builds
CV_StealthSetValue(&cv_itemfinder, 0);
}
// internal game map

View file

@ -20,8 +20,8 @@
#define _HWR_DEFS_
#include "../doomtype.h"
#define ZCLIP_PLANE 4.0f
#define NZCLIP_PLANE 0.9f
#define ZCLIP_PLANE 4.0f // Used for the actual game drawing
#define NZCLIP_PLANE 0.9f // Seems to be only used for the HUD and screen textures
// ==========================================================================
// SIMPLE TYPES
@ -133,12 +133,13 @@ enum EPolyFlags
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_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.
// Hurdler: used for text drawing
PF_Substractive = 0x00000010, // for splat
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

View file

@ -147,10 +147,7 @@ void HWR_DrawFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale,
// | /|
// |/ |
// 0--1
float sdupx = FIXED_TO_FLOAT(vid.fdupx)*2.0f;
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);
float dupx, dupy, fscale, fwidth, fheight;
if (alphalevel >= 10 && alphalevel < 13)
return;
@ -161,40 +158,108 @@ void HWR_DrawFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale,
else
HWR_GetMappedPatch(gpatch, colormap);
dupx = (float)vid.dupx;
dupy = (float)vid.dupy;
switch (option & V_SCALEPATCHMASK)
{
case V_NOSCALEPATCH:
pdupx = pdupy = 2.0f;
dupx = dupy = 1.0f;
break;
case V_SMALLSCALEPATCH:
pdupx = 2.0f * FIXED_TO_FLOAT(vid.fsmalldupx);
pdupy = 2.0f * FIXED_TO_FLOAT(vid.fsmalldupy);
dupx = (float)vid.smalldupx;
dupy = (float)vid.smalldupy;
break;
case V_MEDSCALEPATCH:
pdupx = 2.0f * FIXED_TO_FLOAT(vid.fmeddupx);
pdupy = 2.0f * FIXED_TO_FLOAT(vid.fmeddupy);
dupx = (float)vid.meddupx;
dupy = (float)vid.meddupy;
break;
}
if (option & V_NOSCALESTART)
sdupx = sdupy = 2.0f;
dupx = dupy = (dupx < dupy ? dupx : dupy);
fscale = FIXED_TO_FLOAT(pscale);
if (option & V_SPLITSCREEN)
sdupy /= 2.0f;
if (option & V_FLIP) // Need to flip both this and sow
if (option & V_OFFSET)
{
v[0].x = v[3].x = (cx*sdupx-(gpatch->width-gpatch->leftoffset)*pdupx)/vid.width - 1;
v[2].x = v[1].x = (cx*sdupx+gpatch->leftoffset*pdupx)/vid.width - 1;
cx -= (float)gpatch->leftoffset * dupx * fscale;
cy -= (float)gpatch->topoffset * dupy * fscale;
}
else
{
v[0].x = v[3].x = (cx*sdupx-gpatch->leftoffset*pdupx)/vid.width - 1;
v[2].x = v[1].x = (cx*sdupx+(gpatch->width-gpatch->leftoffset)*pdupx)/vid.width - 1;
cy -= (float)gpatch->topoffset * fscale;
if (option & V_FLIP)
cx -= ((float)gpatch->width - (float)gpatch->leftoffset) * fscale;
else
cx -= (float)gpatch->leftoffset * fscale;
}
v[0].y = v[1].y = 1-(cy*sdupy-gpatch->topoffset*pdupy)/vid.height;
v[2].y = v[3].y = 1-(cy*sdupy+(gpatch->height-gpatch->topoffset)*pdupy)/vid.height;
if (option & V_SPLITSCREEN)
cy /= 2;
if (!(option & V_NOSCALESTART))
{
cx = cx * dupx;
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 (vid.height != BASEVIDHEIGHT * vid.dupy)
{
if ((option & (V_SPLITSCREEN|V_SNAPTOBOTTOM)) == (V_SPLITSCREEN|V_SNAPTOBOTTOM))
cy += ((float)vid.height/2 - ((float)BASEVIDHEIGHT/2 * dupy));
else 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 (pscale != FRACUNIT)
{
fwidth = (float)gpatch->width * fscale * dupx;
fheight = (float)gpatch->height * fscale * dupy;
}
else
{
fwidth = (float)gpatch->width * dupx;
fheight = (float)gpatch->height * 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;
@ -247,10 +312,7 @@ void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscal
// | /|
// |/ |
// 0--1
float sdupx = FIXED_TO_FLOAT(vid.fdupx)*2.0f;
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);
float dupx, dupy, fscale, fwidth, fheight;
if (alphalevel >= 10 && alphalevel < 13)
return;
@ -258,28 +320,109 @@ void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscal
// make patch ready in hardware cache
HWR_GetPatch(gpatch);
dupx = (float)vid.dupx;
dupy = (float)vid.dupy;
switch (option & V_SCALEPATCHMASK)
{
case V_NOSCALEPATCH:
pdupx = pdupy = 2.0f;
dupx = dupy = 1.0f;
break;
case V_SMALLSCALEPATCH:
pdupx = 2.0f * FIXED_TO_FLOAT(vid.fsmalldupx);
pdupy = 2.0f * FIXED_TO_FLOAT(vid.fsmalldupy);
dupx = (float)vid.smalldupx;
dupy = (float)vid.smalldupy;
break;
case V_MEDSCALEPATCH:
pdupx = 2.0f * FIXED_TO_FLOAT(vid.fmeddupx);
pdupy = 2.0f * FIXED_TO_FLOAT(vid.fmeddupy);
dupx = (float)vid.meddupx;
dupy = (float)vid.meddupy;
break;
}
if (option & V_NOSCALESTART)
sdupx = sdupy = 2.0f;
dupx = dupy = (dupx < dupy ? dupx : dupy);
fscale = FIXED_TO_FLOAT(pscale);
v[0].x = v[3].x = (cx*sdupx - gpatch->leftoffset * pdupx) / vid.width - 1;
v[2].x = v[1].x = (cx*sdupx + ((w-sx) - gpatch->leftoffset) * pdupx) / vid.width - 1;
v[0].y = v[1].y = 1 - (cy*sdupy - gpatch->topoffset * pdupy) / vid.height;
v[2].y = v[3].y = 1 - (cy*sdupy + ((h-sy) - gpatch->topoffset) * pdupy) / vid.height;
cy -= (float)gpatch->topoffset * fscale;
cx -= (float)gpatch->leftoffset * fscale;
if (!(option & V_NOSCALESTART))
{
cx = cx * dupx;
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 (vid.height != BASEVIDHEIGHT * vid.dupy)
{
if ((option & (V_SPLITSCREEN|V_SNAPTOBOTTOM)) == (V_SPLITSCREEN|V_SNAPTOBOTTOM))
cy += ((float)vid.height/2 - ((float)BASEVIDHEIGHT/2 * dupy));
else if (option & V_SNAPTOBOTTOM)
cy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy));
else if (!(option & V_SNAPTOTOP))
cy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy))/2;
}
}
}
fwidth = w;
fheight = h;
if (fwidth > w - sx)
fwidth = w - sx;
if (fheight > h - sy)
fheight = h - sy;
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;
@ -656,7 +799,7 @@ void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color)
{
FOutVector v[4];
FSurfaceInfo Surf;
float sdupx, sdupy;
float fx, fy, fw, fh;
if (w < 0 || h < 0)
return; // consistency w/ software
@ -665,16 +808,79 @@ void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color)
// | /|
// |/ |
// 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;
fx = (float)x;
fy = (float)y;
fw = (float)w;
fh = (float)h;
v[0].x = v[3].x = (x*sdupx)/vid.width - 1;
v[2].x = v[1].x = (x*sdupx + w*sdupx)/vid.width - 1;
v[0].y = v[1].y = 1-(y*sdupy)/vid.height;
v[2].y = v[3].y = 1-(y*sdupy + h*sdupy)/vid.height;
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 (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 (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
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
EXPORT void HWRAPI(PostImgRedraw) (float points[SCREENVERTS][SCREENVERTS][2]);
#endif
EXPORT void HWRAPI(FlushScreenTextures) (void);
EXPORT void HWRAPI(StartScreenWipe) (void);
EXPORT void HWRAPI(EndScreenWipe) (void);
EXPORT void HWRAPI(DoScreenWipe) (float alpha);
@ -124,6 +125,7 @@ struct hwdriver_s
#ifdef SHUFFLE
PostImgRedraw pfnPostImgRedraw;
#endif
FlushScreenTextures pfnFlushScreenTextures;
StartScreenWipe pfnStartScreenWipe;
EndScreenWipe pfnEndScreenWipe;
DoScreenWipe pfnDoScreenWipe;

View file

@ -68,6 +68,7 @@ typedef struct gr_vissprite_s
struct gr_vissprite_s *prev;
struct gr_vissprite_s *next;
float x1, x2;
float z1, z2;
float tz, ty;
lumpnum_t patchlumpnum;
boolean flip;

File diff suppressed because it is too large Load diff

View file

@ -59,7 +59,7 @@ typedef struct GLRGBAFloat GLRGBAFloat;
#define N_PI_DEMI (M_PIl/2.0f) //(1.5707963268f)
#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;
// **************************************************************************
@ -107,10 +107,19 @@ static GLint viewport[4];
#endif
// Yay for arbitrary numbers! NextTexAvail is buggy for some reason.
static GLuint screentexture = 60000;
static GLuint startScreenWipe = 60001;
static GLuint endScreenWipe = 60002;
static GLuint finalScreenTexture = 60003;
// Sryder: NextTexAvail is broken for these because palette changes or changes to the texture filter or antialiasing
// flush all of the stored textures, leaving them unavailable at times such as between levels
// These need to start at 0 and be set to their number, and be reset to 0 when deleted so that intel GPUs
// 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
GLuint screentexture = FIRST_TEX_AVAIL;
#endif
@ -263,6 +272,7 @@ FUNCPRINTF void DBG_Printf(const char *lpFmt, ...)
/* texture mapping */ //GL_EXT_copy_texture
#ifndef KOS_GL_COMPATIBILITY
#define pglCopyTexImage2D glCopyTexImage2D
#define pglCopyTexSubImage2D glCopyTexSubImage2D
#endif
#else //!STATIC_OPENGL
@ -387,6 +397,8 @@ static PFNglBindTexture pglBindTexture;
/* 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);
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
/* GLU functions */
typedef GLint (APIENTRY * PFNgluBuild2DMipmaps) (GLenum target, GLint internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *data);
@ -503,6 +515,7 @@ boolean SetupGLfunc(void)
GETOPENGLFUNC(pglBindTexture , glBindTexture)
GETOPENGLFUNC(pglCopyTexImage2D , glCopyTexImage2D)
GETOPENGLFUNC(pglCopyTexSubImage2D , glCopyTexSubImage2D)
#undef GETOPENGLFUNC
@ -654,6 +667,10 @@ void SetModelView(GLint w, GLint 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_height = h;
@ -801,6 +818,7 @@ void Flush(void)
screentexture = FIRST_TEX_AVAIL;
}
#endif
tex_downloaded = 0;
}
@ -1056,30 +1074,56 @@ EXPORT void HWRAPI(SetBlend) (FBITFIELD PolyFlags)
switch (PolyFlags & PF_Blending) {
case PF_Translucent & PF_Blending:
pglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // alpha = level of transparency
#ifndef KOS_GL_COMPATIBILITY
pglAlphaFunc(GL_NOTEQUAL, 0.0f);
#endif
break;
case PF_Masked & PF_Blending:
// Hurdler: does that mean lighting is only made by alpha src?
// it sounds ok, but not for polygonsmooth
pglBlendFunc(GL_SRC_ALPHA, GL_ZERO); // 0 alpha = holes in texture
#ifndef KOS_GL_COMPATIBILITY
pglAlphaFunc(GL_GREATER, 0.5f);
#endif
break;
case PF_Additive & PF_Blending:
#ifdef ATI_RAGE_PRO_COMPATIBILITY
pglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // alpha = level of transparency
#else
pglBlendFunc(GL_SRC_ALPHA, GL_ONE); // src * alpha + dest
#endif
#ifndef KOS_GL_COMPATIBILITY
pglAlphaFunc(GL_NOTEQUAL, 0.0f);
#endif
break;
case PF_Environment & PF_Blending:
pglBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
#ifndef KOS_GL_COMPATIBILITY
pglAlphaFunc(GL_NOTEQUAL, 0.0f);
#endif
break;
case PF_Substractive & PF_Blending:
// good for shadow
// not realy but what else ?
pglBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_COLOR);
#ifndef KOS_GL_COMPATIBILITY
pglAlphaFunc(GL_NOTEQUAL, 0.0f);
#endif
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);
#ifndef KOS_GL_COMPATIBILITY
pglAlphaFunc(GL_NOTEQUAL, 0.0f);
#endif
break;
default : // must be 0, otherwise it's an error
// No blending
pglBlendFunc(GL_ONE, GL_ZERO); // the same as no blending
#ifndef KOS_GL_COMPATIBILITY
pglAlphaFunc(GL_GREATER, 0.5f);
#endif
break;
}
}
@ -1339,6 +1383,7 @@ EXPORT void HWRAPI(SetTexture) (FTextureInfo *pTexInfo)
tex[w*j+i].s.green = 0;
tex[w*j+i].s.blue = 0;
tex[w*j+i].s.alpha = 0;
pTexInfo->flags |= TF_TRANSPARENT; // there is a hole in it
}
else
{
@ -1409,8 +1454,22 @@ EXPORT void HWRAPI(SetTexture) (FTextureInfo *pTexInfo)
tex_downloaded = pTexInfo->downloaded;
pglBindTexture(GL_TEXTURE_2D, pTexInfo->downloaded);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter);
// disable texture filtering on any texture that has holes so there's no dumb borders or blending issues
if (pTexInfo->flags & TF_TRANSPARENT)
{
#ifdef KOS_GL_COMPATIBILITY
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NONE);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NONE);
#else
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
#endif
}
else
{
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter);
}
#ifdef KOS_GL_COMPATIBILITY
pglTexImage2D(GL_TEXTURE_2D, 0, GL_ARGB4444, w, h, 0, GL_ARGB4444, GL_UNSIGNED_BYTE, ptex);
@ -1864,12 +1923,6 @@ static void DrawMD2Ex(INT32 *gl_cmd_buffer, md2_frame_t *frame, INT32 duration,
ambient[1] = 0.75f;
if (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);
@ -1896,10 +1949,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_DIFFUSE, diffuse);
#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
//Hurdler: now it seems to work
pglTranslatef(pos->x, pos->z, pos->y);
@ -1907,14 +1962,6 @@ static void DrawMD2Ex(INT32 *gl_cmd_buffer, md2_frame_t *frame, INT32 duration,
scaley = -scaley;
pglRotatef(pos->angley, 0.0f, -1.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++;
@ -1982,7 +2029,6 @@ static void DrawMD2Ex(INT32 *gl_cmd_buffer, md2_frame_t *frame, INT32 duration,
if (color)
pglDisable(GL_LIGHTING);
pglShadeModel(GL_FLAT);
pglDepthMask(GL_TRUE);
pglDisable(GL_CULL_FACE);
}
@ -2135,10 +2181,25 @@ EXPORT void HWRAPI(PostImgRedraw) (float points[SCREENVERTS][SCREENVERTS][2])
}
#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
EXPORT void HWRAPI(StartScreenWipe) (void)
{
INT32 texsize = 2048;
boolean firstTime = (startScreenWipe == 0);
// Use a power of two texture, dammit
if(screen_width <= 512)
@ -2147,27 +2208,38 @@ EXPORT void HWRAPI(StartScreenWipe) (void)
texsize = 1024;
// Create screen texture
if (firstTime)
startScreenWipe = SCRTEX_STARTSCREENWIPE;
pglBindTexture(GL_TEXTURE_2D, startScreenWipe);
if (firstTime)
{
#ifdef KOS_GL_COMPATIBILITY
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_FILTER_NONE);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_FILTER_NONE);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_FILTER_NONE);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_FILTER_NONE);
#else
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
#endif
Clamp2D(GL_TEXTURE_WRAP_S);
Clamp2D(GL_TEXTURE_WRAP_T);
Clamp2D(GL_TEXTURE_WRAP_S);
Clamp2D(GL_TEXTURE_WRAP_T);
#ifndef KOS_GL_COMPATIBILITY
pglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, texsize, texsize, 0);
pglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, texsize, texsize, 0);
#endif
}
else
#ifndef KOS_GL_COMPATIBILITY
pglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, texsize, texsize);
#endif
tex_downloaded = 0; // 0 so it knows it doesn't have any of the cached patches downloaded right now
tex_downloaded = startScreenWipe;
}
// Create Screen to fade to
EXPORT void HWRAPI(EndScreenWipe)(void)
{
INT32 texsize = 2048;
boolean firstTime = (endScreenWipe == 0);
// Use a power of two texture, dammit
if(screen_width <= 512)
@ -2176,21 +2248,32 @@ EXPORT void HWRAPI(EndScreenWipe)(void)
texsize = 1024;
// Create screen texture
if (firstTime)
endScreenWipe = SCRTEX_ENDSCREENWIPE;
pglBindTexture(GL_TEXTURE_2D, endScreenWipe);
if (firstTime)
{
#ifdef KOS_GL_COMPATIBILITY
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_FILTER_NONE);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_FILTER_NONE);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_FILTER_NONE);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_FILTER_NONE);
#else
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
#endif
Clamp2D(GL_TEXTURE_WRAP_S);
Clamp2D(GL_TEXTURE_WRAP_T);
Clamp2D(GL_TEXTURE_WRAP_S);
Clamp2D(GL_TEXTURE_WRAP_T);
#ifndef KOS_GL_COMPATIBILITY
pglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, texsize, texsize, 0);
pglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, texsize, texsize, 0);
#endif
}
else
#ifndef KOS_GL_COMPATIBILITY
pglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, texsize, texsize);
#endif
tex_downloaded = 0; // 0 so it knows it doesn't have any of the cached patches downloaded right now
tex_downloaded = endScreenWipe;
}
@ -2232,7 +2315,7 @@ EXPORT void HWRAPI(DrawIntermissionBG)(void)
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!
@ -2323,6 +2406,7 @@ EXPORT void HWRAPI(DoScreenWipe)(float alpha)
pglDisable(GL_TEXTURE_2D); // disable the texture in the 2nd texture unit
pglActiveTexture(GL_TEXTURE0);
tex_downloaded = endScreenWipe;
}
else
{
@ -2348,11 +2432,10 @@ EXPORT void HWRAPI(DoScreenWipe)(float alpha)
pglTexCoord2f(xfix, 0.0f);
pglVertex3f(1.0f, -1.0f, 1.0f);
pglEnd();
tex_downloaded = endScreenWipe;
#ifndef MINI_GL_COMPATIBILITY
}
#endif
tex_downloaded = 0; // 0 so it knows it doesn't have any of the cached patches downloaded right now
}
@ -2360,6 +2443,7 @@ EXPORT void HWRAPI(DoScreenWipe)(float alpha)
EXPORT void HWRAPI(MakeScreenTexture) (void)
{
INT32 texsize = 2048;
boolean firstTime = (screentexture == 0);
// Use a power of two texture, dammit
if(screen_width <= 512)
@ -2368,26 +2452,37 @@ EXPORT void HWRAPI(MakeScreenTexture) (void)
texsize = 1024;
// Create screen texture
if (firstTime)
screentexture = SCRTEX_SCREENTEXTURE;
pglBindTexture(GL_TEXTURE_2D, screentexture);
if (firstTime)
{
#ifdef KOS_GL_COMPATIBILITY
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_FILTER_NONE);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_FILTER_NONE);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_FILTER_NONE);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_FILTER_NONE);
#else
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
#endif
Clamp2D(GL_TEXTURE_WRAP_S);
Clamp2D(GL_TEXTURE_WRAP_T);
Clamp2D(GL_TEXTURE_WRAP_S);
Clamp2D(GL_TEXTURE_WRAP_T);
#ifndef KOS_GL_COMPATIBILITY
pglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, texsize, texsize, 0);
pglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, texsize, texsize, 0);
#endif
}
else
#ifndef KOS_GL_COMPATIBILITY
pglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, texsize, texsize);
#endif
tex_downloaded = 0; // 0 so it knows it doesn't have any of the cached patches downloaded right now
tex_downloaded = screentexture;
}
EXPORT void HWRAPI(MakeScreenFinalTexture) (void)
{
INT32 texsize = 2048;
boolean firstTime = (finalScreenTexture == 0);
// Use a power of two texture, dammit
if(screen_width <= 512)
@ -2396,27 +2491,40 @@ EXPORT void HWRAPI(MakeScreenFinalTexture) (void)
texsize = 1024;
// Create screen texture
if (firstTime)
finalScreenTexture = SCRTEX_FINALSCREENTEXTURE;
pglBindTexture(GL_TEXTURE_2D, finalScreenTexture);
if (firstTime)
{
#ifdef KOS_GL_COMPATIBILITY
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_FILTER_NONE);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_FILTER_NONE);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_FILTER_NONE);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_FILTER_NONE);
#else
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
#endif
Clamp2D(GL_TEXTURE_WRAP_S);
Clamp2D(GL_TEXTURE_WRAP_T);
Clamp2D(GL_TEXTURE_WRAP_S);
Clamp2D(GL_TEXTURE_WRAP_T);
#ifndef KOS_GL_COMPATIBILITY
pglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, texsize, texsize, 0);
pglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, texsize, texsize, 0);
#endif
}
else
#ifndef KOS_GL_COMPATIBILITY
pglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, texsize, texsize);
#endif
tex_downloaded = 0; // 0 so it knows it doesn't have any of the cached patches downloaded right now
tex_downloaded = finalScreenTexture;
}
EXPORT void HWRAPI(DrawScreenFinalTexture)(int width, int height)
{
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;
if(screen_width <= 1024)
@ -2427,35 +2535,47 @@ EXPORT void HWRAPI(DrawScreenFinalTexture)(int width, int height)
xfix = 1/((float)(texsize)/((float)((screen_width))));
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);
clearColour.red = clearColour.green = clearColour.blue = 0;
clearColour.alpha = 1;
ClearBuffer(true, false, &clearColour);
pglBindTexture(GL_TEXTURE_2D, finalScreenTexture);
pglBegin(GL_QUADS);
pglColor4f(1.0f, 1.0f, 1.0f, 1.0f);
// Bottom left
pglTexCoord2f(0.0f, 0.0f);
pglVertex3f(-1, -1, 1.0f);
pglVertex3f(-xoff, -yoff, 1.0f);
// Top left
pglTexCoord2f(0.0f, yfix);
pglVertex3f(-1, 1, 1.0f);
pglVertex3f(-xoff, yoff, 1.0f);
// Top right
pglTexCoord2f(xfix, yfix);
pglVertex3f(1, 1, 1.0f);
pglVertex3f(xoff, yoff, 1.0f);
// Bottom right
pglTexCoord2f(xfix, 0.0f);
pglVertex3f(1, -1, 1.0f);
pglVertex3f(xoff, -yoff, 1.0f);
pglEnd();
SetModelView(screen_width, screen_height);
SetStates();
tex_downloaded = 0; // 0 so it knows it doesn't have any of the cached patches downloaded right now
tex_downloaded = finalScreenTexture;
}
#endif //HWRENDER

View file

@ -478,10 +478,10 @@ static const struct {
{NULL, ARCH_NULL}
};
static UINT8 GetUserdataArchType(void)
static UINT8 GetUserdataArchType(int index)
{
UINT8 i;
lua_getmetatable(gL, -1);
lua_getmetatable(gL, index);
for (i = 0; meta2arch[i].meta; i++)
{
@ -560,7 +560,7 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
break;
}
case LUA_TUSERDATA:
switch (GetUserdataArchType())
switch (GetUserdataArchType(myindex))
{
case ARCH_MOBJINFO:
{
@ -777,6 +777,7 @@ static void ArchiveTables(void)
CONS_Alert(CONS_ERROR, "Type of value for table %d entry '%s' (%s) could not be archived!\n", i, lua_tostring(gL, -1), luaL_typename(gL, -1));
lua_pop(gL, 1);
}
lua_pop(gL, 1);
}
lua_pop(gL, 1);

View file

@ -33,7 +33,9 @@
*/
fixed_t FixedMul(fixed_t a, fixed_t b)
{
return (fixed_t)((((INT64)a * b) ) / FRACUNIT);
// Need to cast to unsigned before shifting to avoid undefined behaviour
// for negative integers
return (fixed_t)(((UINT64)((INT64)a * b)) >> FRACBITS);
}
#endif //__USE_C_FIXEDMUL__

View file

@ -6295,6 +6295,13 @@ static void M_DrawConnectIPMenu(void)
static void M_ConnectIP(INT32 choice)
{
(void)choice;
if (*setupm_ip == 0)
{
M_StartMessage("You must specify an IP address.\n", NULL, MM_NOTHING);
return;
}
COM_BufAddText(va("connect \"%s\"\n", setupm_ip));
// A little "please wait" message.
@ -6536,7 +6543,7 @@ static void M_HandleSetupMultiPlayer(INT32 choice)
if (choice < 32 || choice > 127 || itemOn != 0)
break;
l = strlen(setupm_name);
if (l < MAXPLAYERNAME-1)
if (l < MAXPLAYERNAME)
{
S_StartSound(NULL,sfx_menu1); // Tails
setupm_name[l] =(char)choice;

View file

@ -644,13 +644,12 @@ static void M_PNGhdr(png_structp png_ptr, png_infop png_info_ptr, PNG_CONST png_
static void M_PNGText(png_structp png_ptr, png_infop png_info_ptr, PNG_CONST png_byte movie)
{
#ifdef PNG_TEXT_SUPPORTED
#define SRB2PNGTXT 11 //PNG_KEYWORD_MAX_LENGTH(79) is the max
#define SRB2PNGTXT 10 //PNG_KEYWORD_MAX_LENGTH(79) is the max
png_text png_infotext[SRB2PNGTXT];
char keytxt[SRB2PNGTXT][12] = {
"Title", "Author", "Description", "Playername", "Mapnum", "Mapname",
"Title", "Description", "Playername", "Mapnum", "Mapname",
"Location", "Interface", "Revision", "Build Date", "Build Time"};
char titletxt[] = "Sonic Robo Blast 2 " VERSIONSTRING;
png_charp authortxt = I_GetUserName();
png_charp playertxt = cv_playername.zstring;
char desctxt[] = "SRB2 Screenshot";
char Movietxt[] = "SRB2 Movie";
@ -700,19 +699,18 @@ static void M_PNGText(png_structp png_ptr, png_infop png_info_ptr, PNG_CONST png
png_infotext[i].key = keytxt[i];
png_infotext[0].text = titletxt;
png_infotext[1].text = authortxt;
if (movie)
png_infotext[2].text = Movietxt;
png_infotext[1].text = Movietxt;
else
png_infotext[2].text = desctxt;
png_infotext[3].text = playertxt;
png_infotext[4].text = maptext;
png_infotext[5].text = lvlttltext;
png_infotext[6].text = locationtxt;
png_infotext[7].text = interfacetxt;
png_infotext[8].text = strncpy(ctrevision, comprevision, sizeof(ctrevision)-1);
png_infotext[9].text = strncpy(ctdate, compdate, sizeof(ctdate)-1);
png_infotext[10].text = strncpy(cttime, comptime, sizeof(cttime)-1);
png_infotext[1].text = desctxt;
png_infotext[2].text = playertxt;
png_infotext[3].text = maptext;
png_infotext[4].text = lvlttltext;
png_infotext[5].text = locationtxt;
png_infotext[6].text = interfacetxt;
png_infotext[7].text = strncpy(ctrevision, comprevision, sizeof(ctrevision)-1);
png_infotext[8].text = strncpy(ctdate, compdate, sizeof(ctdate)-1);
png_infotext[9].text = strncpy(cttime, comptime, sizeof(cttime)-1);
png_set_text(png_ptr, png_info_ptr, png_infotext, SRB2PNGTXT);
#undef SRB2PNGTXT

View file

@ -2503,11 +2503,6 @@ boolean P_SetupLevel(boolean skipprecip)
// Reset the palette
#ifdef HWRENDER
if (rendermode == render_opengl)
HWR_SetPaletteColor(0);
else
#endif
if (rendermode != render_none)
V_SetPaletteLump("PLAYPAL");
@ -2565,6 +2560,7 @@ boolean P_SetupLevel(boolean skipprecip)
{
tic_t starttime = I_GetTime();
tic_t endtime = starttime + (3*TICRATE)/2;
tic_t nowtime;
S_StartSound(NULL, sfx_s3kaf);
@ -2574,9 +2570,17 @@ boolean P_SetupLevel(boolean skipprecip)
F_WipeEndScreen();
F_RunWipe(wipedefs[wipe_speclevel_towhite], false);
nowtime = lastwipetic;
// Hold on white for extra effect.
while (I_GetTime() < endtime)
I_Sleep();
while (nowtime < endtime)
{
// wait loop
while (!((nowtime = I_GetTime()) - lastwipetic))
I_Sleep();
lastwipetic = nowtime;
if (moviemode) // make sure we save frames for the white hold too
M_SaveFrame();
}
ranspecialwipe = 1;
}
@ -2994,7 +2998,7 @@ boolean P_AddWadFile(const char *wadfilename, char **firstmapname)
if ((numlumps = W_LoadWadFile(wadfilename)) == INT16_MAX)
{
CONS_Printf(M_GetText("Errors occured while loading %s; not added.\n"), wadfilename);
CONS_Printf(M_GetText("Errors occurred while loading %s; not added.\n"), wadfilename);
return false;
}
else wadnum = (UINT16)(numwadfiles-1);

View file

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

View file

@ -2709,7 +2709,7 @@ const char *I_LocateWad(void)
return waddir;
}
#if defined(LINUX) || defined(LINUX64)
#ifdef __linux__
#define MEMINFO_FILE "/proc/meminfo"
#define MEMTOTAL "MemTotal:"
#define MEMFREE "MemFree:"
@ -2729,20 +2729,23 @@ UINT32 I_GetFreeMem(UINT32 *total)
};
if ((kd = kvm_open(NULL, NULL, NULL, O_RDONLY, "kvm_open")) == NULL)
{
*total = 0L;
if (total)
*total = 0L;
return 0;
}
if (kvm_nlist(kd, namelist) != 0)
{
kvm_close (kd);
*total = 0L;
if (total)
*total = 0L;
return 0;
}
if (kvm_read(kd, namelist[X_SUM].n_value, &sum,
sizeof (sum)) != sizeof (sum))
{
kvm_close(kd);
*total = 0L;
if (total)
*total = 0L;
return 0;
}
kvm_close(kd);
@ -2773,7 +2776,7 @@ UINT32 I_GetFreeMem(UINT32 *total)
(PVOID) &pr_arena, sizeof (UINT32));
return pr_arena;
#elif defined (LINUX) || defined (LINUX64)
#elif defined (__linux__)
/* Linux */
char buf[1024];
char *memTag;
@ -2789,25 +2792,28 @@ UINT32 I_GetFreeMem(UINT32 *total)
if (n < 0)
{
// Error
*total = 0L;
if (total)
*total = 0L;
return 0;
}
buf[n] = '\0';
if (NULL == (memTag = strstr(buf, MEMTOTAL)))
if ((memTag = strstr(buf, MEMTOTAL)) == NULL)
{
// Error
*total = 0L;
if (total)
*total = 0L;
return 0;
}
memTag += sizeof (MEMTOTAL);
totalKBytes = atoi(memTag);
if (NULL == (memTag = strstr(buf, MEMFREE)))
if ((memTag = strstr(buf, MEMFREE)) == NULL)
{
// Error
*total = 0L;
if (total)
*total = 0L;
return 0;
}
@ -2822,7 +2828,7 @@ UINT32 I_GetFreeMem(UINT32 *total)
if (total)
*total = 48<<20;
return 48<<20;
#endif /* LINUX */
#endif
}
const CPUInfoFlags *I_CPUInfo(void)

View file

@ -658,6 +658,14 @@ static void Impl_HandleMouseButtonEvent(SDL_MouseButtonEvent evt, Uint32 type)
SDL_memset(&event, 0, sizeof(event_t));
// Ignore the event if the mouse is not actually focused on the window.
// This can happen if you used the mouse to restore keyboard focus;
// this apparently makes a mouse button down event but not a mouse button up event,
// resulting in whatever key was pressed down getting "stuck" if we don't ignore it.
// -- Monster Iestyn (28/05/18)
if (SDL_GetMouseFocus() != window)
return;
/// \todo inputEvent.button.which
if (USE_MOUSEINPUT)
{
@ -1442,6 +1450,7 @@ void I_StartupGraphics(void)
#ifdef SHUFFLE
HWD.pfnPostImgRedraw = hwSym("PostImgRedraw",NULL);
#endif
HWD.pfnFlushScreenTextures=hwSym("FlushScreenTextures",NULL);
HWD.pfnStartScreenWipe = hwSym("StartScreenWipe",NULL);
HWD.pfnEndScreenWipe = hwSym("EndScreenWipe",NULL);
HWD.pfnDoScreenWipe = hwSym("DoScreenWipe",NULL);

View file

@ -214,8 +214,11 @@ void OglSdlFinishUpdate(boolean waitvbl)
HWR_DrawScreenFinalTexture(sdlw, sdlh);
SDL_GL_SwapWindow(window);
SetModelView(realwidth, realheight);
SetStates();
GClipRect(0, 0, realwidth, realheight, NZCLIP_PLANE);
// 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)

View file

@ -1180,12 +1180,6 @@ void I_StartupSound(void)
audio.callback = I_UpdateStream;
audio.userdata = &localdata;
if (dedicated)
{
nosound = nomidimusic = nodigimusic = true;
return;
}
// Configure sound device
CONS_Printf("I_StartupSound:\n");
@ -1481,9 +1475,6 @@ void I_InitMusic(void)
I_AddExitFunc(I_ShutdownGMEMusic);
#endif
if ((nomidimusic && nodigimusic) || dedicated)
return;
#ifdef HAVE_MIXER
MIX_VERSION(&MIXcompiled)
MIXlinked = Mix_Linked_Version();

View file

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

View file

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

View file

@ -210,17 +210,17 @@ void ST_doPaletteStuff(void)
else
palette = 0;
#ifdef HWRENDER
if (rendermode == render_opengl)
palette = 0; // No flashpals here in OpenGL
#endif
palette = min(max(palette, 0), 13);
if (palette != st_palette)
{
st_palette = palette;
#ifdef HWRENDER
if (rendermode == render_opengl)
HWR_SetPaletteColor(0);
else
#endif
if (rendermode != render_none)
{
V_SetPaletteLump(GetPalette()); // Reset the palette

View file

@ -937,14 +937,6 @@ void V_DrawPatchFill(patch_t *pat)
INT32 dupz = (vid.dupx < vid.dupy ? vid.dupx : vid.dupy);
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 (y = 0; y < vid.height; y += ph)

View file

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