Merge branch 'gl-dropshadows' into oglshaderport

This commit is contained in:
Sally Cochenour 2020-01-16 14:55:55 -05:00
commit e5215e929c
30 changed files with 768 additions and 653 deletions

View File

@ -1457,15 +1457,8 @@ static void Got_NetVar(UINT8 **p, INT32 playernum)
{ {
// not from server or remote admin, must be hacked/buggy client // not from server or remote admin, must be hacked/buggy client
CONS_Alert(CONS_WARNING, M_GetText("Illegal netvar command received from %s\n"), player_names[playernum]); CONS_Alert(CONS_WARNING, M_GetText("Illegal netvar command received from %s\n"), player_names[playernum]);
if (server) if (server)
{ SendKick(playernum, KICK_MSG_CON_FAIL);
UINT8 buf[2];
buf[0] = (UINT8)playernum;
buf[1] = KICK_MSG_CON_FAIL;
SendNetXCmd(XD_KICK, &buf, 2);
}
return; return;
} }
netid = READUINT16(*p); netid = READUINT16(*p);

View File

@ -612,15 +612,6 @@ void CON_Ticker(void)
con_tick++; con_tick++;
con_tick &= 7; con_tick &= 7;
// if the menu is open then close the console.
if (menuactive && con_destlines)
{
consoletoggle = false;
con_destlines = 0;
CON_ClearHUD();
I_UpdateMouseGrab();
}
// console key was pushed // console key was pushed
if (consoletoggle) if (consoletoggle)
{ {
@ -777,7 +768,7 @@ boolean CON_Responder(event_t *ev)
// check for console toggle key // check for console toggle key
if (ev->type != ev_console) if (ev->type != ev_console)
{ {
if (modeattacking || metalrecording) if (modeattacking || metalrecording || menuactive)
return false; return false;
if (key == gamecontrol[gc_console][0] || key == gamecontrol[gc_console][1]) if (key == gamecontrol[gc_console][0] || key == gamecontrol[gc_console][1])
@ -792,7 +783,7 @@ boolean CON_Responder(event_t *ev)
// check other keys only if console prompt is active // check other keys only if console prompt is active
if (!consoleready && key < NUMINPUTS) // metzgermeister: boundary check!! if (!consoleready && key < NUMINPUTS) // metzgermeister: boundary check!!
{ {
if (bindtable[key]) if (! menuactive && bindtable[key])
{ {
COM_BufAddText(bindtable[key]); COM_BufAddText(bindtable[key]);
COM_BufAddText("\n"); COM_BufAddText("\n");
@ -1551,9 +1542,14 @@ static void CON_DrawConsole(void)
if (cons_backpic.value || con_forcepic) if (cons_backpic.value || con_forcepic)
{ {
patch_t *con_backpic = W_CachePatchName("CONSBACK", PU_PATCH); patch_t *con_backpic = W_CachePatchName("CONSBACK", PU_PATCH);
int h;
h = con_curlines/vid.dupy;
// Jimita: CON_DrawBackpic just called V_DrawScaledPatch // Jimita: CON_DrawBackpic just called V_DrawScaledPatch
V_DrawScaledPatch(0, 0, 0, con_backpic); //V_DrawScaledPatch(0, 0, 0, con_backpic);
V_DrawCroppedPatch(0, 0, FRACUNIT, 0, con_backpic,
0, ( BASEVIDHEIGHT - h ), BASEVIDWIDTH, h);
W_UnlockCachedPatch(con_backpic); W_UnlockCachedPatch(con_backpic);
} }

View File

@ -391,11 +391,7 @@ static void ExtraDataTicker(void)
{ {
if (server) if (server)
{ {
UINT8 buf[3]; SendKick(i, KICK_MSG_CON_FAIL);
buf[0] = (UINT8)i;
buf[1] = KICK_MSG_CON_FAIL;
SendNetXCmd(XD_KICK, &buf, 2);
DEBFILE(va("player %d kicked [gametic=%u] reason as follows:\n", i, gametic)); DEBFILE(va("player %d kicked [gametic=%u] reason as follows:\n", i, gametic));
} }
CONS_Alert(CONS_WARNING, M_GetText("Got unknown net command [%s]=%d (max %d)\n"), sizeu1(curpos - bufferstart), *curpos, bufferstart[0]); CONS_Alert(CONS_WARNING, M_GetText("Got unknown net command [%s]=%d (max %d)\n"), sizeu1(curpos - bufferstart), *curpos, bufferstart[0]);
@ -437,6 +433,15 @@ void D_ResetTiccmds(void)
D_Clearticcmd(textcmds[i]->tic); D_Clearticcmd(textcmds[i]->tic);
} }
void SendKick(UINT8 playernum, UINT8 msg)
{
UINT8 buf[2];
buf[0] = playernum;
buf[1] = msg;
SendNetXCmd(XD_KICK, &buf, 2);
}
// ----------------------------------------------------------------- // -----------------------------------------------------------------
// end of extra data function // end of extra data function
// ----------------------------------------------------------------- // -----------------------------------------------------------------
@ -1053,10 +1058,7 @@ static void SV_SendResynch(INT32 node)
if (resynch_score[node] > (unsigned)cv_resynchattempts.value*250) if (resynch_score[node] > (unsigned)cv_resynchattempts.value*250)
{ {
UINT8 buf[2]; SendKick(nodetoplayer[node], KICK_MSG_CON_FAIL);
buf[0] = (UINT8)nodetoplayer[node];
buf[1] = KICK_MSG_CON_FAIL;
SendNetXCmd(XD_KICK, &buf, 2);
resynch_score[node] = 0; resynch_score[node] = 0;
} }
} }
@ -1346,11 +1348,11 @@ static void SV_SendPlayerInfo(INT32 node)
{ {
if (!playeringame[i]) if (!playeringame[i])
{ {
netbuffer->u.playerinfo[i].node = 255; // This slot is empty. netbuffer->u.playerinfo[i].num = 255; // This slot is empty.
continue; continue;
} }
netbuffer->u.playerinfo[i].node = i; netbuffer->u.playerinfo[i].num = i;
strncpy(netbuffer->u.playerinfo[i].name, (const char *)&player_names[i], MAXPLAYERNAME+1); strncpy(netbuffer->u.playerinfo[i].name, (const char *)&player_names[i], MAXPLAYERNAME+1);
netbuffer->u.playerinfo[i].name[MAXPLAYERNAME] = '\0'; netbuffer->u.playerinfo[i].name[MAXPLAYERNAME] = '\0';
@ -3216,13 +3218,7 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum)
// protect against hacked/buggy client // protect against hacked/buggy client
CONS_Alert(CONS_WARNING, M_GetText("Illegal add player command received from %s\n"), player_names[playernum]); CONS_Alert(CONS_WARNING, M_GetText("Illegal add player command received from %s\n"), player_names[playernum]);
if (server) if (server)
{ SendKick(playernum, KICK_MSG_CON_FAIL);
UINT8 buf[2];
buf[0] = (UINT8)playernum;
buf[1] = KICK_MSG_CON_FAIL;
SendNetXCmd(XD_KICK, &buf, 2);
}
return; return;
} }
@ -3405,14 +3401,10 @@ void CL_AddSplitscreenPlayer(void)
void CL_RemoveSplitscreenPlayer(void) void CL_RemoveSplitscreenPlayer(void)
{ {
UINT8 buf[2];
if (cl_mode != CL_CONNECTED) if (cl_mode != CL_CONNECTED)
return; return;
buf[0] = (UINT8)secondarydisplayplayer; SendKick(secondarydisplayplayer, KICK_MSG_PLAYER_QUIT);
buf[1] = KICK_MSG_PLAYER_QUIT;
SendNetXCmd(XD_KICK, &buf, 2);
} }
// is there a game running // is there a game running
@ -3951,13 +3943,10 @@ static void HandlePacketFromPlayer(SINT8 node)
if (netcmds[maketic%BACKUPTICS][netconsole].forwardmove > MAXPLMOVE || netcmds[maketic%BACKUPTICS][netconsole].forwardmove < -MAXPLMOVE if (netcmds[maketic%BACKUPTICS][netconsole].forwardmove > MAXPLMOVE || netcmds[maketic%BACKUPTICS][netconsole].forwardmove < -MAXPLMOVE
|| netcmds[maketic%BACKUPTICS][netconsole].sidemove > MAXPLMOVE || netcmds[maketic%BACKUPTICS][netconsole].sidemove < -MAXPLMOVE) || netcmds[maketic%BACKUPTICS][netconsole].sidemove > MAXPLMOVE || netcmds[maketic%BACKUPTICS][netconsole].sidemove < -MAXPLMOVE)
{ {
char buf[2];
CONS_Alert(CONS_WARNING, M_GetText("Illegal movement value received from node %d\n"), netconsole); CONS_Alert(CONS_WARNING, M_GetText("Illegal movement value received from node %d\n"), netconsole);
//D_Clearticcmd(k); //D_Clearticcmd(k);
buf[0] = (char)netconsole; SendKick(netconsole, KICK_MSG_CON_FAIL);
buf[1] = KICK_MSG_CON_FAIL;
SendNetXCmd(XD_KICK, &buf, 2);
break; break;
} }
@ -3994,11 +3983,7 @@ static void HandlePacketFromPlayer(SINT8 node)
} }
else else
{ {
UINT8 buf[3]; SendKick(netconsole, KICK_MSG_CON_FAIL);
buf[0] = (UINT8)netconsole;
buf[1] = KICK_MSG_CON_FAIL;
SendNetXCmd(XD_KICK, &buf, 2);
DEBFILE(va("player %d kicked (synch failure) [%u] %d!=%d\n", DEBFILE(va("player %d kicked (synch failure) [%u] %d!=%d\n",
netconsole, realstart, consistancy[realstart%BACKUPTICS], netconsole, realstart, consistancy[realstart%BACKUPTICS],
SHORT(netbuffer->u.clientpak.consistancy))); SHORT(netbuffer->u.clientpak.consistancy)));
@ -4111,19 +4096,20 @@ static void HandlePacketFromPlayer(SINT8 node)
nodewaiting[node] = 0; nodewaiting[node] = 0;
if (netconsole != -1 && playeringame[netconsole]) if (netconsole != -1 && playeringame[netconsole])
{ {
UINT8 buf[2]; UINT8 kickmsg;
buf[0] = (UINT8)netconsole;
if (netbuffer->packettype == PT_NODETIMEOUT) if (netbuffer->packettype == PT_NODETIMEOUT)
buf[1] = KICK_MSG_TIMEOUT; kickmsg = KICK_MSG_TIMEOUT;
else else
buf[1] = KICK_MSG_PLAYER_QUIT; kickmsg = KICK_MSG_PLAYER_QUIT;
SendNetXCmd(XD_KICK, &buf, 2);
SendKick(netconsole, kickmsg);
nodetoplayer[node] = -1; nodetoplayer[node] = -1;
if (nodetoplayer2[node] != -1 && nodetoplayer2[node] >= 0 if (nodetoplayer2[node] != -1 && nodetoplayer2[node] >= 0
&& playeringame[(UINT8)nodetoplayer2[node]]) && playeringame[(UINT8)nodetoplayer2[node]])
{ {
buf[0] = nodetoplayer2[node]; SendKick(nodetoplayer2[node], kickmsg);
SendNetXCmd(XD_KICK, &buf, 2);
nodetoplayer2[node] = -1; nodetoplayer2[node] = -1;
} }
} }
@ -4136,15 +4122,8 @@ static void HandlePacketFromPlayer(SINT8 node)
if (node != servernode) if (node != servernode)
{ {
CONS_Alert(CONS_WARNING, M_GetText("%s received from non-host %d\n"), "PT_RESYNCHEND", node); CONS_Alert(CONS_WARNING, M_GetText("%s received from non-host %d\n"), "PT_RESYNCHEND", node);
if (server) if (server)
{ SendKick(netconsole, KICK_MSG_CON_FAIL);
UINT8 buf[2];
buf[0] = (UINT8)node;
buf[1] = KICK_MSG_CON_FAIL;
SendNetXCmd(XD_KICK, &buf, 2);
}
break; break;
} }
resynch_local_inprogress = false; resynch_local_inprogress = false;
@ -4161,15 +4140,8 @@ static void HandlePacketFromPlayer(SINT8 node)
if (node != servernode) if (node != servernode)
{ {
CONS_Alert(CONS_WARNING, M_GetText("%s received from non-host %d\n"), "PT_SERVERTICS", node); CONS_Alert(CONS_WARNING, M_GetText("%s received from non-host %d\n"), "PT_SERVERTICS", node);
if (server) if (server)
{ SendKick(netconsole, KICK_MSG_CON_FAIL);
UINT8 buf[2];
buf[0] = (UINT8)node;
buf[1] = KICK_MSG_CON_FAIL;
SendNetXCmd(XD_KICK, &buf, 2);
}
break; break;
} }
@ -4228,15 +4200,8 @@ static void HandlePacketFromPlayer(SINT8 node)
if (node != servernode) if (node != servernode)
{ {
CONS_Alert(CONS_WARNING, M_GetText("%s received from non-host %d\n"), "PT_RESYNCHING", node); CONS_Alert(CONS_WARNING, M_GetText("%s received from non-host %d\n"), "PT_RESYNCHING", node);
if (server) if (server)
{ SendKick(netconsole, KICK_MSG_CON_FAIL);
char buf[2];
buf[0] = (char)node;
buf[1] = KICK_MSG_CON_FAIL;
SendNetXCmd(XD_KICK, &buf, 2);
}
break; break;
} }
resynch_local_inprogress = true; resynch_local_inprogress = true;
@ -4247,15 +4212,8 @@ static void HandlePacketFromPlayer(SINT8 node)
if (node != servernode) if (node != servernode)
{ {
CONS_Alert(CONS_WARNING, M_GetText("%s received from non-host %d\n"), "PT_PING", node); CONS_Alert(CONS_WARNING, M_GetText("%s received from non-host %d\n"), "PT_PING", node);
if (server) if (server)
{ SendKick(netconsole, KICK_MSG_CON_FAIL);
char buf[2];
buf[0] = (char)node;
buf[1] = KICK_MSG_CON_FAIL;
SendNetXCmd(XD_KICK, &buf, 2);
}
break; break;
} }
@ -4278,15 +4236,8 @@ static void HandlePacketFromPlayer(SINT8 node)
if (node != servernode) if (node != servernode)
{ {
CONS_Alert(CONS_WARNING, M_GetText("%s received from non-host %d\n"), "PT_FILEFRAGMENT", node); CONS_Alert(CONS_WARNING, M_GetText("%s received from non-host %d\n"), "PT_FILEFRAGMENT", node);
if (server) if (server)
{ SendKick(netconsole, KICK_MSG_CON_FAIL);
UINT8 buf[2];
buf[0] = (UINT8)node;
buf[1] = KICK_MSG_CON_FAIL;
SendNetXCmd(XD_KICK, &buf, 2);
}
break; break;
} }
if (client) if (client)
@ -4833,13 +4784,8 @@ static inline void PingUpdate(void)
if (pingtimeout[i] > cv_pingtimeout.value) if (pingtimeout[i] > cv_pingtimeout.value)
// ok your net has been bad for too long, you deserve to die. // ok your net has been bad for too long, you deserve to die.
{ {
char buf[2];
pingtimeout[i] = 0; pingtimeout[i] = 0;
SendKick(i, KICK_MSG_PING_HIGH);
buf[0] = (char)i;
buf[1] = KICK_MSG_PING_HIGH;
SendNetXCmd(XD_KICK, &buf, 2);
} }
} }
/* /*

View File

@ -27,7 +27,7 @@ This version is independent of the mod name, and standard
version and subversion. It should only account for the version and subversion. It should only account for the
basic fields of the packet, and change infrequently. basic fields of the packet, and change infrequently.
*/ */
#define PACKETVERSION 1 #define PACKETVERSION 2
// Network play related stuff. // Network play related stuff.
// There is a data struct that stores network // There is a data struct that stores network
@ -366,7 +366,6 @@ typedef struct
UINT8 cheatsenabled; UINT8 cheatsenabled;
UINT8 isdedicated; UINT8 isdedicated;
UINT8 fileneedednum; UINT8 fileneedednum;
SINT8 adminplayer;
tic_t time; tic_t time;
tic_t leveltime; tic_t leveltime;
char servername[MAXSERVERNAME]; char servername[MAXSERVERNAME];
@ -398,7 +397,7 @@ typedef struct
// Shorter player information for external use. // Shorter player information for external use.
typedef struct typedef struct
{ {
UINT8 node; UINT8 num;
char name[MAXPLAYERNAME+1]; char name[MAXPLAYERNAME+1];
UINT8 address[4]; // sending another string would run us up against MAXPACKETLENGTH UINT8 address[4]; // sending another string would run us up against MAXPACKETLENGTH
UINT8 team; UINT8 team;
@ -523,6 +522,7 @@ void D_ClientServerInit(void);
void RegisterNetXCmd(netxcmd_t id, void (*cmd_f)(UINT8 **p, INT32 playernum)); void RegisterNetXCmd(netxcmd_t id, void (*cmd_f)(UINT8 **p, INT32 playernum));
void SendNetXCmd(netxcmd_t id, const void *param, size_t nparam); void SendNetXCmd(netxcmd_t id, const void *param, size_t nparam);
void SendNetXCmd2(netxcmd_t id, const void *param, size_t nparam); // splitsreen player void SendNetXCmd2(netxcmd_t id, const void *param, size_t nparam); // splitsreen player
void SendKick(UINT8 playernum, UINT8 msg);
// Create any new ticcmds and broadcast to other players. // Create any new ticcmds and broadcast to other players.
void NetUpdate(void); void NetUpdate(void);

View File

@ -188,14 +188,14 @@ void D_ProcessEvents(void)
continue; continue;
} }
// Menu input
if (M_Responder(ev))
continue; // menu ate the event
// console input // console input
if (CON_Responder(ev)) if (CON_Responder(ev))
continue; // ate the event continue; // ate the event
// Menu input
if (M_Responder(ev))
continue; // menu ate the event
G_Responder(ev); G_Responder(ev);
} }
} }
@ -502,13 +502,12 @@ static void D_Display(void)
// vid size change is now finished if it was on... // vid size change is now finished if it was on...
vid.recalc = 0; vid.recalc = 0;
// FIXME: draw either console or menu, not the two
if (gamestate != GS_TIMEATTACK)
CON_Drawer();
M_Drawer(); // menu is drawn even on top of everything M_Drawer(); // menu is drawn even on top of everything
// focus lost moved to M_Drawer // focus lost moved to M_Drawer
if (gamestate != GS_TIMEATTACK)
CON_Drawer();
// //
// wipe update // wipe update
// //

