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; return true;
} }
// don't eat the key // ...why shouldn't it eat the key? if it doesn't, it just means you
return false; // can control Sonic from the console, which is silly
return true; //return false;
} }
// command completion forward (tab) and backward (shift-tab) // 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 // enter a char into the command prompt
if (key < 32 || key > 127) 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 // add key to cmd line here
if (key >= 'A' && key <= 'Z' && !shiftdown) //this is only really necessary for dedicated servers 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) if (lastfilenum != -1)
{ {
INT32 dldlength; INT32 dldlength;
static char tempname[32]; static char tempname[28];
fileneeded_t *file = &fileneeded[lastfilenum];
char *filename = file->filename;
Net_GetNetStat(); Net_GetNetStat();
dldlength = (INT32)((fileneeded[lastfilenum].currentsize/(double)fileneeded[lastfilenum].totalsize) * 256); dldlength = (INT32)((file->currentsize/(double)file->totalsize) * 256);
if (dldlength > 256) if (dldlength > 256)
dldlength = 256; dldlength = 256;
V_DrawFill(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-24, 256, 8, 175); V_DrawFill(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-24, 256, 8, 175);
V_DrawFill(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-24, dldlength, 8, 160); V_DrawFill(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-24, dldlength, 8, 160);
memset(tempname, 0, sizeof(tempname)); 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, V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-24-32, V_YELLOWMAP,
va(M_GetText("Downloading \"%s\""), tempname)); va(M_GetText("Downloading \"%s\""), tempname));
V_DrawString(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-24, V_20TRANS|V_MONOSPACE, 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, V_DrawRightAlignedString(BASEVIDWIDTH/2+128, BASEVIDHEIGHT-24, V_20TRANS|V_MONOSPACE,
va("%3.1fK/s ", ((double)getbps)/1024)); va("%3.1fK/s ", ((double)getbps)/1024));
} }
@ -2229,7 +2244,7 @@ static void Command_connect(void)
// Assume we connect directly. // Assume we connect directly.
boolean viams = false; boolean viams = false;
if (COM_Argc() < 2) if (COM_Argc() < 2 || *COM_Argv(1) == 0)
{ {
CONS_Printf(M_GetText( CONS_Printf(M_GetText(
"Connect <serveraddress> (port): connect to a server\n" "Connect <serveraddress> (port): connect to a server\n"
@ -3984,6 +3999,7 @@ FILESTAMP
INT32 k = *txtpak++; // playernum INT32 k = *txtpak++; // playernum
const size_t txtsize = txtpak[0]+1; const size_t txtsize = txtpak[0]+1;
if (i >= gametic) // Don't copy old net commands
M_Memcpy(D_GetTextcmd(i, k), txtpak, txtsize); M_Memcpy(D_GetTextcmd(i, k), txtpak, txtsize);
txtpak += txtsize; txtpak += txtsize;
} }

View file

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

View file

@ -582,7 +582,6 @@ void D_RegisterServerCommands(void)
*/ */
void D_RegisterClientCommands(void) void D_RegisterClientCommands(void)
{ {
const char *username;
INT32 i; INT32 i;
for (i = 0; i < MAXSKINCOLORS; i++) for (i = 0; i < MAXSKINCOLORS; i++)
@ -639,8 +638,6 @@ void D_RegisterClientCommands(void)
#endif #endif
// register these so it is saved to config // register these so it is saved to config
if ((username = I_GetUserName()))
cv_playername.defaultvalue = username;
CV_RegisterVar(&cv_playername); CV_RegisterVar(&cv_playername);
CV_RegisterVar(&cv_playercolor); CV_RegisterVar(&cv_playercolor);
CV_RegisterVar(&cv_skin); // r_things.c (skin NAME) 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 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 findfile(char *filename, const UINT8 *wantedmd5sum, boolean completepath)
{ {
filestatus_t homecheck = filesearch(filename, srb2home, wantedmd5sum, false, 10); filestatus_t homecheck; // store result of last file search
if (homecheck == FS_FOUND) boolean badmd5 = false; // store whether md5 was bad from either of the first two searches (if nothing was found in the third)
return filesearch(filename, srb2home, wantedmd5sum, completepath, 10);
homecheck = filesearch(filename, srb2path, wantedmd5sum, false, 10); // first, check SRB2's "home" directory
if (homecheck == FS_FOUND) homecheck = filesearch(filename, srb2home, wantedmd5sum, completepath, 10);
return 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
// 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 #ifdef _arch_dreamcast
return filesearch(filename, "/cd", wantedmd5sum, completepath, 10); homecheck = filesearch(filename, "/cd", wantedmd5sum, completepath, 10);
#else #else
return filesearch(filename, ".", wantedmd5sum, completepath, 10); homecheck = filesearch(filename, ".", wantedmd5sum, completepath, 10);
#endif #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 #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);
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) if (scrolled > 0)
V_DrawScaledPatch(scrolled - SHORT(pat->width), 0, 0, pat); V_DrawScaledPatch(scrolled - pw, y, V_NOSCALESTART, pat);
for (x = 0; x < fakedwidth; x += SHORT(pat->width))
V_DrawScaledPatch(x + scrolled, 0, 0, pat); V_DrawScaledPatch(x + scrolled, y, V_NOSCALESTART, pat);
}
}
} }
#endif #endif
@ -969,7 +977,7 @@ static const char *credits[] = {
"\1Programming", "\1Programming",
"Alam \"GBC\" Arias", "Alam \"GBC\" Arias",
"Logan \"GBA\" Arias", "Logan \"GBA\" Arias",
"Tim \"RedEnchilada\" Bordelon", "Colette \"fickle\" Bordelon",
"Callum Dickinson", "Callum Dickinson",
"Scott \"Graue\" Feeney", "Scott \"Graue\" Feeney",
"Nathan \"Jazz\" Giroux", "Nathan \"Jazz\" Giroux",
@ -978,12 +986,12 @@ static const char *credits[] = {
"Ronald \"Furyhunter\" Kinard", // The SDL2 port "Ronald \"Furyhunter\" Kinard", // The SDL2 port
"John \"JTE\" Muniz", "John \"JTE\" Muniz",
"Ehab \"Wolfy\" Saeed", "Ehab \"Wolfy\" Saeed",
"\"Kaito Sinclaire\"",
"\"SSNTails\"", "\"SSNTails\"",
"Matthew \"Inuyasha\" Walsh",
"", "",
"\1Programming", "\1Programming",
"\1Assistance", "\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", "Andrew \"orospakr\" Clunis",
"Gregor \"Oogaland\" Dick", "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) "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", "\1Sprite Artists",
"Odi \"Iceman404\" Atunzu", "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", "Jim \"MotorRoach\" DeMello",
"Desmond \"Blade\" DesJardins", "Desmond \"Blade\" DesJardins",
"Sherman \"CoatRack\" DesJardins", "Sherman \"CoatRack\" DesJardins",
@ -1017,7 +1025,7 @@ static const char *credits[] = {
"\1Music and Sound", "\1Music and Sound",
"\1Production", "\1Production",
"Malcolm \"RedXVI\" Brown", "Malcolm \"RedXVI\" Brown",
"David \"Bulmybag\" Bulmer", "Dave \"DemonTomatoDave\" Bulmer",
"Paul \"Boinciel\" Clempson", "Paul \"Boinciel\" Clempson",
"Cyan Helkaraxe", "Cyan Helkaraxe",
"Kepa \"Nev3r\" Iceta", "Kepa \"Nev3r\" Iceta",
@ -1041,13 +1049,13 @@ static const char *credits[] = {
"Kepa \"Nev3r\" Iceta", "Kepa \"Nev3r\" Iceta",
"Thomas \"Shadow Hog\" Igoe", "Thomas \"Shadow Hog\" Igoe",
"Erik \"Torgo\" Nielsen", "Erik \"Torgo\" Nielsen",
"\"Kaito Sinclaire\"",
"Wessel \"Spherallic\" Smit", "Wessel \"Spherallic\" Smit",
"\"Spazzo\"", "\"Spazzo\"",
"\"SSNTails\"", "\"SSNTails\"",
"Rob Tisdell", "Rob Tisdell",
"Jarrett \"JEV3\" Voight", "Jarrett \"JEV3\" Voight",
"Johnny \"Sonikku\" Wallbank", "Johnny \"Sonikku\" Wallbank",
"Matthew \"Inuyasha\" Walsh",
"Marco \"Digiku\" Zafra", "Marco \"Digiku\" Zafra",
"", "",
"\1Boss Design", "\1Boss Design",

View file

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

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
@ -133,12 +133,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

@ -147,10 +147,7 @@ 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, 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;
@ -161,40 +158,108 @@ 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; fscale = FIXED_TO_FLOAT(pscale);
if (option & V_SPLITSCREEN) if (option & V_OFFSET)
sdupy /= 2.0f;
if (option & V_FLIP) // Need to flip both this and sow
{ {
v[0].x = v[3].x = (cx*sdupx-(gpatch->width-gpatch->leftoffset)*pdupx)/vid.width - 1; cx -= (float)gpatch->leftoffset * dupx * fscale;
v[2].x = v[1].x = (cx*sdupx+gpatch->leftoffset*pdupx)/vid.width - 1; cy -= (float)gpatch->topoffset * dupy * fscale;
} }
else else
{ {
v[0].x = v[3].x = (cx*sdupx-gpatch->leftoffset*pdupx)/vid.width - 1; cy -= (float)gpatch->topoffset * fscale;
v[2].x = v[1].x = (cx*sdupx+(gpatch->width-gpatch->leftoffset)*pdupx)/vid.width - 1; 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; if (option & V_SPLITSCREEN)
v[2].y = v[3].y = 1-(cy*sdupy+(gpatch->height-gpatch->topoffset)*pdupy)/vid.height; 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; 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 // 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;
@ -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 // 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);
v[0].x = v[3].x = (cx*sdupx - gpatch->leftoffset * pdupx) / vid.width - 1; cy -= (float)gpatch->topoffset * fscale;
v[2].x = v[1].x = (cx*sdupx + ((w-sx) - gpatch->leftoffset) * pdupx) / vid.width - 1; 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 + ((h-sy) - gpatch->topoffset) * pdupy) / vid.height; 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; 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]; FOutVector v[4];
FSurfaceInfo Surf; FSurfaceInfo Surf;
float sdupx, sdupy; float fx, fy, fw, fh;
if (w < 0 || h < 0) if (w < 0 || h < 0)
return; // consistency w/ software return; // consistency w/ software
@ -665,16 +808,79 @@ 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) fx = (float)x;
sdupx = sdupy = 2.0f; fy = (float)y;
fw = (float)w;
fh = (float)h;
v[0].x = v[3].x = (x*sdupx)/vid.width - 1; if (!(color & V_NOSCALESTART))
v[2].x = v[1].x = (x*sdupx + w*sdupx)/vid.width - 1; {
v[0].y = v[1].y = 1-(y*sdupy)/vid.height; float dupx = (float)vid.dupx, dupy = (float)vid.dupy;
v[2].y = v[3].y = 1-(y*sdupy + h*sdupy)/vid.height;
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 //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;

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 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;
// ************************************************************************** // **************************************************************************
@ -107,10 +107,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
@ -263,6 +272,7 @@ FUNCPRINTF void DBG_Printf(const char *lpFmt, ...)
/* texture mapping */ //GL_EXT_copy_texture /* texture mapping */ //GL_EXT_copy_texture
#ifndef KOS_GL_COMPATIBILITY #ifndef KOS_GL_COMPATIBILITY
#define pglCopyTexImage2D glCopyTexImage2D #define pglCopyTexImage2D glCopyTexImage2D
#define pglCopyTexSubImage2D glCopyTexSubImage2D
#endif #endif
#else //!STATIC_OPENGL #else //!STATIC_OPENGL
@ -387,6 +397,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);
@ -503,6 +515,7 @@ boolean SetupGLfunc(void)
GETOPENGLFUNC(pglBindTexture , glBindTexture) GETOPENGLFUNC(pglBindTexture , glBindTexture)
GETOPENGLFUNC(pglCopyTexImage2D , glCopyTexImage2D) GETOPENGLFUNC(pglCopyTexImage2D , glCopyTexImage2D)
GETOPENGLFUNC(pglCopyTexSubImage2D , glCopyTexSubImage2D)
#undef GETOPENGLFUNC #undef GETOPENGLFUNC
@ -654,6 +667,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;
@ -801,6 +818,7 @@ void Flush(void)
screentexture = FIRST_TEX_AVAIL; screentexture = FIRST_TEX_AVAIL;
} }
#endif #endif
tex_downloaded = 0; tex_downloaded = 0;
} }
@ -1056,30 +1074,56 @@ 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
#ifndef KOS_GL_COMPATIBILITY
pglAlphaFunc(GL_NOTEQUAL, 0.0f);
#endif
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
#ifndef KOS_GL_COMPATIBILITY
pglAlphaFunc(GL_GREATER, 0.5f);
#endif
break; break;
case PF_Additive & PF_Blending: case PF_Additive & PF_Blending:
#ifdef ATI_RAGE_PRO_COMPATIBILITY #ifdef ATI_RAGE_PRO_COMPATIBILITY
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
#else #else
pglBlendFunc(GL_SRC_ALPHA, GL_ONE); // src * alpha + dest pglBlendFunc(GL_SRC_ALPHA, GL_ONE); // src * alpha + dest
#endif
#ifndef KOS_GL_COMPATIBILITY
pglAlphaFunc(GL_NOTEQUAL, 0.0f);
#endif #endif
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);
#ifndef KOS_GL_COMPATIBILITY
pglAlphaFunc(GL_NOTEQUAL, 0.0f);
#endif
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);
#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; 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
#ifndef KOS_GL_COMPATIBILITY
pglAlphaFunc(GL_GREATER, 0.5f);
#endif
break; break;
} }
} }
@ -1339,6 +1383,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
{ {
@ -1409,8 +1454,22 @@ 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);
// 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_MAG_FILTER, mag_filter);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter); pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter);
}
#ifdef KOS_GL_COMPATIBILITY #ifdef KOS_GL_COMPATIBILITY
pglTexImage2D(GL_TEXTURE_2D, 0, GL_ARGB4444, w, h, 0, GL_ARGB4444, GL_UNSIGNED_BYTE, ptex); 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; 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);
@ -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_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);
@ -1907,14 +1962,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++;
@ -1982,7 +2029,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);
} }
@ -2135,10 +2181,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)
@ -2147,7 +2208,12 @@ 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);
if (firstTime)
{
#ifdef KOS_GL_COMPATIBILITY #ifdef KOS_GL_COMPATIBILITY
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_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); pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_FILTER_NONE);
@ -2160,14 +2226,20 @@ EXPORT void HWRAPI(StartScreenWipe) (void)
#ifndef KOS_GL_COMPATIBILITY #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 #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 // 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)
@ -2176,7 +2248,12 @@ 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);
if (firstTime)
{
#ifdef KOS_GL_COMPATIBILITY #ifdef KOS_GL_COMPATIBILITY
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_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); pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_FILTER_NONE);
@ -2189,8 +2266,14 @@ EXPORT void HWRAPI(EndScreenWipe)(void)
#ifndef KOS_GL_COMPATIBILITY #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 #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(); 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!
@ -2323,6 +2406,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
{ {
@ -2348,11 +2432,10 @@ 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;
#ifndef MINI_GL_COMPATIBILITY #ifndef MINI_GL_COMPATIBILITY
} }
#endif #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) 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)
@ -2368,7 +2452,12 @@ 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);
if (firstTime)
{
#ifdef KOS_GL_COMPATIBILITY #ifdef KOS_GL_COMPATIBILITY
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_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); pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_FILTER_NONE);
@ -2381,13 +2470,19 @@ EXPORT void HWRAPI(MakeScreenTexture) (void)
#ifndef KOS_GL_COMPATIBILITY #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 #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) 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)
@ -2396,7 +2491,12 @@ 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);
if (firstTime)
{
#ifdef KOS_GL_COMPATIBILITY #ifdef KOS_GL_COMPATIBILITY
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_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); pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_FILTER_NONE);
@ -2409,14 +2509,22 @@ EXPORT void HWRAPI(MakeScreenFinalTexture) (void)
#ifndef KOS_GL_COMPATIBILITY #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 #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) 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)
@ -2427,35 +2535,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

