Merge remote-tracking branch 'origin/master' into f_wipes

This commit is contained in:
Jaime Passos 2019-11-18 18:48:19 -03:00
commit 8a05afa1aa
52 changed files with 1002 additions and 414 deletions

View File

@ -90,6 +90,7 @@ SINT8 nodetoplayer[MAXNETNODES];
SINT8 nodetoplayer2[MAXNETNODES]; // say the numplayer for this node if any (splitscreen)
UINT8 playerpernode[MAXNETNODES]; // used specialy for scplitscreen
boolean nodeingame[MAXNETNODES]; // set false as nodes leave game
tic_t servermaxping = 800; // server's max ping. Defaults to 800
static tic_t nettics[MAXNETNODES]; // what tic the client have received
static tic_t supposedtics[MAXNETNODES]; // nettics prevision for smaller packet
static UINT8 nodewaiting[MAXNETNODES];
@ -610,6 +611,11 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i)
rsp->health = LONG(players[i].mo->health);
rsp->angle = (angle_t)LONG(players[i].mo->angle);
#ifdef ROTSPRITE
rsp->rollangle = (angle_t)LONG(players[i].mo->rollangle);
#else
rsp->rollangle = 0;
#endif
rsp->x = LONG(players[i].mo->x);
rsp->y = LONG(players[i].mo->y);
rsp->z = LONG(players[i].mo->z);
@ -760,6 +766,9 @@ static void resynch_read_player(resynch_pak *rsp)
//At this point, the player should have a body, whether they were respawned or not.
P_UnsetThingPosition(players[i].mo);
players[i].mo->angle = (angle_t)LONG(rsp->angle);
#ifdef ROTSPRITE
players[i].mo->rollangle = (angle_t)LONG(rsp->rollangle);
#endif
players[i].mo->eflags = (UINT16)SHORT(rsp->eflags);
players[i].mo->flags = LONG(rsp->flags);
players[i].mo->flags2 = LONG(rsp->flags2);
@ -2588,9 +2597,13 @@ static void Command_Nodes(void)
if (playeringame[i])
{
CONS_Printf("%.2u: %*s", i, (int)maxlen, player_names[i]);
CONS_Printf(" - %.2d", playernode[i]);
if (I_GetNodeAddress && (address = I_GetNodeAddress(playernode[i])) != NULL)
CONS_Printf(" - %s", address);
if (playernode[i] != UINT8_MAX)
{
CONS_Printf(" - node %.2d", playernode[i]);
if (I_GetNodeAddress && (address = I_GetNodeAddress(playernode[i])) != NULL)
CONS_Printf(" - %s", address);
}
if (IsPlayerAdmin(i))
CONS_Printf(M_GetText(" (verified admin)"));
@ -3221,10 +3234,10 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum)
{
const char *address;
if (I_GetNodeAddress && (address = I_GetNodeAddress(node)) != NULL)
HU_AddChatText(va("\x82*%s has joined the game (node %d) (%s)", player_names[newplayernum], node, address), false); // merge join notification + IP to avoid clogging console/chat.
HU_AddChatText(va("\x82*%s has joined the game (player %d) (%s)", player_names[newplayernum], newplayernum, address), false); // merge join notification + IP to avoid clogging console/chat.
}
else
HU_AddChatText(va("\x82*%s has joined the game (node %d)", player_names[newplayernum], node), false); // if you don't wanna see the join address.
HU_AddChatText(va("\x82*%s has joined the game (player %d)", player_names[newplayernum], newplayernum), false); // if you don't wanna see the join address.
}
if (server && multiplayer && motd[0] != '\0')
@ -4204,10 +4217,12 @@ static void HandlePacketFromPlayer(SINT8 node)
//Update client ping table from the server.
if (client)
{
INT32 i;
UINT8 i;
for (i = 0; i < MAXPLAYERS; i++)
if (playeringame[i])
playerpingtable[i] = (tic_t)netbuffer->u.pingtable[i];
servermaxping = (tic_t)netbuffer->u.pingtable[MAXPLAYERS];
}
break;
@ -4729,6 +4744,14 @@ void TryRunTics(tic_t realtics)
}
}
/*
Ping Update except better:
We call this once per second and check for people's pings. If their ping happens to be too high, we increment some timer and kick them out.
If they're not lagging, decrement the timer by 1. Of course, reset all of this if they leave.
*/
static INT32 pingtimeout[MAXPLAYERS];
static inline void PingUpdate(void)
{
INT32 i;
@ -4749,6 +4772,8 @@ static inline void PingUpdate(void)
laggers[i] = true;
numlaggers++;
}
else
pingtimeout[i] = 0;
}
//kick lagging players... unless everyone but the server's ping sucks.
@ -4759,12 +4784,27 @@ static inline void PingUpdate(void)
{
if (playeringame[i] && laggers[i])
{
char buf[2];
pingtimeout[i]++;
if (pingtimeout[i] > cv_pingtimeout.value)
// ok your net has been bad for too long, you deserve to die.
{
char buf[2];
buf[0] = (char)i;
buf[1] = KICK_MSG_PING_HIGH;
SendNetXCmd(XD_KICK, &buf, 2);
pingtimeout[i] = 0;
buf[0] = (char)i;
buf[1] = KICK_MSG_PING_HIGH;
SendNetXCmd(XD_KICK, &buf, 2);
}
}
/*
you aren't lagging,
but you aren't free yet.
In case you'll keep spiking,
we just make the timer go back down. (Very unstable net must still get kicked).
*/
else
pingtimeout[i] = (pingtimeout[i] == 0 ? 0 : pingtimeout[i]-1);
}
}
}
@ -4779,10 +4819,13 @@ static inline void PingUpdate(void)
realpingtable[i] = 0; //Reset each as we go.
}
// send the server's maxping as last element of our ping table. This is useful to let us know when we're about to get kicked.
netbuffer->u.pingtable[MAXPLAYERS] = cv_maxping.value;
//send out our ping packets
for (i = 0; i < MAXNETNODES; i++)
if (nodeingame[i])
HSendPacket(i, true, 0, sizeof(INT32) * MAXPLAYERS);
HSendPacket(i, true, 0, sizeof(INT32) * (MAXPLAYERS+1));
pingmeasurecount = 1; //Reset count
}
@ -4812,7 +4855,7 @@ void NetUpdate(void)
if (server)
{
if (netgame && !(gametime % 255))
if (netgame && !(gametime % 35)) // update once per second.
PingUpdate();
// update node latency values so we can take an average later.
for (i = 0; i < MAXPLAYERS; i++)

View File

@ -255,6 +255,7 @@ typedef struct
INT32 health;
angle_t angle;
angle_t rollangle;
fixed_t x;
fixed_t y;
fixed_t z;
@ -423,9 +424,9 @@ typedef struct
serverrefuse_pak serverrefuse; // 65025 bytes (somehow I feel like those values are garbage...)
askinfo_pak askinfo; // 61 bytes
msaskinfo_pak msaskinfo; // 22 bytes
plrinfo playerinfo[MAXPLAYERS]; // 1152 bytes (I'd say 36~38)
plrconfig playerconfig[MAXPLAYERS]; // (up to) 896 bytes (welp they ARE)
UINT32 pingtable[MAXPLAYERS]; // 128 bytes
plrinfo playerinfo[MAXPLAYERS]; // 576 bytes(?)
plrconfig playerconfig[MAXPLAYERS]; // (up to) 528 bytes(?)
UINT32 pingtable[MAXPLAYERS+1]; // 68 bytes
} u; // This is needed to pack diff packet types data together
} ATTRPACK doomdata_t;
@ -487,6 +488,7 @@ extern tic_t jointimeout;
extern UINT16 pingmeasurecount;
extern UINT32 realpingtable[MAXPLAYERS];
extern UINT32 playerpingtable[MAXPLAYERS];
extern tic_t servermaxping;
extern consvar_t cv_joinnextround, cv_allownewplayer, cv_maxplayers, cv_resynchattempts, cv_blamecfail, cv_maxsend, cv_noticedownload, cv_downloadspeed;

View File

@ -180,6 +180,9 @@ void D_ProcessEvents(void)
if (M_ScreenshotResponder(ev))
continue; // ate the event
if (WipeStageTitle)
continue;
if (gameaction == ga_nothing && gamestate == GS_TITLESCREEN)
{
if (cht_Responder(ev))
@ -441,6 +444,17 @@ static void D_Display(void)
if (rendermode != render_none)
{
F_WipeEndScreen();
// Funny.
#ifndef LEVELWIPES
if (WipeStageTitle && st_overlay)
{
lt_ticker--;
lt_lasttic = lt_ticker;
ST_preLevelTitleCardDrawer(0, false);
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, levelfadecol);
F_WipeStartScreen();
}
#endif
F_RunWipe(wipetypepost, gamestate != GS_TIMEATTACK && gamestate != GS_TITLESCREEN);
}
@ -742,14 +756,6 @@ void D_StartTitle(void)
// empty maptol so mario/etc sounds don't play in sound test when they shouldn't
maptol = 0;
// reset to default player stuff
COM_BufAddText (va("%s \"%s\"\n",cv_playername.name,cv_defaultplayername.string));
COM_BufAddText (va("%s \"%s\"\n",cv_skin.name,cv_defaultskin.string));
COM_BufAddText (va("%s \"%s\"\n",cv_playercolor.name,cv_defaultplayercolor.string));
COM_BufAddText (va("%s \"%s\"\n",cv_playername2.name,cv_defaultplayername2.string));
COM_BufAddText (va("%s \"%s\"\n",cv_skin2.name,cv_defaultskin2.string));
COM_BufAddText (va("%s \"%s\"\n",cv_playercolor2.name,cv_defaultplayercolor2.string));
gameaction = ga_nothing;
displayplayer = consoleplayer = 0;
gametype = GT_COOP;

View File

