Merge branch 'next' of https://git.magicalgirl.moe/STJr/SRB2 into gamequit-hook

This commit is contained in:
Zachary McAlpin 2020-05-29 15:32:59 -05:00
commit 7bdea21435
51 changed files with 1358 additions and 767 deletions

View file

@ -2597,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

View file

@ -195,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;
} }
// ----------------------------------------------------------------- // -----------------------------------------------------------------
@ -1495,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);
} }
@ -3293,7 +3294,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))
{ {
@ -3324,10 +3324,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';
}
} }
} }
@ -3883,7 +3888,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
@ -4005,8 +4010,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
@ -4258,15 +4263,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)
@ -4609,11 +4614,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
@ -4622,7 +4627,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));
@ -4665,7 +4670,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;

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;
@ -520,7 +521,7 @@ 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,9 @@ boolean advancedemo;
INT32 debugload = 0; INT32 debugload = 0;
#endif #endif
UINT16 numskincolors;
menucolor_t *menucolorhead, *menucolortail;
char savegamename[256]; char savegamename[256];
char srb2home[256] = "."; char srb2home[256] = ".";
@ -1191,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

@ -838,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);
@ -857,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..
@ -619,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;
@ -1221,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])
@ -1276,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
@ -1317,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);
} }
@ -1344,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();
@ -1405,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;
@ -1428,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)
@ -1447,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
@ -1455,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]))
@ -1474,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
@ -4478,25 +4490,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
@ -4507,18 +4524,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

@ -366,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)
{ {
@ -3952,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"))
{ {
@ -4556,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
@ -9000,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,
@ -9437,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},
@ -9939,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;
@ -10233,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);
@ -10301,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;
@ -10372,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
} }
@ -10481,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...
@ -10812,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

@ -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().

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;

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:

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;
@ -2381,7 +2383,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;
@ -4475,7 +4477,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)

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

@ -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

@ -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

@ -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"
@ -21616,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)
@ -21645,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;
} }
@ -21653,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)
@ -21663,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));
@ -21684,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
} }
@ -21716,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

@ -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
////////////// //////////////
@ -2388,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;
} }
@ -3128,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},

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

@ -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;
} }

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

@ -756,6 +756,7 @@ enum
ARCH_FFLOOR, ARCH_FFLOOR,
ARCH_SLOPE, ARCH_SLOPE,
ARCH_MAPHEADER, ARCH_MAPHEADER,
ARCH_SKINCOLOR,
ARCH_TEND=0xFF, ARCH_TEND=0xFF,
}; };
@ -781,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}
}; };
@ -1068,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;
@ -1299,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

@ -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

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

@ -7548,7 +7548,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++;
} }
@ -8216,13 +8216,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];
} }
} }
@ -9058,7 +9058,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;
@ -9097,7 +9097,7 @@ 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, GTC_CACHE); colormap = R_GetTranslationColormap(TC_DEFAULT, col, GTC_CACHE);
@ -9148,8 +9148,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;
@ -9160,7 +9160,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;
@ -9199,7 +9199,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)
@ -9229,7 +9229,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)
@ -11079,15 +11079,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)
{ {
@ -11154,11 +11154,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;
@ -11204,11 +11204,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);
@ -11218,25 +11218,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
@ -11247,7 +11261,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),
@ -11295,19 +11309,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 */
@ -11328,7 +11342,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;
@ -11344,11 +11358,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;
@ -11376,10 +11392,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)
{ {
@ -11411,7 +11431,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))
@ -11452,7 +11475,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))
@ -11484,12 +11510,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
// ================= // =================

View file

@ -355,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
@ -443,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

@ -5106,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
@ -5143,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;
} }
@ -5181,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)
@ -5212,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;
} }
@ -8804,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
@ -8831,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
@ -8850,7 +8839,7 @@ void A_Dye(mobj_t *actor)
UINT8 color = (UINT8)locvar2; UINT8 color = (UINT8)locvar2;
if (LUA_CallAction("A_Dye", actor)) if (LUA_CallAction("A_Dye", actor))
return; return;
if (color >= MAXTRANSLATIONS) if (color >= numskincolors)
return; return;
if (!color) if (!color)

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;

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
@ -9429,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))
@ -10636,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;
@ -11916,7 +11916,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)
{ {
@ -11939,7 +11939,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))
@ -12578,7 +12578,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);\

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).

View file

