From 0b88c364bca99887530e6d00db3b4c8f56c0a43b Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sat, 11 Aug 2018 18:01:54 +0100 Subject: [PATCH 01/49] Add "Tutorial" to the 1P menu, above "Start Game". It doesn't actually do anything yet, mind! Also, change said menu's def to start at "Start Game" when entering it for the first time. --- src/m_menu.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/m_menu.c b/src/m_menu.c index f99f5d860..50850ecee 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -731,6 +731,7 @@ static menuitem_t SR_EmblemHintMenu[] = // Single Player Main static menuitem_t SP_MainMenu[] = { + {IT_STRING, NULL, "Tutorial", NULL, 84}, {IT_CALL | IT_STRING, NULL, "Start Game", M_LoadGame, 92}, {IT_SECRET, NULL, "Record Attack", M_TimeAttack, 100}, {IT_SECRET, NULL, "NiGHTS Mode", M_NightsAttack, 108}, @@ -739,6 +740,7 @@ static menuitem_t SP_MainMenu[] = enum { + sptutorial, sploadgame, sprecordattack, spnightsmode, @@ -1554,7 +1556,18 @@ menu_t SR_EmblemHintDef = }; // Single Player -menu_t SP_MainDef = CENTERMENUSTYLE(NULL, SP_MainMenu, &MainDef, 72); +menu_t SP_MainDef = //CENTERMENUSTYLE(NULL, SP_MainMenu, &MainDef, 72); +{ + NULL, + sizeof(SP_MainMenu)/sizeof(menuitem_t), + &MainDef, + SP_MainMenu, + M_DrawCenteredMenu, + BASEVIDWIDTH/2, 72, + 1, // start at "Start Game" on first entry + NULL +}; + menu_t SP_LoadDef = { "M_PICKG", From 51b8d6e01a512f758b8ebc0e933a959b140e1057 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sat, 11 Aug 2018 21:17:52 +0100 Subject: [PATCH 02/49] Make "Tutorial" warp directly to MAPZ0 (not configurable yet) --- src/m_menu.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/m_menu.c b/src/m_menu.c index 50850ecee..f8324ab7e 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -273,6 +273,7 @@ menu_t SP_MainDef, OP_MainDef; menu_t MISC_ScrambleTeamDef, MISC_ChangeTeamDef; // Single Player +static void M_StartTutorial(INT32 choice); static void M_LoadGame(INT32 choice); static void M_TimeAttackLevelSelect(INT32 choice); static void M_TimeAttack(INT32 choice); @@ -731,7 +732,7 @@ static menuitem_t SR_EmblemHintMenu[] = // Single Player Main static menuitem_t SP_MainMenu[] = { - {IT_STRING, NULL, "Tutorial", NULL, 84}, + {IT_STRING, NULL, "Tutorial", M_StartTutorial, 84}, {IT_CALL | IT_STRING, NULL, "Start Game", M_LoadGame, 92}, {IT_SECRET, NULL, "Record Attack", M_TimeAttack, 100}, {IT_SECRET, NULL, "NiGHTS Mode", M_NightsAttack, 108}, @@ -6131,6 +6132,22 @@ static void M_LoadGameLevelSelect(INT32 choice) M_SetupNextMenu(&SP_LevelSelectDef); } +static INT32 tutorialmap = 1000; // MAPZ0, temporary value + +// Starts up the tutorial immediately (tbh I wasn't sure where else to put this) +static void M_StartTutorial(INT32 choice) +{ + (void)choice; + if (!tutorialmap) + return; // no map to go to, don't bother + + emeralds = 0; + M_ClearMenus(true); + gamecomplete = false; + cursaveslot = 0; + G_DeferedInitNew(false, G_BuildMapName(tutorialmap), 0, false, false); +} + // ============== // LOAD GAME MENU // ============== From 0da21244c0b0f36da86509916aaee66c6966cf07 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sun, 12 Aug 2018 14:30:49 +0100 Subject: [PATCH 03/49] Added "Tutorialmap" MainCfg option for SOC --- src/dehacked.c | 13 +++++++++++++ src/doomstat.h | 2 ++ src/g_game.c | 2 ++ src/m_menu.c | 2 -- 4 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index fb0f958c3..28c86f56e 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -2863,6 +2863,19 @@ static void readmaincfg(MYFILE *f) startchar = (INT16)value; char_on = -1; } + else if (fastcmp(word, "TUTORIALMAP")) + { + // Support using the actual map name, + // i.e., Level AB, Level FZ, etc. + + // Convert to map number + if (word2[0] >= 'A' && word2[0] <= 'Z') + value = M_MapNumber(word2[0], word2[1]); + else + value = get_number(word2); + + tutorialmap = (INT16)value; + } else deh_warning("Maincfg: unknown word '%s'", word); } diff --git a/src/doomstat.h b/src/doomstat.h index 24b9e5753..18ae04584 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -132,6 +132,8 @@ extern INT16 titlemap; extern boolean hidetitlepics; extern INT16 bootmap; //bootmap for loading a map on startup +extern INT16 tutorialmap; // map to load for tutorial + extern boolean looptitle; // CTF colors. diff --git a/src/g_game.c b/src/g_game.c index 52358a8b9..da6f1bbd1 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -127,6 +127,8 @@ INT16 titlemap = 0; boolean hidetitlepics = false; INT16 bootmap; //bootmap for loading a map on startup +INT16 tutorialmap = 0; // map to load for tutorial + boolean looptitle = false; UINT8 skincolor_redteam = SKINCOLOR_RED; diff --git a/src/m_menu.c b/src/m_menu.c index f8324ab7e..ec7215d46 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -6132,8 +6132,6 @@ static void M_LoadGameLevelSelect(INT32 choice) M_SetupNextMenu(&SP_LevelSelectDef); } -static INT32 tutorialmap = 1000; // MAPZ0, temporary value - // Starts up the tutorial immediately (tbh I wasn't sure where else to put this) static void M_StartTutorial(INT32 choice) { From aba9bd13bbfaa52754a6b54fcc5bf6523c73958a Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Tue, 4 Sep 2018 16:58:49 +0100 Subject: [PATCH 04/49] Add "tutorialmode" var to help the game know when we're in a tutorial or not, add placeholder for tutorial HUD to test it works --- src/d_main.c | 3 +++ src/d_netcmd.c | 2 ++ src/doomstat.h | 1 + src/g_game.c | 1 + src/m_menu.c | 2 ++ src/st_stuff.c | 11 +++++++++++ 6 files changed, 20 insertions(+) diff --git a/src/d_main.c b/src/d_main.c index 95af1f754..c6dd9dc46 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -714,6 +714,9 @@ void D_StartTitle(void) // reset modeattacking modeattacking = ATTACKING_NONE; + // The title screen is obviously not a tutorial! (Unless I'm mistaken) + tutorialmode = false; + // empty maptol so mario/etc sounds don't play in sound test when they shouldn't maptol = 0; diff --git a/src/d_netcmd.c b/src/d_netcmd.c index f9f960a70..e96d98f11 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -1815,6 +1815,8 @@ static void Command_Map_f(void) else fromlevelselect = ((netgame || multiplayer) && ((gametype == newgametype) && (newgametype == GT_COOP))); + tutorialmode = false; // warping takes us out of tutorial mode + D_MapChange(newmapnum, newgametype, false, newresetplayers, 0, false, fromlevelselect); } diff --git a/src/doomstat.h b/src/doomstat.h index 1f78710e2..9a3bff7c0 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -133,6 +133,7 @@ extern boolean hidetitlepics; extern INT16 bootmap; //bootmap for loading a map on startup extern INT16 tutorialmap; // map to load for tutorial +extern boolean tutorialmode; // are we in a tutorial right now? extern boolean looptitle; diff --git a/src/g_game.c b/src/g_game.c index 4b2877f95..38289bcb2 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -128,6 +128,7 @@ boolean hidetitlepics = false; INT16 bootmap; //bootmap for loading a map on startup INT16 tutorialmap = 0; // map to load for tutorial +boolean tutorialmode = false; // are we in a tutorial right now? boolean looptitle = false; diff --git a/src/m_menu.c b/src/m_menu.c index 103e629de..41fb1319d 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -6139,6 +6139,8 @@ static void M_StartTutorial(INT32 choice) if (!tutorialmap) return; // no map to go to, don't bother + tutorialmode = true; // turn on tutorial mode + emeralds = 0; M_ClearMenus(true); gamecomplete = false; diff --git a/src/st_stuff.c b/src/st_stuff.c index fa13e008a..246bae8bc 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -2465,6 +2465,13 @@ static void ST_overlayDrawer(void) ST_drawDebugInfo(); } +static void ST_drawTutorial(void) +{ + // Nothing, ...yet + // Except this for now, just to check it works + V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT/2, 0, "Tutorial placeholder"); +} + void ST_Drawer(void) { #ifdef SEENAMES @@ -2538,4 +2545,8 @@ void ST_Drawer(void) ST_overlayDrawer(); } } + + // Draw tutorial text over everything else + if (tutorialmode) + ST_drawTutorial(); } From bffaafd61ed98eb31e357b5c2a9c9a188528318b Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Tue, 4 Sep 2018 19:21:58 +0100 Subject: [PATCH 05/49] Add V_DrawTutorialBack for drawing a console-like background box, add Lorem ipsum as filler test --- src/st_stuff.c | 8 +++++++- src/v_video.c | 19 +++++++++++++++++++ src/v_video.h | 1 + 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/st_stuff.c b/src/st_stuff.c index 246bae8bc..1adc6596c 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -2467,9 +2467,15 @@ static void ST_overlayDrawer(void) static void ST_drawTutorial(void) { + INT32 charheight = 8; + INT32 y = BASEVIDHEIGHT - ((charheight * 4) + (charheight/2)*5); + INT32 i; // Nothing, ...yet // Except this for now, just to check it works - V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT/2, 0, "Tutorial placeholder"); + //V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT/2, 0, "Tutorial placeholder"); + V_DrawTutorialBack(); + for (i = 0; i < 4; i++, y += 12) + V_DrawString(0, y, 0, "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum"); } void ST_Drawer(void) diff --git a/src/v_video.c b/src/v_video.c index 765965ffd..05401ce56 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -1480,6 +1480,25 @@ void V_DrawFadeConsBack(INT32 plines) *buf = consolebgmap[*buf]; } +// Very similar to F_DrawFadeConsBack, except we draw from the middle(-ish) of the screen to the bottom. +void V_DrawTutorialBack(void) +{ + INT32 charheight = 8*vid.dupy; + UINT8 *deststop, *buf; + +#ifdef HWRENDER + if (rendermode != render_soft) // no support for OpenGL yet + return; +#endif + + // heavily simplified -- we don't need to know x or y position, + // just the start and stop positions + deststop = screens[0] + vid.rowbytes * vid.height; + buf = deststop - vid.rowbytes * ((charheight * 4) + (charheight/2)*5); // 4 lines of space plus gaps between and some leeway + for (; buf < deststop; ++buf) + *buf = consolebgmap[*buf]; +} + // Gets string colormap, used for 0x80 color codes // static const UINT8 *V_GetStringColormap(INT32 colorflags) diff --git a/src/v_video.h b/src/v_video.h index 6113d08ec..850206816 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -158,6 +158,7 @@ void V_DrawFlatFill(INT32 x, INT32 y, INT32 w, INT32 h, lumpnum_t flatnum); void V_DrawFadeScreen(UINT16 color, UINT8 strength); void V_DrawFadeConsBack(INT32 plines); +void V_DrawTutorialBack(void); // draw a single character void V_DrawCharacter(INT32 x, INT32 y, INT32 c, boolean lowercaseallowed); From 16c7c264a5b099e880b4469e044466e602775ca1 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Tue, 4 Sep 2018 19:52:50 +0100 Subject: [PATCH 06/49] Wrap the text and snap to bottom --- src/st_stuff.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/st_stuff.c b/src/st_stuff.c index 1adc6596c..d4c710e97 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -2468,14 +2468,16 @@ static void ST_overlayDrawer(void) static void ST_drawTutorial(void) { INT32 charheight = 8; - INT32 y = BASEVIDHEIGHT - ((charheight * 4) + (charheight/2)*5); - INT32 i; + INT32 y = BASEVIDHEIGHT - ((charheight * 4) + (charheight/2)*4); + char *test; + //INT32 i; // Nothing, ...yet // Except this for now, just to check it works //V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT/2, 0, "Tutorial placeholder"); V_DrawTutorialBack(); - for (i = 0; i < 4; i++, y += 12) - V_DrawString(0, y, 0, "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum"); + //for (i = 0; i < 4; i++, y += 12) + test = V_WordWrap(4, BASEVIDWIDTH-4, 0, "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum"); + V_DrawString(4, y, V_SNAPTOBOTTOM, test); } void ST_Drawer(void) From 15020ae01d1819e27af1a39f5eed434f8dd8cf71 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sat, 3 Nov 2018 10:57:43 -0400 Subject: [PATCH 07/49] Removed TextPrompt-specific code for `text-prompt` branch --- src/st_stuff.c | 19 ------------------- src/v_video.c | 19 ------------------- src/v_video.h | 1 - 3 files changed, 39 deletions(-) diff --git a/src/st_stuff.c b/src/st_stuff.c index d4c710e97..fa13e008a 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -2465,21 +2465,6 @@ static void ST_overlayDrawer(void) ST_drawDebugInfo(); } -static void ST_drawTutorial(void) -{ - INT32 charheight = 8; - INT32 y = BASEVIDHEIGHT - ((charheight * 4) + (charheight/2)*4); - char *test; - //INT32 i; - // Nothing, ...yet - // Except this for now, just to check it works - //V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT/2, 0, "Tutorial placeholder"); - V_DrawTutorialBack(); - //for (i = 0; i < 4; i++, y += 12) - test = V_WordWrap(4, BASEVIDWIDTH-4, 0, "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum"); - V_DrawString(4, y, V_SNAPTOBOTTOM, test); -} - void ST_Drawer(void) { #ifdef SEENAMES @@ -2553,8 +2538,4 @@ void ST_Drawer(void) ST_overlayDrawer(); } } - - // Draw tutorial text over everything else - if (tutorialmode) - ST_drawTutorial(); } diff --git a/src/v_video.c b/src/v_video.c index 05401ce56..765965ffd 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -1480,25 +1480,6 @@ void V_DrawFadeConsBack(INT32 plines) *buf = consolebgmap[*buf]; } -// Very similar to F_DrawFadeConsBack, except we draw from the middle(-ish) of the screen to the bottom. -void V_DrawTutorialBack(void) -{ - INT32 charheight = 8*vid.dupy; - UINT8 *deststop, *buf; - -#ifdef HWRENDER - if (rendermode != render_soft) // no support for OpenGL yet - return; -#endif - - // heavily simplified -- we don't need to know x or y position, - // just the start and stop positions - deststop = screens[0] + vid.rowbytes * vid.height; - buf = deststop - vid.rowbytes * ((charheight * 4) + (charheight/2)*5); // 4 lines of space plus gaps between and some leeway - for (; buf < deststop; ++buf) - *buf = consolebgmap[*buf]; -} - // Gets string colormap, used for 0x80 color codes // static const UINT8 *V_GetStringColormap(INT32 colorflags) diff --git a/src/v_video.h b/src/v_video.h index 850206816..6113d08ec 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -158,7 +158,6 @@ void V_DrawFlatFill(INT32 x, INT32 y, INT32 w, INT32 h, lumpnum_t flatnum); void V_DrawFadeScreen(UINT16 color, UINT8 strength); void V_DrawFadeConsBack(INT32 plines); -void V_DrawTutorialBack(void); // draw a single character void V_DrawCharacter(INT32 x, INT32 y, INT32 c, boolean lowercaseallowed); From cf6a6991cbd9f1710bef5ac70739a1efa4745ab2 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sun, 4 Nov 2018 16:28:25 -0500 Subject: [PATCH 08/49] Trigger line exec by whether mobj is facing its tracer * MFE_TRACERANGLE * Thing 758 MT_ANGLEMAN * mobj thinker behavior * Line Exec 457/458 Enable/Disable --- src/dehacked.c | 1 + src/info.c | 27 +++++++++++++++++++++++++++ src/info.h | 1 + src/p_mobj.c | 40 ++++++++++++++++++++++++++++++++++++++++ src/p_mobj.h | 3 +++ src/p_spec.c | 35 +++++++++++++++++++++++++++++++++++ 6 files changed, 107 insertions(+) diff --git a/src/dehacked.c b/src/dehacked.c index 6c39fc197..9ccefa9ce 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -6937,6 +6937,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_PULL", "MT_GHOST", "MT_OVERLAY", + "MT_ANGLEMAN", "MT_POLYANCHOR", "MT_POLYSPAWN", "MT_POLYSPAWNCRUSH", diff --git a/src/info.c b/src/info.c index 3140bd7de..72abcede1 100644 --- a/src/info.c +++ b/src/info.c @@ -17814,6 +17814,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_ANGLEMAN + 758, // doomednum + S_INVISIBLE, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 8, // radius + 8, // height + 0, // display offset + 10, // mass + 0, // damage + sfx_None, // activesound + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOGRAVITY, // flags + S_NULL // raisestate + }, + { // MT_POLYANCHOR 760, // doomednum S_INVISIBLE, // spawnstate diff --git a/src/info.h b/src/info.h index b757deec0..c9de82541 100644 --- a/src/info.h +++ b/src/info.h @@ -4305,6 +4305,7 @@ typedef enum mobj_type MT_PULL, MT_GHOST, MT_OVERLAY, + MT_ANGLEMAN, MT_POLYANCHOR, MT_POLYSPAWN, MT_POLYSPAWNCRUSH, diff --git a/src/p_mobj.c b/src/p_mobj.c index 717bb92b6..45a26cbc5 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -7435,6 +7435,46 @@ void P_MobjThinker(mobj_t *mobj) if ((mobj->flags & MF_ENEMY) && (mobj->state->nextstate == mobj->info->spawnstate && mobj->tics == 1)) mobj->flags2 &= ~MF2_FRET; + // Angle-to-tracer to trigger a linedef exec + // See Linedef Exec 457 (Track mobj angle to point) + if ((mobj->eflags & MFE_TRACERANGLE) && mobj->tracer && mobj->extravalue2) + { + // mobj->lastlook - Don't disable behavior after first failure + // mobj->extravalue1 - Angle tolerance + // mobj->extravalue2 - Exec tag upon failure + // mobj->cvval - Allowable failure delay + // mobj->cvmem - Failure timer + + angle_t ang = mobj->angle - 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 + // yet tracer is still in the camera view + + // failure state: mobj is not facing tracer + // Reasaonable defaults: ANGLE_67h, ANGLE_292h + if (ang >= mobj->extravalue1 && ang <= ANGLE_MAX - mobj->extravalue1) + { + if (mobj->cvmem) + mobj->cvmem--; + else + { + P_LinedefExecute(mobj->extravalue2, mobj, NULL); + + if (mobj->lastlook) + mobj->cvmem = mobj->cusval; // reset timer for next failure + else + { + // disable after first failure + mobj->eflags &= ~MFE_TRACERANGLE; + mobj->lastlook = mobj->extravalue1 = mobj->extravalue2 = mobj->cvmem = mobj->cusval = 0; + } + } + } + else + mobj->cvmem = mobj->cusval; // reset failure timer + } + switch (mobj->type) { case MT_WALLSPIKEBASE: diff --git a/src/p_mobj.h b/src/p_mobj.h index 5c0408e1b..b80080674 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -239,6 +239,9 @@ typedef enum MFE_SPRUNG = 1<<8, // Platform movement MFE_APPLYPMOMZ = 1<<9, + // Compute and trigger on mobj angle relative to tracer + // See Linedef Exec 457 (Track mobj angle to point) + MFE_TRACERANGLE = 1<<10, // free: to and including 1<<15 } mobjeflag_t; diff --git a/src/p_spec.c b/src/p_spec.c index 9f9e80ecc..6bf20283e 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -3757,6 +3757,41 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) P_ResetColormapFader(§ors[secnum]); break; + case 457: // Track mobj angle to point + if (mo) + { + INT32 failureangle = min(max(abs(sides[line->sidenum[0]].textureoffset>>FRACBITS), 0), 360) * ANG1; + INT32 failuredelay = abs(sides[line->sidenum[0]].rowoffset>>FRACBITS); + INT32 failureexectag = line->sidenum[1] != 0xffff ? + (INT32)(sides[line->sidenum[1]].textureoffset>>FRACBITS) : 0; + boolean persist = (line->flags & ML_EFFECT2); + mobj_t *anchormo; + + if ((secnum = P_FindSectorFromLineTag(line, -1)) < 0) + return; + + anchormo = P_GetObjectTypeInSectorNum(MT_ANGLEMAN, secnum); + if (!anchormo) + return; + + mo->eflags |= MFE_TRACERANGLE; + P_SetTarget(&mo->tracer, anchormo); + mo->lastlook = persist; // don't disable behavior after first failure + mo->extravalue1 = failureangle; // angle to exceed for failure state + mo->extravalue2 = failureexectag; // exec tag for failure state (angle is not within range) + mo->cusval = mo->cvmem = failuredelay; // cusval = tics to allow failure before line trigger; cvmem = decrement timer + } + break; + + case 458: // Stop tracking mobj angle to point + if (mo) + { + mo->eflags &= ~MFE_TRACERANGLE; + P_SetTarget(&mo->tracer, NULL); + mo->lastlook = mo->cvmem = mo->cusval = mo->extravalue1 = mo->extravalue2 = 0; + } + break; + #ifdef POLYOBJECTS case 480: // Polyobj_DoorSlide case 481: // Polyobj_DoorSwing From 4fc335a26b16b7290dc274181264436ff4799d67 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sun, 4 Nov 2018 16:48:18 -0500 Subject: [PATCH 09/49] Line 458: Only do disable operation if MFE_TRACERANGLE is set --- src/p_spec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_spec.c b/src/p_spec.c index 6bf20283e..965e0cbe0 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -3784,7 +3784,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) break; case 458: // Stop tracking mobj angle to point - if (mo) + if (mo && (mo->eflags & MFE_TRACERANGLE)) { mo->eflags &= ~MFE_TRACERANGLE; P_SetTarget(&mo->tracer, NULL); From eaf89cf7b919422d0b033c54a53297026fcfd9bc Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sun, 4 Nov 2018 17:34:00 -0500 Subject: [PATCH 10/49] TRACERANGLE: Run exec *after* resetting mobj values --- src/p_mobj.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 45a26cbc5..c9cacb444 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -7459,7 +7459,7 @@ void P_MobjThinker(mobj_t *mobj) mobj->cvmem--; else { - P_LinedefExecute(mobj->extravalue2, mobj, NULL); + INT32 exectag = mobj->extravalue2; // remember this before we erase the values if (mobj->lastlook) mobj->cvmem = mobj->cusval; // reset timer for next failure @@ -7469,6 +7469,8 @@ void P_MobjThinker(mobj_t *mobj) mobj->eflags &= ~MFE_TRACERANGLE; mobj->lastlook = mobj->extravalue1 = mobj->extravalue2 = mobj->cvmem = mobj->cusval = 0; } + + P_LinedefExecute(exectag, mobj, NULL); } } else From b7c6661c76db66d4158875c60bdf37525b080d86 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sun, 4 Nov 2018 20:16:33 -0500 Subject: [PATCH 11/49] Add MTF_EXTRA flag to monitors, to run linedef exec by Angle (Tag + 16384) upon pop --- src/p_enemy.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/p_enemy.c b/src/p_enemy.c index 8088c20a8..15608f57f 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -3324,6 +3324,11 @@ void A_MonitorPop(mobj_t *actor) newmobj->sprite = SPR_TV1P; } } + + // Run a linedef executor immediately upon popping + // You may want to delay your effects by 18 tics to sync with the reward giving + if (actor->spawnpoint && (actor->spawnpoint->options & MTF_EXTRA) && (actor->spawnpoint->angle & 16384)) + P_LinedefExecute((actor->spawnpoint->angle & 16383), actor->target, NULL); } // Function: A_GoldMonitorPop From eb204b6cc44a7d3bf9f16859274b186b2ad41847 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Mon, 5 Nov 2018 07:41:02 -0500 Subject: [PATCH 12/49] Add exec to GoldMonitorPop; transfer Angle tag to mobj->lastlook for Lua compat --- src/p_enemy.c | 9 +++++++-- src/p_mobj.c | 10 ++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index 15608f57f..6fee7d2f0 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -3327,8 +3327,8 @@ void A_MonitorPop(mobj_t *actor) // Run a linedef executor immediately upon popping // You may want to delay your effects by 18 tics to sync with the reward giving - if (actor->spawnpoint && (actor->spawnpoint->options & MTF_EXTRA) && (actor->spawnpoint->angle & 16384)) - P_LinedefExecute((actor->spawnpoint->angle & 16383), actor->target, NULL); + if (actor->spawnpoint && actor->lastlook) + P_LinedefExecute(actor->lastlook, actor->target, NULL); } // Function: A_GoldMonitorPop @@ -3412,6 +3412,11 @@ void A_GoldMonitorPop(mobj_t *actor) newmobj->sprite = SPR_TV1P; } } + + // Run a linedef executor immediately upon popping + // You may want to delay your effects by 18 tics to sync with the reward giving + if (actor->spawnpoint && actor->lastlook) + P_LinedefExecute(actor->lastlook, actor->target, NULL); } // Function: A_GoldMonitorRestore diff --git a/src/p_mobj.c b/src/p_mobj.c index 717bb92b6..2450fb801 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -10894,6 +10894,16 @@ ML_EFFECT4 : Don't clip inside the ground mobj->flags2 |= MF2_OBJECTFLIP; } + // Extra functionality + if (mthing->options & MTF_EXTRA) + { + if (mobj->flags & MF_MONITOR && (mthing->angle & 16384)) + { + // Store line exec tag to run upon popping + mobj->lastlook = (mthing->angle & 16383); + } + } + // Final set of not being able to draw nightsitems. if (mobj->flags & MF_NIGHTSITEM) mobj->flags2 |= MF2_DONTDRAW; From f66979ba1a3f2b2ea8bb07bc7c31e09094c6e1ec Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Wed, 7 Nov 2018 21:00:38 +0000 Subject: [PATCH 13/49] P_NullPrecipThinker no longer should have FUNCMATH (though I'm not sure if it should have had it in the first place anyway) --- src/p_mobj.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_mobj.h b/src/p_mobj.h index 620028d81..56d9b6dae 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -445,7 +445,7 @@ boolean P_SupermanLook4Players(mobj_t *actor); void P_DestroyRobots(void); void P_SnowThinker(precipmobj_t *mobj); void P_RainThinker(precipmobj_t *mobj); -FUNCMATH void P_NullPrecipThinker(precipmobj_t *mobj); +void P_NullPrecipThinker(precipmobj_t *mobj); void P_RemovePrecipMobj(precipmobj_t *mobj); void P_SetScale(mobj_t *mobj, fixed_t newscale); void P_XYMovement(mobj_t *mo); From 4a4e07e1385ddb1c707e431e6be928cc16a1c724 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Wed, 7 Nov 2018 21:21:36 +0000 Subject: [PATCH 14/49] D_PostEvent_end is only used by Allegro (used by the DOS port) to help timers work, so check for PC_DOS in preprocessor code. Also remove FUNCMATH from said function. --- src/d_main.c | 2 +- src/d_main.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index 170532675..037aeccf9 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -170,7 +170,7 @@ void D_PostEvent(const event_t *ev) eventhead = (eventhead+1) & (MAXEVENTS-1); } // just for lock this function -#ifndef DOXYGEN +#if defined (PC_DOS) && !defined (DOXYGEN) void D_PostEvent_end(void) {}; #endif diff --git a/src/d_main.h b/src/d_main.h index d73b19d1f..4c9c99ea5 100644 --- a/src/d_main.h +++ b/src/d_main.h @@ -40,8 +40,8 @@ void D_SRB2Main(void); // Called by IO functions when input is detected. void D_PostEvent(const event_t *ev); -#ifndef DOXYGEN -FUNCMATH void D_PostEvent_end(void); // delimiter for locking memory +#if defined (PC_DOS) && !defined (DOXYGEN) +void D_PostEvent_end(void); // delimiter for locking memory #endif void D_ProcessEvents(void); From b3e8a1ed88961acad8d45a59c3003af08ccb6b5c Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Wed, 7 Nov 2018 21:37:42 +0000 Subject: [PATCH 15/49] HU_Start should not have FUNCMATH, it has side effects --- src/hu_stuff.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hu_stuff.h b/src/hu_stuff.h index 5356ba8ac..a5c81e6e7 100644 --- a/src/hu_stuff.h +++ b/src/hu_stuff.h @@ -84,7 +84,7 @@ void HU_Init(void); void HU_LoadGraphics(void); // reset heads up when consoleplayer respawns. -FUNCMATH void HU_Start(void); +void HU_Start(void); boolean HU_Responder(event_t *ev); From c47f0045d6a60b41faceff3edd17be58b244c601 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Wed, 7 Nov 2018 21:45:27 +0000 Subject: [PATCH 16/49] ST_Ticker also should not have FUNCMATH, as it also has side effects --- src/st_stuff.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/st_stuff.h b/src/st_stuff.h index c11559d2b..6fafca404 100644 --- a/src/st_stuff.h +++ b/src/st_stuff.h @@ -24,7 +24,7 @@ // // Called by main loop. -FUNCMATH void ST_Ticker(void); +void ST_Ticker(void); // Called by main loop. void ST_Drawer(void); From 0bdbdd1b1ed1ffbb15b99664d037fd5f83b7ad12 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 8 Nov 2018 16:26:55 +0000 Subject: [PATCH 17/49] Remove FUNCMATH from functions with a void return value or args, or examine variables other than their args (which could be modified) --- src/dehacked.c | 2 +- src/f_finale.c | 1 + src/f_finale.h | 2 +- src/r_plane.h | 2 +- src/r_splats.h | 4 ---- src/screen.c | 4 ---- src/sdl/i_cdmus.c | 14 +++++++------- src/sdl/i_system.c | 16 ++++++++-------- src/sdl/i_video.c | 6 +++--- src/sdl/mixer_sound.c | 4 ++-- src/sdl/sdl_sound.c | 2 +- src/sdl12/sdl_sound.c | 2 +- 12 files changed, 26 insertions(+), 33 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index b7e874b16..2fed963f8 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -7769,7 +7769,7 @@ fixed_t get_number(const char *word) #endif } -void FUNCMATH DEH_Check(void) +void DEH_Check(void) { #if defined(_DEBUG) || defined(PARANOIA) const size_t dehstates = sizeof(STATE_LIST)/sizeof(const char*); diff --git a/src/f_finale.c b/src/f_finale.c index fb1387c11..a50e4a5be 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -1401,6 +1401,7 @@ void F_StartGameEnd(void) // void F_GameEndDrawer(void) { + // this function does nothing } // diff --git a/src/f_finale.h b/src/f_finale.h index 1f23643be..8ee02bdf3 100644 --- a/src/f_finale.h +++ b/src/f_finale.h @@ -35,7 +35,7 @@ void F_CutsceneTicker(void); void F_TitleDemoTicker(void); // Called by main loop. -FUNCMATH void F_GameEndDrawer(void); +void F_GameEndDrawer(void); void F_IntroDrawer(void); void F_TitleScreenDrawer(void); diff --git a/src/r_plane.h b/src/r_plane.h index 16c8c12a4..dff58669a 100644 --- a/src/r_plane.h +++ b/src/r_plane.h @@ -87,7 +87,7 @@ extern lighttable_t **planezlight; extern fixed_t *yslope; extern fixed_t distscale[MAXVIDWIDTH]; -FUNCMATH void R_InitPlanes(void); +void R_InitPlanes(void); void R_PortalStoreClipValues(INT32 start, INT32 end, INT16 *ceil, INT16 *floor, fixed_t *scale); void R_PortalRestoreClipValues(INT32 start, INT32 end, INT16 *ceil, INT16 *floor, fixed_t *scale); void R_ClearPlanes(void); diff --git a/src/r_splats.h b/src/r_splats.h index c0ba6881c..349d8fa7a 100644 --- a/src/r_splats.h +++ b/src/r_splats.h @@ -63,11 +63,7 @@ typedef struct floorsplat_s fixed_t P_SegLength(seg_t *seg); // call at P_SetupLevel() -#if !(defined (WALLSPLATS) || defined (FLOORSPLATS)) -FUNCMATH void R_ClearLevelSplats(void); -#else void R_ClearLevelSplats(void); -#endif #ifdef WALLSPLATS void R_AddWallSplat(line_t *wallline, INT16 sectorside, const char *patchname, fixed_t top, diff --git a/src/screen.c b/src/screen.c index 58c38993b..fdd8eb7bd 100644 --- a/src/screen.c +++ b/src/screen.c @@ -71,11 +71,7 @@ consvar_t cv_scr_depth = {"scr_depth", "16 bits", CV_SAVE, scr_depth_cons_t, NUL #endif consvar_t cv_renderview = {"renderview", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -#ifdef DIRECTFULLSCREEN -static FUNCMATH void SCR_ChangeFullscreen (void); -#else static void SCR_ChangeFullscreen (void); -#endif consvar_t cv_fullscreen = {"fullscreen", "Yes", CV_SAVE|CV_CALL, CV_YesNo, SCR_ChangeFullscreen, 0, NULL, NULL, 0, 0, NULL}; diff --git a/src/sdl/i_cdmus.c b/src/sdl/i_cdmus.c index 3105f5122..5d086e73a 100644 --- a/src/sdl/i_cdmus.c +++ b/src/sdl/i_cdmus.c @@ -12,19 +12,19 @@ consvar_t cd_volume = {"cd_volume","31",CV_SAVE,soundvolume_cons_t, NULL, 0, NUL consvar_t cdUpdate = {"cd_update","1",CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; -FUNCMATH void I_InitCD(void){} +void I_InitCD(void){} -FUNCMATH void I_StopCD(void){} +void I_StopCD(void){} -FUNCMATH void I_PauseCD(void){} +void I_PauseCD(void){} -FUNCMATH void I_ResumeCD(void){} +void I_ResumeCD(void){} -FUNCMATH void I_ShutdownCD(void){} +void I_ShutdownCD(void){} -FUNCMATH void I_UpdateCD(void){} +void I_UpdateCD(void){} -FUNCMATH void I_PlayCD(UINT8 track, UINT8 looping) +void I_PlayCD(UINT8 track, UINT8 looping) { (void)track; (void)looping; diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index 7b14f1f18..9a2baf31c 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -1927,14 +1927,14 @@ void I_StartupMouse2(void) // // I_Tactile // -FUNCMATH void I_Tactile(FFType pFFType, const JoyFF_t *FFEffect) +void I_Tactile(FFType pFFType, const JoyFF_t *FFEffect) { // UNUSED. (void)pFFType; (void)FFEffect; } -FUNCMATH void I_Tactile2(FFType pFFType, const JoyFF_t *FFEffect) +void I_Tactile2(FFType pFFType, const JoyFF_t *FFEffect) { // UNUSED. (void)pFFType; @@ -1945,7 +1945,7 @@ FUNCMATH void I_Tactile2(FFType pFFType, const JoyFF_t *FFEffect) */ static ticcmd_t emptycmd; -FUNCMATH ticcmd_t *I_BaseTiccmd(void) +ticcmd_t *I_BaseTiccmd(void) { return &emptycmd; } @@ -1954,7 +1954,7 @@ FUNCMATH ticcmd_t *I_BaseTiccmd(void) */ static ticcmd_t emptycmd2; -FUNCMATH ticcmd_t *I_BaseTiccmd2(void) +ticcmd_t *I_BaseTiccmd2(void) { return &emptycmd2; } @@ -2048,7 +2048,7 @@ tic_t I_GetTime (void) // //I_StartupTimer // -FUNCMATH void I_StartupTimer(void) +void I_StartupTimer(void) { #ifdef _WIN32 // for win2k time bug @@ -2147,11 +2147,11 @@ void I_WaitVBL(INT32 count) SDL_Delay(count); } -FUNCMATH void I_BeginRead(void) +void I_BeginRead(void) { } -FUNCMATH void I_EndRead(void) +void I_EndRead(void) { } @@ -2939,5 +2939,5 @@ const CPUInfoFlags *I_CPUInfo(void) } // note CPUAFFINITY code used to reside here -FUNCMATH void I_RegisterSysCommands(void) {} +void I_RegisterSysCommands(void) {} #endif diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 30ef1b27b..db88f452a 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -1053,7 +1053,7 @@ void I_SetPalette(RGBA_t *palette) } // return number of fullscreen + X11 modes -FUNCMATH INT32 VID_NumModes(void) +INT32 VID_NumModes(void) { if (USE_FULLSCREEN && numVidModes != -1) return numVidModes - firstEntry; @@ -1061,7 +1061,7 @@ FUNCMATH INT32 VID_NumModes(void) return MAXWINMODES; } -FUNCMATH const char *VID_GetModeName(INT32 modeNum) +const char *VID_GetModeName(INT32 modeNum) { #if 0 if (USE_FULLSCREEN && numVidModes != -1) // fullscreen modes @@ -1091,7 +1091,7 @@ FUNCMATH const char *VID_GetModeName(INT32 modeNum) return &vidModeName[modeNum][0]; } -FUNCMATH INT32 VID_GetModeForSize(INT32 w, INT32 h) +INT32 VID_GetModeForSize(INT32 w, INT32 h) { int i; for (i = 0; i < MAXWINMODES; i++) diff --git a/src/sdl/mixer_sound.c b/src/sdl/mixer_sound.c index 4d86d7a3c..f36f08695 100644 --- a/src/sdl/mixer_sound.c +++ b/src/sdl/mixer_sound.c @@ -135,7 +135,7 @@ void I_ShutdownSound(void) #endif } -FUNCMATH void I_UpdateSound(void) +void I_UpdateSound(void) { } @@ -504,7 +504,7 @@ static void mix_gme(void *udata, Uint8 *stream, int len) /// Music System /// ------------------------ -FUNCMATH void I_InitMusic(void) +void I_InitMusic(void) { } diff --git a/src/sdl/sdl_sound.c b/src/sdl/sdl_sound.c index 9f8a3e29d..f4796cd80 100644 --- a/src/sdl/sdl_sound.c +++ b/src/sdl/sdl_sound.c @@ -219,7 +219,7 @@ static void Snd_UnlockAudio(void) //Alam: Unlock audio data and reinstall audio #endif } -FUNCMATH static inline Uint16 Snd_LowerRate(Uint16 sr) +static inline Uint16 Snd_LowerRate(Uint16 sr) { if (sr <= audio.freq) // already lowered rate? return sr; // good then diff --git a/src/sdl12/sdl_sound.c b/src/sdl12/sdl_sound.c index 01a27153e..ed1afd8e2 100644 --- a/src/sdl12/sdl_sound.c +++ b/src/sdl12/sdl_sound.c @@ -236,7 +236,7 @@ static void Snd_UnlockAudio(void) //Alam: Unlock audio data and reinstall audio #endif } -FUNCMATH static inline Uint16 Snd_LowerRate(Uint16 sr) +static inline Uint16 Snd_LowerRate(Uint16 sr) { if (sr <= audio.freq) // already lowered rate? return sr; // good then From 5c61c405514206b6e7b8b46f5322920519efa5f1 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 8 Nov 2018 16:31:20 +0000 Subject: [PATCH 18/49] Clean up doomtype.h a bit, add indenting and comments to make some preprocessor code more readable --- src/doomtype.h | 129 +++++++++++++++++++++++++++---------------------- 1 file changed, 70 insertions(+), 59 deletions(-) diff --git a/src/doomtype.h b/src/doomtype.h index a711b466d..3631eb518 100644 --- a/src/doomtype.h +++ b/src/doomtype.h @@ -44,12 +44,13 @@ typedef long ssize_t; /* Older Visual C++ headers don't have the Win64-compatible typedefs... */ -#if ((_MSC_VER <= 1200) && (!defined(DWORD_PTR))) -#define DWORD_PTR DWORD -#endif - -#if ((_MSC_VER <= 1200) && (!defined(PDWORD_PTR))) -#define PDWORD_PTR PDWORD +#if (_MSC_VER <= 1200) + #ifndef DWORD_PTR + #define DWORD_PTR DWORD + #endif + #ifndef PDWORD_PTR + #define PDWORD_PTR PDWORD + #endif #endif #elif defined (_arch_dreamcast) // KOS Dreamcast #include @@ -102,7 +103,7 @@ typedef long ssize_t; #ifdef _MSC_VER #if (_MSC_VER <= 1800) // MSVC 2013 and back #define snprintf _snprintf -#if (_MSC_VER <= 1200) // MSVC 2012 and back +#if (_MSC_VER <= 1200) // MSVC 6.0 and back #define vsnprintf _vsnprintf #endif #endif @@ -185,7 +186,7 @@ size_t strlcpy(char *dst, const char *src, size_t siz); //faB: clean that up !! #if defined( _MSC_VER) && (_MSC_VER >= 1800) // MSVC 2013 and forward - #include "stdbool.h" + #include "stdbool.h" #elif (defined (_WIN32) || (defined (_WIN32_WCE) && !defined (__GNUC__))) && !defined (_XBOX) #define false FALSE // use windows types #define true TRUE @@ -275,58 +276,68 @@ typedef UINT32 tic_t; #endif #ifdef __GNUC__ // __attribute__ ((X)) -#define FUNCNORETURN __attribute__ ((noreturn)) -#if ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)) && defined (__MINGW32__) -#include "inttypes.h" -#if 0 //defined (__USE_MINGW_ANSI_STDIO) && __USE_MINGW_ANSI_STDIO > 0 -#define FUNCPRINTF __attribute__ ((format(gnu_printf, 1, 2))) -#define FUNCDEBUG __attribute__ ((format(gnu_printf, 2, 3))) -#define FUNCIERROR __attribute__ ((format(gnu_printf, 1, 2),noreturn)) -#elif (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4) -#define FUNCPRINTF __attribute__ ((format(ms_printf, 1, 2))) -#define FUNCDEBUG __attribute__ ((format(ms_printf, 2, 3))) -#define FUNCIERROR __attribute__ ((format(ms_printf, 1, 2),noreturn)) -#else -#define FUNCPRINTF __attribute__ ((format(printf, 1, 2))) -#define FUNCDEBUG __attribute__ ((format(printf, 2, 3))) -#define FUNCIERROR __attribute__ ((format(printf, 1, 2),noreturn)) -#endif -#else -#define FUNCPRINTF __attribute__ ((format(printf, 1, 2))) -#define FUNCDEBUG __attribute__ ((format(printf, 2, 3))) -#define FUNCIERROR __attribute__ ((format(printf, 1, 2),noreturn)) -#endif -#ifndef FUNCIERROR -#define FUNCIERROR __attribute__ ((noreturn)) -#endif -#define FUNCMATH __attribute__((const)) -#if (__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1) -#define FUNCDEAD __attribute__ ((deprecated)) -#define FUNCINLINE __attribute__((always_inline)) -#define FUNCNONNULL __attribute__((nonnull)) -#endif -#define FUNCNOINLINE __attribute__((noinline)) -#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4) -#ifdef __i386__ // i386 only -#define FUNCTARGET(X) __attribute__ ((__target__ (X))) -#endif -#endif -#if defined (__MINGW32__) && ((__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) -#define ATTRPACK __attribute__((packed, gcc_struct)) -#else -#define ATTRPACK __attribute__((packed)) -#endif -#define ATTRUNUSED __attribute__((unused)) -#ifdef _XBOX -#define FILESTAMP I_OutputMsg("%s:%d\n",__FILE__,__LINE__); -#define XBOXSTATIC static -#endif + #define FUNCNORETURN __attribute__ ((noreturn)) + + #if ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)) && defined (__MINGW32__) // MinGW, >= GCC 4.1 + #include "inttypes.h" + #if 0 //defined (__USE_MINGW_ANSI_STDIO) && __USE_MINGW_ANSI_STDIO > 0 + #define FUNCPRINTF __attribute__ ((format(gnu_printf, 1, 2))) + #define FUNCDEBUG __attribute__ ((format(gnu_printf, 2, 3))) + #define FUNCIERROR __attribute__ ((format(gnu_printf, 1, 2),noreturn)) + #elif (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4) // >= GCC 4.4 + #define FUNCPRINTF __attribute__ ((format(ms_printf, 1, 2))) + #define FUNCDEBUG __attribute__ ((format(ms_printf, 2, 3))) + #define FUNCIERROR __attribute__ ((format(ms_printf, 1, 2),noreturn)) + #else + #define FUNCPRINTF __attribute__ ((format(printf, 1, 2))) + #define FUNCDEBUG __attribute__ ((format(printf, 2, 3))) + #define FUNCIERROR __attribute__ ((format(printf, 1, 2),noreturn)) + #endif + #else + #define FUNCPRINTF __attribute__ ((format(printf, 1, 2))) + #define FUNCDEBUG __attribute__ ((format(printf, 2, 3))) + #define FUNCIERROR __attribute__ ((format(printf, 1, 2),noreturn)) + #endif + + #ifndef FUNCIERROR + #define FUNCIERROR __attribute__ ((noreturn)) + #endif + + #define FUNCMATH __attribute__((const)) + + #if (__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1) // >= GCC 3.1 + #define FUNCDEAD __attribute__ ((deprecated)) + #define FUNCINLINE __attribute__((always_inline)) + #define FUNCNONNULL __attribute__((nonnull)) + #endif + + #define FUNCNOINLINE __attribute__((noinline)) + + #if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4) // >= GCC 4.4 + #ifdef __i386__ // i386 only + #define FUNCTARGET(X) __attribute__ ((__target__ (X))) + #endif + #endif + + #if defined (__MINGW32__) && ((__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) // MinGW, >= GCC 3.4 + #define ATTRPACK __attribute__((packed, gcc_struct)) + #else + #define ATTRPACK __attribute__((packed)) + #endif + + #define ATTRUNUSED __attribute__((unused)) + + // Xbox-only macros + #ifdef _XBOX + #define FILESTAMP I_OutputMsg("%s:%d\n",__FILE__,__LINE__); + #define XBOXSTATIC static + #endif #elif defined (_MSC_VER) -#define ATTRNORETURN __declspec(noreturn) -#define ATTRINLINE __forceinline -#if _MSC_VER > 1200 -#define ATTRNOINLINE __declspec(noinline) -#endif + #define ATTRNORETURN __declspec(noreturn) + #define ATTRINLINE __forceinline + #if _MSC_VER > 1200 // >= MSVC 6.0 + #define ATTRNOINLINE __declspec(noinline) + #endif #endif #ifndef FUNCPRINTF From fd20bbb54e5882f43f006bcf60f653455f55ab11 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 8 Nov 2018 17:05:35 +0000 Subject: [PATCH 19/49] More doomtype.h cleaning up: * Move the misc types in the file to bottom, so that ATTRPACK at least is usable for RGBA_t * Include endian.h, so that UINT2RGBA can be defined correctly for big endian builds * Add more comments to make clear the main sections of the file --- src/doomtype.h | 77 ++++++++++++++++++++++++++++---------------------- 1 file changed, 44 insertions(+), 33 deletions(-) diff --git a/src/doomtype.h b/src/doomtype.h index 3631eb518..67c279aa9 100644 --- a/src/doomtype.h +++ b/src/doomtype.h @@ -98,6 +98,8 @@ typedef long ssize_t; #define NOIPX #endif +/* Strings and some misc platform specific stuff */ + #if defined (_MSC_VER) || defined (__OS2__) // Microsoft VisualC++ #ifdef _MSC_VER @@ -179,6 +181,8 @@ size_t strlcpy(char *dst, const char *src, size_t siz); // not the number of bytes in the buffer. #define STRBUFCPY(dst,src) strlcpy(dst, src, sizeof dst) +/* Boolean type definition */ + // \note __BYTEBOOL__ used to be set above if "macintosh" was defined, // if macintosh's version of boolean type isn't needed anymore, then isn't this macro pointless now? #ifndef __BYTEBOOL__ @@ -241,39 +245,7 @@ size_t strlcpy(char *dst, const char *src, size_t siz); #define UINT64_MAX 0xffffffffffffffffULL /* 18446744073709551615ULL */ #endif -union FColorRGBA -{ - UINT32 rgba; - struct - { - UINT8 red; - UINT8 green; - UINT8 blue; - UINT8 alpha; - } s; -} ATTRPACK; -typedef union FColorRGBA RGBA_t; - -typedef enum -{ - postimg_none, - postimg_water, - postimg_motion, - postimg_flip, - postimg_heat -} postimg_t; - -typedef UINT32 lumpnum_t; // 16 : 16 unsigned long (wad num: lump num) -#define LUMPERROR UINT32_MAX - -typedef UINT32 tic_t; -#define INFTICS UINT32_MAX - -#ifdef _BIG_ENDIAN -#define UINT2RGBA(a) a -#else -#define UINT2RGBA(a) (UINT32)((a&0xff)<<24)|((a&0xff00)<<8)|((a&0xff0000)>>8)|(((UINT32)a&0xff000000)>>24) -#endif +/* Compiler-specific attributes and other macros */ #ifdef __GNUC__ // __attribute__ ((X)) #define FUNCNORETURN __attribute__ ((noreturn)) @@ -391,4 +363,43 @@ typedef UINT32 tic_t; #ifndef FILESTAMP #define FILESTAMP #endif + +/* Miscellaneous types that don't fit anywhere else (Can this be changed?) */ + +union FColorRGBA +{ + UINT32 rgba; + struct + { + UINT8 red; + UINT8 green; + UINT8 blue; + UINT8 alpha; + } s; +} ATTRPACK; +typedef union FColorRGBA RGBA_t; + +typedef enum +{ + postimg_none, + postimg_water, + postimg_motion, + postimg_flip, + postimg_heat +} postimg_t; + +typedef UINT32 lumpnum_t; // 16 : 16 unsigned long (wad num: lump num) +#define LUMPERROR UINT32_MAX + +typedef UINT32 tic_t; +#define INFTICS UINT32_MAX + +#include "endian.h" // This is needed to make sure the below macro acts correctly in big endian builds + +#ifdef SRB2_BIG_ENDIAN +#define UINT2RGBA(a) a +#else +#define UINT2RGBA(a) (UINT32)((a&0xff)<<24)|((a&0xff00)<<8)|((a&0xff0000)>>8)|(((UINT32)a&0xff000000)>>24) +#endif + #endif //__DOOMTYPE__ From fa80d6179978b1d8c88eda73d1efde1f4194c2d4 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 8 Nov 2018 17:16:54 +0000 Subject: [PATCH 20/49] byteptr.h: include endian.h to help define WRITE/READ macros correctly according to endianness --- src/byteptr.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/byteptr.h b/src/byteptr.h index 410d7c004..364e6520c 100644 --- a/src/byteptr.h +++ b/src/byteptr.h @@ -15,7 +15,9 @@ #define DEALIGNED #endif -#ifndef _BIG_ENDIAN +#include "endian.h" + +#ifndef SRB2_BIG_ENDIAN // // Little-endian machines // @@ -75,7 +77,7 @@ #define READANGLE(p) *((angle_t *)p)++ #endif -#else //_BIG_ENDIAN +#else //SRB2_BIG_ENDIAN // // definitions for big-endian machines with alignment constraints. // @@ -144,7 +146,7 @@ FUNCINLINE static ATTRINLINE UINT32 readulong(void *ptr) #define READCHAR(p) ({ char *p_tmp = ( char *)p; char b = *p_tmp; p_tmp++; p = (void *)p_tmp; b; }) #define READFIXED(p) ({ fixed_t *p_tmp = (fixed_t *)p; fixed_t b = readlong(p); p_tmp++; p = (void *)p_tmp; b; }) #define READANGLE(p) ({ angle_t *p_tmp = (angle_t *)p; angle_t b = readulong(p); p_tmp++; p = (void *)p_tmp; b; }) -#endif //_BIG_ENDIAN +#endif //SRB2_BIG_ENDIAN #undef DEALIGNED From f50f10ef307fe2a09a2d2fb84cb368ea10b89567 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 8 Nov 2018 20:09:00 +0000 Subject: [PATCH 21/49] d_main.c: remove the _MAX_PATH define, the file hasn't used it since v2.0 --- src/d_main.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index 037aeccf9..15b144dda 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -761,10 +761,6 @@ static inline void D_CleanFile(void) } } -#ifndef _MAX_PATH -#define _MAX_PATH MAX_WADPATH -#endif - // ========================================================================== // Identify the SRB2 version, and IWAD file to use. // ========================================================================== From a542006ae846a2ab87d08e8311e06d76747f3886 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sat, 10 Nov 2018 01:17:11 -0500 Subject: [PATCH 22/49] Hide Tutorial menu option if no tutorialmap --- src/m_menu.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/m_menu.c b/src/m_menu.c index 69c609db0..38ff3f998 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -732,7 +732,7 @@ static menuitem_t SR_EmblemHintMenu[] = // Single Player Main static menuitem_t SP_MainMenu[] = { - {IT_STRING, NULL, "Tutorial", M_StartTutorial, 84}, + {IT_CALL | IT_STRING, NULL, "Tutorial", M_StartTutorial, 84}, {IT_CALL | IT_STRING, NULL, "Start Game", M_LoadGame, 92}, {IT_SECRET, NULL, "Record Attack", M_TimeAttack, 100}, {IT_SECRET, NULL, "NiGHTS Mode", M_NightsAttack, 108}, @@ -6107,6 +6107,8 @@ static void M_CustomLevelSelect(INT32 choice) static void M_SinglePlayerMenu(INT32 choice) { (void)choice; + SP_MainMenu[sptutorial].status = + tutorialmap ? IT_CALL|IT_STRING : IT_NOTHING|IT_DISABLED; SP_MainMenu[sprecordattack].status = (M_SecretUnlocked(SECRET_RECORDATTACK)) ? IT_CALL|IT_STRING : IT_SECRET; SP_MainMenu[spnightsmode].status = From ffed9f4d20eaf77e75bef5588fd2ecc4b10f3126 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sat, 10 Nov 2018 01:31:30 -0500 Subject: [PATCH 23/49] Force camera defaults during tutorialmode (doesn't work in all cases) --- src/p_user.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/p_user.c b/src/p_user.c index dd2ddbc82..75712ff3a 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -8848,7 +8848,18 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall if (P_CameraThinker(player, thiscam, resetcalled)) return true; - if (thiscam == &camera) + if (tutorialmode) + { + // force defaults because we have a camera look section + // \todo would be nice to use cv_cam_*.defaultvalue directly, but string parsing + // is not separated from cv setting (see command.c Setvalue, CV_SetCVar) + camspeed = 0.3; + camstill = false; + camrotate = 0; + camdist = 160; + camheight = 25; + } + else if (thiscam == &camera) { camspeed = cv_cam_speed.value; camstill = cv_cam_still.value; From 28238c41dfd044a46f0624939a07f9fe250bc1c7 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sat, 10 Nov 2018 02:30:21 -0500 Subject: [PATCH 24/49] WIP: First-time tutorial prompt --- src/d_netcmd.c | 1 + src/g_game.h | 1 + src/m_menu.c | 25 +++++++++++++++++++++++++ 3 files changed, 27 insertions(+) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 528d79f3b..dd9ced6c4 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -719,6 +719,7 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_crosshair2); CV_RegisterVar(&cv_alwaysfreelook); CV_RegisterVar(&cv_alwaysfreelook2); + CV_RegisterVar(&cv_postfirsttime); // g_input.c CV_RegisterVar(&cv_sideaxis); diff --git a/src/g_game.h b/src/g_game.h index d6b41830e..00298c623 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -55,6 +55,7 @@ extern tic_t timeinmap; // Ticker for time spent in level (used for levelcard di extern INT16 rw_maximums[NUM_WEAPONS]; // used in game menu +extern consvar_t cv_postfirsttime; extern consvar_t cv_crosshair, cv_crosshair2; extern consvar_t cv_invertmouse, cv_alwaysfreelook, cv_mousemove; extern consvar_t cv_invertmouse2, cv_alwaysfreelook2, cv_mousemove2; diff --git a/src/m_menu.c b/src/m_menu.c index 38ff3f998..b61c6396a 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -441,6 +441,9 @@ static CV_PossibleValue_t serversort_cons_t[] = { }; consvar_t cv_serversort = {"serversort", "Ping", CV_HIDEN | CV_CALL, serversort_cons_t, M_SortServerList, 0, NULL, NULL, 0, 0, NULL}; +// first time memory +consvar_t cv_postfirsttime = {"postfirsttime", "No", CV_HIDEN | CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; + // autorecord demos for time attack static consvar_t cv_autorecord = {"autorecord", "Yes", 0, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -6141,6 +6144,8 @@ static void M_StartTutorial(INT32 choice) if (!tutorialmap) return; // no map to go to, don't bother + CV_SetValue(&cv_postfirsttime, 1); + tutorialmode = true; // turn on tutorial mode emeralds = 0; @@ -6757,6 +6762,20 @@ static void M_HandleLoadSave(INT32 choice) } } +static void M_TutorialResponse(INT32 ch) +{ + CV_SetValue(&cv_postfirsttime, 1); + if (ch != 'y' && ch != KEY_ENTER) + { + return; + // copypasta from M_LoadGame + M_ReadSaveStrings(); + M_SetupNextMenu(&SP_LoadDef); + } + else + M_StartTutorial(0); +} + // // Selected from SRB2 menu // @@ -6764,6 +6783,12 @@ static void M_LoadGame(INT32 choice) { (void)choice; + if (tutorialmap && !cv_postfirsttime.value) + { + M_StartMessage("Do you want to play a brief Tutorial?\n(Press 'Y' to go, or 'N' to skip)", M_TutorialResponse, MM_YESNO); + return; + } + M_ReadSaveStrings(); M_SetupNextMenu(&SP_LoadDef); } From 2da335a1c4cb9af38fbba79c4aadeeb4facf0093 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sat, 10 Nov 2018 13:08:26 +0000 Subject: [PATCH 25/49] Place limit on the amount of alias recursion allowed, to prevent cycles or otherwise excessive recursion --- src/command.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/command.c b/src/command.c index f77fb5a4d..8971d42fc 100644 --- a/src/command.c +++ b/src/command.c @@ -63,6 +63,7 @@ CV_PossibleValue_t CV_Unsigned[] = {{0, "MIN"}, {999999999, "MAX"}, {0, NULL}}; CV_PossibleValue_t CV_Natural[] = {{1, "MIN"}, {999999999, "MAX"}, {0, NULL}}; #define COM_BUF_SIZE 8192 // command buffer size +#define MAX_ALIAS_RECURSION 100 // max recursion allowed for aliases static INT32 com_wait; // one command per frame (for cmd sequences) @@ -485,6 +486,7 @@ static void COM_ExecuteString(char *ptext) { xcommand_t *cmd; cmdalias_t *a; + static INT32 recursion = 0; // detects recursion and stops it if it goes too far COM_TokenizeString(ptext); @@ -497,6 +499,7 @@ static void COM_ExecuteString(char *ptext) { if (!stricmp(com_argv[0], cmd->name)) //case insensitive now that we have lower and uppercase! { + recursion = 0; cmd->function(); return; } @@ -507,11 +510,20 @@ static void COM_ExecuteString(char *ptext) { if (!stricmp(com_argv[0], a->name)) { + if (recursion > MAX_ALIAS_RECURSION) + { + CONS_Alert(CONS_WARNING, M_GetText("Alias recursion cycle detected!\n")); + recursion = 0; + return; + } + recursion++; COM_BufInsertText(a->value); return; } } + recursion = 0; + // check cvars // Hurdler: added at Ebola's request ;) // (don't flood the console in software mode with bad gr_xxx command) From a733a29f4c5889251192184870cc451cacd9dc96 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Mon, 9 Jan 2017 22:13:26 +0000 Subject: [PATCH 26/49] Starting work on porting hw_clip.c/h code, Makefiles and CMake can compile them at least Other notes: * Renamed all new functions to have HWR_ prefix instead of gld_, for consistency * HWR_FrustrumSetup and HWR_SphereInFrustum are disabled and require HAVE_SPHEREFRUSTRUM. This is because 1) SRB2CB did not need the code, so presumably neither will we, and 2) there are some OpenGL API functions used there that due to our way of using OpenGL we don't use outside of r_opengl.c, which makes dealing with HWR_FrustrumSetup complicated in theory * The new clipping functions are not added to OpenGL's "main" rendering code itself just yet, they're just available to use now once hw_clip.h is included --- src/CMakeLists.txt | 2 + src/Makefile | 12 +- src/hardware/hw_clip.c | 465 +++++++++++++++++++++++++++++++++++++++++ src/hardware/hw_clip.h | 24 +++ 4 files changed, 497 insertions(+), 6 deletions(-) create mode 100644 src/hardware/hw_clip.c create mode 100644 src/hardware/hw_clip.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 46a42a92c..0602de9de 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -350,6 +350,7 @@ if(${SRB2_CONFIG_HWRENDER}) set(SRB2_HWRENDER_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_bsp.c ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_cache.c + ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_clip.c ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_draw.c ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_light.c ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_main.c @@ -358,6 +359,7 @@ if(${SRB2_CONFIG_HWRENDER}) ) set (SRB2_HWRENDER_HEADERS + ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_clip.h ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_data.h ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_defs.h ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_dll.h diff --git a/src/Makefile b/src/Makefile index 7a67c3f02..b159de3b8 100644 --- a/src/Makefile +++ b/src/Makefile @@ -269,7 +269,7 @@ ifndef DC endif OPTS+=-DHWRENDER OBJS+=$(OBJDIR)/hw_bsp.o $(OBJDIR)/hw_draw.o $(OBJDIR)/hw_light.o \ - $(OBJDIR)/hw_main.o $(OBJDIR)/hw_md2.o $(OBJDIR)/hw_cache.o $(OBJDIR)/hw_trick.o + $(OBJDIR)/hw_main.o $(OBJDIR)/hw_clip.o $(OBJDIR)/hw_md2.o $(OBJDIR)/hw_cache.o $(OBJDIR)/hw_trick.o endif ifdef NOHS @@ -719,7 +719,7 @@ ifdef MINGW $(OBJDIR)/r_opengl.o: hardware/r_opengl/r_opengl.c hardware/r_opengl/r_opengl.h \ doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \ command.h hardware/hw_data.h hardware/hw_glide.h hardware/hw_defs.h \ - hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h am_map.h \ + hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h am_map.h \ d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \ p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h $(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@ @@ -727,7 +727,7 @@ else $(OBJDIR)/r_opengl.o: hardware/r_opengl/r_opengl.c hardware/r_opengl/r_opengl.h \ doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \ command.h hardware/hw_data.h hardware/hw_glide.h hardware/hw_defs.h \ - hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h am_map.h \ + hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h am_map.h \ d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \ p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h $(CC) $(CFLAGS) $(WFLAGS) -I/usr/X11R6/include -c $< -o $@ @@ -880,7 +880,7 @@ ifndef NOHW $(OBJDIR)/r_opengl.o: hardware/r_opengl/r_opengl.c hardware/r_opengl/r_opengl.h \ doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \ command.h hardware/hw_data.h hardware/hw_glide.h hardware/hw_defs.h \ - hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h am_map.h \ + hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h am_map.h \ d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \ p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h $(CC) $(CFLAGS) $(WFLAGS) -D_WINDOWS -mwindows -c $< -o $@ @@ -888,7 +888,7 @@ $(OBJDIR)/r_opengl.o: hardware/r_opengl/r_opengl.c hardware/r_opengl/r_opengl.h $(OBJDIR)/ogl_win.o: hardware/r_opengl/ogl_win.c hardware/r_opengl/r_opengl.h \ doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \ command.h hardware/hw_data.h hardware/hw_glide.h hardware/hw_defs.h \ - hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h am_map.h \ + hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h am_map.h \ d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \ p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h $(CC) $(CFLAGS) $(WFLAGS) -D_WINDOWS -mwindows -c $< -o $@ @@ -896,7 +896,7 @@ $(OBJDIR)/ogl_win.o: hardware/r_opengl/ogl_win.c hardware/r_opengl/r_opengl.h \ $(OBJDIR)/r_minigl.o: hardware/r_minigl/r_minigl.c hardware/r_opengl/r_opengl.h \ doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \ command.h hardware/hw_data.h hardware/hw_glide.h hardware/hw_defs.h \ - hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h am_map.h \ + hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h am_map.h \ d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \ p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h $(CC) $(CFLAGS) $(WFLAGS) -D_WINDOWS -mwindows -c $< -o $@ diff --git a/src/hardware/hw_clip.c b/src/hardware/hw_clip.c new file mode 100644 index 000000000..47cbbfa2b --- /dev/null +++ b/src/hardware/hw_clip.c @@ -0,0 +1,465 @@ +/* Emacs style mode select -*- C++ -*- + *----------------------------------------------------------------------------- + * + * + * PrBoom: a Doom port merged with LxDoom and LSDLDoom + * based on BOOM, a modified and improved DOOM engine + * Copyright (C) 1999 by + * id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman + * Copyright (C) 1999-2000 by + * Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze + * Copyright 2005, 2006 by + * Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * DESCRIPTION: + * + *--------------------------------------------------------------------- + */ + +/* + * + ** gl_clipper.cpp + ** + ** Handles visibility checks. + ** Loosely based on the JDoom clipper. + ** + **--------------------------------------------------------------------------- + ** Copyright 2003 Tim Stump + ** All rights reserved. + ** + ** Redistribution and use in source and binary forms, with or without + ** modification, are permitted provided that the following conditions + ** are met: + ** + ** 1. Redistributions of source code must retain the above copyright + ** notice, this list of conditions and the following disclaimer. + ** 2. Redistributions in binary form must reproduce the above copyright + ** notice, this list of conditions and the following disclaimer in the + ** documentation and/or other materials provided with the distribution. + ** 3. The name of the author may not be used to endorse or promote products + ** derived from this software without specific prior written permission. + ** + ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + ** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + ** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + ** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + ** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + ** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + ** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + **--------------------------------------------------------------------------- + ** + */ + +#include +#include "../v_video.h" +#include "hw_clip.h" +#include "hw_glob.h" +#include "../r_state.h" +#include "../tables.h" +#include "r_opengl/r_opengl.h" + +#ifdef HAVE_SPHEREFRUSTRUM +static GLdouble viewMatrix[16]; +static GLdouble projMatrix[16]; +float frustum[6][4]; +#endif + +typedef struct clipnode_s + { + struct clipnode_s *prev, *next; + angle_t start, end; + } clipnode_t; + +clipnode_t *freelist; +clipnode_t *clipnodes; +clipnode_t *cliphead; + +static clipnode_t * HWR_clipnode_GetNew(void); +static clipnode_t * HWR_clipnode_NewRange(angle_t start, angle_t end); +static boolean HWR_clipper_IsRangeVisible(angle_t startAngle, angle_t endAngle); +static void HWR_clipper_AddClipRange(angle_t start, angle_t end); +static void HWR_clipper_RemoveRange(clipnode_t * range); +static void HWR_clipnode_Free(clipnode_t *node); + +static clipnode_t * HWR_clipnode_GetNew(void) +{ + if (freelist) + { + clipnode_t * p = freelist; + freelist = p->next; + return p; + } + else + { + return (clipnode_t*)malloc(sizeof(clipnode_t)); + } +} + +static clipnode_t * HWR_clipnode_NewRange(angle_t start, angle_t end) +{ + clipnode_t * c = HWR_clipnode_GetNew(); + c->start = start; + c->end = end; + c->next = c->prev=NULL; + return c; +} + +boolean HWR_clipper_SafeCheckRange(angle_t startAngle, angle_t endAngle) +{ + if(startAngle > endAngle) + { + return (HWR_clipper_IsRangeVisible(startAngle, ANGLE_MAX) || HWR_clipper_IsRangeVisible(0, endAngle)); + } + + return HWR_clipper_IsRangeVisible(startAngle, endAngle); +} + +static boolean HWR_clipper_IsRangeVisible(angle_t startAngle, angle_t endAngle) +{ + clipnode_t *ci; + ci = cliphead; + + if (endAngle == 0 && ci && ci->start == 0) + return false; + + while (ci != NULL && ci->start < endAngle) + { + if (startAngle >= ci->start && endAngle <= ci->end) + { + return false; + } + ci = ci->next; + } + + return true; +} + +static void HWR_clipnode_Free(clipnode_t *node) +{ + node->next = freelist; + freelist = node; +} + +static void HWR_clipper_RemoveRange(clipnode_t *range) +{ + if (range == cliphead) + { + cliphead = cliphead->next; + } + else + { + if (range->prev) + { + range->prev->next = range->next; + } + if (range->next) + { + range->next->prev = range->prev; + } + } + + HWR_clipnode_Free(range); +} + +void HWR_clipper_SafeAddClipRange(angle_t startangle, angle_t endangle) +{ + if(startangle > endangle) + { + // The range has to added in two parts. + HWR_clipper_AddClipRange(startangle, ANGLE_MAX); + HWR_clipper_AddClipRange(0, endangle); + } + else + { + // Add the range as usual. + HWR_clipper_AddClipRange(startangle, endangle); + } +} + +static void HWR_clipper_AddClipRange(angle_t start, angle_t end) +{ + clipnode_t *node, *temp, *prevNode, *node2, *delnode; + + if (cliphead) + { + //check to see if range contains any old ranges + node = cliphead; + while (node != NULL && node->start < end) + { + if (node->start >= start && node->end <= end) + { + temp = node; + node = node->next; + HWR_clipper_RemoveRange(temp); + } + else + { + if (node->start <= start && node->end >= end) + { + return; + } + else + { + node = node->next; + } + } + } + + //check to see if range overlaps a range (or possibly 2) + node = cliphead; + while (node != NULL && node->start <= end) + { + if (node->end >= start) + { + // we found the first overlapping node + if (node->start > start) + { + // the new range overlaps with this node's start point + node->start = start; + } + if (node->end < end) + { + node->end = end; + } + + node2 = node->next; + while (node2 && node2->start <= node->end) + { + if (node2->end > node->end) + { + node->end = node2->end; + } + + delnode = node2; + node2 = node2->next; + HWR_clipper_RemoveRange(delnode); + } + return; + } + node = node->next; + } + + //just add range + node = cliphead; + prevNode = NULL; + temp = HWR_clipnode_NewRange(start, end); + while (node != NULL && node->start < end) + { + prevNode = node; + node = node->next; + } + temp->next = node; + if (node == NULL) + { + temp->prev = prevNode; + if (prevNode) + { + prevNode->next = temp; + } + if (!cliphead) + { + cliphead = temp; + } + } + else + { + if (node == cliphead) + { + cliphead->prev = temp; + cliphead = temp; + } + else + { + temp->prev = prevNode; + prevNode->next = temp; + node->prev = temp; + } + } + } + else + { + temp = HWR_clipnode_NewRange(start, end); + cliphead = temp; + return; + } +} + +void HWR_clipper_Clear(void) +{ + clipnode_t *node = cliphead; + clipnode_t *temp; + + while (node != NULL) + { + temp = node; + node = node->next; + HWR_clipnode_Free(temp); + } + + cliphead = NULL; +} + +#define RMUL (1.6f/1.333333f) + +angle_t HWR_FrustumAngle(void) +{ + double floatangle; + angle_t a1; + + float tilt = (float)fabs(((double)(int)aimingangle) / ANG1); + + // NEWCLIP TODO: SRB2CBTODO: make a global render_fov for this function + + float render_fov = FIXED_TO_FLOAT(cv_grfov.value); + float render_fovratio = (float)BASEVIDWIDTH / (float)BASEVIDHEIGHT; // SRB2CBTODO: NEWCLIPTODO: Is this right? + float render_multiplier = 64.0f / render_fovratio / RMUL; + + if (tilt > 90.0f) + { + tilt = 90.0f; + } + + // If the pitch is larger than this you can look all around at a FOV of 90 + if (abs(aimingangle) > 46 * ANG1) + return 0xffffffff; + + // ok, this is a gross hack that barely works... + // but at least it doesn't overestimate too much... + floatangle = 2.0f + (45.0f + (tilt / 1.9f)) * (float)render_fov * 48.0f / render_multiplier / 90.0f; + a1 = ANG1 * (int)floatangle; + if (a1 >= ANGLE_180) + return 0xffffffff; + return a1; +} + +// SRB2CB I don't think used any of this stuff, let's disable for now since SRB2 probably doesn't want it either +// compiler complains about (p)glGetDoublev anyway, in case anyone wants this +// only r_opengl.c can use the base gl funcs as it turns out, that's a problem for whoever wants sphere frustum checks +// btw to renable define HAVE_SPHEREFRUSTRUM in hw_clip.h +#ifdef HAVE_SPHEREFRUSTRUM +// +// HWR_FrustrumSetup +// + +#define CALCMATRIX(a, b, c, d, e, f, g, h)\ +(float)(viewMatrix[a] * projMatrix[b] + \ +viewMatrix[c] * projMatrix[d] + \ +viewMatrix[e] * projMatrix[f] + \ +viewMatrix[g] * projMatrix[h]) + +#define NORMALIZE_PLANE(i)\ +t = (float)sqrt(\ +frustum[i][0] * frustum[i][0] + \ +frustum[i][1] * frustum[i][1] + \ +frustum[i][2] * frustum[i][2]); \ +frustum[i][0] /= t; \ +frustum[i][1] /= t; \ +frustum[i][2] /= t; \ +frustum[i][3] /= t + +void HWR_FrustrumSetup(void) +{ + float t; + float clip[16]; + + pglGetDoublev(GL_PROJECTION_MATRIX, projMatrix); + pglGetDoublev(GL_MODELVIEW_MATRIX, viewMatrix); + + clip[0] = CALCMATRIX(0, 0, 1, 4, 2, 8, 3, 12); + clip[1] = CALCMATRIX(0, 1, 1, 5, 2, 9, 3, 13); + clip[2] = CALCMATRIX(0, 2, 1, 6, 2, 10, 3, 14); + clip[3] = CALCMATRIX(0, 3, 1, 7, 2, 11, 3, 15); + + clip[4] = CALCMATRIX(4, 0, 5, 4, 6, 8, 7, 12); + clip[5] = CALCMATRIX(4, 1, 5, 5, 6, 9, 7, 13); + clip[6] = CALCMATRIX(4, 2, 5, 6, 6, 10, 7, 14); + clip[7] = CALCMATRIX(4, 3, 5, 7, 6, 11, 7, 15); + + clip[8] = CALCMATRIX(8, 0, 9, 4, 10, 8, 11, 12); + clip[9] = CALCMATRIX(8, 1, 9, 5, 10, 9, 11, 13); + clip[10] = CALCMATRIX(8, 2, 9, 6, 10, 10, 11, 14); + clip[11] = CALCMATRIX(8, 3, 9, 7, 10, 11, 11, 15); + + clip[12] = CALCMATRIX(12, 0, 13, 4, 14, 8, 15, 12); + clip[13] = CALCMATRIX(12, 1, 13, 5, 14, 9, 15, 13); + clip[14] = CALCMATRIX(12, 2, 13, 6, 14, 10, 15, 14); + clip[15] = CALCMATRIX(12, 3, 13, 7, 14, 11, 15, 15); + + // Right plane + frustum[0][0] = clip[ 3] - clip[ 0]; + frustum[0][1] = clip[ 7] - clip[ 4]; + frustum[0][2] = clip[11] - clip[ 8]; + frustum[0][3] = clip[15] - clip[12]; + NORMALIZE_PLANE(0); + + // Left plane + frustum[1][0] = clip[ 3] + clip[ 0]; + frustum[1][1] = clip[ 7] + clip[ 4]; + frustum[1][2] = clip[11] + clip[ 8]; + frustum[1][3] = clip[15] + clip[12]; + NORMALIZE_PLANE(1); + + // Bottom plane + frustum[2][0] = clip[ 3] + clip[ 1]; + frustum[2][1] = clip[ 7] + clip[ 5]; + frustum[2][2] = clip[11] + clip[ 9]; + frustum[2][3] = clip[15] + clip[13]; + NORMALIZE_PLANE(2); + + // Top plane + frustum[3][0] = clip[ 3] - clip[ 1]; + frustum[3][1] = clip[ 7] - clip[ 5]; + frustum[3][2] = clip[11] - clip[ 9]; + frustum[3][3] = clip[15] - clip[13]; + NORMALIZE_PLANE(3); + + // Far plane + frustum[4][0] = clip[ 3] - clip[ 2]; + frustum[4][1] = clip[ 7] - clip[ 6]; + frustum[4][2] = clip[11] - clip[10]; + frustum[4][3] = clip[15] - clip[14]; + NORMALIZE_PLANE(4); + + // Near plane + frustum[5][0] = clip[ 3] + clip[ 2]; + frustum[5][1] = clip[ 7] + clip[ 6]; + frustum[5][2] = clip[11] + clip[10]; + frustum[5][3] = clip[15] + clip[14]; + NORMALIZE_PLANE(5); +} + +boolean HWR_SphereInFrustum(float x, float y, float z, float radius) +{ + int p; + + for (p = 0; p < 4; p++) + { + if (frustum[p][0] * x + + frustum[p][1] * y + + frustum[p][2] * z + + frustum[p][3] <= -radius) + { + return false; + } + } + return true; +} +#endif diff --git a/src/hardware/hw_clip.h b/src/hardware/hw_clip.h new file mode 100644 index 000000000..c55041b7e --- /dev/null +++ b/src/hardware/hw_clip.h @@ -0,0 +1,24 @@ +/* + * hw_clip.h + * SRB2CB + * + * PrBoom's OpenGL clipping + * + * + */ + +// OpenGL BSP clipping +#include "../doomdef.h" +#include "../tables.h" +#include "../doomtype.h" + +//#define HAVE_SPHEREFRUSTRUM // enable if you want HWR_SphereInFrustum and related code + +boolean HWR_clipper_SafeCheckRange(angle_t startAngle, angle_t endAngle); +void HWR_clipper_SafeAddClipRange(angle_t startangle, angle_t endangle); +void HWR_clipper_Clear(void); +angle_t HWR_FrustumAngle(void); +#ifdef HAVE_SPHEREFRUSTRUM +void HWR_FrustrumSetup(void); +boolean HWR_SphereInFrustum(float x, float y, float z, float radius); +#endif From 1e98e3b4f20ae9517a66e79f2a464cbcda9e28b7 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Tue, 10 Jan 2017 18:01:03 +0000 Subject: [PATCH 27/49] More progress, NEWCLIP added to doomdef.h, sadly it actually all lags the game so I've disabled it for now Other notes: * on second thought I'll keep the hw_clip functions' gld prefixes rather than HWR, not like it matters either way * despite the extra lag it does fix the issues with translucent walls and such when displayed at different vertical angles, such as with the GFZ1 waterfall --- src/doomdef.h | 7 ++ src/hardware/hw_clip.c | 62 +++++------ src/hardware/hw_clip.h | 14 +-- src/hardware/hw_main.c | 240 ++++++++++++++++++++++++++++++++++++++++- 4 files changed, 280 insertions(+), 43 deletions(-) diff --git a/src/doomdef.h b/src/doomdef.h index 7f641558f..e5fa3a482 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -502,4 +502,11 @@ extern const char *compdate, *comptime, *comprevision, *compbranch; /// \note Required for proper collision with moving sloped surfaces that have sector specials on them. //#define SECTORSPECIALSAFTERTHINK +/// FINALLY some real clipping that doesn't make walls dissappear AND speeds the game up +/// (that was the original comment from SRB2CB, sadly it is a lie and actually slows game down) +/// on the bright side it fixes some weird issues with translucent walls +/// \note SRB2CB port. +/// SRB2CB itself ported this from PrBoom+ +//#define NEWCLIP + #endif // __DOOMDEF__ diff --git a/src/hardware/hw_clip.c b/src/hardware/hw_clip.c index 47cbbfa2b..8b01cabd5 100644 --- a/src/hardware/hw_clip.c +++ b/src/hardware/hw_clip.c @@ -92,14 +92,14 @@ clipnode_t *freelist; clipnode_t *clipnodes; clipnode_t *cliphead; -static clipnode_t * HWR_clipnode_GetNew(void); -static clipnode_t * HWR_clipnode_NewRange(angle_t start, angle_t end); -static boolean HWR_clipper_IsRangeVisible(angle_t startAngle, angle_t endAngle); -static void HWR_clipper_AddClipRange(angle_t start, angle_t end); -static void HWR_clipper_RemoveRange(clipnode_t * range); -static void HWR_clipnode_Free(clipnode_t *node); +static clipnode_t * gld_clipnode_GetNew(void); +static clipnode_t * gld_clipnode_NewRange(angle_t start, angle_t end); +static boolean gld_clipper_IsRangeVisible(angle_t startAngle, angle_t endAngle); +static void gld_clipper_AddClipRange(angle_t start, angle_t end); +static void gld_clipper_RemoveRange(clipnode_t * range); +static void gld_clipnode_Free(clipnode_t *node); -static clipnode_t * HWR_clipnode_GetNew(void) +static clipnode_t * gld_clipnode_GetNew(void) { if (freelist) { @@ -113,26 +113,26 @@ static clipnode_t * HWR_clipnode_GetNew(void) } } -static clipnode_t * HWR_clipnode_NewRange(angle_t start, angle_t end) +static clipnode_t * gld_clipnode_NewRange(angle_t start, angle_t end) { - clipnode_t * c = HWR_clipnode_GetNew(); + clipnode_t * c = gld_clipnode_GetNew(); c->start = start; c->end = end; c->next = c->prev=NULL; return c; } -boolean HWR_clipper_SafeCheckRange(angle_t startAngle, angle_t endAngle) +boolean gld_clipper_SafeCheckRange(angle_t startAngle, angle_t endAngle) { if(startAngle > endAngle) { - return (HWR_clipper_IsRangeVisible(startAngle, ANGLE_MAX) || HWR_clipper_IsRangeVisible(0, endAngle)); + return (gld_clipper_IsRangeVisible(startAngle, ANGLE_MAX) || gld_clipper_IsRangeVisible(0, endAngle)); } - return HWR_clipper_IsRangeVisible(startAngle, endAngle); + return gld_clipper_IsRangeVisible(startAngle, endAngle); } -static boolean HWR_clipper_IsRangeVisible(angle_t startAngle, angle_t endAngle) +static boolean gld_clipper_IsRangeVisible(angle_t startAngle, angle_t endAngle) { clipnode_t *ci; ci = cliphead; @@ -152,13 +152,13 @@ static boolean HWR_clipper_IsRangeVisible(angle_t startAngle, angle_t endAngle) return true; } -static void HWR_clipnode_Free(clipnode_t *node) +static void gld_clipnode_Free(clipnode_t *node) { node->next = freelist; freelist = node; } -static void HWR_clipper_RemoveRange(clipnode_t *range) +static void gld_clipper_RemoveRange(clipnode_t *range) { if (range == cliphead) { @@ -176,25 +176,25 @@ static void HWR_clipper_RemoveRange(clipnode_t *range) } } - HWR_clipnode_Free(range); + gld_clipnode_Free(range); } -void HWR_clipper_SafeAddClipRange(angle_t startangle, angle_t endangle) +void gld_clipper_SafeAddClipRange(angle_t startangle, angle_t endangle) { if(startangle > endangle) { // The range has to added in two parts. - HWR_clipper_AddClipRange(startangle, ANGLE_MAX); - HWR_clipper_AddClipRange(0, endangle); + gld_clipper_AddClipRange(startangle, ANGLE_MAX); + gld_clipper_AddClipRange(0, endangle); } else { // Add the range as usual. - HWR_clipper_AddClipRange(startangle, endangle); + gld_clipper_AddClipRange(startangle, endangle); } } -static void HWR_clipper_AddClipRange(angle_t start, angle_t end) +static void gld_clipper_AddClipRange(angle_t start, angle_t end) { clipnode_t *node, *temp, *prevNode, *node2, *delnode; @@ -208,7 +208,7 @@ static void HWR_clipper_AddClipRange(angle_t start, angle_t end) { temp = node; node = node->next; - HWR_clipper_RemoveRange(temp); + gld_clipper_RemoveRange(temp); } else { @@ -250,7 +250,7 @@ static void HWR_clipper_AddClipRange(angle_t start, angle_t end) delnode = node2; node2 = node2->next; - HWR_clipper_RemoveRange(delnode); + gld_clipper_RemoveRange(delnode); } return; } @@ -260,7 +260,7 @@ static void HWR_clipper_AddClipRange(angle_t start, angle_t end) //just add range node = cliphead; prevNode = NULL; - temp = HWR_clipnode_NewRange(start, end); + temp = gld_clipnode_NewRange(start, end); while (node != NULL && node->start < end) { prevNode = node; @@ -296,13 +296,13 @@ static void HWR_clipper_AddClipRange(angle_t start, angle_t end) } else { - temp = HWR_clipnode_NewRange(start, end); + temp = gld_clipnode_NewRange(start, end); cliphead = temp; return; } } -void HWR_clipper_Clear(void) +void gld_clipper_Clear(void) { clipnode_t *node = cliphead; clipnode_t *temp; @@ -311,7 +311,7 @@ void HWR_clipper_Clear(void) { temp = node; node = node->next; - HWR_clipnode_Free(temp); + gld_clipnode_Free(temp); } cliphead = NULL; @@ -319,7 +319,7 @@ void HWR_clipper_Clear(void) #define RMUL (1.6f/1.333333f) -angle_t HWR_FrustumAngle(void) +angle_t gld_FrustumAngle(void) { double floatangle; angle_t a1; @@ -356,7 +356,7 @@ angle_t HWR_FrustumAngle(void) // btw to renable define HAVE_SPHEREFRUSTRUM in hw_clip.h #ifdef HAVE_SPHEREFRUSTRUM // -// HWR_FrustrumSetup +// gld_FrustrumSetup // #define CALCMATRIX(a, b, c, d, e, f, g, h)\ @@ -375,7 +375,7 @@ frustum[i][1] /= t; \ frustum[i][2] /= t; \ frustum[i][3] /= t -void HWR_FrustrumSetup(void) +void gld_FrustrumSetup(void) { float t; float clip[16]; @@ -446,7 +446,7 @@ void HWR_FrustrumSetup(void) NORMALIZE_PLANE(5); } -boolean HWR_SphereInFrustum(float x, float y, float z, float radius) +boolean gld_SphereInFrustum(float x, float y, float z, float radius) { int p; diff --git a/src/hardware/hw_clip.h b/src/hardware/hw_clip.h index c55041b7e..3ba26e5e5 100644 --- a/src/hardware/hw_clip.h +++ b/src/hardware/hw_clip.h @@ -12,13 +12,13 @@ #include "../tables.h" #include "../doomtype.h" -//#define HAVE_SPHEREFRUSTRUM // enable if you want HWR_SphereInFrustum and related code +//#define HAVE_SPHEREFRUSTRUM // enable if you want gld_SphereInFrustum and related code -boolean HWR_clipper_SafeCheckRange(angle_t startAngle, angle_t endAngle); -void HWR_clipper_SafeAddClipRange(angle_t startangle, angle_t endangle); -void HWR_clipper_Clear(void); -angle_t HWR_FrustumAngle(void); +boolean gld_clipper_SafeCheckRange(angle_t startAngle, angle_t endAngle); +void gld_clipper_SafeAddClipRange(angle_t startangle, angle_t endangle); +void gld_clipper_Clear(void); +angle_t gld_FrustumAngle(void); #ifdef HAVE_SPHEREFRUSTRUM -void HWR_FrustrumSetup(void); -boolean HWR_SphereInFrustum(float x, float y, float z, float radius); +void gld_FrustrumSetup(void); +boolean gld_SphereInFrustum(float x, float y, float z, float radius); #endif diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 7e8152583..c10f4bf12 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -44,6 +44,10 @@ #endif #include "hw_md2.h" +#ifdef NEWCLIP +#include "hw_clip.h" +#endif + #define R_FAKEFLOORS #define HWPRECIP #define SORTING @@ -99,8 +103,9 @@ CV_PossibleValue_t granisotropicmode_cons_t[] = {{1, "MIN"}, {16, "MAX"}, {0, NU boolean drawsky = true; // needs fix: walls are incorrectly clipped one column less +#ifndef NEWCLIP static consvar_t cv_grclipwalls = {"gr_clipwalls", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; - +#endif //development variables for diverse uses static consvar_t cv_gralpha = {"gr_alpha", "160", 0, CV_Unsigned, NULL, 0, NULL, NULL, 0, 0, NULL}; static consvar_t cv_grbeta = {"gr_beta", "0", 0, CV_Unsigned, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -1030,6 +1035,7 @@ static void HWR_ProjectWall(wallVert3D * wallVerts, // (in fact a clipping plane that has a constant, so can clip with simple 2d) // with the wall segment // +#ifndef NEWCLIP static float HWR_ClipViewSegment(INT32 x, polyvertex_t *v1, polyvertex_t *v2) { float num, den; @@ -1058,6 +1064,7 @@ static float HWR_ClipViewSegment(INT32 x, polyvertex_t *v1, polyvertex_t *v2) return num / den; } +#endif // // HWR_SplitWall @@ -1333,7 +1340,11 @@ static void HWR_DrawSkyWall(wallVert3D *wallVerts, FSurfaceInfo *Surf, fixed_t b // Anything between means the wall segment has been clipped with solidsegs, // reducing wall overdraw to a minimum // +#ifdef NEWCLIP +static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom +#else static void HWR_StoreWallRange(double startfrac, double endfrac) +#endif { wallVert3D wallVerts[4]; v2d_t vs, ve; // start, end vertices of 2d line (view from above) @@ -1358,8 +1369,10 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) extracolormap_t *colormap; FSurfaceInfo Surf; +#ifndef NEWCLIP if (startfrac > endfrac) return; +#endif gr_sidedef = gr_curline->sidedef; gr_linedef = gr_curline->linedef; @@ -1408,15 +1421,19 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) // x offset the texture fixed_t texturehpeg = gr_sidedef->textureoffset + gr_curline->offset; +#ifndef NEWCLIP // clip texture s start/end coords with solidsegs if (startfrac > 0.0f && startfrac < 1.0f) cliplow = (float)(texturehpeg + (gr_curline->flength*FRACUNIT) * startfrac); else +#endif cliplow = (float)texturehpeg; +#ifndef NEWCLIP if (endfrac > 0.0f && endfrac < 1.0f) cliphigh = (float)(texturehpeg + (gr_curline->flength*FRACUNIT) * endfrac); else +#endif cliphigh = (float)(texturehpeg + (gr_curline->flength*FRACUNIT)); } @@ -2325,6 +2342,135 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) //Hurdler: end of 3d-floors test } +// From PrBoom: +// +// e6y: Check whether the player can look beyond this line +// +#ifdef NEWCLIP +// Don't modify anything here, just check +// Kalaron: Modified for sloped linedefs +static boolean CheckClip(seg_t * seg, sector_t * afrontsector, sector_t * abacksector) +{ + fixed_t frontf1,frontf2, frontc1, frontc2; // front floor/ceiling ends + fixed_t backf1, backf2, backc1, backc2; // back floor ceiling ends + + // GZDoom method of sloped line clipping + +#ifdef ESLOPE + if (afrontsector->f_slope || afrontsector->c_slope || abacksector->f_slope || abacksector->c_slope) + { + fixed_t v1x, v1y, v2x, v2y; // the seg's vertexes as fixed_t + v1x = FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv1)->x); + v1y = FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv1)->y); + 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; + + 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) +#undef SLOPEPARAMS + } + else +#endif + { + frontf1 = frontf2 = afrontsector->floorheight; + frontc1 = frontc2 = afrontsector->ceilingheight; + backf1 = backf2 = abacksector->floorheight; + backc1 = backc2 = abacksector->ceilingheight; + } + + // now check for closed sectors! + if (backc1 <= frontf1 && backc2 <= frontf2) + { + if (!seg->sidedef->toptexture) + return false; + + if (abacksector->ceilingpic == skyflatnum && afrontsector->ceilingpic == skyflatnum) + return false; + + return true; + } + + if (backf1 >= frontc1 && backf2 >= frontc2) + { + if (!seg->sidedef->bottomtexture) + return false; + + // properly render skies (consider door "open" if both floors are sky): + if (abacksector->ceilingpic == skyflatnum && afrontsector->ceilingpic == skyflatnum) + return false; + + return true; + } + + if (backc1 <= backf1 && backc2 <= backf2) + { + // preserve a kind of transparent door/lift special effect: + if (backc1 < frontc1 || backc2 < frontc2) + { + if (!seg->sidedef->toptexture) + return false; + } + if (backf1 > frontf1 || backf2 > frontf2) + { + if (!seg->sidedef->bottomtexture) + return false; + } + if (abacksector->ceilingpic == skyflatnum && afrontsector->ceilingpic == skyflatnum) + return false; + + if (abacksector->floorpic == skyflatnum && afrontsector->floorpic == skyflatnum) + return false; + + return true; + } + + + // Reject empty lines used for triggers and special events. + // Identical floor and ceiling on both sides, + // identical light levels on both sides, + // and no middle texture. + if ( +#ifdef POLYOBJECTS + !seg->polyseg && +#endif + gr_backsector->ceilingpic == gr_frontsector->ceilingpic + && gr_backsector->floorpic == gr_frontsector->floorpic +#ifdef ESLOPE + && gr_backsector->f_slope == gr_frontsector->f_slope + && gr_backsector->c_slope == gr_frontsector->c_slope +#endif + && gr_backsector->lightlevel == gr_frontsector->lightlevel + && !gr_curline->sidedef->midtexture + // Check offsets too! + && gr_backsector->floor_xoffs == gr_frontsector->floor_xoffs + && gr_backsector->floor_yoffs == gr_frontsector->floor_yoffs + && gr_backsector->floorpic_angle == gr_frontsector->floorpic_angle + && gr_backsector->ceiling_xoffs == gr_frontsector->ceiling_xoffs + && gr_backsector->ceiling_yoffs == gr_frontsector->ceiling_yoffs + && gr_backsector->ceilingpic_angle == gr_frontsector->ceilingpic_angle + // Consider altered lighting. + && gr_backsector->floorlightsec == gr_frontsector->floorlightsec + && gr_backsector->ceilinglightsec == gr_frontsector->ceilinglightsec + // Consider colormaps + && gr_backsector->extra_colormap == gr_frontsector->extra_colormap + && ((!gr_frontsector->ffloors && !gr_backsector->ffloors) + || gr_frontsector->tag == gr_backsector->tag)) + { + return false; + } + + + return false; +} +#else //Hurdler: just like in r_bsp.c #if 1 #define MAXSEGS MAXVIDWIDTH/2+1 @@ -2610,6 +2756,7 @@ static void HWR_ClearClipSegs(void) gr_solidsegs[1].last = 0x7fffffff; hw_newend = gr_solidsegs+2; } +#endif // NEWCLIP // -----------------+ // HWR_AddLine : Clips the given segment and adds any visible pieces to the line list. @@ -2618,17 +2765,20 @@ static void HWR_ClearClipSegs(void) // -----------------+ static void HWR_AddLine(seg_t * line) { - INT32 x1, x2; angle_t angle1, angle2; +#ifndef NEWCLIP + INT32 x1, x2; angle_t span, tspan; +#endif // SoM: Backsector needs to be run through R_FakeFlat 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; @@ -2641,6 +2791,18 @@ static void HWR_AddLine(seg_t * line) angle1 = R_PointToAngle(v1x, v1y); angle2 = R_PointToAngle(v2x, v2y); +#ifdef NEWCLIP + // PrBoom: Back side, i.e. backface culling - read: endAngle >= startAngle! + if (angle2 - angle1 < ANGLE_180) + return; + + // PrBoom: use REAL clipping math YAYYYYYYY!!! + + if (!gld_clipper_SafeCheckRange(angle2, angle1)) + { + return; + } +#else // Clip to view edges. span = angle1 - angle2; @@ -2719,8 +2881,35 @@ static void HWR_AddLine(seg_t * line) return; } */ +#endif + gr_backsector = line->backsector; +#ifdef NEWCLIP + if (!line->backsector) + { + gld_clipper_SafeAddClipRange(angle2, angle1); + } + else + { + gr_backsector = R_FakeFlat(gr_backsector, &tempsec, NULL, NULL, true); + if (line->frontsector == line->backsector) + { + if (!line->sidedef->midtexture) + { + //e6y: nothing to do here! + //return; + } + } + if (CheckClip(line, gr_frontsector, gr_backsector)) + { + gld_clipper_SafeAddClipRange(angle2, angle1); + } + } + + HWR_ProcessSeg(); // Doesn't need arguments because they're defined globally :D + return; +#else // Single sided line? if (!gr_backsector) goto clipsolid; @@ -2835,6 +3024,7 @@ clipsolid: if (x1 == x2) goto clippass; HWR_ClipSolidWallSegment(x1, x2-1); +#endif } // HWR_CheckBBox @@ -2846,9 +3036,13 @@ clipsolid: static boolean HWR_CheckBBox(fixed_t *bspcoord) { - INT32 boxpos, sx1, sx2; + INT32 boxpos; fixed_t px1, py1, px2, py2; - angle_t angle1, angle2, span, tspan; + angle_t angle1, angle2; +#ifndef NEWCLIP + INT32 sx1, sx2; + angle_t span, tspan; +#endif // Find the corners of the box // that define the edges from current viewpoint. @@ -2874,6 +3068,11 @@ static boolean HWR_CheckBBox(fixed_t *bspcoord) px2 = bspcoord[checkcoord[boxpos][2]]; py2 = bspcoord[checkcoord[boxpos][3]]; +#ifdef NEWCLIP + angle1 = R_PointToAngle(px1, py1); + angle2 = R_PointToAngle(px2, py2); + return gld_clipper_SafeCheckRange(angle2, angle1); +#else // check clip list for an open space angle1 = R_PointToAngle2(dup_viewx>>1, dup_viewy>>1, px1>>1, py1>>1) - dup_viewangle; angle2 = R_PointToAngle2(dup_viewx>>1, dup_viewy>>1, px2>>1, py2>>1) - dup_viewangle; @@ -2921,6 +3120,7 @@ static boolean HWR_CheckBBox(fixed_t *bspcoord) return false; return HWR_ClipToSolidSegs(sx1, sx2 - 1); +#endif } #ifdef POLYOBJECTS @@ -5694,7 +5894,19 @@ if (0) #ifdef SORTING drawcount = 0; #endif +#ifdef NEWCLIP + if (rendermode == render_opengl) + { + angle_t a1 = gld_FrustumAngle(); + gld_clipper_Clear(); + gld_clipper_SafeAddClipRange(viewangle + a1, viewangle - a1); +#ifdef HAVE_SPHEREFRUSTRUM + gld_FrustrumSetup(); +#endif + } +#else HWR_ClearClipSegs(); +#endif //04/01/2000: Hurdler: added for T&L // Actually it only works on Walls and Planes @@ -5704,6 +5916,7 @@ if (0) HWR_RenderBSPNode((INT32)numnodes-1); +#ifndef NEWCLIP // Make a viewangle int so we can render things based on mouselook if (player == &players[consoleplayer]) viewangle = localaiming; @@ -5730,6 +5943,7 @@ if (0) dup_viewangle += ANGLE_90; } +#endif // Check for new console commands. NetUpdate(); @@ -5901,7 +6115,19 @@ if (0) #ifdef SORTING drawcount = 0; #endif +#ifdef NEWCLIP + if (rendermode == render_opengl) + { + angle_t a1 = gld_FrustumAngle(); + gld_clipper_Clear(); + gld_clipper_SafeAddClipRange(viewangle + a1, viewangle - a1); +#ifdef HAVE_SPHEREFRUSTRUM + gld_FrustrumSetup(); +#endif + } +#else HWR_ClearClipSegs(); +#endif //04/01/2000: Hurdler: added for T&L // Actually it only works on Walls and Planes @@ -5911,6 +6137,7 @@ if (0) HWR_RenderBSPNode((INT32)numnodes-1); +#ifndef NEWCLIP // Make a viewangle int so we can render things based on mouselook if (player == &players[consoleplayer]) viewangle = localaiming; @@ -5937,6 +6164,7 @@ if (0) dup_viewangle += ANGLE_90; } +#endif // Check for new console commands. NetUpdate(); @@ -6079,7 +6307,9 @@ static inline void HWR_AddEngineCommands(void) { // engine state variables //CV_RegisterVar(&cv_grzbuffer); +#ifndef NEWCLIP CV_RegisterVar(&cv_grclipwalls); +#endif // engine development mode variables // - usage may vary from version to version.. From c4569e61a8feab59eb5635daf536e9605048a176 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Tue, 10 Jan 2017 20:07:02 +0000 Subject: [PATCH 28/49] Made some efforts to improve efficiency of new code, hard to tell if I've made it better or worse though honestly R_IsEmptyLine is now a thing too btw --- src/hardware/hw_main.c | 94 +++++++++--------------------------------- src/r_bsp.c | 60 ++++++++++++++------------- src/r_bsp.h | 1 + 3 files changed, 52 insertions(+), 103 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index c10f4bf12..c148e7c41 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -2347,6 +2347,7 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) // e6y: Check whether the player can look beyond this line // #ifdef NEWCLIP +boolean checkforemptylines = true; // Don't modify anything here, just check // Kalaron: Modified for sloped linedefs static boolean CheckClip(seg_t * seg, sector_t * afrontsector, sector_t * abacksector) @@ -2389,6 +2390,7 @@ static boolean CheckClip(seg_t * seg, sector_t * afrontsector, sector_t * abacks // now check for closed sectors! if (backc1 <= frontf1 && backc2 <= frontf2) { + checkforemptylines = false; if (!seg->sidedef->toptexture) return false; @@ -2400,6 +2402,7 @@ static boolean CheckClip(seg_t * seg, sector_t * afrontsector, sector_t * abacks if (backf1 >= frontc1 && backf2 >= frontc2) { + checkforemptylines = false; if (!seg->sidedef->bottomtexture) return false; @@ -2412,6 +2415,7 @@ static boolean CheckClip(seg_t * seg, sector_t * afrontsector, sector_t * abacks if (backc1 <= backf1 && backc2 <= backf2) { + checkforemptylines = false; // preserve a kind of transparent door/lift special effect: if (backc1 < frontc1 || backc2 < frontc2) { @@ -2432,41 +2436,12 @@ static boolean CheckClip(seg_t * seg, sector_t * afrontsector, sector_t * abacks return true; } - - // Reject empty lines used for triggers and special events. - // Identical floor and ceiling on both sides, - // identical light levels on both sides, - // and no middle texture. - if ( -#ifdef POLYOBJECTS - !seg->polyseg && -#endif - gr_backsector->ceilingpic == gr_frontsector->ceilingpic - && gr_backsector->floorpic == gr_frontsector->floorpic -#ifdef ESLOPE - && gr_backsector->f_slope == gr_frontsector->f_slope - && gr_backsector->c_slope == gr_frontsector->c_slope -#endif - && gr_backsector->lightlevel == gr_frontsector->lightlevel - && !gr_curline->sidedef->midtexture - // Check offsets too! - && gr_backsector->floor_xoffs == gr_frontsector->floor_xoffs - && gr_backsector->floor_yoffs == gr_frontsector->floor_yoffs - && gr_backsector->floorpic_angle == gr_frontsector->floorpic_angle - && gr_backsector->ceiling_xoffs == gr_frontsector->ceiling_xoffs - && gr_backsector->ceiling_yoffs == gr_frontsector->ceiling_yoffs - && gr_backsector->ceilingpic_angle == gr_frontsector->ceilingpic_angle - // Consider altered lighting. - && gr_backsector->floorlightsec == gr_frontsector->floorlightsec - && gr_backsector->ceilinglightsec == gr_frontsector->ceilinglightsec - // Consider colormaps - && gr_backsector->extra_colormap == gr_frontsector->extra_colormap - && ((!gr_frontsector->ffloors && !gr_backsector->ffloors) - || gr_frontsector->tag == gr_backsector->tag)) - { - return false; - } - + if (backc1 != frontc1 || backc2 != frontc2 + || backf1 != frontf1 || backf2 != frontf2) + { + checkforemptylines = false; + return false; + } return false; } @@ -2802,6 +2777,8 @@ static void HWR_AddLine(seg_t * line) { return; } + + checkforemptylines = true; #else // Clip to view edges. span = angle1 - angle2; @@ -2893,18 +2870,17 @@ static void HWR_AddLine(seg_t * line) else { gr_backsector = R_FakeFlat(gr_backsector, &tempsec, NULL, NULL, true); - if (line->frontsector == line->backsector) - { - if (!line->sidedef->midtexture) - { - //e6y: nothing to do here! - //return; - } - } if (CheckClip(line, gr_frontsector, gr_backsector)) { gld_clipper_SafeAddClipRange(angle2, angle1); + checkforemptylines = false; } + // Reject empty lines used for triggers and special events. + // Identical floor and ceiling on both sides, + // identical light levels on both sides, + // and no middle texture. + if (checkforemptylines && R_IsEmptyLine(line, gr_frontsector, gr_backsector)) + return; } HWR_ProcessSeg(); // Doesn't need arguments because they're defined globally :D @@ -2981,38 +2957,8 @@ static void HWR_AddLine(seg_t * line) // Identical floor and ceiling on both sides, // identical light levels on both sides, // and no middle texture. - if ( -#ifdef POLYOBJECTS - !line->polyseg && -#endif - gr_backsector->ceilingpic == gr_frontsector->ceilingpic - && gr_backsector->floorpic == gr_frontsector->floorpic -#ifdef ESLOPE - && gr_backsector->f_slope == gr_frontsector->f_slope - && gr_backsector->c_slope == gr_frontsector->c_slope -#endif - && gr_backsector->lightlevel == gr_frontsector->lightlevel - && !gr_curline->sidedef->midtexture - // Check offsets too! - && gr_backsector->floor_xoffs == gr_frontsector->floor_xoffs - && gr_backsector->floor_yoffs == gr_frontsector->floor_yoffs - && gr_backsector->floorpic_angle == gr_frontsector->floorpic_angle - && gr_backsector->ceiling_xoffs == gr_frontsector->ceiling_xoffs - && gr_backsector->ceiling_yoffs == gr_frontsector->ceiling_yoffs - && gr_backsector->ceilingpic_angle == gr_frontsector->ceilingpic_angle - // Consider altered lighting. - && gr_backsector->floorlightsec == gr_frontsector->floorlightsec - && gr_backsector->ceilinglightsec == gr_frontsector->ceilinglightsec - // Consider colormaps - && gr_backsector->extra_colormap == gr_frontsector->extra_colormap - && ((!gr_frontsector->ffloors && !gr_backsector->ffloors) - || gr_frontsector->tag == gr_backsector->tag)) - // SoM: For 3D sides... Boris, would you like to take a - // crack at rendering 3D sides? You would need to add the - // above check and add code to HWR_StoreWallRange... - { + if (R_IsEmptyLine(curline, frontsector, backsector)) return; - } clippass: if (x1 == x2) diff --git a/src/r_bsp.c b/src/r_bsp.c index abb11204a..4ce89f009 100644 --- a/src/r_bsp.c +++ b/src/r_bsp.c @@ -365,6 +365,36 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel, return sec; } +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 +#ifdef ESLOPE + && back->f_slope == front->f_slope + && back->c_slope == front->c_slope +#endif + && back->lightlevel == front->lightlevel + && !line->sidedef->midtexture + // Check offsets too! + && back->floor_xoffs == front->floor_xoffs + && back->floor_yoffs == front->floor_yoffs + && back->floorpic_angle == front->floorpic_angle + && back->ceiling_xoffs == front->ceiling_xoffs + && back->ceiling_yoffs == front->ceiling_yoffs + && back->ceilingpic_angle == front->ceilingpic_angle + // Consider altered lighting. + && back->floorlightsec == front->floorlightsec + && back->ceilinglightsec == front->ceilinglightsec + // Consider colormaps + && back->extra_colormap == front->extra_colormap + && ((!front->ffloors && !back->ffloors) + || front->tag == back->tag)); +} + // // R_AddLine // Clips the given segment and adds any visible pieces to the line list. @@ -526,36 +556,8 @@ static void R_AddLine(seg_t *line) // Identical floor and ceiling on both sides, identical light levels on both sides, // and no middle texture. - if ( -#ifdef POLYOBJECTS - !line->polyseg && -#endif - backsector->ceilingpic == frontsector->ceilingpic - && backsector->floorpic == frontsector->floorpic -#ifdef ESLOPE - && backsector->f_slope == frontsector->f_slope - && backsector->c_slope == frontsector->c_slope -#endif - && backsector->lightlevel == frontsector->lightlevel - && !curline->sidedef->midtexture - // Check offsets too! - && backsector->floor_xoffs == frontsector->floor_xoffs - && backsector->floor_yoffs == frontsector->floor_yoffs - && backsector->floorpic_angle == frontsector->floorpic_angle - && backsector->ceiling_xoffs == frontsector->ceiling_xoffs - && backsector->ceiling_yoffs == frontsector->ceiling_yoffs - && backsector->ceilingpic_angle == frontsector->ceilingpic_angle - // Consider altered lighting. - && backsector->floorlightsec == frontsector->floorlightsec - && backsector->ceilinglightsec == frontsector->ceilinglightsec - // Consider colormaps - && backsector->extra_colormap == frontsector->extra_colormap - && ((!frontsector->ffloors && !backsector->ffloors) - || frontsector->tag == backsector->tag)) - { + if (R_IsEmptyLine(line, frontsector, backsector)) return; - } - clippass: R_ClipPassWallSegment(x1, x2 - 1); diff --git a/src/r_bsp.h b/src/r_bsp.h index e871b5dde..80824831b 100644 --- a/src/r_bsp.h +++ b/src/r_bsp.h @@ -50,6 +50,7 @@ extern polyobj_t **po_ptrs; // temp ptr array to sort polyobject pointers sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel, INT32 *ceilinglightlevel, boolean back); +boolean R_IsEmptyLine(seg_t *line, sector_t *front, sector_t *back); INT32 R_GetPlaneLight(sector_t *sector, fixed_t planeheight, boolean underside); void R_Prep3DFloors(sector_t *sector); From 8ba0f2a177086a26313aac58eb8ff4b2ecc95c09 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 12 Jan 2017 21:44:27 +0000 Subject: [PATCH 29/49] clipping code didn't seem so bad this time (at least compared to without), let's enable it now? --- src/doomdef.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doomdef.h b/src/doomdef.h index e5fa3a482..ff09144ed 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -507,6 +507,6 @@ extern const char *compdate, *comptime, *comprevision, *compbranch; /// on the bright side it fixes some weird issues with translucent walls /// \note SRB2CB port. /// SRB2CB itself ported this from PrBoom+ -//#define NEWCLIP +#define NEWCLIP #endif // __DOOMDEF__ From 3608f73d39a60fe79c368691f8171a20691ea4ce Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Mon, 16 Jan 2017 15:48:07 +0000 Subject: [PATCH 30/49] Updated SRB2.cbp for hw_clip.c/h --- SRB2.cbp | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/SRB2.cbp b/SRB2.cbp index 74ec96c6e..5aa623fa8 100644 --- a/SRB2.cbp +++ b/SRB2.cbp @@ -1174,6 +1174,39 @@ HW3SOUND for 3D hardware sound support