Merge branch 'next' into dashmode-fixes

This commit is contained in:
lachwright 2020-05-30 18:13:21 +08:00
commit ae5d5b9546
94 changed files with 3712 additions and 4073 deletions

View File

@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.0)
# DO NOT CHANGE THIS SRB2 STRING! Some variable names depend on this string. # DO NOT CHANGE THIS SRB2 STRING! Some variable names depend on this string.
# Version change is fine. # Version change is fine.
project(SRB2 project(SRB2
VERSION 2.2.2 VERSION 2.2.4
LANGUAGES C) LANGUAGES C)
if(${PROJECT_SOURCE_DIR} MATCHES ${PROJECT_BINARY_DIR}) if(${PROJECT_SOURCE_DIR} MATCHES ${PROJECT_BINARY_DIR})

View File

@ -1,4 +1,4 @@
version: 2.2.2.{branch}-{build} version: 2.2.4.{branch}-{build}
os: MinGW os: MinGW
environment: environment:

View File

@ -750,16 +750,11 @@ linedeftypes
prefix = "(20)"; prefix = "(20)";
} }
21
{
title = "Explicitly Include Line <disabled>";
prefix = "(21)";
}
22 22
{ {
title = "Parameters"; title = "Parameters";
prefix = "(22)"; prefix = "(22)";
flags8text = "[3] Set translucency by X offset";
flags32text = "[5] Render outer sides only"; flags32text = "[5] Render outer sides only";
flags64text = "[6] Trigger linedef executor"; flags64text = "[6] Trigger linedef executor";
flags128text = "[7] Intangible"; flags128text = "[7] Intangible";
@ -1908,6 +1903,27 @@ linedeftypes
prefix = "(333)"; prefix = "(333)";
} }
334
{
title = "Object Dye - Continuous";
flags64text = "[6] Disable for this color";
prefix = "(334)";
}
335
{
title = "Object Dye - Each Time";
flags64text = "[6] Disable for this color";
prefix = "(335)";
}
336
{
title = "Object Dye - Once";
flags64text = "[6] Disable for this color";
prefix = "(336)";
}
399 399
{ {
title = "Level Load"; title = "Level Load";
@ -2218,6 +2234,19 @@ linedeftypes
prefix = "(462)"; prefix = "(462)";
flags8text = "[3] Set delay by backside sector"; flags8text = "[3] Set delay by backside sector";
} }
463
{
title = "Dye Object";
prefix = "(463)";
}
464
{
title = "Trigger Egg Capsule";
prefix = "(464)";
flags64text = "[6] Don't end level";
}
} }
linedefexecmisc linedefexecmisc
@ -2568,45 +2597,63 @@ linedeftypes
500 500
{ {
title = "Scroll Wall Front Side Left"; title = "Scroll Front Wall Left";
prefix = "(500)"; prefix = "(500)";
} }
501 501
{ {
title = "Scroll Wall Front Side Right"; title = "Scroll Front Wall Right";
prefix = "(501)"; prefix = "(501)";
} }
502 502
{ {
title = "Scroll Wall According to Linedef"; title = "Scroll Tagged Wall";
prefix = "(502)"; prefix = "(502)";
flags128text = "[7] Use texture offsets";
flags256text = "[8] Scroll back side";
} }
503 503
{ {
title = "Scroll Wall According to Linedef (Accelerative)"; title = "Scroll Tagged Wall (Accelerative)";
prefix = "(503)"; prefix = "(503)";
flags128text = "[7] Use texture offsets";
flags256text = "[8] Scroll back side";
} }
504 504
{ {
title = "Scroll Wall According to Linedef (Displacement)"; title = "Scroll Tagged Wall (Displacement)";
prefix = "(504)"; prefix = "(504)";
flags128text = "[7] Use texture offsets";
flags256text = "[8] Scroll back side";
} }
505 505
{ {
title = "Scroll Texture by Front Side Offsets"; title = "Scroll Front Wall by Front Side Offsets";
prefix = "(505)"; prefix = "(505)";
} }
506 506
{ {
title = "Scroll Texture by Back Side Offsets"; title = "Scroll Front Wall by Back Side Offsets";
prefix = "(506)"; prefix = "(506)";
} }
507
{
title = "Scroll Back Wall by Front Side Offsets";
prefix = "(507)";
}
508
{
title = "Scroll Back Wall by Back Side Offsets";
prefix = "(508)";
}
} }
planescroll planescroll
@ -3704,6 +3751,7 @@ thingtypes
width = 8; width = 8;
height = 16; height = 16;
sprite = "internal:capsule"; sprite = "internal:capsule";
angletext = "Tag";
} }
292 292
{ {

View File

@ -931,11 +931,8 @@ static inline void AM_drawWalls(void)
l.b.y = lines[i].v2->y >> FRACTOMAPBITS; l.b.y = lines[i].v2->y >> FRACTOMAPBITS;
#define SLOPEPARAMS(slope, end1, end2, normalheight) \ #define SLOPEPARAMS(slope, end1, end2, normalheight) \
if (slope) { \ end1 = P_GetZAt(slope, lines[i].v1->x, lines[i].v1->y, normalheight); \
end1 = P_GetZAt(slope, lines[i].v1->x, lines[i].v1->y); \ end2 = P_GetZAt(slope, lines[i].v2->x, lines[i].v2->y, normalheight);
end2 = P_GetZAt(slope, lines[i].v2->x, lines[i].v2->y); \
} else \
end1 = end2 = normalheight;
SLOPEPARAMS(lines[i].frontsector->f_slope, frontf1, frontf2, lines[i].frontsector->floorheight) SLOPEPARAMS(lines[i].frontsector->f_slope, frontf1, frontf2, lines[i].frontsector->floorheight)
SLOPEPARAMS(lines[i].frontsector->c_slope, frontc1, frontc2, lines[i].frontsector->ceilingheight) SLOPEPARAMS(lines[i].frontsector->c_slope, frontc1, frontc2, lines[i].frontsector->ceilingheight)

View File

@ -459,7 +459,6 @@ boolean B_CheckRespawn(player_t *player)
if (!sonic || sonic->health <= 0) if (!sonic || sonic->health <= 0)
return false; return false;
#ifdef HAVE_BLUA
// B_RespawnBot doesn't do anything if the condition above this isn't met // B_RespawnBot doesn't do anything if the condition above this isn't met
{ {
UINT8 shouldForce = LUAh_BotRespawn(sonic, tails); UINT8 shouldForce = LUAh_BotRespawn(sonic, tails);
@ -472,7 +471,6 @@ boolean B_CheckRespawn(player_t *player)
else if (shouldForce == 2) else if (shouldForce == 2)
return false; return false;
} }
#endif
// Check if Sonic is busy first. // Check if Sonic is busy first.
// If he's doing any of these things, he probably doesn't want to see us. // If he's doing any of these things, he probably doesn't want to see us.

View File

@ -28,12 +28,14 @@
/* Manually defined asset hashes for non-CMake builds /* Manually defined asset hashes for non-CMake builds
* Last updated 2020 / 02 / 15 - v2.2.1 - main assets * Last updated 2020 / 02 / 15 - v2.2.1 - main assets
* Last updated 2020 / 02 / 22 - v2.2.2 - patch.pk3 * Last updated 2020 / 02 / 22 - v2.2.2 - patch.pk3
* Last updated 2020 / 05 / 10 - v2.2.3 - player.dta & patch.pk3
* Last updated 2020 / 05 / 11 - v2.2.4 - patch.pk3
*/ */
#define ASSET_HASH_SRB2_PK3 "0277c9416756627004e83cbb5b2e3e28" #define ASSET_HASH_SRB2_PK3 "0277c9416756627004e83cbb5b2e3e28"
#define ASSET_HASH_ZONES_PK3 "f7e88afb6af7996a834c7d663144bead" #define ASSET_HASH_ZONES_PK3 "f7e88afb6af7996a834c7d663144bead"
#define ASSET_HASH_PLAYER_DTA "ad49e07b17cc662f1ad70c454910b4ae" #define ASSET_HASH_PLAYER_DTA "8a4507ddf9bc0682c09174400f26ad65"
#ifdef USE_PATCH_DTA #ifdef USE_PATCH_DTA
#define ASSET_HASH_PATCH_PK3 "ee54330ecb743314c5f962af4db731ff" #define ASSET_HASH_PATCH_PK3 "bbbf6af3b20349612ee06e0b55979a76"
#endif #endif
#endif #endif

View File

@ -85,6 +85,10 @@ tic_t jointimeout = (10*TICRATE);
static boolean sendingsavegame[MAXNETNODES]; // Are we sending the savegame? static boolean sendingsavegame[MAXNETNODES]; // Are we sending the savegame?
static tic_t freezetimeout[MAXNETNODES]; // Until when can this node freeze the server before getting a timeout? static tic_t freezetimeout[MAXNETNODES]; // Until when can this node freeze the server before getting a timeout?
// Incremented by cv_joindelay when a client joins, decremented each tic.
// If higher than cv_joindelay * 2 (3 joins in a short timespan), joins are temporarily disabled.
static tic_t joindelay = 0;
UINT16 pingmeasurecount = 1; UINT16 pingmeasurecount = 1;
UINT32 realpingtable[MAXPLAYERS]; //the base table of ping where an average will be sent to everyone. UINT32 realpingtable[MAXPLAYERS]; //the base table of ping where an average will be sent to everyone.
UINT32 playerpingtable[MAXPLAYERS]; //table of player latency values. UINT32 playerpingtable[MAXPLAYERS]; //table of player latency values.
@ -191,24 +195,25 @@ static inline void *G_ScpyTiccmd(ticcmd_t* dest, void* src, const size_t n)
// of 512 bytes is like 0.1) // of 512 bytes is like 0.1)
UINT16 software_MAXPACKETLENGTH; UINT16 software_MAXPACKETLENGTH;
/** Guesses the value of a tic from its lowest byte and from maketic /** Guesses the full value of a tic from its lowest byte, for a specific node
* *
* \param low The lowest byte of the tic value * \param low The lowest byte of the tic value
* \param node The node to deduce the tic for
* \return The full tic value * \return The full tic value
* *
*/ */
tic_t ExpandTics(INT32 low) tic_t ExpandTics(INT32 low, INT32 node)
{ {
INT32 delta; INT32 delta;
delta = low - (maketic & UINT8_MAX); delta = low - (nettics[node] & UINT8_MAX);
if (delta >= -64 && delta <= 64) if (delta >= -64 && delta <= 64)
return (maketic & ~UINT8_MAX) + low; return (nettics[node] & ~UINT8_MAX) + low;
else if (delta > 64) else if (delta > 64)
return (maketic & ~UINT8_MAX) - 256 + low; return (nettics[node] & ~UINT8_MAX) - 256 + low;
else //if (delta < -64) else //if (delta < -64)
return (maketic & ~UINT8_MAX) + 256 + low; return (nettics[node] & ~UINT8_MAX) + 256 + low;
} }
// ----------------------------------------------------------------- // -----------------------------------------------------------------
@ -1491,7 +1496,7 @@ static boolean SV_SendServerConfig(INT32 node)
if (!playeringame[i]) if (!playeringame[i])
continue; continue;
netbuffer->u.servercfg.playerskins[i] = (UINT8)players[i].skin; netbuffer->u.servercfg.playerskins[i] = (UINT8)players[i].skin;
netbuffer->u.servercfg.playercolor[i] = (UINT8)players[i].skincolor; netbuffer->u.servercfg.playercolor[i] = (UINT16)players[i].skincolor;
netbuffer->u.servercfg.playeravailabilities[i] = (UINT32)LONG(players[i].availabilities); netbuffer->u.servercfg.playeravailabilities[i] = (UINT32)LONG(players[i].availabilities);
} }
@ -1686,7 +1691,7 @@ static void CL_LoadReceivedSavegame(void)
// load a base level // load a base level
if (P_LoadNetGame()) if (P_LoadNetGame())
{ {
const INT32 actnum = mapheaderinfo[gamemap-1]->actnum; const UINT8 actnum = mapheaderinfo[gamemap-1]->actnum;
CONS_Printf(M_GetText("Map is now \"%s"), G_BuildMapName(gamemap)); CONS_Printf(M_GetText("Map is now \"%s"), G_BuildMapName(gamemap));
if (strcmp(mapheaderinfo[gamemap-1]->lvlttl, "")) if (strcmp(mapheaderinfo[gamemap-1]->lvlttl, ""))
{ {
@ -3077,6 +3082,8 @@ consvar_t cv_allownewplayer = {"allowjoin", "On", CV_NETVAR, CV_OnOff, NULL, 0,
consvar_t cv_joinnextround = {"joinnextround", "Off", CV_NETVAR, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; /// \todo not done consvar_t cv_joinnextround = {"joinnextround", "Off", CV_NETVAR, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; /// \todo not done
static CV_PossibleValue_t maxplayers_cons_t[] = {{2, "MIN"}, {32, "MAX"}, {0, NULL}}; static CV_PossibleValue_t maxplayers_cons_t[] = {{2, "MIN"}, {32, "MAX"}, {0, NULL}};
consvar_t cv_maxplayers = {"maxplayers", "8", CV_SAVE, maxplayers_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_maxplayers = {"maxplayers", "8", CV_SAVE, maxplayers_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
static CV_PossibleValue_t joindelay_cons_t[] = {{1, "MIN"}, {3600, "MAX"}, {0, "Off"}, {0, NULL}};
consvar_t cv_joindelay = {"joindelay", "10", CV_SAVE, joindelay_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
static CV_PossibleValue_t rejointimeout_cons_t[] = {{1, "MIN"}, {60 * FRACUNIT, "MAX"}, {0, "Off"}, {0, NULL}}; static CV_PossibleValue_t rejointimeout_cons_t[] = {{1, "MIN"}, {60 * FRACUNIT, "MAX"}, {0, "Off"}, {0, NULL}};
consvar_t cv_rejointimeout = {"rejointimeout", "Off", CV_SAVE|CV_FLOAT, rejointimeout_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_rejointimeout = {"rejointimeout", "Off", CV_SAVE|CV_FLOAT, rejointimeout_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
@ -3164,6 +3171,8 @@ void SV_ResetServer(void)
neededtic = maketic; neededtic = maketic;
tictoclear = maketic; tictoclear = maketic;
joindelay = 0;
for (i = 0; i < MAXNETNODES; i++) for (i = 0; i < MAXNETNODES; i++)
ResetNode(i); ResetNode(i);
@ -3283,7 +3292,6 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum)
boolean splitscreenplayer; boolean splitscreenplayer;
boolean rejoined; boolean rejoined;
player_t *newplayer; player_t *newplayer;
char *port;
if (playernum != serverplayer && !IsPlayerAdmin(playernum)) if (playernum != serverplayer && !IsPlayerAdmin(playernum))
{ {
@ -3314,10 +3322,15 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum)
if (server && I_GetNodeAddress) if (server && I_GetNodeAddress)
{ {
strcpy(playeraddress[newplayernum], I_GetNodeAddress(node)); const char *address = I_GetNodeAddress(node);
port = strchr(playeraddress[newplayernum], ':'); char *port = NULL;
if (port) if (address) // MI: fix msvcrt.dll!_mbscat crash?
*port = '\0'; {
strcpy(playeraddress[newplayernum], address);
port = strchr(playeraddress[newplayernum], ':');
if (port)
*port = '\0';
}
} }
} }
@ -3613,6 +3626,9 @@ static void HandleConnect(SINT8 node)
SV_SendRefuse(node, M_GetText("No players from\nthis node.")); SV_SendRefuse(node, M_GetText("No players from\nthis node."));
else if (luafiletransfers) else if (luafiletransfers)
SV_SendRefuse(node, M_GetText("The server is broadcasting a file\nrequested by a Lua script.\nPlease wait a bit and then\ntry rejoining.")); SV_SendRefuse(node, M_GetText("The server is broadcasting a file\nrequested by a Lua script.\nPlease wait a bit and then\ntry rejoining."));
else if (netgame && joindelay > 2 * (tic_t)cv_joindelay.value * TICRATE)
SV_SendRefuse(node, va(M_GetText("Too many people are connecting.\nPlease wait %d seconds and then\ntry rejoining."),
(joindelay - 2 * cv_joindelay.value * TICRATE) / TICRATE));
else else
{ {
#ifndef NONET #ifndef NONET
@ -3670,6 +3686,7 @@ static void HandleConnect(SINT8 node)
DEBFILE("send savegame\n"); DEBFILE("send savegame\n");
} }
SV_AddWaitingPlayers(names[0], names[1]); SV_AddWaitingPlayers(names[0], names[1]);
joindelay += cv_joindelay.value * TICRATE;
player_joining = true; player_joining = true;
} }
#else #else
@ -3865,7 +3882,7 @@ static void HandlePacketFromAwayNode(SINT8 node)
for (j = 0; j < MAXPLAYERS; j++) for (j = 0; j < MAXPLAYERS; j++)
{ {
if (netbuffer->u.servercfg.playerskins[j] == 0xFF if (netbuffer->u.servercfg.playerskins[j] == 0xFF
&& netbuffer->u.servercfg.playercolor[j] == 0xFF && netbuffer->u.servercfg.playercolor[j] == 0xFFFF
&& netbuffer->u.servercfg.playeravailabilities[j] == 0xFFFFFFFF) && netbuffer->u.servercfg.playeravailabilities[j] == 0xFFFFFFFF)
continue; // not in game continue; // not in game
@ -3987,8 +4004,8 @@ static void HandlePacketFromPlayer(SINT8 node)
// To save bytes, only the low byte of tic numbers are sent // To save bytes, only the low byte of tic numbers are sent
// Use ExpandTics to figure out what the rest of the bytes are // Use ExpandTics to figure out what the rest of the bytes are
realstart = ExpandTics(netbuffer->u.clientpak.client_tic); realstart = ExpandTics(netbuffer->u.clientpak.client_tic, node);
realend = ExpandTics(netbuffer->u.clientpak.resendfrom); realend = ExpandTics(netbuffer->u.clientpak.resendfrom, node);
if (netbuffer->packettype == PT_CLIENTMIS || netbuffer->packettype == PT_CLIENT2MIS if (netbuffer->packettype == PT_CLIENTMIS || netbuffer->packettype == PT_CLIENT2MIS
|| netbuffer->packettype == PT_NODEKEEPALIVEMIS || netbuffer->packettype == PT_NODEKEEPALIVEMIS
@ -4240,15 +4257,15 @@ static void HandlePacketFromPlayer(SINT8 node)
break; break;
} }
realstart = ExpandTics(netbuffer->u.serverpak.starttic); realstart = netbuffer->u.serverpak.starttic;
realend = realstart + netbuffer->u.serverpak.numtics; realend = realstart + netbuffer->u.serverpak.numtics;
if (!txtpak) if (!txtpak)
txtpak = (UINT8 *)&netbuffer->u.serverpak.cmds[netbuffer->u.serverpak.numslots txtpak = (UINT8 *)&netbuffer->u.serverpak.cmds[netbuffer->u.serverpak.numslots
* netbuffer->u.serverpak.numtics]; * netbuffer->u.serverpak.numtics];
if (realend > gametic + BACKUPTICS) if (realend > gametic + CLIENTBACKUPTICS)
realend = gametic + BACKUPTICS; realend = gametic + CLIENTBACKUPTICS;
cl_packetmissed = realstart > neededtic; cl_packetmissed = realstart > neededtic;
if (realstart <= neededtic && realend > neededtic) if (realstart <= neededtic && realend > neededtic)
@ -4591,11 +4608,11 @@ static void SV_SendTics(void)
for (n = 1; n < MAXNETNODES; n++) for (n = 1; n < MAXNETNODES; n++)
if (nodeingame[n]) if (nodeingame[n])
{ {
lasttictosend = maketic;
// assert supposedtics[n]>=nettics[n] // assert supposedtics[n]>=nettics[n]
realfirsttic = supposedtics[n]; realfirsttic = supposedtics[n];
if (realfirsttic >= maketic) lasttictosend = min(maketic, realfirsttic + CLIENTBACKUPTICS);
if (realfirsttic >= lasttictosend)
{ {
// well we have sent all tics we will so use extrabandwidth // well we have sent all tics we will so use extrabandwidth
// to resent packet that are supposed lost (this is necessary since lost // to resent packet that are supposed lost (this is necessary since lost
@ -4604,7 +4621,7 @@ static void SV_SendTics(void)
DEBFILE(va("Nothing to send node %u mak=%u sup=%u net=%u \n", DEBFILE(va("Nothing to send node %u mak=%u sup=%u net=%u \n",
n, maketic, supposedtics[n], nettics[n])); n, maketic, supposedtics[n], nettics[n]));
realfirsttic = nettics[n]; realfirsttic = nettics[n];
if (realfirsttic >= maketic || (I_GetTime() + n)&3) if (realfirsttic >= lasttictosend || (I_GetTime() + n)&3)
// all tic are ok // all tic are ok
continue; continue;
DEBFILE(va("Sent %d anyway\n", realfirsttic)); DEBFILE(va("Sent %d anyway\n", realfirsttic));
@ -4647,7 +4664,7 @@ static void SV_SendTics(void)
// Send the tics // Send the tics
netbuffer->packettype = PT_SERVERTICS; netbuffer->packettype = PT_SERVERTICS;
netbuffer->u.serverpak.starttic = (UINT8)realfirsttic; netbuffer->u.serverpak.starttic = realfirsttic;
netbuffer->u.serverpak.numtics = (UINT8)(lasttictosend - realfirsttic); netbuffer->u.serverpak.numtics = (UINT8)(lasttictosend - realfirsttic);
netbuffer->u.serverpak.numslots = (UINT8)SHORT(doomcom->numslots); netbuffer->u.serverpak.numslots = (UINT8)SHORT(doomcom->numslots);
bufpos = (UINT8 *)&netbuffer->u.serverpak.cmds; bufpos = (UINT8 *)&netbuffer->u.serverpak.cmds;
@ -5038,12 +5055,21 @@ void NetUpdate(void)
hu_resynching = true; hu_resynching = true;
} }
} }
Net_AckTicker(); Net_AckTicker();
// Handle timeouts to prevent definitive freezes from happenning // Handle timeouts to prevent definitive freezes from happenning
if (server) if (server)
{
for (i = 1; i < MAXNETNODES; i++) for (i = 1; i < MAXNETNODES; i++)
if (nodeingame[i] && freezetimeout[i] < I_GetTime()) if (nodeingame[i] && freezetimeout[i] < I_GetTime())
Net_ConnectionTimeout(i); Net_ConnectionTimeout(i);
// In case the cvar value was lowered
if (joindelay)
joindelay = min(joindelay - 1, 3 * (tic_t)cv_joindelay.value * TICRATE);
}
nowtime /= NEWTICRATERATIO; nowtime /= NEWTICRATERATIO;
if (nowtime > resptime) if (nowtime > resptime)
{ {
@ -5051,6 +5077,7 @@ void NetUpdate(void)
M_Ticker(); M_Ticker();
CON_Ticker(); CON_Ticker();
} }
SV_FileSendTicker(); SV_FileSendTicker();
} }

View File

@ -34,6 +34,7 @@ applications may follow different packet versions.
// Networking and tick handling related. // Networking and tick handling related.
#define BACKUPTICS 96 #define BACKUPTICS 96
#define CLIENTBACKUPTICS 32
#define MAXTEXTCMD 256 #define MAXTEXTCMD 256
// //
// Packet structure // Packet structure
@ -128,7 +129,7 @@ typedef struct
// this packet is too large // this packet is too large
typedef struct typedef struct
{ {
UINT8 starttic; tic_t starttic;
UINT8 numtics; UINT8 numtics;
UINT8 numslots; // "Slots filled": Highest player number in use plus one. UINT8 numslots; // "Slots filled": Highest player number in use plus one.
ticcmd_t cmds[45]; // Normally [BACKUPTIC][MAXPLAYERS] but too large ticcmd_t cmds[45]; // Normally [BACKUPTIC][MAXPLAYERS] but too large
@ -188,7 +189,7 @@ typedef struct
SINT8 xtralife; SINT8 xtralife;
SINT8 pity; SINT8 pity;
UINT8 skincolor; UINT16 skincolor;
INT32 skin; INT32 skin;
UINT32 availabilities; UINT32 availabilities;
// Just in case Lua does something like // Just in case Lua does something like
@ -308,7 +309,7 @@ typedef struct
// 0xFF == not in game; else player skin num // 0xFF == not in game; else player skin num
UINT8 playerskins[MAXPLAYERS]; UINT8 playerskins[MAXPLAYERS];
UINT8 playercolor[MAXPLAYERS]; UINT16 playercolor[MAXPLAYERS];
UINT32 playeravailabilities[MAXPLAYERS]; UINT32 playeravailabilities[MAXPLAYERS];
UINT8 gametype; UINT8 gametype;
@ -414,7 +415,7 @@ typedef struct
{ {
char name[MAXPLAYERNAME+1]; char name[MAXPLAYERNAME+1];
UINT8 skin; UINT8 skin;
UINT8 color; UINT16 color;
UINT32 pflags; UINT32 pflags;
UINT32 score; UINT32 score;
UINT8 ctfteam; UINT8 ctfteam;
@ -515,12 +516,12 @@ extern UINT32 realpingtable[MAXPLAYERS];
extern UINT32 playerpingtable[MAXPLAYERS]; extern UINT32 playerpingtable[MAXPLAYERS];
extern tic_t servermaxping; extern tic_t servermaxping;
extern consvar_t cv_allownewplayer, cv_joinnextround, cv_maxplayers, cv_rejointimeout; extern consvar_t cv_allownewplayer, cv_joinnextround, cv_maxplayers, cv_joindelay, cv_rejointimeout;
extern consvar_t cv_resynchattempts, cv_blamecfail; extern consvar_t cv_resynchattempts, cv_blamecfail;
extern consvar_t cv_maxsend, cv_noticedownload, cv_downloadspeed; extern consvar_t cv_maxsend, cv_noticedownload, cv_downloadspeed;
// Used in d_net, the only dependence // Used in d_net, the only dependence
tic_t ExpandTics(INT32 low); tic_t ExpandTics(INT32 low, INT32 node);
void D_ClientServerInit(void); void D_ClientServerInit(void);
// Initialise the other field // Initialise the other field

View File

@ -125,6 +125,11 @@ boolean advancedemo;
INT32 debugload = 0; INT32 debugload = 0;
#endif #endif
UINT16 numskincolors;
menucolor_t *menucolorhead, *menucolortail;
char savegamename[256];
char srb2home[256] = "."; char srb2home[256] = ".";
char srb2path[256] = "."; char srb2path[256] = ".";
boolean usehome = true; boolean usehome = true;
@ -310,7 +315,9 @@ static void D_Display(void)
F_WipeStartScreen(); F_WipeStartScreen();
// Check for Mega Genesis fade // Check for Mega Genesis fade
wipestyleflags = WSF_FADEOUT; wipestyleflags = WSF_FADEOUT;
if (F_TryColormapFade(31)) if (wipegamestate == (gamestate_t)FORCEWIPE)
F_WipeColorFill(31);
else if (F_TryColormapFade(31))
wipetypepost = -1; // Don't run the fade below this one wipetypepost = -1; // Don't run the fade below this one
F_WipeEndScreen(); F_WipeEndScreen();
F_RunWipe(wipetypepre, gamestate != GS_TIMEATTACK && gamestate != GS_TITLESCREEN); F_RunWipe(wipetypepre, gamestate != GS_TIMEATTACK && gamestate != GS_TITLESCREEN);
@ -991,6 +998,7 @@ static void IdentifyVersion(void)
} }
MUSICTEST("music.dta") MUSICTEST("music.dta")
MUSICTEST("patch_music.pk3")
#ifdef DEVELOP // remove when music_new.dta is merged into music.dta #ifdef DEVELOP // remove when music_new.dta is merged into music.dta
MUSICTEST("music_new.dta") MUSICTEST("music_new.dta")
#endif #endif
@ -1186,6 +1194,10 @@ void D_SRB2Main(void)
if (M_CheckParm("-password") && M_IsNextParm()) if (M_CheckParm("-password") && M_IsNextParm())
D_SetPassword(M_GetNextParm()); D_SetPassword(M_GetNextParm());
// player setup menu colors must be initialized before
// any wad file is added, as they may contain colors themselves
M_InitPlayerSetupColors();
CONS_Printf("Z_Init(): Init zone memory allocation daemon. \n"); CONS_Printf("Z_Init(): Init zone memory allocation daemon. \n");
Z_Init(); Z_Init();

View File

@ -811,6 +811,7 @@ static const char *packettypename[NUMPACKETTYPE] =
"CLIENTJOIN", "CLIENTJOIN",
"NODETIMEOUT", "NODETIMEOUT",
"RESYNCHING", "RESYNCHING",
"LOGIN",
"PING" "PING"
}; };
@ -837,7 +838,7 @@ static void DebugPrintpacket(const char *header)
size_t ntxtcmd = &((UINT8 *)netbuffer)[doomcom->datalength] - cmd; size_t ntxtcmd = &((UINT8 *)netbuffer)[doomcom->datalength] - cmd;
fprintf(debugfile, " firsttic %u ply %d tics %d ntxtcmd %s\n ", fprintf(debugfile, " firsttic %u ply %d tics %d ntxtcmd %s\n ",
(UINT32)ExpandTics(serverpak->starttic), serverpak->numslots, serverpak->numtics, sizeu1(ntxtcmd)); (UINT32)serverpak->starttic, serverpak->numslots, serverpak->numtics, sizeu1(ntxtcmd));
/// \todo Display more readable information about net commands /// \todo Display more readable information about net commands
fprintfstringnewline((char *)cmd, ntxtcmd); fprintfstringnewline((char *)cmd, ntxtcmd);
/*fprintfstring((char *)cmd, 3); /*fprintfstring((char *)cmd, 3);
@ -856,8 +857,8 @@ static void DebugPrintpacket(const char *header)
case PT_NODEKEEPALIVE: case PT_NODEKEEPALIVE:
case PT_NODEKEEPALIVEMIS: case PT_NODEKEEPALIVEMIS:
fprintf(debugfile, " tic %4u resendfrom %u\n", fprintf(debugfile, " tic %4u resendfrom %u\n",
(UINT32)ExpandTics(netbuffer->u.clientpak.client_tic), (UINT32)ExpandTics(netbuffer->u.clientpak.client_tic, doomcom->remotenode),
(UINT32)ExpandTics (netbuffer->u.clientpak.resendfrom)); (UINT32)ExpandTics (netbuffer->u.clientpak.resendfrom, doomcom->remotenode));
break; break;
case PT_TEXTCMD: case PT_TEXTCMD:
case PT_TEXTCMD2: case PT_TEXTCMD2:

View File

@ -225,6 +225,7 @@ consvar_t cv_allowseenames = {"allowseenames", "Yes", CV_NETVAR, CV_YesNo, 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_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}; consvar_t cv_playername2 = {"name2", "Tails", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Name2_OnChange, 0, NULL, NULL, 0, 0, NULL};
// player colors // player colors
UINT16 lastgoodcolor = SKINCOLOR_BLUE, lastgoodcolor2 = SKINCOLOR_BLUE;
consvar_t cv_playercolor = {"color", "Blue", CV_CALL|CV_NOINIT, Color_cons_t, Color_OnChange, 0, NULL, NULL, 0, 0, NULL}; 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}; consvar_t cv_playercolor2 = {"color2", "Orange", CV_CALL|CV_NOINIT, Color_cons_t, Color2_OnChange, 0, NULL, NULL, 0, 0, NULL};
// player's skin, saved for commodity, when using a favorite skins wad.. // player's skin, saved for commodity, when using a favorite skins wad..
@ -573,6 +574,7 @@ void D_RegisterServerCommands(void)
// d_clisrv // d_clisrv
CV_RegisterVar(&cv_maxplayers); CV_RegisterVar(&cv_maxplayers);
CV_RegisterVar(&cv_joindelay);
CV_RegisterVar(&cv_rejointimeout); CV_RegisterVar(&cv_rejointimeout);
CV_RegisterVar(&cv_resynchattempts); CV_RegisterVar(&cv_resynchattempts);
CV_RegisterVar(&cv_maxsend); CV_RegisterVar(&cv_maxsend);
@ -618,7 +620,7 @@ void D_RegisterClientCommands(void)
for (i = 0; i < MAXSKINCOLORS; i++) for (i = 0; i < MAXSKINCOLORS; i++)
{ {
Color_cons_t[i].value = i; Color_cons_t[i].value = i;
Color_cons_t[i].strvalue = Color_Names[i]; Color_cons_t[i].strvalue = skincolors[i].name;
} }
Color_cons_t[MAXSKINCOLORS].value = 0; Color_cons_t[MAXSKINCOLORS].value = 0;
Color_cons_t[MAXSKINCOLORS].strvalue = NULL; Color_cons_t[MAXSKINCOLORS].strvalue = NULL;
@ -1220,15 +1222,20 @@ static void SendNameAndColor(void)
CV_StealthSetValue(&cv_playercolor, skincolor_blueteam); CV_StealthSetValue(&cv_playercolor, skincolor_blueteam);
} }
// never allow the color "none" // don't allow inaccessible colors
if (!cv_playercolor.value) if (!skincolors[cv_playercolor.value].accessible)
{ {
if (players[consoleplayer].skincolor) if (players[consoleplayer].skincolor && skincolors[players[consoleplayer].skincolor].accessible)
CV_StealthSetValue(&cv_playercolor, players[consoleplayer].skincolor); CV_StealthSetValue(&cv_playercolor, players[consoleplayer].skincolor);
else if (skins[players[consoleplayer].skin].prefcolor) else if (skincolors[atoi(cv_playercolor.defaultvalue)].accessible)
CV_StealthSetValue(&cv_playercolor, skins[players[consoleplayer].skin].prefcolor);
else
CV_StealthSet(&cv_playercolor, cv_playercolor.defaultvalue); CV_StealthSet(&cv_playercolor, cv_playercolor.defaultvalue);
else if (skins[players[consoleplayer].skin].prefcolor && skincolors[skins[players[consoleplayer].skin].prefcolor].accessible)
CV_StealthSetValue(&cv_playercolor, skins[players[consoleplayer].skin].prefcolor);
else {
UINT16 i = 0;
while (i<numskincolors && !skincolors[i].accessible) i++;
CV_StealthSetValue(&cv_playercolor, (i != numskincolors) ? i : SKINCOLOR_BLUE);
}
} }
if (!strcmp(cv_playername.string, player_names[consoleplayer]) if (!strcmp(cv_playername.string, player_names[consoleplayer])
@ -1275,10 +1282,10 @@ static void SendNameAndColor(void)
{ {
CV_StealthSetValue(&cv_playercolor, skins[cv_skin.value].prefcolor); CV_StealthSetValue(&cv_playercolor, skins[cv_skin.value].prefcolor);
players[consoleplayer].skincolor = cv_playercolor.value % MAXSKINCOLORS; players[consoleplayer].skincolor = cv_playercolor.value % numskincolors;
if (players[consoleplayer].mo) if (players[consoleplayer].mo)
players[consoleplayer].mo->color = (UINT8)players[consoleplayer].skincolor; players[consoleplayer].mo->color = (UINT16)players[consoleplayer].skincolor;
}*/ }*/
} }
else else
@ -1316,7 +1323,7 @@ static void SendNameAndColor(void)
// Finally write out the complete packet and send it off. // Finally write out the complete packet and send it off.
WRITESTRINGN(p, cv_playername.zstring, MAXPLAYERNAME); WRITESTRINGN(p, cv_playername.zstring, MAXPLAYERNAME);
WRITEUINT32(p, (UINT32)players[consoleplayer].availabilities); WRITEUINT32(p, (UINT32)players[consoleplayer].availabilities);
WRITEUINT8(p, (UINT8)cv_playercolor.value); WRITEUINT16(p, (UINT16)cv_playercolor.value);
WRITEUINT8(p, (UINT8)cv_skin.value); WRITEUINT8(p, (UINT8)cv_skin.value);
SendNetXCmd(XD_NAMEANDCOLOR, buf, p - buf); SendNetXCmd(XD_NAMEANDCOLOR, buf, p - buf);
} }
@ -1343,15 +1350,20 @@ static void SendNameAndColor2(void)
CV_StealthSetValue(&cv_playercolor2, skincolor_blueteam); CV_StealthSetValue(&cv_playercolor2, skincolor_blueteam);
} }
// never allow the color "none" // don't allow inaccessible colors
if (!cv_playercolor2.value) if (!skincolors[cv_playercolor2.value].accessible)
{ {
if (players[secondplaya].skincolor) if (players[secondplaya].skincolor && skincolors[players[secondplaya].skincolor].accessible)
CV_StealthSetValue(&cv_playercolor2, players[secondplaya].skincolor); CV_StealthSetValue(&cv_playercolor2, players[secondplaya].skincolor);
else if (skins[players[secondplaya].skin].prefcolor) else if (skincolors[atoi(cv_playercolor2.defaultvalue)].accessible)
CV_StealthSet(&cv_playercolor, cv_playercolor2.defaultvalue);
else if (skins[players[secondplaya].skin].prefcolor && skincolors[skins[players[secondplaya].skin].prefcolor].accessible)
CV_StealthSetValue(&cv_playercolor2, skins[players[secondplaya].skin].prefcolor); CV_StealthSetValue(&cv_playercolor2, skins[players[secondplaya].skin].prefcolor);
else else {
CV_StealthSet(&cv_playercolor2, cv_playercolor2.defaultvalue); UINT16 i = 0;
while (i<numskincolors && !skincolors[i].accessible) i++;
CV_StealthSetValue(&cv_playercolor2, (i != numskincolors) ? i : SKINCOLOR_BLUE);
}
} }
players[secondplaya].availabilities = R_GetSkinAvailabilities(); players[secondplaya].availabilities = R_GetSkinAvailabilities();
@ -1404,7 +1416,7 @@ static void SendNameAndColor2(void)
{ {
CV_StealthSetValue(&cv_playercolor2, skins[players[secondplaya].skin].prefcolor); CV_StealthSetValue(&cv_playercolor2, skins[players[secondplaya].skin].prefcolor);
players[secondplaya].skincolor = cv_playercolor2.value % MAXSKINCOLORS; players[secondplaya].skincolor = cv_playercolor2.value % numskincolors;
if (players[secondplaya].mo) if (players[secondplaya].mo)
players[secondplaya].mo->color = players[secondplaya].skincolor; players[secondplaya].mo->color = players[secondplaya].skincolor;
@ -1427,7 +1439,8 @@ static void Got_NameAndColor(UINT8 **cp, INT32 playernum)
{ {
player_t *p = &players[playernum]; player_t *p = &players[playernum];
char name[MAXPLAYERNAME+1]; char name[MAXPLAYERNAME+1];
UINT8 color, skin; UINT16 color;
UINT8 skin;
#ifdef PARANOIA #ifdef PARANOIA
if (playernum < 0 || playernum > MAXPLAYERS) if (playernum < 0 || playernum > MAXPLAYERS)
@ -1446,7 +1459,7 @@ static void Got_NameAndColor(UINT8 **cp, INT32 playernum)
READSTRINGN(*cp, name, MAXPLAYERNAME); READSTRINGN(*cp, name, MAXPLAYERNAME);
p->availabilities = READUINT32(*cp); p->availabilities = READUINT32(*cp);
color = READUINT8(*cp); color = READUINT16(*cp);
skin = READUINT8(*cp); skin = READUINT8(*cp);
// set name // set name
@ -1454,9 +1467,9 @@ static void Got_NameAndColor(UINT8 **cp, INT32 playernum)
SetPlayerName(playernum, name); SetPlayerName(playernum, name);
// set color // set color
p->skincolor = color % MAXSKINCOLORS; p->skincolor = color % numskincolors;
if (p->mo) if (p->mo)
p->mo->color = (UINT8)p->skincolor; p->mo->color = (UINT16)p->skincolor;
// normal player colors // normal player colors
if (server && (p != &players[consoleplayer] && p != &players[secondarydisplayplayer])) if (server && (p != &players[consoleplayer] && p != &players[secondarydisplayplayer]))
@ -1473,8 +1486,8 @@ static void Got_NameAndColor(UINT8 **cp, INT32 playernum)
kick = true; kick = true;
} }
// don't allow color "none" // don't allow inaccessible colors
if (!p->skincolor) if (skincolors[p->skincolor].accessible == false)
kick = true; kick = true;
// availabilities // availabilities
@ -4472,25 +4485,30 @@ static void Skin2_OnChange(void)
*/ */
static void Color_OnChange(void) static void Color_OnChange(void)
{ {
if (!Playing()) if (!Playing()) {
return; // do whatever you want if (!cv_playercolor.value || !skincolors[cv_playercolor.value].accessible)
CV_StealthSetValue(&cv_playercolor, lastgoodcolor);
if (!(cv_debug || devparm) && !(multiplayer || netgame)) // In single player.
{
CV_StealthSet(&cv_skin, skins[players[consoleplayer].skin].name);
return;
}
if (!P_PlayerMoving(consoleplayer))
{
// Color change menu scrolling fix is no longer necessary
SendNameAndColor();
} }
else else
{ {
CV_StealthSetValue(&cv_playercolor, if (!(cv_debug || devparm) && !(multiplayer || netgame)) // In single player.
players[consoleplayer].skincolor); {
CV_StealthSet(&cv_skin, skins[players[consoleplayer].skin].name);
return;
}
if (!P_PlayerMoving(consoleplayer) && skincolors[players[consoleplayer].skincolor].accessible == true)
{
// Color change menu scrolling fix is no longer necessary
SendNameAndColor();
}
else
{
CV_StealthSetValue(&cv_playercolor,
players[consoleplayer].skincolor);
}
} }
lastgoodcolor = cv_playercolor.value;
} }
/** Sends a color change for the secondary splitscreen player, unless that /** Sends a color change for the secondary splitscreen player, unless that
@ -4501,18 +4519,24 @@ static void Color_OnChange(void)
static void Color2_OnChange(void) static void Color2_OnChange(void)
{ {
if (!Playing() || !splitscreen) if (!Playing() || !splitscreen)
return; // do whatever you want
if (!P_PlayerMoving(secondarydisplayplayer))
{ {
// Color change menu scrolling fix is no longer necessary if (!cv_playercolor2.value || !skincolors[cv_playercolor2.value].accessible)
SendNameAndColor2(); CV_StealthSetValue(&cv_playercolor2, lastgoodcolor2);
} }
else else
{ {
CV_StealthSetValue(&cv_playercolor2, if (!P_PlayerMoving(secondarydisplayplayer) && skincolors[players[secondarydisplayplayer].skincolor].accessible == true)
players[secondarydisplayplayer].skincolor); {
// Color change menu scrolling fix is no longer necessary
SendNameAndColor2();
}
else
{
CV_StealthSetValue(&cv_playercolor2,
players[secondarydisplayplayer].skincolor);
}
} }
lastgoodcolor2 = cv_playercolor2.value;
} }
/** Displays the result of the chat being muted or unmuted. /** Displays the result of the chat being muted or unmuted.

View File

@ -239,7 +239,8 @@ typedef enum
CR_MACESPIN, CR_MACESPIN,
CR_MINECART, CR_MINECART,
CR_ROLLOUT, CR_ROLLOUT,
CR_PTERABYTE CR_PTERABYTE,
CR_DUSTDEVIL
} carrytype_t; // pw_carry } carrytype_t; // pw_carry
// Player powers. (don't edit this comment) // Player powers. (don't edit this comment)
@ -365,7 +366,7 @@ typedef struct player_s
UINT16 flashpal; UINT16 flashpal;
// Player skin colorshift, 0-15 for which color to draw player. // Player skin colorshift, 0-15 for which color to draw player.
UINT8 skincolor; UINT16 skincolor;
INT32 skin; INT32 skin;
UINT32 availabilities; UINT32 availabilities;

View File

@ -56,10 +56,12 @@ int vsnprintf(char *str, size_t n, const char *fmt, va_list ap);
// The crazy word-reading stuff uses these. // The crazy word-reading stuff uses these.
static char *FREE_STATES[NUMSTATEFREESLOTS]; static char *FREE_STATES[NUMSTATEFREESLOTS];
static char *FREE_MOBJS[NUMMOBJFREESLOTS]; static char *FREE_MOBJS[NUMMOBJFREESLOTS];
static char *FREE_SKINCOLORS[NUMCOLORFREESLOTS];
static UINT8 used_spr[(NUMSPRITEFREESLOTS / 8) + 1]; // Bitwise flag for sprite freeslot in use! I would use ceil() here if I could, but it only saves 1 byte of memory anyway. static UINT8 used_spr[(NUMSPRITEFREESLOTS / 8) + 1]; // Bitwise flag for sprite freeslot in use! I would use ceil() here if I could, but it only saves 1 byte of memory anyway.
#define initfreeslots() {\ #define initfreeslots() {\
memset(FREE_STATES,0,sizeof(char *) * NUMSTATEFREESLOTS);\ memset(FREE_STATES,0,sizeof(char *) * NUMSTATEFREESLOTS);\
memset(FREE_MOBJS,0,sizeof(char *) * NUMMOBJFREESLOTS);\ memset(FREE_MOBJS,0,sizeof(char *) * NUMMOBJFREESLOTS);\
memset(FREE_SKINCOLORS,0,sizeof(char *) * NUMCOLORFREESLOTS);\
memset(used_spr,0,sizeof(UINT8) * ((NUMSPRITEFREESLOTS / 8) + 1));\ memset(used_spr,0,sizeof(UINT8) * ((NUMSPRITEFREESLOTS / 8) + 1));\
} }
@ -77,6 +79,7 @@ static hudnum_t get_huditem(const char *word);
static menutype_t get_menutype(const char *word); static menutype_t get_menutype(const char *word);
//static INT16 get_gametype(const char *word); //static INT16 get_gametype(const char *word);
//static powertype_t get_power(const char *word); //static powertype_t get_power(const char *word);
skincolornum_t get_skincolor(const char *word);
boolean deh_loaded = false; boolean deh_loaded = false;
static int dbg_line; static int dbg_line;
@ -449,7 +452,7 @@ static void readPlayer(MYFILE *f, INT32 num)
else if (fastcmp(word, "OPPOSITECOLOR") || fastcmp(word, "OPPOSITECOLOUR")) else if (fastcmp(word, "OPPOSITECOLOR") || fastcmp(word, "OPPOSITECOLOUR"))
{ {
SLOTFOUND SLOTFOUND
description[num].oppositecolor = (UINT8)get_number(word2); description[num].oppositecolor = (UINT16)get_number(word2);
} }
else if (fastcmp(word, "NAMETAG") || fastcmp(word, "TAGNAME")) else if (fastcmp(word, "NAMETAG") || fastcmp(word, "TAGNAME"))
{ {
@ -459,12 +462,12 @@ static void readPlayer(MYFILE *f, INT32 num)
else if (fastcmp(word, "TAGTEXTCOLOR") || fastcmp(word, "TAGTEXTCOLOUR")) else if (fastcmp(word, "TAGTEXTCOLOR") || fastcmp(word, "TAGTEXTCOLOUR"))
{ {
SLOTFOUND SLOTFOUND
description[num].tagtextcolor = (UINT8)get_number(word2); description[num].tagtextcolor = (UINT16)get_number(word2);
} }
else if (fastcmp(word, "TAGOUTLINECOLOR") || fastcmp(word, "TAGOUTLINECOLOUR")) else if (fastcmp(word, "TAGOUTLINECOLOR") || fastcmp(word, "TAGOUTLINECOLOUR"))
{ {
SLOTFOUND SLOTFOUND
description[num].tagoutlinecolor = (UINT8)get_number(word2); description[num].tagoutlinecolor = (UINT16)get_number(word2);
} }
else if (fastcmp(word, "STATUS")) else if (fastcmp(word, "STATUS"))
{ {
@ -571,6 +574,16 @@ static void readfreeslots(MYFILE *f)
break; break;
} }
} }
else if (fastcmp(type, "SKINCOLOR"))
{
for (i = 0; i < NUMCOLORFREESLOTS; i++)
if (!FREE_SKINCOLORS[i]) {
FREE_SKINCOLORS[i] = Z_Malloc(strlen(word)+1, PU_STATIC, NULL);
strcpy(FREE_SKINCOLORS[i],word);
M_AddMenuColor(numskincolors++);
break;
}
}
else if (fastcmp(type, "SPR2")) else if (fastcmp(type, "SPR2"))
{ {
// Search if we already have an SPR2 by that name... // Search if we already have an SPR2 by that name...
@ -753,6 +766,84 @@ static void readthing(MYFILE *f, INT32 num)
Z_Free(s); Z_Free(s);
} }
static void readskincolor(MYFILE *f, INT32 num)
{
char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
char *word, *word2, *word3;
char *tmp;
Color_cons_t[num].value = num;
do
{
if (myfgets(s, MAXLINELEN, f))
{
if (s[0] == '\n')
break;
tmp = strchr(s, '#');
if (tmp)
*tmp = '\0';
if (s == tmp)
continue; // Skip comment lines, but don't break.
word = strtok(s, " ");
if (word)
strupr(word);
else
break;
word2 = strtok(NULL, " = ");
if (word2) {
word3 = Z_StrDup(word2);
strupr(word2);
} else
break;
if (word2[strlen(word2)-1] == '\n')
word2[strlen(word2)-1] = '\0';
if (word3[strlen(word3)-1] == '\n')
word3[strlen(word3)-1] = '\0';
if (fastcmp(word, "NAME"))
{
deh_strlcpy(skincolors[num].name, word3,
sizeof (skincolors[num].name), va("Skincolor %d: name", num));
}
else if (fastcmp(word, "RAMP"))
{
UINT8 i;
tmp = strtok(word2,",");
for (i = 0; i < COLORRAMPSIZE; i++) {
skincolors[num].ramp[i] = (UINT8)get_number(tmp);
if ((tmp = strtok(NULL,",")) == NULL)
break;
}
}
else if (fastcmp(word, "INVCOLOR"))
{
skincolors[num].invcolor = (UINT16)get_number(word2);
}
else if (fastcmp(word, "INVSHADE"))
{
skincolors[num].invshade = get_number(word2)%COLORRAMPSIZE;
}
else if (fastcmp(word, "CHATCOLOR"))
{
skincolors[num].chatcolor = get_number(word2);
}
else if (fastcmp(word, "ACCESSIBLE"))
{
if (num > FIRSTSUPERCOLOR)
skincolors[num].accessible = (boolean)(atoi(word2) || word2[0] == 'T' || word2[0] == 'Y');
}
else
deh_warning("Skincolor %d: unknown word '%s'", num, word);
}
} while (!myfeof(f)); // finish when the line is empty
Z_Free(s);
}
#ifdef HWRENDER #ifdef HWRENDER
static void readlight(MYFILE *f, INT32 num) static void readlight(MYFILE *f, INT32 num)
{ {
@ -1557,7 +1648,7 @@ static void readlevelheader(MYFILE *f, INT32 num)
} }
else if (fastcmp(word, "ACT")) else if (fastcmp(word, "ACT"))
{ {
if (i >= 0 && i < 20) // 0 for no act number, TTL1 through TTL19 if (i >= 0 && i <= 99) // 0 for no act number
mapheaderinfo[num-1]->actnum = (UINT8)i; mapheaderinfo[num-1]->actnum = (UINT8)i;
else else
deh_warning("Level header %d: invalid act number %d", num, i); deh_warning("Level header %d: invalid act number %d", num, i);
@ -1863,6 +1954,12 @@ static void readlevelheader(MYFILE *f, INT32 num)
} }
else if (fastcmp(word, "STARTRINGS")) else if (fastcmp(word, "STARTRINGS"))
mapheaderinfo[num-1]->startrings = (UINT16)i; mapheaderinfo[num-1]->startrings = (UINT16)i;
else if (fastcmp(word, "SPECIALSTAGETIME"))
mapheaderinfo[num-1]->sstimer = i;
else if (fastcmp(word, "SPECIALSTAGESPHERES"))
mapheaderinfo[num-1]->ssspheres = i;
else if (fastcmp(word, "GRAVITY"))
mapheaderinfo[num-1]->gravity = FLOAT_TO_FIXED(atof(word2));
else else
deh_warning("Level header %d: unknown word '%s'", num, word); deh_warning("Level header %d: unknown word '%s'", num, word);
} }
@ -2807,7 +2904,7 @@ static actionpointer_t actionpointers[] =
{{A_ThrownRing}, "A_THROWNRING"}, {{A_ThrownRing}, "A_THROWNRING"},
{{A_SetSolidSteam}, "A_SETSOLIDSTEAM"}, {{A_SetSolidSteam}, "A_SETSOLIDSTEAM"},
{{A_UnsetSolidSteam}, "A_UNSETSOLIDSTEAM"}, {{A_UnsetSolidSteam}, "A_UNSETSOLIDSTEAM"},
{{A_SignSpin}, "S_SIGNSPIN"}, {{A_SignSpin}, "A_SIGNSPIN"},
{{A_SignPlayer}, "A_SIGNPLAYER"}, {{A_SignPlayer}, "A_SIGNPLAYER"},
{{A_OverlayThink}, "A_OVERLAYTHINK"}, {{A_OverlayThink}, "A_OVERLAYTHINK"},
{{A_JetChase}, "A_JETCHASE"}, {{A_JetChase}, "A_JETCHASE"},
@ -3027,6 +3124,7 @@ static actionpointer_t actionpointers[] =
{{A_DragonbomberSpawn}, "A_DRAGONBOMERSPAWN"}, {{A_DragonbomberSpawn}, "A_DRAGONBOMERSPAWN"},
{{A_DragonWing}, "A_DRAGONWING"}, {{A_DragonWing}, "A_DRAGONWING"},
{{A_DragonSegment}, "A_DRAGONSEGMENT"}, {{A_DragonSegment}, "A_DRAGONSEGMENT"},
{{A_ChangeHeight}, "A_CHANGEHEIGHT"},
{{NULL}, "NONE"}, {{NULL}, "NONE"},
// This NULL entry must be the last in the list // This NULL entry must be the last in the list
@ -3945,19 +4043,19 @@ static void readmaincfg(MYFILE *f)
} }
else if (fastcmp(word, "REDTEAM")) else if (fastcmp(word, "REDTEAM"))
{ {
skincolor_redteam = (UINT8)get_number(word2); skincolor_redteam = (UINT16)get_number(word2);
} }
else if (fastcmp(word, "BLUETEAM")) else if (fastcmp(word, "BLUETEAM"))
{ {
skincolor_blueteam = (UINT8)get_number(word2); skincolor_blueteam = (UINT16)get_number(word2);
} }
else if (fastcmp(word, "REDRING")) else if (fastcmp(word, "REDRING"))
{ {
skincolor_redring = (UINT8)get_number(word2); skincolor_redring = (UINT16)get_number(word2);
} }
else if (fastcmp(word, "BLUERING")) else if (fastcmp(word, "BLUERING"))
{ {
skincolor_bluering = (UINT8)get_number(word2); skincolor_bluering = (UINT16)get_number(word2);
} }
else if (fastcmp(word, "INVULNTICS")) else if (fastcmp(word, "INVULNTICS"))
{ {
@ -4549,6 +4647,18 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile)
ignorelines(f); ignorelines(f);
} }
} }
else if (fastcmp(word, "SKINCOLOR") || fastcmp(word, "COLOR"))
{
if (i == 0 && word2[0] != '0') // If word2 isn't a number
i = get_skincolor(word2); // find a skincolor by name
if (i < numskincolors && i >= (INT32)SKINCOLOR_FIRSTFREESLOT)
readskincolor(f, i);
else
{
deh_warning("Skincolor %d out of range (%d - %d)", i, SKINCOLOR_FIRSTFREESLOT, numskincolors-1);
ignorelines(f);
}
}
else if (fastcmp(word, "SPRITE2")) else if (fastcmp(word, "SPRITE2"))
{ {
if (i == 0 && word2[0] != '0') // If word2 isn't a number if (i == 0 && word2[0] != '0') // If word2 isn't a number
@ -6225,6 +6335,14 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_ROCKET", "S_ROCKET",
"S_LASER", "S_LASER",
"S_LASER2",
"S_LASERFLASH",
"S_LASERFLAME1",
"S_LASERFLAME2",
"S_LASERFLAME3",
"S_LASERFLAME4",
"S_LASERFLAME5",
"S_TORPEDO", "S_TORPEDO",
@ -8985,8 +9103,6 @@ static const char *const ML_LIST[16] = {
"TFERLINE" "TFERLINE"
}; };
// This DOES differ from r_draw's Color_Names, unfortunately.
// Also includes Super colors
static const char *COLOR_ENUMS[] = { static const char *COLOR_ENUMS[] = {
"NONE", // SKINCOLOR_NONE, "NONE", // SKINCOLOR_NONE,
@ -9224,6 +9340,7 @@ static const char *const MENUTYPES_LIST[] = {
"MP_CONNECT", "MP_CONNECT",
"MP_ROOM", "MP_ROOM",
"MP_PLAYERSETUP", // MP_PlayerSetupDef shared with SPLITSCREEN if #defined NONET "MP_PLAYERSETUP", // MP_PlayerSetupDef shared with SPLITSCREEN if #defined NONET
"MP_SERVER_OPTIONS",
// Options // Options
"OP_MAIN", "OP_MAIN",
@ -9233,10 +9350,14 @@ static const char *const MENUTYPES_LIST[] = {
"OP_P1MOUSE", "OP_P1MOUSE",
"OP_P1JOYSTICK", "OP_P1JOYSTICK",
"OP_JOYSTICKSET", // OP_JoystickSetDef shared with P2 "OP_JOYSTICKSET", // OP_JoystickSetDef shared with P2
"OP_P1CAMERA",
"OP_P2CONTROLS", "OP_P2CONTROLS",
"OP_P2MOUSE", "OP_P2MOUSE",
"OP_P2JOYSTICK", "OP_P2JOYSTICK",
"OP_P2CAMERA",
"OP_PLAYSTYLE",
"OP_VIDEO", "OP_VIDEO",
"OP_VIDEOMODE", "OP_VIDEOMODE",
@ -9417,7 +9538,8 @@ struct {
// SKINCOLOR_ doesn't include these..! // SKINCOLOR_ doesn't include these..!
{"MAXSKINCOLORS",MAXSKINCOLORS}, {"MAXSKINCOLORS",MAXSKINCOLORS},
{"MAXTRANSLATIONS",MAXTRANSLATIONS}, {"FIRSTSUPERCOLOR",FIRSTSUPERCOLOR},
{"NUMSUPERCOLORS",NUMSUPERCOLORS},
// Precipitation // Precipitation
{"PRECIP_NONE",PRECIP_NONE}, {"PRECIP_NONE",PRECIP_NONE},
@ -9468,6 +9590,7 @@ struct {
{"CR_MINECART",CR_MINECART}, {"CR_MINECART",CR_MINECART},
{"CR_ROLLOUT",CR_ROLLOUT}, {"CR_ROLLOUT",CR_ROLLOUT},
{"CR_PTERABYTE",CR_PTERABYTE}, {"CR_PTERABYTE",CR_PTERABYTE},
{"CR_DUSTDEVIL",CR_DUSTDEVIL},
// Ring weapons (ringweapons_t) // Ring weapons (ringweapons_t)
// Useful for A_GiveWeapon // Useful for A_GiveWeapon
@ -9918,6 +10041,26 @@ static statenum_t get_state(const char *word)
return S_NULL; return S_NULL;
} }
skincolornum_t get_skincolor(const char *word)
{ // Returns the value of SKINCOLOR_ enumerations
skincolornum_t i;
if (*word >= '0' && *word <= '9')
return atoi(word);
if (fastncmp("SKINCOLOR_",word,10))
word += 10; // take off the SKINCOLOR_
for (i = 0; i < NUMCOLORFREESLOTS; i++) {
if (!FREE_SKINCOLORS[i])
break;
if (fastcmp(word, FREE_SKINCOLORS[i]))
return SKINCOLOR_FIRSTFREESLOT+i;
}
for (i = 0; i < SKINCOLOR_FIRSTFREESLOT; i++)
if (fastcmp(word, COLOR_ENUMS[i]))
return i;
deh_warning("Couldn't find skincolor named 'SKINCOLOR_%s'",word);
return SKINCOLOR_GREEN;
}
static spritenum_t get_sprite(const char *word) static spritenum_t get_sprite(const char *word)
{ // Returns the value of SPR_ enumerations { // Returns the value of SPR_ enumerations
spritenum_t i; spritenum_t i;
@ -10212,6 +10355,11 @@ static fixed_t find_const(const char **rword)
free(word); free(word);
return r; return r;
} }
else if (fastncmp("SKINCOLOR_",word,10)) {
r = get_skincolor(word);
free(word);
return r;
}
else if (fastncmp("MT_",word,3)) { else if (fastncmp("MT_",word,3)) {
r = get_mobjtype(word); r = get_mobjtype(word);
free(word); free(word);
@ -10280,17 +10428,6 @@ static fixed_t find_const(const char **rword)
free(word); free(word);
return r; return r;
} }
else if (fastncmp("SKINCOLOR_",word,10)) {
char *p = word+10;
for (i = 0; i < MAXTRANSLATIONS; i++)
if (fastcmp(p, COLOR_ENUMS[i])) {
free(word);
return i;
}
const_warning("color",word);
free(word);
return 0;
}
else if (fastncmp("GRADE_",word,6)) else if (fastncmp("GRADE_",word,6))
{ {
char *p = word+6; char *p = word+6;
@ -10351,8 +10488,8 @@ void DEH_Check(void)
if (dehpowers != NUMPOWERS) if (dehpowers != NUMPOWERS)
I_Error("You forgot to update the Dehacked powers list, you dolt!\n(%d powers defined, versus %s in the Dehacked list)\n", NUMPOWERS, sizeu1(dehpowers)); I_Error("You forgot to update the Dehacked powers list, you dolt!\n(%d powers defined, versus %s in the Dehacked list)\n", NUMPOWERS, sizeu1(dehpowers));
if (dehcolors != MAXTRANSLATIONS) if (dehcolors != SKINCOLOR_FIRSTFREESLOT)
I_Error("You forgot to update the Dehacked colors list, you dolt!\n(%d colors defined, versus %s in the Dehacked list)\n", MAXTRANSLATIONS, sizeu1(dehcolors)); I_Error("You forgot to update the Dehacked colors list, you dolt!\n(%d colors defined, versus %s in the Dehacked list)\n", SKINCOLOR_FIRSTFREESLOT, sizeu1(dehcolors));
#endif #endif
} }
@ -10460,6 +10597,22 @@ static inline int lib_freeslot(lua_State *L)
if (i == NUMMOBJFREESLOTS) if (i == NUMMOBJFREESLOTS)
CONS_Alert(CONS_WARNING, "Ran out of free MobjType slots!\n"); CONS_Alert(CONS_WARNING, "Ran out of free MobjType slots!\n");
} }
else if (fastcmp(type, "SKINCOLOR"))
{
skincolornum_t i;
for (i = 0; i < NUMCOLORFREESLOTS; i++)
if (!FREE_SKINCOLORS[i]) {
CONS_Printf("Skincolor SKINCOLOR_%s allocated.\n",word);
FREE_SKINCOLORS[i] = Z_Malloc(strlen(word)+1, PU_STATIC, NULL);
strcpy(FREE_SKINCOLORS[i],word);
M_AddMenuColor(numskincolors++);
lua_pushinteger(L, i);
r++;
break;
}
if (i == NUMCOLORFREESLOTS)
CONS_Alert(CONS_WARNING, "Ran out of free skincolor slots!\n");
}
else if (fastcmp(type, "SPR2")) else if (fastcmp(type, "SPR2"))
{ {
// Search if we already have an SPR2 by that name... // Search if we already have an SPR2 by that name...
@ -10791,13 +10944,20 @@ static inline int lib_getenum(lua_State *L)
} }
else if (fastncmp("SKINCOLOR_",word,10)) { else if (fastncmp("SKINCOLOR_",word,10)) {
p = word+10; p = word+10;
for (i = 0; i < MAXTRANSLATIONS; i++) for (i = 0; i < NUMCOLORFREESLOTS; i++) {
if (!FREE_SKINCOLORS[i])
break;
if (fastcmp(p, FREE_SKINCOLORS[i])) {
lua_pushinteger(L, SKINCOLOR_FIRSTFREESLOT+i);
return 1;
}
}
for (i = 0; i < SKINCOLOR_FIRSTFREESLOT; i++)
if (fastcmp(p, COLOR_ENUMS[i])) { if (fastcmp(p, COLOR_ENUMS[i])) {
lua_pushinteger(L, i); lua_pushinteger(L, i);
return 1; return 1;
} }
if (mathlib) return luaL_error(L, "skincolor '%s' could not be found.\n", word); return luaL_error(L, "skincolor '%s' could not be found.\n", word);
return 0;
} }
else if (fastncmp("GRADE_",word,6)) else if (fastncmp("GRADE_",word,6))
{ {

View File

@ -61,6 +61,8 @@
#include "../console.h" #include "../console.h"
#include "../m_menu.h"
#ifdef __GNUG__ #ifdef __GNUG__
#pragma implementation "../i_system.h" #pragma implementation "../i_system.h"
#endif #endif
@ -555,6 +557,7 @@ void I_Error (const char *error, ...)
if (demorecording) if (demorecording)
G_CheckDemoStatus(); G_CheckDemoStatus();
D_QuitNetGame (); D_QuitNetGame ();
M_FreePlayerSetupColors();
if (shutdowning) if (shutdowning)
{ {
@ -622,6 +625,7 @@ void I_Quit (void)
if (demorecording) if (demorecording)
G_CheckDemoStatus(); G_CheckDemoStatus();
D_QuitNetGame (); D_QuitNetGame ();
M_FreePlayerSetupColors();
I_ShutdownMusic(); I_ShutdownMusic();
I_ShutdownSound(); I_ShutdownSound();
I_ShutdownCD(); I_ShutdownCD();

View File

@ -208,10 +208,6 @@ typedef struct
#define ZSHIFT 4 #define ZSHIFT 4
extern const UINT8 Color_Index[MAXTRANSLATIONS-1][16];
extern const char *Color_Names[MAXSKINCOLORS + NUMSUPERCOLORS];
extern const UINT8 Color_Opposite[MAXSKINCOLORS - 1][2];
#define NUMMAPS 1035 #define NUMMAPS 1035
#endif // __DOOMDATA__ #endif // __DOOMDATA__

View File

@ -143,9 +143,9 @@ extern char logfilename[1024];
// we use comprevision and compbranch instead. // we use comprevision and compbranch instead.
#else #else
#define VERSION 202 // Game version #define VERSION 202 // Game version
#define SUBVERSION 2 // more precise version number #define SUBVERSION 4 // more precise version number
#define VERSIONSTRING "v2.2.2" #define VERSIONSTRING "v2.2.4"
#define VERSIONSTRINGW L"v2.2.2" #define VERSIONSTRINGW L"v2.2.4"
// Hey! If you change this, add 1 to the MODVERSION below! // Hey! If you change this, add 1 to the MODVERSION below!
// Otherwise we can't force updates! // Otherwise we can't force updates!
#endif #endif
@ -213,7 +213,7 @@ extern char logfilename[1024];
// it's only for detection of the version the player is using so the MS can alert them of an update. // it's only for detection of the version the player is using so the MS can alert them of an update.
// Only set it higher, not lower, obviously. // Only set it higher, not lower, obviously.
// Note that we use this to help keep internal testing in check; this is why v2.2.0 is not version "1". // Note that we use this to help keep internal testing in check; this is why v2.2.0 is not version "1".
#define MODVERSION 42 #define MODVERSION 44
// To version config.cfg, MAJOREXECVERSION is set equal to MODVERSION automatically. // To version config.cfg, MAJOREXECVERSION is set equal to MODVERSION automatically.
// Increment MINOREXECVERSION whenever a config change is needed that does not correspond // Increment MINOREXECVERSION whenever a config change is needed that does not correspond
@ -239,6 +239,20 @@ extern char logfilename[1024];
#define PLAYERSMASK (MAXPLAYERS-1) #define PLAYERSMASK (MAXPLAYERS-1)
#define MAXPLAYERNAME 21 #define MAXPLAYERNAME 21
#define COLORRAMPSIZE 16
#define MAXCOLORNAME 32
#define NUMCOLORFREESLOTS 1024
typedef struct skincolor_s
{
char name[MAXCOLORNAME+1]; // Skincolor name
UINT8 ramp[COLORRAMPSIZE]; // Colormap ramp
UINT16 invcolor; // Signpost color
UINT8 invshade; // Signpost color shade
UINT16 chatcolor; // Chat color
boolean accessible; // Accessible by the color command + setup menu
} skincolor_t;
typedef enum typedef enum
{ {
SKINCOLOR_NONE = 0, SKINCOLOR_NONE = 0,
@ -317,12 +331,10 @@ typedef enum
SKINCOLOR_RASPBERRY, SKINCOLOR_RASPBERRY,
SKINCOLOR_ROSY, SKINCOLOR_ROSY,
// SKINCOLOR_? - one left before we bump up against 0x39, which isn't a HARD limit anymore but would be excessive FIRSTSUPERCOLOR,
MAXSKINCOLORS,
// Super special awesome Super flashing colors! // Super special awesome Super flashing colors!
SKINCOLOR_SUPERSILVER1 = MAXSKINCOLORS, SKINCOLOR_SUPERSILVER1 = FIRSTSUPERCOLOR,
SKINCOLOR_SUPERSILVER2, SKINCOLOR_SUPERSILVER2,
SKINCOLOR_SUPERSILVER3, SKINCOLOR_SUPERSILVER3,
SKINCOLOR_SUPERSILVER4, SKINCOLOR_SUPERSILVER4,
@ -376,9 +388,17 @@ typedef enum
SKINCOLOR_SUPERTAN4, SKINCOLOR_SUPERTAN4,
SKINCOLOR_SUPERTAN5, SKINCOLOR_SUPERTAN5,
MAXTRANSLATIONS, SKINCOLOR_FIRSTFREESLOT,
NUMSUPERCOLORS = ((MAXTRANSLATIONS - MAXSKINCOLORS)/5) SKINCOLOR_LASTFREESLOT = SKINCOLOR_FIRSTFREESLOT + NUMCOLORFREESLOTS - 1,
} skincolors_t;
MAXSKINCOLORS,
NUMSUPERCOLORS = ((SKINCOLOR_FIRSTFREESLOT - FIRSTSUPERCOLOR)/5)
} skincolornum_t;
extern UINT16 numskincolors;
extern skincolor_t skincolors[MAXSKINCOLORS];
// State updates, number of tics / second. // State updates, number of tics / second.
// NOTE: used to setup the timer rate, see I_StartupTimer(). // NOTE: used to setup the timer rate, see I_StartupTimer().
@ -458,7 +478,7 @@ void CONS_Debug(INT32 debugflags, const char *fmt, ...) FUNCDEBUG;
// Things that used to be in dstrings.h // Things that used to be in dstrings.h
#define SAVEGAMENAME "srb2sav" #define SAVEGAMENAME "srb2sav"
char savegamename[256]; extern char savegamename[256];
// m_misc.h // m_misc.h
#ifdef GETTEXT #ifdef GETTEXT
@ -565,10 +585,6 @@ extern const char *compdate, *comptime, *comprevision, *compbranch;
// None of these that are disabled in the normal build are guaranteed to work perfectly // None of these that are disabled in the normal build are guaranteed to work perfectly
// Compile them at your own risk! // Compile them at your own risk!
/// Backwards compatibility with SRB2CB's slope linedef types.
/// \note A simple shim that prints a warning.
#define ESLOPE_TYPESHIM
/// Allows the use of devmode in multiplayer. AKA "fishcake" /// Allows the use of devmode in multiplayer. AKA "fishcake"
//#define NETGAME_DEVMODE //#define NETGAME_DEVMODE
@ -578,9 +594,6 @@ extern const char *compdate, *comptime, *comprevision, *compbranch;
/// Dumps the contents of a network save game upon consistency failure for debugging. /// Dumps the contents of a network save game upon consistency failure for debugging.
//#define DUMPCONSISTENCY //#define DUMPCONSISTENCY
/// Polyobject fake flat code
#define POLYOBJECTS_PLANES
/// See name of player in your crosshair /// See name of player in your crosshair
#define SEENAMES #define SEENAMES

View File

@ -145,7 +145,7 @@ extern INT32 tutorialanalog; // store cv_analog[0] user value
extern boolean looptitle; extern boolean looptitle;
// CTF colors. // CTF colors.
extern UINT8 skincolor_redteam, skincolor_blueteam, skincolor_redring, skincolor_bluering; extern UINT16 skincolor_redteam, skincolor_blueteam, skincolor_redring, skincolor_bluering;
extern tic_t countdowntimer; extern tic_t countdowntimer;
extern boolean countdowntimeup; extern boolean countdowntimeup;
@ -319,6 +319,9 @@ typedef struct
char selectheading[22]; ///< Level select heading. Allows for controllable grouping. char selectheading[22]; ///< Level select heading. Allows for controllable grouping.
UINT16 startrings; ///< Number of rings players start with. UINT16 startrings; ///< Number of rings players start with.
INT32 sstimer; ///< Timer for special stages.
UINT32 ssspheres; ///< Sphere requirement in special stages.
fixed_t gravity; ///< Map-wide gravity.
// Title card. // Title card.
char ltzzpatch[8]; ///< Zig zag patch. char ltzzpatch[8]; ///< Zig zag patch.
@ -542,7 +545,7 @@ extern recorddata_t *mainrecords[NUMMAPS];
extern UINT8 mapvisited[NUMMAPS]; extern UINT8 mapvisited[NUMMAPS];
// Temporary holding place for nights data for the current map // Temporary holding place for nights data for the current map
nightsdata_t ntemprecords; extern nightsdata_t ntemprecords;
extern UINT32 token; ///< Number of tokens collected in a level extern UINT32 token; ///< Number of tokens collected in a level
extern UINT32 tokenlist; ///< List of tokens collected extern UINT32 tokenlist; ///< List of tokens collected
@ -617,6 +620,19 @@ extern mapthing_t *playerstarts[MAXPLAYERS]; // Cooperative
extern mapthing_t *bluectfstarts[MAXPLAYERS]; // CTF extern mapthing_t *bluectfstarts[MAXPLAYERS]; // CTF
extern mapthing_t *redctfstarts[MAXPLAYERS]; // CTF extern mapthing_t *redctfstarts[MAXPLAYERS]; // CTF
#define WAYPOINTSEQUENCESIZE 256
#define NUMWAYPOINTSEQUENCES 256
extern mobj_t *waypoints[NUMWAYPOINTSEQUENCES][WAYPOINTSEQUENCESIZE];
extern UINT16 numwaypoints[NUMWAYPOINTSEQUENCES];
void P_AddWaypoint(UINT8 sequence, UINT8 id, mobj_t *waypoint);
mobj_t *P_GetFirstWaypoint(UINT8 sequence);
mobj_t *P_GetLastWaypoint(UINT8 sequence);
mobj_t *P_GetPreviousWaypoint(mobj_t *current, boolean wrap);
mobj_t *P_GetNextWaypoint(mobj_t *current, boolean wrap);
mobj_t *P_GetClosestWaypoint(UINT8 sequence, mobj_t *mo);
boolean P_IsDegeneratedWaypointSequence(UINT8 sequence);
// ===================================== // =====================================
// Internal parameters, used for engine. // Internal parameters, used for engine.
// ===================================== // =====================================

View File

@ -2185,7 +2185,7 @@ void F_EndingDrawer(void)
for (i = 0; i < 7; ++i) for (i = 0; i < 7; ++i)
{ {
UINT8* colormap; UINT8* colormap;
skincolors_t col = SKINCOLOR_GREEN; skincolornum_t col = SKINCOLOR_GREEN;
switch (i) switch (i)
{ {
case 1: case 1:

View File

@ -162,7 +162,9 @@ extern wipestyleflags_t wipestyleflags;
// Even my function names are borderline // Even my function names are borderline
boolean F_ShouldColormapFade(void); boolean F_ShouldColormapFade(void);
boolean F_TryColormapFade(UINT8 wipecolor); boolean F_TryColormapFade(UINT8 wipecolor);
#ifndef NOWIPE
void F_DecideWipeStyle(void); void F_DecideWipeStyle(void);
#endif
#define FADECOLORMAPDIV 8 #define FADECOLORMAPDIV 8
#define FADECOLORMAPROWS (256/FADECOLORMAPDIV) #define FADECOLORMAPROWS (256/FADECOLORMAPDIV)

View File

@ -464,6 +464,7 @@ void F_WipeEndScreen(void)
*/ */
boolean F_ShouldColormapFade(void) boolean F_ShouldColormapFade(void)
{ {
#ifndef NOWIPE
if ((wipestyleflags & (WSF_FADEIN|WSF_FADEOUT)) // only if one of those wipestyleflags are actually set if ((wipestyleflags & (WSF_FADEIN|WSF_FADEOUT)) // only if one of those wipestyleflags are actually set
&& !(wipestyleflags & WSF_CROSSFADE)) // and if not crossfading && !(wipestyleflags & WSF_CROSSFADE)) // and if not crossfading
{ {
@ -479,11 +480,13 @@ boolean F_ShouldColormapFade(void)
// Menus // Menus
|| gamestate == GS_TIMEATTACK); || gamestate == GS_TIMEATTACK);
} }
#endif
return false; return false;
} }
/** Decides what wipe style to use. /** Decides what wipe style to use.
*/ */
#ifndef NOWIPE
void F_DecideWipeStyle(void) void F_DecideWipeStyle(void)
{ {
// Set default wipe style // Set default wipe style
@ -493,6 +496,7 @@ void F_DecideWipeStyle(void)
if (F_ShouldColormapFade()) if (F_ShouldColormapFade())
wipestyle = WIPESTYLE_COLORMAP; wipestyle = WIPESTYLE_COLORMAP;
} }
#endif
/** Attempt to run a colormap fade, /** Attempt to run a colormap fade,
provided all the conditionals were properly met. provided all the conditionals were properly met.
@ -501,6 +505,7 @@ void F_DecideWipeStyle(void)
*/ */
boolean F_TryColormapFade(UINT8 wipecolor) boolean F_TryColormapFade(UINT8 wipecolor)
{ {
#ifndef NOWIPE
if (F_ShouldColormapFade()) if (F_ShouldColormapFade())
{ {
#ifdef HWRENDER #ifdef HWRENDER
@ -510,6 +515,7 @@ boolean F_TryColormapFade(UINT8 wipecolor)
return true; return true;
} }
else else
#endif
{ {
F_WipeColorFill(wipecolor); F_WipeColorFill(wipecolor);
return false; return false;
@ -608,6 +614,7 @@ void F_RunWipe(UINT8 wipetype, boolean drawMenu)
tic_t F_GetWipeLength(UINT8 wipetype) tic_t F_GetWipeLength(UINT8 wipetype)
{ {
#ifdef NOWIPE #ifdef NOWIPE
(void)wipetype;
return 0; return 0;
#else #else
static char lumpname[10] = "FADEmmss"; static char lumpname[10] = "FADEmmss";
@ -634,6 +641,7 @@ tic_t F_GetWipeLength(UINT8 wipetype)
boolean F_WipeExists(UINT8 wipetype) boolean F_WipeExists(UINT8 wipetype)
{ {
#ifdef NOWIPE #ifdef NOWIPE
(void)wipetype;
return false; return false;
#else #else
static char lumpname[10] = "FADEmm00"; static char lumpname[10] = "FADEmm00";

View File

@ -68,7 +68,7 @@ static struct {
UINT8 flags; // EZT flags UINT8 flags; // EZT flags
// EZT_COLOR // EZT_COLOR
UINT8 color, lastcolor; UINT16 color, lastcolor;
// EZT_SCALE // EZT_SCALE
fixed_t scale, lastscale; fixed_t scale, lastscale;
@ -82,7 +82,8 @@ static struct {
// There is no conflict here. // There is no conflict here.
typedef struct demoghost { typedef struct demoghost {
UINT8 checksum[16]; UINT8 checksum[16];
UINT8 *buffer, *p, color, fadein; UINT8 *buffer, *p, fadein;
UINT16 color;
UINT16 version; UINT16 version;
mobj_t oldmo, *mo; mobj_t oldmo, *mo;
struct demoghost *next; struct demoghost *next;
@ -93,7 +94,7 @@ demoghost *ghosts = NULL;
// DEMO RECORDING // DEMO RECORDING
// //
#define DEMOVERSION 0x000c #define DEMOVERSION 0x000d
#define DEMOHEADER "\xF0" "SRB2Replay" "\x0F" #define DEMOHEADER "\xF0" "SRB2Replay" "\x0F"
#define DF_GHOST 0x01 // This demo contains ghost data too! #define DF_GHOST 0x01 // This demo contains ghost data too!
@ -280,13 +281,13 @@ void G_GhostAddColor(ghostcolor_t color)
{ {
if (!demorecording || !(demoflags & DF_GHOST)) if (!demorecording || !(demoflags & DF_GHOST))
return; return;
if (ghostext.lastcolor == (UINT8)color) if (ghostext.lastcolor == (UINT16)color)
{ {
ghostext.flags &= ~EZT_COLOR; ghostext.flags &= ~EZT_COLOR;
return; return;
} }
ghostext.flags |= EZT_COLOR; ghostext.flags |= EZT_COLOR;
ghostext.color = (UINT8)color; ghostext.color = (UINT16)color;
} }
void G_GhostAddScale(fixed_t scale) void G_GhostAddScale(fixed_t scale)
@ -425,7 +426,7 @@ void G_WriteGhostTic(mobj_t *ghost)
WRITEUINT8(demo_p,ghostext.flags); WRITEUINT8(demo_p,ghostext.flags);
if (ghostext.flags & EZT_COLOR) if (ghostext.flags & EZT_COLOR)
{ {
WRITEUINT8(demo_p,ghostext.color); WRITEUINT16(demo_p,ghostext.color);
ghostext.lastcolor = ghostext.color; ghostext.lastcolor = ghostext.color;
} }
if (ghostext.flags & EZT_SCALE) if (ghostext.flags & EZT_SCALE)
@ -501,7 +502,7 @@ void G_WriteGhostTic(mobj_t *ghost)
WRITEUINT8(demo_p,ghost->player->followmobj->sprite2); WRITEUINT8(demo_p,ghost->player->followmobj->sprite2);
WRITEUINT16(demo_p,ghost->player->followmobj->sprite); WRITEUINT16(demo_p,ghost->player->followmobj->sprite);
WRITEUINT8(demo_p,(ghost->player->followmobj->frame & FF_FRAMEMASK)); WRITEUINT8(demo_p,(ghost->player->followmobj->frame & FF_FRAMEMASK));
WRITEUINT8(demo_p,ghost->player->followmobj->color); WRITEUINT16(demo_p,ghost->player->followmobj->color);
*followtic_p = followtic; *followtic_p = followtic;
} }
@ -566,7 +567,7 @@ void G_ConsGhostTic(void)
{ // But wait, there's more! { // But wait, there's more!
UINT8 xziptic = READUINT8(demo_p); UINT8 xziptic = READUINT8(demo_p);
if (xziptic & EZT_COLOR) if (xziptic & EZT_COLOR)
demo_p++; demo_p += (demoversion==0x000c) ? 1 : sizeof(UINT16);
if (xziptic & EZT_SCALE) if (xziptic & EZT_SCALE)
demo_p += sizeof(fixed_t); demo_p += sizeof(fixed_t);
if (xziptic & EZT_HIT) if (xziptic & EZT_HIT)
@ -633,7 +634,7 @@ void G_ConsGhostTic(void)
demo_p++; demo_p++;
demo_p += sizeof(UINT16); demo_p += sizeof(UINT16);
demo_p++; demo_p++;
demo_p++; demo_p += (demoversion==0x000c) ? 1 : sizeof(UINT16);
} }
// Re-synchronise // Re-synchronise
@ -731,7 +732,7 @@ void G_GhostTicker(void)
xziptic = READUINT8(g->p); xziptic = READUINT8(g->p);
if (xziptic & EZT_COLOR) if (xziptic & EZT_COLOR)
{ {
g->color = READUINT8(g->p); g->color = (g->version==0x000c) ? READUINT8(g->p) : READUINT16(g->p);
switch(g->color) switch(g->color)
{ {
default: default:
@ -864,7 +865,7 @@ void G_GhostTicker(void)
g->mo->color += abs( ( (signed)( (unsigned)leveltime >> 1 ) % 9) - 4); g->mo->color += abs( ( (signed)( (unsigned)leveltime >> 1 ) % 9) - 4);
break; break;
case GHC_INVINCIBLE: // Mario invincibility (P_CheckInvincibilityTimer) case GHC_INVINCIBLE: // Mario invincibility (P_CheckInvincibilityTimer)
g->mo->color = (UINT8)(SKINCOLOR_RUBY + (leveltime % (MAXSKINCOLORS - SKINCOLOR_RUBY))); // Passes through all saturated colours g->mo->color = (UINT16)(SKINCOLOR_RUBY + (leveltime % (FIRSTSUPERCOLOR - SKINCOLOR_RUBY))); // Passes through all saturated colours
break; break;
default: default:
break; break;
@ -918,7 +919,7 @@ void G_GhostTicker(void)
follow->sprite = READUINT16(g->p); follow->sprite = READUINT16(g->p);
follow->frame = (READUINT8(g->p)) | (g->mo->frame & FF_TRANSMASK); follow->frame = (READUINT8(g->p)) | (g->mo->frame & FF_TRANSMASK);
follow->angle = g->mo->angle; follow->angle = g->mo->angle;
follow->color = READUINT8(g->p); follow->color = (g->version==0x000c) ? READUINT8(g->p) : READUINT16(g->p);
if (!(followtic & FZT_SPAWNED)) if (!(followtic & FZT_SPAWNED))
{ {
@ -1158,7 +1159,7 @@ void G_ReadMetalTic(mobj_t *metal)
follow->sprite = READUINT16(metal_p); follow->sprite = READUINT16(metal_p);
follow->frame = READUINT32(metal_p); // NOT & FF_FRAMEMASK here, so 32 bits follow->frame = READUINT32(metal_p); // NOT & FF_FRAMEMASK here, so 32 bits
follow->angle = metal->angle; follow->angle = metal->angle;
follow->color = READUINT8(metal_p); follow->color = (metalversion==0x000c) ? READUINT8(metal_p) : READUINT16(metal_p);
if (!(followtic & FZT_SPAWNED)) if (!(followtic & FZT_SPAWNED))
{ {
@ -1340,7 +1341,7 @@ void G_WriteMetalTic(mobj_t *metal)
WRITEUINT8(demo_p,metal->player->followmobj->sprite2); WRITEUINT8(demo_p,metal->player->followmobj->sprite2);
WRITEUINT16(demo_p,metal->player->followmobj->sprite); WRITEUINT16(demo_p,metal->player->followmobj->sprite);
WRITEUINT32(demo_p,metal->player->followmobj->frame); // NOT & FF_FRAMEMASK here, so 32 bits WRITEUINT32(demo_p,metal->player->followmobj->frame); // NOT & FF_FRAMEMASK here, so 32 bits
WRITEUINT8(demo_p,metal->player->followmobj->color); WRITEUINT16(demo_p,metal->player->followmobj->color);
*followtic_p = followtic; *followtic_p = followtic;
} }
@ -1394,7 +1395,7 @@ void G_RecordMetal(void)
void G_BeginRecording(void) void G_BeginRecording(void)
{ {
UINT8 i; UINT8 i;
char name[16]; char name[MAXCOLORNAME+1];
player_t *player = &players[consoleplayer]; player_t *player = &players[consoleplayer];
if (demo_p) if (demo_p)
@ -1457,12 +1458,12 @@ void G_BeginRecording(void)
demo_p += 16; demo_p += 16;
// Color // Color
for (i = 0; i < 16 && cv_playercolor.string[i]; i++) for (i = 0; i < MAXCOLORNAME && cv_playercolor.string[i]; i++)
name[i] = cv_playercolor.string[i]; name[i] = cv_playercolor.string[i];
for (; i < 16; i++) for (; i < MAXCOLORNAME; i++)
name[i] = '\0'; name[i] = '\0';
M_Memcpy(demo_p,name,16); M_Memcpy(demo_p,name,MAXCOLORNAME);
demo_p += 16; demo_p += MAXCOLORNAME;
// Stats // Stats
WRITEUINT8(demo_p,player->charability); WRITEUINT8(demo_p,player->charability);
@ -1622,7 +1623,7 @@ UINT8 G_CmpDemoTime(char *oldname, char *newname)
c = READUINT8(p); // SUBVERSION c = READUINT8(p); // SUBVERSION
I_Assert(c == SUBVERSION); I_Assert(c == SUBVERSION);
s = READUINT16(p); s = READUINT16(p);
I_Assert(s == DEMOVERSION); I_Assert(s >= 0x000c);
p += 16; // demo checksum p += 16; // demo checksum
I_Assert(!memcmp(p, "PLAY", 4)); I_Assert(!memcmp(p, "PLAY", 4));
p += 4; // PLAY p += 4; // PLAY
@ -1671,6 +1672,7 @@ UINT8 G_CmpDemoTime(char *oldname, char *newname)
switch(oldversion) // demoversion switch(oldversion) // demoversion
{ {
case DEMOVERSION: // latest always supported case DEMOVERSION: // latest always supported
case 0x000c: // all that changed between then and now was longer color name
break; break;
// too old, cannot support. // too old, cannot support.
default: default:
@ -1744,15 +1746,15 @@ void G_DoPlayDemo(char *defdemoname)
{ {
UINT8 i; UINT8 i;
lumpnum_t l; lumpnum_t l;
char skin[17],color[17],*n,*pdemoname; char skin[17],color[MAXCOLORNAME+1],*n,*pdemoname;
UINT8 version,subversion,charability,charability2,thrustfactor,accelstart,acceleration; UINT8 version,subversion,charability,charability2,thrustfactor,accelstart,acceleration,cnamelen;
pflags_t pflags; pflags_t pflags;
UINT32 randseed, followitem; UINT32 randseed, followitem;
fixed_t camerascale,shieldscale,actionspd,mindash,maxdash,normalspeed,runspeed,jumpfactor,height,spinheight; fixed_t camerascale,shieldscale,actionspd,mindash,maxdash,normalspeed,runspeed,jumpfactor,height,spinheight;
char msg[1024]; char msg[1024];
skin[16] = '\0'; skin[16] = '\0';
color[16] = '\0'; color[MAXCOLORNAME] = '\0';
n = defdemoname+strlen(defdemoname); n = defdemoname+strlen(defdemoname);
while (*n != '/' && *n != '\\' && n != defdemoname) while (*n != '/' && *n != '\\' && n != defdemoname)
@ -1810,6 +1812,11 @@ void G_DoPlayDemo(char *defdemoname)
switch(demoversion) switch(demoversion)
{ {
case DEMOVERSION: // latest always supported case DEMOVERSION: // latest always supported
cnamelen = MAXCOLORNAME;
break;
// all that changed between then and now was longer color name
case 0x000c:
cnamelen = 16;
break; break;
// too old, cannot support. // too old, cannot support.
default: default:
@ -1876,8 +1883,8 @@ void G_DoPlayDemo(char *defdemoname)
demo_p += 16; demo_p += 16;
// Color // Color
M_Memcpy(color,demo_p,16); M_Memcpy(color,demo_p,cnamelen);
demo_p += 16; demo_p += cnamelen;
charability = READUINT8(demo_p); charability = READUINT8(demo_p);
charability2 = READUINT8(demo_p); charability2 = READUINT8(demo_p);
@ -1941,7 +1948,9 @@ void G_DoPlayDemo(char *defdemoname)
// Set skin // Set skin
SetPlayerSkin(0, skin); SetPlayerSkin(0, skin);
#ifdef HAVE_BLUA
LUAh_MapChange(gamemap); LUAh_MapChange(gamemap);
#endif
displayplayer = consoleplayer = 0; displayplayer = consoleplayer = 0;
memset(playeringame,0,sizeof(playeringame)); memset(playeringame,0,sizeof(playeringame));
playeringame[0] = true; playeringame[0] = true;
@ -1949,8 +1958,9 @@ void G_DoPlayDemo(char *defdemoname)
G_InitNew(false, G_BuildMapName(gamemap), true, true, false); G_InitNew(false, G_BuildMapName(gamemap), true, true, false);
// Set color // Set color
for (i = 0; i < MAXSKINCOLORS; i++) players[0].skincolor = skins[players[0].skin].prefcolor;
if (!stricmp(Color_Names[i],color)) for (i = 0; i < numskincolors; i++)
if (!stricmp(skincolors[i].name,color))
{ {
players[0].skincolor = i; players[0].skincolor = i;
break; break;
@ -1992,7 +2002,8 @@ void G_AddGhost(char *defdemoname)
{ {
INT32 i; INT32 i;
lumpnum_t l; lumpnum_t l;
char name[17],skin[17],color[17],*n,*pdemoname,md5[16]; char name[17],skin[17],color[MAXCOLORNAME+1],*n,*pdemoname,md5[16];
UINT8 cnamelen;
demoghost *gh; demoghost *gh;
UINT8 flags; UINT8 flags;
UINT8 *buffer,*p; UINT8 *buffer,*p;
@ -2047,6 +2058,11 @@ void G_AddGhost(char *defdemoname)
switch(ghostversion) switch(ghostversion)
{ {
case DEMOVERSION: // latest always supported case DEMOVERSION: // latest always supported
cnamelen = MAXCOLORNAME;
break;
// all that changed between then and now was longer color name
case 0x000c:
cnamelen = 16;
break; break;
// too old, cannot support. // too old, cannot support.
default: default:
@ -2109,8 +2125,8 @@ void G_AddGhost(char *defdemoname)
p += 16; p += 16;
// Color // Color
M_Memcpy(color, p,16); M_Memcpy(color, p,cnamelen);
p += 16; p += cnamelen;
// Ghosts do not have a player structure to put this in. // Ghosts do not have a player structure to put this in.
p++; // charability p++; // charability
@ -2198,10 +2214,10 @@ void G_AddGhost(char *defdemoname)
// Set color // Set color
gh->mo->color = ((skin_t*)gh->mo->skin)->prefcolor; gh->mo->color = ((skin_t*)gh->mo->skin)->prefcolor;
for (i = 0; i < MAXSKINCOLORS; i++) for (i = 0; i < numskincolors; i++)
if (!stricmp(Color_Names[i],color)) if (!stricmp(skincolors[i].name,color))
{ {
gh->mo->color = (UINT8)i; gh->mo->color = (UINT16)i;
break; break;
} }
gh->oldmo.color = gh->mo->color; gh->oldmo.color = gh->mo->color;
@ -2292,6 +2308,7 @@ void G_DoPlayMetal(void)
switch(metalversion) switch(metalversion)
{ {
case DEMOVERSION: // latest always supported case DEMOVERSION: // latest always supported
case 0x000c: // all that changed between then and now was longer color name
break; break;
// too old, cannot support. // too old, cannot support.
default: default:
@ -2332,6 +2349,38 @@ void G_DoneLevelLoad(void)
=================== ===================
*/ */
// Writes the demo's checksum, or just random garbage if you can't do that for some reason.
static void WriteDemoChecksum(void)
{
UINT8 *p = demobuffer+16; // checksum position
#ifdef NOMD5
UINT8 i;
for (i = 0; i < 16; i++, p++)
*p = P_RandomByte(); // This MD5 was chosen by fair dice roll and most likely < 50% correct.
#else
md5_buffer((char *)p+16, demo_p - (p+16), p); // make a checksum of everything after the checksum in the file.
#endif
}
// Stops recording a demo.
static void G_StopDemoRecording(void)
{
boolean saved = false;
WRITEUINT8(demo_p, DEMOMARKER); // add the demo end marker
WriteDemoChecksum();
saved = FIL_WriteFile(va(pandf, srb2home, demoname), demobuffer, demo_p - demobuffer); // finally output the file.
free(demobuffer);
demorecording = false;
if (modeattacking != ATTACKING_RECORD)
{
if (saved)
CONS_Printf(M_GetText("Demo %s recorded\n"), demoname);
else
CONS_Alert(CONS_WARNING, M_GetText("Demo %s not saved\n"), demoname);
}
}
// Stops metal sonic's demo. Separate from other functions because metal + replays can coexist // Stops metal sonic's demo. Separate from other functions because metal + replays can coexist
void G_StopMetalDemo(void) void G_StopMetalDemo(void)
{ {
@ -2349,20 +2398,8 @@ ATTRNORETURN void FUNCNORETURN G_StopMetalRecording(boolean kill)
boolean saved = false; boolean saved = false;
if (demo_p) if (demo_p)
{ {
UINT8 *p = demobuffer+16; // checksum position WRITEUINT8(demo_p, (kill) ? METALDEATH : DEMOMARKER); // add the demo end (or metal death) marker
if (kill) WriteDemoChecksum();
WRITEUINT8(demo_p, METALDEATH); // add the metal death marker
else
WRITEUINT8(demo_p, DEMOMARKER); // add the demo end marker
#ifdef NOMD5
{
UINT8 i;
for (i = 0; i < 16; i++, p++)
*p = P_RandomByte(); // This MD5 was chosen by fair dice roll and most likely < 50% correct.
}
#else
md5_buffer((char *)p+16, demo_p - (p+16), (void *)p); // make a checksum of everything after the checksum in the file.
#endif
saved = FIL_WriteFile(va("%sMS.LMP", G_BuildMapName(gamemap)), demobuffer, demo_p - demobuffer); // finally output the file. saved = FIL_WriteFile(va("%sMS.LMP", G_BuildMapName(gamemap)), demobuffer, demo_p - demobuffer); // finally output the file.
} }
free(demobuffer); free(demobuffer);
@ -2372,6 +2409,63 @@ ATTRNORETURN void FUNCNORETURN G_StopMetalRecording(boolean kill)
I_Error("Failed to save demo!"); I_Error("Failed to save demo!");
} }
// Stops timing a demo.
static void G_StopTimingDemo(void)
{
INT32 demotime;
double f1, f2;
demotime = I_GetTime() - demostarttime;
if (!demotime)
return;
G_StopDemo();
timingdemo = false;
f1 = (double)demotime;
f2 = (double)framecount*TICRATE;
CONS_Printf(M_GetText("timed %u gametics in %d realtics - %u frames\n%f seconds, %f avg fps\n"),
leveltime,demotime,(UINT32)framecount,f1/TICRATE,f2/f1);
// CSV-readable timedemo results, for external parsing
if (timedemo_csv)
{
FILE *f;
const char *csvpath = va("%s"PATHSEP"%s", srb2home, "timedemo.csv");
const char *header = "id,demoname,seconds,avgfps,leveltime,demotime,framecount,ticrate,rendermode,vidmode,vidwidth,vidheight,procbits\n";
const char *rowformat = "\"%s\",\"%s\",%f,%f,%u,%d,%u,%u,%u,%u,%u,%u,%u\n";
boolean headerrow = !FIL_FileExists(csvpath);
UINT8 procbits = 0;
// Bitness
if (sizeof(void*) == 4)
procbits = 32;
else if (sizeof(void*) == 8)
procbits = 64;
f = fopen(csvpath, "a+");
if (f)
{
if (headerrow)
fputs(header, f);
fprintf(f, rowformat,
timedemo_csv_id,timedemo_name,f1/TICRATE,f2/f1,leveltime,demotime,(UINT32)framecount,TICRATE,rendermode,vid.modenum,vid.width,vid.height,procbits);
fclose(f);
CONS_Printf("Timedemo results saved to '%s'\n", csvpath);
}
else
{
// Just print the CSV output to console
CON_LogMessage(header);
CONS_Printf(rowformat,
timedemo_csv_id,timedemo_name,f1/TICRATE,f2/f1,leveltime,demotime,(UINT32)framecount,TICRATE,rendermode,vid.modenum,vid.width,vid.height,procbits);
}
}
if (restorecv_vidwait != cv_vidwait.value)
CV_SetValue(&cv_vidwait, restorecv_vidwait);
D_AdvanceDemo();
}
// reset engine variable set for the demos // reset engine variable set for the demos
// called from stopdemo command, map command, and g_checkdemoStatus. // called from stopdemo command, map command, and g_checkdemoStatus.
void G_StopDemo(void) void G_StopDemo(void)
@ -2394,66 +2488,13 @@ void G_StopDemo(void)
boolean G_CheckDemoStatus(void) boolean G_CheckDemoStatus(void)
{ {
boolean saved;
G_FreeGhosts(); G_FreeGhosts();
// DO NOT end metal sonic demos here // DO NOT end metal sonic demos here
if (timingdemo) if (timingdemo)
{ {
INT32 demotime; G_StopTimingDemo();
double f1, f2;
demotime = I_GetTime() - demostarttime;
if (!demotime)
return true;
G_StopDemo();
timingdemo = false;
f1 = (double)demotime;
f2 = (double)framecount*TICRATE;
CONS_Printf(M_GetText("timed %u gametics in %d realtics - %u frames\n%f seconds, %f avg fps\n"),
leveltime,demotime,(UINT32)framecount,f1/TICRATE,f2/f1);
// CSV-readable timedemo results, for external parsing
if (timedemo_csv)
{
FILE *f;
const char *csvpath = va("%s"PATHSEP"%s", srb2home, "timedemo.csv");
const char *header = "id,demoname,seconds,avgfps,leveltime,demotime,framecount,ticrate,rendermode,vidmode,vidwidth,vidheight,procbits\n";
const char *rowformat = "\"%s\",\"%s\",%f,%f,%u,%d,%u,%u,%u,%u,%u,%u,%u\n";
boolean headerrow = !FIL_FileExists(csvpath);
UINT8 procbits = 0;
// Bitness
if (sizeof(void*) == 4)
procbits = 32;
else if (sizeof(void*) == 8)
procbits = 64;
f = fopen(csvpath, "a+");
if (f)
{
if (headerrow)
fputs(header, f);
fprintf(f, rowformat,
timedemo_csv_id,timedemo_name,f1/TICRATE,f2/f1,leveltime,demotime,(UINT32)framecount,TICRATE,rendermode,vid.modenum,vid.width,vid.height,procbits);
fclose(f);
CONS_Printf("Timedemo results saved to '%s'\n", csvpath);
}
else
{
// Just print the CSV output to console
CON_LogMessage(header);
CONS_Printf(rowformat,
timedemo_csv_id,timedemo_name,f1/TICRATE,f2/f1,leveltime,demotime,(UINT32)framecount,TICRATE,rendermode,vid.modenum,vid.width,vid.height,procbits);
}
}
if (restorecv_vidwait != cv_vidwait.value)
CV_SetValue(&cv_vidwait, restorecv_vidwait);
D_AdvanceDemo();
return true; return true;
} }
@ -2473,27 +2514,7 @@ boolean G_CheckDemoStatus(void)
if (demorecording) if (demorecording)
{ {
UINT8 *p = demobuffer+16; // checksum position G_StopDemoRecording();
#ifdef NOMD5
UINT8 i;
WRITEUINT8(demo_p, DEMOMARKER); // add the demo end marker
for (i = 0; i < 16; i++, p++)
*p = P_RandomByte(); // This MD5 was chosen by fair dice roll and most likely < 50% correct.
#else
WRITEUINT8(demo_p, DEMOMARKER); // add the demo end marker
md5_buffer((char *)p+16, demo_p - (p+16), p); // make a checksum of everything after the checksum in the file.
#endif
saved = FIL_WriteFile(va(pandf, srb2home, demoname), demobuffer, demo_p - demobuffer); // finally output the file.
free(demobuffer);
demorecording = false;
if (modeattacking != ATTACKING_RECORD)
{
if (saved)
CONS_Printf(M_GetText("Demo %s recorded\n"), demoname);
else
CONS_Alert(CONS_WARNING, M_GetText("Demo %s not saved\n"), demoname);
}
return true; return true;
} }

View File

@ -54,7 +54,7 @@ UINT8 ultimatemode = false;
boolean botingame; boolean botingame;
UINT8 botskin; UINT8 botskin;
UINT8 botcolor; UINT16 botcolor;
JoyType_t Joystick; JoyType_t Joystick;
JoyType_t Joystick2; JoyType_t Joystick2;
@ -135,10 +135,10 @@ INT32 tutorialanalog = 0; // store cv_analog[0] user value
boolean looptitle = false; boolean looptitle = false;
UINT8 skincolor_redteam = SKINCOLOR_RED; UINT16 skincolor_redteam = SKINCOLOR_RED;
UINT8 skincolor_blueteam = SKINCOLOR_BLUE; UINT16 skincolor_blueteam = SKINCOLOR_BLUE;
UINT8 skincolor_redring = SKINCOLOR_SALMON; UINT16 skincolor_redring = SKINCOLOR_SALMON;
UINT8 skincolor_bluering = SKINCOLOR_CORNFLOWER; UINT16 skincolor_bluering = SKINCOLOR_CORNFLOWER;
tic_t countdowntimer = 0; tic_t countdowntimer = 0;
boolean countdowntimeup = false; boolean countdowntimeup = false;
@ -1866,6 +1866,7 @@ void G_StartTitleCard(void)
// //
void G_PreLevelTitleCard(void) void G_PreLevelTitleCard(void)
{ {
#ifndef NOWIPE
tic_t starttime = I_GetTime(); tic_t starttime = I_GetTime();
tic_t endtime = starttime + (PRELEVELTIME*NEWTICRATERATIO); tic_t endtime = starttime + (PRELEVELTIME*NEWTICRATERATIO);
tic_t nowtime = starttime; tic_t nowtime = starttime;
@ -1888,6 +1889,7 @@ void G_PreLevelTitleCard(void)
} }
if (!cv_showhud.value) if (!cv_showhud.value)
wipestyleflags = WSF_CROSSFADE; wipestyleflags = WSF_CROSSFADE;
#endif
} }
static boolean titlecardforreload = false; static boolean titlecardforreload = false;
@ -2382,7 +2384,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
INT16 totalring; INT16 totalring;
UINT8 laps; UINT8 laps;
UINT8 mare; UINT8 mare;
UINT8 skincolor; UINT16 skincolor;
INT32 skin; INT32 skin;
UINT32 availabilities; UINT32 availabilities;
tic_t jointime; tic_t jointime;
@ -4480,7 +4482,7 @@ cleanup:
// //
void G_DeferedInitNew(boolean pultmode, const char *mapname, INT32 pickedchar, boolean SSSG, boolean FLS) void G_DeferedInitNew(boolean pultmode, const char *mapname, INT32 pickedchar, boolean SSSG, boolean FLS)
{ {
UINT8 color = skins[pickedchar].prefcolor; UINT16 color = skins[pickedchar].prefcolor;
paused = false; paused = false;
if (demoplayback) if (demoplayback)
@ -4634,7 +4636,7 @@ char *G_BuildMapTitle(INT32 mapnum)
{ {
size_t len = 1; size_t len = 1;
const char *zonetext = NULL; const char *zonetext = NULL;
const INT32 actnum = mapheaderinfo[mapnum-1]->actnum; const UINT8 actnum = mapheaderinfo[mapnum-1]->actnum;
len += strlen(mapheaderinfo[mapnum-1]->lvlttl); len += strlen(mapheaderinfo[mapnum-1]->lvlttl);
if (!(mapheaderinfo[mapnum-1]->levelflags & LF_NOZONE)) if (!(mapheaderinfo[mapnum-1]->levelflags & LF_NOZONE))

View File

@ -57,6 +57,7 @@ extern UINT8 ultimatemode; // was sk_insane
extern gameaction_t gameaction; extern gameaction_t gameaction;
extern boolean botingame; extern boolean botingame;
extern UINT8 botskin, botcolor; extern UINT8 botskin;
extern UINT16 botcolor;
#endif //__G_STATE__ #endif //__G_STATE__

View File

@ -887,12 +887,10 @@ static void AdjustSegs(void)
float distv1,distv2,tmp; float distv1,distv2,tmp;
nearv1 = nearv2 = MYMAX; nearv1 = nearv2 = MYMAX;
#ifdef POLYOBJECTS
// Don't touch polyobject segs. We'll compensate // Don't touch polyobject segs. We'll compensate
// for this when we go about drawing them. // for this when we go about drawing them.
if (lseg->polyseg) if (lseg->polyseg)
continue; continue;
#endif
if (p) { if (p) {
for (j = 0; j < p->numpts; j++) for (j = 0; j < p->numpts; j++)

View File

@ -298,6 +298,8 @@ light_t *t_lspr[NUMSPRITES] =
// Projectiles // Projectiles
&lspr[NOLIGHT], // SPR_MISL &lspr[NOLIGHT], // SPR_MISL
&lspr[SMALLREDBALL_L], // SPR_LASR
&lspr[REDSHINE_L], // SPR_LASF
&lspr[NOLIGHT], // SPR_TORP &lspr[NOLIGHT], // SPR_TORP
&lspr[NOLIGHT], // SPR_ENRG &lspr[NOLIGHT], // SPR_ENRG
&lspr[NOLIGHT], // SPR_MINE &lspr[NOLIGHT], // SPR_MINE

View File

@ -511,7 +511,7 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool
// Set fixedheight to the slope's height from our viewpoint, if we have a slope // Set fixedheight to the slope's height from our viewpoint, if we have a slope
if (slope) if (slope)
fixedheight = P_GetZAt(slope, viewx, viewy); fixedheight = P_GetSlopeZAt(slope, viewx, viewy);
height = FIXED_TO_FLOAT(fixedheight); height = FIXED_TO_FLOAT(fixedheight);
@ -657,7 +657,7 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool
\ \
if (slope)\ if (slope)\
{\ {\
fixedheight = P_GetZAt(slope, FLOAT_TO_FIXED((vx)), FLOAT_TO_FIXED((vy)));\ fixedheight = P_GetSlopeZAt(slope, FLOAT_TO_FIXED((vx)), FLOAT_TO_FIXED((vy)));\
vert->y = FIXED_TO_FLOAT(fixedheight);\ vert->y = FIXED_TO_FLOAT(fixedheight);\
}\ }\
} }
@ -1100,8 +1100,8 @@ static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum,
float endpegt, endpegb, endpegmul; float endpegt, endpegb, endpegmul;
float endheight = 0.0f, endbheight = 0.0f; float endheight = 0.0f, endbheight = 0.0f;
// compiler complains when P_GetZAt is used in FLOAT_TO_FIXED directly // compiler complains when P_GetSlopeZAt is used in FLOAT_TO_FIXED directly
// use this as a temp var to store P_GetZAt's return value each time // use this as a temp var to store P_GetSlopeZAt's return value each time
fixed_t temp; fixed_t temp;
fixed_t v1x = FLOAT_TO_FIXED(wallVerts[0].x); fixed_t v1x = FLOAT_TO_FIXED(wallVerts[0].x);
@ -1164,26 +1164,16 @@ static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum,
else else
solid = false; solid = false;
if (list[i].slope) temp = P_GetLightZAt(&list[i], v1x, v1y);
{ height = FIXED_TO_FLOAT(temp);
temp = P_GetZAt(list[i].slope, v1x, v1y); temp = P_GetLightZAt(&list[i], v2x, v2y);
height = FIXED_TO_FLOAT(temp); endheight = FIXED_TO_FLOAT(temp);
temp = P_GetZAt(list[i].slope, v2x, v2y);
endheight = FIXED_TO_FLOAT(temp);
}
else
height = endheight = FIXED_TO_FLOAT(list[i].height);
if (solid) if (solid)
{ {
if (*list[i].caster->b_slope) temp = P_GetFFloorBottomZAt(list[i].caster, v1x, v1y);
{ bheight = FIXED_TO_FLOAT(temp);
temp = P_GetZAt(*list[i].caster->b_slope, v1x, v1y); temp = P_GetFFloorBottomZAt(list[i].caster, v2x, v2y);
bheight = FIXED_TO_FLOAT(temp); endbheight = FIXED_TO_FLOAT(temp);
temp = P_GetZAt(*list[i].caster->b_slope, v2x, v2y);
endbheight = FIXED_TO_FLOAT(temp);
}
else
bheight = endbheight = FIXED_TO_FLOAT(*list[i].caster->bottomheight);
} }
if (endheight >= endtop && height >= top) if (endheight >= endtop && height >= top)
@ -1196,15 +1186,10 @@ static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum,
if (i + 1 < sector->numlights) if (i + 1 < sector->numlights)
{ {
if (list[i+1].slope) temp = P_GetLightZAt(&list[i+1], v1x, v1y);
{ bheight = FIXED_TO_FLOAT(temp);
temp = P_GetZAt(list[i+1].slope, v1x, v1y); temp = P_GetLightZAt(&list[i+1], v2x, v2y);
bheight = FIXED_TO_FLOAT(temp); endbheight = FIXED_TO_FLOAT(temp);
temp = P_GetZAt(list[i+1].slope, v2x, v2y);
endbheight = FIXED_TO_FLOAT(temp);
}
else
bheight = endbheight = FIXED_TO_FLOAT(list[i+1].height);
} }
else else
{ {
@ -1343,11 +1328,8 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
v2y = FLOAT_TO_FIXED(ve.y); v2y = FLOAT_TO_FIXED(ve.y);
#define SLOPEPARAMS(slope, end1, end2, normalheight) \ #define SLOPEPARAMS(slope, end1, end2, normalheight) \
if (slope) { \ end1 = P_GetZAt(slope, v1x, v1y, normalheight); \
end1 = P_GetZAt(slope, v1x, v1y); \ end2 = P_GetZAt(slope, v2x, v2y, normalheight);
end2 = P_GetZAt(slope, v2x, v2y); \
} else \
end1 = end2 = normalheight;
SLOPEPARAMS(gr_frontsector->c_slope, worldtop, worldtopslope, gr_frontsector->ceilingheight) SLOPEPARAMS(gr_frontsector->c_slope, worldtop, worldtopslope, gr_frontsector->ceilingheight)
SLOPEPARAMS(gr_frontsector->f_slope, worldbottom, worldbottomslope, gr_frontsector->floorheight) SLOPEPARAMS(gr_frontsector->f_slope, worldbottom, worldbottomslope, gr_frontsector->floorheight)
@ -1602,7 +1584,6 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
// heights of the polygon, and h & l, are the final (clipped) // heights of the polygon, and h & l, are the final (clipped)
// poly coords. // poly coords.
#ifdef POLYOBJECTS
// NOTE: With polyobjects, whenever you need to check the properties of the polyobject sector it belongs to, // NOTE: With polyobjects, whenever you need to check the properties of the polyobject sector it belongs to,
// you must use the linedef's backsector to be correct // you must use the linedef's backsector to be correct
// From CB // From CB
@ -1612,7 +1593,6 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
popenbottom = back->floorheight; popenbottom = back->floorheight;
} }
else else
#endif
{ {
popentop = min(worldtop, worldhigh); popentop = min(worldtop, worldhigh);
popenbottom = max(worldbottom, worldlow); popenbottom = max(worldbottom, worldlow);
@ -1642,7 +1622,6 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
polybottom = polytop - textureheight[gr_midtexture]*repeats; polybottom = polytop - textureheight[gr_midtexture]*repeats;
} }
// CB // CB
#ifdef POLYOBJECTS
// NOTE: With polyobjects, whenever you need to check the properties of the polyobject sector it belongs to, // NOTE: With polyobjects, whenever you need to check the properties of the polyobject sector it belongs to,
// you must use the linedef's backsector to be correct // you must use the linedef's backsector to be correct
if (gr_curline->polyseg) if (gr_curline->polyseg)
@ -1650,7 +1629,6 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
lowcut = polybottom; lowcut = polybottom;
highcut = polytop; highcut = polytop;
} }
#endif
else else
{ {
// The cut-off values of a linedef can always be constant, since every line has an absoulute front and or back sector // The cut-off values of a linedef can always be constant, since every line has an absoulute front and or back sector
@ -1780,7 +1758,6 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
break; break;
} }
#ifdef POLYOBJECTS
if (gr_curline->polyseg && gr_curline->polyseg->translucency > 0) if (gr_curline->polyseg && gr_curline->polyseg->translucency > 0)
{ {
if (gr_curline->polyseg->translucency >= NUMTRANSMAPS) // wall not drawn if (gr_curline->polyseg->translucency >= NUMTRANSMAPS) // wall not drawn
@ -1791,7 +1768,6 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
else else
blendmode = HWR_TranstableToAlpha(gr_curline->polyseg->translucency, &Surf); blendmode = HWR_TranstableToAlpha(gr_curline->polyseg->translucency, &Surf);
} }
#endif
if (gr_frontsector->numlights) if (gr_frontsector->numlights)
{ {
@ -1956,10 +1932,10 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
texnum = R_GetTextureNum(sides[newline->sidenum[0]].midtexture); texnum = R_GetTextureNum(sides[newline->sidenum[0]].midtexture);
} }
h = *rover->t_slope ? P_GetZAt(*rover->t_slope, v1x, v1y) : *rover->topheight; h = P_GetFFloorTopZAt (rover, v1x, v1y);
hS = *rover->t_slope ? P_GetZAt(*rover->t_slope, v2x, v2y) : *rover->topheight; hS = P_GetFFloorTopZAt (rover, v2x, v2y);
l = *rover->b_slope ? P_GetZAt(*rover->b_slope, v1x, v1y) : *rover->bottomheight; l = P_GetFFloorBottomZAt(rover, v1x, v1y);
lS = *rover->b_slope ? P_GetZAt(*rover->b_slope, v2x, v2y) : *rover->bottomheight; lS = P_GetFFloorBottomZAt(rover, v2x, v2y);
if (!(*rover->t_slope) && !gr_frontsector->c_slope && !gr_backsector->c_slope && h > highcut) if (!(*rover->t_slope) && !gr_frontsector->c_slope && !gr_backsector->c_slope && h > highcut)
h = hS = highcut; h = hS = highcut;
if (!(*rover->b_slope) && !gr_frontsector->f_slope && !gr_backsector->f_slope && l < lowcut) if (!(*rover->b_slope) && !gr_frontsector->f_slope && !gr_backsector->f_slope && l < lowcut)
@ -2097,10 +2073,10 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
newline = rover->master->frontsector->lines[0] + linenum; newline = rover->master->frontsector->lines[0] + linenum;
texnum = R_GetTextureNum(sides[newline->sidenum[0]].midtexture); texnum = R_GetTextureNum(sides[newline->sidenum[0]].midtexture);
} }
h = *rover->t_slope ? P_GetZAt(*rover->t_slope, v1x, v1y) : *rover->topheight; h = P_GetFFloorTopZAt (rover, v1x, v1y);
hS = *rover->t_slope ? P_GetZAt(*rover->t_slope, v2x, v2y) : *rover->topheight; hS = P_GetFFloorTopZAt (rover, v2x, v2y);
l = *rover->b_slope ? P_GetZAt(*rover->b_slope, v1x, v1y) : *rover->bottomheight; l = P_GetFFloorBottomZAt(rover, v1x, v1y);
lS = *rover->b_slope ? P_GetZAt(*rover->b_slope, v2x, v2y) : *rover->bottomheight; lS = P_GetFFloorBottomZAt(rover, v2x, v2y);
if (!(*rover->t_slope) && !gr_frontsector->c_slope && !gr_backsector->c_slope && h > highcut) if (!(*rover->t_slope) && !gr_frontsector->c_slope && !gr_backsector->c_slope && h > highcut)
h = hS = highcut; h = hS = highcut;
if (!(*rover->b_slope) && !gr_frontsector->f_slope && !gr_backsector->f_slope && l < lowcut) if (!(*rover->b_slope) && !gr_frontsector->f_slope && !gr_backsector->f_slope && l < lowcut)
@ -2218,24 +2194,21 @@ static boolean CheckClip(seg_t * seg, sector_t * afrontsector, sector_t * abacks
v2x = FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv2)->x); v2x = FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv2)->x);
v2y = FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv2)->y); v2y = FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv2)->y);
#define SLOPEPARAMS(slope, end1, end2, normalheight) \ #define SLOPEPARAMS(slope, end1, end2, normalheight) \
if (slope) { \ end1 = P_GetZAt(slope, v1x, v1y, normalheight); \
end1 = P_GetZAt(slope, v1x, v1y); \ end2 = P_GetZAt(slope, v2x, v2y, normalheight);
end2 = P_GetZAt(slope, v2x, v2y); \
} else \
end1 = end2 = normalheight;
SLOPEPARAMS(afrontsector->f_slope, frontf1, frontf2, afrontsector->floorheight) SLOPEPARAMS(afrontsector->f_slope, frontf1, frontf2, afrontsector-> floorheight)
SLOPEPARAMS(afrontsector->c_slope, frontc1, frontc2, afrontsector->ceilingheight) SLOPEPARAMS(afrontsector->c_slope, frontc1, frontc2, afrontsector->ceilingheight)
SLOPEPARAMS( abacksector->f_slope, backf1, backf2, abacksector->floorheight) SLOPEPARAMS( abacksector->f_slope, backf1, backf2, abacksector-> floorheight)
SLOPEPARAMS( abacksector->c_slope, backc1, backc2, abacksector->ceilingheight) SLOPEPARAMS( abacksector->c_slope, backc1, backc2, abacksector->ceilingheight)
#undef SLOPEPARAMS #undef SLOPEPARAMS
} }
else else
{ {
frontf1 = frontf2 = afrontsector->floorheight; frontf1 = frontf2 = afrontsector-> floorheight;
frontc1 = frontc2 = afrontsector->ceilingheight; frontc1 = frontc2 = afrontsector->ceilingheight;
backf1 = backf2 = abacksector->floorheight; backf1 = backf2 = abacksector-> floorheight;
backc1 = backc2 = abacksector->ceilingheight; backc1 = backc2 = abacksector->ceilingheight;
} }
// properly render skies (consider door "open" if both ceilings are sky) // properly render skies (consider door "open" if both ceilings are sky)
// same for floors // same for floors
@ -2587,10 +2560,8 @@ static void HWR_AddLine(seg_t * line)
static sector_t tempsec; static sector_t tempsec;
fixed_t v1x, v1y, v2x, v2y; // the seg's vertexes as fixed_t fixed_t v1x, v1y, v2x, v2y; // the seg's vertexes as fixed_t
#ifdef POLYOBJECTS
if (line->polyseg && !(line->polyseg->flags & POF_RENDERSIDES)) if (line->polyseg && !(line->polyseg->flags & POF_RENDERSIDES))
return; return;
#endif
gr_curline = line; gr_curline = line;
@ -2717,13 +2688,10 @@ static void HWR_AddLine(seg_t * line)
if (bothceilingssky && bothfloorssky) // everything's sky? let's save us a bit of time then if (bothceilingssky && bothfloorssky) // everything's sky? let's save us a bit of time then
{ {
if ( if (!line->polyseg &&
#ifdef POLYOBJECTS !line->sidedef->midtexture
!line->polyseg && && ((!gr_frontsector->ffloors && !gr_backsector->ffloors)
#endif || (gr_frontsector->tag == gr_backsector->tag)))
!line->sidedef->midtexture
&& ((!gr_frontsector->ffloors && !gr_backsector->ffloors)
|| (gr_frontsector->tag == gr_backsector->tag)))
return; // line is empty, don't even bother return; // line is empty, don't even bother
// treat like wide open window instead // treat like wide open window instead
HWR_ProcessSeg(); // Doesn't need arguments because they're defined globally :D HWR_ProcessSeg(); // Doesn't need arguments because they're defined globally :D
@ -2759,13 +2727,10 @@ static void HWR_AddLine(seg_t * line)
if (bothceilingssky && bothfloorssky) // everything's sky? let's save us a bit of time then if (bothceilingssky && bothfloorssky) // everything's sky? let's save us a bit of time then
{ {
if ( if (!line->polyseg &&
#ifdef POLYOBJECTS !line->sidedef->midtexture
!line->polyseg && && ((!gr_frontsector->ffloors && !gr_backsector->ffloors)
#endif || (gr_frontsector->tag == gr_backsector->tag)))
!line->sidedef->midtexture
&& ((!gr_frontsector->ffloors && !gr_backsector->ffloors)
|| (gr_frontsector->tag == gr_backsector->tag)))
return; // line is empty, don't even bother return; // line is empty, don't even bother
goto clippass; // treat like wide open window instead goto clippass; // treat like wide open window instead
@ -2777,16 +2742,13 @@ static void HWR_AddLine(seg_t * line)
fixed_t backf1, backf2, backc1, backc2; // back floor ceiling ends fixed_t backf1, backf2, backc1, backc2; // back floor ceiling ends
#define SLOPEPARAMS(slope, end1, end2, normalheight) \ #define SLOPEPARAMS(slope, end1, end2, normalheight) \
if (slope) { \ end1 = P_GetZAt(slope, v1x, v1y, normalheight); \
end1 = P_GetZAt(slope, v1x, v1y); \ end2 = P_GetZAt(slope, v2x, v2y, normalheight);
end2 = P_GetZAt(slope, v2x, v2y); \
} else \
end1 = end2 = normalheight;
SLOPEPARAMS(gr_frontsector->f_slope, frontf1, frontf2, gr_frontsector->floorheight) SLOPEPARAMS(gr_frontsector->f_slope, frontf1, frontf2, gr_frontsector-> floorheight)
SLOPEPARAMS(gr_frontsector->c_slope, frontc1, frontc2, gr_frontsector->ceilingheight) SLOPEPARAMS(gr_frontsector->c_slope, frontc1, frontc2, gr_frontsector->ceilingheight)
SLOPEPARAMS( gr_backsector->f_slope, backf1, backf2, gr_backsector->floorheight) SLOPEPARAMS( gr_backsector->f_slope, backf1, backf2, gr_backsector-> floorheight)
SLOPEPARAMS( gr_backsector->c_slope, backc1, backc2, gr_backsector->ceilingheight) SLOPEPARAMS( gr_backsector->c_slope, backc1, backc2, gr_backsector->ceilingheight)
#undef SLOPEPARAMS #undef SLOPEPARAMS
// if both ceilings are skies, consider it always "open" // if both ceilings are skies, consider it always "open"
// same for floors // same for floors
@ -2957,8 +2919,6 @@ static boolean HWR_CheckBBox(fixed_t *bspcoord)
#endif #endif
} }
#ifdef POLYOBJECTS
// //
// HWR_AddPolyObjectSegs // HWR_AddPolyObjectSegs
// //
@ -3001,7 +2961,6 @@ static inline void HWR_AddPolyObjectSegs(void)
Z_Free(gr_fakeline); Z_Free(gr_fakeline);
} }
#ifdef POLYOBJECTS_PLANES
static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, fixed_t fixedheight, static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, fixed_t fixedheight,
FBITFIELD blendmode, UINT8 lightlevel, levelflat_t *levelflat, sector_t *FOFsector, FBITFIELD blendmode, UINT8 lightlevel, levelflat_t *levelflat, sector_t *FOFsector,
UINT8 alpha, extracolormap_t *planecolormap) UINT8 alpha, extracolormap_t *planecolormap)
@ -3256,8 +3215,6 @@ static void HWR_AddPolyObjectPlanes(void)
} }
} }
} }
#endif
#endif
// -----------------+ // -----------------+
// HWR_Subsector : Determine floor/ceiling planes. // HWR_Subsector : Determine floor/ceiling planes.
@ -3349,20 +3306,10 @@ static void HWR_Subsector(size_t num)
} }
else else
{ {
cullFloorHeight = locFloorHeight = gr_frontsector->floorheight; cullFloorHeight = P_GetSectorFloorZAt (gr_frontsector, viewx, viewy);
cullCeilingHeight = locCeilingHeight = gr_frontsector->ceilingheight; cullCeilingHeight = P_GetSectorCeilingZAt(gr_frontsector, viewx, viewy);
locFloorHeight = P_GetSectorFloorZAt (gr_frontsector, gr_frontsector->soundorg.x, gr_frontsector->soundorg.y);
if (gr_frontsector->f_slope) locCeilingHeight = P_GetSectorCeilingZAt(gr_frontsector, gr_frontsector->soundorg.x, gr_frontsector->soundorg.y);
{
cullFloorHeight = P_GetZAt(gr_frontsector->f_slope, viewx, viewy);
locFloorHeight = P_GetZAt(gr_frontsector->f_slope, gr_frontsector->soundorg.x, gr_frontsector->soundorg.y);
}
if (gr_frontsector->c_slope)
{
cullCeilingHeight = P_GetZAt(gr_frontsector->c_slope, viewx, viewy);
locCeilingHeight = P_GetZAt(gr_frontsector->c_slope, gr_frontsector->soundorg.x, gr_frontsector->soundorg.y);
}
} }
// ----- end special tricks ----- // ----- end special tricks -----
@ -3454,13 +3401,8 @@ static void HWR_Subsector(size_t num)
fixed_t cullHeight, centerHeight; fixed_t cullHeight, centerHeight;
// bottom plane // bottom plane
if (*rover->b_slope) cullHeight = P_GetFFloorBottomZAt(rover, viewx, viewy);
{ centerHeight = P_GetFFloorBottomZAt(rover, gr_frontsector->soundorg.x, gr_frontsector->soundorg.y);
cullHeight = P_GetZAt(*rover->b_slope, viewx, viewy);
centerHeight = P_GetZAt(*rover->b_slope, gr_frontsector->soundorg.x, gr_frontsector->soundorg.y);
}
else
cullHeight = centerHeight = *rover->bottomheight;
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERPLANES)) if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERPLANES))
continue; continue;
@ -3520,13 +3462,8 @@ static void HWR_Subsector(size_t num)
} }
// top plane // top plane
if (*rover->t_slope) cullHeight = P_GetFFloorTopZAt(rover, viewx, viewy);
{ centerHeight = P_GetFFloorTopZAt(rover, gr_frontsector->soundorg.x, gr_frontsector->soundorg.y);
cullHeight = P_GetZAt(*rover->t_slope, viewx, viewy);
centerHeight = P_GetZAt(*rover->t_slope, gr_frontsector->soundorg.x, gr_frontsector->soundorg.y);
}
else
cullHeight = centerHeight = *rover->topheight;
if (centerHeight >= locFloorHeight && if (centerHeight >= locFloorHeight &&
centerHeight <= locCeilingHeight && centerHeight <= locCeilingHeight &&
@ -3585,7 +3522,6 @@ static void HWR_Subsector(size_t num)
#endif #endif
#endif //doplanes #endif //doplanes
#ifdef POLYOBJECTS
// Draw all the polyobjects in this subsector // Draw all the polyobjects in this subsector
if (sub->polyList) if (sub->polyList)
{ {
@ -3606,15 +3542,12 @@ static void HWR_Subsector(size_t num)
// Draw polyobject lines. // Draw polyobject lines.
HWR_AddPolyObjectSegs(); HWR_AddPolyObjectSegs();
#ifdef POLYOBJECTS_PLANES
if (sub->validcount != validcount) // This validcount situation seems to let us know that the floors have already been drawn. if (sub->validcount != validcount) // This validcount situation seems to let us know that the floors have already been drawn.
{ {
// Draw polyobject planes // Draw polyobject planes
HWR_AddPolyObjectPlanes(); HWR_AddPolyObjectPlanes();
} }
#endif
} }
#endif
// Hurder ici se passe les choses INT32<33>essantes! // Hurder ici se passe les choses INT32<33>essantes!
// on vient de tracer le sol et le plafond // on vient de tracer le sol et le plafond
@ -3637,14 +3570,8 @@ static void HWR_Subsector(size_t num)
while (count--) while (count--)
{ {
if (!line->glseg if (!line->glseg && !line->polyseg) // ignore segs that belong to polyobjects
#ifdef POLYOBJECTS
&& !line->polyseg // ignore segs that belong to polyobjects
#endif
)
{
HWR_AddLine(line); HWR_AddLine(line);
}
line++; line++;
} }
} }
@ -3959,7 +3886,7 @@ static void HWR_DrawDropShadow(mobj_t *thing, gr_vissprite_t *spr, fixed_t scale
HWR_GetPatch(gpatch); HWR_GetPatch(gpatch);
scalemul = FixedMul(FRACUNIT - floordiff/640, scale); scalemul = FixedMul(FRACUNIT - floordiff/640, scale);
scalemul = FixedMul(scalemul, (thing->radius*2) / gpatch->height); scalemul = FixedMul(scalemul, (thing->radius*2) / SHORT(gpatch->height));
fscale = FIXED_TO_FLOAT(scalemul); fscale = FIXED_TO_FLOAT(scalemul);
fx = FIXED_TO_FLOAT(thing->x); fx = FIXED_TO_FLOAT(thing->x);
@ -3971,9 +3898,9 @@ static void HWR_DrawDropShadow(mobj_t *thing, gr_vissprite_t *spr, fixed_t scale
// 0--1 // 0--1
if (thing && fabsf(fscale - 1.0f) > 1.0E-36f) if (thing && fabsf(fscale - 1.0f) > 1.0E-36f)
offset = (gpatch->height/2) * fscale; offset = (SHORT(gpatch->height)/2) * fscale;
else else
offset = (float)(gpatch->height/2); offset = (float)(SHORT(gpatch->height)/2);
shadowVerts[0].x = shadowVerts[3].x = fx - offset; shadowVerts[0].x = shadowVerts[3].x = fx - offset;
shadowVerts[2].x = shadowVerts[1].x = fx + offset; shadowVerts[2].x = shadowVerts[1].x = fx + offset;
@ -3984,7 +3911,7 @@ static void HWR_DrawDropShadow(mobj_t *thing, gr_vissprite_t *spr, fixed_t scale
{ {
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
{ {
slopez = P_GetZAt(floorslope, FLOAT_TO_FIXED(shadowVerts[i].x), FLOAT_TO_FIXED(shadowVerts[i].z)); slopez = P_GetSlopeZAt(floorslope, FLOAT_TO_FIXED(shadowVerts[i].x), FLOAT_TO_FIXED(shadowVerts[i].z));
shadowVerts[i].y = FIXED_TO_FLOAT(slopez) + 0.05f; shadowVerts[i].y = FIXED_TO_FLOAT(slopez) + 0.05f;
} }
} }
@ -4048,7 +3975,7 @@ static void HWR_DrawDropShadow(mobj_t *thing, gr_vissprite_t *spr, fixed_t scale
} }
// This is expecting a pointer to an array containing 4 wallVerts for a sprite // This is expecting a pointer to an array containing 4 wallVerts for a sprite
static void HWR_RotateSpritePolyToAim(gr_vissprite_t *spr, FOutVector *wallVerts) static void HWR_RotateSpritePolyToAim(gr_vissprite_t *spr, FOutVector *wallVerts, const boolean precip)
{ {
if (cv_grspritebillboarding.value if (cv_grspritebillboarding.value
&& spr && spr->mobj && !(spr->mobj->frame & FF_PAPERSPRITE) && spr && spr->mobj && !(spr->mobj->frame & FF_PAPERSPRITE)
@ -4056,7 +3983,7 @@ static void HWR_RotateSpritePolyToAim(gr_vissprite_t *spr, FOutVector *wallVerts
{ {
float basey = FIXED_TO_FLOAT(spr->mobj->z); float basey = FIXED_TO_FLOAT(spr->mobj->z);
float lowy = wallVerts[0].y; float lowy = wallVerts[0].y;
if (P_MobjFlip(spr->mobj) == -1) if (!precip && P_MobjFlip(spr->mobj) == -1) // precip doesn't have eflags so they can't flip
{ {
basey = FIXED_TO_FLOAT(spr->mobj->z + spr->mobj->height); basey = FIXED_TO_FLOAT(spr->mobj->z + spr->mobj->height);
} }
@ -4169,7 +4096,7 @@ static void HWR_SplitSprite(gr_vissprite_t *spr)
} }
// Let dispoffset work first since this adjust each vertex // Let dispoffset work first since this adjust each vertex
HWR_RotateSpritePolyToAim(spr, baseWallVerts); HWR_RotateSpritePolyToAim(spr, baseWallVerts, false);
realtop = top = baseWallVerts[3].y; realtop = top = baseWallVerts[3].y;
realbot = bot = baseWallVerts[0].y; realbot = bot = baseWallVerts[0].y;
@ -4220,8 +4147,7 @@ static void HWR_SplitSprite(gr_vissprite_t *spr)
for (i = 1; i < sector->numlights; i++) for (i = 1; i < sector->numlights; i++)
{ {
fixed_t h = sector->lightlist[i].slope ? P_GetZAt(sector->lightlist[i].slope, spr->mobj->x, spr->mobj->y) fixed_t h = P_GetLightZAt(&sector->lightlist[i], spr->mobj->x, spr->mobj->y);
: sector->lightlist[i].height;
if (h <= temp) if (h <= temp)
{ {
if (!(spr->mobj->frame & FF_FULLBRIGHT)) if (!(spr->mobj->frame & FF_FULLBRIGHT))
@ -4246,15 +4172,10 @@ static void HWR_SplitSprite(gr_vissprite_t *spr)
if (i + 1 < sector->numlights) if (i + 1 < sector->numlights)
{ {
if (list[i+1].slope) temp = P_GetLightZAt(&list[i+1], v1x, v1y);
{ bheight = FIXED_TO_FLOAT(temp);
temp = P_GetZAt(list[i+1].slope, v1x, v1y); temp = P_GetLightZAt(&list[i+1], v2x, v2y);
bheight = FIXED_TO_FLOAT(temp); endbheight = FIXED_TO_FLOAT(temp);
temp = P_GetZAt(list[i+1].slope, v2x, v2y);
endbheight = FIXED_TO_FLOAT(temp);
}
else
bheight = endbheight = FIXED_TO_FLOAT(list[i+1].height);
} }
else else
{ {
@ -4448,7 +4369,7 @@ static void HWR_DrawSprite(gr_vissprite_t *spr)
} }
// Let dispoffset work first since this adjust each vertex // Let dispoffset work first since this adjust each vertex
HWR_RotateSpritePolyToAim(spr, wallVerts); HWR_RotateSpritePolyToAim(spr, wallVerts, false);
// This needs to be AFTER the shadows so that the regular sprites aren't drawn completely black. // This needs to be AFTER the shadows so that the regular sprites aren't drawn completely black.
// sprite lighting by modulating the RGB components // sprite lighting by modulating the RGB components
@ -4532,7 +4453,7 @@ static inline void HWR_DrawPrecipitationSprite(gr_vissprite_t *spr)
wallVerts[1].z = wallVerts[2].z = spr->z2; wallVerts[1].z = wallVerts[2].z = spr->z2;
// Let dispoffset work first since this adjust each vertex // Let dispoffset work first since this adjust each vertex
HWR_RotateSpritePolyToAim(spr, wallVerts); HWR_RotateSpritePolyToAim(spr, wallVerts, true);
wallVerts[0].sow = wallVerts[3].sow = 0; wallVerts[0].sow = wallVerts[3].sow = 0;
wallVerts[2].sow = wallVerts[1].sow = gpatch->max_s; wallVerts[2].sow = wallVerts[1].sow = gpatch->max_s;
@ -5282,10 +5203,10 @@ static void HWR_ProjectSprite(mobj_t *thing)
rotsprite = sprframe->rotsprite.patch[rot][rollangle]; rotsprite = sprframe->rotsprite.patch[rot][rollangle];
if (rotsprite != NULL) if (rotsprite != NULL)
{ {
spr_width = rotsprite->width << FRACBITS; spr_width = SHORT(rotsprite->width) << FRACBITS;
spr_height = rotsprite->height << FRACBITS; spr_height = SHORT(rotsprite->height) << FRACBITS;
spr_offset = rotsprite->leftoffset << FRACBITS; spr_offset = SHORT(rotsprite->leftoffset) << FRACBITS;
spr_topoffset = rotsprite->topoffset << FRACBITS; spr_topoffset = SHORT(rotsprite->topoffset) << FRACBITS;
// flip -> rotate, not rotate -> flip // flip -> rotate, not rotate -> flip
flip = 0; flip = 0;
} }

View File

@ -677,12 +677,12 @@ spritemodelfound:
#define SETBRIGHTNESS(brightness,r,g,b) \ #define SETBRIGHTNESS(brightness,r,g,b) \
brightness = (UINT8)(((1063*(UINT16)(r))/5000) + ((3576*(UINT16)(g))/5000) + ((361*(UINT16)(b))/5000)) brightness = (UINT8)(((1063*(UINT16)(r))/5000) + ((3576*(UINT16)(g))/5000) + ((361*(UINT16)(b))/5000))
static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, GLMipmap_t *grmip, INT32 skinnum, skincolors_t color) static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, GLMipmap_t *grmip, INT32 skinnum, skincolornum_t color)
{ {
UINT16 w = gpatch->width, h = gpatch->height; UINT16 w = gpatch->width, h = gpatch->height;
UINT32 size = w*h; UINT32 size = w*h;
RGBA_t *image, *blendimage, *cur, blendcolor; RGBA_t *image, *blendimage, *cur, blendcolor;
UINT8 translation[16]; // First the color index UINT16 translation[16]; // First the color index
UINT8 cutoff[16]; // Brightness cutoff before using the next color UINT8 cutoff[16]; // Brightness cutoff before using the next color
UINT8 translen = 0; UINT8 translen = 0;
UINT8 i; UINT8 i;
@ -718,16 +718,16 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch,
if (skinnum == TC_METALSONIC) if (skinnum == TC_METALSONIC)
color = SKINCOLOR_COBALT; color = SKINCOLOR_COBALT;
if (color != SKINCOLOR_NONE) if (color != SKINCOLOR_NONE && color < numskincolors)
{ {
UINT8 numdupes = 1; UINT8 numdupes = 1;
translation[translen] = Color_Index[color-1][0]; translation[translen] = skincolors[color].ramp[0];
cutoff[translen] = 255; cutoff[translen] = 255;
for (i = 1; i < 16; i++) for (i = 1; i < 16; i++)
{ {
if (translation[translen] == Color_Index[color-1][i]) if (translation[translen] == skincolors[color].ramp[i])
{ {
numdupes++; numdupes++;
continue; continue;
@ -741,7 +741,7 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch,
numdupes = 1; numdupes = 1;
translen++; translen++;
translation[translen] = (UINT8)Color_Index[color-1][i]; translation[translen] = (UINT16)skincolors[color].ramp[i];
} }
translen++; translen++;
@ -1043,7 +1043,7 @@ skippixel:
#undef SETBRIGHTNESS #undef SETBRIGHTNESS
static void HWR_GetBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, INT32 skinnum, const UINT8 *colormap, skincolors_t color) static void HWR_GetBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, INT32 skinnum, const UINT8 *colormap, skincolornum_t color)
{ {
// mostly copied from HWR_GetMappedPatch, hence the similarities and comment // mostly copied from HWR_GetMappedPatch, hence the similarities and comment
GLMipmap_t *grmip, *newmip; GLMipmap_t *grmip, *newmip;
@ -1336,7 +1336,7 @@ boolean HWR_DrawModel(gr_vissprite_t *spr)
else else
skinnum = TC_BOSS; skinnum = TC_BOSS;
} }
else if ((skincolors_t)spr->mobj->color != SKINCOLOR_NONE) else if ((skincolornum_t)spr->mobj->color != SKINCOLOR_NONE)
{ {
if (spr->mobj->colorized) if (spr->mobj->colorized)
skinnum = TC_RAINBOW; skinnum = TC_RAINBOW;
@ -1356,7 +1356,7 @@ boolean HWR_DrawModel(gr_vissprite_t *spr)
} }
// Translation or skin number found // Translation or skin number found
HWR_GetBlendedTexture(gpatch, (GLPatch_t *)md2->blendgrpatch, skinnum, spr->colormap, (skincolors_t)spr->mobj->color); HWR_GetBlendedTexture(gpatch, (GLPatch_t *)md2->blendgrpatch, skinnum, spr->colormap, (skincolornum_t)spr->mobj->color);
} }
else else
{ {

View File

@ -68,7 +68,7 @@ patch_t *nightsnum[10]; // 0-9
// Level title and credits fonts // Level title and credits fonts
patch_t *lt_font[LT_FONTSIZE]; patch_t *lt_font[LT_FONTSIZE];
patch_t *cred_font[CRED_FONTSIZE]; patch_t *cred_font[CRED_FONTSIZE];
patch_t *ttlnum[20]; // act numbers (0-19) patch_t *ttlnum[10]; // act numbers (0-9)
// Name tag fonts // Name tag fonts
patch_t *ntb_font[NT_FONTSIZE]; patch_t *ntb_font[NT_FONTSIZE];
@ -243,7 +243,7 @@ void HU_LoadGraphics(void)
tallinfin = (patch_t *)W_CachePatchName("STTINFIN", PU_HUDGFX); tallinfin = (patch_t *)W_CachePatchName("STTINFIN", PU_HUDGFX);
// cache act numbers for level titles // cache act numbers for level titles
for (i = 0; i < 20; i++) for (i = 0; i < 10; i++)
{ {
sprintf(buffer, "TTL%.2d", i); sprintf(buffer, "TTL%.2d", i);
ttlnum[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX); ttlnum[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);
@ -755,113 +755,40 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum)
} }
else else
{ {
const UINT8 color = players[playernum].skincolor; UINT16 chatcolor = skincolors[players[playernum].skincolor].chatcolor;
cstart = "\x83"; if (!chatcolor || chatcolor%0x1000 || chatcolor>V_INVERTMAP)
cstart = "\x80";
// Follow palette order at r_draw.c Color_Names else if (chatcolor == V_MAGENTAMAP)
switch (color) cstart = "\x81";
{ else if (chatcolor == V_YELLOWMAP)
default: cstart = "\x82";
case SKINCOLOR_WHITE: else if (chatcolor == V_GREENMAP)
case SKINCOLOR_BONE: cstart = "\x83";
case SKINCOLOR_CLOUDY: else if (chatcolor == V_BLUEMAP)
case SKINCOLOR_GREY: cstart = "\x84";
case SKINCOLOR_SILVER: else if (chatcolor == V_REDMAP)
case SKINCOLOR_AETHER: cstart = "\x85";
case SKINCOLOR_SLATE: else if (chatcolor == V_GRAYMAP)
cstart = "\x80"; // white cstart = "\x86";
break; else if (chatcolor == V_ORANGEMAP)
case SKINCOLOR_CARBON: cstart = "\x87";
case SKINCOLOR_JET: else if (chatcolor == V_SKYMAP)
case SKINCOLOR_BLACK: cstart = "\x88";
cstart = "\x86"; // V_GRAYMAP else if (chatcolor == V_PURPLEMAP)
break; cstart = "\x89";
case SKINCOLOR_PINK: else if (chatcolor == V_AQUAMAP)
case SKINCOLOR_RUBY: cstart = "\x8a";
case SKINCOLOR_SALMON: else if (chatcolor == V_PERIDOTMAP)
case SKINCOLOR_RED: cstart = "\x8b";
case SKINCOLOR_CRIMSON: else if (chatcolor == V_AZUREMAP)
case SKINCOLOR_FLAME: cstart = "\x8c";
case SKINCOLOR_KETCHUP: else if (chatcolor == V_BROWNMAP)
cstart = "\x85"; // V_REDMAP cstart = "\x8d";
break; else if (chatcolor == V_ROSYMAP)
case SKINCOLOR_YOGURT: cstart = "\x8e";
case SKINCOLOR_BROWN: else if (chatcolor == V_INVERTMAP)
case SKINCOLOR_BRONZE: cstart = "\x8f";
case SKINCOLOR_TAN:
case SKINCOLOR_BEIGE:
case SKINCOLOR_QUAIL:
cstart = "\x8d"; // V_BROWNMAP
break;
case SKINCOLOR_MOSS:
case SKINCOLOR_GREEN:
case SKINCOLOR_FOREST:
case SKINCOLOR_EMERALD:
case SKINCOLOR_MINT:
cstart = "\x83"; // V_GREENMAP
break;
case SKINCOLOR_AZURE:
cstart = "\x8c"; // V_AZUREMAP
break;
case SKINCOLOR_LAVENDER:
case SKINCOLOR_PASTEL:
case SKINCOLOR_PURPLE:
cstart = "\x89"; // V_PURPLEMAP
break;
case SKINCOLOR_PEACHY:
case SKINCOLOR_LILAC:
case SKINCOLOR_PLUM:
case SKINCOLOR_ROSY:
cstart = "\x8e"; // V_ROSYMAP
break;
case SKINCOLOR_SUNSET:
case SKINCOLOR_COPPER:
case SKINCOLOR_APRICOT:
case SKINCOLOR_ORANGE:
case SKINCOLOR_RUST:
cstart = "\x87"; // V_ORANGEMAP
break;
case SKINCOLOR_GOLD:
case SKINCOLOR_SANDY:
case SKINCOLOR_YELLOW:
case SKINCOLOR_OLIVE:
cstart = "\x82"; // V_YELLOWMAP
break;
case SKINCOLOR_LIME:
case SKINCOLOR_PERIDOT:
case SKINCOLOR_APPLE:
cstart = "\x8b"; // V_PERIDOTMAP
break;
case SKINCOLOR_SEAFOAM:
case SKINCOLOR_AQUA:
cstart = "\x8a"; // V_AQUAMAP
break;
case SKINCOLOR_TEAL:
case SKINCOLOR_WAVE:
case SKINCOLOR_CYAN:
case SKINCOLOR_SKY:
case SKINCOLOR_CERULEAN:
case SKINCOLOR_ICY:
case SKINCOLOR_SAPPHIRE:
case SKINCOLOR_VAPOR:
cstart = "\x88"; // V_SKYMAP
break;
case SKINCOLOR_CORNFLOWER:
case SKINCOLOR_BLUE:
case SKINCOLOR_COBALT:
case SKINCOLOR_DUSK:
case SKINCOLOR_BLUEBELL:
cstart = "\x84"; // V_BLUEMAP
break;
case SKINCOLOR_BUBBLEGUM:
case SKINCOLOR_MAGENTA:
case SKINCOLOR_NEON:
case SKINCOLOR_VIOLET:
case SKINCOLOR_RASPBERRY:
cstart = "\x81"; // V_MAGENTAMAP
break;
}
} }
prefix = cstart; prefix = cstart;

View File

@ -85,7 +85,7 @@ extern patch_t *lt_font[LT_FONTSIZE];
extern patch_t *cred_font[CRED_FONTSIZE]; extern patch_t *cred_font[CRED_FONTSIZE];
extern patch_t *ntb_font[NT_FONTSIZE]; extern patch_t *ntb_font[NT_FONTSIZE];
extern patch_t *nto_font[NT_FONTSIZE]; extern patch_t *nto_font[NT_FONTSIZE];
extern patch_t *ttlnum[20]; extern patch_t *ttlnum[10];
extern patch_t *emeraldpics[3][8]; extern patch_t *emeraldpics[3][8];
extern patch_t *rflagico; extern patch_t *rflagico;
extern patch_t *bflagico; extern patch_t *bflagico;

View File

@ -20,6 +20,7 @@
#include "m_misc.h" #include "m_misc.h"
#include "z_zone.h" #include "z_zone.h"
#include "d_player.h" #include "d_player.h"
#include "v_video.h" // V_*MAP constants
#include "lzf.h" #include "lzf.h"
#ifdef HWRENDER #ifdef HWRENDER
#include "hardware/hw_light.h" #include "hardware/hw_light.h"
@ -187,6 +188,8 @@ char sprnames[NUMSPRITES + 1][5] =
// Projectiles // Projectiles
"MISL", "MISL",
"LASR", // GFZ3 laser
"LASF", // GFZ3 laser flames
"TORP", // Torpedo "TORP", // Torpedo
"ENRG", // Energy ball "ENRG", // Energy ball
"MINE", // Skim mine "MINE", // Skim mine
@ -2058,7 +2061,15 @@ state_t states[NUMSTATES] =
{SPR_MISL, FF_FULLBRIGHT, 1, {A_SmokeTrailer}, MT_SMOKE, 0, S_ROCKET}, // S_ROCKET {SPR_MISL, FF_FULLBRIGHT, 1, {A_SmokeTrailer}, MT_SMOKE, 0, S_ROCKET}, // S_ROCKET
{SPR_MISL, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_NULL}, // S_LASER {SPR_LASR, FF_FULLBRIGHT|0, 2, {NULL}, 0, 0, S_NULL}, // S_LASER
{SPR_LASR, FF_FULLBRIGHT|1, 2, {NULL}, 0, 0, S_NULL}, // S_LASER2
{SPR_LASR, FF_FULLBRIGHT|2, 2, {NULL}, 0, 0, S_NULL}, // S_LASERFLASH
{SPR_LASF, FF_FULLBRIGHT|0, 2, {NULL}, 0, 0, S_LASERFLAME2}, // S_LASERFLAME1
{SPR_LASF, FF_FULLBRIGHT|1, 1, {A_ChangeHeight}, 156*FRACUNIT, 3, S_LASERFLAME3}, // S_LASERFLAME2
{SPR_LASF, FF_FULLBRIGHT|2, 0, {A_ChangeHeight}, 32*FRACUNIT, 3, S_LASERFLAME4}, // S_LASERFLAME3
{SPR_LASF, FF_ANIMATE|FF_PAPERSPRITE|FF_FULLBRIGHT|2, 4, {NULL}, 1, 2, S_LASERFLAME5}, // S_LASERFLAME4
{SPR_LASF, FF_ANIMATE|FF_PAPERSPRITE|FF_FULLBRIGHT|4, 28, {NULL}, 2, 2, S_NULL}, // S_LASERFLAME5
{SPR_TORP, 0, 1, {A_SmokeTrailer}, MT_SMOKE, 0, S_TORPEDO}, // S_TORPEDO {SPR_TORP, 0, 1, {A_SmokeTrailer}, MT_SMOKE, 0, S_TORPEDO}, // S_TORPEDO
@ -5665,28 +5676,28 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
{ // MT_EGGMOBILE_FIRE { // MT_EGGMOBILE_FIRE
-1, // doomednum -1, // doomednum
S_SPINFIRE1, // spawnstate S_LASERFLAME1, // spawnstate
1, // spawnhealth 1, // spawnhealth
S_NULL, // seestate S_NULL, // seestate
sfx_None, // seesound sfx_s3kc2s, // seesound
8, // reactiontime 8, // reactiontime
sfx_None, // attacksound sfx_None, // attacksound
S_NULL, // painstate S_NULL, // painstate
0, // painchance 0, // painchance
sfx_None, // painsound sfx_s3k8d, // painsound
S_NULL, // meleestate S_NULL, // meleestate
S_NULL, // missilestate S_NULL, // missilestate
S_NULL, // deathstate S_NULL, // deathstate
S_NULL, // xdeathstate S_NULL, // xdeathstate
sfx_None, // deathsound sfx_None, // deathsound
0, // speed 0, // speed
8*FRACUNIT, // radius 24*FRACUNIT, // radius
14*FRACUNIT, // height 84*FRACUNIT, // height
0, // display offset 0, // display offset
DMG_FIRE, // mass DMG_FIRE, // mass
1, // damage 1, // damage
sfx_None, // activesound sfx_None, // activesound
MF_NOBLOCKMAP|MF_MISSILE|MF_NOGRAVITY|MF_FIRE, // flags MF_NOGRAVITY|MF_FIRE|MF_PAIN, // flags
S_NULL // raisestate S_NULL // raisestate
}, },
@ -9637,8 +9648,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL, // painstate S_NULL, // painstate
0, // painchance 0, // painchance
sfx_None, // painsound sfx_None, // painsound
S_NULL, // meleestate S_LASERFLASH, // meleestate
S_NULL, // missilestate S_LASER2, // missilestate
S_NULL, // deathstate S_NULL, // deathstate
S_NULL, // xdeathstate S_NULL, // xdeathstate
sfx_None, // deathsound sfx_None, // deathsound
@ -9649,7 +9660,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
0, // mass 0, // mass
20, // damage 20, // damage
sfx_None, // activesound sfx_None, // activesound
MF_NOBLOCKMAP|MF_MISSILE|MF_NOGRAVITY, // flags MF_MISSILE|MF_NOGRAVITY, // flags
S_NULL // raisestate S_NULL // raisestate
}, },
@ -21606,8 +21617,140 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
#endif #endif
}; };
skincolor_t skincolors[MAXSKINCOLORS] = {
{"None", {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, SKINCOLOR_NONE, 0, 0, false}, // SKINCOLOR_NONE
/** Patches the mobjinfo table and state table. // Greyscale ranges
{"White", {0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x02, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x11}, SKINCOLOR_BLACK, 5, 0, true}, // SKINCOLOR_WHITE
{"Bone", {0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x05, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x11, 0x12}, SKINCOLOR_JET, 7, 0, true}, // SKINCOLOR_BONE
{"Cloudy", {0x02, 0x03, 0x04, 0x05, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14}, SKINCOLOR_CARBON, 7, 0, true}, // SKINCOLOR_CLOUDY
{"Grey", {0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18}, SKINCOLOR_AETHER, 12, 0, true}, // SKINCOLOR_GREY
{"Silver", {0x02, 0x03, 0x05, 0x07, 0x09, 0x0b, 0x0d, 0x0f, 0x11, 0x13, 0x15, 0x17, 0x19, 0x1b, 0x1d, 0x1f}, SKINCOLOR_SLATE, 12, 0, true}, // SKINCOLOR_SILVER
{"Carbon", {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x16, 0x17, 0x17, 0x19, 0x19, 0x1a, 0x1a, 0x1b, 0x1c, 0x1d}, SKINCOLOR_CLOUDY, 7, V_GRAYMAP, true}, // SKINCOLOR_CARBON
{"Jet", {0x00, 0x05, 0x0a, 0x0f, 0x14, 0x19, 0x1a, 0x1b, 0x1c, 0x1e, 0x1e, 0x1e, 0x1f, 0x1f, 0x1f, 0x1f}, SKINCOLOR_BONE, 7, V_GRAYMAP, true}, // SKINCOLOR_JET
{"Black", {0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1b, 0x1b, 0x1c, 0x1d, 0x1d, 0x1e, 0x1e, 0x1f, 0x1f}, SKINCOLOR_WHITE, 7, V_GRAYMAP, true}, // SKINCOLOR_BLACK
// Desaturated
{"Aether", {0x00, 0x00, 0x01, 0x02, 0x02, 0x03, 0x91, 0x91, 0x91, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xaf}, SKINCOLOR_GREY, 15, 0, true}, // SKINCOLOR_AETHER
{"Slate", {0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0xaa, 0xaa, 0xaa, 0xab, 0xac, 0xac, 0xad, 0xad, 0xae, 0xaf}, SKINCOLOR_SILVER, 12, 0, true}, // SKINCOLOR_SLATE
{"Bluebell", {0x90, 0x91, 0x92, 0x93, 0x94, 0x94, 0x95, 0xac, 0xac, 0xad, 0xad, 0xa8, 0xa8, 0xa9, 0xfd, 0xfe}, SKINCOLOR_COPPER, 4, V_BLUEMAP, true}, // SKINCOLOR_BLUEBELL
{"Pink", {0xd0, 0xd0, 0xd1, 0xd1, 0xd2, 0xd2, 0xd3, 0xd3, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0x2b, 0x2c, 0x2e}, SKINCOLOR_AZURE, 9, V_REDMAP, true}, // SKINCOLOR_PINK
{"Yogurt", {0xd0, 0x30, 0xd8, 0xd9, 0xda, 0xdb, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe3, 0xe6, 0xe8, 0xe9}, SKINCOLOR_RUST, 7, V_BROWNMAP, true}, // SKINCOLOR_YOGURT
{"Brown", {0xdf, 0xe0, 0xe1, 0xe2, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef}, SKINCOLOR_TAN, 2, V_BROWNMAP, true}, // SKINCOLOR_BROWN
{"Bronze", {0xde, 0xe0, 0xe1, 0xe4, 0xe7, 0xe9, 0xeb, 0xec, 0xed, 0xed, 0xed, 0x19, 0x19, 0x1b, 0x1d, 0x1e}, SKINCOLOR_KETCHUP, 0, V_BROWNMAP, true}, // SKINCOLOR_BRONZE
{"Tan", {0x51, 0x51, 0x54, 0x54, 0x55, 0x55, 0x56, 0x56, 0x56, 0x57, 0xf5, 0xf5, 0xf9, 0xf9, 0xed, 0xed}, SKINCOLOR_BROWN, 12, V_BROWNMAP, true}, // SKINCOLOR_TAN
{"Beige", {0x54, 0x55, 0x56, 0x56, 0xf2, 0xf3, 0xf3, 0xf4, 0xf5, 0xf6, 0xf8, 0xf9, 0xfa, 0xfb, 0xed, 0xed}, SKINCOLOR_MOSS, 5, V_BROWNMAP, true}, // SKINCOLOR_BEIGE
{"Moss", {0x58, 0x58, 0x59, 0x59, 0x5a, 0x5a, 0x5b, 0x5b, 0x5b, 0x5c, 0x5d, 0x5d, 0x5e, 0x5e, 0x5f, 0x5f}, SKINCOLOR_BEIGE, 13, V_GREENMAP, true}, // SKINCOLOR_MOSS
{"Azure", {0x90, 0x90, 0x91, 0x91, 0xaa, 0xaa, 0xab, 0xab, 0xab, 0xac, 0xad, 0xad, 0xae, 0xae, 0xaf, 0xaf}, SKINCOLOR_PINK, 5, V_AZUREMAP, true}, // SKINCOLOR_AZURE
{"Lavender", {0xc0, 0xc0, 0xc1, 0xc1, 0xc2, 0xc2, 0xc3, 0xc3, 0xc3, 0xc4, 0xc5, 0xc5, 0xc6, 0xc6, 0xc7, 0xc7}, SKINCOLOR_GOLD, 4, V_PURPLEMAP, true}, // SKINCOLOR_LAVENDER
// Viv's vivid colours (toast 21/07/17)
{"Ruby", {0xb0, 0xb0, 0xc9, 0xca, 0xcc, 0x26, 0x27, 0x28, 0x29, 0x2a, 0xb9, 0xb9, 0xba, 0xba, 0xbb, 0xfd}, SKINCOLOR_EMERALD, 10, V_REDMAP, true}, // SKINCOLOR_RUBY
{"Salmon", {0xd0, 0xd0, 0xd1, 0xd2, 0x20, 0x21, 0x24, 0x25, 0x26, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e}, SKINCOLOR_FOREST, 6, V_REDMAP, true}, // SKINCOLOR_SALMON
{"Red", {0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x47, 0x2e, 0x2f}, SKINCOLOR_GREEN, 10, V_REDMAP, true}, // SKINCOLOR_RED
{"Crimson", {0x27, 0x27, 0x28, 0x28, 0x29, 0x2a, 0x2b, 0x2b, 0x2c, 0x2d, 0x2e, 0x2e, 0x2e, 0x2f, 0x2f, 0x1f}, SKINCOLOR_ICY, 10, V_REDMAP, true}, // SKINCOLOR_CRIMSON
{"Flame", {0x31, 0x32, 0x33, 0x36, 0x22, 0x22, 0x25, 0x25, 0x25, 0xcd, 0xcf, 0xcf, 0xc5, 0xc5, 0xc7, 0xc7}, SKINCOLOR_PURPLE, 8, V_REDMAP, true}, // SKINCOLOR_FLAME
{"Ketchup", {0x48, 0x49, 0x40, 0x33, 0x34, 0x36, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2b, 0x2c, 0x47, 0x2e, 0x2f}, SKINCOLOR_BRONZE, 8, V_REDMAP, true}, // SKINCOLOR_KETCHUP
{"Peachy", {0xd0, 0x30, 0x31, 0x31, 0x32, 0x32, 0xdc, 0xdc, 0xdc, 0xd3, 0xd4, 0xd4, 0xcc, 0xcd, 0xce, 0xcf}, SKINCOLOR_TEAL, 7, V_ROSYMAP, true}, // SKINCOLOR_PEACHY
{"Quail", {0xd8, 0xd9, 0xdb, 0xdc, 0xde, 0xdf, 0xd5, 0xd5, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0x1d, 0x1f}, SKINCOLOR_WAVE, 5, V_BROWNMAP, true}, // SKINCOLOR_QUAIL
{"Sunset", {0x51, 0x52, 0x40, 0x40, 0x34, 0x36, 0xd5, 0xd5, 0xd6, 0xd7, 0xcf, 0xcf, 0xc6, 0xc6, 0xc7, 0xfe}, SKINCOLOR_SAPPHIRE, 5, V_ORANGEMAP, true}, // SKINCOLOR_SUNSET
{"Copper", {0x58, 0x54, 0x40, 0x34, 0x35, 0x38, 0x3a, 0x3c, 0x3d, 0x2a, 0x2b, 0x2c, 0x2c, 0xba, 0xba, 0xbb}, SKINCOLOR_BLUEBELL, 5, V_ORANGEMAP, true}, // SKINCOLOR_COPPER
{"Apricot", {0x00, 0xd8, 0xd9, 0xda, 0xdb, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e}, SKINCOLOR_CYAN, 4, V_ORANGEMAP, true}, // SKINCOLOR_APRICOT
{"Orange", {0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x2c}, SKINCOLOR_BLUE, 4, V_ORANGEMAP, true}, // SKINCOLOR_ORANGE
{"Rust", {0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3c, 0x3d, 0x3d, 0x3d, 0x3f, 0x2c, 0x2d, 0x47, 0x2e, 0x2f, 0x2f}, SKINCOLOR_YOGURT, 8, V_ORANGEMAP, true}, // SKINCOLOR_RUST
{"Gold", {0x51, 0x51, 0x54, 0x54, 0x41, 0x42, 0x43, 0x43, 0x44, 0x45, 0x46, 0x3f, 0x2d, 0x2e, 0x2f, 0x2f}, SKINCOLOR_LAVENDER, 10, V_YELLOWMAP, true}, // SKINCOLOR_GOLD
{"Sandy", {0x53, 0x40, 0x41, 0x42, 0x43, 0xe6, 0xe9, 0xe9, 0xea, 0xec, 0xec, 0xc6, 0xc6, 0xc7, 0xc7, 0xfe}, SKINCOLOR_SKY, 8, V_YELLOWMAP, true}, // SKINCOLOR_SANDY
{"Yellow", {0x52, 0x53, 0x49, 0x49, 0x4a, 0x4a, 0x4b, 0x4b, 0x4b, 0x4c, 0x4d, 0x4d, 0x4e, 0x4e, 0x4f, 0xed}, SKINCOLOR_CORNFLOWER, 8, V_YELLOWMAP, true}, // SKINCOLOR_YELLOW
{"Olive", {0x4b, 0x4b, 0x4c, 0x4c, 0x4d, 0x4e, 0xe7, 0xe7, 0xe9, 0xc5, 0xc5, 0xc6, 0xc6, 0xc7, 0xc7, 0xfd}, SKINCOLOR_DUSK, 3, V_YELLOWMAP, true}, // SKINCOLOR_OLIVE
{"Lime", {0x50, 0x51, 0x52, 0x53, 0x48, 0xbc, 0xbd, 0xbe, 0xbe, 0xbf, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f}, SKINCOLOR_MAGENTA, 9, V_PERIDOTMAP, true}, // SKINCOLOR_LIME
{"Peridot", {0x58, 0x58, 0xbc, 0xbc, 0xbd, 0xbd, 0xbe, 0xbe, 0xbe, 0xbf, 0x5e, 0x5e, 0x5f, 0x5f, 0x77, 0x77}, SKINCOLOR_COBALT, 2, V_PERIDOTMAP, true}, // SKINCOLOR_PERIDOT
{"Apple", {0x49, 0x49, 0xbc, 0xbd, 0xbe, 0xbe, 0xbe, 0x67, 0x69, 0x6a, 0x6b, 0x6b, 0x6c, 0x6d, 0x6d, 0x6d}, SKINCOLOR_RASPBERRY, 13, V_PERIDOTMAP, true}, // SKINCOLOR_APPLE
{"Green", {0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f}, SKINCOLOR_RED, 6, V_GREENMAP, true}, // SKINCOLOR_GREEN
{"Forest", {0x65, 0x66, 0x67, 0x68, 0x69, 0x69, 0x6a, 0x6b, 0x6b, 0x6c, 0x6d, 0x6d, 0x6e, 0x6e, 0x6e, 0x6f}, SKINCOLOR_SALMON, 9, V_GREENMAP, true}, // SKINCOLOR_FOREST
{"Emerald", {0x70, 0x70, 0x71, 0x71, 0x72, 0x72, 0x73, 0x73, 0x73, 0x74, 0x75, 0x75, 0x76, 0x76, 0x77, 0x77}, SKINCOLOR_RUBY, 4, V_GREENMAP, true}, // SKINCOLOR_EMERALD
{"Mint", {0x00, 0x00, 0x58, 0x58, 0x59, 0x62, 0x62, 0x62, 0x64, 0x67, 0x7e, 0x7e, 0x8f, 0x8f, 0x8a, 0x8a}, SKINCOLOR_VIOLET, 5, V_GREENMAP, true}, // SKINCOLOR_MINT
{"Seafoam", {0x01, 0x58, 0x59, 0x5a, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x8f, 0x8f, 0x8a, 0x8a, 0x8a, 0xfd, 0xfd}, SKINCOLOR_PLUM, 6, V_AQUAMAP, true}, // SKINCOLOR_SEAFOAM
{"Aqua", {0x78, 0x79, 0x7a, 0x7a, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c, 0x7d, 0x7e, 0x7e, 0x7f, 0x7f, 0x76, 0x77}, SKINCOLOR_ROSY, 7, V_AQUAMAP, true}, // SKINCOLOR_AQUA
{"Teal", {0x78, 0x78, 0x8c, 0x8c, 0x8d, 0x8d, 0x8d, 0x8e, 0x8e, 0x8f, 0x8f, 0x8f, 0x8a, 0x8a, 0x8a, 0x8a}, SKINCOLOR_PEACHY, 7, V_SKYMAP, true}, // SKINCOLOR_TEAL
{"Wave", {0x00, 0x78, 0x78, 0x79, 0x8d, 0x87, 0x88, 0x89, 0x89, 0xae, 0xa8, 0xa8, 0xa9, 0xa9, 0xfd, 0xfd}, SKINCOLOR_QUAIL, 5, V_SKYMAP, true}, // SKINCOLOR_WAVE
{"Cyan", {0x80, 0x81, 0xff, 0xff, 0x83, 0x83, 0x8d, 0x8d, 0x8d, 0x8e, 0x7e, 0x7f, 0x76, 0x76, 0x77, 0x6e}, SKINCOLOR_APRICOT, 6, V_SKYMAP, true}, // SKINCOLOR_CYAN
{"Sky", {0x80, 0x80, 0x81, 0x82, 0x83, 0x83, 0x84, 0x85, 0x85, 0x86, 0x87, 0x88, 0x89, 0x89, 0x8a, 0x8b}, SKINCOLOR_SANDY, 1, V_SKYMAP, true}, // SKINCOLOR_SKY
{"Cerulean", {0x85, 0x86, 0x87, 0x88, 0x88, 0x89, 0x89, 0x89, 0x8a, 0x8a, 0xfd, 0xfd, 0xfd, 0x1f, 0x1f, 0x1f}, SKINCOLOR_NEON, 4, V_SKYMAP, true}, // SKINCOLOR_CERULEAN
{"Icy", {0x00, 0x00, 0x00, 0x00, 0x80, 0x81, 0x83, 0x83, 0x86, 0x87, 0x95, 0x95, 0xad, 0xad, 0xae, 0xaf}, SKINCOLOR_CRIMSON, 0, V_SKYMAP, true}, // SKINCOLOR_ICY
{"Sapphire", {0x80, 0x83, 0x86, 0x87, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xfd, 0xfe}, SKINCOLOR_SUNSET, 5, V_SKYMAP, true}, // SKINCOLOR_SAPPHIRE
{"Cornflower", {0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x9a, 0x9c, 0x9d, 0x9d, 0x9e, 0x9e, 0x9e}, SKINCOLOR_YELLOW, 4, V_BLUEMAP, true}, // SKINCOLOR_CORNFLOWER
{"Blue", {0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xfd, 0xfe}, SKINCOLOR_ORANGE, 5, V_BLUEMAP, true}, // SKINCOLOR_BLUE
{"Cobalt", {0x93, 0x94, 0x95, 0x96, 0x98, 0x9a, 0x9b, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xfd, 0xfd, 0xfe, 0xfe}, SKINCOLOR_PERIDOT, 5, V_BLUEMAP, true}, // SKINCOLOR_COBALT
{"Vapor", {0x80, 0x81, 0x83, 0x86, 0x94, 0x94, 0xa3, 0xa3, 0xa4, 0xa6, 0xa6, 0xa6, 0xa8, 0xa8, 0xa9, 0xa9}, SKINCOLOR_LILAC, 4, V_SKYMAP, true}, // SKINCOLOR_VAPOR
{"Dusk", {0x92, 0x93, 0x94, 0x94, 0xac, 0xad, 0xad, 0xad, 0xae, 0xae, 0xaf, 0xaf, 0xa9, 0xa9, 0xfd, 0xfd}, SKINCOLOR_OLIVE, 0, V_BLUEMAP, true}, // SKINCOLOR_DUSK
{"Pastel", {0x90, 0x90, 0xa0, 0xa0, 0xa1, 0xa1, 0xa2, 0xa2, 0xa2, 0xa3, 0xa4, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8}, SKINCOLOR_BUBBLEGUM, 9, V_PURPLEMAP, true}, // SKINCOLOR_PASTEL
{"Purple", {0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa4, 0xa5, 0xa5, 0xa5, 0xa6, 0xa7, 0xa7, 0xa8, 0xa8, 0xa9, 0xa9}, SKINCOLOR_FLAME, 7, V_PURPLEMAP, true}, // SKINCOLOR_PURPLE
{"Bubblegum", {0x00, 0xd0, 0xd0, 0xc8, 0xc8, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8}, SKINCOLOR_PASTEL, 8, V_MAGENTAMAP, true}, // SKINCOLOR_BUBBLEGUM
{"Magenta", {0xb3, 0xb3, 0xb4, 0xb5, 0xb6, 0xb6, 0xb7, 0xb7, 0xb7, 0xb8, 0xb9, 0xb9, 0xba, 0xba, 0xbb, 0xbb}, SKINCOLOR_LIME, 6, V_MAGENTAMAP, true}, // SKINCOLOR_MAGENTA
{"Neon", {0xb3, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xb9, 0xba, 0xba, 0xbb, 0xbb, 0xc7, 0xc7, 0x1d, 0x1d, 0x1e}, SKINCOLOR_CERULEAN, 2, V_MAGENTAMAP, true}, // SKINCOLOR_NEON
{"Violet", {0xd0, 0xd1, 0xd2, 0xca, 0xcc, 0xb8, 0xb9, 0xb9, 0xba, 0xa8, 0xa8, 0xa9, 0xa9, 0xfd, 0xfe, 0xfe}, SKINCOLOR_MINT, 6, V_MAGENTAMAP, true}, // SKINCOLOR_VIOLET
{"Lilac", {0x00, 0xd0, 0xd1, 0xd2, 0xd3, 0xc1, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc5, 0xc6, 0xc6, 0xfe, 0x1f}, SKINCOLOR_VAPOR, 4, V_ROSYMAP, true}, // SKINCOLOR_LILAC
{"Plum", {0xc8, 0xd3, 0xd5, 0xd6, 0xd7, 0xce, 0xcf, 0xb9, 0xb9, 0xba, 0xba, 0xa9, 0xa9, 0xa9, 0xfd, 0xfe}, SKINCOLOR_MINT, 7, V_ROSYMAP, true}, // SKINCOLOR_PLUM
{"Raspberry", {0xc8, 0xc9, 0xca, 0xcb, 0xcb, 0xcc, 0xcd, 0xcd, 0xce, 0xb9, 0xb9, 0xba, 0xba, 0xbb, 0xfe, 0xfe}, SKINCOLOR_APPLE, 15, V_MAGENTAMAP, true}, // SKINCOLOR_RASPBERRY
{"Rosy", {0xfc, 0xc8, 0xc8, 0xc9, 0xc9, 0xca, 0xca, 0xcb, 0xcb, 0xcc, 0xcc, 0xcd, 0xcd, 0xce, 0xce, 0xcf}, SKINCOLOR_AQUA, 1, V_ROSYMAP, true}, // SKINCOLOR_ROSY
// super
{"Super Silver 1", {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x03}, SKINCOLOR_BLACK, 15, 0, false}, // SKINCOLOR_SUPERSILVER1
{"Super Silver 2", {0x00, 0x01, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x07}, SKINCOLOR_BLACK, 6, 0, false}, // SKINCOLOR_SUPERSILVER2
{"Super Silver 3", {0x01, 0x02, 0x02, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x07, 0x09, 0x0b}, SKINCOLOR_BLACK, 5, 0, false}, // SKINCOLOR_SUPERSILVER3
{"Super Silver 4", {0x02, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x07, 0x09, 0x0b, 0x0d, 0x0f, 0x11}, SKINCOLOR_BLACK, 5, V_GRAYMAP, false}, // SKINCOLOR_SUPERSILVER4
{"Super Silver 5", {0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x07, 0x09, 0x0b, 0x0d, 0x0f, 0x11, 0x13}, SKINCOLOR_BLACK, 5, V_GRAYMAP, false}, // SKINCOLOR_SUPERSILVER5
{"Super Red 1", {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0xd0, 0xd1, 0xd1, 0xd2, 0xd2}, SKINCOLOR_CYAN, 15, 0, false}, // SKINCOLOR_SUPERRED1
{"Super Red 2", {0x00, 0x00, 0x00, 0xd0, 0xd0, 0xd0, 0xd1, 0xd1, 0xd1, 0xd2, 0xd2, 0xd2, 0x20, 0x20, 0x21, 0x21}, SKINCOLOR_CYAN, 14, V_ROSYMAP, false}, // SKINCOLOR_SUPERRED2
{"Super Red 3", {0x00, 0x00, 0xd0, 0xd0, 0xd1, 0xd1, 0xd2, 0xd2, 0x20, 0x20, 0x21, 0x21, 0x22, 0x22, 0x23, 0x23}, SKINCOLOR_CYAN, 13, V_REDMAP, false}, // SKINCOLOR_SUPERRED3
{"Super Red 4", {0x00, 0xd0, 0xd1, 0xd1, 0xd2, 0xd2, 0x20, 0x20, 0x21, 0x21, 0x22, 0x22, 0x23, 0x23, 0x24, 0x24}, SKINCOLOR_CYAN, 11, V_REDMAP, false}, // SKINCOLOR_SUPERRED4
{"Super Red 5", {0xd0, 0xd1, 0xd2, 0xd2, 0x20, 0x20, 0x21, 0x21, 0x22, 0x22, 0x23, 0x23, 0x24, 0x24, 0x25, 0x25}, SKINCOLOR_CYAN, 10, V_REDMAP, false}, // SKINCOLOR_SUPERRED5
{"Super Orange 1", {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x30, 0x31, 0x32, 0x33, 0x34}, SKINCOLOR_SAPPHIRE, 15, 0, false}, // SKINCOLOR_SUPERORANGE1
{"Super Orange 2", {0x00, 0x00, 0x00, 0x00, 0xd0, 0xd0, 0x30, 0x30, 0x31, 0x31, 0x32, 0x32, 0x33, 0x33, 0x34, 0x34}, SKINCOLOR_SAPPHIRE, 12, V_ORANGEMAP, false}, // SKINCOLOR_SUPERORANGE2
{"Super Orange 3", {0x00, 0x00, 0xd0, 0xd0, 0x30, 0x30, 0x31, 0x31, 0x32, 0x32, 0x33, 0x33, 0x34, 0x34, 0x35, 0x35}, SKINCOLOR_SAPPHIRE, 9, V_ORANGEMAP, false}, // SKINCOLOR_SUPERORANGE3
{"Super Orange 4", {0x00, 0xd0, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x44, 0x45, 0x46}, SKINCOLOR_SAPPHIRE, 4, V_ORANGEMAP, false}, // SKINCOLOR_SUPERORANGE4
{"Super Orange 5", {0xd0, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x44, 0x45, 0x46, 0x47}, SKINCOLOR_SAPPHIRE, 3, V_ORANGEMAP, false}, // SKINCOLOR_SUPERORANGE5
{"Super Gold 1", {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50, 0x51, 0x52, 0x53, 0x48}, SKINCOLOR_CORNFLOWER, 15, 0, false}, // SKINCOLOR_SUPERGOLD1
{"Super Gold 2", {0x00, 0x50, 0x51, 0x52, 0x53, 0x53, 0x48, 0x48, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x40, 0x41}, SKINCOLOR_CORNFLOWER, 9, V_YELLOWMAP, false}, // SKINCOLOR_SUPERGOLD2
{"Super Gold 3", {0x51, 0x52, 0x53, 0x53, 0x48, 0x48, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x40, 0x41, 0x42, 0x43}, SKINCOLOR_CORNFLOWER, 8, V_YELLOWMAP, false}, // SKINCOLOR_SUPERGOLD3
{"Super Gold 4", {0x53, 0x48, 0x48, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46}, SKINCOLOR_CORNFLOWER, 8, V_YELLOWMAP, false}, // SKINCOLOR_SUPERGOLD4
{"Super Gold 5", {0x48, 0x48, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47}, SKINCOLOR_CORNFLOWER, 8, V_YELLOWMAP, false}, // SKINCOLOR_SUPERGOLD5
{"Super Peridot 1", {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x58, 0x58, 0xbc, 0xbc, 0xbc}, SKINCOLOR_COBALT, 15, 0, false}, // SKINCOLOR_SUPERPERIDOT1
{"Super Peridot 2", {0x00, 0x58, 0x58, 0x58, 0xbc, 0xbc, 0xbc, 0xbc, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbe, 0xbe}, SKINCOLOR_COBALT, 4, V_PERIDOTMAP, false}, // SKINCOLOR_SUPERPERIDOT2
{"Super Peridot 3", {0x58, 0x58, 0xbc, 0xbc, 0xbc, 0xbc, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbe, 0xbe, 0xbf, 0xbf}, SKINCOLOR_COBALT, 3, V_PERIDOTMAP, false}, // SKINCOLOR_SUPERPERIDOT3
{"Super Peridot 4", {0x58, 0xbc, 0xbc, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbe, 0xbe, 0xbf, 0xbf, 0x5e, 0x5e, 0x5f}, SKINCOLOR_COBALT, 3, V_PERIDOTMAP, false}, // SKINCOLOR_SUPERPERIDOT4
{"Super Peridot 5", {0xbc, 0xbc, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbe, 0xbe, 0xbf, 0xbf, 0x5e, 0x5e, 0x5f, 0x77}, SKINCOLOR_COBALT, 3, V_PERIDOTMAP, false}, // SKINCOLOR_SUPERPERIDOT5
{"Super Sky 1", {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x81, 0x82, 0x83, 0x84}, SKINCOLOR_RUST, 15, 0, false}, // SKINCOLOR_SUPERSKY1
{"Super Sky 2", {0x00, 0x80, 0x81, 0x82, 0x83, 0x83, 0x84, 0x84, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x86, 0x86}, SKINCOLOR_RUST, 4, V_SKYMAP, false}, // SKINCOLOR_SUPERSKY2
{"Super Sky 3", {0x81, 0x82, 0x83, 0x83, 0x84, 0x84, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x86, 0x86, 0x87, 0x87}, SKINCOLOR_RUST, 3, V_SKYMAP, false}, // SKINCOLOR_SUPERSKY3
{"Super Sky 4", {0x83, 0x84, 0x84, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x86, 0x86, 0x87, 0x87, 0x88, 0x89, 0x8a}, SKINCOLOR_RUST, 3, V_SKYMAP, false}, // SKINCOLOR_SUPERSKY4
{"Super Sky 5", {0x84, 0x84, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x86, 0x86, 0x87, 0x87, 0x88, 0x89, 0x8a, 0x8b}, SKINCOLOR_RUST, 3, V_SKYMAP, false}, // SKINCOLOR_SUPERSKY5
{"Super Purple 1", {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90, 0xa0, 0xa0, 0xa1, 0xa2}, SKINCOLOR_EMERALD, 15, 0, false}, // SKINCOLOR_SUPERPURPLE1
{"Super Purple 2", {0x00, 0x90, 0xa0, 0xa0, 0xa1, 0xa1, 0xa2, 0xa2, 0xa3, 0xa3, 0xa3, 0xa3, 0xa4, 0xa4, 0xa5, 0xa5}, SKINCOLOR_EMERALD, 4, V_PURPLEMAP, false}, // SKINCOLOR_SUPERPURPLE2
{"Super Purple 3", {0xa0, 0xa0, 0xa1, 0xa1, 0xa2, 0xa2, 0xa3, 0xa3, 0xa3, 0xa3, 0xa4, 0xa4, 0xa5, 0xa5, 0xa6, 0xa6}, SKINCOLOR_EMERALD, 0, V_PURPLEMAP, false}, // SKINCOLOR_SUPERPURPLE3
{"Super Purple 4", {0xa1, 0xa2, 0xa2, 0xa3, 0xa3, 0xa3, 0xa3, 0xa4, 0xa4, 0xa5, 0xa5, 0xa6, 0xa6, 0xa7, 0xa8, 0xa9}, SKINCOLOR_EMERALD, 0, V_PURPLEMAP, false}, // SKINCOLOR_SUPERPURPLE4
{"Super Purple 5", {0xa2, 0xa2, 0xa3, 0xa3, 0xa3, 0xa3, 0xa4, 0xa4, 0xa5, 0xa5, 0xa6, 0xa6, 0xa7, 0xa8, 0xa9, 0xfd}, SKINCOLOR_EMERALD, 0, V_PURPLEMAP, false}, // SKINCOLOR_SUPERPURPLE5
{"Super Rust 1", {0x00, 0xd0, 0xd0, 0xd0, 0x30, 0x30, 0x31, 0x32, 0x33, 0x37, 0x3a, 0x44, 0x45, 0x46, 0x47, 0x2e}, SKINCOLOR_CYAN, 14, V_ORANGEMAP, false}, // SKINCOLOR_SUPERRUST1
{"Super Rust 2", {0x30, 0x31, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x38, 0x3a, 0x44, 0x45, 0x46, 0x47, 0x47, 0x2e}, SKINCOLOR_CYAN, 10, V_ORANGEMAP, false}, // SKINCOLOR_SUPERRUST2
{"Super Rust 3", {0x31, 0x32, 0x33, 0x34, 0x36, 0x37, 0x38, 0x3a, 0x44, 0x45, 0x45, 0x46, 0x46, 0x47, 0x2e, 0x2e}, SKINCOLOR_CYAN, 9, V_ORANGEMAP, false}, // SKINCOLOR_SUPERRUST3
{"Super Rust 4", {0x48, 0x40, 0x41, 0x42, 0x43, 0x44, 0x44, 0x45, 0x45, 0x46, 0x46, 0x47, 0x47, 0x2e, 0x2e, 0x2e}, SKINCOLOR_CYAN, 8, V_ORANGEMAP, false}, // SKINCOLOR_SUPERRUST4
{"Super Rust 5", {0x41, 0x42, 0x43, 0x43, 0x44, 0x44, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xed, 0xee, 0xee, 0xef, 0xef}, SKINCOLOR_CYAN, 8, V_ORANGEMAP, false}, // SKINCOLOR_SUPERRUST5
{"Super Tan 1", {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50, 0x51, 0x51, 0x52, 0x52}, SKINCOLOR_BROWN, 14, 0, false}, // SKINCOLOR_SUPERTAN1
{"Super Tan 2", {0x00, 0x50, 0x50, 0x51, 0x51, 0x52, 0x52, 0x52, 0x54, 0x54, 0x54, 0x54, 0x55, 0x56, 0x57, 0xf5}, SKINCOLOR_BROWN, 13, V_BROWNMAP, false}, // SKINCOLOR_SUPERTAN2
{"Super Tan 3", {0x50, 0x51, 0x51, 0x52, 0x52, 0x52, 0x54, 0x54, 0x54, 0x54, 0x55, 0x56, 0x57, 0xf5, 0xf7, 0xf9}, SKINCOLOR_BROWN, 12, V_BROWNMAP, false}, // SKINCOLOR_SUPERTAN3
{"Super Tan 4", {0x51, 0x52, 0x52, 0x52, 0x52, 0x54, 0x54, 0x54, 0x55, 0x56, 0x57, 0xf5, 0xf7, 0xf9, 0xfb, 0xed}, SKINCOLOR_BROWN, 11, V_BROWNMAP, false}, // SKINCOLOR_SUPERTAN4
{"Super Tan 5", {0x52, 0x52, 0x54, 0x54, 0x54, 0x55, 0x56, 0x57, 0xf5, 0xf7, 0xf9, 0xfb, 0xed, 0xee, 0xef, 0xef}, SKINCOLOR_BROWN, 10, V_BROWNMAP, false} // SKINCOLOR_SUPERTAN5
};
/** Patches the mobjinfo, state, and skincolor tables.
* Free slots are emptied out and set to initial values. * Free slots are emptied out and set to initial values.
*/ */
void P_PatchInfoTables(void) void P_PatchInfoTables(void)
@ -21635,6 +21778,11 @@ void P_PatchInfoTables(void)
sprnames[i][0] = '\0'; // i == NUMSPRITES sprnames[i][0] = '\0'; // i == NUMSPRITES
memset(&states[S_FIRSTFREESLOT], 0, sizeof (state_t) * NUMSTATEFREESLOTS); memset(&states[S_FIRSTFREESLOT], 0, sizeof (state_t) * NUMSTATEFREESLOTS);
memset(&mobjinfo[MT_FIRSTFREESLOT], 0, sizeof (mobjinfo_t) * NUMMOBJFREESLOTS); memset(&mobjinfo[MT_FIRSTFREESLOT], 0, sizeof (mobjinfo_t) * NUMMOBJFREESLOTS);
memset(&skincolors[SKINCOLOR_FIRSTFREESLOT], 0, sizeof (skincolor_t) * NUMCOLORFREESLOTS);
for (i = SKINCOLOR_FIRSTFREESLOT; i <= SKINCOLOR_LASTFREESLOT; i++) {
skincolors[i].accessible = false;
skincolors[i].name[0] = '\0';
}
for (i = MT_FIRSTFREESLOT; i <= MT_LASTFREESLOT; i++) for (i = MT_FIRSTFREESLOT; i <= MT_LASTFREESLOT; i++)
mobjinfo[i].doomednum = -1; mobjinfo[i].doomednum = -1;
} }
@ -21643,7 +21791,8 @@ void P_PatchInfoTables(void)
static char *sprnamesbackup; static char *sprnamesbackup;
static state_t *statesbackup; static state_t *statesbackup;
static mobjinfo_t *mobjinfobackup; static mobjinfo_t *mobjinfobackup;
static size_t sprnamesbackupsize, statesbackupsize, mobjinfobackupsize; static skincolor_t *skincolorsbackup;
static size_t sprnamesbackupsize, statesbackupsize, mobjinfobackupsize, skincolorsbackupsize;
#endif #endif
void P_BackupTables(void) void P_BackupTables(void)
@ -21653,6 +21802,7 @@ void P_BackupTables(void)
sprnamesbackup = Z_Malloc(sizeof(sprnames), PU_STATIC, NULL); sprnamesbackup = Z_Malloc(sizeof(sprnames), PU_STATIC, NULL);
statesbackup = Z_Malloc(sizeof(states), PU_STATIC, NULL); statesbackup = Z_Malloc(sizeof(states), PU_STATIC, NULL);
mobjinfobackup = Z_Malloc(sizeof(mobjinfo), PU_STATIC, NULL); mobjinfobackup = Z_Malloc(sizeof(mobjinfo), PU_STATIC, NULL);
skincolorsbackup = Z_Malloc(sizeof(skincolors), PU_STATIC, NULL);
// Sprite names // Sprite names
sprnamesbackupsize = lzf_compress(sprnames, sizeof(sprnames), sprnamesbackup, sizeof(sprnames)); sprnamesbackupsize = lzf_compress(sprnames, sizeof(sprnames), sprnamesbackup, sizeof(sprnames));
@ -21674,6 +21824,13 @@ void P_BackupTables(void)
mobjinfobackup = Z_Realloc(mobjinfobackup, mobjinfobackupsize, PU_STATIC, NULL); mobjinfobackup = Z_Realloc(mobjinfobackup, mobjinfobackupsize, PU_STATIC, NULL);
else else
M_Memcpy(mobjinfobackup, mobjinfo, sizeof(mobjinfo)); M_Memcpy(mobjinfobackup, mobjinfo, sizeof(mobjinfo));
//Skincolor info
skincolorsbackupsize = lzf_compress(skincolors, sizeof(skincolors), skincolorsbackup, sizeof(skincolors));
if (skincolorsbackupsize > 0)
skincolorsbackup = Z_Realloc(skincolorsbackup, skincolorsbackupsize, PU_STATIC, NULL);
else
M_Memcpy(skincolorsbackup, skincolors, sizeof(skincolors));
#endif #endif
} }
@ -21706,5 +21863,13 @@ void P_ResetData(INT32 flags)
else else
M_Memcpy(mobjinfo, mobjinfobackup, sizeof(mobjinfobackup)); M_Memcpy(mobjinfo, mobjinfobackup, sizeof(mobjinfobackup));
} }
if (flags & 8)
{
if (skincolorsbackupsize > 0)
lzf_decompress(skincolorsbackup, skincolorsbackupsize, skincolors, sizeof(skincolors));
else
M_Memcpy(skincolors, skincolorsbackup, sizeof(skincolorsbackup));
}
#endif #endif
} }

View File

@ -284,6 +284,7 @@ void A_RolloutRock();
void A_DragonbomberSpawn(); void A_DragonbomberSpawn();
void A_DragonWing(); void A_DragonWing();
void A_DragonSegment(); void A_DragonSegment();
void A_ChangeHeight();
// ratio of states to sprites to mobj types is roughly 6 : 1 : 1 // ratio of states to sprites to mobj types is roughly 6 : 1 : 1
#define NUMMOBJFREESLOTS 512 #define NUMMOBJFREESLOTS 512
@ -451,6 +452,8 @@ typedef enum sprite
// Projectiles // Projectiles
SPR_MISL, SPR_MISL,
SPR_LASR, // GFZ3 laser
SPR_LASF, // GFZ3 laser flames
SPR_TORP, // Torpedo SPR_TORP, // Torpedo
SPR_ENRG, // Energy ball SPR_ENRG, // Energy ball
SPR_MINE, // Skim mine SPR_MINE, // Skim mine
@ -2220,6 +2223,14 @@ typedef enum state
S_ROCKET, S_ROCKET,
S_LASER, S_LASER,
S_LASER2,
S_LASERFLASH,
S_LASERFLAME1,
S_LASERFLAME2,
S_LASERFLAME3,
S_LASERFLAME4,
S_LASERFLAME5,
S_TORPEDO, S_TORPEDO,

View File

@ -14,7 +14,7 @@
#include "fastcmp.h" #include "fastcmp.h"
#include "p_local.h" #include "p_local.h"
#include "p_setup.h" // So we can have P_SetupLevelSky #include "p_setup.h" // So we can have P_SetupLevelSky
#include "p_slopes.h" // P_GetZAt #include "p_slopes.h" // P_GetSlopeZAt
#include "z_zone.h" #include "z_zone.h"
#include "r_main.h" #include "r_main.h"
#include "r_draw.h" #include "r_draw.h"
@ -27,6 +27,7 @@
#include "hu_stuff.h" // HU_AddChatText #include "hu_stuff.h" // HU_AddChatText
#include "console.h" #include "console.h"
#include "d_netcmd.h" // IsPlayerAdmin #include "d_netcmd.h" // IsPlayerAdmin
#include "m_menu.h" // Player Setup menu color stuff
#include "lua_script.h" #include "lua_script.h"
#include "lua_libs.h" #include "lua_libs.h"
@ -144,6 +145,8 @@ static const struct {
{META_STATE, "state_t"}, {META_STATE, "state_t"},
{META_MOBJINFO, "mobjinfo_t"}, {META_MOBJINFO, "mobjinfo_t"},
{META_SFXINFO, "sfxinfo_t"}, {META_SFXINFO, "sfxinfo_t"},
{META_SKINCOLOR, "skincolor_t"},
{META_COLORRAMP, "skincolor_t.ramp"},
{META_SPRITEINFO, "spriteinfo_t"}, {META_SPRITEINFO, "spriteinfo_t"},
{META_PIVOTLIST, "spriteframepivot_t[]"}, {META_PIVOTLIST, "spriteframepivot_t[]"},
{META_FRAMEPIVOT, "spriteframepivot_t"}, {META_FRAMEPIVOT, "spriteframepivot_t"},
@ -252,6 +255,43 @@ static int lib_reserveLuabanks(lua_State *L)
return 1; return 1;
} }
// M_MENU
//////////////
static int lib_pMoveColorBefore(lua_State *L)
{
UINT16 color = (UINT16)luaL_checkinteger(L, 1);
UINT16 targ = (UINT16)luaL_checkinteger(L, 2);
NOHUD
M_MoveColorBefore(color, targ);
return 0;
}
static int lib_pMoveColorAfter(lua_State *L)
{
UINT16 color = (UINT16)luaL_checkinteger(L, 1);
UINT16 targ = (UINT16)luaL_checkinteger(L, 2);
NOHUD
M_MoveColorAfter(color, targ);
return 0;
}
static int lib_pGetColorBefore(lua_State *L)
{
UINT16 color = (UINT16)luaL_checkinteger(L, 1);
lua_pushinteger(L, M_GetColorBefore(color));
return 1;
}
static int lib_pGetColorAfter(lua_State *L)
{
UINT16 color = (UINT16)luaL_checkinteger(L, 1);
lua_pushinteger(L, M_GetColorAfter(color));
return 1;
}
// M_RANDOM // M_RANDOM
////////////// //////////////
@ -2184,14 +2224,20 @@ static int lib_evStartCrumble(lua_State *L)
static int lib_pGetZAt(lua_State *L) static int lib_pGetZAt(lua_State *L)
{ {
pslope_t *slope = *((pslope_t **)luaL_checkudata(L, 1, META_SLOPE));
fixed_t x = luaL_checkfixed(L, 2); fixed_t x = luaL_checkfixed(L, 2);
fixed_t y = luaL_checkfixed(L, 3); fixed_t y = luaL_checkfixed(L, 3);
//HUDSAFE //HUDSAFE
if (!slope) if (lua_isnil(L, 1))
return LUA_ErrInvalid(L, "pslope_t"); {
fixed_t z = luaL_checkfixed(L, 4);
lua_pushfixed(L, P_GetZAt(NULL, x, y, z));
}
else
{
pslope_t *slope = *((pslope_t **)luaL_checkudata(L, 1, META_SLOPE));
lua_pushfixed(L, P_GetSlopeZAt(slope, x, y));
}
lua_pushfixed(L, P_GetZAt(slope, x, y));
return 1; return 1;
} }
@ -2382,10 +2428,10 @@ static int lib_rGetColorByName(lua_State *L)
// SKINCOLOR_GREEN > "Green" for example // SKINCOLOR_GREEN > "Green" for example
static int lib_rGetNameByColor(lua_State *L) static int lib_rGetNameByColor(lua_State *L)
{ {
UINT8 colornum = (UINT8)luaL_checkinteger(L, 1); UINT16 colornum = (UINT16)luaL_checkinteger(L, 1);
if (!colornum || colornum >= MAXSKINCOLORS) if (!colornum || colornum >= numskincolors)
return luaL_error(L, "skincolor %d out of range (1 - %d).", colornum, MAXSKINCOLORS-1); return luaL_error(L, "skincolor %d out of range (1 - %d).", colornum, numskincolors-1);
lua_pushstring(L, Color_Names[colornum]); lua_pushstring(L, skincolors[colornum].name);
return 1; return 1;
} }
@ -2458,6 +2504,20 @@ static int lib_sStopSound(lua_State *L)
return 0; return 0;
} }
static int lib_sStopSoundByID(lua_State *L)
{
void *origin = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
sfxenum_t sound_id = luaL_checkinteger(L, 2);
//NOHUD
if (!origin)
return LUA_ErrInvalid(L, "mobj_t");
if (sound_id >= NUMSFX)
return luaL_error(L, "sfx %d out of range (0 - %d)", sound_id, NUMSFX-1);
S_StopSoundByID(origin, sound_id);
return 0;
}
static int lib_sChangeMusic(lua_State *L) static int lib_sChangeMusic(lua_State *L)
{ {
#ifdef MUSICSLOT_COMPATIBILITY #ifdef MUSICSLOT_COMPATIBILITY
@ -2878,15 +2938,50 @@ static int lib_gAddGametype(lua_State *L)
return 0; return 0;
} }
static int Lcheckmapnumber (lua_State *L, int idx, const char *fun)
{
if (ISINLEVEL)
return luaL_optinteger(L, idx, gamemap);
else
{
if (lua_isnoneornil(L, idx))
{
return luaL_error(L,
"%s can only be used without a parameter while in a level.",
fun
);
}
else
return luaL_checkinteger(L, idx);
}
}
static int lib_gBuildMapName(lua_State *L) static int lib_gBuildMapName(lua_State *L)
{ {
INT32 map = luaL_optinteger(L, 1, gamemap); INT32 map = Lcheckmapnumber(L, 1, "G_BuildMapName");
//HUDSAFE //HUDSAFE
INLEVEL
lua_pushstring(L, G_BuildMapName(map)); lua_pushstring(L, G_BuildMapName(map));
return 1; return 1;
} }
static int lib_gBuildMapTitle(lua_State *L)
{
INT32 map = Lcheckmapnumber(L, 1, "G_BuildMapTitle");
char *name;
if (map < 1 || map > NUMMAPS)
{
return luaL_error(L,
"map number %d out of range (1 - %d)",
map,
NUMMAPS
);
}
name = G_BuildMapTitle(map);
lua_pushstring(L, name);
Z_Free(name);
return 1;
}
static int lib_gDoReborn(lua_State *L) static int lib_gDoReborn(lua_State *L)
{ {
INT32 playernum = luaL_checkinteger(L, 1); INT32 playernum = luaL_checkinteger(L, 1);
@ -3073,6 +3168,12 @@ static luaL_Reg lib[] = {
{"IsPlayerAdmin", lib_isPlayerAdmin}, {"IsPlayerAdmin", lib_isPlayerAdmin},
{"reserveLuabanks", lib_reserveLuabanks}, {"reserveLuabanks", lib_reserveLuabanks},
// m_menu
{"M_MoveColorAfter",lib_pMoveColorAfter},
{"M_MoveColorBefore",lib_pMoveColorBefore},
{"M_GetColorAfter",lib_pGetColorAfter},
{"M_GetColorBefore",lib_pGetColorBefore},
// m_random // m_random
{"P_RandomFixed",lib_pRandomFixed}, {"P_RandomFixed",lib_pRandomFixed},
{"P_RandomByte",lib_pRandomByte}, {"P_RandomByte",lib_pRandomByte},
@ -3253,6 +3354,7 @@ static luaL_Reg lib[] = {
{"S_StartSound",lib_sStartSound}, {"S_StartSound",lib_sStartSound},
{"S_StartSoundAtVolume",lib_sStartSoundAtVolume}, {"S_StartSoundAtVolume",lib_sStartSoundAtVolume},
{"S_StopSound",lib_sStopSound}, {"S_StopSound",lib_sStopSound},
{"S_StopSoundByID",lib_sStopSoundByID},
{"S_ChangeMusic",lib_sChangeMusic}, {"S_ChangeMusic",lib_sChangeMusic},
{"S_SpeedMusic",lib_sSpeedMusic}, {"S_SpeedMusic",lib_sSpeedMusic},
{"S_StopMusic",lib_sStopMusic}, {"S_StopMusic",lib_sStopMusic},
@ -3271,6 +3373,7 @@ static luaL_Reg lib[] = {
// g_game // g_game
{"G_AddGametype", lib_gAddGametype}, {"G_AddGametype", lib_gAddGametype},
{"G_BuildMapName",lib_gBuildMapName}, {"G_BuildMapName",lib_gBuildMapName},
{"G_BuildMapTitle",lib_gBuildMapTitle},
{"G_DoReborn",lib_gDoReborn}, {"G_DoReborn",lib_gDoReborn},
{"G_SetCustomExitVars",lib_gSetCustomExitVars}, {"G_SetCustomExitVars",lib_gSetCustomExitVars},
{"G_EnoughPlayersFinished",lib_gEnoughPlayersFinished}, {"G_EnoughPlayersFinished",lib_gEnoughPlayersFinished},

View File

@ -80,9 +80,7 @@ static UINT8 lib_searchBlockmap_Lines(lua_State *L, INT32 x, INT32 y, mobj_t *th
{ {
INT32 offset; INT32 offset;
const INT32 *list; // Big blockmap const INT32 *list; // Big blockmap
#ifdef POLYOBJECTS
polymaplink_t *plink; // haleyjd 02/22/06 polymaplink_t *plink; // haleyjd 02/22/06
#endif
line_t *ld; line_t *ld;
if (x < 0 || y < 0 || x >= bmapwidth || y >= bmapheight) if (x < 0 || y < 0 || x >= bmapwidth || y >= bmapheight)
@ -90,7 +88,6 @@ static UINT8 lib_searchBlockmap_Lines(lua_State *L, INT32 x, INT32 y, mobj_t *th
offset = y*bmapwidth + x; offset = y*bmapwidth + x;
#ifdef POLYOBJECTS
// haleyjd 02/22/06: consider polyobject lines // haleyjd 02/22/06: consider polyobject lines
plink = polyblocklinks[offset]; plink = polyblocklinks[offset];
@ -133,7 +130,6 @@ static UINT8 lib_searchBlockmap_Lines(lua_State *L, INT32 x, INT32 y, mobj_t *th
} }
plink = (polymaplink_t *)(plink->link.next); plink = (polymaplink_t *)(plink->link.next);
} }
#endif
offset = *(blockmap + offset); // offset = blockmap[y*bmapwidth+x]; offset = *(blockmap + offset); // offset = blockmap[y*bmapwidth+x];

View File

@ -878,8 +878,8 @@ static int libd_drawNameTag(lua_State *L)
INT32 y; INT32 y;
const char *str; const char *str;
INT32 flags; INT32 flags;
UINT8 basecolor; UINT16 basecolor;
UINT8 outlinecolor; UINT16 outlinecolor;
UINT8 *basecolormap = NULL; UINT8 *basecolormap = NULL;
UINT8 *outlinecolormap = NULL; UINT8 *outlinecolormap = NULL;
@ -908,8 +908,8 @@ static int libd_drawScaledNameTag(lua_State *L)
const char *str; const char *str;
INT32 flags; INT32 flags;
fixed_t scale; fixed_t scale;
UINT8 basecolor; UINT16 basecolor;
UINT8 outlinecolor; UINT16 outlinecolor;
UINT8 *basecolormap = NULL; UINT8 *basecolormap = NULL;
UINT8 *outlinecolormap = NULL; UINT8 *outlinecolormap = NULL;
@ -966,7 +966,7 @@ static int libd_nameTagWidth(lua_State *L)
static int libd_getColormap(lua_State *L) static int libd_getColormap(lua_State *L)
{ {
INT32 skinnum = TC_DEFAULT; INT32 skinnum = TC_DEFAULT;
skincolors_t color = luaL_optinteger(L, 2, 0); skincolornum_t color = luaL_optinteger(L, 2, 0);
UINT8* colormap = NULL; UINT8* colormap = NULL;
HUDONLY HUDONLY
if (lua_isnoneornil(L, 1)) if (lua_isnoneornil(L, 1))

View File

@ -25,6 +25,9 @@
#include "lua_libs.h" #include "lua_libs.h"
#include "lua_hud.h" // hud_running errors #include "lua_hud.h" // hud_running errors
extern CV_PossibleValue_t Color_cons_t[MAXSKINCOLORS+1];
extern void R_FlushTranslationColormapCache(void);
boolean LUA_CallAction(const char *action, mobj_t *actor); boolean LUA_CallAction(const char *action, mobj_t *actor);
state_t *astate; state_t *astate;
@ -1465,6 +1468,229 @@ static int lib_luabankslen(lua_State *L)
return 1; return 1;
} }
////////////////////
// SKINCOLOR INFO //
////////////////////
// Arbitrary skincolors[] table index -> skincolor_t *
static int lib_getSkinColor(lua_State *L)
{
UINT32 i;
lua_remove(L, 1);
i = luaL_checkinteger(L, 1);
if (!i || i >= numskincolors)
return luaL_error(L, "skincolors[] index %d out of range (1 - %d)", i, numskincolors-1);
LUA_PushUserdata(L, &skincolors[i], META_SKINCOLOR);
return 1;
}
//Set the entire c->ramp array
static void setRamp(lua_State *L, skincolor_t* c) {
UINT32 i;
lua_pushnil(L);
for (i=0; i<COLORRAMPSIZE; i++) {
if (lua_objlen(L,-2)<COLORRAMPSIZE) {
luaL_error(L, LUA_QL("skincolor_t") " field 'ramp' must be %d entries long; got %d.", COLORRAMPSIZE, lua_objlen(L,-2));
break;
}
if (lua_next(L, -2) != 0) {
c->ramp[i] = lua_isnumber(L,-1) ? (UINT8)luaL_checkinteger(L,-1) : 120;
lua_pop(L, 1);
} else
c->ramp[i] = 120;
}
lua_pop(L,1);
}
// Lua table full of data -> skincolors[]
static int lib_setSkinColor(lua_State *L)
{
UINT32 j;
skincolor_t *info;
UINT16 cnum; //skincolor num
lua_remove(L, 1); // don't care about skincolors[] userdata.
{
cnum = (UINT16)luaL_checkinteger(L, 1);
if (cnum < SKINCOLOR_FIRSTFREESLOT || cnum >= numskincolors)
return luaL_error(L, "skincolors[] index %d out of range (%d - %d)", cnum, SKINCOLOR_FIRSTFREESLOT, numskincolors-1);
info = &skincolors[cnum]; // get the skincolor to assign to.
}
luaL_checktype(L, 2, LUA_TTABLE); // check that we've been passed a table.
lua_remove(L, 1); // pop skincolor num, don't need it any more.
lua_settop(L, 1); // cut the stack here. the only thing left now is the table of data we're assigning to the skincolor.
if (hud_running)
return luaL_error(L, "Do not alter skincolors in HUD rendering code!");
// clear the skincolor to start with, in case of missing table elements
memset(info,0,sizeof(skincolor_t));
Color_cons_t[cnum].value = cnum;
lua_pushnil(L);
while (lua_next(L, 1)) {
lua_Integer i = 0;
const char *str = NULL;
if (lua_isnumber(L, 2))
i = lua_tointeger(L, 2);
else
str = luaL_checkstring(L, 2);
if (i == 1 || (str && fastcmp(str,"name"))) {
const char* n = luaL_checkstring(L, 3);
strlcpy(info->name, n, MAXCOLORNAME+1);
if (strlen(n) > MAXCOLORNAME)
CONS_Alert(CONS_WARNING, "skincolor_t field 'name' ('%s') longer than %d chars; shortened to %s.\n", n, MAXCOLORNAME, info->name);
} else if (i == 2 || (str && fastcmp(str,"ramp"))) {
if (!lua_istable(L, 3) && luaL_checkudata(L, 3, META_COLORRAMP) == NULL)
return luaL_error(L, LUA_QL("skincolor_t") " field 'ramp' must be a table or array.");
else if (lua_istable(L, 3))
setRamp(L, info);
else
for (j=0; j<COLORRAMPSIZE; j++)
info->ramp[j] = (*((UINT8 **)luaL_checkudata(L, 3, META_COLORRAMP)))[j];
R_FlushTranslationColormapCache();
} else if (i == 3 || (str && fastcmp(str,"invcolor")))
info->invcolor = (UINT16)luaL_checkinteger(L, 3);
else if (i == 4 || (str && fastcmp(str,"invshade")))
info->invshade = (UINT8)luaL_checkinteger(L, 3)%COLORRAMPSIZE;
else if (i == 5 || (str && fastcmp(str,"chatcolor")))
info->chatcolor = (UINT16)luaL_checkinteger(L, 3);
else if (i == 6 || (str && fastcmp(str,"accessible"))) {
boolean v = lua_isboolean(L,3) ? lua_toboolean(L, 3) : true;
if (cnum < FIRSTSUPERCOLOR && v != skincolors[cnum].accessible)
return luaL_error(L, "skincolors[] index %d is a standard color; accessibility changes are prohibited.", i);
else
info->accessible = v;
}
lua_pop(L, 1);
}
return 0;
}
// #skincolors -> numskincolors
static int lib_skincolorslen(lua_State *L)
{
lua_pushinteger(L, numskincolors);
return 1;
}
// skincolor_t *, field -> number
static int skincolor_get(lua_State *L)
{
skincolor_t *info = *((skincolor_t **)luaL_checkudata(L, 1, META_SKINCOLOR));
const char *field = luaL_checkstring(L, 2);
I_Assert(info != NULL);
I_Assert(info >= skincolors);
if (fastcmp(field,"name"))
lua_pushstring(L, info->name);
else if (fastcmp(field,"ramp"))
LUA_PushUserdata(L, info->ramp, META_COLORRAMP);
else if (fastcmp(field,"invcolor"))
lua_pushinteger(L, info->invcolor);
else if (fastcmp(field,"invshade"))
lua_pushinteger(L, info->invshade);
else if (fastcmp(field,"chatcolor"))
lua_pushinteger(L, info->chatcolor);
else if (fastcmp(field,"accessible"))
lua_pushboolean(L, info->accessible);
else
CONS_Debug(DBG_LUA, M_GetText("'%s' has no field named '%s'; returning nil.\n"), "skincolor_t", field);
return 1;
}
// skincolor_t *, field, number -> skincolors[]
static int skincolor_set(lua_State *L)
{
UINT32 i;
skincolor_t *info = *((skincolor_t **)luaL_checkudata(L, 1, META_SKINCOLOR));
const char *field = luaL_checkstring(L, 2);
I_Assert(info != NULL);
I_Assert(info >= skincolors);
if (info-skincolors < SKINCOLOR_FIRSTFREESLOT || info-skincolors >= numskincolors)
return luaL_error(L, "skincolors[] index %d out of range (%d - %d)", info-skincolors, SKINCOLOR_FIRSTFREESLOT, numskincolors-1);
if (fastcmp(field,"name")) {
const char* n = luaL_checkstring(L, 3);
if (strchr(n, ' ') != NULL)
CONS_Alert(CONS_WARNING, "skincolor_t field 'name' ('%s') contains spaces.\n", n);
strlcpy(info->name, n, MAXCOLORNAME+1);
if (strlen(n) > MAXCOLORNAME)
CONS_Alert(CONS_WARNING, "skincolor_t field 'name' ('%s') longer than %d chars; clipped to %s.\n", n, MAXCOLORNAME, info->name);
} else if (fastcmp(field,"ramp")) {
if (!lua_istable(L, 3) && luaL_checkudata(L, 3, META_COLORRAMP) == NULL)
return luaL_error(L, LUA_QL("skincolor_t") " field 'ramp' must be a table or array.");
else if (lua_istable(L, 3))
setRamp(L, info);
else
for (i=0; i<COLORRAMPSIZE; i++)
info->ramp[i] = (*((UINT8 **)luaL_checkudata(L, 3, META_COLORRAMP)))[i];
R_FlushTranslationColormapCache();
} else if (fastcmp(field,"invcolor"))
info->invcolor = (UINT16)luaL_checkinteger(L, 3);
else if (fastcmp(field,"invshade"))
info->invshade = (UINT8)luaL_checkinteger(L, 3)%COLORRAMPSIZE;
else if (fastcmp(field,"chatcolor"))
info->chatcolor = (UINT16)luaL_checkinteger(L, 3);
else if (fastcmp(field,"accessible"))
info->accessible = lua_isboolean(L,3);
else
CONS_Debug(DBG_LUA, M_GetText("'%s' has no field named '%s'; returning nil.\n"), "skincolor_t", field);
return 1;
}
// skincolor_t * -> SKINCOLOR_*
static int skincolor_num(lua_State *L)
{
skincolor_t *info = *((skincolor_t **)luaL_checkudata(L, 1, META_SKINCOLOR));
I_Assert(info != NULL);
I_Assert(info >= skincolors);
lua_pushinteger(L, info-skincolors);
return 1;
}
// ramp, n -> ramp[n]
static int colorramp_get(lua_State *L)
{
UINT8 *colorramp = *((UINT8 **)luaL_checkudata(L, 1, META_COLORRAMP));
UINT32 n = luaL_checkinteger(L, 2);
if (n >= COLORRAMPSIZE)
return luaL_error(L, LUA_QL("skincolor_t") " field 'ramp' index %d out of range (0 - %d)", n, COLORRAMPSIZE-1);
lua_pushinteger(L, colorramp[n]);
return 1;
}
// ramp, n, value -> ramp[n] = value
static int colorramp_set(lua_State *L)
{
UINT8 *colorramp = *((UINT8 **)luaL_checkudata(L, 1, META_COLORRAMP));
UINT16 cnum = (UINT16)(((uint8_t*)colorramp - (uint8_t*)(skincolors[0].ramp))/sizeof(skincolor_t));
UINT32 n = luaL_checkinteger(L, 2);
UINT8 i = (UINT8)luaL_checkinteger(L, 3);
if (cnum < SKINCOLOR_FIRSTFREESLOT || cnum >= numskincolors)
return luaL_error(L, "skincolors[] index %d out of range (%d - %d)", cnum, SKINCOLOR_FIRSTFREESLOT, numskincolors-1);
if (n >= COLORRAMPSIZE)
return luaL_error(L, LUA_QL("skincolor_t") " field 'ramp' index %d out of range (0 - %d)", n, COLORRAMPSIZE-1);
if (hud_running)
return luaL_error(L, "Do not alter skincolor_t in HUD rendering code!");
colorramp[n] = i;
R_FlushTranslationColormapCache();
return 0;
}
// #ramp -> COLORRAMPSIZE
static int colorramp_len(lua_State *L)
{
lua_pushinteger(L, COLORRAMPSIZE);
return 1;
}
////////////////////////////// //////////////////////////////
// //
// Now push all these functions into the Lua state! // Now push all these functions into the Lua state!
@ -1502,6 +1728,28 @@ int LUA_InfoLib(lua_State *L)
lua_setfield(L, -2, "__len"); lua_setfield(L, -2, "__len");
lua_pop(L, 1); lua_pop(L, 1);
luaL_newmetatable(L, META_SKINCOLOR);
lua_pushcfunction(L, skincolor_get);
lua_setfield(L, -2, "__index");
lua_pushcfunction(L, skincolor_set);
lua_setfield(L, -2, "__newindex");
lua_pushcfunction(L, skincolor_num);
lua_setfield(L, -2, "__len");
lua_pop(L, 1);
luaL_newmetatable(L, META_COLORRAMP);
lua_pushcfunction(L, colorramp_get);
lua_setfield(L, -2, "__index");
lua_pushcfunction(L, colorramp_set);
lua_setfield(L, -2, "__newindex");
lua_pushcfunction(L, colorramp_len);
lua_setfield(L, -2, "__len");
lua_pop(L,1);
luaL_newmetatable(L, META_SFXINFO); luaL_newmetatable(L, META_SFXINFO);
lua_pushcfunction(L, sfxinfo_get); lua_pushcfunction(L, sfxinfo_get);
lua_setfield(L, -2, "__index"); lua_setfield(L, -2, "__index");
@ -1605,6 +1853,19 @@ int LUA_InfoLib(lua_State *L)
lua_setmetatable(L, -2); lua_setmetatable(L, -2);
lua_setglobal(L, "mobjinfo"); lua_setglobal(L, "mobjinfo");
lua_newuserdata(L, 0);
lua_createtable(L, 0, 2);
lua_pushcfunction(L, lib_getSkinColor);
lua_setfield(L, -2, "__index");
lua_pushcfunction(L, lib_setSkinColor);
lua_setfield(L, -2, "__newindex");
lua_pushcfunction(L, lib_skincolorslen);
lua_setfield(L, -2, "__len");
lua_setmetatable(L, -2);
lua_setglobal(L, "skincolors");
lua_newuserdata(L, 0); lua_newuserdata(L, 0);
lua_createtable(L, 0, 2); lua_createtable(L, 0, 2);
lua_pushcfunction(L, lib_getSfxInfo); lua_pushcfunction(L, lib_getSfxInfo);

View File

@ -20,6 +20,8 @@ extern lua_State *gL;
#define META_STATE "STATE_T*" #define META_STATE "STATE_T*"
#define META_MOBJINFO "MOBJINFO_T*" #define META_MOBJINFO "MOBJINFO_T*"
#define META_SFXINFO "SFXINFO_T*" #define META_SFXINFO "SFXINFO_T*"
#define META_SKINCOLOR "SKINCOLOR_T*"
#define META_COLORRAMP "SKINCOLOR_T*RAMP"
#define META_SPRITEINFO "SPRITEINFO_T*" #define META_SPRITEINFO "SPRITEINFO_T*"
#define META_PIVOTLIST "SPRITEFRAMEPIVOT_T[]" #define META_PIVOTLIST "SPRITEFRAMEPIVOT_T[]"
#define META_FRAMEPIVOT "SPRITEFRAMEPIVOT_T*" #define META_FRAMEPIVOT "SPRITEFRAMEPIVOT_T*"

View File

@ -2082,6 +2082,12 @@ static int mapheaderinfo_get(lua_State *L)
lua_pushinteger(L, header->menuflags); lua_pushinteger(L, header->menuflags);
else if (fastcmp(field,"startrings")) else if (fastcmp(field,"startrings"))
lua_pushinteger(L, header->startrings); lua_pushinteger(L, header->startrings);
else if (fastcmp(field, "sstimer"))
lua_pushinteger(L, header->sstimer);
else if (fastcmp(field, "ssspheres"))
lua_pushinteger(L, header->ssspheres);
else if (fastcmp(field, "gravity"))
lua_pushfixed(L, header->gravity);
// TODO add support for reading numGradedMares and grades // TODO add support for reading numGradedMares and grades
else { else {
// Read custom vars now // Read custom vars now

View File

@ -172,15 +172,14 @@ static int lib_all7emeralds(lua_State *L)
return 1; return 1;
} }
// Whee, special Lua-exclusive function for making use of Color_Opposite[]
// Returns both color and signpost shade numbers! // Returns both color and signpost shade numbers!
static int lib_coloropposite(lua_State *L) static int lib_coloropposite(lua_State *L)
{ {
UINT8 colornum = (UINT8)luaL_checkinteger(L, 1); UINT16 colornum = (UINT16)luaL_checkinteger(L, 1);
if (!colornum || colornum >= MAXSKINCOLORS) if (!colornum || colornum >= numskincolors)
return luaL_error(L, "skincolor %d out of range (1 - %d).", colornum, MAXSKINCOLORS-1); return luaL_error(L, "skincolor %d out of range (1 - %d).", colornum, numskincolors-1);
lua_pushinteger(L, Color_Opposite[colornum-1][0]); // push color lua_pushinteger(L, skincolors[colornum].invcolor); // push color
lua_pushinteger(L, Color_Opposite[colornum-1][1]); // push sign shade index, 0-15 lua_pushinteger(L, skincolors[colornum].invshade); // push sign shade index, 0-15
return 2; return 2;
} }

View File

@ -574,9 +574,9 @@ static int mobj_set(lua_State *L)
} }
case mobj_color: case mobj_color:
{ {
UINT8 newcolor = (UINT8)luaL_checkinteger(L,3); UINT16 newcolor = (UINT16)luaL_checkinteger(L,3);
if (newcolor >= MAXTRANSLATIONS) if (newcolor >= numskincolors)
return luaL_error(L, "mobj.color %d out of range (0 - %d).", newcolor, MAXTRANSLATIONS-1); return luaL_error(L, "mobj.color %d out of range (0 - %d).", newcolor, numskincolors-1);
mo->color = newcolor; mo->color = newcolor;
break; break;
} }
@ -829,6 +829,15 @@ static int mapthing_set(lua_State *L)
return 0; return 0;
} }
static int mapthing_num(lua_State *L)
{
mapthing_t *mt = *((mapthing_t **)luaL_checkudata(L, 1, META_MAPTHING));
if (!mt)
return luaL_error(L, "accessed mapthing_t doesn't exist anymore.");
lua_pushinteger(L, mt-mapthings);
return 1;
}
static int lib_iterateMapthings(lua_State *L) static int lib_iterateMapthings(lua_State *L)
{ {
size_t i = 0; size_t i = 0;
@ -893,6 +902,9 @@ int LUA_MobjLib(lua_State *L)
lua_pushcfunction(L, mapthing_set); lua_pushcfunction(L, mapthing_set);
lua_setfield(L, -2, "__newindex"); lua_setfield(L, -2, "__newindex");
lua_pushcfunction(L, mapthing_num);
lua_setfield(L, -2, "__len");
lua_pop(L,1); lua_pop(L,1);
lua_newuserdata(L, 0); lua_newuserdata(L, 0);

View File

@ -461,9 +461,9 @@ static int player_set(lua_State *L)
plr->flashpal = (UINT16)luaL_checkinteger(L, 3); plr->flashpal = (UINT16)luaL_checkinteger(L, 3);
else if (fastcmp(field,"skincolor")) else if (fastcmp(field,"skincolor"))
{ {
UINT8 newcolor = (UINT8)luaL_checkinteger(L,3); UINT16 newcolor = (UINT16)luaL_checkinteger(L,3);
if (newcolor >= MAXSKINCOLORS) if (newcolor >= numskincolors)
return luaL_error(L, "player.skincolor %d out of range (0 - %d).", newcolor, MAXSKINCOLORS-1); return luaL_error(L, "player.skincolor %d out of range (0 - %d).", newcolor, numskincolors-1);
plr->skincolor = newcolor; plr->skincolor = newcolor;
} }
else if (fastcmp(field,"score")) else if (fastcmp(field,"score"))

View File

@ -730,9 +730,13 @@ void LUA_InvalidatePlayer(player_t *player)
enum enum
{ {
ARCH_NULL=0, ARCH_NULL=0,
ARCH_BOOLEAN, ARCH_TRUE,
ARCH_SIGNED, ARCH_FALSE,
ARCH_STRING, ARCH_INT8,
ARCH_INT16,
ARCH_INT32,
ARCH_SMALLSTRING,
ARCH_LARGESTRING,
ARCH_TABLE, ARCH_TABLE,
ARCH_MOBJINFO, ARCH_MOBJINFO,
@ -752,6 +756,7 @@ enum
ARCH_FFLOOR, ARCH_FFLOOR,
ARCH_SLOPE, ARCH_SLOPE,
ARCH_MAPHEADER, ARCH_MAPHEADER,
ARCH_SKINCOLOR,
ARCH_TEND=0xFF, ARCH_TEND=0xFF,
}; };
@ -777,6 +782,7 @@ static const struct {
{META_FFLOOR, ARCH_FFLOOR}, {META_FFLOOR, ARCH_FFLOOR},
{META_SLOPE, ARCH_SLOPE}, {META_SLOPE, ARCH_SLOPE},
{META_MAPHEADER, ARCH_MAPHEADER}, {META_MAPHEADER, ARCH_MAPHEADER},
{META_SKINCOLOR, ARCH_SKINCOLOR},
{NULL, ARCH_NULL} {NULL, ARCH_NULL}
}; };
@ -817,22 +823,33 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
WRITEUINT8(save_p, ARCH_NULL); WRITEUINT8(save_p, ARCH_NULL);
return 2; return 2;
case LUA_TBOOLEAN: case LUA_TBOOLEAN:
WRITEUINT8(save_p, ARCH_BOOLEAN); WRITEUINT8(save_p, lua_toboolean(gL, myindex) ? ARCH_TRUE : ARCH_FALSE);
WRITEUINT8(save_p, lua_toboolean(gL, myindex));
break; break;
case LUA_TNUMBER: case LUA_TNUMBER:
{ {
lua_Integer number = lua_tointeger(gL, myindex); lua_Integer number = lua_tointeger(gL, myindex);
WRITEUINT8(save_p, ARCH_SIGNED); if (number >= INT8_MIN && number <= INT8_MAX)
WRITEFIXED(save_p, number); {
WRITEUINT8(save_p, ARCH_INT8);
WRITESINT8(save_p, number);
}
else if (number >= INT16_MIN && number <= INT16_MAX)
{
WRITEUINT8(save_p, ARCH_INT16);
WRITEINT16(save_p, number);
}
else
{
WRITEUINT8(save_p, ARCH_INT32);
WRITEFIXED(save_p, number);
}
break; break;
} }
case LUA_TSTRING: case LUA_TSTRING:
{ {
UINT16 len = (UINT16)lua_objlen(gL, myindex); // get length of string, including embedded zeros UINT32 len = (UINT32)lua_objlen(gL, myindex); // get length of string, including embedded zeros
const char *s = lua_tostring(gL, myindex); const char *s = lua_tostring(gL, myindex);
UINT16 i = 0; UINT32 i = 0;
WRITEUINT8(save_p, ARCH_STRING);
// if you're wondering why we're writing a string to save_p this way, // if you're wondering why we're writing a string to save_p this way,
// it turns out that Lua can have embedded zeros ('\0') in the strings, // it turns out that Lua can have embedded zeros ('\0') in the strings,
// so we can't use WRITESTRING as that cuts off when it finds a '\0'. // so we can't use WRITESTRING as that cuts off when it finds a '\0'.
@ -840,7 +857,16 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
// fixing the awful crashes previously encountered for reading strings longer than 1024 // fixing the awful crashes previously encountered for reading strings longer than 1024
// (yes I know that's kind of a stupid thing to care about, but it'd be evil to trim or ignore them?) // (yes I know that's kind of a stupid thing to care about, but it'd be evil to trim or ignore them?)
// -- Monster Iestyn 05/08/18 // -- Monster Iestyn 05/08/18
WRITEUINT16(save_p, len); // save size of string if (len < 255)
{
WRITEUINT8(save_p, ARCH_SMALLSTRING);
WRITEUINT8(save_p, len); // save size of string
}
else
{
WRITEUINT8(save_p, ARCH_LARGESTRING);
WRITEUINT32(save_p, len); // save size of string
}
while (i < len) while (i < len)
WRITECHAR(save_p, s[i++]); // write chars individually, including the embedded zeros WRITECHAR(save_p, s[i++]); // write chars individually, including the embedded zeros
break; break;
@ -1044,6 +1070,14 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
} }
break; break;
} }
case ARCH_SKINCOLOR:
{
skincolor_t *info = *((skincolor_t **)lua_touserdata(gL, myindex));
WRITEUINT8(save_p, ARCH_SKINCOLOR);
WRITEUINT16(save_p, info - skincolors);
break;
}
default: default:
WRITEUINT8(save_p, ARCH_NULL); WRITEUINT8(save_p, ARCH_NULL);
return 2; return 2;
@ -1170,21 +1204,36 @@ static UINT8 UnArchiveValue(int TABLESINDEX)
case ARCH_NULL: case ARCH_NULL:
lua_pushnil(gL); lua_pushnil(gL);
break; break;
case ARCH_BOOLEAN: case ARCH_TRUE:
lua_pushboolean(gL, READUINT8(save_p)); lua_pushboolean(gL, true);
break; break;
case ARCH_SIGNED: case ARCH_FALSE:
lua_pushboolean(gL, false);
break;
case ARCH_INT8:
lua_pushinteger(gL, READSINT8(save_p));
break;
case ARCH_INT16:
lua_pushinteger(gL, READINT16(save_p));
break;
case ARCH_INT32:
lua_pushinteger(gL, READFIXED(save_p)); lua_pushinteger(gL, READFIXED(save_p));
break; break;
case ARCH_STRING: case ARCH_SMALLSTRING:
case ARCH_LARGESTRING:
{ {
UINT16 len = READUINT16(save_p); // length of string, including embedded zeros UINT32 len;
char *value; char *value;
UINT16 i = 0; UINT32 i = 0;
// See my comments in the ArchiveValue function; // See my comments in the ArchiveValue function;
// it's much the same for reading strings as writing them! // it's much the same for reading strings as writing them!
// (i.e. we can't use READSTRING either) // (i.e. we can't use READSTRING either)
// -- Monster Iestyn 05/08/18 // -- Monster Iestyn 05/08/18
if (type == ARCH_SMALLSTRING)
len = READUINT8(save_p); // length of string, including embedded zeros
else
len = READUINT32(save_p); // length of string, including embedded zeros
value = malloc(len); // make temp buffer of size len value = malloc(len); // make temp buffer of size len
// now read the actual string // now read the actual string
while (i < len) while (i < len)
@ -1260,6 +1309,9 @@ static UINT8 UnArchiveValue(int TABLESINDEX)
case ARCH_MAPHEADER: case ARCH_MAPHEADER:
LUA_PushUserdata(gL, mapheaderinfo[READUINT16(save_p)], META_MAPHEADER); LUA_PushUserdata(gL, mapheaderinfo[READUINT16(save_p)], META_MAPHEADER);
break; break;
case ARCH_SKINCOLOR:
LUA_PushUserdata(gL, &skincolors[READUINT16(save_p)], META_SKINCOLOR);
break;
case ARCH_TEND: case ARCH_TEND:
return 1; return 1;
} }

View File

@ -99,5 +99,8 @@ void COM_Lua_f(void);
// uncomment if you want seg_t/node_t in Lua // uncomment if you want seg_t/node_t in Lua
// #define HAVE_LUA_SEGS // #define HAVE_LUA_SEGS
#define INLEVEL if (gamestate != GS_LEVEL && !titlemapinaction)\ #define ISINLEVEL \
(gamestate == GS_LEVEL || titlemapinaction)
#define INLEVEL if (! ISINLEVEL)\
return luaL_error(L, "This can only be used in a level!"); return luaL_error(L, "This can only be used in a level!");

View File

@ -490,29 +490,28 @@ const UINT8 gifframe_gchead[4] = {0x21,0xF9,0x04,0x04}; // GCE, bytes, packed by
static UINT8 *gifframe_data = NULL; static UINT8 *gifframe_data = NULL;
static size_t gifframe_size = 8192; static size_t gifframe_size = 8192;
//
// GIF_rgbconvert
// converts an RGB frame to a frame with a palette.
//
#ifdef HWRENDER #ifdef HWRENDER
static void hwrconvert(void) static void GIF_rgbconvert(UINT8 *linear, UINT8 *scr)
{ {
UINT8 *linear = HWR_GetScreenshot();
UINT8 *dest = screens[2];
UINT8 r, g, b; UINT8 r, g, b;
INT32 x, y; size_t src = 0, dest = 0;
size_t i = 0; size_t size = (vid.width * vid.height * 3);
InitColorLUT(gif_framepalette); InitColorLUT(gif_framepalette);
for (y = 0; y < vid.height; y++) while (src < size)
{ {
for (x = 0; x < vid.width; x++, i += 3) r = (UINT8)linear[src];
{ g = (UINT8)linear[src + 1];
r = (UINT8)linear[i]; b = (UINT8)linear[src + 2];
g = (UINT8)linear[i + 1]; scr[dest] = colorlookup[r >> SHIFTCOLORBITS][g >> SHIFTCOLORBITS][b >> SHIFTCOLORBITS];
b = (UINT8)linear[i + 2]; src += (3 * scrbuf_downscaleamt);
dest[(y * vid.width) + x] = colorlookup[r >> SHIFTCOLORBITS][g >> SHIFTCOLORBITS][b >> SHIFTCOLORBITS]; dest += scrbuf_downscaleamt;
}
} }
free(linear);
} }
#endif #endif
@ -556,7 +555,11 @@ static void GIF_framewrite(void)
I_ReadScreen(movie_screen); I_ReadScreen(movie_screen);
#ifdef HWRENDER #ifdef HWRENDER
else if (rendermode == render_opengl) else if (rendermode == render_opengl)
hwrconvert(); {
UINT8 *linear = HWR_GetScreenshot();
GIF_rgbconvert(linear, movie_screen);
free(linear);
}
#endif #endif
} }
else else
@ -565,18 +568,20 @@ static void GIF_framewrite(void)
blitw = vid.width; blitw = vid.width;
blith = vid.height; blith = vid.height;
if (gif_frames == 0)
{
if (rendermode == render_soft)
I_ReadScreen(movie_screen);
#ifdef HWRENDER #ifdef HWRENDER
else if (rendermode == render_opengl) // Copy the current OpenGL frame into the base screen
{ if (rendermode == render_opengl)
hwrconvert(); {
VID_BlitLinearScreen(screens[2], screens[0], vid.width*vid.bpp, vid.height, vid.width*vid.bpp, vid.rowbytes); UINT8 *linear = HWR_GetScreenshot();
} GIF_rgbconvert(linear, screens[0]);
#endif free(linear);
} }
#endif
// Copy the first frame into the movie screen
// OpenGL already does the same above.
if (gif_frames == 0 && rendermode == render_soft)
I_ReadScreen(movie_screen);
movie_screen = screens[0]; movie_screen = screens[0];
} }

View File

@ -978,7 +978,7 @@ static mobjflag2_t op_oldflags2 = 0;
static UINT32 op_oldeflags = 0; static UINT32 op_oldeflags = 0;
static fixed_t op_oldmomx = 0, op_oldmomy = 0, op_oldmomz = 0, op_oldheight = 0; static fixed_t op_oldmomx = 0, op_oldmomy = 0, op_oldmomz = 0, op_oldheight = 0;
static statenum_t op_oldstate = 0; static statenum_t op_oldstate = 0;
static UINT8 op_oldcolor = 0; static UINT16 op_oldcolor = 0;
// //
// Static calculation / common output help // Static calculation / common output help
@ -1032,8 +1032,8 @@ static boolean OP_HeightOkay(player_t *player, UINT8 ceiling)
if (ceiling) if (ceiling)
{ {
// Truncate position to match where mapthing would be when spawned // Truncate position to match where mapthing would be when spawned
// (this applies to every further P_GetZAt call as well) // (this applies to every further P_GetSlopeZAt call as well)
fixed_t cheight = sec->c_slope ? P_GetZAt(sec->c_slope, player->mo->x & 0xFFFF0000, player->mo->y & 0xFFFF0000) : sec->ceilingheight; fixed_t cheight = P_GetSectorCeilingZAt(sec, player->mo->x & 0xFFFF0000, player->mo->y & 0xFFFF0000);
if (((cheight - player->mo->z - player->mo->height)>>FRACBITS) >= (1 << (16-ZSHIFT))) if (((cheight - player->mo->z - player->mo->height)>>FRACBITS) >= (1 << (16-ZSHIFT)))
{ {
@ -1044,7 +1044,7 @@ static boolean OP_HeightOkay(player_t *player, UINT8 ceiling)
} }
else else
{ {
fixed_t fheight = sec->f_slope ? P_GetZAt(sec->f_slope, player->mo->x & 0xFFFF0000, player->mo->y & 0xFFFF0000) : sec->floorheight; fixed_t fheight = P_GetSectorFloorZAt(sec, player->mo->x & 0xFFFF0000, player->mo->y & 0xFFFF0000);
if (((player->mo->z - fheight)>>FRACBITS) >= (1 << (16-ZSHIFT))) if (((player->mo->z - fheight)>>FRACBITS) >= (1 << (16-ZSHIFT)))
{ {
CONS_Printf(M_GetText("Sorry, you're too %s to place this object (max: %d %s).\n"), M_GetText("high"), CONS_Printf(M_GetText("Sorry, you're too %s to place this object (max: %d %s).\n"), M_GetText("high"),
@ -1091,12 +1091,12 @@ static mapthing_t *OP_CreateNewMapThing(player_t *player, UINT16 type, boolean c
mt->y = (INT16)(player->mo->y>>FRACBITS); mt->y = (INT16)(player->mo->y>>FRACBITS);
if (ceiling) if (ceiling)
{ {
fixed_t cheight = sec->c_slope ? P_GetZAt(sec->c_slope, mt->x << FRACBITS, mt->y << FRACBITS) : sec->ceilingheight; fixed_t cheight = P_GetSectorCeilingZAt(sec, mt->x << FRACBITS, mt->y << FRACBITS);
mt->z = (UINT16)((cheight - player->mo->z - player->mo->height)>>FRACBITS); mt->z = (UINT16)((cheight - player->mo->z - player->mo->height)>>FRACBITS);
} }
else else
{ {
fixed_t fheight = sec->f_slope ? P_GetZAt(sec->f_slope, mt->x << FRACBITS, mt->y << FRACBITS) : sec->floorheight; fixed_t fheight = P_GetSectorFloorZAt(sec, mt->x << FRACBITS, mt->y << FRACBITS);
mt->z = (UINT16)((player->mo->z - fheight)>>FRACBITS); mt->z = (UINT16)((player->mo->z - fheight)>>FRACBITS);
} }
mt->angle = (INT16)(FixedInt(AngleFixed(player->mo->angle))); mt->angle = (INT16)(FixedInt(AngleFixed(player->mo->angle)));
@ -1342,12 +1342,12 @@ void OP_ObjectplaceMovement(player_t *player)
if (!!(mobjinfo[op_currentthing].flags & MF_SPAWNCEILING) ^ !!(cv_opflags.value & MTF_OBJECTFLIP)) if (!!(mobjinfo[op_currentthing].flags & MF_SPAWNCEILING) ^ !!(cv_opflags.value & MTF_OBJECTFLIP))
{ {
fixed_t cheight = sec->c_slope ? P_GetZAt(sec->c_slope, player->mo->x & 0xFFFF0000, player->mo->y & 0xFFFF0000) : sec->ceilingheight; fixed_t cheight = P_GetSectorCeilingZAt(sec, player->mo->x & 0xFFFF0000, player->mo->y & 0xFFFF0000);
op_displayflags = (UINT16)((cheight - player->mo->z - mobjinfo[op_currentthing].height)>>FRACBITS); op_displayflags = (UINT16)((cheight - player->mo->z - mobjinfo[op_currentthing].height)>>FRACBITS);
} }
else else
{ {
fixed_t fheight = sec->f_slope ? P_GetZAt(sec->f_slope, player->mo->x & 0xFFFF0000, player->mo->y & 0xFFFF0000) : sec->floorheight; fixed_t fheight = P_GetSectorFloorZAt(sec, player->mo->x & 0xFFFF0000, player->mo->y & 0xFFFF0000);
op_displayflags = (UINT16)((player->mo->z - fheight)>>FRACBITS); op_displayflags = (UINT16)((player->mo->z - fheight)>>FRACBITS);
} }
op_displayflags <<= ZSHIFT; op_displayflags <<= ZSHIFT;

View File

@ -523,9 +523,9 @@ emblem_t *M_GetLevelEmblems(INT32 mapnum)
return NULL; return NULL;
} }
skincolors_t M_GetEmblemColor(emblem_t *em) skincolornum_t M_GetEmblemColor(emblem_t *em)
{ {
if (!em || em->color >= MAXSKINCOLORS) if (!em || em->color >= numskincolors)
return SKINCOLOR_NONE; return SKINCOLOR_NONE;
return em->color; return em->color;
} }
@ -549,9 +549,9 @@ const char *M_GetEmblemPatch(emblem_t *em, boolean big)
return pnamebuf; return pnamebuf;
} }
skincolors_t M_GetExtraEmblemColor(extraemblem_t *em) skincolornum_t M_GetExtraEmblemColor(extraemblem_t *em)
{ {
if (!em || em->color >= MAXSKINCOLORS) if (!em || em->color >= numskincolors)
return SKINCOLOR_NONE; return SKINCOLOR_NONE;
return em->color; return em->color;
} }

View File

@ -90,7 +90,7 @@ typedef struct
INT16 tag; ///< Tag of emblem mapthing INT16 tag; ///< Tag of emblem mapthing
INT16 level; ///< Level on which this emblem can be found. INT16 level; ///< Level on which this emblem can be found.
UINT8 sprite; ///< emblem sprite to use, 0 - 25 UINT8 sprite; ///< emblem sprite to use, 0 - 25
UINT8 color; ///< skincolor to use UINT16 color; ///< skincolor to use
INT32 var; ///< If needed, specifies information on the target amount to achieve (or target skin) INT32 var; ///< If needed, specifies information on the target amount to achieve (or target skin)
char hint[110]; ///< Hint for emblem hints menu char hint[110]; ///< Hint for emblem hints menu
UINT8 collected; ///< Do you have this emblem? UINT8 collected; ///< Do you have this emblem?
@ -102,7 +102,7 @@ typedef struct
UINT8 conditionset; ///< Condition set that awards this emblem. UINT8 conditionset; ///< Condition set that awards this emblem.
UINT8 showconditionset; ///< Condition set that shows this emblem. UINT8 showconditionset; ///< Condition set that shows this emblem.
UINT8 sprite; ///< emblem sprite to use, 0 - 25 UINT8 sprite; ///< emblem sprite to use, 0 - 25
UINT8 color; ///< skincolor to use UINT16 color; ///< skincolor to use
UINT8 collected; ///< Do you have this emblem? UINT8 collected; ///< Do you have this emblem?
} extraemblem_t; } extraemblem_t;
@ -172,9 +172,9 @@ INT32 M_CountEmblems(void);
// Emblem shit // Emblem shit
emblem_t *M_GetLevelEmblems(INT32 mapnum); emblem_t *M_GetLevelEmblems(INT32 mapnum);
skincolors_t M_GetEmblemColor(emblem_t *em); skincolornum_t M_GetEmblemColor(emblem_t *em);
const char *M_GetEmblemPatch(emblem_t *em, boolean big); const char *M_GetEmblemPatch(emblem_t *em, boolean big);
skincolors_t M_GetExtraEmblemColor(extraemblem_t *em); skincolornum_t M_GetExtraEmblemColor(extraemblem_t *em);
const char *M_GetExtraEmblemPatch(extraemblem_t *em, boolean big); const char *M_GetExtraEmblemPatch(extraemblem_t *em, boolean big);
// If you're looking to compare stats for unlocks or what not, use these // If you're looking to compare stats for unlocks or what not, use these

View File

@ -882,7 +882,8 @@ static menuitem_t SP_NightsAttackLevelSelectMenu[] =
static menuitem_t SP_NightsAttackMenu[] = static menuitem_t SP_NightsAttackMenu[] =
{ {
{IT_STRING|IT_KEYHANDLER, NULL, "Level Select...", &M_HandleTimeAttackLevelSelect, 52}, {IT_STRING|IT_KEYHANDLER, NULL, "Level Select...", &M_HandleTimeAttackLevelSelect, 52},
{IT_STRING|IT_CVAR, NULL, "Show Records For", &cv_dummymares, 62}, {IT_STRING|IT_CVAR, NULL, "Character", &cv_chooseskin, 62},
{IT_STRING|IT_CVAR, NULL, "Show Records For", &cv_dummymares, 72},
{IT_DISABLED, NULL, "Guest Option...", &SP_NightsGuestReplayDef, 100}, {IT_DISABLED, NULL, "Guest Option...", &SP_NightsGuestReplayDef, 100},
{IT_DISABLED, NULL, "Replay...", &SP_NightsReplayDef, 110}, {IT_DISABLED, NULL, "Replay...", &SP_NightsReplayDef, 110},
@ -893,6 +894,7 @@ static menuitem_t SP_NightsAttackMenu[] =
enum enum
{ {
nalevel, nalevel,
nachar,
narecords, narecords,
naguest, naguest,
@ -1583,7 +1585,7 @@ static menuitem_t OP_ServerOptionsMenu[] =
{IT_HEADER, NULL, "General", NULL, 0}, {IT_HEADER, NULL, "General", NULL, 0},
#ifndef NONET #ifndef NONET
{IT_STRING | IT_CVAR | IT_CV_STRING, {IT_STRING | IT_CVAR | IT_CV_STRING,
NULL, "Server name", &cv_servername, 7}, NULL, "Server name", &cv_servername, 7},
{IT_STRING | IT_CVAR, NULL, "Max Players", &cv_maxplayers, 21}, {IT_STRING | IT_CVAR, NULL, "Max Players", &cv_maxplayers, 21},
{IT_STRING | IT_CVAR, NULL, "Allow Add-on Downloading", &cv_downloading, 26}, {IT_STRING | IT_CVAR, NULL, "Allow Add-on Downloading", &cv_downloading, 26},
{IT_STRING | IT_CVAR, NULL, "Allow players to join", &cv_allownewplayer, 31}, {IT_STRING | IT_CVAR, NULL, "Allow players to join", &cv_allownewplayer, 31},
@ -1628,8 +1630,9 @@ static menuitem_t OP_ServerOptionsMenu[] =
#ifndef NONET #ifndef NONET
{IT_HEADER, NULL, "Advanced", NULL, 225}, {IT_HEADER, NULL, "Advanced", NULL, 225},
{IT_STRING | IT_CVAR | IT_CV_STRING, NULL, "Master server", &cv_masterserver, 231}, {IT_STRING | IT_CVAR | IT_CV_STRING, NULL, "Master server", &cv_masterserver, 231},
{IT_STRING | IT_CVAR, NULL, "Attempts to resynchronise", &cv_resynchattempts, 245}, {IT_STRING | IT_CVAR, NULL, "Join delay", &cv_joindelay, 246},
{IT_STRING | IT_CVAR, NULL, "Attempts to resynchronise", &cv_resynchattempts, 251},
#endif #endif
}; };
@ -1701,7 +1704,7 @@ static INT32 highlightflags, recommendedflags, warningflags;
// Sky Room // Sky Room
menu_t SR_PandoraDef = menu_t SR_PandoraDef =
{ {
MN_SR_MAIN + (MN_SR_PANDORA << 6), MTREE2(MN_SR_MAIN, MN_SR_PANDORA),
"M_PANDRA", "M_PANDRA",
sizeof (SR_PandorasBox)/sizeof (menuitem_t), sizeof (SR_PandorasBox)/sizeof (menuitem_t),
&SPauseDef, &SPauseDef,
@ -1715,12 +1718,12 @@ menu_t SR_PandoraDef =
menu_t SR_MainDef = DEFAULTMENUSTYLE(MN_SR_MAIN, "M_SECRET", SR_MainMenu, &MainDef, 60, 40); menu_t SR_MainDef = DEFAULTMENUSTYLE(MN_SR_MAIN, "M_SECRET", SR_MainMenu, &MainDef, 60, 40);
menu_t SR_LevelSelectDef = MAPPLATTERMENUSTYLE( menu_t SR_LevelSelectDef = MAPPLATTERMENUSTYLE(
MN_SR_MAIN + (MN_SR_LEVELSELECT << 6), MTREE2(MN_SR_MAIN, MN_SR_LEVELSELECT),
NULL, SR_LevelSelectMenu); NULL, SR_LevelSelectMenu);
menu_t SR_UnlockChecklistDef = menu_t SR_UnlockChecklistDef =
{ {
MN_SR_MAIN + (MN_SR_UNLOCKCHECKLIST << 6), MTREE2(MN_SR_MAIN, MN_SR_UNLOCKCHECKLIST),
"M_SECRET", "M_SECRET",
1, 1,
&SR_MainDef, &SR_MainDef,
@ -1733,7 +1736,7 @@ menu_t SR_UnlockChecklistDef =
menu_t SR_SoundTestDef = menu_t SR_SoundTestDef =
{ {
MN_SR_MAIN + (MN_SR_SOUNDTEST << 6), MTREE2(MN_SR_MAIN, MN_SR_SOUNDTEST),
NULL, NULL,
sizeof (SR_SoundTestMenu)/sizeof (menuitem_t), sizeof (SR_SoundTestMenu)/sizeof (menuitem_t),
&SR_MainDef, &SR_MainDef,
@ -1746,7 +1749,7 @@ menu_t SR_SoundTestDef =
menu_t SR_EmblemHintDef = menu_t SR_EmblemHintDef =
{ {
MN_SR_MAIN + (MN_SR_EMBLEMHINT << 6), MTREE2(MN_SR_MAIN, MN_SR_EMBLEMHINT),
NULL, NULL,
sizeof (SR_EmblemHintMenu)/sizeof (menuitem_t), sizeof (SR_EmblemHintMenu)/sizeof (menuitem_t),
&SPauseDef, &SPauseDef,
@ -1773,7 +1776,7 @@ menu_t SP_MainDef = //CENTERMENUSTYLE(NULL, SP_MainMenu, &MainDef, 72);
menu_t SP_LoadDef = menu_t SP_LoadDef =
{ {
MN_SP_MAIN + (MN_SP_LOAD << 6), MTREE2(MN_SP_MAIN, MN_SP_LOAD),
"M_PICKG", "M_PICKG",
1, 1,
&SP_MainDef, &SP_MainDef,
@ -1785,12 +1788,12 @@ menu_t SP_LoadDef =
}; };
menu_t SP_LevelSelectDef = MAPPLATTERMENUSTYLE( menu_t SP_LevelSelectDef = MAPPLATTERMENUSTYLE(
MN_SP_MAIN + (MN_SP_LOAD << 6) + (MN_SP_PLAYER << 12) + (MN_SP_LEVELSELECT << 18), MTREE4(MN_SP_MAIN, MN_SP_LOAD, MN_SP_PLAYER, MN_SP_LEVELSELECT),
NULL, SP_LevelSelectMenu); NULL, SP_LevelSelectMenu);
menu_t SP_LevelStatsDef = menu_t SP_LevelStatsDef =
{ {
MN_SP_MAIN + (MN_SP_LEVELSTATS << 6), MTREE2(MN_SP_MAIN, MN_SP_LEVELSTATS),
"M_STATS", "M_STATS",
1, 1,
&SP_MainDef, &SP_MainDef,
@ -1802,12 +1805,12 @@ menu_t SP_LevelStatsDef =
}; };
menu_t SP_TimeAttackLevelSelectDef = MAPPLATTERMENUSTYLE( menu_t SP_TimeAttackLevelSelectDef = MAPPLATTERMENUSTYLE(
MN_SP_MAIN + (MN_SP_TIMEATTACK << 6) + (MN_SP_TIMEATTACK_LEVELSELECT << 12), MTREE3(MN_SP_MAIN, MN_SP_TIMEATTACK, MN_SP_TIMEATTACK_LEVELSELECT),
"M_ATTACK", SP_TimeAttackLevelSelectMenu); "M_ATTACK", SP_TimeAttackLevelSelectMenu);
static menu_t SP_TimeAttackDef = static menu_t SP_TimeAttackDef =
{ {
MN_SP_MAIN + (MN_SP_TIMEATTACK << 6), MTREE2(MN_SP_MAIN, MN_SP_TIMEATTACK),
"M_ATTACK", "M_ATTACK",
sizeof (SP_TimeAttackMenu)/sizeof (menuitem_t), sizeof (SP_TimeAttackMenu)/sizeof (menuitem_t),
&MainDef, // Doesn't matter. &MainDef, // Doesn't matter.
@ -1819,7 +1822,7 @@ static menu_t SP_TimeAttackDef =
}; };
static menu_t SP_ReplayDef = static menu_t SP_ReplayDef =
{ {
MN_SP_MAIN + (MN_SP_TIMEATTACK << 6) + (MN_SP_REPLAY << 12), MTREE3(MN_SP_MAIN, MN_SP_TIMEATTACK, MN_SP_REPLAY),
"M_ATTACK", "M_ATTACK",
sizeof(SP_ReplayMenu)/sizeof(menuitem_t), sizeof(SP_ReplayMenu)/sizeof(menuitem_t),
&SP_TimeAttackDef, &SP_TimeAttackDef,
@ -1831,7 +1834,7 @@ static menu_t SP_ReplayDef =
}; };
static menu_t SP_GuestReplayDef = static menu_t SP_GuestReplayDef =
{ {
MN_SP_MAIN + (MN_SP_TIMEATTACK << 6) + (MN_SP_GUESTREPLAY << 12), MTREE3(MN_SP_MAIN, MN_SP_TIMEATTACK, MN_SP_GUESTREPLAY),
"M_ATTACK", "M_ATTACK",
sizeof(SP_GuestReplayMenu)/sizeof(menuitem_t), sizeof(SP_GuestReplayMenu)/sizeof(menuitem_t),
&SP_TimeAttackDef, &SP_TimeAttackDef,
@ -1843,7 +1846,7 @@ static menu_t SP_GuestReplayDef =
}; };
static menu_t SP_GhostDef = static menu_t SP_GhostDef =
{ {
MN_SP_MAIN + (MN_SP_TIMEATTACK << 6) + (MN_SP_GHOST << 12), MTREE3(MN_SP_MAIN, MN_SP_TIMEATTACK, MN_SP_GHOST),
"M_ATTACK", "M_ATTACK",
sizeof(SP_GhostMenu)/sizeof(menuitem_t), sizeof(SP_GhostMenu)/sizeof(menuitem_t),
&SP_TimeAttackDef, &SP_TimeAttackDef,
@ -1855,12 +1858,12 @@ static menu_t SP_GhostDef =
}; };
menu_t SP_NightsAttackLevelSelectDef = MAPPLATTERMENUSTYLE( menu_t SP_NightsAttackLevelSelectDef = MAPPLATTERMENUSTYLE(
MN_SP_MAIN + (MN_SP_NIGHTSATTACK << 6) + (MN_SP_NIGHTS_LEVELSELECT << 12), MTREE3(MN_SP_MAIN, MN_SP_NIGHTSATTACK, MN_SP_NIGHTS_LEVELSELECT),
"M_NIGHTS", SP_NightsAttackLevelSelectMenu); "M_NIGHTS", SP_NightsAttackLevelSelectMenu);
static menu_t SP_NightsAttackDef = static menu_t SP_NightsAttackDef =
{ {
MN_SP_MAIN + (MN_SP_NIGHTSATTACK << 6), MTREE2(MN_SP_MAIN, MN_SP_NIGHTSATTACK),
"M_NIGHTS", "M_NIGHTS",
sizeof (SP_NightsAttackMenu)/sizeof (menuitem_t), sizeof (SP_NightsAttackMenu)/sizeof (menuitem_t),
&MainDef, // Doesn't matter. &MainDef, // Doesn't matter.
@ -1872,7 +1875,7 @@ static menu_t SP_NightsAttackDef =
}; };
static menu_t SP_NightsReplayDef = static menu_t SP_NightsReplayDef =
{ {
MN_SP_MAIN + (MN_SP_NIGHTSATTACK << 6) + (MN_SP_NIGHTS_REPLAY << 12), MTREE3(MN_SP_MAIN, MN_SP_NIGHTSATTACK, MN_SP_NIGHTS_REPLAY),
"M_NIGHTS", "M_NIGHTS",
sizeof(SP_NightsReplayMenu)/sizeof(menuitem_t), sizeof(SP_NightsReplayMenu)/sizeof(menuitem_t),
&SP_NightsAttackDef, &SP_NightsAttackDef,
@ -1884,7 +1887,7 @@ static menu_t SP_NightsReplayDef =
}; };
static menu_t SP_NightsGuestReplayDef = static menu_t SP_NightsGuestReplayDef =
{ {
MN_SP_MAIN + (MN_SP_NIGHTSATTACK << 6) + (MN_SP_NIGHTS_GUESTREPLAY << 12), MTREE3(MN_SP_MAIN, MN_SP_NIGHTSATTACK, MN_SP_NIGHTS_GUESTREPLAY),
"M_NIGHTS", "M_NIGHTS",
sizeof(SP_NightsGuestReplayMenu)/sizeof(menuitem_t), sizeof(SP_NightsGuestReplayMenu)/sizeof(menuitem_t),
&SP_NightsAttackDef, &SP_NightsAttackDef,
@ -1896,7 +1899,7 @@ static menu_t SP_NightsGuestReplayDef =
}; };
static menu_t SP_NightsGhostDef = static menu_t SP_NightsGhostDef =
{ {
MN_SP_MAIN + (MN_SP_NIGHTSATTACK << 6) + (MN_SP_NIGHTS_GHOST << 12), MTREE3(MN_SP_MAIN, MN_SP_NIGHTSATTACK, MN_SP_NIGHTS_GHOST),
"M_NIGHTS", "M_NIGHTS",
sizeof(SP_NightsGhostMenu)/sizeof(menuitem_t), sizeof(SP_NightsGhostMenu)/sizeof(menuitem_t),
&SP_NightsAttackDef, &SP_NightsAttackDef,
@ -1910,7 +1913,7 @@ static menu_t SP_NightsGhostDef =
menu_t SP_PlayerDef = menu_t SP_PlayerDef =
{ {
MN_SP_MAIN + (MN_SP_LOAD << 6) + (MN_SP_PLAYER << 12), MTREE3(MN_SP_MAIN, MN_SP_LOAD, MN_SP_PLAYER),
"M_PICKP", "M_PICKP",
sizeof (SP_PlayerMenu)/sizeof (menuitem_t), sizeof (SP_PlayerMenu)/sizeof (menuitem_t),
&SP_MainDef, &SP_MainDef,
@ -1925,7 +1928,7 @@ menu_t SP_PlayerDef =
menu_t MP_SplitServerDef = menu_t MP_SplitServerDef =
{ {
MN_MP_MAIN + (MN_MP_SPLITSCREEN << 6), MTREE2(MN_MP_MAIN, MN_MP_SPLITSCREEN),
"M_MULTI", "M_MULTI",
sizeof (MP_SplitServerMenu)/sizeof (menuitem_t), sizeof (MP_SplitServerMenu)/sizeof (menuitem_t),
#ifndef NONET #ifndef NONET
@ -1957,7 +1960,7 @@ menu_t MP_MainDef =
menu_t MP_ServerDef = menu_t MP_ServerDef =
{ {
MN_MP_MAIN + (MN_MP_SERVER << 6), MTREE2(MN_MP_MAIN, MN_MP_SERVER),
"M_MULTI", "M_MULTI",
sizeof (MP_ServerMenu)/sizeof (menuitem_t), sizeof (MP_ServerMenu)/sizeof (menuitem_t),
&MP_MainDef, &MP_MainDef,
@ -1970,7 +1973,7 @@ menu_t MP_ServerDef =
menu_t MP_ConnectDef = menu_t MP_ConnectDef =
{ {
MN_MP_MAIN + (MN_MP_CONNECT << 6), MTREE2(MN_MP_MAIN, MN_MP_CONNECT),
"M_MULTI", "M_MULTI",
sizeof (MP_ConnectMenu)/sizeof (menuitem_t), sizeof (MP_ConnectMenu)/sizeof (menuitem_t),
&MP_MainDef, &MP_MainDef,
@ -1983,7 +1986,7 @@ menu_t MP_ConnectDef =
menu_t MP_RoomDef = menu_t MP_RoomDef =
{ {
MN_MP_MAIN + (MN_MP_ROOM << 6), MTREE2(MN_MP_MAIN, MN_MP_ROOM),
"M_MULTI", "M_MULTI",
sizeof (MP_RoomMenu)/sizeof (menuitem_t), sizeof (MP_RoomMenu)/sizeof (menuitem_t),
&MP_ConnectDef, &MP_ConnectDef,
@ -1998,9 +2001,9 @@ menu_t MP_RoomDef =
menu_t MP_PlayerSetupDef = menu_t MP_PlayerSetupDef =
{ {
#ifdef NONET #ifdef NONET
MN_MP_MAIN + (MN_MP_PLAYERSETUP << 6), MTREE2(MN_MP_MAIN, MN_MP_PLAYERSETUP),
#else #else
MN_MP_MAIN + (MN_MP_SPLITSCREEN << 6) + (MN_MP_PLAYERSETUP << 12), MTREE3(MN_MP_MAIN, MN_MP_SPLITSCREEN, MN_MP_PLAYERSETUP),
#endif #endif
"M_SPLAYR", "M_SPLAYR",
sizeof (MP_PlayerSetupMenu)/sizeof (menuitem_t), sizeof (MP_PlayerSetupMenu)/sizeof (menuitem_t),
@ -2016,12 +2019,13 @@ menu_t MP_PlayerSetupDef =
menu_t OP_MainDef = DEFAULTMENUSTYLE( menu_t OP_MainDef = DEFAULTMENUSTYLE(
MN_OP_MAIN, MN_OP_MAIN,
"M_OPTTTL", OP_MainMenu, &MainDef, 50, 30); "M_OPTTTL", OP_MainMenu, &MainDef, 50, 30);
menu_t OP_ChangeControlsDef = CONTROLMENUSTYLE( menu_t OP_ChangeControlsDef = CONTROLMENUSTYLE(
MN_OP_MAIN + (MN_OP_CHANGECONTROLS << 12), // second level (<<6) set on runtime MTREE3(MN_OP_MAIN, 0, MN_OP_CHANGECONTROLS), // second level set on runtime
OP_ChangeControlsMenu, &OP_MainDef); OP_ChangeControlsMenu, &OP_MainDef);
menu_t OP_P1ControlsDef = { menu_t OP_P1ControlsDef = {
MN_OP_MAIN + (MN_OP_P1CONTROLS << 6), MTREE2(MN_OP_MAIN, MN_OP_P1CONTROLS),
"M_CONTRO", "M_CONTRO",
sizeof(OP_P1ControlsMenu)/sizeof(menuitem_t), sizeof(OP_P1ControlsMenu)/sizeof(menuitem_t),
&OP_MainDef, &OP_MainDef,
@ -2029,7 +2033,7 @@ menu_t OP_P1ControlsDef = {
M_DrawControlsDefMenu, M_DrawControlsDefMenu,
50, 30, 0, NULL}; 50, 30, 0, NULL};
menu_t OP_P2ControlsDef = { menu_t OP_P2ControlsDef = {
MN_OP_MAIN + (MN_OP_P2CONTROLS << 6), MTREE2(MN_OP_MAIN, MN_OP_P2CONTROLS),
"M_CONTRO", "M_CONTRO",
sizeof(OP_P2ControlsMenu)/sizeof(menuitem_t), sizeof(OP_P2ControlsMenu)/sizeof(menuitem_t),
&OP_MainDef, &OP_MainDef,
@ -2038,20 +2042,22 @@ menu_t OP_P2ControlsDef = {
50, 30, 0, NULL}; 50, 30, 0, NULL};
menu_t OP_MouseOptionsDef = DEFAULTMENUSTYLE( menu_t OP_MouseOptionsDef = DEFAULTMENUSTYLE(
MN_OP_MAIN + (MN_OP_P1CONTROLS << 6) + (MN_OP_P1MOUSE << 12), MTREE3(MN_OP_MAIN, MN_OP_P1CONTROLS, MN_OP_P1MOUSE),
"M_CONTRO", OP_MouseOptionsMenu, &OP_P1ControlsDef, 35, 30); "M_CONTRO", OP_MouseOptionsMenu, &OP_P1ControlsDef, 35, 30);
menu_t OP_Mouse2OptionsDef = DEFAULTMENUSTYLE( menu_t OP_Mouse2OptionsDef = DEFAULTMENUSTYLE(
MN_OP_MAIN + (MN_OP_P2CONTROLS << 6) + (MN_OP_P2MOUSE << 12), MTREE3(MN_OP_MAIN, MN_OP_P2CONTROLS, MN_OP_P2MOUSE),
"M_CONTRO", OP_Mouse2OptionsMenu, &OP_P2ControlsDef, 35, 30); "M_CONTRO", OP_Mouse2OptionsMenu, &OP_P2ControlsDef, 35, 30);
menu_t OP_Joystick1Def = DEFAULTMENUSTYLE( menu_t OP_Joystick1Def = DEFAULTMENUSTYLE(
MN_OP_MAIN + (MN_OP_P1CONTROLS << 6) + (MN_OP_P1JOYSTICK << 12), MTREE3(MN_OP_MAIN, MN_OP_P1CONTROLS, MN_OP_P1JOYSTICK),
"M_CONTRO", OP_Joystick1Menu, &OP_P1ControlsDef, 50, 30); "M_CONTRO", OP_Joystick1Menu, &OP_P1ControlsDef, 50, 30);
menu_t OP_Joystick2Def = DEFAULTMENUSTYLE( menu_t OP_Joystick2Def = DEFAULTMENUSTYLE(
MN_OP_MAIN + (MN_OP_P2CONTROLS << 6) + (MN_OP_P2JOYSTICK << 12), MTREE3(MN_OP_MAIN, MN_OP_P2CONTROLS, MN_OP_P2JOYSTICK),
"M_CONTRO", OP_Joystick2Menu, &OP_P2ControlsDef, 50, 30); "M_CONTRO", OP_Joystick2Menu, &OP_P2ControlsDef, 50, 30);
menu_t OP_JoystickSetDef = menu_t OP_JoystickSetDef =
{ {
MN_OP_MAIN + (MN_OP_JOYSTICKSET << MENUBITS*3), // second (<<6) and third level (<<12) set on runtime MTREE4(MN_OP_MAIN, 0, 0, MN_OP_JOYSTICKSET), // second and third level set on runtime
"M_CONTRO", "M_CONTRO",
sizeof (OP_JoystickSetMenu)/sizeof (menuitem_t), sizeof (OP_JoystickSetMenu)/sizeof (menuitem_t),
&OP_Joystick1Def, &OP_Joystick1Def,
@ -2063,7 +2069,7 @@ menu_t OP_JoystickSetDef =
}; };
menu_t OP_CameraOptionsDef = { menu_t OP_CameraOptionsDef = {
MN_OP_MAIN + (MN_OP_P1CONTROLS << 6) + (MN_OP_P1CAMERA << 12), MTREE3(MN_OP_MAIN, MN_OP_P1CONTROLS, MN_OP_P1CAMERA),
"M_CONTRO", "M_CONTRO",
sizeof (OP_CameraOptionsMenu)/sizeof (menuitem_t), sizeof (OP_CameraOptionsMenu)/sizeof (menuitem_t),
&OP_P1ControlsDef, &OP_P1ControlsDef,
@ -2074,7 +2080,7 @@ menu_t OP_CameraOptionsDef = {
NULL NULL
}; };
menu_t OP_Camera2OptionsDef = { menu_t OP_Camera2OptionsDef = {
MN_OP_MAIN + (MN_OP_P2CONTROLS << 6) + (MN_OP_P2CAMERA << 12), MTREE3(MN_OP_MAIN, MN_OP_P2CONTROLS, MN_OP_P2CAMERA),
"M_CONTRO", "M_CONTRO",
sizeof (OP_Camera2OptionsMenu)/sizeof (menuitem_t), sizeof (OP_Camera2OptionsMenu)/sizeof (menuitem_t),
&OP_P2ControlsDef, &OP_P2ControlsDef,
@ -2088,7 +2094,7 @@ menu_t OP_Camera2OptionsDef = {
static menuitem_t OP_PlaystyleMenu[] = {{IT_KEYHANDLER | IT_NOTHING, NULL, "", M_HandlePlaystyleMenu, 0}}; static menuitem_t OP_PlaystyleMenu[] = {{IT_KEYHANDLER | IT_NOTHING, NULL, "", M_HandlePlaystyleMenu, 0}};
menu_t OP_PlaystyleDef = { menu_t OP_PlaystyleDef = {
MN_OP_MAIN + (MN_OP_P1CONTROLS << 6) + (MN_OP_PLAYSTYLE << 12), MTREE3(MN_OP_MAIN, MN_OP_P1CONTROLS, MN_OP_PLAYSTYLE), ///@TODO the second level should be set in runtime
NULL, NULL,
1, 1,
&OP_P1ControlsDef, &OP_P1ControlsDef,
@ -2114,7 +2120,7 @@ static void M_VideoOptions(INT32 choice)
menu_t OP_VideoOptionsDef = menu_t OP_VideoOptionsDef =
{ {
MN_OP_MAIN + (MN_OP_VIDEO << 6), MTREE2(MN_OP_MAIN, MN_OP_VIDEO),
"M_VIDEO", "M_VIDEO",
sizeof (OP_VideoOptionsMenu)/sizeof (menuitem_t), sizeof (OP_VideoOptionsMenu)/sizeof (menuitem_t),
&OP_MainDef, &OP_MainDef,
@ -2126,7 +2132,7 @@ menu_t OP_VideoOptionsDef =
}; };
menu_t OP_VideoModeDef = menu_t OP_VideoModeDef =
{ {
MN_OP_MAIN + (MN_OP_VIDEO << 6) + (MN_OP_VIDEOMODE << 12), MTREE3(MN_OP_MAIN, MN_OP_VIDEO, MN_OP_VIDEOMODE),
"M_VIDEO", "M_VIDEO",
1, 1,
&OP_VideoOptionsDef, &OP_VideoOptionsDef,
@ -2138,7 +2144,7 @@ menu_t OP_VideoModeDef =
}; };
menu_t OP_ColorOptionsDef = menu_t OP_ColorOptionsDef =
{ {
MN_OP_MAIN + (MN_OP_VIDEO << 6) + (MN_OP_COLOR << 12), MTREE3(MN_OP_MAIN, MN_OP_VIDEO, MN_OP_COLOR),
"M_VIDEO", "M_VIDEO",
sizeof (OP_ColorOptionsMenu)/sizeof (menuitem_t), sizeof (OP_ColorOptionsMenu)/sizeof (menuitem_t),
&OP_VideoOptionsDef, &OP_VideoOptionsDef,
@ -2149,17 +2155,19 @@ menu_t OP_ColorOptionsDef =
NULL NULL
}; };
menu_t OP_SoundOptionsDef = DEFAULTMENUSTYLE( menu_t OP_SoundOptionsDef = DEFAULTMENUSTYLE(
MN_OP_MAIN + (MN_OP_SOUND << 6), MTREE2(MN_OP_MAIN, MN_OP_SOUND),
"M_SOUND", OP_SoundOptionsMenu, &OP_MainDef, 30, 30); "M_SOUND", OP_SoundOptionsMenu, &OP_MainDef, 30, 30);
menu_t OP_SoundAdvancedDef = DEFAULTMENUSTYLE(MN_OP_MAIN + (MN_OP_SOUND << 6), "M_SOUND", OP_SoundAdvancedMenu, &OP_SoundOptionsDef, 30, 30); menu_t OP_SoundAdvancedDef = DEFAULTMENUSTYLE(
MTREE2(MN_OP_MAIN, MN_OP_SOUND),
"M_SOUND", OP_SoundAdvancedMenu, &OP_SoundOptionsDef, 30, 30);
menu_t OP_ServerOptionsDef = DEFAULTSCROLLMENUSTYLE( menu_t OP_ServerOptionsDef = DEFAULTSCROLLMENUSTYLE(
MN_OP_MAIN + (MN_OP_SERVER << 6), MTREE2(MN_OP_MAIN, MN_OP_SERVER),
"M_SERVER", OP_ServerOptionsMenu, &OP_MainDef, 30, 30); "M_SERVER", OP_ServerOptionsMenu, &OP_MainDef, 30, 30);
menu_t OP_MonitorToggleDef = menu_t OP_MonitorToggleDef =
{ {
MN_OP_MAIN + (MN_OP_SERVER << 6) + (MN_OP_MONITORTOGGLE << 12), MTREE3(MN_OP_MAIN, MN_OP_SOUND, MN_OP_MONITORTOGGLE),
"M_SERVER", "M_SERVER",
sizeof (OP_MonitorToggleMenu)/sizeof (menuitem_t), sizeof (OP_MonitorToggleMenu)/sizeof (menuitem_t),
&OP_ServerOptionsDef, &OP_ServerOptionsDef,
@ -2180,16 +2188,16 @@ static void M_OpenGLOptionsMenu(void)
} }
menu_t OP_OpenGLOptionsDef = DEFAULTMENUSTYLE( menu_t OP_OpenGLOptionsDef = DEFAULTMENUSTYLE(
MN_OP_MAIN + (MN_OP_VIDEO << 6) + (MN_OP_OPENGL << 12), MTREE3(MN_OP_MAIN, MN_OP_VIDEO, MN_OP_OPENGL),
"M_VIDEO", OP_OpenGLOptionsMenu, &OP_VideoOptionsDef, 30, 30); "M_VIDEO", OP_OpenGLOptionsMenu, &OP_VideoOptionsDef, 30, 30);
#ifdef ALAM_LIGHTING #ifdef ALAM_LIGHTING
menu_t OP_OpenGLLightingDef = DEFAULTMENUSTYLE( menu_t OP_OpenGLLightingDef = DEFAULTMENUSTYLE(
MN_OP_MAIN + (MN_OP_VIDEO << 6) + (MN_OP_OPENGL << 12) + (MN_OP_OPENGL_LIGHTING << 18), MTREE4(MN_OP_MAIN, MN_OP_VIDEO, MN_OP_OPENGL, MN_OP_OPENGL_LIGHTING),
"M_VIDEO", OP_OpenGLLightingMenu, &OP_OpenGLOptionsDef, 60, 40); "M_VIDEO", OP_OpenGLLightingMenu, &OP_OpenGLOptionsDef, 60, 40);
#endif #endif
menu_t OP_OpenGLFogDef = menu_t OP_OpenGLFogDef =
{ {
MN_OP_MAIN + (MN_OP_VIDEO << 6) + (MN_OP_OPENGL << 12) + (MN_OP_OPENGL_FOG << 18), MTREE4(MN_OP_MAIN, MN_OP_VIDEO, MN_OP_OPENGL, MN_OP_OPENGL_FOG),
"M_VIDEO", "M_VIDEO",
sizeof (OP_OpenGLFogMenu)/sizeof (menuitem_t), sizeof (OP_OpenGLFogMenu)/sizeof (menuitem_t),
&OP_OpenGLOptionsDef, &OP_OpenGLOptionsDef,
@ -2201,12 +2209,12 @@ menu_t OP_OpenGLFogDef =
}; };
#endif #endif
menu_t OP_DataOptionsDef = DEFAULTMENUSTYLE( menu_t OP_DataOptionsDef = DEFAULTMENUSTYLE(
MN_OP_MAIN + (MN_OP_DATA << 6), MTREE2(MN_OP_MAIN, MN_OP_DATA),
"M_DATA", OP_DataOptionsMenu, &OP_MainDef, 60, 30); "M_DATA", OP_DataOptionsMenu, &OP_MainDef, 60, 30);
menu_t OP_ScreenshotOptionsDef = menu_t OP_ScreenshotOptionsDef =
{ {
MN_OP_MAIN + (MN_OP_DATA << 6) + (MN_OP_SCREENSHOTS << 12), MTREE3(MN_OP_MAIN, MN_OP_DATA, MN_OP_SCREENSHOTS),
"M_SCREEN", "M_SCREEN",
sizeof (OP_ScreenshotOptionsMenu)/sizeof (menuitem_t), sizeof (OP_ScreenshotOptionsMenu)/sizeof (menuitem_t),
&OP_DataOptionsDef, &OP_DataOptionsDef,
@ -2218,11 +2226,11 @@ menu_t OP_ScreenshotOptionsDef =
}; };
menu_t OP_AddonsOptionsDef = DEFAULTMENUSTYLE( menu_t OP_AddonsOptionsDef = DEFAULTMENUSTYLE(
MN_OP_MAIN + (MN_OP_DATA << 6) + (MN_OP_ADDONS << 12), MTREE3(MN_OP_MAIN, MN_OP_DATA, MN_OP_ADDONS),
"M_ADDONS", OP_AddonsOptionsMenu, &OP_DataOptionsDef, 30, 30); "M_ADDONS", OP_AddonsOptionsMenu, &OP_DataOptionsDef, 30, 30);
menu_t OP_EraseDataDef = DEFAULTMENUSTYLE( menu_t OP_EraseDataDef = DEFAULTMENUSTYLE(
MN_OP_MAIN + (MN_OP_DATA << 6) + (MN_OP_ERASEDATA << 12), MTREE3(MN_OP_MAIN, MN_OP_DATA, MN_OP_ERASEDATA),
"M_DATA", OP_EraseDataMenu, &OP_DataOptionsDef, 60, 30); "M_DATA", OP_EraseDataMenu, &OP_DataOptionsDef, 60, 30);
// ========================================================================== // ==========================================================================
@ -5180,7 +5188,7 @@ static boolean M_PrepareLevelPlatter(INT32 gt, boolean nextmappick)
{ {
if (M_CanShowLevelOnPlatter(mapnum, gt)) if (M_CanShowLevelOnPlatter(mapnum, gt))
{ {
const INT32 actnum = mapheaderinfo[mapnum]->actnum; const UINT8 actnum = mapheaderinfo[mapnum]->actnum;
const boolean headingisname = (fastcmp(mapheaderinfo[mapnum]->selectheading, mapheaderinfo[mapnum]->lvlttl)); const boolean headingisname = (fastcmp(mapheaderinfo[mapnum]->selectheading, mapheaderinfo[mapnum]->lvlttl));
const boolean wide = (mapheaderinfo[mapnum]->menuflags & LF2_WIDEICON); const boolean wide = (mapheaderinfo[mapnum]->menuflags & LF2_WIDEICON);
@ -7537,7 +7545,7 @@ static void M_DrawSoundTest(void)
{ {
frame[1] = (2-st_time); frame[1] = (2-st_time);
frame[2] = ((cv_soundtest.value - 1) % 9); frame[2] = ((cv_soundtest.value - 1) % 9);
frame[3] += (((cv_soundtest.value - 1) / 9) % (MAXSKINCOLORS - frame[3])); frame[3] += (((cv_soundtest.value - 1) / 9) % (FIRSTSUPERCOLOR - frame[3]));
if (st_time < 2) if (st_time < 2)
st_time++; st_time++;
} }
@ -8205,13 +8213,13 @@ static void M_DrawLoadGameData(void)
{ {
if (charskin->prefoppositecolor) if (charskin->prefoppositecolor)
{ {
col = charskin->prefoppositecolor - 1; col = charskin->prefoppositecolor;
col = Color_Index[col][Color_Opposite[Color_Opposite[col][0] - 1][1]]; col = skincolors[col].ramp[skincolors[skincolors[col].invcolor].invshade];
} }
else else
{ {
col = charskin->prefcolor - 1; col = charskin->prefcolor;
col = Color_Index[Color_Opposite[col][0]-1][Color_Opposite[col][1]]; col = skincolors[skincolors[col].invcolor].ramp[skincolors[col].invshade];
} }
} }
@ -8939,16 +8947,11 @@ static void M_SetupChoosePlayer(INT32 choice)
/* the menus suck -James */ /* the menus suck -James */
if (currentMenu == &SP_LoadDef)/* from save states */ if (currentMenu == &SP_LoadDef)/* from save states */
{ {
SP_PlayerDef.menuid = SP_PlayerDef.menuid = MTREE3(MN_SP_MAIN, MN_SP_LOAD, MN_SP_PLAYER);
MN_SP_MAIN +
( MN_SP_LOAD << 6 ) +
( MN_SP_PLAYER << 12 );
} }
else/* from Secret level select */ else/* from Secret level select */
{ {
SP_PlayerDef.menuid = SP_PlayerDef.menuid = MTREE2(MN_SR_MAIN, MN_SR_PLAYER);
MN_SR_MAIN +
( MN_SR_PLAYER << 6 );
} }
SP_PlayerDef.prevMenu = currentMenu; SP_PlayerDef.prevMenu = currentMenu;
@ -9052,7 +9055,7 @@ static void M_DrawSetupChoosePlayerMenu(void)
skin_t *charskin = &skins[0]; skin_t *charskin = &skins[0];
INT32 skinnum = 0; INT32 skinnum = 0;
UINT8 col; UINT16 col;
UINT8 *colormap = NULL; UINT8 *colormap = NULL;
INT32 prev = -1, next = -1; INT32 prev = -1, next = -1;
@ -9091,10 +9094,10 @@ static void M_DrawSetupChoosePlayerMenu(void)
// Use the opposite of the character's skincolor // Use the opposite of the character's skincolor
col = description[char_on].oppositecolor; col = description[char_on].oppositecolor;
if (!col) if (!col)
col = Color_Opposite[charskin->prefcolor - 1][0]; col = skincolors[charskin->prefcolor].invcolor;
// Make the translation colormap // Make the translation colormap
colormap = R_GetTranslationColormap(TC_DEFAULT, col, 0); colormap = R_GetTranslationColormap(TC_DEFAULT, col, GTC_CACHE);
// Don't render the title map // Don't render the title map
hidetitlemap = true; hidetitlemap = true;
@ -9142,8 +9145,8 @@ static void M_DrawSetupChoosePlayerMenu(void)
INT32 ox, oxsh = FixedInt(FixedMul(BASEVIDWIDTH*FRACUNIT, FixedDiv(char_scroll, 128*FRACUNIT))), txsh; INT32 ox, oxsh = FixedInt(FixedMul(BASEVIDWIDTH*FRACUNIT, FixedDiv(char_scroll, 128*FRACUNIT))), txsh;
patch_t *curpatch = NULL, *prevpatch = NULL, *nextpatch = NULL; patch_t *curpatch = NULL, *prevpatch = NULL, *nextpatch = NULL;
const char *curtext = NULL, *prevtext = NULL, *nexttext = NULL; const char *curtext = NULL, *prevtext = NULL, *nexttext = NULL;
UINT8 curtextcolor = 0, prevtextcolor = 0, nexttextcolor = 0; UINT16 curtextcolor = 0, prevtextcolor = 0, nexttextcolor = 0;
UINT8 curoutlinecolor = 0, prevoutlinecolor = 0, nextoutlinecolor = 0; UINT16 curoutlinecolor = 0, prevoutlinecolor = 0, nextoutlinecolor = 0;
// Name tag // Name tag
curtext = description[char_on].displayname; curtext = description[char_on].displayname;
@ -9154,7 +9157,7 @@ static void M_DrawSetupChoosePlayerMenu(void)
if (!curtextcolor) if (!curtextcolor)
curtextcolor = charskin->prefcolor; curtextcolor = charskin->prefcolor;
if (!curoutlinecolor) if (!curoutlinecolor)
curoutlinecolor = Color_Opposite[charskin->prefcolor - 1][0]; curoutlinecolor = col = skincolors[charskin->prefcolor].invcolor;
txsh = oxsh; txsh = oxsh;
ox = 8 + SHORT((description[char_on].charpic)->width)/2; ox = 8 + SHORT((description[char_on].charpic)->width)/2;
@ -9170,8 +9173,8 @@ static void M_DrawSetupChoosePlayerMenu(void)
{ {
V_DrawNameTag( V_DrawNameTag(
x, y, V_CENTERNAMETAG, FRACUNIT, x, y, V_CENTERNAMETAG, FRACUNIT,
R_GetTranslationColormap(TC_DEFAULT, curtextcolor, 0), R_GetTranslationColormap(TC_DEFAULT, curtextcolor, GTC_CACHE),
R_GetTranslationColormap(TC_DEFAULT, curoutlinecolor, 0), R_GetTranslationColormap(TC_DEFAULT, curoutlinecolor, GTC_CACHE),
curtext curtext
); );
} }
@ -9193,7 +9196,7 @@ static void M_DrawSetupChoosePlayerMenu(void)
if (!prevtextcolor) if (!prevtextcolor)
prevtextcolor = charskin->prefcolor; prevtextcolor = charskin->prefcolor;
if (!prevoutlinecolor) if (!prevoutlinecolor)
prevoutlinecolor = Color_Opposite[charskin->prefcolor - 1][0]; prevoutlinecolor = col = skincolors[charskin->prefcolor].invcolor;
x = (ox - txsh) - w; x = (ox - txsh) - w;
if (prevpatch) if (prevpatch)
@ -9203,8 +9206,8 @@ static void M_DrawSetupChoosePlayerMenu(void)
{ {
V_DrawNameTag( V_DrawNameTag(
x, y, V_CENTERNAMETAG, FRACUNIT, x, y, V_CENTERNAMETAG, FRACUNIT,
R_GetTranslationColormap(TC_DEFAULT, prevtextcolor, 0), R_GetTranslationColormap(TC_DEFAULT, prevtextcolor, GTC_CACHE),
R_GetTranslationColormap(TC_DEFAULT, prevoutlinecolor, 0), R_GetTranslationColormap(TC_DEFAULT, prevoutlinecolor, GTC_CACHE),
prevtext prevtext
); );
} }
@ -9223,7 +9226,7 @@ static void M_DrawSetupChoosePlayerMenu(void)
if (!nexttextcolor) if (!nexttextcolor)
nexttextcolor = charskin->prefcolor; nexttextcolor = charskin->prefcolor;
if (!nextoutlinecolor) if (!nextoutlinecolor)
nextoutlinecolor = Color_Opposite[charskin->prefcolor - 1][0]; nextoutlinecolor = col = skincolors[charskin->prefcolor].invcolor;
x = (ox - txsh) + w; x = (ox - txsh) + w;
if (nextpatch) if (nextpatch)
@ -9233,8 +9236,8 @@ static void M_DrawSetupChoosePlayerMenu(void)
{ {
V_DrawNameTag( V_DrawNameTag(
x, y, V_CENTERNAMETAG, FRACUNIT, x, y, V_CENTERNAMETAG, FRACUNIT,
R_GetTranslationColormap(TC_DEFAULT, nexttextcolor, 0), R_GetTranslationColormap(TC_DEFAULT, nexttextcolor, GTC_CACHE),
R_GetTranslationColormap(TC_DEFAULT, nextoutlinecolor, 0), R_GetTranslationColormap(TC_DEFAULT, nextoutlinecolor, GTC_CACHE),
nexttext nexttext
); );
} }
@ -10822,7 +10825,8 @@ static void M_ServerOptions(INT32 choice)
OP_ServerOptionsMenu[ 3].status = IT_GRAYEDOUT; // Allow add-on downloading OP_ServerOptionsMenu[ 3].status = IT_GRAYEDOUT; // Allow add-on downloading
OP_ServerOptionsMenu[ 4].status = IT_GRAYEDOUT; // Allow players to join OP_ServerOptionsMenu[ 4].status = IT_GRAYEDOUT; // Allow players to join
OP_ServerOptionsMenu[35].status = IT_GRAYEDOUT; // Master server OP_ServerOptionsMenu[35].status = IT_GRAYEDOUT; // Master server
OP_ServerOptionsMenu[36].status = IT_GRAYEDOUT; // Attempts to resynchronise OP_ServerOptionsMenu[36].status = IT_GRAYEDOUT; // Minimum delay between joins
OP_ServerOptionsMenu[37].status = IT_GRAYEDOUT; // Attempts to resynchronise
} }
else else
{ {
@ -10834,14 +10838,15 @@ static void M_ServerOptions(INT32 choice)
? IT_GRAYEDOUT ? IT_GRAYEDOUT
: (IT_STRING | IT_CVAR | IT_CV_STRING)); : (IT_STRING | IT_CVAR | IT_CV_STRING));
OP_ServerOptionsMenu[36].status = IT_STRING | IT_CVAR; OP_ServerOptionsMenu[36].status = IT_STRING | IT_CVAR;
OP_ServerOptionsMenu[37].status = IT_STRING | IT_CVAR;
} }
#endif #endif
/* Disable fading because of different menu head. */ /* Disable fading because of different menu head. */
if (currentMenu == &OP_MainDef)/* from Options menu */ if (currentMenu == &OP_MainDef)/* from Options menu */
OP_ServerOptionsDef.menuid = MN_OP_MAIN + ( MN_OP_SERVER << 6 ); OP_ServerOptionsDef.menuid = MTREE2(MN_OP_MAIN, MN_OP_SERVER);
else/* from Multiplayer menu */ else/* from Multiplayer menu */
OP_ServerOptionsDef.menuid = MN_MP_MAIN + ( MN_MP_SERVER_OPTIONS << 6 ); OP_ServerOptionsDef.menuid = MTREE2(MN_MP_MAIN, MN_MP_SERVER_OPTIONS);
OP_ServerOptionsDef.prevMenu = currentMenu; OP_ServerOptionsDef.prevMenu = currentMenu;
M_SetupNextMenu(&OP_ServerOptionsDef); M_SetupNextMenu(&OP_ServerOptionsDef);
@ -11071,15 +11076,15 @@ static UINT8 multi_spr2;
// this is set before entering the MultiPlayer setup menu, // this is set before entering the MultiPlayer setup menu,
// for either player 1 or 2 // for either player 1 or 2
static char setupm_name[MAXPLAYERNAME+1]; static char setupm_name[MAXPLAYERNAME+1];
static player_t *setupm_player; static player_t *setupm_player;
static consvar_t *setupm_cvskin; static consvar_t *setupm_cvskin;
static consvar_t *setupm_cvcolor; static consvar_t *setupm_cvcolor;
static consvar_t *setupm_cvname; static consvar_t *setupm_cvname;
static consvar_t *setupm_cvdefaultskin; static consvar_t *setupm_cvdefaultskin;
static consvar_t *setupm_cvdefaultcolor; static consvar_t *setupm_cvdefaultcolor;
static INT32 setupm_fakeskin; static INT32 setupm_fakeskin;
static INT32 setupm_fakecolor; static menucolor_t *setupm_fakecolor;
static void M_DrawSetupMultiPlayerMenu(void) static void M_DrawSetupMultiPlayerMenu(void)
{ {
@ -11146,11 +11151,11 @@ static void M_DrawSetupMultiPlayerMenu(void)
sprdef = &skins[setupm_fakeskin].sprites[multi_spr2]; sprdef = &skins[setupm_fakeskin].sprites[multi_spr2];
if (!setupm_fakecolor || !sprdef->numframes) // should never happen but hey, who knows if (!setupm_fakecolor->color || !sprdef->numframes) // should never happen but hey, who knows
goto faildraw; goto faildraw;
// ok, draw player sprite for sure now // ok, draw player sprite for sure now
colormap = R_GetTranslationColormap(setupm_fakeskin, setupm_fakecolor, 0); colormap = R_GetTranslationColormap(setupm_fakeskin, setupm_fakecolor->color, 0);
if (multi_frame >= sprdef->numframes) if (multi_frame >= sprdef->numframes)
multi_frame = 0; multi_frame = 0;
@ -11196,11 +11201,11 @@ colordraw:
// draw color string // draw color string
V_DrawRightAlignedString(BASEVIDWIDTH - x, y, V_DrawRightAlignedString(BASEVIDWIDTH - x, y,
((MP_PlayerSetupMenu[2].status & IT_TYPE) == IT_SPACE ? V_TRANSLUCENT : 0)|(itemOn == 2 ? V_YELLOWMAP : 0)|V_ALLOWLOWERCASE, ((MP_PlayerSetupMenu[2].status & IT_TYPE) == IT_SPACE ? V_TRANSLUCENT : 0)|(itemOn == 2 ? V_YELLOWMAP : 0)|V_ALLOWLOWERCASE,
Color_Names[setupm_fakecolor]); skincolors[setupm_fakecolor->color].name);
if (itemOn == 2 && (MP_PlayerSetupMenu[2].status & IT_TYPE) != IT_SPACE) if (itemOn == 2 && (MP_PlayerSetupMenu[2].status & IT_TYPE) != IT_SPACE)
{ {
V_DrawCharacter(BASEVIDWIDTH - x - 10 - V_StringWidth(Color_Names[setupm_fakecolor], V_ALLOWLOWERCASE) - (skullAnimCounter/5), y, V_DrawCharacter(BASEVIDWIDTH - x - 10 - V_StringWidth(skincolors[setupm_fakecolor->color].name, V_ALLOWLOWERCASE) - (skullAnimCounter/5), y,
'\x1C' | V_YELLOWMAP, false); '\x1C' | V_YELLOWMAP, false);
V_DrawCharacter(BASEVIDWIDTH - x + 2 + (skullAnimCounter/5), y, V_DrawCharacter(BASEVIDWIDTH - x + 2 + (skullAnimCounter/5), y,
'\x1D' | V_YELLOWMAP, false); '\x1D' | V_YELLOWMAP, false);
@ -11210,25 +11215,39 @@ colordraw:
#define indexwidth 8 #define indexwidth 8
{ {
const INT32 colwidth = (282-charw)/(2*indexwidth); const INT32 numcolors = (282-charw)/(2*indexwidth); // Number of colors per side
INT32 i = -colwidth; INT32 w = indexwidth; // Width of a singular color block
INT16 col = setupm_fakecolor - colwidth; menucolor_t *mc = setupm_fakecolor->prev; // Last accessed color
INT32 w = indexwidth;
UINT8 h; UINT8 h;
INT16 i;
while (col < 1) // Draw color in the middle
col += MAXSKINCOLORS-1; x += numcolors*w;
while (i <= colwidth) for (h = 0; h < 16; h++)
{ V_DrawFill(x, y+h, charw, 1, skincolors[setupm_fakecolor->color].ramp[h]);
if (!(i++))
w = charw; //Draw colors from middle to left
else for (i=0; i<numcolors; i++) {
w = indexwidth; x -= w;
// Find accessible color before this one
while (!skincolors[mc->color].accessible)
mc = mc->prev;
for (h = 0; h < 16; h++) for (h = 0; h < 16; h++)
V_DrawFill(x, y+h, w, 1, Color_Index[col-1][h]); V_DrawFill(x, y+h, w, 1, skincolors[mc->color].ramp[h]);
if (++col >= MAXSKINCOLORS) mc = mc->prev;
col -= MAXSKINCOLORS-1; }
// Draw colors from middle to right
mc = setupm_fakecolor->next;
x += numcolors*w + charw;
for (i=0; i<numcolors; i++) {
// Find accessible color after this one
while (!skincolors[mc->color].accessible)
mc = mc->next;
for (h = 0; h < 16; h++)
V_DrawFill(x, y+h, w, 1, skincolors[mc->color].ramp[h]);
x += w; x += w;
mc = mc->next;
} }
} }
#undef charw #undef charw
@ -11239,7 +11258,7 @@ colordraw:
V_DrawString(x, y, V_DrawString(x, y,
((R_SkinAvailable(setupm_cvdefaultskin->string) != setupm_fakeskin ((R_SkinAvailable(setupm_cvdefaultskin->string) != setupm_fakeskin
|| setupm_cvdefaultcolor->value != setupm_fakecolor) || setupm_cvdefaultcolor->value != setupm_fakecolor->color)
? 0 ? 0
: V_TRANSLUCENT) : V_TRANSLUCENT)
| ((itemOn == 3) ? V_YELLOWMAP : 0), | ((itemOn == 3) ? V_YELLOWMAP : 0),
@ -11287,19 +11306,19 @@ static void M_HandleSetupMultiPlayer(INT32 choice)
else if (itemOn == 2) // player color else if (itemOn == 2) // player color
{ {
S_StartSound(NULL,sfx_menu1); // Tails S_StartSound(NULL,sfx_menu1); // Tails
setupm_fakecolor--; setupm_fakecolor = setupm_fakecolor->prev;
} }
break; break;
case KEY_ENTER: case KEY_ENTER:
if (itemOn == 3 if (itemOn == 3
&& (R_SkinAvailable(setupm_cvdefaultskin->string) != setupm_fakeskin && (R_SkinAvailable(setupm_cvdefaultskin->string) != setupm_fakeskin
|| setupm_cvdefaultcolor->value != setupm_fakecolor)) || setupm_cvdefaultcolor->value != setupm_fakecolor->color))
{ {
S_StartSound(NULL,sfx_strpst); S_StartSound(NULL,sfx_strpst);
// you know what? always putting these in the buffer won't hurt anything. // 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 \"%s\"\n",setupm_cvdefaultskin->name,skins[setupm_fakeskin].name));
COM_BufAddText (va("%s %d\n",setupm_cvdefaultcolor->name,setupm_fakecolor)); COM_BufAddText (va("%s %d\n",setupm_cvdefaultcolor->name,setupm_fakecolor->color));
break; break;
} }
/* FALLTHRU */ /* FALLTHRU */
@ -11320,7 +11339,7 @@ static void M_HandleSetupMultiPlayer(INT32 choice)
else if (itemOn == 2) // player color else if (itemOn == 2) // player color
{ {
S_StartSound(NULL,sfx_menu1); // Tails S_StartSound(NULL,sfx_menu1); // Tails
setupm_fakecolor++; setupm_fakecolor = setupm_fakecolor->next;
} }
break; break;
@ -11336,11 +11355,13 @@ static void M_HandleSetupMultiPlayer(INT32 choice)
} }
else if (itemOn == 2) else if (itemOn == 2)
{ {
UINT8 col = skins[setupm_fakeskin].prefcolor; UINT16 col = skins[setupm_fakeskin].prefcolor;
if (setupm_fakecolor != col) if ((setupm_fakecolor->color != col) && skincolors[col].accessible)
{ {
S_StartSound(NULL,sfx_menu1); // Tails S_StartSound(NULL,sfx_menu1); // Tails
setupm_fakecolor = col; for (setupm_fakecolor=menucolorhead;;setupm_fakecolor=setupm_fakecolor->next)
if (setupm_fakecolor->color == col || setupm_fakecolor == menucolortail)
break;
} }
} }
break; break;
@ -11368,10 +11389,14 @@ static void M_HandleSetupMultiPlayer(INT32 choice)
} }
// check color // check color
if (setupm_fakecolor < 1) if (itemOn == 2 && !skincolors[setupm_fakecolor->color].accessible) {
setupm_fakecolor = MAXSKINCOLORS-1; if (choice == KEY_LEFTARROW)
if (setupm_fakecolor > MAXSKINCOLORS-1) while (!skincolors[setupm_fakecolor->color].accessible)
setupm_fakecolor = 1; setupm_fakecolor = setupm_fakecolor->prev;
else if (choice == KEY_RIGHTARROW || choice == KEY_ENTER)
while (!skincolors[setupm_fakecolor->color].accessible)
setupm_fakecolor = setupm_fakecolor->next;
}
if (exitmenu) if (exitmenu)
{ {
@ -11403,7 +11428,10 @@ static void M_SetupMultiPlayer(INT32 choice)
setupm_fakeskin = R_SkinAvailable(setupm_cvskin->string); setupm_fakeskin = R_SkinAvailable(setupm_cvskin->string);
if (setupm_fakeskin == -1) if (setupm_fakeskin == -1)
setupm_fakeskin = 0; setupm_fakeskin = 0;
setupm_fakecolor = setupm_cvcolor->value;
for (setupm_fakecolor=menucolorhead;;setupm_fakecolor=setupm_fakecolor->next)
if (setupm_fakecolor->color == setupm_cvcolor->value || setupm_fakecolor == menucolortail)
break;
// disable skin changes if we can't actually change skins // disable skin changes if we can't actually change skins
if (!CanChangeSkin(consoleplayer)) if (!CanChangeSkin(consoleplayer))
@ -11444,7 +11472,10 @@ static void M_SetupMultiPlayer2(INT32 choice)
setupm_fakeskin = R_SkinAvailable(setupm_cvskin->string); setupm_fakeskin = R_SkinAvailable(setupm_cvskin->string);
if (setupm_fakeskin == -1) if (setupm_fakeskin == -1)
setupm_fakeskin = 0; setupm_fakeskin = 0;
setupm_fakecolor = setupm_cvcolor->value;
for (setupm_fakecolor=menucolorhead;;setupm_fakecolor=setupm_fakecolor->next)
if (setupm_fakecolor->color == setupm_cvcolor->value || setupm_fakecolor == menucolortail)
break;
// disable skin changes if we can't actually change skins // disable skin changes if we can't actually change skins
if (splitscreen && !CanChangeSkin(secondarydisplayplayer)) if (splitscreen && !CanChangeSkin(secondarydisplayplayer))
@ -11476,12 +11507,181 @@ static boolean M_QuitMultiPlayerMenu(void)
setupm_name[l] =0; setupm_name[l] =0;
COM_BufAddText (va("%s \"%s\"\n",setupm_cvname->name,setupm_name)); COM_BufAddText (va("%s \"%s\"\n",setupm_cvname->name,setupm_name));
} }
// you know what? always putting these in the buffer won't hurt anything.
COM_BufAddText (va("%s \"%s\"\n",setupm_cvskin->name,skins[setupm_fakeskin].name)); COM_BufAddText (va("%s \"%s\"\n",setupm_cvskin->name,skins[setupm_fakeskin].name));
COM_BufAddText (va("%s %d\n",setupm_cvcolor->name,setupm_fakecolor)); // send color if changed
if (setupm_fakecolor->color != setupm_cvcolor->value)
COM_BufAddText (va("%s %d\n",setupm_cvcolor->name,setupm_fakecolor->color));
return true; return true;
} }
void M_AddMenuColor(UINT16 color) {
menucolor_t *c;
if (color >= numskincolors) {
CONS_Printf("M_AddMenuColor: color %d does not exist.",color);
return;
}
c = (menucolor_t *)malloc(sizeof(menucolor_t));
c->color = color;
if (menucolorhead == NULL) {
c->next = c;
c->prev = c;
menucolorhead = c;
menucolortail = c;
} else {
c->next = menucolorhead;
c->prev = menucolortail;
menucolortail->next = c;
menucolorhead->prev = c;
menucolortail = c;
}
}
void M_MoveColorBefore(UINT16 color, UINT16 targ) {
menucolor_t *look, *c = NULL, *t = NULL;
if (color == targ)
return;
if (color >= numskincolors) {
CONS_Printf("M_MoveColorBefore: color %d does not exist.",color);
return;
}
if (targ >= numskincolors) {
CONS_Printf("M_MoveColorBefore: target color %d does not exist.",targ);
return;
}
for (look=menucolorhead;;look=look->next) {
if (look->color == color)
c = look;
else if (look->color == targ)
t = look;
if (c != NULL && t != NULL)
break;
if (look==menucolortail)
return;
}
if (c == t->prev)
return;
if (t==menucolorhead)
menucolorhead = c;
if (c==menucolortail)
menucolortail = c->prev;
c->prev->next = c->next;
c->next->prev = c->prev;
c->prev = t->prev;
c->next = t;
t->prev->next = c;
t->prev = c;
}
void M_MoveColorAfter(UINT16 color, UINT16 targ) {
menucolor_t *look, *c = NULL, *t = NULL;
if (color == targ)
return;
if (color >= numskincolors) {
CONS_Printf("M_MoveColorAfter: color %d does not exist.\n",color);
return;
}
if (targ >= numskincolors) {
CONS_Printf("M_MoveColorAfter: target color %d does not exist.\n",targ);
return;
}
for (look=menucolorhead;;look=look->next) {
if (look->color == color)
c = look;
else if (look->color == targ)
t = look;
if (c != NULL && t != NULL)
break;
if (look==menucolortail)
return;
}
if (t == c->prev)
return;
if (t==menucolortail)
menucolortail = c;
else if (c==menucolortail)
menucolortail = c->prev;
c->prev->next = c->next;
c->next->prev = c->prev;
c->next = t->next;
c->prev = t;
t->next->prev = c;
t->next = c;
}
UINT16 M_GetColorBefore(UINT16 color) {
menucolor_t *look;
if (color >= numskincolors) {
CONS_Printf("M_GetColorBefore: color %d does not exist.\n",color);
return 0;
}
for (look=menucolorhead;;look=look->next) {
if (look->color == color)
return look->prev->color;
if (look==menucolortail)
return 0;
}
}
UINT16 M_GetColorAfter(UINT16 color) {
menucolor_t *look;
if (color >= numskincolors) {
CONS_Printf("M_GetColorAfter: color %d does not exist.\n",color);
return 0;
}
for (look=menucolorhead;;look=look->next) {
if (look->color == color)
return look->next->color;
if (look==menucolortail)
return 0;
}
}
void M_InitPlayerSetupColors(void) {
UINT8 i;
numskincolors = SKINCOLOR_FIRSTFREESLOT;
menucolorhead = menucolortail = NULL;
for (i=0; i<numskincolors; i++)
M_AddMenuColor(i);
}
void M_FreePlayerSetupColors(void) {
menucolor_t *look = menucolorhead, *tmp;
if (menucolorhead==NULL)
return;
while (true) {
if (look != menucolortail) {
tmp = look;
look = look->next;
free(tmp);
} else {
free(look);
return;
}
}
menucolorhead = menucolortail = NULL;
}
// ================= // =================
// DATA OPTIONS MENU // DATA OPTIONS MENU
// ================= // =================
@ -11758,8 +11958,8 @@ static void M_Setup1PControlsMenu(INT32 choice)
OP_ChangeControlsMenu[27+3].status = IT_CALL|IT_STRING2; OP_ChangeControlsMenu[27+3].status = IT_CALL|IT_STRING2;
OP_ChangeControlsDef.prevMenu = &OP_P1ControlsDef; OP_ChangeControlsDef.prevMenu = &OP_P1ControlsDef;
OP_ChangeControlsDef.menuid &= ~(((1 << MENUBITS) - 1) << MENUBITS); // remove first level (<< 6) OP_ChangeControlsDef.menuid &= ~(((1 << MENUBITS) - 1) << MENUBITS); // remove second level
OP_ChangeControlsDef.menuid |= MN_OP_P1CONTROLS << MENUBITS; // combine first level (<< 6) OP_ChangeControlsDef.menuid |= MN_OP_P1CONTROLS << MENUBITS; // combine second level
M_SetupNextMenu(&OP_ChangeControlsDef); M_SetupNextMenu(&OP_ChangeControlsDef);
} }
@ -11789,8 +11989,8 @@ static void M_Setup2PControlsMenu(INT32 choice)
OP_ChangeControlsMenu[27+3].status = IT_GRAYEDOUT2; OP_ChangeControlsMenu[27+3].status = IT_GRAYEDOUT2;
OP_ChangeControlsDef.prevMenu = &OP_P2ControlsDef; OP_ChangeControlsDef.prevMenu = &OP_P2ControlsDef;
OP_ChangeControlsDef.menuid &= ~(((1 << MENUBITS) - 1) << MENUBITS); // remove first level (<< 6) OP_ChangeControlsDef.menuid &= ~(((1 << MENUBITS) - 1) << MENUBITS); // remove second level
OP_ChangeControlsDef.menuid |= MN_OP_P2CONTROLS << MENUBITS; // combine first level (<< 6) OP_ChangeControlsDef.menuid |= MN_OP_P2CONTROLS << MENUBITS; // combine second level
M_SetupNextMenu(&OP_ChangeControlsDef); M_SetupNextMenu(&OP_ChangeControlsDef);
} }

View File

@ -31,6 +31,9 @@
#define MENUBITS 6 #define MENUBITS 6
// Menu IDs sectioned by numeric places to signify hierarchy // Menu IDs sectioned by numeric places to signify hierarchy
/**
* IF YOU MODIFY THIS, MODIFY MENUTYPES_LIST[] IN dehacked.c TO MATCH.
*/
typedef enum typedef enum
{ {
MN_NONE, MN_NONE,
@ -129,6 +132,9 @@ typedef enum
MN_SPECIAL, MN_SPECIAL,
NUMMENUTYPES, NUMMENUTYPES,
} menutype_t; // up to 63; MN_SPECIAL = 53 } menutype_t; // up to 63; MN_SPECIAL = 53
#define MTREE2(a,b) (a | (b<<MENUBITS))
#define MTREE3(a,b,c) MTREE2(a, MTREE2(b,c))
#define MTREE4(a,b,c,d) MTREE2(a, MTREE3(b,c,d))
typedef struct typedef struct
{ {
@ -349,11 +355,11 @@ typedef struct
// new character select // new character select
char displayname[SKINNAMESIZE+1]; char displayname[SKINNAMESIZE+1];
SINT8 skinnum[2]; SINT8 skinnum[2];
UINT8 oppositecolor; UINT16 oppositecolor;
char nametag[8]; char nametag[8];
patch_t *namepic; patch_t *namepic;
UINT8 tagtextcolor; UINT16 tagtextcolor;
UINT8 tagoutlinecolor; UINT16 tagoutlinecolor;
} description_t; } description_t;
// level select platter // level select platter
@ -437,6 +443,23 @@ void Addons_option_Onchange(void);
// Moviemode menu updating // Moviemode menu updating
void Moviemode_option_Onchange(void); void Moviemode_option_Onchange(void);
// Player Setup menu colors linked list
typedef struct menucolor_s {
struct menucolor_s *next;
struct menucolor_s *prev;
UINT16 color;
} menucolor_t;
extern menucolor_t *menucolorhead, *menucolortail;
void M_AddMenuColor(UINT16 color);
void M_MoveColorBefore(UINT16 color, UINT16 targ);
void M_MoveColorAfter(UINT16 color, UINT16 targ);
UINT16 M_GetColorBefore(UINT16 color);
UINT16 M_GetColorAfter(UINT16 color);
void M_InitPlayerSetupColors(void);
void M_FreePlayerSetupColors(void);
// These defines make it a little easier to make menus // These defines make it a little easier to make menus
#define DEFAULTMENUSTYLE(id, header, source, prev, x, y)\ #define DEFAULTMENUSTYLE(id, header, source, prev, x, y)\
{\ {\

View File

@ -68,7 +68,7 @@ extern consvar_t cv_masterserver, cv_servername;
// < 0 to not connect (usually -1) (offline mode) // < 0 to not connect (usually -1) (offline mode)
// == 0 to show all rooms, not a valid hosting room // == 0 to show all rooms, not a valid hosting room
// anything else is whatever room the MS assigns to that number (online mode) // anything else is whatever room the MS assigns to that number (online mode)
INT16 ms_RoomId; extern INT16 ms_RoomId;
const char *GetMasterServerPort(void); const char *GetMasterServerPort(void);
const char *GetMasterServerIP(void); const char *GetMasterServerIP(void);

View File

@ -395,7 +395,7 @@ INT32 EV_DoCeiling(line_t *line, ceiling_e type)
sector_t *sec; sector_t *sec;
ceiling_t *ceiling; ceiling_t *ceiling;
while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0) while ((secnum = P_FindSectorFromTag(line->tag,secnum)) >= 0)
{ {
sec = &sectors[secnum]; sec = &sectors[secnum];
@ -615,7 +615,7 @@ INT32 EV_DoCrush(line_t *line, ceiling_e type)
sector_t *sec; sector_t *sec;
ceiling_t *ceiling; ceiling_t *ceiling;
while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0) while ((secnum = P_FindSectorFromTag(line->tag,secnum)) >= 0)
{ {
sec = &sectors[secnum]; sec = &sectors[secnum];

View File

@ -312,6 +312,7 @@ void A_RolloutRock(mobj_t *actor);
void A_DragonbomberSpawn(mobj_t *actor); void A_DragonbomberSpawn(mobj_t *actor);
void A_DragonWing(mobj_t *actor); void A_DragonWing(mobj_t *actor);
void A_DragonSegment(mobj_t *actor); void A_DragonSegment(mobj_t *actor);
void A_ChangeHeight(mobj_t *actor);
//for p_enemy.c //for p_enemy.c
@ -2990,6 +2991,19 @@ void A_Boss1Laser(mobj_t *actor)
angle_t angle; angle_t angle;
mobj_t *point; mobj_t *point;
tic_t dur; tic_t dur;
static const UINT8 LASERCOLORS[] =
{
SKINCOLOR_SUPERRED3,
SKINCOLOR_SUPERRED4,
SKINCOLOR_SUPERRED5,
SKINCOLOR_FLAME,
SKINCOLOR_RED,
SKINCOLOR_RED,
SKINCOLOR_FLAME,
SKINCOLOR_SUPERRED5,
SKINCOLOR_SUPERRED4,
SKINCOLOR_SUPERRED3,
};
if (LUA_CallAction("A_Boss1Laser", actor)) if (LUA_CallAction("A_Boss1Laser", actor))
return; return;
@ -3064,7 +3078,7 @@ void A_Boss1Laser(mobj_t *actor)
point = P_SpawnMobj(x, y, z, locvar1); point = P_SpawnMobj(x, y, z, locvar1);
P_SetTarget(&point->target, actor); P_SetTarget(&point->target, actor);
point->angle = actor->angle; point->angle = actor->angle;
speed = point->radius*2; speed = point->radius;
point->momz = FixedMul(FINECOSINE(angle>>ANGLETOFINESHIFT), speed); point->momz = FixedMul(FINECOSINE(angle>>ANGLETOFINESHIFT), speed);
point->momx = FixedMul(FINESINE(angle>>ANGLETOFINESHIFT), FixedMul(FINECOSINE(point->angle>>ANGLETOFINESHIFT), speed)); point->momx = FixedMul(FINESINE(angle>>ANGLETOFINESHIFT), FixedMul(FINECOSINE(point->angle>>ANGLETOFINESHIFT), speed));
point->momy = FixedMul(FINESINE(angle>>ANGLETOFINESHIFT), FixedMul(FINESINE(point->angle>>ANGLETOFINESHIFT), speed)); point->momy = FixedMul(FINESINE(angle>>ANGLETOFINESHIFT), FixedMul(FINESINE(point->angle>>ANGLETOFINESHIFT), speed));
@ -3073,23 +3087,69 @@ void A_Boss1Laser(mobj_t *actor)
{ {
mobj_t *mo = P_SpawnMobj(point->x, point->y, point->z, point->type); mobj_t *mo = P_SpawnMobj(point->x, point->y, point->z, point->type);
mo->angle = point->angle; mo->angle = point->angle;
mo->color = LASERCOLORS[((UINT8)(i + 3*dur) >> 2) % sizeof(LASERCOLORS)]; // codeing
P_UnsetThingPosition(mo); P_UnsetThingPosition(mo);
mo->flags = MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY; mo->flags = MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY;
P_SetThingPosition(mo); P_SetThingPosition(mo);
if (dur & 1 && mo->info->missilestate)
{
P_SetMobjState(mo, mo->info->missilestate);
if (mo->info->meleestate)
{
mobj_t *mo2 = P_SpawnMobjFromMobj(mo, 0, 0, 0, MT_PARTICLE);
mo2->flags2 |= MF2_LINKDRAW;
P_SetTarget(&mo2->tracer, actor);
P_SetMobjState(mo2, mo->info->meleestate);
}
}
if (dur == 1)
P_SpawnGhostMobj(mo);
x = point->x, y = point->y, z = point->z; x = point->x, y = point->y, z = point->z;
if (P_RailThinker(point)) if (P_RailThinker(point))
break; break;
} }
x += point->momx;
y += point->momy;
floorz = P_FloorzAtPos(x, y, z, mobjinfo[MT_EGGMOBILE_FIRE].height); floorz = P_FloorzAtPos(x, y, z, mobjinfo[MT_EGGMOBILE_FIRE].height);
if (z - floorz < mobjinfo[MT_EGGMOBILE_FIRE].height>>1) if (z - floorz < mobjinfo[MT_EGGMOBILE_FIRE].height>>1 && dur & 1)
{ {
point = P_SpawnMobj(x, y, floorz+1, MT_EGGMOBILE_FIRE); point = P_SpawnMobj(x, y, floorz, MT_EGGMOBILE_FIRE);
point->angle = actor->angle;
point->destscale = actor->scale;
P_SetScale(point, point->destscale);
P_SetTarget(&point->target, actor); P_SetTarget(&point->target, actor);
point->destscale = 3*FRACUNIT; P_MobjCheckWater(point);
point->scalespeed = FRACUNIT>>2; if (point->eflags & (MFE_UNDERWATER|MFE_TOUCHWATER))
point->fuse = TICRATE; {
for (i = 0; i < 2; i++)
{
UINT8 size = 3;
mobj_t *steam = P_SpawnMobj(x, y, point->watertop - size*mobjinfo[MT_DUST].height, MT_DUST);
P_SetScale(steam, size*actor->scale);
P_SetObjectMomZ(steam, FRACUNIT + 2*P_RandomFixed(), true);
P_InstaThrust(steam, FixedAngle(P_RandomKey(360)*FRACUNIT), 2*P_RandomFixed());
if (point->info->painsound)
S_StartSound(steam, point->info->painsound);
}
}
else
{
fixed_t distx = P_ReturnThrustX(point, point->angle, point->radius);
fixed_t disty = P_ReturnThrustY(point, point->angle, point->radius);
if (P_TryMove(point, point->x + distx, point->y + disty, false) // prevents the sprite from clipping into the wall or dangling off ledges
&& P_TryMove(point, point->x - 2*distx, point->y - 2*disty, false)
&& P_TryMove(point, point->x + distx, point->y + disty, false))
{
if (point->info->seesound)
S_StartSound(point, point->info->seesound);
}
else
P_RemoveMobj(point);
}
} }
if (dur > 1) if (dur > 1)
@ -5046,13 +5106,13 @@ void A_SignPlayer(mobj_t *actor)
INT32 locvar2 = var2; INT32 locvar2 = var2;
skin_t *skin = NULL; skin_t *skin = NULL;
mobj_t *ov; mobj_t *ov;
UINT8 facecolor, signcolor = (UINT8)locvar2; UINT16 facecolor, signcolor = (UINT16)locvar2;
UINT32 signframe = states[actor->info->raisestate].frame; UINT32 signframe = states[actor->info->raisestate].frame;
if (LUA_CallAction("A_SignPlayer", actor)) if (LUA_CallAction("A_SignPlayer", actor))
return; return;
if (actor->tracer == NULL || locvar1 < -3 || locvar1 >= numskins || signcolor >= MAXTRANSLATIONS) if (actor->tracer == NULL || locvar1 < -3 || locvar1 >= numskins || signcolor >= numskincolors)
return; return;
// if no face overlay, spawn one // if no face overlay, spawn one
@ -5083,7 +5143,7 @@ void A_SignPlayer(mobj_t *actor)
else if ((actor->target->player->skincolor == skin->prefcolor) && (skin->prefoppositecolor)) // Set it as the skin's preferred oppositecolor? else if ((actor->target->player->skincolor == skin->prefcolor) && (skin->prefoppositecolor)) // Set it as the skin's preferred oppositecolor?
signcolor = skin->prefoppositecolor; signcolor = skin->prefoppositecolor;
else if (actor->target->player->skincolor) // Set the sign to be an appropriate background color for this player's skincolor. 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]; signcolor = skincolors[actor->target->player->skincolor].invcolor;
else else
signcolor = SKINCOLOR_NONE; signcolor = SKINCOLOR_NONE;
} }
@ -5121,7 +5181,7 @@ void A_SignPlayer(mobj_t *actor)
else if (skin->prefoppositecolor) else if (skin->prefoppositecolor)
signcolor = skin->prefoppositecolor; signcolor = skin->prefoppositecolor;
else if (facecolor) else if (facecolor)
signcolor = Color_Opposite[facecolor - 1][0]; signcolor = skincolors[facecolor].invcolor;
} }
if (skin) if (skin)
@ -5152,19 +5212,8 @@ void A_SignPlayer(mobj_t *actor)
} }
actor->tracer->color = signcolor; actor->tracer->color = signcolor;
/* if (signcolor && signcolor < numskincolors)
If you're here from the comment above Color_Opposite, signframe += (15 - skincolors[signcolor].invshade);
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; actor->tracer->frame = signframe;
} }
@ -8744,10 +8793,10 @@ void A_ChangeColorRelative(mobj_t *actor)
{ {
// Have you ever seen anything so hideous? // Have you ever seen anything so hideous?
if (actor->target) if (actor->target)
actor->color = (UINT8)(actor->color + actor->target->color); actor->color = (UINT16)(actor->color + actor->target->color);
} }
else else
actor->color = (UINT8)(actor->color + locvar2); actor->color = (UINT16)(actor->color + locvar2);
} }
// Function: A_ChangeColorAbsolute // Function: A_ChangeColorAbsolute
@ -8771,7 +8820,7 @@ void A_ChangeColorAbsolute(mobj_t *actor)
actor->color = actor->target->color; actor->color = actor->target->color;
} }
else else
actor->color = (UINT8)locvar2; actor->color = (UINT16)locvar2;
} }
// Function: A_Dye // Function: A_Dye
@ -8788,25 +8837,23 @@ void A_Dye(mobj_t *actor)
mobj_t *target = ((locvar1 && actor->target) ? actor->target : actor); mobj_t *target = ((locvar1 && actor->target) ? actor->target : actor);
UINT8 color = (UINT8)locvar2; UINT8 color = (UINT8)locvar2;
#ifdef HAVE_BLUA
if (LUA_CallAction("A_Dye", actor)) if (LUA_CallAction("A_Dye", actor))
return; return;
#endif if (color >= numskincolors)
if (color >= MAXTRANSLATIONS)
return; return;
if (!color) if (!color)
target->colorized = false; target->colorized = false;
else else
target->colorized = true; target->colorized = true;
// What if it's a player? // What if it's a player?
if (target->player) if (target->player)
{ {
target->player->powers[pw_dye] = color; target->player->powers[pw_dye] = color;
return; return;
} }
target->color = color; target->color = color;
} }
@ -9649,6 +9696,9 @@ void A_SplitShot(mobj_t *actor)
if (LUA_CallAction("A_SplitShot", actor)) if (LUA_CallAction("A_SplitShot", actor))
return; return;
if (!actor->target)
return;
A_FaceTarget(actor); A_FaceTarget(actor);
{ {
const angle_t an = (actor->angle + ANGLE_90) >> ANGLETOFINESHIFT; const angle_t an = (actor->angle + ANGLE_90) >> ANGLETOFINESHIFT;
@ -12642,8 +12692,8 @@ void A_Boss5FindWaypoint(mobj_t *actor)
else // locvar1 == 0 else // locvar1 == 0
{ {
fixed_t hackoffset = P_MobjFlip(actor)*56*FRACUNIT; fixed_t hackoffset = P_MobjFlip(actor)*56*FRACUNIT;
INT32 numwaypoints = 0; INT32 numfangwaypoints = 0;
mobj_t **waypoints; mobj_t **fangwaypoints;
INT32 key; INT32 key;
actor->z += hackoffset; actor->z += hackoffset;
@ -12668,7 +12718,7 @@ void A_Boss5FindWaypoint(mobj_t *actor)
continue; continue;
if (!P_CheckSight(actor, mapthings[i].mobj)) if (!P_CheckSight(actor, mapthings[i].mobj))
continue; continue;
numwaypoints++; numfangwaypoints++;
} }
// players also count as waypoints apparently // players also count as waypoints apparently
@ -12690,11 +12740,11 @@ void A_Boss5FindWaypoint(mobj_t *actor)
continue; continue;
if (!P_CheckSight(actor, players[i].mo)) if (!P_CheckSight(actor, players[i].mo))
continue; continue;
numwaypoints++; numfangwaypoints++;
} }
} }
if (!numwaypoints) if (!numfangwaypoints)
{ {
// restore z position // restore z position
actor->z -= hackoffset; actor->z -= hackoffset;
@ -12702,8 +12752,8 @@ void A_Boss5FindWaypoint(mobj_t *actor)
} }
// allocate the table and reset count to zero // allocate the table and reset count to zero
waypoints = Z_Calloc(sizeof(*waypoints)*numwaypoints, PU_STATIC, NULL); fangwaypoints = Z_Calloc(sizeof(*waypoints)*numfangwaypoints, PU_STATIC, NULL);
numwaypoints = 0; numfangwaypoints = 0;
// now find them again and add them to the table! // now find them again and add them to the table!
for (i = 0; i < nummapthings; i++) for (i = 0; i < nummapthings; i++)
@ -12728,7 +12778,7 @@ void A_Boss5FindWaypoint(mobj_t *actor)
} }
if (!P_CheckSight(actor, mapthings[i].mobj)) if (!P_CheckSight(actor, mapthings[i].mobj))
continue; continue;
waypoints[numwaypoints++] = mapthings[i].mobj; fangwaypoints[numfangwaypoints++] = mapthings[i].mobj;
} }
if (actor->extravalue2 > 1) if (actor->extravalue2 > 1)
@ -12749,25 +12799,25 @@ void A_Boss5FindWaypoint(mobj_t *actor)
continue; continue;
if (!P_CheckSight(actor, players[i].mo)) if (!P_CheckSight(actor, players[i].mo))
continue; continue;
waypoints[numwaypoints++] = players[i].mo; fangwaypoints[numfangwaypoints++] = players[i].mo;
} }
} }
// restore z position // restore z position
actor->z -= hackoffset; actor->z -= hackoffset;
if (!numwaypoints) if (!numfangwaypoints)
{ {
Z_Free(waypoints); // free table Z_Free(fangwaypoints); // free table
goto nowaypoints; // ??? goto nowaypoints; // ???
} }
key = P_RandomKey(numwaypoints); key = P_RandomKey(numfangwaypoints);
P_SetTarget(&actor->tracer, waypoints[key]); P_SetTarget(&actor->tracer, fangwaypoints[key]);
if (actor->tracer->type == MT_FANGWAYPOINT) if (actor->tracer->type == MT_FANGWAYPOINT)
actor->tracer->reactiontime = numwaypoints/4; // Monster Iestyn: is this how it should be? I count center waypoints as waypoints unlike the original Lua script actor->tracer->reactiontime = numfangwaypoints/4; // Monster Iestyn: is this how it should be? I count center waypoints as waypoints unlike the original Lua script
Z_Free(waypoints); // free table Z_Free(fangwaypoints); // free table
} }
// now face the tracer you just set! // now face the tracer you just set!
@ -13311,8 +13361,9 @@ static boolean PIT_DustDevilLaunch(mobj_t *thing)
P_ResetPlayer(player); P_ResetPlayer(player);
A_PlayActiveSound(dustdevil); A_PlayActiveSound(dustdevil);
} }
player->powers[pw_carry] = CR_DUSTDEVIL;
player->powers[pw_nocontrol] = 2; player->powers[pw_nocontrol] = 2;
player->drawangle += ANG20; P_SetTarget(&thing->tracer, dustdevil);
P_SetPlayerMobjState(thing, S_PLAY_PAIN); P_SetPlayerMobjState(thing, S_PLAY_PAIN);
if (dist > dragamount) if (dist > dragamount)
@ -13332,7 +13383,9 @@ static boolean PIT_DustDevilLaunch(mobj_t *thing)
P_ResetPlayer(player); P_ResetPlayer(player);
thing->z = dustdevil->z + dustdevil->height; thing->z = dustdevil->z + dustdevil->height;
thrust = 20 * FRACUNIT; thrust = 20 * FRACUNIT;
player->powers[pw_carry] = CR_NONE;
player->powers[pw_nocontrol] = 0; player->powers[pw_nocontrol] = 0;
P_SetTarget(&thing->tracer, NULL);
S_StartSound(thing, sfx_wdjump); S_StartSound(thing, sfx_wdjump);
P_SetPlayerMobjState(thing, S_PLAY_FALL); P_SetPlayerMobjState(thing, S_PLAY_FALL);
} }
@ -14409,3 +14462,43 @@ void A_DragonSegment(mobj_t *actor)
actor->angle = hangle; actor->angle = hangle;
P_TeleportMove(actor, target->x + xdist, target->y + ydist, target->z + zdist); P_TeleportMove(actor, target->x + xdist, target->y + ydist, target->z + zdist);
} }
// Function: A_ChangeHeight
//
// Description: Changes the actor's height by var1
//
// var1 = height
// var2 =
// &1: height is absolute
// &2: scale with actor's scale
//
void A_ChangeHeight(mobj_t *actor)
{
INT32 locvar1 = var1;
INT32 locvar2 = var2;
fixed_t height = locvar1;
boolean reverse;
if (LUA_CallAction("A_ChangeHeight", actor))
return;
reverse = (actor->eflags & MFE_VERTICALFLIP) || (actor->flags2 & MF2_OBJECTFLIP);
if (locvar2 & 2)
height = FixedMul(height, actor->scale);
P_UnsetThingPosition(actor);
if (locvar2 & 1)
{
if (reverse)
actor->z += actor->height - locvar1;
actor->height = locvar1;
}
else
{
if (reverse)
actor->z -= locvar1;
actor->height += locvar1;
}
P_SetThingPosition(actor);
}

View File

@ -696,10 +696,20 @@ void T_BounceCheese(bouncecheese_t *bouncer)
return; return;
} }
T_MovePlane(bouncer->sector, bouncer->speed/2, bouncer->sector->ceilingheight - if (bouncer->speed >= 0) // move floor first to fix height desync and any bizarre bugs following that
70*FRACUNIT, false, true, -1); // move ceiling {
T_MovePlane(bouncer->sector, bouncer->speed/2, bouncer->sector->floorheight - 70*FRACUNIT, T_MovePlane(bouncer->sector, bouncer->speed/2, bouncer->sector->floorheight - 70*FRACUNIT,
false, false, -1); // move floor false, false, -1); // move floor
T_MovePlane(bouncer->sector, bouncer->speed/2, bouncer->sector->ceilingheight -
70*FRACUNIT, false, true, -1); // move ceiling
}
else
{
T_MovePlane(bouncer->sector, bouncer->speed/2, bouncer->sector->ceilingheight -
70*FRACUNIT, false, true, -1); // move ceiling
T_MovePlane(bouncer->sector, bouncer->speed/2, bouncer->sector->floorheight - 70*FRACUNIT,
false, false, -1); // move floor
}
bouncer->sector->floorspeed = -bouncer->speed/2; bouncer->sector->floorspeed = -bouncer->speed/2;
bouncer->sector->ceilspeed = 42; bouncer->sector->ceilspeed = 42;
@ -757,7 +767,7 @@ void T_BounceCheese(bouncecheese_t *bouncer)
// T_StartCrumble //////////////////////////////// // T_StartCrumble ////////////////////////////////
////////////////////////////////////////////////// //////////////////////////////////////////////////
// Crumbling platform Tails 03-11-2002 // Crumbling platform Tails 03-11-2002
void T_StartCrumble(elevator_t *elevator) void T_StartCrumble(crumble_t *crumble)
{ {
ffloor_t *rover; ffloor_t *rover;
sector_t *sector; sector_t *sector;
@ -765,84 +775,96 @@ void T_StartCrumble(elevator_t *elevator)
// Once done, the no-return thinker just sits there, // Once done, the no-return thinker just sits there,
// constantly 'returning'... kind of an oxymoron, isn't it? // constantly 'returning'... kind of an oxymoron, isn't it?
if (((elevator->floordestheight == 1 && elevator->direction == -1) if ((((crumble->flags & CF_REVERSE) && crumble->direction == -1)
|| (elevator->floordestheight == 0 && elevator->direction == 1)) || (!(crumble->flags & CF_REVERSE) && crumble->direction == 1))
&& elevator->type == elevateContinuous) // No return crumbler && !(crumble->flags & CF_RETURN))
{ {
elevator->sector->ceilspeed = 0; crumble->sector->ceilspeed = 0;
elevator->sector->floorspeed = 0; crumble->sector->floorspeed = 0;
return; return;
} }
if (elevator->distance != 0) if (crumble->timer != 0)
{ {
if (elevator->distance > 0) // Count down the timer if (crumble->timer > 0) // Count down the timer
{ {
elevator->distance--; if (--crumble->timer <= 0)
if (elevator->distance <= 0) crumble->timer = -15*TICRATE; // Timer until platform returns to original position.
elevator->distance = -15*TICRATE; // Timer until platform returns to original position.
else else
{ {
// Timer isn't up yet, so just keep waiting. // Timer isn't up yet, so just keep waiting.
elevator->sector->ceilspeed = 0; crumble->sector->ceilspeed = 0;
elevator->sector->floorspeed = 0; crumble->sector->floorspeed = 0;
return; return;
} }
} }
else if (++elevator->distance == 0) // Reposition back to original spot else if (++crumble->timer == 0) // Reposition back to original spot
{ {
for (i = -1; (i = P_FindSectorFromTag(elevator->sourceline->tag, i)) >= 0 ;) for (i = -1; (i = P_FindSectorFromTag(crumble->sourceline->tag, i)) >= 0 ;)
{ {
sector = &sectors[i]; sector = &sectors[i];
for (rover = sector->ffloors; rover; rover = rover->next) for (rover = sector->ffloors; rover; rover = rover->next)
{ {
if (rover->flags & FF_CRUMBLE && rover->flags & FF_FLOATBOB if (!(rover->flags & FF_CRUMBLE))
&& rover->master == elevator->sourceline) continue;
{
rover->alpha = elevator->origspeed;
if (rover->alpha == 0xff) if (!(rover->flags & FF_FLOATBOB))
rover->flags &= ~FF_TRANSLUCENT; continue;
}
if (rover->master != crumble->sourceline)
continue;
rover->alpha = crumble->origalpha;
if (rover->alpha == 0xff)
rover->flags &= ~FF_TRANSLUCENT;
} }
} }
// Up! // Up!
if (elevator->floordestheight == 1) if (crumble->flags & CF_REVERSE)
elevator->direction = -1; crumble->direction = -1;
else else
elevator->direction = 1; crumble->direction = 1;
elevator->sector->ceilspeed = 0; crumble->sector->ceilspeed = 0;
elevator->sector->floorspeed = 0; crumble->sector->floorspeed = 0;
return; return;
} }
// Flash to indicate that the platform is about to return. // Flash to indicate that the platform is about to return.
if (elevator->distance > -224 && (leveltime % ((abs(elevator->distance)/8) + 1) == 0)) if (crumble->timer > -224 && (leveltime % ((abs(crumble->timer)/8) + 1) == 0))
{ {
for (i = -1; (i = P_FindSectorFromTag(elevator->sourceline->tag, i)) >= 0 ;) for (i = -1; (i = P_FindSectorFromTag(crumble->sourceline->tag, i)) >= 0 ;)
{ {
sector = &sectors[i]; sector = &sectors[i];
for (rover = sector->ffloors; rover; rover = rover->next) for (rover = sector->ffloors; rover; rover = rover->next)
{ {
if (!(rover->flags & FF_NORETURN) && rover->flags & FF_CRUMBLE && rover->flags & FF_FLOATBOB if (rover->flags & FF_NORETURN)
&& rover->master == elevator->sourceline) continue;
{
if (rover->alpha == elevator->origspeed)
{
rover->flags |= FF_TRANSLUCENT;
rover->alpha = 0x00;
}
else
{
if (elevator->origspeed == 0xff)
rover->flags &= ~FF_TRANSLUCENT;
rover->alpha = elevator->origspeed; if (!(rover->flags & FF_CRUMBLE))
} continue;
if (!(rover->flags & FF_FLOATBOB))
continue;
if (rover->master != crumble->sourceline)
continue;
if (rover->alpha == crumble->origalpha)
{
rover->flags |= FF_TRANSLUCENT;
rover->alpha = 0x00;
}
else
{
rover->alpha = crumble->origalpha;
if (rover->alpha == 0xff)
rover->flags &= ~FF_TRANSLUCENT;
} }
} }
} }
@ -851,74 +873,62 @@ void T_StartCrumble(elevator_t *elevator)
// We're about to go back to the original position, // We're about to go back to the original position,
// so set this to let other thinkers know what is // so set this to let other thinkers know what is
// about to happen. // about to happen.
if (elevator->distance < 0 && elevator->distance > -3) if (crumble->timer < 0 && crumble->timer > -3)
elevator->sector->crumblestate = CRUMBLE_RESTORE; // makes T_BounceCheese remove itself crumble->sector->crumblestate = CRUMBLE_RESTORE; // makes T_BounceCheese remove itself
} }
if ((elevator->floordestheight == 0 && elevator->direction == -1) if ((!(crumble->flags & CF_REVERSE) && crumble->direction == -1)
|| (elevator->floordestheight == 1 && elevator->direction == 1)) // Down || ((crumble->flags & CF_REVERSE) && crumble->direction == 1)) // Down
{ {
elevator->sector->crumblestate = CRUMBLE_FALL; // Allow floating now. crumble->sector->crumblestate = CRUMBLE_FALL; // Allow floating now.
// Only fall like this if it isn't meant to float on water // Only fall like this if it isn't meant to float on water
if (elevator->high != 42) if (!(crumble->flags & CF_FLOATBOB))
{ {
elevator->speed += gravity; // Gain more and more speed crumble->speed += gravity; // Gain more and more speed
if ((elevator->floordestheight == 0 && !(elevator->sector->ceilingheight < -16384*FRACUNIT)) if ((!(crumble->flags & CF_REVERSE) && crumble->sector->ceilingheight >= -16384*FRACUNIT)
|| (elevator->floordestheight == 1 && !(elevator->sector->ceilingheight > 16384*FRACUNIT))) || ((crumble->flags & CF_REVERSE) && crumble->sector->ceilingheight <= 16384*FRACUNIT))
{ {
fixed_t dest;
if (elevator->floordestheight == 1)
dest = elevator->sector->ceilingheight + (elevator->speed*2);
else
dest = elevator->sector->ceilingheight - (elevator->speed*2);
T_MovePlane //jff 4/7/98 reverse order of ceiling/floor T_MovePlane //jff 4/7/98 reverse order of ceiling/floor
( (
elevator->sector, crumble->sector,
elevator->speed, crumble->speed,
dest, crumble->sector->ceilingheight + crumble->direction*crumble->speed*2,
false, false,
true, // move ceiling true, // move ceiling
elevator->direction crumble->direction
); );
if (elevator->floordestheight == 1) T_MovePlane
dest = elevator->sector->floorheight + (elevator->speed*2); (
else crumble->sector,
dest = elevator->sector->floorheight - (elevator->speed*2); crumble->speed,
crumble->sector->floorheight + crumble->direction*crumble->speed*2,
T_MovePlane false,
( false, // move floor
elevator->sector, crumble->direction
elevator->speed,
dest,
false,
false, // move floor
elevator->direction
); );
elevator->sector->ceilspeed = 42; crumble->sector->ceilspeed = 42;
elevator->sector->floorspeed = elevator->speed*elevator->direction; crumble->sector->floorspeed = crumble->speed*crumble->direction;
} }
} }
} }
else // Up (restore to original position) else // Up (restore to original position)
{ {
elevator->sector->crumblestate = CRUMBLE_WAIT; crumble->sector->crumblestate = CRUMBLE_WAIT;
elevator->sector->ceilingheight = elevator->ceilingwasheight; crumble->sector->ceilingheight = crumble->ceilingwasheight;
elevator->sector->floorheight = elevator->floorwasheight; crumble->sector->floorheight = crumble->floorwasheight;
elevator->sector->floordata = NULL; crumble->sector->floordata = NULL;
elevator->sector->ceilingdata = NULL; crumble->sector->ceilingdata = NULL;
elevator->sector->ceilspeed = 0; crumble->sector->ceilspeed = 0;
elevator->sector->floorspeed = 0; crumble->sector->floorspeed = 0;
elevator->sector->moved = true; crumble->sector->moved = true;
P_RemoveThinker(&elevator->thinker); P_RemoveThinker(&crumble->thinker);
} }
for (i = -1; (i = P_FindSectorFromTag(elevator->sourceline->tag, i)) >= 0 ;) for (i = -1; (i = P_FindSectorFromTag(crumble->sourceline->tag, i)) >= 0 ;)
{ {
sector = &sectors[i]; sector = &sectors[i];
sector->moved = true; sector->moved = true;
@ -1284,7 +1294,7 @@ void T_NoEnemiesSector(noenemies_t *nobaddies)
INT32 secnum = -1; INT32 secnum = -1;
boolean FOFsector = false; boolean FOFsector = false;
while ((secnum = P_FindSectorFromLineTag(nobaddies->sourceline, secnum)) >= 0) while ((secnum = P_FindSectorFromTag(nobaddies->sourceline->tag, secnum)) >= 0)
{ {
sec = &sectors[secnum]; sec = &sectors[secnum];
@ -1300,7 +1310,7 @@ void T_NoEnemiesSector(noenemies_t *nobaddies)
FOFsector = true; FOFsector = true;
while ((targetsecnum = P_FindSectorFromLineTag(sec->lines[i], targetsecnum)) >= 0) while ((targetsecnum = P_FindSectorFromTag(sec->lines[i]->tag, targetsecnum)) >= 0)
{ {
if (T_SectorHasEnemies(&sectors[targetsecnum])) if (T_SectorHasEnemies(&sectors[targetsecnum]))
return; return;
@ -1395,7 +1405,7 @@ void T_EachTimeThinker(eachtime_t *eachtime)
eachtime->playersOnArea[i] = false; eachtime->playersOnArea[i] = false;
} }
while ((secnum = P_FindSectorFromLineTag(eachtime->sourceline, secnum)) >= 0) while ((secnum = P_FindSectorFromTag(eachtime->sourceline->tag, secnum)) >= 0)
{ {
sec = &sectors[secnum]; sec = &sectors[secnum];
@ -1418,7 +1428,7 @@ void T_EachTimeThinker(eachtime_t *eachtime)
FOFsector = true; FOFsector = true;
while ((targetsecnum = P_FindSectorFromLineTag(sec->lines[i], targetsecnum)) >= 0) while ((targetsecnum = P_FindSectorFromTag(sec->lines[i]->tag, targetsecnum)) >= 0)
{ {
targetsec = &sectors[targetsecnum]; targetsec = &sectors[targetsecnum];
@ -1556,7 +1566,7 @@ void T_RaiseSector(raise_t *raise)
if (raise->sector->crumblestate >= CRUMBLE_FALL || raise->sector->ceilingdata) if (raise->sector->crumblestate >= CRUMBLE_FALL || raise->sector->ceilingdata)
return; return;
for (i = -1; (i = P_FindSectorFromTag(raise->sourceline->tag, i)) >= 0 ;) for (i = -1; (i = P_FindSectorFromTag(raise->tag, i)) >= 0 ;)
{ {
sector = &sectors[i]; sector = &sectors[i];
@ -1683,7 +1693,7 @@ void T_RaiseSector(raise_t *raise)
raise->sector->ceilspeed = 42; raise->sector->ceilspeed = 42;
raise->sector->floorspeed = speed*direction; raise->sector->floorspeed = speed*direction;
for (i = -1; (i = P_FindSectorFromTag(raise->sourceline->tag, i)) >= 0 ;) for (i = -1; (i = P_FindSectorFromTag(raise->tag, i)) >= 0 ;)
P_RecalcPrecipInSector(&sectors[i]); P_RecalcPrecipInSector(&sectors[i]);
} }
@ -1801,7 +1811,7 @@ void EV_DoFloor(line_t *line, floor_e floortype)
sector_t *sec; sector_t *sec;
floormove_t *dofloor; floormove_t *dofloor;
while ((secnum = P_FindSectorFromLineTag(line, secnum)) >= 0) while ((secnum = P_FindSectorFromTag(line->tag, secnum)) >= 0)
{ {
sec = &sectors[secnum]; sec = &sectors[secnum];
@ -2017,7 +2027,7 @@ void EV_DoElevator(line_t *line, elevator_e elevtype, boolean customspeed)
elevator_t *elevator; elevator_t *elevator;
// act on all sectors with the same tag as the triggering linedef // act on all sectors with the same tag as the triggering linedef
while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0) while ((secnum = P_FindSectorFromTag(line->tag,secnum)) >= 0)
{ {
sec = &sectors[secnum]; sec = &sectors[secnum];
@ -2231,9 +2241,9 @@ void EV_CrumbleChain(sector_t *sec, ffloor_t *rover)
{ {
mobj_t *spawned = NULL; mobj_t *spawned = NULL;
if (*rover->t_slope) if (*rover->t_slope)
topz = P_GetZAt(*rover->t_slope, a, b) - (spacing>>1); topz = P_GetSlopeZAt(*rover->t_slope, a, b) - (spacing>>1);
if (*rover->b_slope) if (*rover->b_slope)
bottomz = P_GetZAt(*rover->b_slope, a, b); bottomz = P_GetSlopeZAt(*rover->b_slope, a, b);
for (c = topz; c > bottomz; c -= spacing) for (c = topz; c > bottomz; c -= spacing)
{ {
@ -2309,7 +2319,7 @@ void EV_DoContinuousFall(sector_t *sec, sector_t *backsector, fixed_t spd, boole
INT32 EV_StartCrumble(sector_t *sec, ffloor_t *rover, boolean floating, INT32 EV_StartCrumble(sector_t *sec, ffloor_t *rover, boolean floating,
player_t *player, fixed_t origalpha, boolean crumblereturn) player_t *player, fixed_t origalpha, boolean crumblereturn)
{ {
elevator_t *elevator; crumble_t *crumble;
sector_t *foundsec; sector_t *foundsec;
INT32 i; INT32 i;
@ -2320,55 +2330,45 @@ INT32 EV_StartCrumble(sector_t *sec, ffloor_t *rover, boolean floating,
if (sec->crumblestate >= CRUMBLE_ACTIVATED) if (sec->crumblestate >= CRUMBLE_ACTIVATED)
return 0; return 0;
// create and initialize new elevator thinker // create and initialize new crumble thinker
elevator = Z_Calloc(sizeof (*elevator), PU_LEVSPEC, NULL); crumble = Z_Calloc(sizeof (*crumble), PU_LEVSPEC, NULL);
P_AddThinker(THINK_MAIN, &elevator->thinker); P_AddThinker(THINK_MAIN, &crumble->thinker);
elevator->thinker.function.acp1 = (actionf_p1)T_StartCrumble; crumble->thinker.function.acp1 = (actionf_p1)T_StartCrumble;
// Does this crumbler return? // set up the fields
if (crumblereturn) crumble->sector = sec;
elevator->type = elevateBounce; crumble->speed = 0;
else
elevator->type = elevateContinuous;
// set up the fields according to the type of elevator action
elevator->sector = sec;
elevator->speed = 0;
if (player && player->mo && (player->mo->eflags & MFE_VERTICALFLIP)) if (player && player->mo && (player->mo->eflags & MFE_VERTICALFLIP))
{ {
elevator->direction = 1; // Up crumble->direction = 1; // Up
elevator->floordestheight = 1; crumble->flags |= CF_REVERSE;
} }
else else
{ crumble->direction = -1; // Down
elevator->direction = -1; // Down
elevator->floordestheight = 0;
}
elevator->floorwasheight = elevator->sector->floorheight; crumble->floorwasheight = crumble->sector->floorheight;
elevator->ceilingwasheight = elevator->sector->ceilingheight; crumble->ceilingwasheight = crumble->sector->ceilingheight;
elevator->distance = TICRATE; // Used for delay time crumble->timer = TICRATE;
elevator->low = 0; crumble->player = player;
elevator->player = player; crumble->origalpha = origalpha;
elevator->origspeed = origalpha;
elevator->sourceline = rover->master; crumble->sourceline = rover->master;
sec->floordata = elevator; sec->floordata = crumble;
if (crumblereturn)
crumble->flags |= CF_RETURN;
if (floating) if (floating)
elevator->high = 42; crumble->flags |= CF_FLOATBOB;
else
elevator->high = 0;
elevator->sector->crumblestate = CRUMBLE_ACTIVATED; crumble->sector->crumblestate = CRUMBLE_ACTIVATED;
for (i = -1; (i = P_FindSectorFromTag(elevator->sourceline->tag, i)) >= 0 ;) for (i = -1; (i = P_FindSectorFromTag(crumble->sourceline->tag, i)) >= 0 ;)
{ {
foundsec = &sectors[i]; foundsec = &sectors[i];
P_SpawnMobj(foundsec->soundorg.x, foundsec->soundorg.y, elevator->direction == 1 ? elevator->sector->floorheight : elevator->sector->ceilingheight, MT_CRUMBLEOBJ); P_SpawnMobj(foundsec->soundorg.x, foundsec->soundorg.y, crumble->direction == 1 ? crumble->sector->floorheight : crumble->sector->ceilingheight, MT_CRUMBLEOBJ);
} }
return 1; return 1;

View File

@ -2157,7 +2157,6 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
BMBOUNDFIX(xl, xh, yl, yh); BMBOUNDFIX(xl, xh, yl, yh);
#ifdef POLYOBJECTS
// Check polyobjects and see if tmfloorz/tmceilingz need to be altered // Check polyobjects and see if tmfloorz/tmceilingz need to be altered
{ {
validcount++; validcount++;
@ -2229,7 +2228,6 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
} }
} }
} }
#endif
// tmfloorthing is set when tmfloorz comes from a thing's top // tmfloorthing is set when tmfloorz comes from a thing's top
tmfloorthing = NULL; tmfloorthing = NULL;
@ -2387,7 +2385,6 @@ boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam)
BMBOUNDFIX(xl, xh, yl, yh); BMBOUNDFIX(xl, xh, yl, yh);
#ifdef POLYOBJECTS
// Check polyobjects and see if tmfloorz/tmceilingz need to be altered // Check polyobjects and see if tmfloorz/tmceilingz need to be altered
{ {
validcount++; validcount++;
@ -2458,7 +2455,6 @@ boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam)
} }
} }
} }
#endif
// check lines // check lines
for (bx = xl; bx <= xh; bx++) for (bx = xl; bx <= xh; bx++)
@ -3206,102 +3202,83 @@ isblocking:
static boolean P_IsClimbingValid(player_t *player, angle_t angle) static boolean P_IsClimbingValid(player_t *player, angle_t angle)
{ {
fixed_t platx, platy; fixed_t platx, platy;
subsector_t *glidesector; sector_t *glidesector;
fixed_t floorz, ceilingz; fixed_t floorz, ceilingz;
mobj_t *mo = player->mo;
ffloor_t *rover;
platx = P_ReturnThrustX(player->mo, angle, player->mo->radius + FixedMul(8*FRACUNIT, player->mo->scale)); platx = P_ReturnThrustX(mo, angle, mo->radius + FixedMul(8*FRACUNIT, mo->scale));
platy = P_ReturnThrustY(player->mo, angle, player->mo->radius + FixedMul(8*FRACUNIT, player->mo->scale)); platy = P_ReturnThrustY(mo, angle, mo->radius + FixedMul(8*FRACUNIT, mo->scale));
glidesector = R_PointInSubsector(player->mo->x + platx, player->mo->y + platy); glidesector = R_PointInSubsector(mo->x + platx, mo->y + platy)->sector;
floorz = glidesector->sector->f_slope ? P_GetZAt(glidesector->sector->f_slope, player->mo->x, player->mo->y) : glidesector->sector->floorheight; floorz = P_GetSectorFloorZAt (glidesector, mo->x, mo->y);
ceilingz = glidesector->sector->c_slope ? P_GetZAt(glidesector->sector->c_slope, player->mo->x, player->mo->y) : glidesector->sector->ceilingheight; ceilingz = P_GetSectorCeilingZAt(glidesector, mo->x, mo->y);
if (glidesector->sector != player->mo->subsector->sector) if (glidesector != mo->subsector->sector)
{ {
boolean floorclimb = false; boolean floorclimb = false;
fixed_t topheight, bottomheight; fixed_t topheight, bottomheight;
if (glidesector->sector->ffloors) for (rover = glidesector->ffloors; rover; rover = rover->next)
{ {
ffloor_t *rover; if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER))
for (rover = glidesector->sector->ffloors; rover; rover = rover->next) continue;
topheight = P_GetFFloorTopZAt (rover, mo->x, mo->y);
bottomheight = P_GetFFloorBottomZAt(rover, mo->x, mo->y);
floorclimb = true;
if (mo->eflags & MFE_VERTICALFLIP)
{ {
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER)) if ((topheight < mo->z + mo->height) && ((mo->z + mo->height + mo->momz) < topheight))
continue; floorclimb = true;
if (topheight < mo->z) // Waaaay below the ledge.
topheight = *rover->topheight; floorclimb = false;
bottomheight = *rover->bottomheight; if (bottomheight > mo->z + mo->height - FixedMul(16*FRACUNIT,mo->scale))
floorclimb = false;
if (*rover->t_slope)
topheight = P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y);
if (*rover->b_slope)
bottomheight = P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y);
floorclimb = true;
if (player->mo->eflags & MFE_VERTICALFLIP)
{
if ((topheight < player->mo->z + player->mo->height) && ((player->mo->z + player->mo->height + player->mo->momz) < topheight))
{
floorclimb = true;
}
if (topheight < player->mo->z) // Waaaay below the ledge.
{
floorclimb = false;
}
if (bottomheight > player->mo->z + player->mo->height - FixedMul(16*FRACUNIT,player->mo->scale))
{
floorclimb = false;
}
}
else
{
if ((bottomheight > player->mo->z) && ((player->mo->z - player->mo->momz) > bottomheight))
{
floorclimb = true;
}
if (bottomheight > player->mo->z + player->mo->height) // Waaaay below the ledge.
{
floorclimb = false;
}
if (topheight < player->mo->z + FixedMul(16*FRACUNIT,player->mo->scale))
{
floorclimb = false;
}
}
if (floorclimb)
break;
} }
else
{
if ((bottomheight > mo->z) && ((mo->z - mo->momz) > bottomheight))
floorclimb = true;
if (bottomheight > mo->z + mo->height) // Waaaay below the ledge.
floorclimb = false;
if (topheight < mo->z + FixedMul(16*FRACUNIT,mo->scale))
floorclimb = false;
}
if (floorclimb)
break;
} }
if (player->mo->eflags & MFE_VERTICALFLIP) if (mo->eflags & MFE_VERTICALFLIP)
{ {
if ((floorz <= player->mo->z + player->mo->height) if ((floorz <= mo->z + mo->height)
&& ((player->mo->z + player->mo->height - player->mo->momz) <= floorz)) && ((mo->z + mo->height - mo->momz) <= floorz))
floorclimb = true; floorclimb = true;
if ((floorz > player->mo->z) if ((floorz > mo->z)
&& glidesector->sector->floorpic == skyflatnum) && glidesector->floorpic == skyflatnum)
return false; return false;
if ((player->mo->z + player->mo->height - FixedMul(16*FRACUNIT,player->mo->scale) > ceilingz) if ((mo->z + mo->height - FixedMul(16*FRACUNIT,mo->scale) > ceilingz)
|| (player->mo->z + player->mo->height <= floorz)) || (mo->z + mo->height <= floorz))
floorclimb = true; floorclimb = true;
} }
else else
{ {
if ((ceilingz >= player->mo->z) if ((ceilingz >= mo->z)
&& ((player->mo->z - player->mo->momz) >= ceilingz)) && ((mo->z - mo->momz) >= ceilingz))
floorclimb = true; floorclimb = true;
if ((ceilingz < player->mo->z+player->mo->height) if ((ceilingz < mo->z+mo->height)
&& glidesector->sector->ceilingpic == skyflatnum) && glidesector->ceilingpic == skyflatnum)
return false; return false;
if ((player->mo->z + FixedMul(16*FRACUNIT,player->mo->scale) < floorz) if ((mo->z + FixedMul(16*FRACUNIT,mo->scale) < floorz)
|| (player->mo->z >= ceilingz)) || (mo->z >= ceilingz))
floorclimb = true; floorclimb = true;
} }
@ -3389,13 +3366,8 @@ isblocking:
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP)) if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP))
continue; continue;
topheight = *rover->topheight; topheight = P_GetFFloorTopZAt (rover, slidemo->x, slidemo->y);
bottomheight = *rover->bottomheight; bottomheight = P_GetFFloorBottomZAt(rover, slidemo->x, slidemo->y);
if (*rover->t_slope)
topheight = P_GetZAt(*rover->t_slope, slidemo->x, slidemo->y);
if (*rover->b_slope)
bottomheight = P_GetZAt(*rover->b_slope, slidemo->x, slidemo->y);
if (topheight < slidemo->z) if (topheight < slidemo->z)
continue; continue;
@ -3600,9 +3572,7 @@ static void P_CheckLavaWall(mobj_t *mo, sector_t *sec)
if (rover->master->flags & ML_BLOCKMONSTERS) if (rover->master->flags & ML_BLOCKMONSTERS)
continue; continue;
topheight = *rover->t_slope ? topheight = P_GetFFloorTopZAt(rover, mo->x, mo->y);
P_GetZAt(*rover->t_slope, mo->x, mo->y) :
*rover->topheight;
if (mo->eflags & MFE_VERTICALFLIP) if (mo->eflags & MFE_VERTICALFLIP)
{ {
@ -3615,9 +3585,7 @@ static void P_CheckLavaWall(mobj_t *mo, sector_t *sec)
continue; continue;
} }
bottomheight = *rover->b_slope ? bottomheight = P_GetFFloorBottomZAt(rover, mo->x, mo->y);
P_GetZAt(*rover->b_slope, mo->x, mo->y) :
*rover->bottomheight;
if (mo->eflags & MFE_VERTICALFLIP) if (mo->eflags & MFE_VERTICALFLIP)
{ {
@ -4203,11 +4171,8 @@ static boolean PIT_ChangeSector(mobj_t *thing, boolean realcrush)
topheight = *rover->topheight; topheight = *rover->topheight;
bottomheight = *rover->bottomheight; bottomheight = *rover->bottomheight;
//topheight = P_GetFFloorTopZAt (rover, thing->x, thing->y);
/*if (rover->t_slope) //bottomheight = P_GetFFloorBottomZAt(rover, thing->x, thing->y);
topheight = P_GetZAt(rover->t_slope, thing->x, thing->y);
if (rover->b_slope)
bottomheight = P_GetZAt(rover->b_slope, thing->x, thing->y);*/
delta1 = thing->z - (bottomheight + topheight)/2; delta1 = thing->z - (bottomheight + topheight)/2;
delta2 = thingtop - (bottomheight + topheight)/2; delta2 = thingtop - (bottomheight + topheight)/2;
@ -4223,21 +4188,19 @@ static boolean PIT_ChangeSector(mobj_t *thing, boolean realcrush)
{ {
//If the thing was crushed by a crumbling FOF, reward the player who made it crumble! //If the thing was crushed by a crumbling FOF, reward the player who made it crumble!
thinker_t *think; thinker_t *think;
elevator_t *crumbler; crumble_t *crumbler;
for (think = thlist[THINK_MAIN].next; think != &thlist[THINK_MAIN]; think = think->next) for (think = thlist[THINK_MAIN].next; think != &thlist[THINK_MAIN]; think = think->next)
{ {
if (think->function.acp1 != (actionf_p1)T_StartCrumble) if (think->function.acp1 != (actionf_p1)T_StartCrumble)
continue; continue;
crumbler = (elevator_t *)think; crumbler = (crumble_t *)think;
if (crumbler->player && crumbler->player->mo if (crumbler->player && crumbler->player->mo
&& crumbler->player->mo != thing && crumbler->player->mo != thing
&& crumbler->actionsector == thing->subsector->sector && crumbler->actionsector == thing->subsector->sector
&& crumbler->sector == rover->master->frontsector && crumbler->sector == rover->master->frontsector)
&& (crumbler->type == elevateBounce
|| crumbler->type == elevateContinuous))
{ {
killer = crumbler->player->mo; killer = crumbler->player->mo;
} }
@ -4986,10 +4949,7 @@ void P_MapEnd(void)
fixed_t P_FloorzAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height) fixed_t P_FloorzAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height)
{ {
sector_t *sec = R_PointInSubsector(x, y)->sector; sector_t *sec = R_PointInSubsector(x, y)->sector;
fixed_t floorz = sec->floorheight; fixed_t floorz = P_GetSectorFloorZAt(sec, x, y);
if (sec->f_slope)
floorz = P_GetZAt(sec->f_slope, x, y);
// Intercept the stupid 'fall through 3dfloors' bug Tails 03-17-2002 // Intercept the stupid 'fall through 3dfloors' bug Tails 03-17-2002
if (sec->ffloors) if (sec->ffloors)
@ -5006,13 +4966,8 @@ fixed_t P_FloorzAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height)
if ((!(rover->flags & FF_SOLID || rover->flags & FF_QUICKSAND) || (rover->flags & FF_SWIMMABLE))) if ((!(rover->flags & FF_SOLID || rover->flags & FF_QUICKSAND) || (rover->flags & FF_SWIMMABLE)))
continue; continue;
topheight = *rover->topheight; topheight = P_GetFFloorTopZAt (rover, x, y);
bottomheight = *rover->bottomheight; bottomheight = P_GetFFloorBottomZAt(rover, x, y);
if (*rover->t_slope)
topheight = P_GetZAt(*rover->t_slope, x, y);
if (*rover->b_slope)
bottomheight = P_GetZAt(*rover->b_slope, x, y);
if (rover->flags & FF_QUICKSAND) if (rover->flags & FF_QUICKSAND)
{ {

View File

@ -303,45 +303,33 @@ void P_CameraLineOpening(line_t *linedef)
// If you can see through it, why not move the camera through it too? // If you can see through it, why not move the camera through it too?
if (front->camsec >= 0) if (front->camsec >= 0)
{ {
frontfloor = sectors[front->camsec].floorheight; // SRB2CBTODO: ESLOPE (sectors[front->heightsec].f_slope)
frontceiling = sectors[front->camsec].ceilingheight; frontfloor = P_GetSectorFloorZAt (&sectors[front->camsec], camera.x, camera.y);
if (sectors[front->camsec].f_slope) // SRB2CBTODO: ESLOPE (sectors[front->heightsec].f_slope) frontceiling = P_GetSectorCeilingZAt(&sectors[front->camsec], camera.x, camera.y);
frontfloor = P_GetZAt(sectors[front->camsec].f_slope, camera.x, camera.y);
if (sectors[front->camsec].c_slope)
frontceiling = P_GetZAt(sectors[front->camsec].c_slope, camera.x, camera.y);
} }
else if (front->heightsec >= 0) else if (front->heightsec >= 0)
{ {
frontfloor = sectors[front->heightsec].floorheight; // SRB2CBTODO: ESLOPE (sectors[front->heightsec].f_slope)
frontceiling = sectors[front->heightsec].ceilingheight; frontfloor = P_GetSectorFloorZAt (&sectors[front->heightsec], camera.x, camera.y);
if (sectors[front->heightsec].f_slope) // SRB2CBTODO: ESLOPE (sectors[front->heightsec].f_slope) frontceiling = P_GetSectorCeilingZAt(&sectors[front->heightsec], camera.x, camera.y);
frontfloor = P_GetZAt(sectors[front->heightsec].f_slope, camera.x, camera.y);
if (sectors[front->heightsec].c_slope)
frontceiling = P_GetZAt(sectors[front->heightsec].c_slope, camera.x, camera.y);
} }
else else
{ {
frontfloor = P_CameraGetFloorZ(mapcampointer, front, tmx, tmy, linedef); frontfloor = P_CameraGetFloorZ (mapcampointer, front, tmx, tmy, linedef);
frontceiling = P_CameraGetCeilingZ(mapcampointer, front, tmx, tmy, linedef); frontceiling = P_CameraGetCeilingZ(mapcampointer, front, tmx, tmy, linedef);
} }
if (back->camsec >= 0) if (back->camsec >= 0)
{ {
backfloor = sectors[back->camsec].floorheight; // SRB2CBTODO: ESLOPE (sectors[back->heightsec].f_slope)
backceiling = sectors[back->camsec].ceilingheight; backfloor = P_GetSectorFloorZAt (&sectors[back->camsec], camera.x, camera.y);
if (sectors[back->camsec].f_slope) // SRB2CBTODO: ESLOPE (sectors[front->heightsec].f_slope) backceiling = P_GetSectorCeilingZAt(&sectors[back->camsec], camera.x, camera.y);
frontfloor = P_GetZAt(sectors[back->camsec].f_slope, camera.x, camera.y);
if (sectors[back->camsec].c_slope)
frontceiling = P_GetZAt(sectors[back->camsec].c_slope, camera.x, camera.y);
} }
else if (back->heightsec >= 0) else if (back->heightsec >= 0)
{ {
backfloor = sectors[back->heightsec].floorheight; // SRB2CBTODO: ESLOPE (sectors[back->heightsec].f_slope)
backceiling = sectors[back->heightsec].ceilingheight; backfloor = P_GetSectorFloorZAt (&sectors[back->heightsec], camera.x, camera.y);
if (sectors[back->heightsec].f_slope) // SRB2CBTODO: ESLOPE (sectors[front->heightsec].f_slope) backceiling = P_GetSectorCeilingZAt(&sectors[back->heightsec], camera.x, camera.y);
frontfloor = P_GetZAt(sectors[back->heightsec].f_slope, camera.x, camera.y);
if (sectors[back->heightsec].c_slope)
frontceiling = P_GetZAt(sectors[back->heightsec].c_slope, camera.x, camera.y);
} }
else else
{ {
@ -451,7 +439,6 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
I_Assert(back != NULL); I_Assert(back != NULL);
openfloorrover = openceilingrover = NULL; openfloorrover = openceilingrover = NULL;
#ifdef POLYOBJECTS
if (linedef->polyobj) if (linedef->polyobj)
{ {
// set these defaults so that polyobjects don't interfere with collision above or below them // set these defaults so that polyobjects don't interfere with collision above or below them
@ -462,7 +449,6 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
opentopslope = openbottomslope = NULL; opentopslope = openbottomslope = NULL;
} }
else else
#endif
{ // Set open and high/low values here { // Set open and high/low values here
fixed_t frontheight, backheight; fixed_t frontheight, backheight;
@ -517,7 +503,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
texheight = textures[texnum]->height << FRACBITS; texheight = textures[texnum]->height << FRACBITS;
// Set texbottom and textop to the Z coordinates of the texture's boundaries // Set texbottom and textop to the Z coordinates of the texture's boundaries
#if 0 // #ifdef POLYOBJECTS #if 0
// don't remove this code unless solid midtextures // don't remove this code unless solid midtextures
// on non-solid polyobjects should NEVER happen in the future // on non-solid polyobjects should NEVER happen in the future
if (linedef->polyobj && (linedef->polyobj->flags & POF_TESTHEIGHT)) { if (linedef->polyobj && (linedef->polyobj->flags & POF_TESTHEIGHT)) {
@ -560,7 +546,6 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
} }
} }
} }
#ifdef POLYOBJECTS
if (linedef->polyobj) if (linedef->polyobj)
{ {
// Treat polyobj's backsector like a 3D Floor // Treat polyobj's backsector like a 3D Floor
@ -597,94 +582,95 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
// otherwise don't do anything special, pretend there's nothing else there // otherwise don't do anything special, pretend there's nothing else there
} }
else else
#endif
// Check for fake floors in the sector.
if (front->ffloors || back->ffloors)
{ {
ffloor_t *rover; // Check for fake floors in the sector.
fixed_t delta1, delta2; if (front->ffloors || back->ffloors)
// Check for frontsector's fake floors
for (rover = front->ffloors; rover; rover = rover->next)
{ {
fixed_t topheight, bottomheight; ffloor_t *rover;
if (!(rover->flags & FF_EXISTS)) fixed_t delta1, delta2;
continue;
if (mobj->player && (P_CheckSolidLava(rover) || P_CanRunOnWater(mobj->player, rover))) // Check for frontsector's fake floors
; for (rover = front->ffloors; rover; rover = rover->next)
else if (!((rover->flags & FF_BLOCKPLAYER && mobj->player)
|| (rover->flags & FF_BLOCKOTHERS && !mobj->player)))
continue;
topheight = P_GetFOFTopZ(mobj, front, rover, tmx, tmy, linedef);
bottomheight = P_GetFOFBottomZ(mobj, front, rover, tmx, tmy, linedef);
delta1 = abs(mobj->z - (bottomheight + ((topheight - bottomheight)/2)));
delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2)));
if (delta1 >= delta2 && (rover->flags & FF_INTANGIBLEFLATS) != FF_PLATFORM) // thing is below FOF
{ {
if (bottomheight < opentop) { fixed_t topheight, bottomheight;
opentop = bottomheight; if (!(rover->flags & FF_EXISTS))
opentopslope = *rover->b_slope; continue;
openceilingrover = rover;
if (mobj->player && (P_CheckSolidLava(rover) || P_CanRunOnWater(mobj->player, rover)))
;
else if (!((rover->flags & FF_BLOCKPLAYER && mobj->player)
|| (rover->flags & FF_BLOCKOTHERS && !mobj->player)))
continue;
topheight = P_GetFOFTopZ(mobj, front, rover, tmx, tmy, linedef);
bottomheight = P_GetFOFBottomZ(mobj, front, rover, tmx, tmy, linedef);
delta1 = abs(mobj->z - (bottomheight + ((topheight - bottomheight)/2)));
delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2)));
if (delta1 >= delta2 && (rover->flags & FF_INTANGIBLEFLATS) != FF_PLATFORM) // thing is below FOF
{
if (bottomheight < opentop) {
opentop = bottomheight;
opentopslope = *rover->b_slope;
openceilingrover = rover;
}
else if (bottomheight < highceiling)
highceiling = bottomheight;
}
if (delta1 < delta2 && (rover->flags & FF_INTANGIBLEFLATS) != FF_REVERSEPLATFORM) // thing is above FOF
{
if (topheight > openbottom) {
openbottom = topheight;
openbottomslope = *rover->t_slope;
openfloorrover = rover;
}
else if (topheight > lowfloor)
lowfloor = topheight;
} }
else if (bottomheight < highceiling)
highceiling = bottomheight;
} }
if (delta1 < delta2 && (rover->flags & FF_INTANGIBLEFLATS) != FF_REVERSEPLATFORM) // thing is above FOF // Check for backsectors fake floors
for (rover = back->ffloors; rover; rover = rover->next)
{ {
if (topheight > openbottom) { fixed_t topheight, bottomheight;
openbottom = topheight; if (!(rover->flags & FF_EXISTS))
openbottomslope = *rover->t_slope; continue;
openfloorrover = rover;
if (mobj->player && (P_CheckSolidLava(rover) || P_CanRunOnWater(mobj->player, rover)))
;
else if (!((rover->flags & FF_BLOCKPLAYER && mobj->player)
|| (rover->flags & FF_BLOCKOTHERS && !mobj->player)))
continue;
topheight = P_GetFOFTopZ(mobj, back, rover, tmx, tmy, linedef);
bottomheight = P_GetFOFBottomZ(mobj, back, rover, tmx, tmy, linedef);
delta1 = abs(mobj->z - (bottomheight + ((topheight - bottomheight)/2)));
delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2)));
if (delta1 >= delta2 && (rover->flags & FF_INTANGIBLEFLATS) != FF_PLATFORM) // thing is below FOF
{
if (bottomheight < opentop) {
opentop = bottomheight;
opentopslope = *rover->b_slope;
openceilingrover = rover;
}
else if (bottomheight < highceiling)
highceiling = bottomheight;
} }
else if (topheight > lowfloor)
lowfloor = topheight;
}
}
// Check for backsectors fake floors if (delta1 < delta2 && (rover->flags & FF_INTANGIBLEFLATS) != FF_REVERSEPLATFORM) // thing is above FOF
for (rover = back->ffloors; rover; rover = rover->next) {
{ if (topheight > openbottom) {
fixed_t topheight, bottomheight; openbottom = topheight;
if (!(rover->flags & FF_EXISTS)) openbottomslope = *rover->t_slope;
continue; openfloorrover = rover;
}
if (mobj->player && (P_CheckSolidLava(rover) || P_CanRunOnWater(mobj->player, rover))) else if (topheight > lowfloor)
; lowfloor = topheight;
else if (!((rover->flags & FF_BLOCKPLAYER && mobj->player)
|| (rover->flags & FF_BLOCKOTHERS && !mobj->player)))
continue;
topheight = P_GetFOFTopZ(mobj, back, rover, tmx, tmy, linedef);
bottomheight = P_GetFOFBottomZ(mobj, back, rover, tmx, tmy, linedef);
delta1 = abs(mobj->z - (bottomheight + ((topheight - bottomheight)/2)));
delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2)));
if (delta1 >= delta2 && (rover->flags & FF_INTANGIBLEFLATS) != FF_PLATFORM) // thing is below FOF
{
if (bottomheight < opentop) {
opentop = bottomheight;
opentopslope = *rover->b_slope;
openceilingrover = rover;
} }
else if (bottomheight < highceiling)
highceiling = bottomheight;
}
if (delta1 < delta2 && (rover->flags & FF_INTANGIBLEFLATS) != FF_REVERSEPLATFORM) // thing is above FOF
{
if (topheight > openbottom) {
openbottom = topheight;
openbottomslope = *rover->t_slope;
openfloorrover = rover;
}
else if (topheight > lowfloor)
lowfloor = topheight;
} }
} }
} }
@ -934,9 +920,7 @@ boolean P_BlockLinesIterator(INT32 x, INT32 y, boolean (*func)(line_t *))
{ {
INT32 offset; INT32 offset;
const INT32 *list; // Big blockmap const INT32 *list; // Big blockmap
#ifdef POLYOBJECTS
polymaplink_t *plink; // haleyjd 02/22/06 polymaplink_t *plink; // haleyjd 02/22/06
#endif
line_t *ld; line_t *ld;
if (x < 0 || y < 0 || x >= bmapwidth || y >= bmapheight) if (x < 0 || y < 0 || x >= bmapwidth || y >= bmapheight)
@ -944,7 +928,6 @@ boolean P_BlockLinesIterator(INT32 x, INT32 y, boolean (*func)(line_t *))
offset = y*bmapwidth + x; offset = y*bmapwidth + x;
#ifdef POLYOBJECTS
// haleyjd 02/22/06: consider polyobject lines // haleyjd 02/22/06: consider polyobject lines
plink = polyblocklinks[offset]; plink = polyblocklinks[offset];
@ -968,7 +951,6 @@ boolean P_BlockLinesIterator(INT32 x, INT32 y, boolean (*func)(line_t *))
} }
plink = (polymaplink_t *)(plink->link.next); plink = (polymaplink_t *)(plink->link.next);
} }
#endif
offset = *(blockmap + offset); // offset = blockmap[y*bmapwidth+x]; offset = *(blockmap + offset); // offset = blockmap[y*bmapwidth+x];

View File

@ -436,7 +436,7 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state)
mobj->sprite2 = spr2; mobj->sprite2 = spr2;
mobj->frame = frame|(st->frame&~FF_FRAMEMASK); mobj->frame = frame|(st->frame&~FF_FRAMEMASK);
if (mobj->color >= MAXSKINCOLORS && mobj->color < MAXTRANSLATIONS) // Super colours? Super bright! if (mobj->color >= FIRSTSUPERCOLOR && mobj->color < numskincolors) // Super colours? Super bright!
mobj->frame |= FF_FULLBRIGHT; mobj->frame |= FF_FULLBRIGHT;
} }
// Regular sprites // Regular sprites
@ -926,13 +926,8 @@ boolean P_InsideANonSolidFFloor(mobj_t *mobj, ffloor_t *rover)
|| ((rover->flags & FF_BLOCKOTHERS) && !mobj->player))) || ((rover->flags & FF_BLOCKOTHERS) && !mobj->player)))
return false; return false;
topheight = *rover->topheight; topheight = P_GetFFloorTopZAt (rover, mobj->x, mobj->y);
bottomheight = *rover->bottomheight; bottomheight = P_GetFFloorBottomZAt(rover, mobj->x, mobj->y);
if (*rover->t_slope)
topheight = P_GetZAt(*rover->t_slope, mobj->x, mobj->y);
if (*rover->b_slope)
bottomheight = P_GetZAt(*rover->b_slope, mobj->x, mobj->y);
if (mobj->z > topheight) if (mobj->z > topheight)
return false; return false;
@ -963,12 +958,12 @@ static fixed_t HighestOnLine(fixed_t radius, fixed_t x, fixed_t y, line_t *line,
/*CONS_Printf("BEFORE: v1 = %f %f %f\n", /*CONS_Printf("BEFORE: v1 = %f %f %f\n",
FIXED_TO_FLOAT(v1.x), FIXED_TO_FLOAT(v1.x),
FIXED_TO_FLOAT(v1.y), FIXED_TO_FLOAT(v1.y),
FIXED_TO_FLOAT(P_GetZAt(slope, v1.x, v1.y)) FIXED_TO_FLOAT(P_GetSlopeZAt(slope, v1.x, v1.y))
); );
CONS_Printf(" v2 = %f %f %f\n", CONS_Printf(" v2 = %f %f %f\n",
FIXED_TO_FLOAT(v2.x), FIXED_TO_FLOAT(v2.x),
FIXED_TO_FLOAT(v2.y), FIXED_TO_FLOAT(v2.y),
FIXED_TO_FLOAT(P_GetZAt(slope, v2.x, v2.y)) FIXED_TO_FLOAT(P_GetSlopeZAt(slope, v2.x, v2.y))
);*/ );*/
if (abs(v1.x-x) > radius) { if (abs(v1.x-x) > radius) {
@ -1026,24 +1021,24 @@ static fixed_t HighestOnLine(fixed_t radius, fixed_t x, fixed_t y, line_t *line,
/*CONS_Printf("AFTER: v1 = %f %f %f\n", /*CONS_Printf("AFTER: v1 = %f %f %f\n",
FIXED_TO_FLOAT(v1.x), FIXED_TO_FLOAT(v1.x),
FIXED_TO_FLOAT(v1.y), FIXED_TO_FLOAT(v1.y),
FIXED_TO_FLOAT(P_GetZAt(slope, v1.x, v1.y)) FIXED_TO_FLOAT(P_GetSlopeZAt(slope, v1.x, v1.y))
); );
CONS_Printf(" v2 = %f %f %f\n", CONS_Printf(" v2 = %f %f %f\n",
FIXED_TO_FLOAT(v2.x), FIXED_TO_FLOAT(v2.x),
FIXED_TO_FLOAT(v2.y), FIXED_TO_FLOAT(v2.y),
FIXED_TO_FLOAT(P_GetZAt(slope, v2.x, v2.y)) FIXED_TO_FLOAT(P_GetSlopeZAt(slope, v2.x, v2.y))
);*/ );*/
// Return the higher of the two points // Return the higher of the two points
if (actuallylowest) if (actuallylowest)
return min( return min(
P_GetZAt(slope, v1.x, v1.y), P_GetSlopeZAt(slope, v1.x, v1.y),
P_GetZAt(slope, v2.x, v2.y) P_GetSlopeZAt(slope, v2.x, v2.y)
); );
else else
return max( return max(
P_GetZAt(slope, v1.x, v1.y), P_GetSlopeZAt(slope, v1.x, v1.y),
P_GetZAt(slope, v2.x, v2.y) P_GetSlopeZAt(slope, v2.x, v2.y)
); );
} }
@ -1077,7 +1072,7 @@ fixed_t P_MobjFloorZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t
// If the highest point is in the sector, then we have it easy! Just get the Z at that point // If the highest point is in the sector, then we have it easy! Just get the Z at that point
if (R_PointInSubsector(testx, testy)->sector == (boundsec ? boundsec : sector)) if (R_PointInSubsector(testx, testy)->sector == (boundsec ? boundsec : sector))
return P_GetZAt(slope, testx, testy); return P_GetSlopeZAt(slope, testx, testy);
// If boundsec is set, we're looking for specials. In that case, iterate over every line in this sector to find the TRUE highest/lowest point // If boundsec is set, we're looking for specials. In that case, iterate over every line in this sector to find the TRUE highest/lowest point
if (perfect) { if (perfect) {
@ -1117,7 +1112,7 @@ fixed_t P_MobjFloorZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t
// If we're just testing for base sector location (no collision line), just go for the center's spot... // If we're just testing for base sector location (no collision line), just go for the center's spot...
// It'll get fixed when we test for collision anyway, and the final result can't be lower than this // It'll get fixed when we test for collision anyway, and the final result can't be lower than this
if (line == NULL) if (line == NULL)
return P_GetZAt(slope, x, y); return P_GetSlopeZAt(slope, x, y);
return HighestOnLine(mobj->radius, x, y, line, slope, lowest); return HighestOnLine(mobj->radius, x, y, line, slope, lowest);
} else // Well, that makes it easy. Just get the floor height } else // Well, that makes it easy. Just get the floor height
@ -1154,7 +1149,7 @@ fixed_t P_MobjCeilingZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed
// If the highest point is in the sector, then we have it easy! Just get the Z at that point // If the highest point is in the sector, then we have it easy! Just get the Z at that point
if (R_PointInSubsector(testx, testy)->sector == (boundsec ? boundsec : sector)) if (R_PointInSubsector(testx, testy)->sector == (boundsec ? boundsec : sector))
return P_GetZAt(slope, testx, testy); return P_GetSlopeZAt(slope, testx, testy);
// If boundsec is set, we're looking for specials. In that case, iterate over every line in this sector to find the TRUE highest/lowest point // If boundsec is set, we're looking for specials. In that case, iterate over every line in this sector to find the TRUE highest/lowest point
if (perfect) { if (perfect) {
@ -1194,7 +1189,7 @@ fixed_t P_MobjCeilingZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed
// If we're just testing for base sector location (no collision line), just go for the center's spot... // If we're just testing for base sector location (no collision line), just go for the center's spot...
// It'll get fixed when we test for collision anyway, and the final result can't be lower than this // It'll get fixed when we test for collision anyway, and the final result can't be lower than this
if (line == NULL) if (line == NULL)
return P_GetZAt(slope, x, y); return P_GetSlopeZAt(slope, x, y);
return HighestOnLine(mobj->radius, x, y, line, slope, lowest); return HighestOnLine(mobj->radius, x, y, line, slope, lowest);
} else // Well, that makes it easy. Just get the ceiling height } else // Well, that makes it easy. Just get the ceiling height
@ -1232,7 +1227,7 @@ fixed_t P_CameraFloorZ(camera_t *mobj, sector_t *sector, sector_t *boundsec, fix
// If the highest point is in the sector, then we have it easy! Just get the Z at that point // If the highest point is in the sector, then we have it easy! Just get the Z at that point
if (R_PointInSubsector(testx, testy)->sector == (boundsec ? boundsec : sector)) if (R_PointInSubsector(testx, testy)->sector == (boundsec ? boundsec : sector))
return P_GetZAt(slope, testx, testy); return P_GetSlopeZAt(slope, testx, testy);
// If boundsec is set, we're looking for specials. In that case, iterate over every line in this sector to find the TRUE highest/lowest point // If boundsec is set, we're looking for specials. In that case, iterate over every line in this sector to find the TRUE highest/lowest point
if (perfect) { if (perfect) {
@ -1272,7 +1267,7 @@ fixed_t P_CameraFloorZ(camera_t *mobj, sector_t *sector, sector_t *boundsec, fix
// If we're just testing for base sector location (no collision line), just go for the center's spot... // If we're just testing for base sector location (no collision line), just go for the center's spot...
// It'll get fixed when we test for collision anyway, and the final result can't be lower than this // It'll get fixed when we test for collision anyway, and the final result can't be lower than this
if (line == NULL) if (line == NULL)
return P_GetZAt(slope, x, y); return P_GetSlopeZAt(slope, x, y);
return HighestOnLine(mobj->radius, x, y, line, slope, lowest); return HighestOnLine(mobj->radius, x, y, line, slope, lowest);
} else // Well, that makes it easy. Just get the floor height } else // Well, that makes it easy. Just get the floor height
@ -1309,7 +1304,7 @@ fixed_t P_CameraCeilingZ(camera_t *mobj, sector_t *sector, sector_t *boundsec, f
// If the highest point is in the sector, then we have it easy! Just get the Z at that point // If the highest point is in the sector, then we have it easy! Just get the Z at that point
if (R_PointInSubsector(testx, testy)->sector == (boundsec ? boundsec : sector)) if (R_PointInSubsector(testx, testy)->sector == (boundsec ? boundsec : sector))
return P_GetZAt(slope, testx, testy); return P_GetSlopeZAt(slope, testx, testy);
// If boundsec is set, we're looking for specials. In that case, iterate over every line in this sector to find the TRUE highest/lowest point // If boundsec is set, we're looking for specials. In that case, iterate over every line in this sector to find the TRUE highest/lowest point
if (perfect) { if (perfect) {
@ -1349,7 +1344,7 @@ fixed_t P_CameraCeilingZ(camera_t *mobj, sector_t *sector, sector_t *boundsec, f
// If we're just testing for base sector location (no collision line), just go for the center's spot... // If we're just testing for base sector location (no collision line), just go for the center's spot...
// It'll get fixed when we test for collision anyway, and the final result can't be lower than this // It'll get fixed when we test for collision anyway, and the final result can't be lower than this
if (line == NULL) if (line == NULL)
return P_GetZAt(slope, x, y); return P_GetSlopeZAt(slope, x, y);
return HighestOnLine(mobj->radius, x, y, line, slope, lowest); return HighestOnLine(mobj->radius, x, y, line, slope, lowest);
} else // Well, that makes it easy. Just get the ceiling height } else // Well, that makes it easy. Just get the ceiling height
@ -2895,7 +2890,6 @@ static void P_PlayerZMovement(mobj_t *mo)
mo->eflags |= MFE_JUSTHITFLOOR; // Spin Attack mo->eflags |= MFE_JUSTHITFLOOR; // Spin Attack
{ {
#ifdef POLYOBJECTS
// Check if we're on a polyobject // Check if we're on a polyobject
// that triggers a linedef executor. // that triggers a linedef executor.
msecnode_t *node; msecnode_t *node;
@ -2955,8 +2949,6 @@ static void P_PlayerZMovement(mobj_t *mo)
} }
if (!stopmovecut) if (!stopmovecut)
#endif
// Cut momentum in half when you hit the ground and // Cut momentum in half when you hit the ground and
// aren't pressing any controls. // aren't pressing any controls.
if (!(mo->player->cmd.forwardmove || mo->player->cmd.sidemove) && !mo->player->cmomx && !mo->player->cmomy && !(mo->player->pflags & PF_SPINNING)) if (!(mo->player->cmd.forwardmove || mo->player->cmd.sidemove) && !mo->player->cmomx && !mo->player->cmomy && !(mo->player->pflags & PF_SPINNING))
@ -3213,9 +3205,7 @@ static boolean P_SceneryZMovement(mobj_t *mo)
// //
boolean P_CanRunOnWater(player_t *player, ffloor_t *rover) boolean P_CanRunOnWater(player_t *player, ffloor_t *rover)
{ {
fixed_t topheight = *rover->t_slope ? fixed_t topheight = P_GetFFloorTopZAt(rover, player->mo->x, player->mo->y);
P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y) :
*rover->topheight;
if (!player->powers[pw_carry] && !player->homing if (!player->powers[pw_carry] && !player->homing
&& ((player->powers[pw_super] || player->charflags & SF_RUNONWATER || player->dashmode >= DASHMODE_THRESHOLD) && player->mo->ceilingz-topheight >= player->mo->height) && ((player->powers[pw_super] || player->charflags & SF_RUNONWATER || player->dashmode >= DASHMODE_THRESHOLD) && player->mo->ceilingz-topheight >= player->mo->height)
@ -3258,14 +3248,8 @@ void P_MobjCheckWater(mobj_t *mobj)
|| ((rover->flags & FF_BLOCKOTHERS) && !mobj->player))) || ((rover->flags & FF_BLOCKOTHERS) && !mobj->player)))
continue; continue;
topheight = *rover->topheight; topheight = P_GetFFloorTopZAt (rover, mobj->x, mobj->y);
bottomheight = *rover->bottomheight; bottomheight = P_GetFFloorBottomZAt(rover, mobj->x, mobj->y);
if (*rover->t_slope)
topheight = P_GetZAt(*rover->t_slope, mobj->x, mobj->y);
if (*rover->b_slope)
bottomheight = P_GetZAt(*rover->b_slope, mobj->x, mobj->y);
if (mobj->eflags & MFE_VERTICALFLIP) if (mobj->eflags & MFE_VERTICALFLIP)
{ {
@ -3512,14 +3496,8 @@ static void P_SceneryCheckWater(mobj_t *mobj)
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_SWIMMABLE) || rover->flags & FF_BLOCKOTHERS) if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_SWIMMABLE) || rover->flags & FF_BLOCKOTHERS)
continue; continue;
topheight = *rover->topheight; topheight = P_GetFFloorTopZAt (rover, mobj->x, mobj->y);
bottomheight = *rover->bottomheight; bottomheight = P_GetFFloorBottomZAt(rover, mobj->x, mobj->y);
if (*rover->t_slope)
topheight = P_GetZAt(*rover->t_slope, mobj->x, mobj->y);
if (*rover->b_slope)
bottomheight = P_GetZAt(*rover->b_slope, mobj->x, mobj->y);
if (topheight <= mobj->z if (topheight <= mobj->z
|| bottomheight > (mobj->z + (mobj->height>>1))) || bottomheight > (mobj->z + (mobj->height>>1)))
@ -3564,13 +3542,9 @@ static boolean P_CameraCheckHeat(camera_t *thiscam)
if (!(rover->flags & FF_EXISTS)) if (!(rover->flags & FF_EXISTS))
continue; continue;
if (halfheight >= (*rover->t_slope ? if (halfheight >= P_GetFFloorTopZAt(rover, thiscam->x, thiscam->y))
P_GetZAt(*rover->t_slope, thiscam->x, thiscam->y) :
*rover->topheight))
continue; continue;
if (halfheight <= (*rover->b_slope ? if (halfheight <= P_GetFFloorBottomZAt(rover, thiscam->x, thiscam->y))
P_GetZAt(*rover->b_slope, thiscam->x, thiscam->y) :
*rover->bottomheight))
continue; continue;
if (P_FindSpecialLineFromTag(13, rover->master->frontsector->tag, -1) != -1) if (P_FindSpecialLineFromTag(13, rover->master->frontsector->tag, -1) != -1)
@ -3598,13 +3572,9 @@ static boolean P_CameraCheckWater(camera_t *thiscam)
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_SWIMMABLE) || rover->flags & FF_BLOCKOTHERS) if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_SWIMMABLE) || rover->flags & FF_BLOCKOTHERS)
continue; continue;
if (halfheight >= (*rover->t_slope ? if (halfheight >= P_GetFFloorTopZAt(rover, thiscam->x, thiscam->y))
P_GetZAt(*rover->t_slope, thiscam->x, thiscam->y) :
*rover->topheight))
continue; continue;
if (halfheight <= ( if (halfheight <= P_GetFFloorBottomZAt(rover, thiscam->x, thiscam->y))
*rover->b_slope ? P_GetZAt(*rover->b_slope, thiscam->x, thiscam->y) :
*rover->bottomheight))
continue; continue;
return true; return true;
@ -3952,9 +3922,7 @@ static void CalculatePrecipFloor(precipmobj_t *mobj)
mobjsecsubsec = mobj->subsector->sector; mobjsecsubsec = mobj->subsector->sector;
else else
return; return;
mobj->floorz = mobjsecsubsec->f_slope ? mobj->floorz = P_GetSectorFloorZAt(mobjsecsubsec, mobj->x, mobj->y);
P_GetZAt(mobjsecsubsec->f_slope, mobj->x, mobj->y) :
mobjsecsubsec->floorheight;
if (mobjsecsubsec->ffloors) if (mobjsecsubsec->ffloors)
{ {
ffloor_t *rover; ffloor_t *rover;
@ -3969,11 +3937,7 @@ static void CalculatePrecipFloor(precipmobj_t *mobj)
if (!(rover->flags & FF_BLOCKOTHERS) && !(rover->flags & FF_SWIMMABLE)) if (!(rover->flags & FF_BLOCKOTHERS) && !(rover->flags & FF_SWIMMABLE))
continue; continue;
if (*rover->t_slope) topheight = P_GetFFloorTopZAt(rover, mobj->x, mobj->y);
topheight = P_GetZAt(*rover->t_slope, mobj->x, mobj->y);
else
topheight = *rover->topheight;
if (topheight > mobj->floorz) if (topheight > mobj->floorz)
mobj->floorz = topheight; mobj->floorz = topheight;
} }
@ -7059,8 +7023,7 @@ static void P_MobjScaleThink(mobj_t *mobj)
fixed_t oldheight = mobj->height; fixed_t oldheight = mobj->height;
UINT8 correctionType = 0; // Don't correct Z position, just gain height UINT8 correctionType = 0; // Don't correct Z position, just gain height
if ((mobj->flags & MF_NOCLIPHEIGHT || (mobj->z > mobj->floorz && mobj->z + mobj->height < mobj->ceilingz)) if (mobj->flags & MF_NOCLIPHEIGHT || (mobj->z > mobj->floorz && mobj->z + mobj->height < mobj->ceilingz))
&& mobj->type != MT_EGGMOBILE_FIRE)
correctionType = 1; // Correct Z position by centering correctionType = 1; // Correct Z position by centering
else if (mobj->eflags & MFE_VERTICALFLIP) else if (mobj->eflags & MFE_VERTICALFLIP)
correctionType = 2; // Correct Z position by moving down correctionType = 2; // Correct Z position by moving down
@ -7081,10 +7044,6 @@ static void P_MobjScaleThink(mobj_t *mobj)
/// \todo Lua hook for "reached destscale"? /// \todo Lua hook for "reached destscale"?
switch (mobj->type) switch (mobj->type)
{ {
case MT_EGGMOBILE_FIRE:
mobj->destscale = FRACUNIT;
mobj->scalespeed = FRACUNIT>>4;
break;
default: default:
break; break;
} }
@ -8260,6 +8219,7 @@ static boolean P_MobjDeadThink(mobj_t *mobj)
// See Linedef Exec 457 (Track mobj angle to point) // See Linedef Exec 457 (Track mobj angle to point)
static void P_TracerAngleThink(mobj_t *mobj) static void P_TracerAngleThink(mobj_t *mobj)
{ {
angle_t looking;
angle_t ang; angle_t ang;
if (!mobj->tracer) if (!mobj->tracer)
@ -8274,7 +8234,12 @@ static void P_TracerAngleThink(mobj_t *mobj)
// mobj->cvval - Allowable failure delay // mobj->cvval - Allowable failure delay
// mobj->cvmem - Failure timer // mobj->cvmem - Failure timer
ang = mobj->angle - R_PointToAngle2(mobj->x, mobj->y, mobj->tracer->x, mobj->tracer->y); if (mobj->player)
looking = ( mobj->player->cmd.angleturn << 16 );/* fixes CS_LMAOGALOG */
else
looking = mobj->angle;
ang = looking - R_PointToAngle2(mobj->x, mobj->y, mobj->tracer->x, mobj->tracer->y);
// \todo account for distance between mobj and tracer // \todo account for distance between mobj and tracer
// Because closer mobjs can be facing beyond the angle tolerance // Because closer mobjs can be facing beyond the angle tolerance
@ -9464,7 +9429,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
case MT_BOSSFLYPOINT: case MT_BOSSFLYPOINT:
return false; return false;
case MT_NIGHTSCORE: case MT_NIGHTSCORE:
mobj->color = (UINT8)(leveltime % SKINCOLOR_WHITE); mobj->color = (UINT16)(leveltime % SKINCOLOR_WHITE);
break; break;
case MT_JETFUME1: case MT_JETFUME1:
if (!P_JetFume1Think(mobj)) if (!P_JetFume1Think(mobj))
@ -10499,12 +10464,8 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
// Make sure scale matches destscale immediately when spawned // Make sure scale matches destscale immediately when spawned
P_SetScale(mobj, mobj->destscale); P_SetScale(mobj, mobj->destscale);
mobj->floorz = mobj->subsector->sector->f_slope ? mobj->floorz = P_GetSectorFloorZAt (mobj->subsector->sector, x, y);
P_GetZAt(mobj->subsector->sector->f_slope, x, y) : mobj->ceilingz = P_GetSectorCeilingZAt(mobj->subsector->sector, x, y);
mobj->subsector->sector->floorheight;
mobj->ceilingz = mobj->subsector->sector->c_slope ?
P_GetZAt(mobj->subsector->sector->c_slope, x, y) :
mobj->subsector->sector->ceilingheight;
mobj->floorrover = NULL; mobj->floorrover = NULL;
mobj->ceilingrover = NULL; mobj->ceilingrover = NULL;
@ -10675,7 +10636,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
break; break;
case MT_EGGROBO1: case MT_EGGROBO1:
mobj->movecount = P_RandomKey(13); mobj->movecount = P_RandomKey(13);
mobj->color = SKINCOLOR_RUBY + P_RandomKey(MAXSKINCOLORS - SKINCOLOR_RUBY); mobj->color = SKINCOLOR_RUBY + P_RandomKey(numskincolors - SKINCOLOR_RUBY);
break; break;
case MT_HIVEELEMENTAL: case MT_HIVEELEMENTAL:
mobj->extravalue1 = 5; mobj->extravalue1 = 5;
@ -10857,12 +10818,8 @@ static precipmobj_t *P_SpawnPrecipMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype
// set subsector and/or block links // set subsector and/or block links
P_SetPrecipitationThingPosition(mobj); P_SetPrecipitationThingPosition(mobj);
mobj->floorz = starting_floorz = mobj->subsector->sector->f_slope ? mobj->floorz = starting_floorz = P_GetSectorFloorZAt (mobj->subsector->sector, x, y);
P_GetZAt(mobj->subsector->sector->f_slope, x, y) : mobj->ceilingz = P_GetSectorCeilingZAt(mobj->subsector->sector, x, y);
mobj->subsector->sector->floorheight;
mobj->ceilingz = mobj->subsector->sector->c_slope ?
P_GetZAt(mobj->subsector->sector->c_slope, x, y) :
mobj->subsector->sector->ceilingheight;
mobj->floorrover = NULL; mobj->floorrover = NULL;
mobj->ceilingrover = NULL; mobj->ceilingrover = NULL;
@ -11505,12 +11462,8 @@ void P_MovePlayerToSpawn(INT32 playernum, mapthing_t *mthing)
// set Z height // set Z height
sector = R_PointInSubsector(x, y)->sector; sector = R_PointInSubsector(x, y)->sector;
floor = sector->f_slope ? floor = P_GetSectorFloorZAt (sector, x, y);
P_GetZAt(sector->f_slope, x, y) : ceiling = P_GetSectorCeilingZAt(sector, x, y);
sector->floorheight;
ceiling = sector->c_slope ?
P_GetZAt(sector->c_slope, x, y) :
sector->ceilingheight;
ceilingspawn = ceiling - mobjinfo[MT_PLAYER].height; ceilingspawn = ceiling - mobjinfo[MT_PLAYER].height;
if (mthing) if (mthing)
@ -11580,12 +11533,8 @@ void P_MovePlayerToStarpost(INT32 playernum)
P_SetThingPosition(mobj); P_SetThingPosition(mobj);
sector = R_PointInSubsector(mobj->x, mobj->y)->sector; sector = R_PointInSubsector(mobj->x, mobj->y)->sector;
floor = sector->f_slope ? floor = P_GetSectorFloorZAt (sector, mobj->x, mobj->y);
P_GetZAt(sector->f_slope, mobj->x, mobj->y) : ceiling = P_GetSectorCeilingZAt(sector, mobj->x, mobj->y);
sector->floorheight;
ceiling = sector->c_slope ?
P_GetZAt(sector->c_slope, mobj->x, mobj->y) :
sector->ceilingheight;
z = p->starpostz << FRACBITS; z = p->starpostz << FRACBITS;
@ -11634,11 +11583,9 @@ fixed_t P_GetMobjSpawnHeight(const mobjtype_t mobjtype, const fixed_t x, const f
// Establish height. // Establish height.
if (flip) if (flip)
return (ss->sector->c_slope ? P_GetZAt(ss->sector->c_slope, x, y) : ss->sector->ceilingheight) return P_GetSectorCeilingZAt(ss->sector, x, y) - offset - mobjinfo[mobjtype].height;
- offset - mobjinfo[mobjtype].height;
else else
return (ss->sector->f_slope ? P_GetZAt(ss->sector->f_slope, x, y) : ss->sector->floorheight) return P_GetSectorFloorZAt(ss->sector, x, y) + offset;
+ offset;
} }
fixed_t P_GetMapThingSpawnHeight(const mobjtype_t mobjtype, const mapthing_t* mthing, const fixed_t x, const fixed_t y) fixed_t P_GetMapThingSpawnHeight(const mobjtype_t mobjtype, const mapthing_t* mthing, const fixed_t x, const fixed_t y)
@ -11977,7 +11924,7 @@ static boolean P_SetupEmblem(mapthing_t *mthing, mobj_t *mobj)
{ {
INT32 j; INT32 j;
emblem_t* emblem = M_GetLevelEmblems(gamemap); emblem_t* emblem = M_GetLevelEmblems(gamemap);
skincolors_t emcolor; skincolornum_t emcolor;
while (emblem) while (emblem)
{ {
@ -12000,7 +11947,7 @@ static boolean P_SetupEmblem(mapthing_t *mthing, mobj_t *mobj)
mobj->health = j + 1; mobj->health = j + 1;
emcolor = M_GetEmblemColor(&emblemlocations[j]); // workaround for compiler complaint about bad function casting emcolor = M_GetEmblemColor(&emblemlocations[j]); // workaround for compiler complaint about bad function casting
mobj->color = (UINT8)emcolor; mobj->color = (UINT16)emcolor;
if (emblemlocations[j].collected if (emblemlocations[j].collected
|| (emblemlocations[j].type == ET_SKIN && emblemlocations[j].var != players[0].skin)) || (emblemlocations[j].type == ET_SKIN && emblemlocations[j].var != players[0].skin))
@ -12639,7 +12586,7 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean
break; break;
case MT_BALLOON: case MT_BALLOON:
if (mthing->angle > 0) if (mthing->angle > 0)
mobj->color = ((mthing->angle - 1) % (MAXSKINCOLORS - 1)) + 1; mobj->color = ((mthing->angle - 1) % (numskincolors - 1)) + 1;
break; break;
#define makesoftwarecorona(mo, h) \ #define makesoftwarecorona(mo, h) \
corona = P_SpawnMobjFromMobj(mo, 0, 0, h<<FRACBITS, MT_PARTICLE);\ corona = P_SpawnMobjFromMobj(mo, 0, 0, h<<FRACBITS, MT_PARTICLE);\
@ -12739,9 +12686,14 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean
mobj->threshold = min(mthing->extrainfo, 7); mobj->threshold = min(mthing->extrainfo, 7);
break; break;
case MT_TUBEWAYPOINT: case MT_TUBEWAYPOINT:
mobj->health = mthing->angle & 255; {
mobj->threshold = mthing->angle >> 8; UINT8 sequence = mthing->angle >> 8;
UINT8 id = mthing->angle & 255;
mobj->health = id;
mobj->threshold = sequence;
P_AddWaypoint(sequence, id, mobj);
break; break;
}
case MT_IDEYAANCHOR: case MT_IDEYAANCHOR:
mobj->health = mthing->extrainfo; mobj->health = mthing->extrainfo;
break; break;

View File

@ -312,7 +312,7 @@ typedef struct mobj_s
void *skin; // overrides 'sprite' when non-NULL (for player bodies to 'remember' the skin) void *skin; // overrides 'sprite' when non-NULL (for player bodies to 'remember' the skin)
// Player and mobj sprites in multiplayer modes are modified // Player and mobj sprites in multiplayer modes are modified
// using an internal color lookup table for re-indexing. // using an internal color lookup table for re-indexing.
UINT8 color; // This replaces MF_TRANSLATION. Use 0 for default (no translation). UINT16 color; // This replaces MF_TRANSLATION. Use 0 for default (no translation).
// Interaction info, by BLOCKMAP. // Interaction info, by BLOCKMAP.
// Links in blocks (if needed). // Links in blocks (if needed).

File diff suppressed because it is too large Load Diff

View File

@ -18,8 +18,6 @@
#include "p_mobj.h" #include "p_mobj.h"
#include "r_defs.h" #include "r_defs.h"
// haleyjd: temporary define
#ifdef POLYOBJECTS
// //
// Defines // Defines
// //
@ -31,7 +29,6 @@
#define POLYOBJ_SPAWNCRUSH_DOOMEDNUM 762 // todo: REMOVE #define POLYOBJ_SPAWNCRUSH_DOOMEDNUM 762 // todo: REMOVE
#define POLYOBJ_START_LINE 20 #define POLYOBJ_START_LINE 20
#define POLYOBJ_EXPLICIT_LINE 21
#define POLYINFO_SPECIALNUM 22 #define POLYINFO_SPECIALNUM 22
typedef enum typedef enum
@ -143,26 +140,26 @@ typedef struct polymove_s
UINT32 angle; // angle along which to move UINT32 angle; // angle along which to move
} polymove_t; } polymove_t;
// PolyObject waypoint movement return behavior
typedef enum
{
PWR_STOP, // Stop after reaching last waypoint
PWR_WRAP, // Wrap back to first waypoint
PWR_COMEBACK, // Repeat sequence in reverse
} polywaypointreturn_e;
typedef struct polywaypoint_s typedef struct polywaypoint_s
{ {
thinker_t thinker; // must be first thinker_t thinker; // must be first
INT32 polyObjNum; // numeric id of polyobject INT32 polyObjNum; // numeric id of polyobject
INT32 speed; // resultant velocity INT32 speed; // resultant velocity
INT32 sequence; // waypoint sequence # INT32 sequence; // waypoint sequence #
INT32 pointnum; // waypoint # INT32 pointnum; // waypoint #
INT32 direction; // 1 for normal, -1 for backwards INT32 direction; // 1 for normal, -1 for backwards
UINT8 comeback; // reverses and comes back when the end is reached UINT8 returnbehavior; // behavior after reaching the last waypoint
UINT8 wrap; // Wrap around waypoints UINT8 continuous; // continuously move - used with PWR_WRAP or PWR_COMEBACK
UINT8 continuous; // continuously move - used with COMEBACK or WRAP UINT8 stophere; // Will stop after it reaches the next waypoint
UINT8 stophere; // Will stop after it reaches the next waypoint
// Difference between location of PO and location of waypoint (offset)
fixed_t diffx;
fixed_t diffy;
fixed_t diffz;
mobj_t *target; // next waypoint mobj
} polywaypoint_t; } polywaypoint_t;
typedef struct polyslidedoor_s typedef struct polyslidedoor_s
@ -257,15 +254,19 @@ typedef struct polymovedata_s
UINT8 overRide; // if true, will override any action on the object UINT8 overRide; // if true, will override any action on the object
} polymovedata_t; } polymovedata_t;
typedef enum
{
PWF_REVERSE = 1, // Move through waypoints in reverse order
PWF_LOOP = 1<<1, // Loop movement (used with PWR_WRAP or PWR_COMEBACK)
} polywaypointflags_e;
typedef struct polywaypointdata_s typedef struct polywaypointdata_s
{ {
INT32 polyObjNum; // numeric id of polyobject to affect INT32 polyObjNum; // numeric id of polyobject to affect
INT32 sequence; // waypoint sequence # INT32 sequence; // waypoint sequence #
fixed_t speed; // linear speed fixed_t speed; // linear speed
UINT8 reverse; // if true, will go in reverse waypoint order UINT8 returnbehavior; // behavior after reaching the last waypoint
UINT8 comeback; // reverses and comes back when the end is reached UINT8 flags; // PWF_ flags
UINT8 wrap; // Wrap around waypoints
UINT8 continuous; // continuously move - used with COMEBACK or WRAP
} polywaypointdata_t; } polywaypointdata_t;
// polyobject door types // polyobject door types
@ -301,6 +302,14 @@ typedef struct polyrotdisplacedata_s
UINT8 turnobjs; UINT8 turnobjs;
} polyrotdisplacedata_t; } polyrotdisplacedata_t;
typedef struct polyflagdata_s
{
INT32 polyObjNum;
INT32 speed;
UINT32 angle;
fixed_t momx;
} polyflagdata_t;
typedef struct polyfadedata_s typedef struct polyfadedata_s
{ {
INT32 polyObjNum; INT32 polyObjNum;
@ -322,7 +331,6 @@ boolean P_PointInsidePolyobj(polyobj_t *po, fixed_t x, fixed_t y);
boolean P_MobjTouchingPolyobj(polyobj_t *po, mobj_t *mo); boolean P_MobjTouchingPolyobj(polyobj_t *po, mobj_t *mo);
boolean P_MobjInsidePolyobj(polyobj_t *po, mobj_t *mo); boolean P_MobjInsidePolyobj(polyobj_t *po, mobj_t *mo);
boolean P_BBoxInsidePolyobj(polyobj_t *po, fixed_t *bbox); boolean P_BBoxInsidePolyobj(polyobj_t *po, fixed_t *bbox);
void Polyobj_GetInfo(INT16 poid, INT32 *poflags, INT32 *parentID, INT32 *potrans);
// thinkers (needed in p_saveg.c) // thinkers (needed in p_saveg.c)
void T_PolyObjRotate(polyrotate_t *); void T_PolyObjRotate(polyrotate_t *);
@ -335,14 +343,14 @@ void T_PolyObjRotDisplace (polyrotdisplace_t *);
void T_PolyObjFlag (polymove_t *); void T_PolyObjFlag (polymove_t *);
void T_PolyObjFade (polyfade_t *); void T_PolyObjFade (polyfade_t *);
INT32 EV_DoPolyDoor(polydoordata_t *); boolean EV_DoPolyDoor(polydoordata_t *);
INT32 EV_DoPolyObjMove(polymovedata_t *); boolean EV_DoPolyObjMove(polymovedata_t *);
INT32 EV_DoPolyObjWaypoint(polywaypointdata_t *); boolean EV_DoPolyObjWaypoint(polywaypointdata_t *);
INT32 EV_DoPolyObjRotate(polyrotdata_t *); boolean EV_DoPolyObjRotate(polyrotdata_t *);
INT32 EV_DoPolyObjDisplace(polydisplacedata_t *); boolean EV_DoPolyObjDisplace(polydisplacedata_t *);
INT32 EV_DoPolyObjRotDisplace(polyrotdisplacedata_t *); boolean EV_DoPolyObjRotDisplace(polyrotdisplacedata_t *);
INT32 EV_DoPolyObjFlag(struct line_s *); boolean EV_DoPolyObjFlag(polyflagdata_t *);
INT32 EV_DoPolyObjFade(polyfadedata_t *); boolean EV_DoPolyObjFade(polyfadedata_t *);
// //
@ -353,8 +361,6 @@ extern polyobj_t *PolyObjects;
extern INT32 numPolyObjects; extern INT32 numPolyObjects;
extern polymaplink_t **polyblocklinks; // polyobject blockmap extern polymaplink_t **polyblocklinks; // polyobject blockmap
#endif // ifdef POLYOBJECTS
#endif #endif
// EOF // EOF

File diff suppressed because it is too large Load Diff

View File

@ -144,6 +144,133 @@ mapthing_t *playerstarts[MAXPLAYERS];
mapthing_t *bluectfstarts[MAXPLAYERS]; mapthing_t *bluectfstarts[MAXPLAYERS];
mapthing_t *redctfstarts[MAXPLAYERS]; mapthing_t *redctfstarts[MAXPLAYERS];
// Maintain waypoints
mobj_t *waypoints[NUMWAYPOINTSEQUENCES][WAYPOINTSEQUENCESIZE];
UINT16 numwaypoints[NUMWAYPOINTSEQUENCES];
void P_AddWaypoint(UINT8 sequence, UINT8 id, mobj_t *waypoint)
{
waypoints[sequence][id] = waypoint;
if (id >= numwaypoints[sequence])
numwaypoints[sequence] = id + 1;
}
static void P_ResetWaypoints(void)
{
UINT16 sequence, id;
for (sequence = 0; sequence < NUMWAYPOINTSEQUENCES; sequence++)
{
for (id = 0; id < numwaypoints[sequence]; id++)
waypoints[sequence][id] = NULL;
numwaypoints[sequence] = 0;
}
}
mobj_t *P_GetFirstWaypoint(UINT8 sequence)
{
return waypoints[sequence][0];
}
mobj_t *P_GetLastWaypoint(UINT8 sequence)
{
return waypoints[sequence][numwaypoints[sequence] - 1];
}
mobj_t *P_GetPreviousWaypoint(mobj_t *current, boolean wrap)
{
UINT8 sequence = current->threshold;
UINT8 id = current->health;
if (id == 0)
{
if (!wrap)
return NULL;
id = numwaypoints[sequence] - 1;
}
else
id--;
return waypoints[sequence][id];
}
mobj_t *P_GetNextWaypoint(mobj_t *current, boolean wrap)
{
UINT8 sequence = current->threshold;
UINT8 id = current->health;
if (id == numwaypoints[sequence] - 1)
{
if (!wrap)
return NULL;
id = 0;
}
else
id++;
return waypoints[sequence][id];
}
mobj_t *P_GetClosestWaypoint(UINT8 sequence, mobj_t *mo)
{
UINT8 wp;
mobj_t *mo2, *result = NULL;
fixed_t bestdist = 0;
fixed_t curdist;
for (wp = 0; wp < numwaypoints[sequence]; wp++)
{
mo2 = waypoints[sequence][wp];
if (!mo2)
continue;
curdist = P_AproxDistance(P_AproxDistance(mo->x - mo2->x, mo->y - mo2->y), mo->z - mo2->z);
if (result && curdist > bestdist)
continue;
result = mo2;
bestdist = curdist;
}
return result;
}
// Return true if all waypoints are in the same location
boolean P_IsDegeneratedWaypointSequence(UINT8 sequence)
{
mobj_t *first, *waypoint;
UINT8 wp;
if (numwaypoints[sequence] <= 1)
return true;
first = waypoints[sequence][0];
for (wp = 1; wp < numwaypoints[sequence]; wp++)
{
waypoint = waypoints[sequence][wp];
if (!waypoint)
continue;
if (waypoint->x != first->x)
return false;
if (waypoint->y != first->y)
return false;
if (waypoint->z != first->z)
return false;
}
return true;
}
/** Logs an error about a map being corrupt, then terminate. /** Logs an error about a map being corrupt, then terminate.
* This allows reporting highly technical errors for usefulness, without * This allows reporting highly technical errors for usefulness, without
* confusing a novice map designer who simply needs to run ZenNode. * confusing a novice map designer who simply needs to run ZenNode.
@ -218,6 +345,9 @@ static void P_ClearSingleMapHeaderInfo(INT16 i)
mapheaderinfo[num]->typeoflevel = 0; mapheaderinfo[num]->typeoflevel = 0;
mapheaderinfo[num]->nextlevel = (INT16)(i + 1); mapheaderinfo[num]->nextlevel = (INT16)(i + 1);
mapheaderinfo[num]->startrings = 0; mapheaderinfo[num]->startrings = 0;
mapheaderinfo[num]->sstimer = 90;
mapheaderinfo[num]->ssspheres = 1;
mapheaderinfo[num]->gravity = FRACUNIT/2;
mapheaderinfo[num]->keywords[0] = '\0'; mapheaderinfo[num]->keywords[0] = '\0';
snprintf(mapheaderinfo[num]->musname, 7, "%sM", G_BuildMapName(i)); snprintf(mapheaderinfo[num]->musname, 7, "%sM", G_BuildMapName(i));
mapheaderinfo[num]->musname[6] = 0; mapheaderinfo[num]->musname[6] = 0;
@ -953,9 +1083,7 @@ static void P_InitializeLinedef(line_t *ld)
ld->splats = NULL; ld->splats = NULL;
#endif #endif
ld->firsttag = ld->nexttag = -1; ld->firsttag = ld->nexttag = -1;
#ifdef POLYOBJECTS
ld->polyobj = NULL; ld->polyobj = NULL;
#endif
ld->text = NULL; ld->text = NULL;
ld->callcount = 0; ld->callcount = 0;
@ -1869,10 +1997,8 @@ static void P_InitializeSeg(seg_t *seg)
seg->numlights = 0; seg->numlights = 0;
seg->rlights = NULL; seg->rlights = NULL;
#ifdef POLYOBJECTS
seg->polyseg = NULL; seg->polyseg = NULL;
seg->dontrenderme = false; seg->dontrenderme = false;
#endif
} }
static void P_LoadSegs(UINT8 *data) static void P_LoadSegs(UINT8 *data)
@ -2235,11 +2361,9 @@ static boolean P_LoadBlockMap(UINT8 *data, size_t count)
blocklinks = Z_Calloc(count, PU_LEVEL, NULL); blocklinks = Z_Calloc(count, PU_LEVEL, NULL);
blockmap = blockmaplump+4; blockmap = blockmaplump+4;
#ifdef POLYOBJECTS
// haleyjd 2/22/06: setup polyobject blockmap // haleyjd 2/22/06: setup polyobject blockmap
count = sizeof(*polyblocklinks) * bmapwidth * bmapheight; count = sizeof(*polyblocklinks) * bmapwidth * bmapheight;
polyblocklinks = Z_Calloc(count, PU_LEVEL, NULL); polyblocklinks = Z_Calloc(count, PU_LEVEL, NULL);
#endif
return true; return true;
} }
@ -2490,11 +2614,9 @@ static void P_CreateBlockMap(void)
blocklinks = Z_Calloc(count, PU_LEVEL, NULL); blocklinks = Z_Calloc(count, PU_LEVEL, NULL);
blockmap = blockmaplump + 4; blockmap = blockmaplump + 4;
#ifdef POLYOBJECTS
// haleyjd 2/22/06: setup polyobject blockmap // haleyjd 2/22/06: setup polyobject blockmap
count = sizeof(*polyblocklinks) * bmapwidth * bmapheight; count = sizeof(*polyblocklinks) * bmapwidth * bmapheight;
polyblocklinks = Z_Calloc(count, PU_LEVEL, NULL); polyblocklinks = Z_Calloc(count, PU_LEVEL, NULL);
#endif
} }
} }
@ -3550,6 +3672,8 @@ boolean P_LoadLevel(boolean fromnetsave)
P_ResetSpawnpoints(); P_ResetSpawnpoints();
P_ResetWaypoints();
P_MapStart(); P_MapStart();
if (!P_LoadMapFromFile()) if (!P_LoadMapFromFile())

View File

@ -100,7 +100,6 @@ static fixed_t P_InterceptVector2(divline_t *v2, divline_t *v1)
return frac; return frac;
} }
#ifdef POLYOBJECTS
static boolean P_CrossSubsecPolyObj(polyobj_t *po, register los_t *los) static boolean P_CrossSubsecPolyObj(polyobj_t *po, register los_t *los)
{ {
size_t i; size_t i;
@ -169,7 +168,6 @@ static boolean P_CrossSubsecPolyObj(polyobj_t *po, register los_t *los)
return true; return true;
} }
#endif
// //
// P_CrossSubsector // P_CrossSubsector
@ -180,9 +178,7 @@ static boolean P_CrossSubsector(size_t num, register los_t *los)
{ {
seg_t *seg; seg_t *seg;
INT32 count; INT32 count;
#ifdef POLYOBJECTS
polyobj_t *po; // haleyjd 02/23/06 polyobj_t *po; // haleyjd 02/23/06
#endif
#ifdef RANGECHECK #ifdef RANGECHECK
if (num >= numsubsectors) if (num >= numsubsectors)
@ -192,7 +188,6 @@ static boolean P_CrossSubsector(size_t num, register los_t *los)
// haleyjd 02/23/06: this assignment should be after the above check // haleyjd 02/23/06: this assignment should be after the above check
seg = segs + subsectors[num].firstline; seg = segs + subsectors[num].firstline;
#ifdef POLYOBJECTS
// haleyjd 02/23/06: check polyobject lines // haleyjd 02/23/06: check polyobject lines
if ((po = subsectors[num].polyList)) if ((po = subsectors[num].polyList))
{ {
@ -207,7 +202,6 @@ static boolean P_CrossSubsector(size_t num, register los_t *los)
po = (polyobj_t *)(po->link.next); po = (polyobj_t *)(po->link.next);
} }
} }
#endif
for (count = subsectors[num].numlines; --count >= 0; seg++) // check lines for (count = subsectors[num].numlines; --count >= 0; seg++) // check lines
{ {
@ -265,10 +259,10 @@ static boolean P_CrossSubsector(size_t num, register los_t *los)
fracx = los->strace.x + FixedMul(los->strace.dx, frac); fracx = los->strace.x + FixedMul(los->strace.dx, frac);
fracy = los->strace.y + FixedMul(los->strace.dy, frac); fracy = los->strace.y + FixedMul(los->strace.dy, frac);
// calculate sector heights // calculate sector heights
frontf = (front->f_slope) ? P_GetZAt(front->f_slope, fracx, fracy) : front->floorheight; frontf = P_GetSectorFloorZAt (front, fracx, fracy);
frontc = (front->c_slope) ? P_GetZAt(front->c_slope, fracx, fracy) : front->ceilingheight; frontc = P_GetSectorCeilingZAt(front, fracx, fracy);
backf = (back->f_slope) ? P_GetZAt(back->f_slope, fracx, fracy) : back->floorheight; backf = P_GetSectorFloorZAt (back , fracx, fracy);
backc = (back->c_slope) ? P_GetZAt(back->c_slope, fracx, fracy) : back->ceilingheight; backc = P_GetSectorCeilingZAt(back , fracx, fracy);
// crosses a two sided line // crosses a two sided line
// no wall to block sight with? // no wall to block sight with?
if (frontf == backf && frontc == backc if (frontf == backf && frontc == backc
@ -318,10 +312,10 @@ static boolean P_CrossSubsector(size_t num, register los_t *los)
continue; continue;
} }
topz = (*rover->t_slope) ? P_GetZAt(*rover->t_slope, fracx, fracy) : *rover->topheight; topz = P_GetFFloorTopZAt (rover, fracx, fracy);
bottomz = (*rover->b_slope) ? P_GetZAt(*rover->b_slope, fracx, fracy) : *rover->bottomheight; bottomz = P_GetFFloorBottomZAt(rover, fracx, fracy);
topslope = FixedDiv(topz - los->sightzstart , frac); topslope = FixedDiv( topz - los->sightzstart, frac);
bottomslope = FixedDiv(bottomz - los->sightzstart , frac); bottomslope = FixedDiv(bottomz - los->sightzstart, frac);
if (topslope >= los->topslope && bottomslope <= los->bottomslope) if (topslope >= los->topslope && bottomslope <= los->bottomslope)
return false; // view completely blocked return false; // view completely blocked
} }
@ -334,10 +328,10 @@ static boolean P_CrossSubsector(size_t num, register los_t *los)
continue; continue;
} }
topz = (*rover->t_slope) ? P_GetZAt(*rover->t_slope, fracx, fracy) : *rover->topheight; topz = P_GetFFloorTopZAt (rover, fracx, fracy);
bottomz = (*rover->b_slope) ? P_GetZAt(*rover->b_slope, fracx, fracy) : *rover->bottomheight; bottomz = P_GetFFloorBottomZAt(rover, fracx, fracy);
topslope = FixedDiv(topz - los->sightzstart , frac); topslope = FixedDiv( topz - los->sightzstart, frac);
bottomslope = FixedDiv(bottomz - los->sightzstart , frac); bottomslope = FixedDiv(bottomz - los->sightzstart, frac);
if (topslope >= los->topslope && bottomslope <= los->bottomslope) if (topslope >= los->topslope && bottomslope <= los->bottomslope)
return false; // view completely blocked return false; // view completely blocked
} }
@ -413,15 +407,10 @@ boolean P_CheckSight(mobj_t *t1, mobj_t *t2)
// killough 11/98: shortcut for melee situations // killough 11/98: shortcut for melee situations
// same subsector? obviously visible // same subsector? obviously visible
#ifndef POLYOBJECTS
if (t1->subsector == t2->subsector)
return true;
#else
// haleyjd 02/23/06: can't do this if there are polyobjects in the subsec // haleyjd 02/23/06: can't do this if there are polyobjects in the subsec
if (!t1->subsector->polyList && if (!t1->subsector->polyList &&
t1->subsector == t2->subsector) t1->subsector == t2->subsector)
return true; return true;
#endif
// An unobstructed LOS is possible. // An unobstructed LOS is possible.
// Now look from eyes of t1 to any part of t2. // Now look from eyes of t1 to any part of t2.
@ -468,21 +457,10 @@ boolean P_CheckSight(mobj_t *t1, mobj_t *t2)
continue; continue;
} }
if (*rover->t_slope) topz1 = P_GetFFloorTopZAt (rover, t1->x, t1->y);
{ topz2 = P_GetFFloorTopZAt (rover, t2->x, t2->y);
topz1 = P_GetZAt(*rover->t_slope, t1->x, t1->y); bottomz1 = P_GetFFloorBottomZAt(rover, t1->x, t1->y);
topz2 = P_GetZAt(*rover->t_slope, t2->x, t2->y); bottomz2 = P_GetFFloorBottomZAt(rover, t2->x, t2->y);
}
else
topz1 = topz2 = *rover->topheight;
if (*rover->b_slope)
{
bottomz1 = P_GetZAt(*rover->b_slope, t1->x, t1->y);
bottomz2 = P_GetZAt(*rover->b_slope, t2->x, t2->y);
}
else
bottomz1 = bottomz2 = *rover->bottomheight;
// Check for blocking floors here. // Check for blocking floors here.
if ((los.sightzstart < bottomz1 && t2->z >= topz2) if ((los.sightzstart < bottomz1 && t2->z >= topz2)

View File

@ -566,7 +566,7 @@ void P_CopySectorSlope(line_t *line)
int i, special = line->special; int i, special = line->special;
// Check for copy linedefs // Check for copy linedefs
for (i = -1; (i = P_FindSectorFromLineTag(line, i)) >= 0;) for (i = -1; (i = P_FindSectorFromTag(line->tag, i)) >= 0;)
{ {
sector_t *srcsec = sectors + i; sector_t *srcsec = sectors + i;
@ -655,17 +655,49 @@ void P_SpawnSlopes(const boolean fromsave) {
// Various utilities related to slopes // Various utilities related to slopes
// //
//
// P_GetZAt
//
// Returns the height of the sloped plane at (x, y) as a fixed_t // Returns the height of the sloped plane at (x, y) as a fixed_t
// fixed_t P_GetSlopeZAt(const pslope_t *slope, fixed_t x, fixed_t y)
fixed_t P_GetZAt(pslope_t *slope, fixed_t x, fixed_t y)
{ {
fixed_t dist = FixedMul(x - slope->o.x, slope->d.x) + fixed_t dist = FixedMul(x - slope->o.x, slope->d.x) +
FixedMul(y - slope->o.y, slope->d.y); FixedMul(y - slope->o.y, slope->d.y);
return slope->o.z + FixedMul(dist, slope->zdelta); return slope->o.z + FixedMul(dist, slope->zdelta);
}
// Like P_GetSlopeZAt but falls back to z if slope is NULL
fixed_t P_GetZAt(const pslope_t *slope, fixed_t x, fixed_t y, fixed_t z)
{
return slope ? P_GetSlopeZAt(slope, x, y) : z;
}
// Returns the height of the sector floor at (x, y)
fixed_t P_GetSectorFloorZAt(const sector_t *sector, fixed_t x, fixed_t y)
{
return sector->f_slope ? P_GetSlopeZAt(sector->f_slope, x, y) : sector->floorheight;
}
// Returns the height of the sector ceiling at (x, y)
fixed_t P_GetSectorCeilingZAt(const sector_t *sector, fixed_t x, fixed_t y)
{
return sector->c_slope ? P_GetSlopeZAt(sector->c_slope, x, y) : sector->ceilingheight;
}
// Returns the height of the FOF top at (x, y)
fixed_t P_GetFFloorTopZAt(const ffloor_t *ffloor, fixed_t x, fixed_t y)
{
return *ffloor->t_slope ? P_GetSlopeZAt(*ffloor->t_slope, x, y) : *ffloor->topheight;
}
// Returns the height of the FOF bottom at (x, y)
fixed_t P_GetFFloorBottomZAt(const ffloor_t *ffloor, fixed_t x, fixed_t y)
{
return *ffloor->b_slope ? P_GetSlopeZAt(*ffloor->b_slope, x, y) : *ffloor->bottomheight;
}
// Returns the height of the light list at (x, y)
fixed_t P_GetLightZAt(const lightlist_t *light, fixed_t x, fixed_t y)
{
return light->slope ? P_GetSlopeZAt(light->slope, x, y) : light->height;
} }

View File

@ -33,7 +33,21 @@ void P_CopySectorSlope(line_t *line);
pslope_t *P_SlopeById(UINT16 id); pslope_t *P_SlopeById(UINT16 id);
// Returns the height of the sloped plane at (x, y) as a fixed_t // Returns the height of the sloped plane at (x, y) as a fixed_t
fixed_t P_GetZAt(pslope_t *slope, fixed_t x, fixed_t y); fixed_t P_GetSlopeZAt(const pslope_t *slope, fixed_t x, fixed_t y);
// Like P_GetSlopeZAt but falls back to z if slope is NULL
fixed_t P_GetZAt(const pslope_t *slope, fixed_t x, fixed_t y, fixed_t z);
// Returns the height of the sector at (x, y)
fixed_t P_GetSectorFloorZAt (const sector_t *sector, fixed_t x, fixed_t y);
fixed_t P_GetSectorCeilingZAt(const sector_t *sector, fixed_t x, fixed_t y);
// Returns the height of the FOF at (x, y)
fixed_t P_GetFFloorTopZAt (const ffloor_t *ffloor, fixed_t x, fixed_t y);
fixed_t P_GetFFloorBottomZAt(const ffloor_t *ffloor, fixed_t x, fixed_t y);
// Returns the height of the light list at (x, y)
fixed_t P_GetLightZAt(const lightlist_t *light, fixed_t x, fixed_t y);
// Lots of physics-based bullshit // Lots of physics-based bullshit
void P_QuantizeMomentumToSlope(vector3_t *momentum, pslope_t *slope); void P_QuantizeMomentumToSlope(vector3_t *momentum, pslope_t *slope);

File diff suppressed because it is too large Load Diff

View File

@ -55,7 +55,6 @@ fixed_t P_FindNextLowestFloor(sector_t *sec, fixed_t currentheight);
fixed_t P_FindLowestCeilingSurrounding(sector_t *sec); fixed_t P_FindLowestCeilingSurrounding(sector_t *sec);
fixed_t P_FindHighestCeilingSurrounding(sector_t *sec); fixed_t P_FindHighestCeilingSurrounding(sector_t *sec);
INT32 P_FindSectorFromLineTag(line_t *line, INT32 start);
INT32 P_FindSectorFromTag(INT16 tag, INT32 start); INT32 P_FindSectorFromTag(INT16 tag, INT32 start);
INT32 P_FindSpecialLineFromTag(INT16 special, INT16 tag, INT32 start); INT32 P_FindSpecialLineFromTag(INT16 special, INT16 tag, INT32 start);
@ -105,10 +104,9 @@ typedef struct
typedef struct typedef struct
{ {
thinker_t thinker; ///< Thinker structure for laser. thinker_t thinker; ///< Thinker structure for laser.
ffloor_t *ffloor; ///< 3Dfloor that is a laser. INT16 tag;
sector_t *sector; ///< Sector in which the effect takes place.
sector_t *sec;
line_t *sourceline; line_t *sourceline;
UINT8 nobosses;
} laserthink_t; } laserthink_t;
/** Strobe light action structure.. /** Strobe light action structure..
@ -308,10 +306,32 @@ typedef struct
fixed_t delaytimer; fixed_t delaytimer;
fixed_t floorwasheight; // Height the floor WAS at fixed_t floorwasheight; // Height the floor WAS at
fixed_t ceilingwasheight; // Height the ceiling WAS at fixed_t ceilingwasheight; // Height the ceiling WAS at
player_t *player; // Player who initiated the thinker (used for airbob)
line_t *sourceline; line_t *sourceline;
} elevator_t; } elevator_t;
typedef enum
{
CF_RETURN = 1, // Return after crumbling
CF_FLOATBOB = 1<<1, // Float on water
CF_REVERSE = 1<<2, // Reverse gravity
} crumbleflag_t;
typedef struct
{
thinker_t thinker;
line_t *sourceline;
sector_t *sector;
sector_t *actionsector; // The sector the rover action is taking place in.
player_t *player; // Player who initiated the thinker (used for airbob)
INT32 direction;
INT32 origalpha;
INT32 timer;
fixed_t speed;
fixed_t floorwasheight; // Height the floor WAS at
fixed_t ceilingwasheight; // Height the ceiling WAS at
UINT8 flags;
} crumble_t;
typedef struct typedef struct
{ {
thinker_t thinker; thinker_t thinker;
@ -401,7 +421,7 @@ typedef enum
typedef struct typedef struct
{ {
thinker_t thinker; thinker_t thinker;
line_t *sourceline; INT16 tag;
sector_t *sector; sector_t *sector;
fixed_t ceilingbottom; fixed_t ceilingbottom;
fixed_t ceilingtop; fixed_t ceilingtop;
@ -441,7 +461,7 @@ void T_MoveFloor(floormove_t *movefloor);
void T_MoveElevator(elevator_t *elevator); void T_MoveElevator(elevator_t *elevator);
void T_ContinuousFalling(continuousfall_t *faller); void T_ContinuousFalling(continuousfall_t *faller);
void T_BounceCheese(bouncecheese_t *bouncer); void T_BounceCheese(bouncecheese_t *bouncer);
void T_StartCrumble(elevator_t *elevator); void T_StartCrumble(crumble_t *crumble);
void T_MarioBlock(mariothink_t *block); void T_MarioBlock(mariothink_t *block);
void T_FloatSector(floatthink_t *floater); void T_FloatSector(floatthink_t *floater);
void T_MarioBlockChecker(mariocheck_t *block); void T_MarioBlockChecker(mariocheck_t *block);

View File

@ -1490,17 +1490,10 @@ void P_PlayLivesJingle(player_t *player)
if (player && !P_IsLocalPlayer(player)) if (player && !P_IsLocalPlayer(player))
return; return;
if (use1upSound) if (use1upSound || cv_1upsound.value)
S_StartSound(NULL, sfx_oneup); S_StartSound(NULL, sfx_oneup);
else if (mariomode) else if (mariomode)
S_StartSound(NULL, sfx_marioa); S_StartSound(NULL, sfx_marioa);
else if (cv_1upsound.value)
{
if (S_sfx[sfx_oneup].lumpnum != LUMPERROR)
S_StartSound(NULL, sfx_oneup);
else
S_StartSound(NULL, sfx_chchng);/* at least play something! */
}
else else
{ {
P_PlayJingle(player, JT_1UP); P_PlayJingle(player, JT_1UP);
@ -1548,10 +1541,6 @@ boolean P_EvaluateMusicStatus(UINT16 status, const char *musname)
int i; int i;
boolean result = false; boolean result = false;
#ifndef HAVE_BLUA
(void)musname;
#endif
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < MAXPLAYERS; i++)
{ {
if (!P_IsLocalPlayer(&players[i])) if (!P_IsLocalPlayer(&players[i]))
@ -1927,7 +1916,7 @@ void P_SpawnShieldOrb(player_t *player)
shieldobj->colorized = true; shieldobj->colorized = true;
} }
else else
shieldobj->color = (UINT8)shieldobj->info->painchance; shieldobj->color = (UINT16)shieldobj->info->painchance;
shieldobj->threshold = (player->powers[pw_shield] & SH_FORCE) ? SH_FORCE : (player->powers[pw_shield] & SH_NOSTACK); shieldobj->threshold = (player->powers[pw_shield] & SH_FORCE) ? SH_FORCE : (player->powers[pw_shield] & SH_NOSTACK);
if (shieldobj->info->seestate) if (shieldobj->info->seestate)
@ -2278,8 +2267,8 @@ boolean P_InSpaceSector(mobj_t *mo) // Returns true if you are in space
if (GETSECSPECIAL(rover->master->frontsector->special, 1) != SPACESPECIAL) if (GETSECSPECIAL(rover->master->frontsector->special, 1) != SPACESPECIAL)
continue; continue;
topheight = *rover->t_slope ? P_GetZAt(*rover->t_slope, mo->x, mo->y) : *rover->topheight; topheight = P_GetFFloorTopZAt (rover, mo->x, mo->y);
bottomheight = *rover->b_slope ? P_GetZAt(*rover->b_slope, mo->x, mo->y) : *rover->bottomheight; bottomheight = P_GetFFloorBottomZAt(rover, mo->x, mo->y);
if (mo->z + (mo->height/2) > topheight) if (mo->z + (mo->height/2) > topheight)
continue; continue;
@ -2516,8 +2505,8 @@ boolean P_InQuicksand(mobj_t *mo) // Returns true if you are in quicksand
if (!(rover->flags & FF_QUICKSAND)) if (!(rover->flags & FF_QUICKSAND))
continue; continue;
topheight = *rover->t_slope ? P_GetZAt(*rover->t_slope, mo->x, mo->y) : *rover->topheight; topheight = P_GetFFloorTopZAt (rover, mo->x, mo->y);
bottomheight = *rover->b_slope ? P_GetZAt(*rover->b_slope, mo->x, mo->y) : *rover->bottomheight; bottomheight = P_GetFFloorBottomZAt(rover, mo->x, mo->y);
if (mo->z + flipoffset > topheight) if (mo->z + flipoffset > topheight)
continue; continue;
@ -2843,8 +2832,8 @@ static void P_CheckQuicksand(player_t *player)
if (!(rover->flags & FF_QUICKSAND)) if (!(rover->flags & FF_QUICKSAND))
continue; continue;
topheight = *rover->t_slope ? P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y) : *rover->topheight; topheight = P_GetFFloorTopZAt (rover, player->mo->x, player->mo->y);
bottomheight = *rover->b_slope ? P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y) : *rover->bottomheight; bottomheight = P_GetFFloorBottomZAt(rover, player->mo->x, player->mo->y);
if (topheight >= player->mo->z && bottomheight < player->mo->z + player->mo->height) if (topheight >= player->mo->z && bottomheight < player->mo->z + player->mo->height)
{ {
@ -2997,7 +2986,7 @@ static void P_CheckInvincibilityTimer(player_t *player)
return; return;
if (mariomode && !player->powers[pw_super]) if (mariomode && !player->powers[pw_super])
player->mo->color = (UINT8)(SKINCOLOR_RUBY + (leveltime % (MAXSKINCOLORS - SKINCOLOR_RUBY))); // Passes through all saturated colours player->mo->color = (UINT16)(SKINCOLOR_RUBY + (leveltime % (numskincolors - SKINCOLOR_RUBY))); // Passes through all saturated colours
else if (leveltime % (TICRATE/7) == 0) else if (leveltime % (TICRATE/7) == 0)
{ {
mobj_t *sparkle = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_IVSP); mobj_t *sparkle = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_IVSP);
@ -3184,10 +3173,8 @@ static void P_DoClimbing(player_t *player)
floorclimb = true; floorclimb = true;
else else
{ {
floorheight = glidesector->sector->f_slope ? P_GetZAt(glidesector->sector->f_slope, player->mo->x, player->mo->y) floorheight = P_GetSectorFloorZAt (glidesector->sector, player->mo->x, player->mo->y);
: glidesector->sector->floorheight; ceilingheight = P_GetSectorCeilingZAt(glidesector->sector, player->mo->x, player->mo->y);
ceilingheight = glidesector->sector->c_slope ? P_GetZAt(glidesector->sector->c_slope, player->mo->x, player->mo->y)
: glidesector->sector->ceilingheight;
if (glidesector->sector->ffloors) if (glidesector->sector->ffloors)
{ {
@ -3201,8 +3188,8 @@ static void P_DoClimbing(player_t *player)
floorclimb = true; floorclimb = true;
topheight = *rover->t_slope ? P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y) : *rover->topheight; topheight = P_GetFFloorTopZAt (rover, player->mo->x, player->mo->y);
bottomheight = *rover->b_slope ? P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y) : *rover->bottomheight; bottomheight = P_GetFFloorBottomZAt(rover, player->mo->x, player->mo->y);
// Only supports rovers that are moving like an 'elevator', not just the top or bottom. // Only supports rovers that are moving like an 'elevator', not just the top or bottom.
if (rover->master->frontsector->floorspeed && rover->master->frontsector->ceilspeed == 42) if (rover->master->frontsector->floorspeed && rover->master->frontsector->ceilspeed == 42)
@ -3243,8 +3230,7 @@ static void P_DoClimbing(player_t *player)
if (roverbelow == rover) if (roverbelow == rover)
continue; continue;
bottomheight2 = *roverbelow->b_slope ? P_GetZAt(*roverbelow->b_slope, player->mo->x, player->mo->y) : *roverbelow->bottomheight; bottomheight2 = P_GetFFloorBottomZAt(roverbelow, player->mo->x, player->mo->y);
if (bottomheight2 < topheight + FixedMul(16*FRACUNIT, player->mo->scale)) if (bottomheight2 < topheight + FixedMul(16*FRACUNIT, player->mo->scale))
foundfof = true; foundfof = true;
} }
@ -3289,8 +3275,7 @@ static void P_DoClimbing(player_t *player)
if (roverbelow == rover) if (roverbelow == rover)
continue; continue;
topheight2 = *roverbelow->t_slope ? P_GetZAt(*roverbelow->t_slope, player->mo->x, player->mo->y) : *roverbelow->topheight; topheight2 = P_GetFFloorTopZAt(roverbelow, player->mo->x, player->mo->y);
if (topheight2 > bottomheight - FixedMul(16*FRACUNIT, player->mo->scale)) if (topheight2 > bottomheight - FixedMul(16*FRACUNIT, player->mo->scale))
foundfof = true; foundfof = true;
} }
@ -3344,8 +3329,7 @@ static void P_DoClimbing(player_t *player)
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP)) if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP))
continue; continue;
bottomheight = *rover->b_slope ? P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y) : *rover->bottomheight; bottomheight = P_GetFFloorBottomZAt(rover, player->mo->x, player->mo->y);
if (bottomheight < floorheight + FixedMul(16*FRACUNIT, player->mo->scale)) if (bottomheight < floorheight + FixedMul(16*FRACUNIT, player->mo->scale))
{ {
foundfof = true; foundfof = true;
@ -3385,8 +3369,7 @@ static void P_DoClimbing(player_t *player)
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP)) if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP))
continue; continue;
topheight = *rover->t_slope ? P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y) : *rover->topheight; topheight = P_GetFFloorTopZAt(rover, player->mo->x, player->mo->y);
if (topheight > ceilingheight - FixedMul(16*FRACUNIT, player->mo->scale)) if (topheight > ceilingheight - FixedMul(16*FRACUNIT, player->mo->scale))
{ {
foundfof = true; foundfof = true;
@ -3758,12 +3741,8 @@ static void P_DoTeeter(player_t *player)
sec = R_PointInSubsector(checkx, checky)->sector; sec = R_PointInSubsector(checkx, checky)->sector;
ceilingheight = sec->ceilingheight; ceilingheight = P_GetSectorCeilingZAt(sec, checkx, checky);
floorheight = sec->floorheight; floorheight = P_GetSectorFloorZAt (sec, checkx, checky);
if (sec->c_slope)
ceilingheight = P_GetZAt(sec->c_slope, checkx, checky);
if (sec->f_slope)
floorheight = P_GetZAt(sec->f_slope, checkx, checky);
highestceilingheight = (ceilingheight > highestceilingheight) ? ceilingheight : highestceilingheight; highestceilingheight = (ceilingheight > highestceilingheight) ? ceilingheight : highestceilingheight;
lowestfloorheight = (floorheight < lowestfloorheight) ? floorheight : lowestfloorheight; lowestfloorheight = (floorheight < lowestfloorheight) ? floorheight : lowestfloorheight;
@ -3774,8 +3753,8 @@ static void P_DoTeeter(player_t *player)
{ {
if (!(rover->flags & FF_EXISTS)) continue; if (!(rover->flags & FF_EXISTS)) continue;
topheight = *rover->t_slope ? P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y) : *rover->topheight; topheight = P_GetFFloorTopZAt (rover, player->mo->x, player->mo->y);
bottomheight = *rover->b_slope ? P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y) : *rover->bottomheight; bottomheight = P_GetFFloorBottomZAt(rover, player->mo->x, player->mo->y);
if (P_CheckSolidLava(rover)) if (P_CheckSolidLava(rover))
; ;
@ -3847,7 +3826,6 @@ static void P_DoTeeter(player_t *player)
BMBOUNDFIX(xl, xh, yl, yh); BMBOUNDFIX(xl, xh, yl, yh);
// Polyobjects // Polyobjects
#ifdef POLYOBJECTS
validcount++; validcount++;
for (by = yl; by <= yh; by++) for (by = yl; by <= yh; by++)
@ -3941,7 +3919,6 @@ static void P_DoTeeter(player_t *player)
plink = (polymaplink_t *)(plink->link.next); plink = (polymaplink_t *)(plink->link.next);
} }
} }
#endif
if (teeter) // only bother with objects as a last resort if you were already teetering if (teeter) // only bother with objects as a last resort if you were already teetering
{ {
mobj_t *oldtmthing = tmthing; mobj_t *oldtmthing = tmthing;
@ -4442,13 +4419,16 @@ void P_DoJump(player_t *player, boolean soundandstate)
else if (player->powers[pw_carry] == CR_ROLLOUT) else if (player->powers[pw_carry] == CR_ROLLOUT)
{ {
player->mo->momz = 9*FRACUNIT; player->mo->momz = 9*FRACUNIT;
if (P_MobjFlip(player->mo->tracer)*player->mo->tracer->momz > 0) if (player->mo->tracer)
player->mo->momz += player->mo->tracer->momz; {
if (!P_IsObjectOnGround(player->mo->tracer)) if (P_MobjFlip(player->mo->tracer)*player->mo->tracer->momz > 0)
P_SetObjectMomZ(player->mo->tracer, -9*FRACUNIT, true); player->mo->momz += player->mo->tracer->momz;
if (!P_IsObjectOnGround(player->mo->tracer))
P_SetObjectMomZ(player->mo->tracer, -9*FRACUNIT, true);
player->mo->tracer->flags |= MF_PUSHABLE;
P_SetTarget(&player->mo->tracer->tracer, NULL);
}
player->powers[pw_carry] = CR_NONE; player->powers[pw_carry] = CR_NONE;
player->mo->tracer->flags |= MF_PUSHABLE;
P_SetTarget(&player->mo->tracer->tracer, NULL);
P_SetTarget(&player->mo->tracer, NULL); P_SetTarget(&player->mo->tracer, NULL);
} }
else if (player->mo->eflags & MFE_GOOWATER) else if (player->mo->eflags & MFE_GOOWATER)
@ -5006,6 +4986,15 @@ void P_Telekinesis(player_t *player, fixed_t thrust, fixed_t range)
player->pflags |= PF_THOKKED; player->pflags |= PF_THOKKED;
} }
static void P_DoTwinSpin(player_t *player)
{
player->pflags &= ~PF_NOJUMPDAMAGE;
player->pflags |= P_GetJumpFlags(player) | PF_THOKKED;
S_StartSound(player->mo, sfx_s3k42);
player->mo->frame = 0;
P_SetPlayerMobjState(player->mo, S_PLAY_TWINSPIN);
}
// //
// P_DoJumpStuff // P_DoJumpStuff
// //
@ -5176,12 +5165,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd)
break; break;
case CA_TWINSPIN: case CA_TWINSPIN:
if ((player->charability2 == CA2_MELEE) && (!(player->pflags & (PF_THOKKED|PF_USEDOWN)) || player->charflags & SF_MULTIABILITY)) if ((player->charability2 == CA2_MELEE) && (!(player->pflags & (PF_THOKKED|PF_USEDOWN)) || player->charflags & SF_MULTIABILITY))
{ P_DoTwinSpin(player);
player->pflags |= PF_THOKKED;
S_StartSound(player->mo, sfx_s3k42);
player->mo->frame = 0;
P_SetPlayerMobjState(player->mo, S_PLAY_TWINSPIN);
}
break; break;
default: default:
break; break;
@ -5438,12 +5422,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd)
break; break;
case CA_TWINSPIN: case CA_TWINSPIN:
if (!(player->pflags & PF_THOKKED) || player->charflags & SF_MULTIABILITY) if (!(player->pflags & PF_THOKKED) || player->charflags & SF_MULTIABILITY)
{ P_DoTwinSpin(player);
player->pflags |= PF_THOKKED;
S_StartSound(player->mo, sfx_s3k42);
player->mo->frame = 0;
P_SetPlayerMobjState(player->mo, S_PLAY_TWINSPIN);
}
break; break;
default: default:
break; break;
@ -5702,11 +5681,7 @@ static void P_2dMovement(player_t *player)
} }
else if (player->onconveyor == 4 && !P_IsObjectOnGround(player->mo)) // Actual conveyor belt else if (player->onconveyor == 4 && !P_IsObjectOnGround(player->mo)) // Actual conveyor belt
player->cmomx = player->cmomy = 0; player->cmomx = player->cmomy = 0;
else if (player->onconveyor != 2 && player->onconveyor != 4 else if (player->onconveyor != 2 && player->onconveyor != 4 && player->onconveyor != 1)
#ifdef POLYOBJECTS
&& player->onconveyor != 1
#endif
)
player->cmomx = player->cmomy = 0; player->cmomx = player->cmomy = 0;
player->rmomx = player->mo->momx - player->cmomx; player->rmomx = player->mo->momx - player->cmomx;
@ -5901,11 +5876,7 @@ static void P_3dMovement(player_t *player)
} }
else if (player->onconveyor == 4 && !P_IsObjectOnGround(player->mo)) // Actual conveyor belt else if (player->onconveyor == 4 && !P_IsObjectOnGround(player->mo)) // Actual conveyor belt
player->cmomx = player->cmomy = 0; player->cmomx = player->cmomy = 0;
else if (player->onconveyor != 2 && player->onconveyor != 4 else if (player->onconveyor != 2 && player->onconveyor != 4 && player->onconveyor != 1)
#ifdef POLYOBJECTS
&& player->onconveyor != 1
#endif
)
player->cmomx = player->cmomy = 0; player->cmomx = player->cmomy = 0;
player->rmomx = player->mo->momx - player->cmomx; player->rmomx = player->mo->momx - player->cmomx;
@ -7762,7 +7733,7 @@ void P_ElementalFire(player_t *player, boolean cropcircle)
if (player->mo->standingslope) if (player->mo->standingslope)
{ {
ground = P_GetZAt(player->mo->standingslope, newx, newy); ground = P_GetSlopeZAt(player->mo->standingslope, newx, newy);
if (player->mo->eflags & MFE_VERTICALFLIP) if (player->mo->eflags & MFE_VERTICALFLIP)
ground -= FixedMul(mobjinfo[MT_SPINFIRE].height, player->mo->scale); ground -= FixedMul(mobjinfo[MT_SPINFIRE].height, player->mo->scale);
} }
@ -8738,10 +8709,7 @@ static void P_MovePlayer(player_t *player)
static void P_DoZoomTube(player_t *player) static void P_DoZoomTube(player_t *player)
{ {
INT32 sequence;
fixed_t speed; fixed_t speed;
thinker_t *th;
mobj_t *mo2;
mobj_t *waypoint = NULL; mobj_t *waypoint = NULL;
fixed_t dist; fixed_t dist;
boolean reverse; boolean reverse;
@ -8757,8 +8725,6 @@ static void P_DoZoomTube(player_t *player)
speed = abs(player->speed); speed = abs(player->speed);
sequence = player->mo->tracer->threshold;
// change slope // change slope
dist = P_AproxDistance(P_AproxDistance(player->mo->tracer->x - player->mo->x, player->mo->tracer->y - player->mo->y), player->mo->tracer->z - player->mo->z); dist = P_AproxDistance(P_AproxDistance(player->mo->tracer->x - player->mo->x, player->mo->tracer->y - player->mo->y), player->mo->tracer->z - player->mo->z);
@ -8790,28 +8756,7 @@ static void P_DoZoomTube(player_t *player)
CONS_Debug(DBG_GAMELOGIC, "Looking for next waypoint...\n"); CONS_Debug(DBG_GAMELOGIC, "Looking for next waypoint...\n");
// Find next waypoint // Find next waypoint
for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) waypoint = reverse ? P_GetPreviousWaypoint(player->mo->tracer, false) : P_GetNextWaypoint(player->mo->tracer, false);
{
if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed)
continue;
mo2 = (mobj_t *)th;
if (mo2->type != MT_TUBEWAYPOINT)
continue;
if (mo2->threshold != sequence)
continue;
if (reverse && mo2->health != player->mo->tracer->health - 1)
continue;
if (!reverse && mo2->health != player->mo->tracer->health + 1)
continue;
waypoint = mo2;
break;
}
if (waypoint) if (waypoint)
{ {
@ -8862,8 +8807,6 @@ static void P_DoRopeHang(player_t *player)
{ {
INT32 sequence; INT32 sequence;
fixed_t speed; fixed_t speed;
thinker_t *th;
mobj_t *mo2;
mobj_t *waypoint = NULL; mobj_t *waypoint = NULL;
fixed_t dist; fixed_t dist;
fixed_t playerz; fixed_t playerz;
@ -8926,50 +8869,14 @@ static void P_DoRopeHang(player_t *player)
CONS_Debug(DBG_GAMELOGIC, "Looking for next waypoint...\n"); CONS_Debug(DBG_GAMELOGIC, "Looking for next waypoint...\n");
// Find next waypoint // Find next waypoint
for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) waypoint = P_GetNextWaypoint(player->mo->tracer, false);
{
if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed)
continue;
mo2 = (mobj_t *)th;
if (mo2->type != MT_TUBEWAYPOINT)
continue;
if (mo2->threshold != sequence)
continue;
if (mo2->health != player->mo->tracer->health + 1)
continue;
waypoint = mo2;
break;
}
if (!(player->mo->tracer->flags & MF_SLIDEME) && !waypoint) if (!(player->mo->tracer->flags & MF_SLIDEME) && !waypoint)
{ {
CONS_Debug(DBG_GAMELOGIC, "Next waypoint not found, wrapping to start...\n"); CONS_Debug(DBG_GAMELOGIC, "Next waypoint not found, wrapping to start...\n");
// Wrap around back to first waypoint // Wrap around back to first waypoint
for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) waypoint = P_GetFirstWaypoint(sequence);
{
if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed)
continue;
mo2 = (mobj_t *)th;
if (mo2->type != MT_TUBEWAYPOINT)
continue;
if (mo2->threshold != sequence)
continue;
if (mo2->health != 0)
continue;
waypoint = mo2;
break;
}
} }
if (waypoint) if (waypoint)
@ -10235,7 +10142,6 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
} }
} }
#ifdef POLYOBJECTS
// Check polyobjects and see if floorz/ceilingz need to be altered // Check polyobjects and see if floorz/ceilingz need to be altered
{ {
INT32 xl, xh, yl, yh, bx, by; INT32 xl, xh, yl, yh, bx, by;
@ -10314,7 +10220,6 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
} }
} }
} }
#endif
// crushed camera // crushed camera
if (myceilingz <= myfloorz + thiscam->height && !resetcalled && !cameranoclip) if (myceilingz <= myfloorz + thiscam->height && !resetcalled && !cameranoclip)
@ -10667,8 +10572,8 @@ static void P_CalcPostImg(player_t *player)
if (!(rover->flags & FF_EXISTS)) if (!(rover->flags & FF_EXISTS))
continue; continue;
topheight = *rover->t_slope ? P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y) : *rover->topheight; topheight = P_GetFFloorTopZAt (rover, player->mo->x, player->mo->y);
bottomheight = *rover->b_slope ? P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y) : *rover->bottomheight; bottomheight = P_GetFFloorBottomZAt(rover, player->mo->x, player->mo->y);
if (pviewheight >= topheight || pviewheight <= bottomheight) if (pviewheight >= topheight || pviewheight <= bottomheight)
continue; continue;
@ -10690,8 +10595,8 @@ static void P_CalcPostImg(player_t *player)
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_SWIMMABLE) || rover->flags & FF_BLOCKPLAYER) if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_SWIMMABLE) || rover->flags & FF_BLOCKPLAYER)
continue; continue;
topheight = *rover->t_slope ? P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y) : *rover->topheight; topheight = P_GetFFloorTopZAt (rover, player->mo->x, player->mo->y);
bottomheight = *rover->b_slope ? P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y) : *rover->bottomheight; bottomheight = P_GetFFloorBottomZAt(rover, player->mo->x, player->mo->y);
if (pviewheight >= topheight || pviewheight <= bottomheight) if (pviewheight >= topheight || pviewheight <= bottomheight)
continue; continue;
@ -10753,7 +10658,7 @@ static sector_t *P_GetMinecartSector(fixed_t x, fixed_t y, fixed_t z, fixed_t *n
if (!(rover->flags & (FF_EXISTS|FF_BLOCKOTHERS))) if (!(rover->flags & (FF_EXISTS|FF_BLOCKOTHERS)))
continue; continue;
*nz = *rover->t_slope ? P_GetZAt(*rover->t_slope, x, y) : *rover->topheight; *nz = P_GetFFloorTopZAt(rover, x, y);
if (abs(z - *nz) <= 56*FRACUNIT) if (abs(z - *nz) <= 56*FRACUNIT)
{ {
sec = &sectors[rover->secnum]; sec = &sectors[rover->secnum];
@ -10763,7 +10668,7 @@ static sector_t *P_GetMinecartSector(fixed_t x, fixed_t y, fixed_t z, fixed_t *n
} }
*nz = sec->f_slope ? P_GetZAt(sec->f_slope, x, y) : sec->floorheight; *nz = P_GetSectorFloorZAt(sec, x, y);
if (abs(z - *nz) > 56*FRACUNIT) if (abs(z - *nz) > 56*FRACUNIT)
return NULL; return NULL;
@ -11117,8 +11022,8 @@ static void P_MinecartThink(player_t *player)
if (minecart->standingslope) if (minecart->standingslope)
{ {
fixed_t fa2 = (minecart->angle >> ANGLETOFINESHIFT) & FINEMASK; fixed_t fa2 = (minecart->angle >> ANGLETOFINESHIFT) & FINEMASK;
fixed_t front = P_GetZAt(minecart->standingslope, minecart->x, minecart->y); fixed_t front = P_GetSlopeZAt(minecart->standingslope, minecart->x, minecart->y);
fixed_t back = P_GetZAt(minecart->standingslope, minecart->x - FINECOSINE(fa2), minecart->y - FINESINE(fa2)); fixed_t back = P_GetSlopeZAt(minecart->standingslope, minecart->x - FINECOSINE(fa2), minecart->y - FINESINE(fa2));
if (abs(front - back) < 3*FRACUNIT) if (abs(front - back) < 3*FRACUNIT)
currentSpeed += (back - front)/3; currentSpeed += (back - front)/3;
@ -11732,10 +11637,8 @@ void P_PlayerThink(player_t *player)
P_MobjCheckWater(player->mo); P_MobjCheckWater(player->mo);
#ifndef SECTORSPECIALSAFTERTHINK #ifndef SECTORSPECIALSAFTERTHINK
#ifdef POLYOBJECTS
if (player->onconveyor != 1 || !P_IsObjectOnGround(player->mo)) if (player->onconveyor != 1 || !P_IsObjectOnGround(player->mo))
#endif player->onconveyor = 0;
player->onconveyor = 0;
// check special sectors : damage & secrets // check special sectors : damage & secrets
if (!player->spectator) if (!player->spectator)
@ -11948,6 +11851,9 @@ void P_PlayerThink(player_t *player)
factor = 4; factor = 4;
} }
break; break;
case CR_DUSTDEVIL:
player->drawangle += ANG20;
break;
/* -- in case we wanted to have the camera freely movable during zoom tubes /* -- in case we wanted to have the camera freely movable during zoom tubes
case CR_ZOOMTUBE:*/ case CR_ZOOMTUBE:*/
case CR_ROPEHANG: case CR_ROPEHANG:
@ -12093,12 +11999,10 @@ void P_PlayerThink(player_t *player)
// it lasts for one tic. // it lasts for one tic.
player->pflags &= ~PF_FULLSTASIS; player->pflags &= ~PF_FULLSTASIS;
#ifdef POLYOBJECTS
if (player->onconveyor == 1) if (player->onconveyor == 1)
player->onconveyor = 3; player->onconveyor = 3;
else if (player->onconveyor == 3) else if (player->onconveyor == 3)
player->cmomy = player->cmomx = 0; player->cmomy = player->cmomx = 0;
#endif
P_DoSuperStuff(player); P_DoSuperStuff(player);
P_CheckSneakerAndLivesTimer(player); P_CheckSneakerAndLivesTimer(player);
@ -12439,10 +12343,8 @@ void P_PlayerAfterThink(player_t *player)
cmd = &player->cmd; cmd = &player->cmd;
#ifdef SECTORSPECIALSAFTERTHINK #ifdef SECTORSPECIALSAFTERTHINK
#ifdef POLYOBJECTS
if (player->onconveyor != 1 || !P_IsObjectOnGround(player->mo)) if (player->onconveyor != 1 || !P_IsObjectOnGround(player->mo))
#endif player->onconveyor = 0;
player->onconveyor = 0;
// check special sectors : damage & secrets // check special sectors : damage & secrets
if (!player->spectator) if (!player->spectator)
@ -12732,6 +12634,19 @@ void P_PlayerAfterThink(player_t *player)
} }
break; break;
} }
case CR_DUSTDEVIL:
{
mobj_t *mo = player->mo, *dustdevil = player->mo->tracer;
if (abs(mo->x - dustdevil->x) > dustdevil->radius || abs(mo->y - dustdevil->y) > dustdevil->radius)
{
P_SetTarget(&player->mo->tracer, NULL);
player->powers[pw_carry] = CR_NONE;
break;
}
break;
}
case CR_ROLLOUT: case CR_ROLLOUT:
{ {
mobj_t *mo = player->mo, *rock = player->mo->tracer; mobj_t *mo = player->mo, *rock = player->mo->tracer;

View File

@ -354,9 +354,7 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel,
boolean R_IsEmptyLine(seg_t *line, sector_t *front, sector_t *back) boolean R_IsEmptyLine(seg_t *line, sector_t *front, sector_t *back)
{ {
return ( return (
#ifdef POLYOBJECTS
!line->polyseg && !line->polyseg &&
#endif
back->ceilingpic == front->ceilingpic back->ceilingpic == front->ceilingpic
&& back->floorpic == front->floorpic && back->floorpic == front->floorpic
&& back->f_slope == front->f_slope && back->f_slope == front->f_slope
@ -482,13 +480,10 @@ static void R_AddLine(seg_t *line)
if (bothceilingssky && bothfloorssky) // everything's sky? let's save us a bit of time then if (bothceilingssky && bothfloorssky) // everything's sky? let's save us a bit of time then
{ {
if ( if (!line->polyseg &&
#ifdef POLYOBJECTS !line->sidedef->midtexture
!line->polyseg && && ((!frontsector->ffloors && !backsector->ffloors)
#endif || (frontsector->tag == backsector->tag)))
!line->sidedef->midtexture
&& ((!frontsector->ffloors && !backsector->ffloors)
|| (frontsector->tag == backsector->tag)))
return; // line is empty, don't even bother return; // line is empty, don't even bother
goto clippass; // treat like wide open window instead goto clippass; // treat like wide open window instead
@ -500,16 +495,13 @@ static void R_AddLine(seg_t *line)
fixed_t frontf1,frontf2, frontc1, frontc2; // front floor/ceiling ends fixed_t frontf1,frontf2, frontc1, frontc2; // front floor/ceiling ends
fixed_t backf1, backf2, backc1, backc2; // back floor ceiling ends fixed_t backf1, backf2, backc1, backc2; // back floor ceiling ends
#define SLOPEPARAMS(slope, end1, end2, normalheight) \ #define SLOPEPARAMS(slope, end1, end2, normalheight) \
if (slope) { \ end1 = P_GetZAt(slope, line->v1->x, line->v1->y, normalheight); \
end1 = P_GetZAt(slope, line->v1->x, line->v1->y); \ end2 = P_GetZAt(slope, line->v2->x, line->v2->y, normalheight);
end2 = P_GetZAt(slope, line->v2->x, line->v2->y); \
} else \
end1 = end2 = normalheight;
SLOPEPARAMS(frontsector->f_slope, frontf1, frontf2, frontsector->floorheight) SLOPEPARAMS(frontsector->f_slope, frontf1, frontf2, frontsector-> floorheight)
SLOPEPARAMS(frontsector->c_slope, frontc1, frontc2, frontsector->ceilingheight) SLOPEPARAMS(frontsector->c_slope, frontc1, frontc2, frontsector->ceilingheight)
SLOPEPARAMS( backsector->f_slope, backf1, backf2, backsector->floorheight) SLOPEPARAMS( backsector->f_slope, backf1, backf2, backsector-> floorheight)
SLOPEPARAMS( backsector->c_slope, backc1, backc2, backsector->ceilingheight) SLOPEPARAMS( backsector->c_slope, backc1, backc2, backsector->ceilingheight)
#undef SLOPEPARAMS #undef SLOPEPARAMS
// if both ceilings are skies, consider it always "open" // if both ceilings are skies, consider it always "open"
// same for floors // same for floors
@ -654,8 +646,6 @@ static boolean R_CheckBBox(const fixed_t *bspcoord)
return true; return true;
} }
#ifdef POLYOBJECTS
size_t numpolys; // number of polyobjects in current subsector size_t numpolys; // number of polyobjects in current subsector
size_t num_po_ptrs; // number of polyobject pointers allocated size_t num_po_ptrs; // number of polyobject pointers allocated
polyobj_t **po_ptrs; // temp ptr array to sort polyobject pointers polyobj_t **po_ptrs; // temp ptr array to sort polyobject pointers
@ -819,7 +809,6 @@ static void R_AddPolyObjects(subsector_t *sub)
R_AddLine(po_ptrs[i]->segs[j]); R_AddLine(po_ptrs[i]->segs[j]);
} }
} }
#endif
// //
// R_Subsector // R_Subsector
@ -859,13 +848,8 @@ static void R_Subsector(size_t num)
floorcolormap = ceilingcolormap = frontsector->extra_colormap; floorcolormap = ceilingcolormap = frontsector->extra_colormap;
floorcenterz = frontsector->f_slope ? floorcenterz = P_GetSectorFloorZAt (frontsector, frontsector->soundorg.x, frontsector->soundorg.y);
P_GetZAt(frontsector->f_slope, frontsector->soundorg.x, frontsector->soundorg.y) : ceilingcenterz = P_GetSectorCeilingZAt(frontsector, frontsector->soundorg.x, frontsector->soundorg.y);
frontsector->floorheight;
ceilingcenterz = frontsector->c_slope ?
P_GetZAt(frontsector->c_slope, frontsector->soundorg.x, frontsector->soundorg.y) :
frontsector->ceilingheight;
// Check and prep all 3D floors. Set the sector floor/ceiling light levels and colormaps. // Check and prep all 3D floors. Set the sector floor/ceiling light levels and colormaps.
if (frontsector->ffloors) if (frontsector->ffloors)
@ -891,31 +875,23 @@ static void R_Subsector(size_t num)
sub->sector->extra_colormap = frontsector->extra_colormap; sub->sector->extra_colormap = frontsector->extra_colormap;
if ((frontsector->f_slope ? P_GetZAt(frontsector->f_slope, viewx, viewy) : frontsector->floorheight) < viewz if (P_GetSectorFloorZAt(frontsector, viewx, viewy) < viewz
|| frontsector->floorpic == skyflatnum || frontsector->floorpic == skyflatnum
|| (frontsector->heightsec != -1 && sectors[frontsector->heightsec].ceilingpic == skyflatnum)) || (frontsector->heightsec != -1 && sectors[frontsector->heightsec].ceilingpic == skyflatnum))
{ {
floorplane = R_FindPlane(frontsector->floorheight, frontsector->floorpic, floorlightlevel, floorplane = R_FindPlane(frontsector->floorheight, frontsector->floorpic, floorlightlevel,
frontsector->floor_xoffs, frontsector->floor_yoffs, frontsector->floorpic_angle, floorcolormap, NULL frontsector->floor_xoffs, frontsector->floor_yoffs, frontsector->floorpic_angle, floorcolormap, NULL, NULL, frontsector->f_slope);
#ifdef POLYOBJECTS_PLANES
, NULL
#endif
, frontsector->f_slope);
} }
else else
floorplane = NULL; floorplane = NULL;
if ((frontsector->c_slope ? P_GetZAt(frontsector->c_slope, viewx, viewy) : frontsector->ceilingheight) > viewz if (P_GetSectorCeilingZAt(frontsector, viewx, viewy) > viewz
|| frontsector->ceilingpic == skyflatnum || frontsector->ceilingpic == skyflatnum
|| (frontsector->heightsec != -1 && sectors[frontsector->heightsec].floorpic == skyflatnum)) || (frontsector->heightsec != -1 && sectors[frontsector->heightsec].floorpic == skyflatnum))
{ {
ceilingplane = R_FindPlane(frontsector->ceilingheight, frontsector->ceilingpic, ceilingplane = R_FindPlane(frontsector->ceilingheight, frontsector->ceilingpic,
ceilinglightlevel, frontsector->ceiling_xoffs, frontsector->ceiling_yoffs, frontsector->ceilingpic_angle, ceilinglightlevel, frontsector->ceiling_xoffs, frontsector->ceiling_yoffs, frontsector->ceilingpic_angle,
ceilingcolormap, NULL ceilingcolormap, NULL, NULL, frontsector->c_slope);
#ifdef POLYOBJECTS_PLANES
, NULL
#endif
, frontsector->c_slope);
} }
else else
ceilingplane = NULL; ceilingplane = NULL;
@ -946,13 +922,9 @@ static void R_Subsector(size_t num)
ffloor[numffloors].plane = NULL; ffloor[numffloors].plane = NULL;
ffloor[numffloors].polyobj = NULL; ffloor[numffloors].polyobj = NULL;
heightcheck = *rover->b_slope ? heightcheck = P_GetFFloorBottomZAt(rover, viewx, viewy);
P_GetZAt(*rover->b_slope, viewx, viewy) :
*rover->bottomheight;
planecenterz = *rover->b_slope ? planecenterz = P_GetFFloorBottomZAt(rover, frontsector->soundorg.x, frontsector->soundorg.y);
P_GetZAt(*rover->b_slope, frontsector->soundorg.x, frontsector->soundorg.y) :
*rover->bottomheight;
if (planecenterz <= ceilingcenterz if (planecenterz <= ceilingcenterz
&& planecenterz >= floorcenterz && planecenterz >= floorcenterz
&& ((viewz < heightcheck && (rover->flags & FF_BOTHPLANES || !(rover->flags & FF_INVERTPLANES))) && ((viewz < heightcheck && (rover->flags & FF_BOTHPLANES || !(rover->flags & FF_INVERTPLANES)))
@ -963,11 +935,7 @@ static void R_Subsector(size_t num)
ffloor[numffloors].plane = R_FindPlane(*rover->bottomheight, *rover->bottompic, ffloor[numffloors].plane = R_FindPlane(*rover->bottomheight, *rover->bottompic,
*frontsector->lightlist[light].lightlevel, *rover->bottomxoffs, *frontsector->lightlist[light].lightlevel, *rover->bottomxoffs,
*rover->bottomyoffs, *rover->bottomangle, *frontsector->lightlist[light].extra_colormap, rover *rover->bottomyoffs, *rover->bottomangle, *frontsector->lightlist[light].extra_colormap, rover, NULL, *rover->b_slope);
#ifdef POLYOBJECTS_PLANES
, NULL
#endif
, *rover->b_slope);
ffloor[numffloors].slope = *rover->b_slope; ffloor[numffloors].slope = *rover->b_slope;
@ -984,13 +952,9 @@ static void R_Subsector(size_t num)
ffloor[numffloors].plane = NULL; ffloor[numffloors].plane = NULL;
ffloor[numffloors].polyobj = NULL; ffloor[numffloors].polyobj = NULL;
heightcheck = *rover->t_slope ? heightcheck = P_GetFFloorTopZAt(rover, viewx, viewy);
P_GetZAt(*rover->t_slope, viewx, viewy) :
*rover->topheight;
planecenterz = *rover->t_slope ? planecenterz = P_GetFFloorTopZAt(rover, frontsector->soundorg.x, frontsector->soundorg.y);
P_GetZAt(*rover->t_slope, frontsector->soundorg.x, frontsector->soundorg.y) :
*rover->topheight;
if (planecenterz >= floorcenterz if (planecenterz >= floorcenterz
&& planecenterz <= ceilingcenterz && planecenterz <= ceilingcenterz
&& ((viewz > heightcheck && (rover->flags & FF_BOTHPLANES || !(rover->flags & FF_INVERTPLANES))) && ((viewz > heightcheck && (rover->flags & FF_BOTHPLANES || !(rover->flags & FF_INVERTPLANES)))
@ -1000,11 +964,7 @@ static void R_Subsector(size_t num)
ffloor[numffloors].plane = R_FindPlane(*rover->topheight, *rover->toppic, ffloor[numffloors].plane = R_FindPlane(*rover->topheight, *rover->toppic,
*frontsector->lightlist[light].lightlevel, *rover->topxoffs, *rover->topyoffs, *rover->topangle, *frontsector->lightlist[light].lightlevel, *rover->topxoffs, *rover->topyoffs, *rover->topangle,
*frontsector->lightlist[light].extra_colormap, rover *frontsector->lightlist[light].extra_colormap, rover, NULL, *rover->t_slope);
#ifdef POLYOBJECTS_PLANES
, NULL
#endif
, *rover->t_slope);
ffloor[numffloors].slope = *rover->t_slope; ffloor[numffloors].slope = *rover->t_slope;
@ -1019,7 +979,6 @@ static void R_Subsector(size_t num)
} }
} }
#ifdef POLYOBJECTS_PLANES
// Polyobjects have planes, too! // Polyobjects have planes, too!
if (sub->polyList) if (sub->polyList)
{ {
@ -1085,7 +1044,6 @@ static void R_Subsector(size_t num)
po = (polyobj_t *)(po->link.next); po = (polyobj_t *)(po->link.next);
} }
} }
#endif
#ifdef FLOORSPLATS #ifdef FLOORSPLATS
if (sub->splats) if (sub->splats)
@ -1108,21 +1066,15 @@ static void R_Subsector(size_t num)
firstseg = NULL; firstseg = NULL;
#ifdef POLYOBJECTS
// haleyjd 02/19/06: draw polyobjects before static lines // haleyjd 02/19/06: draw polyobjects before static lines
if (sub->polyList) if (sub->polyList)
R_AddPolyObjects(sub); R_AddPolyObjects(sub);
#endif
while (count--) while (count--)
{ {
// CONS_Debug(DBG_GAMELOGIC, "Adding normal line %d...(%d)\n", line->linedef-lines, leveltime); // CONS_Debug(DBG_GAMELOGIC, "Adding normal line %d...(%d)\n", line->linedef-lines, leveltime);
if (!line->glseg if (!line->glseg && !line->polyseg) // ignore segs that belong to polyobjects
#ifdef POLYOBJECTS R_AddLine(line);
&& !line->polyseg // ignore segs that belong to polyobjects
#endif
)
R_AddLine(line);
line++; line++;
curline = NULL; /* cph 2001/11/18 - must clear curline now we're done with it, so stuff doesn't try using it for other things */ curline = NULL; /* cph 2001/11/18 - must clear curline now we're done with it, so stuff doesn't try using it for other things */
} }
@ -1165,7 +1117,7 @@ void R_Prep3DFloors(sector_t *sector)
else else
memset(sector->lightlist, 0, sizeof (lightlist_t) * count); memset(sector->lightlist, 0, sizeof (lightlist_t) * count);
heighttest = sector->c_slope ? P_GetZAt(sector->c_slope, sector->soundorg.x, sector->soundorg.y) : sector->ceilingheight; heighttest = P_GetSectorCeilingZAt(sector, sector->soundorg.x, sector->soundorg.y);
sector->lightlist[0].height = heighttest + 1; sector->lightlist[0].height = heighttest + 1;
sector->lightlist[0].slope = sector->c_slope; sector->lightlist[0].slope = sector->c_slope;
@ -1186,7 +1138,7 @@ void R_Prep3DFloors(sector_t *sector)
&& !(rover->flags & FF_CUTLEVEL) && !(rover->flags & FF_CUTSPRITES))) && !(rover->flags & FF_CUTLEVEL) && !(rover->flags & FF_CUTSPRITES)))
continue; continue;
heighttest = *rover->t_slope ? P_GetZAt(*rover->t_slope, sector->soundorg.x, sector->soundorg.y) : *rover->topheight; heighttest = P_GetFFloorTopZAt(rover, sector->soundorg.x, sector->soundorg.y);
if (heighttest > bestheight && heighttest < maxheight) if (heighttest > bestheight && heighttest < maxheight)
{ {
@ -1196,7 +1148,7 @@ void R_Prep3DFloors(sector_t *sector)
continue; continue;
} }
if (rover->flags & FF_DOUBLESHADOW) { if (rover->flags & FF_DOUBLESHADOW) {
heighttest = *rover->b_slope ? P_GetZAt(*rover->b_slope, sector->soundorg.x, sector->soundorg.y) : *rover->bottomheight; heighttest = P_GetFFloorBottomZAt(rover, sector->soundorg.x, sector->soundorg.y);
if (heighttest > bestheight if (heighttest > bestheight
&& heighttest < maxheight) && heighttest < maxheight)
@ -1238,7 +1190,7 @@ void R_Prep3DFloors(sector_t *sector)
if (best->flags & FF_DOUBLESHADOW) if (best->flags & FF_DOUBLESHADOW)
{ {
heighttest = *best->b_slope ? P_GetZAt(*best->b_slope, sector->soundorg.x, sector->soundorg.y) : *best->bottomheight; heighttest = P_GetFFloorBottomZAt(best, sector->soundorg.x, sector->soundorg.y);
if (bestheight == heighttest) ///TODO: do this in a more efficient way -Red if (bestheight == heighttest) ///TODO: do this in a more efficient way -Red
{ {
sector->lightlist[i].lightlevel = sector->lightlist[best->lastlight].lightlevel; sector->lightlist[i].lightlevel = sector->lightlist[best->lastlight].lightlevel;

View File

@ -40,13 +40,11 @@ void R_PortalClearClipSegs(INT32 start, INT32 end);
void R_ClearDrawSegs(void); void R_ClearDrawSegs(void);
void R_RenderBSPNode(INT32 bspnum); void R_RenderBSPNode(INT32 bspnum);
#ifdef POLYOBJECTS
void R_SortPolyObjects(subsector_t *sub); void R_SortPolyObjects(subsector_t *sub);
extern size_t numpolys; // number of polyobjects in current subsector extern size_t numpolys; // number of polyobjects in current subsector
extern size_t num_po_ptrs; // number of polyobject pointers allocated extern size_t num_po_ptrs; // number of polyobject pointers allocated
extern polyobj_t **po_ptrs; // temp ptr array to sort polyobject pointers extern polyobj_t **po_ptrs; // temp ptr array to sort polyobject pointers
#endif
sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel, sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel,
INT32 *ceilinglightlevel, boolean back); INT32 *ceilinglightlevel, boolean back);

View File

@ -28,8 +28,6 @@
#include "m_aatree.h" #include "m_aatree.h"
#endif #endif
#define POLYOBJECTS
// //
// ClipWallSegment // ClipWallSegment
// Clips the given range of columns // Clips the given range of columns
@ -107,9 +105,7 @@ typedef struct
fixed_t z; ///< Z coordinate. fixed_t z; ///< Z coordinate.
} degenmobj_t; } degenmobj_t;
#ifdef POLYOBJECTS
#include "p_polyobj.h" #include "p_polyobj.h"
#endif
// Store fake planes in a resizable array insted of just by // Store fake planes in a resizable array insted of just by
// heightsec. Allows for multiple fake planes. // heightsec. Allows for multiple fake planes.
@ -434,9 +430,7 @@ typedef struct line_s
void *splats; // wallsplat_t list void *splats; // wallsplat_t list
#endif #endif
INT32 firsttag, nexttag; // improves searches for tags. INT32 firsttag, nexttag; // improves searches for tags.
#ifdef POLYOBJECTS
polyobj_t *polyobj; // Belongs to a polyobject? polyobj_t *polyobj; // Belongs to a polyobject?
#endif
char *text; // a concatenation of all front and back texture names, for linedef specials that require a string. char *text; // a concatenation of all front and back texture names, for linedef specials that require a string.
INT16 callcount; // no. of calls left before triggering, for the "X calls" linedef specials, defaults to 0 INT16 callcount; // no. of calls left before triggering, for the "X calls" linedef specials, defaults to 0
@ -479,9 +473,7 @@ typedef struct subsector_s
sector_t *sector; sector_t *sector;
INT16 numlines; INT16 numlines;
UINT16 firstline; UINT16 firstline;
#ifdef POLYOBJECTS
struct polyobj_s *polyList; // haleyjd 02/19/06: list of polyobjects struct polyobj_s *polyList; // haleyjd 02/19/06: list of polyobjects
#endif
#if 1//#ifdef FLOORSPLATS #if 1//#ifdef FLOORSPLATS
void *splats; // floorsplat_t list void *splats; // floorsplat_t list
#endif #endif
@ -584,10 +576,8 @@ typedef struct seg_s
// Why slow things down by calculating lightlists for every thick side? // Why slow things down by calculating lightlists for every thick side?
size_t numlights; size_t numlights;
r_lightlist_t *rlights; r_lightlist_t *rlights;
#ifdef POLYOBJECTS
polyobj_t *polyseg; polyobj_t *polyseg;
boolean dontrenderme; boolean dontrenderme;
#endif
boolean glseg; boolean glseg;
} seg_t; } seg_t;

View File

@ -135,318 +135,6 @@ UINT32 nflatxshift, nflatyshift, nflatshiftup, nflatmask;
static UINT8** translationtablecache[MAXSKINS + 7] = {NULL}; static UINT8** translationtablecache[MAXSKINS + 7] = {NULL};
const UINT8 Color_Index[MAXTRANSLATIONS-1][16] = {
// {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, // SKINCOLOR_NONE
// Greyscale ranges
{0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x02, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x11}, // SKINCOLOR_WHITE
{0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x05, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x11, 0x12}, // SKINCOLOR_BONE
{0x02, 0x03, 0x04, 0x05, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14}, // SKINCOLOR_CLOUDY
{0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18}, // SKINCOLOR_GREY
{0x02, 0x03, 0x05, 0x07, 0x09, 0x0b, 0x0d, 0x0f, 0x11, 0x13, 0x15, 0x17, 0x19, 0x1b, 0x1d, 0x1f}, // SKINCOLOR_SILVER
{0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x16, 0x17, 0x17, 0x19, 0x19, 0x1a, 0x1a, 0x1b, 0x1c, 0x1d}, // SKINCOLOR_CARBON
{0x00, 0x05, 0x0a, 0x0f, 0x14, 0x19, 0x1a, 0x1b, 0x1c, 0x1e, 0x1e, 0x1e, 0x1f, 0x1f, 0x1f, 0x1f}, // SKINCOLOR_JET
{0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1b, 0x1b, 0x1c, 0x1d, 0x1d, 0x1e, 0x1e, 0x1f, 0x1f}, // SKINCOLOR_BLACK
// Desaturated
{0x00, 0x00, 0x01, 0x02, 0x02, 0x03, 0x91, 0x91, 0x91, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xaf}, // SKINCOLOR_AETHER
{0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0xaa, 0xaa, 0xaa, 0xab, 0xac, 0xac, 0xad, 0xad, 0xae, 0xaf}, // SKINCOLOR_SLATE
{0x90, 0x91, 0x92, 0x93, 0x94, 0x94, 0x95, 0xac, 0xac, 0xad, 0xad, 0xa8, 0xa8, 0xa9, 0xfd, 0xfe}, // SKINCOLOR_BLUEBELL
{0xd0, 0xd0, 0xd1, 0xd1, 0xd2, 0xd2, 0xd3, 0xd3, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0x2b, 0x2c, 0x2e}, // SKINCOLOR_PINK
{0xd0, 0x30, 0xd8, 0xd9, 0xda, 0xdb, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe3, 0xe6, 0xe8, 0xe9}, // SKINCOLOR_YOGURT
{0xdf, 0xe0, 0xe1, 0xe2, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef}, // SKINCOLOR_BROWN
{0xde, 0xe0, 0xe1, 0xe4, 0xe7, 0xe9, 0xeb, 0xec, 0xed, 0xed, 0xed, 0x19, 0x19, 0x1b, 0x1d, 0x1e}, // SKINCOLOR_BRONZE
{0x51, 0x51, 0x54, 0x54, 0x55, 0x55, 0x56, 0x56, 0x56, 0x57, 0xf5, 0xf5, 0xf9, 0xf9, 0xed, 0xed}, // SKINCOLOR_TAN
{0x54, 0x55, 0x56, 0x56, 0xf2, 0xf3, 0xf3, 0xf4, 0xf5, 0xf6, 0xf8, 0xf9, 0xfa, 0xfb, 0xed, 0xed}, // SKINCOLOR_BEIGE
{0x58, 0x58, 0x59, 0x59, 0x5a, 0x5a, 0x5b, 0x5b, 0x5b, 0x5c, 0x5d, 0x5d, 0x5e, 0x5e, 0x5f, 0x5f}, // SKINCOLOR_MOSS
{0x90, 0x90, 0x91, 0x91, 0xaa, 0xaa, 0xab, 0xab, 0xab, 0xac, 0xad, 0xad, 0xae, 0xae, 0xaf, 0xaf}, // SKINCOLOR_AZURE
{0xc0, 0xc0, 0xc1, 0xc1, 0xc2, 0xc2, 0xc3, 0xc3, 0xc3, 0xc4, 0xc5, 0xc5, 0xc6, 0xc6, 0xc7, 0xc7}, // SKINCOLOR_LAVENDER
// Viv's vivid colours (toast 21/07/17)
{0xb0, 0xb0, 0xc9, 0xca, 0xcc, 0x26, 0x27, 0x28, 0x29, 0x2a, 0xb9, 0xb9, 0xba, 0xba, 0xbb, 0xfd}, // SKINCOLOR_RUBY
{0xd0, 0xd0, 0xd1, 0xd2, 0x20, 0x21, 0x24, 0x25, 0x26, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e}, // SKINCOLOR_SALMON
{0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x47, 0x2e, 0x2f}, // SKINCOLOR_RED
{0x27, 0x27, 0x28, 0x28, 0x29, 0x2a, 0x2b, 0x2b, 0x2c, 0x2d, 0x2e, 0x2e, 0x2e, 0x2f, 0x2f, 0x1f}, // SKINCOLOR_CRIMSON
{0x31, 0x32, 0x33, 0x36, 0x22, 0x22, 0x25, 0x25, 0x25, 0xcd, 0xcf, 0xcf, 0xc5, 0xc5, 0xc7, 0xc7}, // SKINCOLOR_FLAME
{0x48, 0x49, 0x40, 0x33, 0x34, 0x36, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2b, 0x2c, 0x47, 0x2e, 0x2f}, // SKINCOLOR_KETCHUP
{0xd0, 0x30, 0x31, 0x31, 0x32, 0x32, 0xdc, 0xdc, 0xdc, 0xd3, 0xd4, 0xd4, 0xcc, 0xcd, 0xce, 0xcf}, // SKINCOLOR_PEACHY
{0xd8, 0xd9, 0xdb, 0xdc, 0xde, 0xdf, 0xd5, 0xd5, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0x1d, 0x1f}, // SKINCOLOR_QUAIL
{0x51, 0x52, 0x40, 0x40, 0x34, 0x36, 0xd5, 0xd5, 0xd6, 0xd7, 0xcf, 0xcf, 0xc6, 0xc6, 0xc7, 0xfe}, // SKINCOLOR_SUNSET
{0x58, 0x54, 0x40, 0x34, 0x35, 0x38, 0x3a, 0x3c, 0x3d, 0x2a, 0x2b, 0x2c, 0x2c, 0xba, 0xba, 0xbb}, // SKINCOLOR_COPPER
{0x00, 0xd8, 0xd9, 0xda, 0xdb, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e}, // SKINCOLOR_APRICOT
{0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x2c}, // SKINCOLOR_ORANGE
{0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3c, 0x3d, 0x3d, 0x3d, 0x3f, 0x2c, 0x2d, 0x47, 0x2e, 0x2f, 0x2f}, // SKINCOLOR_RUST
{0x51, 0x51, 0x54, 0x54, 0x41, 0x42, 0x43, 0x43, 0x44, 0x45, 0x46, 0x3f, 0x2d, 0x2e, 0x2f, 0x2f}, // SKINCOLOR_GOLD
{0x53, 0x40, 0x41, 0x42, 0x43, 0xe6, 0xe9, 0xe9, 0xea, 0xec, 0xec, 0xc6, 0xc6, 0xc7, 0xc7, 0xfe}, // SKINCOLOR_SANDY
{0x52, 0x53, 0x49, 0x49, 0x4a, 0x4a, 0x4b, 0x4b, 0x4b, 0x4c, 0x4d, 0x4d, 0x4e, 0x4e, 0x4f, 0xed}, // SKINCOLOR_YELLOW
{0x4b, 0x4b, 0x4c, 0x4c, 0x4d, 0x4e, 0xe7, 0xe7, 0xe9, 0xc5, 0xc5, 0xc6, 0xc6, 0xc7, 0xc7, 0xfd}, // SKINCOLOR_OLIVE
{0x50, 0x51, 0x52, 0x53, 0x48, 0xbc, 0xbd, 0xbe, 0xbe, 0xbf, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f}, // SKINCOLOR_LIME
{0x58, 0x58, 0xbc, 0xbc, 0xbd, 0xbd, 0xbe, 0xbe, 0xbe, 0xbf, 0x5e, 0x5e, 0x5f, 0x5f, 0x77, 0x77}, // SKINCOLOR_PERIDOT
{0x49, 0x49, 0xbc, 0xbd, 0xbe, 0xbe, 0xbe, 0x67, 0x69, 0x6a, 0x6b, 0x6b, 0x6c, 0x6d, 0x6d, 0x6d}, // SKINCOLOR_APPLE
{0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f}, // SKINCOLOR_GREEN
{0x65, 0x66, 0x67, 0x68, 0x69, 0x69, 0x6a, 0x6b, 0x6b, 0x6c, 0x6d, 0x6d, 0x6e, 0x6e, 0x6e, 0x6f}, // SKINCOLOR_FOREST
{0x70, 0x70, 0x71, 0x71, 0x72, 0x72, 0x73, 0x73, 0x73, 0x74, 0x75, 0x75, 0x76, 0x76, 0x77, 0x77}, // SKINCOLOR_EMERALD
{0x00, 0x00, 0x58, 0x58, 0x59, 0x62, 0x62, 0x62, 0x64, 0x67, 0x7e, 0x7e, 0x8f, 0x8f, 0x8a, 0x8a}, // SKINCOLOR_MINT
{0x01, 0x58, 0x59, 0x5a, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x8f, 0x8f, 0x8a, 0x8a, 0x8a, 0xfd, 0xfd}, // SKINCOLOR_SEAFOAM
{0x78, 0x79, 0x7a, 0x7a, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c, 0x7d, 0x7e, 0x7e, 0x7f, 0x7f, 0x76, 0x77}, // SKINCOLOR_AQUA
{0x78, 0x78, 0x8c, 0x8c, 0x8d, 0x8d, 0x8d, 0x8e, 0x8e, 0x8f, 0x8f, 0x8f, 0x8a, 0x8a, 0x8a, 0x8a}, // SKINCOLOR_TEAL
{0x00, 0x78, 0x78, 0x79, 0x8d, 0x87, 0x88, 0x89, 0x89, 0xae, 0xa8, 0xa8, 0xa9, 0xa9, 0xfd, 0xfd}, // SKINCOLOR_WAVE
{0x80, 0x81, 0xff, 0xff, 0x83, 0x83, 0x8d, 0x8d, 0x8d, 0x8e, 0x7e, 0x7f, 0x76, 0x76, 0x77, 0x6e}, // SKINCOLOR_CYAN
{0x80, 0x80, 0x81, 0x82, 0x83, 0x83, 0x84, 0x85, 0x85, 0x86, 0x87, 0x88, 0x89, 0x89, 0x8a, 0x8b}, // SKINCOLOR_SKY
{0x85, 0x86, 0x87, 0x88, 0x88, 0x89, 0x89, 0x89, 0x8a, 0x8a, 0xfd, 0xfd, 0xfd, 0x1f, 0x1f, 0x1f}, // SKINCOLOR_CERULEAN
{0x00, 0x00, 0x00, 0x00, 0x80, 0x81, 0x83, 0x83, 0x86, 0x87, 0x95, 0x95, 0xad, 0xad, 0xae, 0xaf}, // SKINCOLOR_ICY
{0x80, 0x83, 0x86, 0x87, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xfd, 0xfe}, // SKINCOLOR_SAPPHIRE
{0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x9a, 0x9c, 0x9d, 0x9d, 0x9e, 0x9e, 0x9e}, // SKINCOLOR_CORNFLOWER
{0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xfd, 0xfe}, // SKINCOLOR_BLUE
{0x93, 0x94, 0x95, 0x96, 0x98, 0x9a, 0x9b, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xfd, 0xfd, 0xfe, 0xfe}, // SKINCOLOR_COBALT
{0x80, 0x81, 0x83, 0x86, 0x94, 0x94, 0xa3, 0xa3, 0xa4, 0xa6, 0xa6, 0xa6, 0xa8, 0xa8, 0xa9, 0xa9}, // SKINCOLOR_VAPOR
{0x92, 0x93, 0x94, 0x94, 0xac, 0xad, 0xad, 0xad, 0xae, 0xae, 0xaf, 0xaf, 0xa9, 0xa9, 0xfd, 0xfd}, // SKINCOLOR_DUSK
{0x90, 0x90, 0xa0, 0xa0, 0xa1, 0xa1, 0xa2, 0xa2, 0xa2, 0xa3, 0xa4, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8}, // SKINCOLOR_PASTEL
{0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa4, 0xa5, 0xa5, 0xa5, 0xa6, 0xa7, 0xa7, 0xa8, 0xa8, 0xa9, 0xa9}, // SKINCOLOR_PURPLE
{0x00, 0xd0, 0xd0, 0xc8, 0xc8, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8}, // SKINCOLOR_BUBBLEGUM
{0xb3, 0xb3, 0xb4, 0xb5, 0xb6, 0xb6, 0xb7, 0xb7, 0xb7, 0xb8, 0xb9, 0xb9, 0xba, 0xba, 0xbb, 0xbb}, // SKINCOLOR_MAGENTA
{0xb3, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xb9, 0xba, 0xba, 0xbb, 0xbb, 0xc7, 0xc7, 0x1d, 0x1d, 0x1e}, // SKINCOLOR_NEON
{0xd0, 0xd1, 0xd2, 0xca, 0xcc, 0xb8, 0xb9, 0xb9, 0xba, 0xa8, 0xa8, 0xa9, 0xa9, 0xfd, 0xfe, 0xfe}, // SKINCOLOR_VIOLET
{0x00, 0xd0, 0xd1, 0xd2, 0xd3, 0xc1, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc5, 0xc6, 0xc6, 0xfe, 0x1f}, // SKINCOLOR_LILAC
{0xc8, 0xd3, 0xd5, 0xd6, 0xd7, 0xce, 0xcf, 0xb9, 0xb9, 0xba, 0xba, 0xa9, 0xa9, 0xa9, 0xfd, 0xfe}, // SKINCOLOR_PLUM
{0xc8, 0xc9, 0xca, 0xcb, 0xcb, 0xcc, 0xcd, 0xcd, 0xce, 0xb9, 0xb9, 0xba, 0xba, 0xbb, 0xfe, 0xfe}, // SKINCOLOR_RASPBERRY
{0xfc, 0xc8, 0xc8, 0xc9, 0xc9, 0xca, 0xca, 0xcb, 0xcb, 0xcc, 0xcc, 0xcd, 0xcd, 0xce, 0xce, 0xcf}, // SKINCOLOR_ROSY
// {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, // SKINCOLOR_?
// super
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x03}, // SKINCOLOR_SUPERSILVER1
{0x00, 0x01, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x07}, // SKINCOLOR_SUPERSILVER2
{0x01, 0x02, 0x02, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x07, 0x09, 0x0b}, // SKINCOLOR_SUPERSILVER3
{0x02, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x07, 0x09, 0x0b, 0x0d, 0x0f, 0x11}, // SKINCOLOR_SUPERSILVER4
{0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x07, 0x09, 0x0b, 0x0d, 0x0f, 0x11, 0x13}, // SKINCOLOR_SUPERSILVER5
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0xd0, 0xd1, 0xd1, 0xd2, 0xd2}, // SKINCOLOR_SUPERRED1
{0x00, 0x00, 0x00, 0xd0, 0xd0, 0xd0, 0xd1, 0xd1, 0xd1, 0xd2, 0xd2, 0xd2, 0x20, 0x20, 0x21, 0x21}, // SKINCOLOR_SUPERRED2
{0x00, 0x00, 0xd0, 0xd0, 0xd1, 0xd1, 0xd2, 0xd2, 0x20, 0x20, 0x21, 0x21, 0x22, 0x22, 0x23, 0x23}, // SKINCOLOR_SUPERRED3
{0x00, 0xd0, 0xd1, 0xd1, 0xd2, 0xd2, 0x20, 0x20, 0x21, 0x21, 0x22, 0x22, 0x23, 0x23, 0x24, 0x24}, // SKINCOLOR_SUPERRED4
{0xd0, 0xd1, 0xd2, 0xd2, 0x20, 0x20, 0x21, 0x21, 0x22, 0x22, 0x23, 0x23, 0x24, 0x24, 0x25, 0x25}, // SKINCOLOR_SUPERRED5
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x30, 0x31, 0x32, 0x33, 0x34}, // SKINCOLOR_SUPERORANGE1
{0x00, 0x00, 0x00, 0x00, 0xd0, 0xd0, 0x30, 0x30, 0x31, 0x31, 0x32, 0x32, 0x33, 0x33, 0x34, 0x34}, // SKINCOLOR_SUPERORANGE2
{0x00, 0x00, 0xd0, 0xd0, 0x30, 0x30, 0x31, 0x31, 0x32, 0x32, 0x33, 0x33, 0x34, 0x34, 0x35, 0x35}, // SKINCOLOR_SUPERORANGE3
{0x00, 0xd0, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x44, 0x45, 0x46}, // SKINCOLOR_SUPERORANGE4
{0xd0, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x44, 0x45, 0x46, 0x47}, // SKINCOLOR_SUPERORANGE5
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50, 0x51, 0x52, 0x53, 0x48, 0x48, 0x48}, // SKINCOLOR_SUPERGOLD1
{0x00, 0x50, 0x51, 0x52, 0x53, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x40, 0x41, 0x41, 0x41}, // SKINCOLOR_SUPERGOLD2
{0x51, 0x52, 0x53, 0x53, 0x48, 0x49, 0x49, 0x49, 0x49, 0x49, 0x40, 0x41, 0x42, 0x43, 0x43, 0x43}, // SKINCOLOR_SUPERGOLD3
{0x53, 0x48, 0x48, 0x49, 0x49, 0x49, 0x49, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x46, 0x46}, // SKINCOLOR_SUPERGOLD4
{0x48, 0x48, 0x49, 0x49, 0x49, 0x40, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x47, 0x47}, // SKINCOLOR_SUPERGOLD5
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x58, 0x58, 0xbc, 0xbc, 0xbc}, // SKINCOLOR_SUPERPERIDOT1
{0x00, 0x58, 0x58, 0x58, 0xbc, 0xbc, 0xbc, 0xbc, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbe, 0xbe}, // SKINCOLOR_SUPERPERIDOT2
{0x58, 0x58, 0xbc, 0xbc, 0xbc, 0xbc, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbe, 0xbe, 0xbf, 0xbf}, // SKINCOLOR_SUPERPERIDOT3
{0x58, 0xbc, 0xbc, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbe, 0xbe, 0xbf, 0xbf, 0x5e, 0x5e, 0x5f}, // SKINCOLOR_SUPERPERIDOT4
{0xbc, 0xbc, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbe, 0xbe, 0xbf, 0xbf, 0x5e, 0x5e, 0x5f, 0x77}, // SKINCOLOR_SUPERPERIDOT5
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x81, 0x82, 0x83, 0x84}, // SKINCOLOR_SUPERSKY1
{0x00, 0x80, 0x81, 0x82, 0x83, 0x83, 0x84, 0x84, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x86, 0x86}, // SKINCOLOR_SUPERSKY2
{0x81, 0x82, 0x83, 0x83, 0x84, 0x84, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x86, 0x86, 0x87, 0x87}, // SKINCOLOR_SUPERSKY3
{0x83, 0x84, 0x84, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x86, 0x86, 0x87, 0x87, 0x88, 0x89, 0x8a}, // SKINCOLOR_SUPERSKY4
{0x84, 0x84, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x86, 0x86, 0x87, 0x87, 0x88, 0x89, 0x8a, 0x8b}, // SKINCOLOR_SUPERSKY5
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90, 0xa0, 0xa0, 0xa1, 0xa2}, // SKINCOLOR_SUPERPURPLE1
{0x00, 0x90, 0xa0, 0xa0, 0xa1, 0xa1, 0xa2, 0xa2, 0xa3, 0xa3, 0xa3, 0xa3, 0xa4, 0xa4, 0xa5, 0xa5}, // SKINCOLOR_SUPERPURPLE2
{0xa0, 0xa0, 0xa1, 0xa1, 0xa2, 0xa2, 0xa3, 0xa3, 0xa3, 0xa3, 0xa4, 0xa4, 0xa5, 0xa5, 0xa6, 0xa6}, // SKINCOLOR_SUPERPURPLE3
{0xa1, 0xa2, 0xa2, 0xa3, 0xa3, 0xa3, 0xa3, 0xa4, 0xa4, 0xa5, 0xa5, 0xa6, 0xa6, 0xa7, 0xa8, 0xa9}, // SKINCOLOR_SUPERPURPLE4
{0xa2, 0xa2, 0xa3, 0xa3, 0xa3, 0xa3, 0xa4, 0xa4, 0xa5, 0xa5, 0xa6, 0xa6, 0xa7, 0xa8, 0xa9, 0xfd}, // SKINCOLOR_SUPERPURPLE5
{0x00, 0xd0, 0xd0, 0xd0, 0x30, 0x30, 0x31, 0x32, 0x33, 0x37, 0x3a, 0x44, 0x45, 0x46, 0x47, 0x2e}, // SKINCOLOR_SUPERRUST1
{0x30, 0x31, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x38, 0x3a, 0x44, 0x45, 0x46, 0x47, 0x47, 0x2e}, // SKINCOLOR_SUPERRUST2
{0x31, 0x32, 0x33, 0x34, 0x36, 0x37, 0x38, 0x3a, 0x44, 0x45, 0x45, 0x46, 0x46, 0x47, 0x2e, 0x2e}, // SKINCOLOR_SUPERRUST3
{0x48, 0x40, 0x41, 0x42, 0x43, 0x44, 0x44, 0x45, 0x45, 0x46, 0x46, 0x47, 0x47, 0x2e, 0x2e, 0x2e}, // SKINCOLOR_SUPERRUST4
{0x41, 0x42, 0x43, 0x43, 0x44, 0x44, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xed, 0xee, 0xee, 0xef, 0xef}, // SKINCOLOR_SUPERRUST5
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50, 0x51, 0x51, 0x52, 0x52}, // SKINCOLOR_SUPERTAN1
{0x00, 0x50, 0x50, 0x51, 0x51, 0x52, 0x52, 0x52, 0x54, 0x54, 0x54, 0x54, 0x55, 0x56, 0x57, 0xf5}, // SKINCOLOR_SUPERTAN2
{0x50, 0x51, 0x51, 0x52, 0x52, 0x52, 0x54, 0x54, 0x54, 0x54, 0x55, 0x56, 0x57, 0xf5, 0xf7, 0xf9}, // SKINCOLOR_SUPERTAN3
{0x51, 0x52, 0x52, 0x52, 0x52, 0x54, 0x54, 0x54, 0x55, 0x56, 0x57, 0xf5, 0xf7, 0xf9, 0xfb, 0xed}, // SKINCOLOR_SUPERTAN4
{0x52, 0x52, 0x54, 0x54, 0x54, 0x55, 0x56, 0x57, 0xf5, 0xf7, 0xf9, 0xfb, 0xed, 0xee, 0xef, 0xef} // SKINCOLOR_SUPERTAN5
};
// See also the enum skincolors_t
// TODO Callum: Can this be translated?
const char *Color_Names[MAXSKINCOLORS + NUMSUPERCOLORS] =
{
"None", // SKINCOLOR_NONE,
// Greyscale ranges
"White", // SKINCOLOR_WHITE,
"Bone", // SKINCOLOR_BONE,
"Cloudy", // SKINCOLOR_CLOUDY,
"Grey", // SKINCOLOR_GREY,
"Silver", // SKINCOLOR_SILVER,
"Carbon", // SKINCOLOR_CARBON,
"Jet", // SKINCOLOR_JET,
"Black", // SKINCOLOR_BLACK,
// Desaturated
"Aether", // SKINCOLOR_AETHER,
"Slate", // SKINCOLOR_SLATE,
"Bluebell", // SKINCOLOR_BLUEBELL,
"Pink", // SKINCOLOR_PINK,
"Yogurt", // SKINCOLOR_YOGURT,
"Brown", // SKINCOLOR_BROWN,
"Bronze", // SKINCOLOR_BRONZE,
"Tan", // SKINCOLOR_TAN,
"Beige", // SKINCOLOR_BEIGE,
"Moss", // SKINCOLOR_MOSS,
"Azure", // SKINCOLOR_AZURE,
"Lavender", // SKINCOLOR_LAVENDER,
// Viv's vivid colours (toast 21/07/17)
"Ruby", // SKINCOLOR_RUBY,
"Salmon", // SKINCOLOR_SALMON,
"Red", // SKINCOLOR_RED,
"Crimson", // SKINCOLOR_CRIMSON,
"Flame", // SKINCOLOR_FLAME,
"Ketchup", // SKINCOLOR_KETCHUP,
"Peachy", // SKINCOLOR_PEACHY,
"Quail", // SKINCOLOR_QUAIL,
"Sunset", // SKINCOLOR_SUNSET,
"Copper", // SKINCOLOR_COPPER,
"Apricot", // SKINCOLOR_APRICOT,
"Orange", // SKINCOLOR_ORANGE,
"Rust", // SKINCOLOR_RUST,
"Gold", // SKINCOLOR_GOLD,
"Sandy", // SKINCOLOR_SANDY,
"Yellow", // SKINCOLOR_YELLOW,
"Olive", // SKINCOLOR_OLIVE,
"Lime", // SKINCOLOR_LIME,
"Peridot", // SKINCOLOR_PERIDOT,
"Apple", // SKINCOLOR_APPLE,
"Green", // SKINCOLOR_GREEN,
"Forest", // SKINCOLOR_FOREST,
"Emerald", // SKINCOLOR_EMERALD,
"Mint", // SKINCOLOR_MINT,
"Seafoam", // SKINCOLOR_SEAFOAM,
"Aqua", // SKINCOLOR_AQUA,
"Teal", // SKINCOLOR_TEAL,
"Wave", // SKINCOLOR_WAVE,
"Cyan", // SKINCOLOR_CYAN,
"Sky", // SKINCOLOR_SKY,
"Cerulean", // SKINCOLOR_CERULEAN,
"Icy", // SKINCOLOR_ICY,
"Sapphire", // SKINCOLOR_SAPPHIRE,
"Cornflower", // SKINCOLOR_CORNFLOWER,
"Blue", // SKINCOLOR_BLUE,
"Cobalt", // SKINCOLOR_COBALT,
"Vapor", // SKINCOLOR_VAPOR,
"Dusk", // SKINCOLOR_DUSK,
"Pastel", // SKINCOLOR_PASTEL,
"Purple", // SKINCOLOR_PURPLE,
"Bubblegum", // SKINCOLOR_BUBBLEGUM,
"Magenta", // SKINCOLOR_MAGENTA,
"Neon", // SKINCOLOR_NEON,
"Violet", // SKINCOLOR_VIOLET,
"Lilac", // SKINCOLOR_LILAC,
"Plum", // SKINCOLOR_PLUM,
"Raspberry", // SKINCOLOR_RASPBERRY,
"Rosy", // SKINCOLOR_ROSY,
// Super behaves by different rules (one name per 5 colours), and will be accessed exclusively via R_GetSuperColorByName instead of R_GetColorByName.
"Silver", // SKINCOLOR_SUPERSILVER1,
"Red", // SKINCOLOR_SUPERRED1,
"Orange", // SKINCOLOR_SUPERORANGE1,
"Gold", // SKINCOLOR_SUPERGOLD1,
"Peridot", // SKINCOLOR_SUPERPERIDOT1,
"Sky", // SKINCOLOR_SUPERSKY1,
"Purple", // SKINCOLOR_SUPERPURPLE1,
"Rust", // SKINCOLOR_SUPERRUST1,
"Tan" // SKINCOLOR_SUPERTAN1,
};
/*
A word of warning: If the following array is non-symmetrical,
A_SignPlayer's prefoppositecolor behaviour will break.
*/
// [0] = opposite skin color,
// [1] = shade index used by signpost, 0-15 (actual sprite frame is 15 minus this value)
const UINT8 Color_Opposite[MAXSKINCOLORS - 1][2] =
{
// {SKINCOLOR_NONE, 8}, // SKINCOLOR_NONE
// Greyscale ranges
{SKINCOLOR_BLACK, 5}, // SKINCOLOR_WHITE,
{SKINCOLOR_JET, 7}, // SKINCOLOR_BONE,
{SKINCOLOR_CARBON, 7}, // SKINCOLOR_CLOUDY,
{SKINCOLOR_AETHER, 12}, // SKINCOLOR_GREY,
{SKINCOLOR_SLATE, 12}, // SKINCOLOR_SILVER,
{SKINCOLOR_CLOUDY, 7}, // SKINCOLOR_CARBON,
{SKINCOLOR_BONE, 7}, // SKINCOLOR_JET,
{SKINCOLOR_WHITE, 7}, // SKINCOLOR_BLACK,
// Desaturated
{SKINCOLOR_GREY, 15}, // SKINCOLOR_AETHER,
{SKINCOLOR_SILVER, 12}, // SKINCOLOR_SLATE,
{SKINCOLOR_COPPER, 4}, // SKINCOLOR_BLUEBELL,
{SKINCOLOR_AZURE, 9}, // SKINCOLOR_PINK,
{SKINCOLOR_RUST, 7}, // SKINCOLOR_YOGURT,
{SKINCOLOR_TAN, 2}, // SKINCOLOR_BROWN,
{SKINCOLOR_KETCHUP, 0}, // SKINCOLOR_BRONZE,
{SKINCOLOR_BROWN, 12}, // SKINCOLOR_TAN,
{SKINCOLOR_MOSS, 5}, // SKINCOLOR_BEIGE,
{SKINCOLOR_BEIGE, 13}, // SKINCOLOR_MOSS,
{SKINCOLOR_PINK, 5}, // SKINCOLOR_AZURE,
{SKINCOLOR_GOLD, 4}, // SKINCOLOR_LAVENDER,
// Viv's vivid colours (toast 21/07/17)
{SKINCOLOR_EMERALD, 10}, // SKINCOLOR_RUBY,
{SKINCOLOR_FOREST, 6}, // SKINCOLOR_SALMON,
{SKINCOLOR_GREEN, 10}, // SKINCOLOR_RED,
{SKINCOLOR_ICY, 10}, // SKINCOLOR_CRIMSON,
{SKINCOLOR_PURPLE, 8}, // SKINCOLOR_FLAME,
{SKINCOLOR_BRONZE, 8}, // SKINCOLOR_KETCHUP,
{SKINCOLOR_TEAL, 7}, // SKINCOLOR_PEACHY,
{SKINCOLOR_WAVE, 5}, // SKINCOLOR_QUAIL,
{SKINCOLOR_SAPPHIRE, 5}, // SKINCOLOR_SUNSET,
{SKINCOLOR_BLUEBELL, 5}, // SKINCOLOR_COPPER
{SKINCOLOR_CYAN, 4}, // SKINCOLOR_APRICOT,
{SKINCOLOR_BLUE, 4}, // SKINCOLOR_ORANGE,
{SKINCOLOR_YOGURT, 8}, // SKINCOLOR_RUST,
{SKINCOLOR_LAVENDER, 10}, // SKINCOLOR_GOLD,
{SKINCOLOR_SKY, 8}, // SKINCOLOR_SANDY,
{SKINCOLOR_CORNFLOWER, 8}, // SKINCOLOR_YELLOW,
{SKINCOLOR_DUSK, 3}, // SKINCOLOR_OLIVE,
{SKINCOLOR_MAGENTA, 9}, // SKINCOLOR_LIME,
{SKINCOLOR_COBALT, 2}, // SKINCOLOR_PERIDOT,
{SKINCOLOR_RASPBERRY, 13}, // SKINCOLOR_APPLE,
{SKINCOLOR_RED, 6}, // SKINCOLOR_GREEN,
{SKINCOLOR_SALMON, 9}, // SKINCOLOR_FOREST,
{SKINCOLOR_RUBY, 4}, // SKINCOLOR_EMERALD,
{SKINCOLOR_VIOLET, 5}, // SKINCOLOR_MINT,
{SKINCOLOR_PLUM, 6}, // SKINCOLOR_SEAFOAM,
{SKINCOLOR_ROSY, 7}, // SKINCOLOR_AQUA,
{SKINCOLOR_PEACHY, 7}, // SKINCOLOR_TEAL,
{SKINCOLOR_QUAIL, 5}, // SKINCOLOR_WAVE,
{SKINCOLOR_APRICOT, 6}, // SKINCOLOR_CYAN,
{SKINCOLOR_SANDY, 1}, // SKINCOLOR_SKY,
{SKINCOLOR_NEON, 4}, // SKINCOLOR_CERULEAN,
{SKINCOLOR_CRIMSON, 0}, // SKINCOLOR_ICY,
{SKINCOLOR_SUNSET, 5}, // SKINCOLOR_SAPPHIRE,
{SKINCOLOR_YELLOW, 4}, // SKINCOLOR_CORNFLOWER,
{SKINCOLOR_ORANGE, 5}, // SKINCOLOR_BLUE,
{SKINCOLOR_PERIDOT, 5}, // SKINCOLOR_COBALT,
{SKINCOLOR_LILAC, 4}, // SKINCOLOR_VAPOR,
{SKINCOLOR_OLIVE, 0}, // SKINCOLOR_DUSK,
{SKINCOLOR_BUBBLEGUM, 9}, // SKINCOLOR_PASTEL,
{SKINCOLOR_FLAME, 7}, // SKINCOLOR_PURPLE,
{SKINCOLOR_PASTEL, 8}, // SKINCOLOR_BUBBLEGUM,
{SKINCOLOR_LIME, 6}, // SKINCOLOR_MAGENTA,
{SKINCOLOR_CERULEAN, 2}, // SKINCOLOR_NEON,
{SKINCOLOR_MINT, 6}, // SKINCOLOR_VIOLET,
{SKINCOLOR_VAPOR, 4}, // SKINCOLOR_LILAC,
{SKINCOLOR_MINT, 7}, // SKINCOLOR_PLUM,
{SKINCOLOR_APPLE, 13}, // SKINCOLOR_RASPBERRY
{SKINCOLOR_AQUA, 1} // SKINCOLOR_ROSY,
};
CV_PossibleValue_t Color_cons_t[MAXSKINCOLORS+1]; CV_PossibleValue_t Color_cons_t[MAXSKINCOLORS+1];
/** \brief The R_InitTranslationTables /** \brief The R_InitTranslationTables
@ -496,7 +184,7 @@ void R_InitTranslationTables(void)
\param dest_colormap colormap to populate \param dest_colormap colormap to populate
\param skincolor translation color \param skincolor translation color
*/ */
static void R_RainbowColormap(UINT8 *dest_colormap, UINT8 skincolor) static void R_RainbowColormap(UINT8 *dest_colormap, UINT16 skincolor)
{ {
INT32 i; INT32 i;
RGBA_t color; RGBA_t color;
@ -509,7 +197,7 @@ static void R_RainbowColormap(UINT8 *dest_colormap, UINT8 skincolor)
// first generate the brightness of all the colours of that skincolour // first generate the brightness of all the colours of that skincolour
for (i = 0; i < 16; i++) for (i = 0; i < 16; i++)
{ {
color = V_GetColor(Color_Index[skincolor-1][i]); color = V_GetColor(skincolors[skincolor].ramp[i]);
SETBRIGHTNESS(colorbrightnesses[i], color.s.red, color.s.green, color.s.blue); SETBRIGHTNESS(colorbrightnesses[i], color.s.red, color.s.green, color.s.blue);
} }
@ -530,7 +218,7 @@ static void R_RainbowColormap(UINT8 *dest_colormap, UINT8 skincolor)
if (temp < brightdif) if (temp < brightdif)
{ {
brightdif = (UINT16)temp; brightdif = (UINT16)temp;
dest_colormap[i] = Color_Index[skincolor-1][j]; dest_colormap[i] = skincolors[skincolor].ramp[j];
} }
} }
} }
@ -538,7 +226,7 @@ static void R_RainbowColormap(UINT8 *dest_colormap, UINT8 skincolor)
#undef SETBRIGHTNESS #undef SETBRIGHTNESS
static void R_GenerateTranslationColormap(UINT8 *dest_colormap, INT32 skinnum, UINT8 color) static void R_GenerateTranslationColormap(UINT8 *dest_colormap, INT32 skinnum, UINT16 color)
{ {
INT32 i, starttranscolor, skinramplength; INT32 i, starttranscolor, skinramplength;
@ -551,7 +239,7 @@ static void R_GenerateTranslationColormap(UINT8 *dest_colormap, INT32 skinnum, U
memset(dest_colormap, 0, NUM_PALETTE_ENTRIES * sizeof(UINT8)); memset(dest_colormap, 0, NUM_PALETTE_ENTRIES * sizeof(UINT8));
return; return;
case TC_RAINBOW: case TC_RAINBOW:
if (color >= MAXTRANSLATIONS) if (color >= numskincolors)
I_Error("Invalid skin color #%hu.", (UINT16)color); I_Error("Invalid skin color #%hu.", (UINT16)color);
if (color != SKINCOLOR_NONE) if (color != SKINCOLOR_NONE)
{ {
@ -560,11 +248,11 @@ static void R_GenerateTranslationColormap(UINT8 *dest_colormap, INT32 skinnum, U
} }
break; break;
case TC_BLINK: case TC_BLINK:
if (color >= MAXTRANSLATIONS) if (color >= numskincolors)
I_Error("Invalid skin color #%hu.", (UINT16)color); I_Error("Invalid skin color #%hu.", (UINT16)color);
if (color != SKINCOLOR_NONE) if (color != SKINCOLOR_NONE)
{ {
memset(dest_colormap, Color_Index[color-1][3], NUM_PALETTE_ENTRIES * sizeof(UINT8)); memset(dest_colormap, skincolors[color].ramp[3], NUM_PALETTE_ENTRIES * sizeof(UINT8));
return; return;
} }
break; break;
@ -585,11 +273,11 @@ static void R_GenerateTranslationColormap(UINT8 *dest_colormap, INT32 skinnum, U
{ {
for (i = 0; i < 6; i++) for (i = 0; i < 6; i++)
{ {
dest_colormap[Color_Index[SKINCOLOR_BLUE-1][12-i]] = Color_Index[SKINCOLOR_BLUE-1][i]; dest_colormap[skincolors[SKINCOLOR_BLUE].ramp[12-i]] = skincolors[SKINCOLOR_BLUE].ramp[i];
} }
dest_colormap[159] = dest_colormap[253] = dest_colormap[254] = 0; dest_colormap[159] = dest_colormap[253] = dest_colormap[254] = 0;
for (i = 0; i < 16; i++) for (i = 0; i < 16; i++)
dest_colormap[96+i] = dest_colormap[Color_Index[SKINCOLOR_COBALT-1][i]]; dest_colormap[96+i] = dest_colormap[skincolors[SKINCOLOR_COBALT].ramp[i]];
} }
else if (skinnum == TC_DASHMODE) // This is a long one, because MotorRoach basically hand-picked the indices else if (skinnum == TC_DASHMODE) // This is a long one, because MotorRoach basically hand-picked the indices
{ {
@ -634,7 +322,7 @@ static void R_GenerateTranslationColormap(UINT8 *dest_colormap, INT32 skinnum, U
return; return;
} }
if (color >= MAXTRANSLATIONS) if (color >= numskincolors)
I_Error("Invalid skin color #%hu.", (UINT16)color); I_Error("Invalid skin color #%hu.", (UINT16)color);
starttranscolor = (skinnum != TC_DEFAULT) ? skins[skinnum].starttranscolor : DEFAULT_STARTTRANSCOLOR; starttranscolor = (skinnum != TC_DEFAULT) ? skins[skinnum].starttranscolor : DEFAULT_STARTTRANSCOLOR;
@ -658,7 +346,7 @@ static void R_GenerateTranslationColormap(UINT8 *dest_colormap, INT32 skinnum, U
// Build the translated ramp // Build the translated ramp
for (i = 0; i < skinramplength; i++) for (i = 0; i < skinramplength; i++)
dest_colormap[starttranscolor + i] = (UINT8)Color_Index[color-1][i]; dest_colormap[starttranscolor + i] = (UINT8)skincolors[color].ramp[i];
} }
@ -670,7 +358,7 @@ static void R_GenerateTranslationColormap(UINT8 *dest_colormap, INT32 skinnum, U
\return Colormap. If not cached, caller should Z_Free. \return Colormap. If not cached, caller should Z_Free.
*/ */
UINT8* R_GetTranslationColormap(INT32 skinnum, skincolors_t color, UINT8 flags) UINT8* R_GetTranslationColormap(INT32 skinnum, skincolornum_t color, UINT8 flags)
{ {
UINT8* ret; UINT8* ret;
INT32 skintableindex; INT32 skintableindex;
@ -693,7 +381,7 @@ UINT8* R_GetTranslationColormap(INT32 skinnum, skincolors_t color, UINT8 flags)
// Allocate table for skin if necessary // Allocate table for skin if necessary
if (!translationtablecache[skintableindex]) if (!translationtablecache[skintableindex])
translationtablecache[skintableindex] = Z_Calloc(MAXTRANSLATIONS * sizeof(UINT8**), PU_STATIC, NULL); translationtablecache[skintableindex] = Z_Calloc(MAXSKINCOLORS * sizeof(UINT8**), PU_STATIC, NULL);
// Get colormap // Get colormap
ret = translationtablecache[skintableindex][color]; ret = translationtablecache[skintableindex][color];
@ -728,29 +416,32 @@ void R_FlushTranslationColormapCache(void)
for (i = 0; i < (INT32)(sizeof(translationtablecache) / sizeof(translationtablecache[0])); i++) for (i = 0; i < (INT32)(sizeof(translationtablecache) / sizeof(translationtablecache[0])); i++)
if (translationtablecache[i]) if (translationtablecache[i])
memset(translationtablecache[i], 0, MAXTRANSLATIONS * sizeof(UINT8**)); memset(translationtablecache[i], 0, MAXSKINCOLORS * sizeof(UINT8**));
} }
UINT8 R_GetColorByName(const char *name) UINT16 R_GetColorByName(const char *name)
{ {
UINT8 color = (UINT8)atoi(name); UINT16 color = (UINT16)atoi(name);
if (color > 0 && color < MAXSKINCOLORS) if (color > 0 && color < numskincolors)
return color; return color;
for (color = 1; color < MAXSKINCOLORS; color++) for (color = 1; color < numskincolors; color++)
if (!stricmp(Color_Names[color], name)) if (!stricmp(skincolors[color].name, name))
return color; return color;
return SKINCOLOR_GREEN; return SKINCOLOR_GREEN;
} }
UINT8 R_GetSuperColorByName(const char *name) UINT16 R_GetSuperColorByName(const char *name)
{ {
UINT8 color; /* = (UINT8)atoi(name); -- This isn't relevant to S_SKIN, which is the only way it's accessible right now. Let's simplify things. UINT16 i, color = SKINCOLOR_SUPERGOLD1;
if (color > MAXSKINCOLORS && color < MAXTRANSLATIONS && !((color - MAXSKINCOLORS) % 5)) char *realname = Z_Malloc(MAXCOLORNAME+1, PU_STATIC, NULL);
return color;*/ snprintf(realname, MAXCOLORNAME+1, "Super %s 1", name);
for (color = 0; color < NUMSUPERCOLORS; color++) for (i = 1; i < numskincolors; i++)
if (!stricmp(Color_Names[color + MAXSKINCOLORS], name)) if (!stricmp(skincolors[i].name, realname)) {
return ((color*5) + MAXSKINCOLORS); color = i;
return SKINCOLOR_SUPERGOLD1; break;
}
Z_Free(realname);
return color;
} }
// ========================================================================== // ==========================================================================

View File

@ -112,10 +112,10 @@ extern lumpnum_t viewborderlump[8];
// Initialize color translation tables, for player rendering etc. // Initialize color translation tables, for player rendering etc.
void R_InitTranslationTables(void); void R_InitTranslationTables(void);
UINT8* R_GetTranslationColormap(INT32 skinnum, skincolors_t color, UINT8 flags); UINT8* R_GetTranslationColormap(INT32 skinnum, skincolornum_t color, UINT8 flags);
void R_FlushTranslationColormapCache(void); void R_FlushTranslationColormapCache(void);
UINT8 R_GetColorByName(const char *name); UINT16 R_GetColorByName(const char *name);
UINT8 R_GetSuperColorByName(const char *name); UINT16 R_GetSuperColorByName(const char *name);
// Custom player skin translation // Custom player skin translation
void R_InitViewBuffer(INT32 width, INT32 height); void R_InitViewBuffer(INT32 width, INT32 height);

View File

@ -1388,7 +1388,7 @@ void R_RenderPlayerView(player_t *player)
else else
{ {
portalclipstart = 0; portalclipstart = 0;
portalclipend = viewwidth-1; portalclipend = viewwidth;
R_ClearClipSegs(); R_ClearClipSegs();
} }
R_ClearDrawSegs(); R_ClearDrawSegs();

View File

@ -1231,9 +1231,9 @@ void R_CacheRotSprite(spritenum_t sprnum, UINT8 frame, spriteinfo_t *sprinfo, sp
if (!R_CheckIfPatch(lump)) if (!R_CheckIfPatch(lump))
return; return;
width = patch->width; width = SHORT(patch->width);
height = patch->height; height = SHORT(patch->height);
leftoffset = patch->leftoffset; leftoffset = SHORT(patch->leftoffset);
// rotation pivot // rotation pivot
px = SPRITE_XCENTER; px = SPRITE_XCENTER;
@ -1348,7 +1348,7 @@ void R_CacheRotSprite(spritenum_t sprnum, UINT8 frame, spriteinfo_t *sprinfo, sp
newpatch = R_MaskedFlatToPatch(rawdst, newwidth, newheight, 0, 0, &size); newpatch = R_MaskedFlatToPatch(rawdst, newwidth, newheight, 0, 0, &size);
{ {
newpatch->leftoffset = (newpatch->width / 2) + (leftoffset - px); newpatch->leftoffset = (newpatch->width / 2) + (leftoffset - px);
newpatch->topoffset = (newpatch->height / 2) + (patch->topoffset - py); newpatch->topoffset = (newpatch->height / 2) + (SHORT(patch->topoffset) - py);
} }
//BP: we cannot use special tric in hardware mode because feet in ground caused by z-buffer //BP: we cannot use special tric in hardware mode because feet in ground caused by z-buffer
@ -1358,6 +1358,12 @@ void R_CacheRotSprite(spritenum_t sprnum, UINT8 frame, spriteinfo_t *sprinfo, sp
// P_PrecacheLevel // P_PrecacheLevel
if (devparm) spritememory += size; if (devparm) spritememory += size;
// convert everything to little-endian, for big-endian support
newpatch->width = SHORT(newpatch->width);
newpatch->height = SHORT(newpatch->height);
newpatch->leftoffset = SHORT(newpatch->leftoffset);
newpatch->topoffset = SHORT(newpatch->topoffset);
#ifdef HWRENDER #ifdef HWRENDER
if (rendermode == render_opengl) if (rendermode == render_opengl)
{ {

View File

@ -337,11 +337,7 @@ static visplane_t *new_visplane(unsigned hash)
// //
visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel,
fixed_t xoff, fixed_t yoff, angle_t plangle, extracolormap_t *planecolormap, fixed_t xoff, fixed_t yoff, angle_t plangle, extracolormap_t *planecolormap,
ffloor_t *pfloor ffloor_t *pfloor, polyobj_t *polyobj, pslope_t *slope)
#ifdef POLYOBJECTS_PLANES
, polyobj_t *polyobj
#endif
, pslope_t *slope)
{ {
visplane_t *check; visplane_t *check;
unsigned hash; unsigned hash;
@ -361,7 +357,6 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel,
} }
} }
#ifdef POLYOBJECTS_PLANES
if (polyobj) if (polyobj)
{ {
if (polyobj->angle != 0) if (polyobj->angle != 0)
@ -376,7 +371,6 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel,
yoff += polyobj->centerPt.y; yoff += polyobj->centerPt.y;
} }
} }
#endif
// This appears to fix the Nimbus Ruins sky bug. // This appears to fix the Nimbus Ruins sky bug.
if (picnum == skyflatnum && pfloor) if (picnum == skyflatnum && pfloor)
@ -390,12 +384,10 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel,
for (check = visplanes[hash]; check; check = check->next) for (check = visplanes[hash]; check; check = check->next)
{ {
#ifdef POLYOBJECTS_PLANES
if (check->polyobj && pfloor) if (check->polyobj && pfloor)
continue; continue;
if (polyobj != check->polyobj) if (polyobj != check->polyobj)
continue; continue;
#endif
if (height == check->height && picnum == check->picnum if (height == check->height && picnum == check->picnum
&& lightlevel == check->lightlevel && lightlevel == check->lightlevel
&& xoff == check->xoffs && yoff == check->yoffs && xoff == check->xoffs && yoff == check->yoffs
@ -426,9 +418,7 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel,
check->viewz = viewz; check->viewz = viewz;
check->viewangle = viewangle; check->viewangle = viewangle;
check->plangle = plangle; check->plangle = plangle;
#ifdef POLYOBJECTS_PLANES
check->polyobj = polyobj; check->polyobj = polyobj;
#endif
check->slope = slope; check->slope = slope;
memset(check->top, 0xff, sizeof (check->top)); memset(check->top, 0xff, sizeof (check->top));
@ -496,9 +486,7 @@ visplane_t *R_CheckPlane(visplane_t *pl, INT32 start, INT32 stop)
new_pl->viewz = pl->viewz; new_pl->viewz = pl->viewz;
new_pl->viewangle = pl->viewangle; new_pl->viewangle = pl->viewangle;
new_pl->plangle = pl->plangle; new_pl->plangle = pl->plangle;
#ifdef POLYOBJECTS_PLANES
new_pl->polyobj = pl->polyobj; new_pl->polyobj = pl->polyobj;
#endif
new_pl->slope = pl->slope; new_pl->slope = pl->slope;
pl = new_pl; pl = new_pl;
pl->minx = start; pl->minx = start;
@ -523,11 +511,9 @@ void R_ExpandPlane(visplane_t *pl, INT32 start, INT32 stop)
// INT32 unionl, unionh; // INT32 unionl, unionh;
// INT32 x; // INT32 x;
#ifdef POLYOBJECTS_PLANES
// Don't expand polyobject planes here - we do that on our own. // Don't expand polyobject planes here - we do that on our own.
if (pl->polyobj) if (pl->polyobj)
return; return;
#endif
if (pl->minx > start) pl->minx = start; if (pl->minx > start) pl->minx = start;
if (pl->maxx < stop) pl->maxx = stop; if (pl->maxx < stop) pl->maxx = stop;
@ -603,11 +589,7 @@ void R_DrawPlanes(void)
{ {
for (pl = visplanes[i]; pl; pl = pl->next) for (pl = visplanes[i]; pl; pl = pl->next)
{ {
if (pl->ffloor != NULL if (pl->ffloor != NULL || pl->polyobj != NULL)
#ifdef POLYOBJECTS_PLANES
|| pl->polyobj != NULL
#endif
)
continue; continue;
R_DrawSinglePlane(pl); R_DrawSinglePlane(pl);
@ -851,15 +833,15 @@ static void R_SlopeVectors(visplane_t *pl, INT32 i, float fudge)
floatv3_t p, m, n; floatv3_t p, m, n;
float ang; float ang;
float vx, vy, vz; float vx, vy, vz;
// compiler complains when P_GetZAt is used in FLOAT_TO_FIXED directly // compiler complains when P_GetSlopeZAt is used in FLOAT_TO_FIXED directly
// use this as a temp var to store P_GetZAt's return value each time // use this as a temp var to store P_GetSlopeZAt's return value each time
fixed_t temp; fixed_t temp;
vx = FIXED_TO_FLOAT(pl->viewx+xoffs); vx = FIXED_TO_FLOAT(pl->viewx+xoffs);
vy = FIXED_TO_FLOAT(pl->viewy-yoffs); vy = FIXED_TO_FLOAT(pl->viewy-yoffs);
vz = FIXED_TO_FLOAT(pl->viewz); vz = FIXED_TO_FLOAT(pl->viewz);
temp = P_GetZAt(pl->slope, pl->viewx, pl->viewy); temp = P_GetSlopeZAt(pl->slope, pl->viewx, pl->viewy);
zeroheight = FIXED_TO_FLOAT(temp); zeroheight = FIXED_TO_FLOAT(temp);
// p is the texture origin in view space // p is the texture origin in view space
@ -868,7 +850,7 @@ static void R_SlopeVectors(visplane_t *pl, INT32 i, float fudge)
ang = ANG2RAD(ANGLE_270 - pl->viewangle); ang = ANG2RAD(ANGLE_270 - pl->viewangle);
p.x = vx * cos(ang) - vy * sin(ang); p.x = vx * cos(ang) - vy * sin(ang);
p.z = vx * sin(ang) + vy * cos(ang); p.z = vx * sin(ang) + vy * cos(ang);
temp = P_GetZAt(pl->slope, -xoffs, yoffs); temp = P_GetSlopeZAt(pl->slope, -xoffs, yoffs);
p.y = FIXED_TO_FLOAT(temp) - vz; p.y = FIXED_TO_FLOAT(temp) - vz;
// m is the v direction vector in view space // m is the v direction vector in view space
@ -881,9 +863,9 @@ static void R_SlopeVectors(visplane_t *pl, INT32 i, float fudge)
n.z = -cos(ang); n.z = -cos(ang);
ang = ANG2RAD(pl->plangle); ang = ANG2RAD(pl->plangle);
temp = P_GetZAt(pl->slope, pl->viewx + FLOAT_TO_FIXED(sin(ang)), pl->viewy + FLOAT_TO_FIXED(cos(ang))); temp = P_GetSlopeZAt(pl->slope, pl->viewx + FLOAT_TO_FIXED(sin(ang)), pl->viewy + FLOAT_TO_FIXED(cos(ang)));
m.y = FIXED_TO_FLOAT(temp) - zeroheight; m.y = FIXED_TO_FLOAT(temp) - zeroheight;
temp = P_GetZAt(pl->slope, pl->viewx + FLOAT_TO_FIXED(cos(ang)), pl->viewy - FLOAT_TO_FIXED(sin(ang))); temp = P_GetSlopeZAt(pl->slope, pl->viewx + FLOAT_TO_FIXED(cos(ang)), pl->viewy - FLOAT_TO_FIXED(sin(ang)));
n.y = FIXED_TO_FLOAT(temp) - zeroheight; n.y = FIXED_TO_FLOAT(temp) - zeroheight;
if (ds_powersoftwo) if (ds_powersoftwo)
@ -961,7 +943,6 @@ void R_DrawSinglePlane(visplane_t *pl)
#endif #endif
spanfunc = spanfuncs[BASEDRAWFUNC]; spanfunc = spanfuncs[BASEDRAWFUNC];
#ifdef POLYOBJECTS_PLANES
if (pl->polyobj && pl->polyobj->translucency != 0) if (pl->polyobj && pl->polyobj->translucency != 0)
{ {
spanfunctype = SPANDRAWFUNC_TRANS; spanfunctype = SPANDRAWFUNC_TRANS;
@ -979,95 +960,98 @@ void R_DrawSinglePlane(visplane_t *pl)
else else
light = LIGHTLEVELS-1; light = LIGHTLEVELS-1;
} else }
#endif else
if (pl->ffloor)
{ {
// Don't draw planes that shouldn't be drawn. if (pl->ffloor)
for (rover = pl->ffloor->target->ffloors; rover; rover = rover->next)
{ {
if ((pl->ffloor->flags & FF_CUTEXTRA) && (rover->flags & FF_EXTRA)) // Don't draw planes that shouldn't be drawn.
for (rover = pl->ffloor->target->ffloors; rover; rover = rover->next)
{ {
if (pl->ffloor->flags & FF_EXTRA) if ((pl->ffloor->flags & FF_CUTEXTRA) && (rover->flags & FF_EXTRA))
{ {
// The plane is from an extra 3D floor... Check the flags so if (pl->ffloor->flags & FF_EXTRA)
// there are no undesired cuts. {
if (((pl->ffloor->flags & (FF_FOG|FF_SWIMMABLE)) == (rover->flags & (FF_FOG|FF_SWIMMABLE))) // The plane is from an extra 3D floor... Check the flags so
&& pl->height < *rover->topheight // there are no undesired cuts.
&& pl->height > *rover->bottomheight) if (((pl->ffloor->flags & (FF_FOG|FF_SWIMMABLE)) == (rover->flags & (FF_FOG|FF_SWIMMABLE)))
return; && pl->height < *rover->topheight
&& pl->height > *rover->bottomheight)
return;
}
} }
} }
}
if (pl->ffloor->flags & FF_TRANSLUCENT) if (pl->ffloor->flags & FF_TRANSLUCENT)
{
spanfunctype = SPANDRAWFUNC_TRANS;
// Hacked up support for alpha value in software mode Tails 09-24-2002
if (pl->ffloor->alpha < 12)
return; // Don't even draw it
else if (pl->ffloor->alpha < 38)
ds_transmap = transtables + ((tr_trans90-1)<<FF_TRANSSHIFT);
else if (pl->ffloor->alpha < 64)
ds_transmap = transtables + ((tr_trans80-1)<<FF_TRANSSHIFT);
else if (pl->ffloor->alpha < 89)
ds_transmap = transtables + ((tr_trans70-1)<<FF_TRANSSHIFT);
else if (pl->ffloor->alpha < 115)
ds_transmap = transtables + ((tr_trans60-1)<<FF_TRANSSHIFT);
else if (pl->ffloor->alpha < 140)
ds_transmap = transtables + ((tr_trans50-1)<<FF_TRANSSHIFT);
else if (pl->ffloor->alpha < 166)
ds_transmap = transtables + ((tr_trans40-1)<<FF_TRANSSHIFT);
else if (pl->ffloor->alpha < 192)
ds_transmap = transtables + ((tr_trans30-1)<<FF_TRANSSHIFT);
else if (pl->ffloor->alpha < 217)
ds_transmap = transtables + ((tr_trans20-1)<<FF_TRANSSHIFT);
else if (pl->ffloor->alpha < 243)
ds_transmap = transtables + ((tr_trans10-1)<<FF_TRANSSHIFT);
else // Opaque, but allow transparent flat pixels
spanfunctype = SPANDRAWFUNC_SPLAT;
if ((spanfunctype == SPANDRAWFUNC_SPLAT) || (pl->extra_colormap && (pl->extra_colormap->flags & CMF_FOG)))
light = (pl->lightlevel >> LIGHTSEGSHIFT);
else
light = LIGHTLEVELS-1;
}
else if (pl->ffloor->flags & FF_FOG)
{
spanfunctype = SPANDRAWFUNC_FOG;
light = (pl->lightlevel >> LIGHTSEGSHIFT);
}
else light = (pl->lightlevel >> LIGHTSEGSHIFT);
#ifndef NOWATER
if (pl->ffloor->flags & FF_RIPPLE)
{
INT32 top, bottom;
itswater = true;
if (spanfunctype == SPANDRAWFUNC_TRANS)
{ {
spanfunctype = SPANDRAWFUNC_WATER; spanfunctype = SPANDRAWFUNC_TRANS;
// Copy the current scene, ugh // Hacked up support for alpha value in software mode Tails 09-24-2002
top = pl->high-8; if (pl->ffloor->alpha < 12)
bottom = pl->low+8; return; // Don't even draw it
else if (pl->ffloor->alpha < 38)
ds_transmap = transtables + ((tr_trans90-1)<<FF_TRANSSHIFT);
else if (pl->ffloor->alpha < 64)
ds_transmap = transtables + ((tr_trans80-1)<<FF_TRANSSHIFT);
else if (pl->ffloor->alpha < 89)
ds_transmap = transtables + ((tr_trans70-1)<<FF_TRANSSHIFT);
else if (pl->ffloor->alpha < 115)
ds_transmap = transtables + ((tr_trans60-1)<<FF_TRANSSHIFT);
else if (pl->ffloor->alpha < 140)
ds_transmap = transtables + ((tr_trans50-1)<<FF_TRANSSHIFT);
else if (pl->ffloor->alpha < 166)
ds_transmap = transtables + ((tr_trans40-1)<<FF_TRANSSHIFT);
else if (pl->ffloor->alpha < 192)
ds_transmap = transtables + ((tr_trans30-1)<<FF_TRANSSHIFT);
else if (pl->ffloor->alpha < 217)
ds_transmap = transtables + ((tr_trans20-1)<<FF_TRANSSHIFT);
else if (pl->ffloor->alpha < 243)
ds_transmap = transtables + ((tr_trans10-1)<<FF_TRANSSHIFT);
else // Opaque, but allow transparent flat pixels
spanfunctype = SPANDRAWFUNC_SPLAT;
if (top < 0) if ((spanfunctype == SPANDRAWFUNC_SPLAT) || (pl->extra_colormap && (pl->extra_colormap->flags & CMF_FOG)))
top = 0; light = (pl->lightlevel >> LIGHTSEGSHIFT);
if (bottom > vid.height) else
bottom = vid.height; light = LIGHTLEVELS-1;
// Only copy the part of the screen we need
VID_BlitLinearScreen((splitscreen && viewplayer == &players[secondarydisplayplayer]) ? screens[0] + (top+(vid.height>>1))*vid.width : screens[0]+((top)*vid.width), screens[1]+((top)*vid.width),
vid.width, bottom-top,
vid.width, vid.width);
} }
else if (pl->ffloor->flags & FF_FOG)
{
spanfunctype = SPANDRAWFUNC_FOG;
light = (pl->lightlevel >> LIGHTSEGSHIFT);
}
else light = (pl->lightlevel >> LIGHTSEGSHIFT);
#ifndef NOWATER
if (pl->ffloor->flags & FF_RIPPLE)
{
INT32 top, bottom;
itswater = true;
if (spanfunctype == SPANDRAWFUNC_TRANS)
{
spanfunctype = SPANDRAWFUNC_WATER;
// Copy the current scene, ugh
top = pl->high-8;
bottom = pl->low+8;
if (top < 0)
top = 0;
if (bottom > vid.height)
bottom = vid.height;
// Only copy the part of the screen we need
VID_BlitLinearScreen((splitscreen && viewplayer == &players[secondarydisplayplayer]) ? screens[0] + (top+(vid.height>>1))*vid.width : screens[0]+((top)*vid.width), screens[1]+((top)*vid.width),
vid.width, bottom-top,
vid.width, vid.width);
}
}
#endif
} }
#endif else
light = (pl->lightlevel >> LIGHTSEGSHIFT);
} }
else light = (pl->lightlevel >> LIGHTSEGSHIFT);
if (!pl->slope // Don't mess with angle on slopes! We'll handle this ourselves later if (!pl->slope // Don't mess with angle on slopes! We'll handle this ourselves later
&& viewangle != pl->viewangle+pl->plangle) && viewangle != pl->viewangle+pl->plangle)
@ -1193,7 +1177,7 @@ void R_DrawSinglePlane(visplane_t *pl)
if (itswater) if (itswater)
{ {
INT32 i; INT32 i;
fixed_t plheight = abs(P_GetZAt(pl->slope, pl->viewx, pl->viewy) - pl->viewz); fixed_t plheight = abs(P_GetSlopeZAt(pl->slope, pl->viewx, pl->viewy) - pl->viewz);
fixed_t rxoffs = xoffs; fixed_t rxoffs = xoffs;
fixed_t ryoffs = yoffs; fixed_t ryoffs = yoffs;

View File

@ -47,9 +47,7 @@ typedef struct visplane_s
fixed_t xoffs, yoffs; // Scrolling flats. fixed_t xoffs, yoffs; // Scrolling flats.
struct ffloor_s *ffloor; struct ffloor_s *ffloor;
#ifdef POLYOBJECTS_PLANES
polyobj_t *polyobj; polyobj_t *polyobj;
#endif
pslope_t *slope; pslope_t *slope;
} visplane_t; } visplane_t;
@ -80,11 +78,7 @@ void R_MapPlane(INT32 y, INT32 x1, INT32 x2);
void R_MakeSpans(INT32 x, INT32 t1, INT32 b1, INT32 t2, INT32 b2); void R_MakeSpans(INT32 x, INT32 t1, INT32 b1, INT32 t2, INT32 b2);
void R_DrawPlanes(void); void R_DrawPlanes(void);
visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, fixed_t xoff, fixed_t yoff, angle_t plangle, visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, fixed_t xoff, fixed_t yoff, angle_t plangle,
extracolormap_t *planecolormap, ffloor_t *ffloor extracolormap_t *planecolormap, ffloor_t *ffloor, polyobj_t *polyobj, pslope_t *slope);
#ifdef POLYOBJECTS_PLANES
, polyobj_t *polyobj
#endif
, pslope_t *slope);
visplane_t *R_CheckPlane(visplane_t *pl, INT32 start, INT32 stop); visplane_t *R_CheckPlane(visplane_t *pl, INT32 start, INT32 stop);
void R_ExpandPlane(visplane_t *pl, INT32 start, INT32 stop); void R_ExpandPlane(visplane_t *pl, INT32 start, INT32 stop);
void R_PlaneBounds(visplane_t *plane); void R_PlaneBounds(visplane_t *plane);
@ -112,9 +106,7 @@ typedef struct planemgr_s
struct pslope_s *slope; struct pslope_s *slope;
struct ffloor_s *ffloor; struct ffloor_s *ffloor;
#ifdef POLYOBJECTS_PLANES
polyobj_t *polyobj; polyobj_t *polyobj;
#endif
} visffloor_t; } visffloor_t;
extern visffloor_t ffloor[MAXFFLOORS]; extern visffloor_t ffloor[MAXFFLOORS];

View File

@ -376,16 +376,13 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
fixed_t leftheight, rightheight; fixed_t leftheight, rightheight;
light = &frontsector->lightlist[i]; light = &frontsector->lightlist[i];
rlight = &dc_lightlist[i]; rlight = &dc_lightlist[i];
if (light->slope) { leftheight = P_GetLightZAt(light, ds-> leftpos.x, ds-> leftpos.y);
leftheight = P_GetZAt(light->slope, ds->leftpos.x, ds->leftpos.y); rightheight = P_GetLightZAt(light, ds->rightpos.x, ds->rightpos.y);
rightheight = P_GetZAt(light->slope, ds->rightpos.x, ds->rightpos.y);
} else
leftheight = rightheight = light->height;
leftheight -= viewz; leftheight -= viewz;
rightheight -= viewz; rightheight -= viewz;
rlight->height = (centeryfrac) - FixedMul(leftheight, ds->scale1); rlight->height = (centeryfrac) - FixedMul(leftheight , ds->scale1);
rlight->heightstep = (centeryfrac) - FixedMul(rightheight, ds->scale2); rlight->heightstep = (centeryfrac) - FixedMul(rightheight, ds->scale2);
rlight->heightstep = (rlight->heightstep-rlight->height)/(range); rlight->heightstep = (rlight->heightstep-rlight->height)/(range);
//if (x1 > ds->x1) //if (x1 > ds->x1)
@ -610,7 +607,6 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
// draw the texture // draw the texture
col = (column_t *)((UINT8 *)R_GetColumn(texnum, maskedtexturecol[dc_x]) - 3); col = (column_t *)((UINT8 *)R_GetColumn(texnum, maskedtexturecol[dc_x]) - 3);
//#ifdef POLYOBJECTS_PLANES
#if 0 // Disabling this allows inside edges to render below the planes, for until the clipping is fixed to work right when POs are near the camera. -Red #if 0 // Disabling this allows inside edges to render below the planes, for until the clipping is fixed to work right when POs are near the camera. -Red
if (curline->dontrenderme && curline->polyseg && (curline->polyseg->flags & POF_RENDERPLANES)) if (curline->dontrenderme && curline->polyseg && (curline->polyseg->flags & POF_RENDERPLANES))
{ {
@ -800,11 +796,8 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
rlight = &dc_lightlist[p]; rlight = &dc_lightlist[p];
#define SLOPEPARAMS(slope, end1, end2, normalheight) \ #define SLOPEPARAMS(slope, end1, end2, normalheight) \
if (slope) { \ end1 = P_GetZAt(slope, ds-> leftpos.x, ds-> leftpos.y, normalheight); \
end1 = P_GetZAt(slope, ds->leftpos.x, ds->leftpos.y); \ end2 = P_GetZAt(slope, ds->rightpos.x, ds->rightpos.y, normalheight);
end2 = P_GetZAt(slope, ds->rightpos.x, ds->rightpos.y); \
} else \
end1 = end2 = normalheight;
SLOPEPARAMS(light->slope, leftheight, rightheight, light->height) SLOPEPARAMS(light->slope, leftheight, rightheight, light->height)
SLOPEPARAMS(*pfloor->b_slope, pfloorleft, pfloorright, *pfloor->bottomheight) SLOPEPARAMS(*pfloor->b_slope, pfloorleft, pfloorright, *pfloor->bottomheight)
@ -817,8 +810,8 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
if (leftheight > pfloorleft && rightheight > pfloorright && i+1 < dc_numlights) if (leftheight > pfloorleft && rightheight > pfloorright && i+1 < dc_numlights)
{ {
lightlist_t *nextlight = &frontsector->lightlist[i+1]; lightlist_t *nextlight = &frontsector->lightlist[i+1];
if ((nextlight->slope ? P_GetZAt(nextlight->slope, ds->leftpos.x, ds->leftpos.y) : nextlight->height) > pfloorleft if (P_GetZAt(nextlight->slope, ds-> leftpos.x, ds-> leftpos.y, nextlight->height) > pfloorleft
&& (nextlight->slope ? P_GetZAt(nextlight->slope, ds->rightpos.x, ds->rightpos.y) : nextlight->height) > pfloorright) && P_GetZAt(nextlight->slope, ds->rightpos.x, ds->rightpos.y, nextlight->height) > pfloorright)
continue; continue;
} }
@ -914,15 +907,9 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
dc_texheight = textureheight[texnum]>>FRACBITS; dc_texheight = textureheight[texnum]>>FRACBITS;
// calculate both left ends // calculate both left ends
if (*pfloor->t_slope) left_top = P_GetFFloorTopZAt (pfloor, ds->leftpos.x, ds->leftpos.y) - viewz;
left_top = P_GetZAt(*pfloor->t_slope, ds->leftpos.x, ds->leftpos.y) - viewz; left_bottom = P_GetFFloorBottomZAt(pfloor, ds->leftpos.x, ds->leftpos.y) - viewz;
else
left_top = *pfloor->topheight - viewz;
if (*pfloor->b_slope)
left_bottom = P_GetZAt(*pfloor->b_slope, ds->leftpos.x, ds->leftpos.y) - viewz;
else
left_bottom = *pfloor->bottomheight - viewz;
skewslope = *pfloor->t_slope; // skew using top slope by default skewslope = *pfloor->t_slope; // skew using top slope by default
if (newline) if (newline)
{ {
@ -998,15 +985,8 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
fixed_t right_top, right_bottom; fixed_t right_top, right_bottom;
// calculate right ends now // calculate right ends now
if (*pfloor->t_slope) right_top = P_GetFFloorTopZAt (pfloor, ds->rightpos.x, ds->rightpos.y) - viewz;
right_top = P_GetZAt(*pfloor->t_slope, ds->rightpos.x, ds->rightpos.y) - viewz; right_bottom = P_GetFFloorBottomZAt(pfloor, ds->rightpos.x, ds->rightpos.y) - viewz;
else
right_top = *pfloor->topheight - viewz;
if (*pfloor->b_slope)
right_bottom = P_GetZAt(*pfloor->b_slope, ds->rightpos.x, ds->rightpos.y) - viewz;
else
right_bottom = *pfloor->bottomheight - viewz;
// using INT64 to avoid 32bit overflow // using INT64 to avoid 32bit overflow
top_frac = (INT64)centeryfrac - (((INT64)left_top * ds->scale1) >> FRACBITS); top_frac = (INT64)centeryfrac - (((INT64)left_top * ds->scale1) >> FRACBITS);
@ -1309,10 +1289,8 @@ static void R_RenderSegLoop (void)
for (i = 0; i < numffloors; i++) for (i = 0; i < numffloors; i++)
{ {
#ifdef POLYOBJECTS_PLANES
if (ffloor[i].polyobj && (!curline->polyseg || ffloor[i].polyobj != curline->polyseg)) if (ffloor[i].polyobj && (!curline->polyseg || ffloor[i].polyobj != curline->polyseg))
continue; continue;
#endif
if (ffloor[i].height < viewz) if (ffloor[i].height < viewz)
{ {
@ -1325,18 +1303,19 @@ static void R_RenderSegLoop (void)
if (bottom_w > bottom) if (bottom_w > bottom)
bottom_w = bottom; bottom_w = bottom;
#ifdef POLYOBJECTS_PLANES
// Polyobject-specific hack to fix plane leaking -Red // Polyobject-specific hack to fix plane leaking -Red
if (ffloor[i].polyobj && top_w >= bottom_w) { if (ffloor[i].polyobj && top_w >= bottom_w)
{
ffloor[i].plane->top[rw_x] = 0xFFFF; ffloor[i].plane->top[rw_x] = 0xFFFF;
ffloor[i].plane->bottom[rw_x] = 0x0000; // fix for sky plane drawing crashes - Monster Iestyn 25/05/18 ffloor[i].plane->bottom[rw_x] = 0x0000; // fix for sky plane drawing crashes - Monster Iestyn 25/05/18
} else }
#endif else
if (top_w <= bottom_w)
{ {
ffloor[i].plane->top[rw_x] = (INT16)top_w; if (top_w <= bottom_w)
ffloor[i].plane->bottom[rw_x] = (INT16)bottom_w; {
ffloor[i].plane->top[rw_x] = (INT16)top_w;
ffloor[i].plane->bottom[rw_x] = (INT16)bottom_w;
}
} }
} }
else if (ffloor[i].height > viewz) else if (ffloor[i].height > viewz)
@ -1350,18 +1329,19 @@ static void R_RenderSegLoop (void)
if (bottom_w > bottom) if (bottom_w > bottom)
bottom_w = bottom; bottom_w = bottom;
#ifdef POLYOBJECTS_PLANES
// Polyobject-specific hack to fix plane leaking -Red // Polyobject-specific hack to fix plane leaking -Red
if (ffloor[i].polyobj && top_w >= bottom_w) { if (ffloor[i].polyobj && top_w >= bottom_w)
{
ffloor[i].plane->top[rw_x] = 0xFFFF; ffloor[i].plane->top[rw_x] = 0xFFFF;
ffloor[i].plane->bottom[rw_x] = 0x0000; // fix for sky plane drawing crashes - Monster Iestyn 25/05/18 ffloor[i].plane->bottom[rw_x] = 0x0000; // fix for sky plane drawing crashes - Monster Iestyn 25/05/18
} else }
#endif else
if (top_w <= bottom_w)
{ {
ffloor[i].plane->top[rw_x] = (INT16)top_w; if (top_w <= bottom_w)
ffloor[i].plane->bottom[rw_x] = (INT16)bottom_w; {
ffloor[i].plane->top[rw_x] = (INT16)top_w;
ffloor[i].plane->bottom[rw_x] = (INT16)bottom_w;
}
} }
} }
} }
@ -1788,11 +1768,8 @@ void R_StoreWallRange(INT32 start, INT32 stop)
#define SLOPEPARAMS(slope, end1, end2, normalheight) \ #define SLOPEPARAMS(slope, end1, end2, normalheight) \
if (slope) { \ end1 = P_GetZAt(slope, segleft.x, segleft.y, normalheight); \
end1 = P_GetZAt(slope, segleft.x, segleft.y); \ end2 = P_GetZAt(slope, segright.x, segright.y, normalheight);
end2 = P_GetZAt(slope, segright.x, segright.y); \
} else \
end1 = end2 = normalheight;
SLOPEPARAMS(frontsector->c_slope, worldtop, worldtopslope, frontsector->ceilingheight) SLOPEPARAMS(frontsector->c_slope, worldtop, worldtopslope, frontsector->ceilingheight)
SLOPEPARAMS(frontsector->f_slope, worldbottom, worldbottomslope, frontsector->floorheight) SLOPEPARAMS(frontsector->f_slope, worldbottom, worldbottomslope, frontsector->floorheight)
@ -1818,17 +1795,11 @@ void R_StoreWallRange(INT32 start, INT32 stop)
{ {
for (i = 0; i < numffloors; i++) for (i = 0; i < numffloors; i++)
{ {
#ifdef POLYOBJECTS_PLANES
if (ffloor[i].polyobj && (!ds_p->curline->polyseg || ffloor[i].polyobj != ds_p->curline->polyseg)) if (ffloor[i].polyobj && (!ds_p->curline->polyseg || ffloor[i].polyobj != ds_p->curline->polyseg))
continue; continue;
#endif
if (ffloor[i].slope) { ffloor[i].f_pos = P_GetZAt(ffloor[i].slope, segleft .x, segleft .y, ffloor[i].height) - viewz;
ffloor[i].f_pos = P_GetZAt(ffloor[i].slope, segleft.x, segleft.y) - viewz; ffloor[i].f_pos_slope = P_GetZAt(ffloor[i].slope, segright.x, segright.y, ffloor[i].height) - viewz;
ffloor[i].f_pos_slope = P_GetZAt(ffloor[i].slope, segright.x, segright.y) - viewz;
}
else
ffloor[i].f_pos_slope = ffloor[i].f_pos = ffloor[i].height - viewz;
} }
} }
@ -1921,12 +1892,12 @@ void R_StoreWallRange(INT32 start, INT32 stop)
if (worldbottomslope > worldlowslope || worldbottom > worldlow) if (worldbottomslope > worldlowslope || worldbottom > worldlow)
{ {
ds_p->silhouette = SIL_BOTTOM; ds_p->silhouette = SIL_BOTTOM;
if ((backsector->f_slope ? P_GetZAt(backsector->f_slope, viewx, viewy) : backsector->floorheight) > viewz) if (P_GetSectorFloorZAt(backsector, viewx, viewy) > viewz)
ds_p->bsilheight = INT32_MAX; ds_p->bsilheight = INT32_MAX;
else else
ds_p->bsilheight = (frontsector->f_slope ? INT32_MAX : frontsector->floorheight); ds_p->bsilheight = (frontsector->f_slope ? INT32_MAX : frontsector->floorheight);
} }
else if ((backsector->f_slope ? P_GetZAt(backsector->f_slope, viewx, viewy) : backsector->floorheight) > viewz) else if (P_GetSectorFloorZAt(backsector, viewx, viewy) > viewz)
{ {
ds_p->silhouette = SIL_BOTTOM; ds_p->silhouette = SIL_BOTTOM;
ds_p->bsilheight = INT32_MAX; ds_p->bsilheight = INT32_MAX;
@ -1939,12 +1910,12 @@ void R_StoreWallRange(INT32 start, INT32 stop)
if (worldtopslope < worldhighslope || worldtop < worldhigh) if (worldtopslope < worldhighslope || worldtop < worldhigh)
{ {
ds_p->silhouette |= SIL_TOP; ds_p->silhouette |= SIL_TOP;
if ((backsector->c_slope ? P_GetZAt(backsector->c_slope, viewx, viewy) : backsector->ceilingheight) < viewz) if (P_GetSectorCeilingZAt(backsector, viewx, viewy) < viewz)
ds_p->tsilheight = INT32_MIN; ds_p->tsilheight = INT32_MIN;
else else
ds_p->tsilheight = (frontsector->c_slope ? INT32_MIN : frontsector->ceilingheight); ds_p->tsilheight = (frontsector->c_slope ? INT32_MIN : frontsector->ceilingheight);
} }
else if ((backsector->c_slope ? P_GetZAt(backsector->c_slope, viewx, viewy) : backsector->ceilingheight) < viewz) else if (P_GetSectorCeilingZAt(backsector, viewx, viewy) < viewz)
{ {
ds_p->silhouette |= SIL_TOP; ds_p->silhouette |= SIL_TOP;
ds_p->tsilheight = INT32_MIN; ds_p->tsilheight = INT32_MIN;
@ -2275,10 +2246,10 @@ void R_StoreWallRange(INT32 start, INT32 stop)
continue; continue;
// Oy vey. // Oy vey.
if ( ((*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft .x, segleft .y) : *rover-> topheight) <= worldbottom + viewz if ( ((P_GetFFloorTopZAt (rover, segleft .x, segleft .y)) <= worldbottom + viewz
&& (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover-> topheight) <= worldbottomslope + viewz) && (P_GetFFloorTopZAt (rover, segright.x, segright.y)) <= worldbottomslope + viewz)
||((*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft .x, segleft .y) : *rover->bottomheight) >= worldtop + viewz ||((P_GetFFloorBottomZAt(rover, segleft .x, segleft .y)) >= worldtop + viewz
&& (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) >= worldtopslope + viewz)) && (P_GetFFloorBottomZAt(rover, segright.x, segright.y)) >= worldtopslope + viewz))
continue; continue;
ds_p->thicksides[i] = rover; ds_p->thicksides[i] = rover;
@ -2296,16 +2267,16 @@ void R_StoreWallRange(INT32 start, INT32 stop)
if (rover->norender == leveltime) if (rover->norender == leveltime)
continue; continue;
// Oy vey. // Oy vey.
if ( ((*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft .x, segleft .y) : *rover-> topheight) <= worldbottom + viewz if ( (P_GetFFloorTopZAt (rover, segleft .x, segleft .y) <= worldbottom + viewz
&& (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover-> topheight) <= worldbottomslope + viewz) && P_GetFFloorTopZAt (rover, segright.x, segright.y) <= worldbottomslope + viewz)
||((*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft .x, segleft .y) : *rover->bottomheight) >= worldtop + viewz ||(P_GetFFloorBottomZAt(rover, segleft .x, segleft .y) >= worldtop + viewz
&& (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) >= worldtopslope + viewz)) && P_GetFFloorBottomZAt(rover, segright.x, segright.y) >= worldtopslope + viewz))
continue; continue;
if ( ((*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft .x, segleft .y) : *rover-> topheight) <= worldlow + viewz if ( (P_GetFFloorTopZAt (rover, segleft .x, segleft .y) <= worldlow + viewz
&& (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover-> topheight) <= worldlowslope + viewz) && P_GetFFloorTopZAt (rover, segright.x, segright.y) <= worldlowslope + viewz)
||((*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft .x, segleft .y) : *rover->bottomheight) >= worldhigh + viewz ||(P_GetFFloorBottomZAt(rover, segleft .x, segleft .y) >= worldhigh + viewz
&& (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) >= worldhighslope + viewz)) && P_GetFFloorBottomZAt(rover, segright.x, segright.y) >= worldhighslope + viewz))
continue; continue;
ds_p->thicksides[i] = rover; ds_p->thicksides[i] = rover;
@ -2328,33 +2299,40 @@ void R_StoreWallRange(INT32 start, INT32 stop)
maskedtextureheight = ds_p->maskedtextureheight; // note to red, this == &(ds_p->maskedtextureheight[0]) maskedtextureheight = ds_p->maskedtextureheight; // note to red, this == &(ds_p->maskedtextureheight[0])
#ifdef POLYOBJECTS if (curline->polyseg)
if (curline->polyseg) { // use REAL front and back floors please, so midtexture rendering isn't mucked up { // use REAL front and back floors please, so midtexture rendering isn't mucked up
rw_midtextureslide = rw_midtexturebackslide = 0; rw_midtextureslide = rw_midtexturebackslide = 0;
if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3))
rw_midtexturemid = rw_midtextureback = max(curline->frontsector->floorheight, curline->backsector->floorheight) - viewz; rw_midtexturemid = rw_midtextureback = max(curline->frontsector->floorheight, curline->backsector->floorheight) - viewz;
else else
rw_midtexturemid = rw_midtextureback = min(curline->frontsector->ceilingheight, curline->backsector->ceilingheight) - viewz; rw_midtexturemid = rw_midtextureback = min(curline->frontsector->ceilingheight, curline->backsector->ceilingheight) - viewz;
} else }
#endif else
// Set midtexture starting height {
if (linedef->flags & ML_EFFECT2) { // Ignore slopes when texturing // Set midtexture starting height
rw_midtextureslide = rw_midtexturebackslide = 0; if (linedef->flags & ML_EFFECT2)
if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) { // Ignore slopes when texturing
rw_midtexturemid = rw_midtextureback = max(frontsector->floorheight, backsector->floorheight) - viewz; rw_midtextureslide = rw_midtexturebackslide = 0;
else if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3))
rw_midtexturemid = rw_midtextureback = min(frontsector->ceilingheight, backsector->ceilingheight) - viewz; rw_midtexturemid = rw_midtextureback = max(frontsector->floorheight, backsector->floorheight) - viewz;
else
rw_midtexturemid = rw_midtextureback = min(frontsector->ceilingheight, backsector->ceilingheight) - viewz;
} else if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) { }
rw_midtexturemid = worldbottom; else if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3))
rw_midtextureslide = floorfrontslide; {
rw_midtextureback = worldlow; rw_midtexturemid = worldbottom;
rw_midtexturebackslide = floorbackslide; rw_midtextureslide = floorfrontslide;
} else { rw_midtextureback = worldlow;
rw_midtexturemid = worldtop; rw_midtexturebackslide = floorbackslide;
rw_midtextureslide = ceilingfrontslide; }
rw_midtextureback = worldhigh; else
rw_midtexturebackslide = ceilingbackslide; {
rw_midtexturemid = worldtop;
rw_midtextureslide = ceilingfrontslide;
rw_midtextureback = worldhigh;
rw_midtexturebackslide = ceilingbackslide;
}
} }
rw_midtexturemid += sidedef->rowoffset; rw_midtexturemid += sidedef->rowoffset;
rw_midtextureback += sidedef->rowoffset; rw_midtextureback += sidedef->rowoffset;
@ -2421,17 +2399,13 @@ void R_StoreWallRange(INT32 start, INT32 stop)
// and doesn't need to be marked. // and doesn't need to be marked.
if (frontsector->heightsec == -1) if (frontsector->heightsec == -1)
{ {
if (frontsector->floorpic != skyflatnum && (frontsector->f_slope ? if (frontsector->floorpic != skyflatnum && P_GetSectorFloorZAt(frontsector, viewx, viewy) >= viewz)
P_GetZAt(frontsector->f_slope, viewx, viewy) :
frontsector->floorheight) >= viewz)
{ {
// above view plane // above view plane
markfloor = false; markfloor = false;
} }
if (frontsector->ceilingpic != skyflatnum && (frontsector->c_slope ? if (frontsector->ceilingpic != skyflatnum && P_GetSectorCeilingZAt(frontsector, viewx, viewy) <= viewz)
P_GetZAt(frontsector->c_slope, viewx, viewy) :
frontsector->ceilingheight) <= viewz)
{ {
// below view plane // below view plane
markceiling = false; markceiling = false;
@ -2483,14 +2457,12 @@ void R_StoreWallRange(INT32 start, INT32 stop)
light = &frontsector->lightlist[i]; light = &frontsector->lightlist[i];
rlight = &dc_lightlist[p]; rlight = &dc_lightlist[p];
if (light->slope) { leftheight = P_GetLightZAt(light, segleft.x, segleft.y);
leftheight = P_GetZAt(light->slope, segleft.x, segleft.y); rightheight = P_GetLightZAt(light, segright.x, segright.y);
rightheight = P_GetZAt(light->slope, segright.x, segright.y);
if (light->slope)
// Flag sector as having slopes // Flag sector as having slopes
frontsector->hasslope = true; frontsector->hasslope = true;
} else
leftheight = rightheight = light->height;
leftheight -= viewz; leftheight -= viewz;
rightheight -= viewz; rightheight -= viewz;
@ -2514,19 +2486,17 @@ void R_StoreWallRange(INT32 start, INT32 stop)
if (light->caster && light->caster->flags & FF_CUTSOLIDS) if (light->caster && light->caster->flags & FF_CUTSOLIDS)
{ {
if (*light->caster->b_slope) { leftheight = P_GetFFloorBottomZAt(light->caster, segleft.x, segleft.y);
leftheight = P_GetZAt(*light->caster->b_slope, segleft.x, segleft.y); rightheight = P_GetFFloorBottomZAt(light->caster, segright.x, segright.y);
rightheight = P_GetZAt(*light->caster->b_slope, segright.x, segright.y);
if (*light->caster->b_slope)
// Flag sector as having slopes // Flag sector as having slopes
frontsector->hasslope = true; frontsector->hasslope = true;
} else
leftheight = rightheight = *light->caster->bottomheight;
leftheight -= viewz; leftheight -= viewz;
rightheight -= viewz; rightheight -= viewz;
leftheight >>= 4; leftheight >>= 4;
rightheight >>= 4; rightheight >>= 4;
rlight->botheight = (centeryfrac>>4) - FixedMul(leftheight, rw_scale); rlight->botheight = (centeryfrac>>4) - FixedMul(leftheight, rw_scale);
@ -2610,9 +2580,9 @@ void R_StoreWallRange(INT32 start, INT32 stop)
if (*rover->b_slope || *rover->t_slope) if (*rover->b_slope || *rover->t_slope)
backsector->hasslope = true; backsector->hasslope = true;
roverleft = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) - viewz; roverleft = P_GetFFloorBottomZAt(rover, segleft .x, segleft .y) - viewz;
roverright = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) - viewz; roverright = P_GetFFloorBottomZAt(rover, segright.x, segright.y) - viewz;
planevistest = (*rover->b_slope ? P_GetZAt(*rover->b_slope, viewx, viewy) : *rover->bottomheight); planevistest = P_GetFFloorBottomZAt(rover, viewx, viewy);
if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) && if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) &&
(roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) && (roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) &&
@ -2633,9 +2603,9 @@ void R_StoreWallRange(INT32 start, INT32 stop)
if (i >= MAXFFLOORS) if (i >= MAXFFLOORS)
break; break;
roverleft = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) - viewz; roverleft = P_GetFFloorTopZAt(rover, segleft .x, segleft .y) - viewz;
roverright = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover->topheight) - viewz; roverright = P_GetFFloorTopZAt(rover, segright.x, segright.y) - viewz;
planevistest = (*rover->t_slope ? P_GetZAt(*rover->t_slope, viewx, viewy) : *rover->topheight); planevistest = P_GetFFloorTopZAt(rover, viewx, viewy);
if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) && if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) &&
(roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) && (roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) &&
@ -2667,9 +2637,9 @@ void R_StoreWallRange(INT32 start, INT32 stop)
if (*rover->b_slope || *rover->t_slope) if (*rover->b_slope || *rover->t_slope)
frontsector->hasslope = true; frontsector->hasslope = true;
roverleft = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) - viewz; roverleft = P_GetFFloorBottomZAt(rover, segleft .x, segleft .y) - viewz;
roverright = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) - viewz; roverright = P_GetFFloorBottomZAt(rover, segright.x, segright.y) - viewz;
planevistest = (*rover->b_slope ? P_GetZAt(*rover->b_slope, viewx, viewy) : *rover->bottomheight); planevistest = P_GetFFloorBottomZAt(rover, viewx, viewy);
if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) && if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) &&
(roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) && (roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) &&
@ -2690,9 +2660,9 @@ void R_StoreWallRange(INT32 start, INT32 stop)
if (i >= MAXFFLOORS) if (i >= MAXFFLOORS)
break; break;
roverleft = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) - viewz; roverleft = P_GetFFloorTopZAt(rover, segleft .x, segleft .y) - viewz;
roverright = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover->topheight) - viewz; roverright = P_GetFFloorTopZAt(rover, segright.x, segright.y) - viewz;
planevistest = (*rover->t_slope ? P_GetZAt(*rover->t_slope, viewx, viewy) : *rover->topheight); planevistest = P_GetFFloorTopZAt(rover, viewx, viewy);
if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) && if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) &&
(roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) && (roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) &&
@ -2711,7 +2681,6 @@ void R_StoreWallRange(INT32 start, INT32 stop)
} }
} }
} }
#ifdef POLYOBJECTS_PLANES
if (curline->polyseg && frontsector && (curline->polyseg->flags & POF_RENDERPLANES)) if (curline->polyseg && frontsector && (curline->polyseg->flags & POF_RENDERPLANES))
{ {
while (i < numffloors && ffloor[i].polyobj != curline->polyseg) i++; while (i < numffloors && ffloor[i].polyobj != curline->polyseg) i++;
@ -2750,7 +2719,6 @@ void R_StoreWallRange(INT32 start, INT32 stop)
i++; i++;
} }
} }
#endif
numbackffloors = i; numbackffloors = i;
} }
@ -2804,7 +2772,6 @@ void R_StoreWallRange(INT32 start, INT32 stop)
for (i = 0; i < numffloors; i++) for (i = 0; i < numffloors; i++)
R_ExpandPlane(ffloor[i].plane, rw_x, rw_stopx - 1); R_ExpandPlane(ffloor[i].plane, rw_x, rw_stopx - 1);
} }
#ifdef POLYOBJECTS_PLANES
// FIXME hack to fix planes disappearing when a seg goes behind the camera. This NEEDS to be changed to be done properly. -Red // FIXME hack to fix planes disappearing when a seg goes behind the camera. This NEEDS to be changed to be done properly. -Red
if (curline->polyseg) if (curline->polyseg)
{ {
@ -2819,7 +2786,6 @@ void R_StoreWallRange(INT32 start, INT32 stop)
ffloor[i].plane->maxx = rw_stopx - 1; ffloor[i].plane->maxx = rw_stopx - 1;
} }
} }
#endif
} }
#ifdef WALLSPLATS #ifdef WALLSPLATS

View File

@ -248,7 +248,7 @@ void SetPlayerSkinByNum(INT32 playernum, INT32 skinnum)
{ {
player_t *player = &players[playernum]; player_t *player = &players[playernum];
skin_t *skin = &skins[skinnum]; skin_t *skin = &skins[skinnum];
UINT8 newcolor = 0; UINT16 newcolor = 0;
if (skinnum >= 0 && skinnum < numskins && R_SkinUsable(playernum, skinnum)) // Make sure it exists! if (skinnum >= 0 && skinnum < numskins && R_SkinUsable(playernum, skinnum)) // Make sure it exists!
{ {

View File

@ -65,9 +65,9 @@ typedef struct
// Definable color translation table // Definable color translation table
UINT8 starttranscolor; UINT8 starttranscolor;
UINT8 prefcolor; UINT16 prefcolor;
UINT8 supercolor; UINT16 supercolor;
UINT8 prefoppositecolor; // if 0 use tables instead UINT16 prefoppositecolor; // if 0 use tables instead
fixed_t highresscale; // scale of highres, default is 0.5 fixed_t highresscale; // scale of highres, default is 0.5
UINT8 contspeed; // continue screen animation speed UINT8 contspeed; // continue screen animation speed

View File

@ -888,7 +888,7 @@ static void R_DrawVisSprite(vissprite_t *vis)
vis->x2 = vid.width-1; vis->x2 = vid.width-1;
localcolfunc = (vis->cut & SC_VFLIP) ? R_DrawFlippedMaskedColumn : R_DrawMaskedColumn; localcolfunc = (vis->cut & SC_VFLIP) ? R_DrawFlippedMaskedColumn : R_DrawMaskedColumn;
lengthcol = patch->height; lengthcol = SHORT(patch->height);
// Split drawing loops for paper and non-paper to reduce conditional checks per sprite // Split drawing loops for paper and non-paper to reduce conditional checks per sprite
if (vis->scalestep) if (vis->scalestep)
@ -1019,13 +1019,12 @@ static void R_SplitSprite(vissprite_t *sprite)
for (i = 1; i < sector->numlights; i++) for (i = 1; i < sector->numlights; i++)
{ {
fixed_t testheight = sector->lightlist[i].height; fixed_t testheight;
if (!(sector->lightlist[i].caster->flags & FF_CUTSPRITES)) if (!(sector->lightlist[i].caster->flags & FF_CUTSPRITES))
continue; continue;
if (sector->lightlist[i].slope) testheight = P_GetLightZAt(&sector->lightlist[i], sprite->gx, sprite->gy);
testheight = P_GetZAt(sector->lightlist[i].slope, sprite->gx, sprite->gy);
if (testheight >= sprite->gzt) if (testheight >= sprite->gzt)
continue; continue;
@ -1107,10 +1106,12 @@ fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope)
{ {
sector = node->m_sector; sector = node->m_sector;
slope = (sector->heightsec != -1) ? NULL : sector->f_slope; slope = sector->heightsec != -1 ? NULL : sector->f_slope;
z = slope ? P_GetZAt(slope, thing->x, thing->y) : (
(sector->heightsec != -1) ? sectors[sector->heightsec].floorheight : sector->floorheight if (sector->heightsec != -1)
); z = sectors[sector->heightsec].floorheight;
else
z = P_GetSectorFloorZAt(sector, thing->x, thing->y);
if (z < thing->z+thing->height/2 && z > floorz) if (z < thing->z+thing->height/2 && z > floorz)
{ {
@ -1124,7 +1125,7 @@ fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope)
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERPLANES) || (rover->alpha < 90 && !(rover->flags & FF_SWIMMABLE))) if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERPLANES) || (rover->alpha < 90 && !(rover->flags & FF_SWIMMABLE)))
continue; continue;
z = *rover->t_slope ? P_GetZAt(*rover->t_slope, thing->x, thing->y) : *rover->topheight; z = P_GetFFloorTopZAt(rover, thing->x, thing->y);
if (z < thing->z+thing->height/2 && z > floorz) if (z < thing->z+thing->height/2 && z > floorz)
{ {
floorz = z; floorz = z;
@ -1140,7 +1141,6 @@ fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope)
} }
#if 0 // Unfortunately, this drops CEZ2 down to sub-17 FPS on my i7. #if 0 // Unfortunately, this drops CEZ2 down to sub-17 FPS on my i7.
//#ifdef POLYOBJECTS
// Check polyobjects and see if floorz needs to be altered, for rings only because they don't update floorz // Check polyobjects and see if floorz needs to be altered, for rings only because they don't update floorz
if (thing->type == MT_RING) if (thing->type == MT_RING)
{ {
@ -1231,8 +1231,8 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale,
yscale = FixedDiv(projectiony, tz); yscale = FixedDiv(projectiony, tz);
shadowxscale = FixedMul(thing->radius*2, scalemul); shadowxscale = FixedMul(thing->radius*2, scalemul);
shadowyscale = FixedMul(FixedMul(thing->radius*2, scalemul), FixedDiv(abs(floorz - viewz), tz)); shadowyscale = FixedMul(FixedMul(thing->radius*2, scalemul), FixedDiv(abs(floorz - viewz), tz));
shadowyscale = min(shadowyscale, shadowxscale) / patch->height; shadowyscale = min(shadowyscale, shadowxscale) / SHORT(patch->height);
shadowxscale /= patch->width; shadowxscale /= SHORT(patch->width);
shadowskew = 0; shadowskew = 0;
if (floorslope) if (floorslope)
@ -1247,24 +1247,24 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale,
//CONS_Printf("Shadow is sloped by %d %d\n", xslope, zslope); //CONS_Printf("Shadow is sloped by %d %d\n", xslope, zslope);
if (viewz < floorz) if (viewz < floorz)
shadowyscale += FixedMul(FixedMul(thing->radius*2 / patch->height, scalemul), zslope); shadowyscale += FixedMul(FixedMul(thing->radius*2 / SHORT(patch->height), scalemul), zslope);
else else
shadowyscale -= FixedMul(FixedMul(thing->radius*2 / patch->height, scalemul), zslope); shadowyscale -= FixedMul(FixedMul(thing->radius*2 / SHORT(patch->height), scalemul), zslope);
shadowyscale = abs(shadowyscale); shadowyscale = abs(shadowyscale);
shadowskew = xslope; shadowskew = xslope;
} }
tx -= patch->width * shadowxscale/2; tx -= SHORT(patch->width) * shadowxscale/2;
x1 = (centerxfrac + FixedMul(tx,xscale))>>FRACBITS; x1 = (centerxfrac + FixedMul(tx,xscale))>>FRACBITS;
if (x1 >= viewwidth) return; if (x1 >= viewwidth) return;
tx += patch->width * shadowxscale; tx += SHORT(patch->width) * shadowxscale;
x2 = ((centerxfrac + FixedMul(tx,xscale))>>FRACBITS); x2--; x2 = ((centerxfrac + FixedMul(tx,xscale))>>FRACBITS); x2--;
if (x2 < 0 || x2 <= x1) return; if (x2 < 0 || x2 <= x1) return;
if (shadowyscale < FRACUNIT/patch->height) return; // fix some crashes? if (shadowyscale < FRACUNIT/SHORT(patch->height)) return; // fix some crashes?
shadow = R_NewVisSprite(); shadow = R_NewVisSprite();
shadow->patch = patch; shadow->patch = patch;
@ -1279,8 +1279,8 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale,
shadow->dispoffset = vis->dispoffset - 5; shadow->dispoffset = vis->dispoffset - 5;
shadow->gx = thing->x; shadow->gx = thing->x;
shadow->gy = thing->y; shadow->gy = thing->y;
shadow->gzt = shadow->pz + shadow->patch->height * shadowyscale / 2; shadow->gzt = shadow->pz + SHORT(patch->height) * shadowyscale / 2;
shadow->gz = shadow->gzt - shadow->patch->height * shadowyscale; shadow->gz = shadow->gzt - SHORT(patch->height) * shadowyscale;
shadow->texturemid = FixedMul(thing->scale, FixedDiv(shadow->gzt - viewz, shadowyscale)); shadow->texturemid = FixedMul(thing->scale, FixedDiv(shadow->gzt - viewz, shadowyscale));
if (thing->skin && ((skin_t *)thing->skin)->flags & SF_HIRES) if (thing->skin && ((skin_t *)thing->skin)->flags & SF_HIRES)
shadow->texturemid = FixedMul(shadow->texturemid, ((skin_t *)thing->skin)->highresscale); shadow->texturemid = FixedMul(shadow->texturemid, ((skin_t *)thing->skin)->highresscale);
@ -1301,7 +1301,7 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale,
shadow->startfrac = 0; shadow->startfrac = 0;
//shadow->xiscale = 0x7ffffff0 / (shadow->xscale/2); //shadow->xiscale = 0x7ffffff0 / (shadow->xscale/2);
shadow->xiscale = (patch->width<<FRACBITS)/(x2-x1+1); // fuck it shadow->xiscale = (SHORT(patch->width)<<FRACBITS)/(x2-x1+1); // fuck it
if (shadow->x1 > x1) if (shadow->x1 > x1)
shadow->startfrac += shadow->xiscale*(shadow->x1-x1); shadow->startfrac += shadow->xiscale*(shadow->x1-x1);
@ -1317,8 +1317,7 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale,
// R_GetPlaneLight won't work on sloped lights! // R_GetPlaneLight won't work on sloped lights!
for (lightnum = 1; lightnum < thing->subsector->sector->numlights; lightnum++) { for (lightnum = 1; lightnum < thing->subsector->sector->numlights; lightnum++) {
fixed_t h = thing->subsector->sector->lightlist[lightnum].slope ? P_GetZAt(thing->subsector->sector->lightlist[lightnum].slope, thing->x, thing->y) fixed_t h = P_GetLightZAt(&thing->subsector->sector->lightlist[lightnum], thing->x, thing->y);
: thing->subsector->sector->lightlist[lightnum].height;
if (h <= shadow->gzt) { if (h <= shadow->gzt) {
light = lightnum - 1; light = lightnum - 1;
break; break;
@ -1347,7 +1346,6 @@ static void R_ProjectSprite(mobj_t *thing)
{ {
mobj_t *oldthing = thing; mobj_t *oldthing = thing;
fixed_t tr_x, tr_y; fixed_t tr_x, tr_y;
fixed_t gxt, gyt;
fixed_t tx, tz; fixed_t tx, tz;
fixed_t xscale, yscale, sortscale; //added : 02-02-98 : aaargll..if I were a math-guy!!! fixed_t xscale, yscale, sortscale; //added : 02-02-98 : aaargll..if I were a math-guy!!!
@ -1360,7 +1358,7 @@ static void R_ProjectSprite(mobj_t *thing)
#endif #endif
size_t lump; size_t lump;
size_t rot; size_t frame, rot;
UINT16 flip; UINT16 flip;
boolean vflip = (!(thing->eflags & MFE_VERTICALFLIP) != !(thing->frame & FF_VERTICALFLIP)); boolean vflip = (!(thing->eflags & MFE_VERTICALFLIP) != !(thing->frame & FF_VERTICALFLIP));
@ -1400,21 +1398,16 @@ static void R_ProjectSprite(mobj_t *thing)
tr_x = thing->x - viewx; tr_x = thing->x - viewx;
tr_y = thing->y - viewy; tr_y = thing->y - viewy;
gxt = FixedMul(tr_x, viewcos); tz = FixedMul(tr_x, viewcos) + FixedMul(tr_y, viewsin); // near/far distance
gyt = -FixedMul(tr_y, viewsin);
tz = gxt-gyt;
// thing is behind view plane? // thing is behind view plane?
if (!papersprite && (tz < FixedMul(MINZ, this_scale))) // papersprite clipping is handled later if (!papersprite && (tz < FixedMul(MINZ, this_scale))) // papersprite clipping is handled later
return; return;
gxt = -FixedMul(tr_x, viewsin); basetx = tx = FixedMul(tr_x, viewsin) - FixedMul(tr_y, viewcos); // sideways distance
gyt = FixedMul(tr_y, viewcos);
basetx = tx = -(gyt + gxt);
// too far off the side? // too far off the side?
if (!papersprite && abs(tx) > tz<<2) // papersprite clipping is handled later if (!papersprite && abs(tx) > FixedMul(tz, fovtan)<<2) // papersprite clipping is handled later
return; return;
// aspect ratio stuff // aspect ratio stuff
@ -1427,7 +1420,7 @@ static void R_ProjectSprite(mobj_t *thing)
I_Error("R_ProjectSprite: invalid sprite number %d ", thing->sprite); I_Error("R_ProjectSprite: invalid sprite number %d ", thing->sprite);
#endif #endif
rot = thing->frame&FF_FRAMEMASK; frame = thing->frame&FF_FRAMEMASK;
//Fab : 02-08-98: 'skin' override spritedef currently used for skin //Fab : 02-08-98: 'skin' override spritedef currently used for skin
if (thing->skin && thing->sprite == SPR_PLAY) if (thing->skin && thing->sprite == SPR_PLAY)
@ -1436,15 +1429,15 @@ static void R_ProjectSprite(mobj_t *thing)
#ifdef ROTSPRITE #ifdef ROTSPRITE
sprinfo = &((skin_t *)thing->skin)->sprinfo[thing->sprite2]; sprinfo = &((skin_t *)thing->skin)->sprinfo[thing->sprite2];
#endif #endif
if (rot >= sprdef->numframes) { if (frame >= sprdef->numframes) {
CONS_Alert(CONS_ERROR, M_GetText("R_ProjectSprite: invalid skins[\"%s\"].sprites[%sSPR2_%s] frame %s\n"), ((skin_t *)thing->skin)->name, ((thing->sprite2 & FF_SPR2SUPER) ? "FF_SPR2SUPER|": ""), spr2names[(thing->sprite2 & ~FF_SPR2SUPER)], sizeu5(rot)); CONS_Alert(CONS_ERROR, M_GetText("R_ProjectSprite: invalid skins[\"%s\"].sprites[%sSPR2_%s] frame %s\n"), ((skin_t *)thing->skin)->name, ((thing->sprite2 & FF_SPR2SUPER) ? "FF_SPR2SUPER|": ""), spr2names[(thing->sprite2 & ~FF_SPR2SUPER)], sizeu5(frame));
thing->sprite = states[S_UNKNOWN].sprite; thing->sprite = states[S_UNKNOWN].sprite;
thing->frame = states[S_UNKNOWN].frame; thing->frame = states[S_UNKNOWN].frame;
sprdef = &sprites[thing->sprite]; sprdef = &sprites[thing->sprite];
#ifdef ROTSPRITE #ifdef ROTSPRITE
sprinfo = NULL; sprinfo = NULL;
#endif #endif
rot = thing->frame&FF_FRAMEMASK; frame = thing->frame&FF_FRAMEMASK;
} }
} }
else else
@ -1454,10 +1447,10 @@ static void R_ProjectSprite(mobj_t *thing)
sprinfo = NULL; sprinfo = NULL;
#endif #endif
if (rot >= sprdef->numframes) if (frame >= sprdef->numframes)
{ {
CONS_Alert(CONS_ERROR, M_GetText("R_ProjectSprite: invalid sprite frame %s/%s for %s\n"), CONS_Alert(CONS_ERROR, M_GetText("R_ProjectSprite: invalid sprite frame %s/%s for %s\n"),
sizeu1(rot), sizeu2(sprdef->numframes), sprnames[thing->sprite]); sizeu1(frame), sizeu2(sprdef->numframes), sprnames[thing->sprite]);
if (thing->sprite == thing->state->sprite && thing->frame == thing->state->frame) if (thing->sprite == thing->state->sprite && thing->frame == thing->state->frame)
{ {
thing->state->sprite = states[S_UNKNOWN].sprite; thing->state->sprite = states[S_UNKNOWN].sprite;
@ -1466,11 +1459,11 @@ static void R_ProjectSprite(mobj_t *thing)
thing->sprite = states[S_UNKNOWN].sprite; thing->sprite = states[S_UNKNOWN].sprite;
thing->frame = states[S_UNKNOWN].frame; thing->frame = states[S_UNKNOWN].frame;
sprdef = &sprites[thing->sprite]; sprdef = &sprites[thing->sprite];
rot = thing->frame&FF_FRAMEMASK; frame = thing->frame&FF_FRAMEMASK;
} }
} }
sprframe = &sprdef->spriteframes[rot]; sprframe = &sprdef->spriteframes[frame];
#ifdef PARANOIA #ifdef PARANOIA
if (!sprframe) if (!sprframe)
@ -1524,14 +1517,14 @@ static void R_ProjectSprite(mobj_t *thing)
{ {
rollangle = R_GetRollAngle(thing->rollangle); rollangle = R_GetRollAngle(thing->rollangle);
if (!(sprframe->rotsprite.cached & (1<<rot))) if (!(sprframe->rotsprite.cached & (1<<rot)))
R_CacheRotSprite(thing->sprite, (thing->frame & FF_FRAMEMASK), sprinfo, sprframe, rot, flip); R_CacheRotSprite(thing->sprite, frame, sprinfo, sprframe, rot, flip);
rotsprite = sprframe->rotsprite.patch[rot][rollangle]; rotsprite = sprframe->rotsprite.patch[rot][rollangle];
if (rotsprite != NULL) if (rotsprite != NULL)
{ {
spr_width = rotsprite->width << FRACBITS; spr_width = SHORT(rotsprite->width) << FRACBITS;
spr_height = rotsprite->height << FRACBITS; spr_height = SHORT(rotsprite->height) << FRACBITS;
spr_offset = rotsprite->leftoffset << FRACBITS; spr_offset = SHORT(rotsprite->leftoffset) << FRACBITS;
spr_topoffset = rotsprite->topoffset << FRACBITS; spr_topoffset = SHORT(rotsprite->topoffset) << FRACBITS;
// flip -> rotate, not rotate -> flip // flip -> rotate, not rotate -> flip
flip = 0; flip = 0;
} }
@ -1562,17 +1555,9 @@ static void R_ProjectSprite(mobj_t *thing)
tr_x += FixedMul(offset, cosmul); tr_x += FixedMul(offset, cosmul);
tr_y += FixedMul(offset, sinmul); tr_y += FixedMul(offset, sinmul);
gxt = FixedMul(tr_x, viewcos); tz = FixedMul(tr_x, viewcos) + FixedMul(tr_y, viewsin);
gyt = -FixedMul(tr_y, viewsin);
tz = gxt-gyt;
yscale = FixedDiv(projectiony, tz);
//if (yscale < 64) return; // Fix some funky visuals
gxt = -FixedMul(tr_x, viewsin); tx = FixedMul(tr_x, viewsin) - FixedMul(tr_y, viewcos);
gyt = FixedMul(tr_y, viewcos);
tx = -(gyt + gxt);
xscale = FixedDiv(projection, tz);
x1 = (centerxfrac + FixedMul(tx,xscale))>>FRACBITS;
// Get paperoffset (offset) and paperoffset (distance) // Get paperoffset (offset) and paperoffset (distance)
paperoffset = -FixedMul(tr_x, cosmul) - FixedMul(tr_y, sinmul); paperoffset = -FixedMul(tr_x, cosmul) - FixedMul(tr_y, sinmul);
@ -1586,17 +1571,9 @@ static void R_ProjectSprite(mobj_t *thing)
tr_x += FixedMul(offset2, cosmul); tr_x += FixedMul(offset2, cosmul);
tr_y += FixedMul(offset2, sinmul); tr_y += FixedMul(offset2, sinmul);
gxt = FixedMul(tr_x, viewcos); tz2 = FixedMul(tr_x, viewcos) + FixedMul(tr_y, viewsin);
gyt = -FixedMul(tr_y, viewsin);
tz2 = gxt-gyt;
yscale2 = FixedDiv(projectiony, tz2);
//if (yscale2 < 64) return; // ditto
gxt = -FixedMul(tr_x, viewsin); tx2 = FixedMul(tr_x, viewsin) - FixedMul(tr_y, viewcos);
gyt = FixedMul(tr_y, viewcos);
tx2 = -(gyt + gxt);
xscale2 = FixedDiv(projection, tz2);
x2 = ((centerxfrac + FixedMul(tx2,xscale2))>>FRACBITS);
if (max(tz, tz2) < FixedMul(MINZ, this_scale)) // non-papersprite clipping is handled earlier if (max(tz, tz2) < FixedMul(MINZ, this_scale)) // non-papersprite clipping is handled earlier
return; return;
@ -1607,24 +1584,31 @@ static void R_ProjectSprite(mobj_t *thing)
fixed_t div = FixedDiv(tz2-tz, FixedMul(MINZ, this_scale)-tz); fixed_t div = FixedDiv(tz2-tz, FixedMul(MINZ, this_scale)-tz);
tx += FixedDiv(tx2-tx, div); tx += FixedDiv(tx2-tx, div);
tz = FixedMul(MINZ, this_scale); tz = FixedMul(MINZ, this_scale);
yscale = FixedDiv(projectiony, tz);
xscale = FixedDiv(projection, tz);
x1 = (centerxfrac + FixedMul(tx,xscale))>>FRACBITS;
} }
else if (tz2 < FixedMul(MINZ, this_scale)) else if (tz2 < FixedMul(MINZ, this_scale))
{ {
fixed_t div = FixedDiv(tz-tz2, FixedMul(MINZ, this_scale)-tz2); fixed_t div = FixedDiv(tz-tz2, FixedMul(MINZ, this_scale)-tz2);
tx2 += FixedDiv(tx-tx2, div); tx2 += FixedDiv(tx-tx2, div);
tz2 = FixedMul(MINZ, this_scale); tz2 = FixedMul(MINZ, this_scale);
yscale2 = FixedDiv(projectiony, tz2);
xscale2 = FixedDiv(projection, tz2);
x2 = (centerxfrac + FixedMul(tx2,xscale2))>>FRACBITS;
} }
if (tx2 < -(FixedMul(tz2, fovtan)<<2) || tx > FixedMul(tz, fovtan)<<2) // too far off the side?
return;
yscale = FixedDiv(projectiony, tz);
xscale = FixedDiv(projection, tz);
x1 = (centerxfrac + FixedMul(tx,xscale))>>FRACBITS;
// off the right side? // off the right side?
if (x1 > viewwidth) if (x1 > viewwidth)
return; return;
yscale2 = FixedDiv(projectiony, tz2);
xscale2 = FixedDiv(projection, tz2);
x2 = (centerxfrac + FixedMul(tx2,xscale2))>>FRACBITS;
// off the left side // off the left side
if (x2 < 0) if (x2 < 0)
return; return;
@ -1671,9 +1655,7 @@ static void R_ProjectSprite(mobj_t *thing)
tr_x = thing->x - viewx; tr_x = thing->x - viewx;
tr_y = thing->y - viewy; tr_y = thing->y - viewy;
gxt = FixedMul(tr_x, viewcos); tz = FixedMul(tr_x, viewcos) + FixedMul(tr_y, viewsin);
gyt = -FixedMul(tr_y, viewsin);
tz = gxt-gyt;
linkscale = FixedDiv(projectiony, tz); linkscale = FixedDiv(projectiony, tz);
if (tz < FixedMul(MINZ, this_scale)) if (tz < FixedMul(MINZ, this_scale))
@ -1689,7 +1671,7 @@ static void R_ProjectSprite(mobj_t *thing)
// PORTAL SPRITE CLIPPING // PORTAL SPRITE CLIPPING
if (portalrender && portalclipline) if (portalrender && portalclipline)
{ {
if (x2 < portalclipstart || x1 > portalclipend) if (x2 < portalclipstart || x1 >= portalclipend)
return; return;
if (P_PointOnLineSide(thing->x, thing->y, portalclipline) != 0) if (P_PointOnLineSide(thing->x, thing->y, portalclipline) != 0)
@ -1724,8 +1706,7 @@ static void R_ProjectSprite(mobj_t *thing)
// R_GetPlaneLight won't work on sloped lights! // R_GetPlaneLight won't work on sloped lights!
for (lightnum = 1; lightnum < thing->subsector->sector->numlights; lightnum++) { for (lightnum = 1; lightnum < thing->subsector->sector->numlights; lightnum++) {
fixed_t h = thing->subsector->sector->lightlist[lightnum].slope ? P_GetZAt(thing->subsector->sector->lightlist[lightnum].slope, thing->x, thing->y) fixed_t h = P_GetLightZAt(&thing->subsector->sector->lightlist[lightnum], thing->x, thing->y);
: thing->subsector->sector->lightlist[lightnum].height;
if (h <= gzt) { if (h <= gzt) {
light = lightnum - 1; light = lightnum - 1;
break; break;
@ -1874,7 +1855,6 @@ static void R_ProjectSprite(mobj_t *thing)
static void R_ProjectPrecipitationSprite(precipmobj_t *thing) static void R_ProjectPrecipitationSprite(precipmobj_t *thing)
{ {
fixed_t tr_x, tr_y; fixed_t tr_x, tr_y;
fixed_t gxt, gyt;
fixed_t tx, tz; fixed_t tx, tz;
fixed_t xscale, yscale; //added : 02-02-98 : aaargll..if I were a math-guy!!! fixed_t xscale, yscale; //added : 02-02-98 : aaargll..if I were a math-guy!!!
@ -1895,21 +1875,16 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing)
tr_x = thing->x - viewx; tr_x = thing->x - viewx;
tr_y = thing->y - viewy; tr_y = thing->y - viewy;
gxt = FixedMul(tr_x, viewcos); tz = FixedMul(tr_x, viewcos) + FixedMul(tr_y, viewsin); // near/far distance
gyt = -FixedMul(tr_y, viewsin);
tz = gxt - gyt;
// thing is behind view plane? // thing is behind view plane?
if (tz < MINZ) if (tz < MINZ)
return; return;
gxt = -FixedMul(tr_x, viewsin); tx = FixedMul(tr_x, viewsin) - FixedMul(tr_y, viewcos); // sideways distance
gyt = FixedMul(tr_y, viewcos);
tx = -(gyt + gxt);
// too far off the side? // too far off the side?
if (abs(tx) > tz<<2) if (abs(tx) > FixedMul(tz, fovtan)<<2)
return; return;
// aspect ratio stuff : // aspect ratio stuff :
@ -1959,7 +1934,7 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing)
// PORTAL SPRITE CLIPPING // PORTAL SPRITE CLIPPING
if (portalrender && portalclipline) if (portalrender && portalclipline)
{ {
if (x2 < portalclipstart || x1 > portalclipend) if (x2 < portalclipstart || x1 >= portalclipend)
return; return;
if (P_PointOnLineSide(thing->x, thing->y, portalclipline) != 0) if (P_PointOnLineSide(thing->x, thing->y, portalclipline) != 0)
@ -2271,7 +2246,6 @@ static void R_CreateDrawNodes(maskcount_t* mask, drawnode_t* head, boolean temps
entry->ffloor = ds->thicksides[i]; entry->ffloor = ds->thicksides[i];
} }
} }
#ifdef POLYOBJECTS_PLANES
// Check for a polyobject plane, but only if this is a front line // Check for a polyobject plane, but only if this is a front line
if (ds->curline->polyseg && ds->curline->polyseg->visplane && !ds->curline->side) { if (ds->curline->polyseg && ds->curline->polyseg->visplane && !ds->curline->side) {
plane = ds->curline->polyseg->visplane; plane = ds->curline->polyseg->visplane;
@ -2287,7 +2261,6 @@ static void R_CreateDrawNodes(maskcount_t* mask, drawnode_t* head, boolean temps
} }
ds->curline->polyseg->visplane = NULL; ds->curline->polyseg->visplane = NULL;
} }
#endif
if (ds->maskedtexturecol) if (ds->maskedtexturecol)
{ {
entry = R_CreateDrawNode(head); entry = R_CreateDrawNode(head);
@ -2335,7 +2308,6 @@ static void R_CreateDrawNodes(maskcount_t* mask, drawnode_t* head, boolean temps
if (tempskip) if (tempskip)
return; return;
#ifdef POLYOBJECTS_PLANES
// find all the remaining polyobject planes and add them on the end of the list // find all the remaining polyobject planes and add them on the end of the list
// probably this is a terrible idea if we wanted them to be sorted properly // probably this is a terrible idea if we wanted them to be sorted properly
// but it works getting them in for now // but it works getting them in for now
@ -2356,7 +2328,6 @@ static void R_CreateDrawNodes(maskcount_t* mask, drawnode_t* head, boolean temps
// note: no seg is set, for what should be obvious reasons // note: no seg is set, for what should be obvious reasons
PolyObjects[i].visplane = NULL; PolyObjects[i].visplane = NULL;
} }
#endif
// No vissprites in this mask? // No vissprites in this mask?
if (mask->vissprites[1] - mask->vissprites[0] == 0) if (mask->vissprites[1] - mask->vissprites[0] == 0)
@ -2382,12 +2353,8 @@ static void R_CreateDrawNodes(maskcount_t* mask, drawnode_t* head, boolean temps
continue; continue;
// Effective height may be different for each comparison in the case of slopes // Effective height may be different for each comparison in the case of slopes
if (r2->plane->slope) { planeobjectz = P_GetZAt(r2->plane->slope, rover->gx, rover->gy, r2->plane->height);
planeobjectz = P_GetZAt(r2->plane->slope, rover->gx, rover->gy); planecameraz = P_GetZAt(r2->plane->slope, viewx, viewy, r2->plane->height);
planecameraz = P_GetZAt(r2->plane->slope, viewx, viewy);
}
else
planeobjectz = planecameraz = r2->plane->height;
if (rover->mobjflags & MF_NOCLIPHEIGHT) if (rover->mobjflags & MF_NOCLIPHEIGHT)
{ {
@ -2445,19 +2412,10 @@ static void R_CreateDrawNodes(maskcount_t* mask, drawnode_t* head, boolean temps
if (scale <= rover->sortscale) if (scale <= rover->sortscale)
continue; continue;
if (*r2->ffloor->t_slope) { topplaneobjectz = P_GetFFloorTopZAt (r2->ffloor, rover->gx, rover->gy);
topplaneobjectz = P_GetZAt(*r2->ffloor->t_slope, rover->gx, rover->gy); topplanecameraz = P_GetFFloorTopZAt (r2->ffloor, viewx, viewy);
topplanecameraz = P_GetZAt(*r2->ffloor->t_slope, viewx, viewy); botplaneobjectz = P_GetFFloorBottomZAt(r2->ffloor, rover->gx, rover->gy);
} botplanecameraz = P_GetFFloorBottomZAt(r2->ffloor, viewx, viewy);
else
topplaneobjectz = topplanecameraz = *r2->ffloor->topheight;
if (*r2->ffloor->b_slope) {
botplaneobjectz = P_GetZAt(*r2->ffloor->b_slope, rover->gx, rover->gy);
botplanecameraz = P_GetZAt(*r2->ffloor->b_slope, viewx, viewy);
}
else
botplaneobjectz = botplanecameraz = *r2->ffloor->bottomheight;
if ((topplanecameraz > viewz && botplanecameraz < viewz) || if ((topplanecameraz > viewz && botplanecameraz < viewz) ||
(topplanecameraz < viewz && rover->gzt < topplaneobjectz) || (topplanecameraz < viewz && rover->gzt < topplaneobjectz) ||

View File

@ -134,6 +134,7 @@ consvar_t cv_playmusicifunfocused = {"playmusicifunfocused", "No", CV_SAVE, CV_Y
consvar_t cv_playsoundsifunfocused = {"playsoundsifunfocused", "No", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_playsoundsifunfocused = {"playsoundsifunfocused", "No", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
#ifdef HAVE_OPENMPT #ifdef HAVE_OPENMPT
openmpt_module *openmpt_mhandle = NULL;
static CV_PossibleValue_t interpolationfilter_cons_t[] = {{0, "Default"}, {1, "None"}, {2, "Linear"}, {4, "Cubic"}, {8, "Windowed sinc"}, {0, NULL}}; static CV_PossibleValue_t interpolationfilter_cons_t[] = {{0, "Default"}, {1, "None"}, {2, "Linear"}, {4, "Cubic"}, {8, "Windowed sinc"}, {0, NULL}};
consvar_t cv_modfilter = {"modfilter", "0", CV_SAVE|CV_CALL, interpolationfilter_cons_t, ModFilter_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_modfilter = {"modfilter", "0", CV_SAVE|CV_CALL, interpolationfilter_cons_t, ModFilter_OnChange, 0, NULL, NULL, 0, 0, NULL};
#endif #endif
@ -1675,7 +1676,7 @@ void S_LoadMusicDefs(UINT16 wadnum)
char *lf; char *lf;
char *stoken; char *stoken;
size_t nlf; size_t nlf = 0xFFFFFFFF;
size_t ncr; size_t ncr;
musicdef_t *def = NULL; musicdef_t *def = NULL;
@ -1910,6 +1911,10 @@ UINT32 S_GetMusicPosition(void)
/// In this section: mazmazz doesn't know how to do dynamic arrays or struct pointers! /// In this section: mazmazz doesn't know how to do dynamic arrays or struct pointers!
/// ------------------------ /// ------------------------
char music_stack_nextmusname[7];
boolean music_stack_noposition = false;
UINT32 music_stack_fadeout = 0;
UINT32 music_stack_fadein = 0;
static musicstack_t *music_stacks = NULL; static musicstack_t *music_stacks = NULL;
static musicstack_t *last_music_stack = NULL; static musicstack_t *last_music_stack = NULL;

View File

@ -22,7 +22,7 @@
#ifdef HAVE_OPENMPT #ifdef HAVE_OPENMPT
#include "libopenmpt/libopenmpt.h" #include "libopenmpt/libopenmpt.h"
openmpt_module *openmpt_mhandle; extern openmpt_module *openmpt_mhandle;
#endif #endif
// mask used to indicate sound origin is player item pickup // mask used to indicate sound origin is player item pickup
@ -262,10 +262,10 @@ typedef struct musicstack_s
struct musicstack_s *next; struct musicstack_s *next;
} musicstack_t; } musicstack_t;
char music_stack_nextmusname[7]; extern char music_stack_nextmusname[7];
boolean music_stack_noposition; extern boolean music_stack_noposition;
UINT32 music_stack_fadeout; extern UINT32 music_stack_fadeout;
UINT32 music_stack_fadein; extern UINT32 music_stack_fadein;
void S_SetStackAdjustmentStart(void); void S_SetStackAdjustmentStart(void);
void S_AdjustMusicStackTics(void); void S_AdjustMusicStackTics(void);
@ -333,7 +333,7 @@ void S_StopSoundByNum(sfxenum_t sfxnum);
#ifdef MUSICSLOT_COMPATIBILITY #ifdef MUSICSLOT_COMPATIBILITY
// For compatibility with code/scripts relying on older versions // For compatibility with code/scripts relying on older versions
// This is a list of all the "special" slot names and their associated numbers // This is a list of all the "special" slot names and their associated numbers
const char *compat_special_music_slots[16]; extern const char *compat_special_music_slots[16];
#endif #endif
#endif #endif

View File

@ -526,6 +526,9 @@ void SCR_DisplayTicRate(void)
INT32 ticcntcolor = 0; INT32 ticcntcolor = 0;
const INT32 h = vid.height-(8*vid.dupy); const INT32 h = vid.height-(8*vid.dupy);
if (gamestate == GS_NULL)
return;
for (i = lasttic + 1; i < TICRATE+lasttic && i < ontic; ++i) for (i = lasttic + 1; i < TICRATE+lasttic && i < ontic; ++i)
fpsgraph[i % TICRATE] = false; fpsgraph[i % TICRATE] = false;
@ -538,10 +541,16 @@ void SCR_DisplayTicRate(void)
if (totaltics <= TICRATE/2) ticcntcolor = V_REDMAP; if (totaltics <= TICRATE/2) ticcntcolor = V_REDMAP;
else if (totaltics == TICRATE) ticcntcolor = V_GREENMAP; else if (totaltics == TICRATE) ticcntcolor = V_GREENMAP;
V_DrawString(vid.width-(72*vid.dupx), h, if (cv_ticrate.value == 2) // compact counter
V_YELLOWMAP|V_NOSCALESTART|V_USERHUDTRANS, "FPS:"); V_DrawString(vid.width-(16*vid.dupx), h,
V_DrawString(vid.width-(40*vid.dupx), h, ticcntcolor|V_NOSCALESTART|V_USERHUDTRANS, va("%02d", totaltics));
ticcntcolor|V_NOSCALESTART|V_USERHUDTRANS, va("%02d/%02u", totaltics, TICRATE)); else if (cv_ticrate.value == 1) // full counter
{
V_DrawString(vid.width-(72*vid.dupx), h,
V_YELLOWMAP|V_NOSCALESTART|V_USERHUDTRANS, "FPS:");
V_DrawString(vid.width-(40*vid.dupx), h,
ticcntcolor|V_NOSCALESTART|V_USERHUDTRANS, va("%02d/%02u", totaltics, TICRATE));
}
lasttic = ontic; lasttic = ontic;
} }

View File

@ -27,7 +27,7 @@
#include <unistd.h> #include <unistd.h>
#endif #endif
#ifdef __unix__ #if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON)
#include <errno.h> #include <errno.h>
#endif #endif
@ -142,7 +142,7 @@ int main(int argc, char **argv)
const char *reldir; const char *reldir;
int left; int left;
boolean fileabs; boolean fileabs;
#ifdef __unix__ #if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON)
const char *link; const char *link;
#endif #endif
@ -201,7 +201,7 @@ int main(int argc, char **argv)
M_PathParts(logdir) - 1, M_PathParts(logdir) - 1,
M_PathParts(logfilename) - 1, 0755); M_PathParts(logfilename) - 1, 0755);
#ifdef __unix__ #if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON)
logstream = fopen(logfilename, "w"); logstream = fopen(logfilename, "w");
#ifdef DEFAULTDIR #ifdef DEFAULTDIR
if (logdir) if (logdir)
@ -214,9 +214,9 @@ int main(int argc, char **argv)
{ {
I_OutputMsg("Error symlinking latest-log.txt: %s\n", strerror(errno)); I_OutputMsg("Error symlinking latest-log.txt: %s\n", strerror(errno));
} }
#else/*__unix__*/ #else/*defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON)*/
logstream = fopen("latest-log.txt", "wt+"); logstream = fopen("latest-log.txt", "wt+");
#endif/*__unix__*/ #endif/*defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON)*/
} }
//I_OutputMsg("I_StartupSystem() ...\n"); //I_OutputMsg("I_StartupSystem() ...\n");

View File

@ -178,6 +178,8 @@ static char returnWadPath[256];
#include "../m_argv.h" #include "../m_argv.h"
#include "../m_menu.h"
#ifdef MAC_ALERT #ifdef MAC_ALERT
#include "macosx/mac_alert.h" #include "macosx/mac_alert.h"
#endif #endif
@ -2293,6 +2295,7 @@ void I_Quit(void)
G_StopMetalRecording(false); G_StopMetalRecording(false);
D_QuitNetGame(); D_QuitNetGame();
M_FreePlayerSetupColors();
I_ShutdownMusic(); I_ShutdownMusic();
I_ShutdownSound(); I_ShutdownSound();
I_ShutdownCD(); I_ShutdownCD();
@ -2409,6 +2412,7 @@ void I_Error(const char *error, ...)
G_StopMetalRecording(false); G_StopMetalRecording(false);
D_QuitNetGame(); D_QuitNetGame();
M_FreePlayerSetupColors();
I_ShutdownMusic(); I_ShutdownMusic();
I_ShutdownSound(); I_ShutdownSound();
I_ShutdownCD(); I_ShutdownCD();
@ -2484,7 +2488,7 @@ void I_RemoveExitFunc(void (*func)())
} }
} }
#ifndef __unix__ #if !(defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON))
static void Shittycopyerror(const char *name) static void Shittycopyerror(const char *name)
{ {
I_OutputMsg( I_OutputMsg(
@ -2524,7 +2528,7 @@ static void Shittylogcopy(void)
Shittycopyerror(logfilename); Shittycopyerror(logfilename);
} }
} }
#endif/*__unix__*/ #endif/*!(defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON))*/
// //
// Closes down everything. This includes restoring the initial // Closes down everything. This includes restoring the initial
@ -2548,7 +2552,7 @@ void I_ShutdownSystem(void)
if (logstream) if (logstream)
{ {
I_OutputMsg("I_ShutdownSystem(): end of logstream.\n"); I_OutputMsg("I_ShutdownSystem(): end of logstream.\n");
#ifndef __unix__ #if !(defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON))
Shittylogcopy(); Shittylogcopy();
#endif #endif
fclose(logstream); fclose(logstream);

View File

@ -217,7 +217,6 @@ static void SDLSetMode(INT32 width, INT32 height, SDL_bool fullscreen, SDL_bool
else else
{ {
Impl_CreateWindow(fullscreen); Impl_CreateWindow(fullscreen);
Impl_SetWindowIcon();
wasfullscreen = fullscreen; wasfullscreen = fullscreen;
SDL_SetWindowSize(window, width, height); SDL_SetWindowSize(window, width, height);
if (fullscreen) if (fullscreen)
@ -1632,12 +1631,15 @@ static SDL_bool Impl_CreateWindow(SDL_bool fullscreen)
window = SDL_CreateWindow("SRB2 "VERSIONSTRING, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, window = SDL_CreateWindow("SRB2 "VERSIONSTRING, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
realwidth, realheight, flags); realwidth, realheight, flags);
if (window == NULL) if (window == NULL)
{ {
CONS_Printf(M_GetText("Couldn't create window: %s\n"), SDL_GetError()); CONS_Printf(M_GetText("Couldn't create window: %s\n"), SDL_GetError());
return SDL_FALSE; return SDL_FALSE;
} }
Impl_SetWindowIcon();
return Impl_CreateContext(); return Impl_CreateContext();
} }
@ -1654,12 +1656,8 @@ static void Impl_SetWindowName(const char *title)
static void Impl_SetWindowIcon(void) static void Impl_SetWindowIcon(void)
{ {
if (window == NULL || icoSurface == NULL) if (window && icoSurface)
{ SDL_SetWindowIcon(window, icoSurface);
return;
}
//SDL2STUB(); // Monster Iestyn: why is this stubbed?
SDL_SetWindowIcon(window, icoSurface);
} }
static void Impl_VideoSetupSDLBuffer(void) static void Impl_VideoSetupSDLBuffer(void)
@ -1766,6 +1764,11 @@ void I_StartupGraphics(void)
VID_StartupOpenGL(); VID_StartupOpenGL();
#endif #endif
// Window icon
#ifdef HAVE_IMAGE
icoSurface = IMG_ReadXPMFromArray(SDL_icon_xpm);
#endif
// Fury: we do window initialization after GL setup to allow // Fury: we do window initialization after GL setup to allow
// SDL_GL_LoadLibrary to work well on Windows // SDL_GL_LoadLibrary to work well on Windows
@ -1784,11 +1787,6 @@ void I_StartupGraphics(void)
#ifdef HAVE_TTF #ifdef HAVE_TTF
I_ShutdownTTF(); I_ShutdownTTF();
#endif #endif
// Window icon
#ifdef HAVE_IMAGE
icoSurface = IMG_ReadXPMFromArray(SDL_icon_xpm);
#endif
Impl_SetWindowIcon();
VID_SetMode(VID_GetModeForSize(BASEVIDWIDTH, BASEVIDHEIGHT)); VID_SetMode(VID_GetModeForSize(BASEVIDWIDTH, BASEVIDHEIGHT));

View File

@ -1219,7 +1219,7 @@
C01FCF4B08A954540054247B /* Debug */ = { C01FCF4B08A954540054247B /* Debug */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
CURRENT_PROJECT_VERSION = 2.2.2; CURRENT_PROJECT_VERSION = 2.2.4;
GCC_PREPROCESSOR_DEFINITIONS = ( GCC_PREPROCESSOR_DEFINITIONS = (
"$(inherited)", "$(inherited)",
NORMALSRB2, NORMALSRB2,
@ -1231,7 +1231,7 @@
C01FCF4C08A954540054247B /* Release */ = { C01FCF4C08A954540054247B /* Release */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
CURRENT_PROJECT_VERSION = 2.2.2; CURRENT_PROJECT_VERSION = 2.2.4;
GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_ENABLE_FIX_AND_CONTINUE = NO;
GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
GCC_PREPROCESSOR_DEFINITIONS = ( GCC_PREPROCESSOR_DEFINITIONS = (

View File

@ -527,7 +527,7 @@ sfxinfo_t S_sfx[NUMSFX] =
{"s3k8a", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Boing"}, {"s3k8a", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Boing"},
{"s3k8b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Powerful hit"}, {"s3k8b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Powerful hit"},
{"s3k8c", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Humming power"}, {"s3k8c", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Humming power"},
{"s3k8d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, {"s3k8d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "/"},
{"s3k8e", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Accelerating"}, {"s3k8e", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Accelerating"},
{"s3k8f", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Opening"}, {"s3k8f", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Opening"},
{"s3k90", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Impact"}, {"s3k90", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Impact"},

View File

@ -456,7 +456,7 @@ boolean st_overlay;
// //
// Supports different colors! woo! // Supports different colors! woo!
static void ST_DrawNightsOverlayNum(fixed_t x /* right border */, fixed_t y, fixed_t s, INT32 a, static void ST_DrawNightsOverlayNum(fixed_t x /* right border */, fixed_t y, fixed_t s, INT32 a,
UINT32 num, patch_t **numpat, skincolors_t colornum) UINT32 num, patch_t **numpat, skincolornum_t colornum)
{ {
fixed_t w = SHORT(numpat[0]->width)*s; fixed_t w = SHORT(numpat[0]->width)*s;
const UINT8 *colormap; const UINT8 *colormap;
@ -992,7 +992,7 @@ static void ST_drawLivesArea(void)
static void ST_drawInput(void) static void ST_drawInput(void)
{ {
const INT32 accent = V_SNAPTOLEFT|V_SNAPTOBOTTOM|(stplyr->skincolor ? Color_Index[stplyr->skincolor-1][4] : 0); const INT32 accent = V_SNAPTOLEFT|V_SNAPTOBOTTOM|(stplyr->skincolor ? skincolors[stplyr->skincolor].ramp[4] : 0);
INT32 col; INT32 col;
UINT8 offs; UINT8 offs;
@ -1325,7 +1325,7 @@ void ST_drawTitleCard(void)
{ {
char *lvlttl = mapheaderinfo[gamemap-1]->lvlttl; char *lvlttl = mapheaderinfo[gamemap-1]->lvlttl;
char *subttl = mapheaderinfo[gamemap-1]->subttl; char *subttl = mapheaderinfo[gamemap-1]->subttl;
INT32 actnum = mapheaderinfo[gamemap-1]->actnum; UINT8 actnum = mapheaderinfo[gamemap-1]->actnum;
INT32 lvlttlxpos, ttlnumxpos, zonexpos; INT32 lvlttlxpos, ttlnumxpos, zonexpos;
INT32 subttlxpos = BASEVIDWIDTH/2; INT32 subttlxpos = BASEVIDWIDTH/2;
INT32 ttlscroll = FixedInt(lt_scroll); INT32 ttlscroll = FixedInt(lt_scroll);
@ -1333,13 +1333,12 @@ void ST_drawTitleCard(void)
patch_t *actpat, *zigzag, *zztext; patch_t *actpat, *zigzag, *zztext;
UINT8 colornum; UINT8 colornum;
const UINT8 *colormap; const UINT8 *colormap;
stplyr = &players[consoleplayer];
if (players[consoleplayer].skincolor)
if (stplyr->skincolor) colornum = players[consoleplayer].skincolor;
colornum = stplyr->skincolor;
else else
colornum = cv_playercolor.value; colornum = cv_playercolor.value;
colormap = R_GetTranslationColormap(TC_DEFAULT, colornum, GTC_CACHE); colormap = R_GetTranslationColormap(TC_DEFAULT, colornum, GTC_CACHE);
if (!G_IsTitleCardAvailable()) if (!G_IsTitleCardAvailable())
@ -1383,7 +1382,12 @@ void ST_drawTitleCard(void)
if (actnum) if (actnum)
{ {
if (!splitscreen) if (!splitscreen)
V_DrawMappedPatch(ttlnumxpos + ttlscroll, 104 - ttlscroll, 0, actpat, colormap); {
if (actnum > 9) // slightly offset the act diamond for two-digit act numbers
V_DrawMappedPatch(ttlnumxpos + (V_LevelActNumWidth(actnum)/4) + ttlscroll, 104 - ttlscroll, 0, actpat, colormap);
else
V_DrawMappedPatch(ttlnumxpos + ttlscroll, 104 - ttlscroll, 0, actpat, colormap);
}
V_DrawLevelActNum(ttlnumxpos + ttlscroll, 104, V_PERPLAYER, actnum); V_DrawLevelActNum(ttlnumxpos + ttlscroll, 104, V_PERPLAYER, actnum);
} }
@ -1696,14 +1700,14 @@ static void ST_drawNightsRecords(void)
// 2.0-1: [21:42] <+Rob> Beige - Lavender - Steel Blue - Peach - Orange - Purple - Silver - Yellow - Pink - Red - Blue - Green - Cyan - Gold // 2.0-1: [21:42] <+Rob> Beige - Lavender - Steel Blue - Peach - Orange - Purple - Silver - Yellow - Pink - Red - Blue - Green - Cyan - Gold
/*#define NUMLINKCOLORS 14 /*#define NUMLINKCOLORS 14
static skincolors_t linkColor[NUMLINKCOLORS] = static skincolornum_t linkColor[NUMLINKCOLORS] =
{SKINCOLOR_BEIGE, SKINCOLOR_LAVENDER, SKINCOLOR_AZURE, SKINCOLOR_PEACH, SKINCOLOR_ORANGE, {SKINCOLOR_BEIGE, SKINCOLOR_LAVENDER, SKINCOLOR_AZURE, SKINCOLOR_PEACH, SKINCOLOR_ORANGE,
SKINCOLOR_MAGENTA, SKINCOLOR_SILVER, SKINCOLOR_SUPERGOLD4, SKINCOLOR_PINK, SKINCOLOR_RED, SKINCOLOR_MAGENTA, SKINCOLOR_SILVER, SKINCOLOR_SUPERGOLD4, SKINCOLOR_PINK, SKINCOLOR_RED,
SKINCOLOR_BLUE, SKINCOLOR_GREEN, SKINCOLOR_CYAN, SKINCOLOR_GOLD};*/ SKINCOLOR_BLUE, SKINCOLOR_GREEN, SKINCOLOR_CYAN, SKINCOLOR_GOLD};*/
// 2.2 indev list: (unix time 1470866042) <Rob> Emerald, Aqua, Cyan, Blue, Pastel, Purple, Magenta, Rosy, Red, Orange, Gold, Yellow, Peridot // 2.2 indev list: (unix time 1470866042) <Rob> Emerald, Aqua, Cyan, Blue, Pastel, Purple, Magenta, Rosy, Red, Orange, Gold, Yellow, Peridot
/*#define NUMLINKCOLORS 13 /*#define NUMLINKCOLORS 13
static skincolors_t linkColor[NUMLINKCOLORS] = static skincolornum_t linkColor[NUMLINKCOLORS] =
{SKINCOLOR_EMERALD, SKINCOLOR_AQUA, SKINCOLOR_CYAN, SKINCOLOR_BLUE, SKINCOLOR_PASTEL, {SKINCOLOR_EMERALD, SKINCOLOR_AQUA, SKINCOLOR_CYAN, SKINCOLOR_BLUE, SKINCOLOR_PASTEL,
SKINCOLOR_PURPLE, SKINCOLOR_MAGENTA, SKINCOLOR_ROSY, SKINCOLOR_RED, SKINCOLOR_ORANGE, SKINCOLOR_PURPLE, SKINCOLOR_MAGENTA, SKINCOLOR_ROSY, SKINCOLOR_RED, SKINCOLOR_ORANGE,
SKINCOLOR_GOLD, SKINCOLOR_YELLOW, SKINCOLOR_PERIDOT};*/ SKINCOLOR_GOLD, SKINCOLOR_YELLOW, SKINCOLOR_PERIDOT};*/
@ -1712,7 +1716,7 @@ static skincolors_t linkColor[NUMLINKCOLORS] =
// [20:00:25] <baldobo> Also Icy for the link freeze text color // [20:00:25] <baldobo> Also Icy for the link freeze text color
// [20:04:03] <baldobo> I would start it on lime // [20:04:03] <baldobo> I would start it on lime
/*#define NUMLINKCOLORS 18 /*#define NUMLINKCOLORS 18
static skincolors_t linkColor[NUMLINKCOLORS] = static skincolornum_t linkColor[NUMLINKCOLORS] =
{SKINCOLOR_LIME, SKINCOLOR_EMERALD, SKINCOLOR_AQUA, SKINCOLOR_CYAN, SKINCOLOR_SKY, {SKINCOLOR_LIME, SKINCOLOR_EMERALD, SKINCOLOR_AQUA, SKINCOLOR_CYAN, SKINCOLOR_SKY,
SKINCOLOR_SAPPHIRE, SKINCOLOR_PASTEL, SKINCOLOR_PURPLE, SKINCOLOR_BUBBLEGUM, SKINCOLOR_MAGENTA, SKINCOLOR_SAPPHIRE, SKINCOLOR_PASTEL, SKINCOLOR_PURPLE, SKINCOLOR_BUBBLEGUM, SKINCOLOR_MAGENTA,
SKINCOLOR_ROSY, SKINCOLOR_RUBY, SKINCOLOR_RED, SKINCOLOR_FLAME, SKINCOLOR_SUNSET, SKINCOLOR_ROSY, SKINCOLOR_RUBY, SKINCOLOR_RED, SKINCOLOR_FLAME, SKINCOLOR_SUNSET,
@ -1720,7 +1724,7 @@ static skincolors_t linkColor[NUMLINKCOLORS] =
// 2.2+ list for real this time: https://wiki.srb2.org/wiki/User:Rob/Sandbox (check history around 31/10/17, spoopy) // 2.2+ list for real this time: https://wiki.srb2.org/wiki/User:Rob/Sandbox (check history around 31/10/17, spoopy)
#define NUMLINKCOLORS 12 #define NUMLINKCOLORS 12
static skincolors_t linkColor[2][NUMLINKCOLORS] = { static skincolornum_t linkColor[2][NUMLINKCOLORS] = {
{SKINCOLOR_EMERALD, SKINCOLOR_AQUA, SKINCOLOR_SKY, SKINCOLOR_BLUE, SKINCOLOR_PURPLE, SKINCOLOR_MAGENTA, {SKINCOLOR_EMERALD, SKINCOLOR_AQUA, SKINCOLOR_SKY, SKINCOLOR_BLUE, SKINCOLOR_PURPLE, SKINCOLOR_MAGENTA,
SKINCOLOR_ROSY, SKINCOLOR_RED, SKINCOLOR_ORANGE, SKINCOLOR_GOLD, SKINCOLOR_YELLOW, SKINCOLOR_PERIDOT}, SKINCOLOR_ROSY, SKINCOLOR_RED, SKINCOLOR_ORANGE, SKINCOLOR_GOLD, SKINCOLOR_YELLOW, SKINCOLOR_PERIDOT},
{SKINCOLOR_SEAFOAM, SKINCOLOR_CYAN, SKINCOLOR_WAVE, SKINCOLOR_SAPPHIRE, SKINCOLOR_VAPOR, SKINCOLOR_BUBBLEGUM, {SKINCOLOR_SEAFOAM, SKINCOLOR_CYAN, SKINCOLOR_WAVE, SKINCOLOR_SAPPHIRE, SKINCOLOR_VAPOR, SKINCOLOR_BUBBLEGUM,
@ -1731,7 +1735,7 @@ static void ST_drawNiGHTSLink(void)
static INT32 prevsel[2] = {0, 0}, prevtime[2] = {0, 0}; static INT32 prevsel[2] = {0, 0}, prevtime[2] = {0, 0};
const UINT8 q = ((splitscreen && stplyr == &players[secondarydisplayplayer]) ? 1 : 0); const UINT8 q = ((splitscreen && stplyr == &players[secondarydisplayplayer]) ? 1 : 0);
INT32 sel = ((stplyr->linkcount-1) / 5) % NUMLINKCOLORS, aflag = V_PERPLAYER, mag = ((stplyr->linkcount-1 >= 300) ? 1 : 0); INT32 sel = ((stplyr->linkcount-1) / 5) % NUMLINKCOLORS, aflag = V_PERPLAYER, mag = ((stplyr->linkcount-1 >= 300) ? 1 : 0);
skincolors_t colornum; skincolornum_t colornum;
fixed_t x, y, scale; fixed_t x, y, scale;
if (sel != prevsel[q]) if (sel != prevsel[q])

View File

@ -42,7 +42,8 @@ UINT8 *screens[5];
// screens[3] = fade screen start // screens[3] = fade screen start
// screens[4] = fade screen end, postimage tempoarary buffer // screens[4] = fade screen end, postimage tempoarary buffer
consvar_t cv_ticrate = {"showfps", "No", 0, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; static CV_PossibleValue_t ticrate_cons_t[] = {{0, "No"}, {1, "Full"}, {2, "Compact"}, {0, NULL}};
consvar_t cv_ticrate = {"showfps", "No", CV_SAVE, ticrate_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
static void CV_palette_OnChange(void); static void CV_palette_OnChange(void);
@ -1039,7 +1040,7 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_
// V_DrawContinueIcon // V_DrawContinueIcon
// Draw a mini player! If we can, that is. Otherwise we draw a star. // Draw a mini player! If we can, that is. Otherwise we draw a star.
// //
void V_DrawContinueIcon(INT32 x, INT32 y, INT32 flags, INT32 skinnum, UINT8 skincolor) void V_DrawContinueIcon(INT32 x, INT32 y, INT32 flags, INT32 skinnum, UINT16 skincolor)
{ {
if (skinnum >= 0 && skinnum < numskins && skins[skinnum].sprites[SPR2_XTRA].numframes > XTRA_CONTINUE) if (skinnum >= 0 && skinnum < numskins && skins[skinnum].sprites[SPR2_XTRA].numframes > XTRA_CONTINUE)
{ {
@ -2951,13 +2952,19 @@ void V_DrawPaddedTallNum(INT32 x, INT32 y, INT32 flags, INT32 num, INT32 digits)
} }
// Draw an act number for a level title // Draw an act number for a level title
// Todo: actually draw two-digit numbers as two act num patches void V_DrawLevelActNum(INT32 x, INT32 y, INT32 flags, UINT8 num)
void V_DrawLevelActNum(INT32 x, INT32 y, INT32 flags, INT32 num)
{ {
if (num < 0 || num > 19) if (num > 99)
return; // not supported return; // not supported
V_DrawScaledPatch(x, y, flags, ttlnum[num]); while (num > 0)
{
if (num > 9) // if there are two digits, draw second digit first
V_DrawScaledPatch(x + (V_LevelActNumWidth(num) - V_LevelActNumWidth(num%10)), y, flags, ttlnum[num%10]);
else
V_DrawScaledPatch(x, y, flags, ttlnum[num]);
num = num/10;
}
} }
// Write a string using the credit font // Write a string using the credit font
@ -3338,13 +3345,21 @@ INT32 V_LevelNameHeight(const char *string)
} }
// For ST_drawTitleCard // For ST_drawTitleCard
// Returns the width of the act num patch // Returns the width of the act num patch(es)
INT32 V_LevelActNumWidth(INT32 num) INT16 V_LevelActNumWidth(UINT8 num)
{ {
if (num < 0 || num > 19) INT16 result = 0;
return 0; // not a valid number
return SHORT(ttlnum[num]->width); if (num == 0)
result = SHORT(ttlnum[num]->width);
while (num > 0 && num <= 99)
{
result = result + SHORT(ttlnum[num%10]->width);
num = num/10;
}
return result;
} }
// //

View File

@ -160,7 +160,7 @@ void V_CubeApply(UINT8 *red, UINT8 *green, UINT8 *blue);
void V_DrawStretchyFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vscale, INT32 scrn, patch_t *patch, const UINT8 *colormap); void V_DrawStretchyFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vscale, INT32 scrn, patch_t *patch, const UINT8 *colormap);
void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_t *patch, fixed_t sx, fixed_t sy, fixed_t w, fixed_t h); void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_t *patch, fixed_t sx, fixed_t sy, fixed_t w, fixed_t h);
void V_DrawContinueIcon(INT32 x, INT32 y, INT32 flags, INT32 skinnum, UINT8 skincolor); void V_DrawContinueIcon(INT32 x, INT32 y, INT32 flags, INT32 skinnum, UINT16 skincolor);
// Draw a linear block of pixels into the view buffer. // Draw a linear block of pixels into the view buffer.
void V_DrawBlock(INT32 x, INT32 y, INT32 scrn, INT32 width, INT32 height, const UINT8 *src); void V_DrawBlock(INT32 x, INT32 y, INT32 scrn, INT32 width, INT32 height, const UINT8 *src);
@ -238,12 +238,12 @@ void V_DrawRightAlignedSmallThinStringAtFixed(fixed_t x, fixed_t y, INT32 option
// Draw tall nums, used for menu, HUD, intermission // Draw tall nums, used for menu, HUD, intermission
void V_DrawTallNum(INT32 x, INT32 y, INT32 flags, INT32 num); void V_DrawTallNum(INT32 x, INT32 y, INT32 flags, INT32 num);
void V_DrawPaddedTallNum(INT32 x, INT32 y, INT32 flags, INT32 num, INT32 digits); void V_DrawPaddedTallNum(INT32 x, INT32 y, INT32 flags, INT32 num, INT32 digits);
void V_DrawLevelActNum(INT32 x, INT32 y, INT32 flags, INT32 num); void V_DrawLevelActNum(INT32 x, INT32 y, INT32 flags, UINT8 num);
// Find string width from lt_font chars // Find string width from lt_font chars
INT32 V_LevelNameWidth(const char *string); INT32 V_LevelNameWidth(const char *string);
INT32 V_LevelNameHeight(const char *string); INT32 V_LevelNameHeight(const char *string);
INT32 V_LevelActNumWidth(INT32 num); // act number width INT16 V_LevelActNumWidth(UINT8 num); // act number width
void V_DrawCreditString(fixed_t x, fixed_t y, INT32 option, const char *string); void V_DrawCreditString(fixed_t x, fixed_t y, INT32 option, const char *string);
INT32 V_CreditStringWidth(const char *string); INT32 V_CreditStringWidth(const char *string);

View File

@ -76,6 +76,10 @@ int snprintf(char *str, size_t n, const char *fmt, ...);
//int vsnprintf(char *str, size_t n, const char *fmt, va_list ap); //int vsnprintf(char *str, size_t n, const char *fmt, va_list ap);
#endif #endif
#ifdef _DEBUG
#include "console.h"
#endif
#ifndef O_BINARY #ifndef O_BINARY
#define O_BINARY 0 #define O_BINARY 0
#endif #endif

View File

@ -54,6 +54,8 @@
#include "../screen.h" #include "../screen.h"
#include "../m_menu.h"
// Wheel support for Win95/WinNT3.51 // Wheel support for Win95/WinNT3.51
#include <zmouse.h> #include <zmouse.h>
@ -650,6 +652,7 @@ void I_Error(const char *error, ...)
G_StopMetalRecording(false); G_StopMetalRecording(false);
D_QuitNetGame(); D_QuitNetGame();
M_FreePlayerSetupColors();
// shutdown everything that was started // shutdown everything that was started
I_ShutdownSystem(); I_ShutdownSystem();
@ -746,6 +749,8 @@ void I_Quit(void)
// so do it before. // so do it before.
D_QuitNetGame(); D_QuitNetGame();
M_FreePlayerSetupColors();
// shutdown everything that was started // shutdown everything that was started
I_ShutdownSystem(); I_ShutdownSystem();
@ -3199,7 +3204,7 @@ INT32 I_GetKey(void)
// ----------------- // -----------------
#define DI_KEYBOARD_BUFFERSIZE 32 // number of data elements in keyboard buffer #define DI_KEYBOARD_BUFFERSIZE 32 // number of data elements in keyboard buffer
void I_StartupKeyboard(void) static void I_StartupKeyboard(void)
{ {
DIPROPDWORD dip; DIPROPDWORD dip;
@ -3435,6 +3440,8 @@ INT32 I_StartupSystem(void)
// some 'more global than globals' things to initialize here ? // some 'more global than globals' things to initialize here ?
graphics_started = keyboard_started = sound_started = cdaudio_started = false; graphics_started = keyboard_started = sound_started = cdaudio_started = false;
I_StartupKeyboard();
#ifdef NDEBUG #ifdef NDEBUG
#ifdef BUGTRAP #ifdef BUGTRAP

View File

@ -56,6 +56,7 @@ static consvar_t cv_stretch = {"stretch", "On", CV_SAVE|CV_NOSHOWHELP, CV_OnOff,
static consvar_t cv_ontop = {"ontop", "Never", 0, CV_NeverOnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; static consvar_t cv_ontop = {"ontop", "Never", 0, CV_NeverOnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
boolean highcolor; boolean highcolor;
int vid_opengl_state = 0;
static BOOL bDIBMode; // means we are using DIB instead of DirectDraw surfaces static BOOL bDIBMode; // means we are using DIB instead of DirectDraw surfaces
static LPBITMAPINFO bmiMain = NULL; static LPBITMAPINFO bmiMain = NULL;
@ -949,7 +950,10 @@ INT32 VID_SetMode(INT32 modenum)
} }
void VID_CheckRenderer(void) {} void VID_CheckRenderer(void) {}
void VID_CheckGLLoaded(rendermode_t oldrender) {} void VID_CheckGLLoaded(rendermode_t oldrender)
{
(void)oldrender;
}
// ======================================================================== // ========================================================================
// Free the video buffer of the last video mode, // Free the video buffer of the last video mode,

View File

@ -73,7 +73,7 @@ typedef union
UINT32 score, total; // fake score, total UINT32 score, total; // fake score, total
UINT32 tics; // time UINT32 tics; // time
INT32 actnum; // act number being displayed UINT8 actnum; // act number being displayed
patch_t *ptotal; // TOTAL patch_t *ptotal; // TOTAL
UINT8 gotlife; // Number of extra lives obtained UINT8 gotlife; // Number of extra lives obtained
} coop; } coop;
@ -99,7 +99,7 @@ typedef union
UINT8 continues; UINT8 continues;
patch_t *pcontinues; patch_t *pcontinues;
INT32 *playerchar; // Continue HUD INT32 *playerchar; // Continue HUD
UINT8 *playercolor; UINT16 *playercolor;
UINT8 gotlife; // Number of extra lives obtained UINT8 gotlife; // Number of extra lives obtained
} spec; } spec;
@ -107,7 +107,7 @@ typedef union
struct struct
{ {
UINT32 scores[MAXPLAYERS]; // Winner's score UINT32 scores[MAXPLAYERS]; // Winner's score
UINT8 *color[MAXPLAYERS]; // Winner's color # UINT16 *color[MAXPLAYERS]; // Winner's color #
boolean spectator[MAXPLAYERS]; // Spectator list boolean spectator[MAXPLAYERS]; // Spectator list
INT32 *character[MAXPLAYERS]; // Winner's character # INT32 *character[MAXPLAYERS]; // Winner's character #
INT32 num[MAXPLAYERS]; // Winner's player # INT32 num[MAXPLAYERS]; // Winner's player #
@ -121,7 +121,7 @@ typedef union
struct struct
{ {
UINT8 *color[MAXPLAYERS]; // Winner's color # UINT16 *color[MAXPLAYERS]; // Winner's color #
INT32 *character[MAXPLAYERS]; // Winner's character # INT32 *character[MAXPLAYERS]; // Winner's character #
INT32 num[MAXPLAYERS]; // Winner's player # INT32 num[MAXPLAYERS]; // Winner's player #
char name[MAXPLAYERS][9]; // Winner's name char name[MAXPLAYERS][9]; // Winner's name