@ -1593,7 +1593,7 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
if (diff2 & MD2_SKIN) if (diff2 & MD2_SKIN)
WRITEUINT8(save_p, (UINT8)((skin_t *)mobj->skin - skins)); WRITEUINT8(save_p, (UINT8)((skin_t *)mobj->skin - skins));
if (diff2 & MD2_COLOR) if (diff2 & MD2_COLOR)
WRITEUINT8(save_p, mobj->color); WRITEUINT16(save_p, mobj->color);
if (diff2 & MD2_EXTVAL1) if (diff2 & MD2_EXTVAL1)
WRITEINT32(save_p, mobj->extravalue1); WRITEINT32(save_p, mobj->extravalue1);
if (diff2 & MD2_EXTVAL2) if (diff2 & MD2_EXTVAL2)
@ -2600,7 +2600,7 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker)
if (diff2 & MD2_SKIN) if (diff2 & MD2_SKIN)
mobj->skin = &skins[READUINT8(save_p)]; mobj->skin = &skins[READUINT8(save_p)];
if (diff2 & MD2_COLOR) if (diff2 & MD2_COLOR)
mobj->color = READUINT8(save_p); mobj->color = READUINT16(save_p);
if (diff2 & MD2_EXTVAL1) if (diff2 & MD2_EXTVAL1)
mobj->extravalue1 = READINT32(save_p); mobj->extravalue1 = READINT32(save_p);
if (diff2 & MD2_EXTVAL2) if (diff2 & MD2_EXTVAL2)

View file

@ -3971,7 +3971,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
if (mo) if (mo)
{ {
if (color < 0 || color >= MAXTRANSLATIONS) if (color < 0 || color >= numskincolors)
return; return;
var1 = 0; var1 = 0;
@ -7065,6 +7065,9 @@ void P_SpawnSpecials(boolean fromnetsave)
// 503 is used for a scroller // 503 is used for a scroller
// 504 is used for a scroller // 504 is used for a scroller
// 505 is used for a scroller // 505 is used for a scroller
// 506 is used for a scroller
// 507 is used for a scroller
// 508 is used for a scroller
// 510 is used for a scroller // 510 is used for a scroller
// 511 is used for a scroller // 511 is used for a scroller
// 512 is used for a scroller // 512 is used for a scroller
@ -7581,7 +7584,20 @@ static void P_SpawnScrollers(void)
case 502: case 502:
for (s = -1; (s = P_FindLineFromTag(l->tag, s)) >= 0 ;) for (s = -1; (s = P_FindLineFromTag(l->tag, s)) >= 0 ;)
if (s != (INT32)i) if (s != (INT32)i)
Add_Scroller(sc_side, dx, dy, control, lines[s].sidenum[0], accel, 0); {
if (l->flags & ML_EFFECT2) // use texture offsets instead
{
dx = sides[l->sidenum[0]].textureoffset;
dy = sides[l->sidenum[0]].rowoffset;
}
if (l->flags & ML_EFFECT3)
{
if (lines[s].sidenum[1] != 0xffff)
Add_Scroller(sc_side, dx, dy, control, lines[s].sidenum[1], accel, 0);
}
else
Add_Scroller(sc_side, dx, dy, control, lines[s].sidenum[0], accel, 0);
}
break; break;
case 505: case 505:
@ -7595,7 +7611,25 @@ static void P_SpawnScrollers(void)
if (s != 0xffff) if (s != 0xffff)
Add_Scroller(sc_side, -sides[s].textureoffset, sides[s].rowoffset, -1, lines[i].sidenum[0], accel, 0); Add_Scroller(sc_side, -sides[s].textureoffset, sides[s].rowoffset, -1, lines[i].sidenum[0], accel, 0);
else else
CONS_Debug(DBG_GAMELOGIC, "Line special 506 (line #%s) missing 2nd side!\n", sizeu1(i)); CONS_Debug(DBG_GAMELOGIC, "Line special 506 (line #%s) missing back side!\n", sizeu1(i));
break;
case 507:
s = lines[i].sidenum[0];
if (lines[i].sidenum[1] != 0xffff)
Add_Scroller(sc_side, -sides[s].textureoffset, sides[s].rowoffset, -1, lines[i].sidenum[1], accel, 0);
else
CONS_Debug(DBG_GAMELOGIC, "Line special 507 (line #%s) missing back side!\n", sizeu1(i));
break;
case 508:
s = lines[i].sidenum[1];
if (s != 0xffff)
Add_Scroller(sc_side, -sides[s].textureoffset, sides[s].rowoffset, -1, s, accel, 0);
else
CONS_Debug(DBG_GAMELOGIC, "Line special 508 (line #%s) missing back side!\n", sizeu1(i));
break; break;
case 500: // scroll first side case 500: // scroll first side

View file

@ -1916,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)
@ -2986,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);

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

@ -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

@ -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();

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;
@ -1700,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};*/
@ -1716,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,
@ -1724,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,
@ -1735,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

@ -1040,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)
{ {

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);

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();

View file

@ -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