diff --git a/CMakeLists.txt b/CMakeLists.txt index abec11087..1e46f5dc3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.0) # DO NOT CHANGE THIS SRB2 STRING! Some variable names depend on this string. # Version change is fine. project(SRB2 - VERSION 2.2.2 + VERSION 2.2.4 LANGUAGES C) if(${PROJECT_SOURCE_DIR} MATCHES ${PROJECT_BINARY_DIR}) diff --git a/appveyor.yml b/appveyor.yml index a28935f63..5d599a516 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -version: 2.2.2.{branch}-{build} +version: 2.2.4.{branch}-{build} os: MinGW environment: diff --git a/extras/conf/SRB2-22.cfg b/extras/conf/SRB2-22.cfg index ea783908a..5ed05d4d6 100644 --- a/extras/conf/SRB2-22.cfg +++ b/extras/conf/SRB2-22.cfg @@ -750,16 +750,11 @@ linedeftypes prefix = "(20)"; } - 21 - { - title = "Explicitly Include Line "; - prefix = "(21)"; - } - 22 { title = "Parameters"; prefix = "(22)"; + flags8text = "[3] Set translucency by X offset"; flags32text = "[5] Render outer sides only"; flags64text = "[6] Trigger linedef executor"; flags128text = "[7] Intangible"; @@ -1908,6 +1903,27 @@ linedeftypes prefix = "(333)"; } + 334 + { + title = "Object Dye - Continuous"; + flags64text = "[6] Disable for this color"; + prefix = "(334)"; + } + + 335 + { + title = "Object Dye - Each Time"; + flags64text = "[6] Disable for this color"; + prefix = "(335)"; + } + + 336 + { + title = "Object Dye - Once"; + flags64text = "[6] Disable for this color"; + prefix = "(336)"; + } + 399 { title = "Level Load"; @@ -2218,6 +2234,19 @@ linedeftypes prefix = "(462)"; flags8text = "[3] Set delay by backside sector"; } + + 463 + { + title = "Dye Object"; + prefix = "(463)"; + } + + 464 + { + title = "Trigger Egg Capsule"; + prefix = "(464)"; + flags64text = "[6] Don't end level"; + } } linedefexecmisc @@ -2568,45 +2597,63 @@ linedeftypes 500 { - title = "Scroll Wall Front Side Left"; + title = "Scroll Front Wall Left"; prefix = "(500)"; } 501 { - title = "Scroll Wall Front Side Right"; + title = "Scroll Front Wall Right"; prefix = "(501)"; } 502 { - title = "Scroll Wall According to Linedef"; + title = "Scroll Tagged Wall"; prefix = "(502)"; + flags128text = "[7] Use texture offsets"; + flags256text = "[8] Scroll back side"; } 503 { - title = "Scroll Wall According to Linedef (Accelerative)"; + title = "Scroll Tagged Wall (Accelerative)"; prefix = "(503)"; + flags128text = "[7] Use texture offsets"; + flags256text = "[8] Scroll back side"; } 504 { - title = "Scroll Wall According to Linedef (Displacement)"; + title = "Scroll Tagged Wall (Displacement)"; prefix = "(504)"; + flags128text = "[7] Use texture offsets"; + flags256text = "[8] Scroll back side"; } 505 { - title = "Scroll Texture by Front Side Offsets"; + title = "Scroll Front Wall by Front Side Offsets"; prefix = "(505)"; } 506 { - title = "Scroll Texture by Back Side Offsets"; + title = "Scroll Front Wall by Back Side Offsets"; 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 @@ -3704,6 +3751,7 @@ thingtypes width = 8; height = 16; sprite = "internal:capsule"; + angletext = "Tag"; } 292 { diff --git a/src/am_map.c b/src/am_map.c index cdbaaf80a..53a7480a5 100644 --- a/src/am_map.c +++ b/src/am_map.c @@ -931,11 +931,8 @@ static inline void AM_drawWalls(void) l.b.y = lines[i].v2->y >> FRACTOMAPBITS; #define SLOPEPARAMS(slope, end1, end2, normalheight) \ - if (slope) { \ - end1 = P_GetZAt(slope, lines[i].v1->x, lines[i].v1->y); \ - end2 = P_GetZAt(slope, lines[i].v2->x, lines[i].v2->y); \ - } else \ - end1 = end2 = normalheight; + end1 = P_GetZAt(slope, lines[i].v1->x, lines[i].v1->y, normalheight); \ + end2 = P_GetZAt(slope, lines[i].v2->x, lines[i].v2->y, normalheight); SLOPEPARAMS(lines[i].frontsector->f_slope, frontf1, frontf2, lines[i].frontsector->floorheight) SLOPEPARAMS(lines[i].frontsector->c_slope, frontc1, frontc2, lines[i].frontsector->ceilingheight) diff --git a/src/b_bot.c b/src/b_bot.c index 9a4c20c17..4397938c1 100644 --- a/src/b_bot.c +++ b/src/b_bot.c @@ -459,7 +459,6 @@ boolean B_CheckRespawn(player_t *player) if (!sonic || sonic->health <= 0) return false; -#ifdef HAVE_BLUA // B_RespawnBot doesn't do anything if the condition above this isn't met { UINT8 shouldForce = LUAh_BotRespawn(sonic, tails); @@ -472,7 +471,6 @@ boolean B_CheckRespawn(player_t *player) else if (shouldForce == 2) return false; } -#endif // Check if Sonic is busy first. // If he's doing any of these things, he probably doesn't want to see us. diff --git a/src/config.h.in b/src/config.h.in index 4926f9a06..3b2579965 100644 --- a/src/config.h.in +++ b/src/config.h.in @@ -28,12 +28,14 @@ /* Manually defined asset hashes for non-CMake builds * Last updated 2020 / 02 / 15 - v2.2.1 - main assets * Last updated 2020 / 02 / 22 - v2.2.2 - patch.pk3 + * Last updated 2020 / 05 / 10 - v2.2.3 - player.dta & patch.pk3 + * Last updated 2020 / 05 / 11 - v2.2.4 - patch.pk3 */ #define ASSET_HASH_SRB2_PK3 "0277c9416756627004e83cbb5b2e3e28" #define ASSET_HASH_ZONES_PK3 "f7e88afb6af7996a834c7d663144bead" -#define ASSET_HASH_PLAYER_DTA "ad49e07b17cc662f1ad70c454910b4ae" +#define ASSET_HASH_PLAYER_DTA "8a4507ddf9bc0682c09174400f26ad65" #ifdef USE_PATCH_DTA -#define ASSET_HASH_PATCH_PK3 "ee54330ecb743314c5f962af4db731ff" +#define ASSET_HASH_PATCH_PK3 "bbbf6af3b20349612ee06e0b55979a76" #endif #endif diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 3603bb20d..a85508d11 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -85,6 +85,10 @@ tic_t jointimeout = (10*TICRATE); static boolean sendingsavegame[MAXNETNODES]; // Are we sending the savegame? static tic_t freezetimeout[MAXNETNODES]; // Until when can this node freeze the server before getting a timeout? +// Incremented by cv_joindelay when a client joins, decremented each tic. +// If higher than cv_joindelay * 2 (3 joins in a short timespan), joins are temporarily disabled. +static tic_t joindelay = 0; + UINT16 pingmeasurecount = 1; UINT32 realpingtable[MAXPLAYERS]; //the base table of ping where an average will be sent to everyone. UINT32 playerpingtable[MAXPLAYERS]; //table of player latency values. @@ -191,24 +195,25 @@ static inline void *G_ScpyTiccmd(ticcmd_t* dest, void* src, const size_t n) // of 512 bytes is like 0.1) 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 node The node to deduce the tic for * \return The full tic value * */ -tic_t ExpandTics(INT32 low) +tic_t ExpandTics(INT32 low, INT32 node) { INT32 delta; - delta = low - (maketic & UINT8_MAX); + delta = low - (nettics[node] & UINT8_MAX); if (delta >= -64 && delta <= 64) - return (maketic & ~UINT8_MAX) + low; + return (nettics[node] & ~UINT8_MAX) + low; else if (delta > 64) - return (maketic & ~UINT8_MAX) - 256 + low; + return (nettics[node] & ~UINT8_MAX) - 256 + low; else //if (delta < -64) - return (maketic & ~UINT8_MAX) + 256 + low; + return (nettics[node] & ~UINT8_MAX) + 256 + low; } // ----------------------------------------------------------------- @@ -1491,7 +1496,7 @@ static boolean SV_SendServerConfig(INT32 node) if (!playeringame[i]) continue; 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); } @@ -1686,7 +1691,7 @@ static void CL_LoadReceivedSavegame(void) // load a base level if (P_LoadNetGame()) { - const INT32 actnum = mapheaderinfo[gamemap-1]->actnum; + const UINT8 actnum = mapheaderinfo[gamemap-1]->actnum; CONS_Printf(M_GetText("Map is now \"%s"), G_BuildMapName(gamemap)); if (strcmp(mapheaderinfo[gamemap-1]->lvlttl, "")) { @@ -3077,6 +3082,8 @@ consvar_t cv_allownewplayer = {"allowjoin", "On", CV_NETVAR, CV_OnOff, NULL, 0, consvar_t cv_joinnextround = {"joinnextround", "Off", CV_NETVAR, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; /// \todo not done static CV_PossibleValue_t maxplayers_cons_t[] = {{2, "MIN"}, {32, "MAX"}, {0, NULL}}; consvar_t cv_maxplayers = {"maxplayers", "8", CV_SAVE, maxplayers_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +static CV_PossibleValue_t joindelay_cons_t[] = {{1, "MIN"}, {3600, "MAX"}, {0, "Off"}, {0, NULL}}; +consvar_t cv_joindelay = {"joindelay", "10", CV_SAVE, joindelay_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; static CV_PossibleValue_t rejointimeout_cons_t[] = {{1, "MIN"}, {60 * FRACUNIT, "MAX"}, {0, "Off"}, {0, NULL}}; consvar_t cv_rejointimeout = {"rejointimeout", "Off", CV_SAVE|CV_FLOAT, rejointimeout_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -3164,6 +3171,8 @@ void SV_ResetServer(void) neededtic = maketic; tictoclear = maketic; + joindelay = 0; + for (i = 0; i < MAXNETNODES; i++) ResetNode(i); @@ -3283,7 +3292,6 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum) boolean splitscreenplayer; boolean rejoined; player_t *newplayer; - char *port; if (playernum != serverplayer && !IsPlayerAdmin(playernum)) { @@ -3314,10 +3322,15 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum) if (server && I_GetNodeAddress) { - strcpy(playeraddress[newplayernum], I_GetNodeAddress(node)); - port = strchr(playeraddress[newplayernum], ':'); - if (port) - *port = '\0'; + const char *address = I_GetNodeAddress(node); + char *port = NULL; + if (address) // MI: fix msvcrt.dll!_mbscat crash? + { + strcpy(playeraddress[newplayernum], address); + port = strchr(playeraddress[newplayernum], ':'); + if (port) + *port = '\0'; + } } } @@ -3613,6 +3626,9 @@ static void HandleConnect(SINT8 node) SV_SendRefuse(node, M_GetText("No players from\nthis node.")); else if (luafiletransfers) SV_SendRefuse(node, M_GetText("The server is broadcasting a file\nrequested by a Lua script.\nPlease wait a bit and then\ntry rejoining.")); + else if (netgame && joindelay > 2 * (tic_t)cv_joindelay.value * TICRATE) + SV_SendRefuse(node, va(M_GetText("Too many people are connecting.\nPlease wait %d seconds and then\ntry rejoining."), + (joindelay - 2 * cv_joindelay.value * TICRATE) / TICRATE)); else { #ifndef NONET @@ -3670,6 +3686,7 @@ static void HandleConnect(SINT8 node) DEBFILE("send savegame\n"); } SV_AddWaitingPlayers(names[0], names[1]); + joindelay += cv_joindelay.value * TICRATE; player_joining = true; } #else @@ -3865,7 +3882,7 @@ static void HandlePacketFromAwayNode(SINT8 node) for (j = 0; j < MAXPLAYERS; j++) { 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) continue; // not in game @@ -3987,8 +4004,8 @@ static void HandlePacketFromPlayer(SINT8 node) // To save bytes, only the low byte of tic numbers are sent // Use ExpandTics to figure out what the rest of the bytes are - realstart = ExpandTics(netbuffer->u.clientpak.client_tic); - realend = ExpandTics(netbuffer->u.clientpak.resendfrom); + realstart = ExpandTics(netbuffer->u.clientpak.client_tic, node); + realend = ExpandTics(netbuffer->u.clientpak.resendfrom, node); if (netbuffer->packettype == PT_CLIENTMIS || netbuffer->packettype == PT_CLIENT2MIS || netbuffer->packettype == PT_NODEKEEPALIVEMIS @@ -4240,15 +4257,15 @@ static void HandlePacketFromPlayer(SINT8 node) break; } - realstart = ExpandTics(netbuffer->u.serverpak.starttic); + realstart = netbuffer->u.serverpak.starttic; realend = realstart + netbuffer->u.serverpak.numtics; if (!txtpak) txtpak = (UINT8 *)&netbuffer->u.serverpak.cmds[netbuffer->u.serverpak.numslots * netbuffer->u.serverpak.numtics]; - if (realend > gametic + BACKUPTICS) - realend = gametic + BACKUPTICS; + if (realend > gametic + CLIENTBACKUPTICS) + realend = gametic + CLIENTBACKUPTICS; cl_packetmissed = realstart > neededtic; if (realstart <= neededtic && realend > neededtic) @@ -4591,11 +4608,11 @@ static void SV_SendTics(void) for (n = 1; n < MAXNETNODES; n++) if (nodeingame[n]) { - lasttictosend = maketic; - // assert supposedtics[n]>=nettics[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 // to resent packet that are supposed lost (this is necessary since lost @@ -4604,7 +4621,7 @@ static void SV_SendTics(void) DEBFILE(va("Nothing to send node %u mak=%u sup=%u net=%u \n", n, maketic, supposedtics[n], nettics[n])); realfirsttic = nettics[n]; - if (realfirsttic >= maketic || (I_GetTime() + n)&3) + if (realfirsttic >= lasttictosend || (I_GetTime() + n)&3) // all tic are ok continue; DEBFILE(va("Sent %d anyway\n", realfirsttic)); @@ -4647,7 +4664,7 @@ static void SV_SendTics(void) // Send the tics 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.numslots = (UINT8)SHORT(doomcom->numslots); bufpos = (UINT8 *)&netbuffer->u.serverpak.cmds; @@ -5038,12 +5055,21 @@ void NetUpdate(void) hu_resynching = true; } } + Net_AckTicker(); + // Handle timeouts to prevent definitive freezes from happenning if (server) + { for (i = 1; i < MAXNETNODES; i++) if (nodeingame[i] && freezetimeout[i] < I_GetTime()) Net_ConnectionTimeout(i); + + // In case the cvar value was lowered + if (joindelay) + joindelay = min(joindelay - 1, 3 * (tic_t)cv_joindelay.value * TICRATE); + } + nowtime /= NEWTICRATERATIO; if (nowtime > resptime) { @@ -5051,6 +5077,7 @@ void NetUpdate(void) M_Ticker(); CON_Ticker(); } + SV_FileSendTicker(); } diff --git a/src/d_clisrv.h b/src/d_clisrv.h index 7e5061ff2..aed1cddb1 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -34,6 +34,7 @@ applications may follow different packet versions. // Networking and tick handling related. #define BACKUPTICS 96 +#define CLIENTBACKUPTICS 32 #define MAXTEXTCMD 256 // // Packet structure @@ -128,7 +129,7 @@ typedef struct // this packet is too large typedef struct { - UINT8 starttic; + tic_t starttic; UINT8 numtics; UINT8 numslots; // "Slots filled": Highest player number in use plus one. ticcmd_t cmds[45]; // Normally [BACKUPTIC][MAXPLAYERS] but too large @@ -188,7 +189,7 @@ typedef struct SINT8 xtralife; SINT8 pity; - UINT8 skincolor; + UINT16 skincolor; INT32 skin; UINT32 availabilities; // Just in case Lua does something like @@ -308,7 +309,7 @@ typedef struct // 0xFF == not in game; else player skin num UINT8 playerskins[MAXPLAYERS]; - UINT8 playercolor[MAXPLAYERS]; + UINT16 playercolor[MAXPLAYERS]; UINT32 playeravailabilities[MAXPLAYERS]; UINT8 gametype; @@ -414,7 +415,7 @@ typedef struct { char name[MAXPLAYERNAME+1]; UINT8 skin; - UINT8 color; + UINT16 color; UINT32 pflags; UINT32 score; UINT8 ctfteam; @@ -515,12 +516,12 @@ extern UINT32 realpingtable[MAXPLAYERS]; extern UINT32 playerpingtable[MAXPLAYERS]; extern tic_t servermaxping; -extern consvar_t cv_allownewplayer, cv_joinnextround, cv_maxplayers, cv_rejointimeout; +extern consvar_t cv_allownewplayer, cv_joinnextround, cv_maxplayers, cv_joindelay, cv_rejointimeout; extern consvar_t cv_resynchattempts, cv_blamecfail; extern consvar_t cv_maxsend, cv_noticedownload, cv_downloadspeed; // Used in d_net, the only dependence -tic_t ExpandTics(INT32 low); +tic_t ExpandTics(INT32 low, INT32 node); void D_ClientServerInit(void); // Initialise the other field diff --git a/src/d_main.c b/src/d_main.c index 00aeb541d..2e5519c83 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -125,6 +125,11 @@ boolean advancedemo; INT32 debugload = 0; #endif +UINT16 numskincolors; +menucolor_t *menucolorhead, *menucolortail; + +char savegamename[256]; + char srb2home[256] = "."; char srb2path[256] = "."; boolean usehome = true; @@ -310,7 +315,9 @@ static void D_Display(void) F_WipeStartScreen(); // Check for Mega Genesis fade wipestyleflags = WSF_FADEOUT; - if (F_TryColormapFade(31)) + if (wipegamestate == (gamestate_t)FORCEWIPE) + F_WipeColorFill(31); + else if (F_TryColormapFade(31)) wipetypepost = -1; // Don't run the fade below this one F_WipeEndScreen(); F_RunWipe(wipetypepre, gamestate != GS_TIMEATTACK && gamestate != GS_TITLESCREEN); @@ -991,6 +998,7 @@ static void IdentifyVersion(void) } MUSICTEST("music.dta") + MUSICTEST("patch_music.pk3") #ifdef DEVELOP // remove when music_new.dta is merged into music.dta MUSICTEST("music_new.dta") #endif @@ -1186,6 +1194,10 @@ void D_SRB2Main(void) if (M_CheckParm("-password") && M_IsNextParm()) 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"); Z_Init(); diff --git a/src/d_net.c b/src/d_net.c index 1db75f3da..8e62b8d25 100644 --- a/src/d_net.c +++ b/src/d_net.c @@ -811,6 +811,7 @@ static const char *packettypename[NUMPACKETTYPE] = "CLIENTJOIN", "NODETIMEOUT", "RESYNCHING", + "LOGIN", "PING" }; @@ -837,7 +838,7 @@ static void DebugPrintpacket(const char *header) size_t ntxtcmd = &((UINT8 *)netbuffer)[doomcom->datalength] - cmd; 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 fprintfstringnewline((char *)cmd, ntxtcmd); /*fprintfstring((char *)cmd, 3); @@ -856,8 +857,8 @@ static void DebugPrintpacket(const char *header) case PT_NODEKEEPALIVE: case PT_NODEKEEPALIVEMIS: fprintf(debugfile, " tic %4u resendfrom %u\n", - (UINT32)ExpandTics(netbuffer->u.clientpak.client_tic), - (UINT32)ExpandTics (netbuffer->u.clientpak.resendfrom)); + (UINT32)ExpandTics(netbuffer->u.clientpak.client_tic, doomcom->remotenode), + (UINT32)ExpandTics (netbuffer->u.clientpak.resendfrom, doomcom->remotenode)); break; case PT_TEXTCMD: case PT_TEXTCMD2: diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 1fd53499a..84070135a 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -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_playername2 = {"name2", "Tails", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Name2_OnChange, 0, NULL, NULL, 0, 0, NULL}; // 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_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.. @@ -573,6 +574,7 @@ void D_RegisterServerCommands(void) // d_clisrv CV_RegisterVar(&cv_maxplayers); + CV_RegisterVar(&cv_joindelay); CV_RegisterVar(&cv_rejointimeout); CV_RegisterVar(&cv_resynchattempts); CV_RegisterVar(&cv_maxsend); @@ -618,7 +620,7 @@ void D_RegisterClientCommands(void) for (i = 0; i < MAXSKINCOLORS; 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].strvalue = NULL; @@ -1220,15 +1222,20 @@ static void SendNameAndColor(void) CV_StealthSetValue(&cv_playercolor, skincolor_blueteam); } - // never allow the color "none" - if (!cv_playercolor.value) + // don't allow inaccessible colors + 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); - else if (skins[players[consoleplayer].skin].prefcolor) - CV_StealthSetValue(&cv_playercolor, skins[players[consoleplayer].skin].prefcolor); - else + else if (skincolors[atoi(cv_playercolor.defaultvalue)].accessible) 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 (icolor = (UINT8)players[consoleplayer].skincolor; + players[consoleplayer].mo->color = (UINT16)players[consoleplayer].skincolor; }*/ } else @@ -1316,7 +1323,7 @@ static void SendNameAndColor(void) // Finally write out the complete packet and send it off. WRITESTRINGN(p, cv_playername.zstring, MAXPLAYERNAME); WRITEUINT32(p, (UINT32)players[consoleplayer].availabilities); - WRITEUINT8(p, (UINT8)cv_playercolor.value); + WRITEUINT16(p, (UINT16)cv_playercolor.value); WRITEUINT8(p, (UINT8)cv_skin.value); SendNetXCmd(XD_NAMEANDCOLOR, buf, p - buf); } @@ -1343,15 +1350,20 @@ static void SendNameAndColor2(void) CV_StealthSetValue(&cv_playercolor2, skincolor_blueteam); } - // never allow the color "none" - if (!cv_playercolor2.value) + // don't allow inaccessible colors + 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); - 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); - else - CV_StealthSet(&cv_playercolor2, cv_playercolor2.defaultvalue); + else { + UINT16 i = 0; + while (icolor = players[secondplaya].skincolor; @@ -1427,7 +1439,8 @@ static void Got_NameAndColor(UINT8 **cp, INT32 playernum) { player_t *p = &players[playernum]; char name[MAXPLAYERNAME+1]; - UINT8 color, skin; + UINT16 color; + UINT8 skin; #ifdef PARANOIA if (playernum < 0 || playernum > MAXPLAYERS) @@ -1446,7 +1459,7 @@ static void Got_NameAndColor(UINT8 **cp, INT32 playernum) READSTRINGN(*cp, name, MAXPLAYERNAME); p->availabilities = READUINT32(*cp); - color = READUINT8(*cp); + color = READUINT16(*cp); skin = READUINT8(*cp); // set name @@ -1454,9 +1467,9 @@ static void Got_NameAndColor(UINT8 **cp, INT32 playernum) SetPlayerName(playernum, name); // set color - p->skincolor = color % MAXSKINCOLORS; + p->skincolor = color % numskincolors; if (p->mo) - p->mo->color = (UINT8)p->skincolor; + p->mo->color = (UINT16)p->skincolor; // normal player colors if (server && (p != &players[consoleplayer] && p != &players[secondarydisplayplayer])) @@ -1473,8 +1486,8 @@ static void Got_NameAndColor(UINT8 **cp, INT32 playernum) kick = true; } - // don't allow color "none" - if (!p->skincolor) + // don't allow inaccessible colors + if (skincolors[p->skincolor].accessible == false) kick = true; // availabilities @@ -4472,25 +4485,30 @@ static void Skin2_OnChange(void) */ static void Color_OnChange(void) { - if (!Playing()) - return; // do whatever you want - - 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(); + if (!Playing()) { + if (!cv_playercolor.value || !skincolors[cv_playercolor.value].accessible) + CV_StealthSetValue(&cv_playercolor, lastgoodcolor); } else { - CV_StealthSetValue(&cv_playercolor, - players[consoleplayer].skincolor); + if (!(cv_debug || devparm) && !(multiplayer || netgame)) // In single player. + { + 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 @@ -4501,18 +4519,24 @@ static void Color_OnChange(void) static void Color2_OnChange(void) { if (!Playing() || !splitscreen) - return; // do whatever you want - - if (!P_PlayerMoving(secondarydisplayplayer)) { - // Color change menu scrolling fix is no longer necessary - SendNameAndColor2(); + if (!cv_playercolor2.value || !skincolors[cv_playercolor2.value].accessible) + CV_StealthSetValue(&cv_playercolor2, lastgoodcolor2); } else { - CV_StealthSetValue(&cv_playercolor2, - players[secondarydisplayplayer].skincolor); + if (!P_PlayerMoving(secondarydisplayplayer) && skincolors[players[secondarydisplayplayer].skincolor].accessible == true) + { + // 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. diff --git a/src/d_player.h b/src/d_player.h index 8697e9836..0f1031708 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -239,7 +239,8 @@ typedef enum CR_MACESPIN, CR_MINECART, CR_ROLLOUT, - CR_PTERABYTE + CR_PTERABYTE, + CR_DUSTDEVIL } carrytype_t; // pw_carry // Player powers. (don't edit this comment) @@ -365,7 +366,7 @@ typedef struct player_s UINT16 flashpal; // Player skin colorshift, 0-15 for which color to draw player. - UINT8 skincolor; + UINT16 skincolor; INT32 skin; UINT32 availabilities; diff --git a/src/dehacked.c b/src/dehacked.c index e9d029be0..627a3a119 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -56,10 +56,12 @@ int vsnprintf(char *str, size_t n, const char *fmt, va_list ap); // The crazy word-reading stuff uses these. static char *FREE_STATES[NUMSTATEFREESLOTS]; 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. #define initfreeslots() {\ memset(FREE_STATES,0,sizeof(char *) * NUMSTATEFREESLOTS);\ memset(FREE_MOBJS,0,sizeof(char *) * NUMMOBJFREESLOTS);\ +memset(FREE_SKINCOLORS,0,sizeof(char *) * NUMCOLORFREESLOTS);\ 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 INT16 get_gametype(const char *word); //static powertype_t get_power(const char *word); +skincolornum_t get_skincolor(const char *word); boolean deh_loaded = false; static int dbg_line; @@ -449,7 +452,7 @@ static void readPlayer(MYFILE *f, INT32 num) else if (fastcmp(word, "OPPOSITECOLOR") || fastcmp(word, "OPPOSITECOLOUR")) { SLOTFOUND - description[num].oppositecolor = (UINT8)get_number(word2); + description[num].oppositecolor = (UINT16)get_number(word2); } 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")) { SLOTFOUND - description[num].tagtextcolor = (UINT8)get_number(word2); + description[num].tagtextcolor = (UINT16)get_number(word2); } else if (fastcmp(word, "TAGOUTLINECOLOR") || fastcmp(word, "TAGOUTLINECOLOUR")) { SLOTFOUND - description[num].tagoutlinecolor = (UINT8)get_number(word2); + description[num].tagoutlinecolor = (UINT16)get_number(word2); } else if (fastcmp(word, "STATUS")) { @@ -571,6 +574,16 @@ static void readfreeslots(MYFILE *f) 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")) { // Search if we already have an SPR2 by that name... @@ -753,6 +766,84 @@ static void readthing(MYFILE *f, INT32 num) 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 static void readlight(MYFILE *f, INT32 num) { @@ -1557,7 +1648,7 @@ static void readlevelheader(MYFILE *f, INT32 num) } else if (fastcmp(word, "ACT")) { - if (i >= 0 && i < 20) // 0 for no act number, TTL1 through TTL19 + if (i >= 0 && i <= 99) // 0 for no act number mapheaderinfo[num-1]->actnum = (UINT8)i; else deh_warning("Level header %d: invalid act number %d", num, i); @@ -1863,6 +1954,12 @@ static void readlevelheader(MYFILE *f, INT32 num) } else if (fastcmp(word, "STARTRINGS")) mapheaderinfo[num-1]->startrings = (UINT16)i; + else if (fastcmp(word, "SPECIALSTAGETIME")) + mapheaderinfo[num-1]->sstimer = i; + else if (fastcmp(word, "SPECIALSTAGESPHERES")) + mapheaderinfo[num-1]->ssspheres = i; + else if (fastcmp(word, "GRAVITY")) + mapheaderinfo[num-1]->gravity = FLOAT_TO_FIXED(atof(word2)); else deh_warning("Level header %d: unknown word '%s'", num, word); } @@ -2807,7 +2904,7 @@ static actionpointer_t actionpointers[] = {{A_ThrownRing}, "A_THROWNRING"}, {{A_SetSolidSteam}, "A_SETSOLIDSTEAM"}, {{A_UnsetSolidSteam}, "A_UNSETSOLIDSTEAM"}, - {{A_SignSpin}, "S_SIGNSPIN"}, + {{A_SignSpin}, "A_SIGNSPIN"}, {{A_SignPlayer}, "A_SIGNPLAYER"}, {{A_OverlayThink}, "A_OVERLAYTHINK"}, {{A_JetChase}, "A_JETCHASE"}, @@ -3027,6 +3124,7 @@ static actionpointer_t actionpointers[] = {{A_DragonbomberSpawn}, "A_DRAGONBOMERSPAWN"}, {{A_DragonWing}, "A_DRAGONWING"}, {{A_DragonSegment}, "A_DRAGONSEGMENT"}, + {{A_ChangeHeight}, "A_CHANGEHEIGHT"}, {{NULL}, "NONE"}, // This NULL entry must be the last in the list @@ -3945,19 +4043,19 @@ static void readmaincfg(MYFILE *f) } else if (fastcmp(word, "REDTEAM")) { - skincolor_redteam = (UINT8)get_number(word2); + skincolor_redteam = (UINT16)get_number(word2); } else if (fastcmp(word, "BLUETEAM")) { - skincolor_blueteam = (UINT8)get_number(word2); + skincolor_blueteam = (UINT16)get_number(word2); } else if (fastcmp(word, "REDRING")) { - skincolor_redring = (UINT8)get_number(word2); + skincolor_redring = (UINT16)get_number(word2); } else if (fastcmp(word, "BLUERING")) { - skincolor_bluering = (UINT8)get_number(word2); + skincolor_bluering = (UINT16)get_number(word2); } else if (fastcmp(word, "INVULNTICS")) { @@ -4549,6 +4647,18 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile) 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")) { if (i == 0 && word2[0] != '0') // If word2 isn't a number @@ -6225,6 +6335,14 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_ROCKET", "S_LASER", + "S_LASER2", + "S_LASERFLASH", + + "S_LASERFLAME1", + "S_LASERFLAME2", + "S_LASERFLAME3", + "S_LASERFLAME4", + "S_LASERFLAME5", "S_TORPEDO", @@ -8985,8 +9103,6 @@ static const char *const ML_LIST[16] = { "TFERLINE" }; -// This DOES differ from r_draw's Color_Names, unfortunately. -// Also includes Super colors static const char *COLOR_ENUMS[] = { "NONE", // SKINCOLOR_NONE, @@ -9224,6 +9340,7 @@ static const char *const MENUTYPES_LIST[] = { "MP_CONNECT", "MP_ROOM", "MP_PLAYERSETUP", // MP_PlayerSetupDef shared with SPLITSCREEN if #defined NONET + "MP_SERVER_OPTIONS", // Options "OP_MAIN", @@ -9233,10 +9350,14 @@ static const char *const MENUTYPES_LIST[] = { "OP_P1MOUSE", "OP_P1JOYSTICK", "OP_JOYSTICKSET", // OP_JoystickSetDef shared with P2 + "OP_P1CAMERA", "OP_P2CONTROLS", "OP_P2MOUSE", "OP_P2JOYSTICK", + "OP_P2CAMERA", + + "OP_PLAYSTYLE", "OP_VIDEO", "OP_VIDEOMODE", @@ -9417,7 +9538,8 @@ struct { // SKINCOLOR_ doesn't include these..! {"MAXSKINCOLORS",MAXSKINCOLORS}, - {"MAXTRANSLATIONS",MAXTRANSLATIONS}, + {"FIRSTSUPERCOLOR",FIRSTSUPERCOLOR}, + {"NUMSUPERCOLORS",NUMSUPERCOLORS}, // Precipitation {"PRECIP_NONE",PRECIP_NONE}, @@ -9468,6 +9590,7 @@ struct { {"CR_MINECART",CR_MINECART}, {"CR_ROLLOUT",CR_ROLLOUT}, {"CR_PTERABYTE",CR_PTERABYTE}, + {"CR_DUSTDEVIL",CR_DUSTDEVIL}, // Ring weapons (ringweapons_t) // Useful for A_GiveWeapon @@ -9918,6 +10041,26 @@ static statenum_t get_state(const char *word) 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) { // Returns the value of SPR_ enumerations spritenum_t i; @@ -10212,6 +10355,11 @@ static fixed_t find_const(const char **rword) free(word); return r; } + else if (fastncmp("SKINCOLOR_",word,10)) { + r = get_skincolor(word); + free(word); + return r; + } else if (fastncmp("MT_",word,3)) { r = get_mobjtype(word); free(word); @@ -10280,17 +10428,6 @@ static fixed_t find_const(const char **rword) free(word); 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)) { char *p = word+6; @@ -10351,8 +10488,8 @@ void DEH_Check(void) 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)); - if (dehcolors != MAXTRANSLATIONS) - 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)); + 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", SKINCOLOR_FIRSTFREESLOT, sizeu1(dehcolors)); #endif } @@ -10460,6 +10597,22 @@ static inline int lib_freeslot(lua_State *L) if (i == NUMMOBJFREESLOTS) 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")) { // Search if we already have an SPR2 by that name... @@ -10791,13 +10944,20 @@ static inline int lib_getenum(lua_State *L) } else if (fastncmp("SKINCOLOR_",word,10)) { 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])) { lua_pushinteger(L, i); return 1; } - if (mathlib) return luaL_error(L, "skincolor '%s' could not be found.\n", word); - return 0; + return luaL_error(L, "skincolor '%s' could not be found.\n", word); } else if (fastncmp("GRADE_",word,6)) { diff --git a/src/djgppdos/i_system.c b/src/djgppdos/i_system.c index dae9ed16e..9f6972fa6 100644 --- a/src/djgppdos/i_system.c +++ b/src/djgppdos/i_system.c @@ -61,6 +61,8 @@ #include "../console.h" +#include "../m_menu.h" + #ifdef __GNUG__ #pragma implementation "../i_system.h" #endif @@ -555,6 +557,7 @@ void I_Error (const char *error, ...) if (demorecording) G_CheckDemoStatus(); D_QuitNetGame (); + M_FreePlayerSetupColors(); if (shutdowning) { @@ -622,6 +625,7 @@ void I_Quit (void) if (demorecording) G_CheckDemoStatus(); D_QuitNetGame (); + M_FreePlayerSetupColors(); I_ShutdownMusic(); I_ShutdownSound(); I_ShutdownCD(); diff --git a/src/doomdata.h b/src/doomdata.h index c2ee50c2e..77ed56bc2 100644 --- a/src/doomdata.h +++ b/src/doomdata.h @@ -208,10 +208,6 @@ typedef struct #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 #endif // __DOOMDATA__ diff --git a/src/doomdef.h b/src/doomdef.h index f9828a442..1cb491a10 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -143,9 +143,9 @@ extern char logfilename[1024]; // we use comprevision and compbranch instead. #else #define VERSION 202 // Game version -#define SUBVERSION 2 // more precise version number -#define VERSIONSTRING "v2.2.2" -#define VERSIONSTRINGW L"v2.2.2" +#define SUBVERSION 4 // more precise version number +#define VERSIONSTRING "v2.2.4" +#define VERSIONSTRINGW L"v2.2.4" // Hey! If you change this, add 1 to the MODVERSION below! // Otherwise we can't force updates! #endif @@ -213,7 +213,7 @@ extern char logfilename[1024]; // it's only for detection of the version the player is using so the MS can alert them of an update. // Only set it higher, not lower, obviously. // Note that we use this to help keep internal testing in check; this is why v2.2.0 is not version "1". -#define MODVERSION 42 +#define MODVERSION 44 // To version config.cfg, MAJOREXECVERSION is set equal to MODVERSION automatically. // Increment MINOREXECVERSION whenever a config change is needed that does not correspond @@ -239,6 +239,20 @@ extern char logfilename[1024]; #define PLAYERSMASK (MAXPLAYERS-1) #define 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 { SKINCOLOR_NONE = 0, @@ -317,12 +331,10 @@ typedef enum SKINCOLOR_RASPBERRY, SKINCOLOR_ROSY, - // SKINCOLOR_? - one left before we bump up against 0x39, which isn't a HARD limit anymore but would be excessive - - MAXSKINCOLORS, + FIRSTSUPERCOLOR, // Super special awesome Super flashing colors! - SKINCOLOR_SUPERSILVER1 = MAXSKINCOLORS, + SKINCOLOR_SUPERSILVER1 = FIRSTSUPERCOLOR, SKINCOLOR_SUPERSILVER2, SKINCOLOR_SUPERSILVER3, SKINCOLOR_SUPERSILVER4, @@ -376,9 +388,17 @@ typedef enum SKINCOLOR_SUPERTAN4, SKINCOLOR_SUPERTAN5, - MAXTRANSLATIONS, - NUMSUPERCOLORS = ((MAXTRANSLATIONS - MAXSKINCOLORS)/5) -} skincolors_t; + SKINCOLOR_FIRSTFREESLOT, + SKINCOLOR_LASTFREESLOT = SKINCOLOR_FIRSTFREESLOT + NUMCOLORFREESLOTS - 1, + + MAXSKINCOLORS, + + NUMSUPERCOLORS = ((SKINCOLOR_FIRSTFREESLOT - FIRSTSUPERCOLOR)/5) +} skincolornum_t; + +extern UINT16 numskincolors; + +extern skincolor_t skincolors[MAXSKINCOLORS]; // State updates, number of tics / second. // NOTE: used to setup the timer rate, see I_StartupTimer(). @@ -458,7 +478,7 @@ void CONS_Debug(INT32 debugflags, const char *fmt, ...) FUNCDEBUG; // Things that used to be in dstrings.h #define SAVEGAMENAME "srb2sav" -char savegamename[256]; +extern char savegamename[256]; // m_misc.h #ifdef GETTEXT @@ -565,10 +585,6 @@ extern const char *compdate, *comptime, *comprevision, *compbranch; // None of these that are disabled in the normal build are guaranteed to work perfectly // Compile them at your own risk! -/// Backwards compatibility with SRB2CB's slope linedef types. -/// \note A simple shim that prints a warning. -#define ESLOPE_TYPESHIM - /// Allows the use of devmode in multiplayer. AKA "fishcake" //#define NETGAME_DEVMODE @@ -578,9 +594,6 @@ extern const char *compdate, *comptime, *comprevision, *compbranch; /// Dumps the contents of a network save game upon consistency failure for debugging. //#define DUMPCONSISTENCY -/// Polyobject fake flat code -#define POLYOBJECTS_PLANES - /// See name of player in your crosshair #define SEENAMES diff --git a/src/doomstat.h b/src/doomstat.h index aedb120ff..fa346540c 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -145,7 +145,7 @@ extern INT32 tutorialanalog; // store cv_analog[0] user value extern boolean looptitle; // 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 boolean countdowntimeup; @@ -319,6 +319,9 @@ typedef struct char selectheading[22]; ///< Level select heading. Allows for controllable grouping. UINT16 startrings; ///< Number of rings players start with. + INT32 sstimer; ///< Timer for special stages. + UINT32 ssspheres; ///< Sphere requirement in special stages. + fixed_t gravity; ///< Map-wide gravity. // Title card. char ltzzpatch[8]; ///< Zig zag patch. @@ -542,7 +545,7 @@ extern recorddata_t *mainrecords[NUMMAPS]; extern UINT8 mapvisited[NUMMAPS]; // Temporary holding place for nights data for the current map -nightsdata_t ntemprecords; +extern nightsdata_t ntemprecords; extern UINT32 token; ///< Number of tokens collected in a level extern UINT32 tokenlist; ///< List of tokens collected @@ -617,6 +620,19 @@ extern mapthing_t *playerstarts[MAXPLAYERS]; // Cooperative extern mapthing_t *bluectfstarts[MAXPLAYERS]; // CTF extern mapthing_t *redctfstarts[MAXPLAYERS]; // CTF +#define WAYPOINTSEQUENCESIZE 256 +#define NUMWAYPOINTSEQUENCES 256 +extern mobj_t *waypoints[NUMWAYPOINTSEQUENCES][WAYPOINTSEQUENCESIZE]; +extern UINT16 numwaypoints[NUMWAYPOINTSEQUENCES]; + +void P_AddWaypoint(UINT8 sequence, UINT8 id, mobj_t *waypoint); +mobj_t *P_GetFirstWaypoint(UINT8 sequence); +mobj_t *P_GetLastWaypoint(UINT8 sequence); +mobj_t *P_GetPreviousWaypoint(mobj_t *current, boolean wrap); +mobj_t *P_GetNextWaypoint(mobj_t *current, boolean wrap); +mobj_t *P_GetClosestWaypoint(UINT8 sequence, mobj_t *mo); +boolean P_IsDegeneratedWaypointSequence(UINT8 sequence); + // ===================================== // Internal parameters, used for engine. // ===================================== diff --git a/src/f_finale.c b/src/f_finale.c index 825f646b0..8b5a69ae4 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -2185,7 +2185,7 @@ void F_EndingDrawer(void) for (i = 0; i < 7; ++i) { UINT8* colormap; - skincolors_t col = SKINCOLOR_GREEN; + skincolornum_t col = SKINCOLOR_GREEN; switch (i) { case 1: diff --git a/src/f_finale.h b/src/f_finale.h index 63319d7d6..b3abf1778 100644 --- a/src/f_finale.h +++ b/src/f_finale.h @@ -162,7 +162,9 @@ extern wipestyleflags_t wipestyleflags; // Even my function names are borderline boolean F_ShouldColormapFade(void); boolean F_TryColormapFade(UINT8 wipecolor); +#ifndef NOWIPE void F_DecideWipeStyle(void); +#endif #define FADECOLORMAPDIV 8 #define FADECOLORMAPROWS (256/FADECOLORMAPDIV) diff --git a/src/f_wipe.c b/src/f_wipe.c index 08d7ed991..01b45b0c2 100644 --- a/src/f_wipe.c +++ b/src/f_wipe.c @@ -464,6 +464,7 @@ void F_WipeEndScreen(void) */ boolean F_ShouldColormapFade(void) { +#ifndef NOWIPE if ((wipestyleflags & (WSF_FADEIN|WSF_FADEOUT)) // only if one of those wipestyleflags are actually set && !(wipestyleflags & WSF_CROSSFADE)) // and if not crossfading { @@ -479,11 +480,13 @@ boolean F_ShouldColormapFade(void) // Menus || gamestate == GS_TIMEATTACK); } +#endif return false; } /** Decides what wipe style to use. */ +#ifndef NOWIPE void F_DecideWipeStyle(void) { // Set default wipe style @@ -493,6 +496,7 @@ void F_DecideWipeStyle(void) if (F_ShouldColormapFade()) wipestyle = WIPESTYLE_COLORMAP; } +#endif /** Attempt to run a colormap fade, provided all the conditionals were properly met. @@ -501,6 +505,7 @@ void F_DecideWipeStyle(void) */ boolean F_TryColormapFade(UINT8 wipecolor) { +#ifndef NOWIPE if (F_ShouldColormapFade()) { #ifdef HWRENDER @@ -510,6 +515,7 @@ boolean F_TryColormapFade(UINT8 wipecolor) return true; } else +#endif { F_WipeColorFill(wipecolor); return false; @@ -608,6 +614,7 @@ void F_RunWipe(UINT8 wipetype, boolean drawMenu) tic_t F_GetWipeLength(UINT8 wipetype) { #ifdef NOWIPE + (void)wipetype; return 0; #else static char lumpname[10] = "FADEmmss"; @@ -634,6 +641,7 @@ tic_t F_GetWipeLength(UINT8 wipetype) boolean F_WipeExists(UINT8 wipetype) { #ifdef NOWIPE + (void)wipetype; return false; #else static char lumpname[10] = "FADEmm00"; diff --git a/src/g_demo.c b/src/g_demo.c index 30bc8ca48..7c949a4c8 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -68,7 +68,7 @@ static struct { UINT8 flags; // EZT flags // EZT_COLOR - UINT8 color, lastcolor; + UINT16 color, lastcolor; // EZT_SCALE fixed_t scale, lastscale; @@ -82,7 +82,8 @@ static struct { // There is no conflict here. typedef struct demoghost { UINT8 checksum[16]; - UINT8 *buffer, *p, color, fadein; + UINT8 *buffer, *p, fadein; + UINT16 color; UINT16 version; mobj_t oldmo, *mo; struct demoghost *next; @@ -93,7 +94,7 @@ demoghost *ghosts = NULL; // DEMO RECORDING // -#define DEMOVERSION 0x000c +#define DEMOVERSION 0x000d #define DEMOHEADER "\xF0" "SRB2Replay" "\x0F" #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)) return; - if (ghostext.lastcolor == (UINT8)color) + if (ghostext.lastcolor == (UINT16)color) { ghostext.flags &= ~EZT_COLOR; return; } ghostext.flags |= EZT_COLOR; - ghostext.color = (UINT8)color; + ghostext.color = (UINT16)color; } void G_GhostAddScale(fixed_t scale) @@ -425,7 +426,7 @@ void G_WriteGhostTic(mobj_t *ghost) WRITEUINT8(demo_p,ghostext.flags); if (ghostext.flags & EZT_COLOR) { - WRITEUINT8(demo_p,ghostext.color); + WRITEUINT16(demo_p,ghostext.color); ghostext.lastcolor = ghostext.color; } if (ghostext.flags & EZT_SCALE) @@ -501,7 +502,7 @@ void G_WriteGhostTic(mobj_t *ghost) WRITEUINT8(demo_p,ghost->player->followmobj->sprite2); WRITEUINT16(demo_p,ghost->player->followmobj->sprite); 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; } @@ -566,7 +567,7 @@ void G_ConsGhostTic(void) { // But wait, there's more! UINT8 xziptic = READUINT8(demo_p); if (xziptic & EZT_COLOR) - demo_p++; + demo_p += (demoversion==0x000c) ? 1 : sizeof(UINT16); if (xziptic & EZT_SCALE) demo_p += sizeof(fixed_t); if (xziptic & EZT_HIT) @@ -633,7 +634,7 @@ void G_ConsGhostTic(void) demo_p++; demo_p += sizeof(UINT16); demo_p++; - demo_p++; + demo_p += (demoversion==0x000c) ? 1 : sizeof(UINT16); } // Re-synchronise @@ -731,7 +732,7 @@ void G_GhostTicker(void) xziptic = READUINT8(g->p); if (xziptic & EZT_COLOR) { - g->color = READUINT8(g->p); + g->color = (g->version==0x000c) ? READUINT8(g->p) : READUINT16(g->p); switch(g->color) { default: @@ -864,7 +865,7 @@ void G_GhostTicker(void) g->mo->color += abs( ( (signed)( (unsigned)leveltime >> 1 ) % 9) - 4); break; 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; default: break; @@ -918,7 +919,7 @@ void G_GhostTicker(void) follow->sprite = READUINT16(g->p); follow->frame = (READUINT8(g->p)) | (g->mo->frame & FF_TRANSMASK); 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)) { @@ -1158,7 +1159,7 @@ void G_ReadMetalTic(mobj_t *metal) follow->sprite = READUINT16(metal_p); follow->frame = READUINT32(metal_p); // NOT & FF_FRAMEMASK here, so 32 bits follow->angle = metal->angle; - follow->color = READUINT8(metal_p); + follow->color = (metalversion==0x000c) ? READUINT8(metal_p) : READUINT16(metal_p); if (!(followtic & FZT_SPAWNED)) { @@ -1340,7 +1341,7 @@ void G_WriteMetalTic(mobj_t *metal) WRITEUINT8(demo_p,metal->player->followmobj->sprite2); WRITEUINT16(demo_p,metal->player->followmobj->sprite); 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; } @@ -1394,7 +1395,7 @@ void G_RecordMetal(void) void G_BeginRecording(void) { UINT8 i; - char name[16]; + char name[MAXCOLORNAME+1]; player_t *player = &players[consoleplayer]; if (demo_p) @@ -1457,12 +1458,12 @@ void G_BeginRecording(void) demo_p += 16; // 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]; - for (; i < 16; i++) + for (; i < MAXCOLORNAME; i++) name[i] = '\0'; - M_Memcpy(demo_p,name,16); - demo_p += 16; + M_Memcpy(demo_p,name,MAXCOLORNAME); + demo_p += MAXCOLORNAME; // Stats WRITEUINT8(demo_p,player->charability); @@ -1622,7 +1623,7 @@ UINT8 G_CmpDemoTime(char *oldname, char *newname) c = READUINT8(p); // SUBVERSION I_Assert(c == SUBVERSION); s = READUINT16(p); - I_Assert(s == DEMOVERSION); + I_Assert(s >= 0x000c); p += 16; // demo checksum I_Assert(!memcmp(p, "PLAY", 4)); p += 4; // PLAY @@ -1671,6 +1672,7 @@ UINT8 G_CmpDemoTime(char *oldname, char *newname) switch(oldversion) // demoversion { case DEMOVERSION: // latest always supported + case 0x000c: // all that changed between then and now was longer color name break; // too old, cannot support. default: @@ -1744,15 +1746,15 @@ void G_DoPlayDemo(char *defdemoname) { UINT8 i; lumpnum_t l; - char skin[17],color[17],*n,*pdemoname; - UINT8 version,subversion,charability,charability2,thrustfactor,accelstart,acceleration; + char skin[17],color[MAXCOLORNAME+1],*n,*pdemoname; + UINT8 version,subversion,charability,charability2,thrustfactor,accelstart,acceleration,cnamelen; pflags_t pflags; UINT32 randseed, followitem; fixed_t camerascale,shieldscale,actionspd,mindash,maxdash,normalspeed,runspeed,jumpfactor,height,spinheight; char msg[1024]; skin[16] = '\0'; - color[16] = '\0'; + color[MAXCOLORNAME] = '\0'; n = defdemoname+strlen(defdemoname); while (*n != '/' && *n != '\\' && n != defdemoname) @@ -1810,6 +1812,11 @@ void G_DoPlayDemo(char *defdemoname) switch(demoversion) { case DEMOVERSION: // latest always supported + cnamelen = MAXCOLORNAME; + break; + // all that changed between then and now was longer color name + case 0x000c: + cnamelen = 16; break; // too old, cannot support. default: @@ -1876,8 +1883,8 @@ void G_DoPlayDemo(char *defdemoname) demo_p += 16; // Color - M_Memcpy(color,demo_p,16); - demo_p += 16; + M_Memcpy(color,demo_p,cnamelen); + demo_p += cnamelen; charability = READUINT8(demo_p); charability2 = READUINT8(demo_p); @@ -1941,7 +1948,9 @@ void G_DoPlayDemo(char *defdemoname) // Set skin SetPlayerSkin(0, skin); +#ifdef HAVE_BLUA LUAh_MapChange(gamemap); +#endif displayplayer = consoleplayer = 0; memset(playeringame,0,sizeof(playeringame)); playeringame[0] = true; @@ -1949,8 +1958,9 @@ void G_DoPlayDemo(char *defdemoname) G_InitNew(false, G_BuildMapName(gamemap), true, true, false); // Set color - for (i = 0; i < MAXSKINCOLORS; i++) - if (!stricmp(Color_Names[i],color)) + players[0].skincolor = skins[players[0].skin].prefcolor; + for (i = 0; i < numskincolors; i++) + if (!stricmp(skincolors[i].name,color)) { players[0].skincolor = i; break; @@ -1992,7 +2002,8 @@ void G_AddGhost(char *defdemoname) { INT32 i; 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; UINT8 flags; UINT8 *buffer,*p; @@ -2047,6 +2058,11 @@ void G_AddGhost(char *defdemoname) switch(ghostversion) { case DEMOVERSION: // latest always supported + cnamelen = MAXCOLORNAME; + break; + // all that changed between then and now was longer color name + case 0x000c: + cnamelen = 16; break; // too old, cannot support. default: @@ -2109,8 +2125,8 @@ void G_AddGhost(char *defdemoname) p += 16; // Color - M_Memcpy(color, p,16); - p += 16; + M_Memcpy(color, p,cnamelen); + p += cnamelen; // Ghosts do not have a player structure to put this in. p++; // charability @@ -2198,10 +2214,10 @@ void G_AddGhost(char *defdemoname) // Set color gh->mo->color = ((skin_t*)gh->mo->skin)->prefcolor; - for (i = 0; i < MAXSKINCOLORS; i++) - if (!stricmp(Color_Names[i],color)) + for (i = 0; i < numskincolors; i++) + if (!stricmp(skincolors[i].name,color)) { - gh->mo->color = (UINT8)i; + gh->mo->color = (UINT16)i; break; } gh->oldmo.color = gh->mo->color; @@ -2292,6 +2308,7 @@ void G_DoPlayMetal(void) switch(metalversion) { case DEMOVERSION: // latest always supported + case 0x000c: // all that changed between then and now was longer color name break; // too old, cannot support. default: @@ -2332,6 +2349,38 @@ void G_DoneLevelLoad(void) =================== */ +// Writes the demo's checksum, or just random garbage if you can't do that for some reason. +static void WriteDemoChecksum(void) +{ + UINT8 *p = demobuffer+16; // checksum position +#ifdef NOMD5 + UINT8 i; + for (i = 0; i < 16; i++, p++) + *p = P_RandomByte(); // This MD5 was chosen by fair dice roll and most likely < 50% correct. +#else + md5_buffer((char *)p+16, demo_p - (p+16), p); // make a checksum of everything after the checksum in the file. +#endif +} + +// Stops recording a demo. +static void G_StopDemoRecording(void) +{ + boolean saved = false; + WRITEUINT8(demo_p, DEMOMARKER); // add the demo end marker + WriteDemoChecksum(); + saved = FIL_WriteFile(va(pandf, srb2home, demoname), demobuffer, demo_p - demobuffer); // finally output the file. + free(demobuffer); + demorecording = false; + + if (modeattacking != ATTACKING_RECORD) + { + if (saved) + CONS_Printf(M_GetText("Demo %s recorded\n"), demoname); + else + CONS_Alert(CONS_WARNING, M_GetText("Demo %s not saved\n"), demoname); + } +} + // Stops metal sonic's demo. Separate from other functions because metal + replays can coexist void G_StopMetalDemo(void) { @@ -2349,20 +2398,8 @@ ATTRNORETURN void FUNCNORETURN G_StopMetalRecording(boolean kill) boolean saved = false; if (demo_p) { - UINT8 *p = demobuffer+16; // checksum position - if (kill) - WRITEUINT8(demo_p, METALDEATH); // add the metal death marker - else - WRITEUINT8(demo_p, DEMOMARKER); // add the demo end marker -#ifdef NOMD5 - { - UINT8 i; - for (i = 0; i < 16; i++, p++) - *p = P_RandomByte(); // This MD5 was chosen by fair dice roll and most likely < 50% correct. - } -#else - md5_buffer((char *)p+16, demo_p - (p+16), (void *)p); // make a checksum of everything after the checksum in the file. -#endif + WRITEUINT8(demo_p, (kill) ? METALDEATH : DEMOMARKER); // add the demo end (or metal death) marker + WriteDemoChecksum(); saved = FIL_WriteFile(va("%sMS.LMP", G_BuildMapName(gamemap)), demobuffer, demo_p - demobuffer); // finally output the file. } free(demobuffer); @@ -2372,6 +2409,63 @@ ATTRNORETURN void FUNCNORETURN G_StopMetalRecording(boolean kill) I_Error("Failed to save demo!"); } +// Stops timing a demo. +static void G_StopTimingDemo(void) +{ + INT32 demotime; + double f1, f2; + demotime = I_GetTime() - demostarttime; + if (!demotime) + return; + G_StopDemo(); + timingdemo = false; + f1 = (double)demotime; + f2 = (double)framecount*TICRATE; + + CONS_Printf(M_GetText("timed %u gametics in %d realtics - %u frames\n%f seconds, %f avg fps\n"), + leveltime,demotime,(UINT32)framecount,f1/TICRATE,f2/f1); + + // CSV-readable timedemo results, for external parsing + if (timedemo_csv) + { + FILE *f; + const char *csvpath = va("%s"PATHSEP"%s", srb2home, "timedemo.csv"); + const char *header = "id,demoname,seconds,avgfps,leveltime,demotime,framecount,ticrate,rendermode,vidmode,vidwidth,vidheight,procbits\n"; + const char *rowformat = "\"%s\",\"%s\",%f,%f,%u,%d,%u,%u,%u,%u,%u,%u,%u\n"; + boolean headerrow = !FIL_FileExists(csvpath); + UINT8 procbits = 0; + + // Bitness + if (sizeof(void*) == 4) + procbits = 32; + else if (sizeof(void*) == 8) + procbits = 64; + + f = fopen(csvpath, "a+"); + + if (f) + { + if (headerrow) + fputs(header, f); + fprintf(f, rowformat, + timedemo_csv_id,timedemo_name,f1/TICRATE,f2/f1,leveltime,demotime,(UINT32)framecount,TICRATE,rendermode,vid.modenum,vid.width,vid.height,procbits); + fclose(f); + CONS_Printf("Timedemo results saved to '%s'\n", csvpath); + } + else + { + // Just print the CSV output to console + CON_LogMessage(header); + CONS_Printf(rowformat, + timedemo_csv_id,timedemo_name,f1/TICRATE,f2/f1,leveltime,demotime,(UINT32)framecount,TICRATE,rendermode,vid.modenum,vid.width,vid.height,procbits); + } + } + + if (restorecv_vidwait != cv_vidwait.value) + CV_SetValue(&cv_vidwait, restorecv_vidwait); + D_AdvanceDemo(); +} + // reset engine variable set for the demos // called from stopdemo command, map command, and g_checkdemoStatus. void G_StopDemo(void) @@ -2394,66 +2488,13 @@ void G_StopDemo(void) boolean G_CheckDemoStatus(void) { - boolean saved; - G_FreeGhosts(); // DO NOT end metal sonic demos here if (timingdemo) { - INT32 demotime; - double f1, f2; - demotime = I_GetTime() - demostarttime; - if (!demotime) - return true; - G_StopDemo(); - timingdemo = false; - f1 = (double)demotime; - f2 = (double)framecount*TICRATE; - - CONS_Printf(M_GetText("timed %u gametics in %d realtics - %u frames\n%f seconds, %f avg fps\n"), - leveltime,demotime,(UINT32)framecount,f1/TICRATE,f2/f1); - - // CSV-readable timedemo results, for external parsing - if (timedemo_csv) - { - FILE *f; - const char *csvpath = va("%s"PATHSEP"%s", srb2home, "timedemo.csv"); - const char *header = "id,demoname,seconds,avgfps,leveltime,demotime,framecount,ticrate,rendermode,vidmode,vidwidth,vidheight,procbits\n"; - const char *rowformat = "\"%s\",\"%s\",%f,%f,%u,%d,%u,%u,%u,%u,%u,%u,%u\n"; - boolean headerrow = !FIL_FileExists(csvpath); - UINT8 procbits = 0; - - // Bitness - if (sizeof(void*) == 4) - procbits = 32; - else if (sizeof(void*) == 8) - procbits = 64; - - f = fopen(csvpath, "a+"); - - if (f) - { - if (headerrow) - fputs(header, f); - fprintf(f, rowformat, - timedemo_csv_id,timedemo_name,f1/TICRATE,f2/f1,leveltime,demotime,(UINT32)framecount,TICRATE,rendermode,vid.modenum,vid.width,vid.height,procbits); - fclose(f); - CONS_Printf("Timedemo results saved to '%s'\n", csvpath); - } - else - { - // Just print the CSV output to console - CON_LogMessage(header); - CONS_Printf(rowformat, - timedemo_csv_id,timedemo_name,f1/TICRATE,f2/f1,leveltime,demotime,(UINT32)framecount,TICRATE,rendermode,vid.modenum,vid.width,vid.height,procbits); - } - } - - if (restorecv_vidwait != cv_vidwait.value) - CV_SetValue(&cv_vidwait, restorecv_vidwait); - D_AdvanceDemo(); + G_StopTimingDemo(); return true; } @@ -2473,27 +2514,7 @@ boolean G_CheckDemoStatus(void) if (demorecording) { - UINT8 *p = demobuffer+16; // checksum position -#ifdef NOMD5 - UINT8 i; - WRITEUINT8(demo_p, DEMOMARKER); // add the demo end marker - for (i = 0; i < 16; i++, p++) - *p = P_RandomByte(); // This MD5 was chosen by fair dice roll and most likely < 50% correct. -#else - WRITEUINT8(demo_p, DEMOMARKER); // add the demo end marker - md5_buffer((char *)p+16, demo_p - (p+16), p); // make a checksum of everything after the checksum in the file. -#endif - saved = FIL_WriteFile(va(pandf, srb2home, demoname), demobuffer, demo_p - demobuffer); // finally output the file. - free(demobuffer); - demorecording = false; - - if (modeattacking != ATTACKING_RECORD) - { - if (saved) - CONS_Printf(M_GetText("Demo %s recorded\n"), demoname); - else - CONS_Alert(CONS_WARNING, M_GetText("Demo %s not saved\n"), demoname); - } + G_StopDemoRecording(); return true; } diff --git a/src/g_game.c b/src/g_game.c index 1fb817bf8..76a5efbdd 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -54,7 +54,7 @@ UINT8 ultimatemode = false; boolean botingame; UINT8 botskin; -UINT8 botcolor; +UINT16 botcolor; JoyType_t Joystick; JoyType_t Joystick2; @@ -135,10 +135,10 @@ INT32 tutorialanalog = 0; // store cv_analog[0] user value boolean looptitle = false; -UINT8 skincolor_redteam = SKINCOLOR_RED; -UINT8 skincolor_blueteam = SKINCOLOR_BLUE; -UINT8 skincolor_redring = SKINCOLOR_SALMON; -UINT8 skincolor_bluering = SKINCOLOR_CORNFLOWER; +UINT16 skincolor_redteam = SKINCOLOR_RED; +UINT16 skincolor_blueteam = SKINCOLOR_BLUE; +UINT16 skincolor_redring = SKINCOLOR_SALMON; +UINT16 skincolor_bluering = SKINCOLOR_CORNFLOWER; tic_t countdowntimer = 0; boolean countdowntimeup = false; @@ -1866,6 +1866,7 @@ void G_StartTitleCard(void) // void G_PreLevelTitleCard(void) { +#ifndef NOWIPE tic_t starttime = I_GetTime(); tic_t endtime = starttime + (PRELEVELTIME*NEWTICRATERATIO); tic_t nowtime = starttime; @@ -1888,6 +1889,7 @@ void G_PreLevelTitleCard(void) } if (!cv_showhud.value) wipestyleflags = WSF_CROSSFADE; +#endif } static boolean titlecardforreload = false; @@ -2382,7 +2384,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) INT16 totalring; UINT8 laps; UINT8 mare; - UINT8 skincolor; + UINT16 skincolor; INT32 skin; UINT32 availabilities; tic_t jointime; @@ -4480,7 +4482,7 @@ cleanup: // 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; if (demoplayback) @@ -4634,7 +4636,7 @@ char *G_BuildMapTitle(INT32 mapnum) { size_t len = 1; const char *zonetext = NULL; - const INT32 actnum = mapheaderinfo[mapnum-1]->actnum; + const UINT8 actnum = mapheaderinfo[mapnum-1]->actnum; len += strlen(mapheaderinfo[mapnum-1]->lvlttl); if (!(mapheaderinfo[mapnum-1]->levelflags & LF_NOZONE)) diff --git a/src/g_state.h b/src/g_state.h index 3320ebc47..e364c5a35 100644 --- a/src/g_state.h +++ b/src/g_state.h @@ -57,6 +57,7 @@ extern UINT8 ultimatemode; // was sk_insane extern gameaction_t gameaction; extern boolean botingame; -extern UINT8 botskin, botcolor; +extern UINT8 botskin; +extern UINT16 botcolor; #endif //__G_STATE__ diff --git a/src/hardware/hw_bsp.c b/src/hardware/hw_bsp.c index 6f3dd9fbd..ebb74f653 100644 --- a/src/hardware/hw_bsp.c +++ b/src/hardware/hw_bsp.c @@ -887,12 +887,10 @@ static void AdjustSegs(void) float distv1,distv2,tmp; nearv1 = nearv2 = MYMAX; -#ifdef POLYOBJECTS // Don't touch polyobject segs. We'll compensate // for this when we go about drawing them. if (lseg->polyseg) continue; -#endif if (p) { for (j = 0; j < p->numpts; j++) diff --git a/src/hardware/hw_light.c b/src/hardware/hw_light.c index c5af8d6d3..3d1316a2f 100644 --- a/src/hardware/hw_light.c +++ b/src/hardware/hw_light.c @@ -298,6 +298,8 @@ light_t *t_lspr[NUMSPRITES] = // Projectiles &lspr[NOLIGHT], // SPR_MISL + &lspr[SMALLREDBALL_L], // SPR_LASR + &lspr[REDSHINE_L], // SPR_LASF &lspr[NOLIGHT], // SPR_TORP &lspr[NOLIGHT], // SPR_ENRG &lspr[NOLIGHT], // SPR_MINE diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 7fca7cd91..bcb0afa6e 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -511,7 +511,7 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool // Set fixedheight to the slope's height from our viewpoint, if we have a slope if (slope) - fixedheight = P_GetZAt(slope, viewx, viewy); + fixedheight = P_GetSlopeZAt(slope, viewx, viewy); height = FIXED_TO_FLOAT(fixedheight); @@ -657,7 +657,7 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool \ if (slope)\ {\ - fixedheight = P_GetZAt(slope, FLOAT_TO_FIXED((vx)), FLOAT_TO_FIXED((vy)));\ + fixedheight = P_GetSlopeZAt(slope, FLOAT_TO_FIXED((vx)), FLOAT_TO_FIXED((vy)));\ vert->y = FIXED_TO_FLOAT(fixedheight);\ }\ } @@ -1100,8 +1100,8 @@ static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum, float endpegt, endpegb, endpegmul; float endheight = 0.0f, endbheight = 0.0f; - // compiler complains when P_GetZAt is used in FLOAT_TO_FIXED directly - // use this as a temp var to store P_GetZAt's return value each time + // compiler complains when P_GetSlopeZAt is used in FLOAT_TO_FIXED directly + // use this as a temp var to store P_GetSlopeZAt's return value each time fixed_t temp; fixed_t v1x = FLOAT_TO_FIXED(wallVerts[0].x); @@ -1164,26 +1164,16 @@ static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum, else solid = false; - if (list[i].slope) - { - temp = P_GetZAt(list[i].slope, v1x, v1y); - height = FIXED_TO_FLOAT(temp); - temp = P_GetZAt(list[i].slope, v2x, v2y); - endheight = FIXED_TO_FLOAT(temp); - } - else - height = endheight = FIXED_TO_FLOAT(list[i].height); + temp = P_GetLightZAt(&list[i], v1x, v1y); + height = FIXED_TO_FLOAT(temp); + temp = P_GetLightZAt(&list[i], v2x, v2y); + endheight = FIXED_TO_FLOAT(temp); if (solid) { - if (*list[i].caster->b_slope) - { - temp = P_GetZAt(*list[i].caster->b_slope, v1x, v1y); - bheight = FIXED_TO_FLOAT(temp); - temp = P_GetZAt(*list[i].caster->b_slope, v2x, v2y); - endbheight = FIXED_TO_FLOAT(temp); - } - else - bheight = endbheight = FIXED_TO_FLOAT(*list[i].caster->bottomheight); + temp = P_GetFFloorBottomZAt(list[i].caster, v1x, v1y); + bheight = FIXED_TO_FLOAT(temp); + temp = P_GetFFloorBottomZAt(list[i].caster, v2x, v2y); + endbheight = FIXED_TO_FLOAT(temp); } if (endheight >= endtop && height >= top) @@ -1196,15 +1186,10 @@ static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum, if (i + 1 < sector->numlights) { - if (list[i+1].slope) - { - temp = P_GetZAt(list[i+1].slope, v1x, v1y); - bheight = FIXED_TO_FLOAT(temp); - temp = P_GetZAt(list[i+1].slope, v2x, v2y); - endbheight = FIXED_TO_FLOAT(temp); - } - else - bheight = endbheight = FIXED_TO_FLOAT(list[i+1].height); + temp = P_GetLightZAt(&list[i+1], v1x, v1y); + bheight = FIXED_TO_FLOAT(temp); + temp = P_GetLightZAt(&list[i+1], v2x, v2y); + endbheight = FIXED_TO_FLOAT(temp); } else { @@ -1343,11 +1328,8 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) v2y = FLOAT_TO_FIXED(ve.y); #define SLOPEPARAMS(slope, end1, end2, normalheight) \ - if (slope) { \ - end1 = P_GetZAt(slope, v1x, v1y); \ - end2 = P_GetZAt(slope, v2x, v2y); \ - } else \ - end1 = end2 = normalheight; + end1 = P_GetZAt(slope, v1x, v1y, normalheight); \ + end2 = P_GetZAt(slope, v2x, v2y, normalheight); SLOPEPARAMS(gr_frontsector->c_slope, worldtop, worldtopslope, gr_frontsector->ceilingheight) SLOPEPARAMS(gr_frontsector->f_slope, worldbottom, worldbottomslope, gr_frontsector->floorheight) @@ -1602,7 +1584,6 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) // heights of the polygon, and h & l, are the final (clipped) // poly coords. -#ifdef POLYOBJECTS // NOTE: With polyobjects, whenever you need to check the properties of the polyobject sector it belongs to, // you must use the linedef's backsector to be correct // From CB @@ -1612,7 +1593,6 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) popenbottom = back->floorheight; } else -#endif { popentop = min(worldtop, worldhigh); popenbottom = max(worldbottom, worldlow); @@ -1642,7 +1622,6 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) polybottom = polytop - textureheight[gr_midtexture]*repeats; } // CB -#ifdef POLYOBJECTS // NOTE: With polyobjects, whenever you need to check the properties of the polyobject sector it belongs to, // you must use the linedef's backsector to be correct if (gr_curline->polyseg) @@ -1650,7 +1629,6 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) lowcut = polybottom; highcut = polytop; } -#endif else { // The cut-off values of a linedef can always be constant, since every line has an absoulute front and or back sector @@ -1780,7 +1758,6 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) break; } -#ifdef POLYOBJECTS if (gr_curline->polyseg && gr_curline->polyseg->translucency > 0) { if (gr_curline->polyseg->translucency >= NUMTRANSMAPS) // wall not drawn @@ -1791,7 +1768,6 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) else blendmode = HWR_TranstableToAlpha(gr_curline->polyseg->translucency, &Surf); } -#endif if (gr_frontsector->numlights) { @@ -1956,10 +1932,10 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) texnum = R_GetTextureNum(sides[newline->sidenum[0]].midtexture); } - h = *rover->t_slope ? P_GetZAt(*rover->t_slope, v1x, v1y) : *rover->topheight; - hS = *rover->t_slope ? P_GetZAt(*rover->t_slope, v2x, v2y) : *rover->topheight; - l = *rover->b_slope ? P_GetZAt(*rover->b_slope, v1x, v1y) : *rover->bottomheight; - lS = *rover->b_slope ? P_GetZAt(*rover->b_slope, v2x, v2y) : *rover->bottomheight; + h = P_GetFFloorTopZAt (rover, v1x, v1y); + hS = P_GetFFloorTopZAt (rover, v2x, v2y); + l = P_GetFFloorBottomZAt(rover, v1x, v1y); + lS = P_GetFFloorBottomZAt(rover, v2x, v2y); if (!(*rover->t_slope) && !gr_frontsector->c_slope && !gr_backsector->c_slope && h > highcut) h = hS = highcut; if (!(*rover->b_slope) && !gr_frontsector->f_slope && !gr_backsector->f_slope && l < lowcut) @@ -2097,10 +2073,10 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) newline = rover->master->frontsector->lines[0] + linenum; texnum = R_GetTextureNum(sides[newline->sidenum[0]].midtexture); } - h = *rover->t_slope ? P_GetZAt(*rover->t_slope, v1x, v1y) : *rover->topheight; - hS = *rover->t_slope ? P_GetZAt(*rover->t_slope, v2x, v2y) : *rover->topheight; - l = *rover->b_slope ? P_GetZAt(*rover->b_slope, v1x, v1y) : *rover->bottomheight; - lS = *rover->b_slope ? P_GetZAt(*rover->b_slope, v2x, v2y) : *rover->bottomheight; + h = P_GetFFloorTopZAt (rover, v1x, v1y); + hS = P_GetFFloorTopZAt (rover, v2x, v2y); + l = P_GetFFloorBottomZAt(rover, v1x, v1y); + lS = P_GetFFloorBottomZAt(rover, v2x, v2y); if (!(*rover->t_slope) && !gr_frontsector->c_slope && !gr_backsector->c_slope && h > highcut) h = hS = highcut; if (!(*rover->b_slope) && !gr_frontsector->f_slope && !gr_backsector->f_slope && l < lowcut) @@ -2218,24 +2194,21 @@ static boolean CheckClip(seg_t * seg, sector_t * afrontsector, sector_t * abacks v2x = FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv2)->x); v2y = FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv2)->y); #define SLOPEPARAMS(slope, end1, end2, normalheight) \ - if (slope) { \ - end1 = P_GetZAt(slope, v1x, v1y); \ - end2 = P_GetZAt(slope, v2x, v2y); \ - } else \ - end1 = end2 = normalheight; + end1 = P_GetZAt(slope, v1x, v1y, normalheight); \ + end2 = P_GetZAt(slope, v2x, v2y, normalheight); - SLOPEPARAMS(afrontsector->f_slope, frontf1, frontf2, afrontsector->floorheight) + SLOPEPARAMS(afrontsector->f_slope, frontf1, frontf2, afrontsector-> floorheight) SLOPEPARAMS(afrontsector->c_slope, frontc1, frontc2, afrontsector->ceilingheight) - SLOPEPARAMS( abacksector->f_slope, backf1, backf2, abacksector->floorheight) - SLOPEPARAMS( abacksector->c_slope, backc1, backc2, abacksector->ceilingheight) + SLOPEPARAMS( abacksector->f_slope, backf1, backf2, abacksector-> floorheight) + SLOPEPARAMS( abacksector->c_slope, backc1, backc2, abacksector->ceilingheight) #undef SLOPEPARAMS } else { - frontf1 = frontf2 = afrontsector->floorheight; + frontf1 = frontf2 = afrontsector-> floorheight; frontc1 = frontc2 = afrontsector->ceilingheight; - backf1 = backf2 = abacksector->floorheight; - backc1 = backc2 = abacksector->ceilingheight; + backf1 = backf2 = abacksector-> floorheight; + backc1 = backc2 = abacksector->ceilingheight; } // properly render skies (consider door "open" if both ceilings are sky) // same for floors @@ -2587,10 +2560,8 @@ static void HWR_AddLine(seg_t * line) static sector_t tempsec; fixed_t v1x, v1y, v2x, v2y; // the seg's vertexes as fixed_t -#ifdef POLYOBJECTS if (line->polyseg && !(line->polyseg->flags & POF_RENDERSIDES)) return; -#endif gr_curline = line; @@ -2717,13 +2688,10 @@ static void HWR_AddLine(seg_t * line) if (bothceilingssky && bothfloorssky) // everything's sky? let's save us a bit of time then { - if ( -#ifdef POLYOBJECTS - !line->polyseg && -#endif - !line->sidedef->midtexture - && ((!gr_frontsector->ffloors && !gr_backsector->ffloors) - || (gr_frontsector->tag == gr_backsector->tag))) + if (!line->polyseg && + !line->sidedef->midtexture + && ((!gr_frontsector->ffloors && !gr_backsector->ffloors) + || (gr_frontsector->tag == gr_backsector->tag))) return; // line is empty, don't even bother // treat like wide open window instead HWR_ProcessSeg(); // Doesn't need arguments because they're defined globally :D @@ -2759,13 +2727,10 @@ static void HWR_AddLine(seg_t * line) if (bothceilingssky && bothfloorssky) // everything's sky? let's save us a bit of time then { - if ( -#ifdef POLYOBJECTS - !line->polyseg && -#endif - !line->sidedef->midtexture - && ((!gr_frontsector->ffloors && !gr_backsector->ffloors) - || (gr_frontsector->tag == gr_backsector->tag))) + if (!line->polyseg && + !line->sidedef->midtexture + && ((!gr_frontsector->ffloors && !gr_backsector->ffloors) + || (gr_frontsector->tag == gr_backsector->tag))) return; // line is empty, don't even bother goto clippass; // treat like wide open window instead @@ -2777,16 +2742,13 @@ static void HWR_AddLine(seg_t * line) fixed_t backf1, backf2, backc1, backc2; // back floor ceiling ends #define SLOPEPARAMS(slope, end1, end2, normalheight) \ - if (slope) { \ - end1 = P_GetZAt(slope, v1x, v1y); \ - end2 = P_GetZAt(slope, v2x, v2y); \ - } else \ - end1 = end2 = normalheight; + end1 = P_GetZAt(slope, v1x, v1y, normalheight); \ + end2 = P_GetZAt(slope, v2x, v2y, normalheight); - SLOPEPARAMS(gr_frontsector->f_slope, frontf1, frontf2, gr_frontsector->floorheight) + SLOPEPARAMS(gr_frontsector->f_slope, frontf1, frontf2, gr_frontsector-> floorheight) SLOPEPARAMS(gr_frontsector->c_slope, frontc1, frontc2, gr_frontsector->ceilingheight) - SLOPEPARAMS( gr_backsector->f_slope, backf1, backf2, gr_backsector->floorheight) - SLOPEPARAMS( gr_backsector->c_slope, backc1, backc2, gr_backsector->ceilingheight) + SLOPEPARAMS( gr_backsector->f_slope, backf1, backf2, gr_backsector-> floorheight) + SLOPEPARAMS( gr_backsector->c_slope, backc1, backc2, gr_backsector->ceilingheight) #undef SLOPEPARAMS // if both ceilings are skies, consider it always "open" // same for floors @@ -2957,8 +2919,6 @@ static boolean HWR_CheckBBox(fixed_t *bspcoord) #endif } -#ifdef POLYOBJECTS - // // HWR_AddPolyObjectSegs // @@ -3001,7 +2961,6 @@ static inline void HWR_AddPolyObjectSegs(void) Z_Free(gr_fakeline); } -#ifdef POLYOBJECTS_PLANES static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, fixed_t fixedheight, FBITFIELD blendmode, UINT8 lightlevel, levelflat_t *levelflat, sector_t *FOFsector, UINT8 alpha, extracolormap_t *planecolormap) @@ -3256,8 +3215,6 @@ static void HWR_AddPolyObjectPlanes(void) } } } -#endif -#endif // -----------------+ // HWR_Subsector : Determine floor/ceiling planes. @@ -3349,20 +3306,10 @@ static void HWR_Subsector(size_t num) } else { - cullFloorHeight = locFloorHeight = gr_frontsector->floorheight; - cullCeilingHeight = locCeilingHeight = gr_frontsector->ceilingheight; - - if (gr_frontsector->f_slope) - { - cullFloorHeight = P_GetZAt(gr_frontsector->f_slope, viewx, viewy); - locFloorHeight = P_GetZAt(gr_frontsector->f_slope, gr_frontsector->soundorg.x, gr_frontsector->soundorg.y); - } - - if (gr_frontsector->c_slope) - { - cullCeilingHeight = P_GetZAt(gr_frontsector->c_slope, viewx, viewy); - locCeilingHeight = P_GetZAt(gr_frontsector->c_slope, gr_frontsector->soundorg.x, gr_frontsector->soundorg.y); - } + cullFloorHeight = P_GetSectorFloorZAt (gr_frontsector, viewx, viewy); + cullCeilingHeight = P_GetSectorCeilingZAt(gr_frontsector, viewx, viewy); + locFloorHeight = P_GetSectorFloorZAt (gr_frontsector, gr_frontsector->soundorg.x, gr_frontsector->soundorg.y); + locCeilingHeight = P_GetSectorCeilingZAt(gr_frontsector, gr_frontsector->soundorg.x, gr_frontsector->soundorg.y); } // ----- end special tricks ----- @@ -3454,13 +3401,8 @@ static void HWR_Subsector(size_t num) fixed_t cullHeight, centerHeight; // bottom plane - if (*rover->b_slope) - { - cullHeight = P_GetZAt(*rover->b_slope, viewx, viewy); - centerHeight = P_GetZAt(*rover->b_slope, gr_frontsector->soundorg.x, gr_frontsector->soundorg.y); - } - else - cullHeight = centerHeight = *rover->bottomheight; + cullHeight = P_GetFFloorBottomZAt(rover, viewx, viewy); + centerHeight = P_GetFFloorBottomZAt(rover, gr_frontsector->soundorg.x, gr_frontsector->soundorg.y); if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERPLANES)) continue; @@ -3520,13 +3462,8 @@ static void HWR_Subsector(size_t num) } // top plane - if (*rover->t_slope) - { - cullHeight = P_GetZAt(*rover->t_slope, viewx, viewy); - centerHeight = P_GetZAt(*rover->t_slope, gr_frontsector->soundorg.x, gr_frontsector->soundorg.y); - } - else - cullHeight = centerHeight = *rover->topheight; + cullHeight = P_GetFFloorTopZAt(rover, viewx, viewy); + centerHeight = P_GetFFloorTopZAt(rover, gr_frontsector->soundorg.x, gr_frontsector->soundorg.y); if (centerHeight >= locFloorHeight && centerHeight <= locCeilingHeight && @@ -3585,7 +3522,6 @@ static void HWR_Subsector(size_t num) #endif #endif //doplanes -#ifdef POLYOBJECTS // Draw all the polyobjects in this subsector if (sub->polyList) { @@ -3606,15 +3542,12 @@ static void HWR_Subsector(size_t num) // Draw polyobject lines. HWR_AddPolyObjectSegs(); -#ifdef POLYOBJECTS_PLANES if (sub->validcount != validcount) // This validcount situation seems to let us know that the floors have already been drawn. { // Draw polyobject planes HWR_AddPolyObjectPlanes(); } -#endif } -#endif // Hurder ici se passe les choses INT32�essantes! // on vient de tracer le sol et le plafond @@ -3637,14 +3570,8 @@ static void HWR_Subsector(size_t num) while (count--) { - if (!line->glseg -#ifdef POLYOBJECTS - && !line->polyseg // ignore segs that belong to polyobjects -#endif - ) - { + if (!line->glseg && !line->polyseg) // ignore segs that belong to polyobjects HWR_AddLine(line); - } line++; } } @@ -3959,7 +3886,7 @@ static void HWR_DrawDropShadow(mobj_t *thing, gr_vissprite_t *spr, fixed_t scale HWR_GetPatch(gpatch); scalemul = FixedMul(FRACUNIT - floordiff/640, scale); - scalemul = FixedMul(scalemul, (thing->radius*2) / gpatch->height); + scalemul = FixedMul(scalemul, (thing->radius*2) / SHORT(gpatch->height)); fscale = FIXED_TO_FLOAT(scalemul); fx = FIXED_TO_FLOAT(thing->x); @@ -3971,9 +3898,9 @@ static void HWR_DrawDropShadow(mobj_t *thing, gr_vissprite_t *spr, fixed_t scale // 0--1 if (thing && fabsf(fscale - 1.0f) > 1.0E-36f) - offset = (gpatch->height/2) * fscale; + offset = (SHORT(gpatch->height)/2) * fscale; else - offset = (float)(gpatch->height/2); + offset = (float)(SHORT(gpatch->height)/2); shadowVerts[0].x = shadowVerts[3].x = fx - offset; shadowVerts[2].x = shadowVerts[1].x = fx + offset; @@ -3984,7 +3911,7 @@ static void HWR_DrawDropShadow(mobj_t *thing, gr_vissprite_t *spr, fixed_t scale { for (i = 0; i < 4; i++) { - slopez = P_GetZAt(floorslope, FLOAT_TO_FIXED(shadowVerts[i].x), FLOAT_TO_FIXED(shadowVerts[i].z)); + slopez = P_GetSlopeZAt(floorslope, FLOAT_TO_FIXED(shadowVerts[i].x), FLOAT_TO_FIXED(shadowVerts[i].z)); shadowVerts[i].y = FIXED_TO_FLOAT(slopez) + 0.05f; } } @@ -4048,7 +3975,7 @@ static void HWR_DrawDropShadow(mobj_t *thing, gr_vissprite_t *spr, fixed_t scale } // This is expecting a pointer to an array containing 4 wallVerts for a sprite -static void HWR_RotateSpritePolyToAim(gr_vissprite_t *spr, FOutVector *wallVerts) +static void HWR_RotateSpritePolyToAim(gr_vissprite_t *spr, FOutVector *wallVerts, const boolean precip) { if (cv_grspritebillboarding.value && spr && spr->mobj && !(spr->mobj->frame & FF_PAPERSPRITE) @@ -4056,7 +3983,7 @@ static void HWR_RotateSpritePolyToAim(gr_vissprite_t *spr, FOutVector *wallVerts { float basey = FIXED_TO_FLOAT(spr->mobj->z); float lowy = wallVerts[0].y; - if (P_MobjFlip(spr->mobj) == -1) + if (!precip && P_MobjFlip(spr->mobj) == -1) // precip doesn't have eflags so they can't flip { basey = FIXED_TO_FLOAT(spr->mobj->z + spr->mobj->height); } @@ -4169,7 +4096,7 @@ static void HWR_SplitSprite(gr_vissprite_t *spr) } // Let dispoffset work first since this adjust each vertex - HWR_RotateSpritePolyToAim(spr, baseWallVerts); + HWR_RotateSpritePolyToAim(spr, baseWallVerts, false); realtop = top = baseWallVerts[3].y; realbot = bot = baseWallVerts[0].y; @@ -4220,8 +4147,7 @@ static void HWR_SplitSprite(gr_vissprite_t *spr) for (i = 1; i < sector->numlights; i++) { - fixed_t h = sector->lightlist[i].slope ? P_GetZAt(sector->lightlist[i].slope, spr->mobj->x, spr->mobj->y) - : sector->lightlist[i].height; + fixed_t h = P_GetLightZAt(§or->lightlist[i], spr->mobj->x, spr->mobj->y); if (h <= temp) { if (!(spr->mobj->frame & FF_FULLBRIGHT)) @@ -4246,15 +4172,10 @@ static void HWR_SplitSprite(gr_vissprite_t *spr) if (i + 1 < sector->numlights) { - if (list[i+1].slope) - { - temp = P_GetZAt(list[i+1].slope, v1x, v1y); - bheight = FIXED_TO_FLOAT(temp); - temp = P_GetZAt(list[i+1].slope, v2x, v2y); - endbheight = FIXED_TO_FLOAT(temp); - } - else - bheight = endbheight = FIXED_TO_FLOAT(list[i+1].height); + temp = P_GetLightZAt(&list[i+1], v1x, v1y); + bheight = FIXED_TO_FLOAT(temp); + temp = P_GetLightZAt(&list[i+1], v2x, v2y); + endbheight = FIXED_TO_FLOAT(temp); } else { @@ -4448,7 +4369,7 @@ static void HWR_DrawSprite(gr_vissprite_t *spr) } // Let dispoffset work first since this adjust each vertex - HWR_RotateSpritePolyToAim(spr, wallVerts); + HWR_RotateSpritePolyToAim(spr, wallVerts, false); // This needs to be AFTER the shadows so that the regular sprites aren't drawn completely black. // sprite lighting by modulating the RGB components @@ -4532,7 +4453,7 @@ static inline void HWR_DrawPrecipitationSprite(gr_vissprite_t *spr) wallVerts[1].z = wallVerts[2].z = spr->z2; // Let dispoffset work first since this adjust each vertex - HWR_RotateSpritePolyToAim(spr, wallVerts); + HWR_RotateSpritePolyToAim(spr, wallVerts, true); wallVerts[0].sow = wallVerts[3].sow = 0; wallVerts[2].sow = wallVerts[1].sow = gpatch->max_s; @@ -5282,10 +5203,10 @@ static void HWR_ProjectSprite(mobj_t *thing) rotsprite = sprframe->rotsprite.patch[rot][rollangle]; if (rotsprite != NULL) { - spr_width = rotsprite->width << FRACBITS; - spr_height = rotsprite->height << FRACBITS; - spr_offset = rotsprite->leftoffset << FRACBITS; - spr_topoffset = rotsprite->topoffset << FRACBITS; + spr_width = SHORT(rotsprite->width) << FRACBITS; + spr_height = SHORT(rotsprite->height) << FRACBITS; + spr_offset = SHORT(rotsprite->leftoffset) << FRACBITS; + spr_topoffset = SHORT(rotsprite->topoffset) << FRACBITS; // flip -> rotate, not rotate -> flip flip = 0; } diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index b47ac09bf..e4ea26d86 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -677,12 +677,12 @@ spritemodelfound: #define SETBRIGHTNESS(brightness,r,g,b) \ 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; UINT32 size = w*h; 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 translen = 0; UINT8 i; @@ -718,16 +718,16 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, if (skinnum == TC_METALSONIC) color = SKINCOLOR_COBALT; - if (color != SKINCOLOR_NONE) + if (color != SKINCOLOR_NONE && color < numskincolors) { UINT8 numdupes = 1; - translation[translen] = Color_Index[color-1][0]; + translation[translen] = skincolors[color].ramp[0]; cutoff[translen] = 255; for (i = 1; i < 16; i++) { - if (translation[translen] == Color_Index[color-1][i]) + if (translation[translen] == skincolors[color].ramp[i]) { numdupes++; continue; @@ -741,7 +741,7 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, numdupes = 1; translen++; - translation[translen] = (UINT8)Color_Index[color-1][i]; + translation[translen] = (UINT16)skincolors[color].ramp[i]; } translen++; @@ -1043,7 +1043,7 @@ skippixel: #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 GLMipmap_t *grmip, *newmip; @@ -1336,7 +1336,7 @@ boolean HWR_DrawModel(gr_vissprite_t *spr) else 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) skinnum = TC_RAINBOW; @@ -1356,7 +1356,7 @@ boolean HWR_DrawModel(gr_vissprite_t *spr) } // 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 { diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 6aa5a4510..6f2319a50 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -68,7 +68,7 @@ patch_t *nightsnum[10]; // 0-9 // Level title and credits fonts patch_t *lt_font[LT_FONTSIZE]; patch_t *cred_font[CRED_FONTSIZE]; -patch_t *ttlnum[20]; // act numbers (0-19) +patch_t *ttlnum[10]; // act numbers (0-9) // Name tag fonts patch_t *ntb_font[NT_FONTSIZE]; @@ -243,7 +243,7 @@ void HU_LoadGraphics(void) tallinfin = (patch_t *)W_CachePatchName("STTINFIN", PU_HUDGFX); // cache act numbers for level titles - for (i = 0; i < 20; i++) + for (i = 0; i < 10; i++) { sprintf(buffer, "TTL%.2d", i); ttlnum[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX); @@ -755,113 +755,40 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum) } else { - const UINT8 color = players[playernum].skincolor; + UINT16 chatcolor = skincolors[players[playernum].skincolor].chatcolor; - cstart = "\x83"; - - // Follow palette order at r_draw.c Color_Names - switch (color) - { - default: - case SKINCOLOR_WHITE: - case SKINCOLOR_BONE: - case SKINCOLOR_CLOUDY: - case SKINCOLOR_GREY: - case SKINCOLOR_SILVER: - case SKINCOLOR_AETHER: - case SKINCOLOR_SLATE: - cstart = "\x80"; // white - break; - case SKINCOLOR_CARBON: - case SKINCOLOR_JET: - case SKINCOLOR_BLACK: - cstart = "\x86"; // V_GRAYMAP - break; - case SKINCOLOR_PINK: - case SKINCOLOR_RUBY: - case SKINCOLOR_SALMON: - case SKINCOLOR_RED: - case SKINCOLOR_CRIMSON: - case SKINCOLOR_FLAME: - case SKINCOLOR_KETCHUP: - cstart = "\x85"; // V_REDMAP - break; - case SKINCOLOR_YOGURT: - case SKINCOLOR_BROWN: - case SKINCOLOR_BRONZE: - 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; - } + if (!chatcolor || chatcolor%0x1000 || chatcolor>V_INVERTMAP) + cstart = "\x80"; + else if (chatcolor == V_MAGENTAMAP) + cstart = "\x81"; + else if (chatcolor == V_YELLOWMAP) + cstart = "\x82"; + else if (chatcolor == V_GREENMAP) + cstart = "\x83"; + else if (chatcolor == V_BLUEMAP) + cstart = "\x84"; + else if (chatcolor == V_REDMAP) + cstart = "\x85"; + else if (chatcolor == V_GRAYMAP) + cstart = "\x86"; + else if (chatcolor == V_ORANGEMAP) + cstart = "\x87"; + else if (chatcolor == V_SKYMAP) + cstart = "\x88"; + else if (chatcolor == V_PURPLEMAP) + cstart = "\x89"; + else if (chatcolor == V_AQUAMAP) + cstart = "\x8a"; + else if (chatcolor == V_PERIDOTMAP) + cstart = "\x8b"; + else if (chatcolor == V_AZUREMAP) + cstart = "\x8c"; + else if (chatcolor == V_BROWNMAP) + cstart = "\x8d"; + else if (chatcolor == V_ROSYMAP) + cstart = "\x8e"; + else if (chatcolor == V_INVERTMAP) + cstart = "\x8f"; } prefix = cstart; diff --git a/src/hu_stuff.h b/src/hu_stuff.h index 9e3c66747..63d85f1b8 100644 --- a/src/hu_stuff.h +++ b/src/hu_stuff.h @@ -85,7 +85,7 @@ extern patch_t *lt_font[LT_FONTSIZE]; extern patch_t *cred_font[CRED_FONTSIZE]; extern patch_t *ntb_font[NT_FONTSIZE]; extern patch_t *nto_font[NT_FONTSIZE]; -extern patch_t *ttlnum[20]; +extern patch_t *ttlnum[10]; extern patch_t *emeraldpics[3][8]; extern patch_t *rflagico; extern patch_t *bflagico; diff --git a/src/info.c b/src/info.c index bd6ccb527..f0272fc79 100644 --- a/src/info.c +++ b/src/info.c @@ -20,6 +20,7 @@ #include "m_misc.h" #include "z_zone.h" #include "d_player.h" +#include "v_video.h" // V_*MAP constants #include "lzf.h" #ifdef HWRENDER #include "hardware/hw_light.h" @@ -187,6 +188,8 @@ char sprnames[NUMSPRITES + 1][5] = // Projectiles "MISL", + "LASR", // GFZ3 laser + "LASF", // GFZ3 laser flames "TORP", // Torpedo "ENRG", // Energy ball "MINE", // Skim mine @@ -2058,7 +2061,15 @@ state_t states[NUMSTATES] = {SPR_MISL, FF_FULLBRIGHT, 1, {A_SmokeTrailer}, MT_SMOKE, 0, S_ROCKET}, // S_ROCKET - {SPR_MISL, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_NULL}, // S_LASER + {SPR_LASR, FF_FULLBRIGHT|0, 2, {NULL}, 0, 0, S_NULL}, // S_LASER + {SPR_LASR, FF_FULLBRIGHT|1, 2, {NULL}, 0, 0, S_NULL}, // S_LASER2 + {SPR_LASR, FF_FULLBRIGHT|2, 2, {NULL}, 0, 0, S_NULL}, // S_LASERFLASH + + {SPR_LASF, FF_FULLBRIGHT|0, 2, {NULL}, 0, 0, S_LASERFLAME2}, // S_LASERFLAME1 + {SPR_LASF, FF_FULLBRIGHT|1, 1, {A_ChangeHeight}, 156*FRACUNIT, 3, S_LASERFLAME3}, // S_LASERFLAME2 + {SPR_LASF, FF_FULLBRIGHT|2, 0, {A_ChangeHeight}, 32*FRACUNIT, 3, S_LASERFLAME4}, // S_LASERFLAME3 + {SPR_LASF, FF_ANIMATE|FF_PAPERSPRITE|FF_FULLBRIGHT|2, 4, {NULL}, 1, 2, S_LASERFLAME5}, // S_LASERFLAME4 + {SPR_LASF, FF_ANIMATE|FF_PAPERSPRITE|FF_FULLBRIGHT|4, 28, {NULL}, 2, 2, S_NULL}, // S_LASERFLAME5 {SPR_TORP, 0, 1, {A_SmokeTrailer}, MT_SMOKE, 0, S_TORPEDO}, // S_TORPEDO @@ -5665,28 +5676,28 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = { // MT_EGGMOBILE_FIRE -1, // doomednum - S_SPINFIRE1, // spawnstate + S_LASERFLAME1, // spawnstate 1, // spawnhealth S_NULL, // seestate - sfx_None, // seesound + sfx_s3kc2s, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance - sfx_None, // painsound + sfx_s3k8d, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 8*FRACUNIT, // radius - 14*FRACUNIT, // height + 24*FRACUNIT, // radius + 84*FRACUNIT, // height 0, // display offset DMG_FIRE, // mass 1, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_MISSILE|MF_NOGRAVITY|MF_FIRE, // flags + MF_NOGRAVITY|MF_FIRE|MF_PAIN, // flags S_NULL // raisestate }, @@ -9637,8 +9648,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // painstate 0, // painchance sfx_None, // painsound - S_NULL, // meleestate - S_NULL, // missilestate + S_LASERFLASH, // meleestate + S_LASER2, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound @@ -9649,7 +9660,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 0, // mass 20, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_MISSILE|MF_NOGRAVITY, // flags + MF_MISSILE|MF_NOGRAVITY, // flags S_NULL // raisestate }, @@ -21606,8 +21617,140 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = #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. */ void P_PatchInfoTables(void) @@ -21635,6 +21778,11 @@ void P_PatchInfoTables(void) sprnames[i][0] = '\0'; // i == NUMSPRITES memset(&states[S_FIRSTFREESLOT], 0, sizeof (state_t) * NUMSTATEFREESLOTS); 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++) mobjinfo[i].doomednum = -1; } @@ -21643,7 +21791,8 @@ void P_PatchInfoTables(void) static char *sprnamesbackup; static state_t *statesbackup; static mobjinfo_t *mobjinfobackup; -static size_t sprnamesbackupsize, statesbackupsize, mobjinfobackupsize; +static skincolor_t *skincolorsbackup; +static size_t sprnamesbackupsize, statesbackupsize, mobjinfobackupsize, skincolorsbackupsize; #endif void P_BackupTables(void) @@ -21653,6 +21802,7 @@ void P_BackupTables(void) sprnamesbackup = Z_Malloc(sizeof(sprnames), PU_STATIC, NULL); statesbackup = Z_Malloc(sizeof(states), PU_STATIC, NULL); mobjinfobackup = Z_Malloc(sizeof(mobjinfo), PU_STATIC, NULL); + skincolorsbackup = Z_Malloc(sizeof(skincolors), PU_STATIC, NULL); // Sprite names sprnamesbackupsize = lzf_compress(sprnames, sizeof(sprnames), sprnamesbackup, sizeof(sprnames)); @@ -21674,6 +21824,13 @@ void P_BackupTables(void) mobjinfobackup = Z_Realloc(mobjinfobackup, mobjinfobackupsize, PU_STATIC, NULL); else 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 } @@ -21706,5 +21863,13 @@ void P_ResetData(INT32 flags) else 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 } diff --git a/src/info.h b/src/info.h index 586209ff9..79af9bbbb 100644 --- a/src/info.h +++ b/src/info.h @@ -284,6 +284,7 @@ void A_RolloutRock(); void A_DragonbomberSpawn(); void A_DragonWing(); void A_DragonSegment(); +void A_ChangeHeight(); // ratio of states to sprites to mobj types is roughly 6 : 1 : 1 #define NUMMOBJFREESLOTS 512 @@ -451,6 +452,8 @@ typedef enum sprite // Projectiles SPR_MISL, + SPR_LASR, // GFZ3 laser + SPR_LASF, // GFZ3 laser flames SPR_TORP, // Torpedo SPR_ENRG, // Energy ball SPR_MINE, // Skim mine @@ -2220,6 +2223,14 @@ typedef enum state S_ROCKET, S_LASER, + S_LASER2, + S_LASERFLASH, + + S_LASERFLAME1, + S_LASERFLAME2, + S_LASERFLAME3, + S_LASERFLAME4, + S_LASERFLAME5, S_TORPEDO, diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 74938739c..d460f8cf7 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -14,7 +14,7 @@ #include "fastcmp.h" #include "p_local.h" #include "p_setup.h" // So we can have P_SetupLevelSky -#include "p_slopes.h" // P_GetZAt +#include "p_slopes.h" // P_GetSlopeZAt #include "z_zone.h" #include "r_main.h" #include "r_draw.h" @@ -27,6 +27,7 @@ #include "hu_stuff.h" // HU_AddChatText #include "console.h" #include "d_netcmd.h" // IsPlayerAdmin +#include "m_menu.h" // Player Setup menu color stuff #include "lua_script.h" #include "lua_libs.h" @@ -144,6 +145,8 @@ static const struct { {META_STATE, "state_t"}, {META_MOBJINFO, "mobjinfo_t"}, {META_SFXINFO, "sfxinfo_t"}, + {META_SKINCOLOR, "skincolor_t"}, + {META_COLORRAMP, "skincolor_t.ramp"}, {META_SPRITEINFO, "spriteinfo_t"}, {META_PIVOTLIST, "spriteframepivot_t[]"}, {META_FRAMEPIVOT, "spriteframepivot_t"}, @@ -252,6 +255,43 @@ static int lib_reserveLuabanks(lua_State *L) 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 ////////////// @@ -2184,14 +2224,20 @@ static int lib_evStartCrumble(lua_State *L) static int lib_pGetZAt(lua_State *L) { - pslope_t *slope = *((pslope_t **)luaL_checkudata(L, 1, META_SLOPE)); fixed_t x = luaL_checkfixed(L, 2); fixed_t y = luaL_checkfixed(L, 3); //HUDSAFE - if (!slope) - return LUA_ErrInvalid(L, "pslope_t"); + if (lua_isnil(L, 1)) + { + fixed_t z = luaL_checkfixed(L, 4); + lua_pushfixed(L, P_GetZAt(NULL, x, y, z)); + } + else + { + pslope_t *slope = *((pslope_t **)luaL_checkudata(L, 1, META_SLOPE)); + lua_pushfixed(L, P_GetSlopeZAt(slope, x, y)); + } - lua_pushfixed(L, P_GetZAt(slope, x, y)); return 1; } @@ -2382,10 +2428,10 @@ static int lib_rGetColorByName(lua_State *L) // SKINCOLOR_GREEN > "Green" for example static int lib_rGetNameByColor(lua_State *L) { - UINT8 colornum = (UINT8)luaL_checkinteger(L, 1); - if (!colornum || colornum >= MAXSKINCOLORS) - return luaL_error(L, "skincolor %d out of range (1 - %d).", colornum, MAXSKINCOLORS-1); - lua_pushstring(L, Color_Names[colornum]); + UINT16 colornum = (UINT16)luaL_checkinteger(L, 1); + if (!colornum || colornum >= numskincolors) + return luaL_error(L, "skincolor %d out of range (1 - %d).", colornum, numskincolors-1); + lua_pushstring(L, skincolors[colornum].name); return 1; } @@ -2458,6 +2504,20 @@ static int lib_sStopSound(lua_State *L) return 0; } +static int lib_sStopSoundByID(lua_State *L) +{ + void *origin = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); + sfxenum_t sound_id = luaL_checkinteger(L, 2); + //NOHUD + if (!origin) + return LUA_ErrInvalid(L, "mobj_t"); + if (sound_id >= NUMSFX) + return luaL_error(L, "sfx %d out of range (0 - %d)", sound_id, NUMSFX-1); + + S_StopSoundByID(origin, sound_id); + return 0; +} + static int lib_sChangeMusic(lua_State *L) { #ifdef MUSICSLOT_COMPATIBILITY @@ -2878,15 +2938,50 @@ static int lib_gAddGametype(lua_State *L) return 0; } +static int Lcheckmapnumber (lua_State *L, int idx, const char *fun) +{ + if (ISINLEVEL) + return luaL_optinteger(L, idx, gamemap); + else + { + if (lua_isnoneornil(L, idx)) + { + return luaL_error(L, + "%s can only be used without a parameter while in a level.", + fun + ); + } + else + return luaL_checkinteger(L, idx); + } +} + static int lib_gBuildMapName(lua_State *L) { - INT32 map = luaL_optinteger(L, 1, gamemap); + INT32 map = Lcheckmapnumber(L, 1, "G_BuildMapName"); //HUDSAFE - INLEVEL lua_pushstring(L, G_BuildMapName(map)); return 1; } +static int lib_gBuildMapTitle(lua_State *L) +{ + INT32 map = Lcheckmapnumber(L, 1, "G_BuildMapTitle"); + char *name; + if (map < 1 || map > NUMMAPS) + { + return luaL_error(L, + "map number %d out of range (1 - %d)", + map, + NUMMAPS + ); + } + name = G_BuildMapTitle(map); + lua_pushstring(L, name); + Z_Free(name); + return 1; +} + static int lib_gDoReborn(lua_State *L) { INT32 playernum = luaL_checkinteger(L, 1); @@ -3073,6 +3168,12 @@ static luaL_Reg lib[] = { {"IsPlayerAdmin", lib_isPlayerAdmin}, {"reserveLuabanks", lib_reserveLuabanks}, + // m_menu + {"M_MoveColorAfter",lib_pMoveColorAfter}, + {"M_MoveColorBefore",lib_pMoveColorBefore}, + {"M_GetColorAfter",lib_pGetColorAfter}, + {"M_GetColorBefore",lib_pGetColorBefore}, + // m_random {"P_RandomFixed",lib_pRandomFixed}, {"P_RandomByte",lib_pRandomByte}, @@ -3253,6 +3354,7 @@ static luaL_Reg lib[] = { {"S_StartSound",lib_sStartSound}, {"S_StartSoundAtVolume",lib_sStartSoundAtVolume}, {"S_StopSound",lib_sStopSound}, + {"S_StopSoundByID",lib_sStopSoundByID}, {"S_ChangeMusic",lib_sChangeMusic}, {"S_SpeedMusic",lib_sSpeedMusic}, {"S_StopMusic",lib_sStopMusic}, @@ -3271,6 +3373,7 @@ static luaL_Reg lib[] = { // g_game {"G_AddGametype", lib_gAddGametype}, {"G_BuildMapName",lib_gBuildMapName}, + {"G_BuildMapTitle",lib_gBuildMapTitle}, {"G_DoReborn",lib_gDoReborn}, {"G_SetCustomExitVars",lib_gSetCustomExitVars}, {"G_EnoughPlayersFinished",lib_gEnoughPlayersFinished}, diff --git a/src/lua_blockmaplib.c b/src/lua_blockmaplib.c index bc8d20e8e..5aae73284 100644 --- a/src/lua_blockmaplib.c +++ b/src/lua_blockmaplib.c @@ -80,9 +80,7 @@ static UINT8 lib_searchBlockmap_Lines(lua_State *L, INT32 x, INT32 y, mobj_t *th { INT32 offset; const INT32 *list; // Big blockmap -#ifdef POLYOBJECTS polymaplink_t *plink; // haleyjd 02/22/06 -#endif line_t *ld; if (x < 0 || y < 0 || x >= bmapwidth || y >= bmapheight) @@ -90,7 +88,6 @@ static UINT8 lib_searchBlockmap_Lines(lua_State *L, INT32 x, INT32 y, mobj_t *th offset = y*bmapwidth + x; -#ifdef POLYOBJECTS // haleyjd 02/22/06: consider polyobject lines plink = polyblocklinks[offset]; @@ -133,7 +130,6 @@ static UINT8 lib_searchBlockmap_Lines(lua_State *L, INT32 x, INT32 y, mobj_t *th } plink = (polymaplink_t *)(plink->link.next); } -#endif offset = *(blockmap + offset); // offset = blockmap[y*bmapwidth+x]; diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index 703b924bb..4aa70574b 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -878,8 +878,8 @@ static int libd_drawNameTag(lua_State *L) INT32 y; const char *str; INT32 flags; - UINT8 basecolor; - UINT8 outlinecolor; + UINT16 basecolor; + UINT16 outlinecolor; UINT8 *basecolormap = NULL; UINT8 *outlinecolormap = NULL; @@ -908,8 +908,8 @@ static int libd_drawScaledNameTag(lua_State *L) const char *str; INT32 flags; fixed_t scale; - UINT8 basecolor; - UINT8 outlinecolor; + UINT16 basecolor; + UINT16 outlinecolor; UINT8 *basecolormap = NULL; UINT8 *outlinecolormap = NULL; @@ -966,7 +966,7 @@ static int libd_nameTagWidth(lua_State *L) static int libd_getColormap(lua_State *L) { INT32 skinnum = TC_DEFAULT; - skincolors_t color = luaL_optinteger(L, 2, 0); + skincolornum_t color = luaL_optinteger(L, 2, 0); UINT8* colormap = NULL; HUDONLY if (lua_isnoneornil(L, 1)) diff --git a/src/lua_infolib.c b/src/lua_infolib.c index a82403097..81a215c53 100644 --- a/src/lua_infolib.c +++ b/src/lua_infolib.c @@ -25,6 +25,9 @@ #include "lua_libs.h" #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); state_t *astate; @@ -1465,6 +1468,229 @@ static int lib_luabankslen(lua_State *L) 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; iramp[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; jramp[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; iramp[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! @@ -1502,6 +1728,28 @@ int LUA_InfoLib(lua_State *L) lua_setfield(L, -2, "__len"); 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); lua_pushcfunction(L, sfxinfo_get); lua_setfield(L, -2, "__index"); @@ -1605,6 +1853,19 @@ int LUA_InfoLib(lua_State *L) lua_setmetatable(L, -2); 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_createtable(L, 0, 2); lua_pushcfunction(L, lib_getSfxInfo); diff --git a/src/lua_libs.h b/src/lua_libs.h index d0334d725..a78128e9f 100644 --- a/src/lua_libs.h +++ b/src/lua_libs.h @@ -20,6 +20,8 @@ extern lua_State *gL; #define META_STATE "STATE_T*" #define META_MOBJINFO "MOBJINFO_T*" #define META_SFXINFO "SFXINFO_T*" +#define META_SKINCOLOR "SKINCOLOR_T*" +#define META_COLORRAMP "SKINCOLOR_T*RAMP" #define META_SPRITEINFO "SPRITEINFO_T*" #define META_PIVOTLIST "SPRITEFRAMEPIVOT_T[]" #define META_FRAMEPIVOT "SPRITEFRAMEPIVOT_T*" diff --git a/src/lua_maplib.c b/src/lua_maplib.c index d851c820e..ece42b8d3 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -2082,6 +2082,12 @@ static int mapheaderinfo_get(lua_State *L) lua_pushinteger(L, header->menuflags); else if (fastcmp(field,"startrings")) lua_pushinteger(L, header->startrings); + else if (fastcmp(field, "sstimer")) + lua_pushinteger(L, header->sstimer); + else if (fastcmp(field, "ssspheres")) + lua_pushinteger(L, header->ssspheres); + else if (fastcmp(field, "gravity")) + lua_pushfixed(L, header->gravity); // TODO add support for reading numGradedMares and grades else { // Read custom vars now diff --git a/src/lua_mathlib.c b/src/lua_mathlib.c index 215903278..76c80c541 100644 --- a/src/lua_mathlib.c +++ b/src/lua_mathlib.c @@ -172,15 +172,14 @@ static int lib_all7emeralds(lua_State *L) return 1; } -// Whee, special Lua-exclusive function for making use of Color_Opposite[] // Returns both color and signpost shade numbers! static int lib_coloropposite(lua_State *L) { - UINT8 colornum = (UINT8)luaL_checkinteger(L, 1); - if (!colornum || colornum >= MAXSKINCOLORS) - return luaL_error(L, "skincolor %d out of range (1 - %d).", colornum, MAXSKINCOLORS-1); - lua_pushinteger(L, Color_Opposite[colornum-1][0]); // push color - lua_pushinteger(L, Color_Opposite[colornum-1][1]); // push sign shade index, 0-15 + UINT16 colornum = (UINT16)luaL_checkinteger(L, 1); + if (!colornum || colornum >= numskincolors) + return luaL_error(L, "skincolor %d out of range (1 - %d).", colornum, numskincolors-1); + lua_pushinteger(L, skincolors[colornum].invcolor); // push color + lua_pushinteger(L, skincolors[colornum].invshade); // push sign shade index, 0-15 return 2; } diff --git a/src/lua_mobjlib.c b/src/lua_mobjlib.c index 81729b788..3ca3ca1d7 100644 --- a/src/lua_mobjlib.c +++ b/src/lua_mobjlib.c @@ -574,9 +574,9 @@ static int mobj_set(lua_State *L) } case mobj_color: { - UINT8 newcolor = (UINT8)luaL_checkinteger(L,3); - if (newcolor >= MAXTRANSLATIONS) - return luaL_error(L, "mobj.color %d out of range (0 - %d).", newcolor, MAXTRANSLATIONS-1); + UINT16 newcolor = (UINT16)luaL_checkinteger(L,3); + if (newcolor >= numskincolors) + return luaL_error(L, "mobj.color %d out of range (0 - %d).", newcolor, numskincolors-1); mo->color = newcolor; break; } @@ -829,6 +829,15 @@ static int mapthing_set(lua_State *L) return 0; } +static int mapthing_num(lua_State *L) +{ + mapthing_t *mt = *((mapthing_t **)luaL_checkudata(L, 1, META_MAPTHING)); + if (!mt) + return luaL_error(L, "accessed mapthing_t doesn't exist anymore."); + lua_pushinteger(L, mt-mapthings); + return 1; +} + static int lib_iterateMapthings(lua_State *L) { size_t i = 0; @@ -893,6 +902,9 @@ int LUA_MobjLib(lua_State *L) lua_pushcfunction(L, mapthing_set); lua_setfield(L, -2, "__newindex"); + + lua_pushcfunction(L, mapthing_num); + lua_setfield(L, -2, "__len"); lua_pop(L,1); lua_newuserdata(L, 0); diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index cdece1fb7..1ce9be525 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -461,9 +461,9 @@ static int player_set(lua_State *L) plr->flashpal = (UINT16)luaL_checkinteger(L, 3); else if (fastcmp(field,"skincolor")) { - UINT8 newcolor = (UINT8)luaL_checkinteger(L,3); - if (newcolor >= MAXSKINCOLORS) - return luaL_error(L, "player.skincolor %d out of range (0 - %d).", newcolor, MAXSKINCOLORS-1); + UINT16 newcolor = (UINT16)luaL_checkinteger(L,3); + if (newcolor >= numskincolors) + return luaL_error(L, "player.skincolor %d out of range (0 - %d).", newcolor, numskincolors-1); plr->skincolor = newcolor; } else if (fastcmp(field,"score")) diff --git a/src/lua_script.c b/src/lua_script.c index 6b7b122f0..4f94b007e 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -730,9 +730,13 @@ void LUA_InvalidatePlayer(player_t *player) enum { ARCH_NULL=0, - ARCH_BOOLEAN, - ARCH_SIGNED, - ARCH_STRING, + ARCH_TRUE, + ARCH_FALSE, + ARCH_INT8, + ARCH_INT16, + ARCH_INT32, + ARCH_SMALLSTRING, + ARCH_LARGESTRING, ARCH_TABLE, ARCH_MOBJINFO, @@ -752,6 +756,7 @@ enum ARCH_FFLOOR, ARCH_SLOPE, ARCH_MAPHEADER, + ARCH_SKINCOLOR, ARCH_TEND=0xFF, }; @@ -777,6 +782,7 @@ static const struct { {META_FFLOOR, ARCH_FFLOOR}, {META_SLOPE, ARCH_SLOPE}, {META_MAPHEADER, ARCH_MAPHEADER}, + {META_SKINCOLOR, ARCH_SKINCOLOR}, {NULL, ARCH_NULL} }; @@ -817,22 +823,33 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex) WRITEUINT8(save_p, ARCH_NULL); return 2; case LUA_TBOOLEAN: - WRITEUINT8(save_p, ARCH_BOOLEAN); - WRITEUINT8(save_p, lua_toboolean(gL, myindex)); + WRITEUINT8(save_p, lua_toboolean(gL, myindex) ? ARCH_TRUE : ARCH_FALSE); break; case LUA_TNUMBER: { lua_Integer number = lua_tointeger(gL, myindex); - WRITEUINT8(save_p, ARCH_SIGNED); - WRITEFIXED(save_p, number); + if (number >= INT8_MIN && number <= INT8_MAX) + { + WRITEUINT8(save_p, ARCH_INT8); + WRITESINT8(save_p, number); + } + else if (number >= INT16_MIN && number <= INT16_MAX) + { + WRITEUINT8(save_p, ARCH_INT16); + WRITEINT16(save_p, number); + } + else + { + WRITEUINT8(save_p, ARCH_INT32); + WRITEFIXED(save_p, number); + } break; } case LUA_TSTRING: { - UINT16 len = (UINT16)lua_objlen(gL, myindex); // get length of string, including embedded zeros + UINT32 len = (UINT32)lua_objlen(gL, myindex); // get length of string, including embedded zeros const char *s = lua_tostring(gL, myindex); - UINT16 i = 0; - WRITEUINT8(save_p, ARCH_STRING); + UINT32 i = 0; // if you're wondering why we're writing a string to save_p this way, // it turns out that Lua can have embedded zeros ('\0') in the strings, // so we can't use WRITESTRING as that cuts off when it finds a '\0'. @@ -840,7 +857,16 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex) // fixing the awful crashes previously encountered for reading strings longer than 1024 // (yes I know that's kind of a stupid thing to care about, but it'd be evil to trim or ignore them?) // -- Monster Iestyn 05/08/18 - WRITEUINT16(save_p, len); // save size of string + if (len < 255) + { + WRITEUINT8(save_p, ARCH_SMALLSTRING); + WRITEUINT8(save_p, len); // save size of string + } + else + { + WRITEUINT8(save_p, ARCH_LARGESTRING); + WRITEUINT32(save_p, len); // save size of string + } while (i < len) WRITECHAR(save_p, s[i++]); // write chars individually, including the embedded zeros break; @@ -1044,6 +1070,14 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex) } 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: WRITEUINT8(save_p, ARCH_NULL); return 2; @@ -1170,21 +1204,36 @@ static UINT8 UnArchiveValue(int TABLESINDEX) case ARCH_NULL: lua_pushnil(gL); break; - case ARCH_BOOLEAN: - lua_pushboolean(gL, READUINT8(save_p)); + case ARCH_TRUE: + lua_pushboolean(gL, true); break; - case ARCH_SIGNED: + case ARCH_FALSE: + lua_pushboolean(gL, false); + break; + case ARCH_INT8: + lua_pushinteger(gL, READSINT8(save_p)); + break; + case ARCH_INT16: + lua_pushinteger(gL, READINT16(save_p)); + break; + case ARCH_INT32: lua_pushinteger(gL, READFIXED(save_p)); break; - case ARCH_STRING: + case ARCH_SMALLSTRING: + case ARCH_LARGESTRING: { - UINT16 len = READUINT16(save_p); // length of string, including embedded zeros + UINT32 len; char *value; - UINT16 i = 0; + UINT32 i = 0; + // See my comments in the ArchiveValue function; // it's much the same for reading strings as writing them! // (i.e. we can't use READSTRING either) // -- Monster Iestyn 05/08/18 + if (type == ARCH_SMALLSTRING) + len = READUINT8(save_p); // length of string, including embedded zeros + else + len = READUINT32(save_p); // length of string, including embedded zeros value = malloc(len); // make temp buffer of size len // now read the actual string while (i < len) @@ -1260,6 +1309,9 @@ static UINT8 UnArchiveValue(int TABLESINDEX) case ARCH_MAPHEADER: LUA_PushUserdata(gL, mapheaderinfo[READUINT16(save_p)], META_MAPHEADER); break; + case ARCH_SKINCOLOR: + LUA_PushUserdata(gL, &skincolors[READUINT16(save_p)], META_SKINCOLOR); + break; case ARCH_TEND: return 1; } diff --git a/src/lua_script.h b/src/lua_script.h index 3166fdfc7..8d5bed7c7 100644 --- a/src/lua_script.h +++ b/src/lua_script.h @@ -99,5 +99,8 @@ void COM_Lua_f(void); // uncomment if you want seg_t/node_t in Lua // #define HAVE_LUA_SEGS -#define INLEVEL if (gamestate != GS_LEVEL && !titlemapinaction)\ +#define ISINLEVEL \ + (gamestate == GS_LEVEL || titlemapinaction) + +#define INLEVEL if (! ISINLEVEL)\ return luaL_error(L, "This can only be used in a level!"); diff --git a/src/m_anigif.c b/src/m_anigif.c index ce2ca20b9..1b71a09bc 100644 --- a/src/m_anigif.c +++ b/src/m_anigif.c @@ -490,29 +490,28 @@ const UINT8 gifframe_gchead[4] = {0x21,0xF9,0x04,0x04}; // GCE, bytes, packed by static UINT8 *gifframe_data = NULL; static size_t gifframe_size = 8192; +// +// GIF_rgbconvert +// converts an RGB frame to a frame with a palette. +// #ifdef HWRENDER -static void hwrconvert(void) +static void GIF_rgbconvert(UINT8 *linear, UINT8 *scr) { - UINT8 *linear = HWR_GetScreenshot(); - UINT8 *dest = screens[2]; UINT8 r, g, b; - INT32 x, y; - size_t i = 0; + size_t src = 0, dest = 0; + size_t size = (vid.width * vid.height * 3); InitColorLUT(gif_framepalette); - for (y = 0; y < vid.height; y++) + while (src < size) { - for (x = 0; x < vid.width; x++, i += 3) - { - r = (UINT8)linear[i]; - g = (UINT8)linear[i + 1]; - b = (UINT8)linear[i + 2]; - dest[(y * vid.width) + x] = colorlookup[r >> SHIFTCOLORBITS][g >> SHIFTCOLORBITS][b >> SHIFTCOLORBITS]; - } + r = (UINT8)linear[src]; + g = (UINT8)linear[src + 1]; + b = (UINT8)linear[src + 2]; + scr[dest] = colorlookup[r >> SHIFTCOLORBITS][g >> SHIFTCOLORBITS][b >> SHIFTCOLORBITS]; + src += (3 * scrbuf_downscaleamt); + dest += scrbuf_downscaleamt; } - - free(linear); } #endif @@ -556,7 +555,11 @@ static void GIF_framewrite(void) I_ReadScreen(movie_screen); #ifdef HWRENDER else if (rendermode == render_opengl) - hwrconvert(); + { + UINT8 *linear = HWR_GetScreenshot(); + GIF_rgbconvert(linear, movie_screen); + free(linear); + } #endif } else @@ -565,18 +568,20 @@ static void GIF_framewrite(void) blitw = vid.width; blith = vid.height; - if (gif_frames == 0) - { - if (rendermode == render_soft) - I_ReadScreen(movie_screen); #ifdef HWRENDER - else if (rendermode == render_opengl) - { - hwrconvert(); - VID_BlitLinearScreen(screens[2], screens[0], vid.width*vid.bpp, vid.height, vid.width*vid.bpp, vid.rowbytes); - } -#endif + // Copy the current OpenGL frame into the base screen + if (rendermode == render_opengl) + { + UINT8 *linear = HWR_GetScreenshot(); + GIF_rgbconvert(linear, screens[0]); + free(linear); } +#endif + + // Copy the first frame into the movie screen + // OpenGL already does the same above. + if (gif_frames == 0 && rendermode == render_soft) + I_ReadScreen(movie_screen); movie_screen = screens[0]; } diff --git a/src/m_cheat.c b/src/m_cheat.c index f6fdb63e9..3d188644b 100644 --- a/src/m_cheat.c +++ b/src/m_cheat.c @@ -978,7 +978,7 @@ static mobjflag2_t op_oldflags2 = 0; static UINT32 op_oldeflags = 0; static fixed_t op_oldmomx = 0, op_oldmomy = 0, op_oldmomz = 0, op_oldheight = 0; static statenum_t op_oldstate = 0; -static UINT8 op_oldcolor = 0; +static UINT16 op_oldcolor = 0; // // Static calculation / common output help @@ -1032,8 +1032,8 @@ static boolean OP_HeightOkay(player_t *player, UINT8 ceiling) if (ceiling) { // Truncate position to match where mapthing would be when spawned - // (this applies to every further P_GetZAt call as well) - fixed_t cheight = sec->c_slope ? P_GetZAt(sec->c_slope, player->mo->x & 0xFFFF0000, player->mo->y & 0xFFFF0000) : sec->ceilingheight; + // (this applies to every further P_GetSlopeZAt call as well) + fixed_t cheight = P_GetSectorCeilingZAt(sec, player->mo->x & 0xFFFF0000, player->mo->y & 0xFFFF0000); if (((cheight - player->mo->z - player->mo->height)>>FRACBITS) >= (1 << (16-ZSHIFT))) { @@ -1044,7 +1044,7 @@ static boolean OP_HeightOkay(player_t *player, UINT8 ceiling) } else { - fixed_t fheight = sec->f_slope ? P_GetZAt(sec->f_slope, player->mo->x & 0xFFFF0000, player->mo->y & 0xFFFF0000) : sec->floorheight; + fixed_t fheight = P_GetSectorFloorZAt(sec, player->mo->x & 0xFFFF0000, player->mo->y & 0xFFFF0000); if (((player->mo->z - fheight)>>FRACBITS) >= (1 << (16-ZSHIFT))) { CONS_Printf(M_GetText("Sorry, you're too %s to place this object (max: %d %s).\n"), M_GetText("high"), @@ -1091,12 +1091,12 @@ static mapthing_t *OP_CreateNewMapThing(player_t *player, UINT16 type, boolean c mt->y = (INT16)(player->mo->y>>FRACBITS); if (ceiling) { - fixed_t cheight = sec->c_slope ? P_GetZAt(sec->c_slope, mt->x << FRACBITS, mt->y << FRACBITS) : sec->ceilingheight; + fixed_t cheight = P_GetSectorCeilingZAt(sec, mt->x << FRACBITS, mt->y << FRACBITS); mt->z = (UINT16)((cheight - player->mo->z - player->mo->height)>>FRACBITS); } else { - fixed_t fheight = sec->f_slope ? P_GetZAt(sec->f_slope, mt->x << FRACBITS, mt->y << FRACBITS) : sec->floorheight; + fixed_t fheight = P_GetSectorFloorZAt(sec, mt->x << FRACBITS, mt->y << FRACBITS); mt->z = (UINT16)((player->mo->z - fheight)>>FRACBITS); } mt->angle = (INT16)(FixedInt(AngleFixed(player->mo->angle))); @@ -1342,12 +1342,12 @@ void OP_ObjectplaceMovement(player_t *player) if (!!(mobjinfo[op_currentthing].flags & MF_SPAWNCEILING) ^ !!(cv_opflags.value & MTF_OBJECTFLIP)) { - fixed_t cheight = sec->c_slope ? P_GetZAt(sec->c_slope, player->mo->x & 0xFFFF0000, player->mo->y & 0xFFFF0000) : sec->ceilingheight; + fixed_t cheight = P_GetSectorCeilingZAt(sec, player->mo->x & 0xFFFF0000, player->mo->y & 0xFFFF0000); op_displayflags = (UINT16)((cheight - player->mo->z - mobjinfo[op_currentthing].height)>>FRACBITS); } else { - fixed_t fheight = sec->f_slope ? P_GetZAt(sec->f_slope, player->mo->x & 0xFFFF0000, player->mo->y & 0xFFFF0000) : sec->floorheight; + fixed_t fheight = P_GetSectorFloorZAt(sec, player->mo->x & 0xFFFF0000, player->mo->y & 0xFFFF0000); op_displayflags = (UINT16)((player->mo->z - fheight)>>FRACBITS); } op_displayflags <<= ZSHIFT; diff --git a/src/m_cond.c b/src/m_cond.c index 0abc7adf8..36fcd7cf2 100644 --- a/src/m_cond.c +++ b/src/m_cond.c @@ -523,9 +523,9 @@ emblem_t *M_GetLevelEmblems(INT32 mapnum) 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 em->color; } @@ -549,9 +549,9 @@ const char *M_GetEmblemPatch(emblem_t *em, boolean big) 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 em->color; } diff --git a/src/m_cond.h b/src/m_cond.h index d7b9704dd..9bb162ff3 100644 --- a/src/m_cond.h +++ b/src/m_cond.h @@ -90,7 +90,7 @@ typedef struct INT16 tag; ///< Tag of emblem mapthing INT16 level; ///< Level on which this emblem can be found. 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) char hint[110]; ///< Hint for emblem hints menu UINT8 collected; ///< Do you have this emblem? @@ -102,7 +102,7 @@ typedef struct UINT8 conditionset; ///< Condition set that awards this emblem. UINT8 showconditionset; ///< Condition set that shows this emblem. 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? } extraemblem_t; @@ -172,9 +172,9 @@ INT32 M_CountEmblems(void); // Emblem shit 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); -skincolors_t M_GetExtraEmblemColor(extraemblem_t *em); +skincolornum_t M_GetExtraEmblemColor(extraemblem_t *em); const char *M_GetExtraEmblemPatch(extraemblem_t *em, boolean big); // If you're looking to compare stats for unlocks or what not, use these diff --git a/src/m_menu.c b/src/m_menu.c index 1069f0f30..f9061b251 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -882,7 +882,8 @@ static menuitem_t SP_NightsAttackLevelSelectMenu[] = static menuitem_t SP_NightsAttackMenu[] = { {IT_STRING|IT_KEYHANDLER, NULL, "Level Select...", &M_HandleTimeAttackLevelSelect, 52}, - {IT_STRING|IT_CVAR, NULL, "Show Records For", &cv_dummymares, 62}, + {IT_STRING|IT_CVAR, NULL, "Character", &cv_chooseskin, 62}, + {IT_STRING|IT_CVAR, NULL, "Show Records For", &cv_dummymares, 72}, {IT_DISABLED, NULL, "Guest Option...", &SP_NightsGuestReplayDef, 100}, {IT_DISABLED, NULL, "Replay...", &SP_NightsReplayDef, 110}, @@ -893,6 +894,7 @@ static menuitem_t SP_NightsAttackMenu[] = enum { nalevel, + nachar, narecords, naguest, @@ -1583,7 +1585,7 @@ static menuitem_t OP_ServerOptionsMenu[] = {IT_HEADER, NULL, "General", NULL, 0}, #ifndef NONET {IT_STRING | IT_CVAR | IT_CV_STRING, - NULL, "Server name", &cv_servername, 7}, + NULL, "Server name", &cv_servername, 7}, {IT_STRING | IT_CVAR, NULL, "Max Players", &cv_maxplayers, 21}, {IT_STRING | IT_CVAR, NULL, "Allow Add-on Downloading", &cv_downloading, 26}, {IT_STRING | IT_CVAR, NULL, "Allow players to join", &cv_allownewplayer, 31}, @@ -1628,8 +1630,9 @@ static menuitem_t OP_ServerOptionsMenu[] = #ifndef NONET {IT_HEADER, NULL, "Advanced", NULL, 225}, - {IT_STRING | IT_CVAR | IT_CV_STRING, NULL, "Master server", &cv_masterserver, 231}, - {IT_STRING | IT_CVAR, NULL, "Attempts to resynchronise", &cv_resynchattempts, 245}, + {IT_STRING | IT_CVAR | IT_CV_STRING, NULL, "Master server", &cv_masterserver, 231}, + {IT_STRING | IT_CVAR, NULL, "Join delay", &cv_joindelay, 246}, + {IT_STRING | IT_CVAR, NULL, "Attempts to resynchronise", &cv_resynchattempts, 251}, #endif }; @@ -1701,7 +1704,7 @@ static INT32 highlightflags, recommendedflags, warningflags; // Sky Room menu_t SR_PandoraDef = { - MN_SR_MAIN + (MN_SR_PANDORA << 6), + MTREE2(MN_SR_MAIN, MN_SR_PANDORA), "M_PANDRA", sizeof (SR_PandorasBox)/sizeof (menuitem_t), &SPauseDef, @@ -1715,12 +1718,12 @@ menu_t SR_PandoraDef = menu_t SR_MainDef = DEFAULTMENUSTYLE(MN_SR_MAIN, "M_SECRET", SR_MainMenu, &MainDef, 60, 40); menu_t SR_LevelSelectDef = MAPPLATTERMENUSTYLE( - MN_SR_MAIN + (MN_SR_LEVELSELECT << 6), + MTREE2(MN_SR_MAIN, MN_SR_LEVELSELECT), NULL, SR_LevelSelectMenu); menu_t SR_UnlockChecklistDef = { - MN_SR_MAIN + (MN_SR_UNLOCKCHECKLIST << 6), + MTREE2(MN_SR_MAIN, MN_SR_UNLOCKCHECKLIST), "M_SECRET", 1, &SR_MainDef, @@ -1733,7 +1736,7 @@ menu_t SR_UnlockChecklistDef = menu_t SR_SoundTestDef = { - MN_SR_MAIN + (MN_SR_SOUNDTEST << 6), + MTREE2(MN_SR_MAIN, MN_SR_SOUNDTEST), NULL, sizeof (SR_SoundTestMenu)/sizeof (menuitem_t), &SR_MainDef, @@ -1746,7 +1749,7 @@ menu_t SR_SoundTestDef = menu_t SR_EmblemHintDef = { - MN_SR_MAIN + (MN_SR_EMBLEMHINT << 6), + MTREE2(MN_SR_MAIN, MN_SR_EMBLEMHINT), NULL, sizeof (SR_EmblemHintMenu)/sizeof (menuitem_t), &SPauseDef, @@ -1773,7 +1776,7 @@ menu_t SP_MainDef = //CENTERMENUSTYLE(NULL, SP_MainMenu, &MainDef, 72); menu_t SP_LoadDef = { - MN_SP_MAIN + (MN_SP_LOAD << 6), + MTREE2(MN_SP_MAIN, MN_SP_LOAD), "M_PICKG", 1, &SP_MainDef, @@ -1785,12 +1788,12 @@ menu_t SP_LoadDef = }; menu_t SP_LevelSelectDef = MAPPLATTERMENUSTYLE( - MN_SP_MAIN + (MN_SP_LOAD << 6) + (MN_SP_PLAYER << 12) + (MN_SP_LEVELSELECT << 18), + MTREE4(MN_SP_MAIN, MN_SP_LOAD, MN_SP_PLAYER, MN_SP_LEVELSELECT), NULL, SP_LevelSelectMenu); menu_t SP_LevelStatsDef = { - MN_SP_MAIN + (MN_SP_LEVELSTATS << 6), + MTREE2(MN_SP_MAIN, MN_SP_LEVELSTATS), "M_STATS", 1, &SP_MainDef, @@ -1802,12 +1805,12 @@ menu_t SP_LevelStatsDef = }; menu_t SP_TimeAttackLevelSelectDef = MAPPLATTERMENUSTYLE( - MN_SP_MAIN + (MN_SP_TIMEATTACK << 6) + (MN_SP_TIMEATTACK_LEVELSELECT << 12), + MTREE3(MN_SP_MAIN, MN_SP_TIMEATTACK, MN_SP_TIMEATTACK_LEVELSELECT), "M_ATTACK", SP_TimeAttackLevelSelectMenu); static menu_t SP_TimeAttackDef = { - MN_SP_MAIN + (MN_SP_TIMEATTACK << 6), + MTREE2(MN_SP_MAIN, MN_SP_TIMEATTACK), "M_ATTACK", sizeof (SP_TimeAttackMenu)/sizeof (menuitem_t), &MainDef, // Doesn't matter. @@ -1819,7 +1822,7 @@ static menu_t SP_TimeAttackDef = }; static menu_t SP_ReplayDef = { - MN_SP_MAIN + (MN_SP_TIMEATTACK << 6) + (MN_SP_REPLAY << 12), + MTREE3(MN_SP_MAIN, MN_SP_TIMEATTACK, MN_SP_REPLAY), "M_ATTACK", sizeof(SP_ReplayMenu)/sizeof(menuitem_t), &SP_TimeAttackDef, @@ -1831,7 +1834,7 @@ static menu_t SP_ReplayDef = }; static menu_t SP_GuestReplayDef = { - MN_SP_MAIN + (MN_SP_TIMEATTACK << 6) + (MN_SP_GUESTREPLAY << 12), + MTREE3(MN_SP_MAIN, MN_SP_TIMEATTACK, MN_SP_GUESTREPLAY), "M_ATTACK", sizeof(SP_GuestReplayMenu)/sizeof(menuitem_t), &SP_TimeAttackDef, @@ -1843,7 +1846,7 @@ static menu_t SP_GuestReplayDef = }; static menu_t SP_GhostDef = { - MN_SP_MAIN + (MN_SP_TIMEATTACK << 6) + (MN_SP_GHOST << 12), + MTREE3(MN_SP_MAIN, MN_SP_TIMEATTACK, MN_SP_GHOST), "M_ATTACK", sizeof(SP_GhostMenu)/sizeof(menuitem_t), &SP_TimeAttackDef, @@ -1855,12 +1858,12 @@ static menu_t SP_GhostDef = }; menu_t SP_NightsAttackLevelSelectDef = MAPPLATTERMENUSTYLE( - MN_SP_MAIN + (MN_SP_NIGHTSATTACK << 6) + (MN_SP_NIGHTS_LEVELSELECT << 12), + MTREE3(MN_SP_MAIN, MN_SP_NIGHTSATTACK, MN_SP_NIGHTS_LEVELSELECT), "M_NIGHTS", SP_NightsAttackLevelSelectMenu); static menu_t SP_NightsAttackDef = { - MN_SP_MAIN + (MN_SP_NIGHTSATTACK << 6), + MTREE2(MN_SP_MAIN, MN_SP_NIGHTSATTACK), "M_NIGHTS", sizeof (SP_NightsAttackMenu)/sizeof (menuitem_t), &MainDef, // Doesn't matter. @@ -1872,7 +1875,7 @@ static menu_t SP_NightsAttackDef = }; static menu_t SP_NightsReplayDef = { - MN_SP_MAIN + (MN_SP_NIGHTSATTACK << 6) + (MN_SP_NIGHTS_REPLAY << 12), + MTREE3(MN_SP_MAIN, MN_SP_NIGHTSATTACK, MN_SP_NIGHTS_REPLAY), "M_NIGHTS", sizeof(SP_NightsReplayMenu)/sizeof(menuitem_t), &SP_NightsAttackDef, @@ -1884,7 +1887,7 @@ static menu_t SP_NightsReplayDef = }; static menu_t SP_NightsGuestReplayDef = { - MN_SP_MAIN + (MN_SP_NIGHTSATTACK << 6) + (MN_SP_NIGHTS_GUESTREPLAY << 12), + MTREE3(MN_SP_MAIN, MN_SP_NIGHTSATTACK, MN_SP_NIGHTS_GUESTREPLAY), "M_NIGHTS", sizeof(SP_NightsGuestReplayMenu)/sizeof(menuitem_t), &SP_NightsAttackDef, @@ -1896,7 +1899,7 @@ static menu_t SP_NightsGuestReplayDef = }; static menu_t SP_NightsGhostDef = { - MN_SP_MAIN + (MN_SP_NIGHTSATTACK << 6) + (MN_SP_NIGHTS_GHOST << 12), + MTREE3(MN_SP_MAIN, MN_SP_NIGHTSATTACK, MN_SP_NIGHTS_GHOST), "M_NIGHTS", sizeof(SP_NightsGhostMenu)/sizeof(menuitem_t), &SP_NightsAttackDef, @@ -1910,7 +1913,7 @@ static menu_t SP_NightsGhostDef = menu_t SP_PlayerDef = { - MN_SP_MAIN + (MN_SP_LOAD << 6) + (MN_SP_PLAYER << 12), + MTREE3(MN_SP_MAIN, MN_SP_LOAD, MN_SP_PLAYER), "M_PICKP", sizeof (SP_PlayerMenu)/sizeof (menuitem_t), &SP_MainDef, @@ -1925,7 +1928,7 @@ menu_t SP_PlayerDef = menu_t MP_SplitServerDef = { - MN_MP_MAIN + (MN_MP_SPLITSCREEN << 6), + MTREE2(MN_MP_MAIN, MN_MP_SPLITSCREEN), "M_MULTI", sizeof (MP_SplitServerMenu)/sizeof (menuitem_t), #ifndef NONET @@ -1957,7 +1960,7 @@ menu_t MP_MainDef = menu_t MP_ServerDef = { - MN_MP_MAIN + (MN_MP_SERVER << 6), + MTREE2(MN_MP_MAIN, MN_MP_SERVER), "M_MULTI", sizeof (MP_ServerMenu)/sizeof (menuitem_t), &MP_MainDef, @@ -1970,7 +1973,7 @@ menu_t MP_ServerDef = menu_t MP_ConnectDef = { - MN_MP_MAIN + (MN_MP_CONNECT << 6), + MTREE2(MN_MP_MAIN, MN_MP_CONNECT), "M_MULTI", sizeof (MP_ConnectMenu)/sizeof (menuitem_t), &MP_MainDef, @@ -1983,7 +1986,7 @@ menu_t MP_ConnectDef = menu_t MP_RoomDef = { - MN_MP_MAIN + (MN_MP_ROOM << 6), + MTREE2(MN_MP_MAIN, MN_MP_ROOM), "M_MULTI", sizeof (MP_RoomMenu)/sizeof (menuitem_t), &MP_ConnectDef, @@ -1998,9 +2001,9 @@ menu_t MP_RoomDef = menu_t MP_PlayerSetupDef = { #ifdef NONET - MN_MP_MAIN + (MN_MP_PLAYERSETUP << 6), + MTREE2(MN_MP_MAIN, MN_MP_PLAYERSETUP), #else - MN_MP_MAIN + (MN_MP_SPLITSCREEN << 6) + (MN_MP_PLAYERSETUP << 12), + MTREE3(MN_MP_MAIN, MN_MP_SPLITSCREEN, MN_MP_PLAYERSETUP), #endif "M_SPLAYR", sizeof (MP_PlayerSetupMenu)/sizeof (menuitem_t), @@ -2016,12 +2019,13 @@ menu_t MP_PlayerSetupDef = menu_t OP_MainDef = DEFAULTMENUSTYLE( MN_OP_MAIN, "M_OPTTTL", OP_MainMenu, &MainDef, 50, 30); + menu_t OP_ChangeControlsDef = CONTROLMENUSTYLE( - MN_OP_MAIN + (MN_OP_CHANGECONTROLS << 12), // second level (<<6) set on runtime + MTREE3(MN_OP_MAIN, 0, MN_OP_CHANGECONTROLS), // second level set on runtime OP_ChangeControlsMenu, &OP_MainDef); menu_t OP_P1ControlsDef = { - MN_OP_MAIN + (MN_OP_P1CONTROLS << 6), + MTREE2(MN_OP_MAIN, MN_OP_P1CONTROLS), "M_CONTRO", sizeof(OP_P1ControlsMenu)/sizeof(menuitem_t), &OP_MainDef, @@ -2029,7 +2033,7 @@ menu_t OP_P1ControlsDef = { M_DrawControlsDefMenu, 50, 30, 0, NULL}; menu_t OP_P2ControlsDef = { - MN_OP_MAIN + (MN_OP_P2CONTROLS << 6), + MTREE2(MN_OP_MAIN, MN_OP_P2CONTROLS), "M_CONTRO", sizeof(OP_P2ControlsMenu)/sizeof(menuitem_t), &OP_MainDef, @@ -2038,20 +2042,22 @@ menu_t OP_P2ControlsDef = { 50, 30, 0, NULL}; menu_t OP_MouseOptionsDef = DEFAULTMENUSTYLE( - MN_OP_MAIN + (MN_OP_P1CONTROLS << 6) + (MN_OP_P1MOUSE << 12), + MTREE3(MN_OP_MAIN, MN_OP_P1CONTROLS, MN_OP_P1MOUSE), "M_CONTRO", OP_MouseOptionsMenu, &OP_P1ControlsDef, 35, 30); menu_t OP_Mouse2OptionsDef = DEFAULTMENUSTYLE( - MN_OP_MAIN + (MN_OP_P2CONTROLS << 6) + (MN_OP_P2MOUSE << 12), + MTREE3(MN_OP_MAIN, MN_OP_P2CONTROLS, MN_OP_P2MOUSE), "M_CONTRO", OP_Mouse2OptionsMenu, &OP_P2ControlsDef, 35, 30); + menu_t OP_Joystick1Def = DEFAULTMENUSTYLE( - MN_OP_MAIN + (MN_OP_P1CONTROLS << 6) + (MN_OP_P1JOYSTICK << 12), + MTREE3(MN_OP_MAIN, MN_OP_P1CONTROLS, MN_OP_P1JOYSTICK), "M_CONTRO", OP_Joystick1Menu, &OP_P1ControlsDef, 50, 30); menu_t OP_Joystick2Def = DEFAULTMENUSTYLE( - MN_OP_MAIN + (MN_OP_P2CONTROLS << 6) + (MN_OP_P2JOYSTICK << 12), + MTREE3(MN_OP_MAIN, MN_OP_P2CONTROLS, MN_OP_P2JOYSTICK), "M_CONTRO", OP_Joystick2Menu, &OP_P2ControlsDef, 50, 30); + menu_t OP_JoystickSetDef = { - MN_OP_MAIN + (MN_OP_JOYSTICKSET << MENUBITS*3), // second (<<6) and third level (<<12) set on runtime + MTREE4(MN_OP_MAIN, 0, 0, MN_OP_JOYSTICKSET), // second and third level set on runtime "M_CONTRO", sizeof (OP_JoystickSetMenu)/sizeof (menuitem_t), &OP_Joystick1Def, @@ -2063,7 +2069,7 @@ menu_t OP_JoystickSetDef = }; menu_t OP_CameraOptionsDef = { - MN_OP_MAIN + (MN_OP_P1CONTROLS << 6) + (MN_OP_P1CAMERA << 12), + MTREE3(MN_OP_MAIN, MN_OP_P1CONTROLS, MN_OP_P1CAMERA), "M_CONTRO", sizeof (OP_CameraOptionsMenu)/sizeof (menuitem_t), &OP_P1ControlsDef, @@ -2074,7 +2080,7 @@ menu_t OP_CameraOptionsDef = { NULL }; menu_t OP_Camera2OptionsDef = { - MN_OP_MAIN + (MN_OP_P2CONTROLS << 6) + (MN_OP_P2CAMERA << 12), + MTREE3(MN_OP_MAIN, MN_OP_P2CONTROLS, MN_OP_P2CAMERA), "M_CONTRO", sizeof (OP_Camera2OptionsMenu)/sizeof (menuitem_t), &OP_P2ControlsDef, @@ -2088,7 +2094,7 @@ menu_t OP_Camera2OptionsDef = { static menuitem_t OP_PlaystyleMenu[] = {{IT_KEYHANDLER | IT_NOTHING, NULL, "", M_HandlePlaystyleMenu, 0}}; menu_t OP_PlaystyleDef = { - MN_OP_MAIN + (MN_OP_P1CONTROLS << 6) + (MN_OP_PLAYSTYLE << 12), + MTREE3(MN_OP_MAIN, MN_OP_P1CONTROLS, MN_OP_PLAYSTYLE), ///@TODO the second level should be set in runtime NULL, 1, &OP_P1ControlsDef, @@ -2114,7 +2120,7 @@ static void M_VideoOptions(INT32 choice) menu_t OP_VideoOptionsDef = { - MN_OP_MAIN + (MN_OP_VIDEO << 6), + MTREE2(MN_OP_MAIN, MN_OP_VIDEO), "M_VIDEO", sizeof (OP_VideoOptionsMenu)/sizeof (menuitem_t), &OP_MainDef, @@ -2126,7 +2132,7 @@ menu_t OP_VideoOptionsDef = }; menu_t OP_VideoModeDef = { - MN_OP_MAIN + (MN_OP_VIDEO << 6) + (MN_OP_VIDEOMODE << 12), + MTREE3(MN_OP_MAIN, MN_OP_VIDEO, MN_OP_VIDEOMODE), "M_VIDEO", 1, &OP_VideoOptionsDef, @@ -2138,7 +2144,7 @@ menu_t OP_VideoModeDef = }; menu_t OP_ColorOptionsDef = { - MN_OP_MAIN + (MN_OP_VIDEO << 6) + (MN_OP_COLOR << 12), + MTREE3(MN_OP_MAIN, MN_OP_VIDEO, MN_OP_COLOR), "M_VIDEO", sizeof (OP_ColorOptionsMenu)/sizeof (menuitem_t), &OP_VideoOptionsDef, @@ -2149,17 +2155,19 @@ menu_t OP_ColorOptionsDef = NULL }; menu_t OP_SoundOptionsDef = DEFAULTMENUSTYLE( - MN_OP_MAIN + (MN_OP_SOUND << 6), + MTREE2(MN_OP_MAIN, MN_OP_SOUND), "M_SOUND", OP_SoundOptionsMenu, &OP_MainDef, 30, 30); -menu_t OP_SoundAdvancedDef = DEFAULTMENUSTYLE(MN_OP_MAIN + (MN_OP_SOUND << 6), "M_SOUND", OP_SoundAdvancedMenu, &OP_SoundOptionsDef, 30, 30); +menu_t OP_SoundAdvancedDef = DEFAULTMENUSTYLE( + MTREE2(MN_OP_MAIN, MN_OP_SOUND), + "M_SOUND", OP_SoundAdvancedMenu, &OP_SoundOptionsDef, 30, 30); menu_t OP_ServerOptionsDef = DEFAULTSCROLLMENUSTYLE( - MN_OP_MAIN + (MN_OP_SERVER << 6), + MTREE2(MN_OP_MAIN, MN_OP_SERVER), "M_SERVER", OP_ServerOptionsMenu, &OP_MainDef, 30, 30); menu_t OP_MonitorToggleDef = { - MN_OP_MAIN + (MN_OP_SERVER << 6) + (MN_OP_MONITORTOGGLE << 12), + MTREE3(MN_OP_MAIN, MN_OP_SOUND, MN_OP_MONITORTOGGLE), "M_SERVER", sizeof (OP_MonitorToggleMenu)/sizeof (menuitem_t), &OP_ServerOptionsDef, @@ -2180,16 +2188,16 @@ static void M_OpenGLOptionsMenu(void) } menu_t OP_OpenGLOptionsDef = DEFAULTMENUSTYLE( - MN_OP_MAIN + (MN_OP_VIDEO << 6) + (MN_OP_OPENGL << 12), + MTREE3(MN_OP_MAIN, MN_OP_VIDEO, MN_OP_OPENGL), "M_VIDEO", OP_OpenGLOptionsMenu, &OP_VideoOptionsDef, 30, 30); #ifdef ALAM_LIGHTING menu_t OP_OpenGLLightingDef = DEFAULTMENUSTYLE( - MN_OP_MAIN + (MN_OP_VIDEO << 6) + (MN_OP_OPENGL << 12) + (MN_OP_OPENGL_LIGHTING << 18), + MTREE4(MN_OP_MAIN, MN_OP_VIDEO, MN_OP_OPENGL, MN_OP_OPENGL_LIGHTING), "M_VIDEO", OP_OpenGLLightingMenu, &OP_OpenGLOptionsDef, 60, 40); #endif menu_t OP_OpenGLFogDef = { - MN_OP_MAIN + (MN_OP_VIDEO << 6) + (MN_OP_OPENGL << 12) + (MN_OP_OPENGL_FOG << 18), + MTREE4(MN_OP_MAIN, MN_OP_VIDEO, MN_OP_OPENGL, MN_OP_OPENGL_FOG), "M_VIDEO", sizeof (OP_OpenGLFogMenu)/sizeof (menuitem_t), &OP_OpenGLOptionsDef, @@ -2201,12 +2209,12 @@ menu_t OP_OpenGLFogDef = }; #endif menu_t OP_DataOptionsDef = DEFAULTMENUSTYLE( - MN_OP_MAIN + (MN_OP_DATA << 6), + MTREE2(MN_OP_MAIN, MN_OP_DATA), "M_DATA", OP_DataOptionsMenu, &OP_MainDef, 60, 30); menu_t OP_ScreenshotOptionsDef = { - MN_OP_MAIN + (MN_OP_DATA << 6) + (MN_OP_SCREENSHOTS << 12), + MTREE3(MN_OP_MAIN, MN_OP_DATA, MN_OP_SCREENSHOTS), "M_SCREEN", sizeof (OP_ScreenshotOptionsMenu)/sizeof (menuitem_t), &OP_DataOptionsDef, @@ -2218,11 +2226,11 @@ menu_t OP_ScreenshotOptionsDef = }; menu_t OP_AddonsOptionsDef = DEFAULTMENUSTYLE( - MN_OP_MAIN + (MN_OP_DATA << 6) + (MN_OP_ADDONS << 12), + MTREE3(MN_OP_MAIN, MN_OP_DATA, MN_OP_ADDONS), "M_ADDONS", OP_AddonsOptionsMenu, &OP_DataOptionsDef, 30, 30); menu_t OP_EraseDataDef = DEFAULTMENUSTYLE( - MN_OP_MAIN + (MN_OP_DATA << 6) + (MN_OP_ERASEDATA << 12), + MTREE3(MN_OP_MAIN, MN_OP_DATA, MN_OP_ERASEDATA), "M_DATA", OP_EraseDataMenu, &OP_DataOptionsDef, 60, 30); // ========================================================================== @@ -5180,7 +5188,7 @@ static boolean M_PrepareLevelPlatter(INT32 gt, boolean nextmappick) { if (M_CanShowLevelOnPlatter(mapnum, gt)) { - const INT32 actnum = mapheaderinfo[mapnum]->actnum; + const UINT8 actnum = mapheaderinfo[mapnum]->actnum; const boolean headingisname = (fastcmp(mapheaderinfo[mapnum]->selectheading, mapheaderinfo[mapnum]->lvlttl)); const boolean wide = (mapheaderinfo[mapnum]->menuflags & LF2_WIDEICON); @@ -7537,7 +7545,7 @@ static void M_DrawSoundTest(void) { frame[1] = (2-st_time); 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) st_time++; } @@ -8205,13 +8213,13 @@ static void M_DrawLoadGameData(void) { if (charskin->prefoppositecolor) { - col = charskin->prefoppositecolor - 1; - col = Color_Index[col][Color_Opposite[Color_Opposite[col][0] - 1][1]]; + col = charskin->prefoppositecolor; + col = skincolors[col].ramp[skincolors[skincolors[col].invcolor].invshade]; } else { - col = charskin->prefcolor - 1; - col = Color_Index[Color_Opposite[col][0]-1][Color_Opposite[col][1]]; + col = charskin->prefcolor; + col = skincolors[skincolors[col].invcolor].ramp[skincolors[col].invshade]; } } @@ -8939,16 +8947,11 @@ static void M_SetupChoosePlayer(INT32 choice) /* the menus suck -James */ if (currentMenu == &SP_LoadDef)/* from save states */ { - SP_PlayerDef.menuid = - MN_SP_MAIN + - ( MN_SP_LOAD << 6 ) + - ( MN_SP_PLAYER << 12 ); + SP_PlayerDef.menuid = MTREE3(MN_SP_MAIN, MN_SP_LOAD, MN_SP_PLAYER); } else/* from Secret level select */ { - SP_PlayerDef.menuid = - MN_SR_MAIN + - ( MN_SR_PLAYER << 6 ); + SP_PlayerDef.menuid = MTREE2(MN_SR_MAIN, MN_SR_PLAYER); } SP_PlayerDef.prevMenu = currentMenu; @@ -9052,7 +9055,7 @@ static void M_DrawSetupChoosePlayerMenu(void) skin_t *charskin = &skins[0]; INT32 skinnum = 0; - UINT8 col; + UINT16 col; UINT8 *colormap = NULL; INT32 prev = -1, next = -1; @@ -9091,10 +9094,10 @@ static void M_DrawSetupChoosePlayerMenu(void) // Use the opposite of the character's skincolor col = description[char_on].oppositecolor; if (!col) - col = Color_Opposite[charskin->prefcolor - 1][0]; + col = skincolors[charskin->prefcolor].invcolor; // Make the translation colormap - colormap = R_GetTranslationColormap(TC_DEFAULT, col, 0); + colormap = R_GetTranslationColormap(TC_DEFAULT, col, GTC_CACHE); // Don't render the title map hidetitlemap = true; @@ -9142,8 +9145,8 @@ static void M_DrawSetupChoosePlayerMenu(void) INT32 ox, oxsh = FixedInt(FixedMul(BASEVIDWIDTH*FRACUNIT, FixedDiv(char_scroll, 128*FRACUNIT))), txsh; patch_t *curpatch = NULL, *prevpatch = NULL, *nextpatch = NULL; const char *curtext = NULL, *prevtext = NULL, *nexttext = NULL; - UINT8 curtextcolor = 0, prevtextcolor = 0, nexttextcolor = 0; - UINT8 curoutlinecolor = 0, prevoutlinecolor = 0, nextoutlinecolor = 0; + UINT16 curtextcolor = 0, prevtextcolor = 0, nexttextcolor = 0; + UINT16 curoutlinecolor = 0, prevoutlinecolor = 0, nextoutlinecolor = 0; // Name tag curtext = description[char_on].displayname; @@ -9154,7 +9157,7 @@ static void M_DrawSetupChoosePlayerMenu(void) if (!curtextcolor) curtextcolor = charskin->prefcolor; if (!curoutlinecolor) - curoutlinecolor = Color_Opposite[charskin->prefcolor - 1][0]; + curoutlinecolor = col = skincolors[charskin->prefcolor].invcolor; txsh = oxsh; ox = 8 + SHORT((description[char_on].charpic)->width)/2; @@ -9170,8 +9173,8 @@ static void M_DrawSetupChoosePlayerMenu(void) { V_DrawNameTag( x, y, V_CENTERNAMETAG, FRACUNIT, - R_GetTranslationColormap(TC_DEFAULT, curtextcolor, 0), - R_GetTranslationColormap(TC_DEFAULT, curoutlinecolor, 0), + R_GetTranslationColormap(TC_DEFAULT, curtextcolor, GTC_CACHE), + R_GetTranslationColormap(TC_DEFAULT, curoutlinecolor, GTC_CACHE), curtext ); } @@ -9193,7 +9196,7 @@ static void M_DrawSetupChoosePlayerMenu(void) if (!prevtextcolor) prevtextcolor = charskin->prefcolor; if (!prevoutlinecolor) - prevoutlinecolor = Color_Opposite[charskin->prefcolor - 1][0]; + prevoutlinecolor = col = skincolors[charskin->prefcolor].invcolor; x = (ox - txsh) - w; if (prevpatch) @@ -9203,8 +9206,8 @@ static void M_DrawSetupChoosePlayerMenu(void) { V_DrawNameTag( x, y, V_CENTERNAMETAG, FRACUNIT, - R_GetTranslationColormap(TC_DEFAULT, prevtextcolor, 0), - R_GetTranslationColormap(TC_DEFAULT, prevoutlinecolor, 0), + R_GetTranslationColormap(TC_DEFAULT, prevtextcolor, GTC_CACHE), + R_GetTranslationColormap(TC_DEFAULT, prevoutlinecolor, GTC_CACHE), prevtext ); } @@ -9223,7 +9226,7 @@ static void M_DrawSetupChoosePlayerMenu(void) if (!nexttextcolor) nexttextcolor = charskin->prefcolor; if (!nextoutlinecolor) - nextoutlinecolor = Color_Opposite[charskin->prefcolor - 1][0]; + nextoutlinecolor = col = skincolors[charskin->prefcolor].invcolor; x = (ox - txsh) + w; if (nextpatch) @@ -9233,8 +9236,8 @@ static void M_DrawSetupChoosePlayerMenu(void) { V_DrawNameTag( x, y, V_CENTERNAMETAG, FRACUNIT, - R_GetTranslationColormap(TC_DEFAULT, nexttextcolor, 0), - R_GetTranslationColormap(TC_DEFAULT, nextoutlinecolor, 0), + R_GetTranslationColormap(TC_DEFAULT, nexttextcolor, GTC_CACHE), + R_GetTranslationColormap(TC_DEFAULT, nextoutlinecolor, GTC_CACHE), nexttext ); } @@ -10822,7 +10825,8 @@ static void M_ServerOptions(INT32 choice) OP_ServerOptionsMenu[ 3].status = IT_GRAYEDOUT; // Allow add-on downloading OP_ServerOptionsMenu[ 4].status = IT_GRAYEDOUT; // Allow players to join OP_ServerOptionsMenu[35].status = IT_GRAYEDOUT; // Master server - OP_ServerOptionsMenu[36].status = IT_GRAYEDOUT; // Attempts to resynchronise + OP_ServerOptionsMenu[36].status = IT_GRAYEDOUT; // Minimum delay between joins + OP_ServerOptionsMenu[37].status = IT_GRAYEDOUT; // Attempts to resynchronise } else { @@ -10834,14 +10838,15 @@ static void M_ServerOptions(INT32 choice) ? IT_GRAYEDOUT : (IT_STRING | IT_CVAR | IT_CV_STRING)); OP_ServerOptionsMenu[36].status = IT_STRING | IT_CVAR; + OP_ServerOptionsMenu[37].status = IT_STRING | IT_CVAR; } #endif /* Disable fading because of different menu head. */ if (currentMenu == &OP_MainDef)/* from Options menu */ - OP_ServerOptionsDef.menuid = MN_OP_MAIN + ( MN_OP_SERVER << 6 ); + OP_ServerOptionsDef.menuid = MTREE2(MN_OP_MAIN, MN_OP_SERVER); else/* from Multiplayer menu */ - OP_ServerOptionsDef.menuid = MN_MP_MAIN + ( MN_MP_SERVER_OPTIONS << 6 ); + OP_ServerOptionsDef.menuid = MTREE2(MN_MP_MAIN, MN_MP_SERVER_OPTIONS); OP_ServerOptionsDef.prevMenu = currentMenu; M_SetupNextMenu(&OP_ServerOptionsDef); @@ -11071,15 +11076,15 @@ static UINT8 multi_spr2; // this is set before entering the MultiPlayer setup menu, // for either player 1 or 2 -static char setupm_name[MAXPLAYERNAME+1]; -static player_t *setupm_player; -static consvar_t *setupm_cvskin; -static consvar_t *setupm_cvcolor; -static consvar_t *setupm_cvname; -static consvar_t *setupm_cvdefaultskin; -static consvar_t *setupm_cvdefaultcolor; -static INT32 setupm_fakeskin; -static INT32 setupm_fakecolor; +static char setupm_name[MAXPLAYERNAME+1]; +static player_t *setupm_player; +static consvar_t *setupm_cvskin; +static consvar_t *setupm_cvcolor; +static consvar_t *setupm_cvname; +static consvar_t *setupm_cvdefaultskin; +static consvar_t *setupm_cvdefaultcolor; +static INT32 setupm_fakeskin; +static menucolor_t *setupm_fakecolor; static void M_DrawSetupMultiPlayerMenu(void) { @@ -11146,11 +11151,11 @@ static void M_DrawSetupMultiPlayerMenu(void) 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; // 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) multi_frame = 0; @@ -11196,11 +11201,11 @@ colordraw: // draw color string V_DrawRightAlignedString(BASEVIDWIDTH - x, y, ((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) { - 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); V_DrawCharacter(BASEVIDWIDTH - x + 2 + (skullAnimCounter/5), y, '\x1D' | V_YELLOWMAP, false); @@ -11210,25 +11215,39 @@ colordraw: #define indexwidth 8 { - const INT32 colwidth = (282-charw)/(2*indexwidth); - INT32 i = -colwidth; - INT16 col = setupm_fakecolor - colwidth; - INT32 w = indexwidth; + const INT32 numcolors = (282-charw)/(2*indexwidth); // Number of colors per side + INT32 w = indexwidth; // Width of a singular color block + menucolor_t *mc = setupm_fakecolor->prev; // Last accessed color UINT8 h; + INT16 i; - while (col < 1) - col += MAXSKINCOLORS-1; - while (i <= colwidth) - { - if (!(i++)) - w = charw; - else - w = indexwidth; + // Draw color in the middle + x += numcolors*w; + for (h = 0; h < 16; h++) + V_DrawFill(x, y+h, charw, 1, skincolors[setupm_fakecolor->color].ramp[h]); + + //Draw colors from middle to left + for (i=0; icolor].accessible) + mc = mc->prev; for (h = 0; h < 16; h++) - V_DrawFill(x, y+h, w, 1, Color_Index[col-1][h]); - if (++col >= MAXSKINCOLORS) - col -= MAXSKINCOLORS-1; + V_DrawFill(x, y+h, w, 1, skincolors[mc->color].ramp[h]); + mc = mc->prev; + } + + // Draw colors from middle to right + mc = setupm_fakecolor->next; + x += numcolors*w + charw; + for (i=0; icolor].accessible) + mc = mc->next; + for (h = 0; h < 16; h++) + V_DrawFill(x, y+h, w, 1, skincolors[mc->color].ramp[h]); x += w; + mc = mc->next; } } #undef charw @@ -11239,7 +11258,7 @@ colordraw: V_DrawString(x, y, ((R_SkinAvailable(setupm_cvdefaultskin->string) != setupm_fakeskin - || setupm_cvdefaultcolor->value != setupm_fakecolor) + || setupm_cvdefaultcolor->value != setupm_fakecolor->color) ? 0 : V_TRANSLUCENT) | ((itemOn == 3) ? V_YELLOWMAP : 0), @@ -11287,19 +11306,19 @@ static void M_HandleSetupMultiPlayer(INT32 choice) else if (itemOn == 2) // player color { S_StartSound(NULL,sfx_menu1); // Tails - setupm_fakecolor--; + setupm_fakecolor = setupm_fakecolor->prev; } break; case KEY_ENTER: if (itemOn == 3 && (R_SkinAvailable(setupm_cvdefaultskin->string) != setupm_fakeskin - || setupm_cvdefaultcolor->value != setupm_fakecolor)) + || setupm_cvdefaultcolor->value != setupm_fakecolor->color)) { S_StartSound(NULL,sfx_strpst); // you know what? always putting these in the buffer won't hurt anything. COM_BufAddText (va("%s \"%s\"\n",setupm_cvdefaultskin->name,skins[setupm_fakeskin].name)); - COM_BufAddText (va("%s %d\n",setupm_cvdefaultcolor->name,setupm_fakecolor)); + COM_BufAddText (va("%s %d\n",setupm_cvdefaultcolor->name,setupm_fakecolor->color)); break; } /* FALLTHRU */ @@ -11320,7 +11339,7 @@ static void M_HandleSetupMultiPlayer(INT32 choice) else if (itemOn == 2) // player color { S_StartSound(NULL,sfx_menu1); // Tails - setupm_fakecolor++; + setupm_fakecolor = setupm_fakecolor->next; } break; @@ -11336,11 +11355,13 @@ static void M_HandleSetupMultiPlayer(INT32 choice) } else if (itemOn == 2) { - UINT8 col = skins[setupm_fakeskin].prefcolor; - if (setupm_fakecolor != col) + UINT16 col = skins[setupm_fakeskin].prefcolor; + if ((setupm_fakecolor->color != col) && skincolors[col].accessible) { 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; @@ -11368,10 +11389,14 @@ static void M_HandleSetupMultiPlayer(INT32 choice) } // check color - if (setupm_fakecolor < 1) - setupm_fakecolor = MAXSKINCOLORS-1; - if (setupm_fakecolor > MAXSKINCOLORS-1) - setupm_fakecolor = 1; + if (itemOn == 2 && !skincolors[setupm_fakecolor->color].accessible) { + if (choice == KEY_LEFTARROW) + while (!skincolors[setupm_fakecolor->color].accessible) + 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) { @@ -11403,7 +11428,10 @@ static void M_SetupMultiPlayer(INT32 choice) setupm_fakeskin = R_SkinAvailable(setupm_cvskin->string); if (setupm_fakeskin == -1) 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 if (!CanChangeSkin(consoleplayer)) @@ -11444,7 +11472,10 @@ static void M_SetupMultiPlayer2(INT32 choice) setupm_fakeskin = R_SkinAvailable(setupm_cvskin->string); if (setupm_fakeskin == -1) 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 if (splitscreen && !CanChangeSkin(secondarydisplayplayer)) @@ -11476,12 +11507,181 @@ static boolean M_QuitMultiPlayerMenu(void) setupm_name[l] =0; 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 %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; } +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; inext; + free(tmp); + } else { + free(look); + return; + } + } + + menucolorhead = menucolortail = NULL; +} + // ================= // DATA OPTIONS MENU // ================= @@ -11758,8 +11958,8 @@ static void M_Setup1PControlsMenu(INT32 choice) OP_ChangeControlsMenu[27+3].status = IT_CALL|IT_STRING2; OP_ChangeControlsDef.prevMenu = &OP_P1ControlsDef; - OP_ChangeControlsDef.menuid &= ~(((1 << MENUBITS) - 1) << MENUBITS); // remove first level (<< 6) - OP_ChangeControlsDef.menuid |= MN_OP_P1CONTROLS << MENUBITS; // combine first level (<< 6) + OP_ChangeControlsDef.menuid &= ~(((1 << MENUBITS) - 1) << MENUBITS); // remove second level + OP_ChangeControlsDef.menuid |= MN_OP_P1CONTROLS << MENUBITS; // combine second level M_SetupNextMenu(&OP_ChangeControlsDef); } @@ -11789,8 +11989,8 @@ static void M_Setup2PControlsMenu(INT32 choice) OP_ChangeControlsMenu[27+3].status = IT_GRAYEDOUT2; OP_ChangeControlsDef.prevMenu = &OP_P2ControlsDef; - OP_ChangeControlsDef.menuid &= ~(((1 << MENUBITS) - 1) << MENUBITS); // remove first level (<< 6) - OP_ChangeControlsDef.menuid |= MN_OP_P2CONTROLS << MENUBITS; // combine first level (<< 6) + OP_ChangeControlsDef.menuid &= ~(((1 << MENUBITS) - 1) << MENUBITS); // remove second level + OP_ChangeControlsDef.menuid |= MN_OP_P2CONTROLS << MENUBITS; // combine second level M_SetupNextMenu(&OP_ChangeControlsDef); } diff --git a/src/m_menu.h b/src/m_menu.h index eeda9cc58..cce5a6a6c 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -31,6 +31,9 @@ #define MENUBITS 6 // Menu IDs sectioned by numeric places to signify hierarchy +/** + * IF YOU MODIFY THIS, MODIFY MENUTYPES_LIST[] IN dehacked.c TO MATCH. + */ typedef enum { MN_NONE, @@ -129,6 +132,9 @@ typedef enum MN_SPECIAL, NUMMENUTYPES, } menutype_t; // up to 63; MN_SPECIAL = 53 +#define MTREE2(a,b) (a | (b<= 0) + while ((secnum = P_FindSectorFromTag(line->tag,secnum)) >= 0) { sec = §ors[secnum]; @@ -615,7 +615,7 @@ INT32 EV_DoCrush(line_t *line, ceiling_e type) sector_t *sec; ceiling_t *ceiling; - while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0) + while ((secnum = P_FindSectorFromTag(line->tag,secnum)) >= 0) { sec = §ors[secnum]; diff --git a/src/p_enemy.c b/src/p_enemy.c index 2341be6d3..75d32c506 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -312,6 +312,7 @@ void A_RolloutRock(mobj_t *actor); void A_DragonbomberSpawn(mobj_t *actor); void A_DragonWing(mobj_t *actor); void A_DragonSegment(mobj_t *actor); +void A_ChangeHeight(mobj_t *actor); //for p_enemy.c @@ -2990,6 +2991,19 @@ void A_Boss1Laser(mobj_t *actor) angle_t angle; mobj_t *point; tic_t dur; + static const UINT8 LASERCOLORS[] = + { + SKINCOLOR_SUPERRED3, + SKINCOLOR_SUPERRED4, + SKINCOLOR_SUPERRED5, + SKINCOLOR_FLAME, + SKINCOLOR_RED, + SKINCOLOR_RED, + SKINCOLOR_FLAME, + SKINCOLOR_SUPERRED5, + SKINCOLOR_SUPERRED4, + SKINCOLOR_SUPERRED3, + }; if (LUA_CallAction("A_Boss1Laser", actor)) return; @@ -3064,7 +3078,7 @@ void A_Boss1Laser(mobj_t *actor) point = P_SpawnMobj(x, y, z, locvar1); P_SetTarget(&point->target, actor); point->angle = actor->angle; - speed = point->radius*2; + speed = point->radius; point->momz = FixedMul(FINECOSINE(angle>>ANGLETOFINESHIFT), speed); point->momx = FixedMul(FINESINE(angle>>ANGLETOFINESHIFT), FixedMul(FINECOSINE(point->angle>>ANGLETOFINESHIFT), speed)); point->momy = FixedMul(FINESINE(angle>>ANGLETOFINESHIFT), FixedMul(FINESINE(point->angle>>ANGLETOFINESHIFT), speed)); @@ -3073,23 +3087,69 @@ void A_Boss1Laser(mobj_t *actor) { mobj_t *mo = P_SpawnMobj(point->x, point->y, point->z, point->type); mo->angle = point->angle; + mo->color = LASERCOLORS[((UINT8)(i + 3*dur) >> 2) % sizeof(LASERCOLORS)]; // codeing P_UnsetThingPosition(mo); - mo->flags = MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY; + mo->flags = MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY; P_SetThingPosition(mo); + if (dur & 1 && mo->info->missilestate) + { + P_SetMobjState(mo, mo->info->missilestate); + if (mo->info->meleestate) + { + mobj_t *mo2 = P_SpawnMobjFromMobj(mo, 0, 0, 0, MT_PARTICLE); + mo2->flags2 |= MF2_LINKDRAW; + P_SetTarget(&mo2->tracer, actor); + P_SetMobjState(mo2, mo->info->meleestate); + } + } + + if (dur == 1) + P_SpawnGhostMobj(mo); + x = point->x, y = point->y, z = point->z; if (P_RailThinker(point)) break; } + x += point->momx; + y += point->momy; floorz = P_FloorzAtPos(x, y, z, mobjinfo[MT_EGGMOBILE_FIRE].height); - if (z - floorz < mobjinfo[MT_EGGMOBILE_FIRE].height>>1) + if (z - floorz < mobjinfo[MT_EGGMOBILE_FIRE].height>>1 && dur & 1) { - point = P_SpawnMobj(x, y, floorz+1, MT_EGGMOBILE_FIRE); + point = P_SpawnMobj(x, y, floorz, MT_EGGMOBILE_FIRE); + point->angle = actor->angle; + point->destscale = actor->scale; + P_SetScale(point, point->destscale); P_SetTarget(&point->target, actor); - point->destscale = 3*FRACUNIT; - point->scalespeed = FRACUNIT>>2; - point->fuse = TICRATE; + P_MobjCheckWater(point); + if (point->eflags & (MFE_UNDERWATER|MFE_TOUCHWATER)) + { + for (i = 0; i < 2; i++) + { + UINT8 size = 3; + mobj_t *steam = P_SpawnMobj(x, y, point->watertop - size*mobjinfo[MT_DUST].height, MT_DUST); + P_SetScale(steam, size*actor->scale); + P_SetObjectMomZ(steam, FRACUNIT + 2*P_RandomFixed(), true); + P_InstaThrust(steam, FixedAngle(P_RandomKey(360)*FRACUNIT), 2*P_RandomFixed()); + if (point->info->painsound) + S_StartSound(steam, point->info->painsound); + } + } + else + { + fixed_t distx = P_ReturnThrustX(point, point->angle, point->radius); + fixed_t disty = P_ReturnThrustY(point, point->angle, point->radius); + if (P_TryMove(point, point->x + distx, point->y + disty, false) // prevents the sprite from clipping into the wall or dangling off ledges + && P_TryMove(point, point->x - 2*distx, point->y - 2*disty, false) + && P_TryMove(point, point->x + distx, point->y + disty, false)) + { + if (point->info->seesound) + S_StartSound(point, point->info->seesound); + } + else + P_RemoveMobj(point); + } } if (dur > 1) @@ -5046,13 +5106,13 @@ void A_SignPlayer(mobj_t *actor) INT32 locvar2 = var2; skin_t *skin = NULL; mobj_t *ov; - UINT8 facecolor, signcolor = (UINT8)locvar2; + UINT16 facecolor, signcolor = (UINT16)locvar2; UINT32 signframe = states[actor->info->raisestate].frame; if (LUA_CallAction("A_SignPlayer", actor)) return; - if (actor->tracer == NULL || locvar1 < -3 || locvar1 >= numskins || signcolor >= MAXTRANSLATIONS) + if (actor->tracer == NULL || locvar1 < -3 || locvar1 >= numskins || signcolor >= numskincolors) return; // if no face overlay, spawn one @@ -5083,7 +5143,7 @@ void A_SignPlayer(mobj_t *actor) else if ((actor->target->player->skincolor == skin->prefcolor) && (skin->prefoppositecolor)) // Set it as the skin's preferred oppositecolor? signcolor = skin->prefoppositecolor; 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 signcolor = SKINCOLOR_NONE; } @@ -5121,7 +5181,7 @@ void A_SignPlayer(mobj_t *actor) else if (skin->prefoppositecolor) signcolor = skin->prefoppositecolor; else if (facecolor) - signcolor = Color_Opposite[facecolor - 1][0]; + signcolor = skincolors[facecolor].invcolor; } if (skin) @@ -5152,19 +5212,8 @@ void A_SignPlayer(mobj_t *actor) } actor->tracer->color = signcolor; - /* - If you're here from the comment above Color_Opposite, - the following line is the one which is dependent on the - array being symmetrical. It gets the opposite of the - opposite of your desired colour just so it can get the - brightness frame for the End Sign. It's not a great - design choice, but it's constant time array access and - the idea that the colours should be OPPOSITES is kind - of in the name. If you have a better idea, feel free - to let me know. ~toast 2016/07/20 - */ - if (signcolor && signcolor < MAXSKINCOLORS) - signframe += (15 - Color_Opposite[Color_Opposite[signcolor - 1][0] - 1][1]); + if (signcolor && signcolor < numskincolors) + signframe += (15 - skincolors[signcolor].invshade); actor->tracer->frame = signframe; } @@ -8744,10 +8793,10 @@ void A_ChangeColorRelative(mobj_t *actor) { // Have you ever seen anything so hideous? if (actor->target) - actor->color = (UINT8)(actor->color + actor->target->color); + actor->color = (UINT16)(actor->color + actor->target->color); } else - actor->color = (UINT8)(actor->color + locvar2); + actor->color = (UINT16)(actor->color + locvar2); } // Function: A_ChangeColorAbsolute @@ -8771,7 +8820,7 @@ void A_ChangeColorAbsolute(mobj_t *actor) actor->color = actor->target->color; } else - actor->color = (UINT8)locvar2; + actor->color = (UINT16)locvar2; } // Function: A_Dye @@ -8788,25 +8837,23 @@ void A_Dye(mobj_t *actor) mobj_t *target = ((locvar1 && actor->target) ? actor->target : actor); UINT8 color = (UINT8)locvar2; -#ifdef HAVE_BLUA if (LUA_CallAction("A_Dye", actor)) return; -#endif - if (color >= MAXTRANSLATIONS) + if (color >= numskincolors) return; - + if (!color) target->colorized = false; else target->colorized = true; - + // What if it's a player? if (target->player) { target->player->powers[pw_dye] = color; return; } - + target->color = color; } @@ -9649,6 +9696,9 @@ void A_SplitShot(mobj_t *actor) if (LUA_CallAction("A_SplitShot", actor)) return; + if (!actor->target) + return; + A_FaceTarget(actor); { const angle_t an = (actor->angle + ANGLE_90) >> ANGLETOFINESHIFT; @@ -12642,8 +12692,8 @@ void A_Boss5FindWaypoint(mobj_t *actor) else // locvar1 == 0 { fixed_t hackoffset = P_MobjFlip(actor)*56*FRACUNIT; - INT32 numwaypoints = 0; - mobj_t **waypoints; + INT32 numfangwaypoints = 0; + mobj_t **fangwaypoints; INT32 key; actor->z += hackoffset; @@ -12668,7 +12718,7 @@ void A_Boss5FindWaypoint(mobj_t *actor) continue; if (!P_CheckSight(actor, mapthings[i].mobj)) continue; - numwaypoints++; + numfangwaypoints++; } // players also count as waypoints apparently @@ -12690,11 +12740,11 @@ void A_Boss5FindWaypoint(mobj_t *actor) continue; if (!P_CheckSight(actor, players[i].mo)) continue; - numwaypoints++; + numfangwaypoints++; } } - if (!numwaypoints) + if (!numfangwaypoints) { // restore z position actor->z -= hackoffset; @@ -12702,8 +12752,8 @@ void A_Boss5FindWaypoint(mobj_t *actor) } // allocate the table and reset count to zero - waypoints = Z_Calloc(sizeof(*waypoints)*numwaypoints, PU_STATIC, NULL); - numwaypoints = 0; + fangwaypoints = Z_Calloc(sizeof(*waypoints)*numfangwaypoints, PU_STATIC, NULL); + numfangwaypoints = 0; // now find them again and add them to the table! for (i = 0; i < nummapthings; i++) @@ -12728,7 +12778,7 @@ void A_Boss5FindWaypoint(mobj_t *actor) } if (!P_CheckSight(actor, mapthings[i].mobj)) continue; - waypoints[numwaypoints++] = mapthings[i].mobj; + fangwaypoints[numfangwaypoints++] = mapthings[i].mobj; } if (actor->extravalue2 > 1) @@ -12749,25 +12799,25 @@ void A_Boss5FindWaypoint(mobj_t *actor) continue; if (!P_CheckSight(actor, players[i].mo)) continue; - waypoints[numwaypoints++] = players[i].mo; + fangwaypoints[numfangwaypoints++] = players[i].mo; } } // restore z position actor->z -= hackoffset; - if (!numwaypoints) + if (!numfangwaypoints) { - Z_Free(waypoints); // free table + Z_Free(fangwaypoints); // free table goto nowaypoints; // ??? } - key = P_RandomKey(numwaypoints); + key = P_RandomKey(numfangwaypoints); - P_SetTarget(&actor->tracer, waypoints[key]); + P_SetTarget(&actor->tracer, fangwaypoints[key]); if (actor->tracer->type == MT_FANGWAYPOINT) - actor->tracer->reactiontime = numwaypoints/4; // Monster Iestyn: is this how it should be? I count center waypoints as waypoints unlike the original Lua script - Z_Free(waypoints); // free table + actor->tracer->reactiontime = numfangwaypoints/4; // Monster Iestyn: is this how it should be? I count center waypoints as waypoints unlike the original Lua script + Z_Free(fangwaypoints); // free table } // now face the tracer you just set! @@ -13311,8 +13361,9 @@ static boolean PIT_DustDevilLaunch(mobj_t *thing) P_ResetPlayer(player); A_PlayActiveSound(dustdevil); } + player->powers[pw_carry] = CR_DUSTDEVIL; player->powers[pw_nocontrol] = 2; - player->drawangle += ANG20; + P_SetTarget(&thing->tracer, dustdevil); P_SetPlayerMobjState(thing, S_PLAY_PAIN); if (dist > dragamount) @@ -13332,7 +13383,9 @@ static boolean PIT_DustDevilLaunch(mobj_t *thing) P_ResetPlayer(player); thing->z = dustdevil->z + dustdevil->height; thrust = 20 * FRACUNIT; + player->powers[pw_carry] = CR_NONE; player->powers[pw_nocontrol] = 0; + P_SetTarget(&thing->tracer, NULL); S_StartSound(thing, sfx_wdjump); P_SetPlayerMobjState(thing, S_PLAY_FALL); } @@ -14409,3 +14462,43 @@ void A_DragonSegment(mobj_t *actor) actor->angle = hangle; P_TeleportMove(actor, target->x + xdist, target->y + ydist, target->z + zdist); } + +// Function: A_ChangeHeight +// +// Description: Changes the actor's height by var1 +// +// var1 = height +// var2 = +// &1: height is absolute +// &2: scale with actor's scale +// +void A_ChangeHeight(mobj_t *actor) +{ + INT32 locvar1 = var1; + INT32 locvar2 = var2; + fixed_t height = locvar1; + boolean reverse; + + if (LUA_CallAction("A_ChangeHeight", actor)) + return; + + reverse = (actor->eflags & MFE_VERTICALFLIP) || (actor->flags2 & MF2_OBJECTFLIP); + + if (locvar2 & 2) + height = FixedMul(height, actor->scale); + + P_UnsetThingPosition(actor); + if (locvar2 & 1) + { + if (reverse) + actor->z += actor->height - locvar1; + actor->height = locvar1; + } + else + { + if (reverse) + actor->z -= locvar1; + actor->height += locvar1; + } + P_SetThingPosition(actor); +} diff --git a/src/p_floor.c b/src/p_floor.c index 179cf73c7..a0f7edd9c 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -696,10 +696,20 @@ void T_BounceCheese(bouncecheese_t *bouncer) return; } - 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 + if (bouncer->speed >= 0) // move floor first to fix height desync and any bizarre bugs following that + { + T_MovePlane(bouncer->sector, bouncer->speed/2, bouncer->sector->floorheight - 70*FRACUNIT, + 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->ceilspeed = 42; @@ -757,7 +767,7 @@ void T_BounceCheese(bouncecheese_t *bouncer) // T_StartCrumble //////////////////////////////// ////////////////////////////////////////////////// // Crumbling platform Tails 03-11-2002 -void T_StartCrumble(elevator_t *elevator) +void T_StartCrumble(crumble_t *crumble) { ffloor_t *rover; sector_t *sector; @@ -765,84 +775,96 @@ void T_StartCrumble(elevator_t *elevator) // Once done, the no-return thinker just sits there, // constantly 'returning'... kind of an oxymoron, isn't it? - if (((elevator->floordestheight == 1 && elevator->direction == -1) - || (elevator->floordestheight == 0 && elevator->direction == 1)) - && elevator->type == elevateContinuous) // No return crumbler + if ((((crumble->flags & CF_REVERSE) && crumble->direction == -1) + || (!(crumble->flags & CF_REVERSE) && crumble->direction == 1)) + && !(crumble->flags & CF_RETURN)) { - elevator->sector->ceilspeed = 0; - elevator->sector->floorspeed = 0; + crumble->sector->ceilspeed = 0; + crumble->sector->floorspeed = 0; return; } - if (elevator->distance != 0) + if (crumble->timer != 0) { - if (elevator->distance > 0) // Count down the timer + if (crumble->timer > 0) // Count down the timer { - elevator->distance--; - if (elevator->distance <= 0) - elevator->distance = -15*TICRATE; // Timer until platform returns to original position. + if (--crumble->timer <= 0) + crumble->timer = -15*TICRATE; // Timer until platform returns to original position. else { // Timer isn't up yet, so just keep waiting. - elevator->sector->ceilspeed = 0; - elevator->sector->floorspeed = 0; + crumble->sector->ceilspeed = 0; + crumble->sector->floorspeed = 0; return; } } - else if (++elevator->distance == 0) // Reposition back to original spot + else if (++crumble->timer == 0) // Reposition back to original spot { - for (i = -1; (i = P_FindSectorFromTag(elevator->sourceline->tag, i)) >= 0 ;) + for (i = -1; (i = P_FindSectorFromTag(crumble->sourceline->tag, i)) >= 0 ;) { sector = §ors[i]; for (rover = sector->ffloors; rover; rover = rover->next) { - if (rover->flags & FF_CRUMBLE && rover->flags & FF_FLOATBOB - && rover->master == elevator->sourceline) - { - rover->alpha = elevator->origspeed; + if (!(rover->flags & FF_CRUMBLE)) + continue; - if (rover->alpha == 0xff) - rover->flags &= ~FF_TRANSLUCENT; - } + if (!(rover->flags & FF_FLOATBOB)) + continue; + + if (rover->master != crumble->sourceline) + continue; + + rover->alpha = crumble->origalpha; + + if (rover->alpha == 0xff) + rover->flags &= ~FF_TRANSLUCENT; } } // Up! - if (elevator->floordestheight == 1) - elevator->direction = -1; + if (crumble->flags & CF_REVERSE) + crumble->direction = -1; else - elevator->direction = 1; + crumble->direction = 1; - elevator->sector->ceilspeed = 0; - elevator->sector->floorspeed = 0; + crumble->sector->ceilspeed = 0; + crumble->sector->floorspeed = 0; return; } // Flash to indicate that the platform is about to return. - if (elevator->distance > -224 && (leveltime % ((abs(elevator->distance)/8) + 1) == 0)) + if (crumble->timer > -224 && (leveltime % ((abs(crumble->timer)/8) + 1) == 0)) { - for (i = -1; (i = P_FindSectorFromTag(elevator->sourceline->tag, i)) >= 0 ;) + for (i = -1; (i = P_FindSectorFromTag(crumble->sourceline->tag, i)) >= 0 ;) { sector = §ors[i]; for (rover = sector->ffloors; rover; rover = rover->next) { - if (!(rover->flags & FF_NORETURN) && rover->flags & FF_CRUMBLE && rover->flags & FF_FLOATBOB - && rover->master == elevator->sourceline) - { - if (rover->alpha == elevator->origspeed) - { - rover->flags |= FF_TRANSLUCENT; - rover->alpha = 0x00; - } - else - { - if (elevator->origspeed == 0xff) - rover->flags &= ~FF_TRANSLUCENT; + if (rover->flags & FF_NORETURN) + continue; - rover->alpha = elevator->origspeed; - } + if (!(rover->flags & FF_CRUMBLE)) + continue; + + if (!(rover->flags & FF_FLOATBOB)) + continue; + + if (rover->master != crumble->sourceline) + continue; + + if (rover->alpha == crumble->origalpha) + { + rover->flags |= FF_TRANSLUCENT; + rover->alpha = 0x00; + } + else + { + rover->alpha = crumble->origalpha; + + if (rover->alpha == 0xff) + rover->flags &= ~FF_TRANSLUCENT; } } } @@ -851,74 +873,62 @@ void T_StartCrumble(elevator_t *elevator) // We're about to go back to the original position, // so set this to let other thinkers know what is // about to happen. - if (elevator->distance < 0 && elevator->distance > -3) - elevator->sector->crumblestate = CRUMBLE_RESTORE; // makes T_BounceCheese remove itself + if (crumble->timer < 0 && crumble->timer > -3) + crumble->sector->crumblestate = CRUMBLE_RESTORE; // makes T_BounceCheese remove itself } - if ((elevator->floordestheight == 0 && elevator->direction == -1) - || (elevator->floordestheight == 1 && elevator->direction == 1)) // Down + if ((!(crumble->flags & CF_REVERSE) && crumble->direction == -1) + || ((crumble->flags & CF_REVERSE) && crumble->direction == 1)) // Down { - elevator->sector->crumblestate = CRUMBLE_FALL; // Allow floating now. + crumble->sector->crumblestate = CRUMBLE_FALL; // Allow floating now. // Only fall like this if it isn't meant to float on water - if (elevator->high != 42) + if (!(crumble->flags & CF_FLOATBOB)) { - elevator->speed += gravity; // Gain more and more speed + crumble->speed += gravity; // Gain more and more speed - if ((elevator->floordestheight == 0 && !(elevator->sector->ceilingheight < -16384*FRACUNIT)) - || (elevator->floordestheight == 1 && !(elevator->sector->ceilingheight > 16384*FRACUNIT))) + if ((!(crumble->flags & CF_REVERSE) && crumble->sector->ceilingheight >= -16384*FRACUNIT) + || ((crumble->flags & CF_REVERSE) && crumble->sector->ceilingheight <= 16384*FRACUNIT)) { - fixed_t dest; - - if (elevator->floordestheight == 1) - dest = elevator->sector->ceilingheight + (elevator->speed*2); - else - dest = elevator->sector->ceilingheight - (elevator->speed*2); - T_MovePlane //jff 4/7/98 reverse order of ceiling/floor ( - elevator->sector, - elevator->speed, - dest, + crumble->sector, + crumble->speed, + crumble->sector->ceilingheight + crumble->direction*crumble->speed*2, false, true, // move ceiling - elevator->direction + crumble->direction ); - if (elevator->floordestheight == 1) - dest = elevator->sector->floorheight + (elevator->speed*2); - else - dest = elevator->sector->floorheight - (elevator->speed*2); - - T_MovePlane - ( - elevator->sector, - elevator->speed, - dest, - false, - false, // move floor - elevator->direction + T_MovePlane + ( + crumble->sector, + crumble->speed, + crumble->sector->floorheight + crumble->direction*crumble->speed*2, + false, + false, // move floor + crumble->direction ); - elevator->sector->ceilspeed = 42; - elevator->sector->floorspeed = elevator->speed*elevator->direction; + crumble->sector->ceilspeed = 42; + crumble->sector->floorspeed = crumble->speed*crumble->direction; } } } else // Up (restore to original position) { - elevator->sector->crumblestate = CRUMBLE_WAIT; - elevator->sector->ceilingheight = elevator->ceilingwasheight; - elevator->sector->floorheight = elevator->floorwasheight; - elevator->sector->floordata = NULL; - elevator->sector->ceilingdata = NULL; - elevator->sector->ceilspeed = 0; - elevator->sector->floorspeed = 0; - elevator->sector->moved = true; - P_RemoveThinker(&elevator->thinker); + crumble->sector->crumblestate = CRUMBLE_WAIT; + crumble->sector->ceilingheight = crumble->ceilingwasheight; + crumble->sector->floorheight = crumble->floorwasheight; + crumble->sector->floordata = NULL; + crumble->sector->ceilingdata = NULL; + crumble->sector->ceilspeed = 0; + crumble->sector->floorspeed = 0; + crumble->sector->moved = true; + P_RemoveThinker(&crumble->thinker); } - for (i = -1; (i = P_FindSectorFromTag(elevator->sourceline->tag, i)) >= 0 ;) + for (i = -1; (i = P_FindSectorFromTag(crumble->sourceline->tag, i)) >= 0 ;) { sector = §ors[i]; sector->moved = true; @@ -1284,7 +1294,7 @@ void T_NoEnemiesSector(noenemies_t *nobaddies) INT32 secnum = -1; boolean FOFsector = false; - while ((secnum = P_FindSectorFromLineTag(nobaddies->sourceline, secnum)) >= 0) + while ((secnum = P_FindSectorFromTag(nobaddies->sourceline->tag, secnum)) >= 0) { sec = §ors[secnum]; @@ -1300,7 +1310,7 @@ void T_NoEnemiesSector(noenemies_t *nobaddies) FOFsector = true; - while ((targetsecnum = P_FindSectorFromLineTag(sec->lines[i], targetsecnum)) >= 0) + while ((targetsecnum = P_FindSectorFromTag(sec->lines[i]->tag, targetsecnum)) >= 0) { if (T_SectorHasEnemies(§ors[targetsecnum])) return; @@ -1395,7 +1405,7 @@ void T_EachTimeThinker(eachtime_t *eachtime) eachtime->playersOnArea[i] = false; } - while ((secnum = P_FindSectorFromLineTag(eachtime->sourceline, secnum)) >= 0) + while ((secnum = P_FindSectorFromTag(eachtime->sourceline->tag, secnum)) >= 0) { sec = §ors[secnum]; @@ -1418,7 +1428,7 @@ void T_EachTimeThinker(eachtime_t *eachtime) FOFsector = true; - while ((targetsecnum = P_FindSectorFromLineTag(sec->lines[i], targetsecnum)) >= 0) + while ((targetsecnum = P_FindSectorFromTag(sec->lines[i]->tag, targetsecnum)) >= 0) { targetsec = §ors[targetsecnum]; @@ -1556,7 +1566,7 @@ void T_RaiseSector(raise_t *raise) if (raise->sector->crumblestate >= CRUMBLE_FALL || raise->sector->ceilingdata) return; - for (i = -1; (i = P_FindSectorFromTag(raise->sourceline->tag, i)) >= 0 ;) + for (i = -1; (i = P_FindSectorFromTag(raise->tag, i)) >= 0 ;) { sector = §ors[i]; @@ -1683,7 +1693,7 @@ void T_RaiseSector(raise_t *raise) raise->sector->ceilspeed = 42; raise->sector->floorspeed = speed*direction; - for (i = -1; (i = P_FindSectorFromTag(raise->sourceline->tag, i)) >= 0 ;) + for (i = -1; (i = P_FindSectorFromTag(raise->tag, i)) >= 0 ;) P_RecalcPrecipInSector(§ors[i]); } @@ -1801,7 +1811,7 @@ void EV_DoFloor(line_t *line, floor_e floortype) sector_t *sec; floormove_t *dofloor; - while ((secnum = P_FindSectorFromLineTag(line, secnum)) >= 0) + while ((secnum = P_FindSectorFromTag(line->tag, secnum)) >= 0) { sec = §ors[secnum]; @@ -2017,7 +2027,7 @@ void EV_DoElevator(line_t *line, elevator_e elevtype, boolean customspeed) elevator_t *elevator; // act on all sectors with the same tag as the triggering linedef - while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0) + while ((secnum = P_FindSectorFromTag(line->tag,secnum)) >= 0) { sec = §ors[secnum]; @@ -2231,9 +2241,9 @@ void EV_CrumbleChain(sector_t *sec, ffloor_t *rover) { mobj_t *spawned = NULL; if (*rover->t_slope) - topz = P_GetZAt(*rover->t_slope, a, b) - (spacing>>1); + topz = P_GetSlopeZAt(*rover->t_slope, a, b) - (spacing>>1); if (*rover->b_slope) - bottomz = P_GetZAt(*rover->b_slope, a, b); + bottomz = P_GetSlopeZAt(*rover->b_slope, a, b); for (c = topz; c > bottomz; c -= spacing) { @@ -2309,7 +2319,7 @@ void EV_DoContinuousFall(sector_t *sec, sector_t *backsector, fixed_t spd, boole INT32 EV_StartCrumble(sector_t *sec, ffloor_t *rover, boolean floating, player_t *player, fixed_t origalpha, boolean crumblereturn) { - elevator_t *elevator; + crumble_t *crumble; sector_t *foundsec; INT32 i; @@ -2320,55 +2330,45 @@ INT32 EV_StartCrumble(sector_t *sec, ffloor_t *rover, boolean floating, if (sec->crumblestate >= CRUMBLE_ACTIVATED) return 0; - // create and initialize new elevator thinker - elevator = Z_Calloc(sizeof (*elevator), PU_LEVSPEC, NULL); - P_AddThinker(THINK_MAIN, &elevator->thinker); - elevator->thinker.function.acp1 = (actionf_p1)T_StartCrumble; + // create and initialize new crumble thinker + crumble = Z_Calloc(sizeof (*crumble), PU_LEVSPEC, NULL); + P_AddThinker(THINK_MAIN, &crumble->thinker); + crumble->thinker.function.acp1 = (actionf_p1)T_StartCrumble; - // Does this crumbler return? - if (crumblereturn) - elevator->type = elevateBounce; - else - elevator->type = elevateContinuous; - - // set up the fields according to the type of elevator action - elevator->sector = sec; - elevator->speed = 0; + // set up the fields + crumble->sector = sec; + crumble->speed = 0; if (player && player->mo && (player->mo->eflags & MFE_VERTICALFLIP)) { - elevator->direction = 1; // Up - elevator->floordestheight = 1; + crumble->direction = 1; // Up + crumble->flags |= CF_REVERSE; } else - { - elevator->direction = -1; // Down - elevator->floordestheight = 0; - } + crumble->direction = -1; // Down - elevator->floorwasheight = elevator->sector->floorheight; - elevator->ceilingwasheight = elevator->sector->ceilingheight; - elevator->distance = TICRATE; // Used for delay time - elevator->low = 0; - elevator->player = player; - elevator->origspeed = origalpha; + crumble->floorwasheight = crumble->sector->floorheight; + crumble->ceilingwasheight = crumble->sector->ceilingheight; + crumble->timer = TICRATE; + crumble->player = player; + crumble->origalpha = origalpha; - elevator->sourceline = rover->master; + crumble->sourceline = rover->master; - sec->floordata = elevator; + sec->floordata = crumble; + if (crumblereturn) + crumble->flags |= CF_RETURN; if (floating) - elevator->high = 42; - else - elevator->high = 0; + crumble->flags |= CF_FLOATBOB; - elevator->sector->crumblestate = CRUMBLE_ACTIVATED; + crumble->sector->crumblestate = CRUMBLE_ACTIVATED; - for (i = -1; (i = P_FindSectorFromTag(elevator->sourceline->tag, i)) >= 0 ;) + for (i = -1; (i = P_FindSectorFromTag(crumble->sourceline->tag, i)) >= 0 ;) { foundsec = §ors[i]; - P_SpawnMobj(foundsec->soundorg.x, foundsec->soundorg.y, elevator->direction == 1 ? elevator->sector->floorheight : elevator->sector->ceilingheight, MT_CRUMBLEOBJ); + P_SpawnMobj(foundsec->soundorg.x, foundsec->soundorg.y, crumble->direction == 1 ? crumble->sector->floorheight : crumble->sector->ceilingheight, MT_CRUMBLEOBJ); } return 1; diff --git a/src/p_map.c b/src/p_map.c index accc52836..6e4992473 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -2157,7 +2157,6 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y) BMBOUNDFIX(xl, xh, yl, yh); -#ifdef POLYOBJECTS // Check polyobjects and see if tmfloorz/tmceilingz need to be altered { validcount++; @@ -2229,7 +2228,6 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y) } } } -#endif // tmfloorthing is set when tmfloorz comes from a thing's top tmfloorthing = NULL; @@ -2387,7 +2385,6 @@ boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam) BMBOUNDFIX(xl, xh, yl, yh); -#ifdef POLYOBJECTS // Check polyobjects and see if tmfloorz/tmceilingz need to be altered { validcount++; @@ -2458,7 +2455,6 @@ boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam) } } } -#endif // check lines for (bx = xl; bx <= xh; bx++) @@ -3206,102 +3202,83 @@ isblocking: static boolean P_IsClimbingValid(player_t *player, angle_t angle) { fixed_t platx, platy; - subsector_t *glidesector; + sector_t *glidesector; fixed_t floorz, ceilingz; + mobj_t *mo = player->mo; + ffloor_t *rover; - platx = P_ReturnThrustX(player->mo, angle, player->mo->radius + FixedMul(8*FRACUNIT, player->mo->scale)); - platy = P_ReturnThrustY(player->mo, angle, player->mo->radius + FixedMul(8*FRACUNIT, player->mo->scale)); + platx = P_ReturnThrustX(mo, angle, mo->radius + FixedMul(8*FRACUNIT, mo->scale)); + platy = P_ReturnThrustY(mo, angle, mo->radius + FixedMul(8*FRACUNIT, mo->scale)); - glidesector = R_PointInSubsector(player->mo->x + platx, player->mo->y + platy); + glidesector = R_PointInSubsector(mo->x + platx, mo->y + platy)->sector; - floorz = glidesector->sector->f_slope ? P_GetZAt(glidesector->sector->f_slope, player->mo->x, player->mo->y) : glidesector->sector->floorheight; - ceilingz = glidesector->sector->c_slope ? P_GetZAt(glidesector->sector->c_slope, player->mo->x, player->mo->y) : glidesector->sector->ceilingheight; + floorz = P_GetSectorFloorZAt (glidesector, mo->x, mo->y); + ceilingz = P_GetSectorCeilingZAt(glidesector, mo->x, mo->y); - if (glidesector->sector != player->mo->subsector->sector) + if (glidesector != mo->subsector->sector) { boolean floorclimb = false; fixed_t topheight, bottomheight; - if (glidesector->sector->ffloors) + for (rover = glidesector->ffloors; rover; rover = rover->next) { - ffloor_t *rover; - for (rover = glidesector->sector->ffloors; rover; rover = rover->next) + if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER)) + continue; + + topheight = P_GetFFloorTopZAt (rover, mo->x, mo->y); + bottomheight = P_GetFFloorBottomZAt(rover, mo->x, mo->y); + + floorclimb = true; + + if (mo->eflags & MFE_VERTICALFLIP) { - if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER)) - continue; - - topheight = *rover->topheight; - bottomheight = *rover->bottomheight; - - if (*rover->t_slope) - topheight = P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y); - if (*rover->b_slope) - bottomheight = P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y); - - floorclimb = true; - - if (player->mo->eflags & MFE_VERTICALFLIP) - { - if ((topheight < player->mo->z + player->mo->height) && ((player->mo->z + player->mo->height + player->mo->momz) < topheight)) - { - floorclimb = true; - } - if (topheight < player->mo->z) // Waaaay below the ledge. - { - floorclimb = false; - } - if (bottomheight > player->mo->z + player->mo->height - FixedMul(16*FRACUNIT,player->mo->scale)) - { - floorclimb = false; - } - } - else - { - if ((bottomheight > player->mo->z) && ((player->mo->z - player->mo->momz) > bottomheight)) - { - floorclimb = true; - } - if (bottomheight > player->mo->z + player->mo->height) // Waaaay below the ledge. - { - floorclimb = false; - } - if (topheight < player->mo->z + FixedMul(16*FRACUNIT,player->mo->scale)) - { - floorclimb = false; - } - } - - if (floorclimb) - break; + if ((topheight < mo->z + mo->height) && ((mo->z + mo->height + mo->momz) < topheight)) + floorclimb = true; + if (topheight < mo->z) // Waaaay below the ledge. + floorclimb = false; + if (bottomheight > mo->z + mo->height - FixedMul(16*FRACUNIT,mo->scale)) + floorclimb = false; } + else + { + if ((bottomheight > mo->z) && ((mo->z - mo->momz) > bottomheight)) + floorclimb = true; + if (bottomheight > mo->z + mo->height) // Waaaay below the ledge. + floorclimb = false; + if (topheight < mo->z + FixedMul(16*FRACUNIT,mo->scale)) + floorclimb = false; + } + + if (floorclimb) + break; } - if (player->mo->eflags & MFE_VERTICALFLIP) + if (mo->eflags & MFE_VERTICALFLIP) { - if ((floorz <= player->mo->z + player->mo->height) - && ((player->mo->z + player->mo->height - player->mo->momz) <= floorz)) + if ((floorz <= mo->z + mo->height) + && ((mo->z + mo->height - mo->momz) <= floorz)) floorclimb = true; - if ((floorz > player->mo->z) - && glidesector->sector->floorpic == skyflatnum) + if ((floorz > mo->z) + && glidesector->floorpic == skyflatnum) return false; - if ((player->mo->z + player->mo->height - FixedMul(16*FRACUNIT,player->mo->scale) > ceilingz) - || (player->mo->z + player->mo->height <= floorz)) + if ((mo->z + mo->height - FixedMul(16*FRACUNIT,mo->scale) > ceilingz) + || (mo->z + mo->height <= floorz)) floorclimb = true; } else { - if ((ceilingz >= player->mo->z) - && ((player->mo->z - player->mo->momz) >= ceilingz)) + if ((ceilingz >= mo->z) + && ((mo->z - mo->momz) >= ceilingz)) floorclimb = true; - if ((ceilingz < player->mo->z+player->mo->height) - && glidesector->sector->ceilingpic == skyflatnum) + if ((ceilingz < mo->z+mo->height) + && glidesector->ceilingpic == skyflatnum) return false; - if ((player->mo->z + FixedMul(16*FRACUNIT,player->mo->scale) < floorz) - || (player->mo->z >= ceilingz)) + if ((mo->z + FixedMul(16*FRACUNIT,mo->scale) < floorz) + || (mo->z >= ceilingz)) floorclimb = true; } @@ -3389,13 +3366,8 @@ isblocking: if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP)) continue; - topheight = *rover->topheight; - bottomheight = *rover->bottomheight; - - if (*rover->t_slope) - topheight = P_GetZAt(*rover->t_slope, slidemo->x, slidemo->y); - if (*rover->b_slope) - bottomheight = P_GetZAt(*rover->b_slope, slidemo->x, slidemo->y); + topheight = P_GetFFloorTopZAt (rover, slidemo->x, slidemo->y); + bottomheight = P_GetFFloorBottomZAt(rover, slidemo->x, slidemo->y); if (topheight < slidemo->z) continue; @@ -3600,9 +3572,7 @@ static void P_CheckLavaWall(mobj_t *mo, sector_t *sec) if (rover->master->flags & ML_BLOCKMONSTERS) continue; - topheight = *rover->t_slope ? - P_GetZAt(*rover->t_slope, mo->x, mo->y) : - *rover->topheight; + topheight = P_GetFFloorTopZAt(rover, mo->x, mo->y); if (mo->eflags & MFE_VERTICALFLIP) { @@ -3615,9 +3585,7 @@ static void P_CheckLavaWall(mobj_t *mo, sector_t *sec) continue; } - bottomheight = *rover->b_slope ? - P_GetZAt(*rover->b_slope, mo->x, mo->y) : - *rover->bottomheight; + bottomheight = P_GetFFloorBottomZAt(rover, mo->x, mo->y); if (mo->eflags & MFE_VERTICALFLIP) { @@ -4203,11 +4171,8 @@ static boolean PIT_ChangeSector(mobj_t *thing, boolean realcrush) topheight = *rover->topheight; bottomheight = *rover->bottomheight; - - /*if (rover->t_slope) - topheight = P_GetZAt(rover->t_slope, thing->x, thing->y); - if (rover->b_slope) - bottomheight = P_GetZAt(rover->b_slope, thing->x, thing->y);*/ + //topheight = P_GetFFloorTopZAt (rover, thing->x, thing->y); + //bottomheight = P_GetFFloorBottomZAt(rover, thing->x, thing->y); delta1 = thing->z - (bottomheight + topheight)/2; delta2 = thingtop - (bottomheight + topheight)/2; @@ -4223,21 +4188,19 @@ static boolean PIT_ChangeSector(mobj_t *thing, boolean realcrush) { //If the thing was crushed by a crumbling FOF, reward the player who made it crumble! thinker_t *think; - elevator_t *crumbler; + crumble_t *crumbler; for (think = thlist[THINK_MAIN].next; think != &thlist[THINK_MAIN]; think = think->next) { if (think->function.acp1 != (actionf_p1)T_StartCrumble) continue; - crumbler = (elevator_t *)think; + crumbler = (crumble_t *)think; if (crumbler->player && crumbler->player->mo && crumbler->player->mo != thing && crumbler->actionsector == thing->subsector->sector - && crumbler->sector == rover->master->frontsector - && (crumbler->type == elevateBounce - || crumbler->type == elevateContinuous)) + && crumbler->sector == rover->master->frontsector) { killer = crumbler->player->mo; } @@ -4986,10 +4949,7 @@ void P_MapEnd(void) fixed_t P_FloorzAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height) { sector_t *sec = R_PointInSubsector(x, y)->sector; - fixed_t floorz = sec->floorheight; - - if (sec->f_slope) - floorz = P_GetZAt(sec->f_slope, x, y); + fixed_t floorz = P_GetSectorFloorZAt(sec, x, y); // Intercept the stupid 'fall through 3dfloors' bug Tails 03-17-2002 if (sec->ffloors) @@ -5006,13 +4966,8 @@ fixed_t P_FloorzAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height) if ((!(rover->flags & FF_SOLID || rover->flags & FF_QUICKSAND) || (rover->flags & FF_SWIMMABLE))) continue; - topheight = *rover->topheight; - bottomheight = *rover->bottomheight; - - if (*rover->t_slope) - topheight = P_GetZAt(*rover->t_slope, x, y); - if (*rover->b_slope) - bottomheight = P_GetZAt(*rover->b_slope, x, y); + topheight = P_GetFFloorTopZAt (rover, x, y); + bottomheight = P_GetFFloorBottomZAt(rover, x, y); if (rover->flags & FF_QUICKSAND) { diff --git a/src/p_maputl.c b/src/p_maputl.c index bfca72eda..c6e064d18 100644 --- a/src/p_maputl.c +++ b/src/p_maputl.c @@ -303,45 +303,33 @@ void P_CameraLineOpening(line_t *linedef) // If you can see through it, why not move the camera through it too? if (front->camsec >= 0) { - frontfloor = sectors[front->camsec].floorheight; - frontceiling = sectors[front->camsec].ceilingheight; - if (sectors[front->camsec].f_slope) // SRB2CBTODO: ESLOPE (sectors[front->heightsec].f_slope) - frontfloor = P_GetZAt(sectors[front->camsec].f_slope, camera.x, camera.y); - if (sectors[front->camsec].c_slope) - frontceiling = P_GetZAt(sectors[front->camsec].c_slope, camera.x, camera.y); + // SRB2CBTODO: ESLOPE (sectors[front->heightsec].f_slope) + frontfloor = P_GetSectorFloorZAt (§ors[front->camsec], camera.x, camera.y); + frontceiling = P_GetSectorCeilingZAt(§ors[front->camsec], camera.x, camera.y); } else if (front->heightsec >= 0) { - frontfloor = sectors[front->heightsec].floorheight; - frontceiling = sectors[front->heightsec].ceilingheight; - if (sectors[front->heightsec].f_slope) // SRB2CBTODO: ESLOPE (sectors[front->heightsec].f_slope) - frontfloor = P_GetZAt(sectors[front->heightsec].f_slope, camera.x, camera.y); - if (sectors[front->heightsec].c_slope) - frontceiling = P_GetZAt(sectors[front->heightsec].c_slope, camera.x, camera.y); + // SRB2CBTODO: ESLOPE (sectors[front->heightsec].f_slope) + frontfloor = P_GetSectorFloorZAt (§ors[front->heightsec], camera.x, camera.y); + frontceiling = P_GetSectorCeilingZAt(§ors[front->heightsec], camera.x, camera.y); } else { - frontfloor = P_CameraGetFloorZ(mapcampointer, front, tmx, tmy, linedef); + frontfloor = P_CameraGetFloorZ (mapcampointer, front, tmx, tmy, linedef); frontceiling = P_CameraGetCeilingZ(mapcampointer, front, tmx, tmy, linedef); } if (back->camsec >= 0) { - backfloor = sectors[back->camsec].floorheight; - backceiling = sectors[back->camsec].ceilingheight; - if (sectors[back->camsec].f_slope) // SRB2CBTODO: ESLOPE (sectors[front->heightsec].f_slope) - frontfloor = P_GetZAt(sectors[back->camsec].f_slope, camera.x, camera.y); - if (sectors[back->camsec].c_slope) - frontceiling = P_GetZAt(sectors[back->camsec].c_slope, camera.x, camera.y); + // SRB2CBTODO: ESLOPE (sectors[back->heightsec].f_slope) + backfloor = P_GetSectorFloorZAt (§ors[back->camsec], camera.x, camera.y); + backceiling = P_GetSectorCeilingZAt(§ors[back->camsec], camera.x, camera.y); } else if (back->heightsec >= 0) { - backfloor = sectors[back->heightsec].floorheight; - backceiling = sectors[back->heightsec].ceilingheight; - if (sectors[back->heightsec].f_slope) // SRB2CBTODO: ESLOPE (sectors[front->heightsec].f_slope) - frontfloor = P_GetZAt(sectors[back->heightsec].f_slope, camera.x, camera.y); - if (sectors[back->heightsec].c_slope) - frontceiling = P_GetZAt(sectors[back->heightsec].c_slope, camera.x, camera.y); + // SRB2CBTODO: ESLOPE (sectors[back->heightsec].f_slope) + backfloor = P_GetSectorFloorZAt (§ors[back->heightsec], camera.x, camera.y); + backceiling = P_GetSectorCeilingZAt(§ors[back->heightsec], camera.x, camera.y); } else { @@ -451,7 +439,6 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) I_Assert(back != NULL); openfloorrover = openceilingrover = NULL; -#ifdef POLYOBJECTS if (linedef->polyobj) { // set these defaults so that polyobjects don't interfere with collision above or below them @@ -462,7 +449,6 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) opentopslope = openbottomslope = NULL; } else -#endif { // Set open and high/low values here fixed_t frontheight, backheight; @@ -517,7 +503,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) texheight = textures[texnum]->height << FRACBITS; // Set texbottom and textop to the Z coordinates of the texture's boundaries -#if 0 // #ifdef POLYOBJECTS +#if 0 // don't remove this code unless solid midtextures // on non-solid polyobjects should NEVER happen in the future if (linedef->polyobj && (linedef->polyobj->flags & POF_TESTHEIGHT)) { @@ -560,7 +546,6 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) } } } -#ifdef POLYOBJECTS if (linedef->polyobj) { // Treat polyobj's backsector like a 3D Floor @@ -597,94 +582,95 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) // otherwise don't do anything special, pretend there's nothing else there } else -#endif - // Check for fake floors in the sector. - if (front->ffloors || back->ffloors) { - ffloor_t *rover; - fixed_t delta1, delta2; - - // Check for frontsector's fake floors - for (rover = front->ffloors; rover; rover = rover->next) + // Check for fake floors in the sector. + if (front->ffloors || back->ffloors) { - fixed_t topheight, bottomheight; - if (!(rover->flags & FF_EXISTS)) - continue; + ffloor_t *rover; + fixed_t delta1, delta2; - if (mobj->player && (P_CheckSolidLava(rover) || P_CanRunOnWater(mobj->player, rover))) - ; - else if (!((rover->flags & FF_BLOCKPLAYER && mobj->player) - || (rover->flags & FF_BLOCKOTHERS && !mobj->player))) - continue; - - topheight = P_GetFOFTopZ(mobj, front, rover, tmx, tmy, linedef); - bottomheight = P_GetFOFBottomZ(mobj, front, rover, tmx, tmy, linedef); - - delta1 = abs(mobj->z - (bottomheight + ((topheight - bottomheight)/2))); - delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2))); - - if (delta1 >= delta2 && (rover->flags & FF_INTANGIBLEFLATS) != FF_PLATFORM) // thing is below FOF + // Check for frontsector's fake floors + for (rover = front->ffloors; rover; rover = rover->next) { - if (bottomheight < opentop) { - opentop = bottomheight; - opentopslope = *rover->b_slope; - openceilingrover = rover; + fixed_t topheight, bottomheight; + if (!(rover->flags & FF_EXISTS)) + continue; + + if (mobj->player && (P_CheckSolidLava(rover) || P_CanRunOnWater(mobj->player, rover))) + ; + else if (!((rover->flags & FF_BLOCKPLAYER && mobj->player) + || (rover->flags & FF_BLOCKOTHERS && !mobj->player))) + continue; + + topheight = P_GetFOFTopZ(mobj, front, rover, tmx, tmy, linedef); + bottomheight = P_GetFOFBottomZ(mobj, front, rover, tmx, tmy, linedef); + + delta1 = abs(mobj->z - (bottomheight + ((topheight - bottomheight)/2))); + delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2))); + + if (delta1 >= delta2 && (rover->flags & FF_INTANGIBLEFLATS) != FF_PLATFORM) // thing is below FOF + { + if (bottomheight < opentop) { + opentop = bottomheight; + opentopslope = *rover->b_slope; + openceilingrover = rover; + } + else if (bottomheight < highceiling) + highceiling = bottomheight; + } + + if (delta1 < delta2 && (rover->flags & FF_INTANGIBLEFLATS) != FF_REVERSEPLATFORM) // thing is above FOF + { + if (topheight > openbottom) { + openbottom = topheight; + openbottomslope = *rover->t_slope; + openfloorrover = rover; + } + else if (topheight > lowfloor) + lowfloor = topheight; } - else if (bottomheight < highceiling) - highceiling = bottomheight; } - if (delta1 < delta2 && (rover->flags & FF_INTANGIBLEFLATS) != FF_REVERSEPLATFORM) // thing is above FOF + // Check for backsectors fake floors + for (rover = back->ffloors; rover; rover = rover->next) { - if (topheight > openbottom) { - openbottom = topheight; - openbottomslope = *rover->t_slope; - openfloorrover = rover; + fixed_t topheight, bottomheight; + if (!(rover->flags & FF_EXISTS)) + continue; + + if (mobj->player && (P_CheckSolidLava(rover) || P_CanRunOnWater(mobj->player, rover))) + ; + else if (!((rover->flags & FF_BLOCKPLAYER && mobj->player) + || (rover->flags & FF_BLOCKOTHERS && !mobj->player))) + continue; + + topheight = P_GetFOFTopZ(mobj, back, rover, tmx, tmy, linedef); + bottomheight = P_GetFOFBottomZ(mobj, back, rover, tmx, tmy, linedef); + + delta1 = abs(mobj->z - (bottomheight + ((topheight - bottomheight)/2))); + delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2))); + + if (delta1 >= delta2 && (rover->flags & FF_INTANGIBLEFLATS) != FF_PLATFORM) // thing is below FOF + { + if (bottomheight < opentop) { + opentop = bottomheight; + opentopslope = *rover->b_slope; + openceilingrover = rover; + } + else if (bottomheight < highceiling) + highceiling = bottomheight; } - else if (topheight > lowfloor) - lowfloor = topheight; - } - } - // Check for backsectors fake floors - for (rover = back->ffloors; rover; rover = rover->next) - { - fixed_t topheight, bottomheight; - if (!(rover->flags & FF_EXISTS)) - continue; - - if (mobj->player && (P_CheckSolidLava(rover) || P_CanRunOnWater(mobj->player, rover))) - ; - else if (!((rover->flags & FF_BLOCKPLAYER && mobj->player) - || (rover->flags & FF_BLOCKOTHERS && !mobj->player))) - continue; - - topheight = P_GetFOFTopZ(mobj, back, rover, tmx, tmy, linedef); - bottomheight = P_GetFOFBottomZ(mobj, back, rover, tmx, tmy, linedef); - - delta1 = abs(mobj->z - (bottomheight + ((topheight - bottomheight)/2))); - delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2))); - - if (delta1 >= delta2 && (rover->flags & FF_INTANGIBLEFLATS) != FF_PLATFORM) // thing is below FOF - { - if (bottomheight < opentop) { - opentop = bottomheight; - opentopslope = *rover->b_slope; - openceilingrover = rover; + if (delta1 < delta2 && (rover->flags & FF_INTANGIBLEFLATS) != FF_REVERSEPLATFORM) // thing is above FOF + { + if (topheight > openbottom) { + openbottom = topheight; + openbottomslope = *rover->t_slope; + openfloorrover = rover; + } + else if (topheight > lowfloor) + lowfloor = topheight; } - else if (bottomheight < highceiling) - highceiling = bottomheight; - } - - if (delta1 < delta2 && (rover->flags & FF_INTANGIBLEFLATS) != FF_REVERSEPLATFORM) // thing is above FOF - { - if (topheight > openbottom) { - openbottom = topheight; - openbottomslope = *rover->t_slope; - openfloorrover = rover; - } - else if (topheight > lowfloor) - lowfloor = topheight; } } } @@ -934,9 +920,7 @@ boolean P_BlockLinesIterator(INT32 x, INT32 y, boolean (*func)(line_t *)) { INT32 offset; const INT32 *list; // Big blockmap -#ifdef POLYOBJECTS polymaplink_t *plink; // haleyjd 02/22/06 -#endif line_t *ld; if (x < 0 || y < 0 || x >= bmapwidth || y >= bmapheight) @@ -944,7 +928,6 @@ boolean P_BlockLinesIterator(INT32 x, INT32 y, boolean (*func)(line_t *)) offset = y*bmapwidth + x; -#ifdef POLYOBJECTS // haleyjd 02/22/06: consider polyobject lines plink = polyblocklinks[offset]; @@ -968,7 +951,6 @@ boolean P_BlockLinesIterator(INT32 x, INT32 y, boolean (*func)(line_t *)) } plink = (polymaplink_t *)(plink->link.next); } -#endif offset = *(blockmap + offset); // offset = blockmap[y*bmapwidth+x]; diff --git a/src/p_mobj.c b/src/p_mobj.c index 45a6ffe5b..0f77b77ef 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -436,7 +436,7 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state) mobj->sprite2 = spr2; 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; } // Regular sprites @@ -926,13 +926,8 @@ boolean P_InsideANonSolidFFloor(mobj_t *mobj, ffloor_t *rover) || ((rover->flags & FF_BLOCKOTHERS) && !mobj->player))) return false; - topheight = *rover->topheight; - bottomheight = *rover->bottomheight; - - if (*rover->t_slope) - topheight = P_GetZAt(*rover->t_slope, mobj->x, mobj->y); - if (*rover->b_slope) - bottomheight = P_GetZAt(*rover->b_slope, mobj->x, mobj->y); + topheight = P_GetFFloorTopZAt (rover, mobj->x, mobj->y); + bottomheight = P_GetFFloorBottomZAt(rover, mobj->x, mobj->y); if (mobj->z > topheight) return false; @@ -963,12 +958,12 @@ static fixed_t HighestOnLine(fixed_t radius, fixed_t x, fixed_t y, line_t *line, /*CONS_Printf("BEFORE: v1 = %f %f %f\n", FIXED_TO_FLOAT(v1.x), FIXED_TO_FLOAT(v1.y), - FIXED_TO_FLOAT(P_GetZAt(slope, v1.x, v1.y)) + FIXED_TO_FLOAT(P_GetSlopeZAt(slope, v1.x, v1.y)) ); CONS_Printf(" v2 = %f %f %f\n", FIXED_TO_FLOAT(v2.x), FIXED_TO_FLOAT(v2.y), - FIXED_TO_FLOAT(P_GetZAt(slope, v2.x, v2.y)) + FIXED_TO_FLOAT(P_GetSlopeZAt(slope, v2.x, v2.y)) );*/ if (abs(v1.x-x) > radius) { @@ -1026,24 +1021,24 @@ static fixed_t HighestOnLine(fixed_t radius, fixed_t x, fixed_t y, line_t *line, /*CONS_Printf("AFTER: v1 = %f %f %f\n", FIXED_TO_FLOAT(v1.x), FIXED_TO_FLOAT(v1.y), - FIXED_TO_FLOAT(P_GetZAt(slope, v1.x, v1.y)) + FIXED_TO_FLOAT(P_GetSlopeZAt(slope, v1.x, v1.y)) ); CONS_Printf(" v2 = %f %f %f\n", FIXED_TO_FLOAT(v2.x), FIXED_TO_FLOAT(v2.y), - FIXED_TO_FLOAT(P_GetZAt(slope, v2.x, v2.y)) + FIXED_TO_FLOAT(P_GetSlopeZAt(slope, v2.x, v2.y)) );*/ // Return the higher of the two points if (actuallylowest) return min( - P_GetZAt(slope, v1.x, v1.y), - P_GetZAt(slope, v2.x, v2.y) + P_GetSlopeZAt(slope, v1.x, v1.y), + P_GetSlopeZAt(slope, v2.x, v2.y) ); else return max( - P_GetZAt(slope, v1.x, v1.y), - P_GetZAt(slope, v2.x, v2.y) + P_GetSlopeZAt(slope, v1.x, v1.y), + P_GetSlopeZAt(slope, v2.x, v2.y) ); } @@ -1077,7 +1072,7 @@ fixed_t P_MobjFloorZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t // If the highest point is in the sector, then we have it easy! Just get the Z at that point if (R_PointInSubsector(testx, testy)->sector == (boundsec ? boundsec : sector)) - return P_GetZAt(slope, testx, testy); + return P_GetSlopeZAt(slope, testx, testy); // If boundsec is set, we're looking for specials. In that case, iterate over every line in this sector to find the TRUE highest/lowest point if (perfect) { @@ -1117,7 +1112,7 @@ fixed_t P_MobjFloorZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t // If we're just testing for base sector location (no collision line), just go for the center's spot... // It'll get fixed when we test for collision anyway, and the final result can't be lower than this if (line == NULL) - return P_GetZAt(slope, x, y); + return P_GetSlopeZAt(slope, x, y); return HighestOnLine(mobj->radius, x, y, line, slope, lowest); } else // Well, that makes it easy. Just get the floor height @@ -1154,7 +1149,7 @@ fixed_t P_MobjCeilingZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed // If the highest point is in the sector, then we have it easy! Just get the Z at that point if (R_PointInSubsector(testx, testy)->sector == (boundsec ? boundsec : sector)) - return P_GetZAt(slope, testx, testy); + return P_GetSlopeZAt(slope, testx, testy); // If boundsec is set, we're looking for specials. In that case, iterate over every line in this sector to find the TRUE highest/lowest point if (perfect) { @@ -1194,7 +1189,7 @@ fixed_t P_MobjCeilingZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed // If we're just testing for base sector location (no collision line), just go for the center's spot... // It'll get fixed when we test for collision anyway, and the final result can't be lower than this if (line == NULL) - return P_GetZAt(slope, x, y); + return P_GetSlopeZAt(slope, x, y); return HighestOnLine(mobj->radius, x, y, line, slope, lowest); } else // Well, that makes it easy. Just get the ceiling height @@ -1232,7 +1227,7 @@ fixed_t P_CameraFloorZ(camera_t *mobj, sector_t *sector, sector_t *boundsec, fix // If the highest point is in the sector, then we have it easy! Just get the Z at that point if (R_PointInSubsector(testx, testy)->sector == (boundsec ? boundsec : sector)) - return P_GetZAt(slope, testx, testy); + return P_GetSlopeZAt(slope, testx, testy); // If boundsec is set, we're looking for specials. In that case, iterate over every line in this sector to find the TRUE highest/lowest point if (perfect) { @@ -1272,7 +1267,7 @@ fixed_t P_CameraFloorZ(camera_t *mobj, sector_t *sector, sector_t *boundsec, fix // If we're just testing for base sector location (no collision line), just go for the center's spot... // It'll get fixed when we test for collision anyway, and the final result can't be lower than this if (line == NULL) - return P_GetZAt(slope, x, y); + return P_GetSlopeZAt(slope, x, y); return HighestOnLine(mobj->radius, x, y, line, slope, lowest); } else // Well, that makes it easy. Just get the floor height @@ -1309,7 +1304,7 @@ fixed_t P_CameraCeilingZ(camera_t *mobj, sector_t *sector, sector_t *boundsec, f // If the highest point is in the sector, then we have it easy! Just get the Z at that point if (R_PointInSubsector(testx, testy)->sector == (boundsec ? boundsec : sector)) - return P_GetZAt(slope, testx, testy); + return P_GetSlopeZAt(slope, testx, testy); // If boundsec is set, we're looking for specials. In that case, iterate over every line in this sector to find the TRUE highest/lowest point if (perfect) { @@ -1349,7 +1344,7 @@ fixed_t P_CameraCeilingZ(camera_t *mobj, sector_t *sector, sector_t *boundsec, f // If we're just testing for base sector location (no collision line), just go for the center's spot... // It'll get fixed when we test for collision anyway, and the final result can't be lower than this if (line == NULL) - return P_GetZAt(slope, x, y); + return P_GetSlopeZAt(slope, x, y); return HighestOnLine(mobj->radius, x, y, line, slope, lowest); } else // Well, that makes it easy. Just get the ceiling height @@ -2895,7 +2890,6 @@ static void P_PlayerZMovement(mobj_t *mo) mo->eflags |= MFE_JUSTHITFLOOR; // Spin Attack { -#ifdef POLYOBJECTS // Check if we're on a polyobject // that triggers a linedef executor. msecnode_t *node; @@ -2955,8 +2949,6 @@ static void P_PlayerZMovement(mobj_t *mo) } if (!stopmovecut) -#endif - // Cut momentum in half when you hit the ground and // aren't pressing any controls. if (!(mo->player->cmd.forwardmove || mo->player->cmd.sidemove) && !mo->player->cmomx && !mo->player->cmomy && !(mo->player->pflags & PF_SPINNING)) @@ -3213,9 +3205,7 @@ static boolean P_SceneryZMovement(mobj_t *mo) // boolean P_CanRunOnWater(player_t *player, ffloor_t *rover) { - fixed_t topheight = *rover->t_slope ? - P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y) : - *rover->topheight; + fixed_t topheight = P_GetFFloorTopZAt(rover, player->mo->x, player->mo->y); if (!player->powers[pw_carry] && !player->homing && ((player->powers[pw_super] || player->charflags & SF_RUNONWATER || player->dashmode >= DASHMODE_THRESHOLD) && player->mo->ceilingz-topheight >= player->mo->height) @@ -3258,14 +3248,8 @@ void P_MobjCheckWater(mobj_t *mobj) || ((rover->flags & FF_BLOCKOTHERS) && !mobj->player))) continue; - topheight = *rover->topheight; - bottomheight = *rover->bottomheight; - - if (*rover->t_slope) - topheight = P_GetZAt(*rover->t_slope, mobj->x, mobj->y); - - if (*rover->b_slope) - bottomheight = P_GetZAt(*rover->b_slope, mobj->x, mobj->y); + topheight = P_GetFFloorTopZAt (rover, mobj->x, mobj->y); + bottomheight = P_GetFFloorBottomZAt(rover, mobj->x, mobj->y); if (mobj->eflags & MFE_VERTICALFLIP) { @@ -3512,14 +3496,8 @@ static void P_SceneryCheckWater(mobj_t *mobj) if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_SWIMMABLE) || rover->flags & FF_BLOCKOTHERS) continue; - topheight = *rover->topheight; - bottomheight = *rover->bottomheight; - - if (*rover->t_slope) - topheight = P_GetZAt(*rover->t_slope, mobj->x, mobj->y); - - if (*rover->b_slope) - bottomheight = P_GetZAt(*rover->b_slope, mobj->x, mobj->y); + topheight = P_GetFFloorTopZAt (rover, mobj->x, mobj->y); + bottomheight = P_GetFFloorBottomZAt(rover, mobj->x, mobj->y); if (topheight <= mobj->z || bottomheight > (mobj->z + (mobj->height>>1))) @@ -3564,13 +3542,9 @@ static boolean P_CameraCheckHeat(camera_t *thiscam) if (!(rover->flags & FF_EXISTS)) continue; - if (halfheight >= (*rover->t_slope ? - P_GetZAt(*rover->t_slope, thiscam->x, thiscam->y) : - *rover->topheight)) + if (halfheight >= P_GetFFloorTopZAt(rover, thiscam->x, thiscam->y)) continue; - if (halfheight <= (*rover->b_slope ? - P_GetZAt(*rover->b_slope, thiscam->x, thiscam->y) : - *rover->bottomheight)) + if (halfheight <= P_GetFFloorBottomZAt(rover, thiscam->x, thiscam->y)) continue; if (P_FindSpecialLineFromTag(13, rover->master->frontsector->tag, -1) != -1) @@ -3598,13 +3572,9 @@ static boolean P_CameraCheckWater(camera_t *thiscam) if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_SWIMMABLE) || rover->flags & FF_BLOCKOTHERS) continue; - if (halfheight >= (*rover->t_slope ? - P_GetZAt(*rover->t_slope, thiscam->x, thiscam->y) : - *rover->topheight)) + if (halfheight >= P_GetFFloorTopZAt(rover, thiscam->x, thiscam->y)) continue; - if (halfheight <= ( - *rover->b_slope ? P_GetZAt(*rover->b_slope, thiscam->x, thiscam->y) : - *rover->bottomheight)) + if (halfheight <= P_GetFFloorBottomZAt(rover, thiscam->x, thiscam->y)) continue; return true; @@ -3952,9 +3922,7 @@ static void CalculatePrecipFloor(precipmobj_t *mobj) mobjsecsubsec = mobj->subsector->sector; else return; - mobj->floorz = mobjsecsubsec->f_slope ? - P_GetZAt(mobjsecsubsec->f_slope, mobj->x, mobj->y) : - mobjsecsubsec->floorheight; + mobj->floorz = P_GetSectorFloorZAt(mobjsecsubsec, mobj->x, mobj->y); if (mobjsecsubsec->ffloors) { ffloor_t *rover; @@ -3969,11 +3937,7 @@ static void CalculatePrecipFloor(precipmobj_t *mobj) if (!(rover->flags & FF_BLOCKOTHERS) && !(rover->flags & FF_SWIMMABLE)) continue; - if (*rover->t_slope) - topheight = P_GetZAt(*rover->t_slope, mobj->x, mobj->y); - else - topheight = *rover->topheight; - + topheight = P_GetFFloorTopZAt(rover, mobj->x, mobj->y); if (topheight > mobj->floorz) mobj->floorz = topheight; } @@ -7059,8 +7023,7 @@ static void P_MobjScaleThink(mobj_t *mobj) fixed_t oldheight = mobj->height; UINT8 correctionType = 0; // Don't correct Z position, just gain height - if ((mobj->flags & MF_NOCLIPHEIGHT || (mobj->z > mobj->floorz && mobj->z + mobj->height < mobj->ceilingz)) - && mobj->type != MT_EGGMOBILE_FIRE) + if (mobj->flags & MF_NOCLIPHEIGHT || (mobj->z > mobj->floorz && mobj->z + mobj->height < mobj->ceilingz)) correctionType = 1; // Correct Z position by centering else if (mobj->eflags & MFE_VERTICALFLIP) correctionType = 2; // Correct Z position by moving down @@ -7081,10 +7044,6 @@ static void P_MobjScaleThink(mobj_t *mobj) /// \todo Lua hook for "reached destscale"? switch (mobj->type) { - case MT_EGGMOBILE_FIRE: - mobj->destscale = FRACUNIT; - mobj->scalespeed = FRACUNIT>>4; - break; default: break; } @@ -8260,6 +8219,7 @@ static boolean P_MobjDeadThink(mobj_t *mobj) // See Linedef Exec 457 (Track mobj angle to point) static void P_TracerAngleThink(mobj_t *mobj) { + angle_t looking; angle_t ang; if (!mobj->tracer) @@ -8274,7 +8234,12 @@ static void P_TracerAngleThink(mobj_t *mobj) // mobj->cvval - Allowable failure delay // mobj->cvmem - Failure timer - ang = mobj->angle - R_PointToAngle2(mobj->x, mobj->y, mobj->tracer->x, mobj->tracer->y); + if (mobj->player) + looking = ( mobj->player->cmd.angleturn << 16 );/* fixes CS_LMAOGALOG */ + else + looking = mobj->angle; + + ang = looking - R_PointToAngle2(mobj->x, mobj->y, mobj->tracer->x, mobj->tracer->y); // \todo account for distance between mobj and tracer // Because closer mobjs can be facing beyond the angle tolerance @@ -9464,7 +9429,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) case MT_BOSSFLYPOINT: return false; case MT_NIGHTSCORE: - mobj->color = (UINT8)(leveltime % SKINCOLOR_WHITE); + mobj->color = (UINT16)(leveltime % SKINCOLOR_WHITE); break; case MT_JETFUME1: if (!P_JetFume1Think(mobj)) @@ -10499,12 +10464,8 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) // Make sure scale matches destscale immediately when spawned P_SetScale(mobj, mobj->destscale); - mobj->floorz = mobj->subsector->sector->f_slope ? - P_GetZAt(mobj->subsector->sector->f_slope, x, y) : - mobj->subsector->sector->floorheight; - mobj->ceilingz = mobj->subsector->sector->c_slope ? - P_GetZAt(mobj->subsector->sector->c_slope, x, y) : - mobj->subsector->sector->ceilingheight; + mobj->floorz = P_GetSectorFloorZAt (mobj->subsector->sector, x, y); + mobj->ceilingz = P_GetSectorCeilingZAt(mobj->subsector->sector, x, y); mobj->floorrover = NULL; mobj->ceilingrover = NULL; @@ -10675,7 +10636,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) break; case MT_EGGROBO1: mobj->movecount = P_RandomKey(13); - mobj->color = SKINCOLOR_RUBY + P_RandomKey(MAXSKINCOLORS - SKINCOLOR_RUBY); + mobj->color = SKINCOLOR_RUBY + P_RandomKey(numskincolors - SKINCOLOR_RUBY); break; case MT_HIVEELEMENTAL: mobj->extravalue1 = 5; @@ -10857,12 +10818,8 @@ static precipmobj_t *P_SpawnPrecipMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype // set subsector and/or block links P_SetPrecipitationThingPosition(mobj); - mobj->floorz = starting_floorz = mobj->subsector->sector->f_slope ? - P_GetZAt(mobj->subsector->sector->f_slope, x, y) : - mobj->subsector->sector->floorheight; - mobj->ceilingz = mobj->subsector->sector->c_slope ? - P_GetZAt(mobj->subsector->sector->c_slope, x, y) : - mobj->subsector->sector->ceilingheight; + mobj->floorz = starting_floorz = P_GetSectorFloorZAt (mobj->subsector->sector, x, y); + mobj->ceilingz = P_GetSectorCeilingZAt(mobj->subsector->sector, x, y); mobj->floorrover = NULL; mobj->ceilingrover = NULL; @@ -11505,12 +11462,8 @@ void P_MovePlayerToSpawn(INT32 playernum, mapthing_t *mthing) // set Z height sector = R_PointInSubsector(x, y)->sector; - floor = sector->f_slope ? - P_GetZAt(sector->f_slope, x, y) : - sector->floorheight; - ceiling = sector->c_slope ? - P_GetZAt(sector->c_slope, x, y) : - sector->ceilingheight; + floor = P_GetSectorFloorZAt (sector, x, y); + ceiling = P_GetSectorCeilingZAt(sector, x, y); ceilingspawn = ceiling - mobjinfo[MT_PLAYER].height; if (mthing) @@ -11580,12 +11533,8 @@ void P_MovePlayerToStarpost(INT32 playernum) P_SetThingPosition(mobj); sector = R_PointInSubsector(mobj->x, mobj->y)->sector; - floor = sector->f_slope ? - P_GetZAt(sector->f_slope, mobj->x, mobj->y) : - sector->floorheight; - ceiling = sector->c_slope ? - P_GetZAt(sector->c_slope, mobj->x, mobj->y) : - sector->ceilingheight; + floor = P_GetSectorFloorZAt (sector, mobj->x, mobj->y); + ceiling = P_GetSectorCeilingZAt(sector, mobj->x, mobj->y); z = p->starpostz << FRACBITS; @@ -11634,11 +11583,9 @@ fixed_t P_GetMobjSpawnHeight(const mobjtype_t mobjtype, const fixed_t x, const f // Establish height. if (flip) - return (ss->sector->c_slope ? P_GetZAt(ss->sector->c_slope, x, y) : ss->sector->ceilingheight) - - offset - mobjinfo[mobjtype].height; + return P_GetSectorCeilingZAt(ss->sector, x, y) - offset - mobjinfo[mobjtype].height; else - return (ss->sector->f_slope ? P_GetZAt(ss->sector->f_slope, x, y) : ss->sector->floorheight) - + offset; + return P_GetSectorFloorZAt(ss->sector, x, y) + offset; } fixed_t P_GetMapThingSpawnHeight(const mobjtype_t mobjtype, const mapthing_t* mthing, const fixed_t x, const fixed_t y) @@ -11977,7 +11924,7 @@ static boolean P_SetupEmblem(mapthing_t *mthing, mobj_t *mobj) { INT32 j; emblem_t* emblem = M_GetLevelEmblems(gamemap); - skincolors_t emcolor; + skincolornum_t emcolor; while (emblem) { @@ -12000,7 +11947,7 @@ static boolean P_SetupEmblem(mapthing_t *mthing, mobj_t *mobj) mobj->health = j + 1; 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 || (emblemlocations[j].type == ET_SKIN && emblemlocations[j].var != players[0].skin)) @@ -12639,7 +12586,7 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean break; case MT_BALLOON: if (mthing->angle > 0) - mobj->color = ((mthing->angle - 1) % (MAXSKINCOLORS - 1)) + 1; + mobj->color = ((mthing->angle - 1) % (numskincolors - 1)) + 1; break; #define makesoftwarecorona(mo, h) \ corona = P_SpawnMobjFromMobj(mo, 0, 0, h<threshold = min(mthing->extrainfo, 7); break; case MT_TUBEWAYPOINT: - mobj->health = mthing->angle & 255; - mobj->threshold = mthing->angle >> 8; + { + UINT8 sequence = mthing->angle >> 8; + UINT8 id = mthing->angle & 255; + mobj->health = id; + mobj->threshold = sequence; + P_AddWaypoint(sequence, id, mobj); break; + } case MT_IDEYAANCHOR: mobj->health = mthing->extrainfo; break; diff --git a/src/p_mobj.h b/src/p_mobj.h index eda7383df..dae8c8a86 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -312,7 +312,7 @@ typedef struct mobj_s void *skin; // overrides 'sprite' when non-NULL (for player bodies to 'remember' the skin) // Player and mobj sprites in multiplayer modes are modified // 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. // Links in blocks (if needed). diff --git a/src/p_polyobj.c b/src/p_polyobj.c index 7e1ff1f49..3b6195285 100644 --- a/src/p_polyobj.c +++ b/src/p_polyobj.c @@ -28,12 +28,6 @@ #include "r_state.h" #include "r_defs.h" - -#define POLYOBJECTS - - -#ifdef POLYOBJECTS - /* Theory behind Polyobjects: @@ -146,11 +140,6 @@ FUNCINLINE static ATTRINLINE void Polyobj_vecSub2(vertex_t *dst, vertex_t *v1, v dst->y = v1->y - v2->y; } -// -// P_PointInsidePolyobj -// -// Returns TRUE if the XY point is inside the polyobject -// boolean P_PointInsidePolyobj(polyobj_t *po, fixed_t x, fixed_t y) { size_t i; @@ -164,11 +153,6 @@ boolean P_PointInsidePolyobj(polyobj_t *po, fixed_t x, fixed_t y) return true; } -// -// P_MobjTouchingPolyobj -// -// Returns TRUE if the mobj is touching the edge of a polyobject -// boolean P_MobjTouchingPolyobj(polyobj_t *po, mobj_t *mo) { fixed_t mbbox[4]; @@ -188,11 +172,6 @@ boolean P_MobjTouchingPolyobj(polyobj_t *po, mobj_t *mo) return false; } -// -// P_MobjInsidePolyobj -// -// Returns TRUE if the mobj is inside the polyobject -// boolean P_MobjInsidePolyobj(polyobj_t *po, mobj_t *mo) { fixed_t mbbox[4]; @@ -212,11 +191,6 @@ boolean P_MobjInsidePolyobj(polyobj_t *po, mobj_t *mo) return true; } -// -// P_BBoxInsidePolyobj -// -// Returns TRUE if the bbox is inside the polyobject -// boolean P_BBoxInsidePolyobj(polyobj_t *po, fixed_t *bbox) { size_t i; @@ -230,55 +204,53 @@ boolean P_BBoxInsidePolyobj(polyobj_t *po, fixed_t *bbox) return true; } -// -// Polyobj_GetInfo -// // Finds the 'polyobject settings' linedef for a polyobject // the polyobject's id should be set as its tag -// -void Polyobj_GetInfo(INT16 poid, INT32 *poflags, INT32 *parentID, INT32 *potrans) +static void Polyobj_GetInfo(polyobj_t *po) { - INT32 i = P_FindSpecialLineFromTag(POLYINFO_SPECIALNUM, poid, -1); + INT32 i = P_FindSpecialLineFromTag(POLYINFO_SPECIALNUM, po->id, -1); + + po->flags = POF_SOLID|POF_TESTHEIGHT|POF_RENDERSIDES; if (i == -1) return; // no extra settings to apply, let's leave it - if (parentID) - *parentID = lines[i].frontsector->special; + po->parent = lines[i].frontsector->special; + if (po->parent == po->id) // do not allow a self-reference + po->parent = -1; - if (potrans) - *potrans = (lines[i].frontsector->floorheight>>FRACBITS) / 100; + po->translucency = (lines[i].flags & ML_DONTPEGTOP) + ? (sides[lines[i].sidenum[0]].textureoffset>>FRACBITS) + : ((lines[i].frontsector->floorheight>>FRACBITS) / 100); + + po->translucency = max(min(po->translucency, NUMTRANSMAPS), 0); if (lines[i].flags & ML_EFFECT1) - *poflags |= POF_ONESIDE; + po->flags |= POF_ONESIDE; if (lines[i].flags & ML_EFFECT2) - *poflags &= ~POF_SOLID; + po->flags &= ~POF_SOLID; if (lines[i].flags & ML_EFFECT3) - *poflags |= POF_PUSHABLESTOP; + po->flags |= POF_PUSHABLESTOP; if (lines[i].flags & ML_EFFECT4) - *poflags |= POF_RENDERPLANES; + po->flags |= POF_RENDERPLANES; /*if (lines[i].flags & ML_EFFECT5) - *poflags &= ~POF_CLIPPLANES;*/ + po->flags &= ~POF_CLIPPLANES;*/ if (lines[i].flags & ML_NOCLIMB) // Has a linedef executor - *poflags |= POF_LDEXEC; + po->flags |= POF_LDEXEC; } // Reallocating array maintenance -// -// Polyobj_addVertex -// // Adds a vertex to a polyobject's reallocating vertex arrays, provided // that such a vertex isn't already in the array. Each vertex must only // be translated once during polyobject movement. Keeping track of them // this way results in much more clear and efficient code than what // Hexen used. -// static void Polyobj_addVertex(polyobj_t *po, vertex_t *v) { size_t i; @@ -314,14 +286,10 @@ static void Polyobj_addVertex(polyobj_t *po, vertex_t *v) po->numVertices++; } -// -// Polyobj_addLine -// // Adds a linedef to a polyobject's reallocating linedefs array, provided // that such a linedef isn't already in the array. Each linedef must only // be adjusted once during polyobject movement. Keeping track of them // this way provides the same benefits as for vertices. -// static void Polyobj_addLine(polyobj_t *po, line_t *l) { size_t i; @@ -346,14 +314,10 @@ static void Polyobj_addLine(polyobj_t *po, line_t *l) po->lines[po->numLines++] = l; } -// -// Polyobj_addSeg -// // Adds a single seg to a polyobject's reallocating seg pointer array. // Most polyobjects will have between 4 and 16 segs, so the array size // begins much smaller than usual. Calls Polyobj_addVertex and Polyobj_addLine // to add those respective structures for this seg, as well. -// static void Polyobj_addSeg(polyobj_t *po, seg_t *seg) { if (po->segCount >= po->numSegsAlloc) @@ -379,14 +343,10 @@ static void Polyobj_addSeg(polyobj_t *po, seg_t *seg) // Seg-finding functions -// -// Polyobj_findSegs -// // This method adds segs to a polyobject by following segs from vertex to // vertex. The process stops when the original starting point is reached // or if a particular search ends unexpectedly (ie, the polyobject is not // closed). -// static void Polyobj_findSegs(polyobj_t *po, seg_t *seg) { fixed_t startx, starty; @@ -400,25 +360,29 @@ static void Polyobj_findSegs(polyobj_t *po, seg_t *seg) // Find backfacings for (s = 0; s < numsegs; s++) { + size_t r; + if (segs[s].glseg) continue; - if (segs[s].linedef == seg->linedef - && segs[s].side == 1) + + if (segs[s].linedef != seg->linedef) + continue; + + if (segs[s].side != 1) + continue; + + for (r = 0; r < po->segCount; r++) { - size_t r; - for (r = 0; r < po->segCount; r++) - { - if (po->segs[r] == &segs[s]) - break; - } - - if (r != po->segCount) - continue; - - segs[s].dontrenderme = true; - - Polyobj_addSeg(po, &segs[s]); + if (po->segs[r] == &segs[s]) + break; } + + if (r != po->segCount) + continue; + + segs[s].dontrenderme = true; + + Polyobj_addSeg(po, &segs[s]); } } @@ -438,56 +402,60 @@ newseg: // seg's ending vertex. for (i = 0; i < numsegs; ++i) { + size_t q; + if (segs[i].glseg) continue; if (segs[i].side != 0) // needs to be frontfacing continue; - if (segs[i].v1->x == seg->v2->x && segs[i].v1->y == seg->v2->y) + if (segs[i].v1->x != seg->v2->x) + continue; + if (segs[i].v1->y != seg->v2->y) + continue; + + // Make sure you didn't already add this seg... + for (q = 0; q < po->segCount; q++) { - // Make sure you didn't already add this seg... - size_t q; - for (q = 0; q < po->segCount; q++) - { - if (po->segs[q] == &segs[i]) - break; - } - - if (q != po->segCount) - continue; - - // add the new seg and recurse - Polyobj_addSeg(po, &segs[i]); - seg = &segs[i]; - - if (!(po->flags & POF_ONESIDE)) - { - // Find backfacings - for (q = 0; q < numsegs; q++) - { - if (segs[q].glseg) - continue; - - if (segs[q].linedef == segs[i].linedef - && segs[q].side == 1) - { - size_t r; - for (r=0; r < po->segCount; r++) - { - if (po->segs[r] == &segs[q]) - break; - } - - if (r != po->segCount) - continue; - - segs[q].dontrenderme = true; - Polyobj_addSeg(po, &segs[q]); - } - } - } - - goto newseg; + if (po->segs[q] == &segs[i]) + break; } + + if (q != po->segCount) + continue; + + // add the new seg and recurse + Polyobj_addSeg(po, &segs[i]); + seg = &segs[i]; + + if (!(po->flags & POF_ONESIDE)) + { + // Find backfacings + for (q = 0; q < numsegs; q++) + { + size_t r; + + if (segs[q].glseg) + continue; + if (segs[q].linedef != segs[i].linedef) + continue; + if (segs[q].side != 1) + continue; + + for (r = 0; r < po->segCount; r++) + { + if (po->segs[r] == &segs[q]) + break; + } + + if (r != po->segCount) + continue; + + segs[q].dontrenderme = true; + Polyobj_addSeg(po, &segs[q]); + } + } + + goto newseg; } // error: if we reach here, the seg search never found another seg to @@ -496,91 +464,8 @@ newseg: CONS_Debug(DBG_POLYOBJ, "Polyobject %d is not closed\n", po->id); } -/* -// structure used to store segs during explicit search process -typedef struct segitem_s -{ - seg_t *seg; - INT32 num; -} segitem_t; - -// -// Polyobj_segCompare -// -// Callback for qsort that compares two segitems. -// -static int Polyobj_segCompare(const void *s1, const void *s2) -{ - const segitem_t *si1 = s1; - const segitem_t *si2 = s2; - - return si2->num - si1->num; -} - -// -// Polyobj_findExplicit -// -// Searches for segs to put into a polyobject in an explicitly provided order. -// -static void Polyobj_findExplicit(polyobj_t *po) -{ - // temporary dynamic seg array - segitem_t *segitems = NULL; - size_t numSegItems = 0; - size_t numSegItemsAlloc = 0; - - size_t i; - - // first loop: save off all segs with polyobject's id number - for (i = 0; i < numsegs; ++i) - { - INT32 polyID, parentID; - - if (segs[i].linedef->special != POLYOBJ_EXPLICIT_LINE) - continue; - - Polyobj_GetInfo(segs[i].linedef->tag, &polyID, &parentID, NULL); - - if (polyID == po->id && parentID > 0) - { - if (numSegItems >= numSegItemsAlloc) - { - numSegItemsAlloc = numSegItemsAlloc ? numSegItemsAlloc*2 : 4; - segitems = Z_Realloc(segitems, numSegItemsAlloc*sizeof(segitem_t), PU_STATIC, NULL); - } - segitems[numSegItems].seg = &segs[i]; - segitems[numSegItems].num = parentID; - ++numSegItems; - } - } - - // make sure array isn't empty - if (numSegItems == 0) - { - po->isBad = true; - CONS_Debug(DBG_POLYOBJ, "Polyobject %d is empty\n", po->id); - return; - } - - // sort the array if necessary - if (numSegItems >= 2) - qsort(segitems, numSegItems, sizeof(segitem_t), Polyobj_segCompare); - - // second loop: put the sorted segs into the polyobject - for (i = 0; i < numSegItems; ++i) - Polyobj_addSeg(po, segitems[i].seg); - - // free the temporary array - Z_Free(segitems); -}*/ - // Setup functions -// -// Polyobj_spawnPolyObj -// -// Sets up a Polyobject. -// static void Polyobj_spawnPolyObj(INT32 num, mobj_t *spawnSpot, INT32 id) { size_t i; @@ -604,14 +489,12 @@ static void Polyobj_spawnPolyObj(INT32 num, mobj_t *spawnSpot, INT32 id) po->thrust = FRACUNIT; po->spawnflags = po->flags = 0; - // 1. Search segs for "line start" special with tag matching this - // polyobject's id number. If found, iterate through segs which - // share common vertices and record them into the polyobject. + // Search segs for "line start" special with tag matching this + // polyobject's id number. If found, iterate through segs which + // share common vertices and record them into the polyobject. for (i = 0; i < numsegs; ++i) { seg_t *seg = &segs[i]; - INT32 poflags = POF_SOLID|POF_TESTHEIGHT|POF_RENDERSIDES; - INT32 parentID = 0, potrans = 0; if (seg->glseg) continue; @@ -625,17 +508,13 @@ static void Polyobj_spawnPolyObj(INT32 num, mobj_t *spawnSpot, INT32 id) if (seg->linedef->tag != po->id) continue; - Polyobj_GetInfo(po->id, &poflags, &parentID, &potrans); // apply extra settings if they exist! + Polyobj_GetInfo(po); // apply extra settings if they exist! // save original flags and translucency to reference later for netgames! - po->spawnflags = po->flags = poflags; - po->spawntrans = po->translucency = potrans; + po->spawnflags = po->flags; + po->spawntrans = po->translucency; Polyobj_findSegs(po, seg); - po->parent = parentID; - if (po->parent == po->id) // do not allow a self-reference - po->parent = -1; - // TODO: sound sequence is in args[2] break; } @@ -645,29 +524,7 @@ static void Polyobj_spawnPolyObj(INT32 num, mobj_t *spawnSpot, INT32 id) if (po->isBad) return; - /* - // 2. If no such line existed in the first step, look for a seg with the - // "explicit" special with tag matching this polyobject's id number. If - // found, continue to search for all such lines, storing them in a - // temporary list of segs which is then copied into the polyobject in - // sorted order. - if (po->segCount == 0) - { - UINT16 parent; - Polyobj_findExplicit(po); - // if an error occurred above, quit processing this object - if (po->isBad) - return; - - Polyobj_GetInfo(po->segs[0]->linedef->tag, NULL, NULL, &parent); - po->parent = parent; - if (po->parent == po->id) // do not allow a self-reference - po->parent = -1; - // TODO: sound sequence is in args[3] - }*/ - // make sure array isn't empty - // since Polyobj_findExplicit is disabled currently, we have to do things here instead now! if (po->segCount == 0) { po->isBad = true; @@ -696,12 +553,8 @@ static void Polyobj_spawnPolyObj(INT32 num, mobj_t *spawnSpot, INT32 id) static void Polyobj_attachToSubsec(polyobj_t *po); -// -// Polyobj_moveToSpawnSpot -// // Translates the polyobject's vertices with respect to the difference between // the anchor and spawn spots. Updates linedef bounding boxes as well. -// static void Polyobj_moveToSpawnSpot(mapthing_t *anchor) { polyobj_t *po; @@ -748,11 +601,7 @@ static void Polyobj_moveToSpawnSpot(mapthing_t *anchor) Polyobj_attachToSubsec(po); } -// -// Polyobj_attachToSubsec -// // Attaches a polyobject to its appropriate subsector. -// static void Polyobj_attachToSubsec(polyobj_t *po) { subsector_t *ss; @@ -787,11 +636,7 @@ static void Polyobj_attachToSubsec(polyobj_t *po) po->attached = true; } -// -// Polyobj_removeFromSubsec -// // Removes a polyobject from the subsector to which it is attached. -// static void Polyobj_removeFromSubsec(polyobj_t *po) { if (po->attached) @@ -803,11 +648,7 @@ static void Polyobj_removeFromSubsec(polyobj_t *po) // Blockmap Functions -// -// Polyobj_getLink -// // Retrieves a polymaplink object from the free list or creates a new one. -// static polymaplink_t *Polyobj_getLink(void) { polymaplink_t *l; @@ -826,11 +667,7 @@ static polymaplink_t *Polyobj_getLink(void) return l; } -// -// Polyobj_putLink -// // Puts a polymaplink object into the free list. -// static void Polyobj_putLink(polymaplink_t *l) { memset(l, 0, sizeof(*l)); @@ -838,14 +675,10 @@ static void Polyobj_putLink(polymaplink_t *l) bmap_freelist = l; } -// -// Polyobj_linkToBlockmap -// // Inserts a polyobject into the polyobject blockmap. Unlike, mobj_t's, // polyobjects need to be linked into every blockmap cell which their // bounding box intersects. This ensures the accurate level of clipping // which is present with linedefs but absent from most mobj interactions. -// static void Polyobj_linkToBlockmap(polyobj_t *po) { fixed_t *blockbox = po->blockbox; @@ -890,12 +723,8 @@ static void Polyobj_linkToBlockmap(polyobj_t *po) po->linked = true; } -// -// Polyobj_removeFromBlockmap -// // Unlinks a polyobject from all blockmap cells it intersects and returns // its polymaplink objects to the free list. -// static void Polyobj_removeFromBlockmap(polyobj_t *po) { polymaplink_t *rover; @@ -934,13 +763,9 @@ static void Polyobj_removeFromBlockmap(polyobj_t *po) // Movement functions -// -// Polyobj_untouched -// // A version of Lee's routine from p_maputl.c that accepts an mobj pointer // argument instead of using tmthing. Returns true if the line isn't contacted // and false otherwise. -// static inline boolean Polyobj_untouched(line_t *ld, mobj_t *mo) { fixed_t x, y, ptmbbox[4]; @@ -953,13 +778,9 @@ static inline boolean Polyobj_untouched(line_t *ld, mobj_t *mo) P_BoxOnLineSide(ptmbbox, ld) != -1; } -// -// Polyobj_pushThing -// // Inflicts thrust and possibly damage on a thing which has been found to be // blocking the motion of a polyobject. The default thrust amount is only one // unit, but the motion of the polyobject can be used to change this. -// static void Polyobj_pushThing(polyobj_t *po, line_t *line, mobj_t *mo) { angle_t lineangle; @@ -994,11 +815,7 @@ static void Polyobj_pushThing(polyobj_t *po, line_t *line, mobj_t *mo) } } -// -// Polyobj_slideThing -// // Moves an object resting on top of a polyobject by (x, y). Template function to make alteration easier. -// static void Polyobj_slideThing(mobj_t *mo, fixed_t dx, fixed_t dy) { if (mo->player) { // Finally this doesn't suck eggs -fickle @@ -1046,11 +863,7 @@ static void Polyobj_slideThing(mobj_t *mo, fixed_t dx, fixed_t dy) P_TryMove(mo, mo->x+dx, mo->y+dy, true); } -// -// Polyobj_carryThings -// // Causes objects resting on top of the polyobject to 'ride' with its movement. -// static void Polyobj_carryThings(polyobj_t *po, fixed_t dx, fixed_t dy) { static INT32 pomovecount = 0; @@ -1102,12 +915,8 @@ static void Polyobj_carryThings(polyobj_t *po, fixed_t dx, fixed_t dy) } } -// -// Polyobj_clipThings -// // Checks for things that are in the way of a polyobject line move. // Returns true if something was hit. -// static INT32 Polyobj_clipThings(polyobj_t *po, line_t *line) { INT32 hitflags = 0; @@ -1169,11 +978,8 @@ static INT32 Polyobj_clipThings(polyobj_t *po, line_t *line) return hitflags; } -// -// Polyobj_moveXY -// + // Moves a polyobject on the x-y plane. -// static boolean Polyobj_moveXY(polyobj_t *po, fixed_t x, fixed_t y, boolean checkmobjs) { size_t i; @@ -1229,14 +1035,10 @@ static boolean Polyobj_moveXY(polyobj_t *po, fixed_t x, fixed_t y, boolean check return !(hitflags & 2); } -// -// Polyobj_rotatePoint -// // Rotates a point and then translates it relative to point c. // The formula for this can be found here: // http://www.inversereality.org/tutorials/graphics%20programming/2dtransformations.html // It is, of course, just a vector-matrix multiplication. -// static inline void Polyobj_rotatePoint(vertex_t *v, const vertex_t *c, angle_t ang) { vertex_t tmp = *v; @@ -1248,12 +1050,8 @@ static inline void Polyobj_rotatePoint(vertex_t *v, const vertex_t *c, angle_t a v->y += c->y; } -// -// Polyobj_rotateLine -// // Taken from P_LoadLineDefs; simply updates the linedef's dx, dy, slopetype, // and bounding box to be consistent with its vertices. -// static void Polyobj_rotateLine(line_t *ld) { vertex_t *v1, *v2; @@ -1293,11 +1091,7 @@ static void Polyobj_rotateLine(line_t *ld) } } -// -// Polyobj_rotateThings -// // Causes objects resting on top of the rotating polyobject to 'ride' with its movement. -// static void Polyobj_rotateThings(polyobj_t *po, vertex_t origin, angle_t delta, UINT8 turnthings) { static INT32 pomovecount = 10000; @@ -1373,11 +1167,7 @@ static void Polyobj_rotateThings(polyobj_t *po, vertex_t origin, angle_t delta, } } -// -// Polyobj_rotate -// // Rotates a polyobject around its start point. -// static boolean Polyobj_rotate(polyobj_t *po, angle_t delta, UINT8 turnthings, boolean checkmobjs) { size_t i; @@ -1451,12 +1241,8 @@ static boolean Polyobj_rotate(polyobj_t *po, angle_t delta, UINT8 turnthings, bo // Global Functions // -// -// Polyobj_GetForNum -// // Retrieves a polyobject by its numeric id using hashing. // Returns NULL if no such polyobject exists. -// polyobj_t *Polyobj_GetForNum(INT32 id) { INT32 curidx = PolyObjects[id % numPolyObjects].first; @@ -1467,12 +1253,9 @@ polyobj_t *Polyobj_GetForNum(INT32 id) return curidx == numPolyObjects ? NULL : &PolyObjects[curidx]; } -// -// Polyobj_GetParent -// + // Retrieves the parenting polyobject if one exists. Returns NULL // otherwise. -// #if 0 //unused function static polyobj_t *Polyobj_GetParent(polyobj_t *po) { @@ -1480,12 +1263,8 @@ static polyobj_t *Polyobj_GetParent(polyobj_t *po) } #endif -// -// Polyobj_GetChild -// // Iteratively retrieves the children POs of a parent, // sorta like P_FindSectorSpecialFromTag. -// static polyobj_t *Polyobj_GetChild(polyobj_t *po, INT32 *start) { for (; *start < numPolyObjects; (*start)++) @@ -1504,12 +1283,8 @@ typedef struct mobjqitem_s mobj_t *mo; } mobjqitem_t; -// -// Polyobj_InitLevel -// // Called at the beginning of each map after all other line and thing // processing is finished. -// void Polyobj_InitLevel(void) { thinker_t *th; @@ -1628,9 +1403,6 @@ void Polyobj_InitLevel(void) M_QueueFree(&anchorqueue); } -// -// Polyobj_MoveOnLoad -// // Called when a savegame is being loaded. Rotates and translates an // existing polyobject to its position when the game was saved. // @@ -1655,11 +1427,7 @@ void Polyobj_MoveOnLoad(polyobj_t *po, angle_t angle, fixed_t x, fixed_t y) // Thinker Functions -// -// T_PolyObjRotate -// // Thinker function for PolyObject rotation. -// void T_PolyObjRotate(polyrotate_t *th) { polyobj_t *po = Polyobj_GetForNum(th->polyObjNum); @@ -1720,11 +1488,7 @@ void T_PolyObjRotate(polyrotate_t *th) } } -// -// Polyobj_componentSpeed -// // Calculates the speed components from the desired resultant velocity. -// FUNCINLINE static ATTRINLINE void Polyobj_componentSpeed(INT32 resVel, INT32 angle, fixed_t *xVel, fixed_t *yVel) { @@ -1805,22 +1569,39 @@ void T_PolyObjMove(polymove_t *th) } } -// -// T_PolyObjWaypoint -// -// Kinda like 'Zoom Tubes for PolyObjects' -// +static void T_MovePolyObj(polyobj_t *po, fixed_t distx, fixed_t disty, fixed_t distz) +{ + polyobj_t *child; + INT32 start; + + Polyobj_moveXY(po, distx, disty, true); + // TODO: use T_MovePlane + po->lines[0]->backsector->floorheight += distz; + po->lines[0]->backsector->ceilingheight += distz; + // Sal: Remember to check your sectors! + // Monster Iestyn: we only need to bother with the back sector, now that P_CheckSector automatically checks the blockmap + // updating objects in the front one too just added teleporting to ground bugs + P_CheckSector(po->lines[0]->backsector, (boolean)(po->damage)); + // Apply action to mirroring polyobjects as well + start = 0; + while ((child = Polyobj_GetChild(po, &start))) + { + if (child->isBad) + continue; + + Polyobj_moveXY(child, distx, disty, true); + // TODO: use T_MovePlane + child->lines[0]->backsector->floorheight += distz; + child->lines[0]->backsector->ceilingheight += distz; + P_CheckSector(child->lines[0]->backsector, (boolean)(child->damage)); + } +} + void T_PolyObjWaypoint(polywaypoint_t *th) { - mobj_t *mo2; mobj_t *target = NULL; - mobj_t *waypoint = NULL; - thinker_t *wp; - fixed_t adjustx, adjusty, adjustz; - fixed_t momx, momy, momz, dist; - INT32 start; polyobj_t *po = Polyobj_GetForNum(th->polyObjNum); - polyobj_t *oldpo = po; + fixed_t speed = th->speed; if (!po) #ifdef RANGECHECK @@ -1834,31 +1615,10 @@ void T_PolyObjWaypoint(polywaypoint_t *th) #endif // check for displacement due to override and reattach when possible - if (po->thinker == NULL) + if (!po->thinker) po->thinker = &th->thinker; -/* - // Find out target first. - // We redo this each tic to make savegame compatibility easier. - for (wp = thlist[THINK_MOBJ].next; wp != &thlist[THINK_MOBJ]; wp = wp->next) - { - if (wp->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) - continue; - - mo2 = (mobj_t *)wp; - - if (mo2->type != MT_TUBEWAYPOINT) - continue; - - if (mo2->threshold == th->sequence && mo2->health == th->pointnum) - { - target = mo2; - break; - } - } -*/ - - target = th->target; + target = waypoints[th->sequence][th->pointnum]; if (!target) { @@ -1866,240 +1626,93 @@ void T_PolyObjWaypoint(polywaypoint_t *th) return; } - // Compensate for position offset - adjustx = po->centerPt.x + th->diffx; - adjusty = po->centerPt.y + th->diffy; - adjustz = po->lines[0]->backsector->floorheight + (po->lines[0]->backsector->ceilingheight - po->lines[0]->backsector->floorheight)/2 + th->diffz; - - dist = P_AproxDistance(P_AproxDistance(target->x - adjustx, target->y - adjusty), target->z - adjustz); - - if (dist < 1) - dist = 1; - - momx = FixedMul(FixedDiv(target->x - adjustx, dist), (th->speed)); - momy = FixedMul(FixedDiv(target->y - adjusty, dist), (th->speed)); - momz = FixedMul(FixedDiv(target->z - adjustz, dist), (th->speed)); - - // Calculate the distance between the polyobject and the waypoint - // 'dist' already equals this. - - // Will the polyobject be FURTHER away if the momx/momy/momz is added to - // its current coordinates, or closer? (shift down to fracunits to avoid approximation errors) - if (dist>>FRACBITS <= P_AproxDistance(P_AproxDistance(target->x - adjustx - momx, target->y - adjusty - momy), target->z - adjustz - momz)>>FRACBITS) + // Move along the waypoint sequence until speed for the current tic is exhausted + while (speed > 0) { - // If further away, set XYZ of polyobject to waypoint location - fixed_t amtx, amty, amtz; - fixed_t diffz; - amtx = (target->x - th->diffx) - po->centerPt.x; - amty = (target->y - th->diffy) - po->centerPt.y; - Polyobj_moveXY(po, amtx, amty, true); - // TODO: use T_MovePlane - amtz = (po->lines[0]->backsector->ceilingheight - po->lines[0]->backsector->floorheight)/2; - diffz = po->lines[0]->backsector->floorheight - (target->z - amtz); - po->lines[0]->backsector->floorheight = target->z - amtz; - po->lines[0]->backsector->ceilingheight = target->z + amtz; - // Sal: Remember to check your sectors! - // Monster Iestyn: we only need to bother with the back sector, now that P_CheckSector automatically checks the blockmap - // updating objects in the front one too just added teleporting to ground bugs - P_CheckSector(po->lines[0]->backsector, (boolean)(po->damage)); - // Apply action to mirroring polyobjects as well - start = 0; - while ((po = Polyobj_GetChild(oldpo, &start))) + mobj_t *waypoint = NULL; + fixed_t pox, poy, poz; + fixed_t distx, disty, distz, dist; + + // Current position of polyobject + pox = po->centerPt.x; + poy = po->centerPt.y; + poz = (po->lines[0]->backsector->floorheight + po->lines[0]->backsector->ceilingheight)/2; + + // Calculate the distance between the polyobject and the waypoint + distx = target->x - pox; + disty = target->y - poy; + distz = target->z - poz; + dist = P_AproxDistance(P_AproxDistance(distx, disty), distz); + + if (dist < 1) + dist = 1; + + // Will the polyobject overshoot its target? + if (speed < dist) { - if (po->isBad) - continue; + // No. Move towards waypoint + fixed_t momx, momy, momz; - Polyobj_moveXY(po, amtx, amty, true); - // TODO: use T_MovePlane - po->lines[0]->backsector->floorheight += diffz; // move up/down by same amount as the parent did - po->lines[0]->backsector->ceilingheight += diffz; - // Sal: Remember to check your sectors! - // Monster Iestyn: we only need to bother with the back sector, now that P_CheckSector automatically checks the blockmap - // updating objects in the front one too just added teleporting to ground bugs - P_CheckSector(po->lines[0]->backsector, (boolean)(po->damage)); - } - - po = oldpo; - - if (!th->stophere) - { - CONS_Debug(DBG_POLYOBJ, "Looking for next waypoint...\n"); - - // Find next waypoint - for (wp = thlist[THINK_MOBJ].next; wp != &thlist[THINK_MOBJ]; wp = wp->next) - { - if (wp->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) - continue; - - mo2 = (mobj_t *)wp; - - if (mo2->type != MT_TUBEWAYPOINT) - continue; - - if (mo2->threshold != th->sequence) - continue; - - if (th->direction == -1) - { - if (mo2->health == target->health - 1) - { - waypoint = mo2; - break; - } - } - else - { - if (mo2->health == target->health + 1) - { - waypoint = mo2; - break; - } - } - } - - if (!waypoint && th->wrap) // If specified, wrap waypoints - { - if (!th->continuous) - { - th->wrap = 0; - th->stophere = true; - } - - for (wp = thlist[THINK_MOBJ].next; wp != &thlist[THINK_MOBJ]; wp = wp->next) - { - if (wp->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) - continue; - - mo2 = (mobj_t *)wp; - - if (mo2->type != MT_TUBEWAYPOINT) - continue; - - if (mo2->threshold != th->sequence) - continue; - - if (th->direction == -1) - { - if (waypoint == NULL) - waypoint = mo2; - else if (mo2->health > waypoint->health) - waypoint = mo2; - } - else - { - if (mo2->health == 0) - { - waypoint = mo2; - break; - } - } - } - } - else if (!waypoint && th->comeback) // Come back to the start - { - th->direction = -th->direction; - - if (!th->continuous) - th->comeback = false; - - for (wp = thlist[THINK_MOBJ].next; wp != &thlist[THINK_MOBJ]; wp = wp->next) - { - if (wp->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) - continue; - - mo2 = (mobj_t *)wp; - - if (mo2->type != MT_TUBEWAYPOINT) - continue; - - if (mo2->threshold != th->sequence) - continue; - - if (th->direction == -1) - { - if (mo2->health == target->health - 1) - { - waypoint = mo2; - break; - } - } - else - { - if (mo2->health == target->health + 1) - { - waypoint = mo2; - break; - } - } - } - } - } - - if (waypoint) - { - CONS_Debug(DBG_POLYOBJ, "Found waypoint (sequence %d, number %d).\n", waypoint->threshold, waypoint->health); - - target = waypoint; - th->pointnum = target->health; - // Set the mobj as your target! -- Monster Iestyn 27/12/19 - P_SetTarget(&th->target, target); - - // calculate MOMX/MOMY/MOMZ for next waypoint - // change slope - dist = P_AproxDistance(P_AproxDistance(target->x - adjustx, target->y - adjusty), target->z - adjustz); - - if (dist < 1) - dist = 1; - - momx = FixedMul(FixedDiv(target->x - adjustx, dist), (th->speed)); - momy = FixedMul(FixedDiv(target->y - adjusty, dist), (th->speed)); - momz = FixedMul(FixedDiv(target->z - adjustz, dist), (th->speed)); + momx = FixedMul(FixedDiv(target->x - pox, dist), speed); + momy = FixedMul(FixedDiv(target->y - poy, dist), speed); + momz = FixedMul(FixedDiv(target->z - poz, dist), speed); + T_MovePolyObj(po, momx, momy, momz); + return; } else { - momx = momy = momz = 0; + // Yes. Teleport to waypoint and look for the next one + T_MovePolyObj(po, distx, disty, distz); if (!th->stophere) - CONS_Debug(DBG_POLYOBJ, "Next waypoint not found!\n"); + { + CONS_Debug(DBG_POLYOBJ, "Looking for next waypoint...\n"); + waypoint = (th->direction == -1) ? P_GetPreviousWaypoint(target, false) : P_GetNextWaypoint(target, false); - if (po->thinker == &th->thinker) - po->thinker = NULL; + if (!waypoint && th->returnbehavior == PWR_WRAP) // If specified, wrap waypoints + { + if (!th->continuous) + { + th->returnbehavior = PWR_STOP; + th->stophere = true; + } - P_RemoveThinker(&th->thinker); - return; + waypoint = (th->direction == -1) ? P_GetLastWaypoint(th->sequence) : P_GetFirstWaypoint(th->sequence); + } + else if (!waypoint && th->returnbehavior == PWR_COMEBACK) // Come back to the start + { + th->direction = -th->direction; + + if (!th->continuous) + th->returnbehavior = PWR_STOP; + + waypoint = (th->direction == -1) ? P_GetPreviousWaypoint(target, false) : P_GetNextWaypoint(target, false); + } + } + + if (waypoint) + { + CONS_Debug(DBG_POLYOBJ, "Found waypoint (sequence %d, number %d).\n", waypoint->threshold, waypoint->health); + + target = waypoint; + th->pointnum = target->health; + + // Calculate remaining speed + speed -= dist; + } + else + { + if (!th->stophere) + CONS_Debug(DBG_POLYOBJ, "Next waypoint not found!\n"); + + if (po->thinker == &th->thinker) + po->thinker = NULL; + + P_RemoveThinker(&th->thinker); + return; + } } } - else - { - // momx/momy/momz already equals the right speed - } - - // Move the polyobject - Polyobj_moveXY(po, momx, momy, true); - // TODO: use T_MovePlane - po->lines[0]->backsector->floorheight += momz; - po->lines[0]->backsector->ceilingheight += momz; - // Sal: Remember to check your sectors! - // Monster Iestyn: we only need to bother with the back sector, now that P_CheckSector automatically checks the blockmap - // updating objects in the front one too just added teleporting to ground bugs - P_CheckSector(po->lines[0]->backsector, (boolean)(po->damage)); - - // Apply action to mirroring polyobjects as well - start = 0; - while ((po = Polyobj_GetChild(oldpo, &start))) - { - if (po->isBad) - continue; - - Polyobj_moveXY(po, momx, momy, true); - // TODO: use T_MovePlane - po->lines[0]->backsector->floorheight += momz; - po->lines[0]->backsector->ceilingheight += momz; - // Sal: Remember to check your sectors! - // Monster Iestyn: we only need to bother with the back sector, now that P_CheckSector automatically checks the blockmap - // updating objects in the front one too just added teleporting to ground bugs - P_CheckSector(po->lines[0]->backsector, (boolean)(po->damage)); - } } void T_PolyDoorSlide(polyslidedoor_t *th) @@ -2303,7 +1916,7 @@ void T_PolyDoorSwing(polyswingdoor_t *th) } } -// T_PolyObjDisplace: shift a polyobject based on a control sector's heights. +// Shift a polyobject based on a control sector's heights. void T_PolyObjDisplace(polydisplace_t *th) { polyobj_t *po = Polyobj_GetForNum(th->polyObjNum); @@ -2343,7 +1956,7 @@ void T_PolyObjDisplace(polydisplace_t *th) th->oldHeights = newheights; } -// T_PolyObjRotDisplace: rotate a polyobject based on a control sector's heights. +// Rotate a polyobject based on a control sector's heights. void T_PolyObjRotDisplace(polyrotdisplace_t *th) { polyobj_t *po = Polyobj_GetForNum(th->polyObjNum); @@ -2389,7 +2002,7 @@ static inline INT32 Polyobj_AngSpeed(INT32 speed) // Linedef Handlers -INT32 EV_DoPolyObjRotate(polyrotdata_t *prdata) +boolean EV_DoPolyObjRotate(polyrotdata_t *prdata) { polyobj_t *po; polyobj_t *oldpo; @@ -2399,16 +2012,16 @@ INT32 EV_DoPolyObjRotate(polyrotdata_t *prdata) if (!(po = Polyobj_GetForNum(prdata->polyObjNum))) { CONS_Debug(DBG_POLYOBJ, "EV_DoPolyObjRotate: bad polyobj %d\n", prdata->polyObjNum); - return 0; + return false; } // don't allow line actions to affect bad polyobjects if (po->isBad) - return 0; + return false; // check for override if this polyobj already has a thinker if (po->thinker && !prdata->overRide) - return 0; + return false; // create a new thinker th = Z_Malloc(sizeof(polyrotate_t), PU_LEVSPEC, NULL); @@ -2451,10 +2064,10 @@ INT32 EV_DoPolyObjRotate(polyrotdata_t *prdata) } // action was successful - return 1; + return true; } -INT32 EV_DoPolyObjMove(polymovedata_t *pmdata) +boolean EV_DoPolyObjMove(polymovedata_t *pmdata) { polyobj_t *po; polyobj_t *oldpo; @@ -2464,16 +2077,16 @@ INT32 EV_DoPolyObjMove(polymovedata_t *pmdata) if (!(po = Polyobj_GetForNum(pmdata->polyObjNum))) { CONS_Debug(DBG_POLYOBJ, "EV_DoPolyObjMove: bad polyobj %d\n", pmdata->polyObjNum); - return 0; + return false; } // don't allow line actions to affect bad polyobjects if (po->isBad) - return 0; + return false; // check for override if this polyobj already has a thinker if (po->thinker && !pmdata->overRide) - return 0; + return false; // create a new thinker th = Z_Malloc(sizeof(polymove_t), PU_LEVSPEC, NULL); @@ -2510,31 +2123,27 @@ INT32 EV_DoPolyObjMove(polymovedata_t *pmdata) } // action was successful - return 1; + return true; } -INT32 EV_DoPolyObjWaypoint(polywaypointdata_t *pwdata) +boolean EV_DoPolyObjWaypoint(polywaypointdata_t *pwdata) { polyobj_t *po; polywaypoint_t *th; - mobj_t *mo2; mobj_t *first = NULL; - mobj_t *last = NULL; - mobj_t *target = NULL; - thinker_t *wp; if (!(po = Polyobj_GetForNum(pwdata->polyObjNum))) { CONS_Debug(DBG_POLYOBJ, "EV_DoPolyObjWaypoint: bad polyobj %d\n", pwdata->polyObjNum); - return 0; + return false; } // don't allow line actions to affect bad polyobjects if (po->isBad) - return 0; + return false; if (po->thinker) // Don't crowd out another thinker. - return 0; + return false; // create a new thinker th = Z_Malloc(sizeof(polywaypoint_t), PU_LEVSPEC, NULL); @@ -2545,137 +2154,36 @@ INT32 EV_DoPolyObjWaypoint(polywaypointdata_t *pwdata) // set fields th->polyObjNum = pwdata->polyObjNum; th->speed = pwdata->speed; - th->sequence = pwdata->sequence; // Used to specify sequence # - if (pwdata->reverse) - th->direction = -1; - else - th->direction = 1; + th->sequence = pwdata->sequence; + th->direction = (pwdata->flags & PWF_REVERSE) ? -1 : 1; - th->comeback = pwdata->comeback; - th->continuous = pwdata->continuous; - th->wrap = pwdata->wrap; + th->returnbehavior = pwdata->returnbehavior; + if (pwdata->flags & PWF_LOOP) + th->continuous = true; th->stophere = false; // Find the first waypoint we need to use - for (wp = thlist[THINK_MOBJ].next; wp != &thlist[THINK_MOBJ]; wp = wp->next) - { - if (wp->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) - continue; - - mo2 = (mobj_t *)wp; - - if (mo2->type != MT_TUBEWAYPOINT) - continue; - - if (mo2->threshold != th->sequence) - continue; - - if (th->direction == -1) // highest waypoint # - { - if (mo2->health == 0) - last = mo2; - else - { - if (first == NULL) - first = mo2; - else if (mo2->health > first->health) - first = mo2; - } - } - else // waypoint 0 - { - if (mo2->health == 0) - first = mo2; - else - { - if (last == NULL) - last = mo2; - else if (mo2->health > last->health) - last = mo2; - } - } - } + first = (th->direction == -1) ? P_GetLastWaypoint(th->sequence) : P_GetFirstWaypoint(th->sequence); if (!first) { CONS_Debug(DBG_POLYOBJ, "EV_DoPolyObjWaypoint: Missing starting waypoint!\n"); po->thinker = NULL; P_RemoveThinker(&th->thinker); - return 0; + return false; } - // Hotfix to not crash on single-waypoint sequences -Red - if (!last) - last = first; - - // Set diffx, diffy, diffz - // Put these at 0 for now...might not be needed after all. - th->diffx = 0;//first->x - po->centerPt.x; - th->diffy = 0;//first->y - po->centerPt.y; - th->diffz = 0;//first->z - (po->lines[0]->backsector->floorheight + (po->lines[0]->backsector->ceilingheight - po->lines[0]->backsector->floorheight)/2); - - if (last->x == po->centerPt.x - && last->y == po->centerPt.y - && last->z == (po->lines[0]->backsector->floorheight + (po->lines[0]->backsector->ceilingheight - po->lines[0]->backsector->floorheight)/2)) + // Sanity check: If all waypoints are in the same location, + // don't allow the movement to be continuous so we don't get stuck in an infinite loop. + if (th->continuous && P_IsDegeneratedWaypointSequence(th->sequence)) { - // Already at the destination point... - if (!th->wrap) - { - po->thinker = NULL; - P_RemoveThinker(&th->thinker); - } + CONS_Debug(DBG_POLYOBJ, "EV_DoPolyObjWaypoint: All waypoints are in the same location!\n"); + th->continuous = false; } - // Find the actual target movement waypoint - target = first; - /*for (wp = thlist[THINK_MOBJ].next; wp != &thlist[THINK_MOBJ]; wp = wp->next) - { - if (wp->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) - continue; + th->pointnum = first->health; - mo2 = (mobj_t *)wp; - - if (mo2->type != MT_TUBEWAYPOINT) - continue; - - if (mo2->threshold != th->sequence) - continue; - - if (th->direction == -1) // highest waypoint # - { - if (mo2->health == first->health - 1) - { - target = mo2; - break; - } - } - else // waypoint 0 - { - if (mo2->health == first->health + 1) - { - target = mo2; - break; - } - } - }*/ - - if (!target) - { - CONS_Debug(DBG_POLYOBJ, "EV_DoPolyObjWaypoint: Missing target waypoint!\n"); - po->thinker = NULL; - P_RemoveThinker(&th->thinker); - return 0; - } - - // Set pointnum - th->pointnum = target->health; - th->target = NULL; // set to NULL first so the below doesn't go wrong - // Set the mobj as your target! -- Monster Iestyn 27/12/19 - P_SetTarget(&th->target, target); - - // We don't deal with the mirror crap here, we'll - // handle that in the T_Thinker function. - return 1; + return true; } static void Polyobj_doSlideDoor(polyobj_t *po, polydoordata_t *doordata) @@ -2767,20 +2275,20 @@ static void Polyobj_doSwingDoor(polyobj_t *po, polydoordata_t *doordata) Polyobj_doSwingDoor(po, doordata); } -INT32 EV_DoPolyDoor(polydoordata_t *doordata) +boolean EV_DoPolyDoor(polydoordata_t *doordata) { polyobj_t *po; if (!(po = Polyobj_GetForNum(doordata->polyObjNum))) { CONS_Debug(DBG_POLYOBJ, "EV_DoPolyDoor: bad polyobj %d\n", doordata->polyObjNum); - return 0; + return false; } // don't allow line actions to affect bad polyobjects; // polyobject doors don't allow action overrides if (po->isBad || po->thinker) - return 0; + return false; switch (doordata->doorType) { @@ -2792,13 +2300,13 @@ INT32 EV_DoPolyDoor(polydoordata_t *doordata) break; default: CONS_Debug(DBG_POLYOBJ, "EV_DoPolyDoor: unknown door type %d", doordata->doorType); - return 0; + return false; } - return 1; + return true; } -INT32 EV_DoPolyObjDisplace(polydisplacedata_t *prdata) +boolean EV_DoPolyObjDisplace(polydisplacedata_t *prdata) { polyobj_t *po; polyobj_t *oldpo; @@ -2808,12 +2316,12 @@ INT32 EV_DoPolyObjDisplace(polydisplacedata_t *prdata) if (!(po = Polyobj_GetForNum(prdata->polyObjNum))) { CONS_Debug(DBG_POLYOBJ, "EV_DoPolyObjRotate: bad polyobj %d\n", prdata->polyObjNum); - return 0; + return false; } // don't allow line actions to affect bad polyobjects if (po->isBad) - return 0; + return false; // create a new thinker th = Z_Malloc(sizeof(polydisplace_t), PU_LEVSPEC, NULL); @@ -2841,10 +2349,10 @@ INT32 EV_DoPolyObjDisplace(polydisplacedata_t *prdata) } // action was successful - return 1; + return true; } -INT32 EV_DoPolyObjRotDisplace(polyrotdisplacedata_t *prdata) +boolean EV_DoPolyObjRotDisplace(polyrotdisplacedata_t *prdata) { polyobj_t *po; polyobj_t *oldpo; @@ -2854,12 +2362,12 @@ INT32 EV_DoPolyObjRotDisplace(polyrotdisplacedata_t *prdata) if (!(po = Polyobj_GetForNum(prdata->polyObjNum))) { CONS_Debug(DBG_POLYOBJ, "EV_DoPolyObjRotate: bad polyobj %d\n", prdata->polyObjNum); - return 0; + return false; } // don't allow line actions to affect bad polyobjects if (po->isBad) - return 0; + return false; // create a new thinker th = Z_Malloc(sizeof(polyrotdisplace_t), PU_LEVSPEC, NULL); @@ -2887,7 +2395,7 @@ INT32 EV_DoPolyObjRotDisplace(polyrotdisplacedata_t *prdata) } // action was successful - return 1; + return true; } void T_PolyObjFlag(polymove_t *th) @@ -2936,7 +2444,7 @@ void T_PolyObjFlag(polymove_t *th) Polyobj_attachToSubsec(po); // relink to subsector } -INT32 EV_DoPolyObjFlag(line_t *pfdata) +boolean EV_DoPolyObjFlag(polyflagdata_t *pfdata) { polyobj_t *po; polyobj_t *oldpo; @@ -2944,22 +2452,22 @@ INT32 EV_DoPolyObjFlag(line_t *pfdata) size_t i; INT32 start; - if (!(po = Polyobj_GetForNum(pfdata->tag))) + if (!(po = Polyobj_GetForNum(pfdata->polyObjNum))) { - CONS_Debug(DBG_POLYOBJ, "EV_DoPolyFlag: bad polyobj %d\n", pfdata->tag); - return 0; + CONS_Debug(DBG_POLYOBJ, "EV_DoPolyFlag: bad polyobj %d\n", pfdata->polyObjNum); + return false; } // don't allow line actions to affect bad polyobjects, // polyobject doors don't allow action overrides if (po->isBad || po->thinker) - return 0; + return false; // Must have even # of vertices if (po->numVertices & 1) { CONS_Debug(DBG_POLYOBJ, "EV_DoPolyFlag: Polyobject has odd # of vertices!\n"); - return 0; + return false; } // create a new thinker @@ -2969,11 +2477,11 @@ INT32 EV_DoPolyObjFlag(line_t *pfdata) po->thinker = &th->thinker; // set fields - th->polyObjNum = pfdata->tag; + th->polyObjNum = pfdata->polyObjNum; th->distance = 0; - th->speed = P_AproxDistance(pfdata->dx, pfdata->dy)>>FRACBITS; - th->angle = R_PointToAngle2(pfdata->v1->x, pfdata->v1->y, pfdata->v2->x, pfdata->v2->y)>>ANGLETOFINESHIFT; - th->momx = sides[pfdata->sidenum[0]].textureoffset>>FRACBITS; + th->speed = pfdata->speed; + th->angle = pfdata->angle; + th->momx = pfdata->momx; // save current positions for (i = 0; i < po->numVertices; ++i) @@ -2985,12 +2493,12 @@ INT32 EV_DoPolyObjFlag(line_t *pfdata) start = 0; while ((po = Polyobj_GetChild(oldpo, &start))) { - pfdata->tag = po->id; + pfdata->polyObjNum = po->id; EV_DoPolyObjFlag(pfdata); } // action was successful - return 1; + return true; } void T_PolyObjFade(polyfade_t *th) @@ -3088,7 +2596,7 @@ void T_PolyObjFade(polyfade_t *th) } } -INT32 EV_DoPolyObjFade(polyfadedata_t *pfdata) +boolean EV_DoPolyObjFade(polyfadedata_t *pfdata) { polyobj_t *po; polyobj_t *oldpo; @@ -3098,16 +2606,16 @@ INT32 EV_DoPolyObjFade(polyfadedata_t *pfdata) if (!(po = Polyobj_GetForNum(pfdata->polyObjNum))) { CONS_Debug(DBG_POLYOBJ, "EV_DoPolyObjFade: bad polyobj %d\n", pfdata->polyObjNum); - return 0; + return false; } // don't allow line actions to affect bad polyobjects if (po->isBad) - return 0; + return false; // already equal, nothing to do if (po->translucency == pfdata->destvalue) - return 1; + return true; if (po->thinker && po->thinker->function.acp1 == (actionf_p1)T_PolyObjFade) P_RemoveThinker(po->thinker); @@ -3149,9 +2657,7 @@ INT32 EV_DoPolyObjFade(polyfadedata_t *pfdata) } // action was successful - return 1; + return true; } -#endif // ifdef POLYOBJECTS - // EOF diff --git a/src/p_polyobj.h b/src/p_polyobj.h index d56701d2d..8037c545f 100644 --- a/src/p_polyobj.h +++ b/src/p_polyobj.h @@ -18,8 +18,6 @@ #include "p_mobj.h" #include "r_defs.h" -// haleyjd: temporary define -#ifdef POLYOBJECTS // // Defines // @@ -31,7 +29,6 @@ #define POLYOBJ_SPAWNCRUSH_DOOMEDNUM 762 // todo: REMOVE #define POLYOBJ_START_LINE 20 -#define POLYOBJ_EXPLICIT_LINE 21 #define POLYINFO_SPECIALNUM 22 typedef enum @@ -143,26 +140,26 @@ typedef struct polymove_s UINT32 angle; // angle along which to move } polymove_t; +// PolyObject waypoint movement return behavior +typedef enum +{ + PWR_STOP, // Stop after reaching last waypoint + PWR_WRAP, // Wrap back to first waypoint + PWR_COMEBACK, // Repeat sequence in reverse +} polywaypointreturn_e; + typedef struct polywaypoint_s { thinker_t thinker; // must be first - INT32 polyObjNum; // numeric id of polyobject - INT32 speed; // resultant velocity - INT32 sequence; // waypoint sequence # - INT32 pointnum; // waypoint # - INT32 direction; // 1 for normal, -1 for backwards - UINT8 comeback; // reverses and comes back when the end is reached - UINT8 wrap; // Wrap around waypoints - UINT8 continuous; // continuously move - used with COMEBACK or WRAP - UINT8 stophere; // Will stop after it reaches the next waypoint - - // Difference between location of PO and location of waypoint (offset) - fixed_t diffx; - fixed_t diffy; - fixed_t diffz; - - mobj_t *target; // next waypoint mobj + INT32 polyObjNum; // numeric id of polyobject + INT32 speed; // resultant velocity + INT32 sequence; // waypoint sequence # + INT32 pointnum; // waypoint # + INT32 direction; // 1 for normal, -1 for backwards + UINT8 returnbehavior; // behavior after reaching the last waypoint + UINT8 continuous; // continuously move - used with PWR_WRAP or PWR_COMEBACK + UINT8 stophere; // Will stop after it reaches the next waypoint } polywaypoint_t; typedef struct polyslidedoor_s @@ -257,15 +254,19 @@ typedef struct polymovedata_s UINT8 overRide; // if true, will override any action on the object } polymovedata_t; +typedef enum +{ + PWF_REVERSE = 1, // Move through waypoints in reverse order + PWF_LOOP = 1<<1, // Loop movement (used with PWR_WRAP or PWR_COMEBACK) +} polywaypointflags_e; + typedef struct polywaypointdata_s { - INT32 polyObjNum; // numeric id of polyobject to affect - INT32 sequence; // waypoint sequence # - fixed_t speed; // linear speed - UINT8 reverse; // if true, will go in reverse waypoint order - UINT8 comeback; // reverses and comes back when the end is reached - UINT8 wrap; // Wrap around waypoints - UINT8 continuous; // continuously move - used with COMEBACK or WRAP + INT32 polyObjNum; // numeric id of polyobject to affect + INT32 sequence; // waypoint sequence # + fixed_t speed; // linear speed + UINT8 returnbehavior; // behavior after reaching the last waypoint + UINT8 flags; // PWF_ flags } polywaypointdata_t; // polyobject door types @@ -301,6 +302,14 @@ typedef struct polyrotdisplacedata_s UINT8 turnobjs; } polyrotdisplacedata_t; +typedef struct polyflagdata_s +{ + INT32 polyObjNum; + INT32 speed; + UINT32 angle; + fixed_t momx; +} polyflagdata_t; + typedef struct polyfadedata_s { INT32 polyObjNum; @@ -322,7 +331,6 @@ boolean P_PointInsidePolyobj(polyobj_t *po, fixed_t x, fixed_t y); boolean P_MobjTouchingPolyobj(polyobj_t *po, mobj_t *mo); boolean P_MobjInsidePolyobj(polyobj_t *po, mobj_t *mo); boolean P_BBoxInsidePolyobj(polyobj_t *po, fixed_t *bbox); -void Polyobj_GetInfo(INT16 poid, INT32 *poflags, INT32 *parentID, INT32 *potrans); // thinkers (needed in p_saveg.c) void T_PolyObjRotate(polyrotate_t *); @@ -335,14 +343,14 @@ void T_PolyObjRotDisplace (polyrotdisplace_t *); void T_PolyObjFlag (polymove_t *); void T_PolyObjFade (polyfade_t *); -INT32 EV_DoPolyDoor(polydoordata_t *); -INT32 EV_DoPolyObjMove(polymovedata_t *); -INT32 EV_DoPolyObjWaypoint(polywaypointdata_t *); -INT32 EV_DoPolyObjRotate(polyrotdata_t *); -INT32 EV_DoPolyObjDisplace(polydisplacedata_t *); -INT32 EV_DoPolyObjRotDisplace(polyrotdisplacedata_t *); -INT32 EV_DoPolyObjFlag(struct line_s *); -INT32 EV_DoPolyObjFade(polyfadedata_t *); +boolean EV_DoPolyDoor(polydoordata_t *); +boolean EV_DoPolyObjMove(polymovedata_t *); +boolean EV_DoPolyObjWaypoint(polywaypointdata_t *); +boolean EV_DoPolyObjRotate(polyrotdata_t *); +boolean EV_DoPolyObjDisplace(polydisplacedata_t *); +boolean EV_DoPolyObjRotDisplace(polyrotdisplacedata_t *); +boolean EV_DoPolyObjFlag(polyflagdata_t *); +boolean EV_DoPolyObjFade(polyfadedata_t *); // @@ -353,8 +361,6 @@ extern polyobj_t *PolyObjects; extern INT32 numPolyObjects; extern polymaplink_t **polyblocklinks; // polyobject blockmap -#endif // ifdef POLYOBJECTS - #endif // EOF diff --git a/src/p_saveg.c b/src/p_saveg.c index be2763f27..d6abf4232 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -59,9 +59,6 @@ typedef enum DRONE = 0x80, } player_saveflags; -// -// P_ArchivePlayer -// static inline void P_ArchivePlayer(void) { const player_t *player = &players[consoleplayer]; @@ -77,9 +74,6 @@ static inline void P_ArchivePlayer(void) WRITEINT32(save_p, player->continues); } -// -// P_UnArchivePlayer -// static inline void P_UnArchivePlayer(void) { INT16 skininfo = READUINT16(save_p); @@ -92,9 +86,6 @@ static inline void P_UnArchivePlayer(void) savedata.continues = READINT32(save_p); } -// -// P_NetArchivePlayers -// static void P_NetArchivePlayers(void) { INT32 i, j; @@ -300,9 +291,6 @@ static void P_NetArchivePlayers(void) } } -// -// P_NetUnArchivePlayers -// static void P_NetUnArchivePlayers(void) { INT32 i, j; @@ -1185,9 +1173,6 @@ static void UnArchiveLines(void) } } -// -// P_NetArchiveWorld -// static void P_NetArchiveWorld(void) { // initialize colormap vars because paranoia @@ -1200,9 +1185,6 @@ static void P_NetArchiveWorld(void) R_ClearTextureNumCache(false); } -// -// P_NetUnArchiveWorld -// static void P_NetUnArchiveWorld(void) { UINT16 i; @@ -1318,7 +1300,6 @@ typedef enum tc_planedisplace, tc_dynslopeline, tc_dynslopevert, -#ifdef POLYOBJECTS tc_polyrotate, // haleyjd 03/26/06: polyobjects tc_polymove, tc_polywaypoint, @@ -1328,7 +1309,6 @@ typedef enum tc_polydisplace, tc_polyrotdisplace, tc_polyfade, -#endif tc_end } specials_e; @@ -1362,11 +1342,6 @@ static UINT32 SaveSlope(const pslope_t *slope) return 0xFFFFFFFF; } -// -// SaveMobjThinker -// -// Saves a mobj_t thinker -// static void SaveMobjThinker(const thinker_t *th, const UINT8 type) { const mobj_t *mobj = (const mobj_t *)th; @@ -1618,7 +1593,7 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type) if (diff2 & MD2_SKIN) WRITEUINT8(save_p, (UINT8)((skin_t *)mobj->skin - skins)); if (diff2 & MD2_COLOR) - WRITEUINT8(save_p, mobj->color); + WRITEUINT16(save_p, mobj->color); if (diff2 & MD2_EXTVAL1) WRITEINT32(save_p, mobj->extravalue1); if (diff2 & MD2_EXTVAL2) @@ -1639,11 +1614,6 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type) WRITEUINT32(save_p, mobj->mobjnum); } -// -// SaveNoEnemiesThinker -// -// Saves a noenemies_t thinker -// static void SaveNoEnemiesThinker(const thinker_t *th, const UINT8 type) { const noenemies_t *ht = (const void *)th; @@ -1651,11 +1621,6 @@ static void SaveNoEnemiesThinker(const thinker_t *th, const UINT8 type) WRITEUINT32(save_p, SaveLine(ht->sourceline)); } -// -// SaveBounceCheeseThinker -// -// Saves a bouncecheese_t thinker -// static void SaveBounceCheeseThinker(const thinker_t *th, const UINT8 type) { const bouncecheese_t *ht = (const void *)th; @@ -1669,11 +1634,6 @@ static void SaveBounceCheeseThinker(const thinker_t *th, const UINT8 type) WRITECHAR(save_p, ht->low); } -// -// SaveContinuousFallThinker -// -// Saves a continuousfall_t thinker -// static void SaveContinuousFallThinker(const thinker_t *th, const UINT8 type) { const continuousfall_t *ht = (const void *)th; @@ -1686,11 +1646,6 @@ static void SaveContinuousFallThinker(const thinker_t *th, const UINT8 type) WRITEFIXED(save_p, ht->destheight); } -// -// SaveMarioBlockThinker -// -// Saves a mariothink_t thinker -// static void SaveMarioBlockThinker(const thinker_t *th, const UINT8 type) { const mariothink_t *ht = (const void *)th; @@ -1703,11 +1658,6 @@ static void SaveMarioBlockThinker(const thinker_t *th, const UINT8 type) WRITEINT16(save_p, ht->tag); } -// -// SaveMarioCheckThinker -// -// Saves a mariocheck_t thinker -// static void SaveMarioCheckThinker(const thinker_t *th, const UINT8 type) { const mariocheck_t *ht = (const void *)th; @@ -1716,11 +1666,6 @@ static void SaveMarioCheckThinker(const thinker_t *th, const UINT8 type) WRITEUINT32(save_p, SaveSector(ht->sector)); } -// -// SaveThwompThinker -// -// Saves a thwomp_t thinker -// static void SaveThwompThinker(const thinker_t *th, const UINT8 type) { const thwomp_t *ht = (const void *)th; @@ -1737,11 +1682,6 @@ static void SaveThwompThinker(const thinker_t *th, const UINT8 type) WRITEUINT16(save_p, ht->sound); } -// -// SaveFloatThinker -// -// Saves a floatthink_t thinker -// static void SaveFloatThinker(const thinker_t *th, const UINT8 type) { const floatthink_t *ht = (const void *)th; @@ -1751,10 +1691,6 @@ static void SaveFloatThinker(const thinker_t *th, const UINT8 type) WRITEINT16(save_p, ht->tag); } -// SaveEachTimeThinker -// -// Loads a eachtime_t from a save game -// static void SaveEachTimeThinker(const thinker_t *th, const UINT8 type) { const eachtime_t *ht = (const void *)th; @@ -1769,15 +1705,11 @@ static void SaveEachTimeThinker(const thinker_t *th, const UINT8 type) WRITECHAR(save_p, ht->triggerOnExit); } -// SaveRaiseThinker -// -// Saves a raise_t thinker -// static void SaveRaiseThinker(const thinker_t *th, const UINT8 type) { const raise_t *ht = (const void *)th; WRITEUINT8(save_p, type); - WRITEUINT32(save_p, SaveLine(ht->sourceline)); + WRITEINT16(save_p, ht->tag); WRITEUINT32(save_p, SaveSector(ht->sector)); WRITEFIXED(save_p, ht->ceilingbottom); WRITEFIXED(save_p, ht->ceilingtop); @@ -1787,11 +1719,6 @@ static void SaveRaiseThinker(const thinker_t *th, const UINT8 type) WRITEUINT8(save_p, ht->flags); } -// -// SaveCeilingThinker -// -// Saves a ceiling_t thinker -// static void SaveCeilingThinker(const thinker_t *th, const UINT8 type) { const ceiling_t *ht = (const void *)th; @@ -1813,11 +1740,6 @@ static void SaveCeilingThinker(const thinker_t *th, const UINT8 type) WRITEFIXED(save_p, ht->sourceline); } -// -// SaveFloormoveThinker -// -// Saves a floormove_t thinker -// static void SaveFloormoveThinker(const thinker_t *th, const UINT8 type) { const floormove_t *ht = (const void *)th; @@ -1834,11 +1756,6 @@ static void SaveFloormoveThinker(const thinker_t *th, const UINT8 type) WRITEFIXED(save_p, ht->delaytimer); } -// -// SaveLightflashThinker -// -// Saves a lightflash_t thinker -// static void SaveLightflashThinker(const thinker_t *th, const UINT8 type) { const lightflash_t *ht = (const void *)th; @@ -1848,11 +1765,6 @@ static void SaveLightflashThinker(const thinker_t *th, const UINT8 type) WRITEINT32(save_p, ht->minlight); } -// -// SaveStrobeThinker -// -// Saves a strobe_t thinker -// static void SaveStrobeThinker(const thinker_t *th, const UINT8 type) { const strobe_t *ht = (const void *)th; @@ -1865,11 +1777,6 @@ static void SaveStrobeThinker(const thinker_t *th, const UINT8 type) WRITEINT32(save_p, ht->brighttime); } -// -// SaveGlowThinker -// -// Saves a glow_t thinker -// static void SaveGlowThinker(const thinker_t *th, const UINT8 type) { const glow_t *ht = (const void *)th; @@ -1880,11 +1787,7 @@ static void SaveGlowThinker(const thinker_t *th, const UINT8 type) WRITEINT32(save_p, ht->direction); WRITEINT32(save_p, ht->speed); } -// -// SaveFireflickerThinker -// -// Saves a fireflicker_t thinker -// + static inline void SaveFireflickerThinker(const thinker_t *th, const UINT8 type) { const fireflicker_t *ht = (const void *)th; @@ -1895,11 +1798,7 @@ static inline void SaveFireflickerThinker(const thinker_t *th, const UINT8 type) WRITEINT32(save_p, ht->maxlight); WRITEINT32(save_p, ht->minlight); } -// -// SaveElevatorThinker -// -// Saves a elevator_t thinker -// + static void SaveElevatorThinker(const thinker_t *th, const UINT8 type) { const elevator_t *ht = (const void *)th; @@ -1919,15 +1818,26 @@ static void SaveElevatorThinker(const thinker_t *th, const UINT8 type) WRITEFIXED(save_p, ht->delaytimer); WRITEFIXED(save_p, ht->floorwasheight); WRITEFIXED(save_p, ht->ceilingwasheight); - WRITEUINT32(save_p, SavePlayer(ht->player)); // was dummy WRITEUINT32(save_p, SaveLine(ht->sourceline)); } -// -// SaveScrollThinker -// -// Saves a scroll_t thinker -// +static void SaveCrumbleThinker(const thinker_t *th, const UINT8 type) +{ + const crumble_t *ht = (const void *)th; + WRITEUINT8(save_p, type); + WRITEUINT32(save_p, SaveLine(ht->sourceline)); + WRITEUINT32(save_p, SaveSector(ht->sector)); + WRITEUINT32(save_p, SaveSector(ht->actionsector)); + WRITEUINT32(save_p, SavePlayer(ht->player)); // was dummy + WRITEINT32(save_p, ht->direction); + WRITEINT32(save_p, ht->origalpha); + WRITEINT32(save_p, ht->timer); + WRITEFIXED(save_p, ht->speed); + WRITEFIXED(save_p, ht->floorwasheight); + WRITEFIXED(save_p, ht->ceilingwasheight); + WRITEUINT8(save_p, ht->flags); +} + static inline void SaveScrollThinker(const thinker_t *th, const UINT8 type) { const scroll_t *ht = (const void *)th; @@ -1944,11 +1854,6 @@ static inline void SaveScrollThinker(const thinker_t *th, const UINT8 type) WRITEUINT8(save_p, ht->type); } -// -// SaveFrictionThinker -// -// Saves a friction_t thinker -// static inline void SaveFrictionThinker(const thinker_t *th, const UINT8 type) { const friction_t *ht = (const void *)th; @@ -1960,11 +1865,6 @@ static inline void SaveFrictionThinker(const thinker_t *th, const UINT8 type) WRITEUINT8(save_p, ht->roverfriction); } -// -// SavePusherThinker -// -// Saves a pusher_t thinker -// static inline void SavePusherThinker(const thinker_t *th, const UINT8 type) { const pusher_t *ht = (const void *)th; @@ -1984,25 +1884,15 @@ static inline void SavePusherThinker(const thinker_t *th, const UINT8 type) WRITEINT32(save_p, ht->slider); } -// -// SaveLaserThinker -// -// Saves a laserthink_t thinker -// static void SaveLaserThinker(const thinker_t *th, const UINT8 type) { const laserthink_t *ht = (const void *)th; WRITEUINT8(save_p, type); - WRITEUINT32(save_p, SaveSector(ht->sector)); - WRITEUINT32(save_p, SaveSector(ht->sec)); + WRITEINT16(save_p, ht->tag); WRITEUINT32(save_p, SaveLine(ht->sourceline)); + WRITEUINT8(save_p, ht->nobosses); } -// -// SaveLightlevelThinker -// -// Saves a lightlevel_t thinker -// static void SaveLightlevelThinker(const thinker_t *th, const UINT8 type) { const lightlevel_t *ht = (const void *)th; @@ -2015,11 +1905,6 @@ static void SaveLightlevelThinker(const thinker_t *th, const UINT8 type) WRITEINT32(save_p, ht->timer); } -// -// SaveExecutorThinker -// -// Saves a executor_t thinker -// static void SaveExecutorThinker(const thinker_t *th, const UINT8 type) { const executor_t *ht = (const void *)th; @@ -2030,11 +1915,6 @@ static void SaveExecutorThinker(const thinker_t *th, const UINT8 type) WRITEINT32(save_p, ht->timer); } -// -// SaveDisappearThinker -// -// Saves a disappear_t thinker -// static void SaveDisappearThinker(const thinker_t *th, const UINT8 type) { const disappear_t *ht = (const void *)th; @@ -2048,11 +1928,6 @@ static void SaveDisappearThinker(const thinker_t *th, const UINT8 type) WRITEINT32(save_p, ht->exists); } -// -// SaveFadeThinker -// -// Saves a fade_t thinker -// static void SaveFadeThinker(const thinker_t *th, const UINT8 type) { const fade_t *ht = (const void *)th; @@ -2076,11 +1951,6 @@ static void SaveFadeThinker(const thinker_t *th, const UINT8 type) WRITEUINT8(save_p, ht->exactalpha); } -// -// SaveFadeColormapThinker -// -// Saves a fadecolormap_t thinker -// static void SaveFadeColormapThinker(const thinker_t *th, const UINT8 type) { const fadecolormap_t *ht = (const void *)th; @@ -2093,11 +1963,6 @@ static void SaveFadeColormapThinker(const thinker_t *th, const UINT8 type) WRITEINT32(save_p, ht->timer); } -// -// SavePlaneDisplaceThinker -// -// Saves a planedisplace_t thinker -// static void SavePlaneDisplaceThinker(const thinker_t *th, const UINT8 type) { const planedisplace_t *ht = (const void *)th; @@ -2109,7 +1974,6 @@ static void SavePlaneDisplaceThinker(const thinker_t *th, const UINT8 type) WRITEUINT8(save_p, ht->type); } -/// Save a dynamic slope thinker. static inline void SaveDynamicSlopeThinker(const thinker_t *th, const UINT8 type) { const dynplanethink_t* ht = (const void*)th; @@ -2124,13 +1988,6 @@ static inline void SaveDynamicSlopeThinker(const thinker_t *th, const UINT8 type WRITEMEM(save_p, ht->vex, sizeof(ht->vex)); } -#ifdef POLYOBJECTS - -// -// SavePolyrotateThinker -// -// Saves a polyrotate_t thinker -// static inline void SavePolyrotatetThinker(const thinker_t *th, const UINT8 type) { const polyrotate_t *ht = (const void *)th; @@ -2140,11 +1997,6 @@ static inline void SavePolyrotatetThinker(const thinker_t *th, const UINT8 type) WRITEINT32(save_p, ht->distance); } -// -// SavePolymoveThinker -// -// Saves a polymovet_t thinker -// static void SavePolymoveThinker(const thinker_t *th, const UINT8 type) { const polymove_t *ht = (const void *)th; @@ -2157,11 +2009,6 @@ static void SavePolymoveThinker(const thinker_t *th, const UINT8 type) WRITEANGLE(save_p, ht->angle); } -// -// SavePolywaypointThinker -// -// Saves a polywaypoint_t thinker -// static void SavePolywaypointThinker(const thinker_t *th, UINT8 type) { const polywaypoint_t *ht = (const void *)th; @@ -2171,21 +2018,11 @@ static void SavePolywaypointThinker(const thinker_t *th, UINT8 type) WRITEINT32(save_p, ht->sequence); WRITEINT32(save_p, ht->pointnum); WRITEINT32(save_p, ht->direction); - WRITEUINT8(save_p, ht->comeback); - WRITEUINT8(save_p, ht->wrap); + WRITEUINT8(save_p, ht->returnbehavior); WRITEUINT8(save_p, ht->continuous); WRITEUINT8(save_p, ht->stophere); - WRITEFIXED(save_p, ht->diffx); - WRITEFIXED(save_p, ht->diffy); - WRITEFIXED(save_p, ht->diffz); - WRITEUINT32(save_p, SaveMobjnum(ht->target)); } -// -// SavePolyslidedoorThinker -// -// Saves a polyslidedoor_t thinker -// static void SavePolyslidedoorThinker(const thinker_t *th, const UINT8 type) { const polyslidedoor_t *ht = (const void *)th; @@ -2205,11 +2042,6 @@ static void SavePolyslidedoorThinker(const thinker_t *th, const UINT8 type) WRITEUINT8(save_p, ht->closing); } -// -// SavePolyswingdoorThinker -// -// Saves a polyswingdoor_t thinker -// static void SavePolyswingdoorThinker(const thinker_t *th, const UINT8 type) { const polyswingdoor_t *ht = (const void *)th; @@ -2260,24 +2092,6 @@ static void SavePolyfadeThinker(const thinker_t *th, const UINT8 type) WRITEINT32(save_p, ht->timer); } -#endif -/* -// -// SaveWhatThinker -// -// Saves a what_t thinker -// -static inline void SaveWhatThinker(const thinker_t *th, const UINT8 type) -{ - const what_t *ht = (const void *)th; - WRITEUINT8(save_p, type); -} -*/ - -// -// P_NetArchiveThinkers -// -// static void P_NetArchiveThinkers(void) { const thinker_t *th; @@ -2395,7 +2209,7 @@ static void P_NetArchiveThinkers(void) } else if (th->function.acp1 == (actionf_p1)T_StartCrumble) { - SaveElevatorThinker(th, tc_startcrumble); + SaveCrumbleThinker(th, tc_startcrumble); continue; } else if (th->function.acp1 == (actionf_p1)T_MarioBlock) @@ -2448,7 +2262,6 @@ static void P_NetArchiveThinkers(void) SavePlaneDisplaceThinker(th, tc_planedisplace); continue; } -#ifdef POLYOBJECTS else if (th->function.acp1 == (actionf_p1)T_PolyObjRotate) { SavePolyrotatetThinker(th, tc_polyrotate); @@ -2494,7 +2307,6 @@ static void P_NetArchiveThinkers(void) SavePolyfadeThinker(th, tc_polyfade); continue; } -#endif else if (th->function.acp1 == (actionf_p1)T_DynamicSlopeLine) { SaveDynamicSlopeThinker(th, tc_dynslopeline); @@ -2577,11 +2389,6 @@ static inline pslope_t *LoadSlope(UINT32 slopeid) return NULL; } -// -// LoadMobjThinker -// -// Loads a mobj_t from a save game -// static thinker_t* LoadMobjThinker(actionf_p1 thinker) { thinker_t *next; @@ -2793,7 +2600,7 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker) if (diff2 & MD2_SKIN) mobj->skin = &skins[READUINT8(save_p)]; if (diff2 & MD2_COLOR) - mobj->color = READUINT8(save_p); + mobj->color = READUINT16(save_p); if (diff2 & MD2_EXTVAL1) mobj->extravalue1 = READINT32(save_p); if (diff2 & MD2_EXTVAL2) @@ -2840,10 +2647,6 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker) return &mobj->thinker; } -// LoadNoEnemiesThinker -// -// Loads a noenemies_t from a save game -// static thinker_t* LoadNoEnemiesThinker(actionf_p1 thinker) { noenemies_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -2852,10 +2655,6 @@ static thinker_t* LoadNoEnemiesThinker(actionf_p1 thinker) return &ht->thinker; } -// LoadBounceCheeseThinker -// -// Loads a bouncecheese_t from a save game -// static thinker_t* LoadBounceCheeseThinker(actionf_p1 thinker) { bouncecheese_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -2874,10 +2673,6 @@ static thinker_t* LoadBounceCheeseThinker(actionf_p1 thinker) return &ht->thinker; } -// LoadContinuousFallThinker -// -// Loads a continuousfall_t from a save game -// static thinker_t* LoadContinuousFallThinker(actionf_p1 thinker) { continuousfall_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -2898,10 +2693,6 @@ static thinker_t* LoadContinuousFallThinker(actionf_p1 thinker) return &ht->thinker; } -// LoadMarioBlockThinker -// -// Loads a mariothink_t from a save game -// static thinker_t* LoadMarioBlockThinker(actionf_p1 thinker) { mariothink_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -2922,10 +2713,6 @@ static thinker_t* LoadMarioBlockThinker(actionf_p1 thinker) return &ht->thinker; } -// LoadMarioCheckThinker -// -// Loads a mariocheck_t from a save game -// static thinker_t* LoadMarioCheckThinker(actionf_p1 thinker) { mariocheck_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -2935,10 +2722,6 @@ static thinker_t* LoadMarioCheckThinker(actionf_p1 thinker) return &ht->thinker; } -// LoadThwompThinker -// -// Loads a thwomp_t from a save game -// static thinker_t* LoadThwompThinker(actionf_p1 thinker) { thwomp_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -2963,10 +2746,6 @@ static thinker_t* LoadThwompThinker(actionf_p1 thinker) return &ht->thinker; } -// LoadFloatThinker -// -// Loads a floatthink_t from a save game -// static thinker_t* LoadFloatThinker(actionf_p1 thinker) { floatthink_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -2977,10 +2756,6 @@ static thinker_t* LoadFloatThinker(actionf_p1 thinker) return &ht->thinker; } -// LoadEachTimeThinker -// -// Loads a eachtime_t from a save game -// static thinker_t* LoadEachTimeThinker(actionf_p1 thinker) { size_t i; @@ -2996,15 +2771,11 @@ static thinker_t* LoadEachTimeThinker(actionf_p1 thinker) return &ht->thinker; } -// LoadRaiseThinker -// -// Loads a raise_t from a save game -// static thinker_t* LoadRaiseThinker(actionf_p1 thinker) { raise_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); ht->thinker.function.acp1 = thinker; - ht->sourceline = LoadLine(READUINT32(save_p)); + ht->tag = READINT16(save_p); ht->sector = LoadSector(READUINT32(save_p)); ht->ceilingbottom = READFIXED(save_p); ht->ceilingtop = READFIXED(save_p); @@ -3015,11 +2786,6 @@ static thinker_t* LoadRaiseThinker(actionf_p1 thinker) return &ht->thinker; } -// -// LoadCeilingThinker -// -// Loads a ceiling_t from a save game -// static thinker_t* LoadCeilingThinker(actionf_p1 thinker) { ceiling_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -3044,11 +2810,6 @@ static thinker_t* LoadCeilingThinker(actionf_p1 thinker) return &ht->thinker; } -// -// LoadFloormoveThinker -// -// Loads a floormove_t from a save game -// static thinker_t* LoadFloormoveThinker(actionf_p1 thinker) { floormove_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -3068,11 +2829,6 @@ static thinker_t* LoadFloormoveThinker(actionf_p1 thinker) return &ht->thinker; } -// -// LoadLightflashThinker -// -// Loads a lightflash_t from a save game -// static thinker_t* LoadLightflashThinker(actionf_p1 thinker) { lightflash_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -3085,11 +2841,6 @@ static thinker_t* LoadLightflashThinker(actionf_p1 thinker) return &ht->thinker; } -// -// LoadStrobeThinker -// -// Loads a strobe_t from a save game -// static thinker_t* LoadStrobeThinker(actionf_p1 thinker) { strobe_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -3105,11 +2856,6 @@ static thinker_t* LoadStrobeThinker(actionf_p1 thinker) return &ht->thinker; } -// -// LoadGlowThinker -// -// Loads a glow_t from a save game -// static thinker_t* LoadGlowThinker(actionf_p1 thinker) { glow_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -3123,11 +2869,7 @@ static thinker_t* LoadGlowThinker(actionf_p1 thinker) ht->sector->lightingdata = ht; return &ht->thinker; } -// -// LoadFireflickerThinker -// -// Loads a fireflicker_t from a save game -// + static thinker_t* LoadFireflickerThinker(actionf_p1 thinker) { fireflicker_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -3141,12 +2883,8 @@ static thinker_t* LoadFireflickerThinker(actionf_p1 thinker) ht->sector->lightingdata = ht; return &ht->thinker; } -// -// LoadElevatorThinker -// -// Loads a elevator_t from a save game -// -static thinker_t* LoadElevatorThinker(actionf_p1 thinker, UINT8 floorOrCeiling) + +static thinker_t* LoadElevatorThinker(actionf_p1 thinker, boolean setplanedata) { elevator_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); ht->thinker.function.acp1 = thinker; @@ -3165,25 +2903,39 @@ static thinker_t* LoadElevatorThinker(actionf_p1 thinker, UINT8 floorOrCeiling) ht->delaytimer = READFIXED(save_p); ht->floorwasheight = READFIXED(save_p); ht->ceilingwasheight = READFIXED(save_p); - ht->player = LoadPlayer(READUINT32(save_p)); // was dummy ht->sourceline = LoadLine(READUINT32(save_p)); - if (ht->sector) + if (ht->sector && setplanedata) { - if (floorOrCeiling & 2) - ht->sector->ceilingdata = ht; - if (floorOrCeiling & 1) - ht->sector->floordata = ht; + ht->sector->ceilingdata = ht; + ht->sector->floordata = ht; } return &ht->thinker; } -// -// LoadScrollThinker -// -// Loads a scroll_t from a save game -// +static thinker_t* LoadCrumbleThinker(actionf_p1 thinker) +{ + crumble_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); + ht->thinker.function.acp1 = thinker; + ht->sourceline = LoadLine(READUINT32(save_p)); + ht->sector = LoadSector(READUINT32(save_p)); + ht->actionsector = LoadSector(READUINT32(save_p)); + ht->player = LoadPlayer(READUINT32(save_p)); + ht->direction = READINT32(save_p); + ht->origalpha = READINT32(save_p); + ht->timer = READINT32(save_p); + ht->speed = READFIXED(save_p); + ht->floorwasheight = READFIXED(save_p); + ht->ceilingwasheight = READFIXED(save_p); + ht->flags = READUINT8(save_p); + + if (ht->sector) + ht->sector->floordata = ht; + + return &ht->thinker; +} + static thinker_t* LoadScrollThinker(actionf_p1 thinker) { scroll_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -3201,11 +2953,6 @@ static thinker_t* LoadScrollThinker(actionf_p1 thinker) return &ht->thinker; } -// -// LoadFrictionThinker -// -// Loads a friction_t from a save game -// static inline thinker_t* LoadFrictionThinker(actionf_p1 thinker) { friction_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -3218,11 +2965,6 @@ static inline thinker_t* LoadFrictionThinker(actionf_p1 thinker) return &ht->thinker; } -// -// LoadPusherThinker -// -// Loads a pusher_t from a save game -// static thinker_t* LoadPusherThinker(actionf_p1 thinker) { pusher_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -3244,31 +2986,16 @@ static thinker_t* LoadPusherThinker(actionf_p1 thinker) return &ht->thinker; } -// -// LoadLaserThinker -// -// Loads a laserthink_t from a save game -// static inline thinker_t* LoadLaserThinker(actionf_p1 thinker) { laserthink_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); - ffloor_t *rover = NULL; ht->thinker.function.acp1 = thinker; - ht->sector = LoadSector(READUINT32(save_p)); - ht->sec = LoadSector(READUINT32(save_p)); + ht->tag = READINT16(save_p); ht->sourceline = LoadLine(READUINT32(save_p)); - for (rover = ht->sector->ffloors; rover; rover = rover->next) - if (rover->secnum == (size_t)(ht->sec - sectors) - && rover->master == ht->sourceline) - ht->ffloor = rover; + ht->nobosses = READUINT8(save_p); return &ht->thinker; } -// -// LoadLightlevelThinker -// -// Loads a lightlevel_t from a save game -// static inline thinker_t* LoadLightlevelThinker(actionf_p1 thinker) { lightlevel_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -3284,11 +3011,6 @@ static inline thinker_t* LoadLightlevelThinker(actionf_p1 thinker) return &ht->thinker; } -// -// LoadExecutorThinker -// -// Loads a executor_t from a save game -// static inline thinker_t* LoadExecutorThinker(actionf_p1 thinker) { executor_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -3300,11 +3022,6 @@ static inline thinker_t* LoadExecutorThinker(actionf_p1 thinker) return &ht->thinker; } -// -// LoadDisappearThinker -// -// Loads a disappear_t thinker -// static inline thinker_t* LoadDisappearThinker(actionf_p1 thinker) { disappear_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -3319,11 +3036,6 @@ static inline thinker_t* LoadDisappearThinker(actionf_p1 thinker) return &ht->thinker; } -// -// LoadFadeThinker -// -// Loads a fade_t thinker -// static inline thinker_t* LoadFadeThinker(actionf_p1 thinker) { sector_t *ss; @@ -3366,10 +3078,6 @@ static inline thinker_t* LoadFadeThinker(actionf_p1 thinker) return &ht->thinker; } -// LoadFadeColormapThinker -// -// Loads a fadecolormap_t from a save game -// static inline thinker_t* LoadFadeColormapThinker(actionf_p1 thinker) { fadecolormap_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -3385,11 +3093,6 @@ static inline thinker_t* LoadFadeColormapThinker(actionf_p1 thinker) return &ht->thinker; } -// -// LoadPlaneDisplaceThinker -// -// Loads a planedisplace_t thinker -// static inline thinker_t* LoadPlaneDisplaceThinker(actionf_p1 thinker) { planedisplace_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -3403,7 +3106,6 @@ static inline thinker_t* LoadPlaneDisplaceThinker(actionf_p1 thinker) return &ht->thinker; } -/// Save a dynamic slope thinker. static inline thinker_t* LoadDynamicSlopeThinker(actionf_p1 thinker) { dynplanethink_t* ht = Z_Malloc(sizeof(*ht), PU_LEVSPEC, NULL); @@ -3418,13 +3120,6 @@ static inline thinker_t* LoadDynamicSlopeThinker(actionf_p1 thinker) return &ht->thinker; } -#ifdef POLYOBJECTS - -// -// LoadPolyrotateThinker -// -// Loads a polyrotate_t thinker -// static inline thinker_t* LoadPolyrotatetThinker(actionf_p1 thinker) { polyrotate_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -3435,11 +3130,6 @@ static inline thinker_t* LoadPolyrotatetThinker(actionf_p1 thinker) return &ht->thinker; } -// -// LoadPolymoveThinker -// -// Loads a polymovet_t thinker -// static thinker_t* LoadPolymoveThinker(actionf_p1 thinker) { polymove_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -3453,11 +3143,6 @@ static thinker_t* LoadPolymoveThinker(actionf_p1 thinker) return &ht->thinker; } -// -// LoadPolywaypointThinker -// -// Loads a polywaypoint_t thinker -// static inline thinker_t* LoadPolywaypointThinker(actionf_p1 thinker) { polywaypoint_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -3467,22 +3152,12 @@ static inline thinker_t* LoadPolywaypointThinker(actionf_p1 thinker) ht->sequence = READINT32(save_p); ht->pointnum = READINT32(save_p); ht->direction = READINT32(save_p); - ht->comeback = READUINT8(save_p); - ht->wrap = READUINT8(save_p); + ht->returnbehavior = READUINT8(save_p); ht->continuous = READUINT8(save_p); ht->stophere = READUINT8(save_p); - ht->diffx = READFIXED(save_p); - ht->diffy = READFIXED(save_p); - ht->diffz = READFIXED(save_p); - ht->target = LoadMobj(READUINT32(save_p)); return &ht->thinker; } -// -// LoadPolyslidedoorThinker -// -// loads a polyslidedoor_t thinker -// static inline thinker_t* LoadPolyslidedoorThinker(actionf_p1 thinker) { polyslidedoor_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -3503,11 +3178,6 @@ static inline thinker_t* LoadPolyslidedoorThinker(actionf_p1 thinker) return &ht->thinker; } -// -// LoadPolyswingdoorThinker -// -// Loads a polyswingdoor_t thinker -// static inline thinker_t* LoadPolyswingdoorThinker(actionf_p1 thinker) { polyswingdoor_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -3523,11 +3193,6 @@ static inline thinker_t* LoadPolyswingdoorThinker(actionf_p1 thinker) return &ht->thinker; } -// -// LoadPolydisplaceThinker -// -// Loads a polydisplace_t thinker -// static inline thinker_t* LoadPolydisplaceThinker(actionf_p1 thinker) { polydisplace_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -3552,11 +3217,6 @@ static inline thinker_t* LoadPolyrotdisplaceThinker(actionf_p1 thinker) return &ht->thinker; } -// -// LoadPolyfadeThinker -// -// Loads a polyfadet_t thinker -// static thinker_t* LoadPolyfadeThinker(actionf_p1 thinker) { polyfade_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -3571,24 +3231,7 @@ static thinker_t* LoadPolyfadeThinker(actionf_p1 thinker) ht->timer = READINT32(save_p); return &ht->thinker; } -#endif -/* -// -// LoadWhatThinker -// -// load a what_t thinker -// -static inline void LoadWhatThinker(actionf_p1 thinker) -{ - what_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); - ht->thinker.function.acp1 = thinker; -} -*/ - -// -// P_NetUnArchiveThinkers -// static void P_NetUnArchiveThinkers(void) { thinker_t *currentthinker; @@ -3673,7 +3316,7 @@ static void P_NetUnArchiveThinkers(void) break; case tc_elevator: - th = LoadElevatorThinker((actionf_p1)T_MoveElevator, 3); + th = LoadElevatorThinker((actionf_p1)T_MoveElevator, true); break; case tc_continuousfalling: @@ -3696,10 +3339,8 @@ static void P_NetUnArchiveThinkers(void) th = LoadRaiseThinker((actionf_p1)T_RaiseSector); break; - /// \todo rewrite all the code that uses an elevator_t but isn't an elevator - /// \note working on it! case tc_camerascanner: - th = LoadElevatorThinker((actionf_p1)T_CameraScanner, 0); + th = LoadElevatorThinker((actionf_p1)T_CameraScanner, false); break; case tc_bouncecheese: @@ -3707,7 +3348,7 @@ static void P_NetUnArchiveThinkers(void) break; case tc_startcrumble: - th = LoadElevatorThinker((actionf_p1)T_StartCrumble, 1); + th = LoadCrumbleThinker((actionf_p1)T_StartCrumble); break; case tc_marioblock: @@ -3750,7 +3391,6 @@ static void P_NetUnArchiveThinkers(void) case tc_planedisplace: th = LoadPlaneDisplaceThinker((actionf_p1)T_PlaneDisplace); break; -#ifdef POLYOBJECTS case tc_polyrotate: th = LoadPolyrotatetThinker((actionf_p1)T_PolyObjRotate); break; @@ -3761,7 +3401,6 @@ static void P_NetUnArchiveThinkers(void) case tc_polywaypoint: th = LoadPolywaypointThinker((actionf_p1)T_PolyObjWaypoint); - restoreNum = true; break; case tc_polyslidedoor: @@ -3787,7 +3426,6 @@ static void P_NetUnArchiveThinkers(void) case tc_polyfade: th = LoadPolyfadeThinker((actionf_p1)T_PolyObjFade); break; -#endif case tc_dynslopeline: th = LoadDynamicSlopeThinker((actionf_p1)T_DynamicSlopeLine); @@ -3822,7 +3460,6 @@ static void P_NetUnArchiveThinkers(void) if (restoreNum) { executor_t *delay = NULL; - polywaypoint_t *polywp = NULL; UINT32 mobjnum; for (currentthinker = thlist[THINK_MAIN].next; currentthinker != &thlist[THINK_MAIN]; currentthinker = currentthinker->next) { @@ -3833,15 +3470,6 @@ static void P_NetUnArchiveThinkers(void) continue; delay->caller = P_FindNewPosition(mobjnum); } - for (currentthinker = thlist[THINK_POLYOBJ].next; currentthinker != &thlist[THINK_POLYOBJ]; currentthinker = currentthinker->next) - { - if (currentthinker->function.acp1 != (actionf_p1)T_PolyObjWaypoint) - continue; - polywp = (void *)currentthinker; - if (!(mobjnum = (UINT32)(size_t)polywp->target)) - continue; - polywp->target = P_FindNewPosition(mobjnum); - } } } @@ -3849,7 +3477,6 @@ static void P_NetUnArchiveThinkers(void) // // haleyjd 03/26/06: PolyObject saving code // -#ifdef POLYOBJECTS #define PD_FLAGS 0x01 #define PD_TRANS 0x02 @@ -3938,10 +3565,7 @@ static inline void P_UnArchivePolyObjects(void) for (i = 0; i < numSavedPolys; ++i) P_UnArchivePolyObj(&PolyObjects[i]); } -#endif -// -// P_FinishMobjs -// + static inline void P_FinishMobjs(void) { thinker_t *currentthinker; @@ -4050,9 +3674,6 @@ static void P_RelinkPointers(void) } } -// -// P_NetArchiveSpecials -// static inline void P_NetArchiveSpecials(void) { size_t i, z; @@ -4093,9 +3714,6 @@ static inline void P_NetArchiveSpecials(void) WRITEUINT8(save_p, 0x00); } -// -// P_NetUnArchiveSpecials -// static void P_NetUnArchiveSpecials(void) { size_t i; @@ -4420,9 +4038,7 @@ void P_SaveNetGame(void) if (gamestate == GS_LEVEL) { P_NetArchiveWorld(); -#ifdef POLYOBJECTS P_ArchivePolyObjects(); -#endif P_NetArchiveThinkers(); P_NetArchiveSpecials(); P_NetArchiveColormaps(); @@ -4460,9 +4076,7 @@ boolean P_LoadNetGame(void) if (gamestate == GS_LEVEL) { P_NetUnArchiveWorld(); -#ifdef POLYOBJECTS P_UnArchivePolyObjects(); -#endif P_NetUnArchiveThinkers(); P_NetUnArchiveSpecials(); P_NetUnArchiveColormaps(); diff --git a/src/p_setup.c b/src/p_setup.c index 8c73b85e6..84e89d746 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -144,6 +144,133 @@ mapthing_t *playerstarts[MAXPLAYERS]; mapthing_t *bluectfstarts[MAXPLAYERS]; mapthing_t *redctfstarts[MAXPLAYERS]; +// Maintain waypoints +mobj_t *waypoints[NUMWAYPOINTSEQUENCES][WAYPOINTSEQUENCESIZE]; +UINT16 numwaypoints[NUMWAYPOINTSEQUENCES]; + +void P_AddWaypoint(UINT8 sequence, UINT8 id, mobj_t *waypoint) +{ + waypoints[sequence][id] = waypoint; + if (id >= numwaypoints[sequence]) + numwaypoints[sequence] = id + 1; +} + +static void P_ResetWaypoints(void) +{ + UINT16 sequence, id; + for (sequence = 0; sequence < NUMWAYPOINTSEQUENCES; sequence++) + { + for (id = 0; id < numwaypoints[sequence]; id++) + waypoints[sequence][id] = NULL; + + numwaypoints[sequence] = 0; + } +} + +mobj_t *P_GetFirstWaypoint(UINT8 sequence) +{ + return waypoints[sequence][0]; +} + +mobj_t *P_GetLastWaypoint(UINT8 sequence) +{ + return waypoints[sequence][numwaypoints[sequence] - 1]; +} + +mobj_t *P_GetPreviousWaypoint(mobj_t *current, boolean wrap) +{ + UINT8 sequence = current->threshold; + UINT8 id = current->health; + + if (id == 0) + { + if (!wrap) + return NULL; + + id = numwaypoints[sequence] - 1; + } + else + id--; + + return waypoints[sequence][id]; +} + +mobj_t *P_GetNextWaypoint(mobj_t *current, boolean wrap) +{ + UINT8 sequence = current->threshold; + UINT8 id = current->health; + + if (id == numwaypoints[sequence] - 1) + { + if (!wrap) + return NULL; + + id = 0; + } + else + id++; + + return waypoints[sequence][id]; +} + +mobj_t *P_GetClosestWaypoint(UINT8 sequence, mobj_t *mo) +{ + UINT8 wp; + mobj_t *mo2, *result = NULL; + fixed_t bestdist = 0; + fixed_t curdist; + + for (wp = 0; wp < numwaypoints[sequence]; wp++) + { + mo2 = waypoints[sequence][wp]; + + if (!mo2) + continue; + + curdist = P_AproxDistance(P_AproxDistance(mo->x - mo2->x, mo->y - mo2->y), mo->z - mo2->z); + + if (result && curdist > bestdist) + continue; + + result = mo2; + bestdist = curdist; + } + + return result; +} + +// Return true if all waypoints are in the same location +boolean P_IsDegeneratedWaypointSequence(UINT8 sequence) +{ + mobj_t *first, *waypoint; + UINT8 wp; + + if (numwaypoints[sequence] <= 1) + return true; + + first = waypoints[sequence][0]; + + for (wp = 1; wp < numwaypoints[sequence]; wp++) + { + waypoint = waypoints[sequence][wp]; + + if (!waypoint) + continue; + + if (waypoint->x != first->x) + return false; + + if (waypoint->y != first->y) + return false; + + if (waypoint->z != first->z) + return false; + } + + return true; +} + + /** Logs an error about a map being corrupt, then terminate. * This allows reporting highly technical errors for usefulness, without * confusing a novice map designer who simply needs to run ZenNode. @@ -218,6 +345,9 @@ static void P_ClearSingleMapHeaderInfo(INT16 i) mapheaderinfo[num]->typeoflevel = 0; mapheaderinfo[num]->nextlevel = (INT16)(i + 1); mapheaderinfo[num]->startrings = 0; + mapheaderinfo[num]->sstimer = 90; + mapheaderinfo[num]->ssspheres = 1; + mapheaderinfo[num]->gravity = FRACUNIT/2; mapheaderinfo[num]->keywords[0] = '\0'; snprintf(mapheaderinfo[num]->musname, 7, "%sM", G_BuildMapName(i)); mapheaderinfo[num]->musname[6] = 0; @@ -953,9 +1083,7 @@ static void P_InitializeLinedef(line_t *ld) ld->splats = NULL; #endif ld->firsttag = ld->nexttag = -1; -#ifdef POLYOBJECTS ld->polyobj = NULL; -#endif ld->text = NULL; ld->callcount = 0; @@ -1869,10 +1997,8 @@ static void P_InitializeSeg(seg_t *seg) seg->numlights = 0; seg->rlights = NULL; -#ifdef POLYOBJECTS seg->polyseg = NULL; seg->dontrenderme = false; -#endif } static void P_LoadSegs(UINT8 *data) @@ -2235,11 +2361,9 @@ static boolean P_LoadBlockMap(UINT8 *data, size_t count) blocklinks = Z_Calloc(count, PU_LEVEL, NULL); blockmap = blockmaplump+4; -#ifdef POLYOBJECTS // haleyjd 2/22/06: setup polyobject blockmap count = sizeof(*polyblocklinks) * bmapwidth * bmapheight; polyblocklinks = Z_Calloc(count, PU_LEVEL, NULL); -#endif return true; } @@ -2490,11 +2614,9 @@ static void P_CreateBlockMap(void) blocklinks = Z_Calloc(count, PU_LEVEL, NULL); blockmap = blockmaplump + 4; -#ifdef POLYOBJECTS // haleyjd 2/22/06: setup polyobject blockmap count = sizeof(*polyblocklinks) * bmapwidth * bmapheight; polyblocklinks = Z_Calloc(count, PU_LEVEL, NULL); -#endif } } @@ -3550,6 +3672,8 @@ boolean P_LoadLevel(boolean fromnetsave) P_ResetSpawnpoints(); + P_ResetWaypoints(); + P_MapStart(); if (!P_LoadMapFromFile()) diff --git a/src/p_sight.c b/src/p_sight.c index 3d1ee9e60..2e1e49997 100644 --- a/src/p_sight.c +++ b/src/p_sight.c @@ -100,7 +100,6 @@ static fixed_t P_InterceptVector2(divline_t *v2, divline_t *v1) return frac; } -#ifdef POLYOBJECTS static boolean P_CrossSubsecPolyObj(polyobj_t *po, register los_t *los) { size_t i; @@ -169,7 +168,6 @@ static boolean P_CrossSubsecPolyObj(polyobj_t *po, register los_t *los) return true; } -#endif // // P_CrossSubsector @@ -180,9 +178,7 @@ static boolean P_CrossSubsector(size_t num, register los_t *los) { seg_t *seg; INT32 count; -#ifdef POLYOBJECTS polyobj_t *po; // haleyjd 02/23/06 -#endif #ifdef RANGECHECK if (num >= numsubsectors) @@ -192,7 +188,6 @@ static boolean P_CrossSubsector(size_t num, register los_t *los) // haleyjd 02/23/06: this assignment should be after the above check seg = segs + subsectors[num].firstline; -#ifdef POLYOBJECTS // haleyjd 02/23/06: check polyobject lines if ((po = subsectors[num].polyList)) { @@ -207,7 +202,6 @@ static boolean P_CrossSubsector(size_t num, register los_t *los) po = (polyobj_t *)(po->link.next); } } -#endif for (count = subsectors[num].numlines; --count >= 0; seg++) // check lines { @@ -265,10 +259,10 @@ static boolean P_CrossSubsector(size_t num, register los_t *los) fracx = los->strace.x + FixedMul(los->strace.dx, frac); fracy = los->strace.y + FixedMul(los->strace.dy, frac); // calculate sector heights - frontf = (front->f_slope) ? P_GetZAt(front->f_slope, fracx, fracy) : front->floorheight; - frontc = (front->c_slope) ? P_GetZAt(front->c_slope, fracx, fracy) : front->ceilingheight; - backf = (back->f_slope) ? P_GetZAt(back->f_slope, fracx, fracy) : back->floorheight; - backc = (back->c_slope) ? P_GetZAt(back->c_slope, fracx, fracy) : back->ceilingheight; + frontf = P_GetSectorFloorZAt (front, fracx, fracy); + frontc = P_GetSectorCeilingZAt(front, fracx, fracy); + backf = P_GetSectorFloorZAt (back , fracx, fracy); + backc = P_GetSectorCeilingZAt(back , fracx, fracy); // crosses a two sided line // no wall to block sight with? if (frontf == backf && frontc == backc @@ -318,10 +312,10 @@ static boolean P_CrossSubsector(size_t num, register los_t *los) continue; } - topz = (*rover->t_slope) ? P_GetZAt(*rover->t_slope, fracx, fracy) : *rover->topheight; - bottomz = (*rover->b_slope) ? P_GetZAt(*rover->b_slope, fracx, fracy) : *rover->bottomheight; - topslope = FixedDiv(topz - los->sightzstart , frac); - bottomslope = FixedDiv(bottomz - los->sightzstart , frac); + topz = P_GetFFloorTopZAt (rover, fracx, fracy); + bottomz = P_GetFFloorBottomZAt(rover, fracx, fracy); + topslope = FixedDiv( topz - los->sightzstart, frac); + bottomslope = FixedDiv(bottomz - los->sightzstart, frac); if (topslope >= los->topslope && bottomslope <= los->bottomslope) return false; // view completely blocked } @@ -334,10 +328,10 @@ static boolean P_CrossSubsector(size_t num, register los_t *los) continue; } - topz = (*rover->t_slope) ? P_GetZAt(*rover->t_slope, fracx, fracy) : *rover->topheight; - bottomz = (*rover->b_slope) ? P_GetZAt(*rover->b_slope, fracx, fracy) : *rover->bottomheight; - topslope = FixedDiv(topz - los->sightzstart , frac); - bottomslope = FixedDiv(bottomz - los->sightzstart , frac); + topz = P_GetFFloorTopZAt (rover, fracx, fracy); + bottomz = P_GetFFloorBottomZAt(rover, fracx, fracy); + topslope = FixedDiv( topz - los->sightzstart, frac); + bottomslope = FixedDiv(bottomz - los->sightzstart, frac); if (topslope >= los->topslope && bottomslope <= los->bottomslope) return false; // view completely blocked } @@ -413,15 +407,10 @@ boolean P_CheckSight(mobj_t *t1, mobj_t *t2) // killough 11/98: shortcut for melee situations // same subsector? obviously visible -#ifndef POLYOBJECTS - if (t1->subsector == t2->subsector) - return true; -#else // haleyjd 02/23/06: can't do this if there are polyobjects in the subsec if (!t1->subsector->polyList && t1->subsector == t2->subsector) return true; -#endif // An unobstructed LOS is possible. // Now look from eyes of t1 to any part of t2. @@ -468,21 +457,10 @@ boolean P_CheckSight(mobj_t *t1, mobj_t *t2) continue; } - if (*rover->t_slope) - { - topz1 = P_GetZAt(*rover->t_slope, t1->x, t1->y); - topz2 = P_GetZAt(*rover->t_slope, t2->x, t2->y); - } - else - topz1 = topz2 = *rover->topheight; - - if (*rover->b_slope) - { - bottomz1 = P_GetZAt(*rover->b_slope, t1->x, t1->y); - bottomz2 = P_GetZAt(*rover->b_slope, t2->x, t2->y); - } - else - bottomz1 = bottomz2 = *rover->bottomheight; + topz1 = P_GetFFloorTopZAt (rover, t1->x, t1->y); + topz2 = P_GetFFloorTopZAt (rover, t2->x, t2->y); + bottomz1 = P_GetFFloorBottomZAt(rover, t1->x, t1->y); + bottomz2 = P_GetFFloorBottomZAt(rover, t2->x, t2->y); // Check for blocking floors here. if ((los.sightzstart < bottomz1 && t2->z >= topz2) diff --git a/src/p_slopes.c b/src/p_slopes.c index 4b5838077..6aeb1b025 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -566,7 +566,7 @@ void P_CopySectorSlope(line_t *line) int i, special = line->special; // Check for copy linedefs - for (i = -1; (i = P_FindSectorFromLineTag(line, i)) >= 0;) + for (i = -1; (i = P_FindSectorFromTag(line->tag, i)) >= 0;) { sector_t *srcsec = sectors + i; @@ -655,17 +655,49 @@ void P_SpawnSlopes(const boolean fromsave) { // Various utilities related to slopes // -// -// P_GetZAt -// // Returns the height of the sloped plane at (x, y) as a fixed_t -// -fixed_t P_GetZAt(pslope_t *slope, fixed_t x, fixed_t y) +fixed_t P_GetSlopeZAt(const pslope_t *slope, fixed_t x, fixed_t y) { - fixed_t dist = FixedMul(x - slope->o.x, slope->d.x) + - FixedMul(y - slope->o.y, slope->d.y); + fixed_t dist = FixedMul(x - slope->o.x, slope->d.x) + + FixedMul(y - slope->o.y, slope->d.y); - return slope->o.z + FixedMul(dist, slope->zdelta); + return slope->o.z + FixedMul(dist, slope->zdelta); +} + +// Like P_GetSlopeZAt but falls back to z if slope is NULL +fixed_t P_GetZAt(const pslope_t *slope, fixed_t x, fixed_t y, fixed_t z) +{ + return slope ? P_GetSlopeZAt(slope, x, y) : z; +} + +// Returns the height of the sector floor at (x, y) +fixed_t P_GetSectorFloorZAt(const sector_t *sector, fixed_t x, fixed_t y) +{ + return sector->f_slope ? P_GetSlopeZAt(sector->f_slope, x, y) : sector->floorheight; +} + +// Returns the height of the sector ceiling at (x, y) +fixed_t P_GetSectorCeilingZAt(const sector_t *sector, fixed_t x, fixed_t y) +{ + return sector->c_slope ? P_GetSlopeZAt(sector->c_slope, x, y) : sector->ceilingheight; +} + +// Returns the height of the FOF top at (x, y) +fixed_t P_GetFFloorTopZAt(const ffloor_t *ffloor, fixed_t x, fixed_t y) +{ + return *ffloor->t_slope ? P_GetSlopeZAt(*ffloor->t_slope, x, y) : *ffloor->topheight; +} + +// Returns the height of the FOF bottom at (x, y) +fixed_t P_GetFFloorBottomZAt(const ffloor_t *ffloor, fixed_t x, fixed_t y) +{ + return *ffloor->b_slope ? P_GetSlopeZAt(*ffloor->b_slope, x, y) : *ffloor->bottomheight; +} + +// Returns the height of the light list at (x, y) +fixed_t P_GetLightZAt(const lightlist_t *light, fixed_t x, fixed_t y) +{ + return light->slope ? P_GetSlopeZAt(light->slope, x, y) : light->height; } diff --git a/src/p_slopes.h b/src/p_slopes.h index e7c850ab8..06d900b66 100644 --- a/src/p_slopes.h +++ b/src/p_slopes.h @@ -33,7 +33,21 @@ void P_CopySectorSlope(line_t *line); pslope_t *P_SlopeById(UINT16 id); // Returns the height of the sloped plane at (x, y) as a fixed_t -fixed_t P_GetZAt(pslope_t *slope, fixed_t x, fixed_t y); +fixed_t P_GetSlopeZAt(const pslope_t *slope, fixed_t x, fixed_t y); + +// Like P_GetSlopeZAt but falls back to z if slope is NULL +fixed_t P_GetZAt(const pslope_t *slope, fixed_t x, fixed_t y, fixed_t z); + +// Returns the height of the sector at (x, y) +fixed_t P_GetSectorFloorZAt (const sector_t *sector, fixed_t x, fixed_t y); +fixed_t P_GetSectorCeilingZAt(const sector_t *sector, fixed_t x, fixed_t y); + +// Returns the height of the FOF at (x, y) +fixed_t P_GetFFloorTopZAt (const ffloor_t *ffloor, fixed_t x, fixed_t y); +fixed_t P_GetFFloorBottomZAt(const ffloor_t *ffloor, fixed_t x, fixed_t y); + +// Returns the height of the light list at (x, y) +fixed_t P_GetLightZAt(const lightlist_t *light, fixed_t x, fixed_t y); // Lots of physics-based bullshit void P_QuantizeMomentumToSlope(vector3_t *momentum, pslope_t *slope); diff --git a/src/p_spec.c b/src/p_spec.c index 88a1bee90..57ae42c69 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -987,42 +987,12 @@ static sector_t *P_FindModelCeilingSector(fixed_t ceildestheight, INT32 secnum) } #endif -/** Searches the tag lists for the next sector tagged to a line. - * - * \param line Tagged line used as a reference. - * \param start -1 to start at the beginning, or the result of a previous call - * to keep searching. - * \return Number of the next tagged sector found. - * \sa P_FindSectorFromTag, P_FindLineFromLineTag - */ -INT32 P_FindSectorFromLineTag(line_t *line, INT32 start) -{ - if (line->tag == -1) - { - start++; - - if (start >= (INT32)numsectors) - return -1; - - return start; - } - else - { - start = start >= 0 ? sectors[start].nexttag : - sectors[(unsigned)line->tag % numsectors].firsttag; - while (start >= 0 && sectors[start].tag != line->tag) - start = sectors[start].nexttag; - return start; - } -} - /** Searches the tag lists for the next sector with a given tag. * * \param tag Tag number to look for. * \param start -1 to start anew, or the result of a previous call to keep * searching. * \return Number of the next tagged sector found. - * \sa P_FindSectorFromLineTag */ INT32 P_FindSectorFromTag(INT16 tag, INT32 start) { @@ -1045,42 +1015,12 @@ INT32 P_FindSectorFromTag(INT16 tag, INT32 start) } } -/** Searches the tag lists for the next line tagged to a line. - * - * \param line Tagged line used as a reference. - * \param start -1 to start anew, or the result of a previous call to keep - * searching. - * \return Number of the next tagged line found. - * \sa P_FindSectorFromLineTag - */ -static INT32 P_FindLineFromLineTag(const line_t *line, INT32 start) -{ - if (line->tag == -1) - { - start++; - - if (start >= (INT32)numlines) - return -1; - - return start; - } - else - { - start = start >= 0 ? lines[start].nexttag : - lines[(unsigned)line->tag % numlines].firsttag; - while (start >= 0 && lines[start].tag != line->tag) - start = lines[start].nexttag; - return start; - } -} -#if 0 /** Searches the tag lists for the next line with a given tag and special. * * \param tag Tag number. * \param start -1 to start anew, or the result of a previous call to keep * searching. * \return Number of next suitable line found. - * \sa P_FindLineFromLineTag * \author Graue */ static INT32 P_FindLineFromTag(INT32 tag, INT32 start) @@ -1089,7 +1029,7 @@ static INT32 P_FindLineFromTag(INT32 tag, INT32 start) { start++; - if (start >= numlines) + if (start >= (INT32)numlines) return -1; return start; @@ -1103,10 +1043,7 @@ static INT32 P_FindLineFromTag(INT32 tag, INT32 start) return start; } } -#endif -// -// P_FindSpecialLineFromTag -// + INT32 P_FindSpecialLineFromTag(INT16 special, INT16 tag, INT32 start) { if (tag == -1) @@ -1136,14 +1073,8 @@ INT32 P_FindSpecialLineFromTag(INT16 special, INT16 tag, INT32 start) } } -// haleyjd: temporary define -#ifdef POLYOBJECTS -// -// PolyDoor -// // Parses arguments for parameterized polyobject door types -// static boolean PolyDoor(line_t *line) { polydoordata_t pdd; @@ -1180,11 +1111,7 @@ static boolean PolyDoor(line_t *line) return EV_DoPolyDoor(&pdd); } -// -// PolyMove -// // Parses arguments for parameterized polyobject move specials -// static boolean PolyMove(line_t *line) { polymovedata_t pmd; @@ -1199,12 +1126,8 @@ static boolean PolyMove(line_t *line) return EV_DoPolyObjMove(&pmd); } -// -// PolyInvisible -// // Makes a polyobject invisible and intangible // If NOCLIMB is ticked, the polyobject will still be tangible, just not visible. -// static void PolyInvisible(line_t *line) { INT32 polyObjNum = line->tag; @@ -1227,12 +1150,8 @@ static void PolyInvisible(line_t *line) po->flags &= ~POF_RENDERALL; } -// -// PolyVisible -// // Makes a polyobject visible and tangible // If NOCLIMB is ticked, the polyobject will not be tangible, just visible. -// static void PolyVisible(line_t *line) { INT32 polyObjNum = line->tag; @@ -1255,16 +1174,14 @@ static void PolyVisible(line_t *line) po->flags |= (po->spawnflags & POF_RENDERALL); } -// -// PolyTranslucency -// + // Sets the translucency of a polyobject // Frontsector floor / 100 = translevel -// static void PolyTranslucency(line_t *line) { INT32 polyObjNum = line->tag; polyobj_t *po; + INT32 value; if (!(po = Polyobj_GetForNum(polyObjNum))) { @@ -1276,37 +1193,28 @@ static void PolyTranslucency(line_t *line) if (po->isBad) return; - // if DONTPEGBOTTOM, specify raw translucency value in Front X Offset - // else, take it out of 1000. If Front X Offset is specified, use that. Else, use floorheight. + // If Front X Offset is specified, use that. Else, use floorheight. + value = (sides[line->sidenum[0]].textureoffset ? sides[line->sidenum[0]].textureoffset : line->frontsector->floorheight) >> FRACBITS; + + // If DONTPEGBOTTOM, specify raw translucency value. Else, take it out of 1000. + if (!(line->flags & ML_DONTPEGBOTTOM)) + value /= 100; + if (line->flags & ML_EFFECT3) // relative calc - po->translucency = max(min(po->translucency + ((line->flags & ML_DONTPEGBOTTOM) ? - (sides[line->sidenum[0]].textureoffset ? - max(min(sides[line->sidenum[0]].textureoffset>>FRACBITS, NUMTRANSMAPS), -NUMTRANSMAPS) - : max(min(line->frontsector->floorheight>>FRACBITS, NUMTRANSMAPS), -NUMTRANSMAPS)) - : (sides[line->sidenum[0]].textureoffset ? - max(min(sides[line->sidenum[0]].textureoffset>>FRACBITS, 1000), -1000) / 100 - : max(min(line->frontsector->floorheight>>FRACBITS, 1000), -1000) / 100)), - NUMTRANSMAPS), 0); + po->translucency += value; else - po->translucency = (line->flags & ML_DONTPEGBOTTOM) ? - (sides[line->sidenum[0]].textureoffset ? - max(min(sides[line->sidenum[0]].textureoffset>>FRACBITS, NUMTRANSMAPS), 0) - : max(min(line->frontsector->floorheight>>FRACBITS, NUMTRANSMAPS), 0)) - : (sides[line->sidenum[0]].textureoffset ? - max(min(sides[line->sidenum[0]].textureoffset>>FRACBITS, 1000), 0) / 100 - : max(min(line->frontsector->floorheight>>FRACBITS, 1000), 0) / 100); + po->translucency = value; + + po->translucency = max(min(po->translucency, NUMTRANSMAPS), 0); } -// -// PolyFade -// // Makes a polyobject translucency fade and applies tangibility -// static boolean PolyFade(line_t *line) { INT32 polyObjNum = line->tag; polyobj_t *po; polyfadedata_t pfd; + INT32 value; if (!(po = Polyobj_GetForNum(polyObjNum))) { @@ -1329,25 +1237,19 @@ static boolean PolyFade(line_t *line) pfd.polyObjNum = polyObjNum; - // if DONTPEGBOTTOM, specify raw translucency value in Front X Offset - // else, take it out of 1000. If Front X Offset is specified, use that. Else, use floorheight. + // If Front X Offset is specified, use that. Else, use floorheight. + value = (sides[line->sidenum[0]].textureoffset ? sides[line->sidenum[0]].textureoffset : line->frontsector->floorheight) >> FRACBITS; + + // If DONTPEGBOTTOM, specify raw translucency value. Else, take it out of 1000. + if (!(line->flags & ML_DONTPEGBOTTOM)) + value /= 100; + if (line->flags & ML_EFFECT3) // relative calc - pfd.destvalue = max(min(po->translucency + ((line->flags & ML_DONTPEGBOTTOM) ? - (sides[line->sidenum[0]].textureoffset ? - max(min(sides[line->sidenum[0]].textureoffset>>FRACBITS, NUMTRANSMAPS), -NUMTRANSMAPS) - : max(min(line->frontsector->floorheight>>FRACBITS, NUMTRANSMAPS), -NUMTRANSMAPS)) - : (sides[line->sidenum[0]].textureoffset ? - max(min(sides[line->sidenum[0]].textureoffset>>FRACBITS, 1000), -1000) / 100 - : max(min(line->frontsector->floorheight>>FRACBITS, 1000), -1000) / 100)), - NUMTRANSMAPS), 0); + pfd.destvalue = po->translucency + value; else - pfd.destvalue = (line->flags & ML_DONTPEGBOTTOM) ? - (sides[line->sidenum[0]].textureoffset ? - max(min(sides[line->sidenum[0]].textureoffset>>FRACBITS, NUMTRANSMAPS), 0) - : max(min(line->frontsector->floorheight>>FRACBITS, NUMTRANSMAPS), 0)) - : (sides[line->sidenum[0]].textureoffset ? - max(min(sides[line->sidenum[0]].textureoffset>>FRACBITS, 1000), 0) / 100 - : max(min(line->frontsector->floorheight>>FRACBITS, 1000), 0) / 100); + pfd.destvalue = value; + + pfd.destvalue = max(min(pfd.destvalue, NUMTRANSMAPS), 0); // already equal, nothing to do if (po->translucency == pfd.destvalue) @@ -1366,11 +1268,7 @@ static boolean PolyFade(line_t *line) return EV_DoPolyObjFade(&pfd); } -// -// PolyWaypoint -// // Parses arguments for parameterized polyobject waypoint movement -// static boolean PolyWaypoint(line_t *line) { polywaypointdata_t pwd; @@ -1378,19 +1276,26 @@ static boolean PolyWaypoint(line_t *line) pwd.polyObjNum = line->tag; pwd.speed = sides[line->sidenum[0]].textureoffset / 8; pwd.sequence = sides[line->sidenum[0]].rowoffset >> FRACBITS; // Sequence # - pwd.reverse = (line->flags & ML_EFFECT1) == ML_EFFECT1; // Reverse? - pwd.comeback = (line->flags & ML_EFFECT2) == ML_EFFECT2; // Return when reaching end? - pwd.wrap = (line->flags & ML_EFFECT3) == ML_EFFECT3; // Wrap around waypoints - pwd.continuous = (line->flags & ML_EFFECT4) == ML_EFFECT4; // Continuously move - used with COMEBACK or WRAP + + // Behavior after reaching the last waypoint? + if (line->flags & ML_EFFECT3) + pwd.returnbehavior = PWR_WRAP; // Wrap back to first waypoint + else if (line->flags & ML_EFFECT2) + pwd.returnbehavior = PWR_COMEBACK; // Go through sequence in reverse + else + pwd.returnbehavior = PWR_STOP; // Stop + + // Flags + pwd.flags = 0; + if (line->flags & ML_EFFECT1) + pwd.flags |= PWF_REVERSE; + if (line->flags & ML_EFFECT4) + pwd.flags |= PWF_LOOP; return EV_DoPolyObjWaypoint(&pwd); } -// -// PolyRotate -// // Parses arguments for parameterized polyobject rotate specials -// static boolean PolyRotate(line_t *line) { polyrotdata_t prd; @@ -1415,11 +1320,20 @@ static boolean PolyRotate(line_t *line) return EV_DoPolyObjRotate(&prd); } -// -// PolyDisplace -// +// Parses arguments for polyobject flag waving special +static boolean PolyFlag(line_t *line) +{ + polyflagdata_t pfd; + + pfd.polyObjNum = line->tag; + pfd.speed = P_AproxDistance(line->dx, line->dy) >> FRACBITS; + pfd.angle = R_PointToAngle2(line->v1->x, line->v1->y, line->v2->x, line->v2->y) >> ANGLETOFINESHIFT; + pfd.momx = sides[line->sidenum[0]].textureoffset >> FRACBITS; + + return EV_DoPolyObjFlag(&pfd); +} + // Parses arguments for parameterized polyobject move-by-sector-heights specials -// static boolean PolyDisplace(line_t *line) { polydisplacedata_t pdd; @@ -1434,8 +1348,7 @@ static boolean PolyDisplace(line_t *line) } -/** Similar to PolyDisplace(). - */ +// Parses arguments for parameterized polyobject rotate-by-sector-heights specials static boolean PolyRotDisplace(line_t *line) { polyrotdisplacedata_t pdd; @@ -1461,8 +1374,6 @@ static boolean PolyRotDisplace(line_t *line) return EV_DoPolyObjRotDisplace(&pdd); } -#endif // ifdef POLYOBJECTS - /** Changes a sector's tag. * Used by the linedef executor tag changer and by crumblers. * @@ -2500,7 +2411,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) newceilinglightsec = line->frontsector->ceilinglightsec; // act on all sectors with the same tag as the triggering linedef - while ((secnum = P_FindSectorFromLineTag(line, secnum)) >= 0) + while ((secnum = P_FindSectorFromTag(line->tag, secnum)) >= 0) { if (sectors[secnum].lightingdata) { @@ -2555,7 +2466,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) case 409: // Change tagged sectors' tag // (formerly "Change calling sectors' tag", but behavior was changed) { - while ((secnum = P_FindSectorFromLineTag(line, secnum)) >= 0) + while ((secnum = P_FindSectorFromTag(line->tag, secnum)) >= 0) P_ChangeSectorTag(secnum,(INT16)(sides[line->sidenum[0]].textureoffset>>FRACBITS)); break; } @@ -2565,7 +2476,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) break; case 411: // Stop floor/ceiling movement in tagged sector(s) - while ((secnum = P_FindSectorFromLineTag(line, secnum)) >= 0) + while ((secnum = P_FindSectorFromTag(line->tag, secnum)) >= 0) { if (sectors[secnum].floordata) { @@ -2635,7 +2546,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) } else { - if ((secnum = P_FindSectorFromLineTag(line, -1)) < 0) + if ((secnum = P_FindSectorFromTag(line->tag, -1)) < 0) return; dest = P_GetObjectTypeInSectorNum(MT_TELEPORTMAN, secnum); @@ -2750,7 +2661,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) // Additionally play the sound from tagged sectors' soundorgs sector_t *sec; - while ((secnum = P_FindSectorFromLineTag(line, secnum)) >= 0) + while ((secnum = P_FindSectorFromTag(line->tag, secnum)) >= 0) { sec = §ors[secnum]; S_StartSound(&sec->soundorg, sfxnum); @@ -2865,7 +2776,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) break; case 416: // Spawn adjustable fire flicker - while ((secnum = P_FindSectorFromLineTag(line, secnum)) >= 0) + while ((secnum = P_FindSectorFromTag(line->tag, secnum)) >= 0) { if (line->flags & ML_NOCLIMB && line->backsector) { @@ -2899,7 +2810,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) break; case 417: // Spawn adjustable glowing light - while ((secnum = P_FindSectorFromLineTag(line, secnum)) >= 0) + while ((secnum = P_FindSectorFromTag(line->tag, secnum)) >= 0) { if (line->flags & ML_NOCLIMB && line->backsector) { @@ -2933,7 +2844,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) break; case 418: // Spawn adjustable strobe flash (unsynchronized) - while ((secnum = P_FindSectorFromLineTag(line, secnum)) >= 0) + while ((secnum = P_FindSectorFromTag(line->tag, secnum)) >= 0) { if (line->flags & ML_NOCLIMB && line->backsector) { @@ -2967,7 +2878,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) break; case 419: // Spawn adjustable strobe flash (synchronized) - while ((secnum = P_FindSectorFromLineTag(line, secnum)) >= 0) + while ((secnum = P_FindSectorFromTag(line->tag, secnum)) >= 0) { if (line->flags & ML_NOCLIMB && line->backsector) { @@ -3015,7 +2926,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) break; case 421: // Stop lighting effect in tagged sectors - while ((secnum = P_FindSectorFromLineTag(line, secnum)) >= 0) + while ((secnum = P_FindSectorFromTag(line->tag, secnum)) >= 0) if (sectors[secnum].lightingdata) { P_RemoveThinker(&((elevator_t *)sectors[secnum].lightingdata)->thinker); @@ -3030,7 +2941,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) if ((!mo || !mo->player) && !titlemapinaction) // only players have views, and title screens return; - if ((secnum = P_FindSectorFromLineTag(line, -1)) < 0) + if ((secnum = P_FindSectorFromTag(line->tag, -1)) < 0) return; altview = P_GetObjectTypeInSectorNum(MT_ALTVIEWMAN, secnum); @@ -3349,7 +3260,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) if (line->sidenum[1] != 0xffff) state = (statenum_t)sides[line->sidenum[1]].toptexture; - while ((secnum = P_FindSectorFromLineTag(line, secnum)) >= 0) + while ((secnum = P_FindSectorFromTag(line->tag, secnum)) >= 0) { boolean tryagain; sec = sectors + secnum; @@ -3504,7 +3415,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) // Except it is activated by linedef executor, not level load // This could even override existing colormaps I believe // -- Monster Iestyn 14/06/18 - for (secnum = -1; (secnum = P_FindSectorFromLineTag(line, secnum)) >= 0 ;) + for (secnum = -1; (secnum = P_FindSectorFromTag(line->tag, secnum)) >= 0 ;) { P_ResetColormapFader(§ors[secnum]); @@ -3832,7 +3743,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) } case 455: // Fade colormap - for (secnum = -1; (secnum = P_FindSectorFromLineTag(line, secnum)) >= 0 ;) + for (secnum = -1; (secnum = P_FindSectorFromTag(line->tag, secnum)) >= 0 ;) { extracolormap_t *source_exc, *dest_exc, *exc; INT32 speed = (INT32)((line->flags & ML_DONTPEGBOTTOM) || !sides[line->sidenum[0]].rowoffset) && line->sidenum[1] != 0xFFFF ? @@ -3921,7 +3832,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) break; case 456: // Stop fade colormap - for (secnum = -1; (secnum = P_FindSectorFromLineTag(line, secnum)) >= 0 ;) + for (secnum = -1; (secnum = P_FindSectorFromTag(line->tag, secnum)) >= 0 ;) P_ResetColormapFader(§ors[secnum]); break; @@ -3935,7 +3846,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) boolean persist = (line->flags & ML_EFFECT2); mobj_t *anchormo; - if ((secnum = P_FindSectorFromLineTag(line, -1)) < 0) + if ((secnum = P_FindSectorFromTag(line->tag, -1)) < 0) return; anchormo = P_GetObjectTypeInSectorNum(MT_ANGLEMAN, secnum); @@ -4060,7 +3971,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) if (mo) { - if (color < 0 || color >= MAXTRANSLATIONS) + if (color < 0 || color >= numskincolors) return; var1 = 0; @@ -4070,7 +3981,47 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) } break; -#ifdef POLYOBJECTS + case 464: // Trigger Egg Capsule + { + thinker_t *th; + mobj_t *mo2; + + // Find the center of the Eggtrap and release all the pretty animals! + // The chimps are my friends.. heeheeheheehehee..... - LouisJM + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) + { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + + mo2 = (mobj_t *)th; + + if (mo2->type != MT_EGGTRAP) + continue; + + if (!mo2->spawnpoint) + continue; + + if (mo2->spawnpoint->angle != line->tag) + continue; + + P_KillMobj(mo2, NULL, mo, 0); + } + + if (!(line->flags & ML_NOCLIMB)) + { + INT32 i; + + // Mark all players with the time to exit thingy! + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + continue; + P_DoPlayerExit(&players[i]); + } + } + } + break; + case 480: // Polyobj_DoorSlide case 481: // Polyobj_DoorSwing PolyDoor(line); @@ -4100,7 +4051,6 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) case 492: PolyFade(line); break; -#endif default: break; @@ -4860,9 +4810,7 @@ DoneSection2: INT32 sequence; fixed_t speed; INT32 lineindex; - thinker_t *th; mobj_t *waypoint = NULL; - mobj_t *mo2; angle_t an; if (player->mo->tracer && player->mo->tracer->type == MT_TUBEWAYPOINT && player->powers[pw_carry] == CR_ZOOMTUBE) @@ -4887,25 +4835,7 @@ DoneSection2: break; } - // scan the thinkers - // to find the first waypoint - for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) - { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) - continue; - - mo2 = (mobj_t *)th; - - if (mo2->type != MT_TUBEWAYPOINT) - continue; - if (mo2->threshold != sequence) - continue; - if (mo2->health != 0) - continue; - - waypoint = mo2; - break; - } + waypoint = P_GetFirstWaypoint(sequence); if (!waypoint) { @@ -4942,9 +4872,7 @@ DoneSection2: INT32 sequence; fixed_t speed; INT32 lineindex; - thinker_t *th; mobj_t *waypoint = NULL; - mobj_t *mo2; angle_t an; if (player->mo->tracer && player->mo->tracer->type == MT_TUBEWAYPOINT && player->powers[pw_carry] == CR_ZOOMTUBE) @@ -4969,25 +4897,7 @@ DoneSection2: break; } - // scan the thinkers - // to find the last waypoint - for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) - { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) - continue; - - mo2 = (mobj_t *)th; - - if (mo2->type != MT_TUBEWAYPOINT) - continue; - if (mo2->threshold != sequence) - continue; - - if (!waypoint) - waypoint = mo2; - else if (mo2->health > waypoint->health) - waypoint = mo2; - } + waypoint = P_GetLastWaypoint(sequence); if (!waypoint) { @@ -5069,14 +4979,11 @@ DoneSection2: INT32 sequence; fixed_t speed; INT32 lineindex; - thinker_t *th; mobj_t *waypointmid = NULL; mobj_t *waypointhigh = NULL; mobj_t *waypointlow = NULL; - mobj_t *mo2; mobj_t *closest = NULL; vector3_t p, line[2], resulthigh, resultlow; - mobj_t *highest = NULL; if (player->mo->tracer && player->mo->tracer->type == MT_TUBEWAYPOINT && player->powers[pw_carry] == CR_ROPEHANG) break; @@ -5122,98 +5029,16 @@ DoneSection2: // Determine the closest spot on the line between the three waypoints // Put player at that location. - // scan the thinkers - // to find the first waypoint - for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) - { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) - continue; + waypointmid = P_GetClosestWaypoint(sequence, player->mo); - mo2 = (mobj_t *)th; - - if (mo2->type != MT_TUBEWAYPOINT) - continue; - - if (mo2->threshold != sequence) - continue; - - if (!highest) - highest = mo2; - else if (mo2->health > highest->health) // Find the highest waypoint # in case we wrap - highest = mo2; - - if (closest && P_AproxDistance(P_AproxDistance(player->mo->x-mo2->x, player->mo->y-mo2->y), - player->mo->z-mo2->z) > P_AproxDistance(P_AproxDistance(player->mo->x-closest->x, - player->mo->y-closest->y), player->mo->z-closest->z)) - continue; - - // Found a target - closest = mo2; - } - - waypointmid = closest; - - closest = NULL; - - if (waypointmid == NULL) + if (!waypointmid) { CONS_Debug(DBG_GAMELOGIC, "ERROR: WAYPOINT(S) IN SEQUENCE %d NOT FOUND.\n", sequence); break; } - // Find waypoint before this one (waypointlow) - for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) - { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) - continue; - - mo2 = (mobj_t *)th; - - if (mo2->type != MT_TUBEWAYPOINT) - continue; - - if (mo2->threshold != sequence) - continue; - - if (waypointmid->health == 0) - { - if (mo2->health != highest->health) - continue; - } - else if (mo2->health != waypointmid->health - 1) - continue; - - // Found a target - waypointlow = mo2; - break; - } - - // Find waypoint after this one (waypointhigh) - for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) - { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) - continue; - - mo2 = (mobj_t *)th; - - if (mo2->type != MT_TUBEWAYPOINT) - continue; - - if (mo2->threshold != sequence) - continue; - - if (waypointmid->health == highest->health) - { - if (mo2->health != 0) - continue; - } - else if (mo2->health != waypointmid->health + 1) - continue; - - // Found a target - waypointhigh = mo2; - break; - } + waypointlow = P_GetPreviousWaypoint(waypointmid, true); + waypointhigh = P_GetNextWaypoint(waypointmid, true); CONS_Debug(DBG_GAMELOGIC, "WaypointMid: %d; WaypointLow: %d; WaypointHigh: %d\n", waypointmid->health, waypointlow ? waypointlow->health : -1, waypointhigh ? waypointhigh->health : -1); @@ -5260,6 +5085,7 @@ DoneSection2: if (lines[lineindex].flags & ML_EFFECT1) // Don't wrap { + mobj_t *highest = P_GetLastWaypoint(sequence); highest->flags |= MF_SLIDEME; } @@ -5271,7 +5097,7 @@ DoneSection2: player->mo->y = resulthigh.y; player->mo->z = resulthigh.z - P_GetPlayerHeight(player); } - else if ((lines[lineindex].flags & ML_EFFECT1) && waypointmid->health == highest->health) + else if ((lines[lineindex].flags & ML_EFFECT1) && waypointmid->health == numwaypoints[sequence] - 1) { closest = waypointmid; player->mo->x = resultlow.x; @@ -6037,12 +5863,10 @@ static void P_AddBlockThinker(sector_t *sec, line_t *sourceline) * there already. * * \param sec Control sector. - * \param actionsector Target sector. - * \param sourceline Control linedef. * \sa P_SpawnSpecials, T_RaiseSector * \author SSNTails */ -static void P_AddRaiseThinker(sector_t *sec, line_t *sourceline, fixed_t speed, fixed_t ceilingtop, fixed_t ceilingbottom, boolean lower, boolean spindash) +static void P_AddRaiseThinker(sector_t *sec, INT16 tag, fixed_t speed, fixed_t ceilingtop, fixed_t ceilingbottom, boolean lower, boolean spindash) { raise_t *raise; @@ -6051,7 +5875,7 @@ static void P_AddRaiseThinker(sector_t *sec, line_t *sourceline, fixed_t speed, raise->thinker.function.acp1 = (actionf_p1)T_RaiseSector; - raise->sourceline = sourceline; + raise->tag = tag; raise->sector = sec; raise->ceilingtop = ceilingtop; @@ -6065,7 +5889,7 @@ static void P_AddRaiseThinker(sector_t *sec, line_t *sourceline, fixed_t speed, raise->flags |= RF_SPINDASH; } -static void P_AddAirbob(sector_t *sec, line_t *sourceline, fixed_t dist, boolean raise, boolean spindash, boolean dynamic) +static void P_AddAirbob(sector_t *sec, INT16 tag, fixed_t dist, boolean raise, boolean spindash, boolean dynamic) { raise_t *airbob; @@ -6074,7 +5898,7 @@ static void P_AddAirbob(sector_t *sec, line_t *sourceline, fixed_t dist, boolean airbob->thinker.function.acp1 = (actionf_p1)T_RaiseSector; - airbob->sourceline = sourceline; + airbob->tag = tag; airbob->sector = sec; airbob->ceilingtop = sec->ceilingheight; @@ -6094,12 +5918,10 @@ static void P_AddAirbob(sector_t *sec, line_t *sourceline, fixed_t dist, boolean * Even thwomps need to think! * * \param sec Control sector. - * \param actionsector Target sector. - * \param sourceline Control linedef. * \sa P_SpawnSpecials, T_ThwompSector * \author SSNTails */ -static inline void P_AddThwompThinker(sector_t *sec, sector_t *actionsector, line_t *sourceline) +static inline void P_AddThwompThinker(sector_t *sec, INT16 tag, line_t *sourceline, fixed_t crushspeed, fixed_t retractspeed, UINT16 sound) { thwomp_t *thwomp; @@ -6117,14 +5939,14 @@ static inline void P_AddThwompThinker(sector_t *sec, sector_t *actionsector, lin // set up the fields according to the type of elevator action thwomp->sourceline = sourceline; thwomp->sector = sec; - thwomp->crushspeed = (sourceline->flags & ML_EFFECT5) ? sourceline->dy >> 3 : 10*FRACUNIT; - thwomp->retractspeed = (sourceline->flags & ML_EFFECT5) ? sourceline->dx >> 3 : 2*FRACUNIT; + thwomp->crushspeed = crushspeed; + thwomp->retractspeed = retractspeed; thwomp->direction = 0; thwomp->floorstartheight = sec->floorheight; thwomp->ceilingstartheight = sec->ceilingheight; thwomp->delay = 1; - thwomp->tag = actionsector->tag; - thwomp->sound = (sourceline->flags & ML_EFFECT4) ? sides[sourceline->sidenum[0]].textureoffset >> FRACBITS : sfx_thwomp; + thwomp->tag = tag; + thwomp->sound = sound; sec->floordata = thwomp; sec->ceilingdata = thwomp; @@ -6185,6 +6007,8 @@ static inline void P_AddCameraScanner(sector_t *sourcesec, sector_t *actionsecto { elevator_t *elevator; // Why not? LOL + CONS_Alert(CONS_WARNING, M_GetText("Detected a camera scanner effect (linedef type 5). This effect is deprecated and will be removed in the future!\n")); + // create and initialize new elevator thinker elevator = Z_Calloc(sizeof (*elevator), PU_LEVSPEC, NULL); P_AddThinker(THINK_MAIN, &elevator->thinker); @@ -6198,94 +6022,85 @@ static inline void P_AddCameraScanner(sector_t *sourcesec, sector_t *actionsecto elevator->distance = FixedInt(AngleFixed(angle)); } -static const ffloortype_e laserflags = FF_EXISTS|FF_RENDERALL|FF_NOSHADE|FF_EXTRA|FF_CUTEXTRA|FF_TRANSLUCENT; - /** Flashes a laser block. * * \param flash Thinker structure for this laser. - * \sa EV_AddLaserThinker + * \sa P_AddLaserThinker * \author SSNTails */ void T_LaserFlash(laserthink_t *flash) { msecnode_t *node; mobj_t *thing; - sector_t *sourcesec; - ffloor_t *fflr = flash->ffloor; - sector_t *sector = flash->sector; + INT32 s; + ffloor_t *fflr; + sector_t *sector; + sector_t *sourcesec = flash->sourceline->frontsector; fixed_t top, bottom; - if (!fflr || !(fflr->flags & FF_EXISTS)) - return; - - if (leveltime & 2) - //fflr->flags |= FF_RENDERALL; - fflr->alpha = 0xB0; - else - //fflr->flags &= ~FF_RENDERALL; - fflr->alpha = 0x90; - - sourcesec = fflr->master->frontsector; // Less to type! - - top = (*fflr->t_slope) ? P_GetZAt(*fflr->t_slope, sector->soundorg.x, sector->soundorg.y) - : *fflr->topheight; - bottom = (*fflr->b_slope) ? P_GetZAt(*fflr->b_slope, sector->soundorg.x, sector->soundorg.y) - : *fflr->bottomheight; - sector->soundorg.z = (top + bottom)/2; - S_StartSound(§or->soundorg, sfx_laser); - - // Seek out objects to DESTROY! MUAHAHHAHAHAA!!!*cough* - for (node = sector->touching_thinglist; node && node->m_thing; node = node->m_thinglist_next) + for (s = -1; (s = P_FindSectorFromTag(flash->tag, s)) >= 0 ;) { - thing = node->m_thing; + sector = §ors[s]; + for (fflr = sector->ffloors; fflr; fflr = fflr->next) + { + if (fflr->master != flash->sourceline) + continue; - if ((fflr->master->flags & ML_EFFECT1) - && thing->flags & MF_BOSS) - continue; // Don't hurt bosses + if (!(fflr->flags & FF_EXISTS)) + break; - // Don't endlessly kill egg guard shields (or anything else for that matter) - if (thing->health <= 0) - continue; + if (leveltime & 2) + //fflr->flags |= FF_RENDERALL; + fflr->alpha = 0xB0; + else + //fflr->flags &= ~FF_RENDERALL; + fflr->alpha = 0x90; - top = P_GetSpecialTopZ(thing, sourcesec, sector); - bottom = P_GetSpecialBottomZ(thing, sourcesec, sector); + top = P_GetFFloorTopZAt (fflr, sector->soundorg.x, sector->soundorg.y); + bottom = P_GetFFloorBottomZAt(fflr, sector->soundorg.x, sector->soundorg.y); + sector->soundorg.z = (top + bottom)/2; + S_StartSound(§or->soundorg, sfx_laser); - if (thing->z >= top - || thing->z + thing->height <= bottom) - continue; + // Seek out objects to DESTROY! MUAHAHHAHAHAA!!!*cough* + for (node = sector->touching_thinglist; node && node->m_thing; node = node->m_thinglist_next) + { + thing = node->m_thing; - if (thing->flags & MF_SHOOTABLE) - P_DamageMobj(thing, NULL, NULL, 1, 0); - else if (thing->type == MT_EGGSHIELD) - P_KillMobj(thing, NULL, NULL, 0); + if (flash->nobosses && thing->flags & MF_BOSS) + continue; // Don't hurt bosses + + // Don't endlessly kill egg guard shields (or anything else for that matter) + if (thing->health <= 0) + continue; + + top = P_GetSpecialTopZ(thing, sourcesec, sector); + bottom = P_GetSpecialBottomZ(thing, sourcesec, sector); + + if (thing->z >= top + || thing->z + thing->height <= bottom) + continue; + + if (thing->flags & MF_SHOOTABLE) + P_DamageMobj(thing, NULL, NULL, 1, 0); + else if (thing->type == MT_EGGSHIELD) + P_KillMobj(thing, NULL, NULL, 0); + } + + break; + } } } -/** Adds a laser thinker to a 3Dfloor. - * - * \param fflr 3Dfloor to turn into a laser block. - * \param sector Target sector. - * \param secthkiners Lists of thinkers sorted by sector. May be NULL. - * \sa T_LaserFlash - * \author SSNTails - */ -static inline void EV_AddLaserThinker(sector_t *sec, sector_t *sec2, line_t *line, thinkerlist_t *secthinkers) +static inline void P_AddLaserThinker(INT16 tag, line_t *line, boolean nobosses) { - laserthink_t *flash; - ffloor_t *fflr = P_AddFakeFloor(sec, sec2, line, laserflags, secthinkers); - - if (!fflr) - return; - - flash = Z_Calloc(sizeof (*flash), PU_LEVSPEC, NULL); + laserthink_t *flash = Z_Calloc(sizeof (*flash), PU_LEVSPEC, NULL); P_AddThinker(THINK_MAIN, &flash->thinker); flash->thinker.function.acp1 = (actionf_p1)T_LaserFlash; - flash->ffloor = fflr; - flash->sector = sec; // For finding mobjs - flash->sec = sec2; + flash->tag = tag; flash->sourceline = line; + flash->nobosses = nobosses; } // @@ -6315,11 +6130,11 @@ static void P_RunLevelLoadExecutors(void) void P_InitSpecials(void) { // Set the default gravity. Custom gravity overrides this setting. - gravity = FRACUNIT/2; + gravity = mapheaderinfo[gamemap-1]->gravity; // Defaults in case levels don't have them set. - sstimer = 90*TICRATE + 6; - ssspheres = 1; + sstimer = mapheaderinfo[gamemap-1]->sstimer*TICRATE + 6; + ssspheres = mapheaderinfo[gamemap-1]->ssspheres; CheckForBustableBlocks = CheckForBouncySector = CheckForQuicksand = CheckForMarioBlocks = CheckForFloatBob = CheckForReverseGravity = false; @@ -6506,7 +6321,7 @@ void P_SpawnSpecials(boolean fromnetsave) case 1: // Definable gravity per sector sec = sides[*lines[i].sidenum].sector - sectors; - for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(lines[i].tag, s)) >= 0 ;) { sectors[s].gravity = §ors[sec].floorheight; // This allows it to change in realtime! @@ -6530,7 +6345,7 @@ void P_SpawnSpecials(boolean fromnetsave) case 5: // Change camera info sec = sides[*lines[i].sidenum].sector - sectors; - for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(lines[i].tag, s)) >= 0 ;) P_AddCameraScanner(§ors[sec], §ors[s], R_PointToAngle2(lines[i].v2->x, lines[i].v2->y, lines[i].v1->x, lines[i].v1->y)); break; @@ -6557,7 +6372,7 @@ void P_SpawnSpecials(boolean fromnetsave) P_ApplyFlatAlignment(lines + i, lines[i].frontsector, flatangle, xoffs, yoffs); else { - for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0;) + for (s = -1; (s = P_FindSectorFromTag(lines[i].tag, s)) >= 0;) P_ApplyFlatAlignment(lines + i, sectors + s, flatangle, xoffs, yoffs); } } @@ -6568,7 +6383,7 @@ void P_SpawnSpecials(boolean fromnetsave) break; case 8: // Sector Parameters - for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(lines[i].tag, s)) >= 0 ;) { if (lines[i].flags & ML_NOCLIMB) { @@ -6596,7 +6411,7 @@ void P_SpawnSpecials(boolean fromnetsave) case 10: // Vertical culling plane for sprites and FOFs sec = sides[*lines[i].sidenum].sector - sectors; - for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(lines[i].tag, s)) >= 0 ;) sectors[s].cullheight = &lines[i]; // This allows it to change in realtime! break; @@ -6657,18 +6472,18 @@ void P_SpawnSpecials(boolean fromnetsave) case 63: // support for drawn heights coming from different sector sec = sides[*lines[i].sidenum].sector-sectors; - for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(lines[i].tag, s)) >= 0 ;) sectors[s].heightsec = (INT32)sec; break; case 64: // Appearing/Disappearing FOF option if (lines[i].flags & ML_BLOCKMONSTERS) { // Find FOFs by control sector tag - for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(lines[i].tag, s)) >= 0 ;) for (j = 0; (unsigned)j < sectors[s].linecount; j++) if (sectors[s].lines[j]->special >= 100 && sectors[s].lines[j]->special < 300) Add_MasterDisappearer(abs(lines[i].dx>>FRACBITS), abs(lines[i].dy>>FRACBITS), abs(sides[lines[i].sidenum[0]].sector->floorheight>>FRACBITS), (INT32)(sectors[s].lines[j]-lines), (INT32)i); } else // Find FOFs by effect sector tag - for (s = -1; (s = P_FindLineFromLineTag(lines + i, s)) >= 0 ;) + for (s = -1; (s = P_FindLineFromTag(lines[i].tag, s)) >= 0 ;) { if ((size_t)s == i) continue; @@ -6678,15 +6493,15 @@ void P_SpawnSpecials(boolean fromnetsave) break; case 66: // Displace floor by front sector - for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(lines[i].tag, s)) >= 0 ;) P_AddPlaneDisplaceThinker(pd_floor, P_AproxDistance(lines[i].dx, lines[i].dy)>>8, sides[lines[i].sidenum[0]].sector-sectors, s, !!(lines[i].flags & ML_NOCLIMB)); break; case 67: // Displace ceiling by front sector - for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(lines[i].tag, s)) >= 0 ;) P_AddPlaneDisplaceThinker(pd_ceiling, P_AproxDistance(lines[i].dx, lines[i].dy)>>8, sides[lines[i].sidenum[0]].sector-sectors, s, !!(lines[i].flags & ML_NOCLIMB)); break; case 68: // Displace both floor AND ceiling by front sector - for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(lines[i].tag, s)) >= 0 ;) P_AddPlaneDisplaceThinker(pd_both, P_AproxDistance(lines[i].dx, lines[i].dy)>>8, sides[lines[i].sidenum[0]].sector-sectors, s, !!(lines[i].flags & ML_NOCLIMB)); break; @@ -6883,16 +6698,16 @@ void P_SpawnSpecials(boolean fromnetsave) { fixed_t dist = (lines[i].special == 150) ? 16*FRACUNIT : P_AproxDistance(lines[i].dx, lines[i].dy); P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL, secthinkers); - P_AddAirbob(lines[i].frontsector, lines + i, dist, false, !!(lines[i].flags & ML_NOCLIMB), false); + P_AddAirbob(lines[i].frontsector, lines[i].tag, dist, false, !!(lines[i].flags & ML_NOCLIMB), false); break; } case 152: // Adjustable air bobbing platform in reverse P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL, secthinkers); - P_AddAirbob(lines[i].frontsector, lines + i, P_AproxDistance(lines[i].dx, lines[i].dy), true, !!(lines[i].flags & ML_NOCLIMB), false); + P_AddAirbob(lines[i].frontsector, lines[i].tag, P_AproxDistance(lines[i].dx, lines[i].dy), true, !!(lines[i].flags & ML_NOCLIMB), false); break; case 153: // Dynamic Sinking Platform P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL, secthinkers); - P_AddAirbob(lines[i].frontsector, lines + i, P_AproxDistance(lines[i].dx, lines[i].dy), false, !!(lines[i].flags & ML_NOCLIMB), true); + P_AddAirbob(lines[i].frontsector, lines[i].tag, P_AproxDistance(lines[i].dx, lines[i].dy), false, !!(lines[i].flags & ML_NOCLIMB), true); break; case 160: // Float/bob platform @@ -6942,13 +6757,13 @@ void P_SpawnSpecials(boolean fromnetsave) case 176: // Air bobbing platform that will crumble and bob on the water when it falls and hits P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_FLOATBOB|FF_CRUMBLE, secthinkers); - P_AddAirbob(lines[i].frontsector, lines + i, 16*FRACUNIT, false, !!(lines[i].flags & ML_NOCLIMB), false); + P_AddAirbob(lines[i].frontsector, lines[i].tag, 16*FRACUNIT, false, !!(lines[i].flags & ML_NOCLIMB), false); break; case 177: // Air bobbing platform that will crumble and bob on // the water when it falls and hits, then never return P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL|FF_FLOATBOB|FF_CRUMBLE|FF_NORETURN, secthinkers); - P_AddAirbob(lines[i].frontsector, lines + i, 16*FRACUNIT, false, !!(lines[i].flags & ML_NOCLIMB), false); + P_AddAirbob(lines[i].frontsector, lines[i].tag, 16*FRACUNIT, false, !!(lines[i].flags & ML_NOCLIMB), false); break; case 178: // Crumbling platform that will float when it hits water @@ -6961,7 +6776,7 @@ void P_SpawnSpecials(boolean fromnetsave) case 180: // Air bobbing platform that will crumble P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL|FF_CRUMBLE, secthinkers); - P_AddAirbob(lines[i].frontsector, lines + i, 16*FRACUNIT, false, !!(lines[i].flags & ML_NOCLIMB), false); + P_AddAirbob(lines[i].frontsector, lines[i].tag, 16*FRACUNIT, false, !!(lines[i].flags & ML_NOCLIMB), false); break; case 190: // Rising Platform FOF (solid, opaque, shadows) @@ -6988,7 +6803,7 @@ void P_SpawnSpecials(boolean fromnetsave) ffloorflags |= FF_NOSHADE; P_AddFakeFloorsByLine(i, ffloorflags, secthinkers); - P_AddRaiseThinker(lines[i].frontsector, &lines[i], speed, ceilingtop, ceilingbottom, !!(lines[i].flags & ML_BLOCKMONSTERS), !!(lines[i].flags & ML_NOCLIMB)); + P_AddRaiseThinker(lines[i].frontsector, lines[i].tag, speed, ceilingtop, ceilingbottom, !!(lines[i].flags & ML_BLOCKMONSTERS), !!(lines[i].flags & ML_NOCLIMB)); break; } @@ -7046,14 +6861,14 @@ void P_SpawnSpecials(boolean fromnetsave) break; case 251: // A THWOMP! - sec = sides[*lines[i].sidenum].sector - sectors; - for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) - { - P_AddThwompThinker(§ors[sec], §ors[s], &lines[i]); - P_AddFakeFloor(§ors[s], §ors[sec], lines + i, - FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL, secthinkers); - } + { + fixed_t crushspeed = (lines[i].flags & ML_EFFECT5) ? lines[i].dy >> 3 : 10*FRACUNIT; + fixed_t retractspeed = (lines[i].flags & ML_EFFECT5) ? lines[i].dx >> 3 : 2*FRACUNIT; + UINT16 sound = (lines[i].flags & ML_EFFECT4) ? sides[lines[i].sidenum[0]].textureoffset >> FRACBITS : sfx_thwomp; + P_AddThwompThinker(lines[i].frontsector, lines[i].tag, &lines[i], crushspeed, retractspeed, sound); + P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL, secthinkers); break; + } case 252: // Shatter block (breaks when touched) ffloorflags = FF_EXISTS|FF_BLOCKOTHERS|FF_RENDERALL|FF_BUSTUP|FF_SHATTER; @@ -7092,11 +6907,8 @@ void P_SpawnSpecials(boolean fromnetsave) break; case 258: // Laser block - sec = sides[*lines[i].sidenum].sector - sectors; - - // No longer totally disrupts netgames - for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) - EV_AddLaserThinker(§ors[s], §ors[sec], lines + i, secthinkers); + P_AddLaserThinker(lines[i].tag, lines + i, !!(lines[i].flags & ML_EFFECT1)); + P_AddFakeFloorsByLine(i, FF_EXISTS|FF_RENDERALL|FF_NOSHADE|FF_EXTRA|FF_CUTEXTRA|FF_TRANSLUCENT, secthinkers); break; case 259: // Custom FOF @@ -7253,6 +7065,9 @@ void P_SpawnSpecials(boolean fromnetsave) // 503 is used for a scroller // 504 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 // 511 is used for a scroller // 512 is used for a scroller @@ -7282,46 +7097,46 @@ void P_SpawnSpecials(boolean fromnetsave) case 600: // floor lighting independently (e.g. lava) sec = sides[*lines[i].sidenum].sector-sectors; - for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(lines[i].tag, s)) >= 0 ;) sectors[s].floorlightsec = (INT32)sec; break; case 601: // ceiling lighting independently sec = sides[*lines[i].sidenum].sector-sectors; - for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(lines[i].tag, s)) >= 0 ;) sectors[s].ceilinglightsec = (INT32)sec; break; case 602: // Adjustable pulsating light sec = sides[*lines[i].sidenum].sector - sectors; - for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(lines[i].tag, s)) >= 0 ;) P_SpawnAdjustableGlowingLight(§ors[sec], §ors[s], P_AproxDistance(lines[i].dx, lines[i].dy)>>FRACBITS); break; case 603: // Adjustable flickering light sec = sides[*lines[i].sidenum].sector - sectors; - for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(lines[i].tag, s)) >= 0 ;) P_SpawnAdjustableFireFlicker(§ors[sec], §ors[s], P_AproxDistance(lines[i].dx, lines[i].dy)>>FRACBITS); break; case 604: // Adjustable Blinking Light (unsynchronized) sec = sides[*lines[i].sidenum].sector - sectors; - for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(lines[i].tag, s)) >= 0 ;) P_SpawnAdjustableStrobeFlash(§ors[sec], §ors[s], abs(lines[i].dx)>>FRACBITS, abs(lines[i].dy)>>FRACBITS, false); break; case 605: // Adjustable Blinking Light (synchronized) sec = sides[*lines[i].sidenum].sector - sectors; - for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(lines[i].tag, s)) >= 0 ;) P_SpawnAdjustableStrobeFlash(§ors[sec], §ors[s], abs(lines[i].dx)>>FRACBITS, abs(lines[i].dy)>>FRACBITS, true); break; case 606: // HACK! Copy colormaps. Just plain colormaps. - for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(lines[i].tag, s)) >= 0 ;) sectors[s].extra_colormap = sectors[s].spawn_extra_colormap = sides[lines[i].sidenum[0]].colormap_data; break; @@ -7337,7 +7152,6 @@ void P_SpawnSpecials(boolean fromnetsave) Z_Free(secthinkers); -#ifdef POLYOBJECTS // haleyjd 02/20/06: spawn polyobjects Polyobj_InitLevel(); @@ -7346,7 +7160,7 @@ void P_SpawnSpecials(boolean fromnetsave) switch (lines[i].special) { case 30: // Polyobj_Flag - EV_DoPolyObjFlag(&lines[i]); + PolyFlag(&lines[i]); break; case 31: // Polyobj_Displace @@ -7358,7 +7172,6 @@ void P_SpawnSpecials(boolean fromnetsave) break; } } -#endif P_RunLevelLoadExecutors(); } @@ -7376,7 +7189,7 @@ static void P_AddFakeFloorsByLine(size_t line, ffloortype_e ffloorflags, thinker INT32 s; size_t sec = sides[*lines[line].sidenum].sector-sectors; - for (s = -1; (s = P_FindSectorFromLineTag(lines+line, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(lines[line].tag, s)) >= 0 ;) P_AddFakeFloor(§ors[s], §ors[sec], lines+line, ffloorflags, secthinkers); } @@ -7738,7 +7551,7 @@ static void P_SpawnScrollers(void) case 513: // scroll effect ceiling case 533: // scroll and carry objects on ceiling - for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(l->tag, s)) >= 0 ;) Add_Scroller(sc_ceiling, -dx, dy, control, s, accel, l->flags & ML_NOCLIMB); if (special != 533) break; @@ -7747,13 +7560,13 @@ static void P_SpawnScrollers(void) case 523: // carry objects on ceiling dx = FixedMul(dx, CARRYFACTOR); dy = FixedMul(dy, CARRYFACTOR); - for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(l->tag, s)) >= 0 ;) Add_Scroller(sc_carry_ceiling, dx, dy, control, s, accel, l->flags & ML_NOCLIMB); break; case 510: // scroll effect floor case 530: // scroll and carry objects on floor - for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(l->tag, s)) >= 0 ;) Add_Scroller(sc_floor, -dx, dy, control, s, accel, l->flags & ML_NOCLIMB); if (special != 530) break; @@ -7762,16 +7575,29 @@ static void P_SpawnScrollers(void) case 520: // carry objects on floor dx = FixedMul(dx, CARRYFACTOR); dy = FixedMul(dy, CARRYFACTOR); - for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(l->tag, s)) >= 0 ;) Add_Scroller(sc_carry, dx, dy, control, s, accel, l->flags & ML_NOCLIMB); break; // scroll wall according to linedef // (same direction and speed as scrolling floors) case 502: - for (s = -1; (s = P_FindLineFromLineTag(l, s)) >= 0 ;) + for (s = -1; (s = P_FindLineFromTag(l->tag, s)) >= 0 ;) 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; case 505: @@ -7785,7 +7611,25 @@ static void P_SpawnScrollers(void) if (s != 0xffff) Add_Scroller(sc_side, -sides[s].textureoffset, sides[s].rowoffset, -1, lines[i].sidenum[0], accel, 0); 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; case 500: // scroll first side @@ -7839,7 +7683,7 @@ void T_Disappear(disappear_t *d) ffloor_t *rover; register INT32 s; - for (s = -1; (s = P_FindSectorFromLineTag(&lines[d->affectee], s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(lines[d->affectee].tag, s)) >= 0 ;) { for (rover = sectors[s].ffloors; rover; rover = rover->next) { @@ -7854,10 +7698,7 @@ void T_Disappear(disappear_t *d) if (!(lines[d->sourceline].flags & ML_NOCLIMB)) { - if (*rover->t_slope) - sectors[s].soundorg.z = P_GetZAt(*rover->t_slope, sectors[s].soundorg.x, sectors[s].soundorg.y); - else - sectors[s].soundorg.z = *rover->topheight; + sectors[s].soundorg.z = P_GetFFloorTopZAt(rover, sectors[s].soundorg.x, sectors[s].soundorg.y); S_StartSound(§ors[s].soundorg, sfx_appear); } } @@ -8596,7 +8437,7 @@ static void P_SpawnFriction(void) else movefactor = FRACUNIT; - for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(l->tag, s)) >= 0 ;) Add_Friction(friction, movefactor, s, -1); } } @@ -9131,15 +8972,15 @@ static void P_SpawnPushers(void) switch (l->special) { case 541: // wind - for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(l->tag, s)) >= 0 ;) Add_Pusher(p_wind, l->dx, l->dy, NULL, s, -1, l->flags & ML_NOCLIMB, l->flags & ML_EFFECT4); break; case 544: // current - for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(l->tag, s)) >= 0 ;) Add_Pusher(p_current, l->dx, l->dy, NULL, s, -1, l->flags & ML_NOCLIMB, l->flags & ML_EFFECT4); break; case 547: // push/pull - for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(l->tag, s)) >= 0 ;) { thing = P_GetPushThing(s); if (thing) // No MT_P* means no effect @@ -9147,19 +8988,19 @@ static void P_SpawnPushers(void) } break; case 545: // current up - for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(l->tag, s)) >= 0 ;) Add_Pusher(p_upcurrent, l->dx, l->dy, NULL, s, -1, l->flags & ML_NOCLIMB, l->flags & ML_EFFECT4); break; case 546: // current down - for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(l->tag, s)) >= 0 ;) Add_Pusher(p_downcurrent, l->dx, l->dy, NULL, s, -1, l->flags & ML_NOCLIMB, l->flags & ML_EFFECT4); break; case 542: // wind up - for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(l->tag, s)) >= 0 ;) Add_Pusher(p_upwind, l->dx, l->dy, NULL, s, -1, l->flags & ML_NOCLIMB, l->flags & ML_EFFECT4); break; case 543: // wind down - for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(l->tag, s)) >= 0 ;) Add_Pusher(p_downwind, l->dx, l->dy, NULL, s, -1, l->flags & ML_NOCLIMB, l->flags & ML_EFFECT4); break; } diff --git a/src/p_spec.h b/src/p_spec.h index 8e778b9ed..596d8171d 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -55,7 +55,6 @@ fixed_t P_FindNextLowestFloor(sector_t *sec, fixed_t currentheight); fixed_t P_FindLowestCeilingSurrounding(sector_t *sec); fixed_t P_FindHighestCeilingSurrounding(sector_t *sec); -INT32 P_FindSectorFromLineTag(line_t *line, INT32 start); INT32 P_FindSectorFromTag(INT16 tag, INT32 start); INT32 P_FindSpecialLineFromTag(INT16 special, INT16 tag, INT32 start); @@ -105,10 +104,9 @@ typedef struct typedef struct { thinker_t thinker; ///< Thinker structure for laser. - ffloor_t *ffloor; ///< 3Dfloor that is a laser. - sector_t *sector; ///< Sector in which the effect takes place. - sector_t *sec; + INT16 tag; line_t *sourceline; + UINT8 nobosses; } laserthink_t; /** Strobe light action structure.. @@ -308,10 +306,32 @@ typedef struct fixed_t delaytimer; fixed_t floorwasheight; // Height the floor WAS at fixed_t ceilingwasheight; // Height the ceiling WAS at - player_t *player; // Player who initiated the thinker (used for airbob) line_t *sourceline; } elevator_t; +typedef enum +{ + CF_RETURN = 1, // Return after crumbling + CF_FLOATBOB = 1<<1, // Float on water + CF_REVERSE = 1<<2, // Reverse gravity +} crumbleflag_t; + +typedef struct +{ + thinker_t thinker; + line_t *sourceline; + sector_t *sector; + sector_t *actionsector; // The sector the rover action is taking place in. + player_t *player; // Player who initiated the thinker (used for airbob) + INT32 direction; + INT32 origalpha; + INT32 timer; + fixed_t speed; + fixed_t floorwasheight; // Height the floor WAS at + fixed_t ceilingwasheight; // Height the ceiling WAS at + UINT8 flags; +} crumble_t; + typedef struct { thinker_t thinker; @@ -401,7 +421,7 @@ typedef enum typedef struct { thinker_t thinker; - line_t *sourceline; + INT16 tag; sector_t *sector; fixed_t ceilingbottom; fixed_t ceilingtop; @@ -441,7 +461,7 @@ void T_MoveFloor(floormove_t *movefloor); void T_MoveElevator(elevator_t *elevator); void T_ContinuousFalling(continuousfall_t *faller); void T_BounceCheese(bouncecheese_t *bouncer); -void T_StartCrumble(elevator_t *elevator); +void T_StartCrumble(crumble_t *crumble); void T_MarioBlock(mariothink_t *block); void T_FloatSector(floatthink_t *floater); void T_MarioBlockChecker(mariocheck_t *block); diff --git a/src/p_user.c b/src/p_user.c index c7f772fb0..5381c7bbb 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1490,17 +1490,10 @@ void P_PlayLivesJingle(player_t *player) if (player && !P_IsLocalPlayer(player)) return; - if (use1upSound) + if (use1upSound || cv_1upsound.value) S_StartSound(NULL, sfx_oneup); else if (mariomode) S_StartSound(NULL, sfx_marioa); - else if (cv_1upsound.value) - { - if (S_sfx[sfx_oneup].lumpnum != LUMPERROR) - S_StartSound(NULL, sfx_oneup); - else - S_StartSound(NULL, sfx_chchng);/* at least play something! */ - } else { P_PlayJingle(player, JT_1UP); @@ -1548,10 +1541,6 @@ boolean P_EvaluateMusicStatus(UINT16 status, const char *musname) int i; boolean result = false; -#ifndef HAVE_BLUA - (void)musname; -#endif - for (i = 0; i < MAXPLAYERS; i++) { if (!P_IsLocalPlayer(&players[i])) @@ -1927,7 +1916,7 @@ void P_SpawnShieldOrb(player_t *player) shieldobj->colorized = true; } 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); if (shieldobj->info->seestate) @@ -2278,8 +2267,8 @@ boolean P_InSpaceSector(mobj_t *mo) // Returns true if you are in space if (GETSECSPECIAL(rover->master->frontsector->special, 1) != SPACESPECIAL) continue; - topheight = *rover->t_slope ? P_GetZAt(*rover->t_slope, mo->x, mo->y) : *rover->topheight; - bottomheight = *rover->b_slope ? P_GetZAt(*rover->b_slope, mo->x, mo->y) : *rover->bottomheight; + topheight = P_GetFFloorTopZAt (rover, mo->x, mo->y); + bottomheight = P_GetFFloorBottomZAt(rover, mo->x, mo->y); if (mo->z + (mo->height/2) > topheight) continue; @@ -2516,8 +2505,8 @@ boolean P_InQuicksand(mobj_t *mo) // Returns true if you are in quicksand if (!(rover->flags & FF_QUICKSAND)) continue; - topheight = *rover->t_slope ? P_GetZAt(*rover->t_slope, mo->x, mo->y) : *rover->topheight; - bottomheight = *rover->b_slope ? P_GetZAt(*rover->b_slope, mo->x, mo->y) : *rover->bottomheight; + topheight = P_GetFFloorTopZAt (rover, mo->x, mo->y); + bottomheight = P_GetFFloorBottomZAt(rover, mo->x, mo->y); if (mo->z + flipoffset > topheight) continue; @@ -2843,8 +2832,8 @@ static void P_CheckQuicksand(player_t *player) if (!(rover->flags & FF_QUICKSAND)) continue; - topheight = *rover->t_slope ? P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y) : *rover->topheight; - bottomheight = *rover->b_slope ? P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y) : *rover->bottomheight; + topheight = P_GetFFloorTopZAt (rover, player->mo->x, player->mo->y); + bottomheight = P_GetFFloorBottomZAt(rover, player->mo->x, player->mo->y); if (topheight >= player->mo->z && bottomheight < player->mo->z + player->mo->height) { @@ -2997,7 +2986,7 @@ static void P_CheckInvincibilityTimer(player_t *player) return; 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) { mobj_t *sparkle = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_IVSP); @@ -3184,10 +3173,8 @@ static void P_DoClimbing(player_t *player) floorclimb = true; else { - floorheight = glidesector->sector->f_slope ? P_GetZAt(glidesector->sector->f_slope, player->mo->x, player->mo->y) - : glidesector->sector->floorheight; - ceilingheight = glidesector->sector->c_slope ? P_GetZAt(glidesector->sector->c_slope, player->mo->x, player->mo->y) - : glidesector->sector->ceilingheight; + floorheight = P_GetSectorFloorZAt (glidesector->sector, player->mo->x, player->mo->y); + ceilingheight = P_GetSectorCeilingZAt(glidesector->sector, player->mo->x, player->mo->y); if (glidesector->sector->ffloors) { @@ -3201,8 +3188,8 @@ static void P_DoClimbing(player_t *player) floorclimb = true; - topheight = *rover->t_slope ? P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y) : *rover->topheight; - bottomheight = *rover->b_slope ? P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y) : *rover->bottomheight; + topheight = P_GetFFloorTopZAt (rover, player->mo->x, player->mo->y); + bottomheight = P_GetFFloorBottomZAt(rover, player->mo->x, player->mo->y); // Only supports rovers that are moving like an 'elevator', not just the top or bottom. if (rover->master->frontsector->floorspeed && rover->master->frontsector->ceilspeed == 42) @@ -3243,8 +3230,7 @@ static void P_DoClimbing(player_t *player) if (roverbelow == rover) continue; - bottomheight2 = *roverbelow->b_slope ? P_GetZAt(*roverbelow->b_slope, player->mo->x, player->mo->y) : *roverbelow->bottomheight; - + bottomheight2 = P_GetFFloorBottomZAt(roverbelow, player->mo->x, player->mo->y); if (bottomheight2 < topheight + FixedMul(16*FRACUNIT, player->mo->scale)) foundfof = true; } @@ -3289,8 +3275,7 @@ static void P_DoClimbing(player_t *player) if (roverbelow == rover) continue; - topheight2 = *roverbelow->t_slope ? P_GetZAt(*roverbelow->t_slope, player->mo->x, player->mo->y) : *roverbelow->topheight; - + topheight2 = P_GetFFloorTopZAt(roverbelow, player->mo->x, player->mo->y); if (topheight2 > bottomheight - FixedMul(16*FRACUNIT, player->mo->scale)) foundfof = true; } @@ -3344,8 +3329,7 @@ static void P_DoClimbing(player_t *player) if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP)) continue; - bottomheight = *rover->b_slope ? P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y) : *rover->bottomheight; - + bottomheight = P_GetFFloorBottomZAt(rover, player->mo->x, player->mo->y); if (bottomheight < floorheight + FixedMul(16*FRACUNIT, player->mo->scale)) { foundfof = true; @@ -3385,8 +3369,7 @@ static void P_DoClimbing(player_t *player) if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP)) continue; - topheight = *rover->t_slope ? P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y) : *rover->topheight; - + topheight = P_GetFFloorTopZAt(rover, player->mo->x, player->mo->y); if (topheight > ceilingheight - FixedMul(16*FRACUNIT, player->mo->scale)) { foundfof = true; @@ -3758,12 +3741,8 @@ static void P_DoTeeter(player_t *player) sec = R_PointInSubsector(checkx, checky)->sector; - ceilingheight = sec->ceilingheight; - floorheight = sec->floorheight; - if (sec->c_slope) - ceilingheight = P_GetZAt(sec->c_slope, checkx, checky); - if (sec->f_slope) - floorheight = P_GetZAt(sec->f_slope, checkx, checky); + ceilingheight = P_GetSectorCeilingZAt(sec, checkx, checky); + floorheight = P_GetSectorFloorZAt (sec, checkx, checky); highestceilingheight = (ceilingheight > highestceilingheight) ? ceilingheight : highestceilingheight; lowestfloorheight = (floorheight < lowestfloorheight) ? floorheight : lowestfloorheight; @@ -3774,8 +3753,8 @@ static void P_DoTeeter(player_t *player) { if (!(rover->flags & FF_EXISTS)) continue; - topheight = *rover->t_slope ? P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y) : *rover->topheight; - bottomheight = *rover->b_slope ? P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y) : *rover->bottomheight; + topheight = P_GetFFloorTopZAt (rover, player->mo->x, player->mo->y); + bottomheight = P_GetFFloorBottomZAt(rover, player->mo->x, player->mo->y); if (P_CheckSolidLava(rover)) ; @@ -3847,7 +3826,6 @@ static void P_DoTeeter(player_t *player) BMBOUNDFIX(xl, xh, yl, yh); // Polyobjects -#ifdef POLYOBJECTS validcount++; for (by = yl; by <= yh; by++) @@ -3941,7 +3919,6 @@ static void P_DoTeeter(player_t *player) plink = (polymaplink_t *)(plink->link.next); } } -#endif if (teeter) // only bother with objects as a last resort if you were already teetering { mobj_t *oldtmthing = tmthing; @@ -4442,13 +4419,16 @@ void P_DoJump(player_t *player, boolean soundandstate) else if (player->powers[pw_carry] == CR_ROLLOUT) { player->mo->momz = 9*FRACUNIT; - if (P_MobjFlip(player->mo->tracer)*player->mo->tracer->momz > 0) - player->mo->momz += player->mo->tracer->momz; - if (!P_IsObjectOnGround(player->mo->tracer)) - P_SetObjectMomZ(player->mo->tracer, -9*FRACUNIT, true); + if (player->mo->tracer) + { + if (P_MobjFlip(player->mo->tracer)*player->mo->tracer->momz > 0) + player->mo->momz += player->mo->tracer->momz; + if (!P_IsObjectOnGround(player->mo->tracer)) + P_SetObjectMomZ(player->mo->tracer, -9*FRACUNIT, true); + player->mo->tracer->flags |= MF_PUSHABLE; + P_SetTarget(&player->mo->tracer->tracer, NULL); + } player->powers[pw_carry] = CR_NONE; - player->mo->tracer->flags |= MF_PUSHABLE; - P_SetTarget(&player->mo->tracer->tracer, NULL); P_SetTarget(&player->mo->tracer, NULL); } else if (player->mo->eflags & MFE_GOOWATER) @@ -5006,6 +4986,15 @@ void P_Telekinesis(player_t *player, fixed_t thrust, fixed_t range) player->pflags |= PF_THOKKED; } +static void P_DoTwinSpin(player_t *player) +{ + player->pflags &= ~PF_NOJUMPDAMAGE; + player->pflags |= P_GetJumpFlags(player) | PF_THOKKED; + S_StartSound(player->mo, sfx_s3k42); + player->mo->frame = 0; + P_SetPlayerMobjState(player->mo, S_PLAY_TWINSPIN); +} + // // P_DoJumpStuff // @@ -5176,12 +5165,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) break; case CA_TWINSPIN: if ((player->charability2 == CA2_MELEE) && (!(player->pflags & (PF_THOKKED|PF_USEDOWN)) || player->charflags & SF_MULTIABILITY)) - { - player->pflags |= PF_THOKKED; - S_StartSound(player->mo, sfx_s3k42); - player->mo->frame = 0; - P_SetPlayerMobjState(player->mo, S_PLAY_TWINSPIN); - } + P_DoTwinSpin(player); break; default: break; @@ -5438,12 +5422,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) break; case CA_TWINSPIN: if (!(player->pflags & PF_THOKKED) || player->charflags & SF_MULTIABILITY) - { - player->pflags |= PF_THOKKED; - S_StartSound(player->mo, sfx_s3k42); - player->mo->frame = 0; - P_SetPlayerMobjState(player->mo, S_PLAY_TWINSPIN); - } + P_DoTwinSpin(player); break; default: break; @@ -5702,11 +5681,7 @@ static void P_2dMovement(player_t *player) } else if (player->onconveyor == 4 && !P_IsObjectOnGround(player->mo)) // Actual conveyor belt player->cmomx = player->cmomy = 0; - else if (player->onconveyor != 2 && player->onconveyor != 4 -#ifdef POLYOBJECTS - && player->onconveyor != 1 -#endif - ) + else if (player->onconveyor != 2 && player->onconveyor != 4 && player->onconveyor != 1) player->cmomx = player->cmomy = 0; player->rmomx = player->mo->momx - player->cmomx; @@ -5901,11 +5876,7 @@ static void P_3dMovement(player_t *player) } else if (player->onconveyor == 4 && !P_IsObjectOnGround(player->mo)) // Actual conveyor belt player->cmomx = player->cmomy = 0; - else if (player->onconveyor != 2 && player->onconveyor != 4 -#ifdef POLYOBJECTS - && player->onconveyor != 1 -#endif - ) + else if (player->onconveyor != 2 && player->onconveyor != 4 && player->onconveyor != 1) player->cmomx = player->cmomy = 0; player->rmomx = player->mo->momx - player->cmomx; @@ -7762,7 +7733,7 @@ void P_ElementalFire(player_t *player, boolean cropcircle) if (player->mo->standingslope) { - ground = P_GetZAt(player->mo->standingslope, newx, newy); + ground = P_GetSlopeZAt(player->mo->standingslope, newx, newy); if (player->mo->eflags & MFE_VERTICALFLIP) ground -= FixedMul(mobjinfo[MT_SPINFIRE].height, player->mo->scale); } @@ -8738,10 +8709,7 @@ static void P_MovePlayer(player_t *player) static void P_DoZoomTube(player_t *player) { - INT32 sequence; fixed_t speed; - thinker_t *th; - mobj_t *mo2; mobj_t *waypoint = NULL; fixed_t dist; boolean reverse; @@ -8757,8 +8725,6 @@ static void P_DoZoomTube(player_t *player) speed = abs(player->speed); - sequence = player->mo->tracer->threshold; - // change slope dist = P_AproxDistance(P_AproxDistance(player->mo->tracer->x - player->mo->x, player->mo->tracer->y - player->mo->y), player->mo->tracer->z - player->mo->z); @@ -8790,28 +8756,7 @@ static void P_DoZoomTube(player_t *player) CONS_Debug(DBG_GAMELOGIC, "Looking for next waypoint...\n"); // Find next waypoint - for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) - { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) - continue; - - mo2 = (mobj_t *)th; - - if (mo2->type != MT_TUBEWAYPOINT) - continue; - - if (mo2->threshold != sequence) - continue; - - if (reverse && mo2->health != player->mo->tracer->health - 1) - continue; - - if (!reverse && mo2->health != player->mo->tracer->health + 1) - continue; - - waypoint = mo2; - break; - } + waypoint = reverse ? P_GetPreviousWaypoint(player->mo->tracer, false) : P_GetNextWaypoint(player->mo->tracer, false); if (waypoint) { @@ -8862,8 +8807,6 @@ static void P_DoRopeHang(player_t *player) { INT32 sequence; fixed_t speed; - thinker_t *th; - mobj_t *mo2; mobj_t *waypoint = NULL; fixed_t dist; fixed_t playerz; @@ -8926,50 +8869,14 @@ static void P_DoRopeHang(player_t *player) CONS_Debug(DBG_GAMELOGIC, "Looking for next waypoint...\n"); // Find next waypoint - for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) - { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) - continue; - - mo2 = (mobj_t *)th; - - if (mo2->type != MT_TUBEWAYPOINT) - continue; - - if (mo2->threshold != sequence) - continue; - - if (mo2->health != player->mo->tracer->health + 1) - continue; - - waypoint = mo2; - break; - } + waypoint = P_GetNextWaypoint(player->mo->tracer, false); if (!(player->mo->tracer->flags & MF_SLIDEME) && !waypoint) { CONS_Debug(DBG_GAMELOGIC, "Next waypoint not found, wrapping to start...\n"); // Wrap around back to first waypoint - for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) - { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) - continue; - - mo2 = (mobj_t *)th; - - if (mo2->type != MT_TUBEWAYPOINT) - continue; - - if (mo2->threshold != sequence) - continue; - - if (mo2->health != 0) - continue; - - waypoint = mo2; - break; - } + waypoint = P_GetFirstWaypoint(sequence); } if (waypoint) @@ -10235,7 +10142,6 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall } } -#ifdef POLYOBJECTS // Check polyobjects and see if floorz/ceilingz need to be altered { INT32 xl, xh, yl, yh, bx, by; @@ -10314,7 +10220,6 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall } } } -#endif // crushed camera if (myceilingz <= myfloorz + thiscam->height && !resetcalled && !cameranoclip) @@ -10667,8 +10572,8 @@ static void P_CalcPostImg(player_t *player) if (!(rover->flags & FF_EXISTS)) continue; - topheight = *rover->t_slope ? P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y) : *rover->topheight; - bottomheight = *rover->b_slope ? P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y) : *rover->bottomheight; + topheight = P_GetFFloorTopZAt (rover, player->mo->x, player->mo->y); + bottomheight = P_GetFFloorBottomZAt(rover, player->mo->x, player->mo->y); if (pviewheight >= topheight || pviewheight <= bottomheight) continue; @@ -10690,8 +10595,8 @@ static void P_CalcPostImg(player_t *player) if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_SWIMMABLE) || rover->flags & FF_BLOCKPLAYER) continue; - topheight = *rover->t_slope ? P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y) : *rover->topheight; - bottomheight = *rover->b_slope ? P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y) : *rover->bottomheight; + topheight = P_GetFFloorTopZAt (rover, player->mo->x, player->mo->y); + bottomheight = P_GetFFloorBottomZAt(rover, player->mo->x, player->mo->y); if (pviewheight >= topheight || pviewheight <= bottomheight) continue; @@ -10753,7 +10658,7 @@ static sector_t *P_GetMinecartSector(fixed_t x, fixed_t y, fixed_t z, fixed_t *n if (!(rover->flags & (FF_EXISTS|FF_BLOCKOTHERS))) continue; - *nz = *rover->t_slope ? P_GetZAt(*rover->t_slope, x, y) : *rover->topheight; + *nz = P_GetFFloorTopZAt(rover, x, y); if (abs(z - *nz) <= 56*FRACUNIT) { sec = §ors[rover->secnum]; @@ -10763,7 +10668,7 @@ static sector_t *P_GetMinecartSector(fixed_t x, fixed_t y, fixed_t z, fixed_t *n } - *nz = sec->f_slope ? P_GetZAt(sec->f_slope, x, y) : sec->floorheight; + *nz = P_GetSectorFloorZAt(sec, x, y); if (abs(z - *nz) > 56*FRACUNIT) return NULL; @@ -11117,8 +11022,8 @@ static void P_MinecartThink(player_t *player) if (minecart->standingslope) { fixed_t fa2 = (minecart->angle >> ANGLETOFINESHIFT) & FINEMASK; - fixed_t front = P_GetZAt(minecart->standingslope, minecart->x, minecart->y); - fixed_t back = P_GetZAt(minecart->standingslope, minecart->x - FINECOSINE(fa2), minecart->y - FINESINE(fa2)); + fixed_t front = P_GetSlopeZAt(minecart->standingslope, minecart->x, minecart->y); + fixed_t back = P_GetSlopeZAt(minecart->standingslope, minecart->x - FINECOSINE(fa2), minecart->y - FINESINE(fa2)); if (abs(front - back) < 3*FRACUNIT) currentSpeed += (back - front)/3; @@ -11732,10 +11637,8 @@ void P_PlayerThink(player_t *player) P_MobjCheckWater(player->mo); #ifndef SECTORSPECIALSAFTERTHINK -#ifdef POLYOBJECTS if (player->onconveyor != 1 || !P_IsObjectOnGround(player->mo)) -#endif - player->onconveyor = 0; + player->onconveyor = 0; // check special sectors : damage & secrets if (!player->spectator) @@ -11948,6 +11851,9 @@ void P_PlayerThink(player_t *player) factor = 4; } break; + case CR_DUSTDEVIL: + player->drawangle += ANG20; + break; /* -- in case we wanted to have the camera freely movable during zoom tubes case CR_ZOOMTUBE:*/ case CR_ROPEHANG: @@ -12093,12 +11999,10 @@ void P_PlayerThink(player_t *player) // it lasts for one tic. player->pflags &= ~PF_FULLSTASIS; -#ifdef POLYOBJECTS if (player->onconveyor == 1) player->onconveyor = 3; else if (player->onconveyor == 3) player->cmomy = player->cmomx = 0; -#endif P_DoSuperStuff(player); P_CheckSneakerAndLivesTimer(player); @@ -12439,10 +12343,8 @@ void P_PlayerAfterThink(player_t *player) cmd = &player->cmd; #ifdef SECTORSPECIALSAFTERTHINK -#ifdef POLYOBJECTS if (player->onconveyor != 1 || !P_IsObjectOnGround(player->mo)) -#endif - player->onconveyor = 0; + player->onconveyor = 0; // check special sectors : damage & secrets if (!player->spectator) @@ -12732,6 +12634,19 @@ void P_PlayerAfterThink(player_t *player) } break; } + case CR_DUSTDEVIL: + { + mobj_t *mo = player->mo, *dustdevil = player->mo->tracer; + + if (abs(mo->x - dustdevil->x) > dustdevil->radius || abs(mo->y - dustdevil->y) > dustdevil->radius) + { + P_SetTarget(&player->mo->tracer, NULL); + player->powers[pw_carry] = CR_NONE; + break; + } + + break; + } case CR_ROLLOUT: { mobj_t *mo = player->mo, *rock = player->mo->tracer; diff --git a/src/r_bsp.c b/src/r_bsp.c index 77ab2a82f..60291da0f 100644 --- a/src/r_bsp.c +++ b/src/r_bsp.c @@ -354,9 +354,7 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel, boolean R_IsEmptyLine(seg_t *line, sector_t *front, sector_t *back) { return ( -#ifdef POLYOBJECTS !line->polyseg && -#endif back->ceilingpic == front->ceilingpic && back->floorpic == front->floorpic && back->f_slope == front->f_slope @@ -482,13 +480,10 @@ static void R_AddLine(seg_t *line) if (bothceilingssky && bothfloorssky) // everything's sky? let's save us a bit of time then { - if ( -#ifdef POLYOBJECTS - !line->polyseg && -#endif - !line->sidedef->midtexture - && ((!frontsector->ffloors && !backsector->ffloors) - || (frontsector->tag == backsector->tag))) + if (!line->polyseg && + !line->sidedef->midtexture + && ((!frontsector->ffloors && !backsector->ffloors) + || (frontsector->tag == backsector->tag))) return; // line is empty, don't even bother goto clippass; // treat like wide open window instead @@ -500,16 +495,13 @@ static void R_AddLine(seg_t *line) fixed_t frontf1,frontf2, frontc1, frontc2; // front floor/ceiling ends fixed_t backf1, backf2, backc1, backc2; // back floor ceiling ends #define SLOPEPARAMS(slope, end1, end2, normalheight) \ - if (slope) { \ - end1 = P_GetZAt(slope, line->v1->x, line->v1->y); \ - end2 = P_GetZAt(slope, line->v2->x, line->v2->y); \ - } else \ - end1 = end2 = normalheight; + end1 = P_GetZAt(slope, line->v1->x, line->v1->y, normalheight); \ + end2 = P_GetZAt(slope, line->v2->x, line->v2->y, normalheight); - SLOPEPARAMS(frontsector->f_slope, frontf1, frontf2, frontsector->floorheight) + SLOPEPARAMS(frontsector->f_slope, frontf1, frontf2, frontsector-> floorheight) SLOPEPARAMS(frontsector->c_slope, frontc1, frontc2, frontsector->ceilingheight) - SLOPEPARAMS( backsector->f_slope, backf1, backf2, backsector->floorheight) - SLOPEPARAMS( backsector->c_slope, backc1, backc2, backsector->ceilingheight) + SLOPEPARAMS( backsector->f_slope, backf1, backf2, backsector-> floorheight) + SLOPEPARAMS( backsector->c_slope, backc1, backc2, backsector->ceilingheight) #undef SLOPEPARAMS // if both ceilings are skies, consider it always "open" // same for floors @@ -654,8 +646,6 @@ static boolean R_CheckBBox(const fixed_t *bspcoord) return true; } -#ifdef POLYOBJECTS - size_t numpolys; // number of polyobjects in current subsector size_t num_po_ptrs; // number of polyobject pointers allocated polyobj_t **po_ptrs; // temp ptr array to sort polyobject pointers @@ -819,7 +809,6 @@ static void R_AddPolyObjects(subsector_t *sub) R_AddLine(po_ptrs[i]->segs[j]); } } -#endif // // R_Subsector @@ -859,13 +848,8 @@ static void R_Subsector(size_t num) floorcolormap = ceilingcolormap = frontsector->extra_colormap; - floorcenterz = frontsector->f_slope ? - P_GetZAt(frontsector->f_slope, frontsector->soundorg.x, frontsector->soundorg.y) : - frontsector->floorheight; - - ceilingcenterz = frontsector->c_slope ? - P_GetZAt(frontsector->c_slope, frontsector->soundorg.x, frontsector->soundorg.y) : - frontsector->ceilingheight; + floorcenterz = P_GetSectorFloorZAt (frontsector, frontsector->soundorg.x, frontsector->soundorg.y); + ceilingcenterz = P_GetSectorCeilingZAt(frontsector, frontsector->soundorg.x, frontsector->soundorg.y); // Check and prep all 3D floors. Set the sector floor/ceiling light levels and colormaps. if (frontsector->ffloors) @@ -891,31 +875,23 @@ static void R_Subsector(size_t num) sub->sector->extra_colormap = frontsector->extra_colormap; - if ((frontsector->f_slope ? P_GetZAt(frontsector->f_slope, viewx, viewy) : frontsector->floorheight) < viewz + if (P_GetSectorFloorZAt(frontsector, viewx, viewy) < viewz || frontsector->floorpic == skyflatnum || (frontsector->heightsec != -1 && sectors[frontsector->heightsec].ceilingpic == skyflatnum)) { floorplane = R_FindPlane(frontsector->floorheight, frontsector->floorpic, floorlightlevel, - frontsector->floor_xoffs, frontsector->floor_yoffs, frontsector->floorpic_angle, floorcolormap, NULL -#ifdef POLYOBJECTS_PLANES - , NULL -#endif - , frontsector->f_slope); + frontsector->floor_xoffs, frontsector->floor_yoffs, frontsector->floorpic_angle, floorcolormap, NULL, NULL, frontsector->f_slope); } else floorplane = NULL; - if ((frontsector->c_slope ? P_GetZAt(frontsector->c_slope, viewx, viewy) : frontsector->ceilingheight) > viewz + if (P_GetSectorCeilingZAt(frontsector, viewx, viewy) > viewz || frontsector->ceilingpic == skyflatnum || (frontsector->heightsec != -1 && sectors[frontsector->heightsec].floorpic == skyflatnum)) { ceilingplane = R_FindPlane(frontsector->ceilingheight, frontsector->ceilingpic, ceilinglightlevel, frontsector->ceiling_xoffs, frontsector->ceiling_yoffs, frontsector->ceilingpic_angle, - ceilingcolormap, NULL -#ifdef POLYOBJECTS_PLANES - , NULL -#endif - , frontsector->c_slope); + ceilingcolormap, NULL, NULL, frontsector->c_slope); } else ceilingplane = NULL; @@ -946,13 +922,9 @@ static void R_Subsector(size_t num) ffloor[numffloors].plane = NULL; ffloor[numffloors].polyobj = NULL; - heightcheck = *rover->b_slope ? - P_GetZAt(*rover->b_slope, viewx, viewy) : - *rover->bottomheight; + heightcheck = P_GetFFloorBottomZAt(rover, viewx, viewy); - planecenterz = *rover->b_slope ? - P_GetZAt(*rover->b_slope, frontsector->soundorg.x, frontsector->soundorg.y) : - *rover->bottomheight; + planecenterz = P_GetFFloorBottomZAt(rover, frontsector->soundorg.x, frontsector->soundorg.y); if (planecenterz <= ceilingcenterz && planecenterz >= floorcenterz && ((viewz < heightcheck && (rover->flags & FF_BOTHPLANES || !(rover->flags & FF_INVERTPLANES))) @@ -963,11 +935,7 @@ static void R_Subsector(size_t num) ffloor[numffloors].plane = R_FindPlane(*rover->bottomheight, *rover->bottompic, *frontsector->lightlist[light].lightlevel, *rover->bottomxoffs, - *rover->bottomyoffs, *rover->bottomangle, *frontsector->lightlist[light].extra_colormap, rover -#ifdef POLYOBJECTS_PLANES - , NULL -#endif - , *rover->b_slope); + *rover->bottomyoffs, *rover->bottomangle, *frontsector->lightlist[light].extra_colormap, rover, NULL, *rover->b_slope); ffloor[numffloors].slope = *rover->b_slope; @@ -984,13 +952,9 @@ static void R_Subsector(size_t num) ffloor[numffloors].plane = NULL; ffloor[numffloors].polyobj = NULL; - heightcheck = *rover->t_slope ? - P_GetZAt(*rover->t_slope, viewx, viewy) : - *rover->topheight; + heightcheck = P_GetFFloorTopZAt(rover, viewx, viewy); - planecenterz = *rover->t_slope ? - P_GetZAt(*rover->t_slope, frontsector->soundorg.x, frontsector->soundorg.y) : - *rover->topheight; + planecenterz = P_GetFFloorTopZAt(rover, frontsector->soundorg.x, frontsector->soundorg.y); if (planecenterz >= floorcenterz && planecenterz <= ceilingcenterz && ((viewz > heightcheck && (rover->flags & FF_BOTHPLANES || !(rover->flags & FF_INVERTPLANES))) @@ -1000,11 +964,7 @@ static void R_Subsector(size_t num) ffloor[numffloors].plane = R_FindPlane(*rover->topheight, *rover->toppic, *frontsector->lightlist[light].lightlevel, *rover->topxoffs, *rover->topyoffs, *rover->topangle, - *frontsector->lightlist[light].extra_colormap, rover -#ifdef POLYOBJECTS_PLANES - , NULL -#endif - , *rover->t_slope); + *frontsector->lightlist[light].extra_colormap, rover, NULL, *rover->t_slope); ffloor[numffloors].slope = *rover->t_slope; @@ -1019,7 +979,6 @@ static void R_Subsector(size_t num) } } -#ifdef POLYOBJECTS_PLANES // Polyobjects have planes, too! if (sub->polyList) { @@ -1085,7 +1044,6 @@ static void R_Subsector(size_t num) po = (polyobj_t *)(po->link.next); } } -#endif #ifdef FLOORSPLATS if (sub->splats) @@ -1108,21 +1066,15 @@ static void R_Subsector(size_t num) firstseg = NULL; -#ifdef POLYOBJECTS // haleyjd 02/19/06: draw polyobjects before static lines if (sub->polyList) R_AddPolyObjects(sub); -#endif while (count--) { // CONS_Debug(DBG_GAMELOGIC, "Adding normal line %d...(%d)\n", line->linedef-lines, leveltime); - if (!line->glseg -#ifdef POLYOBJECTS - && !line->polyseg // ignore segs that belong to polyobjects -#endif - ) - R_AddLine(line); + if (!line->glseg && !line->polyseg) // ignore segs that belong to polyobjects + R_AddLine(line); line++; curline = NULL; /* cph 2001/11/18 - must clear curline now we're done with it, so stuff doesn't try using it for other things */ } @@ -1165,7 +1117,7 @@ void R_Prep3DFloors(sector_t *sector) else memset(sector->lightlist, 0, sizeof (lightlist_t) * count); - heighttest = sector->c_slope ? P_GetZAt(sector->c_slope, sector->soundorg.x, sector->soundorg.y) : sector->ceilingheight; + heighttest = P_GetSectorCeilingZAt(sector, sector->soundorg.x, sector->soundorg.y); sector->lightlist[0].height = heighttest + 1; sector->lightlist[0].slope = sector->c_slope; @@ -1186,7 +1138,7 @@ void R_Prep3DFloors(sector_t *sector) && !(rover->flags & FF_CUTLEVEL) && !(rover->flags & FF_CUTSPRITES))) continue; - heighttest = *rover->t_slope ? P_GetZAt(*rover->t_slope, sector->soundorg.x, sector->soundorg.y) : *rover->topheight; + heighttest = P_GetFFloorTopZAt(rover, sector->soundorg.x, sector->soundorg.y); if (heighttest > bestheight && heighttest < maxheight) { @@ -1196,7 +1148,7 @@ void R_Prep3DFloors(sector_t *sector) continue; } if (rover->flags & FF_DOUBLESHADOW) { - heighttest = *rover->b_slope ? P_GetZAt(*rover->b_slope, sector->soundorg.x, sector->soundorg.y) : *rover->bottomheight; + heighttest = P_GetFFloorBottomZAt(rover, sector->soundorg.x, sector->soundorg.y); if (heighttest > bestheight && heighttest < maxheight) @@ -1238,7 +1190,7 @@ void R_Prep3DFloors(sector_t *sector) if (best->flags & FF_DOUBLESHADOW) { - heighttest = *best->b_slope ? P_GetZAt(*best->b_slope, sector->soundorg.x, sector->soundorg.y) : *best->bottomheight; + heighttest = P_GetFFloorBottomZAt(best, sector->soundorg.x, sector->soundorg.y); if (bestheight == heighttest) ///TODO: do this in a more efficient way -Red { sector->lightlist[i].lightlevel = sector->lightlist[best->lastlight].lightlevel; diff --git a/src/r_bsp.h b/src/r_bsp.h index 1562b79f6..e2da8ebaf 100644 --- a/src/r_bsp.h +++ b/src/r_bsp.h @@ -40,13 +40,11 @@ void R_PortalClearClipSegs(INT32 start, INT32 end); void R_ClearDrawSegs(void); void R_RenderBSPNode(INT32 bspnum); -#ifdef POLYOBJECTS void R_SortPolyObjects(subsector_t *sub); extern size_t numpolys; // number of polyobjects in current subsector extern size_t num_po_ptrs; // number of polyobject pointers allocated extern polyobj_t **po_ptrs; // temp ptr array to sort polyobject pointers -#endif sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel, INT32 *ceilinglightlevel, boolean back); diff --git a/src/r_defs.h b/src/r_defs.h index 4a8f5be34..a36568192 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -28,8 +28,6 @@ #include "m_aatree.h" #endif -#define POLYOBJECTS - // // ClipWallSegment // Clips the given range of columns @@ -107,9 +105,7 @@ typedef struct fixed_t z; ///< Z coordinate. } degenmobj_t; -#ifdef POLYOBJECTS #include "p_polyobj.h" -#endif // Store fake planes in a resizable array insted of just by // heightsec. Allows for multiple fake planes. @@ -434,9 +430,7 @@ typedef struct line_s void *splats; // wallsplat_t list #endif INT32 firsttag, nexttag; // improves searches for tags. -#ifdef POLYOBJECTS polyobj_t *polyobj; // Belongs to a polyobject? -#endif char *text; // a concatenation of all front and back texture names, for linedef specials that require a string. INT16 callcount; // no. of calls left before triggering, for the "X calls" linedef specials, defaults to 0 @@ -479,9 +473,7 @@ typedef struct subsector_s sector_t *sector; INT16 numlines; UINT16 firstline; -#ifdef POLYOBJECTS struct polyobj_s *polyList; // haleyjd 02/19/06: list of polyobjects -#endif #if 1//#ifdef FLOORSPLATS void *splats; // floorsplat_t list #endif @@ -584,10 +576,8 @@ typedef struct seg_s // Why slow things down by calculating lightlists for every thick side? size_t numlights; r_lightlist_t *rlights; -#ifdef POLYOBJECTS polyobj_t *polyseg; boolean dontrenderme; -#endif boolean glseg; } seg_t; diff --git a/src/r_draw.c b/src/r_draw.c index 0155ec113..5351ef37f 100644 --- a/src/r_draw.c +++ b/src/r_draw.c @@ -135,318 +135,6 @@ UINT32 nflatxshift, nflatyshift, nflatshiftup, nflatmask; 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]; /** \brief The R_InitTranslationTables @@ -496,7 +184,7 @@ void R_InitTranslationTables(void) \param dest_colormap colormap to populate \param skincolor translation color */ -static void R_RainbowColormap(UINT8 *dest_colormap, UINT8 skincolor) +static void R_RainbowColormap(UINT8 *dest_colormap, UINT16 skincolor) { INT32 i; 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 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); } @@ -530,7 +218,7 @@ static void R_RainbowColormap(UINT8 *dest_colormap, UINT8 skincolor) if (temp < brightdif) { 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 -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; @@ -551,7 +239,7 @@ static void R_GenerateTranslationColormap(UINT8 *dest_colormap, INT32 skinnum, U memset(dest_colormap, 0, NUM_PALETTE_ENTRIES * sizeof(UINT8)); return; case TC_RAINBOW: - if (color >= MAXTRANSLATIONS) + if (color >= numskincolors) I_Error("Invalid skin color #%hu.", (UINT16)color); if (color != SKINCOLOR_NONE) { @@ -560,11 +248,11 @@ static void R_GenerateTranslationColormap(UINT8 *dest_colormap, INT32 skinnum, U } break; case TC_BLINK: - if (color >= MAXTRANSLATIONS) + if (color >= numskincolors) I_Error("Invalid skin color #%hu.", (UINT16)color); 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; } break; @@ -585,11 +273,11 @@ static void R_GenerateTranslationColormap(UINT8 *dest_colormap, INT32 skinnum, U { 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; 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 { @@ -634,7 +322,7 @@ static void R_GenerateTranslationColormap(UINT8 *dest_colormap, INT32 skinnum, U return; } - if (color >= MAXTRANSLATIONS) + if (color >= numskincolors) I_Error("Invalid skin color #%hu.", (UINT16)color); 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 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. */ -UINT8* R_GetTranslationColormap(INT32 skinnum, skincolors_t color, UINT8 flags) +UINT8* R_GetTranslationColormap(INT32 skinnum, skincolornum_t color, UINT8 flags) { UINT8* ret; INT32 skintableindex; @@ -693,7 +381,7 @@ UINT8* R_GetTranslationColormap(INT32 skinnum, skincolors_t color, UINT8 flags) // Allocate table for skin if necessary 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 ret = translationtablecache[skintableindex][color]; @@ -728,29 +416,32 @@ void R_FlushTranslationColormapCache(void) for (i = 0; i < (INT32)(sizeof(translationtablecache) / sizeof(translationtablecache[0])); 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); - if (color > 0 && color < MAXSKINCOLORS) + UINT16 color = (UINT16)atoi(name); + if (color > 0 && color < numskincolors) return color; - for (color = 1; color < MAXSKINCOLORS; color++) - if (!stricmp(Color_Names[color], name)) + for (color = 1; color < numskincolors; color++) + if (!stricmp(skincolors[color].name, name)) return color; 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. - if (color > MAXSKINCOLORS && color < MAXTRANSLATIONS && !((color - MAXSKINCOLORS) % 5)) - return color;*/ - for (color = 0; color < NUMSUPERCOLORS; color++) - if (!stricmp(Color_Names[color + MAXSKINCOLORS], name)) - return ((color*5) + MAXSKINCOLORS); - return SKINCOLOR_SUPERGOLD1; + UINT16 i, color = SKINCOLOR_SUPERGOLD1; + char *realname = Z_Malloc(MAXCOLORNAME+1, PU_STATIC, NULL); + snprintf(realname, MAXCOLORNAME+1, "Super %s 1", name); + for (i = 1; i < numskincolors; i++) + if (!stricmp(skincolors[i].name, realname)) { + color = i; + break; + } + Z_Free(realname); + return color; } // ========================================================================== diff --git a/src/r_draw.h b/src/r_draw.h index 4d94f861b..329c4974a 100644 --- a/src/r_draw.h +++ b/src/r_draw.h @@ -112,10 +112,10 @@ extern lumpnum_t viewborderlump[8]; // Initialize color translation tables, for player rendering etc. 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); -UINT8 R_GetColorByName(const char *name); -UINT8 R_GetSuperColorByName(const char *name); +UINT16 R_GetColorByName(const char *name); +UINT16 R_GetSuperColorByName(const char *name); // Custom player skin translation void R_InitViewBuffer(INT32 width, INT32 height); diff --git a/src/r_main.c b/src/r_main.c index 9a3d98870..e47bb06e3 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -1388,7 +1388,7 @@ void R_RenderPlayerView(player_t *player) else { portalclipstart = 0; - portalclipend = viewwidth-1; + portalclipend = viewwidth; R_ClearClipSegs(); } R_ClearDrawSegs(); diff --git a/src/r_patch.c b/src/r_patch.c index 9e31d4d19..ad4b3329a 100644 --- a/src/r_patch.c +++ b/src/r_patch.c @@ -1231,9 +1231,9 @@ void R_CacheRotSprite(spritenum_t sprnum, UINT8 frame, spriteinfo_t *sprinfo, sp if (!R_CheckIfPatch(lump)) return; - width = patch->width; - height = patch->height; - leftoffset = patch->leftoffset; + width = SHORT(patch->width); + height = SHORT(patch->height); + leftoffset = SHORT(patch->leftoffset); // rotation pivot px = SPRITE_XCENTER; @@ -1348,7 +1348,7 @@ void R_CacheRotSprite(spritenum_t sprnum, UINT8 frame, spriteinfo_t *sprinfo, sp newpatch = R_MaskedFlatToPatch(rawdst, newwidth, newheight, 0, 0, &size); { newpatch->leftoffset = (newpatch->width / 2) + (leftoffset - px); - newpatch->topoffset = (newpatch->height / 2) + (patch->topoffset - py); + newpatch->topoffset = (newpatch->height / 2) + (SHORT(patch->topoffset) - py); } //BP: we cannot use special tric in hardware mode because feet in ground caused by z-buffer @@ -1358,6 +1358,12 @@ void R_CacheRotSprite(spritenum_t sprnum, UINT8 frame, spriteinfo_t *sprinfo, sp // P_PrecacheLevel if (devparm) spritememory += size; + // convert everything to little-endian, for big-endian support + newpatch->width = SHORT(newpatch->width); + newpatch->height = SHORT(newpatch->height); + newpatch->leftoffset = SHORT(newpatch->leftoffset); + newpatch->topoffset = SHORT(newpatch->topoffset); + #ifdef HWRENDER if (rendermode == render_opengl) { diff --git a/src/r_plane.c b/src/r_plane.c index ca5aa758e..6857b6dca 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -337,11 +337,7 @@ static visplane_t *new_visplane(unsigned hash) // visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, fixed_t xoff, fixed_t yoff, angle_t plangle, extracolormap_t *planecolormap, - ffloor_t *pfloor -#ifdef POLYOBJECTS_PLANES - , polyobj_t *polyobj -#endif - , pslope_t *slope) + ffloor_t *pfloor, polyobj_t *polyobj, pslope_t *slope) { visplane_t *check; unsigned hash; @@ -361,7 +357,6 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, } } -#ifdef POLYOBJECTS_PLANES if (polyobj) { if (polyobj->angle != 0) @@ -376,7 +371,6 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, yoff += polyobj->centerPt.y; } } -#endif // This appears to fix the Nimbus Ruins sky bug. if (picnum == skyflatnum && pfloor) @@ -390,12 +384,10 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, for (check = visplanes[hash]; check; check = check->next) { -#ifdef POLYOBJECTS_PLANES if (check->polyobj && pfloor) continue; if (polyobj != check->polyobj) continue; -#endif if (height == check->height && picnum == check->picnum && lightlevel == check->lightlevel && xoff == check->xoffs && yoff == check->yoffs @@ -426,9 +418,7 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, check->viewz = viewz; check->viewangle = viewangle; check->plangle = plangle; -#ifdef POLYOBJECTS_PLANES check->polyobj = polyobj; -#endif check->slope = slope; memset(check->top, 0xff, sizeof (check->top)); @@ -496,9 +486,7 @@ visplane_t *R_CheckPlane(visplane_t *pl, INT32 start, INT32 stop) new_pl->viewz = pl->viewz; new_pl->viewangle = pl->viewangle; new_pl->plangle = pl->plangle; -#ifdef POLYOBJECTS_PLANES new_pl->polyobj = pl->polyobj; -#endif new_pl->slope = pl->slope; pl = new_pl; pl->minx = start; @@ -523,11 +511,9 @@ void R_ExpandPlane(visplane_t *pl, INT32 start, INT32 stop) // INT32 unionl, unionh; // INT32 x; -#ifdef POLYOBJECTS_PLANES // Don't expand polyobject planes here - we do that on our own. if (pl->polyobj) return; -#endif if (pl->minx > start) pl->minx = start; if (pl->maxx < stop) pl->maxx = stop; @@ -603,11 +589,7 @@ void R_DrawPlanes(void) { for (pl = visplanes[i]; pl; pl = pl->next) { - if (pl->ffloor != NULL -#ifdef POLYOBJECTS_PLANES - || pl->polyobj != NULL -#endif - ) + if (pl->ffloor != NULL || pl->polyobj != NULL) continue; R_DrawSinglePlane(pl); @@ -851,15 +833,15 @@ static void R_SlopeVectors(visplane_t *pl, INT32 i, float fudge) floatv3_t p, m, n; float ang; float vx, vy, vz; - // compiler complains when P_GetZAt is used in FLOAT_TO_FIXED directly - // use this as a temp var to store P_GetZAt's return value each time + // compiler complains when P_GetSlopeZAt is used in FLOAT_TO_FIXED directly + // use this as a temp var to store P_GetSlopeZAt's return value each time fixed_t temp; vx = FIXED_TO_FLOAT(pl->viewx+xoffs); vy = FIXED_TO_FLOAT(pl->viewy-yoffs); vz = FIXED_TO_FLOAT(pl->viewz); - temp = P_GetZAt(pl->slope, pl->viewx, pl->viewy); + temp = P_GetSlopeZAt(pl->slope, pl->viewx, pl->viewy); zeroheight = FIXED_TO_FLOAT(temp); // p is the texture origin in view space @@ -868,7 +850,7 @@ static void R_SlopeVectors(visplane_t *pl, INT32 i, float fudge) ang = ANG2RAD(ANGLE_270 - pl->viewangle); p.x = vx * cos(ang) - vy * sin(ang); p.z = vx * sin(ang) + vy * cos(ang); - temp = P_GetZAt(pl->slope, -xoffs, yoffs); + temp = P_GetSlopeZAt(pl->slope, -xoffs, yoffs); p.y = FIXED_TO_FLOAT(temp) - vz; // m is the v direction vector in view space @@ -881,9 +863,9 @@ static void R_SlopeVectors(visplane_t *pl, INT32 i, float fudge) n.z = -cos(ang); ang = ANG2RAD(pl->plangle); - temp = P_GetZAt(pl->slope, pl->viewx + FLOAT_TO_FIXED(sin(ang)), pl->viewy + FLOAT_TO_FIXED(cos(ang))); + temp = P_GetSlopeZAt(pl->slope, pl->viewx + FLOAT_TO_FIXED(sin(ang)), pl->viewy + FLOAT_TO_FIXED(cos(ang))); m.y = FIXED_TO_FLOAT(temp) - zeroheight; - temp = P_GetZAt(pl->slope, pl->viewx + FLOAT_TO_FIXED(cos(ang)), pl->viewy - FLOAT_TO_FIXED(sin(ang))); + temp = P_GetSlopeZAt(pl->slope, pl->viewx + FLOAT_TO_FIXED(cos(ang)), pl->viewy - FLOAT_TO_FIXED(sin(ang))); n.y = FIXED_TO_FLOAT(temp) - zeroheight; if (ds_powersoftwo) @@ -961,7 +943,6 @@ void R_DrawSinglePlane(visplane_t *pl) #endif spanfunc = spanfuncs[BASEDRAWFUNC]; -#ifdef POLYOBJECTS_PLANES if (pl->polyobj && pl->polyobj->translucency != 0) { spanfunctype = SPANDRAWFUNC_TRANS; @@ -979,95 +960,98 @@ void R_DrawSinglePlane(visplane_t *pl) else light = LIGHTLEVELS-1; - } else -#endif - if (pl->ffloor) + } + else { - // Don't draw planes that shouldn't be drawn. - for (rover = pl->ffloor->target->ffloors; rover; rover = rover->next) + if (pl->ffloor) { - if ((pl->ffloor->flags & FF_CUTEXTRA) && (rover->flags & FF_EXTRA)) + // Don't draw planes that shouldn't be drawn. + for (rover = pl->ffloor->target->ffloors; rover; rover = rover->next) { - if (pl->ffloor->flags & FF_EXTRA) + if ((pl->ffloor->flags & FF_CUTEXTRA) && (rover->flags & FF_EXTRA)) { - // The plane is from an extra 3D floor... Check the flags so - // there are no undesired cuts. - if (((pl->ffloor->flags & (FF_FOG|FF_SWIMMABLE)) == (rover->flags & (FF_FOG|FF_SWIMMABLE))) - && pl->height < *rover->topheight - && pl->height > *rover->bottomheight) - return; + if (pl->ffloor->flags & FF_EXTRA) + { + // The plane is from an extra 3D floor... Check the flags so + // there are no undesired cuts. + if (((pl->ffloor->flags & (FF_FOG|FF_SWIMMABLE)) == (rover->flags & (FF_FOG|FF_SWIMMABLE))) + && pl->height < *rover->topheight + && pl->height > *rover->bottomheight) + return; + } } } - } - if (pl->ffloor->flags & FF_TRANSLUCENT) - { - spanfunctype = SPANDRAWFUNC_TRANS; - - // Hacked up support for alpha value in software mode Tails 09-24-2002 - if (pl->ffloor->alpha < 12) - return; // Don't even draw it - else if (pl->ffloor->alpha < 38) - ds_transmap = transtables + ((tr_trans90-1)<ffloor->alpha < 64) - ds_transmap = transtables + ((tr_trans80-1)<ffloor->alpha < 89) - ds_transmap = transtables + ((tr_trans70-1)<ffloor->alpha < 115) - ds_transmap = transtables + ((tr_trans60-1)<ffloor->alpha < 140) - ds_transmap = transtables + ((tr_trans50-1)<ffloor->alpha < 166) - ds_transmap = transtables + ((tr_trans40-1)<ffloor->alpha < 192) - ds_transmap = transtables + ((tr_trans30-1)<ffloor->alpha < 217) - ds_transmap = transtables + ((tr_trans20-1)<ffloor->alpha < 243) - ds_transmap = transtables + ((tr_trans10-1)<extra_colormap && (pl->extra_colormap->flags & CMF_FOG))) - light = (pl->lightlevel >> LIGHTSEGSHIFT); - else - light = LIGHTLEVELS-1; - } - else if (pl->ffloor->flags & FF_FOG) - { - spanfunctype = SPANDRAWFUNC_FOG; - light = (pl->lightlevel >> LIGHTSEGSHIFT); - } - else light = (pl->lightlevel >> LIGHTSEGSHIFT); - -#ifndef NOWATER - if (pl->ffloor->flags & FF_RIPPLE) - { - INT32 top, bottom; - - itswater = true; - if (spanfunctype == SPANDRAWFUNC_TRANS) + if (pl->ffloor->flags & FF_TRANSLUCENT) { - spanfunctype = SPANDRAWFUNC_WATER; + spanfunctype = SPANDRAWFUNC_TRANS; - // Copy the current scene, ugh - top = pl->high-8; - bottom = pl->low+8; + // Hacked up support for alpha value in software mode Tails 09-24-2002 + if (pl->ffloor->alpha < 12) + return; // Don't even draw it + else if (pl->ffloor->alpha < 38) + ds_transmap = transtables + ((tr_trans90-1)<ffloor->alpha < 64) + ds_transmap = transtables + ((tr_trans80-1)<ffloor->alpha < 89) + ds_transmap = transtables + ((tr_trans70-1)<ffloor->alpha < 115) + ds_transmap = transtables + ((tr_trans60-1)<ffloor->alpha < 140) + ds_transmap = transtables + ((tr_trans50-1)<ffloor->alpha < 166) + ds_transmap = transtables + ((tr_trans40-1)<ffloor->alpha < 192) + ds_transmap = transtables + ((tr_trans30-1)<ffloor->alpha < 217) + ds_transmap = transtables + ((tr_trans20-1)<ffloor->alpha < 243) + ds_transmap = transtables + ((tr_trans10-1)< vid.height) - bottom = vid.height; - - // Only copy the part of the screen we need - VID_BlitLinearScreen((splitscreen && viewplayer == &players[secondarydisplayplayer]) ? screens[0] + (top+(vid.height>>1))*vid.width : screens[0]+((top)*vid.width), screens[1]+((top)*vid.width), - vid.width, bottom-top, - vid.width, vid.width); + if ((spanfunctype == SPANDRAWFUNC_SPLAT) || (pl->extra_colormap && (pl->extra_colormap->flags & CMF_FOG))) + light = (pl->lightlevel >> LIGHTSEGSHIFT); + else + light = LIGHTLEVELS-1; } + else if (pl->ffloor->flags & FF_FOG) + { + spanfunctype = SPANDRAWFUNC_FOG; + light = (pl->lightlevel >> LIGHTSEGSHIFT); + } + else light = (pl->lightlevel >> LIGHTSEGSHIFT); + + #ifndef NOWATER + if (pl->ffloor->flags & FF_RIPPLE) + { + INT32 top, bottom; + + itswater = true; + if (spanfunctype == SPANDRAWFUNC_TRANS) + { + spanfunctype = SPANDRAWFUNC_WATER; + + // Copy the current scene, ugh + top = pl->high-8; + bottom = pl->low+8; + + if (top < 0) + top = 0; + if (bottom > vid.height) + bottom = vid.height; + + // Only copy the part of the screen we need + VID_BlitLinearScreen((splitscreen && viewplayer == &players[secondarydisplayplayer]) ? screens[0] + (top+(vid.height>>1))*vid.width : screens[0]+((top)*vid.width), screens[1]+((top)*vid.width), + vid.width, bottom-top, + vid.width, vid.width); + } + } + #endif } -#endif + else + light = (pl->lightlevel >> LIGHTSEGSHIFT); } - else light = (pl->lightlevel >> LIGHTSEGSHIFT); if (!pl->slope // Don't mess with angle on slopes! We'll handle this ourselves later && viewangle != pl->viewangle+pl->plangle) @@ -1193,7 +1177,7 @@ void R_DrawSinglePlane(visplane_t *pl) if (itswater) { INT32 i; - fixed_t plheight = abs(P_GetZAt(pl->slope, pl->viewx, pl->viewy) - pl->viewz); + fixed_t plheight = abs(P_GetSlopeZAt(pl->slope, pl->viewx, pl->viewy) - pl->viewz); fixed_t rxoffs = xoffs; fixed_t ryoffs = yoffs; diff --git a/src/r_plane.h b/src/r_plane.h index a1a5b7a78..67fa19f38 100644 --- a/src/r_plane.h +++ b/src/r_plane.h @@ -47,9 +47,7 @@ typedef struct visplane_s fixed_t xoffs, yoffs; // Scrolling flats. struct ffloor_s *ffloor; -#ifdef POLYOBJECTS_PLANES polyobj_t *polyobj; -#endif pslope_t *slope; } visplane_t; @@ -80,11 +78,7 @@ void R_MapPlane(INT32 y, INT32 x1, INT32 x2); void R_MakeSpans(INT32 x, INT32 t1, INT32 b1, INT32 t2, INT32 b2); void R_DrawPlanes(void); visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, fixed_t xoff, fixed_t yoff, angle_t plangle, - extracolormap_t *planecolormap, ffloor_t *ffloor -#ifdef POLYOBJECTS_PLANES - , polyobj_t *polyobj -#endif - , pslope_t *slope); + extracolormap_t *planecolormap, ffloor_t *ffloor, polyobj_t *polyobj, pslope_t *slope); visplane_t *R_CheckPlane(visplane_t *pl, INT32 start, INT32 stop); void R_ExpandPlane(visplane_t *pl, INT32 start, INT32 stop); void R_PlaneBounds(visplane_t *plane); @@ -112,9 +106,7 @@ typedef struct planemgr_s struct pslope_s *slope; struct ffloor_s *ffloor; -#ifdef POLYOBJECTS_PLANES polyobj_t *polyobj; -#endif } visffloor_t; extern visffloor_t ffloor[MAXFFLOORS]; diff --git a/src/r_segs.c b/src/r_segs.c index b6b4ca44c..741a25254 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -376,16 +376,13 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) fixed_t leftheight, rightheight; light = &frontsector->lightlist[i]; rlight = &dc_lightlist[i]; - if (light->slope) { - leftheight = P_GetZAt(light->slope, ds->leftpos.x, ds->leftpos.y); - rightheight = P_GetZAt(light->slope, ds->rightpos.x, ds->rightpos.y); - } else - leftheight = rightheight = light->height; + leftheight = P_GetLightZAt(light, ds-> leftpos.x, ds-> leftpos.y); + rightheight = P_GetLightZAt(light, ds->rightpos.x, ds->rightpos.y); - leftheight -= viewz; + leftheight -= viewz; rightheight -= viewz; - rlight->height = (centeryfrac) - FixedMul(leftheight, ds->scale1); + rlight->height = (centeryfrac) - FixedMul(leftheight , ds->scale1); rlight->heightstep = (centeryfrac) - FixedMul(rightheight, ds->scale2); rlight->heightstep = (rlight->heightstep-rlight->height)/(range); //if (x1 > ds->x1) @@ -610,7 +607,6 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) // draw the texture col = (column_t *)((UINT8 *)R_GetColumn(texnum, maskedtexturecol[dc_x]) - 3); -//#ifdef POLYOBJECTS_PLANES #if 0 // Disabling this allows inside edges to render below the planes, for until the clipping is fixed to work right when POs are near the camera. -Red if (curline->dontrenderme && curline->polyseg && (curline->polyseg->flags & POF_RENDERPLANES)) { @@ -800,11 +796,8 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) rlight = &dc_lightlist[p]; #define SLOPEPARAMS(slope, end1, end2, normalheight) \ - if (slope) { \ - end1 = P_GetZAt(slope, ds->leftpos.x, ds->leftpos.y); \ - end2 = P_GetZAt(slope, ds->rightpos.x, ds->rightpos.y); \ - } else \ - end1 = end2 = normalheight; + end1 = P_GetZAt(slope, ds-> leftpos.x, ds-> leftpos.y, normalheight); \ + end2 = P_GetZAt(slope, ds->rightpos.x, ds->rightpos.y, normalheight); SLOPEPARAMS(light->slope, leftheight, rightheight, light->height) SLOPEPARAMS(*pfloor->b_slope, pfloorleft, pfloorright, *pfloor->bottomheight) @@ -817,8 +810,8 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) if (leftheight > pfloorleft && rightheight > pfloorright && i+1 < dc_numlights) { lightlist_t *nextlight = &frontsector->lightlist[i+1]; - if ((nextlight->slope ? P_GetZAt(nextlight->slope, ds->leftpos.x, ds->leftpos.y) : nextlight->height) > pfloorleft - && (nextlight->slope ? P_GetZAt(nextlight->slope, ds->rightpos.x, ds->rightpos.y) : nextlight->height) > pfloorright) + if (P_GetZAt(nextlight->slope, ds-> leftpos.x, ds-> leftpos.y, nextlight->height) > pfloorleft + && P_GetZAt(nextlight->slope, ds->rightpos.x, ds->rightpos.y, nextlight->height) > pfloorright) continue; } @@ -914,15 +907,9 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) dc_texheight = textureheight[texnum]>>FRACBITS; // calculate both left ends - if (*pfloor->t_slope) - left_top = P_GetZAt(*pfloor->t_slope, ds->leftpos.x, ds->leftpos.y) - viewz; - else - left_top = *pfloor->topheight - viewz; + left_top = P_GetFFloorTopZAt (pfloor, ds->leftpos.x, ds->leftpos.y) - viewz; + left_bottom = P_GetFFloorBottomZAt(pfloor, ds->leftpos.x, ds->leftpos.y) - viewz; - if (*pfloor->b_slope) - left_bottom = P_GetZAt(*pfloor->b_slope, ds->leftpos.x, ds->leftpos.y) - viewz; - else - left_bottom = *pfloor->bottomheight - viewz; skewslope = *pfloor->t_slope; // skew using top slope by default if (newline) { @@ -998,15 +985,8 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) fixed_t right_top, right_bottom; // calculate right ends now - if (*pfloor->t_slope) - right_top = P_GetZAt(*pfloor->t_slope, ds->rightpos.x, ds->rightpos.y) - viewz; - else - right_top = *pfloor->topheight - viewz; - - if (*pfloor->b_slope) - right_bottom = P_GetZAt(*pfloor->b_slope, ds->rightpos.x, ds->rightpos.y) - viewz; - else - right_bottom = *pfloor->bottomheight - viewz; + right_top = P_GetFFloorTopZAt (pfloor, ds->rightpos.x, ds->rightpos.y) - viewz; + right_bottom = P_GetFFloorBottomZAt(pfloor, ds->rightpos.x, ds->rightpos.y) - viewz; // using INT64 to avoid 32bit overflow top_frac = (INT64)centeryfrac - (((INT64)left_top * ds->scale1) >> FRACBITS); @@ -1309,10 +1289,8 @@ static void R_RenderSegLoop (void) for (i = 0; i < numffloors; i++) { -#ifdef POLYOBJECTS_PLANES if (ffloor[i].polyobj && (!curline->polyseg || ffloor[i].polyobj != curline->polyseg)) continue; -#endif if (ffloor[i].height < viewz) { @@ -1325,18 +1303,19 @@ static void R_RenderSegLoop (void) if (bottom_w > bottom) bottom_w = bottom; -#ifdef POLYOBJECTS_PLANES // Polyobject-specific hack to fix plane leaking -Red - if (ffloor[i].polyobj && top_w >= bottom_w) { + if (ffloor[i].polyobj && top_w >= bottom_w) + { ffloor[i].plane->top[rw_x] = 0xFFFF; ffloor[i].plane->bottom[rw_x] = 0x0000; // fix for sky plane drawing crashes - Monster Iestyn 25/05/18 - } else -#endif - - if (top_w <= bottom_w) + } + else { - ffloor[i].plane->top[rw_x] = (INT16)top_w; - ffloor[i].plane->bottom[rw_x] = (INT16)bottom_w; + if (top_w <= bottom_w) + { + ffloor[i].plane->top[rw_x] = (INT16)top_w; + ffloor[i].plane->bottom[rw_x] = (INT16)bottom_w; + } } } else if (ffloor[i].height > viewz) @@ -1350,18 +1329,19 @@ static void R_RenderSegLoop (void) if (bottom_w > bottom) bottom_w = bottom; -#ifdef POLYOBJECTS_PLANES // Polyobject-specific hack to fix plane leaking -Red - if (ffloor[i].polyobj && top_w >= bottom_w) { + if (ffloor[i].polyobj && top_w >= bottom_w) + { ffloor[i].plane->top[rw_x] = 0xFFFF; ffloor[i].plane->bottom[rw_x] = 0x0000; // fix for sky plane drawing crashes - Monster Iestyn 25/05/18 - } else -#endif - - if (top_w <= bottom_w) + } + else { - ffloor[i].plane->top[rw_x] = (INT16)top_w; - ffloor[i].plane->bottom[rw_x] = (INT16)bottom_w; + if (top_w <= bottom_w) + { + ffloor[i].plane->top[rw_x] = (INT16)top_w; + ffloor[i].plane->bottom[rw_x] = (INT16)bottom_w; + } } } } @@ -1788,11 +1768,8 @@ void R_StoreWallRange(INT32 start, INT32 stop) #define SLOPEPARAMS(slope, end1, end2, normalheight) \ - if (slope) { \ - end1 = P_GetZAt(slope, segleft.x, segleft.y); \ - end2 = P_GetZAt(slope, segright.x, segright.y); \ - } else \ - end1 = end2 = normalheight; + end1 = P_GetZAt(slope, segleft.x, segleft.y, normalheight); \ + end2 = P_GetZAt(slope, segright.x, segright.y, normalheight); SLOPEPARAMS(frontsector->c_slope, worldtop, worldtopslope, frontsector->ceilingheight) SLOPEPARAMS(frontsector->f_slope, worldbottom, worldbottomslope, frontsector->floorheight) @@ -1818,17 +1795,11 @@ void R_StoreWallRange(INT32 start, INT32 stop) { for (i = 0; i < numffloors; i++) { -#ifdef POLYOBJECTS_PLANES if (ffloor[i].polyobj && (!ds_p->curline->polyseg || ffloor[i].polyobj != ds_p->curline->polyseg)) continue; -#endif - if (ffloor[i].slope) { - ffloor[i].f_pos = P_GetZAt(ffloor[i].slope, segleft.x, segleft.y) - viewz; - ffloor[i].f_pos_slope = P_GetZAt(ffloor[i].slope, segright.x, segright.y) - viewz; - } - else - ffloor[i].f_pos_slope = ffloor[i].f_pos = ffloor[i].height - viewz; + ffloor[i].f_pos = P_GetZAt(ffloor[i].slope, segleft .x, segleft .y, ffloor[i].height) - viewz; + ffloor[i].f_pos_slope = P_GetZAt(ffloor[i].slope, segright.x, segright.y, ffloor[i].height) - viewz; } } @@ -1921,12 +1892,12 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (worldbottomslope > worldlowslope || worldbottom > worldlow) { ds_p->silhouette = SIL_BOTTOM; - if ((backsector->f_slope ? P_GetZAt(backsector->f_slope, viewx, viewy) : backsector->floorheight) > viewz) + if (P_GetSectorFloorZAt(backsector, viewx, viewy) > viewz) ds_p->bsilheight = INT32_MAX; else ds_p->bsilheight = (frontsector->f_slope ? INT32_MAX : frontsector->floorheight); } - else if ((backsector->f_slope ? P_GetZAt(backsector->f_slope, viewx, viewy) : backsector->floorheight) > viewz) + else if (P_GetSectorFloorZAt(backsector, viewx, viewy) > viewz) { ds_p->silhouette = SIL_BOTTOM; ds_p->bsilheight = INT32_MAX; @@ -1939,12 +1910,12 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (worldtopslope < worldhighslope || worldtop < worldhigh) { ds_p->silhouette |= SIL_TOP; - if ((backsector->c_slope ? P_GetZAt(backsector->c_slope, viewx, viewy) : backsector->ceilingheight) < viewz) + if (P_GetSectorCeilingZAt(backsector, viewx, viewy) < viewz) ds_p->tsilheight = INT32_MIN; else ds_p->tsilheight = (frontsector->c_slope ? INT32_MIN : frontsector->ceilingheight); } - else if ((backsector->c_slope ? P_GetZAt(backsector->c_slope, viewx, viewy) : backsector->ceilingheight) < viewz) + else if (P_GetSectorCeilingZAt(backsector, viewx, viewy) < viewz) { ds_p->silhouette |= SIL_TOP; ds_p->tsilheight = INT32_MIN; @@ -2275,10 +2246,10 @@ void R_StoreWallRange(INT32 start, INT32 stop) continue; // Oy vey. - if ( ((*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft .x, segleft .y) : *rover-> topheight) <= worldbottom + viewz - && (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover-> topheight) <= worldbottomslope + viewz) - ||((*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft .x, segleft .y) : *rover->bottomheight) >= worldtop + viewz - && (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) >= worldtopslope + viewz)) + if ( ((P_GetFFloorTopZAt (rover, segleft .x, segleft .y)) <= worldbottom + viewz + && (P_GetFFloorTopZAt (rover, segright.x, segright.y)) <= worldbottomslope + viewz) + ||((P_GetFFloorBottomZAt(rover, segleft .x, segleft .y)) >= worldtop + viewz + && (P_GetFFloorBottomZAt(rover, segright.x, segright.y)) >= worldtopslope + viewz)) continue; ds_p->thicksides[i] = rover; @@ -2296,16 +2267,16 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (rover->norender == leveltime) continue; // Oy vey. - if ( ((*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft .x, segleft .y) : *rover-> topheight) <= worldbottom + viewz - && (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover-> topheight) <= worldbottomslope + viewz) - ||((*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft .x, segleft .y) : *rover->bottomheight) >= worldtop + viewz - && (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) >= worldtopslope + viewz)) + if ( (P_GetFFloorTopZAt (rover, segleft .x, segleft .y) <= worldbottom + viewz + && P_GetFFloorTopZAt (rover, segright.x, segright.y) <= worldbottomslope + viewz) + ||(P_GetFFloorBottomZAt(rover, segleft .x, segleft .y) >= worldtop + viewz + && P_GetFFloorBottomZAt(rover, segright.x, segright.y) >= worldtopslope + viewz)) continue; - if ( ((*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft .x, segleft .y) : *rover-> topheight) <= worldlow + viewz - && (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover-> topheight) <= worldlowslope + viewz) - ||((*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft .x, segleft .y) : *rover->bottomheight) >= worldhigh + viewz - && (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) >= worldhighslope + viewz)) + if ( (P_GetFFloorTopZAt (rover, segleft .x, segleft .y) <= worldlow + viewz + && P_GetFFloorTopZAt (rover, segright.x, segright.y) <= worldlowslope + viewz) + ||(P_GetFFloorBottomZAt(rover, segleft .x, segleft .y) >= worldhigh + viewz + && P_GetFFloorBottomZAt(rover, segright.x, segright.y) >= worldhighslope + viewz)) continue; ds_p->thicksides[i] = rover; @@ -2328,33 +2299,40 @@ void R_StoreWallRange(INT32 start, INT32 stop) maskedtextureheight = ds_p->maskedtextureheight; // note to red, this == &(ds_p->maskedtextureheight[0]) -#ifdef POLYOBJECTS - if (curline->polyseg) { // use REAL front and back floors please, so midtexture rendering isn't mucked up + if (curline->polyseg) + { // use REAL front and back floors please, so midtexture rendering isn't mucked up rw_midtextureslide = rw_midtexturebackslide = 0; if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) rw_midtexturemid = rw_midtextureback = max(curline->frontsector->floorheight, curline->backsector->floorheight) - viewz; else rw_midtexturemid = rw_midtextureback = min(curline->frontsector->ceilingheight, curline->backsector->ceilingheight) - viewz; - } else -#endif - // Set midtexture starting height - if (linedef->flags & ML_EFFECT2) { // Ignore slopes when texturing - rw_midtextureslide = rw_midtexturebackslide = 0; - if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) - rw_midtexturemid = rw_midtextureback = max(frontsector->floorheight, backsector->floorheight) - viewz; - else - rw_midtexturemid = rw_midtextureback = min(frontsector->ceilingheight, backsector->ceilingheight) - viewz; + } + else + { + // Set midtexture starting height + if (linedef->flags & ML_EFFECT2) + { // Ignore slopes when texturing + rw_midtextureslide = rw_midtexturebackslide = 0; + if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) + rw_midtexturemid = rw_midtextureback = max(frontsector->floorheight, backsector->floorheight) - viewz; + else + rw_midtexturemid = rw_midtextureback = min(frontsector->ceilingheight, backsector->ceilingheight) - viewz; - } else if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) { - rw_midtexturemid = worldbottom; - rw_midtextureslide = floorfrontslide; - rw_midtextureback = worldlow; - rw_midtexturebackslide = floorbackslide; - } else { - rw_midtexturemid = worldtop; - rw_midtextureslide = ceilingfrontslide; - rw_midtextureback = worldhigh; - rw_midtexturebackslide = ceilingbackslide; + } + else if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) + { + rw_midtexturemid = worldbottom; + rw_midtextureslide = floorfrontslide; + rw_midtextureback = worldlow; + rw_midtexturebackslide = floorbackslide; + } + else + { + rw_midtexturemid = worldtop; + rw_midtextureslide = ceilingfrontslide; + rw_midtextureback = worldhigh; + rw_midtexturebackslide = ceilingbackslide; + } } rw_midtexturemid += sidedef->rowoffset; rw_midtextureback += sidedef->rowoffset; @@ -2421,17 +2399,13 @@ void R_StoreWallRange(INT32 start, INT32 stop) // and doesn't need to be marked. if (frontsector->heightsec == -1) { - if (frontsector->floorpic != skyflatnum && (frontsector->f_slope ? - P_GetZAt(frontsector->f_slope, viewx, viewy) : - frontsector->floorheight) >= viewz) + if (frontsector->floorpic != skyflatnum && P_GetSectorFloorZAt(frontsector, viewx, viewy) >= viewz) { // above view plane markfloor = false; } - if (frontsector->ceilingpic != skyflatnum && (frontsector->c_slope ? - P_GetZAt(frontsector->c_slope, viewx, viewy) : - frontsector->ceilingheight) <= viewz) + if (frontsector->ceilingpic != skyflatnum && P_GetSectorCeilingZAt(frontsector, viewx, viewy) <= viewz) { // below view plane markceiling = false; @@ -2483,14 +2457,12 @@ void R_StoreWallRange(INT32 start, INT32 stop) light = &frontsector->lightlist[i]; rlight = &dc_lightlist[p]; - if (light->slope) { - leftheight = P_GetZAt(light->slope, segleft.x, segleft.y); - rightheight = P_GetZAt(light->slope, segright.x, segright.y); + leftheight = P_GetLightZAt(light, segleft.x, segleft.y); + rightheight = P_GetLightZAt(light, segright.x, segright.y); + if (light->slope) // Flag sector as having slopes frontsector->hasslope = true; - } else - leftheight = rightheight = light->height; leftheight -= viewz; rightheight -= viewz; @@ -2514,19 +2486,17 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (light->caster && light->caster->flags & FF_CUTSOLIDS) { - if (*light->caster->b_slope) { - leftheight = P_GetZAt(*light->caster->b_slope, segleft.x, segleft.y); - rightheight = P_GetZAt(*light->caster->b_slope, segright.x, segright.y); + leftheight = P_GetFFloorBottomZAt(light->caster, segleft.x, segleft.y); + rightheight = P_GetFFloorBottomZAt(light->caster, segright.x, segright.y); + if (*light->caster->b_slope) // Flag sector as having slopes frontsector->hasslope = true; - } else - leftheight = rightheight = *light->caster->bottomheight; - leftheight -= viewz; + leftheight -= viewz; rightheight -= viewz; - leftheight >>= 4; + leftheight >>= 4; rightheight >>= 4; rlight->botheight = (centeryfrac>>4) - FixedMul(leftheight, rw_scale); @@ -2610,9 +2580,9 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (*rover->b_slope || *rover->t_slope) backsector->hasslope = true; - roverleft = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) - viewz; - roverright = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) - viewz; - planevistest = (*rover->b_slope ? P_GetZAt(*rover->b_slope, viewx, viewy) : *rover->bottomheight); + roverleft = P_GetFFloorBottomZAt(rover, segleft .x, segleft .y) - viewz; + roverright = P_GetFFloorBottomZAt(rover, segright.x, segright.y) - viewz; + planevistest = P_GetFFloorBottomZAt(rover, viewx, viewy); if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) && (roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) && @@ -2633,9 +2603,9 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (i >= MAXFFLOORS) break; - roverleft = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) - viewz; - roverright = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover->topheight) - viewz; - planevistest = (*rover->t_slope ? P_GetZAt(*rover->t_slope, viewx, viewy) : *rover->topheight); + roverleft = P_GetFFloorTopZAt(rover, segleft .x, segleft .y) - viewz; + roverright = P_GetFFloorTopZAt(rover, segright.x, segright.y) - viewz; + planevistest = P_GetFFloorTopZAt(rover, viewx, viewy); if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) && (roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) && @@ -2667,9 +2637,9 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (*rover->b_slope || *rover->t_slope) frontsector->hasslope = true; - roverleft = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) - viewz; - roverright = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) - viewz; - planevistest = (*rover->b_slope ? P_GetZAt(*rover->b_slope, viewx, viewy) : *rover->bottomheight); + roverleft = P_GetFFloorBottomZAt(rover, segleft .x, segleft .y) - viewz; + roverright = P_GetFFloorBottomZAt(rover, segright.x, segright.y) - viewz; + planevistest = P_GetFFloorBottomZAt(rover, viewx, viewy); if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) && (roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) && @@ -2690,9 +2660,9 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (i >= MAXFFLOORS) break; - roverleft = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) - viewz; - roverright = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover->topheight) - viewz; - planevistest = (*rover->t_slope ? P_GetZAt(*rover->t_slope, viewx, viewy) : *rover->topheight); + roverleft = P_GetFFloorTopZAt(rover, segleft .x, segleft .y) - viewz; + roverright = P_GetFFloorTopZAt(rover, segright.x, segright.y) - viewz; + planevistest = P_GetFFloorTopZAt(rover, viewx, viewy); if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) && (roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) && @@ -2711,7 +2681,6 @@ void R_StoreWallRange(INT32 start, INT32 stop) } } } -#ifdef POLYOBJECTS_PLANES if (curline->polyseg && frontsector && (curline->polyseg->flags & POF_RENDERPLANES)) { while (i < numffloors && ffloor[i].polyobj != curline->polyseg) i++; @@ -2750,7 +2719,6 @@ void R_StoreWallRange(INT32 start, INT32 stop) i++; } } -#endif numbackffloors = i; } @@ -2804,7 +2772,6 @@ void R_StoreWallRange(INT32 start, INT32 stop) for (i = 0; i < numffloors; i++) R_ExpandPlane(ffloor[i].plane, rw_x, rw_stopx - 1); } -#ifdef POLYOBJECTS_PLANES // FIXME hack to fix planes disappearing when a seg goes behind the camera. This NEEDS to be changed to be done properly. -Red if (curline->polyseg) { @@ -2819,7 +2786,6 @@ void R_StoreWallRange(INT32 start, INT32 stop) ffloor[i].plane->maxx = rw_stopx - 1; } } -#endif } #ifdef WALLSPLATS diff --git a/src/r_skins.c b/src/r_skins.c index caf1fb172..57ce382c4 100644 --- a/src/r_skins.c +++ b/src/r_skins.c @@ -248,7 +248,7 @@ void SetPlayerSkinByNum(INT32 playernum, INT32 skinnum) { player_t *player = &players[playernum]; skin_t *skin = &skins[skinnum]; - UINT8 newcolor = 0; + UINT16 newcolor = 0; if (skinnum >= 0 && skinnum < numskins && R_SkinUsable(playernum, skinnum)) // Make sure it exists! { diff --git a/src/r_skins.h b/src/r_skins.h index 96697b422..45c90bdb4 100644 --- a/src/r_skins.h +++ b/src/r_skins.h @@ -65,9 +65,9 @@ typedef struct // Definable color translation table UINT8 starttranscolor; - UINT8 prefcolor; - UINT8 supercolor; - UINT8 prefoppositecolor; // if 0 use tables instead + UINT16 prefcolor; + UINT16 supercolor; + UINT16 prefoppositecolor; // if 0 use tables instead fixed_t highresscale; // scale of highres, default is 0.5 UINT8 contspeed; // continue screen animation speed diff --git a/src/r_things.c b/src/r_things.c index b4ffd4408..14782d0c2 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -888,7 +888,7 @@ static void R_DrawVisSprite(vissprite_t *vis) vis->x2 = vid.width-1; localcolfunc = (vis->cut & SC_VFLIP) ? R_DrawFlippedMaskedColumn : R_DrawMaskedColumn; - lengthcol = patch->height; + lengthcol = SHORT(patch->height); // Split drawing loops for paper and non-paper to reduce conditional checks per sprite if (vis->scalestep) @@ -1019,13 +1019,12 @@ static void R_SplitSprite(vissprite_t *sprite) for (i = 1; i < sector->numlights; i++) { - fixed_t testheight = sector->lightlist[i].height; + fixed_t testheight; if (!(sector->lightlist[i].caster->flags & FF_CUTSPRITES)) continue; - if (sector->lightlist[i].slope) - testheight = P_GetZAt(sector->lightlist[i].slope, sprite->gx, sprite->gy); + testheight = P_GetLightZAt(§or->lightlist[i], sprite->gx, sprite->gy); if (testheight >= sprite->gzt) continue; @@ -1107,10 +1106,12 @@ fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope) { sector = node->m_sector; - slope = (sector->heightsec != -1) ? NULL : sector->f_slope; - z = slope ? P_GetZAt(slope, thing->x, thing->y) : ( - (sector->heightsec != -1) ? sectors[sector->heightsec].floorheight : sector->floorheight - ); + slope = sector->heightsec != -1 ? NULL : sector->f_slope; + + if (sector->heightsec != -1) + z = sectors[sector->heightsec].floorheight; + else + z = P_GetSectorFloorZAt(sector, thing->x, thing->y); if (z < thing->z+thing->height/2 && z > floorz) { @@ -1124,7 +1125,7 @@ fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope) if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERPLANES) || (rover->alpha < 90 && !(rover->flags & FF_SWIMMABLE))) continue; - z = *rover->t_slope ? P_GetZAt(*rover->t_slope, thing->x, thing->y) : *rover->topheight; + z = P_GetFFloorTopZAt(rover, thing->x, thing->y); if (z < thing->z+thing->height/2 && z > floorz) { floorz = z; @@ -1140,7 +1141,6 @@ fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope) } #if 0 // Unfortunately, this drops CEZ2 down to sub-17 FPS on my i7. -//#ifdef POLYOBJECTS // Check polyobjects and see if floorz needs to be altered, for rings only because they don't update floorz if (thing->type == MT_RING) { @@ -1231,8 +1231,8 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale, yscale = FixedDiv(projectiony, tz); shadowxscale = FixedMul(thing->radius*2, scalemul); shadowyscale = FixedMul(FixedMul(thing->radius*2, scalemul), FixedDiv(abs(floorz - viewz), tz)); - shadowyscale = min(shadowyscale, shadowxscale) / patch->height; - shadowxscale /= patch->width; + shadowyscale = min(shadowyscale, shadowxscale) / SHORT(patch->height); + shadowxscale /= SHORT(patch->width); shadowskew = 0; if (floorslope) @@ -1247,24 +1247,24 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale, //CONS_Printf("Shadow is sloped by %d %d\n", xslope, zslope); if (viewz < floorz) - shadowyscale += FixedMul(FixedMul(thing->radius*2 / patch->height, scalemul), zslope); + shadowyscale += FixedMul(FixedMul(thing->radius*2 / SHORT(patch->height), scalemul), zslope); else - shadowyscale -= FixedMul(FixedMul(thing->radius*2 / patch->height, scalemul), zslope); + shadowyscale -= FixedMul(FixedMul(thing->radius*2 / SHORT(patch->height), scalemul), zslope); shadowyscale = abs(shadowyscale); shadowskew = xslope; } - tx -= patch->width * shadowxscale/2; + tx -= SHORT(patch->width) * shadowxscale/2; x1 = (centerxfrac + FixedMul(tx,xscale))>>FRACBITS; if (x1 >= viewwidth) return; - tx += patch->width * shadowxscale; + tx += SHORT(patch->width) * shadowxscale; x2 = ((centerxfrac + FixedMul(tx,xscale))>>FRACBITS); x2--; if (x2 < 0 || x2 <= x1) return; - if (shadowyscale < FRACUNIT/patch->height) return; // fix some crashes? + if (shadowyscale < FRACUNIT/SHORT(patch->height)) return; // fix some crashes? shadow = R_NewVisSprite(); shadow->patch = patch; @@ -1279,8 +1279,8 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale, shadow->dispoffset = vis->dispoffset - 5; shadow->gx = thing->x; shadow->gy = thing->y; - shadow->gzt = shadow->pz + shadow->patch->height * shadowyscale / 2; - shadow->gz = shadow->gzt - shadow->patch->height * shadowyscale; + shadow->gzt = shadow->pz + SHORT(patch->height) * shadowyscale / 2; + shadow->gz = shadow->gzt - SHORT(patch->height) * shadowyscale; shadow->texturemid = FixedMul(thing->scale, FixedDiv(shadow->gzt - viewz, shadowyscale)); if (thing->skin && ((skin_t *)thing->skin)->flags & SF_HIRES) shadow->texturemid = FixedMul(shadow->texturemid, ((skin_t *)thing->skin)->highresscale); @@ -1301,7 +1301,7 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale, shadow->startfrac = 0; //shadow->xiscale = 0x7ffffff0 / (shadow->xscale/2); - shadow->xiscale = (patch->width<xiscale = (SHORT(patch->width)<x1 > x1) shadow->startfrac += shadow->xiscale*(shadow->x1-x1); @@ -1317,8 +1317,7 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale, // R_GetPlaneLight won't work on sloped lights! for (lightnum = 1; lightnum < thing->subsector->sector->numlights; lightnum++) { - fixed_t h = thing->subsector->sector->lightlist[lightnum].slope ? P_GetZAt(thing->subsector->sector->lightlist[lightnum].slope, thing->x, thing->y) - : thing->subsector->sector->lightlist[lightnum].height; + fixed_t h = P_GetLightZAt(&thing->subsector->sector->lightlist[lightnum], thing->x, thing->y); if (h <= shadow->gzt) { light = lightnum - 1; break; @@ -1347,7 +1346,6 @@ static void R_ProjectSprite(mobj_t *thing) { mobj_t *oldthing = thing; fixed_t tr_x, tr_y; - fixed_t gxt, gyt; fixed_t tx, tz; fixed_t xscale, yscale, sortscale; //added : 02-02-98 : aaargll..if I were a math-guy!!! @@ -1360,7 +1358,7 @@ static void R_ProjectSprite(mobj_t *thing) #endif size_t lump; - size_t rot; + size_t frame, rot; UINT16 flip; boolean vflip = (!(thing->eflags & MFE_VERTICALFLIP) != !(thing->frame & FF_VERTICALFLIP)); @@ -1400,21 +1398,16 @@ static void R_ProjectSprite(mobj_t *thing) tr_x = thing->x - viewx; tr_y = thing->y - viewy; - gxt = FixedMul(tr_x, viewcos); - gyt = -FixedMul(tr_y, viewsin); - - tz = gxt-gyt; + tz = FixedMul(tr_x, viewcos) + FixedMul(tr_y, viewsin); // near/far distance // thing is behind view plane? if (!papersprite && (tz < FixedMul(MINZ, this_scale))) // papersprite clipping is handled later return; - gxt = -FixedMul(tr_x, viewsin); - gyt = FixedMul(tr_y, viewcos); - basetx = tx = -(gyt + gxt); + basetx = tx = FixedMul(tr_x, viewsin) - FixedMul(tr_y, viewcos); // sideways distance // too far off the side? - if (!papersprite && abs(tx) > tz<<2) // papersprite clipping is handled later + if (!papersprite && abs(tx) > FixedMul(tz, fovtan)<<2) // papersprite clipping is handled later return; // aspect ratio stuff @@ -1427,7 +1420,7 @@ static void R_ProjectSprite(mobj_t *thing) I_Error("R_ProjectSprite: invalid sprite number %d ", thing->sprite); #endif - rot = thing->frame&FF_FRAMEMASK; + frame = thing->frame&FF_FRAMEMASK; //Fab : 02-08-98: 'skin' override spritedef currently used for skin if (thing->skin && thing->sprite == SPR_PLAY) @@ -1436,15 +1429,15 @@ static void R_ProjectSprite(mobj_t *thing) #ifdef ROTSPRITE sprinfo = &((skin_t *)thing->skin)->sprinfo[thing->sprite2]; #endif - if (rot >= sprdef->numframes) { - CONS_Alert(CONS_ERROR, M_GetText("R_ProjectSprite: invalid skins[\"%s\"].sprites[%sSPR2_%s] frame %s\n"), ((skin_t *)thing->skin)->name, ((thing->sprite2 & FF_SPR2SUPER) ? "FF_SPR2SUPER|": ""), spr2names[(thing->sprite2 & ~FF_SPR2SUPER)], sizeu5(rot)); + if (frame >= sprdef->numframes) { + CONS_Alert(CONS_ERROR, M_GetText("R_ProjectSprite: invalid skins[\"%s\"].sprites[%sSPR2_%s] frame %s\n"), ((skin_t *)thing->skin)->name, ((thing->sprite2 & FF_SPR2SUPER) ? "FF_SPR2SUPER|": ""), spr2names[(thing->sprite2 & ~FF_SPR2SUPER)], sizeu5(frame)); thing->sprite = states[S_UNKNOWN].sprite; thing->frame = states[S_UNKNOWN].frame; sprdef = &sprites[thing->sprite]; #ifdef ROTSPRITE sprinfo = NULL; #endif - rot = thing->frame&FF_FRAMEMASK; + frame = thing->frame&FF_FRAMEMASK; } } else @@ -1454,10 +1447,10 @@ static void R_ProjectSprite(mobj_t *thing) sprinfo = NULL; #endif - if (rot >= sprdef->numframes) + if (frame >= sprdef->numframes) { CONS_Alert(CONS_ERROR, M_GetText("R_ProjectSprite: invalid sprite frame %s/%s for %s\n"), - sizeu1(rot), sizeu2(sprdef->numframes), sprnames[thing->sprite]); + sizeu1(frame), sizeu2(sprdef->numframes), sprnames[thing->sprite]); if (thing->sprite == thing->state->sprite && thing->frame == thing->state->frame) { thing->state->sprite = states[S_UNKNOWN].sprite; @@ -1466,11 +1459,11 @@ static void R_ProjectSprite(mobj_t *thing) thing->sprite = states[S_UNKNOWN].sprite; thing->frame = states[S_UNKNOWN].frame; sprdef = &sprites[thing->sprite]; - rot = thing->frame&FF_FRAMEMASK; + frame = thing->frame&FF_FRAMEMASK; } } - sprframe = &sprdef->spriteframes[rot]; + sprframe = &sprdef->spriteframes[frame]; #ifdef PARANOIA if (!sprframe) @@ -1524,14 +1517,14 @@ static void R_ProjectSprite(mobj_t *thing) { rollangle = R_GetRollAngle(thing->rollangle); if (!(sprframe->rotsprite.cached & (1<sprite, (thing->frame & FF_FRAMEMASK), sprinfo, sprframe, rot, flip); + R_CacheRotSprite(thing->sprite, frame, sprinfo, sprframe, rot, flip); rotsprite = sprframe->rotsprite.patch[rot][rollangle]; if (rotsprite != NULL) { - spr_width = rotsprite->width << FRACBITS; - spr_height = rotsprite->height << FRACBITS; - spr_offset = rotsprite->leftoffset << FRACBITS; - spr_topoffset = rotsprite->topoffset << FRACBITS; + spr_width = SHORT(rotsprite->width) << FRACBITS; + spr_height = SHORT(rotsprite->height) << FRACBITS; + spr_offset = SHORT(rotsprite->leftoffset) << FRACBITS; + spr_topoffset = SHORT(rotsprite->topoffset) << FRACBITS; // flip -> rotate, not rotate -> flip flip = 0; } @@ -1562,17 +1555,9 @@ static void R_ProjectSprite(mobj_t *thing) tr_x += FixedMul(offset, cosmul); tr_y += FixedMul(offset, sinmul); - gxt = FixedMul(tr_x, viewcos); - gyt = -FixedMul(tr_y, viewsin); - tz = gxt-gyt; - yscale = FixedDiv(projectiony, tz); - //if (yscale < 64) return; // Fix some funky visuals + tz = FixedMul(tr_x, viewcos) + FixedMul(tr_y, viewsin); - gxt = -FixedMul(tr_x, viewsin); - gyt = FixedMul(tr_y, viewcos); - tx = -(gyt + gxt); - xscale = FixedDiv(projection, tz); - x1 = (centerxfrac + FixedMul(tx,xscale))>>FRACBITS; + tx = FixedMul(tr_x, viewsin) - FixedMul(tr_y, viewcos); // Get paperoffset (offset) and paperoffset (distance) paperoffset = -FixedMul(tr_x, cosmul) - FixedMul(tr_y, sinmul); @@ -1586,17 +1571,9 @@ static void R_ProjectSprite(mobj_t *thing) tr_x += FixedMul(offset2, cosmul); tr_y += FixedMul(offset2, sinmul); - gxt = FixedMul(tr_x, viewcos); - gyt = -FixedMul(tr_y, viewsin); - tz2 = gxt-gyt; - yscale2 = FixedDiv(projectiony, tz2); - //if (yscale2 < 64) return; // ditto + tz2 = FixedMul(tr_x, viewcos) + FixedMul(tr_y, viewsin); - gxt = -FixedMul(tr_x, viewsin); - gyt = FixedMul(tr_y, viewcos); - tx2 = -(gyt + gxt); - xscale2 = FixedDiv(projection, tz2); - x2 = ((centerxfrac + FixedMul(tx2,xscale2))>>FRACBITS); + tx2 = FixedMul(tr_x, viewsin) - FixedMul(tr_y, viewcos); if (max(tz, tz2) < FixedMul(MINZ, this_scale)) // non-papersprite clipping is handled earlier return; @@ -1607,24 +1584,31 @@ static void R_ProjectSprite(mobj_t *thing) fixed_t div = FixedDiv(tz2-tz, FixedMul(MINZ, this_scale)-tz); tx += FixedDiv(tx2-tx, div); tz = FixedMul(MINZ, this_scale); - yscale = FixedDiv(projectiony, tz); - xscale = FixedDiv(projection, tz); - x1 = (centerxfrac + FixedMul(tx,xscale))>>FRACBITS; } else if (tz2 < FixedMul(MINZ, this_scale)) { fixed_t div = FixedDiv(tz-tz2, FixedMul(MINZ, this_scale)-tz2); tx2 += FixedDiv(tx-tx2, div); tz2 = FixedMul(MINZ, this_scale); - yscale2 = FixedDiv(projectiony, tz2); - xscale2 = FixedDiv(projection, tz2); - x2 = (centerxfrac + FixedMul(tx2,xscale2))>>FRACBITS; } + if (tx2 < -(FixedMul(tz2, fovtan)<<2) || tx > FixedMul(tz, fovtan)<<2) // too far off the side? + return; + + yscale = FixedDiv(projectiony, tz); + xscale = FixedDiv(projection, tz); + + x1 = (centerxfrac + FixedMul(tx,xscale))>>FRACBITS; + // off the right side? if (x1 > viewwidth) return; + yscale2 = FixedDiv(projectiony, tz2); + xscale2 = FixedDiv(projection, tz2); + + x2 = (centerxfrac + FixedMul(tx2,xscale2))>>FRACBITS; + // off the left side if (x2 < 0) return; @@ -1671,9 +1655,7 @@ static void R_ProjectSprite(mobj_t *thing) tr_x = thing->x - viewx; tr_y = thing->y - viewy; - gxt = FixedMul(tr_x, viewcos); - gyt = -FixedMul(tr_y, viewsin); - tz = gxt-gyt; + tz = FixedMul(tr_x, viewcos) + FixedMul(tr_y, viewsin); linkscale = FixedDiv(projectiony, tz); if (tz < FixedMul(MINZ, this_scale)) @@ -1689,7 +1671,7 @@ static void R_ProjectSprite(mobj_t *thing) // PORTAL SPRITE CLIPPING if (portalrender && portalclipline) { - if (x2 < portalclipstart || x1 > portalclipend) + if (x2 < portalclipstart || x1 >= portalclipend) return; if (P_PointOnLineSide(thing->x, thing->y, portalclipline) != 0) @@ -1724,8 +1706,7 @@ static void R_ProjectSprite(mobj_t *thing) // R_GetPlaneLight won't work on sloped lights! for (lightnum = 1; lightnum < thing->subsector->sector->numlights; lightnum++) { - fixed_t h = thing->subsector->sector->lightlist[lightnum].slope ? P_GetZAt(thing->subsector->sector->lightlist[lightnum].slope, thing->x, thing->y) - : thing->subsector->sector->lightlist[lightnum].height; + fixed_t h = P_GetLightZAt(&thing->subsector->sector->lightlist[lightnum], thing->x, thing->y); if (h <= gzt) { light = lightnum - 1; break; @@ -1874,7 +1855,6 @@ static void R_ProjectSprite(mobj_t *thing) static void R_ProjectPrecipitationSprite(precipmobj_t *thing) { fixed_t tr_x, tr_y; - fixed_t gxt, gyt; fixed_t tx, tz; fixed_t xscale, yscale; //added : 02-02-98 : aaargll..if I were a math-guy!!! @@ -1895,21 +1875,16 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing) tr_x = thing->x - viewx; tr_y = thing->y - viewy; - gxt = FixedMul(tr_x, viewcos); - gyt = -FixedMul(tr_y, viewsin); - - tz = gxt - gyt; + tz = FixedMul(tr_x, viewcos) + FixedMul(tr_y, viewsin); // near/far distance // thing is behind view plane? if (tz < MINZ) return; - gxt = -FixedMul(tr_x, viewsin); - gyt = FixedMul(tr_y, viewcos); - tx = -(gyt + gxt); + tx = FixedMul(tr_x, viewsin) - FixedMul(tr_y, viewcos); // sideways distance // too far off the side? - if (abs(tx) > tz<<2) + if (abs(tx) > FixedMul(tz, fovtan)<<2) return; // aspect ratio stuff : @@ -1959,7 +1934,7 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing) // PORTAL SPRITE CLIPPING if (portalrender && portalclipline) { - if (x2 < portalclipstart || x1 > portalclipend) + if (x2 < portalclipstart || x1 >= portalclipend) return; if (P_PointOnLineSide(thing->x, thing->y, portalclipline) != 0) @@ -2271,7 +2246,6 @@ static void R_CreateDrawNodes(maskcount_t* mask, drawnode_t* head, boolean temps entry->ffloor = ds->thicksides[i]; } } -#ifdef POLYOBJECTS_PLANES // Check for a polyobject plane, but only if this is a front line if (ds->curline->polyseg && ds->curline->polyseg->visplane && !ds->curline->side) { plane = ds->curline->polyseg->visplane; @@ -2287,7 +2261,6 @@ static void R_CreateDrawNodes(maskcount_t* mask, drawnode_t* head, boolean temps } ds->curline->polyseg->visplane = NULL; } -#endif if (ds->maskedtexturecol) { entry = R_CreateDrawNode(head); @@ -2335,7 +2308,6 @@ static void R_CreateDrawNodes(maskcount_t* mask, drawnode_t* head, boolean temps if (tempskip) return; -#ifdef POLYOBJECTS_PLANES // find all the remaining polyobject planes and add them on the end of the list // probably this is a terrible idea if we wanted them to be sorted properly // but it works getting them in for now @@ -2356,7 +2328,6 @@ static void R_CreateDrawNodes(maskcount_t* mask, drawnode_t* head, boolean temps // note: no seg is set, for what should be obvious reasons PolyObjects[i].visplane = NULL; } -#endif // No vissprites in this mask? if (mask->vissprites[1] - mask->vissprites[0] == 0) @@ -2382,12 +2353,8 @@ static void R_CreateDrawNodes(maskcount_t* mask, drawnode_t* head, boolean temps continue; // Effective height may be different for each comparison in the case of slopes - if (r2->plane->slope) { - planeobjectz = P_GetZAt(r2->plane->slope, rover->gx, rover->gy); - planecameraz = P_GetZAt(r2->plane->slope, viewx, viewy); - } - else - planeobjectz = planecameraz = r2->plane->height; + planeobjectz = P_GetZAt(r2->plane->slope, rover->gx, rover->gy, r2->plane->height); + planecameraz = P_GetZAt(r2->plane->slope, viewx, viewy, r2->plane->height); if (rover->mobjflags & MF_NOCLIPHEIGHT) { @@ -2445,19 +2412,10 @@ static void R_CreateDrawNodes(maskcount_t* mask, drawnode_t* head, boolean temps if (scale <= rover->sortscale) continue; - if (*r2->ffloor->t_slope) { - topplaneobjectz = P_GetZAt(*r2->ffloor->t_slope, rover->gx, rover->gy); - topplanecameraz = P_GetZAt(*r2->ffloor->t_slope, viewx, viewy); - } - else - topplaneobjectz = topplanecameraz = *r2->ffloor->topheight; - - if (*r2->ffloor->b_slope) { - botplaneobjectz = P_GetZAt(*r2->ffloor->b_slope, rover->gx, rover->gy); - botplanecameraz = P_GetZAt(*r2->ffloor->b_slope, viewx, viewy); - } - else - botplaneobjectz = botplanecameraz = *r2->ffloor->bottomheight; + topplaneobjectz = P_GetFFloorTopZAt (r2->ffloor, rover->gx, rover->gy); + topplanecameraz = P_GetFFloorTopZAt (r2->ffloor, viewx, viewy); + botplaneobjectz = P_GetFFloorBottomZAt(r2->ffloor, rover->gx, rover->gy); + botplanecameraz = P_GetFFloorBottomZAt(r2->ffloor, viewx, viewy); if ((topplanecameraz > viewz && botplanecameraz < viewz) || (topplanecameraz < viewz && rover->gzt < topplaneobjectz) || diff --git a/src/s_sound.c b/src/s_sound.c index 6952b17f2..5ed9fd83a 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -134,6 +134,7 @@ consvar_t cv_playmusicifunfocused = {"playmusicifunfocused", "No", CV_SAVE, CV_Y consvar_t cv_playsoundsifunfocused = {"playsoundsifunfocused", "No", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; #ifdef HAVE_OPENMPT +openmpt_module *openmpt_mhandle = NULL; static CV_PossibleValue_t interpolationfilter_cons_t[] = {{0, "Default"}, {1, "None"}, {2, "Linear"}, {4, "Cubic"}, {8, "Windowed sinc"}, {0, NULL}}; consvar_t cv_modfilter = {"modfilter", "0", CV_SAVE|CV_CALL, interpolationfilter_cons_t, ModFilter_OnChange, 0, NULL, NULL, 0, 0, NULL}; #endif @@ -1675,7 +1676,7 @@ void S_LoadMusicDefs(UINT16 wadnum) char *lf; char *stoken; - size_t nlf; + size_t nlf = 0xFFFFFFFF; size_t ncr; musicdef_t *def = NULL; @@ -1910,6 +1911,10 @@ UINT32 S_GetMusicPosition(void) /// In this section: mazmazz doesn't know how to do dynamic arrays or struct pointers! /// ------------------------ +char music_stack_nextmusname[7]; +boolean music_stack_noposition = false; +UINT32 music_stack_fadeout = 0; +UINT32 music_stack_fadein = 0; static musicstack_t *music_stacks = NULL; static musicstack_t *last_music_stack = NULL; diff --git a/src/s_sound.h b/src/s_sound.h index 119722af4..3334fcb69 100644 --- a/src/s_sound.h +++ b/src/s_sound.h @@ -22,7 +22,7 @@ #ifdef HAVE_OPENMPT #include "libopenmpt/libopenmpt.h" -openmpt_module *openmpt_mhandle; +extern openmpt_module *openmpt_mhandle; #endif // mask used to indicate sound origin is player item pickup @@ -262,10 +262,10 @@ typedef struct musicstack_s struct musicstack_s *next; } musicstack_t; -char music_stack_nextmusname[7]; -boolean music_stack_noposition; -UINT32 music_stack_fadeout; -UINT32 music_stack_fadein; +extern char music_stack_nextmusname[7]; +extern boolean music_stack_noposition; +extern UINT32 music_stack_fadeout; +extern UINT32 music_stack_fadein; void S_SetStackAdjustmentStart(void); void S_AdjustMusicStackTics(void); @@ -333,7 +333,7 @@ void S_StopSoundByNum(sfxenum_t sfxnum); #ifdef MUSICSLOT_COMPATIBILITY // For compatibility with code/scripts relying on older versions // This is a list of all the "special" slot names and their associated numbers -const char *compat_special_music_slots[16]; +extern const char *compat_special_music_slots[16]; #endif #endif diff --git a/src/screen.c b/src/screen.c index 6e5fd54cd..e01d1a81a 100644 --- a/src/screen.c +++ b/src/screen.c @@ -526,6 +526,9 @@ void SCR_DisplayTicRate(void) INT32 ticcntcolor = 0; const INT32 h = vid.height-(8*vid.dupy); + if (gamestate == GS_NULL) + return; + for (i = lasttic + 1; i < TICRATE+lasttic && i < ontic; ++i) fpsgraph[i % TICRATE] = false; @@ -538,10 +541,16 @@ void SCR_DisplayTicRate(void) if (totaltics <= TICRATE/2) ticcntcolor = V_REDMAP; else if (totaltics == TICRATE) ticcntcolor = V_GREENMAP; - V_DrawString(vid.width-(72*vid.dupx), h, - V_YELLOWMAP|V_NOSCALESTART|V_USERHUDTRANS, "FPS:"); - V_DrawString(vid.width-(40*vid.dupx), h, - ticcntcolor|V_NOSCALESTART|V_USERHUDTRANS, va("%02d/%02u", totaltics, TICRATE)); + if (cv_ticrate.value == 2) // compact counter + V_DrawString(vid.width-(16*vid.dupx), h, + ticcntcolor|V_NOSCALESTART|V_USERHUDTRANS, va("%02d", totaltics)); + else if (cv_ticrate.value == 1) // full counter + { + V_DrawString(vid.width-(72*vid.dupx), h, + V_YELLOWMAP|V_NOSCALESTART|V_USERHUDTRANS, "FPS:"); + V_DrawString(vid.width-(40*vid.dupx), h, + ticcntcolor|V_NOSCALESTART|V_USERHUDTRANS, va("%02d/%02u", totaltics, TICRATE)); + } lasttic = ontic; } diff --git a/src/sdl/i_main.c b/src/sdl/i_main.c index 5d0009927..3eded734f 100644 --- a/src/sdl/i_main.c +++ b/src/sdl/i_main.c @@ -27,7 +27,7 @@ #include #endif -#ifdef __unix__ +#if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON) #include #endif @@ -142,7 +142,7 @@ int main(int argc, char **argv) const char *reldir; int left; boolean fileabs; -#ifdef __unix__ +#if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON) const char *link; #endif @@ -201,7 +201,7 @@ int main(int argc, char **argv) M_PathParts(logdir) - 1, M_PathParts(logfilename) - 1, 0755); -#ifdef __unix__ +#if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON) logstream = fopen(logfilename, "w"); #ifdef DEFAULTDIR if (logdir) @@ -214,9 +214,9 @@ int main(int argc, char **argv) { I_OutputMsg("Error symlinking latest-log.txt: %s\n", strerror(errno)); } -#else/*__unix__*/ +#else/*defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON)*/ logstream = fopen("latest-log.txt", "wt+"); -#endif/*__unix__*/ +#endif/*defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON)*/ } //I_OutputMsg("I_StartupSystem() ...\n"); diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index a86af316e..4fdcec87e 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -178,6 +178,8 @@ static char returnWadPath[256]; #include "../m_argv.h" +#include "../m_menu.h" + #ifdef MAC_ALERT #include "macosx/mac_alert.h" #endif @@ -2293,6 +2295,7 @@ void I_Quit(void) G_StopMetalRecording(false); D_QuitNetGame(); + M_FreePlayerSetupColors(); I_ShutdownMusic(); I_ShutdownSound(); I_ShutdownCD(); @@ -2409,6 +2412,7 @@ void I_Error(const char *error, ...) G_StopMetalRecording(false); D_QuitNetGame(); + M_FreePlayerSetupColors(); I_ShutdownMusic(); I_ShutdownSound(); I_ShutdownCD(); @@ -2484,7 +2488,7 @@ void I_RemoveExitFunc(void (*func)()) } } -#ifndef __unix__ +#if !(defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON)) static void Shittycopyerror(const char *name) { I_OutputMsg( @@ -2524,7 +2528,7 @@ static void Shittylogcopy(void) Shittycopyerror(logfilename); } } -#endif/*__unix__*/ +#endif/*!(defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON))*/ // // Closes down everything. This includes restoring the initial @@ -2548,7 +2552,7 @@ void I_ShutdownSystem(void) if (logstream) { I_OutputMsg("I_ShutdownSystem(): end of logstream.\n"); -#ifndef __unix__ +#if !(defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON)) Shittylogcopy(); #endif fclose(logstream); diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index ec7bfc1c4..0abc9280c 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -217,7 +217,6 @@ static void SDLSetMode(INT32 width, INT32 height, SDL_bool fullscreen, SDL_bool else { Impl_CreateWindow(fullscreen); - Impl_SetWindowIcon(); wasfullscreen = fullscreen; SDL_SetWindowSize(window, width, height); if (fullscreen) @@ -1632,12 +1631,15 @@ static SDL_bool Impl_CreateWindow(SDL_bool fullscreen) window = SDL_CreateWindow("SRB2 "VERSIONSTRING, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, realwidth, realheight, flags); + if (window == NULL) { CONS_Printf(M_GetText("Couldn't create window: %s\n"), SDL_GetError()); return SDL_FALSE; } + Impl_SetWindowIcon(); + return Impl_CreateContext(); } @@ -1654,12 +1656,8 @@ static void Impl_SetWindowName(const char *title) static void Impl_SetWindowIcon(void) { - if (window == NULL || icoSurface == NULL) - { - return; - } - //SDL2STUB(); // Monster Iestyn: why is this stubbed? - SDL_SetWindowIcon(window, icoSurface); + if (window && icoSurface) + SDL_SetWindowIcon(window, icoSurface); } static void Impl_VideoSetupSDLBuffer(void) @@ -1766,6 +1764,11 @@ void I_StartupGraphics(void) VID_StartupOpenGL(); #endif + // Window icon +#ifdef HAVE_IMAGE + icoSurface = IMG_ReadXPMFromArray(SDL_icon_xpm); +#endif + // Fury: we do window initialization after GL setup to allow // SDL_GL_LoadLibrary to work well on Windows @@ -1784,11 +1787,6 @@ void I_StartupGraphics(void) #ifdef HAVE_TTF I_ShutdownTTF(); #endif - // Window icon -#ifdef HAVE_IMAGE - icoSurface = IMG_ReadXPMFromArray(SDL_icon_xpm); -#endif - Impl_SetWindowIcon(); VID_SetMode(VID_GetModeForSize(BASEVIDWIDTH, BASEVIDHEIGHT)); diff --git a/src/sdl/macosx/Srb2mac.xcodeproj/project.pbxproj b/src/sdl/macosx/Srb2mac.xcodeproj/project.pbxproj index 182220265..745513eeb 100644 --- a/src/sdl/macosx/Srb2mac.xcodeproj/project.pbxproj +++ b/src/sdl/macosx/Srb2mac.xcodeproj/project.pbxproj @@ -1219,7 +1219,7 @@ C01FCF4B08A954540054247B /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - CURRENT_PROJECT_VERSION = 2.2.2; + CURRENT_PROJECT_VERSION = 2.2.4; GCC_PREPROCESSOR_DEFINITIONS = ( "$(inherited)", NORMALSRB2, @@ -1231,7 +1231,7 @@ C01FCF4C08A954540054247B /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - CURRENT_PROJECT_VERSION = 2.2.2; + CURRENT_PROJECT_VERSION = 2.2.4; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_PREPROCESSOR_DEFINITIONS = ( diff --git a/src/sounds.c b/src/sounds.c index ca943c2d0..9894fd13e 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -527,7 +527,7 @@ sfxinfo_t S_sfx[NUMSFX] = {"s3k8a", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Boing"}, {"s3k8b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Powerful hit"}, {"s3k8c", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Humming power"}, - {"s3k8d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"s3k8d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "/"}, {"s3k8e", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Accelerating"}, {"s3k8f", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Opening"}, {"s3k90", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Impact"}, diff --git a/src/st_stuff.c b/src/st_stuff.c index 6e365dc68..086e80291 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -456,7 +456,7 @@ boolean st_overlay; // // Supports different colors! woo! 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; const UINT8 *colormap; @@ -992,7 +992,7 @@ static void ST_drawLivesArea(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; UINT8 offs; @@ -1325,7 +1325,7 @@ void ST_drawTitleCard(void) { char *lvlttl = mapheaderinfo[gamemap-1]->lvlttl; char *subttl = mapheaderinfo[gamemap-1]->subttl; - INT32 actnum = mapheaderinfo[gamemap-1]->actnum; + UINT8 actnum = mapheaderinfo[gamemap-1]->actnum; INT32 lvlttlxpos, ttlnumxpos, zonexpos; INT32 subttlxpos = BASEVIDWIDTH/2; INT32 ttlscroll = FixedInt(lt_scroll); @@ -1333,13 +1333,12 @@ void ST_drawTitleCard(void) patch_t *actpat, *zigzag, *zztext; UINT8 colornum; const UINT8 *colormap; - stplyr = &players[consoleplayer]; - - if (stplyr->skincolor) - colornum = stplyr->skincolor; + + if (players[consoleplayer].skincolor) + colornum = players[consoleplayer].skincolor; else colornum = cv_playercolor.value; - + colormap = R_GetTranslationColormap(TC_DEFAULT, colornum, GTC_CACHE); if (!G_IsTitleCardAvailable()) @@ -1383,7 +1382,12 @@ void ST_drawTitleCard(void) if (actnum) { if (!splitscreen) - V_DrawMappedPatch(ttlnumxpos + ttlscroll, 104 - ttlscroll, 0, actpat, colormap); + { + if (actnum > 9) // slightly offset the act diamond for two-digit act numbers + V_DrawMappedPatch(ttlnumxpos + (V_LevelActNumWidth(actnum)/4) + ttlscroll, 104 - ttlscroll, 0, actpat, colormap); + else + V_DrawMappedPatch(ttlnumxpos + ttlscroll, 104 - ttlscroll, 0, actpat, colormap); + } V_DrawLevelActNum(ttlnumxpos + ttlscroll, 104, V_PERPLAYER, actnum); } @@ -1696,14 +1700,14 @@ static void ST_drawNightsRecords(void) // 2.0-1: [21:42] <+Rob> Beige - Lavender - Steel Blue - Peach - Orange - Purple - Silver - Yellow - Pink - Red - Blue - Green - Cyan - Gold /*#define NUMLINKCOLORS 14 -static skincolors_t linkColor[NUMLINKCOLORS] = +static skincolornum_t linkColor[NUMLINKCOLORS] = {SKINCOLOR_BEIGE, SKINCOLOR_LAVENDER, SKINCOLOR_AZURE, SKINCOLOR_PEACH, SKINCOLOR_ORANGE, SKINCOLOR_MAGENTA, SKINCOLOR_SILVER, SKINCOLOR_SUPERGOLD4, SKINCOLOR_PINK, SKINCOLOR_RED, SKINCOLOR_BLUE, SKINCOLOR_GREEN, SKINCOLOR_CYAN, SKINCOLOR_GOLD};*/ // 2.2 indev list: (unix time 1470866042) Emerald, Aqua, Cyan, Blue, Pastel, Purple, Magenta, Rosy, Red, Orange, Gold, Yellow, Peridot /*#define NUMLINKCOLORS 13 -static skincolors_t linkColor[NUMLINKCOLORS] = +static skincolornum_t linkColor[NUMLINKCOLORS] = {SKINCOLOR_EMERALD, SKINCOLOR_AQUA, SKINCOLOR_CYAN, SKINCOLOR_BLUE, SKINCOLOR_PASTEL, SKINCOLOR_PURPLE, SKINCOLOR_MAGENTA, SKINCOLOR_ROSY, SKINCOLOR_RED, SKINCOLOR_ORANGE, SKINCOLOR_GOLD, SKINCOLOR_YELLOW, SKINCOLOR_PERIDOT};*/ @@ -1712,7 +1716,7 @@ static skincolors_t linkColor[NUMLINKCOLORS] = // [20:00:25] Also Icy for the link freeze text color // [20:04:03] I would start it on lime /*#define NUMLINKCOLORS 18 -static skincolors_t linkColor[NUMLINKCOLORS] = +static skincolornum_t linkColor[NUMLINKCOLORS] = {SKINCOLOR_LIME, SKINCOLOR_EMERALD, SKINCOLOR_AQUA, SKINCOLOR_CYAN, SKINCOLOR_SKY, SKINCOLOR_SAPPHIRE, SKINCOLOR_PASTEL, SKINCOLOR_PURPLE, SKINCOLOR_BUBBLEGUM, SKINCOLOR_MAGENTA, SKINCOLOR_ROSY, SKINCOLOR_RUBY, SKINCOLOR_RED, SKINCOLOR_FLAME, SKINCOLOR_SUNSET, @@ -1720,7 +1724,7 @@ static skincolors_t linkColor[NUMLINKCOLORS] = // 2.2+ list for real this time: https://wiki.srb2.org/wiki/User:Rob/Sandbox (check history around 31/10/17, spoopy) #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_ROSY, SKINCOLOR_RED, SKINCOLOR_ORANGE, SKINCOLOR_GOLD, SKINCOLOR_YELLOW, SKINCOLOR_PERIDOT}, {SKINCOLOR_SEAFOAM, SKINCOLOR_CYAN, SKINCOLOR_WAVE, SKINCOLOR_SAPPHIRE, SKINCOLOR_VAPOR, SKINCOLOR_BUBBLEGUM, @@ -1731,7 +1735,7 @@ static void ST_drawNiGHTSLink(void) static INT32 prevsel[2] = {0, 0}, prevtime[2] = {0, 0}; 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); - skincolors_t colornum; + skincolornum_t colornum; fixed_t x, y, scale; if (sel != prevsel[q]) diff --git a/src/v_video.c b/src/v_video.c index 2d1014c23..5a985555f 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -42,7 +42,8 @@ UINT8 *screens[5]; // screens[3] = fade screen start // screens[4] = fade screen end, postimage tempoarary buffer -consvar_t cv_ticrate = {"showfps", "No", 0, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; +static CV_PossibleValue_t ticrate_cons_t[] = {{0, "No"}, {1, "Full"}, {2, "Compact"}, {0, NULL}}; +consvar_t cv_ticrate = {"showfps", "No", CV_SAVE, ticrate_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; static void CV_palette_OnChange(void); @@ -1039,7 +1040,7 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_ // V_DrawContinueIcon // 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) { @@ -2951,13 +2952,19 @@ void V_DrawPaddedTallNum(INT32 x, INT32 y, INT32 flags, INT32 num, INT32 digits) } // Draw an act number for a level title -// Todo: actually draw two-digit numbers as two act num patches -void V_DrawLevelActNum(INT32 x, INT32 y, INT32 flags, INT32 num) +void V_DrawLevelActNum(INT32 x, INT32 y, INT32 flags, UINT8 num) { - if (num < 0 || num > 19) + if (num > 99) return; // not supported - V_DrawScaledPatch(x, y, flags, ttlnum[num]); + while (num > 0) + { + if (num > 9) // if there are two digits, draw second digit first + V_DrawScaledPatch(x + (V_LevelActNumWidth(num) - V_LevelActNumWidth(num%10)), y, flags, ttlnum[num%10]); + else + V_DrawScaledPatch(x, y, flags, ttlnum[num]); + num = num/10; + } } // Write a string using the credit font @@ -3338,13 +3345,21 @@ INT32 V_LevelNameHeight(const char *string) } // For ST_drawTitleCard -// Returns the width of the act num patch -INT32 V_LevelActNumWidth(INT32 num) +// Returns the width of the act num patch(es) +INT16 V_LevelActNumWidth(UINT8 num) { - if (num < 0 || num > 19) - return 0; // not a valid number + INT16 result = 0; - return SHORT(ttlnum[num]->width); + if (num == 0) + result = SHORT(ttlnum[num]->width); + + while (num > 0 && num <= 99) + { + result = result + SHORT(ttlnum[num%10]->width); + num = num/10; + } + + return result; } // diff --git a/src/v_video.h b/src/v_video.h index ed623a57f..9f7a9a9e9 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -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_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. void V_DrawBlock(INT32 x, INT32 y, INT32 scrn, INT32 width, INT32 height, const UINT8 *src); @@ -238,12 +238,12 @@ void V_DrawRightAlignedSmallThinStringAtFixed(fixed_t x, fixed_t y, INT32 option // Draw tall nums, used for menu, HUD, intermission void V_DrawTallNum(INT32 x, INT32 y, INT32 flags, INT32 num); void V_DrawPaddedTallNum(INT32 x, INT32 y, INT32 flags, INT32 num, INT32 digits); -void V_DrawLevelActNum(INT32 x, INT32 y, INT32 flags, INT32 num); +void V_DrawLevelActNum(INT32 x, INT32 y, INT32 flags, UINT8 num); // Find string width from lt_font chars INT32 V_LevelNameWidth(const char *string); INT32 V_LevelNameHeight(const char *string); -INT32 V_LevelActNumWidth(INT32 num); // act number width +INT16 V_LevelActNumWidth(UINT8 num); // act number width void V_DrawCreditString(fixed_t x, fixed_t y, INT32 option, const char *string); INT32 V_CreditStringWidth(const char *string); diff --git a/src/w_wad.c b/src/w_wad.c index a81132354..041222479 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -76,6 +76,10 @@ int snprintf(char *str, size_t n, const char *fmt, ...); //int vsnprintf(char *str, size_t n, const char *fmt, va_list ap); #endif +#ifdef _DEBUG +#include "console.h" +#endif + #ifndef O_BINARY #define O_BINARY 0 #endif diff --git a/src/win32/win_sys.c b/src/win32/win_sys.c index 42733c309..6c4ff4484 100644 --- a/src/win32/win_sys.c +++ b/src/win32/win_sys.c @@ -54,6 +54,8 @@ #include "../screen.h" +#include "../m_menu.h" + // Wheel support for Win95/WinNT3.51 #include @@ -650,6 +652,7 @@ void I_Error(const char *error, ...) G_StopMetalRecording(false); D_QuitNetGame(); + M_FreePlayerSetupColors(); // shutdown everything that was started I_ShutdownSystem(); @@ -746,6 +749,8 @@ void I_Quit(void) // so do it before. D_QuitNetGame(); + M_FreePlayerSetupColors(); + // shutdown everything that was started I_ShutdownSystem(); @@ -3199,7 +3204,7 @@ INT32 I_GetKey(void) // ----------------- #define DI_KEYBOARD_BUFFERSIZE 32 // number of data elements in keyboard buffer -void I_StartupKeyboard(void) +static void I_StartupKeyboard(void) { DIPROPDWORD dip; @@ -3435,6 +3440,8 @@ INT32 I_StartupSystem(void) // some 'more global than globals' things to initialize here ? graphics_started = keyboard_started = sound_started = cdaudio_started = false; + I_StartupKeyboard(); + #ifdef NDEBUG #ifdef BUGTRAP diff --git a/src/win32/win_vid.c b/src/win32/win_vid.c index 4e7bab569..5fa219586 100644 --- a/src/win32/win_vid.c +++ b/src/win32/win_vid.c @@ -56,6 +56,7 @@ static consvar_t cv_stretch = {"stretch", "On", CV_SAVE|CV_NOSHOWHELP, CV_OnOff, static consvar_t cv_ontop = {"ontop", "Never", 0, CV_NeverOnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; boolean highcolor; +int vid_opengl_state = 0; static BOOL bDIBMode; // means we are using DIB instead of DirectDraw surfaces static LPBITMAPINFO bmiMain = NULL; @@ -949,7 +950,10 @@ INT32 VID_SetMode(INT32 modenum) } void VID_CheckRenderer(void) {} -void VID_CheckGLLoaded(rendermode_t oldrender) {} +void VID_CheckGLLoaded(rendermode_t oldrender) +{ + (void)oldrender; +} // ======================================================================== // Free the video buffer of the last video mode, diff --git a/src/y_inter.c b/src/y_inter.c index f1764a816..2fe0de605 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -73,7 +73,7 @@ typedef union UINT32 score, total; // fake score, total UINT32 tics; // time - INT32 actnum; // act number being displayed + UINT8 actnum; // act number being displayed patch_t *ptotal; // TOTAL UINT8 gotlife; // Number of extra lives obtained } coop; @@ -99,7 +99,7 @@ typedef union UINT8 continues; patch_t *pcontinues; INT32 *playerchar; // Continue HUD - UINT8 *playercolor; + UINT16 *playercolor; UINT8 gotlife; // Number of extra lives obtained } spec; @@ -107,7 +107,7 @@ typedef union struct { UINT32 scores[MAXPLAYERS]; // Winner's score - UINT8 *color[MAXPLAYERS]; // Winner's color # + UINT16 *color[MAXPLAYERS]; // Winner's color # boolean spectator[MAXPLAYERS]; // Spectator list INT32 *character[MAXPLAYERS]; // Winner's character # INT32 num[MAXPLAYERS]; // Winner's player # @@ -121,7 +121,7 @@ typedef union struct { - UINT8 *color[MAXPLAYERS]; // Winner's color # + UINT16 *color[MAXPLAYERS]; // Winner's color # INT32 *character[MAXPLAYERS]; // Winner's character # INT32 num[MAXPLAYERS]; // Winner's player # char name[MAXPLAYERS][9]; // Winner's name