View File

@ -1124,13 +1124,7 @@ static void SetPlayerName(INT32 playernum, char *newname)
{ {
CONS_Printf(M_GetText("Player %d sent a bad name change\n"), playernum+1); CONS_Printf(M_GetText("Player %d sent a bad name change\n"), playernum+1);
if (server && netgame) if (server && netgame)
{ SendKick(playernum, KICK_MSG_CON_FAIL);
UINT8 buf[2];
buf[0] = (UINT8)playernum;
buf[1] = KICK_MSG_CON_FAIL;
SendNetXCmd(XD_KICK, &buf, 2);
}
} }
} }
@ -1487,12 +1481,8 @@ static void Got_NameAndColor(UINT8 **cp, INT32 playernum)
if (kick) if (kick)
{ {
UINT8 buf[2];
CONS_Alert(CONS_WARNING, M_GetText("Illegal color change received from %s (team: %d), color: %d)\n"), player_names[playernum], p->ctfteam, p->skincolor); CONS_Alert(CONS_WARNING, M_GetText("Illegal color change received from %s (team: %d), color: %d)\n"), player_names[playernum], p->ctfteam, p->skincolor);
SendKick(playernum, KICK_MSG_CON_FAIL);
buf[0] = (UINT8)playernum;
buf[1] = KICK_MSG_CON_FAIL;
SendNetXCmd(XD_KICK, &buf, 2);
return; return;
} }
} }
@ -2032,13 +2022,7 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum)
{ {
CONS_Alert(CONS_WARNING, M_GetText("Illegal map change received from %s\n"), player_names[playernum]); CONS_Alert(CONS_WARNING, M_GetText("Illegal map change received from %s\n"), player_names[playernum]);
if (server) if (server)
{ SendKick(playernum, KICK_MSG_CON_FAIL);
UINT8 buf[2];
buf[0] = (UINT8)playernum;
buf[1] = KICK_MSG_CON_FAIL;
SendNetXCmd(XD_KICK, &buf, 2);
}
return; return;
} }
@ -2149,13 +2133,7 @@ static void Got_Pause(UINT8 **cp, INT32 playernum)
{ {
CONS_Alert(CONS_WARNING, M_GetText("Illegal pause command received from %s\n"), player_names[playernum]); CONS_Alert(CONS_WARNING, M_GetText("Illegal pause command received from %s\n"), player_names[playernum]);
if (server) if (server)
{ SendKick(playernum, KICK_MSG_CON_FAIL);
UINT8 buf[2];
buf[0] = (UINT8)playernum;
buf[1] = KICK_MSG_CON_FAIL;
SendNetXCmd(XD_KICK, &buf, 2);
}
return; return;
} }
@ -2230,13 +2208,7 @@ static void Got_Suicide(UINT8 **cp, INT32 playernum)
{ {
CONS_Alert(CONS_WARNING, M_GetText("Illegal suicide command received from %s\n"), player_names[playernum]); CONS_Alert(CONS_WARNING, M_GetText("Illegal suicide command received from %s\n"), player_names[playernum]);
if (server) if (server)
{ SendKick(playernum, KICK_MSG_CON_FAIL);
UINT8 buf[2];
buf[0] = (UINT8)playernum;
buf[1] = KICK_MSG_CON_FAIL;
SendNetXCmd(XD_KICK, &buf, 2);
}
return; return;
} }
@ -2299,13 +2271,7 @@ static void Got_Clearscores(UINT8 **cp, INT32 playernum)
{ {
CONS_Alert(CONS_WARNING, M_GetText("Illegal clear scores command received from %s\n"), player_names[playernum]); CONS_Alert(CONS_WARNING, M_GetText("Illegal clear scores command received from %s\n"), player_names[playernum]);
if (server) if (server)
{ SendKick(playernum, KICK_MSG_CON_FAIL);
UINT8 buf[2];
buf[0] = (UINT8)playernum;
buf[1] = KICK_MSG_CON_FAIL;
SendNetXCmd(XD_KICK, &buf, 2);
}
return; return;
} }
@ -2652,13 +2618,7 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum)
// this should never happen unless the client is hacked/buggy // this should never happen unless the client is hacked/buggy
CONS_Alert(CONS_WARNING, M_GetText("Illegal team change received from player %s\n"), player_names[playernum]); CONS_Alert(CONS_WARNING, M_GetText("Illegal team change received from player %s\n"), player_names[playernum]);
if (server) if (server)
{ SendKick(playernum, KICK_MSG_CON_FAIL);
UINT8 buf[2];
buf[0] = (UINT8)playernum;
buf[1] = KICK_MSG_CON_FAIL;
SendNetXCmd(XD_KICK, &buf, 2);
}
} }
if (NetPacket.packet.verification) // Special marker that the server sent the request if (NetPacket.packet.verification) // Special marker that the server sent the request
@ -2667,13 +2627,7 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum)
{ {
CONS_Alert(CONS_WARNING, M_GetText("Illegal team change received from player %s\n"), player_names[playernum]); CONS_Alert(CONS_WARNING, M_GetText("Illegal team change received from player %s\n"), player_names[playernum]);
if (server) if (server)
{ SendKick(playernum, KICK_MSG_CON_FAIL);
UINT8 buf[2];
buf[0] = (UINT8)playernum;
buf[1] = KICK_MSG_CON_FAIL;
SendNetXCmd(XD_KICK, &buf, 2);
}
return; return;
} }
playernum = NetPacket.packet.playernum; playernum = NetPacket.packet.playernum;
@ -2706,13 +2660,7 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum)
{ {
CONS_Alert(CONS_WARNING, M_GetText("Illegal team change received from player %s\n"), player_names[playernum]); CONS_Alert(CONS_WARNING, M_GetText("Illegal team change received from player %s\n"), player_names[playernum]);
if (server) if (server)
{ SendKick(playernum, KICK_MSG_CON_FAIL);
UINT8 buf[2];
buf[0] = (UINT8)playernum;
buf[1] = KICK_MSG_CON_FAIL;
SendNetXCmd(XD_KICK, &buf, 2);
}
} }
return; return;
} }
@ -2770,12 +2718,8 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum)
if (server && ((NetPacket.packet.newteam < 0 || NetPacket.packet.newteam > 3) || error)) if (server && ((NetPacket.packet.newteam < 0 || NetPacket.packet.newteam > 3) || error))
{ {
UINT8 buf[2];
buf[0] = (UINT8)playernum;
buf[1] = KICK_MSG_CON_FAIL;
CONS_Alert(CONS_WARNING, M_GetText("Illegal team change received from player %s\n"), player_names[playernum]); CONS_Alert(CONS_WARNING, M_GetText("Illegal team change received from player %s\n"), player_names[playernum]);
SendNetXCmd(XD_KICK, &buf, 2); SendKick(playernum, KICK_MSG_CON_FAIL);
} }
//Safety first! //Safety first!
@ -3067,13 +3011,7 @@ static void Got_Verification(UINT8 **cp, INT32 playernum)
{ {
CONS_Alert(CONS_WARNING, M_GetText("Illegal verification received from %s (serverplayer is %s)\n"), player_names[playernum], player_names[serverplayer]); CONS_Alert(CONS_WARNING, M_GetText("Illegal verification received from %s (serverplayer is %s)\n"), player_names[playernum], player_names[serverplayer]);
if (server) if (server)
{ SendKick(playernum, KICK_MSG_CON_FAIL);
UINT8 buf[2];
buf[0] = (UINT8)playernum;
buf[1] = KICK_MSG_CON_FAIL;
SendNetXCmd(XD_KICK, &buf, 2);
}
return; return;
} }
@ -3123,13 +3061,7 @@ static void Got_Removal(UINT8 **cp, INT32 playernum)
{ {
CONS_Alert(CONS_WARNING, M_GetText("Illegal demotion received from %s (serverplayer is %s)\n"), player_names[playernum], player_names[serverplayer]); CONS_Alert(CONS_WARNING, M_GetText("Illegal demotion received from %s (serverplayer is %s)\n"), player_names[playernum], player_names[serverplayer]);
if (server) if (server)
{ SendKick(playernum, KICK_MSG_CON_FAIL);
UINT8 buf[2];
buf[0] = (UINT8)playernum;
buf[1] = KICK_MSG_CON_FAIL;
SendNetXCmd(XD_KICK, &buf, 2);
}
return; return;
} }
@ -3203,14 +3135,7 @@ static void Got_MotD_f(UINT8 **cp, INT32 playernum)
{ {
CONS_Alert(CONS_WARNING, M_GetText("Illegal motd change received from %s\n"), player_names[playernum]); CONS_Alert(CONS_WARNING, M_GetText("Illegal motd change received from %s\n"), player_names[playernum]);
if (server) if (server)
{ SendKick(playernum, KICK_MSG_CON_FAIL);
UINT8 buf[2];
buf[0] = (UINT8)playernum;
buf[1] = KICK_MSG_CON_FAIL;
SendNetXCmd(XD_KICK, &buf, 2);
}
Z_Free(mymotd); Z_Free(mymotd);
return; return;
} }
@ -3266,13 +3191,7 @@ static void Got_RunSOCcmd(UINT8 **cp, INT32 playernum)
{ {
CONS_Alert(CONS_WARNING, M_GetText("Illegal runsoc command received from %s\n"), player_names[playernum]); CONS_Alert(CONS_WARNING, M_GetText("Illegal runsoc command received from %s\n"), player_names[playernum]);
if (server) if (server)
{ SendKick(playernum, KICK_MSG_CON_FAIL);
UINT8 buf[2];
buf[0] = (UINT8)playernum;
buf[1] = KICK_MSG_CON_FAIL;
SendNetXCmd(XD_KICK, &buf, 2);
}
return; return;
} }
@ -3429,13 +3348,8 @@ static void Got_RequestAddfilecmd(UINT8 **cp, INT32 playernum)
if ((playernum != serverplayer && !IsPlayerAdmin(playernum)) || kick) if ((playernum != serverplayer && !IsPlayerAdmin(playernum)) || kick)
{ {
UINT8 buf[2];
CONS_Alert(CONS_WARNING, M_GetText("Illegal addfile command received from %s\n"), player_names[playernum]); CONS_Alert(CONS_WARNING, M_GetText("Illegal addfile command received from %s\n"), player_names[playernum]);
SendKick(playernum, KICK_MSG_CON_FAIL);
buf[0] = (UINT8)playernum;
buf[1] = KICK_MSG_CON_FAIL;
SendNetXCmd(XD_KICK, &buf, 2);
return; return;
} }
@ -3484,13 +3398,7 @@ static void Got_Addfilecmd(UINT8 **cp, INT32 playernum)
{ {
CONS_Alert(CONS_WARNING, M_GetText("Illegal addfile command received from %s\n"), player_names[playernum]); CONS_Alert(CONS_WARNING, M_GetText("Illegal addfile command received from %s\n"), player_names[playernum]);
if (server) if (server)
{ SendKick(playernum, KICK_MSG_CON_FAIL);
UINT8 buf[2];
buf[0] = (UINT8)playernum;
buf[1] = KICK_MSG_CON_FAIL;
SendNetXCmd(XD_KICK, &buf, 2);
}
return; return;
} }
@ -4283,13 +4191,7 @@ static void Got_ExitLevelcmd(UINT8 **cp, INT32 playernum)
{ {
CONS_Alert(CONS_WARNING, M_GetText("Illegal exitlevel command received from %s\n"), player_names[playernum]); CONS_Alert(CONS_WARNING, M_GetText("Illegal exitlevel command received from %s\n"), player_names[playernum]);
if (server) if (server)
{ SendKick(playernum, KICK_MSG_CON_FAIL);
UINT8 buf[2];
buf[0] = (UINT8)playernum;
buf[1] = KICK_MSG_CON_FAIL;
SendNetXCmd(XD_KICK, &buf, 2);
}
return; return;
} }

View File

@ -72,6 +72,7 @@
#include "../v_video.h" #include "../v_video.h"
#include "hw_clip.h" #include "hw_clip.h"
#include "hw_glob.h" #include "hw_glob.h"
#include "../r_main.h"
#include "../r_state.h" #include "../r_state.h"
#include "../tables.h" #include "../tables.h"
#include "r_opengl/r_opengl.h" #include "r_opengl/r_opengl.h"
@ -328,7 +329,7 @@ angle_t gld_FrustumAngle(angle_t tiltangle)
// NEWCLIP TODO: SRB2CBTODO: make a global render_fov for this function // NEWCLIP TODO: SRB2CBTODO: make a global render_fov for this function
float render_fov = FIXED_TO_FLOAT(cv_grfov.value); float render_fov = FIXED_TO_FLOAT(cv_fov.value);
float render_fovratio = (float)BASEVIDWIDTH / (float)BASEVIDHEIGHT; // SRB2CBTODO: NEWCLIPTODO: Is this right? float render_fovratio = (float)BASEVIDWIDTH / (float)BASEVIDHEIGHT; // SRB2CBTODO: NEWCLIPTODO: Is this right?
float render_multiplier = 64.0f / render_fovratio / RMUL; float render_multiplier = 64.0f / render_fovratio / RMUL;

View File