@ -478,10 +478,10 @@ static const struct {
{NULL, ARCH_NULL} {NULL, ARCH_NULL}
}; };
static UINT8 GetUserdataArchType(void) static UINT8 GetUserdataArchType(int index)
{ {
UINT8 i; UINT8 i;
lua_getmetatable(gL, -1); lua_getmetatable(gL, index);
for (i = 0; meta2arch[i].meta; i++) for (i = 0; meta2arch[i].meta; i++)
{ {
@ -560,7 +560,7 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
break; break;
} }
case LUA_TUSERDATA: case LUA_TUSERDATA:
switch (GetUserdataArchType()) switch (GetUserdataArchType(myindex))
{ {
case ARCH_MOBJINFO: 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)); 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); 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) 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__ #endif //__USE_C_FIXEDMUL__

View file

@ -6295,6 +6295,13 @@ static void M_DrawConnectIPMenu(void)
static void M_ConnectIP(INT32 choice) static void M_ConnectIP(INT32 choice)
{ {
(void)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)); COM_BufAddText(va("connect \"%s\"\n", setupm_ip));
// A little "please wait" message. // A little "please wait" message.
@ -6536,7 +6543,7 @@ static void M_HandleSetupMultiPlayer(INT32 choice)
if (choice < 32 || choice > 127 || itemOn != 0) if (choice < 32 || choice > 127 || itemOn != 0)
break; break;
l = strlen(setupm_name); l = strlen(setupm_name);
if (l < MAXPLAYERNAME-1) if (l < MAXPLAYERNAME)
{ {
S_StartSound(NULL,sfx_menu1); // Tails S_StartSound(NULL,sfx_menu1); // Tails
setupm_name[l] =(char)choice; 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) static void M_PNGText(png_structp png_ptr, png_infop png_info_ptr, PNG_CONST png_byte movie)
{ {
#ifdef PNG_TEXT_SUPPORTED #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]; png_text png_infotext[SRB2PNGTXT];
char keytxt[SRB2PNGTXT][12] = { char keytxt[SRB2PNGTXT][12] = {
"Title", "Author", "Description", "Playername", "Mapnum", "Mapname", "Title", "Description", "Playername", "Mapnum", "Mapname",
"Location", "Interface", "Revision", "Build Date", "Build Time"}; "Location", "Interface", "Revision", "Build Date", "Build Time"};
char titletxt[] = "Sonic Robo Blast 2 " VERSIONSTRING; char titletxt[] = "Sonic Robo Blast 2 " VERSIONSTRING;
png_charp authortxt = I_GetUserName();
png_charp playertxt = cv_playername.zstring; png_charp playertxt = cv_playername.zstring;
char desctxt[] = "SRB2 Screenshot"; char desctxt[] = "SRB2 Screenshot";
char Movietxt[] = "SRB2 Movie"; 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[i].key = keytxt[i];
png_infotext[0].text = titletxt; png_infotext[0].text = titletxt;
png_infotext[1].text = authortxt;
if (movie) if (movie)
png_infotext[2].text = Movietxt; png_infotext[1].text = Movietxt;
else else
png_infotext[2].text = desctxt; png_infotext[1].text = desctxt;
png_infotext[3].text = playertxt; png_infotext[2].text = playertxt;
png_infotext[4].text = maptext; png_infotext[3].text = maptext;
png_infotext[5].text = lvlttltext; png_infotext[4].text = lvlttltext;
png_infotext[6].text = locationtxt; png_infotext[5].text = locationtxt;
png_infotext[7].text = interfacetxt; png_infotext[6].text = interfacetxt;
png_infotext[8].text = strncpy(ctrevision, comprevision, sizeof(ctrevision)-1); png_infotext[7].text = strncpy(ctrevision, comprevision, sizeof(ctrevision)-1);
png_infotext[9].text = strncpy(ctdate, compdate, sizeof(ctdate)-1); png_infotext[8].text = strncpy(ctdate, compdate, sizeof(ctdate)-1);
png_infotext[10].text = strncpy(cttime, comptime, sizeof(cttime)-1); png_infotext[9].text = strncpy(cttime, comptime, sizeof(cttime)-1);
png_set_text(png_ptr, png_info_ptr, png_infotext, SRB2PNGTXT); png_set_text(png_ptr, png_info_ptr, png_infotext, SRB2PNGTXT);
#undef SRB2PNGTXT #undef SRB2PNGTXT

View file

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

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

@ -2709,7 +2709,7 @@ const char *I_LocateWad(void)
return waddir; return waddir;
} }
#if defined(LINUX) || defined(LINUX64) #ifdef __linux__
#define MEMINFO_FILE "/proc/meminfo" #define MEMINFO_FILE "/proc/meminfo"
#define MEMTOTAL "MemTotal:" #define MEMTOTAL "MemTotal:"
#define MEMFREE "MemFree:" #define MEMFREE "MemFree:"
@ -2729,12 +2729,14 @@ UINT32 I_GetFreeMem(UINT32 *total)
}; };
if ((kd = kvm_open(NULL, NULL, NULL, O_RDONLY, "kvm_open")) == NULL) if ((kd = kvm_open(NULL, NULL, NULL, O_RDONLY, "kvm_open")) == NULL)
{ {
if (total)
*total = 0L; *total = 0L;
return 0; return 0;
} }
if (kvm_nlist(kd, namelist) != 0) if (kvm_nlist(kd, namelist) != 0)
{ {
kvm_close (kd); kvm_close (kd);
if (total)
*total = 0L; *total = 0L;
return 0; return 0;
} }
@ -2742,6 +2744,7 @@ UINT32 I_GetFreeMem(UINT32 *total)
sizeof (sum)) != sizeof (sum)) sizeof (sum)) != sizeof (sum))
{ {
kvm_close(kd); kvm_close(kd);
if (total)
*total = 0L; *total = 0L;
return 0; return 0;
} }
@ -2773,7 +2776,7 @@ UINT32 I_GetFreeMem(UINT32 *total)
(PVOID) &pr_arena, sizeof (UINT32)); (PVOID) &pr_arena, sizeof (UINT32));
return pr_arena; return pr_arena;
#elif defined (LINUX) || defined (LINUX64) #elif defined (__linux__)
/* Linux */ /* Linux */
char buf[1024]; char buf[1024];
char *memTag; char *memTag;
@ -2789,14 +2792,16 @@ UINT32 I_GetFreeMem(UINT32 *total)
if (n < 0) if (n < 0)
{ {
// Error // Error
if (total)
*total = 0L; *total = 0L;
return 0; return 0;
} }
buf[n] = '\0'; buf[n] = '\0';
if (NULL == (memTag = strstr(buf, MEMTOTAL))) if ((memTag = strstr(buf, MEMTOTAL)) == NULL)
{ {
// Error // Error
if (total)
*total = 0L; *total = 0L;
return 0; return 0;
} }
@ -2804,9 +2809,10 @@ UINT32 I_GetFreeMem(UINT32 *total)
memTag += sizeof (MEMTOTAL); memTag += sizeof (MEMTOTAL);
totalKBytes = atoi(memTag); totalKBytes = atoi(memTag);
if (NULL == (memTag = strstr(buf, MEMFREE))) if ((memTag = strstr(buf, MEMFREE)) == NULL)
{ {
// Error // Error
if (total)
*total = 0L; *total = 0L;
return 0; return 0;
} }
@ -2822,7 +2828,7 @@ UINT32 I_GetFreeMem(UINT32 *total)
if (total) if (total)
*total = 48<<20; *total = 48<<20;
return 48<<20; return 48<<20;
#endif /* LINUX */ #endif
} }
const CPUInfoFlags *I_CPUInfo(void) 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)); 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 /// \todo inputEvent.button.which
if (USE_MOUSEINPUT) if (USE_MOUSEINPUT)
{ {
@ -1442,6 +1450,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

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

View file

@ -100,6 +100,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

@ -1972,6 +1972,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

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