@ -87,6 +87,7 @@ static void JoinTimeout_OnChange(void);
static void CoopStarposts_OnChange(void);
static void CoopLives_OnChange(void);
static void ExitMove_OnChange(void);
static void Ringslinger_OnChange(void);
static void Gravity_OnChange(void);
@ -223,8 +224,8 @@ consvar_t cv_allowseenames = {"allowseenames", "Yes", CV_NETVAR, CV_YesNo, NULL,
#endif
// names
consvar_t cv_playername = {"name", "Sonic", CV_CALL|CV_NOINIT, NULL, Name_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_playername2 = {"name2", "Tails", CV_CALL|CV_NOINIT, NULL, Name2_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_playername = {"name", "Sonic", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Name_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_playername2 = {"name2", "Tails", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Name2_OnChange, 0, NULL, NULL, 0, 0, NULL};
// player colors
consvar_t cv_playercolor = {"color", "Blue", CV_CALL|CV_NOINIT, Color_cons_t, Color_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_playercolor2 = {"color2", "Orange", CV_CALL|CV_NOINIT, Color_cons_t, Color2_OnChange, 0, NULL, NULL, 0, 0, NULL};
@ -233,8 +234,6 @@ consvar_t cv_skin = {"skin", DEFAULTSKIN, CV_CALL|CV_NOINIT, NULL, Skin_OnChange
consvar_t cv_skin2 = {"skin2", DEFAULTSKIN2, CV_CALL|CV_NOINIT, NULL, Skin2_OnChange, 0, NULL, NULL, 0, 0, NULL};
// saved versions of the above six
consvar_t cv_defaultplayername = {"defaultname", "Sonic", CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_defaultplayername2 = {"defaultname2", "Tails", CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_defaultplayercolor = {"defaultcolor", "Blue", CV_SAVE, Color_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_defaultplayercolor2 = {"defaultcolor2", "Orange", CV_SAVE, Color_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_defaultskin = {"defaultskin", DEFAULTSKIN, CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL};
@ -343,6 +342,14 @@ consvar_t cv_nettimeout = {"nettimeout", "350", CV_CALL|CV_SAVE, nettimeout_cons
static CV_PossibleValue_t jointimeout_cons_t[] = {{5*TICRATE, "MIN"}, {60*TICRATE, "MAX"}, {0, NULL}};
consvar_t cv_jointimeout = {"jointimeout", "350", CV_CALL|CV_SAVE, jointimeout_cons_t, JoinTimeout_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_maxping = {"maxping", "0", CV_SAVE, CV_Unsigned, NULL, 0, NULL, NULL, 0, 0, NULL};
static CV_PossibleValue_t pingtimeout_cons_t[] = {{8, "MIN"}, {120, "MAX"}, {0, NULL}};
consvar_t cv_pingtimeout = {"pingtimeout", "10", CV_SAVE, pingtimeout_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
// show your ping on the HUD next to framerate. Defaults to warning only (shows up if your ping is > maxping)
static CV_PossibleValue_t showping_cons_t[] = {{0, "Off"}, {1, "Always"}, {2, "Warning"}, {0, NULL}};
consvar_t cv_showping = {"showping", "Warning", CV_SAVE, showping_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
// Intermission time Tails 04-19-2002
static CV_PossibleValue_t inttime_cons_t[] = {{0, "MIN"}, {3600, "MAX"}, {0, NULL}};
consvar_t cv_inttime = {"inttime", "10", CV_NETVAR, inttime_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
@ -355,9 +362,12 @@ consvar_t cv_cooplives = {"cooplives", "Avoid Game Over", CV_NETVAR|CV_CALL|CV_C
static CV_PossibleValue_t advancemap_cons_t[] = {{0, "Off"}, {1, "Next"}, {2, "Random"}, {0, NULL}};
consvar_t cv_advancemap = {"advancemap", "Next", CV_NETVAR, advancemap_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
static CV_PossibleValue_t playersforexit_cons_t[] = {{0, "One"}, {1, "1/4"}, {2, "Half"}, {3, "3/4"}, {4, "All"}, {0, NULL}};
consvar_t cv_playersforexit = {"playersforexit", "All", CV_NETVAR, playersforexit_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_exitmove = {"exitmove", "Off", CV_NETVAR|CV_CALL, CV_OnOff, ExitMove_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_runscripts = {"runscripts", "Yes", 0, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_pause = {"pausepermission", "Server", CV_NETVAR, pause_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
@ -516,6 +526,7 @@ void D_RegisterServerCommands(void)
CV_RegisterVar(&cv_inttime);
CV_RegisterVar(&cv_advancemap);
CV_RegisterVar(&cv_playersforexit);
CV_RegisterVar(&cv_exitmove);
CV_RegisterVar(&cv_timelimit);
CV_RegisterVar(&cv_playbackspeed);
CV_RegisterVar(&cv_forceskin);
@ -579,6 +590,8 @@ void D_RegisterServerCommands(void)
CV_RegisterVar(&cv_skipmapcheck);
CV_RegisterVar(&cv_sleep);
CV_RegisterVar(&cv_maxping);
CV_RegisterVar(&cv_pingtimeout);
CV_RegisterVar(&cv_showping);
#ifdef SEENAMES
CV_RegisterVar(&cv_allowseenames);
@ -670,10 +683,8 @@ void D_RegisterClientCommands(void)
CV_RegisterVar(&cv_playercolor2);
CV_RegisterVar(&cv_skin2);
// saved versions of the above six
CV_RegisterVar(&cv_defaultplayername);
CV_RegisterVar(&cv_defaultplayercolor);
CV_RegisterVar(&cv_defaultskin);
CV_RegisterVar(&cv_defaultplayername2);
CV_RegisterVar(&cv_defaultplayercolor2);
CV_RegisterVar(&cv_defaultskin2);
@ -3007,7 +3018,7 @@ static void Command_Verify_f(void)
if (COM_Argc() != 2)
{
CONS_Printf(M_GetText("promote <node>: give admin privileges to a node\n"));
CONS_Printf(M_GetText("promote <playernum>: give admin privileges to a player\n"));
return;
}
@ -3063,7 +3074,7 @@ static void Command_RemoveAdmin_f(void)
if (COM_Argc() != 2)
{
CONS_Printf(M_GetText("demote <node>: remove admin privileges from a node\n"));
CONS_Printf(M_GetText("demote <playernum>: remove admin privileges from a player\n"));
return;
}
@ -3782,6 +3793,17 @@ static void CoopLives_OnChange(void)
}
}
static void ExitMove_OnChange(void)
{
if (!(netgame || multiplayer) || gametype != GT_COOP)
return;
if (cv_exitmove.value)
CONS_Printf(M_GetText("Players can now move after completing the level.\n"));
else
CONS_Printf(M_GetText("Players can no longer move after completing the level.\n"));
}
UINT32 timelimitintics = 0;
/** Deals with a timelimit change by printing the change to the console.

View File

@ -26,10 +26,8 @@ extern consvar_t cv_playername2;
extern consvar_t cv_playercolor2;
extern consvar_t cv_skin2;
// saved versions of the above six
extern consvar_t cv_defaultplayername;
extern consvar_t cv_defaultplayercolor;
extern consvar_t cv_defaultskin;
extern consvar_t cv_defaultplayername2;
extern consvar_t cv_defaultplayercolor2;
extern consvar_t cv_defaultskin2;
@ -96,7 +94,7 @@ extern consvar_t cv_recycler;
extern consvar_t cv_itemfinder;
extern consvar_t cv_inttime, cv_coopstarposts, cv_cooplives, cv_advancemap, cv_playersforexit;
extern consvar_t cv_inttime, cv_coopstarposts, cv_cooplives, cv_advancemap, cv_playersforexit, cv_exitmove;
extern consvar_t cv_overtime;
extern consvar_t cv_startinglives;
@ -108,6 +106,9 @@ extern consvar_t cv_ringslinger, cv_soundtest;
extern consvar_t cv_specialrings, cv_powerstones, cv_matchboxes, cv_competitionboxes;
extern consvar_t cv_maxping;
extern consvar_t cv_pingtimeout;
extern consvar_t cv_showping;
extern consvar_t cv_skipmapcheck;

View File

@ -716,7 +716,7 @@ void SV_FileSendTicker(void)
if (ram)
M_Memcpy(p->data, &f->id.ram[transfer[i].position], size);
else if (fread(p->data, 1, size, transfer[i].currentfile) != size)
I_Error("SV_FileSendTicker: can't read %s byte on %s at %d because %s", sizeu1(size), f->id.filename, transfer[i].position, strerror(ferror(transfer[i].currentfile)));
I_Error("SV_FileSendTicker: can't read %s byte on %s at %d because %s", sizeu1(size), f->id.filename, transfer[i].position, M_FileError(transfer[i].currentfile));
p->position = LONG(transfer[i].position);
// Put flag so receiver knows the total size
if (transfer[i].position + size == f->size)
@ -794,7 +794,7 @@ void Got_Filetxpak(void)
// We can receive packet in the wrong order, anyway all os support gaped file
fseek(file->file, pos, SEEK_SET);
if (fwrite(netbuffer->u.filetxpak.data,size,1,file->file) != 1)
I_Error("Can't write to %s: %s\n",filename, strerror(ferror(file->file)));
I_Error("Can't write to %s: %s\n",filename, M_FileError(file->file));
file->currentsize += size;
// Finished?

View File

@ -151,6 +151,7 @@ typedef enum
/*** misc ***/
PF_FORCESTRAFE = 1<<28, // Turning inputs are translated into strafing inputs
PF_CANCARRY = 1<<29, // Can carry another player?
PF_FINISHED = 1<<30, // The player finished the level. NOT the same as exiting
// up to 1<<31 is free
} pflags_t;

View File

@ -1201,6 +1201,14 @@ static void readlevelheader(MYFILE *f, INT32 num)
word2 = tmp += 2;
i = atoi(word2); // used for numerical settings
if (fastcmp(word, "LEVELNAME"))
{
deh_strlcpy(mapheaderinfo[num-1]->lvlttl, word2,
sizeof(mapheaderinfo[num-1]->lvlttl), va("Level header %d: levelname", num));
strlcpy(mapheaderinfo[num-1]->selectheading, word2, sizeof(mapheaderinfo[num-1]->selectheading)); // not deh_ so only complains once
continue;
}
// CHEAP HACK: move this over here for lowercase subtitles
if (fastcmp(word, "SUBTITLE"))
{
@ -1344,12 +1352,6 @@ static void readlevelheader(MYFILE *f, INT32 num)
}
// Strings that can be truncated
else if (fastcmp(word, "LEVELNAME"))
{
deh_strlcpy(mapheaderinfo[num-1]->lvlttl, word2,
sizeof(mapheaderinfo[num-1]->lvlttl), va("Level header %d: levelname", num));
strlcpy(mapheaderinfo[num-1]->selectheading, word2, sizeof(mapheaderinfo[num-1]->selectheading)); // not deh_ so only complains once
}
else if (fastcmp(word, "SELECTHEADING"))
{
deh_strlcpy(mapheaderinfo[num-1]->selectheading, word2,
@ -1573,6 +1575,20 @@ static void readlevelheader(MYFILE *f, INT32 num)
else
mapheaderinfo[num-1]->levelflags &= ~LF_MIXNIGHTSCOUNTDOWN;
}
else if (fastcmp(word, "WARNINGTITLE"))
{
if (i || word2[0] == 'T' || word2[0] == 'Y')
mapheaderinfo[num-1]->levelflags |= LF_WARNINGTITLE;
else
mapheaderinfo[num-1]->levelflags &= ~LF_WARNINGTITLE;
}
else if (fastcmp(word, "NOTITLECARD"))
{
if (i || word2[0] == 'T' || word2[0] == 'Y')
mapheaderinfo[num-1]->levelflags |= LF_NOTITLECARD;
else
mapheaderinfo[num-1]->levelflags &= ~LF_NOTITLECARD;
}
// Individual triggers for menu flags
else if (fastcmp(word, "HIDDEN"))
@ -5343,6 +5359,7 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_FSGNA",
"S_FSGNB",
"S_FSGNC",
"S_FSGND",
// Black Eggman (Boss 7)
"S_BLACKEGG_STND",
@ -7322,13 +7339,9 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_FIREFLOWER2",
"S_FIREFLOWER3",
"S_FIREFLOWER4",
"S_FIREBALL1",
"S_FIREBALL2",
"S_FIREBALL3",
"S_FIREBALL4",
"S_FIREBALLEXP1",
"S_FIREBALLEXP2",
"S_FIREBALLEXP3",
"S_FIREBALL",
"S_FIREBALLTRAIL1",
"S_FIREBALLTRAIL2",
"S_SHELL",
"S_PUMA_START1",
"S_PUMA_START2",
@ -7497,6 +7510,9 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_POPHAT_SHOOT1",
"S_POPHAT_SHOOT2",
"S_POPHAT_SHOOT3",
"S_POPHAT_SHOOT4",
"S_POPSHOT",
"S_POPSHOT_TRAIL",
"S_HIVEELEMENTAL_LOOK",
"S_HIVEELEMENTAL_PREPARE1",
@ -8317,6 +8333,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
"MT_BLUEGOOMBA",
"MT_FIREFLOWER",
"MT_FIREBALL",
"MT_FIREBALLTRAIL",
"MT_SHELL",
"MT_PUMA",
"MT_PUMATRAIL",
@ -8361,6 +8378,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
"MT_PENGUINATOR",
"MT_POPHAT",
"MT_POPSHOT",
"MT_POPSHOT_TRAIL",
"MT_HIVEELEMENTAL",
"MT_BUMBLEBORE",
@ -8570,6 +8588,7 @@ static const char *const PLAYERFLAG_LIST[] = {
/*** misc ***/
"FORCESTRAFE", // Translate turn inputs into strafe inputs
"CANCARRY", // Can carry?
"FINISHED",
NULL // stop loop here.
};
@ -9012,6 +9031,8 @@ struct {
{"LF_NOZONE",LF_NOZONE},
{"LF_SAVEGAME",LF_SAVEGAME},
{"LF_MIXNIGHTSCOUNTDOWN",LF_MIXNIGHTSCOUNTDOWN},
{"LF_NOTITLECARD",LF_NOTITLECARD},
{"LF_WARNINGTITLE",LF_WARNINGTITLE},
// And map flags
{"LF2_HIDEINMENU",LF2_HIDEINMENU},
{"LF2_HIDEINSTATS",LF2_HIDEINSTATS},

View File

@ -98,6 +98,9 @@ void I_FinishUpdate (void)
if (cv_ticrate.value)
SCR_DisplayTicRate();
if (cv_showping.value && netgame && consoleplayer != serverplayer)
SCR_DisplayLocalPing();
//blast it to the screen
// this code sucks
//memcpy(dascreen,screens[0],screenwidth*screenheight);

View File

@ -349,6 +349,8 @@ typedef struct
#define LF_NOZONE 16 ///< Don't include "ZONE" on level title
#define LF_SAVEGAME 32 ///< Save the game upon loading this level
#define LF_MIXNIGHTSCOUNTDOWN 64 ///< Play sfx_timeup instead of music change for NiGHTS countdown
#define LF_WARNINGTITLE 128 ///< WARNING! WARNING! WARNING! WARNING!
#define LF_NOTITLECARD 256 ///< Don't start the title card
#define LF2_HIDEINMENU 1 ///< Hide in the multiplayer menu
#define LF2_HIDEINSTATS 2 ///< Hide in the statistics screen

View File

@ -1389,10 +1389,13 @@ void F_StartGameEvaluation(void)
// Credits option in secrets menu
if (cursaveslot == -1)
{
S_FadeOutStopMusic(2*MUSICRATE);
F_StartGameEnd();
return;
}
S_FadeOutStopMusic(5*MUSICRATE);
G_SetGamestate(GS_EVALUATION);
// Just in case they're open ... somehow
@ -1639,7 +1642,7 @@ void F_StartEnding(void)
gameaction = ga_nothing;
paused = false;
CON_ToggleOff();
S_StopMusic(); // todo: placeholder
S_StopMusic();
S_StopSounds();
finalecount = -10; // what? this totally isn't a hack. why are you asking?
@ -1720,6 +1723,9 @@ void F_EndingTicker(void)
return;
}
if (finalecount == -8)
S_ChangeMusicInternal((goodending ? "_endg" : "_endb"), false);
if (goodending && finalecount == INFLECTIONPOINT) // time to swap some assets
{
endegrk[0] = W_CachePatchName("ENDEGRK2", PU_LEVEL);
@ -2149,7 +2155,6 @@ void F_StartGameEnd(void)
gameaction = ga_nothing;
paused = false;
CON_ToggleOff();
S_StopMusic();
S_StopSounds();
// In case menus are still up?!!
@ -2592,6 +2597,10 @@ void F_TitleScreenDrawer(void)
if (gamestate != GS_TITLESCREEN && gamestate != GS_WAITINGPLAYERS)
return;
// Don't draw if title mode is set to Old/None and the patch isn't there
if (!ttwing && (curttmode == TTMODE_OLD || curttmode == TTMODE_NONE))
return;
// rei|miru: use title pics?
hidepics = curhidepics;
if (hidepics)

View File

@ -142,7 +142,7 @@ void F_MenuPresTicker(boolean run);
extern boolean WipeInAction;
extern boolean WipeInLevel;
extern INT32 lastwipetic;
extern boolean WipeStageTitle;
typedef enum
{
@ -167,6 +167,11 @@ extern wipestyleflags_t wipestyleflags;
#define FADEBLUEFACTOR 10
extern UINT8 wipecolorfill;
extern INT32 lastwipetic;
// Don't know where else to place this constant
// But this file seems appropriate
#define PRELEVELTIME 24 // frames in tics
void F_WipeStartScreen(void);
void F_WipeEndScreen(void);

View File

@ -19,6 +19,7 @@
#include "r_draw.h" // transtable
#include "p_pspr.h" // tr_transxxx
#include "p_local.h"
#include "st_stuff.h"
#include "w_wad.h"
#include "z_zone.h"
@ -30,7 +31,6 @@
#include "m_misc.h" // movie mode
#include "doomstat.h"
#include "st_stuff.h"
#ifdef HAVE_BLUA
#include "lua_hud.h" // level title
@ -92,6 +92,7 @@ UINT8 wipedefs[NUMWIPEDEFS] = {
boolean WipeInAction = false;
boolean WipeInLevel = false;
boolean WipeStageTitle = false;
INT32 lastwipetic = 0;
wipestyle_t wipestyle = WIPESTYLE_NORMAL;
@ -193,22 +194,14 @@ static fademask_t *F_GetFadeMask(UINT8 masknum, UINT8 scrnnum) {
*/
void F_WipeStageTitle(void)
{
if (wipestyle == WIPESTYLE_LEVEL
&& (!titlemapinaction)
&& (wipestyleflags & WSF_FADEIN)
&& *mapheaderinfo[gamemap-1]->lvlttl != '\0'
#ifdef HAVE_BLUA
&& LUA_HudEnabled(hud_stagetitle)
#endif
)
// draw level title
if ((WipeStageTitle && st_overlay)
&& (wipestyle == WIPESTYLE_LEVEL)
&& !(mapheaderinfo[gamemap-1]->levelflags & LF_NOTITLECARD)
&& *mapheaderinfo[gamemap-1]->lvlttl != '\0')
{
stplyr = &players[consoleplayer];
ST_drawLevelTitle(TICRATE);
if (splitscreen)
{
stplyr = &players[secondarydisplayplayer];
ST_drawLevelTitle(TICRATE);
}
ST_runTitleCard();
ST_drawWipeTitleCard();
}
}
@ -457,6 +450,15 @@ void F_RunWipe(UINT8 wipetype, boolean drawMenu)
#endif
F_DoWipe(fmask);
// draw level title
if ((WipeStageTitle && st_overlay)
&& !(mapheaderinfo[gamemap-1]->levelflags & LF_NOTITLECARD)
&& *mapheaderinfo[gamemap-1]->lvlttl != '\0')
{
ST_runTitleCard();
ST_drawWipeTitleCard();
}
I_OsPolling();
I_UpdateNoBlit();
@ -468,8 +470,10 @@ void F_RunWipe(UINT8 wipetype, boolean drawMenu)
if (moviemode)
M_SaveFrame();
}
WipeInAction = false;
WipeInLevel = false;
WipeStageTitle = false;
#endif
}
@ -497,6 +501,7 @@ void F_WipeTicker(void)
// stop
WipeInAction = false;
WipeInLevel = false;
WipeStageTitle = false;
return;
}
@ -508,6 +513,7 @@ void F_WipeTicker(void)
#endif
F_DoWipe(fmask);
#endif
WipeStageTitle = false;
#endif
}

View File

@ -47,6 +47,10 @@
#include "m_cond.h" // condition sets
#include "md5.h" // demo checksums
#ifdef HAVE_BLUA
#include "lua_hud.h"
#endif
gameaction_t gameaction;
gamestate_t gamestate = GS_NULL;
UINT8 ultimatemode = false;
@ -1703,6 +1707,61 @@ void G_DoLoadLevel(boolean resetplayer)
CON_ClearHUD();
}
//
// Start the title card.
//
void G_StartTitleCard(void)
{
// The title card has been disabled for this map.
// Oh well.
if (mapheaderinfo[gamemap-1]->levelflags & LF_NOTITLECARD)
{
WipeStageTitle = false;
return;
}
// clear the hud
CON_ClearHUD();
// prepare status bar
ST_startTitleCard();
// start the title card
WipeStageTitle = (!titlemapinaction);
WipeInLevel = true;
wipestyleflags |= WSF_FADEIN;
wipestyleflags &= ~WSF_FADEOUT;
}
//
// Run the title card before fading in to the level.
//
void G_PreLevelTitleCard(tic_t ticker, boolean update)
{
tic_t starttime = I_GetTime();
tic_t endtime = starttime + (PRELEVELTIME*NEWTICRATERATIO);
tic_t nowtime = starttime;
tic_t lasttime = starttime;
while (nowtime < endtime)
{
// draw loop
while (!((nowtime = I_GetTime()) - lasttime))
I_Sleep();
lasttime = nowtime;
// Run some bullshit whatever
D_ProcessEvents();
ST_runTitleCard();
ST_preLevelTitleCardDrawer(ticker, update);
if (moviemode)
M_SaveFrame();
if (takescreenshot) // Only take screenshots after drawing.
M_DoScreenShot();
}
}
INT32 pausedelay = 0;
boolean pausebreakkey = false;
static INT32 camtoggledelay, camtoggledelay2 = 0;
@ -1992,7 +2051,7 @@ void G_Ticker(boolean run)
if (titledemo)
F_TitleDemoTicker();
P_Ticker(run); // tic the game
ST_Ticker();
ST_Ticker(run);
F_TextPromptTicker();
AM_Ticker();
HU_Ticker();
@ -2833,6 +2892,31 @@ void G_AddPlayer(INT32 playernum)
P_DoPlayerExit(p);
}
boolean G_EnoughPlayersFinished(void)
{
UINT8 numneeded = (G_IsSpecialStage(gamemap) ? 4 : cv_playersforexit.value);
INT32 total = 0;
INT32 exiting = 0;
INT32 i;
for (i = 0; i < MAXPLAYERS; i++)
{
if (!playeringame[i] || players[i].spectator || players[i].bot)
continue;
if (players[i].lives <= 0)
continue;
total++;
if (players[i].pflags & PF_FINISHED)
exiting++;
}
if (exiting)
return exiting * 4 / total >= numneeded;
else
return false;
}
void G_ExitLevel(void)
{
if (gamestate == GS_LEVEL)
@ -4031,7 +4115,7 @@ char *G_BuildMapTitle(INT32 mapnum)
len += strlen(mapheaderinfo[mapnum-1]->lvlttl);
if (!(mapheaderinfo[mapnum-1]->levelflags & LF_NOZONE))
{
zonetext = M_GetText("ZONE");
zonetext = M_GetText("Zone");
len += strlen(zonetext) + 1; // ' ' + zonetext
}
if (actnum > 0)
@ -5194,7 +5278,10 @@ void G_ReadMetalTic(mobj_t *metal)
{ // But wait, there's more!
xziptic = READUINT8(metal_p);
if (xziptic & EZT_FLIP)
{
metal->eflags ^= MFE_VERTICALFLIP;
metal->flags2 ^= MF2_OBJECTFLIP;
}
if (xziptic & EZT_SCALE)
{
metal->destscale = READFIXED(metal_p);

View File

@ -140,7 +140,8 @@ void G_SpawnPlayer(INT32 playernum, boolean starpost);
void G_DeferedInitNew(boolean pultmode, const char *mapname, INT32 pickedchar,
boolean SSSG, boolean FLS);
void G_DoLoadLevel(boolean resetplayer);
void G_StartTitleCard(void);
void G_PreLevelTitleCard(tic_t ticker, boolean update);
void G_DeferedPlayDemo(const char *demo);
// Can be called by the startup code or M_Responder, calls P_SetupLevel.
@ -208,6 +209,7 @@ boolean G_GametypeHasSpectators(void);
boolean G_RingSlingerGametype(void);
boolean G_PlatformGametype(void);
boolean G_TagGametype(void);
boolean G_EnoughPlayersFinished(void);
void G_ExitLevel(void);
void G_NextLevel(void);
void G_Continue(void);

View File

@ -380,9 +380,9 @@ void HWR_DrawStretchyFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t
{
FSurfaceInfo Surf;
Surf.FlatColor.s.red = Surf.FlatColor.s.green = Surf.FlatColor.s.blue = 0xff;
if (alphalevel == 13) Surf.FlatColor.s.alpha = softwaretranstogl_lo[cv_translucenthud.value];
else if (alphalevel == 14) Surf.FlatColor.s.alpha = softwaretranstogl[cv_translucenthud.value];
else if (alphalevel == 15) Surf.FlatColor.s.alpha = softwaretranstogl_hi[cv_translucenthud.value];
if (alphalevel == 13) Surf.FlatColor.s.alpha = softwaretranstogl_lo[st_translucency];
else if (alphalevel == 14) Surf.FlatColor.s.alpha = softwaretranstogl[st_translucency];
else if (alphalevel == 15) Surf.FlatColor.s.alpha = softwaretranstogl_hi[st_translucency];
else Surf.FlatColor.s.alpha = softwaretranstogl[10-alphalevel];
flags |= PF_Modulated;
HWD.pfnDrawPolygon(&Surf, v, 4, flags);
@ -538,9 +538,9 @@ void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscal
{
FSurfaceInfo Surf;
Surf.FlatColor.s.red = Surf.FlatColor.s.green = Surf.FlatColor.s.blue = 0xff;
if (alphalevel == 13) Surf.FlatColor.s.alpha = softwaretranstogl_lo[cv_translucenthud.value];
else if (alphalevel == 14) Surf.FlatColor.s.alpha = softwaretranstogl[cv_translucenthud.value];
else if (alphalevel == 15) Surf.FlatColor.s.alpha = softwaretranstogl_hi[cv_translucenthud.value];
if (alphalevel == 13) Surf.FlatColor.s.alpha = softwaretranstogl_lo[st_translucency];
else if (alphalevel == 14) Surf.FlatColor.s.alpha = softwaretranstogl[st_translucency];
else if (alphalevel == 15) Surf.FlatColor.s.alpha = softwaretranstogl_hi[st_translucency];
else Surf.FlatColor.s.alpha = softwaretranstogl[10-alphalevel];
flags |= PF_Modulated;
HWD.pfnDrawPolygon(&Surf, v, 4, flags);

View File

@ -4068,6 +4068,7 @@ static gr_vissprite_t *HWR_NewVisSprite(void)
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)
{
@ -4098,6 +4099,7 @@ static fixed_t HWR_OpaqueFloorAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t hei
return floorz;
}
#endif //#ifdef GLBADSHADOWS
//
// HWR_DoCulling
@ -4139,6 +4141,7 @@ static boolean HWR_DoCulling(line_t *cullheight, line_t *viewcullheight, float v
return false;
}
#ifdef GLBADSHADOWS
static void HWR_DrawSpriteShadow(gr_vissprite_t *spr, GLPatch_t *gpatch, float this_scale)
{
FOutVector swallVerts[4];
@ -4311,6 +4314,7 @@ static void HWR_DrawSpriteShadow(gr_vissprite_t *spr, GLPatch_t *gpatch, float t
HWD.pfnDrawPolygon(&sSurf, swallVerts, 4, PF_Translucent|PF_Modulated|PF_Clip);
}
}
#endif //#ifdef GLBADSHADOWS
// This is expecting a pointer to an array containing 4 wallVerts for a sprite
static void HWR_RotateSpritePolyToAim(gr_vissprite_t *spr, FOutVector *wallVerts)
@ -4386,6 +4390,7 @@ static void HWR_SplitSprite(gr_vissprite_t *spr)
//Hurdler: 25/04/2000: now support colormap in hardware mode
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.
@ -4401,6 +4406,7 @@ static void HWR_SplitSprite(gr_vissprite_t *spr)
////////////////////
HWR_DrawSpriteShadow(spr, gpatch, this_scale);
}
#endif //#ifdef GLBADSHADOWS
baseWallVerts[0].x = baseWallVerts[3].x = spr->x1;
baseWallVerts[2].x = baseWallVerts[1].x = spr->x2;
@ -4788,6 +4794,7 @@ static void HWR_DrawSprite(gr_vissprite_t *spr)
//Hurdler: 25/04/2000: now support colormap in hardware mode
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.
@ -4803,6 +4810,7 @@ static void HWR_DrawSprite(gr_vissprite_t *spr)
////////////////////
HWR_DrawSpriteShadow(spr, gpatch, this_scale);
}
#endif //#ifdef GLBADSHADOWS
// if it has a dispoffset, push it a little towards the camera
if (spr->dispoffset) {

View File

@ -498,24 +498,24 @@ static void DoSayCommand(SINT8 target, size_t usedargs, UINT8 flags)
if (strlen(msg) > 4 && strnicmp(msg, "/pm", 3) == 0) // used /pm
{
// what we're gonna do now is check if the node exists
// what we're gonna do now is check if the player exists
// with that logic, characters 4 and 5 are our numbers:
const char *newmsg;
char *nodenum = (char*) malloc(3);
INT32 spc = 1; // used if nodenum[1] is a space.
char *playernum = (char*) malloc(3);
INT32 spc = 1; // used if playernum[1] is a space.
strncpy(nodenum, msg+3, 3);
strncpy(playernum, msg+3, 3);
// check for undesirable characters in our "number"
if (((nodenum[0] < '0') || (nodenum[0] > '9')) || ((nodenum[1] < '0') || (nodenum[1] > '9')))
if (((playernum[0] < '0') || (playernum[0] > '9')) || ((playernum[1] < '0') || (playernum[1] > '9')))
{
// check if nodenum[1] is a space
if (nodenum[1] == ' ')
// check if playernum[1] is a space
if (playernum[1] == ' ')
spc = 0;
// let it slide
else
{
HU_AddChatText("\x82NOTICE: \x80Invalid command format. Correct format is \'/pm<node> \'.", false);
free(nodenum);
HU_AddChatText("\x82NOTICE: \x80Invalid command format. Correct format is \'/pm<playernum> \'.", false);
free(playernum);
return;
}
}
@ -524,14 +524,14 @@ static void DoSayCommand(SINT8 target, size_t usedargs, UINT8 flags)
{
if (msg[5] != ' ')
{
HU_AddChatText("\x82NOTICE: \x80Invalid command format. Correct format is \'/pm<node> \'.", false);
free(nodenum);
HU_AddChatText("\x82NOTICE: \x80Invalid command format. Correct format is \'/pm<playernum> \'.", false);
free(playernum);
return;
}
}
target = atoi((const char*) nodenum); // turn that into a number
free(nodenum);
target = atoi((const char*) playernum); // turn that into a number
free(playernum);
//CONS_Printf("%d\n", target);
// check for target player, if it doesn't exist then we can't send the message!
@ -2322,13 +2322,14 @@ void HU_Erase(void)
//
// HU_drawPing
//
void HU_drawPing(INT32 x, INT32 y, INT32 ping, boolean notext)
void HU_drawPing(INT32 x, INT32 y, UINT32 ping, boolean notext, INT32 flags)
{
UINT8 numbars = 1; // how many ping bars do we draw?
UINT8 barcolor = 35; // color we use for the bars (green, yellow or red)
SINT8 i = 0;
SINT8 yoffset = 6;
INT32 dx = x+1 - (V_SmallStringWidth(va("%dms", ping), V_ALLOWLOWERCASE)/2);
INT32 dx = x+1 - (V_SmallStringWidth(va("%dms", ping),
V_ALLOWLOWERCASE|flags)/2);
if (ping < 128)
{
@ -2342,13 +2343,13 @@ void HU_drawPing(INT32 x, INT32 y, INT32 ping, boolean notext)
}
if (!notext || vid.width >= 640) // how sad, we're using a shit resolution.
V_DrawSmallString(dx, y+4, V_ALLOWLOWERCASE, va("%dms", ping));
V_DrawSmallString(dx, y+4, V_ALLOWLOWERCASE|flags, va("%dms", ping));
for (i=0; (i<3); i++) // Draw the ping bar
{
V_DrawFill(x+2 *(i-1), y+yoffset-4, 2, 8-yoffset, 31);
V_DrawFill(x+2 *(i-1), y+yoffset-4, 2, 8-yoffset, 31|flags);
if (i < numbars)
V_DrawFill(x+2 *(i-1), y+yoffset-3, 1, 8-yoffset-1, barcolor);
V_DrawFill(x+2 *(i-1), y+yoffset-3, 1, 8-yoffset-1, barcolor|flags);
yoffset -= 2;
}
@ -2379,7 +2380,7 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I
if (!splitscreen) // don't draw it on splitscreen,
{
if (!(tab[i].num == serverplayer))
HU_drawPing(x+ 253, y+2, playerpingtable[tab[i].num], false);
HU_drawPing(x+ 253, y, playerpingtable[tab[i].num], false, 0);
//else
// V_DrawSmallString(x+ 246, y+4, V_YELLOWMAP, "SERVER");
}
@ -2443,7 +2444,7 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I
V_DrawSmallScaledPatch(x-32, y-4, 0, tagico);
}
if (players[tab[i].num].exiting)
if (players[tab[i].num].exiting || (players[tab[i].num].pflags & PF_FINISHED))
V_DrawSmallScaledPatch(x - SHORT(exiticon->width)/2 - 1, y-3, 0, exiticon);
if (gametype == GT_RACE)
@ -2578,7 +2579,7 @@ static void HU_Draw32TeamTabRankings(playersort_t *tab, INT32 whiteplayer)
if (!splitscreen)
{
if (!(tab[i].num == serverplayer))
HU_drawPing(x+ 135, y+3, playerpingtable[tab[i].num], true);
HU_drawPing(x+ 135, y+1, playerpingtable[tab[i].num], true, 0);
//else
//V_DrawSmallString(x+ 129, y+4, V_YELLOWMAP, "HOST");
}
@ -2702,7 +2703,7 @@ void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer)
if (!splitscreen)
{
if (!(tab[i].num == serverplayer))
HU_drawPing(x+ 113, y+2, playerpingtable[tab[i].num], false);
HU_drawPing(x+ 113, y, playerpingtable[tab[i].num], false, 0);
//else
// V_DrawSmallString(x+ 94, y+4, V_YELLOWMAP, "SERVER");
}
@ -2733,7 +2734,7 @@ void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scoreline
strlcpy(name, tab[i].name, 7);
if (!(tab[i].num == serverplayer))
HU_drawPing(x+ 113, y+2, playerpingtable[tab[i].num], false);
HU_drawPing(x+ 113, y, playerpingtable[tab[i].num], false, 0);
//else
// V_DrawSmallString(x+ 94, y+4, V_YELLOWMAP, "SERVER");
@ -2747,7 +2748,7 @@ void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scoreline
else if (G_TagGametype() && players[tab[i].num].pflags & PF_TAGIT)
V_DrawSmallScaledPatch(x-28, y-4, 0, tagico);
if (players[tab[i].num].exiting)
if (players[tab[i].num].exiting || (players[tab[i].num].pflags & PF_FINISHED))
V_DrawSmallScaledPatch(x - SHORT(exiticon->width)/2 - 1, y-3, 0, exiticon);
// Draw emeralds
@ -2841,7 +2842,7 @@ static void HU_Draw32TabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scor
if (!splitscreen) // don't draw it on splitscreen,
{
if (!(tab[i].num == serverplayer))
HU_drawPing(x+ 135, y+3, playerpingtable[tab[i].num], true);
HU_drawPing(x+ 135, y+1, playerpingtable[tab[i].num], true, 0);
//else
// V_DrawSmallString(x+ 129, y+4, V_YELLOWMAP, "HOST");
}

View File

@ -28,7 +28,7 @@
// Level title font
#define LT_FONTSTART '!' // the first font characters
#define LT_FONTEND 'Z' // the last font characters
#define LT_FONTEND 'z' // the last font characters
#define LT_FONTSIZE (LT_FONTEND - LT_FONTSTART + 1)
#define CRED_FONTSTART '!' // the first font character
@ -113,7 +113,7 @@ void HU_Drawer(void);
char HU_dequeueChatChar(void);
void HU_Erase(void);
void HU_clearChatChars(void);
void HU_drawPing(INT32 x, INT32 y, INT32 ping, boolean notext); // Lat': Ping drawer for scoreboard.
void HU_drawPing(INT32 x, INT32 y, UINT32 ping, boolean notext, INT32 flags); // Lat': Ping drawer for scoreboard.
void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, INT32 whiteplayer);
void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer);
void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, INT32 whiteplayer);

View File

@ -1487,6 +1487,7 @@ state_t states[NUMSTATES] =
{SPR_FSGN, 0|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_FSGNA
{SPR_FSGN, 1|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_FSGNB
{SPR_FSGN, 2|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_FSGNC
{SPR_FSGN, 3|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_FSGND
// Black Eggman (Boss 7)
{SPR_BRAK, 0, 1, {A_SetReactionTime}, 0, 0, S_BLACKEGG_STND2}, // S_BLACKEGG_STND
@ -3527,13 +3528,9 @@ state_t states[NUMSTATES] =
{SPR_FFWR, 3, 3, {NULL}, 0, 0, S_FIREFLOWER1}, // S_FIREFLOWER4
// Thrown Mario Fireball
{SPR_FBLL, FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_FIREBALL2}, // S_FIREBALL1
{SPR_FBLL, FF_FULLBRIGHT|1, 3, {NULL}, 0, 0, S_FIREBALL3}, // S_FIREBALL2
{SPR_FBLL, FF_FULLBRIGHT|2, 3, {NULL}, 0, 0, S_FIREBALL4}, // S_FIREBALL3
{SPR_FBLL, FF_FULLBRIGHT|3, 3, {NULL}, 0, 0, S_FIREBALL1}, // S_FIREBALL4
{SPR_FBLL, FF_FULLBRIGHT|4, 3, {NULL}, 0, 0, S_FIREBALLEXP2}, // S_FIREBALLEXP1
{SPR_FBLL, FF_FULLBRIGHT|5, 3, {NULL}, 0, 0, S_FIREBALLEXP3}, // S_FIREBALLEXP2
{SPR_FBLL, FF_FULLBRIGHT|6, 3, {NULL}, 0, 0, S_NULL}, // S_FIREBALLEXP3
{SPR_FBLL, FF_FULLBRIGHT, 1, {A_SpawnObjectRelative}, 0, MT_FIREBALLTRAIL, S_FIREBALL}, // S_FIREBALL
{SPR_FBLL, 1|FF_FULLBRIGHT|FF_TRANS50, 1, {A_SetScale}, FRACUNIT*3/4, 0, S_FIREBALLTRAIL2}, // S_FIREBALLTRAIL1
{SPR_FBLL, 1|FF_FULLBRIGHT|FF_TRANS50, 8, {A_SetScale}, FRACUNIT/6, 1, S_NULL}, // S_FIREBALLTRAIL2
// Turtle Shell
{SPR_SHLL, 0, -1, {NULL}, 0, 0, S_NULL}, // S_SHELL
@ -3722,9 +3719,12 @@ state_t states[NUMSTATES] =
{SPR_PENG, 0, 5, {A_FaceTarget}, 0, 0, S_PENGUINATOR_LOOK}, // S_PENGUINATOR_SLIDE5
{SPR_POPH, 0, 2, {A_Look}, (2048<<16)|1, 0, S_POPHAT_LOOK}, // S_POPHAT_LOOK
{SPR_POPH, 1, 2, {A_LobShot}, MT_POPSHOT, (70<<16)|60, S_POPHAT_SHOOT2}, // S_POPHAT_SHOOT1
{SPR_POPH, 2, 1, {NULL}, 0, 0, S_POPHAT_SHOOT3}, // S_POPHAT_SHOOT2
{SPR_POPH, 0, 57, {NULL}, 0, 0, S_POPHAT_LOOK}, // S_POPHAT_SHOOT3
{SPR_POPH, 1, 0, {A_MultiShotDist}, (MT_SPINDUST<<16)|4, 24, S_POPHAT_SHOOT2}, // S_POPHAT_SHOOT1
{SPR_POPH, 1, 2, {A_LobShot}, MT_POPSHOT, (70<<16)|60, S_POPHAT_SHOOT3}, // S_POPHAT_SHOOT2
{SPR_POPH, 2, 1, {NULL}, 0, 0, S_POPHAT_SHOOT4}, // S_POPHAT_SHOOT3
{SPR_POPH, 0, 57, {NULL}, 0, 0, S_POPHAT_LOOK}, // S_POPHAT_SHOOT4
{SPR_POPH, 3, 3, {A_SpawnObjectRelative}, 0, MT_POPSHOT_TRAIL, S_POPSHOT}, // S_POPSHOT
{SPR_NULL, 0, 2, {NULL}, 0, 0, S_SPINDUST1}, // S_POPSHOT_TRAIL
{SPR_HIVE, 0, 5, {A_Look}, 1, 1, S_HIVEELEMENTAL_LOOK}, // S_HIVEELEMENTAL_LOOK
{SPR_HIVE, 0, 14, {A_PlaySound}, sfx_s3k76, 1, S_HIVEELEMENTAL_PREPARE2}, // S_HIVEELEMENTAL_PREPARE1
@ -6115,11 +6115,11 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL, // meleestate
S_NULL, // missilestate
S_FSGNC, // deathstate
S_NULL, // xdeathstate
S_FSGND, // xdeathstate
sfx_None, // deathsound
0, // speed
124*FRACUNIT, // radius
640*FRACUNIT, // height
74*FRACUNIT, // radius
320*FRACUNIT, // height
0, // display offset
0, // mass
0, // damage
@ -18910,31 +18910,58 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
{ // MT_FIREBALL
-1, // doomednum
S_FIREBALL1, // spawnstate
S_FIREBALL, // spawnstate
1000, // spawnhealth
S_FIREBALLEXP1, // seestate
S_NULL, // seestate
sfx_None, // seesound
8, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
0, // painchance
sfx_None, // painsound
S_FIREBALLEXP1, // meleestate
S_FIREBALLEXP1, // missilestate
S_FIREBALLEXP1, // deathstate
S_FIREBALLEXP1, // xdeathstate
sfx_mario1, // deathsound
10*FRACUNIT, // speed
S_NULL, // meleestate
S_NULL, // missilestate
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
40*FRACUNIT, // speed
4*FRACUNIT, // radius
8*FRACUNIT, // height
0, // display offset
DMG_FIRE, // mass
1, // damage
sfx_None, // activesound
MF_NOBLOCKMAP|MF_FIRE|MF_MISSILE, // flags
MF_FIRE|MF_BOUNCE|MF_MISSILE, // flags
S_NULL // raisestate
},
{ // MT_FIREBALLTRAIL
-1, // doomednum
S_FIREBALLTRAIL1, // spawnstate
1000, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
8, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
0, // painchance
sfx_None, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
0, // speed
16*FRACUNIT, // radius
16*FRACUNIT, // height
0, // display offset
0, // mass
1, // damage
sfx_None, // activesound
MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP|MF_RUNSPAWNFUNC, // flags
S_NULL // raisestate
},
{ // MT_SHELL
1804, // doomednum
S_SHELL, // spawnstate
@ -19989,10 +20016,10 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
{ // MT_POPSHOT
-1, // doomednum
S_ROCKCRUMBLEI, // spawnstate
S_POPSHOT, // spawnstate
1, // spawnhealth
S_NULL, // seestate
sfx_cannon, // seesound
sfx_kc4c, // seesound
0, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
@ -20000,9 +20027,9 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
sfx_None, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_XPLD1, // deathstate
S_SONIC3KBOSSEXPLOSION1, // deathstate
S_NULL, // xdeathstate
sfx_pop, // deathsound
sfx_cybdth, // deathsound
0, // speed
16*FRACUNIT, // radius
32*FRACUNIT, // height
@ -20014,6 +20041,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL // raisestate
},
{ // MT_POPSHOT_TRAIL
-1, // doomednum
S_POPSHOT_TRAIL,// spawnstate
1000, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
8, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
0, // painchance
sfx_None, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
4*FRACUNIT, // speed
4*FRACUNIT, // radius
4*FRACUNIT, // height
0, // display offset
4, // mass
0, // damage
sfx_None, // activesound
MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_NOCLIP, // flags
S_NULL // raisestate
},
{ // MT_HIVEELEMENTAL
127, // doomednum
S_HIVEELEMENTAL_LOOK, // spawnstate

View File

@ -1657,6 +1657,7 @@ typedef enum state
S_FSGNA,
S_FSGNB,
S_FSGNC,
S_FSGND,
// Black Eggman (Boss 7)
S_BLACKEGG_STND,
@ -3637,13 +3638,9 @@ typedef enum state
S_FIREFLOWER2,
S_FIREFLOWER3,
S_FIREFLOWER4,
S_FIREBALL1,
S_FIREBALL2,
S_FIREBALL3,
S_FIREBALL4,
S_FIREBALLEXP1,
S_FIREBALLEXP2,
S_FIREBALLEXP3,
S_FIREBALL,
S_FIREBALLTRAIL1,
S_FIREBALLTRAIL2,
S_SHELL,
S_PUMA_START1,
S_PUMA_START2,
@ -3812,6 +3809,9 @@ typedef enum state
S_POPHAT_SHOOT1,
S_POPHAT_SHOOT2,
S_POPHAT_SHOOT3,
S_POPHAT_SHOOT4,
S_POPSHOT,
S_POPSHOT_TRAIL,
S_HIVEELEMENTAL_LOOK,
S_HIVEELEMENTAL_PREPARE1,
@ -4654,6 +4654,7 @@ typedef enum mobj_type
MT_BLUEGOOMBA,
MT_FIREFLOWER,
MT_FIREBALL,
MT_FIREBALLTRAIL,
MT_SHELL,
MT_PUMA,
MT_PUMATRAIL,
@ -4698,6 +4699,7 @@ typedef enum mobj_type
MT_PENGUINATOR,
MT_POPHAT,
MT_POPSHOT,
MT_POPSHOT_TRAIL,
MT_HIVEELEMENTAL,
MT_BUMBLEBORE,

View File

@ -1165,6 +1165,17 @@ static int lib_pElementalFire(lua_State *L)
return 0;
}
static int lib_pDoPlayerFinish(lua_State *L)
{
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
NOHUD
INLEVEL
if (!player)
return LUA_ErrInvalid(L, "player_t");
P_DoPlayerFinish(player);
return 0;
}
static int lib_pDoPlayerExit(lua_State *L)
{
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
@ -2674,6 +2685,13 @@ static int lib_gSetCustomExitVars(lua_State *L)
return 0;
}
static int lib_gEnoughPlayersFinished(lua_State *L)
{
INLEVEL
lua_pushboolean(L, G_EnoughPlayersFinished());
return 1;
}
static int lib_gExitLevel(lua_State *L)
{
int n = lua_gettop(L); // Num arguments
@ -2869,6 +2887,7 @@ static luaL_Reg lib[] = {
{"P_DoBubbleBounce",lib_pDoBubbleBounce},
{"P_BlackOw",lib_pBlackOw},
{"P_ElementalFire",lib_pElementalFire},
{"P_DoPlayerFinish",lib_pDoPlayerFinish},
{"P_DoPlayerExit",lib_pDoPlayerExit},
{"P_InstaThrust",lib_pInstaThrust},
{"P_ReturnThrustX",lib_pReturnThrustX},
@ -2981,6 +3000,7 @@ static luaL_Reg lib[] = {
{"G_BuildMapName",lib_gBuildMapName},
{"G_DoReborn",lib_gDoReborn},
{"G_SetCustomExitVars",lib_gSetCustomExitVars},
{"G_EnoughPlayersFinished",lib_gEnoughPlayersFinished},
{"G_ExitLevel",lib_gExitLevel},
{"G_IsSpecialStage",lib_gIsSpecialStage},
{"G_GametypeUsesLives",lib_gGametypeUsesLives},

View File

@ -43,3 +43,4 @@ boolean LUA_HudEnabled(enum hud option);
void LUAh_GameHUD(player_t *stplyr);
void LUAh_ScoresHUD(void);
void LUAh_TitleHUD(void);
void LUAh_TitleCardHUD(player_t *stplyr);

View File

@ -92,12 +92,14 @@ static const char *const patch_opt[] = {
enum hudhook {
hudhook_game = 0,
hudhook_scores,
hudhook_title
hudhook_title,
hudhook_titlecard
};
static const char *const hudhook_opt[] = {
"game",
"scores",
"title",
"titlecard",
NULL};
// alignment types for v.drawString
@ -910,9 +912,17 @@ static int libd_RandomChance(lua_State *L)
return 1;
}
// 30/10/18 Lat': Get cv_translucenthud's value for HUD rendering as a normal V_xxTRANS int
// 30/10/18 Lat': Get st_translucency's value for HUD rendering as a normal V_xxTRANS int
// Could as well be thrown in global vars for ease of access but I guess it makes sense for it to be a HUD fn
static int libd_getlocaltransflag(lua_State *L)
{
HUDONLY
lua_pushinteger(L, (10-st_translucency)*V_10TRANS);
return 1;
}
// Get cv_translucenthud's value for HUD rendering as a normal V_xxTRANS int
static int libd_getusertransflag(lua_State *L)
{
HUDONLY
lua_pushinteger(L, (10-cv_translucenthud.value)*V_10TRANS); // A bit weird that it's called "translucenthud" yet 10 is fully opaque :V
@ -954,6 +964,7 @@ static luaL_Reg lib_draw[] = {
{"dupy", libd_dupy},
{"renderer", libd_renderer},
{"localTransFlag", libd_getlocaltransflag},
{"userTransFlag", libd_getusertransflag},
{NULL, NULL}
};
@ -1043,6 +1054,9 @@ int LUA_HudLib(lua_State *L)
lua_newtable(L);
lua_rawseti(L, -2, 4); // HUD[3] = title rendering functions array
lua_newtable(L);
lua_rawseti(L, -2, 5); // HUD[4] = title card rendering functions array
lua_setfield(L, LUA_REGISTRYINDEX, "HUD");
luaL_newmetatable(L, META_HUDINFO);
@ -1180,4 +1194,38 @@ void LUAh_TitleHUD(void)
hud_running = false;
}
void LUAh_TitleCardHUD(player_t *stplayr)
{
if (!gL || !(hudAvailable & (1<<hudhook_titlecard)))
return;
hud_running = true;
lua_pop(gL, -1);
lua_getfield(gL, LUA_REGISTRYINDEX, "HUD");
I_Assert(lua_istable(gL, -1));
lua_rawgeti(gL, -1, 5); // HUD[5] = rendering funcs
I_Assert(lua_istable(gL, -1));
lua_rawgeti(gL, -2, 1); // HUD[1] = lib_draw
I_Assert(lua_istable(gL, -1));
lua_remove(gL, -3); // pop HUD
LUA_PushUserdata(gL, stplayr, META_PLAYER);
lua_pushinteger(gL, lt_ticker);
lua_pushinteger(gL, (lt_endtime + TICRATE));
lua_pushnil(gL);
while (lua_next(gL, -6) != 0) {
lua_pushvalue(gL, -6); // graphics library (HUD[1])
lua_pushvalue(gL, -6); // stplayr
lua_pushvalue(gL, -6); // lt_ticker
lua_pushvalue(gL, -6); // lt_endtime
LUA_Call(gL, 4);
}
lua_pop(gL, -1);
hud_running = false;
}
#endif

View File

@ -744,7 +744,7 @@ static int power_get(lua_State *L)
UINT16 *powers = *((UINT16 **)luaL_checkudata(L, 1, META_POWERS));
powertype_t p = luaL_checkinteger(L, 2);
if (p >= NUMPOWERS)
return luaL_error(L, LUA_QL("powertype_t") " cannot be %u", p);
return luaL_error(L, LUA_QL("powertype_t") " cannot be %d", (INT16)p);
lua_pushinteger(L, powers[p]);
return 1;
}
@ -756,7 +756,7 @@ static int power_set(lua_State *L)
powertype_t p = luaL_checkinteger(L, 2);
UINT16 i = (UINT16)luaL_checkinteger(L, 3);
if (p >= NUMPOWERS)
return luaL_error(L, LUA_QL("powertype_t") " cannot be %u", p);
return luaL_error(L, LUA_QL("powertype_t") " cannot be %d", (INT16)p);
if (hud_running)
return luaL_error(L, "Do not alter player_t in HUD rendering code!");
powers[p] = i;

View File

@ -16,6 +16,7 @@
#include "doomdef.h"
#include "command.h"
#include "m_argv.h"
#include "m_misc.h"
/** \brief number of arg
*/
@ -161,7 +162,7 @@ void M_FindResponseFile(void)
if (!file)
I_Error("No more free memory for the response file");
if (fread(file, size, 1, handle) != 1)
I_Error("Couldn't read response file because %s", strerror(ferror(handle)));
I_Error("Couldn't read response file because %s", M_FileError(handle));
fclose(handle);
// keep all the command line arguments following @responsefile

View File

@ -201,14 +201,7 @@ FUNCMATH FUNCINLINE static ATTRINLINE fixed_t FixedDiv(fixed_t a, fixed_t b)
*/
FUNCMATH FUNCINLINE static ATTRINLINE fixed_t FixedRem(fixed_t x, fixed_t y)
{
const boolean n = x < 0;
x = abs(x);
while (x >= y)
x -= y;
if (n)
return -x;
else
return x;
return x % y;
}
/** \brief The FixedSqrt function

View File

@ -1224,32 +1224,33 @@ static menuitem_t OP_VideoOptionsMenu[] =
NULL, "HUD Transparency", &cv_translucenthud, 66},
{IT_STRING | IT_CVAR, NULL, "Score/Time/Rings", &cv_timetic, 71},
{IT_STRING | IT_CVAR, NULL, "Show Powerups", &cv_powerupdisplay, 76},
{IT_STRING | IT_CVAR, NULL, "Local ping display", &cv_showping, 81}, // shows ping next to framerate if we want to.
#ifdef SEENAMES
{IT_STRING | IT_CVAR, NULL, "Show player names", &cv_seenames, 81},
{IT_STRING | IT_CVAR, NULL, "Show player names", &cv_seenames, 86},
#endif
{IT_HEADER, NULL, "Console", NULL, 90},
{IT_STRING | IT_CVAR, NULL, "Background color", &cons_backcolor, 96},
{IT_STRING | IT_CVAR, NULL, "Text Size", &cv_constextsize, 101},
{IT_HEADER, NULL, "Console", NULL, 95},
{IT_STRING | IT_CVAR, NULL, "Background color", &cons_backcolor, 101},
{IT_STRING | IT_CVAR, NULL, "Text Size", &cv_constextsize, 106},
{IT_HEADER, NULL, "Chat", NULL, 110},
{IT_STRING | IT_CVAR, NULL, "Chat Mode", &cv_consolechat, 116},
{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Chat Box Width", &cv_chatwidth, 121},
{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Chat Box Height", &cv_chatheight, 126},
{IT_STRING | IT_CVAR, NULL, "Message Fadeout Time", &cv_chattime, 131},
{IT_STRING | IT_CVAR, NULL, "Chat Notifications", &cv_chatnotifications, 136},
{IT_STRING | IT_CVAR, NULL, "Spam Protection", &cv_chatspamprotection, 141},
{IT_STRING | IT_CVAR, NULL, "Chat background tint", &cv_chatbacktint, 146},
{IT_HEADER, NULL, "Chat", NULL, 115},
{IT_STRING | IT_CVAR, NULL, "Chat Mode", &cv_consolechat, 121},
{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Chat Box Width", &cv_chatwidth, 126},
{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Chat Box Height", &cv_chatheight, 131},
{IT_STRING | IT_CVAR, NULL, "Message Fadeout Time", &cv_chattime, 136},
{IT_STRING | IT_CVAR, NULL, "Chat Notifications", &cv_chatnotifications, 141},
{IT_STRING | IT_CVAR, NULL, "Spam Protection", &cv_chatspamprotection, 146},
{IT_STRING | IT_CVAR, NULL, "Chat background tint", &cv_chatbacktint, 151},
{IT_HEADER, NULL, "Level", NULL, 155},
{IT_STRING | IT_CVAR, NULL, "Draw Distance", &cv_drawdist, 161},
{IT_STRING | IT_CVAR, NULL, "Weather Draw Dist.", &cv_drawdist_precip, 166},
{IT_STRING | IT_CVAR, NULL, "NiGHTS Hoop Draw Dist.", &cv_drawdist_nights, 171},
{IT_HEADER, NULL, "Level", NULL, 160},
{IT_STRING | IT_CVAR, NULL, "Draw Distance", &cv_drawdist, 166},
{IT_STRING | IT_CVAR, NULL, "Weather Draw Dist.", &cv_drawdist_precip, 171},
{IT_STRING | IT_CVAR, NULL, "NiGHTS Hoop Draw Dist.", &cv_drawdist_nights, 176},
{IT_HEADER, NULL, "Diagnostic", NULL, 180},
{IT_STRING | IT_CVAR, NULL, "Show FPS", &cv_ticrate, 186},
{IT_STRING | IT_CVAR, NULL, "Clear Before Redraw", &cv_homremoval, 191},
{IT_STRING | IT_CVAR, NULL, "Show \"FOCUS LOST\"", &cv_showfocuslost, 196},
{IT_HEADER, NULL, "Diagnostic", NULL, 184},
{IT_STRING | IT_CVAR, NULL, "Show FPS", &cv_ticrate, 190},
{IT_STRING | IT_CVAR, NULL, "Clear Before Redraw", &cv_homremoval, 195},
{IT_STRING | IT_CVAR, NULL, "Show \"FOCUS LOST\"", &cv_showfocuslost, 200},
};
static menuitem_t OP_VideoModeMenu[] =
@ -7179,7 +7180,7 @@ static void M_DrawSoundTest(void)
titl = va("%s - ", curplaying->title);
}
else
titl = "NONE - ";
titl = "None - ";
i = V_LevelNameWidth(titl);
@ -7193,7 +7194,7 @@ static void M_DrawSoundTest(void)
while (x > y)
{
x -= i;
V_DrawLevelTitle(x, 24, 0, titl);
V_DrawLevelTitle(x, 22, 0, titl);
}
if (curplaying)
@ -10472,7 +10473,6 @@ static consvar_t *setupm_cvcolor;
static consvar_t *setupm_cvname;
static consvar_t *setupm_cvdefaultskin;
static consvar_t *setupm_cvdefaultcolor;
static consvar_t *setupm_cvdefaultname;
static INT32 setupm_fakeskin;
static INT32 setupm_fakecolor;
@ -10634,8 +10634,7 @@ colordraw:
V_DrawString(x, y,
((R_SkinAvailable(setupm_cvdefaultskin->string) != setupm_fakeskin
|| setupm_cvdefaultcolor->value != setupm_fakecolor
|| strcmp(setupm_name, setupm_cvdefaultname->string))
|| setupm_cvdefaultcolor->value != setupm_fakecolor)
? 0
: V_TRANSLUCENT)
| ((itemOn == 3) ? V_YELLOWMAP : 0),
@ -10690,14 +10689,12 @@ static void M_HandleSetupMultiPlayer(INT32 choice)
case KEY_ENTER:
if (itemOn == 3
&& (R_SkinAvailable(setupm_cvdefaultskin->string) != setupm_fakeskin
|| setupm_cvdefaultcolor->value != setupm_fakecolor
|| strcmp(setupm_name, setupm_cvdefaultname->string)))
|| setupm_cvdefaultcolor->value != setupm_fakecolor))
{
S_StartSound(NULL,sfx_strpst);
// you know what? always putting these in the buffer won't hurt anything.
COM_BufAddText (va("%s \"%s\"\n",setupm_cvdefaultskin->name,skins[setupm_fakeskin].name));
COM_BufAddText (va("%s %d\n",setupm_cvdefaultcolor->name,setupm_fakecolor));
COM_BufAddText (va("%s %s\n",setupm_cvdefaultname->name,setupm_name));
break;
}
/* FALLTHRU */
@ -10796,7 +10793,6 @@ static void M_SetupMultiPlayer(INT32 choice)
setupm_cvname = &cv_playername;
setupm_cvdefaultskin = &cv_defaultskin;
setupm_cvdefaultcolor = &cv_defaultplayercolor;
setupm_cvdefaultname = &cv_defaultplayername;
// For whatever reason this doesn't work right if you just use ->value
setupm_fakeskin = R_SkinAvailable(setupm_cvskin->string);
@ -10838,7 +10834,6 @@ static void M_SetupMultiPlayer2(INT32 choice)
setupm_cvname = &cv_playername2;
setupm_cvdefaultskin = &cv_defaultskin2;
setupm_cvdefaultcolor = &cv_defaultplayercolor2;
setupm_cvdefaultname = &cv_defaultplayername2;
// For whatever reason this doesn't work right if you just use ->value
setupm_fakeskin = R_SkinAvailable(setupm_cvskin->string);

View File

@ -23,6 +23,8 @@
#include <unistd.h>
#endif
#include <errno.h>
// Extended map support.
#include <ctype.h>
@ -521,6 +523,12 @@ void M_FirstLoadConfig(void)
// make sure I_Quit() will write back the correct config
// (do not write back the config if it crash before)
gameconfig_loaded = true;
// reset to default player stuff
COM_BufAddText (va("%s \"%s\"\n",cv_skin.name,cv_defaultskin.string));
COM_BufAddText (va("%s \"%s\"\n",cv_playercolor.name,cv_defaultplayercolor.string));
COM_BufAddText (va("%s \"%s\"\n",cv_skin2.name,cv_defaultskin2.string));
COM_BufAddText (va("%s \"%s\"\n",cv_playercolor2.name,cv_defaultplayercolor2.string));
}
/** Saves the game configuration.
@ -2435,3 +2443,13 @@ void M_SetupMemcpy(void)
M_Memcpy = cpu_cpy;
#endif
}
/** Return the appropriate message for a file error or end of file.
*/
const char *M_FileError(FILE *fp)
{
if (ferror(fp))
return strerror(errno);
else
return "end-of-file";
}

View File

@ -94,6 +94,8 @@ void strcatbf(char *s1, const char *s2, const char *s3);
void M_SetupMemcpy(void);
const char *M_FileError(FILE *handle);
// counting bits, for weapon ammo code, usually
FUNCMATH UINT8 M_CountBits(UINT32 num, UINT8 size);

View File

@ -4070,19 +4070,28 @@ bossjustdie:
mobj_t *pole = P_SpawnMobj(
mo->tracer->x - P_ReturnThrustX(mo->tracer, mo->tracer->angle, speed*time),
mo->tracer->y - P_ReturnThrustY(mo->tracer, mo->tracer->angle, speed*time),
mo->tracer->floorz + 4*FRACUNIT,
mo->tracer->floorz + (256+1)*FRACUNIT,
MT_FSGNB);
P_SetTarget(&pole->tracer, P_SpawnMobj(
pole->x, pole->y,
pole->z - 256*FRACUNIT,
MT_FSGNB));
P_SetTarget(&pole->tracer->tracer, P_SpawnMobj(
pole->x + P_ReturnThrustX(pole, mo->tracer->angle, FRACUNIT),
pole->y + P_ReturnThrustY(pole, mo->tracer->angle, FRACUNIT),
pole->z + 256*FRACUNIT,
MT_FSGNA));
pole->angle = mo->tracer->angle;
pole->tracer->angle = pole->angle - ANGLE_90;
pole->tracer->flags |= MF_NOCLIPTHING;
P_SetScale(pole, (pole->destscale = 2*FRACUNIT));
P_SetScale(pole->tracer, (pole->tracer->destscale = 2*FRACUNIT));
pole->angle = pole->tracer->angle = mo->tracer->angle;
pole->tracer->tracer->angle = pole->angle - ANGLE_90;
pole->momx = P_ReturnThrustX(pole, pole->angle, speed);
pole->momy = P_ReturnThrustY(pole, pole->angle, speed);
pole->tracer->momx = pole->momx;
pole->tracer->momy = pole->momy;
pole->tracer->tracer->momx = pole->momx;
pole->tracer->tracer->momy = pole->momy;
}
}
else
@ -5121,7 +5130,7 @@ void A_SignPlayer(mobj_t *actor)
return;
#endif
if (actor->tracer == NULL || locvar1 < -3 || locvar1 >= numskins)
if (actor->tracer == NULL || locvar1 < -3 || locvar1 >= numskins || signcolor >= MAXTRANSLATIONS)
return;
// if no face overlay, spawn one
@ -5148,26 +5157,9 @@ void A_SignPlayer(mobj_t *actor)
if (signcolor)
;
else if ((actor->target->player->skincolor == skin->prefcolor) && (skin->prefoppositecolor)) // Set it as the skin's preferred oppositecolor?
{
signcolor = skin->prefoppositecolor;
/*
If you're here from the comment above Color_Opposite,
the following line is the one which is dependent on the
array being symmetrical. It gets the opposite of the
opposite of your desired colour just so it can get the
brightness frame for the End Sign. It's not a great
design choice, but it's constant time array access and
the idea that the colours should be OPPOSITES is kind
of in the name. If you have a better idea, feel free
to let me know. ~toast 2016/07/20
*/
signframe += (15 - Color_Opposite[Color_Opposite[skin->prefoppositecolor - 1][0] - 1][1]);
}
else if (actor->target->player->skincolor) // Set the sign to be an appropriate background color for this player's skincolor.
{
signcolor = Color_Opposite[actor->target->player->skincolor - 1][0];
signframe += (15 - Color_Opposite[actor->target->player->skincolor - 1][1]);
}
else
signcolor = SKINCOLOR_NONE;
}
@ -5188,10 +5180,10 @@ void A_SignPlayer(mobj_t *actor)
skinnum = P_RandomKey(skincount);
for (skincount = 0; skincount < numskins; skincount++)
{
if (skincheck(skincount))
skinnum++;
if (skincount > skinnum)
break;
if (skincheck(skincount))
skinnum++;
}
}
else // otherwise, advance 1 skin
@ -5203,42 +5195,46 @@ void A_SignPlayer(mobj_t *actor)
skin = &skins[skinnum];
}
else // specific skin
{
skin = &skins[locvar1];
}
facecolor = skin->prefcolor;
if (signcolor)
;
else if (skin->prefoppositecolor)
{
signcolor = skin->prefoppositecolor;
}
else
{
else if (facecolor)
signcolor = Color_Opposite[facecolor - 1][0];
}
signframe += (15 - Color_Opposite[Color_Opposite[signcolor - 1][0] - 1][1]);
}
if (skin != NULL && skin->sprites[SPR2_SIGN].numframes) // player face
if (skin && skin->sprites[SPR2_SIGN].numframes) // player face
{
ov->color = facecolor;
ov->skin = skin;
P_SetMobjState(ov, actor->info->seestate); // S_PLAY_SIGN
actor->tracer->color = signcolor;
actor->tracer->frame = signframe;
}
else // Eggman face
{
ov->color = SKINCOLOR_NONE;
P_SetMobjState(ov, actor->info->meleestate); // S_EGGMANSIGN
if (signcolor)
actor->tracer->color = signcolor;
else
actor->tracer->color = signcolor = SKINCOLOR_CARBON;
actor->tracer->frame = signframe += (15 - Color_Opposite[Color_Opposite[signcolor - 1][0] - 1][1]);
if (!signcolor)
signcolor = SKINCOLOR_CARBON;
}
actor->tracer->color = signcolor;
/*
If you're here from the comment above Color_Opposite,
the following line is the one which is dependent on the
array being symmetrical. It gets the opposite of the
opposite of your desired colour just so it can get the
brightness frame for the End Sign. It's not a great
design choice, but it's constant time array access and
the idea that the colours should be OPPOSITES is kind
of in the name. If you have a better idea, feel free
to let me know. ~toast 2016/07/20
*/
if (signcolor && signcolor < MAXSKINCOLORS)
signframe += (15 - Color_Opposite[Color_Opposite[signcolor - 1][0] - 1][1]);
actor->tracer->frame = signframe;
}
// Function: A_OverlayThink

View File

@ -2741,7 +2741,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
case MT_EGGTRAP:
// Time for birdies! Yaaaaaaaay!
target->fuse = TICRATE*2;
target->fuse = TICRATE;
break;
case MT_MINECART:
@ -3002,6 +3002,10 @@ static inline void P_NiGHTSDamage(mobj_t *target, mobj_t *source)
P_SetPlayerMobjState(target, S_PLAY_NIGHTS_STUN);
S_StartSound(target, sfx_nghurt);
#ifdef ROTSPRITE
player->mo->rollangle = 0;
#endif
if (oldnightstime > 10*TICRATE
&& player->nightstime < 10*TICRATE)
{

View File

@ -172,6 +172,7 @@ void P_ElementalFire(player_t *player, boolean cropcircle);
void P_DoPityCheck(player_t *player);
void P_PlayerThink(player_t *player);
void P_PlayerAfterThink(player_t *player);
void P_DoPlayerFinish(player_t *player);
void P_DoPlayerExit(player_t *player);
void P_NightserizePlayer(player_t *player, INT32 ptime);

View File

@ -592,6 +592,9 @@ static void P_DoTailsCarry(player_t *sonic, player_t *tails)
if (!(tails->pflags & PF_CANCARRY))
return;
if (sonic->pflags & PF_FINISHED)
return;
if (tails->bot == 1)
return;
@ -661,31 +664,32 @@ static void P_SlapStick(mobj_t *fang, mobj_t *pole)
momx2 = fang->momx/dist;
momy2 = fang->momy/dist;
pole->tracer->momx = momx1 + (dist-1)*momx2;
pole->tracer->momy = momy1 + (dist-1)*momy2;
pole->tracer->tracer->momx = momx1 + (dist-1)*momx2;
pole->tracer->tracer->momy = momy1 + (dist-1)*momy2;
fang->momx = (dist-1)*momx1 + momx2;
fang->momy = (dist-1)*momy1 + momy2;
#undef dist
P_SetMobjState(pole, pole->info->deathstate);
P_SetObjectMomZ(pole->tracer, 6*FRACUNIT, false);
pole->tracer->flags &= ~(MF_NOGRAVITY|MF_NOCLIP);
pole->tracer->movedir = ANGLE_67h;
if ((R_PointToAngle(fang->x - pole->tracer->x, fang->y - pole->tracer->y) - pole->angle) > ANGLE_180)
pole->tracer->movedir = InvAngle(pole->tracer->movedir);
P_SetObjectMomZ(pole->tracer->tracer, 6*FRACUNIT, false);
pole->tracer->tracer->flags &= ~(MF_NOGRAVITY|MF_NOCLIP);
pole->tracer->tracer->movedir = ANGLE_67h;
if ((R_PointToAngle(fang->x - pole->tracer->tracer->x, fang->y - pole->tracer->tracer->y) - pole->angle) > ANGLE_180)
pole->tracer->tracer->movedir = InvAngle(pole->tracer->movedir);
P_SetObjectMomZ(fang, 14*FRACUNIT, false);
fang->flags |= MF_NOGRAVITY|MF_NOCLIP;
P_SetMobjState(fang, fang->info->xdeathstate);
pole->tracer->tics = pole->tics = fang->tics;
pole->tracer->tracer->tics = pole->tracer->tics = pole->tics = fang->tics;
var1 = var2 = 0;
A_Scream(pole->tracer);
A_Scream(pole->tracer->tracer);
S_StartSound(fang, sfx_altdi1);
P_SetTarget(&pole->tracer->tracer, NULL);
P_SetMobjState(pole->tracer, pole->info->xdeathstate);
P_SetTarget(&pole->tracer, NULL);
P_SetMobjState(pole, pole->info->deathstate);
}
static void P_PlayerBarrelCollide(mobj_t *toucher, mobj_t *barrel)
@ -1089,7 +1093,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
return true; // overhead
if (thing->z + thing->height < tmthing->z)
return true; // underneath
if (!thing->tracer)
if (!thing->tracer || !thing->tracer->tracer)
return true;
P_SlapStick(tmthing, thing);
// no return value was used in the original prototype script at this point,
@ -1301,6 +1305,11 @@ static boolean PIT_CheckThing(mobj_t *thing)
return false;
}
// Fireball touched an enemy
// Don't bounce though, just despawn right there
if ((tmthing->type == MT_FIREBALL) && (thing->flags & MF_ENEMY))
P_KillMobj(tmthing, NULL, NULL, 0);
// damage / explode
if (tmthing->flags & MF_ENEMY) // An actual ENEMY! (Like the deton, for example)
P_DamageMobj(thing, tmthing, tmthing, 1, 0);

View File

@ -246,6 +246,7 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state)
{
case S_PLAY_STND:
case S_PLAY_WAIT:
case S_PLAY_NIGHTS_STAND:
player->panim = PA_IDLE;
break;
case S_PLAY_EDGE:
@ -254,6 +255,7 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state)
case S_PLAY_WALK:
case S_PLAY_SKID:
case S_PLAY_FLOAT:
case S_PLAY_NIGHTS_FLOAT:
player->panim = PA_WALK;
break;
case S_PLAY_RUN:
@ -269,6 +271,7 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state)
break;
case S_PLAY_ROLL:
//case S_PLAY_SPINDASH: -- everyone can ROLL thanks to zoom tubes...
case S_PLAY_NIGHTS_ATTACK:
player->panim = PA_ROLL;
break;
case S_PLAY_JUMP:
@ -8227,7 +8230,7 @@ void P_MobjThinker(mobj_t *mobj)
mobj->flags2 ^= MF2_DONTDRAW;
break;
case MT_EGGTRAP: // Egg Capsule animal release
if (mobj->fuse > 0 && mobj->fuse < 2*TICRATE-(TICRATE/7))
if (mobj->fuse > 0)// && mobj->fuse < TICRATE-(TICRATE/7))
{
INT32 i;
fixed_t x,y,z;
@ -8236,9 +8239,9 @@ void P_MobjThinker(mobj_t *mobj)
mobj_t *flicky;
z = mobj->subsector->sector->floorheight + FRACUNIT + (P_RandomKey(64)<<FRACBITS);
for (i = 0; i < 2; i++)
for (i = 0; i < 3; i++)
{
const angle_t fa = (P_RandomByte()*FINEANGLES/16) & FINEMASK;
const angle_t fa = P_RandomKey(FINEANGLES) & FINEMASK;
ns = 64 * FRACUNIT;
x = mobj->x + FixedMul(FINESINE(fa),ns);
y = mobj->y + FixedMul(FINECOSINE(fa),ns);
@ -8690,6 +8693,13 @@ void P_MobjThinker(mobj_t *mobj)
case MT_KOOPA:
P_KoopaThinker(mobj);
break;
case MT_FIREBALL:
if (P_AproxDistance(mobj->momx, mobj->momy) <= 16*FRACUNIT) // Once fireballs lose enough speed, kill them
{
P_KillMobj(mobj, NULL, NULL, 0);
return;
}
break;
case MT_REDRING:
if (((mobj->z < mobj->floorz) || (mobj->z + mobj->height > mobj->ceilingz))
&& mobj->flags & MF_MISSILE)

View File

@ -3244,47 +3244,22 @@ boolean P_SetupLevel(boolean skipprecip)
#endif
}
// Stage title!
wipestyleflags |= WSF_FADEIN;
wipestyleflags &= ~WSF_FADEOUT;
WipeInLevel = true;
if (rendermode != render_none
&& (!titlemapinaction)
&& ranspecialwipe != 2
&& *mapheaderinfo[gamemap-1]->lvlttl != '\0'
#ifdef HAVE_BLUA
&& LUA_HudEnabled(hud_stagetitle)
#endif
)
{
tic_t starttime = I_GetTime();
tic_t endtime = starttime + (10*NEWTICRATERATIO);
tic_t nowtime = starttime;
tic_t lasttime = starttime;
while (nowtime < endtime)
{
// draw loop
while (!((nowtime = I_GetTime()) - lasttime))
I_Sleep();
lasttime = nowtime;
// No render mode, stop here.
if (rendermode == render_none)
return true;
F_WipeColorFill(levelfadecol);
stplyr = &players[consoleplayer];
ST_drawLevelTitle(nowtime - starttime);
if (splitscreen)
{
stplyr = &players[secondarydisplayplayer];
ST_drawLevelTitle(nowtime - starttime);
}
// Title card!
G_StartTitleCard();
I_OsPolling();
I_UpdateNoBlit();
I_FinishUpdate(); // page flip or blit buffer
// Can the title card actually run, though?
if (!WipeStageTitle)
return true;
if (ranspecialwipe == 2)
return true;
if (moviemode) // make sure we save frames for the white hold too
M_SaveFrame();
}
}
// If so...
if ((!(mapheaderinfo[gamemap-1]->levelflags & LF_NOTITLECARD)) && (*mapheaderinfo[gamemap-1]->lvlttl != '\0'))
G_PreLevelTitleCard(lt_ticker, true);
return true;
}

View File

@ -4675,7 +4675,7 @@ DoneSection2:
{
INT32 lineindex;
P_DoPlayerExit(player);
P_DoPlayerFinish(player);
P_SetupSignExit(player);
// important: use sector->tag on next line instead of player->mo->subsector->tag

View File

@ -636,6 +636,10 @@ static void P_DeNightserizePlayer(player_t *player)
player->marebonuslap = 0;
player->flyangle = 0;
player->anotherflyangle = 0;
#ifdef ROTSPRITE
player->mo->rollangle = 0;
#endif
P_SetTarget(&player->mo->target, NULL);
P_SetTarget(&player->axis1, P_SetTarget(&player->axis2, NULL));
@ -762,6 +766,9 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime)
player->secondjump = 0;
player->flyangle = 0;
player->anotherflyangle = 0;
#ifdef ROTSPRITE
player->mo->rollangle = 0;
#endif
player->powers[pw_shield] = SH_NONE;
player->powers[pw_super] = 0;
@ -2124,6 +2131,30 @@ void P_SpawnSpinMobj(player_t *player, mobjtype_t type)
P_SetTarget(&mobj->target, player->mo); // the one thing P_SpawnGhostMobj doesn't do
}
/** Called when \p player finishes the level.
*
* Only use for cases where the player should be able to move
* while waiting for others to finish. Otherwise, use P_DoPlayerExit().
*
* In single player or if ::cv_exitmove is disabled, this will also cause
* P_PlayerThink() to call P_DoPlayerExit(), so you do not need to
* make a special cases for those.
*
* \param player The player who finished the level.
* \sa P_DoPlayerExit
*
*/
void P_DoPlayerFinish(player_t *player)
{
if (player->pflags & PF_FINISHED)
return;
player->pflags |= PF_FINISHED;
if (netgame)
CONS_Printf(M_GetText("%s has completed the level.\n"), player_names[player-players]);
}
//
// P_DoPlayerExit
//
@ -2158,12 +2189,14 @@ void P_DoPlayerExit(player_t *player)
player->pflags |= P_GetJumpFlags(player);
P_SetPlayerMobjState(player->mo, S_PLAY_JUMP);
}
else if (player->pflags & PF_STARTDASH)
{
player->pflags &= ~PF_STARTDASH;
P_SetPlayerMobjState(player->mo, S_PLAY_STND);
}
player->powers[pw_underwater] = 0;
player->powers[pw_spacetime] = 0;
P_RestoreMusic(player);
if (playeringame[player-players] && netgame && !circuitmap)
CONS_Printf(M_GetText("%s has completed the level.\n"), player_names[player-players]);
}
#define SPACESPECIAL 12
@ -3993,12 +4026,13 @@ static void P_DoFiring(player_t *player, ticcmd_t *cmd)
if (player->pflags & PF_ATTACKDOWN || player->climbing || (G_TagGametype() && !(player->pflags & PF_TAGIT)))
return;
if ((player->powers[pw_shield] & SH_STACK) == SH_FIREFLOWER)
if (((player->powers[pw_shield] & SH_STACK) == SH_FIREFLOWER) && !(player->weapondelay))
{
player->pflags |= PF_ATTACKDOWN;
mo = P_SpawnPlayerMissile(player->mo, MT_FIREBALL, 0);
P_InstaThrust(mo, player->mo->angle, ((mo->info->speed>>FRACBITS)*player->mo->scale) + player->speed);
S_StartSound(player->mo, sfx_mario7);
P_SetWeaponDelay(player, TICRATE); // Short delay between fireballs so you can't spam them everywhere
return;
}
@ -7701,9 +7735,9 @@ void P_ElementalFire(player_t *player, boolean cropcircle)
I_Assert(!P_MobjWasRemoved(player->mo));
if (player->mo->eflags & MFE_VERTICALFLIP)
ground = player->mo->ceilingz - FixedMul(mobjinfo[MT_SPINFIRE].height, player->mo->scale);
ground = player->mo->ceilingz - FixedMul(mobjinfo[MT_SPINFIRE].height - 1, player->mo->scale);
else
ground = player->mo->floorz;
ground = player->mo->floorz + 1;
if (cropcircle)
{
@ -9889,10 +9923,20 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
pviewheight = FixedMul(41*player->height/48, mo->scale);
if (mo->eflags & MFE_VERTICALFLIP)
z = mo->z + mo->height - pviewheight - camheight + distz;
if (sign)
{
if (mo->eflags & MFE_VERTICALFLIP)
z = sign->ceilingz - pviewheight - camheight;
else
z = sign->floorz + pviewheight + camheight;
}
else
z = mo->z + pviewheight + camheight + distz;
{
if (mo->eflags & MFE_VERTICALFLIP)
z = mo->z + mo->height - pviewheight - camheight + distz;
else
z = mo->z + pviewheight + camheight + distz;
}
// move camera down to move under lower ceilings
newsubsec = R_IsPointInSubsector(((mo->x>>FRACBITS) + (thiscam->x>>FRACBITS))<<(FRACBITS-1), ((mo->y>>FRACBITS) + (thiscam->y>>FRACBITS))<<(FRACBITS-1));
@ -11400,6 +11444,14 @@ void P_PlayerThink(player_t *player)
}
}
if (player->pflags & PF_FINISHED)
{
if (cv_exitmove.value && !G_EnoughPlayersFinished())
player->exiting = 0;
else
P_DoPlayerExit(player);
}
// check water content, set stuff in mobj
P_MobjCheckWater(player->mo);

View File

@ -123,8 +123,12 @@ 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_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_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};
@ -1172,8 +1176,12 @@ void R_RegisterEngineStuff(void)
CV_RegisterVar(&cv_chasecam);
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_cam_dist);

View File

@ -76,7 +76,12 @@ extern consvar_t cv_showhud, cv_translucenthud;
extern consvar_t cv_homremoval;
extern consvar_t cv_chasecam, cv_chasecam2;
extern consvar_t cv_flipcam, cv_flipcam2;
extern consvar_t cv_shadow, cv_shadowoffs;
#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_drawdist, cv_drawdist_nights, cv_drawdist_precip;
extern consvar_t cv_skybox;

View File

@ -1066,16 +1066,15 @@ void R_ParseSPRTINFOLump(UINT16 wadNum, UINT16 lumpNum)
sprinfoToken = M_GetToken(sprinfoText);
while (sprinfoToken != NULL)
{
if (!stricmp(sprinfoToken, "SPRITE") || !stricmp(sprinfoToken, "SPRITE2"))
{
Z_Free(sprinfoToken);
R_ParseSpriteInfo(!stricmp(sprinfoToken, "SPRITE2"));
}
if (!stricmp(sprinfoToken, "SPRITE"))
R_ParseSpriteInfo(false);
else if (!stricmp(sprinfoToken, "SPRITE2"))
R_ParseSpriteInfo(true);
else
I_Error("Error parsing SPRTINFO lump: Unknown keyword \"%s\"", sprinfoToken);
Z_Free(sprinfoToken);
sprinfoToken = M_GetToken(NULL);
}
Z_Free(sprinfoToken);
Z_Free((void *)sprinfoText);
}

View File

@ -1196,20 +1196,20 @@ static void R_ProjectSprite(mobj_t *thing)
#ifdef ROTSPRITE
sprinfo = NULL;
#endif
}
if (rot >= sprdef->numframes)
{
CONS_Alert(CONS_ERROR, M_GetText("R_ProjectSprite: invalid sprite frame %s/%s for %s\n"),
sizeu1(rot), sizeu2(sprdef->numframes), sprnames[thing->sprite]);
thing->sprite = states[S_UNKNOWN].sprite;
thing->frame = states[S_UNKNOWN].frame;
sprdef = &sprites[thing->sprite];
rot = thing->frame&FF_FRAMEMASK;
if (!thing->skin)
if (rot >= sprdef->numframes)
{
thing->state->sprite = thing->sprite;
thing->state->frame = thing->frame;
CONS_Alert(CONS_ERROR, M_GetText("R_ProjectSprite: invalid sprite frame %s/%s for %s\n"),
sizeu1(rot), sizeu2(sprdef->numframes), sprnames[thing->sprite]);
if (thing->sprite == thing->state->sprite && thing->frame == thing->state->frame)
{
thing->state->sprite = states[S_UNKNOWN].sprite;
thing->state->frame = states[S_UNKNOWN].frame;
}
thing->sprite = states[S_UNKNOWN].sprite;
thing->frame = states[S_UNKNOWN].frame;
sprdef = &sprites[thing->sprite];
rot = thing->frame&FF_FRAMEMASK;
}
}

View File

@ -428,6 +428,17 @@ void SCR_DisplayTicRate(void)
lasttic = ontic;
}
void SCR_DisplayLocalPing(void)
{
UINT32 ping = playerpingtable[consoleplayer]; // consoleplayer's ping is everyone's ping in a splitnetgame :P
if (cv_showping.value == 1 || (cv_showping.value == 2 && servermaxping && ping > servermaxping)) // only show 2 (warning) if our ping is at a bad level
{
INT32 dispy = cv_ticrate.value ? 180 : 189;
HU_drawPing(307, dispy, ping, true, V_SNAPTORIGHT | V_SNAPTOBOTTOM);
}
}
void SCR_ClosedCaptions(void)
{
UINT8 i;

View File

@ -167,5 +167,6 @@ FUNCMATH boolean SCR_IsAspectCorrect(INT32 width, INT32 height);
// move out to main code for consistency
void SCR_DisplayTicRate(void);
void SCR_ClosedCaptions(void);
void SCR_DisplayLocalPing(void);
#undef DNWH
#endif //__SCREEN_H__

View File

@ -1180,6 +1180,9 @@ void I_FinishUpdate(void)
{
if (cv_ticrate.value)
SCR_DisplayTicRate();
if (cv_showping.value && netgame && consoleplayer != serverplayer)
SCR_DisplayLocalPing();
}
if (rendermode == render_soft && screens[0])

View File

@ -779,7 +779,7 @@ sfxinfo_t S_sfx[NUMSFX] =
{"kc49", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"kc4a", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"kc4b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"kc4c", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"kc4c", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Pop-shot"},
{"kc4d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Power up"},
{"kc4e", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"kc4f", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},

View File

@ -23,6 +23,7 @@
#include "v_video.h"
#include "z_zone.h"
#include "hu_stuff.h"
#include "console.h"
#include "s_sound.h"
#include "i_system.h"
#include "m_menu.h"
@ -186,14 +187,18 @@ boolean ST_SameTeam(player_t *a, player_t *b)
static boolean st_stopped = true;
void ST_Ticker(void)
void ST_Ticker(boolean run)
{
if (st_stopped)
return;
if (run)
ST_runTitleCard();
}
// 0 is default, any others are special palettes.
INT32 st_palette = 0;
INT32 st_translucency = 0;
void ST_doPaletteStuff(void)
{
@ -818,7 +823,7 @@ static void ST_drawLivesArea(void)
face = superprefix[stplyr->skin];
V_DrawSmallMappedPatch(hudinfo[HUD_LIVES].x, hudinfo[HUD_LIVES].y,
hudinfo[HUD_LIVES].f|V_PERPLAYER|V_HUDTRANS, face, colormap);
if (cv_translucenthud.value == 10 && stplyr->powers[pw_super] == 1 && stplyr->mo->tracer)
if (st_translucency == 10 && stplyr->powers[pw_super] == 1 && stplyr->mo->tracer)
{
INT32 v_supertrans = (stplyr->mo->tracer->frame & FF_TRANSMASK) >> FF_TRANSSHIFT;
if (v_supertrans < 10)
@ -1160,16 +1165,144 @@ static void ST_drawInput(void)
V_DrawThinString(x, y, hudinfo[HUD_LIVES].f|((leveltime & 4) ? V_YELLOWMAP : V_REDMAP), "BAD DEMO!!");
}
void ST_drawLevelTitle(tic_t titletime)
static patch_t *lt_patches[3];
static INT32 lt_scroll = 0;
static INT32 lt_mom = 0;
static INT32 lt_zigzag = 0;
tic_t lt_ticker = 0, lt_lasttic = 0;
tic_t lt_exitticker = 0, lt_endtime = 0;
//
// Load the graphics for the title card.
//
static void ST_cacheLevelTitle(void)
{
if (!(mapheaderinfo[gamemap-1]->levelflags & LF_WARNINGTITLE))
{
lt_patches[0] = (patch_t *)W_CachePatchName("LTACTBLU", PU_HUDGFX);
lt_patches[1] = (patch_t *)W_CachePatchName("LTZIGZAG", PU_HUDGFX);
lt_patches[2] = (patch_t *)W_CachePatchName("LTZZTEXT", PU_HUDGFX);
}
else // boss map
{
lt_patches[0] = (patch_t *)W_CachePatchName("LTACTRED", PU_HUDGFX);
lt_patches[1] = (patch_t *)W_CachePatchName("LTZIGRED", PU_HUDGFX);
lt_patches[2] = (patch_t *)W_CachePatchName("LTZZWARN", PU_HUDGFX);
}
}
//
// Start the title card.
//
void ST_startTitleCard(void)
{
// cache every HUD patch used
ST_cacheLevelTitle();
// initialize HUD variables
lt_ticker = lt_exitticker = lt_lasttic = 0;
lt_endtime = 2*TICRATE;
lt_scroll = BASEVIDWIDTH * FRACUNIT;
lt_zigzag = -((lt_patches[1])->width * FRACUNIT);
lt_mom = 0;
}
//
// What happens before drawing the title card.
// Which is just setting the HUD translucency.
//
void ST_preDrawTitleCard(void)
{
if (lt_ticker >= (lt_endtime + TICRATE))
return;
if (!lt_exitticker)
st_translucency = 0;
else
st_translucency = max(0, min((INT32)lt_exitticker-4, cv_translucenthud.value));
}
//
// Run the title card.
// Called from ST_Ticker.
//
void ST_runTitleCard(void)
{
if (lt_ticker >= (lt_endtime + TICRATE))
return;
if (!(paused || P_AutoPause()))
{
// tick
lt_ticker++;
if (lt_ticker >= lt_endtime)
lt_exitticker++;
// scroll to screen (level title)
if (!lt_exitticker)
{
if (abs(lt_scroll) > FRACUNIT)
lt_scroll -= (lt_scroll>>2);
else
lt_scroll = 0;
}
// scroll away from screen (level title)
else
{
lt_mom -= FRACUNIT*6;
lt_scroll += lt_mom;
}
// scroll to screen (zigzag)
if (!lt_exitticker)
{
if (abs(lt_zigzag) > FRACUNIT)
lt_zigzag -= (lt_zigzag>>2);
else
lt_zigzag = 0;
}
// scroll away from screen (zigzag)
else
lt_zigzag += lt_mom;
}
}
//
// Draw the title card itself.
//
void ST_drawTitleCard(void)
{
char *lvlttl = mapheaderinfo[gamemap-1]->lvlttl;
char *subttl = mapheaderinfo[gamemap-1]->subttl;
INT32 actnum = mapheaderinfo[gamemap-1]->actnum;
INT32 lvlttly, zoney, lvlttlxpos, ttlnumxpos, zonexpos;
INT32 lvlttlxpos, ttlnumxpos, zonexpos;
INT32 subttlxpos = BASEVIDWIDTH/2;
INT32 ttlscroll = FixedInt(lt_scroll);
INT32 zzticker;
patch_t *actpat, *zigzag, *zztext;
if (!(titletime > 2 && titletime-3 < 110))
#ifdef HAVE_BLUA
if (!LUA_HudEnabled(hud_stagetitle))
goto luahook;
#endif
if (lt_ticker >= (lt_endtime + TICRATE))
#ifdef HAVE_BLUA
goto luahook;
#else
return;
#endif
#ifndef LEVELWIPES
if ((lt_ticker-lt_lasttic) > 1)
lt_ticker = lt_lasttic+1;
#endif
ST_cacheLevelTitle();
actpat = lt_patches[0];
zigzag = lt_patches[1];
zztext = lt_patches[2];
lvlttlxpos = ((BASEVIDWIDTH/2) - (V_LevelNameWidth(lvlttl)/2));
@ -1177,72 +1310,73 @@ void ST_drawLevelTitle(tic_t titletime)
lvlttlxpos -= V_LevelActNumWidth(actnum);
ttlnumxpos = lvlttlxpos + V_LevelNameWidth(lvlttl);
zonexpos = ttlnumxpos - V_LevelNameWidth(M_GetText("ZONE"));
zonexpos = ttlnumxpos - V_LevelNameWidth(M_GetText("Zone"));
ttlnumxpos++;
if (lvlttlxpos < 0)
lvlttlxpos = 0;
#if 0 // toaster's experiment. srb2&toast.exe one day, maybe? Requires stuff below to be converted to fixed point.
#define MIDTTLY 79
#define MIDZONEY 105
#define MIDDIFF 4
if (titletime < 10)
if (!splitscreen || (splitscreen && stplyr == &players[displayplayer]))
{
fixed_t z = ((titletime - 3)<<FRACBITS)/7;
INT32 ttlh = V_LevelNameHeight(lvlttl);
zoney = (200<<FRACBITS) - ((200 - (MIDZONEY + MIDDIFF))*z);
lvlttly = ((MIDTTLY + ttlh - MIDDIFF)*z) - (ttlh<<FRACBITS);
zzticker = lt_ticker;
V_DrawScaledPatch(FixedInt(lt_zigzag), (-zzticker) % zigzag->height, V_SNAPTOTOP|V_SNAPTOLEFT, zigzag);
V_DrawScaledPatch(FixedInt(lt_zigzag), (zigzag->height-zzticker) % zigzag->height, V_SNAPTOTOP|V_SNAPTOLEFT, zigzag);
V_DrawScaledPatch(FixedInt(lt_zigzag), (-zigzag->height+zzticker) % zztext->height, V_SNAPTOTOP|V_SNAPTOLEFT, zztext);
V_DrawScaledPatch(FixedInt(lt_zigzag), (zzticker) % zztext->height, V_SNAPTOTOP|V_SNAPTOLEFT, zztext);
}
else if (titletime < 105)
{
fixed_t z = (((titletime - 10)*MIDDIFF)<<(FRACBITS+1))/95;
zoney = ((MIDZONEY + MIDDIFF)<<FRACBITS) - z;
lvlttly = ((MIDTTLY - MIDDIFF)<<FRACBITS) + z;
}
else
{
fixed_t z = ((titletime - 105)<<FRACBITS)/7;
INT32 zoneh = V_LevelNameHeight(M_GetText("ZONE"));
zoney = (MIDZONEY + zoneh - MIDDIFF)*(FRACUNIT - z) - (zoneh<<FRACBITS);
lvlttly = ((MIDTTLY + MIDDIFF)<<FRACBITS) + ((200 - (MIDTTLY + MIDDIFF))*z);
}
#undef MIDTTLY
#undef MIDZONEY
#undef MIDDIFF
#else
// There's no consistent algorithm that can accurately define the old positions
// so I just ended up resorting to a single switch statement to define them
switch (titletime-3)
{
case 0: zoney = 200; lvlttly = 0; break;
case 1: zoney = 188; lvlttly = 12; break;
case 2: zoney = 176; lvlttly = 24; break;
case 3: zoney = 164; lvlttly = 36; break;
case 4: zoney = 152; lvlttly = 48; break;
case 5: zoney = 140; lvlttly = 60; break;
case 6: zoney = 128; lvlttly = 72; break;
case 105: zoney = 80; lvlttly = 104; break;
case 106: zoney = 56; lvlttly = 128; break;
case 107: zoney = 32; lvlttly = 152; break;
case 108: zoney = 8; lvlttly = 176; break;
case 109: zoney = 0; lvlttly = 200; break;
default: zoney = 104; lvlttly = 80; break;
}
#endif
if (actnum)
V_DrawLevelActNum(ttlnumxpos, zoney, V_PERPLAYER, actnum);
V_DrawLevelTitle(lvlttlxpos, lvlttly, V_PERPLAYER, lvlttl);
{
if (!splitscreen)
V_DrawScaledPatch(ttlnumxpos + ttlscroll, 104 - ttlscroll, 0, actpat);
V_DrawLevelActNum(ttlnumxpos + ttlscroll, 104, V_PERPLAYER, actnum);
}
V_DrawLevelTitle(lvlttlxpos - ttlscroll, 80, V_PERPLAYER, lvlttl);
if (!(mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE))
V_DrawLevelTitle(zonexpos, zoney, V_PERPLAYER, M_GetText("ZONE"));
V_DrawLevelTitle(zonexpos + ttlscroll, 104, V_PERPLAYER, M_GetText("Zone"));
V_DrawCenteredString(subttlxpos - ttlnumxpos, 128, V_PERPLAYER|V_ALLOWLOWERCASE, subttl);
if (lvlttly+48 < 200)
V_DrawCenteredString(subttlxpos, lvlttly+48, V_PERPLAYER|V_ALLOWLOWERCASE, subttl);
lt_lasttic = lt_ticker;
#ifdef HAVE_BLUA
luahook:
LUAh_TitleCardHUD(stplyr);
#endif
}
//
// Drawer for G_PreLevelTitleCard.
//
void ST_preLevelTitleCardDrawer(tic_t ticker, boolean update)
{
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, levelfadecol);
#ifndef LEVELWIPES
if (ticker < PRELEVELTIME-1)
#endif
ST_drawWipeTitleCard();
I_OsPolling();
I_UpdateNoBlit();
if (update)
I_FinishUpdate(); // page flip or blit buffer
}
//
// Draw the title card while on a wipe.
// Also used in G_PreLevelTitleCard.
//
void ST_drawWipeTitleCard(void)
{
stplyr = &players[consoleplayer];
ST_preDrawTitleCard();
ST_drawTitleCard();
if (splitscreen)
{
stplyr = &players[secondarydisplayplayer];
ST_preDrawTitleCard();
ST_drawTitleCard();
}
}
static void ST_drawPowerupHUD(void)
@ -2106,7 +2240,7 @@ static void ST_drawTextHUD(void)
textHUDdraw(M_GetText("\x82""FIRE:""\x80 Enter game"))
}
if (gametype == GT_COOP && (!stplyr->spectator || (!(maptol & TOL_NIGHTS) && G_IsSpecialStage(gamemap))) && stplyr->exiting)
if (gametype == GT_COOP && (!stplyr->spectator || (!(maptol & TOL_NIGHTS) && G_IsSpecialStage(gamemap))) && (stplyr->exiting || (stplyr->pflags & PF_FINISHED)))
{
UINT8 numneeded = (G_IsSpecialStage(gamemap) ? 4 : cv_playersforexit.value);
if (numneeded)
@ -2121,7 +2255,7 @@ static void ST_drawTextHUD(void)
continue;
total++;
if (players[i].exiting)
if (players[i].exiting || (players[i].pflags & PF_FINISHED))
exiting++;
}
@ -2394,12 +2528,25 @@ static void ST_doItemFinderIconsAndSound(void)
S_StartSound(NULL, sfx_emfind);
}
//
// Draw the status bar overlay, customisable: the user chooses which
// kind of information to overlay
//
static void ST_overlayDrawer(void)
{
//hu_showscores = auto hide score/time/rings when tab rankings are shown
// Decide whether to draw the stage title or not
boolean stagetitle = false;
// Check for a valid level title
// If the HUD is enabled
// And, if Lua is running, if the HUD library has the stage title enabled
if (!(mapheaderinfo[gamemap-1]->levelflags & LF_NOTITLECARD) && *mapheaderinfo[gamemap-1]->lvlttl != '\0' && !(hu_showscores && (netgame || multiplayer)))
{
stagetitle = true;
ST_preDrawTitleCard();
}
// hu_showscores = auto hide score/time/rings when tab rankings are shown
if (!(hu_showscores && (netgame || multiplayer)))
{
if ((maptol & TOL_NIGHTS || G_IsSpecialStage(gamemap)) &&
@ -2550,12 +2697,8 @@ static void ST_overlayDrawer(void)
#endif
// draw level title Tails
if (*mapheaderinfo[gamemap-1]->lvlttl != '\0' && !(hu_showscores && (netgame || multiplayer))
#ifdef HAVE_BLUA
&& LUA_HudEnabled(hud_stagetitle)
#endif
)
ST_drawLevelTitle(timeinmap+70);
if (stagetitle && (!WipeInAction) && (!WipeStageTitle))
ST_drawTitleCard();
if (!hu_showscores && (netgame || multiplayer)
#ifdef HAVE_BLUA
@ -2631,6 +2774,8 @@ void ST_Drawer(void)
}
}
st_translucency = cv_translucenthud.value;
if (st_overlay)
{
// No deadview!

View File

@ -24,7 +24,7 @@
//
// Called by main loop.
void ST_Ticker(void);
void ST_Ticker(boolean run);
// Called by main loop.
void ST_Drawer(void);
@ -47,8 +47,16 @@ void ST_ReloadSkinFaceGraphics(void);
void ST_doPaletteStuff(void);
// level title draw
void ST_drawLevelTitle(tic_t titletime);
// title card
void ST_startTitleCard(void);
void ST_runTitleCard(void);
void ST_drawTitleCard(void);
void ST_preDrawTitleCard(void);
void ST_preLevelTitleCardDrawer(tic_t ticker, boolean update);
void ST_drawWipeTitleCard(void);
extern tic_t lt_ticker, lt_lasttic;
extern tic_t lt_exitticker, lt_endtime;
// return if player a is in the same team as player b
boolean ST_SameTeam(player_t *a, player_t *b);
@ -59,6 +67,7 @@ boolean ST_SameTeam(player_t *a, player_t *b);
extern boolean st_overlay; // sb overlay on or off when fullscreen
extern INT32 st_palette; // 0 is default, any others are special palettes.
extern INT32 st_translucency;
extern lumpnum_t st_borderpatchnum;
// patches, also used in intermission

View File

@ -18,6 +18,7 @@
#include "p_local.h" // stplyr
#include "g_game.h" // players
#include "v_video.h"
#include "st_stuff.h"
#include "hu_stuff.h"
#include "r_draw.h"
#include "console.h"
@ -574,11 +575,11 @@ void V_DrawStretchyFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vsca
if ((alphalevel = ((scrn & V_ALPHAMASK) >> V_ALPHASHIFT)))
{
if (alphalevel == 13)
alphalevel = hudminusalpha[cv_translucenthud.value];
alphalevel = hudminusalpha[st_translucency];
else if (alphalevel == 14)
alphalevel = 10 - cv_translucenthud.value;
alphalevel = 10 - st_translucency;
else if (alphalevel == 15)
alphalevel = hudplusalpha[cv_translucenthud.value];
alphalevel = hudplusalpha[st_translucency];
if (alphalevel >= 10)
return; // invis
@ -874,11 +875,11 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_
if ((alphalevel = ((scrn & V_ALPHAMASK) >> V_ALPHASHIFT)))
{
if (alphalevel == 13)
alphalevel = hudminusalpha[cv_translucenthud.value];
alphalevel = hudminusalpha[st_translucency];
else if (alphalevel == 14)
alphalevel = 10 - cv_translucenthud.value;
alphalevel = 10 - st_translucency;
else if (alphalevel == 15)
alphalevel = hudplusalpha[cv_translucenthud.value];
alphalevel = hudplusalpha[st_translucency];
if (alphalevel >= 10)
return; // invis
@ -1393,11 +1394,11 @@ void V_DrawFillConsoleMap(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c)
if ((alphalevel = ((c & V_ALPHAMASK) >> V_ALPHASHIFT)))
{
if (alphalevel == 13)
alphalevel = hudminusalpha[cv_translucenthud.value];
alphalevel = hudminusalpha[st_translucency];
else if (alphalevel == 14)
alphalevel = 10 - cv_translucenthud.value;
alphalevel = 10 - st_translucency;
else if (alphalevel == 15)
alphalevel = hudplusalpha[cv_translucenthud.value];
alphalevel = hudplusalpha[st_translucency];
if (alphalevel >= 10)
return; // invis
@ -2899,7 +2900,7 @@ void V_DrawLevelTitle(INT32 x, INT32 y, INT32 option, const char *string)
continue;
}
c = toupper(*ch) - LT_FONTSTART;
c = *ch - LT_FONTSTART;
if (c < 0 || c >= LT_FONTSIZE || !lt_font[c])
{
cx += 16*dupx;
@ -2934,7 +2935,7 @@ INT32 V_LevelNameWidth(const char *string)
{
if (string[i] & 0x80)
continue;
c = toupper(string[i]) - LT_FONTSTART;
c = string[i] - LT_FONTSTART;
if (c < 0 || c >= LT_FONTSIZE || !lt_font[c])
w += 16;
else
@ -2953,7 +2954,7 @@ INT32 V_LevelNameHeight(const char *string)
for (i = 0; i < strlen(string); i++)
{
c = toupper(string[i]) - LT_FONTSTART;
c = string[i] - LT_FONTSTART;
if (c < 0 || c >= LT_FONTSIZE || !lt_font[c])
continue;
@ -2964,7 +2965,7 @@ INT32 V_LevelNameHeight(const char *string)
return w;
}
// For ST_drawLevelTitle
// For ST_drawTitleCard
// Returns the width of the act num patch
INT32 V_LevelActNumWidth(INT32 num)
{

View File

@ -383,7 +383,7 @@ static lumpinfo_t* ResGetLumpsWad (FILE* handle, UINT16* nlmp, const char* filen
// read the header
if (fread(&header, 1, sizeof header, handle) < sizeof header)
{
CONS_Alert(CONS_ERROR, M_GetText("Can't read wad header because %s\n"), strerror(ferror(handle)));
CONS_Alert(CONS_ERROR, M_GetText("Can't read wad header because %s\n"), M_FileError(handle));
return NULL;
}
@ -406,7 +406,7 @@ static lumpinfo_t* ResGetLumpsWad (FILE* handle, UINT16* nlmp, const char* filen
if (fseek(handle, header.infotableofs, SEEK_SET) == -1
|| fread(fileinfo, 1, i, handle) < i)
{
CONS_Alert(CONS_ERROR, M_GetText("Corrupt wadfile directory (%s)\n"), strerror(ferror(handle)));
CONS_Alert(CONS_ERROR, M_GetText("Corrupt wadfile directory (%s)\n"), M_FileError(handle));
free(fileinfov);
return NULL;
}
@ -427,7 +427,7 @@ static lumpinfo_t* ResGetLumpsWad (FILE* handle, UINT16* nlmp, const char* filen
handle) < sizeof realsize)
{
I_Error("corrupt compressed file: %s; maybe %s", /// \todo Avoid the bailout?
filename, strerror(ferror(handle)));
filename, M_FileError(handle));
}
realsize = LONG(realsize);
if (realsize != 0)
@ -565,7 +565,7 @@ static lumpinfo_t* ResGetLumpsZip (FILE* handle, UINT16* nlmp)
fseek(handle, -4, SEEK_CUR);
if (fread(&zend, 1, sizeof zend, handle) < sizeof zend)
{
CONS_Alert(CONS_ERROR, "Corrupt central directory (%s)\n", strerror(ferror(handle)));
CONS_Alert(CONS_ERROR, "Corrupt central directory (%s)\n", M_FileError(handle));
return NULL;
}
numlumps = zend.entries;
@ -582,7 +582,7 @@ static lumpinfo_t* ResGetLumpsZip (FILE* handle, UINT16* nlmp)
if (fread(zentry, 1, sizeof(zentry_t), handle) < sizeof(zentry_t))
{
CONS_Alert(CONS_ERROR, "Failed to read central directory (%s)\n", strerror(ferror(handle)));
CONS_Alert(CONS_ERROR, "Failed to read central directory (%s)\n", M_FileError(handle));
Z_Free(lumpinfo);
free(zentries);
return NULL;
@ -602,7 +602,7 @@ static lumpinfo_t* ResGetLumpsZip (FILE* handle, UINT16* nlmp)
fullname = malloc(zentry->namelen + 1);
if (fgets(fullname, zentry->namelen + 1, handle) != fullname)
{
CONS_Alert(CONS_ERROR, "Unable to read lumpname (%s)\n", strerror(ferror(handle)));
CONS_Alert(CONS_ERROR, "Unable to read lumpname (%s)\n", M_FileError(handle));
Z_Free(lumpinfo);
free(zentries);
free(fullname);

View File

@ -371,6 +371,9 @@ void I_FinishUpdate(void)
if (cv_ticrate.value)
SCR_DisplayTicRate();
if (cv_showping.value && netgame && consoleplayer != serverplayer)
SCR_DisplayLocalPing();
//
if (bDIBMode)
{

View File

@ -399,10 +399,13 @@ void Y_IntermissionDrawer(void)
// draw the "got through act" lines and act number
V_DrawLevelTitle(data.coop.passedx1, 49, 0, data.coop.passed1);
V_DrawLevelTitle(data.coop.passedx2, 49+V_LevelNameHeight(data.coop.passed2)+2, 0, data.coop.passed2);
{
INT32 h = V_LevelNameHeight(data.coop.passed2);
V_DrawLevelTitle(data.coop.passedx2, 49+h+2, 0, data.coop.passed2);
if (data.coop.actnum)
V_DrawLevelActNum(244, 57, 0, data.coop.actnum);
if (data.coop.actnum)
V_DrawLevelActNum(244, 42+h, 0, data.coop.actnum);
}
bonusy = 150;
// Total
@ -485,10 +488,10 @@ void Y_IntermissionDrawer(void)
if (drawsection == 1)
{
const char *ringtext = "\x82" "50 RINGS, NO SHIELD";
const char *tut1text = "\x82" "PRESS " "\x80" "SPIN";
const char *tut2text = "\x82" "MID-" "\x80" "JUMP";
ttheight = 16;
const char *ringtext = "\x82" "50 rings, no shield";
const char *tut1text = "\x82" "press " "\x80" "spin";
const char *tut2text = "\x82" "mid-" "\x80" "jump";
ttheight = 8;
V_DrawLevelTitle(data.spec.passedx1 + xoffset1, ttheight, 0, data.spec.passed1);
ttheight += V_LevelNameHeight(data.spec.passed3) + 2;
V_DrawLevelTitle(data.spec.passedx3 + xoffset2, ttheight, 0, data.spec.passed3);
@ -497,9 +500,9 @@ void Y_IntermissionDrawer(void)
ttheight = 108;
V_DrawLevelTitle(BASEVIDWIDTH/2 + xoffset4 - (V_LevelNameWidth(ringtext)/2), ttheight, 0, ringtext);
ttheight += V_LevelNameHeight(ringtext) + 2;
V_DrawLevelTitle(BASEVIDWIDTH/2 + xoffset5 - (V_LevelNameWidth(tut1text)/2), ttheight, 0, tut1text);
ttheight += V_LevelNameHeight(tut1text) + 2;
V_DrawLevelTitle(BASEVIDWIDTH/2 + xoffset5 - (V_LevelNameWidth(tut1text)/2), ttheight, 0, tut1text);
ttheight += V_LevelNameHeight(tut2text) + 2;
V_DrawLevelTitle(BASEVIDWIDTH/2 + xoffset6 - (V_LevelNameWidth(tut2text)/2), ttheight, 0, tut2text);
}
else
@ -1384,21 +1387,21 @@ void Y_StartIntermission(void)
// too long so just show "YOU GOT THROUGH THE ACT"
if (strlen(skins[players[consoleplayer].skin].realname) > 13)
{
strcpy(data.coop.passed1, "YOU GOT");
strcpy(data.coop.passed2, (mapheaderinfo[gamemap-1]->actnum) ? "THROUGH ACT" : "THROUGH THE ACT");
strcpy(data.coop.passed1, "you got");
strcpy(data.coop.passed2, (mapheaderinfo[gamemap-1]->actnum) ? "through act" : "through the act");
}
// long enough that "X GOT" won't fit so use "X PASSED THE ACT"
else if (strlen(skins[players[consoleplayer].skin].realname) > 8)
{
strcpy(data.coop.passed1, skins[players[consoleplayer].skin].realname);
strcpy(data.coop.passed2, (mapheaderinfo[gamemap-1]->actnum) ? "PASSED ACT" : "PASSED THE ACT");
strcpy(data.coop.passed2, (mapheaderinfo[gamemap-1]->actnum) ? "passed act" : "passed the act");
}
// length is okay for normal use
else
{
snprintf(data.coop.passed1, sizeof data.coop.passed1, "%s GOT",
snprintf(data.coop.passed1, sizeof data.coop.passed1, "%s got",
skins[players[consoleplayer].skin].realname);
strcpy(data.coop.passed2, (mapheaderinfo[gamemap-1]->actnum) ? "THROUGH ACT" : "THROUGH THE ACT");
strcpy(data.coop.passed2, (mapheaderinfo[gamemap-1]->actnum) ? "through act" : "through the act");
}
// set X positions
@ -1498,7 +1501,7 @@ void Y_StartIntermission(void)
// set up the "got through act" message according to skin name
if (stagefailed)
{
strcpy(data.spec.passed2, "SPECIAL STAGE");
strcpy(data.spec.passed2, "Special Stage");
data.spec.passed1[0] = '\0';
}
else if (ALL7EMERALDS(emeralds))
@ -1507,13 +1510,13 @@ void Y_StartIntermission(void)
sizeof data.spec.passed1, "%s",
skins[players[consoleplayer].skin].realname);
data.spec.passed1[sizeof data.spec.passed1 - 1] = '\0';
strcpy(data.spec.passed2, "GOT THEM ALL!");
strcpy(data.spec.passed2, "got them all!");
if (players[consoleplayer].charflags & SF_SUPER)
{
strcpy(data.spec.passed3, "CAN NOW BECOME");
strcpy(data.spec.passed3, "can now become");
snprintf(data.spec.passed4,
sizeof data.spec.passed4, "SUPER %s",
sizeof data.spec.passed4, "Super %s",
skins[players[consoleplayer].skin].realname);
data.spec.passed4[sizeof data.spec.passed4 - 1] = '\0';
}
@ -1523,13 +1526,13 @@ void Y_StartIntermission(void)
if (strlen(skins[players[consoleplayer].skin].realname) <= SKINNAMESIZE-5)
{
snprintf(data.spec.passed1,
sizeof data.spec.passed1, "%s GOT",
sizeof data.spec.passed1, "%s got",
skins[players[consoleplayer].skin].realname);
data.spec.passed1[sizeof data.spec.passed1 - 1] = '\0';
}
else
strcpy(data.spec.passed1, "YOU GOT");
strcpy(data.spec.passed2, "A CHAOS EMERALD");
strcpy(data.spec.passed1, "You got");
strcpy(data.spec.passed2, "a Chaos Emerald");
if (P_GetNextEmerald() > 6)
{
data.spec.passed2[15] = '?';