@ -41,6 +41,7 @@
#include "../i_system.h" #include "../i_system.h"
#include "../m_cheat.h" #include "../m_cheat.h"
#include "../f_finale.h" #include "../f_finale.h"
#include "../r_things.h" // R_GetShadowZ
#ifdef ESLOPE #ifdef ESLOPE
#include "../p_slopes.h" #include "../p_slopes.h"
#endif #endif
@ -3661,39 +3662,6 @@ static gr_vissprite_t *HWR_NewVisSprite(void)
return HWR_GetVisSprite(gr_visspritecount++); return HWR_GetVisSprite(gr_visspritecount++);
} }
#ifdef GLBADSHADOWS
// Finds a floor through which light does not pass.
static fixed_t HWR_OpaqueFloorAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height)
{
const sector_t *sec = R_PointInSubsector(x, y)->sector;
fixed_t floorz = sec->floorheight;
if (sec->ffloors)
{
ffloor_t *rover;
fixed_t delta1, delta2;
const fixed_t thingtop = z + height;
for (rover = sec->ffloors; rover; rover = rover->next)
{
if (!(rover->flags & FF_EXISTS)
|| !(rover->flags & FF_RENDERPLANES)
|| rover->flags & FF_TRANSLUCENT
|| rover->flags & FF_FOG
|| rover->flags & FF_INVERTPLANES)
continue;
delta1 = z - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2));
delta2 = thingtop - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2));
if (*rover->topheight > floorz && abs(delta1) < abs(delta2))
floorz = *rover->topheight;
}
}
return floorz;
}
#endif //#ifdef GLBADSHADOWS
// //
// HWR_DoCulling // HWR_DoCulling
// Hardware version of R_DoCulling // Hardware version of R_DoCulling
@ -3734,181 +3702,120 @@ static boolean HWR_DoCulling(line_t *cullheight, line_t *viewcullheight, float v
return false; return false;
} }
#ifdef GLBADSHADOWS static void HWR_DrawDropShadow(mobj_t *thing, gr_vissprite_t *spr, fixed_t scale)
static void HWR_DrawSpriteShadow(gr_vissprite_t *spr, GLPatch_t *gpatch, float this_scale)
{ {
FOutVector swallVerts[4]; GLPatch_t *gpatch;
FOutVector shadowVerts[4];
FSurfaceInfo sSurf; FSurfaceInfo sSurf;
fixed_t floorheight, mobjfloor; float fscale; float fx; float fy; float offset;
float offset = 0; UINT8 lightlevel = 255;
extracolormap_t *colormap = NULL;
UINT8 i;
mobjfloor = HWR_OpaqueFloorAtPos( INT32 light;
spr->mobj->x, spr->mobj->y, fixed_t scalemul;
spr->mobj->z, spr->mobj->height); UINT16 alpha;
if (cv_shadowoffs.value) fixed_t floordiff;
{ fixed_t floorz;
angle_t shadowdir; fixed_t slopez;
pslope_t *floorslope;
// Set direction floorz = R_GetShadowZ(thing, &floorslope);
if (splitscreen && stplyr == &players[secondarydisplayplayer])
shadowdir = localangle2 + FixedAngle(cv_cam2_rotate.value);
else
shadowdir = localangle + FixedAngle(cv_cam_rotate.value);
// Find floorheight //if (abs(floorz - gr_viewz) / tz > 4) return; // Prevent stretchy shadows and possible crashes
floorheight = HWR_OpaqueFloorAtPos(
spr->mobj->x + P_ReturnThrustX(spr->mobj, shadowdir, spr->mobj->z - mobjfloor),
spr->mobj->y + P_ReturnThrustY(spr->mobj, shadowdir, spr->mobj->z - mobjfloor),
spr->mobj->z, spr->mobj->height);
// The shadow is falling ABOVE it's mobj? floordiff = abs(thing->z - floorz);
// Don't draw it, then!
if (spr->mobj->z < floorheight)
return;
else
{
fixed_t floorz;
floorz = HWR_OpaqueFloorAtPos(
spr->mobj->x + P_ReturnThrustX(spr->mobj, shadowdir, spr->mobj->z - floorheight),
spr->mobj->y + P_ReturnThrustY(spr->mobj, shadowdir, spr->mobj->z - floorheight),
spr->mobj->z, spr->mobj->height);
// The shadow would be falling on a wall? Don't draw it, then.
// Would draw midair otherwise.
if (floorz < floorheight)
return;
}
floorheight = FixedInt(spr->mobj->z - floorheight); alpha = floordiff / (4*FRACUNIT) + 75;
if (alpha >= 255) return;
alpha = 255 - alpha;
offset = floorheight; gpatch = (GLPatch_t *)W_CachePatchName("DSHADOW", PU_CACHE);
} if (!(gpatch && gpatch->mipmap->grInfo.format)) return;
else HWR_GetPatch(gpatch);
floorheight = FixedInt(spr->mobj->z - mobjfloor);
scalemul = FixedMul(FRACUNIT - floordiff/640, scale);
scalemul = FixedMul(scalemul, (thing->radius*2) / gpatch->height);
fscale = FIXED_TO_FLOAT(scalemul);
fx = FIXED_TO_FLOAT(thing->x);
fy = FIXED_TO_FLOAT(thing->y);
// create the sprite billboard
//
// 3--2 // 3--2
// | /| // | /|
// |/ | // |/ |
// 0--1 // 0--1
// x1/x2 were already scaled in HWR_ProjectSprite if (thing && fabsf(fscale - 1.0f) > 1.0E-36f)
// First match the normal sprite offset = (gpatch->height/2) * fscale;
swallVerts[0].x = swallVerts[3].x = spr->x1; else
swallVerts[2].x = swallVerts[1].x = spr->x2; offset = (float)(gpatch->height/2);
swallVerts[0].z = swallVerts[3].z = spr->z1;
swallVerts[2].z = swallVerts[1].z = spr->z2;
if (spr->mobj && fabsf(this_scale - 1.0f) > 1.0E-36f) shadowVerts[0].x = shadowVerts[3].x = fx - offset;
shadowVerts[2].x = shadowVerts[1].x = fx + offset;
shadowVerts[0].z = shadowVerts[1].z = fy - offset;
shadowVerts[3].z = shadowVerts[2].z = fy + offset;
if (floorslope)
{ {
// Always a pixel above the floor, perfectly flat. for (i = 0; i < 4; i++)
swallVerts[0].y = swallVerts[1].y = swallVerts[2].y = swallVerts[3].y = spr->ty - gpatch->topoffset * this_scale - (floorheight+3); {
slopez = P_GetZAt(floorslope, FLOAT_TO_FIXED(shadowVerts[i].x), FLOAT_TO_FIXED(shadowVerts[i].z));
// Now transform the TOP vertices along the floor in the direction of the camera shadowVerts[i].y = FIXED_TO_FLOAT(slopez) + 0.05f;
swallVerts[3].x = spr->x1 + ((gpatch->height * this_scale) + offset) * gr_viewcos; }
swallVerts[2].x = spr->x2 + ((gpatch->height * this_scale) + offset) * gr_viewcos;
swallVerts[3].z = spr->z1 + ((gpatch->height * this_scale) + offset) * gr_viewsin;
swallVerts[2].z = spr->z2 + ((gpatch->height * this_scale) + offset) * gr_viewsin;
} }
else else
{ {
// Always a pixel above the floor, perfectly flat. for (i = 0; i < 4; i++)
swallVerts[0].y = swallVerts[1].y = swallVerts[2].y = swallVerts[3].y = spr->ty - gpatch->topoffset - (floorheight+3); shadowVerts[i].y = FIXED_TO_FLOAT(floorz) + 0.05f;
// Now transform the TOP vertices along the floor in the direction of the camera
swallVerts[3].x = spr->x1 + (gpatch->height + offset) * gr_viewcos;
swallVerts[2].x = spr->x2 + (gpatch->height + offset) * gr_viewcos;
swallVerts[3].z = spr->z1 + (gpatch->height + offset) * gr_viewsin;
swallVerts[2].z = spr->z2 + (gpatch->height + offset) * gr_viewsin;
}
// We also need to move the bottom ones away when shadowoffs is on
if (cv_shadowoffs.value)
{
swallVerts[0].x = spr->x1 + offset * gr_viewcos;
swallVerts[1].x = spr->x2 + offset * gr_viewcos;
swallVerts[0].z = spr->z1 + offset * gr_viewsin;
swallVerts[1].z = spr->z2 + offset * gr_viewsin;
} }
if (spr->flip) if (spr->flip)
{ {
swallVerts[0].s = swallVerts[3].s = gpatch->max_s; shadowVerts[0].s = shadowVerts[3].s = gpatch->max_s;
swallVerts[2].s = swallVerts[1].s = 0; shadowVerts[2].s = shadowVerts[1].s = 0;
} }
else else
{ {
swallVerts[0].s = swallVerts[3].s = 0; shadowVerts[0].s = shadowVerts[3].s = 0;
swallVerts[2].s = swallVerts[1].s = gpatch->max_s; shadowVerts[2].s = shadowVerts[1].s = gpatch->max_s;
} }
// flip the texture coords (look familiar?) // flip the texture coords (look familiar?)
if (spr->vflip) if (spr->vflip)
{ {
swallVerts[3].t = swallVerts[2].t = gpatch->max_t; shadowVerts[3].t = shadowVerts[2].t = gpatch->max_t;
swallVerts[0].t = swallVerts[1].t = 0; shadowVerts[0].t = shadowVerts[1].t = 0;
} }
else else
{ {
swallVerts[3].t = swallVerts[2].t = 0; shadowVerts[3].t = shadowVerts[2].t = 0;
swallVerts[0].t = swallVerts[1].t = gpatch->max_t; shadowVerts[0].t = shadowVerts[1].t = gpatch->max_t;
} }
sSurf.PolyColor.s.red = 0x00; if (thing->subsector->sector->numlights)
sSurf.PolyColor.s.blue = 0x00;
sSurf.PolyColor.s.green = 0x00;
/*if (spr->mobj->frame & FF_TRANSMASK || spr->mobj->flags2 & MF2_SHADOW)
{ {
sector_t *sector = spr->mobj->subsector->sector; light = R_GetPlaneLight(thing->subsector->sector, floorz, false); // Always use the light at the top instead of whatever I was doing before
UINT8 lightlevel = 255;
extracolormap_t *colormap = sector->extra_colormap;
if (sector->numlights) lightlevel = *thing->subsector->sector->lightlist[light].lightlevel;
{
INT32 light = R_GetPlaneLight(sector, spr->mobj->floorz, false);
if (!(spr->mobj->frame & FF_FULLBRIGHT)) if (*thing->subsector->sector->lightlist[light].extra_colormap)
lightlevel = *sector->lightlist[light].lightlevel; colormap = *thing->subsector->sector->lightlist[light].extra_colormap;
if (*sector->lightlist[light].extra_colormap)
colormap = *sector->lightlist[light].extra_colormap;
}
else
{
lightlevel = sector->lightlevel;
if (sector->extra_colormap)
colormap = sector->extra_colormap;
}
if (colormap)
sSurf.PolyColor.rgba = HWR_Lighting(lightlevel/2, colormap->rgba, colormap->fadergba, false, true);
else
sSurf.PolyColor.rgba = HWR_Lighting(lightlevel/2, NORMALFOG, FADEFOG, false, true);
}*/
// shadow is always half as translucent as the sprite itself
if (!cv_translucency.value) // use default translucency (main sprite won't have any translucency)
sSurf.PolyColor.s.alpha = 0x80; // default
else if (spr->mobj->flags2 & MF2_SHADOW)
sSurf.PolyColor.s.alpha = 0x20;
else if (spr->mobj->frame & FF_TRANSMASK)
{
HWR_TranstableToAlpha((spr->mobj->frame & FF_TRANSMASK)>>FF_TRANSSHIFT, &sSurf);
sSurf.PolyColor.s.alpha /= 2; //cut alpha in half!
} }
else else
sSurf.PolyColor.s.alpha = 0x80; // default
if (sSurf.PolyColor.s.alpha > floorheight/4)
{ {
sSurf.PolyColor.s.alpha = (UINT8)(sSurf.PolyColor.s.alpha - floorheight/4); lightlevel = thing->subsector->sector->lightlevel;
HWD.pfnSetShader(1); // floor shader
HWD.pfnDrawPolygon(&sSurf, swallVerts, 4, PF_Translucent|PF_Modulated|PF_Clip); if (thing->subsector->sector->extra_colormap)
colormap = thing->subsector->sector->extra_colormap;
} }
HWR_Lighting(&sSurf, lightlevel, colormap);
sSurf.PolyColor.s.alpha = alpha;
HWD.pfnSetShader(3); // sprite shader
HWD.pfnDrawPolygon(&sSurf, shadowVerts, 4, PF_Translucent|PF_Modulated|PF_Clip);
} }
#endif //#ifdef GLBADSHADOWS
// This is expecting a pointer to an array containing 4 wallVerts for a sprite // This is expecting a pointer to an array containing 4 wallVerts for a sprite
static void HWR_RotateSpritePolyToAim(gr_vissprite_t *spr, FOutVector *wallVerts) static void HWR_RotateSpritePolyToAim(gr_vissprite_t *spr, FOutVector *wallVerts)
@ -3984,24 +3891,6 @@ static void HWR_SplitSprite(gr_vissprite_t *spr)
//Hurdler: 25/04/2000: now support colormap in hardware mode //Hurdler: 25/04/2000: now support colormap in hardware mode
HWR_GetMappedPatch(gpatch, spr->colormap); HWR_GetMappedPatch(gpatch, spr->colormap);
#ifdef GLBADSHADOWS
// Draw shadow BEFORE sprite
if (cv_shadow.value // Shadows enabled
&& (spr->mobj->flags & (MF_SCENERY|MF_SPAWNCEILING|MF_NOGRAVITY)) != (MF_SCENERY|MF_SPAWNCEILING|MF_NOGRAVITY) // Ceiling scenery have no shadow.
&& !(spr->mobj->flags2 & MF2_DEBRIS) // Debris have no corona or shadow.
#ifdef ALAM_LIGHTING
&& !(t_lspr[spr->mobj->sprite]->type // Things with dynamic lights have no shadow.
&& (!spr->mobj->player || spr->mobj->player->powers[pw_super])) // Except for non-super players.
#endif
&& (spr->mobj->z >= spr->mobj->floorz)) // Without this, your shadow shows on the floor, even after you die and fall through the ground.
{
////////////////////
// SHADOW SPRITE! //
////////////////////
HWR_DrawSpriteShadow(spr, gpatch, this_scale);
}
#endif //#ifdef GLBADSHADOWS
baseWallVerts[0].x = baseWallVerts[3].x = spr->x1; baseWallVerts[0].x = baseWallVerts[3].x = spr->x1;
baseWallVerts[2].x = baseWallVerts[1].x = spr->x2; baseWallVerts[2].x = baseWallVerts[1].x = spr->x2;
baseWallVerts[0].z = baseWallVerts[3].z = spr->z1; baseWallVerts[0].z = baseWallVerts[3].z = spr->z1;
@ -4384,25 +4273,7 @@ static void HWR_DrawSprite(gr_vissprite_t *spr)
//Hurdler: 25/04/2000: now support colormap in hardware mode //Hurdler: 25/04/2000: now support colormap in hardware mode
HWR_GetMappedPatch(gpatch, spr->colormap); HWR_GetMappedPatch(gpatch, spr->colormap);
#ifdef GLBADSHADOWS // if it has a dispoffset, push it a little towards the camera
// Draw shadow BEFORE sprite
if (cv_shadow.value // Shadows enabled
&& (spr->mobj->flags & (MF_SCENERY|MF_SPAWNCEILING|MF_NOGRAVITY)) != (MF_SCENERY|MF_SPAWNCEILING|MF_NOGRAVITY) // Ceiling scenery have no shadow.
&& !(spr->mobj->flags2 & MF2_DEBRIS) // Debris have no corona or shadow.
#ifdef ALAM_LIGHTING
&& !(t_lspr[spr->mobj->sprite]->type // Things with dynamic lights have no shadow.
&& (!spr->mobj->player || spr->mobj->player->powers[pw_super])) // Except for non-super players.
#endif
&& (spr->mobj->z >= spr->mobj->floorz)) // Without this, your shadow shows on the floor, even after you die and fall through the ground.
{
////////////////////
// SHADOW SPRITE! //
////////////////////
HWR_DrawSpriteShadow(spr, gpatch, this_scale);
}
#endif //#ifdef GLBADSHADOWS
// if it has a dispoffset, push it a little tards the camera
if (spr->dispoffset) { if (spr->dispoffset) {
float co = -gr_viewcos*(0.05f*spr->dispoffset); float co = -gr_viewcos*(0.05f*spr->dispoffset);
float si = -gr_viewsin*(0.05f*spr->dispoffset); float si = -gr_viewsin*(0.05f*spr->dispoffset);
@ -5003,6 +4874,12 @@ static void HWR_DrawSprites(void)
HWR_DrawPrecipitationSprite(spr); HWR_DrawPrecipitationSprite(spr);
else else
#endif #endif
{
if (spr->mobj && spr->mobj->shadowscale && !(spr->mobj->frame & FF_PAPERSPRITE))
{
HWR_DrawDropShadow(spr->mobj, spr, spr->mobj->shadowscale);
}
if (spr->mobj && spr->mobj->skin && spr->mobj->sprite == SPR_PLAY) if (spr->mobj && spr->mobj->skin && spr->mobj->sprite == SPR_PLAY)
{ {
if (!cv_grmodels.value || md2_playermodels[(skin_t*)spr->mobj->skin-skins].notfound || md2_playermodels[(skin_t*)spr->mobj->skin-skins].scale < 0.0f) if (!cv_grmodels.value || md2_playermodels[(skin_t*)spr->mobj->skin-skins].notfound || md2_playermodels[(skin_t*)spr->mobj->skin-skins].scale < 0.0f)
@ -5023,6 +4900,7 @@ static void HWR_DrawSprites(void)
HWR_DrawSprite(spr); HWR_DrawSprite(spr);
} }
} }
}
} }
} }
} }
@ -5125,6 +5003,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
spritedef_t *sprdef; spritedef_t *sprdef;
spriteframe_t *sprframe; spriteframe_t *sprframe;
spriteinfo_t *sprinfo; spriteinfo_t *sprinfo;
md2_t *md2;
size_t lumpoff; size_t lumpoff;
unsigned rot; unsigned rot;
UINT16 flip; UINT16 flip;
@ -5156,8 +5035,21 @@ static void HWR_ProjectSprite(mobj_t *thing)
tz = (tr_x * gr_viewcos) + (tr_y * gr_viewsin); tz = (tr_x * gr_viewcos) + (tr_y * gr_viewsin);
// thing is behind view plane? // thing is behind view plane?
if (tz < ZCLIP_PLANE && !papersprite && (!cv_grmodels.value || md2_models[thing->sprite].notfound == true)) //Yellow: Only MD2's dont disappear if (tz < ZCLIP_PLANE && !papersprite)
return; {
if (cv_grmodels.value) //Yellow: Only MD2's dont disappear
{
if (thing->skin && thing->sprite == SPR_PLAY)
md2 = &md2_playermodels[( (skin_t *)thing->skin - skins )];
else
md2 = &md2_models[thing->sprite];
if (md2->notfound || md2->scale < 0.0f)
return;
}
else
return;
}
// The above can stay as it works for cutting sprites that are too close // The above can stay as it works for cutting sprites that are too close
tr_x = FIXED_TO_FLOAT(thing->x); tr_x = FIXED_TO_FLOAT(thing->x);
@ -5525,7 +5417,7 @@ static void HWR_DrawSkyBackground(player_t *player)
if (cv_grskydome.value) if (cv_grskydome.value)
{ {
FTransform dometransform; FTransform dometransform;
const float fpov = FIXED_TO_FLOAT(cv_grfov.value+player->fovadd); const float fpov = FIXED_TO_FLOAT(cv_fov.value+player->fovadd);
postimg_t *type; postimg_t *type;
if (splitscreen && player == &players[secondarydisplayplayer]) if (splitscreen && player == &players[secondarydisplayplayer])
@ -5705,7 +5597,7 @@ void HWR_SetViewSize(void)
// ========================================================================== // ==========================================================================
void HWR_RenderSkyboxView(INT32 viewnumber, player_t *player) void HWR_RenderSkyboxView(INT32 viewnumber, player_t *player)
{ {
const float fpov = FIXED_TO_FLOAT(cv_grfov.value+player->fovadd); const float fpov = FIXED_TO_FLOAT(cv_fov.value+player->fovadd);
postimg_t *type; postimg_t *type;
if (splitscreen && player == &players[secondarydisplayplayer]) if (splitscreen && player == &players[secondarydisplayplayer])
@ -5846,7 +5738,7 @@ if (0)
viewangle = localaiming2; viewangle = localaiming2;
// Handle stuff when you are looking farther up or down. // Handle stuff when you are looking farther up or down.
if ((aimingangle || cv_grfov.value+player->fovadd > 90*FRACUNIT)) if ((aimingangle || cv_fov.value+player->fovadd > 90*FRACUNIT))
{ {
dup_viewangle += ANGLE_90; dup_viewangle += ANGLE_90;
HWR_ClearClipSegs(); HWR_ClearClipSegs();
@ -5910,7 +5802,7 @@ if (0)
// ========================================================================== // ==========================================================================
void HWR_RenderPlayerView(INT32 viewnumber, player_t *player) void HWR_RenderPlayerView(INT32 viewnumber, player_t *player)
{ {
const float fpov = FIXED_TO_FLOAT(cv_grfov.value+player->fovadd); const float fpov = FIXED_TO_FLOAT(cv_fov.value+player->fovadd);
postimg_t *type; postimg_t *type;
const boolean skybox = (skyboxmo[0] && cv_skybox.value); // True if there's a skybox object and skyboxes are on const boolean skybox = (skyboxmo[0] && cv_skybox.value); // True if there's a skybox object and skyboxes are on
@ -6067,7 +5959,7 @@ if (0)
viewangle = localaiming2; viewangle = localaiming2;
// Handle stuff when you are looking farther up or down. // Handle stuff when you are looking farther up or down.
if ((aimingangle || cv_grfov.value+player->fovadd > 90*FRACUNIT)) if ((aimingangle || cv_fov.value+player->fovadd > 90*FRACUNIT))
{ {
dup_viewangle += ANGLE_90; dup_viewangle += ANGLE_90;
HWR_ClearClipSegs(); HWR_ClearClipSegs();
@ -6183,9 +6075,7 @@ static void CV_grmodellighting_OnChange(void);
static void CV_grfiltermode_OnChange(void); static void CV_grfiltermode_OnChange(void);
static void CV_granisotropic_OnChange(void); static void CV_granisotropic_OnChange(void);
static void CV_grfogdensity_OnChange(void); static void CV_grfogdensity_OnChange(void);
static void CV_grfov_OnChange(void);
static CV_PossibleValue_t grfov_cons_t[] = {{0, "MIN"}, {179*FRACUNIT, "MAX"}, {0, NULL}};
static CV_PossibleValue_t grfiltermode_cons_t[]= {{HWD_SET_TEXTUREFILTER_POINTSAMPLED, "Nearest"}, static CV_PossibleValue_t grfiltermode_cons_t[]= {{HWD_SET_TEXTUREFILTER_POINTSAMPLED, "Nearest"},
{HWD_SET_TEXTUREFILTER_BILINEAR, "Bilinear"}, {HWD_SET_TEXTUREFILTER_TRILINEAR, "Trilinear"}, {HWD_SET_TEXTUREFILTER_BILINEAR, "Bilinear"}, {HWD_SET_TEXTUREFILTER_TRILINEAR, "Trilinear"},
{HWD_SET_TEXTUREFILTER_MIXED1, "Linear_Nearest"}, {HWD_SET_TEXTUREFILTER_MIXED1, "Linear_Nearest"},
@ -6195,8 +6085,8 @@ static CV_PossibleValue_t grfiltermode_cons_t[]= {{HWD_SET_TEXTUREFILTER_POINTSA
CV_PossibleValue_t granisotropicmode_cons_t[] = {{1, "MIN"}, {16, "MAX"}, {0, NULL}}; CV_PossibleValue_t granisotropicmode_cons_t[] = {{1, "MIN"}, {16, "MAX"}, {0, NULL}};
consvar_t cv_grshaders = {"gr_shaders", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grshaders = {"gr_shaders", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_grfovchange = {"gr_fovchange", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_fovchange = {"gr_fovchange", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_grfog = {"gr_fog", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grfog = {"gr_fog", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_grfogcolor = {"gr_fogcolor", "AAAAAA", CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grfogcolor = {"gr_fogcolor", "AAAAAA", CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_grsoftwarefog = {"gr_softwarefog", "Off", CV_SAVE, grsoftwarefog_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grsoftwarefog = {"gr_softwarefog", "Off", CV_SAVE, grsoftwarefog_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
@ -6217,7 +6107,6 @@ consvar_t cv_grskydome = {"gr_skydome", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL,
consvar_t cv_grfakecontrast = {"gr_fakecontrast", "Smooth", CV_SAVE, grfakecontrast_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grfakecontrast = {"gr_fakecontrast", "Smooth", CV_SAVE, grfakecontrast_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_grrounddown = {"gr_rounddown", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grrounddown = {"gr_rounddown", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_grfov = {"gr_fov", "90", CV_FLOAT|CV_CALL, grfov_cons_t, CV_grfov_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_grfogdensity = {"gr_fogdensity", "150", CV_CALL|CV_NOINIT, CV_Unsigned, consvar_t cv_grfogdensity = {"gr_fogdensity", "150", CV_CALL|CV_NOINIT, CV_Unsigned,
CV_grfogdensity_OnChange, 0, NULL, NULL, 0, 0, NULL}; CV_grfogdensity_OnChange, 0, NULL, NULL, 0, 0, NULL};
@ -6253,17 +6142,10 @@ static void CV_granisotropic_OnChange(void)
HWD.pfnSetSpecialState(HWD_SET_TEXTUREANISOTROPICMODE, cv_granisotropicmode.value); HWD.pfnSetSpecialState(HWD_SET_TEXTUREANISOTROPICMODE, cv_granisotropicmode.value);
} }
static void CV_grfov_OnChange(void)
{
if ((netgame || multiplayer) && !cv_debug && cv_grfov.value != 90*FRACUNIT)
CV_Set(&cv_grfov, cv_grfov.defaultvalue);
}
//added by Hurdler: console varibale that are saved //added by Hurdler: console varibale that are saved
void HWR_AddCommands(void) void HWR_AddCommands(void)
{ {
CV_RegisterVar(&cv_grfovchange); CV_RegisterVar(&cv_fovchange);
CV_RegisterVar(&cv_grfov);
CV_RegisterVar(&cv_grfogdensity); CV_RegisterVar(&cv_grfogdensity);
CV_RegisterVar(&cv_grfogcolor); CV_RegisterVar(&cv_grfogcolor);

View File

@ -86,8 +86,8 @@ extern consvar_t cv_grstaticlighting;
extern consvar_t cv_grcoronas; extern consvar_t cv_grcoronas;
extern consvar_t cv_grcoronasize; extern consvar_t cv_grcoronasize;
#endif #endif
extern consvar_t cv_grshaders; extern consvar_t cv_grshaders;
extern consvar_t cv_grfov;
extern consvar_t cv_grmodels; extern consvar_t cv_grmodels;
extern consvar_t cv_grmodelinterpolation; extern consvar_t cv_grmodelinterpolation;
extern consvar_t cv_grmodellighting; extern consvar_t cv_grmodellighting;
@ -98,7 +98,7 @@ extern consvar_t cv_grsoftwarefog;
extern consvar_t cv_grfiltermode; extern consvar_t cv_grfiltermode;
extern consvar_t cv_granisotropicmode; extern consvar_t cv_granisotropicmode;
extern consvar_t cv_grcorrecttricks; extern consvar_t cv_grcorrecttricks;
extern consvar_t cv_grfovchange; extern consvar_t cv_fovchange;
extern consvar_t cv_grsolvetjoin; extern consvar_t cv_grsolvetjoin;
extern consvar_t cv_grshearing; extern consvar_t cv_grshearing;
extern consvar_t cv_grspritebillboarding; extern consvar_t cv_grspritebillboarding;

View File

@ -31,7 +31,9 @@
#include <math.h> #include <math.h>
#include "r_opengl.h" #include "r_opengl.h"
#include "r_vbo.h" #include "r_vbo.h"
#include "../../p_tick.h" // for leveltime (NOTE: THIS IS BAD, FIGURE OUT HOW TO PROPERLY IMPLEMENT gl_leveltime) #include "../../p_tick.h" // for leveltime (NOTE: THIS IS BAD, FIGURE OUT HOW TO PROPERLY IMPLEMENT gl_leveltime)
#include "../../r_main.h" // AIMINGTODY (ALSO BAD)
#if defined (HWRENDER) && !defined (NOROPENGL) #if defined (HWRENDER) && !defined (NOROPENGL)
@ -2817,15 +2819,13 @@ EXPORT void HWRAPI(SetTransform) (FTransform *stransform)
{ {
static boolean special_splitscreen; static boolean special_splitscreen;
boolean shearing = false; boolean shearing = false;
float used_fov;
pglLoadIdentity(); pglLoadIdentity();
if (stransform) if (stransform)
{ {
boolean fovx90; used_fov = stransform->fovxangle;
shearing = stransform->shearing;
#ifdef USE_FTRANSFORM_MIRROR #ifdef USE_FTRANSFORM_MIRROR
// mirroring from Kart // mirroring from Kart
if (stransform->mirror) if (stransform->mirror)
@ -2837,48 +2837,45 @@ EXPORT void HWRAPI(SetTransform) (FTransform *stransform)
else else
pglScalef(stransform->scalex, stransform->scaley, -stransform->scalez); pglScalef(stransform->scalex, stransform->scaley, -stransform->scalez);
pglMatrixMode(GL_MODELVIEW); pglRotatef(stransform->anglex , 1.0f, 0.0f, 0.0f);
pglRotatef(stransform->anglex, 1.0f, 0.0f, 0.0f);
pglRotatef(stransform->angley+270.0f, 0.0f, 1.0f, 0.0f); pglRotatef(stransform->angley+270.0f, 0.0f, 1.0f, 0.0f);
pglTranslatef(-stransform->x, -stransform->z, -stransform->y); pglTranslatef(-stransform->x, -stransform->z, -stransform->y);
pglMatrixMode(GL_PROJECTION); special_splitscreen = stransform->splitscreen;
pglLoadIdentity(); shearing = stransform->shearing;
// jimita 14042019
// Simulate Software's y-shearing
// https://zdoom.org/wiki/Y-shearing
if (shearing)
{
float dy = FIXED_TO_FLOAT(AIMINGTODY(stransform->viewaiming)) * 2; //screen_width/BASEVIDWIDTH;
pglTranslatef(0.0f, -dy/BASEVIDHEIGHT, 0.0f);
}
fovx90 = stransform->fovxangle > 0.0f && fabsf(stransform->fovxangle - 90.0f) < 0.5f;
special_splitscreen = (stransform->splitscreen && fovx90);
if (special_splitscreen)
GLPerspective(53.13f, 2*ASPECT_RATIO); // 53.13 = 2*atan(0.5)
else
GLPerspective(stransform->fovxangle, ASPECT_RATIO);
pglGetFloatv(GL_PROJECTION_MATRIX, projMatrix); // added for new coronas' code (without depth buffer)
pglMatrixMode(GL_MODELVIEW);
} }
else else
{ {
used_fov = fov;
pglScalef(1.0f, 1.0f, -1.0f); pglScalef(1.0f, 1.0f, -1.0f);
pglMatrixMode(GL_PROJECTION);
pglLoadIdentity();
if (special_splitscreen)
GLPerspective(53.13f, 2*ASPECT_RATIO); // 53.13 = 2*atan(0.5)
else
//Hurdler: is "fov" correct?
GLPerspective(fov, ASPECT_RATIO);
pglGetFloatv(GL_PROJECTION_MATRIX, projMatrix); // added for new coronas' code (without depth buffer)
pglMatrixMode(GL_MODELVIEW);
} }
pglMatrixMode(GL_PROJECTION);
pglLoadIdentity();
// jimita 14042019
// Simulate Software's y-shearing
// https://zdoom.org/wiki/Y-shearing
if (shearing)
{
fixed_t dy = AIMINGTODY(stransform->viewaiming);
float fdy = FIXED_TO_FLOAT(dy) * 2; //screen_width/BASEVIDWIDTH;
pglTranslatef(0.0f, -fdy/BASEVIDHEIGHT, 0.0f);
}
if (special_splitscreen)
{
used_fov = atan(tan(used_fov*M_PI/360)*0.8)*360/M_PI;
GLPerspective(used_fov, 2*ASPECT_RATIO);
}
else
GLPerspective(used_fov, ASPECT_RATIO);
pglGetFloatv(GL_PROJECTION_MATRIX, projMatrix); // added for new coronas' code (without depth buffer)
pglMatrixMode(GL_MODELVIEW);
pglGetFloatv(GL_MODELVIEW_MATRIX, modelMatrix); // added for new coronas' code (without depth buffer) pglGetFloatv(GL_MODELVIEW_MATRIX, modelMatrix); // added for new coronas' code (without depth buffer)
} }
EXPORT INT32 HWRAPI(GetTextureUsed) (void) EXPORT INT32 HWRAPI(GetTextureUsed) (void)

View File

@ -659,13 +659,7 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum)
M_GetText("Illegal say command received from %s while muted\n") : M_GetText("Illegal csay command received from non-admin %s\n"), M_GetText("Illegal say command received from %s while muted\n") : M_GetText("Illegal csay command received from non-admin %s\n"),
player_names[playernum]); player_names[playernum]);
if (server) if (server)
{ SendKick(playernum, KICK_MSG_CON_FAIL);
UINT8 buf[2];
buf[0] = (UINT8)playernum;
buf[1] = KICK_MSG_CON_FAIL;
SendNetXCmd(XD_KICK, &buf, 2);
}
return; return;
} }
@ -679,13 +673,7 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum)
{ {
CONS_Alert(CONS_WARNING, M_GetText("Illegal say command received from %s containing invalid characters\n"), player_names[playernum]); CONS_Alert(CONS_WARNING, M_GetText("Illegal say command received from %s containing invalid characters\n"), player_names[playernum]);
if (server) if (server)
{ SendKick(playernum, KICK_MSG_CON_FAIL);
char buf[2];
buf[0] = (char)playernum;
buf[1] = KICK_MSG_CON_FAIL;
SendNetXCmd(XD_KICK, &buf, 2);
}
return; return;
} }
} }

View File

@ -5734,7 +5734,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
0, // mass 0, // mass
0, // damage 0, // damage
sfx_spring, // activesound sfx_spring, // activesound
MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOCLIPTHING, // flags MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPHEIGHT, // flags
S_EGGMOBILE2_POGO5 // raisestate S_EGGMOBILE2_POGO5 // raisestate
}, },

View File

@ -87,13 +87,7 @@ deny:
CONS_Alert(CONS_WARNING, M_GetText("Illegal lua command received from %s\n"), player_names[playernum]); CONS_Alert(CONS_WARNING, M_GetText("Illegal lua command received from %s\n"), player_names[playernum]);
if (server) if (server)
{ SendKick(playernum, KICK_MSG_CON_FAIL);
UINT8 bufn[2];
bufn[0] = (UINT8)playernum;
bufn[1] = KICK_MSG_CON_FAIL;
SendNetXCmd(XD_KICK, &bufn, 2);
}
} }
// Wrapper for COM_AddCommand commands // Wrapper for COM_AddCommand commands

View File

@ -157,13 +157,21 @@ static const char *const side_opt[] = {
enum vertex_e { enum vertex_e {
vertex_valid = 0, vertex_valid = 0,
vertex_x, vertex_x,
vertex_y vertex_y,
vertex_floorz,
vertex_floorzset,
vertex_ceilingz,
vertex_ceilingzset
}; };
static const char *const vertex_opt[] = { static const char *const vertex_opt[] = {
"valid", "valid",
"x", "x",
"y", "y",
"floorz",
"floorzset",
"ceilingz",
"ceilingzset",
NULL}; NULL};
enum ffloor_e { enum ffloor_e {
@ -968,6 +976,18 @@ static int vertex_get(lua_State *L)
case vertex_y: case vertex_y:
lua_pushfixed(L, vertex->y); lua_pushfixed(L, vertex->y);
return 1; return 1;
case vertex_floorzset:
lua_pushboolean(L, vertex->floorzset);
return 1;
case vertex_ceilingzset:
lua_pushboolean(L, vertex->ceilingzset);
return 1;
case vertex_floorz:
lua_pushfixed(L, vertex->floorz);
return 1;
case vertex_ceilingz:
lua_pushfixed(L, vertex->ceilingz);
return 1;
} }
return 0; return 0;
} }

View File

@ -88,7 +88,8 @@ enum mobj_e {
#ifdef ESLOPE #ifdef ESLOPE
mobj_standingslope, mobj_standingslope,
#endif #endif
mobj_colorized mobj_colorized,
mobj_shadowscale
}; };
static const char *const mobj_opt[] = { static const char *const mobj_opt[] = {
@ -156,6 +157,7 @@ static const char *const mobj_opt[] = {
"standingslope", "standingslope",
#endif #endif
"colorized", "colorized",
"shadowscale",
NULL}; NULL};
#define UNIMPLEMENTED luaL_error(L, LUA_QL("mobj_t") " field " LUA_QS " is not implemented for Lua and cannot be accessed.", mobj_opt[field]) #define UNIMPLEMENTED luaL_error(L, LUA_QL("mobj_t") " field " LUA_QS " is not implemented for Lua and cannot be accessed.", mobj_opt[field])
@ -390,6 +392,9 @@ static int mobj_get(lua_State *L)
case mobj_colorized: case mobj_colorized:
lua_pushboolean(L, mo->colorized); lua_pushboolean(L, mo->colorized);
break; break;
case mobj_shadowscale:
lua_pushfixed(L, mo->shadowscale);
break;
default: // extra custom variables in Lua memory default: // extra custom variables in Lua memory
lua_getfield(L, LUA_REGISTRYINDEX, LREG_EXTVARS); lua_getfield(L, LUA_REGISTRYINDEX, LREG_EXTVARS);
I_Assert(lua_istable(L, -1)); I_Assert(lua_istable(L, -1));
@ -719,6 +724,8 @@ static int mobj_set(lua_State *L)
case mobj_colorized: case mobj_colorized:
mo->colorized = luaL_checkboolean(L, 3); mo->colorized = luaL_checkboolean(L, 3);
break; break;
case mobj_shadowscale:
mo->shadowscale = luaL_checkfixed(L, 3);
default: default:
lua_getfield(L, LUA_REGISTRYINDEX, LREG_EXTVARS); lua_getfield(L, LUA_REGISTRYINDEX, LREG_EXTVARS);
I_Assert(lua_istable(L, -1)); I_Assert(lua_istable(L, -1));

View File

@ -274,12 +274,6 @@ int LUA_PushGlobals(lua_State *L, const char *word)
return 0; return 0;
LUA_PushUserdata(L, &players[serverplayer], META_PLAYER); LUA_PushUserdata(L, &players[serverplayer], META_PLAYER);
return 1; return 1;
} else if (fastcmp(word,"admin")) { // BACKWARDS COMPATIBILITY HACK: This was replaced with IsPlayerAdmin(), but some 2.1 Lua scripts still use the admin variable. It now points to the first admin player in the array.
LUA_Deprecated(L, "admin", "IsPlayerAdmin(player)");
if (!playeringame[adminplayers[0]] || IsPlayerAdmin(serverplayer))
return 0;
LUA_PushUserdata(L, &players[adminplayers[0]], META_PLAYER);
return 1;
} else if (fastcmp(word,"emeralds")) { } else if (fastcmp(word,"emeralds")) {
lua_pushinteger(L, emeralds); lua_pushinteger(L, emeralds);
return 1; return 1;

View File

@ -1397,7 +1397,7 @@ static menuitem_t OP_OpenGLOptionsMenu[] =
{IT_STRING|IT_CVAR, NULL, "Model lighting", &cv_grmodellighting, 32}, {IT_STRING|IT_CVAR, NULL, "Model lighting", &cv_grmodellighting, 32},
{IT_HEADER, NULL, "General", NULL, 51}, {IT_HEADER, NULL, "General", NULL, 51},
{IT_STRING|IT_CVAR, NULL, "Field of view", &cv_grfov, 63}, {IT_STRING|IT_CVAR, NULL, "Field of view", &cv_fov, 63},
{IT_STRING|IT_CVAR, NULL, "Quality", &cv_scr_depth, 73}, {IT_STRING|IT_CVAR, NULL, "Quality", &cv_scr_depth, 73},
{IT_STRING|IT_CVAR, NULL, "Texture Filter", &cv_grfiltermode, 83}, {IT_STRING|IT_CVAR, NULL, "Texture Filter", &cv_grfiltermode, 83},
{IT_STRING|IT_CVAR, NULL, "Anisotropic", &cv_granisotropicmode,93}, {IT_STRING|IT_CVAR, NULL, "Anisotropic", &cv_granisotropicmode,93},
@ -7233,7 +7233,7 @@ static void M_EmblemHints(INT32 choice)
static void M_DrawEmblemHints(void) static void M_DrawEmblemHints(void)
{ {
INT32 i, j = 0, x, y; INT32 i, j = 0, x, y, left_hints = NUMHINTS;
UINT32 collected = 0, local = 0; UINT32 collected = 0, local = 0;
emblem_t *emblem; emblem_t *emblem;
const char *hint; const char *hint;
@ -7250,6 +7250,11 @@ static void M_DrawEmblemHints(void)
x = (local > NUMHINTS ? 4 : 12); x = (local > NUMHINTS ? 4 : 12);
y = 8; y = 8;
// If there are more than 1 page's but less than 2 pages' worth of emblems,
// put half (rounded up) of the hints on the left, and half (rounded down) on the right
if (local > NUMHINTS && local < (NUMHINTS*2)-1)
left_hints = (local + 1) / 2;
if (!local) if (!local)
V_DrawCenteredString(160, 48, V_YELLOWMAP, "No hidden emblems on this map."); V_DrawCenteredString(160, 48, V_YELLOWMAP, "No hidden emblems on this map.");
else for (i = 0; i < numemblems; i++) else for (i = 0; i < numemblems; i++)
@ -7282,7 +7287,7 @@ static void M_DrawEmblemHints(void)
y += 28; y += 28;
if (++j == NUMHINTS) if (++j == left_hints)
{ {
x = 4+(BASEVIDWIDTH/2); x = 4+(BASEVIDWIDTH/2);
y = 8; y = 8;

View File

@ -433,7 +433,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|| special->state == &states[S_FANG_BOUNCE4] || special->state == &states[S_FANG_BOUNCE4]
|| special->state == &states[S_FANG_PINCHBOUNCE3] || special->state == &states[S_FANG_PINCHBOUNCE3]
|| special->state == &states[S_FANG_PINCHBOUNCE4]) || special->state == &states[S_FANG_PINCHBOUNCE4])
&& P_MobjFlip(special)*((special->z + special->height/2) - (toucher->z - toucher->height/2)) > (special->height/4)) && P_MobjFlip(special)*((special->z + special->height/2) - (toucher->z + toucher->height/2)) > (toucher->height/2))
{ {
P_DamageMobj(toucher, special, special, 1, 0); P_DamageMobj(toucher, special, special, 1, 0);
P_SetTarget(&special->tracer, toucher); P_SetTarget(&special->tracer, toucher);
@ -1869,6 +1869,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
S_StartSound(toucher, special->info->deathsound); // was NULL, but changed to player so you could hear others pick up rings S_StartSound(toucher, special->info->deathsound); // was NULL, but changed to player so you could hear others pick up rings
P_KillMobj(special, NULL, toucher, 0); P_KillMobj(special, NULL, toucher, 0);
special->shadowscale = 0;
} }
/** Prints death messages relating to a dying or hit player. /** Prints death messages relating to a dying or hit player.

View File

@ -3902,11 +3902,15 @@ static void P_PlayerMobjThinker(mobj_t *mobj)
mobj->z += mobj->momz; mobj->z += mobj->momz;
P_SetThingPosition(mobj); P_SetThingPosition(mobj);
P_CheckPosition(mobj, mobj->x, mobj->y); P_CheckPosition(mobj, mobj->x, mobj->y);
mobj->floorz = tmfloorz;
mobj->ceilingz = tmceilingz;
goto animonly; goto animonly;
} }
else if (mobj->player->powers[pw_carry] == CR_MACESPIN) else if (mobj->player->powers[pw_carry] == CR_MACESPIN)
{ {
P_CheckPosition(mobj, mobj->x, mobj->y); P_CheckPosition(mobj, mobj->x, mobj->y);
mobj->floorz = tmfloorz;
mobj->ceilingz = tmceilingz;
goto animonly; goto animonly;
} }
} }
@ -10553,6 +10557,22 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
else else
mobj->z = z; mobj->z = z;
// Set shadowscale here, before spawn hook so that Lua can change it
if (
type == MT_PLAYER ||
type == MT_ROLLOUTROCK ||
type == MT_EGGMOBILE4_MACE ||
(type >= MT_SMALLMACE && type <= MT_REDSPRINGBALL) ||
(mobj->flags & MF_ENEMY)
)
mobj->shadowscale = FRACUNIT;
else if (
type >= MT_RING && type <= MT_FLINGEMERALD && type != MT_EMERALDSPAWN
)
mobj->shadowscale = 2*FRACUNIT/3;
else
mobj->shadowscale = 0;
#ifdef HAVE_BLUA #ifdef HAVE_BLUA
// DANGER! This can cause P_SpawnMobj to return NULL! // DANGER! This can cause P_SpawnMobj to return NULL!
// Avoid using P_RemoveMobj on the newly created mobj in "MobjSpawn" Lua hooks! // Avoid using P_RemoveMobj on the newly created mobj in "MobjSpawn" Lua hooks!

View File

@ -375,6 +375,7 @@ typedef struct mobj_s
#endif #endif
boolean colorized; // Whether the mobj uses the rainbow colormap boolean colorized; // Whether the mobj uses the rainbow colormap
fixed_t shadowscale; // If this object casts a shadow, and the size relative to radius
// WARNING: New fields must be added separately to savegame and Lua. // WARNING: New fields must be added separately to savegame and Lua.
} mobj_t; } mobj_t;

View File

@ -846,6 +846,8 @@ static void P_LoadVertices(UINT8 *data)
{ {
v->x = SHORT(mv->x)<<FRACBITS; v->x = SHORT(mv->x)<<FRACBITS;
v->y = SHORT(mv->y)<<FRACBITS; v->y = SHORT(mv->y)<<FRACBITS;
v->floorzset = v->ceilingzset = false;
v->floorz = v->ceilingz = 0;
} }
} }
@ -1366,6 +1368,16 @@ static void ParseTextmapVertexParameter(UINT32 i, char *param, char *val)
vertexes[i].x = FLOAT_TO_FIXED(atof(val)); vertexes[i].x = FLOAT_TO_FIXED(atof(val));
else if (fastcmp(param, "y")) else if (fastcmp(param, "y"))
vertexes[i].y = FLOAT_TO_FIXED(atof(val)); vertexes[i].y = FLOAT_TO_FIXED(atof(val));
else if (fastcmp(param, "zfloor"))
{
vertexes[i].floorz = FLOAT_TO_FIXED(atof(val));
vertexes[i].floorzset = true;
}
else if (fastcmp(param, "zceiling"))
{
vertexes[i].ceilingz = FLOAT_TO_FIXED(atof(val));
vertexes[i].ceilingzset = true;
}
} }
static void ParseTextmapSectorParameter(UINT32 i, char *param, char *val) static void ParseTextmapSectorParameter(UINT32 i, char *param, char *val)
@ -1573,6 +1585,8 @@ static void P_LoadTextmap(void)
{ {
// Defaults. // Defaults.
vt->x = vt->y = INT32_MAX; vt->x = vt->y = INT32_MAX;
vt->floorzset = vt->ceilingzset = false;
vt->floorz = vt->ceilingz = 0;
TextmapParse(vertexesPos[i], i, ParseTextmapVertexParameter); TextmapParse(vertexesPos[i], i, ParseTextmapVertexParameter);
@ -3567,11 +3581,11 @@ boolean P_LoadLevel(boolean fromnetsave)
return false; return false;
// init gravity, tag lists, // init gravity, tag lists,
// anything that P_ResetDynamicSlopes/P_LoadThings needs to know // anything that P_SpawnSlopes/P_LoadThings needs to know
P_InitSpecials(); P_InitSpecials();
#ifdef ESLOPE #ifdef ESLOPE
P_ResetDynamicSlopes(fromnetsave); P_SpawnSlopes(fromnetsave);
#endif #endif
P_SpawnMapThings(!fromnetsave); P_SpawnMapThings(!fromnetsave);

View File

@ -458,8 +458,8 @@ static pslope_t *MakeViaMapthings(INT16 tag1, INT16 tag2, INT16 tag3, UINT8 flag
return ret; return ret;
} }
/// Create vertex based slopes. /// Create vertex based slopes using tagged mapthings.
static void line_SpawnViaVertexes(const int linenum, const boolean spawnthinker) static void line_SpawnViaMapthingVertexes(const int linenum, const boolean spawnthinker)
{ {
line_t *line = lines + linenum; line_t *line = lines + linenum;
side_t *side; side_t *side;
@ -507,6 +507,55 @@ static void line_SpawnViaVertexes(const int linenum, const boolean spawnthinker)
side->sector->hasslope = true; side->sector->hasslope = true;
} }
/// Spawn textmap vertex slopes.
static void SpawnVertexSlopes(void)
{
line_t *l1, *l2;
sector_t* sc;
vertex_t *v1, *v2, *v3;
size_t i;
for (i = 0, sc = sectors; i < numsectors; i++, sc++)
{
// The vertex slopes only work for 3-vertex sectors (and thus 3-sided sectors).
if (sc->linecount != 3)
continue;
l1 = sc->lines[0];
l2 = sc->lines[1];
// Determine the vertexes.
v1 = l1->v1;
v2 = l1->v2;
if ((l2->v1 != v1) && (l2->v1 != v2))
v3 = l2->v1;
else
v3 = l2->v2;
if (v1->floorzset || v2->floorzset || v3->floorzset)
{
vector3_t vtx[3] = {
{v1->x, v1->y, v1->floorzset ? v1->floorz : sc->floorheight},
{v2->x, v2->y, v2->floorzset ? v2->floorz : sc->floorheight},
{v3->x, v3->y, v3->floorzset ? v3->floorz : sc->floorheight}};
pslope_t *slop = Slope_Add(0);
sc->f_slope = slop;
sc->hasslope = true;
ReconfigureViaVertexes(slop, vtx[0], vtx[1], vtx[2]);
}
if (v1->ceilingzset || v2->ceilingzset || v3->ceilingzset)
{
vector3_t vtx[3] = {
{v1->x, v1->y, v1->ceilingzset ? v1->ceilingz : sc->ceilingheight},
{v2->x, v2->y, v2->ceilingzset ? v2->ceilingz : sc->ceilingheight},
{v3->x, v3->y, v3->ceilingzset ? v3->ceilingz : sc->ceilingheight}};
pslope_t *slop = Slope_Add(0);
sc->c_slope = slop;
sc->hasslope = true;
ReconfigureViaVertexes(slop, vtx[0], vtx[1], vtx[2]);
}
}
}
// //
// P_CopySectorSlope // P_CopySectorSlope
@ -551,12 +600,16 @@ pslope_t *P_SlopeById(UINT16 id)
return ret; return ret;
} }
/// Reset slopes and read them from special lines. /// Initializes and reads the slopes from the map data.
void P_ResetDynamicSlopes(const boolean fromsave) { void P_SpawnSlopes(const boolean fromsave) {
size_t i; size_t i;
slopelist = NULL; slopelist = NULL;
slopecount = 0; slopecount = 0;
/// Generates vertex slopes.
SpawnVertexSlopes();
/// Generates line special-defined slopes. /// Generates line special-defined slopes.
for (i = 0; i < numlines; i++) for (i = 0; i < numlines; i++)
{ {
@ -577,7 +630,7 @@ void P_ResetDynamicSlopes(const boolean fromsave) {
case 705: case 705:
case 714: case 714:
case 715: case 715:
line_SpawnViaVertexes(i, !fromsave); line_SpawnViaMapthingVertexes(i, !fromsave);
break; break;
default: default:

View File

@ -23,7 +23,7 @@ extern UINT16 slopecount;
void P_LinkSlopeThinkers (void); void P_LinkSlopeThinkers (void);
void P_CalculateSlopeNormal(pslope_t *slope); void P_CalculateSlopeNormal(pslope_t *slope);
void P_ResetDynamicSlopes(const boolean fromsave); void P_SpawnSlopes(const boolean fromsave);
// //
// P_CopySectorSlope // P_CopySectorSlope

View File

@ -6353,7 +6353,7 @@ static void P_RunLevelLoadExecutors(void)
} }
/** Before things are loaded, initialises certain stuff in case they're needed /** Before things are loaded, initialises certain stuff in case they're needed
* by P_ResetDynamicSlopes or P_LoadThings. This was split off from * by P_SpawnSlopes or P_LoadThings. This was split off from
* P_SpawnSpecials, in case you couldn't tell. * P_SpawnSpecials, in case you couldn't tell.
* *
* \sa P_SpawnSpecials, P_InitTagLists * \sa P_SpawnSpecials, P_InitTagLists

View File

@ -8672,7 +8672,7 @@ static void P_MovePlayer(player_t *player)
} }
#ifdef HWRENDER #ifdef HWRENDER
if (rendermode == render_opengl && cv_grfovchange.value) if (rendermode == render_opengl && cv_fovchange.value)
{ {
fixed_t speed; fixed_t speed;
const fixed_t runnyspeed = 20*FRACUNIT; const fixed_t runnyspeed = 20*FRACUNIT;
@ -9279,6 +9279,7 @@ mobj_t *P_LookForFocusTarget(player_t *player, mobj_t *exclude, SINT8 direction,
// If nonenemies is true, includes monitors and springs! // If nonenemies is true, includes monitors and springs!
// If bullet is true, you can look up and the distance is further, // If bullet is true, you can look up and the distance is further,
// but your total angle span you can look is limited to compensate. (Also, allows monitors.) // but your total angle span you can look is limited to compensate. (Also, allows monitors.)
// If you modify this, please also modify P_HomingAttack.
// //
mobj_t *P_LookForEnemies(player_t *player, boolean nonenemies, boolean bullet) mobj_t *P_LookForEnemies(player_t *player, boolean nonenemies, boolean bullet)
{ {
@ -9374,15 +9375,18 @@ boolean P_HomingAttack(mobj_t *source, mobj_t *enemy) // Home in on your target
if (!enemy) if (!enemy)
return false; return false;
if (!enemy->health) if (enemy->flags & MF_NOCLIPTHING)
return false;
if (enemy->health <= 0) // dead
return false;
if (!((enemy->flags & (MF_ENEMY|MF_BOSS|MF_MONITOR) && (enemy->flags & MF_SHOOTABLE)) || (enemy->flags & MF_SPRING)) == !(enemy->flags2 & MF2_INVERTAIMABLE)) // allows if it has the flags desired XOR it has the invert aimable flag
return false; return false;
if (enemy->flags2 & MF2_FRET) if (enemy->flags2 & MF2_FRET)
return false; return false;
if (!(enemy->flags & (MF_SHOOTABLE|MF_SPRING)) == !(enemy->flags2 & MF2_INVERTAIMABLE)) // allows if it has the flags desired XOR it has the invert aimable flag
return false;
// change angle // change angle
source->angle = R_PointToAngle2(source->x, source->y, enemy->x, enemy->y); source->angle = R_PointToAngle2(source->x, source->y, enemy->x, enemy->y);
if (source->player) if (source->player)
@ -10105,13 +10109,6 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
{ {
dist = camdist; dist = camdist;
// x1.5 dist for splitscreen
if (splitscreen)
{
dist = FixedMul(dist, 3*FRACUNIT/2);
camheight = FixedMul(camheight, 3*FRACUNIT/2);
}
if (sign) // signpost camera has specific placement if (sign) // signpost camera has specific placement
{ {
camheight = mo->scale << 7; camheight = mo->scale << 7;
@ -10511,13 +10508,17 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
if (!(multiplayer || netgame) && !splitscreen) if (!(multiplayer || netgame) && !splitscreen)
{ {
fixed_t vx = thiscam->x, vy = thiscam->y; fixed_t vx = thiscam->x, vy = thiscam->y;
fixed_t vz = thiscam->z + thiscam->height / 2;
if (player->awayviewtics && player->awayviewmobj != NULL && !P_MobjWasRemoved(player->awayviewmobj)) // Camera must obviously exist if (player->awayviewtics && player->awayviewmobj != NULL && !P_MobjWasRemoved(player->awayviewmobj)) // Camera must obviously exist
{ {
vx = player->awayviewmobj->x; vx = player->awayviewmobj->x;
vy = player->awayviewmobj->y; vy = player->awayviewmobj->y;
vz = player->awayviewmobj->z + player->awayviewmobj->height / 2;
} }
if (P_AproxDistance(vx - mo->x, vy - mo->y) < FixedMul(48*FRACUNIT, mo->scale)) /* check z distance too for orbital camera */
if (P_AproxDistance(P_AproxDistance(vx - mo->x, vy - mo->y),
vz - ( mo->z + mo->height / 2 )) < FixedMul(48*FRACUNIT, mo->scale))
mo->flags2 |= MF2_SHADOW; mo->flags2 |= MF2_SHADOW;
else else
mo->flags2 &= ~MF2_SHADOW; mo->flags2 &= ~MF2_SHADOW;

View File

@ -84,6 +84,8 @@ typedef struct extracolormap_s
typedef struct typedef struct
{ {
fixed_t x, y; fixed_t x, y;
boolean floorzset, ceilingzset;
fixed_t floorz, ceilingz;
} vertex_t; } vertex_t;
// Forward of linedefs, for sectors. // Forward of linedefs, for sectors.

View File

@ -33,6 +33,7 @@
#include "z_zone.h" #include "z_zone.h"
#include "m_random.h" // quake camera shake #include "m_random.h" // quake camera shake
#include "r_portal.h" #include "r_portal.h"
#include "r_main.h"
#ifdef HWRENDER #ifdef HWRENDER
#include "hardware/hw_main.h" #include "hardware/hw_main.h"
@ -59,6 +60,7 @@ INT32 centerx, centery;
fixed_t centerxfrac, centeryfrac; fixed_t centerxfrac, centeryfrac;
fixed_t projection; fixed_t projection;
fixed_t projectiony; // aspect ratio fixed_t projectiony; // aspect ratio
fixed_t fovtan; // field of view
// just for profiling purposes // just for profiling purposes
size_t framecount; size_t framecount;
@ -108,10 +110,12 @@ static CV_PossibleValue_t drawdist_precip_cons_t[] = {
{1024, "1024"}, {1536, "1536"}, {2048, "2048"}, {1024, "1024"}, {1536, "1536"}, {2048, "2048"},
{0, "None"}, {0, NULL}}; {0, "None"}, {0, NULL}};
static CV_PossibleValue_t fov_cons_t[] = {{60*FRACUNIT, "MIN"}, {179*FRACUNIT, "MAX"}, {0, NULL}};
static CV_PossibleValue_t translucenthud_cons_t[] = {{0, "MIN"}, {10, "MAX"}, {0, NULL}}; static CV_PossibleValue_t translucenthud_cons_t[] = {{0, "MIN"}, {10, "MAX"}, {0, NULL}};
static CV_PossibleValue_t maxportals_cons_t[] = {{0, "MIN"}, {12, "MAX"}, {0, NULL}}; // lmao rendering 32 portals, you're a card static CV_PossibleValue_t maxportals_cons_t[] = {{0, "MIN"}, {12, "MAX"}, {0, NULL}}; // lmao rendering 32 portals, you're a card
static CV_PossibleValue_t homremoval_cons_t[] = {{0, "No"}, {1, "Yes"}, {2, "Flash"}, {0, NULL}}; static CV_PossibleValue_t homremoval_cons_t[] = {{0, "No"}, {1, "Yes"}, {2, "Flash"}, {0, NULL}};
static void Fov_OnChange(void);
static void ChaseCam_OnChange(void); static void ChaseCam_OnChange(void);
static void ChaseCam2_OnChange(void); static void ChaseCam2_OnChange(void);
static void FlipCam_OnChange(void); static void FlipCam_OnChange(void);
@ -125,12 +129,6 @@ consvar_t cv_chasecam2 = {"chasecam2", "On", CV_CALL, CV_OnOff, ChaseCam2_OnChan
consvar_t cv_flipcam = {"flipcam", "No", CV_SAVE|CV_CALL|CV_NOINIT, CV_YesNo, FlipCam_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_flipcam = {"flipcam", "No", CV_SAVE|CV_CALL|CV_NOINIT, CV_YesNo, FlipCam_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_flipcam2 = {"flipcam2", "No", CV_SAVE|CV_CALL|CV_NOINIT, CV_YesNo, FlipCam2_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_flipcam2 = {"flipcam2", "No", CV_SAVE|CV_CALL|CV_NOINIT, CV_YesNo, FlipCam2_OnChange, 0, NULL, NULL, 0, 0, NULL};
#if defined(FLOORSPLATS) || defined(GLBADSHADOWS)
consvar_t cv_shadow = {"shadow", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
#endif //#if defined(FLOORSPLATS) || defined(GLBADSHADOWS)
#ifdef GLBADSHADOWS
consvar_t cv_shadowoffs = {"offsetshadows", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
#endif //#ifdef GLBADSHADOWS
consvar_t cv_skybox = {"skybox", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_skybox = {"skybox", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_allowmlook = {"allowmlook", "Yes", CV_NETVAR, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_allowmlook = {"allowmlook", "Yes", CV_NETVAR, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_showhud = {"showhud", "Yes", CV_CALL, CV_YesNo, R_SetViewSize, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_showhud = {"showhud", "Yes", CV_CALL, CV_YesNo, R_SetViewSize, 0, NULL, NULL, 0, 0, NULL};
@ -141,6 +139,7 @@ consvar_t cv_drawdist = {"drawdist", "Infinite", CV_SAVE, drawdist_cons_t, NULL,
consvar_t cv_drawdist_nights = {"drawdist_nights", "2048", CV_SAVE, drawdist_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_drawdist_nights = {"drawdist_nights", "2048", CV_SAVE, drawdist_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_drawdist_precip = {"drawdist_precip", "1024", CV_SAVE, drawdist_precip_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_drawdist_precip = {"drawdist_precip", "1024", CV_SAVE, drawdist_precip_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
//consvar_t cv_precipdensity = {"precipdensity", "Moderate", CV_SAVE, precipdensity_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; //consvar_t cv_precipdensity = {"precipdensity", "Moderate", CV_SAVE, precipdensity_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_fov = {"fov", "90", CV_FLOAT|CV_CALL, fov_cons_t, Fov_OnChange, 0, NULL, NULL, 0, 0, NULL};
// Okay, whoever said homremoval causes a performance hit should be shot. // Okay, whoever said homremoval causes a performance hit should be shot.
consvar_t cv_homremoval = {"homremoval", "No", CV_SAVE, homremoval_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_homremoval = {"homremoval", "No", CV_SAVE, homremoval_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
@ -184,6 +183,14 @@ void SplitScreen_OnChange(void)
} }
} }
} }
static void Fov_OnChange(void)
{
// Shouldn't be needed with render parity?
//if ((netgame || multiplayer) && !cv_debug && cv_fov.value != 90*FRACUNIT)
// CV_Set(&cv_fov, cv_fov.defaultvalue);
R_SetViewSize();
}
static void ChaseCam_OnChange(void) static void ChaseCam_OnChange(void)
{ {
@ -448,8 +455,8 @@ static void R_InitTextureMapping(void)
// //
// Calc focallength // Calc focallength
// so FIELDOFVIEW angles covers SCREENWIDTH. // so FIELDOFVIEW angles covers SCREENWIDTH.
focallength = FixedDiv(centerxfrac, focallength = FixedDiv(projection,
FINETANGENT(FINEANGLES/4+/*cv_fov.value*/ FIELDOFVIEW/2)); FINETANGENT(FINEANGLES/4+FIELDOFVIEW/2));
#ifdef ESLOPE #ifdef ESLOPE
focallengthf = FIXED_TO_FLOAT(focallength); focallengthf = FIXED_TO_FLOAT(focallength);
@ -457,9 +464,9 @@ static void R_InitTextureMapping(void)
for (i = 0; i < FINEANGLES/2; i++) for (i = 0; i < FINEANGLES/2; i++)
{ {
if (FINETANGENT(i) > FRACUNIT*2) if (FINETANGENT(i) > fovtan*2)
t = -1; t = -1;
else if (FINETANGENT(i) < -FRACUNIT*2) else if (FINETANGENT(i) < -fovtan*2)
t = viewwidth+1; t = viewwidth+1;
else else
{ {
@ -563,6 +570,7 @@ void R_ExecuteSetViewSize(void)
INT32 j; INT32 j;
INT32 level; INT32 level;
INT32 startmapl; INT32 startmapl;
angle_t fov;
setsizeneeded = false; setsizeneeded = false;
@ -585,9 +593,12 @@ void R_ExecuteSetViewSize(void)
centerxfrac = centerx<<FRACBITS; centerxfrac = centerx<<FRACBITS;
centeryfrac = centery<<FRACBITS; centeryfrac = centery<<FRACBITS;
projection = centerxfrac; fov = FixedAngle(cv_fov.value/2) + ANGLE_90;
//projectiony = (((vid.height*centerx*BASEVIDWIDTH)/BASEVIDHEIGHT)/vid.width)<<FRACBITS; fovtan = FINETANGENT(fov >> ANGLETOFINESHIFT);
projectiony = centerxfrac; if (splitscreen == 1) // Splitscreen FOV should be adjusted to maintain expected vertical view
fovtan = 17*fovtan/10;
projection = projectiony = FixedDiv(centerxfrac, fovtan);
R_InitViewBuffer(scaledviewwidth, viewheight); R_InitViewBuffer(scaledviewwidth, viewheight);
@ -608,7 +619,7 @@ void R_ExecuteSetViewSize(void)
for (i = 0; i < j; i++) for (i = 0; i < j; i++)
{ {
dy = ((i - viewheight*8)<<FRACBITS) + FRACUNIT/2; dy = ((i - viewheight*8)<<FRACBITS) + FRACUNIT/2;
dy = abs(dy); dy = FixedMul(abs(dy), fovtan);
yslopetab[i] = FixedDiv(centerx*FRACUNIT, dy); yslopetab[i] = FixedDiv(centerx*FRACUNIT, dy);
} }
} }
@ -1203,15 +1214,10 @@ void R_RegisterEngineStuff(void)
CV_RegisterVar(&cv_drawdist); CV_RegisterVar(&cv_drawdist);
CV_RegisterVar(&cv_drawdist_nights); CV_RegisterVar(&cv_drawdist_nights);
CV_RegisterVar(&cv_drawdist_precip); CV_RegisterVar(&cv_drawdist_precip);
CV_RegisterVar(&cv_fov);
CV_RegisterVar(&cv_chasecam); CV_RegisterVar(&cv_chasecam);
CV_RegisterVar(&cv_chasecam2); CV_RegisterVar(&cv_chasecam2);
#if defined(FLOORSPLATS) || defined(GLBADSHADOWS)
CV_RegisterVar(&cv_shadow);
#endif //#if defined(FLOORSPLATS) || defined(GLBADSHADOWS)
#ifdef GLBADSHADOWS
CV_RegisterVar(&cv_shadowoffs);
#endif //#ifdef GLBADSHADOWS
CV_RegisterVar(&cv_skybox); CV_RegisterVar(&cv_skybox);
CV_RegisterVar(&cv_cam_dist); CV_RegisterVar(&cv_cam_dist);

View File

@ -76,14 +76,9 @@ extern consvar_t cv_showhud, cv_translucenthud;
extern consvar_t cv_homremoval; extern consvar_t cv_homremoval;
extern consvar_t cv_chasecam, cv_chasecam2; extern consvar_t cv_chasecam, cv_chasecam2;
extern consvar_t cv_flipcam, cv_flipcam2; extern consvar_t cv_flipcam, cv_flipcam2;
#if defined(FLOORSPLATS) || defined(GLBADSHADOWS)
extern consvar_t cv_shadow;
#endif
#ifdef GLBADSHADOWS
extern conscar_t cv_shadowoffs;
#endif //#ifdef GLBADSHADOWS
extern consvar_t cv_translucency; extern consvar_t cv_translucency;
extern consvar_t cv_drawdist, cv_drawdist_nights, cv_drawdist_precip; extern consvar_t cv_drawdist, cv_drawdist_nights, cv_drawdist_precip;
extern consvar_t cv_fov;
extern consvar_t cv_skybox; extern consvar_t cv_skybox;
extern consvar_t cv_tailspickup; extern consvar_t cv_tailspickup;

View File

@ -756,9 +756,7 @@ void R_DrawFlippedMaskedColumn(column_t *column, INT32 texheight)
static void R_DrawVisSprite(vissprite_t *vis) static void R_DrawVisSprite(vissprite_t *vis)
{ {
column_t *column; column_t *column;
#ifdef RANGECHECK
INT32 texturecolumn; INT32 texturecolumn;
#endif
fixed_t frac; fixed_t frac;
patch_t *patch = vis->patch; patch_t *patch = vis->patch;
fixed_t this_scale = vis->mobj->scale; fixed_t this_scale = vis->mobj->scale;
@ -891,6 +889,7 @@ static void R_DrawVisSprite(vissprite_t *vis)
if (!(vis->scalestep)) if (!(vis->scalestep))
{ {
sprtopscreen = centeryfrac - FixedMul(dc_texturemid, spryscale); sprtopscreen = centeryfrac - FixedMul(dc_texturemid, spryscale);
sprtopscreen += vis->shear.tan * vis->shear.offset;
dc_iscale = FixedDiv(FRACUNIT, vis->scale); dc_iscale = FixedDiv(FRACUNIT, vis->scale);
} }
@ -906,28 +905,51 @@ static void R_DrawVisSprite(vissprite_t *vis)
if (vis->x2 >= vid.width) if (vis->x2 >= vid.width)
vis->x2 = vid.width-1; vis->x2 = vid.width-1;
for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, frac += vis->xiscale) // Split drawing loops for paper and non-paper to reduce conditional checks per sprite
if (vis->scalestep)
{ {
#ifdef RANGECHECK // Papersprite drawing loop
texturecolumn = frac>>FRACBITS; for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, spryscale += vis->scalestep)
if (texturecolumn < 0 || texturecolumn >= SHORT(patch->width))
I_Error("R_DrawSpriteRange: bad texturecolumn at %d from end", vis->x2 - dc_x);
column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[texturecolumn]));
#else
column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[frac>>FRACBITS]));
#endif
if (vis->scalestep)
{ {
angle_t angle = ((vis->centerangle + xtoviewangle[dc_x]) >> ANGLETOFINESHIFT) & 0xFFF;
texturecolumn = (vis->paperoffset - FixedMul(FINETANGENT(angle), vis->paperdistance)) / this_scale;
if (texturecolumn < 0 || texturecolumn >= SHORT(patch->width))
continue;
if (vis->xiscale < 0) // Flipped sprite
texturecolumn = SHORT(patch->width) - 1 - texturecolumn;
sprtopscreen = (centeryfrac - FixedMul(dc_texturemid, spryscale)); sprtopscreen = (centeryfrac - FixedMul(dc_texturemid, spryscale));
dc_iscale = (0xffffffffu / (unsigned)spryscale); dc_iscale = (0xffffffffu / (unsigned)spryscale);
column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[texturecolumn]));
if (vis->cut & SC_VFLIP)
R_DrawFlippedMaskedColumn(column, patch->height);
else
R_DrawMaskedColumn(column);
}
}
else
{
// Non-paper drawing loop
for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, frac += vis->xiscale, sprtopscreen += vis->shear.tan)
{
#ifdef RANGECHECK
texturecolumn = frac>>FRACBITS;
if (texturecolumn < 0 || texturecolumn >= SHORT(patch->width))
I_Error("R_DrawSpriteRange: bad texturecolumn at %d from end", vis->x2 - dc_x);
column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[texturecolumn]));
#else
column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[frac>>FRACBITS]));
#endif
if (vis->cut & SC_VFLIP)
R_DrawFlippedMaskedColumn(column, patch->height);
else
R_DrawMaskedColumn(column);
} }
if (vis->cut & SC_VFLIP)
R_DrawFlippedMaskedColumn(column, patch->height);
else
R_DrawMaskedColumn(column);
spryscale += vis->scalestep;
} }
colfunc = colfuncs[BASEDRAWFUNC]; colfunc = colfuncs[BASEDRAWFUNC];
@ -1086,7 +1108,264 @@ static void R_SplitSprite(vissprite_t *sprite)
} }
} }
//#define PROPERPAPER // This was reverted less than 7 hours before 2.2's release because of very strange, frequent crashes. //
// R_GetShadowZ(thing, shadowslope)
// Get the first visible floor below the object for shadows
// shadowslope is filled with the floor's slope, if provided
//
fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope)
{
fixed_t z, floorz = INT32_MIN;
pslope_t *slope, *floorslope = NULL;
msecnode_t *node;
sector_t *sector;
ffloor_t *rover;
for (node = thing->touching_sectorlist; node; node = node->m_sectorlist_next)
{
sector = node->m_sector;
slope = (sector->heightsec != -1) ? NULL : sector->f_slope;
z = slope ? P_GetZAt(slope, thing->x, thing->y) : (
(sector->heightsec != -1) ? sectors[sector->heightsec].floorheight : sector->floorheight
);
if (z < thing->z+thing->height/2 && z > floorz)
{
floorz = z;
floorslope = slope;
}
if (sector->ffloors)
for (rover = sector->ffloors; rover; rover = rover->next)
{
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERPLANES) || (rover->alpha < 90 && !(rover->flags & FF_SWIMMABLE)))
continue;
z = *rover->t_slope ? P_GetZAt(*rover->t_slope, thing->x, thing->y) : *rover->topheight;
if (z < thing->z+thing->height/2 && z > floorz)
{
floorz = z;
floorslope = *rover->t_slope;
}
}
}
if (thing->floorz > floorz + (!floorslope ? 0 : FixedMul(abs(floorslope->zdelta), thing->radius*3/2)))
{
floorz = thing->floorz;
floorslope = NULL;
}
#if 0 // Unfortunately, this drops CEZ2 down to sub-17 FPS on my i7.
//#ifdef POLYOBJECTS
// Check polyobjects and see if floorz needs to be altered, for rings only because they don't update floorz
if (thing->type == MT_RING)
{
INT32 xl, xh, yl, yh, bx, by;
xl = (unsigned)(thing->x - thing->radius - bmaporgx)>>MAPBLOCKSHIFT;
xh = (unsigned)(thing->x + thing->radius - bmaporgx)>>MAPBLOCKSHIFT;
yl = (unsigned)(thing->y - thing->radius - bmaporgy)>>MAPBLOCKSHIFT;
yh = (unsigned)(thing->y + thing->radius - bmaporgy)>>MAPBLOCKSHIFT;
BMBOUNDFIX(xl, xh, yl, yh);
validcount++;
for (by = yl; by <= yh; by++)
for (bx = xl; bx <= xh; bx++)
{
INT32 offset;
polymaplink_t *plink; // haleyjd 02/22/06
if (bx < 0 || by < 0 || bx >= bmapwidth || by >= bmapheight)
continue;
offset = by*bmapwidth + bx;
// haleyjd 02/22/06: consider polyobject lines
plink = polyblocklinks[offset];
while (plink)
{
polyobj_t *po = plink->po;
if (po->validcount != validcount) // if polyobj hasn't been checked
{
po->validcount = validcount;
if (!P_MobjInsidePolyobj(po, thing) || !(po->flags & POF_RENDERPLANES))
{
plink = (polymaplink_t *)(plink->link.next);
continue;
}
// We're inside it! Yess...
z = po->lines[0]->backsector->ceilingheight;
if (z < thing->z+thing->height/2 && z > floorz)
{
floorz = z;
floorslope = NULL;
}
}
plink = (polymaplink_t *)(plink->link.next);
}
}
}
#endif
if (shadowslope != NULL)
*shadowslope = floorslope;
return floorz;
}
static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale, fixed_t tx, fixed_t tz)
{
vissprite_t *shadow;
patch_t *patch;
fixed_t xscale, yscale, shadowxscale, shadowyscale, shadowskew, x1, x2;
INT32 light = 0;
fixed_t scalemul; UINT8 trans;
fixed_t floordiff;
fixed_t floorz;
pslope_t *floorslope;
floorz = R_GetShadowZ(thing, &floorslope);
if (abs(floorz-viewz)/tz > 4) return; // Prevent stretchy shadows and possible crashes
floordiff = abs(thing->z - floorz);
trans = floordiff / (100*FRACUNIT) + 3;
if (trans >= 9) return;
scalemul = FixedMul(FRACUNIT - floordiff/640, scale);
patch = W_CachePatchName("DSHADOW", PU_CACHE);
xscale = FixedDiv(projection, tz);
yscale = FixedDiv(projectiony, tz);
shadowxscale = FixedMul(thing->radius*2, scalemul);
shadowyscale = FixedMul(FixedMul(thing->radius*2, scalemul), FixedDiv(abs(floorz - viewz), tz));
shadowyscale = min(shadowyscale, shadowxscale) / patch->height;
shadowxscale /= patch->width;
shadowskew = 0;
if (floorslope)
{
// haha let's try some dumb stuff
fixed_t xslope, zslope;
angle_t sloperelang = (R_PointToAngle(thing->x, thing->y) - floorslope->xydirection) >> ANGLETOFINESHIFT;
xslope = FixedMul(FINESINE(sloperelang), floorslope->zdelta);
zslope = FixedMul(FINECOSINE(sloperelang), floorslope->zdelta);
//CONS_Printf("Shadow is sloped by %d %d\n", xslope, zslope);
if (viewz < floorz)
shadowyscale += FixedMul(FixedMul(thing->radius*2 / patch->height, scalemul), zslope);
else
shadowyscale -= FixedMul(FixedMul(thing->radius*2 / patch->height, scalemul), zslope);
shadowyscale = abs(shadowyscale);
shadowskew = xslope;
}
tx -= patch->width * shadowxscale/2;
x1 = (centerxfrac + FixedMul(tx,xscale))>>FRACBITS;
if (x1 >= viewwidth) return;
tx += patch->width * shadowxscale;
x2 = ((centerxfrac + FixedMul(tx,xscale))>>FRACBITS); x2--;
if (x2 < 0 || x2 <= x1) return;
if (shadowyscale < FRACUNIT/patch->height) return; // fix some crashes?
shadow = R_NewVisSprite();
shadow->patch = patch;
shadow->heightsec = vis->heightsec;
shadow->thingheight = FRACUNIT;
shadow->pz = floorz;
shadow->pzt = shadow->pz + shadow->thingheight;
shadow->mobjflags = 0;
shadow->sortscale = vis->sortscale;
shadow->dispoffset = vis->dispoffset - 5;
shadow->gx = thing->x;
shadow->gy = thing->y;
shadow->gzt = shadow->pz + shadow->patch->height * shadowyscale / 2;
shadow->gz = shadow->gzt - shadow->patch->height * shadowyscale;
shadow->texturemid = FixedMul(thing->scale, FixedDiv(shadow->gzt - viewz, shadowyscale));
if (thing->skin && ((skin_t *)thing->skin)->flags & SF_HIRES)
shadow->texturemid = FixedMul(shadow->texturemid, ((skin_t *)thing->skin)->highresscale);
shadow->scalestep = 0;
shadow->shear.tan = shadowskew; // repurposed variable
shadow->mobj = thing; // Easy access! Tails 06-07-2002
shadow->x1 = x1 < 0 ? 0 : x1;
shadow->x2 = x2 >= viewwidth ? viewwidth-1 : x2;
// PORTAL SEMI-CLIPPING
if (portalrender)
{
if (shadow->x1 < portalclipstart)
shadow->x1 = portalclipstart;
if (shadow->x2 >= portalclipend)
shadow->x2 = portalclipend-1;
}
shadow->xscale = FixedMul(xscale, shadowxscale); //SoM: 4/17/2000
shadow->scale = FixedMul(yscale, shadowyscale);
shadow->sector = vis->sector;
shadow->szt = (INT16)((centeryfrac - FixedMul(shadow->gzt - viewz, yscale))>>FRACBITS);
shadow->sz = (INT16)((centeryfrac - FixedMul(shadow->gz - viewz, yscale))>>FRACBITS);
shadow->cut = SC_ISSCALED|SC_SHADOW; //check this
shadow->startfrac = 0;
//shadow->xiscale = 0x7ffffff0 / (shadow->xscale/2);
shadow->xiscale = (patch->width<<FRACBITS)/(x2-x1+1); // fuck it
if (shadow->x1 > x1)
shadow->startfrac += shadow->xiscale*(shadow->x1-x1);
// reusing x1 variable
x1 += (x2-x1)/2;
shadow->shear.offset = (vis->x1-x1)/2;
if (thing->subsector->sector->numlights)
{
INT32 lightnum;
#ifdef ESLOPE // R_GetPlaneLight won't work on sloped lights!
light = thing->subsector->sector->numlights - 1;
for (lightnum = 1; lightnum < thing->subsector->sector->numlights; lightnum++) {
fixed_t h = thing->subsector->sector->lightlist[lightnum].slope ? P_GetZAt(thing->subsector->sector->lightlist[lightnum].slope, thing->x, thing->y)
: thing->subsector->sector->lightlist[lightnum].height;
if (h <= shadow->gzt) {
light = lightnum - 1;
break;
}
}
#else
light = R_GetPlaneLight(thing->subsector->sector, shadow->gzt, false);
#endif
}
if (thing->subsector->sector->numlights)
shadow->extra_colormap = *thing->subsector->sector->lightlist[light].extra_colormap;
else
shadow->extra_colormap = thing->subsector->sector->extra_colormap;
shadow->transmap = transtables + (trans<<FF_TRANSSHIFT);
shadow->colormap = scalelight[0][0]; // full dark!
objectsdrawn++;
}
// //
// R_ProjectSprite // R_ProjectSprite
@ -1124,7 +1403,11 @@ static void R_ProjectSprite(mobj_t *thing)
fixed_t iscale; fixed_t iscale;
fixed_t scalestep; fixed_t scalestep;
fixed_t offset, offset2; fixed_t offset, offset2;
fixed_t basetx; // drop shadows
boolean papersprite = !!(thing->frame & FF_PAPERSPRITE); boolean papersprite = !!(thing->frame & FF_PAPERSPRITE);
fixed_t paperoffset = 0, paperdistance = 0; angle_t centerangle = 0;
INT32 dispoffset = thing->info->dispoffset; INT32 dispoffset = thing->info->dispoffset;
@ -1142,10 +1425,6 @@ static void R_ProjectSprite(mobj_t *thing)
INT32 rollangle = 0; INT32 rollangle = 0;
#endif #endif
#ifndef PROPERPAPER
fixed_t ang_scale = FRACUNIT;
#endif
// transform the origin point // transform the origin point
tr_x = thing->x - viewx; tr_x = thing->x - viewx;
tr_y = thing->y - viewy; tr_y = thing->y - viewy;
@ -1156,15 +1435,15 @@ static void R_ProjectSprite(mobj_t *thing)
tz = gxt-gyt; tz = gxt-gyt;
// thing is behind view plane? // thing is behind view plane?
if (!(papersprite) && (tz < FixedMul(MINZ, this_scale))) // papersprite clipping is handled later if (!papersprite && (tz < FixedMul(MINZ, this_scale))) // papersprite clipping is handled later
return; return;
gxt = -FixedMul(tr_x, viewsin); gxt = -FixedMul(tr_x, viewsin);
gyt = FixedMul(tr_y, viewcos); gyt = FixedMul(tr_y, viewcos);
tx = -(gyt + gxt); basetx = tx = -(gyt + gxt);
// too far off the side? // too far off the side?
if (abs(tx) > tz<<2) if (!papersprite && abs(tx) > tz<<2) // papersprite clipping is handled later
return; return;
// aspect ratio stuff // aspect ratio stuff
@ -1228,13 +1507,7 @@ static void R_ProjectSprite(mobj_t *thing)
#endif #endif
if (sprframe->rotate != SRF_SINGLE || papersprite) if (sprframe->rotate != SRF_SINGLE || papersprite)
{
ang = R_PointToAngle (thing->x, thing->y) - (thing->player ? thing->player->drawangle : thing->angle); ang = R_PointToAngle (thing->x, thing->y) - (thing->player ? thing->player->drawangle : thing->angle);
#ifndef PROPERPAPER
if (papersprite)
ang_scale = abs(FINESINE(ang>>ANGLETOFINESHIFT));
#endif
}
if (sprframe->rotate == SRF_SINGLE) if (sprframe->rotate == SRF_SINGLE)
{ {
@ -1300,31 +1573,11 @@ static void R_ProjectSprite(mobj_t *thing)
else else
offset = -spr_offset; offset = -spr_offset;
offset = FixedMul(offset, this_scale); offset = FixedMul(offset, this_scale);
#ifndef PROPERPAPER
tx += FixedMul(offset, ang_scale);
x1 = (centerxfrac + FixedMul (tx,xscale)) >>FRACBITS;
// off the right side?
if (x1 > viewwidth)
return;
#endif
offset2 = FixedMul(spr_width, this_scale); offset2 = FixedMul(spr_width, this_scale);
#ifndef PROPERPAPER
tx += FixedMul(offset2, ang_scale);
x2 = ((centerxfrac + FixedMul (tx,xscale)) >> FRACBITS) - (papersprite ? 2 : 1);
// off the left side
if (x2 < 0)
return;
#endif
if (papersprite) if (papersprite)
{ {
fixed_t fixed_t xscale2, yscale2, cosmul, sinmul, tx2, tz2;
#ifdef PROPERPAPER
xscale2,
#endif
yscale2, cosmul, sinmul, tz2;
INT32 range; INT32 range;
if (ang >= ANGLE_180) if (ang >= ANGLE_180)
@ -1342,19 +1595,23 @@ static void R_ProjectSprite(mobj_t *thing)
gyt = -FixedMul(tr_y, viewsin); gyt = -FixedMul(tr_y, viewsin);
tz = gxt-gyt; tz = gxt-gyt;
yscale = FixedDiv(projectiony, tz); yscale = FixedDiv(projectiony, tz);
if (yscale < 64) return; // Fix some funky visuals //if (yscale < 64) return; // Fix some funky visuals
#ifdef PROPERPAPER
gxt = -FixedMul(tr_x, viewsin); gxt = -FixedMul(tr_x, viewsin);
gyt = FixedMul(tr_y, viewcos); gyt = FixedMul(tr_y, viewcos);
tx = -(gyt + gxt); tx = -(gyt + gxt);
xscale = FixedDiv(projection, tz); xscale = FixedDiv(projection, tz);
x1 = (centerxfrac + FixedMul(tx,xscale))>>FRACBITS; x1 = (centerxfrac + FixedMul(tx,xscale))>>FRACBITS;
// off the right side? // Get paperoffset (offset) and paperoffset (distance)
if (x1 > viewwidth) paperoffset = -FixedMul(tr_x, cosmul) - FixedMul(tr_y, sinmul);
return; paperdistance = -FixedMul(tr_x, sinmul) + FixedMul(tr_y, cosmul);
#endif if (paperdistance < 0)
{
paperoffset = -paperoffset;
paperdistance = -paperdistance;
}
centerangle = viewangle - thing->angle;
tr_x += FixedMul(offset2, cosmul); tr_x += FixedMul(offset2, cosmul);
tr_y += FixedMul(offset2, sinmul); tr_y += FixedMul(offset2, sinmul);
@ -1362,38 +1619,52 @@ static void R_ProjectSprite(mobj_t *thing)
gyt = -FixedMul(tr_y, viewsin); gyt = -FixedMul(tr_y, viewsin);
tz2 = gxt-gyt; tz2 = gxt-gyt;
yscale2 = FixedDiv(projectiony, tz2); yscale2 = FixedDiv(projectiony, tz2);
if (yscale2 < 64) return; // ditto //if (yscale2 < 64) return; // ditto
#ifdef PROPERPAPER
gxt = -FixedMul(tr_x, viewsin); gxt = -FixedMul(tr_x, viewsin);
gyt = FixedMul(tr_y, viewcos); gyt = FixedMul(tr_y, viewcos);
tx = -(gyt + gxt); tx2 = -(gyt + gxt);
xscale2 = FixedDiv(projection, tz2); xscale2 = FixedDiv(projection, tz2);
x2 = (centerxfrac + FixedMul(tx,xscale2))>>FRACBITS; x2--; x2 = ((centerxfrac + FixedMul(tx2,xscale2))>>FRACBITS);
if (max(tz, tz2) < FixedMul(MINZ, this_scale)) // non-papersprite clipping is handled earlier
return;
// Needs partially clipped
if (tz < FixedMul(MINZ, this_scale))
{
fixed_t div = FixedDiv(tz2-tz, FixedMul(MINZ, this_scale)-tz);
tx += FixedDiv(tx2-tx, div);
tz = FixedMul(MINZ, this_scale);
yscale = FixedDiv(projectiony, tz);
xscale = FixedDiv(projection, tz);
x1 = (centerxfrac + FixedMul(tx,xscale))>>FRACBITS;
}
else if (tz2 < FixedMul(MINZ, this_scale))
{
fixed_t div = FixedDiv(tz-tz2, FixedMul(MINZ, this_scale)-tz2);
tx2 += FixedDiv(tx-tx2, div);
tz2 = FixedMul(MINZ, this_scale);
yscale2 = FixedDiv(projectiony, tz2);
xscale2 = FixedDiv(projection, tz2);
x2 = (centerxfrac + FixedMul(tx2,xscale2))>>FRACBITS;
}
// off the right side?
if (x1 > viewwidth)
return;
// off the left side // off the left side
if (x2 < 0) if (x2 < 0)
return; return;
#endif
if (max(tz, tz2) < FixedMul(MINZ, this_scale)) // non-papersprite clipping is handled earlier
return;
if ((range = x2 - x1) <= 0) if ((range = x2 - x1) <= 0)
return; return;
#ifdef PROPERPAPER
range++; // fencepost problem range++; // fencepost problem
#endif
scalestep = (yscale2 - yscale)/range; scalestep = ((yscale2 - yscale)/range) ?: 1;
xscale = xscale = FixedDiv(range<<FRACBITS, abs(offset2));
#ifdef PROPERPAPER
FixedDiv(range<<FRACBITS, abs(offset2))+1
#else
FixedMul(xscale, ang_scale)
#endif
;
// The following two are alternate sorting methods which might be more applicable in some circumstances. TODO - maybe enable via MF2? // The following two are alternate sorting methods which might be more applicable in some circumstances. TODO - maybe enable via MF2?
// sortscale = max(yscale, yscale2); // sortscale = max(yscale, yscale2);
@ -1403,7 +1674,6 @@ static void R_ProjectSprite(mobj_t *thing)
{ {
scalestep = 0; scalestep = 0;
yscale = sortscale; yscale = sortscale;
#ifdef PROPERPAPER
tx += offset; tx += offset;
x1 = (centerxfrac + FixedMul(tx,xscale))>>FRACBITS; x1 = (centerxfrac + FixedMul(tx,xscale))>>FRACBITS;
@ -1417,7 +1687,6 @@ static void R_ProjectSprite(mobj_t *thing)
// off the left side // off the left side
if (x2 < 0) if (x2 < 0)
return; return;
#endif
} }
if ((thing->flags2 & MF2_LINKDRAW) && thing->tracer) // toast 16/09/16 (SYMMETRY) if ((thing->flags2 & MF2_LINKDRAW) && thing->tracer) // toast 16/09/16 (SYMMETRY)
@ -1538,6 +1807,11 @@ static void R_ProjectSprite(mobj_t *thing)
vis->pzt = vis->pz + vis->thingheight; vis->pzt = vis->pz + vis->thingheight;
vis->texturemid = vis->gzt - viewz; vis->texturemid = vis->gzt - viewz;
vis->scalestep = scalestep; vis->scalestep = scalestep;
vis->paperoffset = paperoffset;
vis->paperdistance = paperdistance;
vis->centerangle = centerangle;
vis->shear.tan = 0;
vis->shear.offset = 0;
vis->mobj = thing; // Easy access! Tails 06-07-2002 vis->mobj = thing; // Easy access! Tails 06-07-2002
@ -1630,6 +1904,9 @@ static void R_ProjectSprite(mobj_t *thing)
if (thing->subsector->sector->numlights) if (thing->subsector->sector->numlights)
R_SplitSprite(vis); R_SplitSprite(vis);
if (oldthing->shadowscale && !papersprite)
R_ProjectDropShadow(oldthing, vis, oldthing->shadowscale, basetx, tz);
// Debug // Debug
++objectsdrawn; ++objectsdrawn;
} }
@ -1753,6 +2030,9 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing)
vis->pzt = vis->pz + vis->thingheight; vis->pzt = vis->pz + vis->thingheight;
vis->texturemid = vis->gzt - viewz; vis->texturemid = vis->gzt - viewz;
vis->scalestep = 0; vis->scalestep = 0;
vis->paperdistance = 0;
vis->shear.tan = 0;
vis->shear.offset = 0;
vis->x1 = x1 < 0 ? 0 : x1; vis->x1 = x1 < 0 ? 0 : x1;
vis->x2 = x2 >= viewwidth ? viewwidth-1 : x2; vis->x2 = x2 >= viewwidth ? viewwidth-1 : x2;
@ -1945,6 +2225,9 @@ static void R_SortVisSprites(vissprite_t* vsprsortedhead, UINT32 start, UINT32 e
if (!(ds->cut & SC_LINKDRAW)) if (!(ds->cut & SC_LINKDRAW))
continue; continue;
if (ds->cut & SC_SHADOW)
continue;
// reuse dsfirst... // reuse dsfirst...
for (dsfirst = unsorted.prev; dsfirst != &unsorted; dsfirst = dsfirst->prev) for (dsfirst = unsorted.prev; dsfirst != &unsorted; dsfirst = dsfirst->prev)
{ {
@ -1952,6 +2235,10 @@ static void R_SortVisSprites(vissprite_t* vsprsortedhead, UINT32 start, UINT32 e
if (dsfirst->cut & SC_LINKDRAW) if (dsfirst->cut & SC_LINKDRAW)
continue; continue;
// don't connect to your shadow!
if (dsfirst->cut & SC_SHADOW)
continue;
// don't connect if it's not the tracer // don't connect if it's not the tracer
if (dsfirst->mobj != ds->mobj) if (dsfirst->mobj != ds->mobj)
continue; continue;

View File

@ -51,6 +51,8 @@ void R_DrawFlippedMaskedColumn(column_t *column, INT32 texheight);
// (only sprites from namelist are added or replaced) // (only sprites from namelist are added or replaced)
void R_AddSpriteDefs(UINT16 wadnum); void R_AddSpriteDefs(UINT16 wadnum);
fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope);
//SoM: 6/5/2000: Light sprites correctly! //SoM: 6/5/2000: Light sprites correctly!
void R_AddSprites(sector_t *sec, INT32 lightlevel); void R_AddSprites(sector_t *sec, INT32 lightlevel);
void R_InitSprites(void); void R_InitSprites(void);
@ -149,7 +151,8 @@ typedef enum
SC_LINKDRAW = 1<<3, SC_LINKDRAW = 1<<3,
SC_FULLBRIGHT = 1<<4, SC_FULLBRIGHT = 1<<4,
SC_VFLIP = 1<<5, SC_VFLIP = 1<<5,
SC_ISSCALED = 1>>6, SC_ISSCALED = 1<<6,
SC_SHADOW = 1<<7,
// masks // masks
SC_CUTMASK = SC_TOP|SC_BOTTOM, SC_CUTMASK = SC_TOP|SC_BOTTOM,
SC_FLAGMASK = ~SC_CUTMASK SC_FLAGMASK = ~SC_CUTMASK
@ -177,8 +180,16 @@ typedef struct vissprite_s
fixed_t startfrac; // horizontal position of x1 fixed_t startfrac; // horizontal position of x1
fixed_t scale, sortscale; // sortscale only differs from scale for paper sprites and MF2_LINKDRAW fixed_t scale, sortscale; // sortscale only differs from scale for paper sprites and MF2_LINKDRAW
fixed_t scalestep; // only for paper sprites, 0 otherwise fixed_t scalestep; // only for paper sprites, 0 otherwise
fixed_t paperoffset, paperdistance; // for paper sprites, offset/dist relative to the angle
fixed_t xiscale; // negative if flipped fixed_t xiscale; // negative if flipped
angle_t centerangle; // for paper sprites
struct {
fixed_t tan; // The amount to shear the sprite vertically per row
INT32 offset; // The center of the shearing location offset from x1
} shear;
fixed_t texturemid; fixed_t texturemid;
patch_t *patch; patch_t *patch;